aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/DMA-ISA-LPC.txt151
-rw-r--r--Documentation/DocBook/kernel-hacking.tmpl310
-rw-r--r--Documentation/RCU/rcuref.txt74
-rw-r--r--Documentation/applying-patches.txt439
-rw-r--r--Documentation/dvb/bt8xx.txt89
-rw-r--r--Documentation/dvb/ci.txt9
-rw-r--r--Documentation/fb/cyblafb/bugs14
-rw-r--r--Documentation/fb/cyblafb/credits7
-rw-r--r--Documentation/fb/cyblafb/documentation17
-rw-r--r--Documentation/fb/cyblafb/fb.modes155
-rw-r--r--Documentation/fb/cyblafb/performance80
-rw-r--r--Documentation/fb/cyblafb/todo32
-rw-r--r--Documentation/fb/cyblafb/usage206
-rw-r--r--Documentation/fb/cyblafb/whycyblafb85
-rw-r--r--Documentation/fb/modedb.txt73
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/filesystems/files.txt123
-rw-r--r--Documentation/filesystems/fuse.txt315
-rw-r--r--Documentation/filesystems/ntfs.txt12
-rw-r--r--Documentation/filesystems/proc.txt42
-rw-r--r--Documentation/filesystems/v9fs.txt95
-rw-r--r--Documentation/filesystems/vfs.txt435
-rw-r--r--Documentation/input/yealink.txt203
-rw-r--r--Documentation/kdump/kdump.txt16
-rw-r--r--Documentation/sparse.txt2
-rw-r--r--Documentation/video4linux/CARDLIST.bttv4
-rw-r--r--Documentation/video4linux/CARDLIST.saa71343
-rw-r--r--Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--MAINTAINERS37
-rw-r--r--arch/alpha/kernel/module.c8
-rw-r--r--arch/alpha/kernel/osf_sys.c4
-rw-r--r--arch/alpha/kernel/sys_marvel.c5
-rw-r--r--arch/arm/common/locomo.c101
-rw-r--r--arch/arm/configs/s3c2410_defconfig218
-rw-r--r--arch/arm/mach-clps7500/core.c2
-rw-r--r--arch/arm/mach-ebsa110/core.c2
-rw-r--r--arch/arm/mach-epxa10db/arch.c2
-rw-r--r--arch/arm/mach-footbridge/isa.c2
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c2
-rw-r--r--arch/arm/mach-ixp2000/core.c2
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c2
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c2
-rw-r--r--arch/arm/mach-omap1/Kconfig8
-rw-r--r--arch/arm/mach-omap1/Makefile3
-rw-r--r--arch/arm/mach-omap1/board-generic.c38
-rw-r--r--arch/arm/mach-omap1/board-h2.c27
-rw-r--r--arch/arm/mach-omap1/board-h3.c17
-rw-r--r--arch/arm/mach-omap1/board-innovator.c13
-rw-r--r--arch/arm/mach-omap1/board-netstar.c9
-rw-r--r--arch/arm/mach-omap1/board-osk.c124
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c5
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c64
-rw-r--r--arch/arm/mach-omap1/devices.c351
-rw-r--r--arch/arm/mach-omap1/fpga.c4
-rw-r--r--arch/arm/mach-omap1/io.c30
-rw-r--r--arch/arm/mach-omap1/irq.c2
-rw-r--r--arch/arm/mach-omap1/leds-h2p2-debug.c3
-rw-r--r--arch/arm/mach-omap1/leds-innovator.c2
-rw-r--r--arch/arm/mach-omap1/leds-osk.c8
-rw-r--r--arch/arm/mach-omap1/leds.c12
-rw-r--r--arch/arm/mach-omap1/serial.c86
-rw-r--r--arch/arm/mach-omap1/time.c40
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c2
-rw-r--r--arch/arm/mach-rpc/riscpc.c2
-rw-r--r--arch/arm/mach-s3c2410/devs.c11
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c51
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-shark/core.c2
-rw-r--r--arch/arm/mm/flush.c52
-rw-r--r--arch/i386/boot/video.S7
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c20
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-smi.c2
-rw-r--r--arch/i386/kernel/io_apic.c4
-rw-r--r--arch/i386/kernel/mpparse.c24
-rw-r--r--arch/i386/kernel/ptrace.c22
-rw-r--r--arch/i386/kernel/setup.c17
-rw-r--r--arch/i386/kernel/sigframe.h8
-rw-r--r--arch/i386/kernel/time.c3
-rw-r--r--arch/i386/pci/i386.c6
-rw-r--r--arch/ia64/Kconfig6
-rw-r--r--arch/ia64/configs/sn2_defconfig1
-rw-r--r--arch/ia64/configs/tiger_defconfig1
-rw-r--r--arch/ia64/configs/zx1_defconfig1
-rw-r--r--arch/ia64/defconfig3
-rw-r--r--arch/ia64/kernel/acpi.c2
-rw-r--r--arch/ia64/kernel/entry.S29
-rw-r--r--arch/ia64/kernel/iosapic.c2
-rw-r--r--arch/ia64/kernel/perfmon.c9
-rw-r--r--arch/ia64/lib/memcpy_mck.S3
-rw-r--r--arch/ia64/mm/fault.c6
-rw-r--r--arch/ia64/pci/pci.c2
-rw-r--r--arch/ia64/sn/kernel/setup.c2
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c4
-rw-r--r--arch/ia64/sn/kernel/xpnet.c6
-rw-r--r--arch/m68k/amiga/amisound.c2
-rw-r--r--arch/m68k/mac/macboing.c3
-rw-r--r--arch/m68knommu/platform/523x/Makefile19
-rw-r--r--arch/m68knommu/platform/5272/config.c6
-rw-r--r--arch/m68knommu/platform/5307/Makefile1
-rw-r--r--arch/m68knommu/platform/68328/config.c94
-rw-r--r--arch/m68knommu/platform/68328/timers.c106
-rw-r--r--arch/m68knommu/platform/68EZ328/config.c80
-rw-r--r--arch/m68knommu/platform/68VZ328/config.c (renamed from arch/m68knommu/platform/68VZ328/de2/config.c)141
-rw-r--r--arch/m68knommu/platform/68VZ328/ucdimm/config.c117
-rw-r--r--arch/mips/Kconfig7
-rw-r--r--arch/mips/configs/tb0287_defconfig1041
-rw-r--r--arch/mips/kernel/genrtc.c2
-rw-r--r--arch/mips/kernel/i8259.c2
-rw-r--r--arch/mips/kernel/irixioctl.c5
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-tb0287.c65
-rw-r--r--arch/ppc/8xx_io/cs4218_tdm.c2
-rw-r--r--arch/ppc/Kconfig10
-rw-r--r--arch/ppc/boot/common/ns16550.c8
-rw-r--r--arch/ppc/boot/common/util.S2
-rw-r--r--arch/ppc/kernel/Makefile3
-rw-r--r--arch/ppc/kernel/pci.c1
-rw-r--r--arch/ppc/kernel/syscalls.c4
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/platforms/4xx/ebony.c13
-rw-r--r--arch/ppc/platforms/hdpu.c2
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c7
-rw-r--r--arch/ppc/syslib/mpc10x_common.c4
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c2
-rw-r--r--arch/ppc/syslib/mv64x60.c2
-rw-r--r--arch/ppc/syslib/qspan_pci.c2
-rw-r--r--arch/ppc64/Makefile21
-rw-r--r--arch/ppc64/boot/Makefile53
-rw-r--r--arch/ppc64/boot/main.c31
-rw-r--r--arch/ppc64/kernel/bpa_iic.c28
-rw-r--r--arch/ppc64/kernel/eeh.c86
-rw-r--r--arch/ppc64/kernel/iSeries_VpdInfo.c5
-rw-r--r--arch/ppc64/kernel/iomap.c32
-rw-r--r--arch/ppc64/kernel/iommu.c3
-rw-r--r--arch/ppc64/kernel/maple_pci.c4
-rw-r--r--arch/ppc64/kernel/misc.S6
-rw-r--r--arch/ppc64/kernel/pSeries_iommu.c72
-rw-r--r--arch/ppc64/kernel/pci.c67
-rw-r--r--arch/ppc64/kernel/pci.h1
-rw-r--r--arch/ppc64/kernel/pci_dn.c47
-rw-r--r--arch/ppc64/kernel/pci_iommu.c2
-rw-r--r--arch/ppc64/kernel/pmac_feature.c8
-rw-r--r--arch/ppc64/kernel/pmac_pci.c6
-rw-r--r--arch/ppc64/kernel/pmc.c2
-rw-r--r--arch/ppc64/kernel/prom.c1
-rw-r--r--arch/ppc64/kernel/rtas_pci.c39
-rw-r--r--arch/ppc64/kernel/setup.c2
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c55
-rw-r--r--arch/ppc64/kernel/syscalls.c4
-rw-r--r--arch/ppc64/kernel/u3_iommu.c4
-rw-r--r--arch/ppc64/kernel/udbg.c6
-rw-r--r--arch/ppc64/mm/init.c4
-rw-r--r--arch/s390/Makefile2
-rw-r--r--arch/sparc/lib/atomic32.c2
-rw-r--r--arch/sparc64/kernel/pci.c127
-rw-r--r--arch/sparc64/kernel/pci_psycho.c34
-rw-r--r--arch/sparc64/kernel/pci_sabre.c36
-rw-r--r--arch/sparc64/kernel/pci_schizo.c48
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c9
-rw-r--r--arch/sparc64/lib/Makefile2
-rw-r--r--arch/sparc64/lib/mb.S73
-rw-r--r--arch/sparc64/solaris/ioctl.c15
-rw-r--r--arch/sparc64/solaris/timod.c29
-rw-r--r--arch/um/Makefile-x86_641
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h14
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h14
-rw-r--r--arch/um/scripts/Makefile.rules5
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c17
-rw-r--r--arch/x86_64/kernel/e820.c16
-rw-r--r--arch/x86_64/kernel/genapic_flat.c10
-rw-r--r--arch/x86_64/kernel/io_apic.c4
-rw-r--r--arch/x86_64/kernel/smpboot.c19
-rw-r--r--drivers/acorn/block/fd1772.c12
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/atm/idt77105.c6
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/block/acsi.c2
-rw-r--r--drivers/block/acsi_slm.c2
-rw-r--r--drivers/block/ataflop.c14
-rw-r--r--drivers/block/deadline-iosched.c5
-rw-r--r--drivers/block/floppy.c4
-rw-r--r--drivers/block/ps2esdi.c3
-rw-r--r--drivers/block/ub.c273
-rw-r--r--drivers/cdrom/aztcd.c2
-rw-r--r--drivers/cdrom/gscd.c2
-rw-r--r--drivers/cdrom/optcd.c2
-rw-r--r--drivers/cdrom/sbpcd.c9
-rw-r--r--drivers/cdrom/sjcd.c2
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/generic.c33
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/drm/drmP.h4
-rw-r--r--drivers/char/hangcheck-timer.c3
-rw-r--r--drivers/char/ip2main.c3
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c5
-rw-r--r--drivers/char/istallion.c2
-rw-r--r--drivers/char/keyboard.c3
-rw-r--r--drivers/char/pty.c5
-rw-r--r--drivers/char/synclink.c29
-rw-r--r--drivers/char/synclinkmp.c41
-rw-r--r--drivers/char/tty_io.c87
-rw-r--r--drivers/char/vt.c37
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/cpufreq/cpufreq.c6
-rw-r--r--drivers/i2c/busses/Kconfig16
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-pxa.c1022
-rw-r--r--drivers/ide/legacy/ide-cs.c6
-rw-r--r--drivers/ieee1394/video1394.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c8
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c8
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/md/md.c4
-rw-r--r--drivers/media/Makefile5
-rw-r--r--drivers/media/common/ir-common.c68
-rw-r--r--drivers/media/common/saa7146_fops.c1
-rw-r--r--drivers/media/common/saa7146_i2c.c6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c102
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c763
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c554
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h8
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c282
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h2
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig2
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c94
-rw-r--r--drivers/media/dvb/dvb-core/demux.h36
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c20
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c532
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h116
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c9
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig23
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c2
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c66
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h27
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c20
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c40
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c21
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c20
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c339
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c290
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.h109
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c7
-rw-r--r--drivers/media/dvb/frontends/cx24110.c22
-rw-r--r--drivers/media/dvb/frontends/cx24110.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c1
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c1
-rw-r--r--drivers/media/dvb/frontends/mt352.c6
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c9
-rw-r--r--drivers/media/dvb/frontends/or51132.c29
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c162
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h3
-rw-r--r--drivers/media/dvb/frontends/stv0297.c129
-rw-r--r--drivers/media/dvb/frontends/stv0297.h8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c19
-rw-r--r--drivers/media/dvb/frontends/stv0299.h4
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c3
-rw-r--r--drivers/media/dvb/frontends/ves1820.c15
-rw-r--r--drivers/media/dvb/ttpci/av7110.c201
-rw-r--r--drivers/media/dvb/ttpci/av7110.h11
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c8
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c140
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c74
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c9
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c197
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c5
-rw-r--r--drivers/media/dvb/ttpci/budget.c6
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c10
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c1
-rw-r--r--drivers/media/video/Kconfig15
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/btcx-risc.c1
-rw-r--r--drivers/media/video/btcx-risc.h1
-rw-r--r--drivers/media/video/bttv-cards.c1180
-rw-r--r--drivers/media/video/bttv-driver.c67
-rw-r--r--drivers/media/video/bttv-gpio.c1
-rw-r--r--drivers/media/video/bttv-i2c.c2
-rw-r--r--drivers/media/video/bttv-if.c1
-rw-r--r--drivers/media/video/bttv-risc.c1
-rw-r--r--drivers/media/video/bttv-vbi.c1
-rw-r--r--drivers/media/video/bttv.h3
-rw-r--r--drivers/media/video/bttvp.h1
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c73
-rw-r--r--drivers/media/video/cx88/cx88-cards.c26
-rw-r--r--drivers/media/video/cx88/cx88-core.c21
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c53
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c1
-rw-r--r--drivers/media/video/cx88/cx88-input.c97
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c37
-rw-r--r--drivers/media/video/cx88/cx88-reg.h24
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c742
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c1
-rw-r--r--drivers/media/video/cx88/cx88-video.c408
-rw-r--r--drivers/media/video/cx88/cx88.h41
-rw-r--r--drivers/media/video/ir-kbd-gpio.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c1
-rw-r--r--drivers/media/video/msp3400.c10
-rw-r--r--drivers/media/video/msp3400.h1
-rw-r--r--drivers/media/video/mt20xx.c2
-rw-r--r--drivers/media/video/rds.h48
-rw-r--r--drivers/media/video/saa6588.c534
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c132
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h1
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c25
-rw-r--r--drivers/media/video/saa7134/saa7134.h4
-rw-r--r--drivers/media/video/tda8290.c19
-rw-r--r--drivers/media/video/tda9887.c52
-rw-r--r--drivers/media/video/tea5767.c37
-rw-r--r--drivers/media/video/tuner-core.c91
-rw-r--r--drivers/media/video/tuner-simple.c54
-rw-r--r--drivers/media/video/tvaudio.c206
-rw-r--r--drivers/media/video/tveeprom.c362
-rw-r--r--drivers/media/video/tvmixer.c1
-rw-r--r--drivers/media/video/v4l1-compat.c16
-rw-r--r--drivers/media/video/v4l2-common.c18
-rw-r--r--drivers/media/video/video-buf-dvb.c1
-rw-r--r--drivers/media/video/video-buf.c1
-rw-r--r--drivers/mmc/mmc.c12
-rw-r--r--drivers/mmc/mmci.c2
-rw-r--r--drivers/mmc/pxamci.c4
-rw-r--r--drivers/mmc/wbsd.c4
-rw-r--r--drivers/net/atari_bionet.c2
-rw-r--r--drivers/net/atari_pamsnet.c2
-rw-r--r--drivers/net/bnx2.c7
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--drivers/net/cris/eth_v10.c6
-rw-r--r--drivers/net/cs89x0.c19
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/irda/irda-usb.c13
-rw-r--r--drivers/net/irda/vlsi_ir.h6
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parport/parport_pc.c2
-rw-r--r--drivers/pci/Kconfig17
-rw-r--r--drivers/pci/Makefile22
-rw-r--r--drivers/pci/bus.c51
-rw-r--r--drivers/pci/gen-devlist.c132
-rw-r--r--drivers/pci/hotplug.c53
-rw-r--r--drivers/pci/hotplug/Makefile3
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c8
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c299
-rw-r--r--drivers/pci/hotplug/rpaphp.h35
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c146
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c299
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c66
-rw-r--r--drivers/pci/hotplug/rpaphp_vio.c129
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c195
-rw-r--r--drivers/pci/hotplug/shpchp.h2
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pci/names.c137
-rw-r--r--drivers/pci/pci-driver.c37
-rw-r--r--drivers/pci/pci.c104
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/pci/pci.ids10180
-rw-r--r--drivers/pci/pcie/portdrv_pci.c8
-rw-r--r--drivers/pci/probe.c54
-rw-r--r--drivers/pci/proc.c12
-rw-r--r--drivers/pci/quirks.c13
-rw-r--r--drivers/pci/setup-bus.c4
-rw-r--r--drivers/pci/setup-res.c7
-rw-r--r--drivers/pcmcia/Kconfig7
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/cs.c9
-rw-r--r--drivers/pcmcia/cs_internal.h4
-rw-r--r--drivers/pcmcia/ds.c34
-rw-r--r--drivers/pcmcia/omap_cf.c373
-rw-r--r--drivers/pcmcia/pcmcia_resource.c11
-rw-r--r--drivers/pcmcia/yenta_socket.c47
-rw-r--r--drivers/sbus/char/aurora.c3
-rw-r--r--drivers/scsi/ahci.c16
-rw-r--r--drivers/scsi/ata_piix.c24
-rw-r--r--drivers/scsi/ch.c2
-rw-r--r--drivers/scsi/pluto.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c2
-rw-r--r--drivers/scsi/sata_mv.c16
-rw-r--r--drivers/scsi/sata_sis.c96
-rw-r--r--drivers/scsi/sata_uli.c14
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/8250_accent.c2
-rw-r--r--drivers/serial/8250_boca.c2
-rw-r--r--drivers/serial/8250_fourport.c2
-rw-r--r--drivers/serial/8250_hub6.c2
-rw-r--r--drivers/serial/8250_mca.c2
-rw-r--r--drivers/serial/serial_txx9.c118
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/class/Kconfig21
-rw-r--r--drivers/usb/class/usblp.c9
-rw-r--r--drivers/usb/core/Makefile4
-rw-r--r--drivers/usb/core/devio.c102
-rw-r--r--drivers/usb/core/hcd-pci.c28
-rw-r--r--drivers/usb/core/hcd.h8
-rw-r--r--drivers/usb/core/hub.c115
-rw-r--r--drivers/usb/core/hub.h7
-rw-r--r--drivers/usb/core/inode.c9
-rw-r--r--drivers/usb/core/message.c8
-rw-r--r--drivers/usb/core/urb.c26
-rw-r--r--drivers/usb/core/usb.c35
-rw-r--r--drivers/usb/core/usb.h5
-rw-r--r--drivers/usb/gadget/ether.c33
-rw-r--r--drivers/usb/gadget/file_storage.c33
-rw-r--r--drivers/usb/gadget/gadget_chips.h55
-rw-r--r--drivers/usb/gadget/serial.c51
-rw-r--r--drivers/usb/gadget/zero.c48
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/ehci-q.c7
-rw-r--r--drivers/usb/host/ehci-sched.c4
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/host/hc_crisv10.c4
-rw-r--r--drivers/usb/host/isp116x-hcd.c88
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c24
-rw-r--r--drivers/usb/host/ohci-s3c2410.c4
-rw-r--r--drivers/usb/input/Kconfig14
-rw-r--r--drivers/usb/input/Makefile1
-rw-r--r--drivers/usb/input/hid-core.c9
-rw-r--r--drivers/usb/input/keyspan_remote.c5
-rw-r--r--drivers/usb/input/map_to_7segment.h189
-rw-r--r--drivers/usb/input/yealink.c1013
-rw-r--r--drivers/usb/input/yealink.h220
-rw-r--r--drivers/usb/misc/auerswald.c3
-rw-r--r--drivers/usb/misc/ldusb.c6
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c4
-rw-r--r--drivers/usb/misc/usbtest.c2
-rw-r--r--drivers/usb/mon/Makefile2
-rw-r--r--drivers/usb/mon/mon_dma.c55
-rw-r--r--drivers/usb/mon/mon_text.c35
-rw-r--r--drivers/usb/mon/usb_mon.h4
-rw-r--r--drivers/usb/net/Kconfig208
-rw-r--r--drivers/usb/net/Makefile8
-rw-r--r--drivers/usb/net/asix.c948
-rw-r--r--drivers/usb/net/catc.c2
-rw-r--r--drivers/usb/net/cdc_ether.c509
-rw-r--r--drivers/usb/net/cdc_subset.c335
-rw-r--r--drivers/usb/net/gl620a.c407
-rw-r--r--drivers/usb/net/kaweth.c1
-rw-r--r--drivers/usb/net/net1080.c622
-rw-r--r--drivers/usb/net/pegasus.c1
-rw-r--r--drivers/usb/net/plusb.c156
-rw-r--r--drivers/usb/net/rndis_host.c615
-rw-r--r--drivers/usb/net/rtl8150.c1
-rw-r--r--drivers/usb/net/usbnet.c3226
-rw-r--r--drivers/usb/net/usbnet.h193
-rw-r--r--drivers/usb/net/zaurus.c386
-rw-r--r--drivers/usb/net/zd1201.c1
-rw-r--r--drivers/usb/serial/cypress_m8.c251
-rw-r--r--drivers/usb/serial/ftdi_sio.c56
-rw-r--r--drivers/usb/serial/ftdi_sio.h54
-rw-r--r--drivers/usb/serial/keyspan.c8
-rw-r--r--drivers/usb/serial/option.c203
-rw-r--r--drivers/usb/serial/pl2303.c6
-rw-r--r--drivers/usb/serial/usb-serial.c24
-rw-r--r--drivers/usb/storage/Kconfig12
-rw-r--r--drivers/usb/storage/Makefile1
-rw-r--r--drivers/usb/storage/onetouch.c210
-rw-r--r--drivers/usb/storage/onetouch.h9
-rw-r--r--drivers/usb/storage/scsiglue.c8
-rw-r--r--drivers/usb/storage/shuttle_usbat.c97
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/storage/unusual_devs.h19
-rw-r--r--drivers/usb/storage/usb.c79
-rw-r--r--drivers/usb/storage/usb.h1
-rw-r--r--drivers/video/Kconfig82
-rw-r--r--drivers/video/Makefile7
-rw-r--r--drivers/video/aty/aty128fb.c4
-rw-r--r--drivers/video/aty/atyfb_base.c14
-rw-r--r--drivers/video/aty/radeon_base.c34
-rw-r--r--drivers/video/console/bitblit.c148
-rw-r--r--drivers/video/console/fbcon.c185
-rw-r--r--drivers/video/console/fbcon.h3
-rw-r--r--drivers/video/console/vgacon.c71
-rw-r--r--drivers/video/cyblafb.c1456
-rw-r--r--drivers/video/fbcvt.c380
-rw-r--r--drivers/video/fbmem.c69
-rw-r--r--drivers/video/fbmon.c39
-rw-r--r--drivers/video/geode/Kconfig10
-rw-r--r--drivers/video/geode/display_gx1.c2
-rw-r--r--drivers/video/geode/geodefb.h1
-rw-r--r--drivers/video/geode/gx1fb_core.c182
-rw-r--r--drivers/video/geode/video_cs5530.c4
-rw-r--r--drivers/video/i810/Makefile5
-rw-r--r--drivers/video/i810/i810-i2c.c257
-rw-r--r--drivers/video/i810/i810.h14
-rw-r--r--drivers/video/i810/i810_main.c185
-rw-r--r--drivers/video/i810/i810_main.h16
-rw-r--r--drivers/video/intelfb/intelfb.h1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c21
-rw-r--r--drivers/video/intelfb/intelfbhw.c4
-rw-r--r--drivers/video/matrox/matroxfb_misc.c30
-rw-r--r--drivers/video/modedb.c62
-rw-r--r--drivers/video/nvidia/nv_i2c.c16
-rw-r--r--drivers/video/nvidia/nv_local.h4
-rw-r--r--drivers/video/nvidia/nv_proto.h2
-rw-r--r--drivers/video/nvidia/nv_setup.c6
-rw-r--r--drivers/video/nvidia/nvidia.c18
-rw-r--r--drivers/video/offb.c2
-rw-r--r--drivers/video/pxafb.c32
-rw-r--r--drivers/video/pxafb.h2
-rw-r--r--drivers/video/riva/fbdev.c4
-rw-r--r--drivers/video/s3c2410fb.c915
-rw-r--r--drivers/video/s3c2410fb.h56
-rw-r--r--drivers/video/savage/savagefb-i2c.c16
-rw-r--r--drivers/video/savage/savagefb.h13
-rw-r--r--drivers/video/savage/savagefb_driver.c152
-rw-r--r--drivers/video/sis/300vtbl.h1363
-rw-r--r--drivers/video/sis/310vtbl.h2125
-rw-r--r--drivers/video/sis/Makefile2
-rw-r--r--drivers/video/sis/init.c5603
-rw-r--r--drivers/video/sis/init.h1732
-rw-r--r--drivers/video/sis/init301.c9630
-rw-r--r--drivers/video/sis/init301.h351
-rw-r--r--drivers/video/sis/initdef.h145
-rw-r--r--drivers/video/sis/initextlfb.c238
-rw-r--r--drivers/video/sis/oem300.h335
-rw-r--r--drivers/video/sis/oem310.h421
-rw-r--r--drivers/video/sis/osdef.h27
-rw-r--r--drivers/video/sis/sis.h746
-rw-r--r--drivers/video/sis/sis_accel.c479
-rw-r--r--drivers/video/sis/sis_accel.h9
-rw-r--r--drivers/video/sis/sis_main.c7525
-rw-r--r--drivers/video/sis/sis_main.h602
-rw-r--r--drivers/video/sis/vgatypes.h155
-rw-r--r--drivers/video/sis/vstruct.h1097
-rw-r--r--drivers/video/tridentfb.c5
-rw-r--r--drivers/video/vesafb.c38
-rw-r--r--drivers/w1/Kconfig16
-rw-r--r--drivers/w1/Makefile7
-rw-r--r--drivers/w1/ds_w1_bridge.c24
-rw-r--r--drivers/w1/dscore.c161
-rw-r--r--drivers/w1/dscore.h10
-rw-r--r--drivers/w1/w1.c302
-rw-r--r--drivers/w1/w1.h22
-rw-r--r--drivers/w1/w1_ds2433.c327
-rw-r--r--drivers/w1/w1_family.c11
-rw-r--r--drivers/w1/w1_family.h7
-rw-r--r--drivers/w1/w1_int.c26
-rw-r--r--drivers/w1/w1_io.c24
-rw-r--r--drivers/w1/w1_io.h1
-rw-r--r--drivers/w1/w1_netlink.c26
-rw-r--r--drivers/w1/w1_netlink.h2
-rw-r--r--drivers/w1/w1_smem.c49
-rw-r--r--drivers/w1/w1_therm.c47
-rw-r--r--fs/9p/9p.c359
-rw-r--r--fs/9p/9p.h341
-rw-r--r--fs/9p/Makefile17
-rw-r--r--fs/9p/conv.c693
-rw-r--r--fs/9p/conv.h36
-rw-r--r--fs/9p/debug.h70
-rw-r--r--fs/9p/error.c93
-rw-r--r--fs/9p/error.h178
-rw-r--r--fs/9p/fid.c241
-rw-r--r--fs/9p/fid.h57
-rw-r--r--fs/9p/mux.c475
-rw-r--r--fs/9p/mux.h41
-rw-r--r--fs/9p/trans_fd.c172
-rw-r--r--fs/9p/trans_sock.c290
-rw-r--r--fs/9p/transport.h46
-rw-r--r--fs/9p/v9fs.c452
-rw-r--r--fs/9p/v9fs.h103
-rw-r--r--fs/9p/v9fs_vfs.h53
-rw-r--r--fs/9p/vfs_dentry.c126
-rw-r--r--fs/9p/vfs_dir.c226
-rw-r--r--fs/9p/vfs_file.c401
-rw-r--r--fs/9p/vfs_inode.c1338
-rw-r--r--fs/9p/vfs_super.c280
-rw-r--r--fs/Kconfig24
-rw-r--r--fs/Makefile2
-rw-r--r--fs/affs/inode.c1
-rw-r--r--fs/aio.c34
-rw-r--r--fs/autofs/autofs_i.h3
-rw-r--r--fs/autofs/dirhash.c5
-rw-r--r--fs/autofs/inode.c3
-rw-r--r--fs/bfs/bfs.h1
-rw-r--r--fs/bfs/dir.c25
-rw-r--r--fs/bfs/file.c23
-rw-r--r--fs/bfs/inode.c104
-rw-r--r--fs/bio.c2
-rw-r--r--fs/compat.c6
-rw-r--r--fs/compat_ioctl.c7
-rw-r--r--fs/exec.c8
-rw-r--r--fs/ext2/ialloc.c5
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext2/xattr.h8
-rw-r--r--fs/ext2/xattr_security.c22
-rw-r--r--fs/ext3/ialloc.c5
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/ext3/xattr.h11
-rw-r--r--fs/ext3/xattr_security.c22
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/fcntl.c60
-rw-r--r--fs/file.c387
-rw-r--r--fs/file_table.c40
-rw-r--r--fs/fuse/Makefile7
-rw-r--r--fs/fuse/dev.c877
-rw-r--r--fs/fuse/dir.c982
-rw-r--r--fs/fuse/file.c555
-rw-r--r--fs/fuse/fuse_i.h451
-rw-r--r--fs/fuse/inode.c591
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hpfs/inode.c1
-rw-r--r--fs/inode.c12
-rw-r--r--fs/jffs/inode-v23.c1
-rw-r--r--fs/jfs/inode.c2
-rw-r--r--fs/locks.c8
-rw-r--r--fs/minix/inode.c1
-rw-r--r--fs/namei.c26
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/ntfs/ChangeLog70
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c293
-rw-r--r--fs/ntfs/attrib.c125
-rw-r--r--fs/ntfs/attrib.h2
-rw-r--r--fs/ntfs/compress.c8
-rw-r--r--fs/ntfs/dir.c3
-rw-r--r--fs/ntfs/file.c9
-rw-r--r--fs/ntfs/index.c1
-rw-r--r--fs/ntfs/inode.c227
-rw-r--r--fs/ntfs/lcnalloc.c39
-rw-r--r--fs/ntfs/lcnalloc.h21
-rw-r--r--fs/ntfs/logfile.c251
-rw-r--r--fs/ntfs/logfile.h8
-rw-r--r--fs/ntfs/malloc.h48
-rw-r--r--fs/ntfs/mft.c4
-rw-r--r--fs/ntfs/runlist.c374
-rw-r--r--fs/ntfs/runlist.h3
-rw-r--r--fs/ntfs/super.c16
-rw-r--r--fs/ntfs/unistr.c3
-rw-r--r--fs/open.c43
-rw-r--r--fs/proc/array.c5
-rw-r--r--fs/proc/base.c33
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/qnx4/inode.c1
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/select.c23
-rw-r--r--fs/smbfs/inode.c1
-rw-r--r--fs/sysv/inode.c1
-rw-r--r--fs/udf/inode.c2
-rw-r--r--fs/ufs/inode.c1
-rw-r--r--fs/xfs/Makefile-linux-2.615
-rw-r--r--fs/xfs/support/ktrace.c2
-rw-r--r--include/asm-alpha/pci.h13
-rw-r--r--include/asm-arm/arch-pxa/hardware.h18
-rw-r--r--include/asm-arm/arch-pxa/i2c.h70
-rw-r--r--include/asm-arm/arch-pxa/mmc.h1
-rw-r--r--include/asm-arm/arch-pxa/pxafb.h1
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h69
-rw-r--r--include/asm-arm/arch-s3c2410/regs-lcd.h17
-rw-r--r--include/asm-arm/arch-sa1100/hardware.h18
-rw-r--r--include/asm-arm/cacheflush.h7
-rw-r--r--include/asm-arm/pci.h13
-rw-r--r--include/asm-generic/pci.h13
-rw-r--r--include/asm-i386/mach-default/mach_reboot.h10
-rw-r--r--include/asm-i386/mmzone.h2
-rw-r--r--include/asm-ia64/iosapic.h4
-rw-r--r--include/asm-ia64/irq.h4
-rw-r--r--include/asm-ia64/pci.h13
-rw-r--r--include/asm-ia64/system.h1
-rw-r--r--include/asm-m68knommu/coldfire.h6
-rw-r--r--include/asm-m68knommu/m523xsim.h46
-rw-r--r--include/asm-m68knommu/mcfsim.h6
-rw-r--r--include/asm-m68knommu/mcfuart.h2
-rw-r--r--include/asm-mips/irq.h3
-rw-r--r--include/asm-mips/vr41xx/tb0287.h43
-rw-r--r--include/asm-parisc/pci.h13
-rw-r--r--include/asm-powerpc/8253pit.h8
-rw-r--r--include/asm-powerpc/agp.h8
-rw-r--r--include/asm-powerpc/bugs.h8
-rw-r--r--include/asm-powerpc/errno.h6
-rw-r--r--include/asm-powerpc/ioctl.h6
-rw-r--r--include/asm-powerpc/ioctls.h6
-rw-r--r--include/asm-powerpc/linkage.h6
-rw-r--r--include/asm-powerpc/mc146818rtc.h6
-rw-r--r--include/asm-powerpc/mman.h6
-rw-r--r--include/asm-powerpc/module.h6
-rw-r--r--include/asm-powerpc/msgbuf.h (renamed from include/asm-ppc/msgbuf.h)16
-rw-r--r--include/asm-powerpc/namei.h14
-rw-r--r--include/asm-powerpc/param.h (renamed from include/asm-ppc/param.h)8
-rw-r--r--include/asm-powerpc/poll.h6
-rw-r--r--include/asm-powerpc/sembuf.h6
-rw-r--r--include/asm-powerpc/setup.h9
-rw-r--r--include/asm-powerpc/shmbuf.h14
-rw-r--r--include/asm-powerpc/shmparam.h6
-rw-r--r--include/asm-powerpc/siginfo.h6
-rw-r--r--include/asm-powerpc/socket.h6
-rw-r--r--include/asm-powerpc/sockios.h6
-rw-r--r--include/asm-powerpc/string.h6
-rw-r--r--include/asm-powerpc/termbits.h6
-rw-r--r--include/asm-powerpc/termios.h6
-rw-r--r--include/asm-powerpc/timex.h (renamed from include/asm-ppc/timex.h)37
-rw-r--r--include/asm-powerpc/topology.h (renamed from include/asm-ppc64/topology.h)9
-rw-r--r--include/asm-powerpc/unaligned.h9
-rw-r--r--include/asm-powerpc/user.h (renamed from include/asm-ppc/user.h)15
-rw-r--r--include/asm-ppc/irq.h4
-rw-r--r--include/asm-ppc/pci.h13
-rw-r--r--include/asm-ppc/reg.h6
-rw-r--r--include/asm-ppc/setup.h14
-rw-r--r--include/asm-ppc/topology.h6
-rw-r--r--include/asm-ppc64/eeh.h39
-rw-r--r--include/asm-ppc64/io.h42
-rw-r--r--include/asm-ppc64/msgbuf.h27
-rw-r--r--include/asm-ppc64/param.h31
-rw-r--r--include/asm-ppc64/pci-bridge.h45
-rw-r--r--include/asm-ppc64/pci.h13
-rw-r--r--include/asm-ppc64/prom.h19
-rw-r--r--include/asm-ppc64/segment.h6
-rw-r--r--include/asm-ppc64/setup.h6
-rw-r--r--include/asm-ppc64/timex.h26
-rw-r--r--include/asm-ppc64/user.h58
-rw-r--r--include/asm-sh/irq.h4
-rw-r--r--include/asm-sparc64/pci.h2
-rw-r--r--include/asm-sparc64/system.h49
-rw-r--r--include/asm-x86_64/irq.h4
-rw-r--r--include/linux/bfs_fs.h23
-rw-r--r--include/linux/crc16.h44
-rw-r--r--include/linux/dccp.h3
-rw-r--r--include/linux/fb.h28
-rw-r--r--include/linux/file.h30
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/fuse.h259
-rw-r--r--include/linux/i2c-pxa.h48
-rw-r--r--include/linux/in6.h36
-rw-r--r--include/linux/init_task.h18
-rw-r--r--include/linux/ipv6.h15
-rw-r--r--include/linux/mempolicy.h1
-rw-r--r--include/linux/mmc/host.h10
-rw-r--r--include/linux/pci.h519
-rw-r--r--include/linux/pci_regs.h448
-rw-r--r--include/linux/rcupdate.h4
-rw-r--r--include/linux/rcuref.h220
-rw-r--r--include/linux/sched.h5
-rw-r--r--include/linux/security.h180
-rw-r--r--include/linux/serial_8250.h15
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/skbuff.h2
-rw-r--r--include/linux/timer.h4
-rw-r--r--include/linux/tty.h3
-rw-r--r--include/linux/usb.h11
-rw-r--r--include/linux/usb_isp116x.h30
-rw-r--r--include/linux/videodev.h3
-rw-r--r--include/linux/videodev2.h4
-rw-r--r--include/media/audiochip.h1
-rw-r--r--include/media/id.h1
-rw-r--r--include/media/ir-common.h4
-rw-r--r--include/media/saa7146.h13
-rw-r--r--include/media/tuner.h193
-rw-r--r--include/media/tveeprom.h9
-rw-r--r--include/media/video-buf.h1
-rw-r--r--include/net/ax25.h2
-rw-r--r--include/net/compat.h5
-rw-r--r--include/net/ipv6.h5
-rw-r--r--include/net/transp_v6.h2
-rw-r--r--include/pcmcia/ds.h2
-rw-r--r--include/sound/pcm.h5
-rw-r--r--include/sound/tea575x-tuner.h2
-rw-r--r--include/video/cyblafb.h171
-rw-r--r--include/video/sisfb.h188
-rw-r--r--kernel/cpuset.c4
-rw-r--r--kernel/exit.c26
-rw-r--r--kernel/fork.c101
-rw-r--r--kernel/rcupdate.c14
-rw-r--r--kernel/sched.c1
-rw-r--r--lib/Kconfig8
-rw-r--r--lib/Makefile3
-rw-r--r--lib/crc16.c67
-rw-r--r--mm/mempolicy.c2
-rw-r--r--mm/page-writeback.c6
-rw-r--r--mm/shmem.c21
-rw-r--r--mm/slab.c1134
-rw-r--r--mm/vmalloc.c7
-rw-r--r--net/atm/mpc.c2
-rw-r--r--net/ax25/ax25_addr.c27
-rw-r--r--net/core/dst.c3
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/core/pktgen.c2
-rw-r--r--net/dccp/ccids/ccid3.c163
-rw-r--r--net/dccp/ccids/ccid3.h14
-rw-r--r--net/dccp/ccids/lib/packet_history.h3
-rw-r--r--net/dccp/dccp.h16
-rw-r--r--net/dccp/input.c4
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/minisocks.c1
-rw-r--r--net/dccp/options.c90
-rw-r--r--net/decnet/dn_route.c3
-rw-r--r--net/ieee80211/Kconfig1
-rw-r--r--net/ipv4/af_inet.c13
-rw-r--r--net/ipv4/fib_trie.c804
-rw-r--r--net/ipv4/inetpeer.c3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c24
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c5
-rw-r--r--net/ipv4/netfilter/ipt_owner.c1
-rw-r--r--net/ipv4/route.c29
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/datagram.c139
-rw-r--r--net/ipv6/exthdrs.c116
-rw-r--r--net/ipv6/icmp.c20
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_flowlabel.c16
-rw-r--r--net/ipv6/ip6_output.c24
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipv6_sockglue.c186
-rw-r--r--net/ipv6/ndisc.c16
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c5
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c1
-rw-r--r--net/ipv6/raw.c21
-rw-r--r--net/ipv6/reassembly.c9
-rw-r--r--net/ipv6/tcp_ipv6.c36
-rw-r--r--net/ipv6/udp.c25
-rw-r--r--net/netrom/nr_loopback.c2
-rw-r--r--net/rose/rose_subr.c4
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/xfrm/xfrm_policy.c8
-rw-r--r--security/dummy.c52
-rw-r--r--security/selinux/hooks.c178
-rw-r--r--sound/oss/midibuf.c2
-rw-r--r--sound/oss/soundcard.c3
-rw-r--r--sound/oss/sys_timer.c3
-rw-r--r--sound/oss/uart6850.c3
-rw-r--r--sound/usb/usbaudio.c10
844 files changed, 56353 insertions, 43097 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index f28a24e0279b..f6de52b01059 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -46,6 +46,8 @@ SubmittingPatches
46 - procedure to get a source patch included into the kernel tree. 46 - procedure to get a source patch included into the kernel tree.
47VGA-softcursor.txt 47VGA-softcursor.txt
48 - how to change your VGA cursor from a blinking underscore. 48 - how to change your VGA cursor from a blinking underscore.
49applying-patches.txt
50 - description of various trees and how to apply their patches.
49arm/ 51arm/
50 - directory with info about Linux on the ARM architecture. 52 - directory with info about Linux on the ARM architecture.
51basic_profiling.txt 53basic_profiling.txt
diff --git a/Documentation/DMA-ISA-LPC.txt b/Documentation/DMA-ISA-LPC.txt
new file mode 100644
index 000000000000..705f6be92bdb
--- /dev/null
+++ b/Documentation/DMA-ISA-LPC.txt
@@ -0,0 +1,151 @@
1 DMA with ISA and LPC devices
2 ============================
3
4 Pierre Ossman <drzeus@drzeus.cx>
5
6This document describes how to do DMA transfers using the old ISA DMA
7controller. Even though ISA is more or less dead today the LPC bus
8uses the same DMA system so it will be around for quite some time.
9
10Part I - Headers and dependencies
11---------------------------------
12
13To do ISA style DMA you need to include two headers:
14
15#include <linux/dma-mapping.h>
16#include <asm/dma.h>
17
18The first is the generic DMA API used to convert virtual addresses to
19physical addresses (see Documentation/DMA-API.txt for details).
20
21The second contains the routines specific to ISA DMA transfers. Since
22this is not present on all platforms make sure you construct your
23Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
24to build your driver on unsupported platforms.
25
26Part II - Buffer allocation
27---------------------------
28
29The ISA DMA controller has some very strict requirements on which
30memory it can access so extra care must be taken when allocating
31buffers.
32
33(You usually need a special buffer for DMA transfers instead of
34transferring directly to and from your normal data structures.)
35
36The DMA-able address space is the lowest 16 MB of _physical_ memory.
37Also the transfer block may not cross page boundaries (which are 64
38or 128 KiB depending on which channel you use).
39
40In order to allocate a piece of memory that satisfies all these
41requirements you pass the flag GFP_DMA to kmalloc.
42
43Unfortunately the memory available for ISA DMA is scarce so unless you
44allocate the memory during boot-up it's a good idea to also pass
45__GFP_REPEAT and __GFP_NOWARN to make the allocater try a bit harder.
46
47(This scarcity also means that you should allocate the buffer as
48early as possible and not release it until the driver is unloaded.)
49
50Part III - Address translation
51------------------------------
52
53To translate the virtual address to a physical use the normal DMA
54API. Do _not_ use isa_virt_to_phys() even though it does the same
55thing. The reason for this is that the function isa_virt_to_phys()
56will require a Kconfig dependency to ISA, not just ISA_DMA_API which
57is really all you need. Remember that even though the DMA controller
58has its origins in ISA it is used elsewhere.
59
60Note: x86_64 had a broken DMA API when it came to ISA but has since
61been fixed. If your arch has problems then fix the DMA API instead of
62reverting to the ISA functions.
63
64Part IV - Channels
65------------------
66
67A normal ISA DMA controller has 8 channels. The lower four are for
688-bit transfers and the upper four are for 16-bit transfers.
69
70(Actually the DMA controller is really two separate controllers where
71channel 4 is used to give DMA access for the second controller (0-3).
72This means that of the four 16-bits channels only three are usable.)
73
74You allocate these in a similar fashion as all basic resources:
75
76extern int request_dma(unsigned int dmanr, const char * device_id);
77extern void free_dma(unsigned int dmanr);
78
79The ability to use 16-bit or 8-bit transfers is _not_ up to you as a
80driver author but depends on what the hardware supports. Check your
81specs or test different channels.
82
83Part V - Transfer data
84----------------------
85
86Now for the good stuff, the actual DMA transfer. :)
87
88Before you use any ISA DMA routines you need to claim the DMA lock
89using claim_dma_lock(). The reason is that some DMA operations are
90not atomic so only one driver may fiddle with the registers at a
91time.
92
93The first time you use the DMA controller you should call
94clear_dma_ff(). This clears an internal register in the DMA
95controller that is used for the non-atomic operations. As long as you
96(and everyone else) uses the locking functions then you only need to
97reset this once.
98
99Next, you tell the controller in which direction you intend to do the
100transfer using set_dma_mode(). Currently you have the options
101DMA_MODE_READ and DMA_MODE_WRITE.
102
103Set the address from where the transfer should start (this needs to
104be 16-bit aligned for 16-bit transfers) and how many bytes to
105transfer. Note that it's _bytes_. The DMA routines will do all the
106required translation to values that the DMA controller understands.
107
108The final step is enabling the DMA channel and releasing the DMA
109lock.
110
111Once the DMA transfer is finished (or timed out) you should disable
112the channel again. You should also check get_dma_residue() to make
113sure that all data has been transfered.
114
115Example:
116
117int flags, residue;
118
119flags = claim_dma_lock();
120
121clear_dma_ff();
122
123set_dma_mode(channel, DMA_MODE_WRITE);
124set_dma_addr(channel, phys_addr);
125set_dma_count(channel, num_bytes);
126
127dma_enable(channel);
128
129release_dma_lock(flags);
130
131while (!device_done());
132
133flags = claim_dma_lock();
134
135dma_disable(channel);
136
137residue = dma_get_residue(channel);
138if (residue != 0)
139 printk(KERN_ERR "driver: Incomplete DMA transfer!"
140 " %d bytes left!\n", residue);
141
142release_dma_lock(flags);
143
144Part VI - Suspend/resume
145------------------------
146
147It is the driver's responsibility to make sure that the machine isn't
148suspended while a DMA transfer is in progress. Also, all DMA settings
149are lost when the system suspends so if your driver relies on the DMA
150controller being in a certain state then you have to restore these
151registers upon resume.
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 49a9ef82d575..6367bba32d22 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -8,8 +8,7 @@
8 8
9 <authorgroup> 9 <authorgroup>
10 <author> 10 <author>
11 <firstname>Paul</firstname> 11 <firstname>Rusty</firstname>
12 <othername>Rusty</othername>
13 <surname>Russell</surname> 12 <surname>Russell</surname>
14 <affiliation> 13 <affiliation>
15 <address> 14 <address>
@@ -20,7 +19,7 @@
20 </authorgroup> 19 </authorgroup>
21 20
22 <copyright> 21 <copyright>
23 <year>2001</year> 22 <year>2005</year>
24 <holder>Rusty Russell</holder> 23 <holder>Rusty Russell</holder>
25 </copyright> 24 </copyright>
26 25
@@ -64,7 +63,7 @@
64 <chapter id="introduction"> 63 <chapter id="introduction">
65 <title>Introduction</title> 64 <title>Introduction</title>
66 <para> 65 <para>
67 Welcome, gentle reader, to Rusty's Unreliable Guide to Linux 66 Welcome, gentle reader, to Rusty's Remarkably Unreliable Guide to Linux
68 Kernel Hacking. This document describes the common routines and 67 Kernel Hacking. This document describes the common routines and
69 general requirements for kernel code: its goal is to serve as a 68 general requirements for kernel code: its goal is to serve as a
70 primer for Linux kernel development for experienced C 69 primer for Linux kernel development for experienced C
@@ -96,13 +95,13 @@
96 95
97 <listitem> 96 <listitem>
98 <para> 97 <para>
99 not associated with any process, serving a softirq, tasklet or bh; 98 not associated with any process, serving a softirq or tasklet;
100 </para> 99 </para>
101 </listitem> 100 </listitem>
102 101
103 <listitem> 102 <listitem>
104 <para> 103 <para>
105 running in kernel space, associated with a process; 104 running in kernel space, associated with a process (user context);
106 </para> 105 </para>
107 </listitem> 106 </listitem>
108 107
@@ -114,11 +113,12 @@
114 </itemizedlist> 113 </itemizedlist>
115 114
116 <para> 115 <para>
117 There is a strict ordering between these: other than the last 116 There is an ordering between these. The bottom two can preempt
118 category (userspace) each can only be pre-empted by those above. 117 each other, but above that is a strict hierarchy: each can only be
119 For example, while a softirq is running on a CPU, no other 118 preempted by the ones above it. For example, while a softirq is
120 softirq will pre-empt it, but a hardware interrupt can. However, 119 running on a CPU, no other softirq will preempt it, but a hardware
121 any other CPUs in the system execute independently. 120 interrupt can. However, any other CPUs in the system execute
121 independently.
122 </para> 122 </para>
123 123
124 <para> 124 <para>
@@ -130,10 +130,10 @@
130 <title>User Context</title> 130 <title>User Context</title>
131 131
132 <para> 132 <para>
133 User context is when you are coming in from a system call or 133 User context is when you are coming in from a system call or other
134 other trap: you can sleep, and you own the CPU (except for 134 trap: like userspace, you can be preempted by more important tasks
135 interrupts) until you call <function>schedule()</function>. 135 and by interrupts. You can sleep, by calling
136 In other words, user context (unlike userspace) is not pre-emptable. 136 <function>schedule()</function>.
137 </para> 137 </para>
138 138
139 <note> 139 <note>
@@ -153,7 +153,7 @@
153 153
154 <caution> 154 <caution>
155 <para> 155 <para>
156 Beware that if you have interrupts or bottom halves disabled 156 Beware that if you have preemption or softirqs disabled
157 (see below), <function>in_interrupt()</function> will return a 157 (see below), <function>in_interrupt()</function> will return a
158 false positive. 158 false positive.
159 </para> 159 </para>
@@ -168,10 +168,10 @@
168 <hardware>keyboard</hardware> are examples of real 168 <hardware>keyboard</hardware> are examples of real
169 hardware which produce interrupts at any time. The kernel runs 169 hardware which produce interrupts at any time. The kernel runs
170 interrupt handlers, which services the hardware. The kernel 170 interrupt handlers, which services the hardware. The kernel
171 guarantees that this handler is never re-entered: if another 171 guarantees that this handler is never re-entered: if the same
172 interrupt arrives, it is queued (or dropped). Because it 172 interrupt arrives, it is queued (or dropped). Because it
173 disables interrupts, this handler has to be fast: frequently it 173 disables interrupts, this handler has to be fast: frequently it
174 simply acknowledges the interrupt, marks a `software interrupt' 174 simply acknowledges the interrupt, marks a 'software interrupt'
175 for execution and exits. 175 for execution and exits.
176 </para> 176 </para>
177 177
@@ -188,60 +188,52 @@
188 </sect1> 188 </sect1>
189 189
190 <sect1 id="basics-softirqs"> 190 <sect1 id="basics-softirqs">
191 <title>Software Interrupt Context: Bottom Halves, Tasklets, softirqs</title> 191 <title>Software Interrupt Context: Softirqs and Tasklets</title>
192 192
193 <para> 193 <para>
194 Whenever a system call is about to return to userspace, or a 194 Whenever a system call is about to return to userspace, or a
195 hardware interrupt handler exits, any `software interrupts' 195 hardware interrupt handler exits, any 'software interrupts'
196 which are marked pending (usually by hardware interrupts) are 196 which are marked pending (usually by hardware interrupts) are
197 run (<filename>kernel/softirq.c</filename>). 197 run (<filename>kernel/softirq.c</filename>).
198 </para> 198 </para>
199 199
200 <para> 200 <para>
201 Much of the real interrupt handling work is done here. Early in 201 Much of the real interrupt handling work is done here. Early in
202 the transition to <acronym>SMP</acronym>, there were only `bottom 202 the transition to <acronym>SMP</acronym>, there were only 'bottom
203 halves' (BHs), which didn't take advantage of multiple CPUs. Shortly 203 halves' (BHs), which didn't take advantage of multiple CPUs. Shortly
204 after we switched from wind-up computers made of match-sticks and snot, 204 after we switched from wind-up computers made of match-sticks and snot,
205 we abandoned this limitation. 205 we abandoned this limitation and switched to 'softirqs'.
206 </para> 206 </para>
207 207
208 <para> 208 <para>
209 <filename class="headerfile">include/linux/interrupt.h</filename> lists the 209 <filename class="headerfile">include/linux/interrupt.h</filename> lists the
210 different BH's. No matter how many CPUs you have, no two BHs will run at 210 different softirqs. A very important softirq is the
211 the same time. This made the transition to SMP simpler, but sucks hard for 211 timer softirq (<filename
212 scalable performance. A very important bottom half is the timer 212 class="headerfile">include/linux/timer.h</filename>): you can
213 BH (<filename class="headerfile">include/linux/timer.h</filename>): you 213 register to have it call functions for you in a given length of
214 can register to have it call functions for you in a given length of time. 214 time.
215 </para> 215 </para>
216 216
217 <para> 217 <para>
218 2.3.43 introduced softirqs, and re-implemented the (now 218 Softirqs are often a pain to deal with, since the same softirq
219 deprecated) BHs underneath them. Softirqs are fully-SMP 219 will run simultaneously on more than one CPU. For this reason,
220 versions of BHs: they can run on as many CPUs at once as 220 tasklets (<filename
221 required. This means they need to deal with any races in shared 221 class="headerfile">include/linux/interrupt.h</filename>) are more
222 data using their own locks. A bitmask is used to keep track of 222 often used: they are dynamically-registrable (meaning you can have
223 which are enabled, so the 32 available softirqs should not be 223 as many as you want), and they also guarantee that any tasklet
224 used up lightly. (<emphasis>Yes</emphasis>, people will 224 will only run on one CPU at any time, although different tasklets
225 notice). 225 can run simultaneously.
226 </para>
227
228 <para>
229 tasklets (<filename class="headerfile">include/linux/interrupt.h</filename>)
230 are like softirqs, except they are dynamically-registrable (meaning you
231 can have as many as you want), and they also guarantee that any tasklet
232 will only run on one CPU at any time, although different tasklets can
233 run simultaneously (unlike different BHs).
234 </para> 226 </para>
235 <caution> 227 <caution>
236 <para> 228 <para>
237 The name `tasklet' is misleading: they have nothing to do with `tasks', 229 The name 'tasklet' is misleading: they have nothing to do with 'tasks',
238 and probably more to do with some bad vodka Alexey Kuznetsov had at the 230 and probably more to do with some bad vodka Alexey Kuznetsov had at the
239 time. 231 time.
240 </para> 232 </para>
241 </caution> 233 </caution>
242 234
243 <para> 235 <para>
244 You can tell you are in a softirq (or bottom half, or tasklet) 236 You can tell you are in a softirq (or tasklet)
245 using the <function>in_softirq()</function> macro 237 using the <function>in_softirq()</function> macro
246 (<filename class="headerfile">include/linux/interrupt.h</filename>). 238 (<filename class="headerfile">include/linux/interrupt.h</filename>).
247 </para> 239 </para>
@@ -288,11 +280,10 @@
288 <term>A rigid stack limit</term> 280 <term>A rigid stack limit</term>
289 <listitem> 281 <listitem>
290 <para> 282 <para>
291 The kernel stack is about 6K in 2.2 (for most 283 Depending on configuration options the kernel stack is about 3K to 6K for most 32-bit architectures: it's
292 architectures: it's about 14K on the Alpha), and shared 284 about 14K on most 64-bit archs, and often shared with interrupts
293 with interrupts so you can't use it all. Avoid deep 285 so you can't use it all. Avoid deep recursion and huge local
294 recursion and huge local arrays on the stack (allocate 286 arrays on the stack (allocate them dynamically instead).
295 them dynamically instead).
296 </para> 287 </para>
297 </listitem> 288 </listitem>
298 </varlistentry> 289 </varlistentry>
@@ -339,7 +330,7 @@ asmlinkage long sys_mycall(int arg)
339 330
340 <para> 331 <para>
341 If all your routine does is read or write some parameter, consider 332 If all your routine does is read or write some parameter, consider
342 implementing a <function>sysctl</function> interface instead. 333 implementing a <function>sysfs</function> interface instead.
343 </para> 334 </para>
344 335
345 <para> 336 <para>
@@ -417,7 +408,10 @@ cond_resched(); /* Will sleep */
417 </para> 408 </para>
418 409
419 <para> 410 <para>
420 You will eventually lock up your box if you break these rules. 411 You should always compile your kernel
412 <symbol>CONFIG_DEBUG_SPINLOCK_SLEEP</symbol> on, and it will warn
413 you if you break these rules. If you <emphasis>do</emphasis> break
414 the rules, you will eventually lock up your box.
421 </para> 415 </para>
422 416
423 <para> 417 <para>
@@ -515,8 +509,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
515 success). 509 success).
516 </para> 510 </para>
517 </caution> 511 </caution>
518 [Yes, this moronic interface makes me cringe. Please submit a 512 [Yes, this moronic interface makes me cringe. The flamewar comes up every year or so. --RR.]
519 patch and become my hero --RR.]
520 </para> 513 </para>
521 <para> 514 <para>
522 The functions may sleep implicitly. This should never be called 515 The functions may sleep implicitly. This should never be called
@@ -587,10 +580,11 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
587 </variablelist> 580 </variablelist>
588 581
589 <para> 582 <para>
590 If you see a <errorname>kmem_grow: Called nonatomically from int 583 If you see a <errorname>sleeping function called from invalid
591 </errorname> warning message you called a memory allocation function 584 context</errorname> warning message, then maybe you called a
592 from interrupt context without <constant>GFP_ATOMIC</constant>. 585 sleeping allocation function from interrupt context without
593 You should really fix that. Run, don't walk. 586 <constant>GFP_ATOMIC</constant>. You should really fix that.
587 Run, don't walk.
594 </para> 588 </para>
595 589
596 <para> 590 <para>
@@ -639,16 +633,16 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
639 </sect1> 633 </sect1>
640 634
641 <sect1 id="routines-udelay"> 635 <sect1 id="routines-udelay">
642 <title><function>udelay()</function>/<function>mdelay()</function> 636 <title><function>mdelay()</function>/<function>udelay()</function>
643 <filename class="headerfile">include/asm/delay.h</filename> 637 <filename class="headerfile">include/asm/delay.h</filename>
644 <filename class="headerfile">include/linux/delay.h</filename> 638 <filename class="headerfile">include/linux/delay.h</filename>
645 </title> 639 </title>
646 640
647 <para> 641 <para>
648 The <function>udelay()</function> function can be used for small pauses. 642 The <function>udelay()</function> and <function>ndelay()</function> functions can be used for small pauses.
649 Do not use large values with <function>udelay()</function> as you risk 643 Do not use large values with them as you risk
650 overflow - the helper function <function>mdelay()</function> is useful 644 overflow - the helper function <function>mdelay()</function> is useful
651 here, or even consider <function>schedule_timeout()</function>. 645 here, or consider <function>msleep()</function>.
652 </para> 646 </para>
653 </sect1> 647 </sect1>
654 648
@@ -698,8 +692,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
698 These routines disable soft interrupts on the local CPU, and 692 These routines disable soft interrupts on the local CPU, and
699 restore them. They are reentrant; if soft interrupts were 693 restore them. They are reentrant; if soft interrupts were
700 disabled before, they will still be disabled after this pair 694 disabled before, they will still be disabled after this pair
701 of functions has been called. They prevent softirqs, tasklets 695 of functions has been called. They prevent softirqs and tasklets
702 and bottom halves from running on the current CPU. 696 from running on the current CPU.
703 </para> 697 </para>
704 </sect1> 698 </sect1>
705 699
@@ -708,10 +702,16 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
708 <filename class="headerfile">include/asm/smp.h</filename></title> 702 <filename class="headerfile">include/asm/smp.h</filename></title>
709 703
710 <para> 704 <para>
711 <function>smp_processor_id()</function> returns the current 705 <function>get_cpu()</function> disables preemption (so you won't
712 processor number, between 0 and <symbol>NR_CPUS</symbol> (the 706 suddenly get moved to another CPU) and returns the current
713 maximum number of CPUs supported by Linux, currently 32). These 707 processor number, between 0 and <symbol>NR_CPUS</symbol>. Note
714 values are not necessarily continuous. 708 that the CPU numbers are not necessarily continuous. You return
709 it again with <function>put_cpu()</function> when you are done.
710 </para>
711 <para>
712 If you know you cannot be preempted by another task (ie. you are
713 in interrupt context, or have preemption disabled) you can use
714 smp_processor_id().
715 </para> 715 </para>
716 </sect1> 716 </sect1>
717 717
@@ -722,19 +722,14 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
722 <para> 722 <para>
723 After boot, the kernel frees up a special section; functions 723 After boot, the kernel frees up a special section; functions
724 marked with <type>__init</type> and data structures marked with 724 marked with <type>__init</type> and data structures marked with
725 <type>__initdata</type> are dropped after boot is complete (within 725 <type>__initdata</type> are dropped after boot is complete: similarly
726 modules this directive is currently ignored). <type>__exit</type> 726 modules discard this memory after initialization. <type>__exit</type>
727 is used to declare a function which is only required on exit: the 727 is used to declare a function which is only required on exit: the
728 function will be dropped if this file is not compiled as a module. 728 function will be dropped if this file is not compiled as a module.
729 See the header file for use. Note that it makes no sense for a function 729 See the header file for use. Note that it makes no sense for a function
730 marked with <type>__init</type> to be exported to modules with 730 marked with <type>__init</type> to be exported to modules with
731 <function>EXPORT_SYMBOL()</function> - this will break. 731 <function>EXPORT_SYMBOL()</function> - this will break.
732 </para> 732 </para>
733 <para>
734 Static data structures marked as <type>__initdata</type> must be initialised
735 (as opposed to ordinary static data which is zeroed BSS) and cannot be
736 <type>const</type>.
737 </para>
738 733
739 </sect1> 734 </sect1>
740 735
@@ -762,9 +757,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
762 <para> 757 <para>
763 The function can return a negative error number to cause 758 The function can return a negative error number to cause
764 module loading to fail (unfortunately, this has no effect if 759 module loading to fail (unfortunately, this has no effect if
765 the module is compiled into the kernel). For modules, this is 760 the module is compiled into the kernel). This function is
766 called in user context, with interrupts enabled, and the 761 called in user context with interrupts enabled, so it can sleep.
767 kernel lock held, so it can sleep.
768 </para> 762 </para>
769 </sect1> 763 </sect1>
770 764
@@ -779,6 +773,34 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
779 reached zero. This function can also sleep, but cannot fail: 773 reached zero. This function can also sleep, but cannot fail:
780 everything must be cleaned up by the time it returns. 774 everything must be cleaned up by the time it returns.
781 </para> 775 </para>
776
777 <para>
778 Note that this macro is optional: if it is not present, your
779 module will not be removable (except for 'rmmod -f').
780 </para>
781 </sect1>
782
783 <sect1 id="routines-module-use-counters">
784 <title> <function>try_module_get()</function>/<function>module_put()</function>
785 <filename class="headerfile">include/linux/module.h</filename></title>
786
787 <para>
788 These manipulate the module usage count, to protect against
789 removal (a module also can't be removed if another module uses one
790 of its exported symbols: see below). Before calling into module
791 code, you should call <function>try_module_get()</function> on
792 that module: if it fails, then the module is being removed and you
793 should act as if it wasn't there. Otherwise, you can safely enter
794 the module, and call <function>module_put()</function> when you're
795 finished.
796 </para>
797
798 <para>
799 Most registerable structures have an
800 <structfield>owner</structfield> field, such as in the
801 <structname>file_operations</structname> structure. Set this field
802 to the macro <symbol>THIS_MODULE</symbol>.
803 </para>
782 </sect1> 804 </sect1>
783 805
784 <!-- add info on new-style module refcounting here --> 806 <!-- add info on new-style module refcounting here -->
@@ -821,7 +843,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
821 There is a macro to do this: 843 There is a macro to do this:
822 <function>wait_event_interruptible()</function> 844 <function>wait_event_interruptible()</function>
823 845
824 <filename class="headerfile">include/linux/sched.h</filename> The 846 <filename class="headerfile">include/linux/wait.h</filename> The
825 first argument is the wait queue head, and the second is an 847 first argument is the wait queue head, and the second is an
826 expression which is evaluated; the macro returns 848 expression which is evaluated; the macro returns
827 <returnvalue>0</returnvalue> when this expression is true, or 849 <returnvalue>0</returnvalue> when this expression is true, or
@@ -847,10 +869,11 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
847 <para> 869 <para>
848 Call <function>wake_up()</function> 870 Call <function>wake_up()</function>
849 871
850 <filename class="headerfile">include/linux/sched.h</filename>;, 872 <filename class="headerfile">include/linux/wait.h</filename>;,
851 which will wake up every process in the queue. The exception is 873 which will wake up every process in the queue. The exception is
852 if one has <constant>TASK_EXCLUSIVE</constant> set, in which case 874 if one has <constant>TASK_EXCLUSIVE</constant> set, in which case
853 the remainder of the queue will not be woken. 875 the remainder of the queue will not be woken. There are other variants
876 of this basic function available in the same header.
854 </para> 877 </para>
855 </sect1> 878 </sect1>
856 </chapter> 879 </chapter>
@@ -863,7 +886,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
863 first class of operations work on <type>atomic_t</type> 886 first class of operations work on <type>atomic_t</type>
864 887
865 <filename class="headerfile">include/asm/atomic.h</filename>; this 888 <filename class="headerfile">include/asm/atomic.h</filename>; this
866 contains a signed integer (at least 24 bits long), and you must use 889 contains a signed integer (at least 32 bits long), and you must use
867 these functions to manipulate or read atomic_t variables. 890 these functions to manipulate or read atomic_t variables.
868 <function>atomic_read()</function> and 891 <function>atomic_read()</function> and
869 <function>atomic_set()</function> get and set the counter, 892 <function>atomic_set()</function> get and set the counter,
@@ -882,13 +905,12 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
882 905
883 <para> 906 <para>
884 Note that these functions are slower than normal arithmetic, and 907 Note that these functions are slower than normal arithmetic, and
885 so should not be used unnecessarily. On some platforms they 908 so should not be used unnecessarily.
886 are much slower, like 32-bit Sparc where they use a spinlock.
887 </para> 909 </para>
888 910
889 <para> 911 <para>
890 The second class of atomic operations is atomic bit operations on a 912 The second class of atomic operations is atomic bit operations on an
891 <type>long</type>, defined in 913 <type>unsigned long</type>, defined in
892 914
893 <filename class="headerfile">include/linux/bitops.h</filename>. These 915 <filename class="headerfile">include/linux/bitops.h</filename>. These
894 operations generally take a pointer to the bit pattern, and a bit 916 operations generally take a pointer to the bit pattern, and a bit
@@ -899,7 +921,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
899 <function>test_and_clear_bit()</function> and 921 <function>test_and_clear_bit()</function> and
900 <function>test_and_change_bit()</function> do the same thing, 922 <function>test_and_change_bit()</function> do the same thing,
901 except return true if the bit was previously set; these are 923 except return true if the bit was previously set; these are
902 particularly useful for very simple locking. 924 particularly useful for atomically setting flags.
903 </para> 925 </para>
904 926
905 <para> 927 <para>
@@ -907,12 +929,6 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
907 than BITS_PER_LONG. The resulting behavior is strange on big-endian 929 than BITS_PER_LONG. The resulting behavior is strange on big-endian
908 platforms though so it is a good idea not to do this. 930 platforms though so it is a good idea not to do this.
909 </para> 931 </para>
910
911 <para>
912 Note that the order of bits depends on the architecture, and in
913 particular, the bitfield passed to these operations must be at
914 least as large as a <type>long</type>.
915 </para>
916 </chapter> 932 </chapter>
917 933
918 <chapter id="symbols"> 934 <chapter id="symbols">
@@ -932,11 +948,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
932 <filename class="headerfile">include/linux/module.h</filename></title> 948 <filename class="headerfile">include/linux/module.h</filename></title>
933 949
934 <para> 950 <para>
935 This is the classic method of exporting a symbol, and it works 951 This is the classic method of exporting a symbol: dynamically
936 for both modules and non-modules. In the kernel all these 952 loaded modules will be able to use the symbol as normal.
937 declarations are often bundled into a single file to help
938 genksyms (which searches source files for these declarations).
939 See the comment on genksyms and Makefiles below.
940 </para> 953 </para>
941 </sect1> 954 </sect1>
942 955
@@ -949,7 +962,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
949 symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can 962 symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can
950 only be seen by modules with a 963 only be seen by modules with a
951 <function>MODULE_LICENSE()</function> that specifies a GPL 964 <function>MODULE_LICENSE()</function> that specifies a GPL
952 compatible license. 965 compatible license. It implies that the function is considered
966 an internal implementation issue, and not really an interface.
953 </para> 967 </para>
954 </sect1> 968 </sect1>
955 </chapter> 969 </chapter>
@@ -962,12 +976,13 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
962 <filename class="headerfile">include/linux/list.h</filename></title> 976 <filename class="headerfile">include/linux/list.h</filename></title>
963 977
964 <para> 978 <para>
965 There are three sets of linked-list routines in the kernel 979 There used to be three sets of linked-list routines in the kernel
966 headers, but this one seems to be winning out (and Linus has 980 headers, but this one is the winner. If you don't have some
967 used it). If you don't have some particular pressing need for 981 particular pressing need for a single list, it's a good choice.
968 a single list, it's a good choice. In fact, I don't care 982 </para>
969 whether it's a good choice or not, just use it so we can get 983
970 rid of the others. 984 <para>
985 In particular, <function>list_for_each_entry</function> is useful.
971 </para> 986 </para>
972 </sect1> 987 </sect1>
973 988
@@ -979,14 +994,13 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
979 convention, and return <returnvalue>0</returnvalue> for success, 994 convention, and return <returnvalue>0</returnvalue> for success,
980 and a negative error number 995 and a negative error number
981 (eg. <returnvalue>-EFAULT</returnvalue>) for failure. This can be 996 (eg. <returnvalue>-EFAULT</returnvalue>) for failure. This can be
982 unintuitive at first, but it's fairly widespread in the networking 997 unintuitive at first, but it's fairly widespread in the kernel.
983 code, for example.
984 </para> 998 </para>
985 999
986 <para> 1000 <para>
987 The filesystem code uses <function>ERR_PTR()</function> 1001 Using <function>ERR_PTR()</function>
988 1002
989 <filename class="headerfile">include/linux/fs.h</filename>; to 1003 <filename class="headerfile">include/linux/err.h</filename>; to
990 encode a negative error number into a pointer, and 1004 encode a negative error number into a pointer, and
991 <function>IS_ERR()</function> and <function>PTR_ERR()</function> 1005 <function>IS_ERR()</function> and <function>PTR_ERR()</function>
992 to get it back out again: avoids a separate pointer parameter for 1006 to get it back out again: avoids a separate pointer parameter for
@@ -1040,7 +1054,7 @@ static struct block_device_operations opt_fops = {
1040 supported, due to lack of general use, but the following are 1054 supported, due to lack of general use, but the following are
1041 considered standard (see the GCC info page section "C 1055 considered standard (see the GCC info page section "C
1042 Extensions" for more details - Yes, really the info page, the 1056 Extensions" for more details - Yes, really the info page, the
1043 man page is only a short summary of the stuff in info): 1057 man page is only a short summary of the stuff in info).
1044 </para> 1058 </para>
1045 <itemizedlist> 1059 <itemizedlist>
1046 <listitem> 1060 <listitem>
@@ -1091,7 +1105,7 @@ static struct block_device_operations opt_fops = {
1091 </listitem> 1105 </listitem>
1092 <listitem> 1106 <listitem>
1093 <para> 1107 <para>
1094 Function names as strings (__FUNCTION__) 1108 Function names as strings (__func__).
1095 </para> 1109 </para>
1096 </listitem> 1110 </listitem>
1097 <listitem> 1111 <listitem>
@@ -1164,63 +1178,35 @@ static struct block_device_operations opt_fops = {
1164 <listitem> 1178 <listitem>
1165 <para> 1179 <para>
1166 Usually you want a configuration option for your kernel hack. 1180 Usually you want a configuration option for your kernel hack.
1167 Edit <filename>Config.in</filename> in the appropriate directory 1181 Edit <filename>Kconfig</filename> in the appropriate directory.
1168 (but under <filename>arch/</filename> it's called 1182 The Config language is simple to use by cut and paste, and there's
1169 <filename>config.in</filename>). The Config Language used is not 1183 complete documentation in
1170 bash, even though it looks like bash; the safe way is to use only 1184 <filename>Documentation/kbuild/kconfig-language.txt</filename>.
1171 the constructs that you already see in
1172 <filename>Config.in</filename> files (see
1173 <filename>Documentation/kbuild/kconfig-language.txt</filename>).
1174 It's good to run "make xconfig" at least once to test (because
1175 it's the only one with a static parser).
1176 </para>
1177
1178 <para>
1179 Variables which can be Y or N use <type>bool</type> followed by a
1180 tagline and the config define name (which must start with
1181 CONFIG_). The <type>tristate</type> function is the same, but
1182 allows the answer M (which defines
1183 <symbol>CONFIG_foo_MODULE</symbol> in your source, instead of
1184 <symbol>CONFIG_FOO</symbol>) if <symbol>CONFIG_MODULES</symbol>
1185 is enabled.
1186 </para> 1185 </para>
1187 1186
1188 <para> 1187 <para>
1189 You may well want to make your CONFIG option only visible if 1188 You may well want to make your CONFIG option only visible if
1190 <symbol>CONFIG_EXPERIMENTAL</symbol> is enabled: this serves as a 1189 <symbol>CONFIG_EXPERIMENTAL</symbol> is enabled: this serves as a
1191 warning to users. There many other fancy things you can do: see 1190 warning to users. There many other fancy things you can do: see
1192 the various <filename>Config.in</filename> files for ideas. 1191 the various <filename>Kconfig</filename> files for ideas.
1193 </para> 1192 </para>
1194 </listitem>
1195 1193
1196 <listitem>
1197 <para> 1194 <para>
1198 Edit the <filename>Makefile</filename>: the CONFIG variables are 1195 In your description of the option, make sure you address both the
1199 exported here so you can conditionalize compilation with `ifeq'. 1196 expert user and the user who knows nothing about your feature. Mention
1200 If your file exports symbols then add the names to 1197 incompatibilities and issues here. <emphasis> Definitely
1201 <varname>export-objs</varname> so that genksyms will find them. 1198 </emphasis> end your description with <quote> if in doubt, say N
1202 <caution> 1199 </quote> (or, occasionally, `Y'); this is for people who have no
1203 <para> 1200 idea what you are talking about.
1204 There is a restriction on the kernel build system that objects
1205 which export symbols must have globally unique names.
1206 If your object does not have a globally unique name then the
1207 standard fix is to move the
1208 <function>EXPORT_SYMBOL()</function> statements to their own
1209 object with a unique name.
1210 This is why several systems have separate exporting objects,
1211 usually suffixed with ksyms.
1212 </para>
1213 </caution>
1214 </para> 1201 </para>
1215 </listitem> 1202 </listitem>
1216 1203
1217 <listitem> 1204 <listitem>
1218 <para> 1205 <para>
1219 Document your option in Documentation/Configure.help. Mention 1206 Edit the <filename>Makefile</filename>: the CONFIG variables are
1220 incompatibilities and issues here. <emphasis> Definitely 1207 exported here so you can usually just add a "obj-$(CONFIG_xxx) +=
1221 </emphasis> end your description with <quote> if in doubt, say N 1208 xxx.o" line. The syntax is documented in
1222 </quote> (or, occasionally, `Y'); this is for people who have no 1209 <filename>Documentation/kbuild/makefiles.txt</filename>.
1223 idea what you are talking about.
1224 </para> 1210 </para>
1225 </listitem> 1211 </listitem>
1226 1212
@@ -1253,20 +1239,12 @@ static struct block_device_operations opt_fops = {
1253 </para> 1239 </para>
1254 1240
1255 <para> 1241 <para>
1256 <filename>include/linux/brlock.h:</filename> 1242 <filename>include/asm-i386/delay.h:</filename>
1257 </para> 1243 </para>
1258 <programlisting> 1244 <programlisting>
1259extern inline void br_read_lock (enum brlock_indices idx) 1245#define ndelay(n) (__builtin_constant_p(n) ? \
1260{ 1246 ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
1261 /* 1247 __ndelay(n))
1262 * This causes a link-time bug message if an
1263 * invalid index is used:
1264 */
1265 if (idx >= __BR_END)
1266 __br_lock_usage_bug();
1267
1268 read_lock(&amp;__brlock_array[smp_processor_id()][idx]);
1269}
1270 </programlisting> 1248 </programlisting>
1271 1249
1272 <para> 1250 <para>
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
new file mode 100644
index 000000000000..a23fee66064d
--- /dev/null
+++ b/Documentation/RCU/rcuref.txt
@@ -0,0 +1,74 @@
1Refcounter framework for elements of lists/arrays protected by
2RCU.
3
4Refcounting on elements of lists which are protected by traditional
5reader/writer spinlocks or semaphores are straight forward as in:
6
71. 2.
8add() search_and_reference()
9{ {
10 alloc_object read_lock(&list_lock);
11 ... search_for_element
12 atomic_set(&el->rc, 1); atomic_inc(&el->rc);
13 write_lock(&list_lock); ...
14 add_element read_unlock(&list_lock);
15 ... ...
16 write_unlock(&list_lock); }
17}
18
193. 4.
20release_referenced() delete()
21{ {
22 ... write_lock(&list_lock);
23 atomic_dec(&el->rc, relfunc) ...
24 ... delete_element
25} write_unlock(&list_lock);
26 ...
27 if (atomic_dec_and_test(&el->rc))
28 kfree(el);
29 ...
30 }
31
32If this list/array is made lock free using rcu as in changing the
33write_lock in add() and delete() to spin_lock and changing read_lock
34in search_and_reference to rcu_read_lock(), the rcuref_get in
35search_and_reference could potentially hold reference to an element which
36has already been deleted from the list/array. rcuref_lf_get_rcu takes
37care of this scenario. search_and_reference should look as;
38
391. 2.
40add() search_and_reference()
41{ {
42 alloc_object rcu_read_lock();
43 ... search_for_element
44 atomic_set(&el->rc, 1); if (rcuref_inc_lf(&el->rc)) {
45 write_lock(&list_lock); rcu_read_unlock();
46 return FAIL;
47 add_element }
48 ... ...
49 write_unlock(&list_lock); rcu_read_unlock();
50} }
513. 4.
52release_referenced() delete()
53{ {
54 ... write_lock(&list_lock);
55 rcuref_dec(&el->rc, relfunc) ...
56 ... delete_element
57} write_unlock(&list_lock);
58 ...
59 if (rcuref_dec_and_test(&el->rc))
60 call_rcu(&el->head, el_free);
61 ...
62 }
63
64Sometimes, reference to the element need to be obtained in the
65update (write) stream. In such cases, rcuref_inc_lf might be an overkill
66since the spinlock serialising list updates are held. rcuref_inc
67is to be used in such cases.
68For arches which do not have cmpxchg rcuref_inc_lf
69api uses a hashed spinlock implementation and the same hashed spinlock
70is acquired in all rcuref_xxx primitives to preserve atomicity.
71Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the
72refcounter atleast at one place. Mixing rcuref_inc and atomic_xxx api
73might lead to races. rcuref_inc_lf() must be used in lockfree
74RCU critical sections only.
diff --git a/Documentation/applying-patches.txt b/Documentation/applying-patches.txt
new file mode 100644
index 000000000000..681e426e2482
--- /dev/null
+++ b/Documentation/applying-patches.txt
@@ -0,0 +1,439 @@
1
2 Applying Patches To The Linux Kernel
3 ------------------------------------
4
5 (Written by Jesper Juhl, August 2005)
6
7
8
9A frequently asked question on the Linux Kernel Mailing List is how to apply
10a patch to the kernel or, more specifically, what base kernel a patch for
11one of the many trees/branches should be applied to. Hopefully this document
12will explain this to you.
13
14In addition to explaining how to apply and revert patches, a brief
15description of the different kernel trees (and examples of how to apply
16their specific patches) is also provided.
17
18
19What is a patch?
20---
21 A patch is a small text document containing a delta of changes between two
22different versions of a source tree. Patches are created with the `diff'
23program.
24To correctly apply a patch you need to know what base it was generated from
25and what new version the patch will change the source tree into. These
26should both be present in the patch file metadata or be possible to deduce
27from the filename.
28
29
30How do I apply or revert a patch?
31---
32 You apply a patch with the `patch' program. The patch program reads a diff
33(or patch) file and makes the changes to the source tree described in it.
34
35Patches for the Linux kernel are generated relative to the parent directory
36holding the kernel source dir.
37
38This means that paths to files inside the patch file contain the name of the
39kernel source directories it was generated against (or some other directory
40names like "a/" and "b/").
41Since this is unlikely to match the name of the kernel source dir on your
42local machine (but is often useful info to see what version an otherwise
43unlabeled patch was generated against) you should change into your kernel
44source directory and then strip the first element of the path from filenames
45in the patch file when applying it (the -p1 argument to `patch' does this).
46
47To revert a previously applied patch, use the -R argument to patch.
48So, if you applied a patch like this:
49 patch -p1 < ../patch-x.y.z
50
51You can revert (undo) it like this:
52 patch -R -p1 < ../patch-x.y.z
53
54
55How do I feed a patch/diff file to `patch'?
56---
57 This (as usual with Linux and other UNIX like operating systems) can be
58done in several different ways.
59In all the examples below I feed the file (in uncompressed form) to patch
60via stdin using the following syntax:
61 patch -p1 < path/to/patch-x.y.z
62
63If you just want to be able to follow the examples below and don't want to
64know of more than one way to use patch, then you can stop reading this
65section here.
66
67Patch can also get the name of the file to use via the -i argument, like
68this:
69 patch -p1 -i path/to/patch-x.y.z
70
71If your patch file is compressed with gzip or bzip2 and you don't want to
72uncompress it before applying it, then you can feed it to patch like this
73instead:
74 zcat path/to/patch-x.y.z.gz | patch -p1
75 bzcat path/to/patch-x.y.z.bz2 | patch -p1
76
77If you wish to uncompress the patch file by hand first before applying it
78(what I assume you've done in the examples below), then you simply run
79gunzip or bunzip2 on the file - like this:
80 gunzip patch-x.y.z.gz
81 bunzip2 patch-x.y.z.bz2
82
83Which will leave you with a plain text patch-x.y.z file that you can feed to
84patch via stdin or the -i argument, as you prefer.
85
86A few other nice arguments for patch are -s which causes patch to be silent
87except for errors which is nice to prevent errors from scrolling out of the
88screen too fast, and --dry-run which causes patch to just print a listing of
89what would happen, but doesn't actually make any changes. Finally --verbose
90tells patch to print more information about the work being done.
91
92
93Common errors when patching
94---
95 When patch applies a patch file it attempts to verify the sanity of the
96file in different ways.
97Checking that the file looks like a valid patch file, checking the code
98around the bits being modified matches the context provided in the patch are
99just two of the basic sanity checks patch does.
100
101If patch encounters something that doesn't look quite right it has two
102options. It can either refuse to apply the changes and abort or it can try
103to find a way to make the patch apply with a few minor changes.
104
105One example of something that's not 'quite right' that patch will attempt to
106fix up is if all the context matches, the lines being changed match, but the
107line numbers are different. This can happen, for example, if the patch makes
108a change in the middle of the file but for some reasons a few lines have
109been added or removed near the beginning of the file. In that case
110everything looks good it has just moved up or down a bit, and patch will
111usually adjust the line numbers and apply the patch.
112
113Whenever patch applies a patch that it had to modify a bit to make it fit
114it'll tell you about it by saying the patch applied with 'fuzz'.
115You should be wary of such changes since even though patch probably got it
116right it doesn't /always/ get it right, and the result will sometimes be
117wrong.
118
119When patch encounters a change that it can't fix up with fuzz it rejects it
120outright and leaves a file with a .rej extension (a reject file). You can
121read this file to see exactely what change couldn't be applied, so you can
122go fix it up by hand if you wish.
123
124If you don't have any third party patches applied to your kernel source, but
125only patches from kernel.org and you apply the patches in the correct order,
126and have made no modifications yourself to the source files, then you should
127never see a fuzz or reject message from patch. If you do see such messages
128anyway, then there's a high risk that either your local source tree or the
129patch file is corrupted in some way. In that case you should probably try
130redownloading the patch and if things are still not OK then you'd be advised
131to start with a fresh tree downloaded in full from kernel.org.
132
133Let's look a bit more at some of the messages patch can produce.
134
135If patch stops and presents a "File to patch:" prompt, then patch could not
136find a file to be patched. Most likely you forgot to specify -p1 or you are
137in the wrong directory. Less often, you'll find patches that need to be
138applied with -p0 instead of -p1 (reading the patch file should reveal if
139this is the case - if so, then this is an error by the person who created
140the patch but is not fatal).
141
142If you get "Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines)." or a
143message similar to that, then it means that patch had to adjust the location
144of the change (in this example it needed to move 7 lines from where it
145expected to make the change to make it fit).
146The resulting file may or may not be OK, depending on the reason the file
147was different than expected.
148This often happens if you try to apply a patch that was generated against a
149different kernel version than the one you are trying to patch.
150
151If you get a message like "Hunk #3 FAILED at 2387.", then it means that the
152patch could not be applied correctly and the patch program was unable to
153fuzz its way through. This will generate a .rej file with the change that
154caused the patch to fail and also a .orig file showing you the original
155content that couldn't be changed.
156
157If you get "Reversed (or previously applied) patch detected! Assume -R? [n]"
158then patch detected that the change contained in the patch seems to have
159already been made.
160If you actually did apply this patch previously and you just re-applied it
161in error, then just say [n]o and abort this patch. If you applied this patch
162previously and actually intended to revert it, but forgot to specify -R,
163then you can say [y]es here to make patch revert it for you.
164This can also happen if the creator of the patch reversed the source and
165destination directories when creating the patch, and in that case reverting
166the patch will in fact apply it.
167
168A message similar to "patch: **** unexpected end of file in patch" or "patch
169unexpectedly ends in middle of line" means that patch could make no sense of
170the file you fed to it. Either your download is broken or you tried to feed
171patch a compressed patch file without uncompressing it first.
172
173As I already mentioned above, these errors should never happen if you apply
174a patch from kernel.org to the correct version of an unmodified source tree.
175So if you get these errors with kernel.org patches then you should probably
176assume that either your patch file or your tree is broken and I'd advice you
177to start over with a fresh download of a full kernel tree and the patch you
178wish to apply.
179
180
181Are there any alternatives to `patch'?
182---
183 Yes there are alternatives. You can use the `interdiff' program
184(http://cyberelk.net/tim/patchutils/) to generate a patch representing the
185differences between two patches and then apply the result.
186This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single
187step. The -z flag to interdiff will even let you feed it patches in gzip or
188bzip2 compressed form directly without the use of zcat or bzcat or manual
189decompression.
190
191Here's how you'd go from 2.6.12.2 to 2.6.12.3 in a single step:
192 interdiff -z ../patch-2.6.12.2.bz2 ../patch-2.6.12.3.gz | patch -p1
193
194Although interdiff may save you a step or two you are generally advised to
195do the additional steps since interdiff can get things wrong in some cases.
196
197 Another alternative is `ketchup', which is a python script for automatic
198downloading and applying of patches (http://www.selenic.com/ketchup/).
199
200Other nice tools are diffstat which shows a summary of changes made by a
201patch, lsdiff which displays a short listing of affected files in a patch
202file, along with (optionally) the line numbers of the start of each patch
203and grepdiff which displays a list of the files modified by a patch where
204the patch contains a given regular expression.
205
206
207Where can I download the patches?
208---
209 The patches are available at http://kernel.org/
210Most recent patches are linked from the front page, but they also have
211specific homes.
212
213The 2.6.x.y (-stable) and 2.6.x patches live at
214 ftp://ftp.kernel.org/pub/linux/kernel/v2.6/
215
216The -rc patches live at
217 ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing/
218
219The -git patches live at
220 ftp://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/
221
222The -mm kernels live at
223 ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/
224
225In place of ftp.kernel.org you can use ftp.cc.kernel.org, where cc is a
226country code. This way you'll be downloading from a mirror site that's most
227likely geographically closer to you, resulting in faster downloads for you,
228less bandwidth used globally and less load on the main kernel.org servers -
229these are good things, do use mirrors when possible.
230
231
232The 2.6.x kernels
233---
234 These are the base stable releases released by Linus. The highest numbered
235release is the most recent.
236
237If regressions or other serious flaws are found then a -stable fix patch
238will be released (see below) on top of this base. Once a new 2.6.x base
239kernel is released, a patch is made available that is a delta between the
240previous 2.6.x kernel and the new one.
241
242To apply a patch moving from 2.6.11 to 2.6.12 you'd do the following (note
243that such patches do *NOT* apply on top of 2.6.x.y kernels but on top of the
244base 2.6.x kernel - if you need to move from 2.6.x.y to 2.6.x+1 you need to
245first revert the 2.6.x.y patch).
246
247Here are some examples:
248
249# moving from 2.6.11 to 2.6.12
250$ cd ~/linux-2.6.11 # change to kernel source dir
251$ patch -p1 < ../patch-2.6.12 # apply the 2.6.12 patch
252$ cd ..
253$ mv linux-2.6.11 linux-2.6.12 # rename source dir
254
255# moving from 2.6.11.1 to 2.6.12
256$ cd ~/linux-2.6.11.1 # change to kernel source dir
257$ patch -p1 -R < ../patch-2.6.11.1 # revert the 2.6.11.1 patch
258 # source dir is now 2.6.11
259$ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch
260$ cd ..
261$ mv linux-2.6.11.1 inux-2.6.12 # rename source dir
262
263
264The 2.6.x.y kernels
265---
266 Kernels with 4 digit versions are -stable kernels. They contain small(ish)
267critical fixes for security problems or significant regressions discovered
268in a given 2.6.x kernel.
269
270This is the recommended branch for users who want the most recent stable
271kernel and are not interested in helping test development/experimental
272versions.
273
274If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is
275the current stable kernel.
276
277These patches are not incremental, meaning that for example the 2.6.12.3
278patch does not apply on top of the 2.6.12.2 kernel source, but rather on top
279of the base 2.6.12 kernel source.
280So, in order to apply the 2.6.12.3 patch to your existing 2.6.12.2 kernel
281source you have to first back out the 2.6.12.2 patch (so you are left with a
282base 2.6.12 kernel source) and then apply the new 2.6.12.3 patch.
283
284Here's a small example:
285
286$ cd ~/linux-2.6.12.2 # change into the kernel source dir
287$ patch -p1 -R < ../patch-2.6.12.2 # revert the 2.6.12.2 patch
288$ patch -p1 < ../patch-2.6.12.3 # apply the new 2.6.12.3 patch
289$ cd ..
290$ mv linux-2.6.12.2 linux-2.6.12.3 # rename the kernel source dir
291
292
293The -rc kernels
294---
295 These are release-candidate kernels. These are development kernels released
296by Linus whenever he deems the current git (the kernel's source management
297tool) tree to be in a reasonably sane state adequate for testing.
298
299These kernels are not stable and you should expect occasional breakage if
300you intend to run them. This is however the most stable of the main
301development branches and is also what will eventually turn into the next
302stable kernel, so it is important that it be tested by as many people as
303possible.
304
305This is a good branch to run for people who want to help out testing
306development kernels but do not want to run some of the really experimental
307stuff (such people should see the sections about -git and -mm kernels below).
308
309The -rc patches are not incremental, they apply to a base 2.6.x kernel, just
310like the 2.6.x.y patches described above. The kernel version before the -rcN
311suffix denotes the version of the kernel that this -rc kernel will eventually
312turn into.
313So, 2.6.13-rc5 means that this is the fifth release candidate for the 2.6.13
314kernel and the patch should be applied on top of the 2.6.12 kernel source.
315
316Here are 3 examples of how to apply these patches:
317
318# first an example of moving from 2.6.12 to 2.6.13-rc3
319$ cd ~/linux-2.6.12 # change into the 2.6.12 source dir
320$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
321$ cd ..
322$ mv linux-2.6.12 linux-2.6.13-rc3 # rename the source dir
323
324# now let's move from 2.6.13-rc3 to 2.6.13-rc5
325$ cd ~/linux-2.6.13-rc3 # change into the 2.6.13-rc3 dir
326$ patch -p1 -R < ../patch-2.6.13-rc3 # revert the 2.6.13-rc3 patch
327$ patch -p1 < ../patch-2.6.13-rc5 # apply the new 2.6.13-rc5 patch
328$ cd ..
329$ mv linux-2.6.13-rc3 linux-2.6.13-rc5 # rename the source dir
330
331# finally let's try and move from 2.6.12.3 to 2.6.13-rc5
332$ cd ~/linux-2.6.12.3 # change to the kernel source dir
333$ patch -p1 -R < ../patch-2.6.12.3 # revert the 2.6.12.3 patch
334$ patch -p1 < ../patch-2.6.13-rc5 # apply new 2.6.13-rc5 patch
335$ cd ..
336$ mv linux-2.6.12.3 linux-2.6.13-rc5 # rename the kernel source dir
337
338
339The -git kernels
340---
341 These are daily snapshots of Linus' kernel tree (managed in a git
342repository, hence the name).
343
344These patches are usually released daily and represent the current state of
345Linus' tree. They are more experimental than -rc kernels since they are
346generated automatically without even a cursory glance to see if they are
347sane.
348
349-git patches are not incremental and apply either to a base 2.6.x kernel or
350a base 2.6.x-rc kernel - you can see which from their name.
351A patch named 2.6.12-git1 applies to the 2.6.12 kernel source and a patch
352named 2.6.13-rc3-git2 applies to the source of the 2.6.13-rc3 kernel.
353
354Here are some examples of how to apply these patches:
355
356# moving from 2.6.12 to 2.6.12-git1
357$ cd ~/linux-2.6.12 # change to the kernel source dir
358$ patch -p1 < ../patch-2.6.12-git1 # apply the 2.6.12-git1 patch
359$ cd ..
360$ mv linux-2.6.12 linux-2.6.12-git1 # rename the kernel source dir
361
362# moving from 2.6.12-git1 to 2.6.13-rc2-git3
363$ cd ~/linux-2.6.12-git1 # change to the kernel source dir
364$ patch -p1 -R < ../patch-2.6.12-git1 # revert the 2.6.12-git1 patch
365 # we now have a 2.6.12 kernel
366$ patch -p1 < ../patch-2.6.13-rc2 # apply the 2.6.13-rc2 patch
367 # the kernel is now 2.6.13-rc2
368$ patch -p1 < ../patch-2.6.13-rc2-git3 # apply the 2.6.13-rc2-git3 patch
369 # the kernel is now 2.6.13-rc2-git3
370$ cd ..
371$ mv linux-2.6.12-git1 linux-2.6.13-rc2-git3 # rename source dir
372
373
374The -mm kernels
375---
376 These are experimental kernels released by Andrew Morton.
377
378The -mm tree serves as a sort of proving ground for new features and other
379experimental patches.
380Once a patch has proved its worth in -mm for a while Andrew pushes it on to
381Linus for inclusion in mainline.
382
383Although it's encouraged that patches flow to Linus via the -mm tree, this
384is not always enforced.
385Subsystem maintainers (or individuals) sometimes push their patches directly
386to Linus, even though (or after) they have been merged and tested in -mm (or
387sometimes even without prior testing in -mm).
388
389You should generally strive to get your patches into mainline via -mm to
390ensure maximum testing.
391
392This branch is in constant flux and contains many experimental features, a
393lot of debugging patches not appropriate for mainline etc and is the most
394experimental of the branches described in this document.
395
396These kernels are not appropriate for use on systems that are supposed to be
397stable and they are more risky to run than any of the other branches (make
398sure you have up-to-date backups - that goes for any experimental kernel but
399even more so for -mm kernels).
400
401These kernels in addition to all the other experimental patches they contain
402usually also contain any changes in the mainline -git kernels available at
403the time of release.
404
405Testing of -mm kernels is greatly appreciated since the whole point of the
406tree is to weed out regressions, crashes, data corruption bugs, build
407breakage (and any other bug in general) before changes are merged into the
408more stable mainline Linus tree.
409But testers of -mm should be aware that breakage in this tree is more common
410than in any other tree.
411
412The -mm kernels are not released on a fixed schedule, but usually a few -mm
413kernels are released in between each -rc kernel (1 to 3 is common).
414The -mm kernels apply to either a base 2.6.x kernel (when no -rc kernels
415have been released yet) or to a Linus -rc kernel.
416
417Here are some examples of applying the -mm patches:
418
419# moving from 2.6.12 to 2.6.12-mm1
420$ cd ~/linux-2.6.12 # change to the 2.6.12 source dir
421$ patch -p1 < ../2.6.12-mm1 # apply the 2.6.12-mm1 patch
422$ cd ..
423$ mv linux-2.6.12 linux-2.6.12-mm1 # rename the source appropriately
424
425# moving from 2.6.12-mm1 to 2.6.13-rc3-mm3
426$ cd ~/linux-2.6.12-mm1
427$ patch -p1 -R < ../2.6.12-mm1 # revert the 2.6.12-mm1 patch
428 # we now have a 2.6.12 source
429$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
430 # we now have a 2.6.13-rc3 source
431$ patch -p1 < ../2.6.13-rc3-mm3 # apply the 2.6.13-rc3-mm3 patch
432$ cd ..
433$ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir
434
435
436This concludes this list of explanations of the various kernel trees and I
437hope you are now crystal clear on how to apply the various patches and help
438testing the kernel.
439
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index 4b8c326c6aac..cb63b7a93c82 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,55 +1,74 @@
1How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working 1How to get the Nebula, PCTV and Twinhan DST cards working
2========================================================================================= 2=========================================================
3 3
41) General information 4This class of cards has a bt878a as the PCI interface, and
5====================== 5require the bttv driver.
6 6
7This class of cards has a bt878a chip as the PCI interface. 7Please pay close attention to the warning about the bttv module
8The different card drivers require the bttv driver to provide the means 8options below for the DST card.
9to access the i2c bus and the gpio pins of the bt8xx chipset.
10 9
112) Compilation rules for Kernel >= 2.6.12 101) General informations
12========================================= 11=======================
13 12
14Enable the following options: 13These drivers require the bttv driver to provide the means to access
14the i2c bus and the gpio pins of the bt8xx chipset.
15 15
16Because of this, you need to enable
16"Device drivers" => "Multimedia devices" 17"Device drivers" => "Multimedia devices"
17 => "Video For Linux" => "BT848 Video For Linux" 18 => "Video For Linux" => "BT848 Video For Linux"
19
20Furthermore you need to enable
18"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" 21"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
19 => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards" 22 => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards"
20 23
213) Loading Modules, described by two approaches 242) Loading Modules
22=============================================== 25==================
23 26
24In 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
25i2c communication for us, plus the common dvb-bt8xx device driver, 28i2c communication for us, plus the common dvb-bt8xx device driver.
26which is called the backend. 29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
27The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110), 30TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
28TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend.
29For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt.
30 31
313a) The manual approach 323a) Nebula / Pinnacle PCTV
32----------------------- 33--------------------------
33 34
34Loading modules: 35 $ modprobe bttv (normally bttv is being loaded automatically by kmod)
35modprobe bttv 36 $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
36modprobe dvb-bt8xx
37 37
38Unloading modules:
39modprobe -r dvb-bt8xx
40modprobe -r bttv
41 38
423b) The automatic approach 393b) TwinHan and Clones
43-------------------------- 40--------------------------
44 41
45If not already done by installation, place a line either in 42 $ modprobe bttv i2c_hw=1 card=0x71
46/etc/modules.conf or in /etc/modprobe.conf containing this text: 43 $ modprobe dvb-bt8xx
47alias char-major-81 bttv 44 $ modprobe dst
45
46The value 0x71 will override the PCI type detection for dvb-bt8xx,
47which is necessary for TwinHan cards.
48
49If you're having an older card (blue color circuit) and card=0x71 locks
50your machine, try using 0x68, too. If that does not work, ask on the
51mailing list.
52
53The DST module takes a couple of useful parameters.
54
55verbose takes values 0 to 4. These values control the verbosity level,
56and can be used to debug also.
57
58verbose=0 means complete disabling of messages
59 1 only error messages are displayed
60 2 notifications are also displayed
61 3 informational messages are also displayed
62 4 debug setting
63
64dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
650x20 means it has a Conditional Access slot.
66
67The autodected values are determined bythe cards 'response
68string' which you can see in your logs e.g.
48 69
49Then place a line in /etc/modules containing this text: 70dst_get_device_id: Recognise [DSTMCI]
50dvb-bt8xx
51 71
52Reboot your system and have fun!
53 72
54-- 73--
55Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla 74Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt
index 62e0701b542a..95f0e73b2135 100644
--- a/Documentation/dvb/ci.txt
+++ b/Documentation/dvb/ci.txt
@@ -23,7 +23,6 @@ This application requires the following to function properly as of now.
23 eg: $ szap -c channels.conf -r "TMC" -x 23 eg: $ szap -c channels.conf -r "TMC" -x
24 24
25 (b) a channels.conf containing a valid PMT PID 25 (b) a channels.conf containing a valid PMT PID
26
27 eg: TMC:11996:h:0:27500:278:512:650:321 26 eg: TMC:11996:h:0:27500:278:512:650:321
28 27
29 here 278 is a valid PMT PID. the rest of the values are the 28 here 278 is a valid PMT PID. the rest of the values are the
@@ -31,13 +30,7 @@ This application requires the following to function properly as of now.
31 30
32 (c) after running a szap, you have to run ca_zap, for the 31 (c) after running a szap, you have to run ca_zap, for the
33 descrambler to function, 32 descrambler to function,
34 33 eg: $ ca_zap channels.conf "TMC"
35 eg: $ ca_zap patched_channels.conf "TMC"
36
37 The patched means a patch to apply to scan, such that scan can
38 generate a channels.conf_with pmt, which has this PMT PID info
39 (NOTE: szap cannot use this channels.conf with the PMT_PID)
40
41 34
42 (d) Hopeflly Enjoy your favourite subscribed channel as you do with 35 (d) Hopeflly Enjoy your favourite subscribed channel as you do with
43 a FTA card. 36 a FTA card.
diff --git a/Documentation/fb/cyblafb/bugs b/Documentation/fb/cyblafb/bugs
new file mode 100644
index 000000000000..f90cc66ea919
--- /dev/null
+++ b/Documentation/fb/cyblafb/bugs
@@ -0,0 +1,14 @@
1Bugs
2====
3
4I currently don't know of any bug. Please do send reports to:
5 - linux-fbdev-devel@lists.sourceforge.net
6 - Knut_Petersen@t-online.de.
7
8
9Untested features
10=================
11
12All LCD stuff is untested. If it worked in tridentfb, it should work in
13cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
14
diff --git a/Documentation/fb/cyblafb/credits b/Documentation/fb/cyblafb/credits
new file mode 100644
index 000000000000..0eb3b443dc2b
--- /dev/null
+++ b/Documentation/fb/cyblafb/credits
@@ -0,0 +1,7 @@
1Thanks to
2=========
3 * Alan Hourihane, for writing the X trident driver
4 * Jani Monoses, for writing the tridentfb driver
5 * Antonino A. Daplas, for review of the first published
6 version of cyblafb and some code
7 * Jochen Hein, for testing and a helpfull bug report
diff --git a/Documentation/fb/cyblafb/documentation b/Documentation/fb/cyblafb/documentation
new file mode 100644
index 000000000000..bb1aac048425
--- /dev/null
+++ b/Documentation/fb/cyblafb/documentation
@@ -0,0 +1,17 @@
1Available Documentation
2=======================
3
4Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
52001, available from VIA:
6
7 http://www.viavpsd.com/product/6/15/DS8601A182.pdf
8
9The datasheet is incomplete, some registers that need to be programmed are not
10explained at all and important bits are listed as "reserved". But you really
11need the datasheet to understand the code. "p. xxx" comments refer to page
12numbers of this document.
13
14XFree/XOrg drivers are available and of good quality, looking at the code
15there is a good idea if the datasheet does not provide enough information
16or if the datasheet seems to be wrong.
17
diff --git a/Documentation/fb/cyblafb/fb.modes b/Documentation/fb/cyblafb/fb.modes
new file mode 100644
index 000000000000..cf4351fc32ff
--- /dev/null
+++ b/Documentation/fb/cyblafb/fb.modes
@@ -0,0 +1,155 @@
1#
2# Sample fb.modes file
3#
4# Provides an incomplete list of working modes for
5# the cyberblade/i1 graphics core.
6#
7# The value 4294967256 is used instead of -40. Of course, -40 is not
8# a really reasonable value, but chip design does not always follow
9# logic. Believe me, it's ok, and it's the way the BIOS does it.
10#
11# fbset requires 4294967256 in fb.modes and -40 as an argument to
12# the -t parameter. That's also not too reasonable, and it might change
13# in the future or might even be differt for your current version.
14#
15
16mode "640x480-50"
17 geometry 640 480 640 3756 8
18 timings 47619 4294967256 24 17 0 216 3
19endmode
20
21mode "640x480-60"
22 geometry 640 480 640 3756 8
23 timings 39682 4294967256 24 17 0 216 3
24endmode
25
26mode "640x480-70"
27 geometry 640 480 640 3756 8
28 timings 34013 4294967256 24 17 0 216 3
29endmode
30
31mode "640x480-72"
32 geometry 640 480 640 3756 8
33 timings 33068 4294967256 24 17 0 216 3
34endmode
35
36mode "640x480-75"
37 geometry 640 480 640 3756 8
38 timings 31746 4294967256 24 17 0 216 3
39endmode
40
41mode "640x480-80"
42 geometry 640 480 640 3756 8
43 timings 29761 4294967256 24 17 0 216 3
44endmode
45
46mode "640x480-85"
47 geometry 640 480 640 3756 8
48 timings 28011 4294967256 24 17 0 216 3
49endmode
50
51mode "800x600-50"
52 geometry 800 600 800 3221 8
53 timings 30303 96 24 14 0 136 11
54endmode
55
56mode "800x600-60"
57 geometry 800 600 800 3221 8
58 timings 25252 96 24 14 0 136 11
59endmode
60
61mode "800x600-70"
62 geometry 800 600 800 3221 8
63 timings 21645 96 24 14 0 136 11
64endmode
65
66mode "800x600-72"
67 geometry 800 600 800 3221 8
68 timings 21043 96 24 14 0 136 11
69endmode
70
71mode "800x600-75"
72 geometry 800 600 800 3221 8
73 timings 20202 96 24 14 0 136 11
74endmode
75
76mode "800x600-80"
77 geometry 800 600 800 3221 8
78 timings 18939 96 24 14 0 136 11
79endmode
80
81mode "800x600-85"
82 geometry 800 600 800 3221 8
83 timings 17825 96 24 14 0 136 11
84endmode
85
86mode "1024x768-50"
87 geometry 1024 768 1024 2815 8
88 timings 19054 144 24 29 0 120 3
89endmode
90
91mode "1024x768-60"
92 geometry 1024 768 1024 2815 8
93 timings 15880 144 24 29 0 120 3
94endmode
95
96mode "1024x768-70"
97 geometry 1024 768 1024 2815 8
98 timings 13610 144 24 29 0 120 3
99endmode
100
101mode "1024x768-72"
102 geometry 1024 768 1024 2815 8
103 timings 13232 144 24 29 0 120 3
104endmode
105
106mode "1024x768-75"
107 geometry 1024 768 1024 2815 8
108 timings 12703 144 24 29 0 120 3
109endmode
110
111mode "1024x768-80"
112 geometry 1024 768 1024 2815 8
113 timings 11910 144 24 29 0 120 3
114endmode
115
116mode "1024x768-85"
117 geometry 1024 768 1024 2815 8
118 timings 11209 144 24 29 0 120 3
119endmode
120
121mode "1280x1024-50"
122 geometry 1280 1024 1280 2662 8
123 timings 11114 232 16 39 0 160 3
124endmode
125
126mode "1280x1024-60"
127 geometry 1280 1024 1280 2662 8
128 timings 9262 232 16 39 0 160 3
129endmode
130
131mode "1280x1024-70"
132 geometry 1280 1024 1280 2662 8
133 timings 7939 232 16 39 0 160 3
134endmode
135
136mode "1280x1024-72"
137 geometry 1280 1024 1280 2662 8
138 timings 7719 232 16 39 0 160 3
139endmode
140
141mode "1280x1024-75"
142 geometry 1280 1024 1280 2662 8
143 timings 7410 232 16 39 0 160 3
144endmode
145
146mode "1280x1024-80"
147 geometry 1280 1024 1280 2662 8
148 timings 6946 232 16 39 0 160 3
149endmode
150
151mode "1280x1024-85"
152 geometry 1280 1024 1280 2662 8
153 timings 6538 232 16 39 0 160 3
154endmode
155
diff --git a/Documentation/fb/cyblafb/performance b/Documentation/fb/cyblafb/performance
new file mode 100644
index 000000000000..eb4e47a9cea6
--- /dev/null
+++ b/Documentation/fb/cyblafb/performance
@@ -0,0 +1,80 @@
1Speed
2=====
3
4CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
5for mode 1280x1024-[8,16,32]@61 Hz.
6
7Test 1: Cat a file with 2000 lines of 0 characters.
8Test 2: Cat a file with 2000 lines of 80 characters.
9Test 3: Cat a file with 2000 lines of 160 characters.
10
11All values show system time use in seconds, kernel 2.6.12 was used for
12the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
13patch that speeds up kernel bitblitting a lot ( > 20%).
14
15+-----------+-----------------------------------------------------+
16| | not accelerated |
17| TRIDENTFB +-----------------+-----------------+-----------------+
18| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
19| | noypan | ypan | noypan | ypan | noypan | ypan |
20+-----------+--------+--------+--------+--------+--------+--------+
21| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- |
22| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- |
23| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- |
24+-----------+--------+--------+--------+--------+--------+--------+
25| Comments | | | completely bro- |
26| | | | ken, monitor |
27| | | | switches off |
28+-----------+-----------------+-----------------+-----------------+
29
30
31+-----------+-----------------------------------------------------+
32| | accelerated |
33| TRIDENTFB +-----------------+-----------------+-----------------+
34| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
35| | noypan | ypan | noypan | ypan | noypan | ypan |
36+-----------+--------+--------+--------+--------+--------+--------+
37| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- |
38| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- |
39| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- |
40+-----------+--------+--------+--------+--------+--------+--------+
41| Comments | broken, writing | broken, ok only | completely bro- |
42| | to wrong places | if bgcolor is | ken, monitor |
43| | on screen + bug | black, bug in | switches off |
44| | in fillrect() | fillrect() | |
45+-----------+-----------------+-----------------+-----------------+
46
47
48+-----------+-----------------------------------------------------+
49| | not accelerated |
50| VESAFB +-----------------+-----------------+-----------------+
51| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
52| | noypan | ypan | noypan | ypan | noypan | ypan |
53+-----------+--------+--------+--------+--------+--------+--------+
54| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- |
55| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- |
56| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- |
57+-----------+--------+--------+--------+--------+--------+--------+
58| Comments | vga=0x307 | vga=0x31a | vga=0x31b not |
59| | fh=80kHz | fh=80kHz | supported by |
60| | fv=75kHz | fv=75kHz | video BIOS and |
61| | | | hardware |
62+-----------+-----------------+-----------------+-----------------+
63
64
65+-----------+-----------------------------------------------------+
66| | accelerated |
67| CYBLAFB +-----------------+-----------------+-----------------+
68| | 8 bpp | 16 bpp | 32 bpp |
69| | noypan | ypan | noypan | ypan | noypan | ypan |
70+-----------+--------+--------+--------+--------+--------+--------+
71| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 |
72| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 |
73| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 |
74+-----------+--------+--------+--------+--------+--------+--------+
75| Comments | | | |
76| | | | |
77| | | | |
78| | | | |
79+-----------+-----------------+-----------------+-----------------+
80
diff --git a/Documentation/fb/cyblafb/todo b/Documentation/fb/cyblafb/todo
new file mode 100644
index 000000000000..80fb2f89b6c1
--- /dev/null
+++ b/Documentation/fb/cyblafb/todo
@@ -0,0 +1,32 @@
1TODO / Missing features
2=======================
3
4Verify LCD stuff "stretch" and "center" options are
5 completely untested ... this code needs to be
6 verified. As I don't have access to such
7 hardware, please contact me if you are
8 willing run some tests.
9
10Interlaced video modes The reason that interleaved
11 modes are disabled is that I do not know
12 the meaning of the vertical interlace
13 parameter. Also the datasheet mentions a
14 bit d8 of a horizontal interlace parameter,
15 but nowhere the lower 8 bits. Please help
16 if you can.
17
18low-res double scan modes Who needs it?
19
20accelerated color blitting Who needs it? The console driver does use color
21 blitting for nothing but drawing the penguine,
22 everything else is done using color expanding
23 blitting of 1bpp character bitmaps.
24
25xpanning Who needs it?
26
27ioctls Who needs it?
28
29TV-out Will be done later
30
31??? Feel free to contact me if you have any
32 feature requests
diff --git a/Documentation/fb/cyblafb/usage b/Documentation/fb/cyblafb/usage
new file mode 100644
index 000000000000..e627c8f54211
--- /dev/null
+++ b/Documentation/fb/cyblafb/usage
@@ -0,0 +1,206 @@
1CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
2into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
3tested using a VIA EPIA 5000 board.
4
5Cyblafb - compiled into the kernel or as a module?
6==================================================
7
8You might compile cyblafb either as a module or compile it permanently into the
9kernel.
10
11Unless you have a real reason to do so you should not compile both vesafb and
12cyblafb permanently into the kernel. It's possible and it helps during the
13developement cycle, but it's useless and will at least block some otherwise
14usefull memory for ordinary users.
15
16Selecting Modes
17===============
18
19 Startup Mode
20 ============
21
22 First of all, you might use the "vga=???" boot parameter as it is
23 documented in vesafb.txt and svga.txt. Cyblafb will detect the video
24 mode selected and will use the geometry and timings found by
25 inspecting the hardware registers.
26
27 video=cyblafb vga=0x317
28
29 Alternatively you might use a combination of the mode, ref and bpp
30 parameters. If you compiled the driver into the kernel, add something
31 like this to the kernel command line:
32
33 video=cyblafb:1280x1024,bpp=16,ref=50 ...
34
35 If you compiled the driver as a module, the same mode would be
36 selected by the following command:
37
38 modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
39
40 None of the modes possible to select as startup modes are affected by
41 the problems described at the end of the next subsection.
42
43 Mode changes using fbset
44 ========================
45
46 You might use fbset to change the video mode, see "man fbset". Cyblafb
47 generally does assume that you know what you are doing. But it does
48 some checks, especially those that are needed to prevent you from
49 damaging your hardware.
50
51 - only 8, 16, 24 and 32 bpp video modes are accepted
52 - interlaced video modes are not accepted
53 - double scan video modes are not accepted
54 - if a flat panel is found, cyblafb does not allow you
55 to program a resolution higher than the physical
56 resolution of the flat panel monitor
57 - cyblafb does not allow xres to differ from xres_virtual
58 - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
59 and (currently) 24 bit modes use a doubled vclk internally,
60 the dotclock limit as seen by fbset is 115 MHz for those
61 modes and 230 MHz for 8 and 16 bpp modes.
62
63 Any request that violates the rules given above will be ignored and
64 fbset will return an error.
65
66 If you program a virtual y resolution higher than the hardware limit,
67 cyblafb will silently decrease that value to the highest possible
68 value.
69
70 Attempts to disable acceleration are ignored.
71
72 Some video modes that should work do not work as expected. If you use
73 the standard fb.modes, fbset 640x480-60 will program that mode, but
74 you will see a vertical area, about two characters wide, with only
75 much darker characters than the other characters on the screen.
76 Cyblafb does allow that mode to be set, as it does not violate the
77 official specifications. It would need a lot of code to reliably sort
78 out all invalid modes, playing around with the margin values will
79 give a valid mode quickly. And if cyblafb would detect such an invalid
80 mode, should it silently alter the requested values or should it
81 report an error? Both options have some pros and cons. As stated
82 above, none of the startup modes are affected, and if you set
83 verbosity to 1 or higher, cyblafb will print the fbset command that
84 would be needed to program that mode using fbset.
85
86
87Other Parameters
88================
89
90
91crt don't autodetect, assume monitor connected to
92 standard VGA connector
93
94fp don't autodetect, assume flat panel display
95 connected to flat panel monitor interface
96
97nativex inform driver about native x resolution of
98 flat panel monitor connected to special
99 interface (should be autodetected)
100
101stretch stretch image to adapt low resolution modes to
102 higer resolutions of flat panel monitors
103 connected to special interface
104
105center center image to adapt low resolution modes to
106 higer resolutions of flat panel monitors
107 connected to special interface
108
109memsize use if autodetected memsize is wrong ...
110 should never be necessary
111
112nopcirr disable PCI read retry
113nopciwr disable PCI write retry
114nopcirb disable PCI read bursts
115nopciwb disable PCI write bursts
116
117bpp bpp for specified modes
118 valid values: 8 || 16 || 24 || 32
119
120ref refresh rate for specified mode
121 valid values: 50 <= ref <= 85
122
123mode 640x480 or 800x600 or 1024x768 or 1280x1024
124 if not specified, the startup mode will be detected
125 and used, so you might also use the vga=??? parameter
126 described in vesafb.txt. If you do not specify a mode,
127 bpp and ref parameters are ignored.
128
129verbosity 0 is the default, increase to at least 2 for every
130 bug report!
131
132vesafb allows cyblafb to be loaded after vesafb has been
133 loaded. See sections "Module unloading ...".
134
135
136Development hints
137=================
138
139It's much faster do compile a module and to load the new version after
140unloading the old module than to compile a new kernel and to reboot. So if you
141try to work on cyblafb, it might be a good idea to use cyblafb as a module.
142In real life, fast often means dangerous, and that's also the case here. If
143you introduce a serious bug when cyblafb is compiled into the kernel, the
144kernel will lock or oops with a high probability before the file system is
145mounted, and the danger for your data is low. If you load a broken own version
146of cyblafb on a running system, the danger for the integrity of the file
147system is much higher as you might need a hard reset afterwards. Decide
148yourself.
149
150Module unloading, the vfb method
151================================
152
153If you want to unload/reload cyblafb using the virtual framebuffer, you need
154to enable vfb support in the kernel first. After that, load the modules as
155shown below:
156
157 modprobe vfb vfb_enable=1
158 modprobe fbcon
159 modprobe cyblafb
160 fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
161 con2fb /dev/fb1 /dev/tty1
162 ...
163
164If you now made some changes to cyblafb and want to reload it, you might do it
165as show below:
166
167 con2fb /dev/fb0 /dev/tty1
168 ...
169 rmmod cyblafb
170 modprobe cyblafb
171 con2fb /dev/fb1 /dev/tty1
172 ...
173
174Of course, you might choose another mode, and most certainly you also want to
175map some other /dev/tty* to the real framebuffer device. You might also choose
176to compile fbcon as a kernel module or place it permanently in the kernel.
177
178I do not know of any way to unload fbcon, and fbcon will prevent the
179framebuffer device loaded first from unloading. [If there is a way, then
180please add a description here!]
181
182Module unloading, the vesafb method
183===================================
184
185Configure the kernel:
186
187 <*> Support for frame buffer devices
188 [*] VESA VGA graphics support
189 <M> Cyberblade/i1 support
190
191Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
192parameter is important, choose any vga parameter you like as long as it is
193a graphics mode.
194
195After booting, load cyblafb without any mode and bpp parameter and assign
196cyblafb to individual ttys using con2fb, e.g.:
197
198 modprobe cyblafb vesafb=1
199 con2fb /dev/fb1 /dev/tty1
200
201Unloading cyblafb works without problems after you assign vesafb to all
202ttys again, e.g.:
203
204 con2fb /dev/fb0 /dev/tty1
205 rmmod cyblafb
206
diff --git a/Documentation/fb/cyblafb/whycyblafb b/Documentation/fb/cyblafb/whycyblafb
new file mode 100644
index 000000000000..a123bc11e698
--- /dev/null
+++ b/Documentation/fb/cyblafb/whycyblafb
@@ -0,0 +1,85 @@
1I tried the following framebuffer drivers:
2
3 - TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
4 graphics cores like the cyberblade/i1. It claims to support a great
5 number of devices, but documentation for most of these devices is
6 unfortunately not available. There is _no_ reason to use tridentfb
7 for cyberblade/i1 + CRT users. VESAFB is faster, and the one
8 advantage, mode switching, is broken in tridentfb.
9
10 - VESAFB is used by many distributions as a standard. Vesafb does
11 not support mode switching. VESAFB is a bit faster than the working
12 configurations of TRIDENTFB, but it is still too slow, even if you
13 use ypan.
14
15 - EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
16 graphics core, but it still has serious bugs and developement seems
17 to have stopped. This is the one driver with TV-out support. If you
18 do need this feature, try epiafb.
19
20None of these drivers was a real option for me.
21
22I believe that is unreasonable to change code that announces to support 20
23devices if I only have more or less sufficient documentation for exactly one
24of these. The risk of breaking device foo while fixing device bar is too high.
25
26So I decided to start CyBlaFB as a stripped down tridentfb.
27
28All code specific to other Trident chips has been removed. After that there
29were a lot of cosmetic changes to increase the readability of the code. All
30register names were changed to those mnemonics used in the datasheet. Function
31and macro names were changed if they hindered easy understanding of the code.
32
33After that I debugged the code and implemented some new features. I'll try to
34give a little summary of the main changes:
35
36 - calculation of vertical and horizontal timings was fixed
37
38 - video signal quality has been improved dramatically
39
40 - acceleration:
41
42 - fillrect and copyarea were fixed and reenabled
43
44 - color expanding imageblit was newly implemented, color
45 imageblit (only used to draw the penguine) still uses the
46 generic code.
47
48 - init of the acceleration engine was improved and moved to a
49 place where it really works ...
50
51 - sync function has a timeout now and tries to reset and
52 reinit the accel engine if necessary
53
54 - fewer slow copyarea calls when doing ypan scrolling by using
55 undocumented bit d21 of screen start address stored in
56 CR2B[5]. BIOS does use it also, so this should be safe.
57
58 - cyblafb rejects any attempt to set modes that would cause vclk
59 values above reasonable 230 MHz. 32bit modes use a clock
60 multiplicator of 2, so fbset does show the correct values for
61 pixclock but not for vclk in this case. The fbset limit is 115 MHz
62 for 32 bpp modes.
63
64 - cyblafb rejects modes known to be broken or unimplemented (all
65 interlaced modes, all doublescan modes for now)
66
67 - cyblafb now works independant of the video mode in effect at startup
68 time (tridentfb does not init all needed registers to reasonable
69 values)
70
71 - switching between video modes does work reliably now
72
73 - the first video mode now is the one selected on startup using the
74 vga=???? mechanism or any of
75 - 640x480, 800x600, 1024x768, 1280x1024
76 - 8, 16, 24 or 32 bpp
77 - refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
78 is limited to 63Hz)
79
80 - pci retry and pci burst mode are settable (try to disable if you
81 experience latency problems)
82
83 - built as a module cyblafb might be unloaded and reloaded using
84 the vfb module and con2vt or might be used together with vesafb
85
diff --git a/Documentation/fb/modedb.txt b/Documentation/fb/modedb.txt
index e04458b319d5..4fcdb4cf4cca 100644
--- a/Documentation/fb/modedb.txt
+++ b/Documentation/fb/modedb.txt
@@ -20,12 +20,83 @@ in a video= option, fbmem considers that to be a global video mode option.
20 20
21Valid mode specifiers (mode_option argument): 21Valid mode specifiers (mode_option argument):
22 22
23 <xres>x<yres>[-<bpp>][@<refresh>] 23 <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m]
24 <name>[-<bpp>][@<refresh>] 24 <name>[-<bpp>][@<refresh>]
25 25
26with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string. 26with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string.
27Things between square brackets are optional. 27Things between square brackets are optional.
28 28
29If 'M' is specified in the mode_option argument (after <yres> and before
30<bpp> and <refresh>, if specified) the timings will be calculated using
31VESA(TM) Coordinated Video Timings instead of looking up the mode from a table.
32If 'R' is specified, do a 'reduced blanking' calculation for digital displays.
33If 'i' is specified, calculate for an interlaced mode. And if 'm' is
34specified, add margins to the calculation (1.8% of xres rounded down to 8
35pixels and 1.8% of yres).
36
37 Sample usage: 1024x768M@60m - CVT timing with margins
38
39***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo *****
40
41What is the VESA(TM) Coordinated Video Timings (CVT)?
42
43From the VESA(TM) Website:
44
45 "The purpose of CVT is to provide a method for generating a consistent
46 and coordinated set of standard formats, display refresh rates, and
47 timing specifications for computer display products, both those
48 employing CRTs, and those using other display technologies. The
49 intention of CVT is to give both source and display manufacturers a
50 common set of tools to enable new timings to be developed in a
51 consistent manner that ensures greater compatibility."
52
53This is the third standard approved by VESA(TM) concerning video timings. The
54first was the Discrete Video Timings (DVT) which is a collection of
55pre-defined modes approved by VESA(TM). The second is the Generalized Timing
56Formula (GTF) which is an algorithm to calculate the timings, given the
57pixelclock, the horizontal sync frequency, or the vertical refresh rate.
58
59The GTF is limited by the fact that it is designed mainly for CRT displays.
60It artificially increases the pixelclock because of its high blanking
61requirement. This is inappropriate for digital display interface with its high
62data rate which requires that it conserves the pixelclock as much as possible.
63Also, GTF does not take into account the aspect ratio of the display.
64
65The CVT addresses these limitations. If used with CRT's, the formula used
66is a derivation of GTF with a few modifications. If used with digital
67displays, the "reduced blanking" calculation can be used.
68
69From the framebuffer subsystem perspective, new formats need not be added
70to the global mode database whenever a new mode is released by display
71manufacturers. Specifying for CVT will work for most, if not all, relatively
72new CRT displays and probably with most flatpanels, if 'reduced blanking'
73calculation is specified. (The CVT compatibility of the display can be
74determined from its EDID. The version 1.3 of the EDID has extra 128-byte
75blocks where additional timing information is placed. As of this time, there
76is no support yet in the layer to parse this additional blocks.)
77
78CVT also introduced a new naming convention (should be seen from dmesg output):
79
80 <pix>M<a>[-R]
81
82 where: pix = total amount of pixels in MB (xres x yres)
83 M = always present
84 a = aspect ratio (3 - 4:3; 4 - 5:4; 9 - 15:9, 16:9; A - 16:10)
85 -R = reduced blanking
86
87 example: .48M3-R - 800x600 with reduced blanking
88
89Note: VESA(TM) has restrictions on what is a standard CVT timing:
90
91 - aspect ratio can only be one of the above values
92 - acceptable refresh rates are 50, 60, 70 or 85 Hz only
93 - if reduced blanking, the refresh rate must be at 60Hz
94
95If one of the above are not satisfied, the kernel will print a warning but the
96timings will still be calculated.
97
98***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo *****
99
29To find a suitable video mode, you just call 100To find a suitable video mode, you just call
30 101
31int __init fb_find_mode(struct fb_var_screeninfo *var, 102int __init fb_find_mode(struct fb_var_screeninfo *var,
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 2e0a01b21fe0..5f95d4b3cab1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -25,15 +25,6 @@ Who: Pavel Machek <pavel@suse.cz>
25 25
26--------------------------- 26---------------------------
27 27
28What: PCI Name Database (CONFIG_PCI_NAMES)
29When: July 2005
30Why: It bloats the kernel unnecessarily, and is handled by userspace better
31 (pciutils supports it.) Will eliminate the need to try to keep the
32 pci.ids file in sync with the sf.net database all of the time.
33Who: Greg Kroah-Hartman <gregkh@suse.de>
34
35---------------------------
36
37What: io_remap_page_range() (macro or function) 28What: io_remap_page_range() (macro or function)
38When: September 2005 29When: September 2005
39Why: Replaced by io_remap_pfn_range() which allows more memory space 30Why: Replaced by io_remap_pfn_range() which allows more memory space
diff --git a/Documentation/filesystems/files.txt b/Documentation/filesystems/files.txt
new file mode 100644
index 000000000000..8c206f4e0250
--- /dev/null
+++ b/Documentation/filesystems/files.txt
@@ -0,0 +1,123 @@
1File management in the Linux kernel
2-----------------------------------
3
4This document describes how locking for files (struct file)
5and file descriptor table (struct files) works.
6
7Up until 2.6.12, the file descriptor table has been protected
8with a lock (files->file_lock) and reference count (files->count).
9->file_lock protected accesses to all the file related fields
10of the table. ->count was used for sharing the file descriptor
11table between tasks cloned with CLONE_FILES flag. Typically
12this would be the case for posix threads. As with the common
13refcounting model in the kernel, the last task doing
14a put_files_struct() frees the file descriptor (fd) table.
15The files (struct file) themselves are protected using
16reference count (->f_count).
17
18In the new lock-free model of file descriptor management,
19the reference counting is similar, but the locking is
20based on RCU. The file descriptor table contains multiple
21elements - the fd sets (open_fds and close_on_exec, the
22array of file pointers, the sizes of the sets and the array
23etc.). In order for the updates to appear atomic to
24a lock-free reader, all the elements of the file descriptor
25table are in a separate structure - struct fdtable.
26files_struct contains a pointer to struct fdtable through
27which the actual fd table is accessed. Initially the
28fdtable is embedded in files_struct itself. On a subsequent
29expansion of fdtable, a new fdtable structure is allocated
30and files->fdtab points to the new structure. The fdtable
31structure is freed with RCU and lock-free readers either
32see the old fdtable or the new fdtable making the update
33appear atomic. Here are the locking rules for
34the fdtable structure -
35
361. All references to the fdtable must be done through
37 the files_fdtable() macro :
38
39 struct fdtable *fdt;
40
41 rcu_read_lock();
42
43 fdt = files_fdtable(files);
44 ....
45 if (n <= fdt->max_fds)
46 ....
47 ...
48 rcu_read_unlock();
49
50 files_fdtable() uses rcu_dereference() macro which takes care of
51 the memory barrier requirements for lock-free dereference.
52 The fdtable pointer must be read within the read-side
53 critical section.
54
552. Reading of the fdtable as described above must be protected
56 by rcu_read_lock()/rcu_read_unlock().
57
583. For any update to the the fd table, files->file_lock must
59 be held.
60
614. To look up the file structure given an fd, a reader
62 must use either fcheck() or fcheck_files() APIs. These
63 take care of barrier requirements due to lock-free lookup.
64 An example :
65
66 struct file *file;
67
68 rcu_read_lock();
69 file = fcheck(fd);
70 if (file) {
71 ...
72 }
73 ....
74 rcu_read_unlock();
75
765. Handling of the file structures is special. Since the look-up
77 of the fd (fget()/fget_light()) are lock-free, it is possible
78 that look-up may race with the last put() operation on the
79 file structure. This is avoided using the rcuref APIs
80 on ->f_count :
81
82 rcu_read_lock();
83 file = fcheck_files(files, fd);
84 if (file) {
85 if (rcuref_inc_lf(&file->f_count))
86 *fput_needed = 1;
87 else
88 /* Didn't get the reference, someone's freed */
89 file = NULL;
90 }
91 rcu_read_unlock();
92 ....
93 return file;
94
95 rcuref_inc_lf() detects if refcounts is already zero or
96 goes to zero during increment. If it does, we fail
97 fget()/fget_light().
98
996. Since both fdtable and file structures can be looked up
100 lock-free, they must be installed using rcu_assign_pointer()
101 API. If they are looked up lock-free, rcu_dereference()
102 must be used. However it is advisable to use files_fdtable()
103 and fcheck()/fcheck_files() which take care of these issues.
104
1057. While updating, the fdtable pointer must be looked up while
106 holding files->file_lock. If ->file_lock is dropped, then
107 another thread expand the files thereby creating a new
108 fdtable and making the earlier fdtable pointer stale.
109 For example :
110
111 spin_lock(&files->file_lock);
112 fd = locate_fd(files, file, start);
113 if (fd >= 0) {
114 /* locate_fd() may have expanded fdtable, load the ptr */
115 fdt = files_fdtable(files);
116 FD_SET(fd, fdt->open_fds);
117 FD_CLR(fd, fdt->close_on_exec);
118 spin_unlock(&files->file_lock);
119 .....
120
121 Since locate_fd() can drop ->file_lock (and reacquire ->file_lock),
122 the fdtable pointer (fdt) must be loaded after locate_fd().
123
diff --git a/Documentation/filesystems/fuse.txt b/Documentation/filesystems/fuse.txt
new file mode 100644
index 000000000000..6b5741e651a2
--- /dev/null
+++ b/Documentation/filesystems/fuse.txt
@@ -0,0 +1,315 @@
1Definitions
2~~~~~~~~~~~
3
4Userspace filesystem:
5
6 A filesystem in which data and metadata are provided by an ordinary
7 userspace process. The filesystem can be accessed normally through
8 the kernel interface.
9
10Filesystem daemon:
11
12 The process(es) providing the data and metadata of the filesystem.
13
14Non-privileged mount (or user mount):
15
16 A userspace filesystem mounted by a non-privileged (non-root) user.
17 The filesystem daemon is running with the privileges of the mounting
18 user. NOTE: this is not the same as mounts allowed with the "user"
19 option in /etc/fstab, which is not discussed here.
20
21Mount owner:
22
23 The user who does the mounting.
24
25User:
26
27 The user who is performing filesystem operations.
28
29What is FUSE?
30~~~~~~~~~~~~~
31
32FUSE is a userspace filesystem framework. It consists of a kernel
33module (fuse.ko), a userspace library (libfuse.*) and a mount utility
34(fusermount).
35
36One of the most important features of FUSE is allowing secure,
37non-privileged mounts. This opens up new possibilities for the use of
38filesystems. A good example is sshfs: a secure network filesystem
39using the sftp protocol.
40
41The userspace library and utilities are available from the FUSE
42homepage:
43
44 http://fuse.sourceforge.net/
45
46Mount options
47~~~~~~~~~~~~~
48
49'fd=N'
50
51 The file descriptor to use for communication between the userspace
52 filesystem and the kernel. The file descriptor must have been
53 obtained by opening the FUSE device ('/dev/fuse').
54
55'rootmode=M'
56
57 The file mode of the filesystem's root in octal representation.
58
59'user_id=N'
60
61 The numeric user id of the mount owner.
62
63'group_id=N'
64
65 The numeric group id of the mount owner.
66
67'default_permissions'
68
69 By default FUSE doesn't check file access permissions, the
70 filesystem is free to implement it's access policy or leave it to
71 the underlying file access mechanism (e.g. in case of network
72 filesystems). This option enables permission checking, restricting
73 access based on file mode. This is option is usually useful
74 together with the 'allow_other' mount option.
75
76'allow_other'
77
78 This option overrides the security measure restricting file access
79 to the user mounting the filesystem. This option is by default only
80 allowed to root, but this restriction can be removed with a
81 (userspace) configuration option.
82
83'max_read=N'
84
85 With this option the maximum size of read operations can be set.
86 The default is infinite. Note that the size of read requests is
87 limited anyway to 32 pages (which is 128kbyte on i386).
88
89How do non-privileged mounts work?
90~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91
92Since the mount() system call is a privileged operation, a helper
93program (fusermount) is needed, which is installed setuid root.
94
95The implication of providing non-privileged mounts is that the mount
96owner must not be able to use this capability to compromise the
97system. Obvious requirements arising from this are:
98
99 A) mount owner should not be able to get elevated privileges with the
100 help of the mounted filesystem
101
102 B) mount owner should not get illegitimate access to information from
103 other users' and the super user's processes
104
105 C) mount owner should not be able to induce undesired behavior in
106 other users' or the super user's processes
107
108How are requirements fulfilled?
109~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110
111 A) The mount owner could gain elevated privileges by either:
112
113 1) creating a filesystem containing a device file, then opening
114 this device
115
116 2) creating a filesystem containing a suid or sgid application,
117 then executing this application
118
119 The solution is not to allow opening device files and ignore
120 setuid and setgid bits when executing programs. To ensure this
121 fusermount always adds "nosuid" and "nodev" to the mount options
122 for non-privileged mounts.
123
124 B) If another user is accessing files or directories in the
125 filesystem, the filesystem daemon serving requests can record the
126 exact sequence and timing of operations performed. This
127 information is otherwise inaccessible to the mount owner, so this
128 counts as an information leak.
129
130 The solution to this problem will be presented in point 2) of C).
131
132 C) There are several ways in which the mount owner can induce
133 undesired behavior in other users' processes, such as:
134
135 1) mounting a filesystem over a file or directory which the mount
136 owner could otherwise not be able to modify (or could only
137 make limited modifications).
138
139 This is solved in fusermount, by checking the access
140 permissions on the mountpoint and only allowing the mount if
141 the mount owner can do unlimited modification (has write
142 access to the mountpoint, and mountpoint is not a "sticky"
143 directory)
144
145 2) Even if 1) is solved the mount owner can change the behavior
146 of other users' processes.
147
148 i) It can slow down or indefinitely delay the execution of a
149 filesystem operation creating a DoS against the user or the
150 whole system. For example a suid application locking a
151 system file, and then accessing a file on the mount owner's
152 filesystem could be stopped, and thus causing the system
153 file to be locked forever.
154
155 ii) It can present files or directories of unlimited length, or
156 directory structures of unlimited depth, possibly causing a
157 system process to eat up diskspace, memory or other
158 resources, again causing DoS.
159
160 The solution to this as well as B) is not to allow processes
161 to access the filesystem, which could otherwise not be
162 monitored or manipulated by the mount owner. Since if the
163 mount owner can ptrace a process, it can do all of the above
164 without using a FUSE mount, the same criteria as used in
165 ptrace can be used to check if a process is allowed to access
166 the filesystem or not.
167
168 Note that the ptrace check is not strictly necessary to
169 prevent B/2/i, it is enough to check if mount owner has enough
170 privilege to send signal to the process accessing the
171 filesystem, since SIGSTOP can be used to get a similar effect.
172
173I think these limitations are unacceptable?
174~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175
176If a sysadmin trusts the users enough, or can ensure through other
177measures, that system processes will never enter non-privileged
178mounts, it can relax the last limitation with a "user_allow_other"
179config option. If this config option is set, the mounting user can
180add the "allow_other" mount option which disables the check for other
181users' processes.
182
183Kernel - userspace interface
184~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186The following diagram shows how a filesystem operation (in this
187example unlink) is performed in FUSE.
188
189NOTE: everything in this description is greatly simplified
190
191 | "rm /mnt/fuse/file" | FUSE filesystem daemon
192 | |
193 | | >sys_read()
194 | | >fuse_dev_read()
195 | | >request_wait()
196 | | [sleep on fc->waitq]
197 | |
198 | >sys_unlink() |
199 | >fuse_unlink() |
200 | [get request from |
201 | fc->unused_list] |
202 | >request_send() |
203 | [queue req on fc->pending] |
204 | [wake up fc->waitq] | [woken up]
205 | >request_wait_answer() |
206 | [sleep on req->waitq] |
207 | | <request_wait()
208 | | [remove req from fc->pending]
209 | | [copy req to read buffer]
210 | | [add req to fc->processing]
211 | | <fuse_dev_read()
212 | | <sys_read()
213 | |
214 | | [perform unlink]
215 | |
216 | | >sys_write()
217 | | >fuse_dev_write()
218 | | [look up req in fc->processing]
219 | | [remove from fc->processing]
220 | | [copy write buffer to req]
221 | [woken up] | [wake up req->waitq]
222 | | <fuse_dev_write()
223 | | <sys_write()
224 | <request_wait_answer() |
225 | <request_send() |
226 | [add request to |
227 | fc->unused_list] |
228 | <fuse_unlink() |
229 | <sys_unlink() |
230
231There are a couple of ways in which to deadlock a FUSE filesystem.
232Since we are talking about unprivileged userspace programs,
233something must be done about these.
234
235Scenario 1 - Simple deadlock
236-----------------------------
237
238 | "rm /mnt/fuse/file" | FUSE filesystem daemon
239 | |
240 | >sys_unlink("/mnt/fuse/file") |
241 | [acquire inode semaphore |
242 | for "file"] |
243 | >fuse_unlink() |
244 | [sleep on req->waitq] |
245 | | <sys_read()
246 | | >sys_unlink("/mnt/fuse/file")
247 | | [acquire inode semaphore
248 | | for "file"]
249 | | *DEADLOCK*
250
251The solution for this is to allow requests to be interrupted while
252they are in userspace:
253
254 | [interrupted by signal] |
255 | <fuse_unlink() |
256 | [release semaphore] | [semaphore acquired]
257 | <sys_unlink() |
258 | | >fuse_unlink()
259 | | [queue req on fc->pending]
260 | | [wake up fc->waitq]
261 | | [sleep on req->waitq]
262
263If the filesystem daemon was single threaded, this will stop here,
264since there's no other thread to dequeue and execute the request.
265In this case the solution is to kill the FUSE daemon as well. If
266there are multiple serving threads, you just have to kill them as
267long as any remain.
268
269Moral: a filesystem which deadlocks, can soon find itself dead.
270
271Scenario 2 - Tricky deadlock
272----------------------------
273
274This one needs a carefully crafted filesystem. It's a variation on
275the above, only the call back to the filesystem is not explicit,
276but is caused by a pagefault.
277
278 | Kamikaze filesystem thread 1 | Kamikaze filesystem thread 2
279 | |
280 | [fd = open("/mnt/fuse/file")] | [request served normally]
281 | [mmap fd to 'addr'] |
282 | [close fd] | [FLUSH triggers 'magic' flag]
283 | [read a byte from addr] |
284 | >do_page_fault() |
285 | [find or create page] |
286 | [lock page] |
287 | >fuse_readpage() |
288 | [queue READ request] |
289 | [sleep on req->waitq] |
290 | | [read request to buffer]
291 | | [create reply header before addr]
292 | | >sys_write(addr - headerlength)
293 | | >fuse_dev_write()
294 | | [look up req in fc->processing]
295 | | [remove from fc->processing]
296 | | [copy write buffer to req]
297 | | >do_page_fault()
298 | | [find or create page]
299 | | [lock page]
300 | | * DEADLOCK *
301
302Solution is again to let the the request be interrupted (not
303elaborated further).
304
305An additional problem is that while the write buffer is being
306copied to the request, the request must not be interrupted. This
307is because the destination address of the copy may not be valid
308after the request is interrupted.
309
310This is solved with doing the copy atomically, and allowing
311interruption while the page(s) belonging to the write buffer are
312faulted with get_user_pages(). The 'req->locked' flag indicates
313when the copy is taking place, and interruption is delayed until
314this flag is unset.
315
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
index eef4aca0c753..a5fbc8e897fa 100644
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -439,6 +439,18 @@ ChangeLog
439 439
440Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. 440Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
441 441
4422.1.24:
443 - Support journals ($LogFile) which have been modified by chkdsk. This
444 means users can boot into Windows after we marked the volume dirty.
445 The Windows boot will run chkdsk and then reboot. The user can then
446 immediately boot into Linux rather than having to do a full Windows
447 boot first before rebooting into Linux and we will recognize such a
448 journal and empty it as it is clean by definition.
449 - Support journals ($LogFile) with only one restart page as well as
450 journals with two different restart pages. We sanity check both and
451 either use the only sane one or the more recent one of the two in the
452 case that both are valid.
453 - Lots of bug fixes and enhancements across the board.
4422.1.23: 4542.1.23:
443 - Stamp the user space journal, aka transaction log, aka $UsnJrnl, if 455 - Stamp the user space journal, aka transaction log, aka $UsnJrnl, if
444 it is present and active thus telling Windows and applications using 456 it is present and active thus telling Windows and applications using
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 5024ba7a592c..d4773565ea2f 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1241,16 +1241,38 @@ swap-intensive.
1241overcommit_memory 1241overcommit_memory
1242----------------- 1242-----------------
1243 1243
1244This file contains one value. The following algorithm is used to decide if 1244Controls overcommit of system memory, possibly allowing processes
1245there's enough memory: if the value of overcommit_memory is positive, then 1245to allocate (but not use) more memory than is actually available.
1246there's always enough memory. This is a useful feature, since programs often 1246
1247malloc() huge amounts of memory 'just in case', while they only use a small 1247
1248part of it. Leaving this value at 0 will lead to the failure of such a huge 12480 - Heuristic overcommit handling. Obvious overcommits of
1249malloc(), when in fact the system has enough memory for the program to run. 1249 address space are refused. Used for a typical system. It
1250 1250 ensures a seriously wild allocation fails while allowing
1251On the other hand, enabling this feature can cause you to run out of memory 1251 overcommit to reduce swap usage. root is allowed to
1252and thrash the system to death, so large and/or important servers will want to 1252 allocate slighly more memory in this mode. This is the
1253set this value to 0. 1253 default.
1254
12551 - Always overcommit. Appropriate for some scientific
1256 applications.
1257
12582 - Don't overcommit. The total address space commit
1259 for the system is not permitted to exceed swap plus a
1260 configurable percentage (default is 50) of physical RAM.
1261 Depending on the percentage you use, in most situations
1262 this means a process will not be killed while attempting
1263 to use already-allocated memory but will receive errors
1264 on memory allocation as appropriate.
1265
1266overcommit_ratio
1267----------------
1268
1269Percentage of physical memory size to include in overcommit calculations
1270(see above.)
1271
1272Memory allocation limit = swapspace + physmem * (overcommit_ratio / 100)
1273
1274 swapspace = total size of all swap areas
1275 physmem = size of physical memory in system
1254 1276
1255nr_hugepages and hugetlb_shm_group 1277nr_hugepages and hugetlb_shm_group
1256---------------------------------- 1278----------------------------------
diff --git a/Documentation/filesystems/v9fs.txt b/Documentation/filesystems/v9fs.txt
new file mode 100644
index 000000000000..4e92feb6b507
--- /dev/null
+++ b/Documentation/filesystems/v9fs.txt
@@ -0,0 +1,95 @@
1 V9FS: 9P2000 for Linux
2 ======================
3
4ABOUT
5=====
6
7v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol.
8
9This software was originally developed by Ron Minnich <rminnich@lanl.gov>
10and Maya Gokhale <maya@lanl.gov>. Additional development by Greg Watson
11<gwatson@lanl.gov> and most recently Eric Van Hensbergen
12<ericvh@gmail.com> and Latchesar Ionkov <lucho@ionkov.net>.
13
14USAGE
15=====
16
17For remote file server:
18
19 mount -t 9P 10.10.1.2 /mnt/9
20
21For Plan 9 From User Space applications (http://swtch.com/plan9)
22
23 mount -t 9P `namespace`/acme /mnt/9 -o proto=unix,name=$USER
24
25OPTIONS
26=======
27
28 proto=name select an alternative transport. Valid options are
29 currently:
30 unix - specifying a named pipe mount point
31 tcp - specifying a normal TCP/IP connection
32 fd - used passed file descriptors for connection
33 (see rfdno and wfdno)
34
35 name=name user name to attempt mount as on the remote server. The
36 server may override or ignore this value. Certain user
37 names may require authentication.
38
39 aname=name aname specifies the file tree to access when the server is
40 offering several exported file systems.
41
42 debug=n specifies debug level. The debug level is a bitmask.
43 0x01 = display verbose error messages
44 0x02 = developer debug (DEBUG_CURRENT)
45 0x04 = display 9P trace
46 0x08 = display VFS trace
47 0x10 = display Marshalling debug
48 0x20 = display RPC debug
49 0x40 = display transport debug
50 0x80 = display allocation debug
51
52 rfdno=n the file descriptor for reading with proto=fd
53
54 wfdno=n the file descriptor for writing with proto=fd
55
56 maxdata=n the number of bytes to use for 9P packet payload (msize)
57
58 port=n port to connect to on the remote server
59
60 timeout=n request timeouts (in ms) (default 60000ms)
61
62 noextend force legacy mode (no 9P2000.u semantics)
63
64 uid attempt to mount as a particular uid
65
66 gid attempt to mount with a particular gid
67
68 afid security channel - used by Plan 9 authentication protocols
69
70 nodevmap do not map special files - represent them as normal files.
71 This can be used to share devices/named pipes/sockets between
72 hosts. This functionality will be expanded in later versions.
73
74RESOURCES
75=========
76
77The Linux version of the 9P server, along with some client-side utilities
78can be found at http://v9fs.sf.net (along with a CVS repository of the
79development branch of this module). There are user and developer mailing
80lists here, as well as a bug-tracker.
81
82For more information on the Plan 9 Operating System check out
83http://plan9.bell-labs.com/plan9
84
85For information on Plan 9 from User Space (Plan 9 applications and libraries
86ported to Linux/BSD/OSX/etc) check out http://swtch.com/plan9
87
88
89STATUS
90======
91
92The 2.6 kernel support is working on PPC and x86.
93
94PLEASE USE THE SOURCEFORGE BUG-TRACKER TO REPORT PROBLEMS.
95
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 3f318dd44c77..f042c12e0ed2 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -1,35 +1,27 @@
1/* -*- auto-fill -*- */
2 1
3 Overview of the Virtual File System 2 Overview of the Linux Virtual File System
4 3
5 Richard Gooch <rgooch@atnf.csiro.au> 4 Original author: Richard Gooch <rgooch@atnf.csiro.au>
6 5
7 5-JUL-1999 6 Last updated on August 25, 2005
8 7
8 Copyright (C) 1999 Richard Gooch
9 Copyright (C) 2005 Pekka Enberg
9 10
10Conventions used in this document <section> 11 This file is released under the GPLv2.
11=================================
12 12
13Each section in this document will have the string "<section>" at the
14right-hand side of the section title. Each subsection will have
15"<subsection>" at the right-hand side. These strings are meant to make
16it easier to search through the document.
17 13
18NOTE that the master copy of this document is available online at: 14What is it?
19http://www.atnf.csiro.au/~rgooch/linux/docs/vfs.txt
20
21
22What is it? <section>
23=========== 15===========
24 16
25The Virtual File System (otherwise known as the Virtual Filesystem 17The Virtual File System (otherwise known as the Virtual Filesystem
26Switch) is the software layer in the kernel that provides the 18Switch) is the software layer in the kernel that provides the
27filesystem interface to userspace programs. It also provides an 19filesystem interface to userspace programs. It also provides an
28abstraction within the kernel which allows different filesystem 20abstraction within the kernel which allows different filesystem
29implementations to co-exist. 21implementations to coexist.
30 22
31 23
32A Quick Look At How It Works <section> 24A Quick Look At How It Works
33============================ 25============================
34 26
35In this section I'll briefly describe how things work, before 27In this section I'll briefly describe how things work, before
@@ -38,7 +30,8 @@ when user programs open and manipulate files, and then look from the
38other view which is how a filesystem is supported and subsequently 30other view which is how a filesystem is supported and subsequently
39mounted. 31mounted.
40 32
41Opening a File <subsection> 33
34Opening a File
42-------------- 35--------------
43 36
44The VFS implements the open(2), stat(2), chmod(2) and similar system 37The VFS implements the open(2), stat(2), chmod(2) and similar system
@@ -77,7 +70,7 @@ back to userspace.
77 70
78Opening a file requires another operation: allocation of a file 71Opening a file requires another operation: allocation of a file
79structure (this is the kernel-side implementation of file 72structure (this is the kernel-side implementation of file
80descriptors). The freshly allocated file structure is initialised with 73descriptors). The freshly allocated file structure is initialized with
81a pointer to the dentry and a set of file operation member functions. 74a pointer to the dentry and a set of file operation member functions.
82These are taken from the inode data. The open() file method is then 75These are taken from the inode data. The open() file method is then
83called so the specific filesystem implementation can do it's work. You 76called so the specific filesystem implementation can do it's work. You
@@ -102,7 +95,8 @@ filesystem or driver code at the same time, on different
102processors. You should ensure that access to shared resources is 95processors. You should ensure that access to shared resources is
103protected by appropriate locks. 96protected by appropriate locks.
104 97
105Registering and Mounting a Filesystem <subsection> 98
99Registering and Mounting a Filesystem
106------------------------------------- 100-------------------------------------
107 101
108If you want to support a new kind of filesystem in the kernel, all you 102If you want to support a new kind of filesystem in the kernel, all you
@@ -123,17 +117,21 @@ updated to point to the root inode for the new filesystem.
123It's now time to look at things in more detail. 117It's now time to look at things in more detail.
124 118
125 119
126struct file_system_type <section> 120struct file_system_type
127======================= 121=======================
128 122
129This describes the filesystem. As of kernel 2.1.99, the following 123This describes the filesystem. As of kernel 2.6.13, the following
130members are defined: 124members are defined:
131 125
132struct file_system_type { 126struct file_system_type {
133 const char *name; 127 const char *name;
134 int fs_flags; 128 int fs_flags;
135 struct super_block *(*read_super) (struct super_block *, void *, int); 129 struct super_block *(*get_sb) (struct file_system_type *, int,
136 struct file_system_type * next; 130 const char *, void *);
131 void (*kill_sb) (struct super_block *);
132 struct module *owner;
133 struct file_system_type * next;
134 struct list_head fs_supers;
137}; 135};
138 136
139 name: the name of the filesystem type, such as "ext2", "iso9660", 137 name: the name of the filesystem type, such as "ext2", "iso9660",
@@ -141,51 +139,97 @@ struct file_system_type {
141 139
142 fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.) 140 fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
143 141
144 read_super: the method to call when a new instance of this 142 get_sb: the method to call when a new instance of this
145 filesystem should be mounted 143 filesystem should be mounted
146 144
147 next: for internal VFS use: you should initialise this to NULL 145 kill_sb: the method to call when an instance of this filesystem
146 should be unmounted
147
148 owner: for internal VFS use: you should initialize this to THIS_MODULE in
149 most cases.
148 150
149The read_super() method has the following arguments: 151 next: for internal VFS use: you should initialize this to NULL
152
153The get_sb() method has the following arguments:
150 154
151 struct super_block *sb: the superblock structure. This is partially 155 struct super_block *sb: the superblock structure. This is partially
152 initialised by the VFS and the rest must be initialised by the 156 initialized by the VFS and the rest must be initialized by the
153 read_super() method 157 get_sb() method
158
159 int flags: mount flags
160
161 const char *dev_name: the device name we are mounting.
154 162
155 void *data: arbitrary mount options, usually comes as an ASCII 163 void *data: arbitrary mount options, usually comes as an ASCII
156 string 164 string
157 165
158 int silent: whether or not to be silent on error 166 int silent: whether or not to be silent on error
159 167
160The read_super() method must determine if the block device specified 168The get_sb() method must determine if the block device specified
161in the superblock contains a filesystem of the type the method 169in the superblock contains a filesystem of the type the method
162supports. On success the method returns the superblock pointer, on 170supports. On success the method returns the superblock pointer, on
163failure it returns NULL. 171failure it returns NULL.
164 172
165The most interesting member of the superblock structure that the 173The most interesting member of the superblock structure that the
166read_super() method fills in is the "s_op" field. This is a pointer to 174get_sb() method fills in is the "s_op" field. This is a pointer to
167a "struct super_operations" which describes the next level of the 175a "struct super_operations" which describes the next level of the
168filesystem implementation. 176filesystem implementation.
169 177
178Usually, a filesystem uses generic one of the generic get_sb()
179implementations and provides a fill_super() method instead. The
180generic methods are:
181
182 get_sb_bdev: mount a filesystem residing on a block device
170 183
171struct super_operations <section> 184 get_sb_nodev: mount a filesystem that is not backed by a device
185
186 get_sb_single: mount a filesystem which shares the instance between
187 all mounts
188
189A fill_super() method implementation has the following arguments:
190
191 struct super_block *sb: the superblock structure. The method fill_super()
192 must initialize this properly.
193
194 void *data: arbitrary mount options, usually comes as an ASCII
195 string
196
197 int silent: whether or not to be silent on error
198
199
200struct super_operations
172======================= 201=======================
173 202
174This describes how the VFS can manipulate the superblock of your 203This describes how the VFS can manipulate the superblock of your
175filesystem. As of kernel 2.1.99, the following members are defined: 204filesystem. As of kernel 2.6.13, the following members are defined:
176 205
177struct super_operations { 206struct super_operations {
178 void (*read_inode) (struct inode *); 207 struct inode *(*alloc_inode)(struct super_block *sb);
179 int (*write_inode) (struct inode *, int); 208 void (*destroy_inode)(struct inode *);
180 void (*put_inode) (struct inode *); 209
181 void (*drop_inode) (struct inode *); 210 void (*read_inode) (struct inode *);
182 void (*delete_inode) (struct inode *); 211
183 int (*notify_change) (struct dentry *, struct iattr *); 212 void (*dirty_inode) (struct inode *);
184 void (*put_super) (struct super_block *); 213 int (*write_inode) (struct inode *, int);
185 void (*write_super) (struct super_block *); 214 void (*put_inode) (struct inode *);
186 int (*statfs) (struct super_block *, struct statfs *, int); 215 void (*drop_inode) (struct inode *);
187 int (*remount_fs) (struct super_block *, int *, char *); 216 void (*delete_inode) (struct inode *);
188 void (*clear_inode) (struct inode *); 217 void (*put_super) (struct super_block *);
218 void (*write_super) (struct super_block *);
219 int (*sync_fs)(struct super_block *sb, int wait);
220 void (*write_super_lockfs) (struct super_block *);
221 void (*unlockfs) (struct super_block *);
222 int (*statfs) (struct super_block *, struct kstatfs *);
223 int (*remount_fs) (struct super_block *, int *, char *);
224 void (*clear_inode) (struct inode *);
225 void (*umount_begin) (struct super_block *);
226
227 void (*sync_inodes) (struct super_block *sb,
228 struct writeback_control *wbc);
229 int (*show_options)(struct seq_file *, struct vfsmount *);
230
231 ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
232 ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
189}; 233};
190 234
191All methods are called without any locks being held, unless otherwise 235All methods are called without any locks being held, unless otherwise
@@ -193,43 +237,62 @@ noted. This means that most methods can block safely. All methods are
193only called from a process context (i.e. not from an interrupt handler 237only called from a process context (i.e. not from an interrupt handler
194or bottom half). 238or bottom half).
195 239
240 alloc_inode: this method is called by inode_alloc() to allocate memory
241 for struct inode and initialize it.
242
243 destroy_inode: this method is called by destroy_inode() to release
244 resources allocated for struct inode.
245
196 read_inode: this method is called to read a specific inode from the 246 read_inode: this method is called to read a specific inode from the
197 mounted filesystem. The "i_ino" member in the "struct inode" 247 mounted filesystem. The i_ino member in the struct inode is
198 will be initialised by the VFS to indicate which inode to 248 initialized by the VFS to indicate which inode to read. Other
199 read. Other members are filled in by this method 249 members are filled in by this method.
250
251 You can set this to NULL and use iget5_locked() instead of iget()
252 to read inodes. This is necessary for filesystems for which the
253 inode number is not sufficient to identify an inode.
254
255 dirty_inode: this method is called by the VFS to mark an inode dirty.
200 256
201 write_inode: this method is called when the VFS needs to write an 257 write_inode: this method is called when the VFS needs to write an
202 inode to disc. The second parameter indicates whether the write 258 inode to disc. The second parameter indicates whether the write
203 should be synchronous or not, not all filesystems check this flag. 259 should be synchronous or not, not all filesystems check this flag.
204 260
205 put_inode: called when the VFS inode is removed from the inode 261 put_inode: called when the VFS inode is removed from the inode
206 cache. This method is optional 262 cache.
207 263
208 drop_inode: called when the last access to the inode is dropped, 264 drop_inode: called when the last access to the inode is dropped,
209 with the inode_lock spinlock held. 265 with the inode_lock spinlock held.
210 266
211 This method should be either NULL (normal unix filesystem 267 This method should be either NULL (normal UNIX filesystem
212 semantics) or "generic_delete_inode" (for filesystems that do not 268 semantics) or "generic_delete_inode" (for filesystems that do not
213 want to cache inodes - causing "delete_inode" to always be 269 want to cache inodes - causing "delete_inode" to always be
214 called regardless of the value of i_nlink) 270 called regardless of the value of i_nlink)
215 271
216 The "generic_delete_inode()" behaviour is equivalent to the 272 The "generic_delete_inode()" behavior is equivalent to the
217 old practice of using "force_delete" in the put_inode() case, 273 old practice of using "force_delete" in the put_inode() case,
218 but does not have the races that the "force_delete()" approach 274 but does not have the races that the "force_delete()" approach
219 had. 275 had.
220 276
221 delete_inode: called when the VFS wants to delete an inode 277 delete_inode: called when the VFS wants to delete an inode
222 278
223 notify_change: called when VFS inode attributes are changed. If this
224 is NULL the VFS falls back to the write_inode() method. This
225 is called with the kernel lock held
226
227 put_super: called when the VFS wishes to free the superblock 279 put_super: called when the VFS wishes to free the superblock
228 (i.e. unmount). This is called with the superblock lock held 280 (i.e. unmount). This is called with the superblock lock held
229 281
230 write_super: called when the VFS superblock needs to be written to 282 write_super: called when the VFS superblock needs to be written to
231 disc. This method is optional 283 disc. This method is optional
232 284
285 sync_fs: called when VFS is writing out all dirty data associated with
286 a superblock. The second parameter indicates whether the method
287 should wait until the write out has been completed. Optional.
288
289 write_super_lockfs: called when VFS is locking a filesystem and forcing
290 it into a consistent state. This function is currently used by the
291 Logical Volume Manager (LVM).
292
293 unlockfs: called when VFS is unlocking a filesystem and making it writable
294 again.
295
233 statfs: called when the VFS needs to get filesystem statistics. This 296 statfs: called when the VFS needs to get filesystem statistics. This
234 is called with the kernel lock held 297 is called with the kernel lock held
235 298
@@ -238,21 +301,31 @@ or bottom half).
238 301
239 clear_inode: called then the VFS clears the inode. Optional 302 clear_inode: called then the VFS clears the inode. Optional
240 303
304 umount_begin: called when the VFS is unmounting a filesystem.
305
306 sync_inodes: called when the VFS is writing out dirty data associated with
307 a superblock.
308
309 show_options: called by the VFS to show mount options for /proc/<pid>/mounts.
310
311 quota_read: called by the VFS to read from filesystem quota file.
312
313 quota_write: called by the VFS to write to filesystem quota file.
314
241The read_inode() method is responsible for filling in the "i_op" 315The read_inode() method is responsible for filling in the "i_op"
242field. This is a pointer to a "struct inode_operations" which 316field. This is a pointer to a "struct inode_operations" which
243describes the methods that can be performed on individual inodes. 317describes the methods that can be performed on individual inodes.
244 318
245 319
246struct inode_operations <section> 320struct inode_operations
247======================= 321=======================
248 322
249This describes how the VFS can manipulate an inode in your 323This describes how the VFS can manipulate an inode in your
250filesystem. As of kernel 2.1.99, the following members are defined: 324filesystem. As of kernel 2.6.13, the following members are defined:
251 325
252struct inode_operations { 326struct inode_operations {
253 struct file_operations * default_file_ops; 327 int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
254 int (*create) (struct inode *,struct dentry *,int); 328 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
255 int (*lookup) (struct inode *,struct dentry *);
256 int (*link) (struct dentry *,struct inode *,struct dentry *); 329 int (*link) (struct dentry *,struct inode *,struct dentry *);
257 int (*unlink) (struct inode *,struct dentry *); 330 int (*unlink) (struct inode *,struct dentry *);
258 int (*symlink) (struct inode *,struct dentry *,const char *); 331 int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -261,25 +334,22 @@ struct inode_operations {
261 int (*mknod) (struct inode *,struct dentry *,int,dev_t); 334 int (*mknod) (struct inode *,struct dentry *,int,dev_t);
262 int (*rename) (struct inode *, struct dentry *, 335 int (*rename) (struct inode *, struct dentry *,
263 struct inode *, struct dentry *); 336 struct inode *, struct dentry *);
264 int (*readlink) (struct dentry *, char *,int); 337 int (*readlink) (struct dentry *, char __user *,int);
265 struct dentry * (*follow_link) (struct dentry *, struct dentry *); 338 void * (*follow_link) (struct dentry *, struct nameidata *);
266 int (*readpage) (struct file *, struct page *); 339 void (*put_link) (struct dentry *, struct nameidata *, void *);
267 int (*writepage) (struct page *page, struct writeback_control *wbc);
268 int (*bmap) (struct inode *,int);
269 void (*truncate) (struct inode *); 340 void (*truncate) (struct inode *);
270 int (*permission) (struct inode *, int); 341 int (*permission) (struct inode *, int, struct nameidata *);
271 int (*smap) (struct inode *,int); 342 int (*setattr) (struct dentry *, struct iattr *);
272 int (*updatepage) (struct file *, struct page *, const char *, 343 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
273 unsigned long, unsigned int, int); 344 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
274 int (*revalidate) (struct dentry *); 345 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
346 ssize_t (*listxattr) (struct dentry *, char *, size_t);
347 int (*removexattr) (struct dentry *, const char *);
275}; 348};
276 349
277Again, all methods are called without any locks being held, unless 350Again, all methods are called without any locks being held, unless
278otherwise noted. 351otherwise noted.
279 352
280 default_file_ops: this is a pointer to a "struct file_operations"
281 which describes how to open and then manipulate open files
282
283 create: called by the open(2) and creat(2) system calls. Only 353 create: called by the open(2) and creat(2) system calls. Only
284 required if you want to support regular files. The dentry you 354 required if you want to support regular files. The dentry you
285 get should not have an inode (i.e. it should be a negative 355 get should not have an inode (i.e. it should be a negative
@@ -328,31 +398,143 @@ otherwise noted.
328 you want to support reading symbolic links 398 you want to support reading symbolic links
329 399
330 follow_link: called by the VFS to follow a symbolic link to the 400 follow_link: called by the VFS to follow a symbolic link to the
331 inode it points to. Only required if you want to support 401 inode it points to. Only required if you want to support
332 symbolic links 402 symbolic links. This function returns a void pointer cookie
403 that is passed to put_link().
404
405 put_link: called by the VFS to release resources allocated by
406 follow_link(). The cookie returned by follow_link() is passed to
407 to this function as the last parameter. It is used by filesystems
408 such as NFS where page cache is not stable (i.e. page that was
409 installed when the symbolic link walk started might not be in the
410 page cache at the end of the walk).
411
412 truncate: called by the VFS to change the size of a file. The i_size
413 field of the inode is set to the desired size by the VFS before
414 this function is called. This function is called by the truncate(2)
415 system call and related functionality.
416
417 permission: called by the VFS to check for access rights on a POSIX-like
418 filesystem.
419
420 setattr: called by the VFS to set attributes for a file. This function is
421 called by chmod(2) and related system calls.
422
423 getattr: called by the VFS to get attributes of a file. This function is
424 called by stat(2) and related system calls.
425
426 setxattr: called by the VFS to set an extended attribute for a file.
427 Extended attribute is a name:value pair associated with an inode. This
428 function is called by setxattr(2) system call.
429
430 getxattr: called by the VFS to retrieve the value of an extended attribute
431 name. This function is called by getxattr(2) function call.
432
433 listxattr: called by the VFS to list all extended attributes for a given
434 file. This function is called by listxattr(2) system call.
435
436 removexattr: called by the VFS to remove an extended attribute from a file.
437 This function is called by removexattr(2) system call.
438
439
440struct address_space_operations
441===============================
442
443This describes how the VFS can manipulate mapping of a file to page cache in
444your filesystem. As of kernel 2.6.13, the following members are defined:
445
446struct address_space_operations {
447 int (*writepage)(struct page *page, struct writeback_control *wbc);
448 int (*readpage)(struct file *, struct page *);
449 int (*sync_page)(struct page *);
450 int (*writepages)(struct address_space *, struct writeback_control *);
451 int (*set_page_dirty)(struct page *page);
452 int (*readpages)(struct file *filp, struct address_space *mapping,
453 struct list_head *pages, unsigned nr_pages);
454 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
455 int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
456 sector_t (*bmap)(struct address_space *, sector_t);
457 int (*invalidatepage) (struct page *, unsigned long);
458 int (*releasepage) (struct page *, int);
459 ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
460 loff_t offset, unsigned long nr_segs);
461 struct page* (*get_xip_page)(struct address_space *, sector_t,
462 int);
463};
464
465 writepage: called by the VM write a dirty page to backing store.
466
467 readpage: called by the VM to read a page from backing store.
468
469 sync_page: called by the VM to notify the backing store to perform all
470 queued I/O operations for a page. I/O operations for other pages
471 associated with this address_space object may also be performed.
472
473 writepages: called by the VM to write out pages associated with the
474 address_space object.
475
476 set_page_dirty: called by the VM to set a page dirty.
477
478 readpages: called by the VM to read pages associated with the address_space
479 object.
333 480
481 prepare_write: called by the generic write path in VM to set up a write
482 request for a page.
334 483
335struct file_operations <section> 484 commit_write: called by the generic write path in VM to write page to
485 its backing store.
486
487 bmap: called by the VFS to map a logical block offset within object to
488 physical block number. This method is use by for the legacy FIBMAP
489 ioctl. Other uses are discouraged.
490
491 invalidatepage: called by the VM on truncate to disassociate a page from its
492 address_space mapping.
493
494 releasepage: called by the VFS to release filesystem specific metadata from
495 a page.
496
497 direct_IO: called by the VM for direct I/O writes and reads.
498
499 get_xip_page: called by the VM to translate a block number to a page.
500 The page is valid until the corresponding filesystem is unmounted.
501 Filesystems that want to use execute-in-place (XIP) need to implement
502 it. An example implementation can be found in fs/ext2/xip.c.
503
504
505struct file_operations
336====================== 506======================
337 507
338This describes how the VFS can manipulate an open file. As of kernel 508This describes how the VFS can manipulate an open file. As of kernel
3392.1.99, the following members are defined: 5092.6.13, the following members are defined:
340 510
341struct file_operations { 511struct file_operations {
342 loff_t (*llseek) (struct file *, loff_t, int); 512 loff_t (*llseek) (struct file *, loff_t, int);
343 ssize_t (*read) (struct file *, char *, size_t, loff_t *); 513 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
344 ssize_t (*write) (struct file *, const char *, size_t, loff_t *); 514 ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
515 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
516 ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
345 int (*readdir) (struct file *, void *, filldir_t); 517 int (*readdir) (struct file *, void *, filldir_t);
346 unsigned int (*poll) (struct file *, struct poll_table_struct *); 518 unsigned int (*poll) (struct file *, struct poll_table_struct *);
347 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); 519 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
520 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
521 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
348 int (*mmap) (struct file *, struct vm_area_struct *); 522 int (*mmap) (struct file *, struct vm_area_struct *);
349 int (*open) (struct inode *, struct file *); 523 int (*open) (struct inode *, struct file *);
524 int (*flush) (struct file *);
350 int (*release) (struct inode *, struct file *); 525 int (*release) (struct inode *, struct file *);
351 int (*fsync) (struct file *, struct dentry *); 526 int (*fsync) (struct file *, struct dentry *, int datasync);
352 int (*fasync) (struct file *, int); 527 int (*aio_fsync) (struct kiocb *, int datasync);
353 int (*check_media_change) (kdev_t dev); 528 int (*fasync) (int, struct file *, int);
354 int (*revalidate) (kdev_t dev);
355 int (*lock) (struct file *, int, struct file_lock *); 529 int (*lock) (struct file *, int, struct file_lock *);
530 ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
531 ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
532 ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
533 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
534 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
535 int (*check_flags)(int);
536 int (*dir_notify)(struct file *filp, unsigned long arg);
537 int (*flock) (struct file *, int, struct file_lock *);
356}; 538};
357 539
358Again, all methods are called without any locks being held, unless 540Again, all methods are called without any locks being held, unless
@@ -362,8 +544,12 @@ otherwise noted.
362 544
363 read: called by read(2) and related system calls 545 read: called by read(2) and related system calls
364 546
547 aio_read: called by io_submit(2) and other asynchronous I/O operations
548
365 write: called by write(2) and related system calls 549 write: called by write(2) and related system calls
366 550
551 aio_write: called by io_submit(2) and other asynchronous I/O operations
552
367 readdir: called when the VFS needs to read the directory contents 553 readdir: called when the VFS needs to read the directory contents
368 554
369 poll: called by the VFS when a process wants to check if there is 555 poll: called by the VFS when a process wants to check if there is
@@ -372,18 +558,25 @@ otherwise noted.
372 558
373 ioctl: called by the ioctl(2) system call 559 ioctl: called by the ioctl(2) system call
374 560
561 unlocked_ioctl: called by the ioctl(2) system call. Filesystems that do not
562 require the BKL should use this method instead of the ioctl() above.
563
564 compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
565 are used on 64 bit kernels.
566
375 mmap: called by the mmap(2) system call 567 mmap: called by the mmap(2) system call
376 568
377 open: called by the VFS when an inode should be opened. When the VFS 569 open: called by the VFS when an inode should be opened. When the VFS
378 opens a file, it creates a new "struct file" and initialises 570 opens a file, it creates a new "struct file". It then calls the
379 the "f_op" file operations member with the "default_file_ops" 571 open method for the newly allocated file structure. You might
380 field in the inode structure. It then calls the open method 572 think that the open method really belongs in
381 for the newly allocated file structure. You might think that 573 "struct inode_operations", and you may be right. I think it's
382 the open method really belongs in "struct inode_operations", 574 done the way it is because it makes filesystems simpler to
383 and you may be right. I think it's done the way it is because 575 implement. The open() method is a good place to initialize the
384 it makes filesystems simpler to implement. The open() method 576 "private_data" member in the file structure if you want to point
385 is a good place to initialise the "private_data" member in the 577 to a device structure
386 file structure if you want to point to a device structure 578
579 flush: called by the close(2) system call to flush a file
387 580
388 release: called when the last reference to an open file is closed 581 release: called when the last reference to an open file is closed
389 582
@@ -392,6 +585,23 @@ otherwise noted.
392 fasync: called by the fcntl(2) system call when asynchronous 585 fasync: called by the fcntl(2) system call when asynchronous
393 (non-blocking) mode is enabled for a file 586 (non-blocking) mode is enabled for a file
394 587
588 lock: called by the fcntl(2) system call for F_GETLK, F_SETLK, and F_SETLKW
589 commands
590
591 readv: called by the readv(2) system call
592
593 writev: called by the writev(2) system call
594
595 sendfile: called by the sendfile(2) system call
596
597 get_unmapped_area: called by the mmap(2) system call
598
599 check_flags: called by the fcntl(2) system call for F_SETFL command
600
601 dir_notify: called by the fcntl(2) system call for F_NOTIFY command
602
603 flock: called by the flock(2) system call
604
395Note that the file operations are implemented by the specific 605Note that the file operations are implemented by the specific
396filesystem in which the inode resides. When opening a device node 606filesystem in which the inode resides. When opening a device node
397(character or block special) most filesystems will call special 607(character or block special) most filesystems will call special
@@ -400,29 +610,28 @@ driver information. These support routines replace the filesystem file
400operations with those for the device driver, and then proceed to call 610operations with those for the device driver, and then proceed to call
401the new open() method for the file. This is how opening a device file 611the new open() method for the file. This is how opening a device file
402in the filesystem eventually ends up calling the device driver open() 612in the filesystem eventually ends up calling the device driver open()
403method. Note the devfs (the Device FileSystem) has a more direct path 613method.
404from device node to device driver (this is an unofficial kernel
405patch).
406 614
407 615
408Directory Entry Cache (dcache) <section> 616Directory Entry Cache (dcache)
409------------------------------ 617==============================
618
410 619
411struct dentry_operations 620struct dentry_operations
412======================== 621------------------------
413 622
414This describes how a filesystem can overload the standard dentry 623This describes how a filesystem can overload the standard dentry
415operations. Dentries and the dcache are the domain of the VFS and the 624operations. Dentries and the dcache are the domain of the VFS and the
416individual filesystem implementations. Device drivers have no business 625individual filesystem implementations. Device drivers have no business
417here. These methods may be set to NULL, as they are either optional or 626here. These methods may be set to NULL, as they are either optional or
418the VFS uses a default. As of kernel 2.1.99, the following members are 627the VFS uses a default. As of kernel 2.6.13, the following members are
419defined: 628defined:
420 629
421struct dentry_operations { 630struct dentry_operations {
422 int (*d_revalidate)(struct dentry *); 631 int (*d_revalidate)(struct dentry *, struct nameidata *);
423 int (*d_hash) (struct dentry *, struct qstr *); 632 int (*d_hash) (struct dentry *, struct qstr *);
424 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); 633 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
425 void (*d_delete)(struct dentry *); 634 int (*d_delete)(struct dentry *);
426 void (*d_release)(struct dentry *); 635 void (*d_release)(struct dentry *);
427 void (*d_iput)(struct dentry *, struct inode *); 636 void (*d_iput)(struct dentry *, struct inode *);
428}; 637};
@@ -451,6 +660,7 @@ Each dentry has a pointer to its parent dentry, as well as a hash list
451of child dentries. Child dentries are basically like files in a 660of child dentries. Child dentries are basically like files in a
452directory. 661directory.
453 662
663
454Directory Entry Cache APIs 664Directory Entry Cache APIs
455-------------------------- 665--------------------------
456 666
@@ -471,7 +681,7 @@ manipulate dentries:
471 "d_delete" method is called 681 "d_delete" method is called
472 682
473 d_drop: this unhashes a dentry from its parents hash list. A 683 d_drop: this unhashes a dentry from its parents hash list. A
474 subsequent call to dput() will dellocate the dentry if its 684 subsequent call to dput() will deallocate the dentry if its
475 usage count drops to 0 685 usage count drops to 0
476 686
477 d_delete: delete a dentry. If there are no other open references to 687 d_delete: delete a dentry. If there are no other open references to
@@ -507,16 +717,16 @@ up by walking the tree starting with the first component
507of the pathname and using that dentry along with the next 717of the pathname and using that dentry along with the next
508component to look up the next level and so on. Since it 718component to look up the next level and so on. Since it
509is a frequent operation for workloads like multiuser 719is a frequent operation for workloads like multiuser
510environments and webservers, it is important to optimize 720environments and web servers, it is important to optimize
511this path. 721this path.
512 722
513Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus 723Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus
514in every component during path look-up. Since 2.5.10 onwards, 724in every component during path look-up. Since 2.5.10 onwards,
515fastwalk algorithm changed this by holding the dcache_lock 725fast-walk algorithm changed this by holding the dcache_lock
516at the beginning and walking as many cached path component 726at the beginning and walking as many cached path component
517dentries as possible. This signficantly decreases the number 727dentries as possible. This significantly decreases the number
518of acquisition of dcache_lock. However it also increases the 728of acquisition of dcache_lock. However it also increases the
519lock hold time signficantly and affects performance in large 729lock hold time significantly and affects performance in large
520SMP machines. Since 2.5.62 kernel, dcache has been using 730SMP machines. Since 2.5.62 kernel, dcache has been using
521a new locking model that uses RCU to make dcache look-up 731a new locking model that uses RCU to make dcache look-up
522lock-free. 732lock-free.
@@ -527,7 +737,7 @@ protected the hash chain, d_child, d_alias, d_lru lists as well
527as d_inode and several other things like mount look-up. RCU-based 737as d_inode and several other things like mount look-up. RCU-based
528changes affect only the way the hash chain is protected. For everything 738changes affect only the way the hash chain is protected. For everything
529else the dcache_lock must be taken for both traversing as well as 739else the dcache_lock must be taken for both traversing as well as
530updating. The hash chain updations too take the dcache_lock. 740updating. The hash chain updates too take the dcache_lock.
531The significant change is the way d_lookup traverses the hash chain, 741The significant change is the way d_lookup traverses the hash chain,
532it doesn't acquire the dcache_lock for this and rely on RCU to 742it doesn't acquire the dcache_lock for this and rely on RCU to
533ensure that the dentry has not been *freed*. 743ensure that the dentry has not been *freed*.
@@ -535,14 +745,15 @@ ensure that the dentry has not been *freed*.
535 745
536Dcache locking details 746Dcache locking details
537---------------------- 747----------------------
748
538For many multi-user workloads, open() and stat() on files are 749For many multi-user workloads, open() and stat() on files are
539very frequently occurring operations. Both involve walking 750very frequently occurring operations. Both involve walking
540of path names to find the dentry corresponding to the 751of path names to find the dentry corresponding to the
541concerned file. In 2.4 kernel, dcache_lock was held 752concerned file. In 2.4 kernel, dcache_lock was held
542during look-up of each path component. Contention and 753during look-up of each path component. Contention and
543cacheline bouncing of this global lock caused significant 754cache-line bouncing of this global lock caused significant
544scalability problems. With the introduction of RCU 755scalability problems. With the introduction of RCU
545in linux kernel, this was worked around by making 756in Linux kernel, this was worked around by making
546the look-up of path components during path walking lock-free. 757the look-up of path components during path walking lock-free.
547 758
548 759
@@ -562,7 +773,7 @@ Some of the important changes are :
5622. Insertion of a dentry into the hash table is done using 7732. Insertion of a dentry into the hash table is done using
563 hlist_add_head_rcu() which take care of ordering the writes - 774 hlist_add_head_rcu() which take care of ordering the writes -
564 the writes to the dentry must be visible before the dentry 775 the writes to the dentry must be visible before the dentry
565 is inserted. This works in conjuction with hlist_for_each_rcu() 776 is inserted. This works in conjunction with hlist_for_each_rcu()
566 while walking the hash chain. The only requirement is that 777 while walking the hash chain. The only requirement is that
567 all initialization to the dentry must be done before hlist_add_head_rcu() 778 all initialization to the dentry must be done before hlist_add_head_rcu()
568 since we don't have dcache_lock protection while traversing 779 since we don't have dcache_lock protection while traversing
@@ -584,7 +795,7 @@ Some of the important changes are :
584 the same. In some sense, dcache_rcu path walking looks like 795 the same. In some sense, dcache_rcu path walking looks like
585 the pre-2.5.10 version. 796 the pre-2.5.10 version.
586 797
5875. All dentry hash chain updations must take the dcache_lock as well as 7985. All dentry hash chain updates must take the dcache_lock as well as
588 the per-dentry lock in that order. dput() does this to ensure 799 the per-dentry lock in that order. dput() does this to ensure
589 that a dentry that has just been looked up in another CPU 800 that a dentry that has just been looked up in another CPU
590 doesn't get deleted before dget() can be done on it. 801 doesn't get deleted before dget() can be done on it.
@@ -640,10 +851,10 @@ handled as described below :
640 Since we redo the d_parent check and compare name while holding 851 Since we redo the d_parent check and compare name while holding
641 d_lock, lock-free look-up will not race against d_move(). 852 d_lock, lock-free look-up will not race against d_move().
642 853
6434. There can be a theoritical race when a dentry keeps coming back 8544. There can be a theoretical race when a dentry keeps coming back
644 to original bucket due to double moves. Due to this look-up may 855 to original bucket due to double moves. Due to this look-up may
645 consider that it has never moved and can end up in a infinite loop. 856 consider that it has never moved and can end up in a infinite loop.
646 But this is not any worse that theoritical livelocks we already 857 But this is not any worse that theoretical livelocks we already
647 have in the kernel. 858 have in the kernel.
648 859
649 860
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
new file mode 100644
index 000000000000..85f095a7ad04
--- /dev/null
+++ b/Documentation/input/yealink.txt
@@ -0,0 +1,203 @@
1Driver documentation for yealink usb-p1k phones
2
30. Status
4~~~~~~~~~
5
6The p1k is a relatively cheap usb 1.1 phone with:
7 - keyboard full support, yealink.ko / input event API
8 - LCD full support, yealink.ko / sysfs API
9 - LED full support, yealink.ko / sysfs API
10 - dialtone full support, yealink.ko / sysfs API
11 - ringtone full support, yealink.ko / sysfs API
12 - audio playback full support, snd_usb_audio.ko / alsa API
13 - audio record full support, snd_usb_audio.ko / alsa API
14
15For vendor documentation see http://www.yealink.com
16
17
181. Compilation (stand alone version)
19~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
21Currently only kernel 2.6.x.y versions are supported.
22In order to build the yealink.ko module do:
23
24 make
25
26If you encounter problems please check if in the MAKE_OPTS variable in
27the Makefile is pointing to the location where your kernel sources
28are located, default /usr/src/linux.
29
30
31
322. keyboard features
33~~~~~~~~~~~~~~~~~~~~
34The current mapping in the kernel is provided by the map_p1k_to_key
35function:
36
37 Physical USB-P1K button layout input events
38
39
40 up up
41 IN OUT left, right
42 down down
43
44 pickup C hangup enter, backspace, escape
45 1 2 3 1, 2, 3
46 4 5 6 4, 5, 6,
47 7 8 9 7, 8, 9,
48 * 0 # *, 0, #,
49
50 The "up" and "down" keys, are symbolised by arrows on the button.
51 The "pickup" and "hangup" keys are symbolised by a green and red phone
52 on the button.
53
54
553. LCD features
56~~~~~~~~~~~~~~~
57The LCD is divided and organised as a 3 line display:
58
59 |[] [][] [][] [][] in |[][]
60 |[] M [][] D [][] : [][] out |[][]
61 store
62
63 NEW REP SU MO TU WE TH FR SA
64
65 [] [] [] [] [] [] [] [] [] [] [] []
66 [] [] [] [] [] [] [] [] [] [] [] []
67
68
69Line 1 Format (see below) : 18.e8.M8.88...188
70 Icon names : M D : IN OUT STORE
71Line 2 Format : .........
72 Icon name : NEW REP SU MO TU WE TH FR SA
73Line 3 Format : 888888888888
74
75
76Format description:
77 From a user space perspective the world is seperated in "digits" and "icons".
78 A digit can have a character set, an icon can only be ON or OFF.
79
80 Format specifier
81 '8' : Generic 7 segment digit with individual addressable segments
82
83 Reduced capabillity 7 segm digit, when segments are hard wired together.
84 '1' : 2 segments digit only able to produce a 1.
85 'e' : Most significant day of the month digit,
86 able to produce at least 1 2 3.
87 'M' : Most significant minute digit,
88 able to produce at least 0 1 2 3 4 5.
89
90 Icons or pictograms:
91 '.' : For example like AM, PM, SU, a 'dot' .. or other single segment
92 elements.
93
94
954. Driver usage
96~~~~~~~~~~~~~~~
97For userland the following interfaces are available using the sysfs interface:
98 /sys/.../
99 line1 Read/Write, lcd line1
100 line2 Read/Write, lcd line2
101 line3 Read/Write, lcd line3
102
103 get_icons Read, returns a set of available icons.
104 hide_icon Write, hide the element by writing the icon name.
105 show_icon Write, display the element by writing the icon name.
106
107 map_seg7 Read/Write, the 7 segments char set, common for all
108 yealink phones. (see map_to_7segment.h)
109
110 ringtone Write, upload binary representation of a ringtone,
111 see yealink.c. status EXPERIMENTAL due to potential
112 races between async. and sync usb calls.
113
114
1154.1 lineX
116~~~~~~~~~
117Reading /sys/../lineX will return the format string with its current value:
118
119 Example:
120 cat ./line3
121 888888888888
122 Linux Rocks!
123
124Writing to /sys/../lineX will set the coresponding LCD line.
125 - Excess characters are ignored.
126 - If less characters are written than allowed, the remaining digits are
127 unchanged.
128 - The tab '\t'and '\n' char does not overwrite the original content.
129 - Writing a space to an icon will always hide its content.
130
131 Example:
132 date +"%m.%e.%k:%M" | sed 's/^0/ /' > ./line1
133
134 Will update the LCD with the current date & time.
135
136
1374.2 get_icons
138~~~~~~~~~~~~~
139Reading will return all available icon names and its current settings:
140
141 cat ./get_icons
142 on M
143 on D
144 on :
145 IN
146 OUT
147 STORE
148 NEW
149 REP
150 SU
151 MO
152 TU
153 WE
154 TH
155 FR
156 SA
157 LED
158 DIALTONE
159 RINGTONE
160
161
1624.3 show/hide icons
163~~~~~~~~~~~~~~~~~~~
164Writing to these files will update the state of the icon.
165Only one icon at a time can be updated.
166
167If an icon is also on a ./lineX the corresponding value is
168updated with the first letter of the icon.
169
170 Example - light up the store icon:
171 echo -n "STORE" > ./show_icon
172
173 cat ./line1
174 18.e8.M8.88...188
175 S
176
177 Example - sound the ringtone for 10 seconds:
178 echo -n RINGTONE > /sys/..../show_icon
179 sleep 10
180 echo -n RINGTONE > /sys/..../hide_icon
181
182
1835. Sound features
184~~~~~~~~~~~~~~~~~
185Sound is supported by the ALSA driver: snd_usb_audio
186
187One 16-bit channel with sample and playback rates of 8000 Hz is the practical
188limit of the device.
189
190 Example - recording test:
191 arecord -v -d 10 -r 8000 -f S16_LE -t wav foobar.wav
192
193 Example - playback test:
194 aplay foobar.wav
195
196
1976. Credits & Acknowledgments
198~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199 - Olivier Vandorpe, for starting the usbb2k-api project doing much of
200 the reverse engineering.
201 - Martin Diehl, for pointing out how to handle USB memory allocation.
202 - Dmitry Torokhov, for the numerous code reviews and suggestions.
203
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 7ff213f4becd..1f5f7d28c9e6 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -39,8 +39,7 @@ SETUP
39 and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch 39 and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch
40 and after that build the source. 40 and after that build the source.
41 41
422) Download and build the appropriate (latest) kexec/kdump (-mm) kernel 422) Download and build the appropriate (2.6.13-rc1 onwards) vanilla kernel.
43 patchset and apply it to the vanilla kernel tree.
44 43
45 Two kernels need to be built in order to get this feature working. 44 Two kernels need to be built in order to get this feature working.
46 45
@@ -84,15 +83,16 @@ SETUP
84 83
854) Load the second kernel to be booted using: 844) Load the second kernel to be booted using:
86 85
87 kexec -p <second-kernel> --crash-dump --args-linux --append="root=<root-dev> 86 kexec -p <second-kernel> --args-linux --elf32-core-headers
88 init 1 irqpoll" 87 --append="root=<root-dev> init 1 irqpoll"
89 88
90 Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work, 89 Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work,
91 as of now. 90 as of now.
92 ii) By default ELF headers are stored in ELF32 format (for i386). This 91 ii) By default ELF headers are stored in ELF64 format. Option
93 is sufficient to represent the physical memory up to 4GB. To store 92 --elf32-core-headers forces generation of ELF32 headers. gdb can
94 headers in ELF64 format, specifiy "--elf64-core-headers" on the 93 not open ELF64 headers on 32 bit systems. So creating ELF32
95 kexec command line additionally. 94 headers can come handy for users who have got non-PAE systems and
95 hence have memory less than 4GB.
96 iii) Specify "irqpoll" as command line parameter. This reduces driver 96 iii) Specify "irqpoll" as command line parameter. This reduces driver
97 initialization failures in second kernel due to shared interrupts. 97 initialization failures in second kernel due to shared interrupts.
98 98
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index f97841478459..5df44dc894e5 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -57,7 +57,7 @@ With BK, you can just get it from
57 57
58and DaveJ has tar-balls at 58and DaveJ has tar-balls at
59 59
60 http://www.codemonkey.org.uk/projects/bitkeeper/sparse/ 60 http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
61 61
62 62
63Once you have it, just do 63Once you have it, just do
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 62a12a08e2ac..ec785f9f15a3 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -126,10 +126,12 @@ card=124 - AverMedia AverTV DVB-T 761
126card=125 - MATRIX Vision Sigma-SQ 126card=125 - MATRIX Vision Sigma-SQ
127card=126 - MATRIX Vision Sigma-SLC 127card=126 - MATRIX Vision Sigma-SLC
128card=127 - APAC Viewcomp 878(AMAX) 128card=127 - APAC Viewcomp 878(AMAX)
129card=128 - DVICO FusionHDTV DVB-T Lite 129card=128 - DViCO FusionHDTV DVB-T Lite
130card=129 - V-Gear MyVCD 130card=129 - V-Gear MyVCD
131card=130 - Super TV Tuner 131card=130 - Super TV Tuner
132card=131 - Tibet Systems 'Progress DVR' CS16 132card=131 - Tibet Systems 'Progress DVR' CS16
133card=132 - Kodicom 4400R (master) 133card=132 - Kodicom 4400R (master)
134card=133 - Kodicom 4400R (slave) 134card=133 - Kodicom 4400R (slave)
135card=134 - Adlink RTV24 135card=134 - Adlink RTV24
136card=135 - DViCO FusionHDTV 5 Lite
137card=136 - Acorp Y878F
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 1b5a3a9ffbe2..dc57225f39be 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -62,3 +62,6 @@
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]
66 65 -> V-Stream Studio TV Terminator
67 66 -> Yuan TUN-900 (saa7135)
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f3302e1b1b9c..f5876be658a6 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -64,3 +64,4 @@ tuner=62 - Philips TEA5767HN FM Radio
64tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner 64tuner=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)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e4e82921070..f038dca34ee8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -116,6 +116,12 @@ M: ajk@iehk.rwth-aachen.de
116L: linux-hams@vger.kernel.org 116L: linux-hams@vger.kernel.org
117S: Maintained 117S: Maintained
118 118
119YEALINK PHONE DRIVER
120P: Henk Vergonet
121M: Henk.Vergonet@gmail.com
122L: usbb2k-api-dev@nongnu.org
123S: Maintained
124
1198139CP 10/100 FAST ETHERNET DRIVER 1258139CP 10/100 FAST ETHERNET DRIVER
120P: Jeff Garzik 126P: Jeff Garzik
121M: jgarzik@pobox.com 127M: jgarzik@pobox.com
@@ -620,6 +626,12 @@ M: rmk@arm.linux.org.uk
620W: http://www.arm.linux.org.uk/ 626W: http://www.arm.linux.org.uk/
621S: Maintained 627S: Maintained
622 628
629CYBLAFB FRAMEBUFFER DRIVER
630P: Knut Petersen
631M: Knut_Petersen@t-online.de
632L: linux-fbdev-devel@lists.sourceforge.net
633S: Maintained
634
623CYCLADES 2X SYNC CARD DRIVER 635CYCLADES 2X SYNC CARD DRIVER
624P: Arnaldo Carvalho de Melo 636P: Arnaldo Carvalho de Melo
625M: acme@conectiva.com.br 637M: acme@conectiva.com.br
@@ -919,6 +931,13 @@ L: linux-tape@vger.kernel.org
919W: http://sourceforge.net/projects/ftape 931W: http://sourceforge.net/projects/ftape
920S: Orphan 932S: Orphan
921 933
934FUSE: FILESYSTEM IN USERSPACE
935P: Miklos Szeredi
936M: miklos@szeredi.hu
937L: fuse-devel@lists.sourceforge.net
938W: http://fuse.sourceforge.net/
939S: Maintained
940
922FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) 941FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
923P: Rik Faith 942P: Rik Faith
924M: faith@cs.unc.edu 943M: faith@cs.unc.edu
@@ -1813,13 +1832,6 @@ M: hch@infradead.org
1813L: linux-abi-devel@lists.sourceforge.net 1832L: linux-abi-devel@lists.sourceforge.net
1814S: Maintained 1833S: Maintained
1815 1834
1816PCI ID DATABASE
1817P: Martin Mares
1818M: mj@ucw.cz
1819L: pciids-devel@lists.sourceforge.net
1820W: http://pciids.sourceforge.net/
1821S: Maintained
1822
1823PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES) 1835PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
1824P: Thomas Sailer 1836P: Thomas Sailer
1825M: sailer@ife.ee.ethz.ch 1837M: sailer@ife.ee.ethz.ch
@@ -2685,6 +2697,17 @@ L: rio500-users@lists.sourceforge.net
2685W: http://rio500.sourceforge.net 2697W: http://rio500.sourceforge.net
2686S: Maintained 2698S: Maintained
2687 2699
2700V9FS FILE SYSTEM
2701P: Eric Van Hensbergen
2702M: ericvh@gmail.com
2703P: Ron Minnich
2704M: rminnich@lanl.gov
2705P: Latchesar Ionkov
2706M: lucho@ionkov.net
2707L: v9fs-developer@lists.sourceforge.net
2708W: http://v9fs.sf.net
2709S: Maintained
2710
2688VIDEO FOR LINUX 2711VIDEO FOR LINUX
2689P: Mauro Carvalho Chehab 2712P: Mauro Carvalho Chehab
2690M: mchehab@brturbo.com.br 2713M: mchehab@brturbo.com.br
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index fc271e316a38..aac6d4b22f7a 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -47,7 +47,7 @@ module_free(struct module *mod, void *module_region)
47 47
48struct got_entry { 48struct got_entry {
49 struct got_entry *next; 49 struct got_entry *next;
50 Elf64_Addr r_offset; 50 Elf64_Sxword r_addend;
51 int got_offset; 51 int got_offset;
52}; 52};
53 53
@@ -57,14 +57,14 @@ process_reloc_for_got(Elf64_Rela *rela,
57{ 57{
58 unsigned long r_sym = ELF64_R_SYM (rela->r_info); 58 unsigned long r_sym = ELF64_R_SYM (rela->r_info);
59 unsigned long r_type = ELF64_R_TYPE (rela->r_info); 59 unsigned long r_type = ELF64_R_TYPE (rela->r_info);
60 Elf64_Addr r_offset = rela->r_offset; 60 Elf64_Sxword r_addend = rela->r_addend;
61 struct got_entry *g; 61 struct got_entry *g;
62 62
63 if (r_type != R_ALPHA_LITERAL) 63 if (r_type != R_ALPHA_LITERAL)
64 return; 64 return;
65 65
66 for (g = chains + r_sym; g ; g = g->next) 66 for (g = chains + r_sym; g ; g = g->next)
67 if (g->r_offset == r_offset) { 67 if (g->r_addend == r_addend) {
68 if (g->got_offset == 0) { 68 if (g->got_offset == 0) {
69 g->got_offset = *poffset; 69 g->got_offset = *poffset;
70 *poffset += 8; 70 *poffset += 8;
@@ -74,7 +74,7 @@ process_reloc_for_got(Elf64_Rela *rela,
74 74
75 g = kmalloc (sizeof (*g), GFP_KERNEL); 75 g = kmalloc (sizeof (*g), GFP_KERNEL);
76 g->next = chains[r_sym].next; 76 g->next = chains[r_sym].next;
77 g->r_offset = r_offset; 77 g->r_addend = r_addend;
78 g->got_offset = *poffset; 78 g->got_offset = *poffset;
79 *poffset += 8; 79 *poffset += 8;
80 chains[r_sym].next = g; 80 chains[r_sym].next = g;
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 167fd89f8707..2b034182a0ca 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -974,6 +974,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
974 size_t size; 974 size_t size;
975 long timeout; 975 long timeout;
976 int ret = -EINVAL; 976 int ret = -EINVAL;
977 struct fdtable *fdt;
977 978
978 timeout = MAX_SCHEDULE_TIMEOUT; 979 timeout = MAX_SCHEDULE_TIMEOUT;
979 if (tvp) { 980 if (tvp) {
@@ -995,7 +996,8 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
995 } 996 }
996 } 997 }
997 998
998 if (n < 0 || n > current->files->max_fdset) 999 fdt = files_fdtable(current->files);
1000 if (n < 0 || n > fdt->max_fdset)
999 goto out_nofds; 1001 goto out_nofds;
1000 1002
1001 /* 1003 /*
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 804727853d25..e32fee505220 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -373,12 +373,11 @@ marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
373 irq += 0x80; /* offset for lsi */ 373 irq += 0x80; /* offset for lsi */
374 374
375#if 1 375#if 1
376 printk("PCI:%d:%d:%d (hose %d) [%s] is using MSI\n", 376 printk("PCI:%d:%d:%d (hose %d) is using MSI\n",
377 dev->bus->number, 377 dev->bus->number,
378 PCI_SLOT(dev->devfn), 378 PCI_SLOT(dev->devfn),
379 PCI_FUNC(dev->devfn), 379 PCI_FUNC(dev->devfn),
380 hose->index, 380 hose->index);
381 pci_pretty_name (dev));
382 printk(" %d message(s) from 0x%04x\n", 381 printk(" %d message(s) from 0x%04x\n",
383 1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4), 382 1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
384 msg_dat); 383 msg_dat);
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 51f430cc2fbf..2786f7c34b3f 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -541,6 +541,103 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
541 return ret; 541 return ret;
542} 542}
543 543
544#ifdef CONFIG_PM
545
546struct locomo_save_data {
547 u16 LCM_GPO;
548 u16 LCM_SPICT;
549 u16 LCM_GPE;
550 u16 LCM_ASD;
551 u16 LCM_SPIMD;
552};
553
554static int locomo_suspend(struct device *dev, u32 pm_message_t, u32 level)
555{
556 struct locomo *lchip = dev_get_drvdata(dev);
557 struct locomo_save_data *save;
558 unsigned long flags;
559
560 if (level != SUSPEND_DISABLE)
561 return 0;
562
563 save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
564 if (!save)
565 return -ENOMEM;
566
567 dev->power.saved_state = (void *) save;
568
569 spin_lock_irqsave(&lchip->lock, flags);
570
571 save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */
572 locomo_writel(0x00, lchip->base + LOCOMO_GPO);
573 save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPICT); /* SPI */
574 locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
575 save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */
576 locomo_writel(0x00, lchip->base + LOCOMO_GPE);
577 save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */
578 locomo_writel(0x00, lchip->base + LOCOMO_ASD);
579 save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPIMD); /* SPI */
580 locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD);
581
582 locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
583 locomo_writel(0x00, lchip->base + LOCOMO_DAC);
584 locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
585
586 if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) )
587 locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */
588 else
589 /* 18MHz already enabled, so no wait */
590 locomo_writel(0xc1, lchip->base + LOCOMO_C32K); /* CLK32 on */
591
592 locomo_writel(0x00, lchip->base + LOCOMO_TADC); /* 18MHz clock off*/
593 locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC); /* 22MHz/24MHz clock off */
594 locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); /* FL */
595
596 spin_unlock_irqrestore(&lchip->lock, flags);
597
598 return 0;
599}
600
601static int locomo_resume(struct device *dev, u32 level)
602{
603 struct locomo *lchip = dev_get_drvdata(dev);
604 struct locomo_save_data *save;
605 unsigned long r;
606 unsigned long flags;
607
608 if (level != RESUME_ENABLE)
609 return 0;
610
611 save = (struct locomo_save_data *) dev->power.saved_state;
612 if (!save)
613 return 0;
614
615 spin_lock_irqsave(&lchip->lock, flags);
616
617 locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
618 locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT);
619 locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
620 locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
621 locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD);
622
623 locomo_writel(0x00, lchip->base + LOCOMO_C32K);
624 locomo_writel(0x90, lchip->base + LOCOMO_TADC);
625
626 locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
627 r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
628 r &= 0xFEFF;
629 locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
630 locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
631
632 spin_unlock_irqrestore(&lchip->lock, flags);
633
634 dev->power.saved_state = NULL;
635 kfree(save);
636
637 return 0;
638}
639#endif
640
544/** 641/**
545 * locomo_probe - probe for a single LoCoMo chip. 642 * locomo_probe - probe for a single LoCoMo chip.
546 * @phys_addr: physical address of device. 643 * @phys_addr: physical address of device.
@@ -707,6 +804,10 @@ static struct device_driver locomo_device_driver = {
707 .bus = &platform_bus_type, 804 .bus = &platform_bus_type,
708 .probe = locomo_probe, 805 .probe = locomo_probe,
709 .remove = locomo_remove, 806 .remove = locomo_remove,
807#ifdef CONFIG_PM
808 .suspend = locomo_suspend,
809 .resume = locomo_resume,
810#endif
710}; 811};
711 812
712/* 813/*
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 96a794d8de84..756348bf5170 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-git4 3# Linux kernel version: 2.6.13-git8
4# Wed Jun 22 15:56:42 2005 4# Thu Sep 8 19:24:02 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_ALL is not set 38# CONFIG_KALLSYMS_ALL is not set
@@ -88,7 +90,9 @@ CONFIG_ARCH_S3C2410=y
88# 90#
89# S3C24XX Implementations 91# S3C24XX Implementations
90# 92#
93CONFIG_MACH_ANUBIS=y
91CONFIG_ARCH_BAST=y 94CONFIG_ARCH_BAST=y
95CONFIG_BAST_PC104_IRQ=y
92CONFIG_ARCH_H1940=y 96CONFIG_ARCH_H1940=y
93CONFIG_MACH_N30=y 97CONFIG_MACH_N30=y
94CONFIG_ARCH_SMDK2410=y 98CONFIG_ARCH_SMDK2410=y
@@ -112,6 +116,7 @@ CONFIG_S3C2410_DMA=y
112# CONFIG_S3C2410_DMA_DEBUG is not set 116# CONFIG_S3C2410_DMA_DEBUG is not set
113# CONFIG_S3C2410_PM_DEBUG is not set 117# CONFIG_S3C2410_PM_DEBUG is not set
114# CONFIG_S3C2410_PM_CHECK is not set 118# CONFIG_S3C2410_PM_CHECK is not set
119CONFIG_PM_SIMTEC=y
115CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 120CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
116 121
117# 122#
@@ -149,7 +154,15 @@ CONFIG_ISA_DMA_API=y
149# 154#
150# CONFIG_SMP is not set 155# CONFIG_SMP is not set
151# CONFIG_PREEMPT is not set 156# CONFIG_PREEMPT is not set
152# CONFIG_DISCONTIGMEM is not set 157# CONFIG_NO_IDLE_HZ is not set
158# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
159CONFIG_SELECT_MEMORY_MODEL=y
160CONFIG_FLATMEM_MANUAL=y
161# CONFIG_DISCONTIGMEM_MANUAL is not set
162# CONFIG_SPARSEMEM_MANUAL is not set
163CONFIG_FLATMEM=y
164CONFIG_FLAT_NODE_MEM_MAP=y
165# CONFIG_SPARSEMEM_STATIC is not set
153CONFIG_ALIGNMENT_TRAP=y 166CONFIG_ALIGNMENT_TRAP=y
154 167
155# 168#
@@ -186,6 +199,74 @@ CONFIG_PM=y
186CONFIG_APM=y 199CONFIG_APM=y
187 200
188# 201#
202# Networking
203#
204CONFIG_NET=y
205
206#
207# Networking options
208#
209# CONFIG_PACKET is not set
210CONFIG_UNIX=y
211# CONFIG_NET_KEY is not set
212CONFIG_INET=y
213# CONFIG_IP_MULTICAST is not set
214# CONFIG_IP_ADVANCED_ROUTER is not set
215CONFIG_IP_FIB_HASH=y
216CONFIG_IP_PNP=y
217# CONFIG_IP_PNP_DHCP is not set
218CONFIG_IP_PNP_BOOTP=y
219# CONFIG_IP_PNP_RARP is not set
220# CONFIG_NET_IPIP is not set
221# CONFIG_NET_IPGRE is not set
222# CONFIG_ARPD is not set
223# CONFIG_SYN_COOKIES is not set
224# CONFIG_INET_AH is not set
225# CONFIG_INET_ESP is not set
226# CONFIG_INET_IPCOMP is not set
227# CONFIG_INET_TUNNEL is not set
228CONFIG_INET_DIAG=y
229CONFIG_INET_TCP_DIAG=y
230# CONFIG_TCP_CONG_ADVANCED is not set
231CONFIG_TCP_CONG_BIC=y
232# CONFIG_IPV6 is not set
233# CONFIG_NETFILTER is not set
234
235#
236# DCCP Configuration (EXPERIMENTAL)
237#
238# CONFIG_IP_DCCP is not set
239
240#
241# SCTP Configuration (EXPERIMENTAL)
242#
243# CONFIG_IP_SCTP is not set
244# CONFIG_ATM is not set
245# CONFIG_BRIDGE is not set
246# CONFIG_VLAN_8021Q is not set
247# CONFIG_DECNET is not set
248# CONFIG_LLC2 is not set
249# CONFIG_IPX is not set
250# CONFIG_ATALK is not set
251# CONFIG_X25 is not set
252# CONFIG_LAPB is not set
253# CONFIG_NET_DIVERT is not set
254# CONFIG_ECONET is not set
255# CONFIG_WAN_ROUTER is not set
256# CONFIG_NET_SCHED is not set
257# CONFIG_NET_CLS_ROUTE is not set
258
259#
260# Network testing
261#
262# CONFIG_NET_PKTGEN is not set
263# CONFIG_NETFILTER_NETLINK is not set
264# CONFIG_HAMRADIO is not set
265# CONFIG_IRDA is not set
266# CONFIG_BT is not set
267# CONFIG_IEEE80211 is not set
268
269#
189# Device Drivers 270# Device Drivers
190# 271#
191 272
@@ -258,6 +339,7 @@ CONFIG_MTD_ROM=y
258# CONFIG_MTD_IMPA7 is not set 339# CONFIG_MTD_IMPA7 is not set
259CONFIG_MTD_BAST=y 340CONFIG_MTD_BAST=y
260CONFIG_MTD_BAST_MAXSIZE=4 341CONFIG_MTD_BAST_MAXSIZE=4
342# CONFIG_MTD_PLATRAM is not set
261 343
262# 344#
263# Self-contained MTD device drivers 345# Self-contained MTD device drivers
@@ -312,7 +394,6 @@ CONFIG_BLK_DEV_RAM=y
312CONFIG_BLK_DEV_RAM_COUNT=16 394CONFIG_BLK_DEV_RAM_COUNT=16
313CONFIG_BLK_DEV_RAM_SIZE=4096 395CONFIG_BLK_DEV_RAM_SIZE=4096
314CONFIG_BLK_DEV_INITRD=y 396CONFIG_BLK_DEV_INITRD=y
315CONFIG_INITRAMFS_SOURCE=""
316# CONFIG_CDROM_PKTCDVD is not set 397# CONFIG_CDROM_PKTCDVD is not set
317 398
318# 399#
@@ -354,6 +435,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
354# 435#
355# SCSI device support 436# SCSI device support
356# 437#
438# CONFIG_RAID_ATTRS is not set
357# CONFIG_SCSI is not set 439# CONFIG_SCSI is not set
358 440
359# 441#
@@ -376,70 +458,8 @@ CONFIG_BLK_DEV_IDE_BAST=y
376# 458#
377 459
378# 460#
379# Networking support 461# Network device support
380#
381CONFIG_NET=y
382
383#
384# Networking options
385# 462#
386# CONFIG_PACKET is not set
387CONFIG_UNIX=y
388# CONFIG_NET_KEY is not set
389CONFIG_INET=y
390CONFIG_IP_FIB_HASH=y
391# CONFIG_IP_FIB_TRIE is not set
392# CONFIG_IP_MULTICAST is not set
393# CONFIG_IP_ADVANCED_ROUTER is not set
394CONFIG_IP_PNP=y
395# CONFIG_IP_PNP_DHCP is not set
396CONFIG_IP_PNP_BOOTP=y
397# CONFIG_IP_PNP_RARP is not set
398# CONFIG_NET_IPIP is not set
399# CONFIG_NET_IPGRE is not set
400# CONFIG_ARPD is not set
401# CONFIG_SYN_COOKIES is not set
402# CONFIG_INET_AH is not set
403# CONFIG_INET_ESP is not set
404# CONFIG_INET_IPCOMP is not set
405# CONFIG_INET_TUNNEL is not set
406CONFIG_IP_TCPDIAG=y
407# CONFIG_IP_TCPDIAG_IPV6 is not set
408# CONFIG_IPV6 is not set
409# CONFIG_NETFILTER is not set
410
411#
412# SCTP Configuration (EXPERIMENTAL)
413#
414# CONFIG_IP_SCTP is not set
415# CONFIG_ATM is not set
416# CONFIG_BRIDGE is not set
417# CONFIG_VLAN_8021Q is not set
418# CONFIG_DECNET is not set
419# CONFIG_LLC2 is not set
420# CONFIG_IPX is not set
421# CONFIG_ATALK is not set
422# CONFIG_X25 is not set
423# CONFIG_LAPB is not set
424# CONFIG_NET_DIVERT is not set
425# CONFIG_ECONET is not set
426# CONFIG_WAN_ROUTER is not set
427
428#
429# QoS and/or fair queueing
430#
431# CONFIG_NET_SCHED is not set
432# CONFIG_NET_CLS_ROUTE is not set
433
434#
435# Network testing
436#
437# CONFIG_NET_PKTGEN is not set
438# CONFIG_NETPOLL is not set
439# CONFIG_NET_POLL_CONTROLLER is not set
440# CONFIG_HAMRADIO is not set
441# CONFIG_IRDA is not set
442# CONFIG_BT is not set
443CONFIG_NETDEVICES=y 463CONFIG_NETDEVICES=y
444# CONFIG_DUMMY is not set 464# CONFIG_DUMMY is not set
445# CONFIG_BONDING is not set 465# CONFIG_BONDING is not set
@@ -447,6 +467,11 @@ CONFIG_NETDEVICES=y
447# CONFIG_TUN is not set 467# CONFIG_TUN is not set
448 468
449# 469#
470# PHY device support
471#
472# CONFIG_PHYLIB is not set
473
474#
450# Ethernet (10 or 100Mbit) 475# Ethernet (10 or 100Mbit)
451# 476#
452CONFIG_NET_ETHERNET=y 477CONFIG_NET_ETHERNET=y
@@ -480,6 +505,8 @@ CONFIG_DM9000=m
480# CONFIG_SLIP is not set 505# CONFIG_SLIP is not set
481# CONFIG_SHAPER is not set 506# CONFIG_SHAPER is not set
482# CONFIG_NETCONSOLE is not set 507# CONFIG_NETCONSOLE is not set
508# CONFIG_NETPOLL is not set
509# CONFIG_NET_POLL_CONTROLLER is not set
483 510
484# 511#
485# ISDN subsystem 512# ISDN subsystem
@@ -562,7 +589,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
562CONFIG_SERIAL_8250_MANY_PORTS=y 589CONFIG_SERIAL_8250_MANY_PORTS=y
563CONFIG_SERIAL_8250_SHARE_IRQ=y 590CONFIG_SERIAL_8250_SHARE_IRQ=y
564# CONFIG_SERIAL_8250_DETECT_IRQ is not set 591# CONFIG_SERIAL_8250_DETECT_IRQ is not set
565# CONFIG_SERIAL_8250_MULTIPORT is not set
566# CONFIG_SERIAL_8250_RSA is not set 592# CONFIG_SERIAL_8250_RSA is not set
567 593
568# 594#
@@ -605,7 +631,6 @@ CONFIG_S3C2410_RTC=y
605# 631#
606# Ftape, the floppy tape device driver 632# Ftape, the floppy tape device driver
607# 633#
608# CONFIG_DRM is not set
609# CONFIG_RAW_DRIVER is not set 634# CONFIG_RAW_DRIVER is not set
610 635
611# 636#
@@ -628,7 +653,7 @@ CONFIG_I2C_ALGOBIT=m
628# 653#
629# I2C Hardware Bus support 654# I2C Hardware Bus support
630# 655#
631# CONFIG_I2C_ISA is not set 656CONFIG_I2C_ISA=m
632# CONFIG_I2C_PARPORT is not set 657# CONFIG_I2C_PARPORT is not set
633# CONFIG_I2C_PARPORT_LIGHT is not set 658# CONFIG_I2C_PARPORT_LIGHT is not set
634CONFIG_I2C_S3C2410=y 659CONFIG_I2C_S3C2410=y
@@ -636,14 +661,33 @@ CONFIG_I2C_S3C2410=y
636# CONFIG_I2C_PCA_ISA is not set 661# CONFIG_I2C_PCA_ISA is not set
637 662
638# 663#
639# Hardware Sensors Chip support 664# Miscellaneous I2C Chip support
640# 665#
641CONFIG_I2C_SENSOR=m 666# CONFIG_SENSORS_DS1337 is not set
667# CONFIG_SENSORS_DS1374 is not set
668CONFIG_SENSORS_EEPROM=m
669# CONFIG_SENSORS_PCF8574 is not set
670# CONFIG_SENSORS_PCA9539 is not set
671# CONFIG_SENSORS_PCF8591 is not set
672# CONFIG_SENSORS_RTC8564 is not set
673# CONFIG_SENSORS_MAX6875 is not set
674# CONFIG_I2C_DEBUG_CORE is not set
675# CONFIG_I2C_DEBUG_ALGO is not set
676# CONFIG_I2C_DEBUG_BUS is not set
677# CONFIG_I2C_DEBUG_CHIP is not set
678
679#
680# Hardware Monitoring support
681#
682CONFIG_HWMON=y
683CONFIG_HWMON_VID=m
642# CONFIG_SENSORS_ADM1021 is not set 684# CONFIG_SENSORS_ADM1021 is not set
643# CONFIG_SENSORS_ADM1025 is not set 685# CONFIG_SENSORS_ADM1025 is not set
644# CONFIG_SENSORS_ADM1026 is not set 686# CONFIG_SENSORS_ADM1026 is not set
645# CONFIG_SENSORS_ADM1031 is not set 687# CONFIG_SENSORS_ADM1031 is not set
688# CONFIG_SENSORS_ADM9240 is not set
646# CONFIG_SENSORS_ASB100 is not set 689# CONFIG_SENSORS_ASB100 is not set
690# CONFIG_SENSORS_ATXP1 is not set
647# CONFIG_SENSORS_DS1621 is not set 691# CONFIG_SENSORS_DS1621 is not set
648# CONFIG_SENSORS_FSCHER is not set 692# CONFIG_SENSORS_FSCHER is not set
649# CONFIG_SENSORS_FSCPOS is not set 693# CONFIG_SENSORS_FSCPOS is not set
@@ -662,27 +706,21 @@ CONFIG_SENSORS_LM85=m
662# CONFIG_SENSORS_LM92 is not set 706# CONFIG_SENSORS_LM92 is not set
663# CONFIG_SENSORS_MAX1619 is not set 707# CONFIG_SENSORS_MAX1619 is not set
664# CONFIG_SENSORS_PC87360 is not set 708# CONFIG_SENSORS_PC87360 is not set
665# CONFIG_SENSORS_SMSC47B397 is not set
666# CONFIG_SENSORS_SMSC47M1 is not set 709# CONFIG_SENSORS_SMSC47M1 is not set
710# CONFIG_SENSORS_SMSC47B397 is not set
667# CONFIG_SENSORS_W83781D is not set 711# CONFIG_SENSORS_W83781D is not set
712# CONFIG_SENSORS_W83792D is not set
668# CONFIG_SENSORS_W83L785TS is not set 713# CONFIG_SENSORS_W83L785TS is not set
669# CONFIG_SENSORS_W83627HF is not set 714# CONFIG_SENSORS_W83627HF is not set
715# CONFIG_SENSORS_W83627EHF is not set
716# CONFIG_HWMON_DEBUG_CHIP is not set
670 717
671# 718#
672# Other I2C Chip support 719# Misc devices
673# 720#
674# CONFIG_SENSORS_DS1337 is not set
675CONFIG_SENSORS_EEPROM=m
676# CONFIG_SENSORS_PCF8574 is not set
677# CONFIG_SENSORS_PCF8591 is not set
678# CONFIG_SENSORS_RTC8564 is not set
679# CONFIG_I2C_DEBUG_CORE is not set
680# CONFIG_I2C_DEBUG_ALGO is not set
681# CONFIG_I2C_DEBUG_BUS is not set
682# CONFIG_I2C_DEBUG_CHIP is not set
683 721
684# 722#
685# Misc devices 723# Multimedia Capabilities Port drivers
686# 724#
687 725
688# 726#
@@ -731,7 +769,7 @@ CONFIG_DUMMY_CONSOLE=y
731# USB support 769# USB support
732# 770#
733CONFIG_USB_ARCH_HAS_HCD=y 771CONFIG_USB_ARCH_HAS_HCD=y
734# CONFIG_USB_ARCH_HAS_OHCI is not set 772CONFIG_USB_ARCH_HAS_OHCI=y
735# CONFIG_USB is not set 773# CONFIG_USB is not set
736 774
737# 775#
@@ -749,6 +787,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
749# 787#
750CONFIG_EXT2_FS=y 788CONFIG_EXT2_FS=y
751# CONFIG_EXT2_FS_XATTR is not set 789# CONFIG_EXT2_FS_XATTR is not set
790# CONFIG_EXT2_FS_XIP is not set
752CONFIG_EXT3_FS=y 791CONFIG_EXT3_FS=y
753CONFIG_EXT3_FS_XATTR=y 792CONFIG_EXT3_FS_XATTR=y
754# CONFIG_EXT3_FS_POSIX_ACL is not set 793# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -758,6 +797,7 @@ CONFIG_JBD=y
758CONFIG_FS_MBCACHE=y 797CONFIG_FS_MBCACHE=y
759# CONFIG_REISERFS_FS is not set 798# CONFIG_REISERFS_FS is not set
760# CONFIG_JFS_FS is not set 799# CONFIG_JFS_FS is not set
800# CONFIG_FS_POSIX_ACL is not set
761 801
762# 802#
763# XFS support 803# XFS support
@@ -765,6 +805,7 @@ CONFIG_FS_MBCACHE=y
765# CONFIG_XFS_FS is not set 805# CONFIG_XFS_FS is not set
766# CONFIG_MINIX_FS is not set 806# CONFIG_MINIX_FS is not set
767CONFIG_ROMFS_FS=y 807CONFIG_ROMFS_FS=y
808CONFIG_INOTIFY=y
768# CONFIG_QUOTA is not set 809# CONFIG_QUOTA is not set
769CONFIG_DNOTIFY=y 810CONFIG_DNOTIFY=y
770# CONFIG_AUTOFS_FS is not set 811# CONFIG_AUTOFS_FS is not set
@@ -791,11 +832,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
791# 832#
792CONFIG_PROC_FS=y 833CONFIG_PROC_FS=y
793CONFIG_SYSFS=y 834CONFIG_SYSFS=y
794# CONFIG_DEVPTS_FS_XATTR is not set
795# CONFIG_TMPFS is not set 835# CONFIG_TMPFS is not set
796# CONFIG_HUGETLBFS is not set 836# CONFIG_HUGETLBFS is not set
797# CONFIG_HUGETLB_PAGE is not set 837# CONFIG_HUGETLB_PAGE is not set
798CONFIG_RAMFS=y 838CONFIG_RAMFS=y
839# CONFIG_RELAYFS_FS is not set
799 840
800# 841#
801# Miscellaneous filesystems 842# Miscellaneous filesystems
@@ -812,8 +853,7 @@ CONFIG_JFFS_FS_VERBOSE=0
812# CONFIG_JFFS_PROC_FS is not set 853# CONFIG_JFFS_PROC_FS is not set
813CONFIG_JFFS2_FS=y 854CONFIG_JFFS2_FS=y
814CONFIG_JFFS2_FS_DEBUG=0 855CONFIG_JFFS2_FS_DEBUG=0
815# CONFIG_JFFS2_FS_NAND is not set 856CONFIG_JFFS2_FS_WRITEBUFFER=y
816# CONFIG_JFFS2_FS_NOR_ECC is not set
817# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 857# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
818CONFIG_JFFS2_ZLIB=y 858CONFIG_JFFS2_ZLIB=y
819CONFIG_JFFS2_RTIME=y 859CONFIG_JFFS2_RTIME=y
@@ -835,6 +875,7 @@ CONFIG_NFS_FS=y
835# CONFIG_NFSD is not set 875# CONFIG_NFSD is not set
836CONFIG_ROOT_NFS=y 876CONFIG_ROOT_NFS=y
837CONFIG_LOCKD=y 877CONFIG_LOCKD=y
878CONFIG_NFS_COMMON=y
838CONFIG_SUNRPC=y 879CONFIG_SUNRPC=y
839# CONFIG_RPCSEC_GSS_KRB5 is not set 880# CONFIG_RPCSEC_GSS_KRB5 is not set
840# CONFIG_RPCSEC_GSS_SPKM3 is not set 881# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -920,6 +961,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
920CONFIG_DEBUG_KERNEL=y 961CONFIG_DEBUG_KERNEL=y
921# CONFIG_MAGIC_SYSRQ is not set 962# CONFIG_MAGIC_SYSRQ is not set
922CONFIG_LOG_BUF_SHIFT=16 963CONFIG_LOG_BUF_SHIFT=16
964CONFIG_DETECT_SOFTLOCKUP=y
923# CONFIG_SCHEDSTATS is not set 965# CONFIG_SCHEDSTATS is not set
924# CONFIG_DEBUG_SLAB is not set 966# CONFIG_DEBUG_SLAB is not set
925# CONFIG_DEBUG_SPINLOCK is not set 967# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 112f1d68fb2b..e216ab8b9e8f 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -354,7 +354,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
354 354
355static struct platform_device serial_device = { 355static struct platform_device serial_device = {
356 .name = "serial8250", 356 .name = "serial8250",
357 .id = 0, 357 .id = PLAT8250_DEV_PLATFORM,
358 .dev = { 358 .dev = {
359 .platform_data = serial_platform_data, 359 .platform_data = serial_platform_data,
360 }, 360 },
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 23c4da10101b..5aeadfd72143 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -219,7 +219,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
219 219
220static struct platform_device serial_device = { 220static struct platform_device serial_device = {
221 .name = "serial8250", 221 .name = "serial8250",
222 .id = 0, 222 .id = PLAT8250_DEV_PLATFORM,
223 .dev = { 223 .dev = {
224 .platform_data = serial_platform_data, 224 .platform_data = serial_platform_data,
225 }, 225 },
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 7daa021676d0..44c56571d183 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -52,7 +52,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
52 52
53static struct platform_device serial_device = { 53static struct platform_device serial_device = {
54 .name = "serial8250", 54 .name = "serial8250",
55 .id = 0, 55 .id = PLAT8250_DEV_PLATFORM,
56 .dev = { 56 .dev = {
57 .platform_data = serial_platform_data, 57 .platform_data = serial_platform_data,
58 }, 58 },
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
index aa3a1fef563e..28846c7edaaf 100644
--- a/arch/arm/mach-footbridge/isa.c
+++ b/arch/arm/mach-footbridge/isa.c
@@ -34,7 +34,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
34 34
35static struct platform_device serial_device = { 35static struct platform_device serial_device = {
36 .name = "serial8250", 36 .name = "serial8250",
37 .id = 0, 37 .id = PLAT8250_DEV_PLATFORM,
38 .dev = { 38 .dev = {
39 .platform_data = serial_platform_data, 39 .platform_data = serial_platform_data,
40 }, 40 },
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 4b3199319e68..a4a7c0125d03 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -90,7 +90,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
90 90
91static struct platform_device serial_device = { 91static struct platform_device serial_device = {
92 .name = "serial8250", 92 .name = "serial8250",
93 .id = 0, 93 .id = PLAT8250_DEV_PLATFORM,
94 .dev = { 94 .dev = {
95 .platform_data = serial_platform_data, 95 .platform_data = serial_platform_data,
96 }, 96 },
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 098c817a7fb8..74bd2fd602d4 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -174,7 +174,7 @@ static struct resource ixp2000_uart_resource = {
174 174
175static struct platform_device ixp2000_serial_device = { 175static struct platform_device ixp2000_serial_device = {
176 .name = "serial8250", 176 .name = "serial8250",
177 .id = 0, 177 .id = PLAT8250_DEV_PLATFORM,
178 .dev = { 178 .dev = {
179 .platform_data = ixp2000_serial_port, 179 .platform_data = ixp2000_serial_port,
180 }, 180 },
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 8b2f25322452..050c92768913 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -66,7 +66,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
66 66
67static struct platform_device coyote_uart = { 67static struct platform_device coyote_uart = {
68 .name = "serial8250", 68 .name = "serial8250",
69 .id = 0, 69 .id = PLAT8250_DEV_PLATFORM,
70 .dev = { 70 .dev = {
71 .platform_data = coyote_uart_data, 71 .platform_data = coyote_uart_data,
72 }, 72 },
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 3fd92c5cbaa8..29a6d02fa851 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -93,7 +93,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
93 93
94static struct platform_device gtwx5715_uart_device = { 94static struct platform_device gtwx5715_uart_device = {
95 .name = "serial8250", 95 .name = "serial8250",
96 .id = 0, 96 .id = PLAT8250_DEV_PLATFORM,
97 .dev = { 97 .dev = {
98 .platform_data = gtwx5715_uart_platform_data, 98 .platform_data = gtwx5715_uart_platform_data,
99 }, 99 },
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 6c14ff3c23a0..ae1fa099d5fa 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -96,7 +96,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
96 96
97static struct platform_device ixdp425_uart = { 97static struct platform_device ixdp425_uart = {
98 .name = "serial8250", 98 .name = "serial8250",
99 .id = 0, 99 .id = PLAT8250_DEV_PLATFORM,
100 .dev.platform_data = ixdp425_uart_data, 100 .dev.platform_data = ixdp425_uart_data,
101 .num_resources = 2, 101 .num_resources = 2,
102 .resource = ixdp425_uart_resources 102 .resource = ixdp425_uart_resources
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 7408ac94f771..27fc2e8e5fca 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -47,6 +47,14 @@ config MACH_OMAP_OSK
47 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here 47 TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
48 if you have such a board. 48 if you have such a board.
49 49
50config OMAP_OSK_MISTRAL
51 bool "Mistral QVGA board Support"
52 depends on MACH_OMAP_OSK
53 help
54 The OSK supports an optional add-on board with a Quarter-VGA
55 touchscreen, PDA-ish buttons, a resume button, bicolor LED,
56 and camera connector. Say Y here if you have this board.
57
50config MACH_OMAP_PERSEUS2 58config MACH_OMAP_PERSEUS2
51 bool "TI Perseus2" 59 bool "TI Perseus2"
52 depends on ARCH_OMAP1 && ARCH_OMAP730 60 depends on ARCH_OMAP1 && ARCH_OMAP730
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index d386fd913f0c..181a93deaaee 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 6obj-y := io.o id.o irq.o time.o serial.o devices.o
7led-y := leds.o 7led-y := leds.o
8 8
9# Specific board support 9# Specific board support
@@ -23,6 +23,7 @@ endif
23 23
24# LEDs support 24# LEDs support
25led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o 25led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
26led-$(CONFIG_MACH_OMAP_H3) += leds-h2p2-debug.o
26led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o 27led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
27led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o 28led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
28led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o 29led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 122796ebe8f5..c209c7172a9a 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -48,19 +48,43 @@ static struct omap_usb_config generic1510_usb_config __initdata = {
48 48
49#if defined(CONFIG_ARCH_OMAP16XX) 49#if defined(CONFIG_ARCH_OMAP16XX)
50static struct omap_usb_config generic1610_usb_config __initdata = { 50static struct omap_usb_config generic1610_usb_config __initdata = {
51#ifdef CONFIG_USB_OTG
52 .otg = 1,
53#endif
51 .register_host = 1, 54 .register_host = 1,
52 .register_dev = 1, 55 .register_dev = 1,
53 .hmc_mode = 16, 56 .hmc_mode = 16,
54 .pins[0] = 6, 57 .pins[0] = 6,
55}; 58};
59
60static struct omap_mmc_config generic_mmc_config __initdata = {
61 .mmc [0] = {
62 .enabled = 0,
63 .wire4 = 0,
64 .wp_pin = -1,
65 .power_pin = -1,
66 .switch_pin = -1,
67 },
68 .mmc [1] = {
69 .enabled = 0,
70 .wire4 = 0,
71 .wp_pin = -1,
72 .power_pin = -1,
73 .switch_pin = -1,
74 },
75};
76
56#endif 77#endif
57 78
58static struct omap_board_config_kernel generic_config[] = { 79static struct omap_board_config_kernel generic_config[] = {
59 { OMAP_TAG_USB, NULL }, 80 { OMAP_TAG_USB, NULL },
81 { OMAP_TAG_MMC, &generic_mmc_config },
60}; 82};
61 83
62static void __init omap_generic_init(void) 84static void __init omap_generic_init(void)
63{ 85{
86 const struct omap_uart_config *uart_conf;
87
64 /* 88 /*
65 * Make sure the serial ports are muxed on at this point. 89 * Make sure the serial ports are muxed on at this point.
66 * You have to mux them off in device drivers later on 90 * You have to mux them off in device drivers later on
@@ -76,6 +100,18 @@ static void __init omap_generic_init(void)
76 generic_config[0].data = &generic1610_usb_config; 100 generic_config[0].data = &generic1610_usb_config;
77 } 101 }
78#endif 102#endif
103
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
79 omap_board_config = generic_config; 115 omap_board_config = generic_config;
80 omap_board_config_size = ARRAY_SIZE(generic_config); 116 omap_board_config_size = ARRAY_SIZE(generic_config);
81 omap_serial_init(generic_serial_ports); 117 omap_serial_init(generic_serial_ports);
@@ -83,7 +119,7 @@ static void __init omap_generic_init(void)
83 119
84static void __init omap_generic_map_io(void) 120static void __init omap_generic_map_io(void)
85{ 121{
86 omap_map_common_io() 122 omap_map_common_io();
87} 123}
88 124
89MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") 125MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index f4983ee95ab4..d46a70063b0c 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -33,6 +33,7 @@
33#include <asm/mach/map.h> 33#include <asm/mach/map.h>
34 34
35#include <asm/arch/gpio.h> 35#include <asm/arch/gpio.h>
36#include <asm/arch/mux.h>
36#include <asm/arch/tc.h> 37#include <asm/arch/tc.h>
37#include <asm/arch/usb.h> 38#include <asm/arch/usb.h>
38#include <asm/arch/common.h> 39#include <asm/arch/common.h>
@@ -80,8 +81,7 @@ static struct flash_platform_data h2_flash_data = {
80}; 81};
81 82
82static struct resource h2_flash_resource = { 83static struct resource h2_flash_resource = {
83 .start = OMAP_CS2B_PHYS, 84 /* This is on CS3, wherever it's mapped */
84 .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
85 .flags = IORESOURCE_MEM, 85 .flags = IORESOURCE_MEM,
86}; 86};
87 87
@@ -126,10 +126,9 @@ static void __init h2_init_smc91x(void)
126 printk("Error requesting gpio 0 for smc91x irq\n"); 126 printk("Error requesting gpio 0 for smc91x irq\n");
127 return; 127 return;
128 } 128 }
129 omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE);
130} 129}
131 130
132void h2_init_irq(void) 131static void __init h2_init_irq(void)
133{ 132{
134 omap_init_irq(); 133 omap_init_irq();
135 omap_gpio_init(); 134 omap_gpio_init();
@@ -152,9 +151,13 @@ static struct omap_usb_config h2_usb_config __initdata = {
152}; 151};
153 152
154static struct omap_mmc_config h2_mmc_config __initdata = { 153static struct omap_mmc_config h2_mmc_config __initdata = {
155 .mmc_blocks = 1, 154 .mmc [0] = {
156 .mmc1_power_pin = -1, /* tps65010 gpio3 */ 155 .enabled = 1,
157 .mmc1_switch_pin = OMAP_MPUIO(1), 156 .wire4 = 1,
157 .wp_pin = OMAP_MPUIO(3),
158 .power_pin = -1, /* tps65010 gpio3 */
159 .switch_pin = OMAP_MPUIO(1),
160 },
158}; 161};
159 162
160static struct omap_board_config_kernel h2_config[] = { 163static struct omap_board_config_kernel h2_config[] = {
@@ -164,6 +167,16 @@ static struct omap_board_config_kernel h2_config[] = {
164 167
165static void __init h2_init(void) 168static void __init h2_init(void)
166{ 169{
170 /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
171 * and NAND (either 16bit or 8bit) on CS3.
172 */
173 h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
174 h2_flash_resource.end += SZ_32M - 1;
175
176 /* MMC: card detect and WP */
177 // omap_cfg_reg(U19_ARMIO1); /* CD */
178 omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
179
167 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); 180 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
168 omap_board_config = h2_config; 181 omap_board_config = h2_config;
169 omap_board_config_size = ARRAY_SIZE(h2_config); 182 omap_board_config_size = ARRAY_SIZE(h2_config);
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 7cd419d61b40..2798613696fa 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -82,8 +82,7 @@ static struct flash_platform_data h3_flash_data = {
82}; 82};
83 83
84static struct resource h3_flash_resource = { 84static struct resource h3_flash_resource = {
85 .start = OMAP_CS2B_PHYS, 85 /* This is on CS3, wherever it's mapped */
86 .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
87 .flags = IORESOURCE_MEM, 86 .flags = IORESOURCE_MEM,
88}; 87};
89 88
@@ -161,13 +160,26 @@ static struct omap_usb_config h3_usb_config __initdata = {
161 .pins[1] = 3, 160 .pins[1] = 3,
162}; 161};
163 162
163static struct omap_mmc_config h3_mmc_config __initdata = {
164 .mmc[0] = {
165 .enabled = 1,
166 .power_pin = -1, /* tps65010 GPIO4 */
167 .switch_pin = OMAP_MPUIO(1),
168 },
169};
170
164static struct omap_board_config_kernel h3_config[] = { 171static struct omap_board_config_kernel h3_config[] = {
165 { OMAP_TAG_USB, &h3_usb_config }, 172 { OMAP_TAG_USB, &h3_usb_config },
173 { OMAP_TAG_MMC, &h3_mmc_config },
166}; 174};
167 175
168static void __init h3_init(void) 176static void __init h3_init(void)
169{ 177{
178 h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
179 h3_flash_resource.end += OMAP_CS3_SIZE - 1;
170 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 180 (void) platform_add_devices(devices, ARRAY_SIZE(devices));
181 omap_board_config = h3_config;
182 omap_board_config_size = ARRAY_SIZE(h3_config);
171} 183}
172 184
173static void __init h3_init_smc91x(void) 185static void __init h3_init_smc91x(void)
@@ -177,7 +189,6 @@ static void __init h3_init_smc91x(void)
177 printk("Error requesting gpio 40 for smc91x irq\n"); 189 printk("Error requesting gpio 40 for smc91x irq\n");
178 return; 190 return;
179 } 191 }
180 omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE);
181} 192}
182 193
183void h3_init_irq(void) 194void h3_init_irq(void)
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 91de60a91ef8..df0312b596e4 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -29,6 +29,7 @@
29#include <asm/mach/flash.h> 29#include <asm/mach/flash.h>
30#include <asm/mach/map.h> 30#include <asm/mach/map.h>
31 31
32#include <asm/arch/mux.h>
32#include <asm/arch/fpga.h> 33#include <asm/arch/fpga.h>
33#include <asm/arch/gpio.h> 34#include <asm/arch/gpio.h>
34#include <asm/arch/tc.h> 35#include <asm/arch/tc.h>
@@ -173,7 +174,6 @@ static void __init innovator_init_smc91x(void)
173 printk("Error requesting gpio 0 for smc91x irq\n"); 174 printk("Error requesting gpio 0 for smc91x irq\n");
174 return; 175 return;
175 } 176 }
176 omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
177 } 177 }
178} 178}
179 179
@@ -220,8 +220,19 @@ static struct omap_usb_config h2_usb_config __initdata = {
220}; 220};
221#endif 221#endif
222 222
223static struct omap_mmc_config innovator_mmc_config __initdata = {
224 .mmc [0] = {
225 .enabled = 1,
226 .wire4 = 1,
227 .wp_pin = OMAP_MPUIO(3),
228 .power_pin = -1, /* FPGA F3 UIO42 */
229 .switch_pin = -1, /* FPGA F4 UIO43 */
230 },
231};
232
223static struct omap_board_config_kernel innovator_config[] = { 233static struct omap_board_config_kernel innovator_config[] = {
224 { OMAP_TAG_USB, NULL }, 234 { OMAP_TAG_USB, NULL },
235 { OMAP_TAG_MMC, &innovator_mmc_config },
225}; 236};
226 237
227static void __init innovator_init(void) 238static void __init innovator_init(void)
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 6750b2014092..d904e643f5ec 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -75,16 +75,15 @@ static void __init netstar_init(void)
75 mdelay(50); /* 50ms until PHY ready */ 75 mdelay(50); /* 50ms until PHY ready */
76 /* smc91x interrupt pin */ 76 /* smc91x interrupt pin */
77 omap_request_gpio(8); 77 omap_request_gpio(8);
78 omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
79 78
80 omap_request_gpio(12); 79 omap_request_gpio(12);
81 omap_request_gpio(13); 80 omap_request_gpio(13);
82 omap_request_gpio(14); 81 omap_request_gpio(14);
83 omap_request_gpio(15); 82 omap_request_gpio(15);
84 omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE); 83 set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
85 omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE); 84 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
86 omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE); 85 set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
87 omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE); 86 set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
88 87
89 platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices)); 88 platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
90 89
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 6844e536c698..21103df50415 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -29,11 +29,16 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/interrupt.h>
33
34#include <linux/mtd/mtd.h>
35#include <linux/mtd/partitions.h>
32 36
33#include <asm/hardware.h> 37#include <asm/hardware.h>
34#include <asm/mach-types.h> 38#include <asm/mach-types.h>
35#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
36#include <asm/mach/map.h> 40#include <asm/mach/map.h>
41#include <asm/mach/flash.h>
37 42
38#include <asm/arch/gpio.h> 43#include <asm/arch/gpio.h>
39#include <asm/arch/usb.h> 44#include <asm/arch/usb.h>
@@ -41,12 +46,56 @@
41#include <asm/arch/tc.h> 46#include <asm/arch/tc.h>
42#include <asm/arch/common.h> 47#include <asm/arch/common.h>
43 48
44static struct map_desc osk5912_io_desc[] __initdata = { 49static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
45{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE, 50
46 MT_DEVICE }, 51static struct mtd_partition osk_partitions[] = {
52 /* bootloader (U-Boot, etc) in first sector */
53 {
54 .name = "bootloader",
55 .offset = 0,
56 .size = SZ_128K,
57 .mask_flags = MTD_WRITEABLE, /* force read-only */
58 },
59 /* bootloader params in the next sector */
60 {
61 .name = "params",
62 .offset = MTDPART_OFS_APPEND,
63 .size = SZ_128K,
64 .mask_flags = 0,
65 }, {
66 .name = "kernel",
67 .offset = MTDPART_OFS_APPEND,
68 .size = SZ_2M,
69 .mask_flags = 0
70 }, {
71 .name = "filesystem",
72 .offset = MTDPART_OFS_APPEND,
73 .size = MTDPART_SIZ_FULL,
74 .mask_flags = 0
75 }
47}; 76};
48 77
49static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0}; 78static struct flash_platform_data osk_flash_data = {
79 .map_name = "cfi_probe",
80 .width = 2,
81 .parts = osk_partitions,
82 .nr_parts = ARRAY_SIZE(osk_partitions),
83};
84
85static struct resource osk_flash_resource = {
86 /* this is on CS3, wherever it's mapped */
87 .flags = IORESOURCE_MEM,
88};
89
90static struct platform_device osk5912_flash_device = {
91 .name = "omapflash",
92 .id = 0,
93 .dev = {
94 .platform_data = &osk_flash_data,
95 },
96 .num_resources = 1,
97 .resource = &osk_flash_resource,
98};
50 99
51static struct resource osk5912_smc91x_resources[] = { 100static struct resource osk5912_smc91x_resources[] = {
52 [0] = { 101 [0] = {
@@ -86,9 +135,16 @@ static struct platform_device osk5912_cf_device = {
86 .resource = osk5912_cf_resources, 135 .resource = osk5912_cf_resources,
87}; 136};
88 137
138static struct platform_device osk5912_mcbsp1_device = {
139 .name = "omap_mcbsp",
140 .id = 1,
141};
142
89static struct platform_device *osk5912_devices[] __initdata = { 143static struct platform_device *osk5912_devices[] __initdata = {
144 &osk5912_flash_device,
90 &osk5912_smc91x_device, 145 &osk5912_smc91x_device,
91 &osk5912_cf_device, 146 &osk5912_cf_device,
147 &osk5912_mcbsp1_device,
92}; 148};
93 149
94static void __init osk_init_smc91x(void) 150static void __init osk_init_smc91x(void)
@@ -97,7 +153,6 @@ static void __init osk_init_smc91x(void)
97 printk("Error requesting gpio 0 for smc91x irq\n"); 153 printk("Error requesting gpio 0 for smc91x irq\n");
98 return; 154 return;
99 } 155 }
100 omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
101 156
102 /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ 157 /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
103 EMIFS_CCS(1) |= 0x2; 158 EMIFS_CCS(1) |= 0x2;
@@ -110,11 +165,11 @@ static void __init osk_init_cf(void)
110 printk("Error requesting gpio 62 for CF irq\n"); 165 printk("Error requesting gpio 62 for CF irq\n");
111 return; 166 return;
112 } 167 }
113 /* it's really active-low */ 168 /* the CF I/O IRQ is really active-low */
114 omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE); 169 set_irq_type(OMAP_GPIO_IRQ(62), IRQT_FALLING);
115} 170}
116 171
117void osk_init_irq(void) 172static void __init osk_init_irq(void)
118{ 173{
119 omap_init_irq(); 174 omap_init_irq();
120 omap_gpio_init(); 175 omap_gpio_init();
@@ -142,18 +197,69 @@ static struct omap_board_config_kernel osk_config[] = {
142 { OMAP_TAG_USB, &osk_usb_config }, 197 { OMAP_TAG_USB, &osk_usb_config },
143}; 198};
144 199
200#ifdef CONFIG_OMAP_OSK_MISTRAL
201
202#ifdef CONFIG_PM
203static irqreturn_t
204osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
205{
206 return IRQ_HANDLED;
207}
208#endif
209
210static void __init osk_mistral_init(void)
211{
212 /* FIXME here's where to feed in framebuffer, touchpad, and
213 * keyboard setup ... not in the drivers for those devices!
214 *
215 * NOTE: we could actually tell if there's a Mistral board
216 * attached, e.g. by trying to read something from the ads7846.
217 * But this is too early for that...
218 */
219
220 /* the sideways button (SW1) is for use as a "wakeup" button */
221 omap_cfg_reg(N15_1610_MPUIO2);
222 if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
223 int ret = 0;
224 omap_set_gpio_direction(OMAP_MPUIO(2), 1);
225 set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING);
226#ifdef CONFIG_PM
227 /* share the IRQ in case someone wants to use the
228 * button for more than wakeup from system sleep.
229 */
230 ret = request_irq(OMAP_GPIO_IRQ(OMAP_MPUIO(2)),
231 &osk_mistral_wake_interrupt,
232 SA_SHIRQ, "mistral_wakeup",
233 &osk_mistral_wake_interrupt);
234 if (ret != 0) {
235 omap_free_gpio(OMAP_MPUIO(2));
236 printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n",
237 ret);
238 } else
239 enable_irq_wake(OMAP_GPIO_IRQ(OMAP_MPUIO(2)));
240#endif
241 } else
242 printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
243}
244#else
245static void __init osk_mistral_init(void) { }
246#endif
247
145static void __init osk_init(void) 248static void __init osk_init(void)
146{ 249{
250 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
251 osk_flash_resource.end += SZ_32M - 1;
147 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); 252 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
148 omap_board_config = osk_config; 253 omap_board_config = osk_config;
149 omap_board_config_size = ARRAY_SIZE(osk_config); 254 omap_board_config_size = ARRAY_SIZE(osk_config);
150 USB_TRANSCEIVER_CTRL_REG |= (3 << 1); 255 USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
256
257 osk_mistral_init();
151} 258}
152 259
153static void __init osk_map_io(void) 260static void __init osk_map_io(void)
154{ 261{
155 omap_map_common_io(); 262 omap_map_common_io();
156 iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
157 omap_serial_init(osk_serial_ports); 263 omap_serial_init(osk_serial_ports);
158} 264}
159 265
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 213317392d9b..107c68c8ab54 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -24,6 +24,7 @@
24#include <asm/mach/flash.h> 24#include <asm/mach/flash.h>
25#include <asm/mach/map.h> 25#include <asm/mach/map.h>
26 26
27#include <asm/arch/tc.h>
27#include <asm/arch/gpio.h> 28#include <asm/arch/gpio.h>
28#include <asm/arch/mux.h> 29#include <asm/arch/mux.h>
29#include <asm/arch/fpga.h> 30#include <asm/arch/fpga.h>
@@ -83,8 +84,8 @@ static struct flash_platform_data p2_flash_data = {
83}; 84};
84 85
85static struct resource p2_flash_resource = { 86static struct resource p2_flash_resource = {
86 .start = OMAP_FLASH_0_START, 87 .start = OMAP_CS0_PHYS,
87 .end = OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1, 88 .end = OMAP_CS0_PHYS + SZ_32M - 1,
88 .flags = IORESOURCE_MEM, 89 .flags = IORESOURCE_MEM,
89}; 90};
90 91
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index e42281988990..bf30b1acda0b 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -25,13 +25,14 @@
25#include <asm/hardware.h> 25#include <asm/hardware.h>
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
28#include <asm/mach/flash.h>
28#include <asm/mach/map.h> 29#include <asm/mach/map.h>
29 30
31#include <asm/arch/common.h>
30#include <asm/arch/gpio.h> 32#include <asm/arch/gpio.h>
31#include <asm/arch/tc.h>
32#include <asm/arch/mux.h> 33#include <asm/arch/mux.h>
34#include <asm/arch/tc.h>
33#include <asm/arch/usb.h> 35#include <asm/arch/usb.h>
34#include <asm/arch/common.h>
35 36
36extern void omap_init_time(void); 37extern void omap_init_time(void);
37extern int omap_gpio_init(void); 38extern int omap_gpio_init(void);
@@ -74,7 +75,7 @@ static struct plat_serial8250_port voiceblue_ports[] = {
74 75
75static struct platform_device serial_device = { 76static struct platform_device serial_device = {
76 .name = "serial8250", 77 .name = "serial8250",
77 .id = 1, 78 .id = PLAT8250_DEV_PLATFORM1,
78 .dev = { 79 .dev = {
79 .platform_data = voiceblue_ports, 80 .platform_data = voiceblue_ports,
80 }, 81 },
@@ -86,6 +87,27 @@ static int __init ext_uart_init(void)
86} 87}
87arch_initcall(ext_uart_init); 88arch_initcall(ext_uart_init);
88 89
90static struct flash_platform_data voiceblue_flash_data = {
91 .map_name = "cfi_probe",
92 .width = 2,
93};
94
95static struct resource voiceblue_flash_resource = {
96 .start = OMAP_CS0_PHYS,
97 .end = OMAP_CS0_PHYS + SZ_32M - 1,
98 .flags = IORESOURCE_MEM,
99};
100
101static struct platform_device voiceblue_flash_device = {
102 .name = "omapflash",
103 .id = 0,
104 .dev = {
105 .platform_data = &voiceblue_flash_data,
106 },
107 .num_resources = 1,
108 .resource = &voiceblue_flash_resource,
109};
110
89static struct resource voiceblue_smc91x_resources[] = { 111static struct resource voiceblue_smc91x_resources[] = {
90 [0] = { 112 [0] = {
91 .start = OMAP_CS2_PHYS + 0x300, 113 .start = OMAP_CS2_PHYS + 0x300,
@@ -107,6 +129,7 @@ static struct platform_device voiceblue_smc91x_device = {
107}; 129};
108 130
109static struct platform_device *voiceblue_devices[] __initdata = { 131static struct platform_device *voiceblue_devices[] __initdata = {
132 &voiceblue_flash_device,
110 &voiceblue_smc91x_device, 133 &voiceblue_smc91x_device,
111}; 134};
112 135
@@ -119,8 +142,17 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
119 .pins[2] = 6, 142 .pins[2] = 6,
120}; 143};
121 144
145static struct omap_mmc_config voiceblue_mmc_config __initdata = {
146 .mmc[0] = {
147 .enabled = 1,
148 .power_pin = 2,
149 .switch_pin = -1,
150 },
151};
152
122static struct omap_board_config_kernel voiceblue_config[] = { 153static struct omap_board_config_kernel voiceblue_config[] = {
123 { OMAP_TAG_USB, &voiceblue_usb_config }, 154 { OMAP_TAG_USB, &voiceblue_usb_config },
155 { OMAP_TAG_MMC, &voiceblue_mmc_config },
124}; 156};
125 157
126static void __init voiceblue_init_irq(void) 158static void __init voiceblue_init_irq(void)
@@ -131,9 +163,6 @@ static void __init voiceblue_init_irq(void)
131 163
132static void __init voiceblue_init(void) 164static void __init voiceblue_init(void)
133{ 165{
134 /* There is a good chance board is going up, so enable Power LED
135 * (it is connected through invertor) */
136 omap_writeb(0x00, OMAP_LPG1_LCR);
137 /* Watchdog */ 166 /* Watchdog */
138 omap_request_gpio(0); 167 omap_request_gpio(0);
139 /* smc91x reset */ 168 /* smc91x reset */
@@ -145,7 +174,6 @@ static void __init voiceblue_init(void)
145 mdelay(50); /* 50ms until PHY ready */ 174 mdelay(50); /* 50ms until PHY ready */
146 /* smc91x interrupt pin */ 175 /* smc91x interrupt pin */
147 omap_request_gpio(8); 176 omap_request_gpio(8);
148 omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
149 /* 16C554 reset*/ 177 /* 16C554 reset*/
150 omap_request_gpio(6); 178 omap_request_gpio(6);
151 omap_set_gpio_direction(6, 0); 179 omap_set_gpio_direction(6, 0);
@@ -155,14 +183,19 @@ static void __init voiceblue_init(void)
155 omap_request_gpio(13); 183 omap_request_gpio(13);
156 omap_request_gpio(14); 184 omap_request_gpio(14);
157 omap_request_gpio(15); 185 omap_request_gpio(15);
158 omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE); 186 set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING);
159 omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE); 187 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
160 omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE); 188 set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING);
161 omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE); 189 set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING);
162 190
163 platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); 191 platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
164 omap_board_config = voiceblue_config; 192 omap_board_config = voiceblue_config;
165 omap_board_config_size = ARRAY_SIZE(voiceblue_config); 193 omap_board_config_size = ARRAY_SIZE(voiceblue_config);
194
195 /* There is a good chance board is going up, so enable power LED
196 * (it is connected through invertor) */
197 omap_writeb(0x00, OMAP_LPG1_LCR);
198 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
166} 199}
167 200
168static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; 201static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
@@ -184,9 +217,9 @@ static int panic_event(struct notifier_block *this, unsigned long event,
184 if (test_and_set_bit(MACHINE_PANICED, &machine_state)) 217 if (test_and_set_bit(MACHINE_PANICED, &machine_state))
185 return NOTIFY_DONE; 218 return NOTIFY_DONE;
186 219
187 /* Flash Power LED 220 /* Flash power LED */
188 * (TODO: Enable clock right way (enabled in bootloader already)) */
189 omap_writeb(0x78, OMAP_LPG1_LCR); 221 omap_writeb(0x78, OMAP_LPG1_LCR);
222 omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
190 223
191 return NOTIFY_DONE; 224 return NOTIFY_DONE;
192} 225}
@@ -195,15 +228,14 @@ static struct notifier_block panic_block = {
195 .notifier_call = panic_event, 228 .notifier_call = panic_event,
196}; 229};
197 230
198static int __init setup_notifier(void) 231static int __init voiceblue_setup(void)
199{ 232{
200 /* Setup panic notifier */ 233 /* Setup panic notifier */
201 notifier_chain_register(&panic_notifier_list, &panic_block); 234 notifier_chain_register(&panic_notifier_list, &panic_block);
202 235
203 return 0; 236 return 0;
204} 237}
205 238postcore_initcall(voiceblue_setup);
206postcore_initcall(setup_notifier);
207 239
208static int wdt_gpio_state; 240static int wdt_gpio_state;
209 241
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
new file mode 100644
index 000000000000..e8b3981444cd
--- /dev/null
+++ b/arch/arm/mach-omap1/devices.c
@@ -0,0 +1,351 @@
1/*
2 * linux/arch/arm/mach-omap1/devices.c
3 *
4 * OMAP1 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/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
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
79/*-------------------------------------------------------------------------*/
80
81#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
82
83static u64 irda_dmamask = 0xffffffff;
84
85static struct platform_device omap1610ir_device = {
86 .name = "omap1610-ir",
87 .id = -1,
88 .dev = {
89 .release = omap_nop_release,
90 .dma_mask = &irda_dmamask,
91 },
92};
93
94static void omap_init_irda(void)
95{
96 /* FIXME define and use a boot tag, members something like:
97 * u8 uart; // uart1, or uart3
98 * ... but driver only handles uart3 for now
99 * s16 fir_sel; // gpio for SIR vs FIR
100 * ... may prefer a callback for SIR/MIR/FIR mode select;
101 * while h2 uses a GPIO, H3 uses a gpio expander
102 */
103 if (machine_is_omap_h2()
104 || machine_is_omap_h3())
105 (void) platform_device_register(&omap1610ir_device);
106}
107#else
108static inline void omap_init_irda(void) {}
109#endif
110
111/*-------------------------------------------------------------------------*/
112
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)
245
246#define OMAP_RTC_BASE 0xfffb4800
247
248static struct resource rtc_resources[] = {
249 {
250 .start = OMAP_RTC_BASE,
251 .end = OMAP_RTC_BASE + 0x5f,
252 .flags = IORESOURCE_MEM,
253 },
254 {
255 .start = INT_RTC_TIMER,
256 .flags = IORESOURCE_IRQ,
257 },
258 {
259 .start = INT_RTC_ALARM,
260 .flags = IORESOURCE_IRQ,
261 },
262};
263
264static struct platform_device omap_rtc_device = {
265 .name = "omap_rtc",
266 .id = -1,
267 .dev = {
268 .release = omap_nop_release,
269 },
270 .num_resources = ARRAY_SIZE(rtc_resources),
271 .resource = rtc_resources,
272};
273
274static void omap_init_rtc(void)
275{
276 (void) platform_device_register(&omap_rtc_device);
277}
278#else
279static inline void omap_init_rtc(void) {}
280#endif
281
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
315/*-------------------------------------------------------------------------*/
316
317/*
318 * This gets called after board-specific INIT_MACHINE, and initializes most
319 * on-chip peripherals accessible on this board (except for few like USB):
320 *
321 * (a) Does any "standard config" pin muxing needed. Board-specific
322 * code will have muxed GPIO pins and done "nonstandard" setup;
323 * that code could live in the boot loader.
324 * (b) Populating board-specific platform_data with the data drivers
325 * rely on to handle wiring variations.
326 * (c) Creating platform devices as meaningful on this board and
327 * with this kernel configuration.
328 *
329 * Claiming GPIOs, and setting their direction and initial values, is the
330 * responsibility of the device drivers. So is responding to probe().
331 *
332 * Board-specific knowlege like creating devices or pin setup is to be
333 * kept out of drivers as much as possible. In particular, pin setup
334 * may be handled by the boot loader, and drivers should expect it will
335 * normally have been done by the time they're probed.
336 */
337static int __init omap_init_devices(void)
338{
339 /* please keep these calls, and their implementations above,
340 * in alphabetical order so they're easier to sort through.
341 */
342 omap_init_i2c();
343 omap_init_irda();
344 omap_init_mmc();
345 omap_init_rtc();
346 omap_init_wdt();
347
348 return 0;
349}
350arch_initcall(omap_init_devices);
351
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index c12a78335625..aca2a120813a 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/fpga.c 2 * linux/arch/arm/mach-omap1/fpga.c
3 * 3 *
4 * Interrupt handler for OMAP-1510 Innovator FPGA 4 * Interrupt handler for OMAP-1510 Innovator FPGA
5 * 5 *
@@ -181,7 +181,7 @@ void omap1510_fpga_init_irq(void)
181 */ 181 */
182 omap_request_gpio(13); 182 omap_request_gpio(13);
183 omap_set_gpio_direction(13, 1); 183 omap_set_gpio_direction(13, 1);
184 omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE); 184 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
185 set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux); 185 set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
186} 186}
187 187
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 207df0fe934d..eb8261d7dead 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -19,6 +19,7 @@
19 19
20extern int clk_init(void); 20extern int clk_init(void);
21extern void omap_check_revision(void); 21extern void omap_check_revision(void);
22extern void omap_sram_init(void);
22 23
23/* 24/*
24 * The machine specific code may provide the extra mapping besides the 25 * The machine specific code may provide the extra mapping besides the
@@ -32,7 +33,6 @@ static struct map_desc omap_io_desc[] __initdata = {
32static struct map_desc omap730_io_desc[] __initdata = { 33static struct map_desc omap730_io_desc[] __initdata = {
33 { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE }, 34 { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE },
34 { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE }, 35 { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
35 { OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE }
36}; 36};
37#endif 37#endif
38 38
@@ -40,27 +40,13 @@ static struct map_desc omap730_io_desc[] __initdata = {
40static struct map_desc omap1510_io_desc[] __initdata = { 40static struct map_desc omap1510_io_desc[] __initdata = {
41 { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE }, 41 { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE },
42 { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE }, 42 { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
43 { OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE }
44}; 43};
45#endif 44#endif
46 45
47#if defined(CONFIG_ARCH_OMAP16XX) 46#if defined(CONFIG_ARCH_OMAP16XX)
48static struct map_desc omap1610_io_desc[] __initdata = { 47static struct map_desc omap16xx_io_desc[] __initdata = {
49 { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, 48 { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE },
50 { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, 49 { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
51 { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE }
52};
53
54static struct map_desc omap5912_io_desc[] __initdata = {
55 { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE },
56 { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
57/*
58 * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
59 * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
60 * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
61 * can be used.
62 */
63 { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE }
64}; 50};
65#endif 51#endif
66 52
@@ -86,14 +72,13 @@ static void __init _omap_map_io(void)
86 } 72 }
87#endif 73#endif
88#if defined(CONFIG_ARCH_OMAP16XX) 74#if defined(CONFIG_ARCH_OMAP16XX)
89 if (cpu_is_omap1610() || cpu_is_omap1710()) { 75 if (cpu_is_omap16xx()) {
90 iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc)); 76 iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
91 }
92 if (cpu_is_omap5912()) {
93 iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
94 } 77 }
95#endif 78#endif
96 79
80 omap_sram_init();
81
97 /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort 82 /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
98 * on a Posted Write in the TIPB Bridge". 83 * on a Posted Write in the TIPB Bridge".
99 */ 84 */
@@ -108,8 +93,9 @@ static void __init _omap_map_io(void)
108/* 93/*
109 * This should only get called from board specific init 94 * This should only get called from board specific init
110 */ 95 */
111void omap_map_common_io(void) 96void __init omap_map_common_io(void)
112{ 97{
113 if (!initialized) 98 if (!initialized)
114 _omap_map_io(); 99 _omap_map_io();
115} 100}
101
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index afd5d67e4ae7..192ce6055faa 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/irq.c 2 * linux/arch/arm/mach-omap1/irq.c
3 * 3 *
4 * Interrupt handler for all OMAP boards 4 * Interrupt handler for all OMAP boards
5 * 5 *
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index ec0d8285f243..be283cda63dd 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/leds-h2p2-debug.c 2 * linux/arch/arm/mach-omap1/leds-h2p2-debug.c
3 * 3 *
4 * Copyright 2003 by Texas Instruments Incorporated 4 * Copyright 2003 by Texas Instruments Incorporated
5 * 5 *
@@ -13,6 +13,7 @@
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>
16 17
17#include <asm/io.h> 18#include <asm/io.h>
18#include <asm/hardware.h> 19#include <asm/hardware.h>
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
index 8043b7d0f66e..c8ffd1ddcded 100644
--- a/arch/arm/mach-omap1/leds-innovator.c
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/leds-innovator.c 2 * linux/arch/arm/mach-omap1/leds-innovator.c
3 */ 3 */
4#include <linux/config.h> 4#include <linux/config.h>
5#include <linux/init.h> 5#include <linux/init.h>
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
index 4a0e8b9d4fc3..2c8bda847c18 100644
--- a/arch/arm/mach-omap1/leds-osk.c
+++ b/arch/arm/mach-omap1/leds-osk.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/leds-osk.c 2 * linux/arch/arm/mach-omap1/leds-osk.c
3 * 3 *
4 * LED driver for OSK, and optionally Mistral QVGA, boards 4 * LED driver for OSK, and optionally Mistral QVGA, boards
5 */ 5 */
@@ -64,7 +64,7 @@ static void tps_work(void *unused)
64 64
65static DECLARE_WORK(work, tps_work, NULL); 65static DECLARE_WORK(work, tps_work, NULL);
66 66
67#ifdef CONFIG_FB_OMAP 67#ifdef CONFIG_OMAP_OSK_MISTRAL
68 68
69/* For now, all system indicators require the Mistral board, since that 69/* For now, all system indicators require the Mistral board, since that
70 * LED can be manipulated without a task context. This LED is either red, 70 * LED can be manipulated without a task context. This LED is either red,
@@ -127,7 +127,7 @@ void osk_leds_event(led_event_t evt)
127 hw_led_state = 0; 127 hw_led_state = 0;
128 break; 128 break;
129 129
130#ifdef CONFIG_FB_OMAP 130#ifdef CONFIG_OMAP_OSK_MISTRAL
131 131
132 case led_timer: 132 case led_timer:
133 hw_led_state ^= TIMER_LED; 133 hw_led_state ^= TIMER_LED;
@@ -144,7 +144,7 @@ void osk_leds_event(led_event_t evt)
144 mistral_setled(); 144 mistral_setled();
145 break; 145 break;
146 146
147#endif /* CONFIG_FB_OMAP */ 147#endif /* CONFIG_OMAP_OSK_MISTRAL */
148 148
149 /* "green" == tps LED1 (leftmost, normally power-good) 149 /* "green" == tps LED1 (leftmost, normally power-good)
150 * works only with DC adapter, not on battery power! 150 * works only with DC adapter, not on battery power!
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
index 8ab21fe98e1b..5c6b1bb6e722 100644
--- a/arch/arm/mach-omap1/leds.c
+++ b/arch/arm/mach-omap1/leds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-omap/leds.c 2 * linux/arch/arm/mach-omap1/leds.c
3 * 3 *
4 * OMAP LEDs dispatcher 4 * OMAP LEDs dispatcher
5 */ 5 */
@@ -20,7 +20,9 @@ omap_leds_init(void)
20 if (machine_is_omap_innovator()) 20 if (machine_is_omap_innovator())
21 leds_event = innovator_leds_event; 21 leds_event = innovator_leds_event;
22 22
23 else if (machine_is_omap_h2() || machine_is_omap_perseus2()) 23 else if (machine_is_omap_h2()
24 || machine_is_omap_h3()
25 || machine_is_omap_perseus2())
24 leds_event = h2p2_dbg_leds_event; 26 leds_event = h2p2_dbg_leds_event;
25 27
26 else if (machine_is_omap_osk()) 28 else if (machine_is_omap_osk())
@@ -30,8 +32,12 @@ omap_leds_init(void)
30 return -1; 32 return -1;
31 33
32 if (machine_is_omap_h2() 34 if (machine_is_omap_h2()
35 || machine_is_omap_h3()
33 || machine_is_omap_perseus2() 36 || machine_is_omap_perseus2()
34 || machine_is_omap_osk()) { 37#ifdef CONFIG_OMAP_OSK_MISTRAL
38 || machine_is_omap_osk()
39#endif
40 ) {
35 41
36 /* LED1/LED2 pins can be used as GPIO (as done here), or by 42 /* LED1/LED2 pins can be used as GPIO (as done here), or by
37 * the LPG (works even in deep sleep!), to drive a bicolor 43 * the LPG (works even in deep sleep!), to drive a bicolor
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 214e5d17c8b5..40c4f7c40e73 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -24,7 +24,11 @@
24 24
25#include <asm/arch/board.h> 25#include <asm/arch/board.h>
26#include <asm/arch/mux.h> 26#include <asm/arch/mux.h>
27#include <asm/arch/gpio.h>
27#include <asm/arch/fpga.h> 28#include <asm/arch/fpga.h>
29#ifdef CONFIG_PM
30#include <asm/arch/pm.h>
31#endif
28 32
29static struct clk * uart1_ck = NULL; 33static struct clk * uart1_ck = NULL;
30static struct clk * uart2_ck = NULL; 34static struct clk * uart2_ck = NULL;
@@ -94,7 +98,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
94 98
95static struct platform_device serial_device = { 99static struct platform_device serial_device = {
96 .name = "serial8250", 100 .name = "serial8250",
97 .id = 0, 101 .id = PLAT8250_DEV_PLATFORM,
98 .dev = { 102 .dev = {
99 .platform_data = serial_platform_data, 103 .platform_data = serial_platform_data,
100 }, 104 },
@@ -193,6 +197,86 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
193 } 197 }
194} 198}
195 199
200#ifdef CONFIG_OMAP_SERIAL_WAKE
201
202static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id,
203 struct pt_regs *regs)
204{
205 /* Need to do something with serial port right after wake-up? */
206 return IRQ_HANDLED;
207}
208
209/*
210 * Reroutes serial RX lines to GPIO lines for the duration of
211 * sleep to allow waking up the device from serial port even
212 * in deep sleep.
213 */
214void omap_serial_wake_trigger(int enable)
215{
216 if (!cpu_is_omap16xx())
217 return;
218
219 if (uart1_ck != NULL) {
220 if (enable)
221 omap_cfg_reg(V14_16XX_GPIO37);
222 else
223 omap_cfg_reg(V14_16XX_UART1_RX);
224 }
225 if (uart2_ck != NULL) {
226 if (enable)
227 omap_cfg_reg(R9_16XX_GPIO18);
228 else
229 omap_cfg_reg(R9_16XX_UART2_RX);
230 }
231 if (uart3_ck != NULL) {
232 if (enable)
233 omap_cfg_reg(L14_16XX_GPIO49);
234 else
235 omap_cfg_reg(L14_16XX_UART3_RX);
236 }
237}
238
239static void __init omap_serial_set_port_wakeup(int gpio_nr)
240{
241 int ret;
242
243 ret = omap_request_gpio(gpio_nr);
244 if (ret < 0) {
245 printk(KERN_ERR "Could not request UART wake GPIO: %i\n",
246 gpio_nr);
247 return;
248 }
249 omap_set_gpio_direction(gpio_nr, 1);
250 set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING);
251 ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
252 0, "serial wakeup", NULL);
253 if (ret) {
254 omap_free_gpio(gpio_nr);
255 printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
256 gpio_nr);
257 return;
258 }
259 enable_irq_wake(OMAP_GPIO_IRQ(gpio_nr));
260}
261
262static int __init omap_serial_wakeup_init(void)
263{
264 if (!cpu_is_omap16xx())
265 return 0;
266
267 if (uart1_ck != NULL)
268 omap_serial_set_port_wakeup(37);
269 if (uart2_ck != NULL)
270 omap_serial_set_port_wakeup(18);
271 if (uart3_ck != NULL)
272 omap_serial_set_port_wakeup(49);
273
274 return 0;
275}
276late_initcall(omap_serial_wakeup_init);
277
278#endif /* CONFIG_OMAP_SERIAL_WAKE */
279
196static int __init omap_init(void) 280static int __init omap_init(void)
197{ 281{
198 return platform_device_register(&serial_device); 282 return platform_device_register(&serial_device);
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index d540539c9bbb..191a9b1ee9b7 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -247,13 +247,6 @@ unsigned long long sched_clock(void)
247#define OMAP_32K_TIMER_TCR 0x04 247#define OMAP_32K_TIMER_TCR 0x04
248 248
249#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) 249#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
250#if (32768 % HZ) != 0
251/* We cannot ignore modulo.
252 * Potential error can be as high as several percent.
253 */
254#define OMAP_32K_TICK_MODULO (32768 % HZ)
255static unsigned modulo_count = 0; /* Counts 1/HZ units */
256#endif
257 250
258/* 251/*
259 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 252 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
@@ -296,13 +289,22 @@ static inline void omap_32k_timer_stop(void)
296} 289}
297 290
298/* 291/*
299 * Rounds down to nearest usec 292 * Rounds down to nearest usec. Note that this will overflow for larger values.
300 */ 293 */
301static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) 294static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
302{ 295{
303 return (ticks_32k * 5*5*5*5*5*5) >> 9; 296 return (ticks_32k * 5*5*5*5*5*5) >> 9;
304} 297}
305 298
299/*
300 * Rounds down to nearest nsec.
301 */
302static inline unsigned long long
303omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
304{
305 return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
306}
307
306static unsigned long omap_32k_last_tick = 0; 308static unsigned long omap_32k_last_tick = 0;
307 309
308/* 310/*
@@ -315,6 +317,15 @@ static unsigned long omap_32k_timer_gettimeoffset(void)
315} 317}
316 318
317/* 319/*
320 * Returns current time from boot in nsecs. It's OK for this to wrap
321 * around for now, as it's just a relative time stamp.
322 */
323unsigned long long sched_clock(void)
324{
325 return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
326}
327
328/*
318 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this 329 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
319 * function is also called from other interrupts to remove latency 330 * function is also called from other interrupts to remove latency
320 * issues with dynamic tick. In the dynamic tick case, we need to lock 331 * issues with dynamic tick. In the dynamic tick case, we need to lock
@@ -330,19 +341,6 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
330 now = omap_32k_sync_timer_read(); 341 now = omap_32k_sync_timer_read();
331 342
332 while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { 343 while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
333#ifdef OMAP_32K_TICK_MODULO
334 /* Modulo addition may put omap_32k_last_tick ahead of now
335 * and cause unwanted repetition of the while loop.
336 */
337 if (unlikely(now - omap_32k_last_tick == ~0))
338 break;
339
340 modulo_count += OMAP_32K_TICK_MODULO;
341 if (modulo_count > HZ) {
342 ++omap_32k_last_tick;
343 modulo_count -= HZ;
344 }
345#endif
346 omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; 344 omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
347 timer_tick(regs); 345 timer_tick(regs);
348 } 346 }
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 8ccffba0018f..366a9bde3d8b 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -22,7 +22,7 @@
22#include <asm/arch/corgi.h> 22#include <asm/arch/corgi.h>
23#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
24 24
25static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED; 25static DEFINE_SPINLOCK(corgi_ssp_lock);
26static struct ssp_dev corgi_ssp_dev; 26static struct ssp_dev corgi_ssp_dev;
27static struct ssp_state corgi_ssp_state; 27static struct ssp_state corgi_ssp_state;
28 28
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index a10268618f74..e3587efec4bf 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -140,7 +140,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
140 140
141static struct platform_device serial_device = { 141static struct platform_device serial_device = {
142 .name = "serial8250", 142 .name = "serial8250",
143 .id = 0, 143 .id = PLAT8250_DEV_PLATFORM,
144 .dev = { 144 .dev = {
145 .platform_data = serial_platform_data, 145 .platform_data = serial_platform_data,
146 }, 146 },
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 4664bd11adc1..0077937a7ab8 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -29,7 +29,7 @@
29#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
30#include <asm/mach/map.h> 30#include <asm/mach/map.h>
31#include <asm/mach/irq.h> 31#include <asm/mach/irq.h>
32 32#include <asm/arch/fb.h>
33#include <asm/hardware.h> 33#include <asm/hardware.h>
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
@@ -103,6 +103,15 @@ struct platform_device s3c_device_lcd = {
103 103
104EXPORT_SYMBOL(s3c_device_lcd); 104EXPORT_SYMBOL(s3c_device_lcd);
105 105
106static struct s3c2410fb_mach_info s3c2410fb_info;
107
108void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
109{
110 memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
111 s3c_device_lcd.dev.platform_data = &s3c2410fb_info;
112}
113EXPORT_SYMBOL(set_s3c2410fb_info);
114
106/* NAND Controller */ 115/* NAND Controller */
107 116
108static struct resource s3c_nand_resource[] = { 117static struct resource s3c_nand_resource[] = {
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index e9182242da95..1a3367da6408 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -381,7 +381,7 @@ static struct plat_serial8250_port bast_sio_data[] = {
381 381
382static struct platform_device bast_sio = { 382static struct platform_device bast_sio = {
383 .name = "serial8250", 383 .name = "serial8250",
384 .id = 0, 384 .id = PLAT8250_DEV_PLATFORM,
385 .dev = { 385 .dev = {
386 .platform_data = &bast_sio_data, 386 .platform_data = &bast_sio_data,
387 }, 387 },
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index ea4fb1a97a50..6ff1889fbd21 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -45,6 +45,9 @@
45 45
46//#include <asm/debug-ll.h> 46//#include <asm/debug-ll.h>
47#include <asm/arch/regs-serial.h> 47#include <asm/arch/regs-serial.h>
48#include <asm/arch/regs-lcd.h>
49
50#include <asm/arch/fb.h>
48 51
49#include <linux/serial_core.h> 52#include <linux/serial_core.h>
50 53
@@ -88,6 +91,48 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] = {
88 91
89 92
90 93
94/**
95 * Set lcd on or off
96 **/
97static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
98 .fixed_syncs= 1,
99 .regs={
100 .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
101 S3C2410_LCDCON1_TFT | \
102 S3C2410_LCDCON1_CLKVAL(0x0C),
103
104 .lcdcon2= S3C2410_LCDCON2_VBPD(7) | \
105 S3C2410_LCDCON2_LINEVAL(319) | \
106 S3C2410_LCDCON2_VFPD(6) | \
107 S3C2410_LCDCON2_VSPW(0),
108
109 .lcdcon3= S3C2410_LCDCON3_HBPD(19) | \
110 S3C2410_LCDCON3_HOZVAL(239) | \
111 S3C2410_LCDCON3_HFPD(7),
112
113 .lcdcon4= S3C2410_LCDCON4_MVAL(0) | \
114 S3C2410_LCDCON4_HSPW(3),
115
116 .lcdcon5= S3C2410_LCDCON5_FRM565 | \
117 S3C2410_LCDCON5_INVVLINE | \
118 S3C2410_LCDCON5_HWSWP,
119 },
120 .lpcsel= 0x02,
121 .gpccon= 0xaa940659,
122 .gpccon_mask= 0xffffffff,
123 .gpcup= 0x0000ffff,
124 .gpcup_mask= 0xffffffff,
125 .gpdcon= 0xaa84aaa0,
126 .gpdcon_mask= 0xffffffff,
127 .gpdup= 0x0000faff,
128 .gpdup_mask= 0xffffffff,
129
130 .width= 240,
131 .height= 320,
132 .xres= {240,240,240},
133 .yres= {320,320,320},
134 .bpp= {16,16,16},
135};
91 136
92static struct platform_device *h1940_devices[] __initdata = { 137static struct platform_device *h1940_devices[] __initdata = {
93 &s3c_device_usb, 138 &s3c_device_usb,
@@ -116,6 +161,11 @@ void __init h1940_init_irq(void)
116 161
117} 162}
118 163
164void __init h1940_init(void)
165{
166 set_s3c2410fb_info(&h1940_lcdcfg);
167}
168
119MACHINE_START(H1940, "IPAQ-H1940") 169MACHINE_START(H1940, "IPAQ-H1940")
120 /* Maintainer: Ben Dooks <ben@fluff.org> */ 170 /* Maintainer: Ben Dooks <ben@fluff.org> */
121 .phys_ram = S3C2410_SDRAM_PA, 171 .phys_ram = S3C2410_SDRAM_PA,
@@ -124,5 +174,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
124 .boot_params = S3C2410_SDRAM_PA + 0x100, 174 .boot_params = S3C2410_SDRAM_PA + 0x100,
125 .map_io = h1940_map_io, 175 .map_io = h1940_map_io,
126 .init_irq = h1940_init_irq, 176 .init_irq = h1940_init_irq,
177 .init_machine = h1940_init,
127 .timer = &s3c24xx_timer, 178 .timer = &s3c24xx_timer,
128MACHINE_END 179MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 924e8464c212..8f9ab2893df4 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -221,7 +221,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
221 221
222static struct platform_device serial_device = { 222static struct platform_device serial_device = {
223 .name = "serial8250", 223 .name = "serial8250",
224 .id = 0, 224 .id = PLAT8250_DEV_PLATFORM,
225 .dev = { 225 .dev = {
226 .platform_data = serial_platform_data, 226 .platform_data = serial_platform_data,
227 }, 227 },
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index e737eae4521f..946c0d11c73b 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -41,7 +41,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
41 41
42static struct platform_device serial_device = { 42static struct platform_device serial_device = {
43 .name = "serial8250", 43 .name = "serial8250",
44 .id = 0, 44 .id = PLAT8250_DEV_PLATFORM,
45 .dev = { 45 .dev = {
46 .platform_data = serial_platform_data, 46 .platform_data = serial_platform_data,
47 }, 47 },
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 191788fb18d1..b0208c992576 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -16,6 +16,58 @@
16#include <asm/tlbflush.h> 16#include <asm/tlbflush.h>
17 17
18#ifdef CONFIG_CPU_CACHE_VIPT 18#ifdef CONFIG_CPU_CACHE_VIPT
19
20void flush_cache_mm(struct mm_struct *mm)
21{
22 if (cache_is_vivt()) {
23 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
24 __cpuc_flush_user_all();
25 return;
26 }
27
28 if (cache_is_vipt_aliasing()) {
29 asm( "mcr p15, 0, %0, c7, c14, 0\n"
30 " mcr p15, 0, %0, c7, c5, 0\n"
31 " mcr p15, 0, %0, c7, c10, 4"
32 :
33 : "r" (0)
34 : "cc");
35 }
36}
37
38void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
39{
40 if (cache_is_vivt()) {
41 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask))
42 __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
43 vma->vm_flags);
44 return;
45 }
46
47 if (cache_is_vipt_aliasing()) {
48 asm( "mcr p15, 0, %0, c7, c14, 0\n"
49 " mcr p15, 0, %0, c7, c5, 0\n"
50 " mcr p15, 0, %0, c7, c10, 4"
51 :
52 : "r" (0)
53 : "cc");
54 }
55}
56
57void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
58{
59 if (cache_is_vivt()) {
60 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
61 unsigned long addr = user_addr & PAGE_MASK;
62 __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
63 }
64 return;
65 }
66
67 if (cache_is_vipt_aliasing())
68 flush_pfn_alias(pfn, user_addr);
69}
70
19#define ALIAS_FLUSH_START 0xffff4000 71#define ALIAS_FLUSH_START 0xffff4000
20 72
21#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) 73#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 0587477c99f2..92f669470142 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -97,6 +97,7 @@
97#define PARAM_VESAPM_OFF 0x30 97#define PARAM_VESAPM_OFF 0x30
98#define PARAM_LFB_PAGES 0x32 98#define PARAM_LFB_PAGES 0x32
99#define PARAM_VESA_ATTRIB 0x34 99#define PARAM_VESA_ATTRIB 0x34
100#define PARAM_CAPABILITIES 0x36
100 101
101/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ 102/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
102#ifdef CONFIG_VIDEO_RETAIN 103#ifdef CONFIG_VIDEO_RETAIN
@@ -233,6 +234,10 @@ mopar_gr:
233 movw 18(%di), %ax 234 movw 18(%di), %ax
234 movl %eax, %fs:(PARAM_LFB_SIZE) 235 movl %eax, %fs:(PARAM_LFB_SIZE)
235 236
237# store mode capabilities
238 movl 10(%di), %eax
239 movl %eax, %fs:(PARAM_CAPABILITIES)
240
236# switching the DAC to 8-bit is for <= 8 bpp only 241# switching the DAC to 8-bit is for <= 8 bpp only
237 movw %fs:(PARAM_LFB_DEPTH), %ax 242 movw %fs:(PARAM_LFB_DEPTH), %ax
238 cmpw $8, %ax 243 cmpw $8, %ax
@@ -1944,7 +1949,7 @@ store_edid:
1944 movw $0x4f15, %ax # do VBE/DDC 1949 movw $0x4f15, %ax # do VBE/DDC
1945 movw $0x01, %bx 1950 movw $0x01, %bx
1946 movw $0x00, %cx 1951 movw $0x00, %cx
1947 movw $0x01, %dx 1952 movw $0x00, %dx
1948 movw $0x140, %di 1953 movw $0x140, %di
1949 int $0x10 1954 int $0x10
1950 1955
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index bf02b5026e62..8ef38544453c 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -467,11 +467,11 @@ static void __init longhaul_setup_voltagescaling(void)
467 } 467 }
468 468
469 if (vrmrev==0) { 469 if (vrmrev==0) {
470 dprintk ("VRM 8.5 \n"); 470 dprintk ("VRM 8.5\n");
471 memcpy (voltage_table, vrm85scales, sizeof(voltage_table)); 471 memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
472 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25; 472 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
473 } else { 473 } else {
474 dprintk ("Mobile VRM \n"); 474 dprintk ("Mobile VRM\n");
475 memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table)); 475 memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
476 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5; 476 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
477 } 477 }
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 327a55d4d1c6..c397b6220430 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -259,7 +259,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
259 259
260 if (model->op_points == NULL) { 260 if (model->op_points == NULL) {
261 /* Matched a non-match */ 261 /* Matched a non-match */
262 dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n", 262 dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n",
263 cpu->x86_model_id); 263 cpu->x86_model_id);
264#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 264#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
265 dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n"); 265 dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
@@ -402,7 +402,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
402 402
403 for (i=0; i<p.state_count; i++) { 403 for (i=0; i<p.state_count; i++) {
404 if (p.states[i].control != p.states[i].status) { 404 if (p.states[i].control != p.states[i].status) {
405 dprintk("Different control (%x) and status values (%x)\n", 405 dprintk("Different control (%llu) and status values (%llu)\n",
406 p.states[i].control, p.states[i].status); 406 p.states[i].control, p.states[i].status);
407 result = -EINVAL; 407 result = -EINVAL;
408 goto err_unreg; 408 goto err_unreg;
@@ -415,7 +415,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
415 } 415 }
416 416
417 if (p.states[i].core_frequency > p.states[0].core_frequency) { 417 if (p.states[i].core_frequency > p.states[0].core_frequency) {
418 dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i, 418 dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i,
419 p.states[i].core_frequency, p.states[0].core_frequency); 419 p.states[i].core_frequency, p.states[0].core_frequency);
420 p.states[i].core_frequency = 0; 420 p.states[i].core_frequency = 0;
421 continue; 421 continue;
@@ -498,13 +498,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
498 if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST)) 498 if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
499 return -ENODEV; 499 return -ENODEV;
500 500
501 for (i = 0; i < N_IDS; i++)
502 if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
503 break;
504
505 if (i != N_IDS)
506 centrino_cpu[policy->cpu] = &cpu_ids[i];
507
508 if (is_const_loops_cpu(policy->cpu)) { 501 if (is_const_loops_cpu(policy->cpu)) {
509 centrino_driver.flags |= CPUFREQ_CONST_LOOPS; 502 centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
510 } 503 }
@@ -513,6 +506,13 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
513 if (policy->cpu != 0) 506 if (policy->cpu != 0)
514 return -ENODEV; 507 return -ENODEV;
515 508
509 for (i = 0; i < N_IDS; i++)
510 if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
511 break;
512
513 if (i != N_IDS)
514 centrino_cpu[policy->cpu] = &cpu_ids[i];
515
516 if (!centrino_cpu[policy->cpu]) { 516 if (!centrino_cpu[policy->cpu]) {
517 dprintk(KERN_INFO PFX "found unsupported CPU with " 517 dprintk(KERN_INFO PFX "found unsupported CPU with "
518 "Enhanced SpeedStep: send /proc/cpuinfo to " 518 "Enhanced SpeedStep: send /proc/cpuinfo to "
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index b25fb6b635ae..2718fb6f6aba 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -99,7 +99,7 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
99 u32 function = GET_SPEEDSTEP_FREQS; 99 u32 function = GET_SPEEDSTEP_FREQS;
100 100
101 if (!(ist_info.event & 0xFFFF)) { 101 if (!(ist_info.event & 0xFFFF)) {
102 dprintk("bug #1422 -- can't read freqs from BIOS\n", result); 102 dprintk("bug #1422 -- can't read freqs from BIOS\n");
103 return -ENODEV; 103 return -ENODEV;
104 } 104 }
105 105
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 889eda2d7b17..1efdc76ae96d 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1634,9 +1634,9 @@ void disable_IO_APIC(void)
1634 clear_IO_APIC(); 1634 clear_IO_APIC();
1635 1635
1636 /* 1636 /*
1637 * If the i82559 is routed through an IOAPIC 1637 * If the i8259 is routed through an IOAPIC
1638 * Put that IOAPIC in virtual wire mode 1638 * Put that IOAPIC in virtual wire mode
1639 * so legacy interrups can be delivered. 1639 * so legacy interrupts can be delivered.
1640 */ 1640 */
1641 pin = find_isa_irq_pin(0, mp_ExtINT); 1641 pin = find_isa_irq_pin(0, mp_ExtINT);
1642 if (pin != -1) { 1642 if (pin != -1) {
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index cafaeffe3818..15949fd08109 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -122,8 +122,8 @@ static int MP_valid_apicid(int apicid, int version)
122 122
123static void __init MP_processor_info (struct mpc_config_processor *m) 123static void __init MP_processor_info (struct mpc_config_processor *m)
124{ 124{
125 int ver, apicid, cpu, found_bsp = 0; 125 int ver, apicid;
126 physid_mask_t tmp; 126 physid_mask_t phys_cpu;
127 127
128 if (!(m->mpc_cpuflag & CPU_ENABLED)) 128 if (!(m->mpc_cpuflag & CPU_ENABLED))
129 return; 129 return;
@@ -181,7 +181,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
181 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 181 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
182 Dprintk(" Bootup CPU\n"); 182 Dprintk(" Bootup CPU\n");
183 boot_cpu_physical_apicid = m->mpc_apicid; 183 boot_cpu_physical_apicid = m->mpc_apicid;
184 found_bsp = 1;
185 } 184 }
186 185
187 if (num_processors >= NR_CPUS) { 186 if (num_processors >= NR_CPUS) {
@@ -195,29 +194,26 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
195 " Processor ignored.\n", maxcpus); 194 " Processor ignored.\n", maxcpus);
196 return; 195 return;
197 } 196 }
198 num_processors++;
199 ver = m->mpc_apicver; 197 ver = m->mpc_apicver;
200 198
201 if (!MP_valid_apicid(apicid, ver)) { 199 if (!MP_valid_apicid(apicid, ver)) {
202 printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", 200 printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
203 m->mpc_apicid, MAX_APICS); 201 m->mpc_apicid, MAX_APICS);
204 --num_processors;
205 return; 202 return;
206 } 203 }
207 204
208 if (found_bsp) 205 cpu_set(num_processors, cpu_possible_map);
209 cpu = 0; 206 num_processors++;
210 else 207 phys_cpu = apicid_to_cpu_present(apicid);
211 cpu = num_processors - 1; 208 physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
212 cpu_set(cpu, cpu_possible_map); 209
213 tmp = apicid_to_cpu_present(apicid);
214 physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
215
216 /* 210 /*
217 * Validate version 211 * Validate version
218 */ 212 */
219 if (ver == 0x0) { 213 if (ver == 0x0) {
220 printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid); 214 printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! "
215 "fixing up to 0x10. (tell your hw vendor)\n",
216 m->mpc_apicid);
221 ver = 0x10; 217 ver = 0x10;
222 } 218 }
223 apic_version[m->mpc_apicid] = ver; 219 apic_version[m->mpc_apicid] = ver;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 340980203b09..7b6368bf8974 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -694,17 +694,22 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
694__attribute__((regparm(3))) 694__attribute__((regparm(3)))
695int do_syscall_trace(struct pt_regs *regs, int entryexit) 695int do_syscall_trace(struct pt_regs *regs, int entryexit)
696{ 696{
697 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0; 697 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
698 /* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall 698 /*
699 * interception. */ 699 * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
700 * interception
701 */
700 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP); 702 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
703 int ret = 0;
701 704
702 /* do the secure computing check first */ 705 /* do the secure computing check first */
703 secure_computing(regs->orig_eax); 706 if (!entryexit)
707 secure_computing(regs->orig_eax);
704 708
705 if (unlikely(current->audit_context)) { 709 if (unlikely(current->audit_context)) {
706 if (entryexit) 710 if (entryexit)
707 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); 711 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
712 regs->eax);
708 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only 713 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
709 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is 714 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
710 * not used, entry.S will call us only on syscall exit, not 715 * not used, entry.S will call us only on syscall exit, not
@@ -738,7 +743,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
738 /* the 0x80 provides a way for the tracing parent to distinguish 743 /* the 0x80 provides a way for the tracing parent to distinguish
739 between a syscall stop and SIGTRAP delivery */ 744 between a syscall stop and SIGTRAP delivery */
740 /* Note that the debugger could change the result of test_thread_flag!*/ 745 /* Note that the debugger could change the result of test_thread_flag!*/
741 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); 746 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
742 747
743 /* 748 /*
744 * this isn't the same as continuing with a signal, but it will do 749 * this isn't the same as continuing with a signal, but it will do
@@ -750,7 +755,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
750 current->exit_code = 0; 755 current->exit_code = 0;
751 } 756 }
752 ret = is_sysemu; 757 ret = is_sysemu;
753 out: 758out:
754 if (unlikely(current->audit_context) && !entryexit) 759 if (unlikely(current->audit_context) && !entryexit)
755 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, 760 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
756 regs->ebx, regs->ecx, regs->edx, regs->esi); 761 regs->ebx, regs->ecx, regs->edx, regs->esi);
@@ -759,6 +764,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
759 764
760 regs->orig_eax = -1; /* force skip of syscall restarting */ 765 regs->orig_eax = -1; /* force skip of syscall restarting */
761 if (unlikely(current->audit_context)) 766 if (unlikely(current->audit_context))
762 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); 767 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
768 regs->eax);
763 return 1; 769 return 1;
764} 770}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index a659d274914c..f3d808451d25 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -139,6 +139,7 @@ struct sys_desc_table_struct {
139 unsigned char table[0]; 139 unsigned char table[0];
140}; 140};
141struct edid_info edid_info; 141struct edid_info edid_info;
142EXPORT_SYMBOL_GPL(edid_info);
142struct ist_info ist_info; 143struct ist_info ist_info;
143#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \ 144#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
144 defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) 145 defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
@@ -1299,7 +1300,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1299 */ 1300 */
1300static void __init register_memory(void) 1301static void __init register_memory(void)
1301{ 1302{
1302 unsigned long gapstart, gapsize; 1303 unsigned long gapstart, gapsize, round;
1303 unsigned long long last; 1304 unsigned long long last;
1304 int i; 1305 int i;
1305 1306
@@ -1344,14 +1345,14 @@ static void __init register_memory(void)
1344 } 1345 }
1345 1346
1346 /* 1347 /*
1347 * Start allocating dynamic PCI memory a bit into the gap, 1348 * See how much we want to round up: start off with
1348 * aligned up to the nearest megabyte. 1349 * rounding to the next 1MB area.
1349 *
1350 * Question: should we try to pad it up a bit (do something
1351 * like " + (gapsize >> 3)" in there too?). We now have the
1352 * technology.
1353 */ 1350 */
1354 pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; 1351 round = 0x100000;
1352 while ((gapsize >> 4) > round)
1353 round += round;
1354 /* Fun with two's complement */
1355 pci_mem_start = (gapstart + round) & -round;
1355 1356
1356 printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", 1357 printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
1357 pci_mem_start, gapstart, gapsize); 1358 pci_mem_start, gapstart, gapsize);
diff --git a/arch/i386/kernel/sigframe.h b/arch/i386/kernel/sigframe.h
index d21b14f5c25c..0b2221711dad 100644
--- a/arch/i386/kernel/sigframe.h
+++ b/arch/i386/kernel/sigframe.h
@@ -1,6 +1,6 @@
1struct sigframe 1struct sigframe
2{ 2{
3 char *pretcode; 3 char __user *pretcode;
4 int sig; 4 int sig;
5 struct sigcontext sc; 5 struct sigcontext sc;
6 struct _fpstate fpstate; 6 struct _fpstate fpstate;
@@ -10,10 +10,10 @@ struct sigframe
10 10
11struct rt_sigframe 11struct rt_sigframe
12{ 12{
13 char *pretcode; 13 char __user *pretcode;
14 int sig; 14 int sig;
15 struct siginfo *pinfo; 15 struct siginfo __user *pinfo;
16 void *puc; 16 void __user *puc;
17 struct siginfo info; 17 struct siginfo info;
18 struct ucontext uc; 18 struct ucontext uc;
19 struct _fpstate fpstate; 19 struct _fpstate fpstate;
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index eefea7c55008..2883a4d4f01f 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -329,8 +329,7 @@ EXPORT_SYMBOL(get_cmos_time);
329 329
330static void sync_cmos_clock(unsigned long dummy); 330static void sync_cmos_clock(unsigned long dummy);
331 331
332static struct timer_list sync_cmos_timer = 332static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
333 TIMER_INITIALIZER(sync_cmos_clock, 0, 0);
334 333
335static void sync_cmos_clock(unsigned long dummy) 334static void sync_cmos_clock(unsigned long dummy)
336{ 335{
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index 3cc480998a47..6d6338500c3c 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -283,9 +283,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
283 /* Write-combine setting is ignored, it is changed via the mtrr 283 /* Write-combine setting is ignored, it is changed via the mtrr
284 * interfaces on this platform. 284 * interfaces on this platform.
285 */ 285 */
286 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 286 if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
287 vma->vm_end - vma->vm_start, 287 vma->vm_end - vma->vm_start,
288 vma->vm_page_prot)) 288 vma->vm_page_prot))
289 return -EAGAIN; 289 return -EAGAIN;
290 290
291 return 0; 291 return 0;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 00151a8320d8..ed25d66c8d50 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -339,12 +339,6 @@ config IA64_PALINFO
339 To use this option, you have to ensure that the "/proc file system 339 To use this option, you have to ensure that the "/proc file system
340 support" (CONFIG_PROC_FS) is enabled, too. 340 support" (CONFIG_PROC_FS) is enabled, too.
341 341
342config ACPI_DEALLOCATE_IRQ
343 bool
344 depends on ACPI
345 depends on IOSAPIC && EXPERIMENTAL
346 default y
347
348source "drivers/firmware/Kconfig" 342source "drivers/firmware/Kconfig"
349 343
350source "fs/Kconfig.binfmt" 344source "fs/Kconfig.binfmt"
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 1ca6e6e11b42..08112ab38468 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -111,7 +111,6 @@ CONFIG_COMPAT=y
111CONFIG_IA64_MCA_RECOVERY=y 111CONFIG_IA64_MCA_RECOVERY=y
112CONFIG_PERFMON=y 112CONFIG_PERFMON=y
113CONFIG_IA64_PALINFO=y 113CONFIG_IA64_PALINFO=y
114CONFIG_ACPI_DEALLOCATE_IRQ=y
115 114
116# 115#
117# Firmware Drivers 116# Firmware Drivers
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 3ec94a12eac0..d452e18ac494 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
109CONFIG_IA64_MCA_RECOVERY=y 109CONFIG_IA64_MCA_RECOVERY=y
110CONFIG_PERFMON=y 110CONFIG_PERFMON=y
111CONFIG_IA64_PALINFO=y 111CONFIG_IA64_PALINFO=y
112CONFIG_ACPI_DEALLOCATE_IRQ=y
113 112
114# 113#
115# Firmware Drivers 114# Firmware Drivers
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index d4cf73d124bc..80b0e9eb7fb3 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
109CONFIG_IA64_MCA_RECOVERY=y 109CONFIG_IA64_MCA_RECOVERY=y
110CONFIG_PERFMON=y 110CONFIG_PERFMON=y
111CONFIG_IA64_PALINFO=y 111CONFIG_IA64_PALINFO=y
112CONFIG_ACPI_DEALLOCATE_IRQ=y
113 112
114# 113#
115# Firmware Drivers 114# Firmware Drivers
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index b6ec8d32c346..5da208115ea1 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -99,7 +99,6 @@ CONFIG_COMPAT=y
99CONFIG_IA64_MCA_RECOVERY=y 99CONFIG_IA64_MCA_RECOVERY=y
100CONFIG_PERFMON=y 100CONFIG_PERFMON=y
101CONFIG_IA64_PALINFO=y 101CONFIG_IA64_PALINFO=y
102CONFIG_ACPI_DEALLOCATE_IRQ=y
103 102
104# 103#
105# Firmware Drivers 104# Firmware Drivers
@@ -335,7 +334,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
335CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 334CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
336# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set 335# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
337# CONFIG_SCSI_IPR is not set 336# CONFIG_SCSI_IPR is not set
338CONFIG_SCSI_QLOGIC_FC=y 337# CONFIG_SCSI_QLOGIC_FC is not set
339# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set 338# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
340CONFIG_SCSI_QLOGIC_1280=y 339CONFIG_SCSI_QLOGIC_1280=y
341# CONFIG_SCSI_QLOGIC_1280_1040 is not set 340# CONFIG_SCSI_QLOGIC_1280_1040 is not set
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 318787c84ac0..28a4529fdd60 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -583,14 +583,12 @@ int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
583 583
584EXPORT_SYMBOL(acpi_register_gsi); 584EXPORT_SYMBOL(acpi_register_gsi);
585 585
586#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
587void acpi_unregister_gsi(u32 gsi) 586void acpi_unregister_gsi(u32 gsi)
588{ 587{
589 iosapic_unregister_intr(gsi); 588 iosapic_unregister_intr(gsi);
590} 589}
591 590
592EXPORT_SYMBOL(acpi_unregister_gsi); 591EXPORT_SYMBOL(acpi_unregister_gsi);
593#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
594 592
595static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) 593static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size)
596{ 594{
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 6d70fec82d0e..ba0b6a1f429f 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -204,9 +204,6 @@ GLOBAL_ENTRY(ia64_switch_to)
204(p6) br.cond.dpnt .map 204(p6) br.cond.dpnt .map
205 ;; 205 ;;
206.done: 206.done:
207(p6) ssm psr.ic // if we had to map, reenable the psr.ic bit FIRST!!!
208 ;;
209(p6) srlz.d
210 ld8 sp=[r21] // load kernel stack pointer of new task 207 ld8 sp=[r21] // load kernel stack pointer of new task
211 mov IA64_KR(CURRENT)=in0 // update "current" application register 208 mov IA64_KR(CURRENT)=in0 // update "current" application register
212 mov r8=r13 // return pointer to previously running task 209 mov r8=r13 // return pointer to previously running task
@@ -234,6 +231,9 @@ GLOBAL_ENTRY(ia64_switch_to)
234 mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped... 231 mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped...
235 ;; 232 ;;
236 itr.d dtr[r25]=r23 // wire in new mapping... 233 itr.d dtr[r25]=r23 // wire in new mapping...
234 ssm psr.ic // reenable the psr.ic bit
235 ;;
236 srlz.d
237 br.cond.sptk .done 237 br.cond.sptk .done
238END(ia64_switch_to) 238END(ia64_switch_to)
239 239
@@ -470,6 +470,29 @@ ENTRY(load_switch_stack)
470 br.cond.sptk.many b7 470 br.cond.sptk.many b7
471END(load_switch_stack) 471END(load_switch_stack)
472 472
473GLOBAL_ENTRY(prefetch_stack)
474 add r14 = -IA64_SWITCH_STACK_SIZE, sp
475 add r15 = IA64_TASK_THREAD_KSP_OFFSET, in0
476 ;;
477 ld8 r16 = [r15] // load next's stack pointer
478 lfetch.fault.excl [r14], 128
479 ;;
480 lfetch.fault.excl [r14], 128
481 lfetch.fault [r16], 128
482 ;;
483 lfetch.fault.excl [r14], 128
484 lfetch.fault [r16], 128
485 ;;
486 lfetch.fault.excl [r14], 128
487 lfetch.fault [r16], 128
488 ;;
489 lfetch.fault.excl [r14], 128
490 lfetch.fault [r16], 128
491 ;;
492 lfetch.fault [r16], 128
493 br.ret.sptk.many rp
494END(prefetch_switch_stack)
495
473GLOBAL_ENTRY(execve) 496GLOBAL_ENTRY(execve)
474 mov r15=__NR_execve // put syscall number in place 497 mov r15=__NR_execve // put syscall number in place
475 break __BREAK_SYSCALL 498 break __BREAK_SYSCALL
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index a13df592ebf7..574084f343fa 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -782,7 +782,6 @@ again:
782 return vector; 782 return vector;
783} 783}
784 784
785#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
786void 785void
787iosapic_unregister_intr (unsigned int gsi) 786iosapic_unregister_intr (unsigned int gsi)
788{ 787{
@@ -865,7 +864,6 @@ iosapic_unregister_intr (unsigned int gsi)
865 spin_unlock(&iosapic_lock); 864 spin_unlock(&iosapic_lock);
866 spin_unlock_irqrestore(&idesc->lock, flags); 865 spin_unlock_irqrestore(&idesc->lock, flags);
867} 866}
868#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
869 867
870/* 868/*
871 * ACPI calls this when it finds an entry for a platform interrupt. 869 * ACPI calls this when it finds an entry for a platform interrupt.
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f1201ac8a116..1650353e3f77 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -38,6 +38,7 @@
38#include <linux/pagemap.h> 38#include <linux/pagemap.h>
39#include <linux/mount.h> 39#include <linux/mount.h>
40#include <linux/bitops.h> 40#include <linux/bitops.h>
41#include <linux/rcupdate.h>
41 42
42#include <asm/errno.h> 43#include <asm/errno.h>
43#include <asm/intrinsics.h> 44#include <asm/intrinsics.h>
@@ -496,7 +497,7 @@ typedef struct {
496static pfm_stats_t pfm_stats[NR_CPUS]; 497static pfm_stats_t pfm_stats[NR_CPUS];
497static pfm_session_t pfm_sessions; /* global sessions information */ 498static pfm_session_t pfm_sessions; /* global sessions information */
498 499
499static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED; 500static DEFINE_SPINLOCK(pfm_alt_install_check);
500static pfm_intr_handler_desc_t *pfm_alt_intr_handler; 501static pfm_intr_handler_desc_t *pfm_alt_intr_handler;
501 502
502static struct proc_dir_entry *perfmon_dir; 503static struct proc_dir_entry *perfmon_dir;
@@ -2217,15 +2218,17 @@ static void
2217pfm_free_fd(int fd, struct file *file) 2218pfm_free_fd(int fd, struct file *file)
2218{ 2219{
2219 struct files_struct *files = current->files; 2220 struct files_struct *files = current->files;
2221 struct fdtable *fdt = files_fdtable(files);
2220 2222
2221 /* 2223 /*
2222 * there ie no fd_uninstall(), so we do it here 2224 * there ie no fd_uninstall(), so we do it here
2223 */ 2225 */
2224 spin_lock(&files->file_lock); 2226 spin_lock(&files->file_lock);
2225 files->fd[fd] = NULL; 2227 rcu_assign_pointer(fdt->fd[fd], NULL);
2226 spin_unlock(&files->file_lock); 2228 spin_unlock(&files->file_lock);
2227 2229
2228 if (file) put_filp(file); 2230 if (file)
2231 put_filp(file);
2229 put_unused_fd(fd); 2232 put_unused_fd(fd);
2230} 2233}
2231 2234
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 6f308e62c137..46c9331e7ab5 100644
--- a/arch/ia64/lib/memcpy_mck.S
+++ b/arch/ia64/lib/memcpy_mck.S
@@ -625,8 +625,11 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \
625 clrrrb 625 clrrrb
626 ;; 626 ;;
627 alloc saved_pfs_stack=ar.pfs,3,3,3,0 627 alloc saved_pfs_stack=ar.pfs,3,3,3,0
628 cmp.lt p8,p0=A,r0
628 sub B = dst0, saved_in0 // how many byte copied so far 629 sub B = dst0, saved_in0 // how many byte copied so far
629 ;; 630 ;;
631(p8) mov A = 0; // A shouldn't be negative, cap it
632 ;;
630 sub C = A, B 633 sub C = A, B
631 sub D = saved_in2, A 634 sub D = saved_in2, A
632 ;; 635 ;;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 24614869e866..3c32af910d60 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -230,9 +230,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
230 return; 230 return;
231 } 231 }
232 232
233 if (ia64_done_with_exception(regs))
234 return;
235
236 /* 233 /*
237 * Since we have no vma's for region 5, we might get here even if the address is 234 * Since we have no vma's for region 5, we might get here even if the address is
238 * valid, due to the VHPT walker inserting a non present translation that becomes 235 * valid, due to the VHPT walker inserting a non present translation that becomes
@@ -243,6 +240,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
243 if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address)) 240 if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
244 return; 241 return;
245 242
243 if (ia64_done_with_exception(regs))
244 return;
245
246 /* 246 /*
247 * Oops. The kernel tried to access some bad page. We'll have to terminate things 247 * Oops. The kernel tried to access some bad page. We'll have to terminate things
248 * with extreme prejudice. 248 * with extreme prejudice.
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9977c122e9fa..9b5de589b82f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -498,13 +498,11 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
498 return acpi_pci_irq_enable(dev); 498 return acpi_pci_irq_enable(dev);
499} 499}
500 500
501#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
502void 501void
503pcibios_disable_device (struct pci_dev *dev) 502pcibios_disable_device (struct pci_dev *dev)
504{ 503{
505 acpi_pci_irq_disable(dev); 504 acpi_pci_irq_disable(dev);
506} 505}
507#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
508 506
509void 507void
510pcibios_align_resource (void *data, struct resource *res, 508pcibios_align_resource (void *data, struct resource *res,
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a594aca959e6..14908ad7db8c 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -56,7 +56,7 @@
56 56
57DEFINE_PER_CPU(struct pda_s, pda_percpu); 57DEFINE_PER_CPU(struct pda_s, pda_percpu);
58 58
59#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */ 59#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */
60 60
61lboard_t *root_lboard[MAX_COMPACT_NODES]; 61lboard_t *root_lboard[MAX_COMPACT_NODES];
62 62
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index bb1d5cf30440..ed7c21586e98 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -885,6 +885,10 @@ xpc_init(void)
885 pid_t pid; 885 pid_t pid;
886 886
887 887
888 if (!ia64_platform_is("sn2")) {
889 return -ENODEV;
890 }
891
888 /* 892 /*
889 * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng 893 * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
890 * both a partition's reserved page and its XPC variables. Its size was 894 * both a partition's reserved page and its XPC variables. Its size was
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
index 78c13d676fa6..e5c6d3c0a8e9 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -130,7 +130,7 @@ struct net_device *xpnet_device;
130 */ 130 */
131static u64 xpnet_broadcast_partitions; 131static u64 xpnet_broadcast_partitions;
132/* protect above */ 132/* protect above */
133static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED; 133static DEFINE_SPINLOCK(xpnet_broadcast_lock);
134 134
135/* 135/*
136 * Since the Block Transfer Engine (BTE) is being used for the transfer 136 * Since the Block Transfer Engine (BTE) is being used for the transfer
@@ -636,6 +636,10 @@ xpnet_init(void)
636 int result = -ENOMEM; 636 int result = -ENOMEM;
637 637
638 638
639 if (!ia64_platform_is("sn2")) {
640 return -ENODEV;
641 }
642
639 dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME); 643 dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
640 644
641 /* 645 /*
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index cb5d93630467..bd5d134e9f12 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -63,7 +63,7 @@ void __init amiga_init_sound(void)
63} 63}
64 64
65static void nosound( unsigned long ignored ); 65static void nosound( unsigned long ignored );
66static struct timer_list sound_timer = TIMER_INITIALIZER(nosound, 0, 0); 66static DEFINE_TIMER(sound_timer, nosound, 0, 0);
67 67
68void amiga_mksound( unsigned int hz, unsigned int ticks ) 68void amiga_mksound( unsigned int hz, unsigned int ticks )
69{ 69{
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 44c5cd2ad6a8..8f0640847ad2 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -56,8 +56,7 @@ static void ( *mac_special_bell )( unsigned int, unsigned int, unsigned int );
56/* 56/*
57 * our timer to start/continue/stop the bell 57 * our timer to start/continue/stop the bell
58 */ 58 */
59static struct timer_list mac_sound_timer = 59static DEFINE_TIMER(mac_sound_timer, mac_nosound, 0, 0);
60 TIMER_INITIALIZER(mac_nosound, 0, 0);
61 60
62/* 61/*
63 * Sort of initialize the sound chip (called from mac_mksound on the first 62 * Sort of initialize the sound chip (called from mac_mksound on the first
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
new file mode 100644
index 000000000000..c1578b016160
--- /dev/null
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -0,0 +1,19 @@
1#
2# Makefile for the m68knommu linux kernel.
3#
4
5#
6# If you want to play with the HW breakpoints then you will
7# need to add define this, which will give you a stack backtrace
8# on the console port whenever a DBG interrupt occurs. You have to
9# set up you HW breakpoints to trigger a DBG interrupt:
10#
11# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
12# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
13#
14
15ifdef CONFIG_FULLDEBUG
16AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
17endif
18
19obj-y := config.o
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 5cb28690f89a..cf36e7d007b9 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -104,11 +104,11 @@ int mcf_timerirqpending(int timer)
104 104
105void config_BSP(char *commandp, int size) 105void config_BSP(char *commandp, int size)
106{ 106{
107#if 0 107#if defined (CONFIG_MOD5272)
108 volatile unsigned long *pivrp; 108 volatile unsigned char *pivrp;
109 109
110 /* Set base of device vectors to be 64 */ 110 /* Set base of device vectors to be 64 */
111 pivrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PIVR); 111 pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR);
112 *pivrp = 0x40; 112 *pivrp = 0x40;
113#endif 113#endif
114 114
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 84b6b70641e1..6fe5a2b8fb08 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -19,6 +19,7 @@ endif
19obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o 19obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
20obj-$(CONFIG_M5206) += timers.o 20obj-$(CONFIG_M5206) += timers.o
21obj-$(CONFIG_M5206e) += timers.o 21obj-$(CONFIG_M5206e) += timers.o
22obj-$(CONFIG_M523x) += pit.o
22obj-$(CONFIG_M5249) += timers.o 23obj-$(CONFIG_M5249) += timers.o
23obj-$(CONFIG_M527x) += pit.o 24obj-$(CONFIG_M527x) += pit.o
24obj-$(CONFIG_M5272) += timers.o 25obj-$(CONFIG_M5272) += timers.o
diff --git a/arch/m68knommu/platform/68328/config.c b/arch/m68knommu/platform/68328/config.c
index fd7c93f86481..bcfa5d7fe1e2 100644
--- a/arch/m68knommu/platform/68328/config.c
+++ b/arch/m68knommu/platform/68328/config.c
@@ -1,5 +1,7 @@
1/***************************************************************************/
2
1/* 3/*
2 * linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c 4 * linux/arch/m68knommu/platform/68328/config.c
3 * 5 *
4 * Copyright (C) 1993 Hamish Macdonald 6 * Copyright (C) 1993 Hamish Macdonald
5 * Copyright (C) 1999 D. Jeff Dionne 7 * Copyright (C) 1999 D. Jeff Dionne
@@ -11,6 +13,8 @@
11 * VZ Support/Fixes Evan Stawnyczy <e@lineo.ca> 13 * VZ Support/Fixes Evan Stawnyczy <e@lineo.ca>
12 */ 14 */
13 15
16/***************************************************************************/
17
14#include <asm/dbg.h> 18#include <asm/dbg.h>
15#include <stdarg.h> 19#include <stdarg.h>
16#include <linux/config.h> 20#include <linux/config.h>
@@ -29,76 +33,16 @@
29#include <asm/machdep.h> 33#include <asm/machdep.h>
30#include <asm/MC68328.h> 34#include <asm/MC68328.h>
31 35
36/***************************************************************************/
32 37
33void BSP_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) 38void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
34{ 39void m68328_timer_tick(void);
35 40unsigned long m68328_timer_gettimeoffset(void);
36#ifdef CONFIG_XCOPILOT_BUGS 41void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
37 /*
38 * The only thing I know is that CLK32 is not available on Xcopilot
39 * I have little idea about what frequency SYSCLK has on Xcopilot.
40 * The values for prescaler and compare registers were simply
41 * taken from the original source
42 */
43
44 /* Restart mode, Enable int, SYSCLK, Enable timer */
45 TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN;
46 /* Set prescaler */
47 TPRER2 = 2;
48 /* Set compare register */
49 TCMP2 = 0xd7e4;
50#else
51 /* Restart mode, Enable int, 32KHz, Enable timer */
52 TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
53 /* Set prescaler (Divide 32KHz by 32)*/
54 TPRER2 = 31;
55 /* Set compare register 32Khz / 32 / 10 = 100 */
56 TCMP2 = 10;
57#endif
58
59 request_irq(TMR2_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
60}
61
62void BSP_tick(void)
63{
64 /* Reset Timer2 */
65 TSTAT2 &= 0;
66}
67 42
68unsigned long BSP_gettimeoffset (void) 43/***************************************************************************/
69{
70 return 0;
71}
72 44
73void BSP_gettod (int *yearp, int *monp, int *dayp, 45void m68328_reset (void)
74 int *hourp, int *minp, int *secp)
75{
76}
77
78int BSP_hwclk(int op, struct hwclk_time *t)
79{
80 if (!op) {
81 /* read */
82 } else {
83 /* write */
84 }
85 return 0;
86}
87
88int BSP_set_clock_mmss (unsigned long nowtime)
89{
90#if 0
91 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
92
93 tod->second1 = real_seconds / 10;
94 tod->second2 = real_seconds % 10;
95 tod->minute1 = real_minutes / 10;
96 tod->minute2 = real_minutes % 10;
97#endif
98 return 0;
99}
100
101void BSP_reset (void)
102{ 46{
103 local_irq_disable(); 47 local_irq_disable();
104 asm volatile ("moveal #0x10c00000, %a0;\n\t" 48 asm volatile ("moveal #0x10c00000, %a0;\n\t"
@@ -108,18 +52,22 @@ void BSP_reset (void)
108 "jmp (%a0);"); 52 "jmp (%a0);");
109} 53}
110 54
55/***************************************************************************/
56
111void config_BSP(char *command, int len) 57void config_BSP(char *command, int len)
112{ 58{
113 printk(KERN_INFO "\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n"); 59 printk(KERN_INFO "\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
114 printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n"); 60 printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
115 printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n"); 61 printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
116 62
117 mach_sched_init = BSP_sched_init; 63 mach_sched_init = m68328_timer_init;
118 mach_tick = BSP_tick; 64 mach_tick = m68328_timer_tick;
119 mach_gettimeoffset = BSP_gettimeoffset; 65 mach_gettimeoffset = m68328_timer_gettimeoffset;
120 mach_gettod = BSP_gettod; 66 mach_gettod = m68328_timer_gettod;
121 mach_hwclk = NULL; 67 mach_hwclk = NULL;
122 mach_set_clock_mmss = NULL; 68 mach_set_clock_mmss = NULL;
123 mach_reset = BSP_reset; 69 mach_reset = m68328_reset;
124 *command = '\0'; 70 *command = '\0';
125} 71}
72
73/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c
new file mode 100644
index 000000000000..68c2cd6b0030
--- /dev/null
+++ b/arch/m68knommu/platform/68328/timers.c
@@ -0,0 +1,106 @@
1/***************************************************************************/
2
3/*
4 * linux/arch/m68knommu/platform/68328/timers.c
5 *
6 * Copyright (C) 1993 Hamish Macdonald
7 * Copyright (C) 1999 D. Jeff Dionne
8 * Copyright (C) 2001 Georges Menie, Ken Desmet
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive
12 * for more details.
13 */
14
15/***************************************************************************/
16
17#include <linux/config.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/mm.h>
21#include <asm/setup.h>
22#include <asm/system.h>
23#include <asm/pgtable.h>
24#include <asm/irq.h>
25#include <asm/machdep.h>
26#include <asm/MC68VZ328.h>
27
28/***************************************************************************/
29
30#if defined(CONFIG_DRAGEN2)
31/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
32#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
33#define CLOCK_PRE 7
34#define TICKS_PER_JIFFY 41450
35
36#elif defined(CONFIG_XCOPILOT_BUGS)
37/*
38 * The only thing I know is that CLK32 is not available on Xcopilot
39 * I have little idea about what frequency SYSCLK has on Xcopilot.
40 * The values for prescaler and compare registers were simply
41 * taken from the original source
42 */
43#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
44#define CLOCK_PRE 2
45#define TICKS_PER_JIFFY 0xd7e4
46
47#else
48/* default to using the 32Khz clock */
49#define CLOCK_SOURCE TCTL_CLKSOURCE_32KHZ
50#define CLOCK_PRE 31
51#define TICKS_PER_JIFFY 10
52#endif
53
54/***************************************************************************/
55
56void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
57{
58 /* disable timer 1 */
59 TCTL = 0;
60
61 /* set ISR */
62 if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL))
63 panic("Unable to attach timer interrupt\n");
64
65 /* Restart mode, Enable int, Set clock source */
66 TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
67 TPRER = CLOCK_PRE;
68 TCMP = TICKS_PER_JIFFY;
69
70 /* Enable timer 1 */
71 TCTL |= TCTL_TEN;
72}
73
74/***************************************************************************/
75
76void m68328_timer_tick(void)
77{
78 /* Reset Timer1 */
79 TSTAT &= 0;
80}
81/***************************************************************************/
82
83unsigned long m68328_timer_gettimeoffset(void)
84{
85 unsigned long ticks = TCN, offset = 0;
86
87 /* check for pending interrupt */
88 if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
89 offset = 1000000 / HZ;
90 ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
91 return ticks + offset;
92}
93
94/***************************************************************************/
95
96void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
97{
98 long now = RTCTIME;
99
100 *year = *mon = *day = 1;
101 *hour = (now >> 24) % 24;
102 *min = (now >> 16) % 60;
103 *sec = now % 60;
104}
105
106/***************************************************************************/
diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c
index c21971971ff5..d8d56e5de310 100644
--- a/arch/m68knommu/platform/68EZ328/config.c
+++ b/arch/m68knommu/platform/68EZ328/config.c
@@ -1,5 +1,7 @@
1/***************************************************************************/
2
1/* 3/*
2 * linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c 4 * linux/arch/m68knommu/platform/68EZ328/config.c
3 * 5 *
4 * Copyright (C) 1993 Hamish Macdonald 6 * Copyright (C) 1993 Hamish Macdonald
5 * Copyright (C) 1999 D. Jeff Dionne 7 * Copyright (C) 1999 D. Jeff Dionne
@@ -9,6 +11,8 @@
9 * for more details. 11 * for more details.
10 */ 12 */
11 13
14/***************************************************************************/
15
12#include <stdarg.h> 16#include <stdarg.h>
13#include <linux/config.h> 17#include <linux/config.h>
14#include <linux/types.h> 18#include <linux/types.h>
@@ -20,68 +24,22 @@
20#include <asm/setup.h> 24#include <asm/setup.h>
21#include <asm/system.h> 25#include <asm/system.h>
22#include <asm/pgtable.h> 26#include <asm/pgtable.h>
23#include <asm/irq.h>
24#include <asm/machdep.h> 27#include <asm/machdep.h>
25#include <asm/MC68EZ328.h> 28#include <asm/MC68EZ328.h>
26#ifdef CONFIG_UCSIMM 29#ifdef CONFIG_UCSIMM
27#include <asm/bootstd.h> 30#include <asm/bootstd.h>
28#endif 31#endif
29#ifdef CONFIG_PILOT
30#include "PalmV/romfs.h"
31#endif
32
33void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
34{
35 /* Restart mode, Enable int, 32KHz, Enable timer */
36 TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
37 /* Set prescaler (Divide 32KHz by 32)*/
38 TPRER = 31;
39 /* Set compare register 32Khz / 32 / 10 = 100 */
40 TCMP = 10;
41
42 request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
43}
44
45void BSP_tick(void)
46{
47 /* Reset Timer1 */
48 TSTAT &= 0;
49}
50
51unsigned long BSP_gettimeoffset (void)
52{
53 return 0;
54}
55 32
56void BSP_gettod (int *yearp, int *monp, int *dayp, 33/***************************************************************************/
57 int *hourp, int *minp, int *secp)
58{
59}
60 34
61int BSP_hwclk(int op, struct hwclk_time *t) 35void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
62{ 36void m68328_timer_tick(void);
63 if (!op) { 37unsigned long m68328_timer_gettimeoffset(void);
64 /* read */ 38void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
65 } else {
66 /* write */
67 }
68 return 0;
69}
70 39
71int BSP_set_clock_mmss (unsigned long nowtime) 40/***************************************************************************/
72{
73#if 0
74 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
75 41
76 tod->second1 = real_seconds / 10; 42void m68ez328_reset(void)
77 tod->second2 = real_seconds % 10;
78 tod->minute1 = real_minutes / 10;
79 tod->minute2 = real_minutes % 10;
80#endif
81 return 0;
82}
83
84void BSP_reset (void)
85{ 43{
86 local_irq_disable(); 44 local_irq_disable();
87 asm volatile (" 45 asm volatile ("
@@ -93,6 +51,8 @@ void BSP_reset (void)
93 "); 51 ");
94} 52}
95 53
54/***************************************************************************/
55
96unsigned char *cs8900a_hwaddr; 56unsigned char *cs8900a_hwaddr;
97static int errno; 57static int errno;
98 58
@@ -119,11 +79,13 @@ void config_BSP(char *command, int len)
119 else command[0] = 0; 79 else command[0] = 0;
120#endif 80#endif
121 81
122 mach_sched_init = BSP_sched_init; 82 mach_sched_init = m68328_timer_init;
123 mach_tick = BSP_tick; 83 mach_tick = m68328_timer_tick;
124 mach_gettimeoffset = BSP_gettimeoffset; 84 mach_gettimeoffset = m68328_timer_gettimeoffset;
125 mach_gettod = BSP_gettod; 85 mach_gettod = m68328_timer_gettod;
126 mach_hwclk = NULL; 86 mach_hwclk = NULL;
127 mach_set_clock_mmss = NULL; 87 mach_set_clock_mmss = NULL;
128 mach_reset = BSP_reset; 88 mach_reset = m68ez328_reset;
129} 89}
90
91/***************************************************************************/
diff --git a/arch/m68knommu/platform/68VZ328/de2/config.c b/arch/m68knommu/platform/68VZ328/config.c
index d0586197f113..d926524cdf82 100644
--- a/arch/m68knommu/platform/68VZ328/de2/config.c
+++ b/arch/m68knommu/platform/68VZ328/config.c
@@ -1,5 +1,7 @@
1/***************************************************************************/
2
1/* 3/*
2 * linux/arch/m68knommu/platform/MC68VZ328/de2/config.c 4 * linux/arch/m68knommu/platform/68VZ328/config.c
3 * 5 *
4 * Copyright (C) 1993 Hamish Macdonald 6 * Copyright (C) 1993 Hamish Macdonald
5 * Copyright (C) 1999 D. Jeff Dionne 7 * Copyright (C) 1999 D. Jeff Dionne
@@ -10,6 +12,8 @@
10 * for more details. 12 * for more details.
11 */ 13 */
12 14
15/***************************************************************************/
16
13#include <linux/config.h> 17#include <linux/config.h>
14#include <linux/types.h> 18#include <linux/types.h>
15#include <linux/kernel.h> 19#include <linux/kernel.h>
@@ -25,66 +29,25 @@
25#include <asm/irq.h> 29#include <asm/irq.h>
26#include <asm/machdep.h> 30#include <asm/machdep.h>
27#include <asm/MC68VZ328.h> 31#include <asm/MC68VZ328.h>
32#include <asm/bootstd.h>
28 33
29#ifdef CONFIG_INIT_LCD 34#ifdef CONFIG_INIT_LCD
30#include "screen.h" 35#include "bootlogo.h"
31#endif 36#endif
32 37
33/* with a 33.16 MHz clock, this will give usec resolution to the time functions */ 38/***************************************************************************/
34#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
35#define CLOCK_PRE 7
36#define TICKS_PER_JIFFY 41450
37
38static void
39dragen2_sched_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
40{
41 /* disable timer 1 */
42 TCTL = 0;
43
44 /* set ISR */
45 if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL))
46 panic("Unable to attach timer interrupt\n");
47
48 /* Restart mode, Enable int, Set clock source */
49 TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
50 TPRER = CLOCK_PRE;
51 TCMP = TICKS_PER_JIFFY;
52
53 /* Enable timer 1 */
54 TCTL |= TCTL_TEN;
55}
56
57static void dragen2_tick(void)
58{
59 /* Reset Timer1 */
60 TSTAT &= 0;
61}
62
63static unsigned long dragen2_gettimeoffset(void)
64{
65 unsigned long ticks = TCN, offset = 0;
66
67 /* check for pending interrupt */
68 if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
69 offset = 1000000 / HZ;
70
71 ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
72 39
73 return ticks + offset; 40void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
74} 41void m68328_timer_tick(void);
42unsigned long m68328_timer_gettimeoffset(void);
43void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
75 44
76static void dragen2_gettod(int *year, int *mon, int *day, int *hour, 45/***************************************************************************/
77 int *min, int *sec) 46/* Init Drangon Engine hardware */
78{ 47/***************************************************************************/
79 long now = RTCTIME; 48#if defined(CONFIG_DRAGEN2)
80 49
81 *year = *mon = *day = 1; 50static void m68vz328_reset(void)
82 *hour = (now >> 24) % 24;
83 *min = (now >> 16) % 60;
84 *sec = now % 60;
85}
86
87static void dragen2_reset(void)
88{ 51{
89 local_irq_disable(); 52 local_irq_disable();
90 53
@@ -103,7 +66,7 @@ static void dragen2_reset(void)
103 ); 66 );
104} 67}
105 68
106static void init_hardware(void) 69static void init_hardware(char *command, int size)
107{ 70{
108#ifdef CONFIG_DIRECT_IO_ACCESS 71#ifdef CONFIG_DIRECT_IO_ACCESS
109 SCR = 0x10; /* allow user access to internal registers */ 72 SCR = 0x10; /* allow user access to internal registers */
@@ -170,6 +133,60 @@ static void init_hardware(void)
170#endif 133#endif
171} 134}
172 135
136/***************************************************************************/
137/* Init RT-Control uCdimm hardware */
138/***************************************************************************/
139#elif defined(CONFIG_UCDIMM)
140
141static void m68vz328_reset(void)
142{
143 local_irq_disable();
144 asm volatile ("
145 moveal #0x10c00000, %a0;
146 moveb #0, 0xFFFFF300;
147 moveal 0(%a0), %sp;
148 moveal 4(%a0), %a0;
149 jmp (%a0);
150 ");
151}
152
153unsigned char *cs8900a_hwaddr;
154static int errno;
155
156_bsc0(char *, getserialnum)
157_bsc1(unsigned char *, gethwaddr, int, a)
158_bsc1(char *, getbenv, char *, a)
159
160static void init_hardware(char *command, int size)
161{
162 char *p;
163
164 printk(KERN_INFO "uCdimm serial string [%s]\n", getserialnum());
165 p = cs8900a_hwaddr = gethwaddr(0);
166 printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
167 p[0], p[1], p[2], p[3], p[4], p[5]);
168 p = getbenv("APPEND");
169 if (p)
170 strcpy(p, command);
171 else
172 command[0] = 0;
173}
174
175/***************************************************************************/
176#else
177
178static void m68vz328_reset(void)
179{
180}
181
182static void init_hardware(char *command, int size)
183{
184}
185
186/***************************************************************************/
187#endif
188/***************************************************************************/
189
173void config_BSP(char *command, int size) 190void config_BSP(char *command, int size)
174{ 191{
175 printk(KERN_INFO "68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n"); 192 printk(KERN_INFO "68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
@@ -181,11 +198,13 @@ void config_BSP(char *command, int size)
181 memset(command, 0, size); 198 memset(command, 0, size);
182#endif 199#endif
183 200
184 init_hardware(); 201 init_hardware(command, size);
185 202
186 mach_sched_init = (void *)dragen2_sched_init; 203 mach_sched_init = (void *) m68328_timer_init;
187 mach_tick = dragen2_tick; 204 mach_tick = m68328_timer_tick;
188 mach_gettimeoffset = dragen2_gettimeoffset; 205 mach_gettimeoffset = m68328_timer_gettimeoffset;
189 mach_reset = dragen2_reset; 206 mach_gettod = m68328_timer_gettod;
190 mach_gettod = dragen2_gettod; 207 mach_reset = m68vz328_reset;
191} 208}
209
210/***************************************************************************/
diff --git a/arch/m68knommu/platform/68VZ328/ucdimm/config.c b/arch/m68knommu/platform/68VZ328/ucdimm/config.c
deleted file mode 100644
index 2deadaffd81e..000000000000
--- a/arch/m68knommu/platform/68VZ328/ucdimm/config.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * linux/arch/m68knommu/platform/68VZ328/ucdimm/config.c
3 *
4 * Copyright (C) 1993 Hamish Macdonald
5 * Copyright (C) 1999 D. Jeff Dionne
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
9 * for more details.
10 */
11
12#include <stdarg.h>
13#include <linux/config.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/mm.h>
17#include <linux/tty.h>
18#include <linux/console.h>
19
20#include <asm/setup.h>
21#include <asm/system.h>
22#include <asm/pgtable.h>
23#include <asm/irq.h>
24#include <asm/machdep.h>
25#include <asm/MC68VZ328.h>
26#include <asm/bootstd.h>
27
28void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
29{
30 /* Restart mode, Enable int, 32KHz, Enable timer */
31 TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
32 /* Set prescaler (Divide 32KHz by 32)*/
33 TPRER = 31;
34 /* Set compare register 32Khz / 32 / 10 = 100 */
35 TCMP = 10;
36
37 request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
38}
39
40void BSP_tick(void)
41{
42 /* Reset Timer1 */
43 TSTAT &= 0;
44}
45
46unsigned long BSP_gettimeoffset (void)
47{
48 return 0;
49}
50
51void BSP_gettod (int *yearp, int *monp, int *dayp,
52 int *hourp, int *minp, int *secp)
53{
54}
55
56int BSP_hwclk(int op, struct hwclk_time *t)
57{
58 if (!op) {
59 /* read */
60 } else {
61 /* write */
62 }
63 return 0;
64}
65
66int BSP_set_clock_mmss (unsigned long nowtime)
67{
68#if 0
69 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
70
71 tod->second1 = real_seconds / 10;
72 tod->second2 = real_seconds % 10;
73 tod->minute1 = real_minutes / 10;
74 tod->minute2 = real_minutes % 10;
75#endif
76 return 0;
77}
78
79void BSP_reset (void)
80{
81 local_irq_disable();
82 asm volatile ("
83 moveal #0x10c00000, %a0;
84 moveb #0, 0xFFFFF300;
85 moveal 0(%a0), %sp;
86 moveal 4(%a0), %a0;
87 jmp (%a0);
88 ");
89}
90
91unsigned char *cs8900a_hwaddr;
92static int errno;
93
94_bsc0(char *, getserialnum)
95_bsc1(unsigned char *, gethwaddr, int, a)
96_bsc1(char *, getbenv, char *, a)
97
98void config_BSP(char *command, int len)
99{
100 unsigned char *p;
101
102 printk(KERN_INFO "\n68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
103
104 printk(KERN_INFO "uCdimm serial string [%s]\n",getserialnum());
105 p = cs8900a_hwaddr = gethwaddr(0);
106 printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
107 p[0], p[1], p[2], p[3], p[4], p[5]);
108 p = getbenv("APPEND");
109 if (p) strcpy(p,command);
110 else command[0] = 0;
111
112 mach_sched_init = BSP_sched_init;
113 mach_tick = BSP_tick;
114 mach_gettimeoffset = BSP_gettimeoffset;
115 mach_gettod = BSP_gettod;
116 mach_reset = BSP_reset;
117}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8d76eb1ff291..0eb71ac303af 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -154,6 +154,13 @@ config TANBAC_TB0226
154 The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC. 154 The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC.
155 Please refer to <http://www.tanbac.co.jp/> about Mbase. 155 Please refer to <http://www.tanbac.co.jp/> about Mbase.
156 156
157config TANBAC_TB0287
158 bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
159 depends on TANBAC_TB022X
160 help
161 The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC.
162 Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
163
157config VICTOR_MPC30X 164config VICTOR_MPC30X
158 bool "Support for Victor MP-C303/304" 165 bool "Support for Victor MP-C303/304"
159 depends on MACH_VR41XX 166 depends on MACH_VR41XX
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
new file mode 100644
index 000000000000..17b9f2f65ba0
--- /dev/null
+++ b/arch/mips/configs/tb0287_defconfig
@@ -0,0 +1,1041 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13-mm1
4# Thu Sep 1 22:58:34 2005
5#
6CONFIG_MIPS=y
7
8#
9# Code maturity level options
10#
11CONFIG_EXPERIMENTAL=y
12CONFIG_CLEAN_COMPILE=y
13CONFIG_BROKEN_ON_SMP=y
14CONFIG_INIT_ENV_ARG_LIMIT=32
15
16#
17# General setup
18#
19CONFIG_LOCALVERSION=""
20CONFIG_LOCALVERSION_AUTO=y
21CONFIG_SWAP=y
22CONFIG_SYSVIPC=y
23# CONFIG_POSIX_MQUEUE is not set
24# CONFIG_BSD_PROCESS_ACCT is not set
25CONFIG_SYSCTL=y
26# CONFIG_AUDIT is not set
27# CONFIG_HOTPLUG is not set
28CONFIG_KOBJECT_UEVENT=y
29# CONFIG_IKCONFIG is not set
30CONFIG_INITRAMFS_SOURCE=""
31CONFIG_EMBEDDED=y
32CONFIG_KALLSYMS=y
33# CONFIG_KALLSYMS_EXTRA_PASS is not set
34CONFIG_PRINTK=y
35CONFIG_BUG=y
36CONFIG_BASE_FULL=y
37CONFIG_FUTEX=y
38CONFIG_EPOLL=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_SHMEM=y
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45# CONFIG_TINY_SHMEM is not set
46CONFIG_BASE_SMALL=0
47
48#
49# Loadable module support
50#
51CONFIG_MODULES=y
52CONFIG_MODULE_UNLOAD=y
53# CONFIG_MODULE_FORCE_UNLOAD is not set
54CONFIG_OBSOLETE_MODPARM=y
55CONFIG_MODVERSIONS=y
56CONFIG_MODULE_SRCVERSION_ALL=y
57CONFIG_KMOD=y
58CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
59CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
60CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
61CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
62
63#
64# Kernel type
65#
66CONFIG_32BIT=y
67# CONFIG_64BIT is not set
68
69#
70# Machine selection
71#
72# CONFIG_MACH_JAZZ is not set
73CONFIG_MACH_VR41XX=y
74# CONFIG_NEC_CMBVR4133 is not set
75# CONFIG_CASIO_E55 is not set
76# CONFIG_IBM_WORKPAD is not set
77CONFIG_TANBAC_TB022X=y
78# CONFIG_TANBAC_TB0226 is not set
79CONFIG_TANBAC_TB0287=y
80# CONFIG_VICTOR_MPC30X is not set
81# CONFIG_ZAO_CAPCELLA is not set
82CONFIG_PCI_VR41XX=y
83# CONFIG_VRC4173 is not set
84# CONFIG_TOSHIBA_JMR3927 is not set
85# CONFIG_MIPS_COBALT is not set
86# CONFIG_MACH_DECSTATION is not set
87# CONFIG_MIPS_EV64120 is not set
88# CONFIG_MIPS_EV96100 is not set
89# CONFIG_MIPS_IVR is not set
90# CONFIG_LASAT is not set
91# CONFIG_MIPS_ITE8172 is not set
92# CONFIG_MIPS_ATLAS is not set
93# CONFIG_MIPS_MALTA is not set
94# CONFIG_MIPS_SEAD is not set
95# CONFIG_MOMENCO_OCELOT is not set
96# CONFIG_MOMENCO_OCELOT_G is not set
97# CONFIG_MOMENCO_OCELOT_C is not set
98# CONFIG_MOMENCO_OCELOT_3 is not set
99# CONFIG_MOMENCO_JAGUAR_ATX is not set
100# CONFIG_PMC_YOSEMITE is not set
101# CONFIG_DDB5074 is not set
102# CONFIG_DDB5476 is not set
103# CONFIG_DDB5477 is not set
104# CONFIG_QEMU is not set
105# CONFIG_SGI_IP22 is not set
106# CONFIG_SGI_IP27 is not set
107# CONFIG_SGI_IP32 is not set
108# CONFIG_SOC_AU1X00 is not set
109# CONFIG_SIBYTE_SB1xxx_SOC is not set
110# CONFIG_SNI_RM200_PCI is not set
111# CONFIG_TOSHIBA_RBTX4927 is not set
112CONFIG_RWSEM_GENERIC_SPINLOCK=y
113CONFIG_GENERIC_CALIBRATE_DELAY=y
114CONFIG_HAVE_DEC_LOCK=y
115CONFIG_DMA_NONCOHERENT=y
116CONFIG_DMA_NEED_PCI_MAP_STATE=y
117CONFIG_CPU_LITTLE_ENDIAN=y
118CONFIG_IRQ_CPU=y
119CONFIG_MIPS_L1_CACHE_SHIFT=5
120
121#
122# CPU selection
123#
124# CONFIG_CPU_MIPS32 is not set
125# CONFIG_CPU_MIPS64 is not set
126# CONFIG_CPU_R3000 is not set
127# CONFIG_CPU_TX39XX is not set
128CONFIG_CPU_VR41XX=y
129# CONFIG_CPU_R4300 is not set
130# CONFIG_CPU_R4X00 is not set
131# CONFIG_CPU_TX49XX is not set
132# CONFIG_CPU_R5000 is not set
133# CONFIG_CPU_R5432 is not set
134# CONFIG_CPU_R6000 is not set
135# CONFIG_CPU_NEVADA is not set
136# CONFIG_CPU_R8000 is not set
137# CONFIG_CPU_R10000 is not set
138# CONFIG_CPU_RM7000 is not set
139# CONFIG_CPU_RM9000 is not set
140# CONFIG_CPU_SB1 is not set
141CONFIG_PAGE_SIZE_4KB=y
142# CONFIG_PAGE_SIZE_8KB is not set
143# CONFIG_PAGE_SIZE_16KB is not set
144# CONFIG_PAGE_SIZE_64KB is not set
145# CONFIG_CPU_ADVANCED is not set
146CONFIG_CPU_HAS_SYNC=y
147CONFIG_ARCH_FLATMEM_ENABLE=y
148CONFIG_SELECT_MEMORY_MODEL=y
149CONFIG_FLATMEM_MANUAL=y
150# CONFIG_DISCONTIGMEM_MANUAL is not set
151# CONFIG_SPARSEMEM_MANUAL is not set
152CONFIG_FLATMEM=y
153CONFIG_FLAT_NODE_MEM_MAP=y
154# CONFIG_SPARSEMEM_STATIC is not set
155# CONFIG_PREEMPT is not set
156
157#
158# Bus options (PCI, PCMCIA, EISA, ISA, TC)
159#
160CONFIG_HW_HAS_PCI=y
161CONFIG_PCI=y
162# CONFIG_PCI_LEGACY_PROC is not set
163CONFIG_MMU=y
164
165#
166# PCCARD (PCMCIA/CardBus) support
167#
168# CONFIG_PCCARD is not set
169
170#
171# PCI Hotplug Support
172#
173# CONFIG_HOTPLUG_PCI is not set
174
175#
176# Executable file formats
177#
178CONFIG_BINFMT_ELF=y
179# CONFIG_BINFMT_MISC is not set
180CONFIG_TRAD_SIGNALS=y
181
182#
183# Networking
184#
185CONFIG_NET=y
186
187#
188# Networking options
189#
190CONFIG_PACKET=y
191# CONFIG_PACKET_MMAP is not set
192CONFIG_UNIX=y
193CONFIG_XFRM=y
194CONFIG_XFRM_USER=m
195# CONFIG_NET_KEY is not set
196CONFIG_INET=y
197CONFIG_IP_MULTICAST=y
198CONFIG_IP_ADVANCED_ROUTER=y
199CONFIG_ASK_IP_FIB_HASH=y
200# CONFIG_IP_FIB_TRIE is not set
201CONFIG_IP_FIB_HASH=y
202CONFIG_IP_MULTIPLE_TABLES=y
203CONFIG_IP_ROUTE_MULTIPATH=y
204# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
205CONFIG_IP_ROUTE_VERBOSE=y
206CONFIG_IP_PNP=y
207# CONFIG_IP_PNP_DHCP is not set
208CONFIG_IP_PNP_BOOTP=y
209# CONFIG_IP_PNP_RARP is not set
210CONFIG_NET_IPIP=m
211CONFIG_NET_IPGRE=m
212# CONFIG_NET_IPGRE_BROADCAST is not set
213# CONFIG_IP_MROUTE is not set
214# CONFIG_ARPD is not set
215CONFIG_SYN_COOKIES=y
216# CONFIG_INET_AH is not set
217# CONFIG_INET_ESP is not set
218# CONFIG_INET_IPCOMP is not set
219CONFIG_INET_TUNNEL=m
220CONFIG_INET_DIAG=y
221CONFIG_INET_TCP_DIAG=y
222CONFIG_TCP_CONG_ADVANCED=y
223
224#
225# TCP congestion control
226#
227CONFIG_TCP_CONG_BIC=y
228CONFIG_TCP_CONG_WESTWOOD=m
229CONFIG_TCP_CONG_HTCP=m
230# CONFIG_TCP_CONG_HSTCP is not set
231# CONFIG_TCP_CONG_HYBLA is not set
232# CONFIG_TCP_CONG_VEGAS is not set
233# CONFIG_TCP_CONG_SCALABLE is not set
234# CONFIG_IPV6 is not set
235# CONFIG_NETFILTER is not set
236
237#
238# DCCP Configuration (EXPERIMENTAL)
239#
240# CONFIG_IP_DCCP is not set
241
242#
243# SCTP Configuration (EXPERIMENTAL)
244#
245# CONFIG_IP_SCTP is not set
246# CONFIG_ATM is not set
247# CONFIG_BRIDGE is not set
248# CONFIG_VLAN_8021Q is not set
249# CONFIG_DECNET is not set
250# CONFIG_LLC2 is not set
251# CONFIG_IPX is not set
252# CONFIG_ATALK is not set
253# CONFIG_X25 is not set
254# CONFIG_LAPB is not set
255# CONFIG_NET_DIVERT is not set
256# CONFIG_ECONET is not set
257# CONFIG_WAN_ROUTER is not set
258# CONFIG_NET_SCHED is not set
259# CONFIG_NET_CLS_ROUTE is not set
260
261#
262# Network testing
263#
264# CONFIG_NET_PKTGEN is not set
265# CONFIG_NETFILTER_NETLINK is not set
266# CONFIG_HAMRADIO is not set
267# CONFIG_IRDA is not set
268# CONFIG_BT is not set
269# CONFIG_IEEE80211 is not set
270
271#
272# Device Drivers
273#
274
275#
276# Generic Driver Options
277#
278CONFIG_STANDALONE=y
279CONFIG_PREVENT_FIRMWARE_BUILD=y
280# CONFIG_FW_LOADER is not set
281
282#
283# Memory Technology Devices (MTD)
284#
285# CONFIG_MTD is not set
286
287#
288# Parallel port support
289#
290# CONFIG_PARPORT is not set
291
292#
293# Plug and Play support
294#
295
296#
297# Block devices
298#
299# CONFIG_BLK_DEV_FD is not set
300# CONFIG_BLK_CPQ_DA is not set
301# CONFIG_BLK_CPQ_CISS_DA is not set
302# CONFIG_BLK_DEV_DAC960 is not set
303# CONFIG_BLK_DEV_UMEM is not set
304# CONFIG_BLK_DEV_COW_COMMON is not set
305CONFIG_BLK_DEV_LOOP=m
306# CONFIG_BLK_DEV_CRYPTOLOOP is not set
307CONFIG_BLK_DEV_NBD=m
308# CONFIG_BLK_DEV_SX8 is not set
309# CONFIG_BLK_DEV_UB is not set
310CONFIG_BLK_DEV_RAM=y
311CONFIG_BLK_DEV_RAM_COUNT=16
312CONFIG_BLK_DEV_RAM_SIZE=4096
313# CONFIG_BLK_DEV_INITRD is not set
314# CONFIG_LBD is not set
315# CONFIG_CDROM_PKTCDVD is not set
316
317#
318# IO Schedulers
319#
320CONFIG_IOSCHED_NOOP=y
321CONFIG_IOSCHED_AS=y
322CONFIG_IOSCHED_DEADLINE=y
323CONFIG_IOSCHED_CFQ=y
324# CONFIG_ATA_OVER_ETH is not set
325
326#
327# ATA/ATAPI/MFM/RLL support
328#
329CONFIG_IDE=y
330CONFIG_BLK_DEV_IDE=y
331
332#
333# Please see Documentation/ide.txt for help/info on IDE drives
334#
335# CONFIG_BLK_DEV_IDE_SATA is not set
336CONFIG_BLK_DEV_IDEDISK=y
337# CONFIG_IDEDISK_MULTI_MODE is not set
338# CONFIG_BLK_DEV_IDECD is not set
339# CONFIG_BLK_DEV_IDETAPE is not set
340# CONFIG_BLK_DEV_IDEFLOPPY is not set
341# CONFIG_BLK_DEV_IDESCSI is not set
342# CONFIG_IDE_TASK_IOCTL is not set
343
344#
345# IDE chipset support/bugfixes
346#
347CONFIG_IDE_GENERIC=y
348CONFIG_BLK_DEV_IDEPCI=y
349# CONFIG_IDEPCI_SHARE_IRQ is not set
350# CONFIG_BLK_DEV_OFFBOARD is not set
351# CONFIG_BLK_DEV_GENERIC is not set
352# CONFIG_BLK_DEV_OPTI621 is not set
353CONFIG_BLK_DEV_IDEDMA_PCI=y
354# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
355# CONFIG_IDEDMA_PCI_AUTO is not set
356# CONFIG_BLK_DEV_AEC62XX is not set
357# CONFIG_BLK_DEV_ALI15X3 is not set
358# CONFIG_BLK_DEV_AMD74XX is not set
359# CONFIG_BLK_DEV_CMD64X is not set
360# CONFIG_BLK_DEV_TRIFLEX is not set
361# CONFIG_BLK_DEV_CY82C693 is not set
362# CONFIG_BLK_DEV_CS5520 is not set
363# CONFIG_BLK_DEV_CS5530 is not set
364# CONFIG_BLK_DEV_HPT34X is not set
365# CONFIG_BLK_DEV_HPT366 is not set
366# CONFIG_BLK_DEV_SC1200 is not set
367# CONFIG_BLK_DEV_PIIX is not set
368# CONFIG_BLK_DEV_IT821X is not set
369# CONFIG_BLK_DEV_NS87415 is not set
370# CONFIG_BLK_DEV_PDC202XX_OLD is not set
371# CONFIG_BLK_DEV_PDC202XX_NEW is not set
372# CONFIG_BLK_DEV_SVWKS is not set
373CONFIG_BLK_DEV_SIIMAGE=y
374# CONFIG_BLK_DEV_SLC90E66 is not set
375# CONFIG_BLK_DEV_TRM290 is not set
376# CONFIG_BLK_DEV_VIA82CXXX is not set
377# CONFIG_IDE_ARM is not set
378CONFIG_BLK_DEV_IDEDMA=y
379# CONFIG_IDEDMA_IVB is not set
380# CONFIG_IDEDMA_AUTO is not set
381# CONFIG_BLK_DEV_HD is not set
382
383#
384# SCSI device support
385#
386# CONFIG_RAID_ATTRS is not set
387CONFIG_SCSI=y
388CONFIG_SCSI_PROC_FS=y
389
390#
391# SCSI support type (disk, tape, CD-ROM)
392#
393CONFIG_BLK_DEV_SD=y
394# CONFIG_CHR_DEV_ST is not set
395# CONFIG_CHR_DEV_OSST is not set
396# CONFIG_BLK_DEV_SR is not set
397# CONFIG_CHR_DEV_SG is not set
398# CONFIG_CHR_DEV_SCH is not set
399
400#
401# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
402#
403# CONFIG_SCSI_MULTI_LUN is not set
404# CONFIG_SCSI_CONSTANTS is not set
405# CONFIG_SCSI_LOGGING is not set
406
407#
408# SCSI Transport Attributes
409#
410# CONFIG_SCSI_SPI_ATTRS is not set
411# CONFIG_SCSI_FC_ATTRS is not set
412# CONFIG_SCSI_ISCSI_ATTRS is not set
413
414#
415# SCSI low-level drivers
416#
417# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
418# CONFIG_SCSI_3W_9XXX is not set
419# CONFIG_SCSI_ARCMSR is not set
420# CONFIG_SCSI_ACARD is not set
421# CONFIG_SCSI_AACRAID is not set
422# CONFIG_SCSI_AIC7XXX is not set
423# CONFIG_SCSI_AIC7XXX_OLD is not set
424# CONFIG_SCSI_AIC79XX is not set
425# CONFIG_SCSI_DPT_I2O is not set
426# CONFIG_MEGARAID_NEWGEN is not set
427# CONFIG_MEGARAID_LEGACY is not set
428# CONFIG_SCSI_SATA is not set
429# CONFIG_SCSI_BUSLOGIC is not set
430# CONFIG_SCSI_DMX3191D is not set
431# CONFIG_SCSI_EATA is not set
432# CONFIG_SCSI_FUTURE_DOMAIN is not set
433# CONFIG_SCSI_GDTH is not set
434# CONFIG_SCSI_IPS is not set
435# CONFIG_SCSI_INITIO is not set
436# CONFIG_SCSI_INIA100 is not set
437# CONFIG_SCSI_SYM53C8XX_2 is not set
438# CONFIG_SCSI_IPR is not set
439# CONFIG_SCSI_QLOGIC_FC is not set
440# CONFIG_SCSI_QLOGIC_1280 is not set
441CONFIG_SCSI_QLA2XXX=y
442# CONFIG_SCSI_QLA21XX is not set
443# CONFIG_SCSI_QLA22XX is not set
444# CONFIG_SCSI_QLA2300 is not set
445# CONFIG_SCSI_QLA2322 is not set
446# CONFIG_SCSI_QLA6312 is not set
447# CONFIG_SCSI_QLA24XX is not set
448# CONFIG_SCSI_LPFC is not set
449# CONFIG_SCSI_DC395x is not set
450# CONFIG_SCSI_DC390T is not set
451# CONFIG_SCSI_NSP32 is not set
452# CONFIG_SCSI_DEBUG is not set
453
454#
455# Multi-device support (RAID and LVM)
456#
457# CONFIG_MD is not set
458
459#
460# Fusion MPT device support
461#
462# CONFIG_FUSION is not set
463# CONFIG_FUSION_SPI is not set
464# CONFIG_FUSION_FC is not set
465
466#
467# IEEE 1394 (FireWire) support
468#
469CONFIG_IEEE1394=m
470
471#
472# Subsystem Options
473#
474# CONFIG_IEEE1394_VERBOSEDEBUG is not set
475# CONFIG_IEEE1394_OUI_DB is not set
476CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
477CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
478# CONFIG_IEEE1394_EXPORT_FULL_API is not set
479
480#
481# Device Drivers
482#
483
484#
485# Texas Instruments PCILynx requires I2C
486#
487CONFIG_IEEE1394_OHCI1394=m
488
489#
490# Protocol Drivers
491#
492CONFIG_IEEE1394_VIDEO1394=m
493CONFIG_IEEE1394_SBP2=m
494# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
495CONFIG_IEEE1394_ETH1394=m
496CONFIG_IEEE1394_DV1394=m
497CONFIG_IEEE1394_RAWIO=m
498CONFIG_IEEE1394_CMP=m
499CONFIG_IEEE1394_AMDTP=m
500
501#
502# I2O device support
503#
504# CONFIG_I2O is not set
505
506#
507# Network device support
508#
509CONFIG_NETDEVICES=y
510CONFIG_DUMMY=m
511# CONFIG_BONDING is not set
512# CONFIG_EQUALIZER is not set
513# CONFIG_TUN is not set
514
515#
516# ARCnet devices
517#
518# CONFIG_ARCNET is not set
519
520#
521# PHY device support
522#
523# CONFIG_PHYLIB is not set
524
525#
526# Ethernet (10 or 100Mbit)
527#
528CONFIG_NET_ETHERNET=y
529CONFIG_MII=y
530# CONFIG_HAPPYMEAL is not set
531# CONFIG_SUNGEM is not set
532# CONFIG_NET_VENDOR_3COM is not set
533
534#
535# Tulip family network device support
536#
537# CONFIG_NET_TULIP is not set
538# CONFIG_HP100 is not set
539# CONFIG_NET_PCI is not set
540
541#
542# Ethernet (1000 Mbit)
543#
544# CONFIG_ACENIC is not set
545# CONFIG_DL2K is not set
546# CONFIG_E1000 is not set
547# CONFIG_NS83820 is not set
548# CONFIG_HAMACHI is not set
549# CONFIG_YELLOWFIN is not set
550CONFIG_R8169=y
551# CONFIG_R8169_NAPI is not set
552# CONFIG_SIS190 is not set
553# CONFIG_SKGE is not set
554# CONFIG_SKY2 is not set
555# CONFIG_SK98LIN is not set
556# CONFIG_TIGON3 is not set
557# CONFIG_BNX2 is not set
558
559#
560# Ethernet (10000 Mbit)
561#
562# CONFIG_CHELSIO_T1 is not set
563# CONFIG_IXGB is not set
564# CONFIG_S2IO is not set
565
566#
567# Token Ring devices
568#
569# CONFIG_TR is not set
570
571#
572# Wireless LAN (non-hamradio)
573#
574# CONFIG_NET_RADIO is not set
575
576#
577# Wan interfaces
578#
579# CONFIG_WAN is not set
580# CONFIG_FDDI is not set
581# CONFIG_HIPPI is not set
582# CONFIG_PPP is not set
583# CONFIG_SLIP is not set
584# CONFIG_NET_FC is not set
585# CONFIG_SHAPER is not set
586# CONFIG_NETCONSOLE is not set
587# CONFIG_KGDBOE is not set
588# CONFIG_NETPOLL is not set
589# CONFIG_NETPOLL_RX is not set
590# CONFIG_NETPOLL_TRAP is not set
591# CONFIG_NET_POLL_CONTROLLER is not set
592
593#
594# ISDN subsystem
595#
596# CONFIG_ISDN is not set
597
598#
599# Telephony Support
600#
601# CONFIG_PHONE is not set
602
603#
604# Input device support
605#
606CONFIG_INPUT=y
607
608#
609# Userland interfaces
610#
611# CONFIG_INPUT_MOUSEDEV is not set
612# CONFIG_INPUT_JOYDEV is not set
613# CONFIG_INPUT_TSDEV is not set
614# CONFIG_INPUT_EVDEV is not set
615# CONFIG_INPUT_EVBUG is not set
616
617#
618# Input Device Drivers
619#
620# CONFIG_INPUT_KEYBOARD is not set
621# CONFIG_INPUT_MOUSE is not set
622# CONFIG_INPUT_JOYSTICK is not set
623# CONFIG_INPUT_TOUCHSCREEN is not set
624# CONFIG_INPUT_MISC is not set
625
626#
627# Hardware I/O ports
628#
629# CONFIG_SERIO is not set
630# CONFIG_GAMEPORT is not set
631
632#
633# Character devices
634#
635CONFIG_VT=y
636CONFIG_VT_CONSOLE=y
637CONFIG_HW_CONSOLE=y
638# CONFIG_SERIAL_NONSTANDARD is not set
639
640#
641# Serial drivers
642#
643# CONFIG_SERIAL_8250 is not set
644
645#
646# Non-8250 serial port support
647#
648CONFIG_SERIAL_CORE=y
649CONFIG_SERIAL_CORE_CONSOLE=y
650CONFIG_SERIAL_VR41XX=y
651CONFIG_SERIAL_VR41XX_CONSOLE=y
652# CONFIG_SERIAL_JSM is not set
653CONFIG_UNIX98_PTYS=y
654CONFIG_LEGACY_PTYS=y
655CONFIG_LEGACY_PTY_COUNT=256
656
657#
658# IPMI
659#
660# CONFIG_IPMI_HANDLER is not set
661
662#
663# Watchdog Cards
664#
665# CONFIG_WATCHDOG is not set
666# CONFIG_RTC is not set
667# CONFIG_GEN_RTC is not set
668# CONFIG_RTC_VR41XX is not set
669# CONFIG_DTLK is not set
670# CONFIG_R3964 is not set
671# CONFIG_APPLICOM is not set
672# CONFIG_TANBAC_TB0219 is not set
673
674#
675# Ftape, the floppy tape device driver
676#
677# CONFIG_DRM is not set
678CONFIG_GPIO_VR41XX=y
679# CONFIG_RAW_DRIVER is not set
680
681#
682# TPM devices
683#
684# CONFIG_TCG_TPM is not set
685
686#
687# I2C support
688#
689# CONFIG_I2C is not set
690
691#
692# Dallas's 1-wire bus
693#
694# CONFIG_W1 is not set
695
696#
697# Hardware Monitoring support
698#
699# CONFIG_HWMON is not set
700# CONFIG_HWMON_VID is not set
701
702#
703# Misc devices
704#
705
706#
707# Multimedia Capabilities Port drivers
708#
709
710#
711# Multimedia devices
712#
713# CONFIG_VIDEO_DEV is not set
714
715#
716# Digital Video Broadcasting Devices
717#
718# CONFIG_DVB is not set
719
720#
721# Graphics support
722#
723# CONFIG_FB is not set
724
725#
726# Console display driver support
727#
728# CONFIG_VGA_CONSOLE is not set
729CONFIG_DUMMY_CONSOLE=y
730
731#
732# Speakup console speech
733#
734# CONFIG_SPEAKUP is not set
735
736#
737# Sound
738#
739# CONFIG_SOUND is not set
740
741#
742# USB support
743#
744CONFIG_USB_ARCH_HAS_HCD=y
745CONFIG_USB_ARCH_HAS_OHCI=y
746CONFIG_USB=m
747# CONFIG_USB_DEBUG is not set
748
749#
750# Miscellaneous USB options
751#
752# CONFIG_USB_DEVICEFS is not set
753# CONFIG_USB_BANDWIDTH is not set
754# CONFIG_USB_DYNAMIC_MINORS is not set
755# CONFIG_USB_OTG is not set
756
757#
758# USB Host Controller Drivers
759#
760CONFIG_USB_EHCI_HCD=m
761# CONFIG_USB_EHCI_SPLIT_ISO is not set
762# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
763# CONFIG_USB_ISP116X_HCD is not set
764CONFIG_USB_OHCI_HCD=m
765# CONFIG_USB_OHCI_BIG_ENDIAN is not set
766CONFIG_USB_OHCI_LITTLE_ENDIAN=y
767# CONFIG_USB_UHCI_HCD is not set
768# CONFIG_USB_SL811_HCD is not set
769
770#
771# USB Device Class drivers
772#
773# CONFIG_USB_BLUETOOTH_TTY is not set
774# CONFIG_USB_ACM is not set
775# CONFIG_USB_PRINTER is not set
776
777#
778# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
779#
780CONFIG_USB_STORAGE=m
781# CONFIG_USB_STORAGE_DEBUG is not set
782# CONFIG_USB_STORAGE_DATAFAB is not set
783# CONFIG_USB_STORAGE_FREECOM is not set
784# CONFIG_USB_STORAGE_ISD200 is not set
785# CONFIG_USB_STORAGE_DPCM is not set
786# CONFIG_USB_STORAGE_USBAT is not set
787# CONFIG_USB_STORAGE_SDDR09 is not set
788# CONFIG_USB_STORAGE_SDDR55 is not set
789# CONFIG_USB_STORAGE_JUMPSHOT is not set
790
791#
792# USB Input Devices
793#
794CONFIG_USB_HID=m
795CONFIG_USB_HIDINPUT=y
796# CONFIG_HID_FF is not set
797# CONFIG_USB_HIDDEV is not set
798
799#
800# USB HID Boot Protocol drivers
801#
802# CONFIG_USB_KBD is not set
803# CONFIG_USB_MOUSE is not set
804# CONFIG_USB_AIPTEK is not set
805# CONFIG_USB_WACOM is not set
806# CONFIG_USB_ACECAD is not set
807# CONFIG_USB_KBTAB is not set
808# CONFIG_USB_POWERMATE is not set
809# CONFIG_USB_MTOUCH is not set
810# CONFIG_USB_ITMTOUCH is not set
811# CONFIG_USB_EGALAX is not set
812# CONFIG_USB_YEALINK is not set
813# CONFIG_USB_XPAD is not set
814# CONFIG_USB_ATI_REMOTE is not set
815# CONFIG_USB_KEYSPAN_REMOTE is not set
816# CONFIG_USB_APPLETOUCH is not set
817
818#
819# USB Imaging devices
820#
821# CONFIG_USB_MDC800 is not set
822# CONFIG_USB_MICROTEK is not set
823
824#
825# USB Multimedia devices
826#
827# CONFIG_USB_DABUSB is not set
828
829#
830# Video4Linux support is needed for USB Multimedia device support
831#
832
833#
834# USB Network Adapters
835#
836# CONFIG_USB_CATC is not set
837# CONFIG_USB_KAWETH is not set
838# CONFIG_USB_PEGASUS is not set
839# CONFIG_USB_RTL8150 is not set
840# CONFIG_USB_USBNET is not set
841CONFIG_USB_MON=y
842
843#
844# USB port drivers
845#
846
847#
848# USB Serial Converter support
849#
850# CONFIG_USB_SERIAL is not set
851
852#
853# USB Miscellaneous drivers
854#
855# CONFIG_USB_EMI62 is not set
856# CONFIG_USB_EMI26 is not set
857# CONFIG_USB_AUERSWALD is not set
858# CONFIG_USB_RIO500 is not set
859# CONFIG_USB_LEGOTOWER is not set
860# CONFIG_USB_LCD is not set
861# CONFIG_USB_LED is not set
862# CONFIG_USB_CYTHERM is not set
863# CONFIG_USB_GOTEMP is not set
864# CONFIG_USB_PHIDGETKIT is not set
865# CONFIG_USB_PHIDGETSERVO is not set
866# CONFIG_USB_IDMOUSE is not set
867# CONFIG_USB_SISUSBVGA is not set
868# CONFIG_USB_LD is not set
869
870#
871# USB DSL modem support
872#
873
874#
875# USB Gadget Support
876#
877# CONFIG_USB_GADGET is not set
878
879#
880# MMC/SD Card support
881#
882# CONFIG_MMC is not set
883
884#
885# InfiniBand support
886#
887# CONFIG_INFINIBAND is not set
888
889#
890# SN Devices
891#
892
893#
894# Distributed Lock Manager
895#
896# CONFIG_DLM is not set
897
898#
899# File systems
900#
901CONFIG_EXT2_FS=y
902# CONFIG_EXT2_FS_XATTR is not set
903# CONFIG_EXT2_FS_XIP is not set
904# CONFIG_EXT3_FS is not set
905# CONFIG_REISER4_FS is not set
906# CONFIG_REISERFS_FS is not set
907# CONFIG_JFS_FS is not set
908# CONFIG_FS_POSIX_ACL is not set
909
910#
911# XFS support
912#
913CONFIG_XFS_FS=y
914# CONFIG_XFS_RT is not set
915CONFIG_XFS_QUOTA=y
916# CONFIG_XFS_SECURITY is not set
917CONFIG_XFS_POSIX_ACL=y
918# CONFIG_OCFS2_FS is not set
919# CONFIG_MINIX_FS is not set
920CONFIG_ROMFS_FS=m
921CONFIG_INOTIFY=y
922# CONFIG_QUOTA is not set
923CONFIG_QUOTACTL=y
924# CONFIG_DNOTIFY is not set
925# CONFIG_AUTOFS_FS is not set
926CONFIG_AUTOFS4_FS=y
927# CONFIG_FUSE_FS is not set
928
929#
930# CD-ROM/DVD Filesystems
931#
932# CONFIG_ISO9660_FS is not set
933# CONFIG_UDF_FS is not set
934
935#
936# DOS/FAT/NT Filesystems
937#
938# CONFIG_MSDOS_FS is not set
939# CONFIG_VFAT_FS is not set
940# CONFIG_NTFS_FS is not set
941
942#
943# Pseudo filesystems
944#
945CONFIG_PROC_FS=y
946CONFIG_PROC_KCORE=y
947CONFIG_SYSFS=y
948CONFIG_TMPFS=y
949# CONFIG_HUGETLB_PAGE is not set
950CONFIG_RAMFS=y
951# CONFIG_CONFIGFS_FS is not set
952# CONFIG_RELAYFS_FS is not set
953
954#
955# Miscellaneous filesystems
956#
957# CONFIG_ADFS_FS is not set
958# CONFIG_AFFS_FS is not set
959# CONFIG_ASFS_FS is not set
960# CONFIG_HFS_FS is not set
961# CONFIG_HFSPLUS_FS is not set
962# CONFIG_BEFS_FS is not set
963# CONFIG_BFS_FS is not set
964# CONFIG_EFS_FS is not set
965CONFIG_CRAMFS=m
966# CONFIG_VXFS_FS is not set
967# CONFIG_HPFS_FS is not set
968# CONFIG_QNX4FS_FS is not set
969# CONFIG_SYSV_FS is not set
970# CONFIG_UFS_FS is not set
971
972#
973# Network File Systems
974#
975CONFIG_NFS_FS=y
976CONFIG_NFS_V3=y
977# CONFIG_NFS_V3_ACL is not set
978# CONFIG_NFS_V4 is not set
979# CONFIG_NFS_DIRECTIO is not set
980# CONFIG_NFSD is not set
981CONFIG_ROOT_NFS=y
982CONFIG_LOCKD=y
983CONFIG_LOCKD_V4=y
984CONFIG_NFS_COMMON=y
985CONFIG_SUNRPC=y
986# CONFIG_RPCSEC_GSS_KRB5 is not set
987# CONFIG_RPCSEC_GSS_SPKM3 is not set
988# CONFIG_SMB_FS is not set
989# CONFIG_CIFS is not set
990# CONFIG_NCP_FS is not set
991# CONFIG_CODA_FS is not set
992# CONFIG_AFS_FS is not set
993# CONFIG_9P_FS is not set
994
995#
996# Partition Types
997#
998# CONFIG_PARTITION_ADVANCED is not set
999CONFIG_MSDOS_PARTITION=y
1000
1001#
1002# Native Language Support
1003#
1004# CONFIG_NLS is not set
1005
1006#
1007# Kernel hacking
1008#
1009# CONFIG_PRINTK_TIME is not set
1010# CONFIG_DEBUG_KERNEL is not set
1011CONFIG_LOG_BUF_SHIFT=14
1012CONFIG_CROSSCOMPILE=y
1013CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
1014
1015#
1016# Security options
1017#
1018CONFIG_KEYS=y
1019CONFIG_KEYS_DEBUG_PROC_KEYS=y
1020# CONFIG_SECURITY is not set
1021
1022#
1023# Cryptographic options
1024#
1025# CONFIG_CRYPTO is not set
1026
1027#
1028# Hardware crypto devices
1029#
1030
1031#
1032# Library routines
1033#
1034# CONFIG_CRC_CCITT is not set
1035# CONFIG_CRC16 is not set
1036CONFIG_CRC32=y
1037# CONFIG_LIBCRC32C is not set
1038CONFIG_ZLIB_INFLATE=m
1039CONFIG_GENERIC_HARDIRQS=y
1040CONFIG_GENERIC_IRQ_PROBE=y
1041CONFIG_ISA_DMA_API=y
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
index 288bf51ad4ec..71416e7bbbaa 100644
--- a/arch/mips/kernel/genrtc.c
+++ b/arch/mips/kernel/genrtc.c
@@ -14,7 +14,7 @@
14#include <asm/rtc.h> 14#include <asm/rtc.h>
15#include <asm/time.h> 15#include <asm/time.h>
16 16
17static spinlock_t mips_rtc_lock = SPIN_LOCK_UNLOCKED; 17static DEFINE_SPINLOCK(mips_rtc_lock);
18 18
19unsigned int get_rtc_time(struct rtc_time *time) 19unsigned int get_rtc_time(struct rtc_time *time)
20{ 20{
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 7eec7568bfea..447759201d1d 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq);
31 * moves to arch independent land 31 * moves to arch independent land
32 */ 32 */
33 33
34spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; 34spinlock_t DEFINE_SPINLOCK(i8259A_lock);
35 35
36static void end_8259A_irq (unsigned int irq) 36static void end_8259A_irq (unsigned int irq)
37{ 37{
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index 4cd3d38a22c2..3cdc22346f4c 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -14,6 +14,7 @@
14#include <linux/syscalls.h> 14#include <linux/syscalls.h>
15#include <linux/tty.h> 15#include <linux/tty.h>
16#include <linux/file.h> 16#include <linux/file.h>
17#include <linux/rcupdate.h>
17 18
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19#include <asm/ioctl.h> 20#include <asm/ioctl.h>
@@ -33,7 +34,7 @@ static struct tty_struct *get_tty(int fd)
33 struct file *filp; 34 struct file *filp;
34 struct tty_struct *ttyp = NULL; 35 struct tty_struct *ttyp = NULL;
35 36
36 spin_lock(&current->files->file_lock); 37 rcu_read_lock();
37 filp = fcheck(fd); 38 filp = fcheck(fd);
38 if(filp && filp->private_data) { 39 if(filp && filp->private_data) {
39 ttyp = (struct tty_struct *) filp->private_data; 40 ttyp = (struct tty_struct *) filp->private_data;
@@ -41,7 +42,7 @@ static struct tty_struct *get_tty(int fd)
41 if(ttyp->magic != TTY_MAGIC) 42 if(ttyp->magic != TTY_MAGIC)
42 ttyp =NULL; 43 ttyp =NULL;
43 } 44 }
44 spin_unlock(&current->files->file_lock); 45 rcu_read_unlock();
45 return ttyp; 46 return ttyp;
46} 47}
47 48
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c53e4cb359ba..83d81c9cdc2b 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
48obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o 48obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o
49obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o 49obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
50obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o 50obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
51obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
51obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o 52obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o
52obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o 53obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
53obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o 54obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c
new file mode 100644
index 000000000000..8436d7f1fdb2
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0287.c
@@ -0,0 +1,65 @@
1/*
2 * fixup-tb0287.c, The TANBAC TB0287 specific PCI fixups.
3 *
4 * Copyright (C) 2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
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#include <linux/init.h>
21#include <linux/pci.h>
22
23#include <asm/vr41xx/tb0287.h>
24
25int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
26{
27 unsigned char bus;
28 int irq = -1;
29
30 bus = dev->bus->number;
31 if (bus == 0) {
32 switch (slot) {
33 case 16:
34 irq = TB0287_SM501_IRQ;
35 break;
36 case 17:
37 irq = TB0287_SIL680A_IRQ;
38 break;
39 default:
40 break;
41 }
42 } else if (bus == 1) {
43 switch (PCI_SLOT(dev->devfn)) {
44 case 0:
45 irq = TB0287_PCI_SLOT_IRQ;
46 break;
47 case 2:
48 case 3:
49 irq = TB0287_RTL8110_IRQ;
50 break;
51 default:
52 break;
53 }
54 } else if (bus > 1) {
55 irq = TB0287_PCI_SLOT_IRQ;
56 }
57
58 return irq;
59}
60
61/* Do platform specific device initialization at pci_enable_device() time */
62int pcibios_plat_dev_init(struct pci_dev *dev)
63{
64 return 0;
65}
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 89fe0ceeaa40..2ca9ec7ec3a7 100644
--- a/arch/ppc/8xx_io/cs4218_tdm.c
+++ b/arch/ppc/8xx_io/cs4218_tdm.c
@@ -1380,7 +1380,7 @@ static void cs_nosound(unsigned long xx)
1380 spin_unlock_irqrestore(&cs4218_lock, flags); 1380 spin_unlock_irqrestore(&cs4218_lock, flags);
1381} 1381}
1382 1382
1383static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0); 1383static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
1384}; 1384};
1385 1385
1386static void cs_mksound(unsigned int hz, unsigned int ticks) 1386static void cs_mksound(unsigned int hz, unsigned int ticks)
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 6ab7e5ea5fcf..e3f1ce33e642 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -499,11 +499,6 @@ config WINCEPT
499 MPC821 PowerPC, introduced in 1998 and designed to be used in 499 MPC821 PowerPC, introduced in 1998 and designed to be used in
500 thin-client machines. Say Y to support it directly. 500 thin-client machines. Say Y to support it directly.
501 501
502 Be aware that PCI buses can only function when SYS board is plugged
503 into the PIB (Platform IO Board) board from Freescale which provide
504 3 PCI slots. The PIBs PCI initialization is the bootloader's
505 responsiblilty.
506
507endchoice 502endchoice
508 503
509choice 504choice
@@ -680,6 +675,11 @@ config MPC834x_SYS
680 help 675 help
681 This option enables support for the MPC 834x SYS evaluation board. 676 This option enables support for the MPC 834x SYS evaluation board.
682 677
678 Be aware that PCI buses can only function when SYS board is plugged
679 into the PIB (Platform IO Board) board from Freescale which provide
680 3 PCI slots. The PIBs PCI initialization is the bootloader's
681 responsiblilty.
682
683config EV64360 683config EV64360
684 bool "Marvell-EV64360BP" 684 bool "Marvell-EV64360BP"
685 help 685 help
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c
index 9017c547a6f6..26818bbb6cff 100644
--- a/arch/ppc/boot/common/ns16550.c
+++ b/arch/ppc/boot/common/ns16550.c
@@ -23,7 +23,7 @@ static int shift;
23 23
24unsigned long serial_init(int chan, void *ignored) 24unsigned long serial_init(int chan, void *ignored)
25{ 25{
26 unsigned long com_port; 26 unsigned long com_port, base_baud;
27 unsigned char lcr, dlm; 27 unsigned char lcr, dlm;
28 28
29 /* We need to find out which type io we're expecting. If it's 29 /* We need to find out which type io we're expecting. If it's
@@ -43,6 +43,8 @@ unsigned long serial_init(int chan, void *ignored)
43 43
44 /* How far apart the registers are. */ 44 /* How far apart the registers are. */
45 shift = rs_table[chan].iomem_reg_shift; 45 shift = rs_table[chan].iomem_reg_shift;
46 /* Base baud.. */
47 base_baud = rs_table[chan].baud_base;
46 48
47 /* save the LCR */ 49 /* save the LCR */
48 lcr = inb(com_port + (UART_LCR << shift)); 50 lcr = inb(com_port + (UART_LCR << shift));
@@ -62,9 +64,9 @@ unsigned long serial_init(int chan, void *ignored)
62 else { 64 else {
63 /* Input clock. */ 65 /* Input clock. */
64 outb(com_port + (UART_DLL << shift), 66 outb(com_port + (UART_DLL << shift),
65 (BASE_BAUD / SERIAL_BAUD) & 0xFF); 67 (base_baud / SERIAL_BAUD) & 0xFF);
66 outb(com_port + (UART_DLM << shift), 68 outb(com_port + (UART_DLM << shift),
67 (BASE_BAUD / SERIAL_BAUD) >> 8); 69 (base_baud / SERIAL_BAUD) >> 8);
68 /* 8 data, 1 stop, no parity */ 70 /* 8 data, 1 stop, no parity */
69 outb(com_port + (UART_LCR << shift), 0x03); 71 outb(com_port + (UART_LCR << shift), 0x03);
70 /* RTS/DTR */ 72 /* RTS/DTR */
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
index 47e641455bc5..c96c9f80521e 100644
--- a/arch/ppc/boot/common/util.S
+++ b/arch/ppc/boot/common/util.S
@@ -252,7 +252,7 @@ _GLOBAL(flush_instruction_cache)
2521: dcbf r0,r3 # Flush the data cache 2521: dcbf r0,r3 # Flush the data cache
253 icbi r0,r3 # Invalidate the instruction cache 253 icbi r0,r3 # Invalidate the instruction cache
254 addi r3,r3,0x10 # Increment by one cache line 254 addi r3,r3,0x10 # Increment by one cache line
255 cmplwi cr0,r3,r4 # Are we at the end yet? 255 cmplw cr0,r3,r4 # Are we at the end yet?
256 blt 1b # No, keep flushing and invalidating 256 blt 1b # No, keep flushing and invalidating
257#else 257#else
258 /* Enable, invalidate and then disable the L1 icache/dcache. */ 258 /* Enable, invalidate and then disable the L1 icache/dcache. */
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index b1457a8a9c0f..1fb92f16acd6 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -15,8 +15,9 @@ extra-y += vmlinux.lds
15obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ 15obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
16 process.o signal.o ptrace.o align.o \ 16 process.o signal.o ptrace.o align.o \
17 semaphore.o syscalls.o setup.o \ 17 semaphore.o syscalls.o setup.o \
18 cputable.o ppc_htab.o perfmon.o 18 cputable.o ppc_htab.o
19obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o 19obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
20obj-$(CONFIG_E500) += perfmon.o
20obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o 21obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
21obj-$(CONFIG_POWER4) += cpu_setup_power4.o 22obj-$(CONFIG_POWER4) += cpu_setup_power4.o
22obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o 23obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 7b3586a3bf30..854e45beb387 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -80,7 +80,6 @@ fixup_broken_pcnet32(struct pci_dev* dev)
80 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 80 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
81 dev->vendor = PCI_VENDOR_ID_AMD; 81 dev->vendor = PCI_VENDOR_ID_AMD;
82 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); 82 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
83 pci_name_device(dev);
84 } 83 }
85} 84}
86DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); 85DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 124313ce3c09..127f040de9de 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -41,10 +41,6 @@
41#include <asm/ipc.h> 41#include <asm/ipc.h>
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43 43
44void
45check_bugs(void)
46{
47}
48 44
49/* 45/*
50 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 46 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index d87423d1003a..8356d544fa60 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -849,10 +849,12 @@ void AltivecAssistException(struct pt_regs *regs)
849} 849}
850#endif /* CONFIG_ALTIVEC */ 850#endif /* CONFIG_ALTIVEC */
851 851
852#ifdef CONFIG_E500
852void PerformanceMonitorException(struct pt_regs *regs) 853void PerformanceMonitorException(struct pt_regs *regs)
853{ 854{
854 perf_irq(regs); 855 perf_irq(regs);
855} 856}
857#endif
856 858
857#ifdef CONFIG_FSL_BOOKE 859#ifdef CONFIG_FSL_BOOKE
858void CacheLockingException(struct pt_regs *regs, unsigned long address, 860void CacheLockingException(struct pt_regs *regs, unsigned long address,
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 0fd3442f5131..d6b2b1965dcb 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -91,15 +91,10 @@ ebony_calibrate_decr(void)
91 * on Rev. C silicon then errata forces us to 91 * on Rev. C silicon then errata forces us to
92 * use the internal clock. 92 * use the internal clock.
93 */ 93 */
94 switch (PVR_REV(mfspr(SPRN_PVR))) { 94 if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0)
95 case PVR_REV(PVR_440GP_RB): 95 freq = EBONY_440GP_RB_SYSCLK;
96 freq = EBONY_440GP_RB_SYSCLK; 96 else
97 break; 97 freq = EBONY_440GP_RC_SYSCLK;
98 case PVR_REV(PVR_440GP_RC1):
99 default:
100 freq = EBONY_440GP_RC_SYSCLK;
101 break;
102 }
103 98
104 ibm44x_calibrate_decr(freq); 99 ibm44x_calibrate_decr(freq);
105} 100}
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index b659d7b3d747..ff3796860123 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -58,7 +58,7 @@ static void parse_bootinfo(unsigned long r3,
58static void hdpu_set_l1pe(void); 58static void hdpu_set_l1pe(void);
59static void hdpu_cpustate_set(unsigned char new_state); 59static void hdpu_cpustate_set(unsigned char new_state);
60#ifdef CONFIG_SMP 60#ifdef CONFIG_SMP
61static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED; 61static DEFINE_SPINLOCK(timebase_lock);
62static unsigned int timebase_upper = 0, timebase_lower = 0; 62static unsigned int timebase_upper = 0, timebase_lower = 0;
63extern int smp_tb_synchronized; 63extern int smp_tb_synchronized;
64 64
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index d4776af6a3ca..0bb919859b8b 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -236,9 +236,10 @@ void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
236 /* Disable L2C on rev.A, rev.B and 800MHz version of rev.C, 236 /* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
237 enable it on all other revisions 237 enable it on all other revisions
238 */ 238 */
239 u32 pvr = mfspr(SPRN_PVR); 239 if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 ||
240 if (pvr == PVR_440GX_RA || pvr == PVR_440GX_RB || 240 strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0
241 (pvr == PVR_440GX_RC && p->cpu > 667000000)) 241 || (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C")
242 == 0 && p->cpu > 667000000))
242 ibm440gx_l2c_disable(); 243 ibm440gx_l2c_disable();
243 else 244 else
244 ibm440gx_l2c_enable(); 245 ibm440gx_l2c_enable();
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
index 87065e2e4c5f..3e039706bdbc 100644
--- a/arch/ppc/syslib/mpc10x_common.c
+++ b/arch/ppc/syslib/mpc10x_common.c
@@ -140,12 +140,12 @@ struct platform_device ppc_sys_platform_devices[] = {
140 }, 140 },
141 [MPC10X_UART0] = { 141 [MPC10X_UART0] = {
142 .name = "serial8250", 142 .name = "serial8250",
143 .id = 0, 143 .id = PLAT8250_DEV_PLATFORM,
144 .dev.platform_data = serial_plat_uart0, 144 .dev.platform_data = serial_plat_uart0,
145 }, 145 },
146 [MPC10X_UART1] = { 146 [MPC10X_UART1] = {
147 .name = "serial8250", 147 .name = "serial8250",
148 .id = 1, 148 .id = PLAT8250_DEV_PLATFORM1,
149 .dev.platform_data = serial_plat_uart1, 149 .dev.platform_data = serial_plat_uart1,
150 }, 150 },
151 151
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 5aaf0e58e1f9..95b3b8a7f0ba 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -165,7 +165,7 @@ struct platform_device ppc_sys_platform_devices[] = {
165 }, 165 },
166 [MPC83xx_DUART] = { 166 [MPC83xx_DUART] = {
167 .name = "serial8250", 167 .name = "serial8250",
168 .id = 0, 168 .id = PLAT8250_DEV_PLATFORM,
169 .dev.platform_data = serial_platform_data, 169 .dev.platform_data = serial_platform_data,
170 }, 170 },
171 [MPC83xx_SEC2] = { 171 [MPC83xx_SEC2] = {
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 8af322dd476a..bbc5ac0de878 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -282,7 +282,7 @@ struct platform_device ppc_sys_platform_devices[] = {
282 }, 282 },
283 [MPC85xx_DUART] = { 283 [MPC85xx_DUART] = {
284 .name = "serial8250", 284 .name = "serial8250",
285 .id = 0, 285 .id = PLAT8250_DEV_PLATFORM,
286 .dev.platform_data = serial_platform_data, 286 .dev.platform_data = serial_platform_data,
287 }, 287 },
288 [MPC85xx_PERFMON] = { 288 [MPC85xx_PERFMON] = {
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 6262b11f366f..839f8872826f 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -31,7 +31,7 @@
31 31
32 32
33u8 mv64x60_pci_exclude_bridge = 1; 33u8 mv64x60_pci_exclude_bridge = 1;
34spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; 34DEFINE_SPINLOCK(mv64x60_lock);
35 35
36static phys_addr_t mv64x60_bridge_pbase; 36static phys_addr_t mv64x60_bridge_pbase;
37static void *mv64x60_bridge_vbase; 37static void *mv64x60_bridge_vbase;
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c
index 57f4ed5e5ae1..0970b5d30391 100644
--- a/arch/ppc/syslib/qspan_pci.c
+++ b/arch/ppc/syslib/qspan_pci.c
@@ -94,7 +94,7 @@
94#define mk_config_type1(bus, dev, offset) \ 94#define mk_config_type1(bus, dev, offset) \
95 mk_config_addr(bus, dev, offset) | 1; 95 mk_config_addr(bus, dev, offset) | 1;
96 96
97static spinlock_t pcibios_lock = SPIN_LOCK_UNLOCKED; 97static DEFINE_SPINLOCK(pcibios_lock);
98 98
99int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, 99int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
100 unsigned char offset, unsigned char *val) 100 unsigned char offset, unsigned char *val)
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index d795775a5cd7..0a23aeacba88 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -89,11 +89,12 @@ drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/
89 89
90boot := arch/ppc64/boot 90boot := arch/ppc64/boot
91 91
92boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd 92boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd
93boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd 93boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode
94boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm 94boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd
95boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd 95boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm
96$(boottarget-y): vmlinux 96boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd
97$(boottargets-y): vmlinux
97 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 98 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
98 99
99bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage 100bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
@@ -124,8 +125,10 @@ include3/asm:
124 $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm 125 $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
125 126
126define archhelp 127define archhelp
127 echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' 128 echo ' zImage.vmode - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)'
128 echo ' zImage.initrd- Compressed kernel image with initrd attached,' 129 echo ' zImage.initrd.vmode - Compressed kernel image with initrd attached,'
129 echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' 130 echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz'
130 echo ' (arch/$(ARCH)/boot/zImage.initrd)' 131 echo ' (arch/$(ARCH)/boot/zImage.initrd.vmode)'
132 echo ' zImage - zImage for pSeries machines'
133 echo ' zImage.initrd - zImage with initrd for pSeries machines'
131endef 134endef
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 2c5f5e73d00c..33fdc8710891 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC $@
37quiet_cmd_bootas = BOOTAS $@ 37quiet_cmd_bootas = BOOTAS $@
38 cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< 38 cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
39 39
40quiet_cmd_bootld = BOOTLD $@
41 cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2)
42
40$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c 43$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
41 $(call if_changed_dep,bootcc) 44 $(call if_changed_dep,bootcc)
42$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S 45$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
@@ -53,7 +56,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
53gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) 56gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
54 57
55hostprogs-y := addnote addRamDisk 58hostprogs-y := addnote addRamDisk
56targets += zImage zImage.initrd imagesize.c \ 59targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
57 $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ 60 $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
58 $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ 61 $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
59 $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ 62 $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -63,7 +66,7 @@ extra-y := initrd.o
63quiet_cmd_ramdisk = RAMDISK $@ 66quiet_cmd_ramdisk = RAMDISK $@
64 cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ 67 cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
65 68
66quiet_cmd_stripvm = STRIP $@ 69quiet_cmd_stripvm = STRIP $@
67 cmd_stripvm = $(STRIP) -s $< -o $@ 70 cmd_stripvm = $(STRIP) -s $< -o $@
68 71
69vmlinux.strip: vmlinux FORCE 72vmlinux.strip: vmlinux FORCE
@@ -71,12 +74,20 @@ vmlinux.strip: vmlinux FORCE
71$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE 74$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
72 $(call if_changed,ramdisk) 75 $(call if_changed,ramdisk)
73 76
74addsection = $(CROSS32OBJCOPY) $(1) \ 77quiet_cmd_addsection = ADDSEC $@
75 --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ 78 cmd_addsection = $(CROSS32OBJCOPY) $@ \
76 --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) 79 --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
80 --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
81
82quiet_cmd_imagesize = GENSIZE $@
83 cmd_imagesize = ls -l vmlinux.strip | \
84 awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
85 > $(obj)/imagesize.c && \
86 $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
87 awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
77 88
78quiet_cmd_addnote = ADDNOTE $@ 89quiet_cmd_addnote = ADDNOTE $@
79 cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ 90 cmd_addnote = $(obj)/addnote $@
80 91
81$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE 92$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
82 $(call if_changed,gzip) 93 $(call if_changed,gzip)
@@ -85,28 +96,30 @@ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
85 cp -f $(obj)/ramdisk.image.gz $@ 96 cp -f $(obj)/ramdisk.image.gz $@
86 97
87$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE 98$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
88 touch $@ 99 @touch $@
89 100
90$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE 101$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
91 $(call if_changed_dep,bootcc) 102 $(call if_changed_dep,bootcc)
92 $(call addsection, $@) 103 $(call cmd,addsection)
104
105$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
106$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
107 $(call cmd,bootld,$(obj-boot))
108
109$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
110$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
111 $(call cmd,bootld,$(obj-boot))
93 112
94$(obj)/zImage: obj-boot += $(call obj-sec, $(required)) 113$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
95$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE 114 @cp -f $< $@
96 $(call if_changed,addnote) 115 $(call if_changed,addnote)
97 116
98$(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) 117$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
99$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE 118 @cp -f $< $@
100 $(call if_changed,addnote) 119 $(call if_changed,addnote)
101 120
102$(obj)/imagesize.c: vmlinux.strip 121$(obj)/imagesize.c: vmlinux.strip
103 @echo Generating $@ 122 $(call cmd,imagesize)
104 ls -l vmlinux.strip | \
105 awk '{printf "/* generated -- do not edit! */\n" \
106 "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
107 $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
108 awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
109 >> $(obj)/imagesize.c
110 123
111install: $(CONFIGURE) $(BOOTIMAGE) 124install: $(CONFIGURE) $(BOOTIMAGE)
112 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" 125 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index 99e68cfbe688..f7ec19a2d0b0 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long);
23 23
24/* Value picked to match that used by yaboot */ 24/* Value picked to match that used by yaboot */
25#define PROG_START 0x01400000 25#define PROG_START 0x01400000
26#define RAM_END (256<<20) // Fixme: use OF */ 26#define RAM_END (512<<20) // Fixme: use OF */
27#define ONE_MB 0x100000
27 28
28static char *avail_ram; 29static char *avail_ram;
29static char *begin_avail, *end_avail; 30static char *begin_avail, *end_avail;
@@ -32,6 +33,7 @@ static unsigned int heap_use;
32static unsigned int heap_max; 33static unsigned int heap_max;
33 34
34extern char _start[]; 35extern char _start[];
36extern char _end[];
35extern char _vmlinux_start[]; 37extern char _vmlinux_start[];
36extern char _vmlinux_end[]; 38extern char _vmlinux_end[];
37extern char _initrd_start[]; 39extern char _initrd_start[];
@@ -58,13 +60,13 @@ typedef void (*kernel_entry_t)( unsigned long,
58 60
59#undef DEBUG 61#undef DEBUG
60 62
61static unsigned long claim_base = PROG_START; 63static unsigned long claim_base;
62 64
63static unsigned long try_claim(unsigned long size) 65static unsigned long try_claim(unsigned long size)
64{ 66{
65 unsigned long addr = 0; 67 unsigned long addr = 0;
66 68
67 for(; claim_base < RAM_END; claim_base += 0x100000) { 69 for(; claim_base < RAM_END; claim_base += ONE_MB) {
68#ifdef DEBUG 70#ifdef DEBUG
69 printf(" trying: 0x%08lx\n\r", claim_base); 71 printf(" trying: 0x%08lx\n\r", claim_base);
70#endif 72#endif
@@ -95,7 +97,26 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
95 if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) 97 if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
96 exit(); 98 exit();
97 99
98 printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); 100 printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
101
102 /*
103 * The first available claim_base must be above the end of the
104 * the loaded kernel wrapper file (_start to _end includes the
105 * initrd image if it is present) and rounded up to a nice
106 * 1 MB boundary for good measure.
107 */
108
109 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
110
111#if defined(PROG_START)
112 /*
113 * Maintain a "magic" minimum address. This keeps some older
114 * firmware platforms running.
115 */
116
117 if (claim_base < PROG_START)
118 claim_base = PROG_START;
119#endif
99 120
100 /* 121 /*
101 * Now we try to claim some memory for the kernel itself 122 * Now we try to claim some memory for the kernel itself
@@ -105,7 +126,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
105 * size... In practice we add 1Mb, that is enough, but we should really 126 * size... In practice we add 1Mb, that is enough, but we should really
106 * consider fixing the Makefile to put a _raw_ kernel in there ! 127 * consider fixing the Makefile to put a _raw_ kernel in there !
107 */ 128 */
108 vmlinux_memsize += 0x100000; 129 vmlinux_memsize += ONE_MB;
109 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); 130 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
110 vmlinux.addr = try_claim(vmlinux_memsize); 131 vmlinux.addr = try_claim(vmlinux_memsize);
111 if (vmlinux.addr == 0) { 132 if (vmlinux.addr == 0) {
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
index c8f3dc3fad70..0aaa878e19d3 100644
--- a/arch/ppc64/kernel/bpa_iic.c
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic(int cpu)
205} 205}
206 206
207#ifdef CONFIG_SMP 207#ifdef CONFIG_SMP
208
209/* Use the highest interrupt priorities for IPI */
210static inline int iic_ipi_to_irq(int ipi)
211{
212 return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi;
213}
214
215static inline int iic_irq_to_ipi(int irq)
216{
217 return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET);
218}
219
208void iic_setup_cpu(void) 220void iic_setup_cpu(void)
209{ 221{
210 out_be64(&__get_cpu_var(iic).regs->prio, 0xff); 222 out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)
212 224
213void iic_cause_IPI(int cpu, int mesg) 225void iic_cause_IPI(int cpu, int mesg)
214{ 226{
215 out_be64(&per_cpu(iic, cpu).regs->generate, mesg); 227 out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
216} 228}
217 229
218static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) 230static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
219{ 231{
220 232 smp_message_recv(iic_irq_to_ipi(irq), regs);
221 smp_message_recv(irq - IIC_IPI_OFFSET, regs);
222 return IRQ_HANDLED; 233 return IRQ_HANDLED;
223} 234}
224 235
225static void iic_request_ipi(int irq, const char *name) 236static void iic_request_ipi(int ipi, const char *name)
226{ 237{
238 int irq;
239
240 irq = iic_ipi_to_irq(ipi);
227 /* IPIs are marked SA_INTERRUPT as they must run with irqs 241 /* IPIs are marked SA_INTERRUPT as they must run with irqs
228 * disabled */ 242 * disabled */
229 get_irq_desc(irq)->handler = &iic_pic; 243 get_irq_desc(irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, const char *name)
233 247
234void iic_request_IPIs(void) 248void iic_request_IPIs(void)
235{ 249{
236 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call"); 250 iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
237 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched"); 251 iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
238#ifdef CONFIG_DEBUGGER 252#ifdef CONFIG_DEBUGGER
239 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); 253 iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
240#endif /* CONFIG_DEBUGGER */ 254#endif /* CONFIG_DEBUGGER */
241} 255}
242#endif /* CONFIG_SMP */ 256#endif /* CONFIG_SMP */
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index af5272fedadf..ba93fd731222 100644
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -202,10 +202,9 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
202 while (n) { 202 while (n) {
203 struct pci_io_addr_range *piar; 203 struct pci_io_addr_range *piar;
204 piar = rb_entry(n, struct pci_io_addr_range, rb_node); 204 piar = rb_entry(n, struct pci_io_addr_range, rb_node);
205 printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s %s\n", 205 printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
206 (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt, 206 (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
207 piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev), 207 piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
208 pci_pretty_name(piar->pcidev));
209 cnt++; 208 cnt++;
210 n = rb_next(n); 209 n = rb_next(n);
211 } 210 }
@@ -255,22 +254,24 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
255static void __pci_addr_cache_insert_device(struct pci_dev *dev) 254static void __pci_addr_cache_insert_device(struct pci_dev *dev)
256{ 255{
257 struct device_node *dn; 256 struct device_node *dn;
257 struct pci_dn *pdn;
258 int i; 258 int i;
259 int inserted = 0; 259 int inserted = 0;
260 260
261 dn = pci_device_to_OF_node(dev); 261 dn = pci_device_to_OF_node(dev);
262 if (!dn) { 262 if (!dn) {
263 printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n", 263 printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n",
264 pci_name(dev), pci_pretty_name(dev)); 264 pci_name(dev));
265 return; 265 return;
266 } 266 }
267 267
268 /* Skip any devices for which EEH is not enabled. */ 268 /* Skip any devices for which EEH is not enabled. */
269 if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || 269 pdn = dn->data;
270 dn->eeh_mode & EEH_MODE_NOCHECK) { 270 if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
271 pdn->eeh_mode & EEH_MODE_NOCHECK) {
271#ifdef DEBUG 272#ifdef DEBUG
272 printk(KERN_INFO "PCI: skip building address cache for=%s %s\n", 273 printk(KERN_INFO "PCI: skip building address cache for=%s\n",
273 pci_name(dev), pci_pretty_name(dev)); 274 pci_name(dev));
274#endif 275#endif
275 return; 276 return;
276 } 277 }
@@ -416,6 +417,7 @@ int eeh_unregister_notifier(struct notifier_block *nb)
416static int read_slot_reset_state(struct device_node *dn, int rets[]) 417static int read_slot_reset_state(struct device_node *dn, int rets[])
417{ 418{
418 int token, outputs; 419 int token, outputs;
420 struct pci_dn *pdn = dn->data;
419 421
420 if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { 422 if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
421 token = ibm_read_slot_reset_state2; 423 token = ibm_read_slot_reset_state2;
@@ -425,8 +427,8 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
425 outputs = 3; 427 outputs = 3;
426 } 428 }
427 429
428 return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, 430 return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
429 BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); 431 BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
430} 432}
431 433
432/** 434/**
@@ -447,12 +449,12 @@ static void eeh_panic(struct pci_dev *dev, int reset_state)
447 * in light of potential corruption, we can use it here. 449 * in light of potential corruption, we can use it here.
448 */ 450 */
449 if (panic_on_oops) 451 if (panic_on_oops)
450 panic("EEH: MMIO failure (%d) on device:%s %s\n", reset_state, 452 panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
451 pci_name(dev), pci_pretty_name(dev)); 453 pci_name(dev));
452 else { 454 else {
453 __get_cpu_var(ignored_failures)++; 455 __get_cpu_var(ignored_failures)++;
454 printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s %s\n", 456 printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
455 reset_state, pci_name(dev), pci_pretty_name(dev)); 457 reset_state, pci_name(dev));
456 } 458 }
457} 459}
458 460
@@ -482,8 +484,8 @@ static void eeh_event_handler(void *dummy)
482 break; 484 break;
483 485
484 printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " 486 printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
485 "%s %s\n", event->reset_state, 487 "%s\n", event->reset_state,
486 pci_name(event->dev), pci_pretty_name(event->dev)); 488 pci_name(event->dev));
487 489
488 atomic_set(&eeh_fail_count, 0); 490 atomic_set(&eeh_fail_count, 0);
489 notifier_call_chain (&eeh_notifier_chain, 491 notifier_call_chain (&eeh_notifier_chain,
@@ -535,6 +537,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
535 unsigned long flags; 537 unsigned long flags;
536 int rc, reset_state; 538 int rc, reset_state;
537 struct eeh_event *event; 539 struct eeh_event *event;
540 struct pci_dn *pdn;
538 541
539 __get_cpu_var(total_mmio_ffs)++; 542 __get_cpu_var(total_mmio_ffs)++;
540 543
@@ -543,14 +546,15 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
543 546
544 if (!dn) 547 if (!dn)
545 return 0; 548 return 0;
549 pdn = dn->data;
546 550
547 /* Access to IO BARs might get this far and still not want checking. */ 551 /* Access to IO BARs might get this far and still not want checking. */
548 if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || 552 if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
549 dn->eeh_mode & EEH_MODE_NOCHECK) { 553 pdn->eeh_mode & EEH_MODE_NOCHECK) {
550 return 0; 554 return 0;
551 } 555 }
552 556
553 if (!dn->eeh_config_addr) { 557 if (!pdn->eeh_config_addr) {
554 return 0; 558 return 0;
555 } 559 }
556 560
@@ -558,7 +562,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
558 * If we already have a pending isolation event for this 562 * If we already have a pending isolation event for this
559 * 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...
560 */ 564 */
561 if (dn->eeh_mode & EEH_MODE_ISOLATED) { 565 if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
562 atomic_inc(&eeh_fail_count); 566 atomic_inc(&eeh_fail_count);
563 if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { 567 if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
564 /* re-read the slot reset state */ 568 /* re-read the slot reset state */
@@ -583,7 +587,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
583 } 587 }
584 588
585 /* prevent repeated reports of this failure */ 589 /* prevent repeated reports of this failure */
586 dn->eeh_mode |= EEH_MODE_ISOLATED; 590 pdn->eeh_mode |= EEH_MODE_ISOLATED;
587 591
588 reset_state = rets[0]; 592 reset_state = rets[0];
589 593
@@ -591,9 +595,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
591 memset(slot_errbuf, 0, eeh_error_buf_size); 595 memset(slot_errbuf, 0, eeh_error_buf_size);
592 596
593 rc = rtas_call(ibm_slot_error_detail, 597 rc = rtas_call(ibm_slot_error_detail,
594 8, 1, NULL, dn->eeh_config_addr, 598 8, 1, NULL, pdn->eeh_config_addr,
595 BUID_HI(dn->phb->buid), 599 BUID_HI(pdn->phb->buid),
596 BUID_LO(dn->phb->buid), NULL, 0, 600 BUID_LO(pdn->phb->buid), NULL, 0,
597 virt_to_phys(slot_errbuf), 601 virt_to_phys(slot_errbuf),
598 eeh_error_buf_size, 602 eeh_error_buf_size,
599 1 /* Temporary Error */); 603 1 /* Temporary Error */);
@@ -680,8 +684,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
680 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); 684 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
681 u32 *regs; 685 u32 *regs;
682 int enable; 686 int enable;
687 struct pci_dn *pdn = dn->data;
683 688
684 dn->eeh_mode = 0; 689 pdn->eeh_mode = 0;
685 690
686 if (status && strcmp(status, "ok") != 0) 691 if (status && strcmp(status, "ok") != 0)
687 return NULL; /* ignore devices with bad status */ 692 return NULL; /* ignore devices with bad status */
@@ -692,7 +697,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
692 697
693 /* There is nothing to check on PCI to ISA bridges */ 698 /* There is nothing to check on PCI to ISA bridges */
694 if (dn->type && !strcmp(dn->type, "isa")) { 699 if (dn->type && !strcmp(dn->type, "isa")) {
695 dn->eeh_mode |= EEH_MODE_NOCHECK; 700 pdn->eeh_mode |= EEH_MODE_NOCHECK;
696 return NULL; 701 return NULL;
697 } 702 }
698 703
@@ -709,7 +714,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
709 enable = 0; 714 enable = 0;
710 715
711 if (!enable) 716 if (!enable)
712 dn->eeh_mode |= EEH_MODE_NOCHECK; 717 pdn->eeh_mode |= EEH_MODE_NOCHECK;
713 718
714 /* Ok... see if this device supports EEH. Some do, some don't, 719 /* Ok... see if this device supports EEH. Some do, some don't,
715 * and the only way to find out is to check each and every one. */ 720 * and the only way to find out is to check each and every one. */
@@ -722,8 +727,8 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
722 EEH_ENABLE); 727 EEH_ENABLE);
723 if (ret == 0) { 728 if (ret == 0) {
724 eeh_subsystem_enabled = 1; 729 eeh_subsystem_enabled = 1;
725 dn->eeh_mode |= EEH_MODE_SUPPORTED; 730 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
726 dn->eeh_config_addr = regs[0]; 731 pdn->eeh_config_addr = regs[0];
727#ifdef DEBUG 732#ifdef DEBUG
728 printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); 733 printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
729#endif 734#endif
@@ -731,10 +736,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
731 736
732 /* This device doesn't support EEH, but it may have an 737 /* This device doesn't support EEH, but it may have an
733 * EEH parent, in which case we mark it as supported. */ 738 * EEH parent, in which case we mark it as supported. */
734 if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { 739 if (dn->parent && dn->parent->data
740 && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
735 /* Parent supports EEH. */ 741 /* Parent supports EEH. */
736 dn->eeh_mode |= EEH_MODE_SUPPORTED; 742 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
737 dn->eeh_config_addr = dn->parent->eeh_config_addr; 743 pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
738 return NULL; 744 return NULL;
739 } 745 }
740 } 746 }
@@ -791,11 +797,13 @@ void __init eeh_init(void)
791 for (phb = of_find_node_by_name(NULL, "pci"); phb; 797 for (phb = of_find_node_by_name(NULL, "pci"); phb;
792 phb = of_find_node_by_name(phb, "pci")) { 798 phb = of_find_node_by_name(phb, "pci")) {
793 unsigned long buid; 799 unsigned long buid;
800 struct pci_dn *pci;
794 801
795 buid = get_phb_buid(phb); 802 buid = get_phb_buid(phb);
796 if (buid == 0) 803 if (buid == 0 || phb->data == NULL)
797 continue; 804 continue;
798 805
806 pci = phb->data;
799 info.buid_lo = BUID_LO(buid); 807 info.buid_lo = BUID_LO(buid);
800 info.buid_hi = BUID_HI(buid); 808 info.buid_hi = BUID_HI(buid);
801 traverse_pci_devices(phb, early_enable_eeh, &info); 809 traverse_pci_devices(phb, early_enable_eeh, &info);
@@ -824,9 +832,9 @@ void eeh_add_device_early(struct device_node *dn)
824 struct pci_controller *phb; 832 struct pci_controller *phb;
825 struct eeh_early_enable_info info; 833 struct eeh_early_enable_info info;
826 834
827 if (!dn) 835 if (!dn || !dn->data)
828 return; 836 return;
829 phb = dn->phb; 837 phb = PCI_DN(dn)->phb;
830 if (NULL == phb || 0 == phb->buid) { 838 if (NULL == phb || 0 == phb->buid) {
831 printk(KERN_WARNING "EEH: Expected buid but found none\n"); 839 printk(KERN_WARNING "EEH: Expected buid but found none\n");
832 return; 840 return;
@@ -851,8 +859,7 @@ void eeh_add_device_late(struct pci_dev *dev)
851 return; 859 return;
852 860
853#ifdef DEBUG 861#ifdef DEBUG
854 printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev), 862 printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
855 pci_pretty_name(dev));
856#endif 863#endif
857 864
858 pci_addr_cache_insert_device (dev); 865 pci_addr_cache_insert_device (dev);
@@ -873,8 +880,7 @@ void eeh_remove_device(struct pci_dev *dev)
873 880
874 /* Unregister the device with the EEH/PCI address search system */ 881 /* Unregister the device with the EEH/PCI address search system */
875#ifdef DEBUG 882#ifdef DEBUG
876 printk(KERN_DEBUG "EEH: remove device %s %s\n", pci_name(dev), 883 printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
877 pci_pretty_name(dev));
878#endif 884#endif
879 pci_addr_cache_remove_device(dev); 885 pci_addr_cache_remove_device(dev);
880} 886}
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
index d11c732daf81..5d921792571f 100644
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
+++ b/arch/ppc64/kernel/iSeries_VpdInfo.c
@@ -264,8 +264,5 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
264 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", 264 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ",
265 count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, 265 count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
266 frame, card); 266 frame, card);
267 if (pci_class_name(PciDev->class >> 8) == 0) 267 printk("0x%04X\n", (int)(PciDev->class >> 8));
268 printk("0x%04X\n", (int)(PciDev->class >> 8));
269 else
270 printk("%s\n", pci_class_name(PciDev->class >> 8));
271} 268}
diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c
index 153cc8b0f136..6160c8dbb7c5 100644
--- a/arch/ppc64/kernel/iomap.c
+++ b/arch/ppc64/kernel/iomap.c
@@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr)
22{ 22{
23 return readw(addr); 23 return readw(addr);
24} 24}
25unsigned int fastcall ioread16be(void __iomem *addr)
26{
27 return in_be16(addr);
28}
25unsigned int fastcall ioread32(void __iomem *addr) 29unsigned int fastcall ioread32(void __iomem *addr)
26{ 30{
27 return readl(addr); 31 return readl(addr);
28} 32}
33unsigned int fastcall ioread32be(void __iomem *addr)
34{
35 return in_be32(addr);
36}
29EXPORT_SYMBOL(ioread8); 37EXPORT_SYMBOL(ioread8);
30EXPORT_SYMBOL(ioread16); 38EXPORT_SYMBOL(ioread16);
39EXPORT_SYMBOL(ioread16be);
31EXPORT_SYMBOL(ioread32); 40EXPORT_SYMBOL(ioread32);
41EXPORT_SYMBOL(ioread32be);
32 42
33void fastcall iowrite8(u8 val, void __iomem *addr) 43void fastcall iowrite8(u8 val, void __iomem *addr)
34{ 44{
@@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr)
38{ 48{
39 writew(val, addr); 49 writew(val, addr);
40} 50}
51void fastcall iowrite16be(u16 val, void __iomem *addr)
52{
53 out_be16(addr, val);
54}
41void fastcall iowrite32(u32 val, void __iomem *addr) 55void fastcall iowrite32(u32 val, void __iomem *addr)
42{ 56{
43 writel(val, addr); 57 writel(val, addr);
44} 58}
59void fastcall iowrite32be(u32 val, void __iomem *addr)
60{
61 out_be32(addr, val);
62}
45EXPORT_SYMBOL(iowrite8); 63EXPORT_SYMBOL(iowrite8);
46EXPORT_SYMBOL(iowrite16); 64EXPORT_SYMBOL(iowrite16);
65EXPORT_SYMBOL(iowrite16be);
47EXPORT_SYMBOL(iowrite32); 66EXPORT_SYMBOL(iowrite32);
67EXPORT_SYMBOL(iowrite32be);
48 68
49/* 69/*
50 * These are the "repeat read/write" functions. Note the 70 * These are the "repeat read/write" functions. Note the
@@ -56,15 +76,15 @@ EXPORT_SYMBOL(iowrite32);
56 */ 76 */
57void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) 77void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
58{ 78{
59 _insb((u8 __force *) addr, dst, count); 79 _insb((u8 __iomem *) addr, dst, count);
60} 80}
61void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) 81void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
62{ 82{
63 _insw_ns((u16 __force *) addr, dst, count); 83 _insw_ns((u16 __iomem *) addr, dst, count);
64} 84}
65void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) 85void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
66{ 86{
67 _insl_ns((u32 __force *) addr, dst, count); 87 _insl_ns((u32 __iomem *) addr, dst, count);
68} 88}
69EXPORT_SYMBOL(ioread8_rep); 89EXPORT_SYMBOL(ioread8_rep);
70EXPORT_SYMBOL(ioread16_rep); 90EXPORT_SYMBOL(ioread16_rep);
@@ -72,15 +92,15 @@ EXPORT_SYMBOL(ioread32_rep);
72 92
73void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 93void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
74{ 94{
75 _outsb((u8 __force *) addr, src, count); 95 _outsb((u8 __iomem *) addr, src, count);
76} 96}
77void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 97void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
78{ 98{
79 _outsw_ns((u16 __force *) addr, src, count); 99 _outsw_ns((u16 __iomem *) addr, src, count);
80} 100}
81void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 101void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
82{ 102{
83 _outsl_ns((u32 __force *) addr, src, count); 103 _outsl_ns((u32 __iomem *) addr, src, count);
84} 104}
85EXPORT_SYMBOL(iowrite8_rep); 105EXPORT_SYMBOL(iowrite8_rep);
86EXPORT_SYMBOL(iowrite16_rep); 106EXPORT_SYMBOL(iowrite16_rep);
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 845eebd1e28d..9032b6bfe036 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -438,7 +438,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
438 438
439void iommu_free_table(struct device_node *dn) 439void iommu_free_table(struct device_node *dn)
440{ 440{
441 struct iommu_table *tbl = dn->iommu_table; 441 struct pci_dn *pdn = dn->data;
442 struct iommu_table *tbl = pdn->iommu_table;
442 unsigned long bitmap_sz, i; 443 unsigned long bitmap_sz, i;
443 unsigned int order; 444 unsigned int order;
444 445
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
index 53993999b265..5a8b4d8c2dd6 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/ppc64/kernel/maple_pci.c
@@ -447,9 +447,9 @@ void __init maple_pci_init(void)
447 */ 447 */
448 if (u3_agp) { 448 if (u3_agp) {
449 struct device_node *np = u3_agp->arch_data; 449 struct device_node *np = u3_agp->arch_data;
450 np->busno = 0xf0; 450 PCI_DN(np)->busno = 0xf0;
451 for (np = np->child; np; np = np->sibling) 451 for (np = np->child; np; np = np->sibling)
452 np->busno = 0xf0; 452 PCI_DN(np)->busno = 0xf0;
453 } 453 }
454 454
455 /* Tell pci.c to use the common resource allocation mecanism */ 455 /* Tell pci.c to use the common resource allocation mecanism */
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 757903544e24..e7241ad80a08 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -1431,9 +1431,9 @@ _GLOBAL(sys_call_table)
1431 .llong .sys_ni_syscall /* 195 - 32bit only stat64 */ 1431 .llong .sys_ni_syscall /* 195 - 32bit only stat64 */
1432 .llong .sys_ni_syscall /* 32bit only lstat64 */ 1432 .llong .sys_ni_syscall /* 32bit only lstat64 */
1433 .llong .sys_ni_syscall /* 32bit only fstat64 */ 1433 .llong .sys_ni_syscall /* 32bit only fstat64 */
1434 .llong .sys_ni_syscall /* 32bit only pciconfig_read */ 1434 .llong .sys_pciconfig_read
1435 .llong .sys_ni_syscall /* 32bit only pciconfig_write */ 1435 .llong .sys_pciconfig_write
1436 .llong .sys_ni_syscall /* 32bit only pciconfig_iobase */ 1436 .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */
1437 .llong .sys_ni_syscall /* reserved for MacOnLinux */ 1437 .llong .sys_ni_syscall /* reserved for MacOnLinux */
1438 .llong .sys_getdents64 1438 .llong .sys_getdents64
1439 .llong .sys_pivot_root 1439 .llong .sys_pivot_root
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 9d5e1e7fc389..f0fd7fbd6531 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/ppc64/kernel/pSeries_iommu.c
@@ -295,7 +295,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
295 struct iommu_table *tbl, 295 struct iommu_table *tbl,
296 unsigned int *dma_window) 296 unsigned int *dma_window)
297{ 297{
298 tbl->it_busno = dn->bussubno; 298 tbl->it_busno = PCI_DN(dn)->bussubno;
299 299
300 /* TODO: Parse field size properties properly. */ 300 /* TODO: Parse field size properties properly. */
301 tbl->it_size = (((unsigned long)dma_window[4] << 32) | 301 tbl->it_size = (((unsigned long)dma_window[4] << 32) |
@@ -311,6 +311,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
311static void iommu_bus_setup_pSeries(struct pci_bus *bus) 311static void iommu_bus_setup_pSeries(struct pci_bus *bus)
312{ 312{
313 struct device_node *dn, *pdn; 313 struct device_node *dn, *pdn;
314 struct pci_dn *pci;
314 struct iommu_table *tbl; 315 struct iommu_table *tbl;
315 316
316 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); 317 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
@@ -325,6 +326,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
325 */ 326 */
326 327
327 dn = pci_bus_to_OF_node(bus); 328 dn = pci_bus_to_OF_node(bus);
329 pci = dn->data;
328 330
329 if (!bus->self) { 331 if (!bus->self) {
330 /* Root bus */ 332 /* Root bus */
@@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
341 * alltogether. This leaves 768MB for the window. 343 * alltogether. This leaves 768MB for the window.
342 */ 344 */
343 DBG("PHB has io-hole, reserving 256MB\n"); 345 DBG("PHB has io-hole, reserving 256MB\n");
344 dn->phb->dma_window_size = 3 << 28; 346 pci->phb->dma_window_size = 3 << 28;
345 dn->phb->dma_window_base_cur = 1 << 28; 347 pci->phb->dma_window_base_cur = 1 << 28;
346 } else { 348 } else {
347 /* 1GB window by default */ 349 /* 1GB window by default */
348 dn->phb->dma_window_size = 1 << 30; 350 pci->phb->dma_window_size = 1 << 30;
349 dn->phb->dma_window_base_cur = 0; 351 pci->phb->dma_window_base_cur = 0;
350 } 352 }
351 353
352 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 354 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
353 355
354 iommu_table_setparms(dn->phb, dn, tbl); 356 iommu_table_setparms(pci->phb, dn, tbl);
355 dn->iommu_table = iommu_init_table(tbl); 357 pci->iommu_table = iommu_init_table(tbl);
356 } else { 358 } else {
357 /* Do a 128MB table at root. This is used for the IDE 359 /* Do a 128MB table at root. This is used for the IDE
358 * controller on some SMP-mode POWER4 machines. It 360 * controller on some SMP-mode POWER4 machines. It
@@ -363,16 +365,16 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
363 * Allocate at offset 128MB to avoid having to deal 365 * Allocate at offset 128MB to avoid having to deal
364 * with ISA holes; 128MB table for IDE is plenty. 366 * with ISA holes; 128MB table for IDE is plenty.
365 */ 367 */
366 dn->phb->dma_window_size = 1 << 27; 368 pci->phb->dma_window_size = 1 << 27;
367 dn->phb->dma_window_base_cur = 1 << 27; 369 pci->phb->dma_window_base_cur = 1 << 27;
368 370
369 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 371 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
370 372
371 iommu_table_setparms(dn->phb, dn, tbl); 373 iommu_table_setparms(pci->phb, dn, tbl);
372 dn->iommu_table = iommu_init_table(tbl); 374 pci->iommu_table = iommu_init_table(tbl);
373 375
374 /* All child buses have 256MB tables */ 376 /* All child buses have 256MB tables */
375 dn->phb->dma_window_size = 1 << 28; 377 pci->phb->dma_window_size = 1 << 28;
376 } 378 }
377 } else { 379 } else {
378 pdn = pci_bus_to_OF_node(bus->parent); 380 pdn = pci_bus_to_OF_node(bus->parent);
@@ -386,12 +388,12 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
386 388
387 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 389 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
388 390
389 iommu_table_setparms(dn->phb, dn, tbl); 391 iommu_table_setparms(pci->phb, dn, tbl);
390 392
391 dn->iommu_table = iommu_init_table(tbl); 393 pci->iommu_table = iommu_init_table(tbl);
392 } else { 394 } else {
393 /* Lower than first child or under python, use parent table */ 395 /* Lower than first child or under python, use parent table */
394 dn->iommu_table = pdn->iommu_table; 396 pci->iommu_table = PCI_DN(pdn)->iommu_table;
395 } 397 }
396 } 398 }
397} 399}
@@ -401,6 +403,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
401{ 403{
402 struct iommu_table *tbl; 404 struct iommu_table *tbl;
403 struct device_node *dn, *pdn; 405 struct device_node *dn, *pdn;
406 struct pci_dn *ppci;
404 unsigned int *dma_window = NULL; 407 unsigned int *dma_window = NULL;
405 408
406 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); 409 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
@@ -419,22 +422,24 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
419 return; 422 return;
420 } 423 }
421 424
422 if (!pdn->iommu_table) { 425 ppci = pdn->data;
426 if (!ppci->iommu_table) {
423 /* Bussubno hasn't been copied yet. 427 /* Bussubno hasn't been copied yet.
424 * Do it now because iommu_table_setparms_lpar needs it. 428 * Do it now because iommu_table_setparms_lpar needs it.
425 */ 429 */
426 pdn->bussubno = bus->number; 430
431 ppci->bussubno = bus->number;
427 432
428 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 433 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
429 GFP_KERNEL); 434 GFP_KERNEL);
430 435
431 iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); 436 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
432 437
433 pdn->iommu_table = iommu_init_table(tbl); 438 ppci->iommu_table = iommu_init_table(tbl);
434 } 439 }
435 440
436 if (pdn != dn) 441 if (pdn != dn)
437 dn->iommu_table = pdn->iommu_table; 442 PCI_DN(dn)->iommu_table = ppci->iommu_table;
438} 443}
439 444
440 445
@@ -449,11 +454,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
449 */ 454 */
450 mydn = dn = pci_device_to_OF_node(dev); 455 mydn = dn = pci_device_to_OF_node(dev);
451 456
452 while (dn && dn->iommu_table == NULL) 457 while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
453 dn = dn->parent; 458 dn = dn->parent;
454 459
455 if (dn) { 460 if (dn && dn->data) {
456 mydn->iommu_table = dn->iommu_table; 461 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
457 } else { 462 } else {
458 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); 463 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
459 } 464 }
@@ -463,10 +468,11 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
463{ 468{
464 int err = NOTIFY_OK; 469 int err = NOTIFY_OK;
465 struct device_node *np = node; 470 struct device_node *np = node;
471 struct pci_dn *pci = np->data;
466 472
467 switch (action) { 473 switch (action) {
468 case PSERIES_RECONFIG_REMOVE: 474 case PSERIES_RECONFIG_REMOVE:
469 if (np->iommu_table && 475 if (pci->iommu_table &&
470 get_property(np, "ibm,dma-window", NULL)) 476 get_property(np, "ibm,dma-window", NULL))
471 iommu_free_table(np); 477 iommu_free_table(np);
472 break; 478 break;
@@ -486,6 +492,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
486 struct device_node *pdn, *dn; 492 struct device_node *pdn, *dn;
487 struct iommu_table *tbl; 493 struct iommu_table *tbl;
488 int *dma_window = NULL; 494 int *dma_window = NULL;
495 struct pci_dn *pci;
489 496
490 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); 497 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);
491 498
@@ -497,8 +504,10 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
497 */ 504 */
498 dn = pci_device_to_OF_node(dev); 505 dn = pci_device_to_OF_node(dev);
499 506
500 for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { 507 for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table;
501 dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); 508 pdn = pdn->parent) {
509 dma_window = (unsigned int *)
510 get_property(pdn, "ibm,dma-window", NULL);
502 if (dma_window) 511 if (dma_window)
503 break; 512 break;
504 } 513 }
@@ -515,20 +524,21 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
515 DBG("Found DMA window, allocating table\n"); 524 DBG("Found DMA window, allocating table\n");
516 } 525 }
517 526
518 if (!pdn->iommu_table) { 527 pci = pdn->data;
528 if (!pci->iommu_table) {
519 /* iommu_table_setparms_lpar needs bussubno. */ 529 /* iommu_table_setparms_lpar needs bussubno. */
520 pdn->bussubno = pdn->phb->bus->number; 530 pci->bussubno = pci->phb->bus->number;
521 531
522 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), 532 tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
523 GFP_KERNEL); 533 GFP_KERNEL);
524 534
525 iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); 535 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
526 536
527 pdn->iommu_table = iommu_init_table(tbl); 537 pci->iommu_table = iommu_init_table(tbl);
528 } 538 }
529 539
530 if (pdn != dn) 540 if (pdn != dn)
531 dn->iommu_table = pdn->iommu_table; 541 PCI_DN(dn)->iommu_table = pci->iommu_table;
532} 542}
533 543
534static void iommu_bus_setup_null(struct pci_bus *b) { } 544static void iommu_bus_setup_null(struct pci_bus *b) { }
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index d0d55c7908ef..8447dcc2c2b3 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -21,6 +21,7 @@
21#include <linux/bootmem.h> 21#include <linux/bootmem.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/syscalls.h>
24 25
25#include <asm/processor.h> 26#include <asm/processor.h>
26#include <asm/io.h> 27#include <asm/io.h>
@@ -84,7 +85,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev)
84 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { 85 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
85 dev->vendor = PCI_VENDOR_ID_AMD; 86 dev->vendor = PCI_VENDOR_ID_AMD;
86 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); 87 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
87 pci_name_device(dev);
88 } 88 }
89} 89}
90DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); 90DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
@@ -838,9 +838,11 @@ int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
838 * device tree. If they are then we need to scan all the 838 * device tree. If they are then we need to scan all the
839 * functions of this slot. 839 * functions of this slot.
840 */ 840 */
841 for (dn = busdn->child; dn; dn = dn->sibling) 841 for (dn = busdn->child; dn; dn = dn->sibling) {
842 if ((dn->devfn >> 3) == (devfn >> 3)) 842 struct pci_dn *pdn = dn->data;
843 if (pdn && (pdn->devfn >> 3) == (devfn >> 3))
843 return 1; 844 return 1;
845 }
844 846
845 return 0; 847 return 0;
846} 848}
@@ -983,3 +985,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
983} 985}
984 986
985#endif /* CONFIG_PPC_MULTIPLATFORM */ 987#endif /* CONFIG_PPC_MULTIPLATFORM */
988
989
990#define IOBASE_BRIDGE_NUMBER 0
991#define IOBASE_MEMORY 1
992#define IOBASE_IO 2
993#define IOBASE_ISA_IO 3
994#define IOBASE_ISA_MEM 4
995
996long sys_pciconfig_iobase(long which, unsigned long in_bus,
997 unsigned long in_devfn)
998{
999 struct pci_controller* hose;
1000 struct list_head *ln;
1001 struct pci_bus *bus = NULL;
1002 struct device_node *hose_node;
1003
1004 /* Argh ! Please forgive me for that hack, but that's the
1005 * simplest way to get existing XFree to not lockup on some
1006 * G5 machines... So when something asks for bus 0 io base
1007 * (bus 0 is HT root), we return the AGP one instead.
1008 */
1009#ifdef CONFIG_PPC_PMAC
1010 if (systemcfg->platform == PLATFORM_POWERMAC &&
1011 machine_is_compatible("MacRISC4"))
1012 if (in_bus == 0)
1013 in_bus = 0xf0;
1014#endif /* CONFIG_PPC_PMAC */
1015
1016 /* That syscall isn't quite compatible with PCI domains, but it's
1017 * used on pre-domains setup. We return the first match
1018 */
1019
1020 for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
1021 bus = pci_bus_b(ln);
1022 if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
1023 break;
1024 bus = NULL;
1025 }
1026 if (bus == NULL || bus->sysdata == NULL)
1027 return -ENODEV;
1028
1029 hose_node = (struct device_node *)bus->sysdata;
1030 hose = PCI_DN(hose_node)->phb;
1031
1032 switch (which) {
1033 case IOBASE_BRIDGE_NUMBER:
1034 return (long)hose->first_busno;
1035 case IOBASE_MEMORY:
1036 return (long)hose->pci_mem_offset;
1037 case IOBASE_IO:
1038 return (long)hose->io_base_phys;
1039 case IOBASE_ISA_IO:
1040 return (long)isa_io_base;
1041 case IOBASE_ISA_MEM:
1042 return -EINVAL;
1043 }
1044
1045 return -EOPNOTSUPP;
1046}
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 26be78b13af1..5eb2cc320566 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -34,7 +34,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
34 34
35void pci_devs_phb_init(void); 35void pci_devs_phb_init(void);
36void pci_devs_phb_init_dynamic(struct pci_controller *phb); 36void pci_devs_phb_init_dynamic(struct pci_controller *phb);
37struct device_node *fetch_dev_dn(struct pci_dev *dev);
38 37
39/* PCI address cache management routines */ 38/* PCI address cache management routines */
40void pci_addr_cache_insert_device(struct pci_dev *dev); 39void pci_addr_cache_insert_device(struct pci_dev *dev);
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index ec345462afc3..a86389d07d57 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -23,6 +23,8 @@
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/bootmem.h>
26 28
27#include <asm/io.h> 29#include <asm/io.h>
28#include <asm/prom.h> 30#include <asm/prom.h>
@@ -40,16 +42,26 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
40 struct pci_controller *phb = data; 42 struct pci_controller *phb = data;
41 int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); 43 int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
42 u32 *regs; 44 u32 *regs;
43 45 struct pci_dn *pdn;
44 dn->phb = phb; 46
47 if (phb->is_dynamic)
48 pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
49 else
50 pdn = alloc_bootmem(sizeof(*pdn));
51 if (pdn == NULL)
52 return NULL;
53 memset(pdn, 0, sizeof(*pdn));
54 dn->data = pdn;
55 pdn->node = dn;
56 pdn->phb = phb;
45 regs = (u32 *)get_property(dn, "reg", NULL); 57 regs = (u32 *)get_property(dn, "reg", NULL);
46 if (regs) { 58 if (regs) {
47 /* First register entry is addr (00BBSS00) */ 59 /* First register entry is addr (00BBSS00) */
48 dn->busno = (regs[0] >> 16) & 0xff; 60 pdn->busno = (regs[0] >> 16) & 0xff;
49 dn->devfn = (regs[0] >> 8) & 0xff; 61 pdn->devfn = (regs[0] >> 8) & 0xff;
50 } 62 }
51 63
52 dn->pci_ext_config_space = (type && *type == 1); 64 pdn->pci_ext_config_space = (type && *type == 1);
53 return NULL; 65 return NULL;
54} 66}
55 67
@@ -112,10 +124,15 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
112void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) 124void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
113{ 125{
114 struct device_node * dn = (struct device_node *) phb->arch_data; 126 struct device_node * dn = (struct device_node *) phb->arch_data;
127 struct pci_dn *pdn;
115 128
116 /* PHB nodes themselves must not match */ 129 /* PHB nodes themselves must not match */
117 dn->devfn = dn->busno = -1; 130 update_dn_pci_info(dn, phb);
118 dn->phb = phb; 131 pdn = dn->data;
132 if (pdn) {
133 pdn->devfn = pdn->busno = -1;
134 pdn->phb = phb;
135 }
119 136
120 /* Update dn->phb ptrs for new phb and children devices */ 137 /* Update dn->phb ptrs for new phb and children devices */
121 traverse_pci_devices(dn, update_dn_pci_info, phb); 138 traverse_pci_devices(dn, update_dn_pci_info, phb);
@@ -123,14 +140,17 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
123 140
124/* 141/*
125 * Traversal func that looks for a <busno,devfcn> value. 142 * Traversal func that looks for a <busno,devfcn> value.
126 * If found, the device_node is returned (thus terminating the traversal). 143 * If found, the pci_dn is returned (thus terminating the traversal).
127 */ 144 */
128static void *is_devfn_node(struct device_node *dn, void *data) 145static void *is_devfn_node(struct device_node *dn, void *data)
129{ 146{
130 int busno = ((unsigned long)data >> 8) & 0xff; 147 int busno = ((unsigned long)data >> 8) & 0xff;
131 int devfn = ((unsigned long)data) & 0xff; 148 int devfn = ((unsigned long)data) & 0xff;
149 struct pci_dn *pci = dn->data;
132 150
133 return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL; 151 if (pci && (devfn == pci->devfn) && (busno == pci->busno))
152 return dn;
153 return NULL;
134} 154}
135 155
136/* 156/*
@@ -149,13 +169,10 @@ static void *is_devfn_node(struct device_node *dn, void *data)
149struct device_node *fetch_dev_dn(struct pci_dev *dev) 169struct device_node *fetch_dev_dn(struct pci_dev *dev)
150{ 170{
151 struct device_node *orig_dn = dev->sysdata; 171 struct device_node *orig_dn = dev->sysdata;
152 struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */
153 struct device_node *phb_dn;
154 struct device_node *dn; 172 struct device_node *dn;
155 unsigned long searchval = (dev->bus->number << 8) | dev->devfn; 173 unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
156 174
157 phb_dn = phb->arch_data; 175 dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
158 dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval);
159 if (dn) 176 if (dn)
160 dev->sysdata = dn; 177 dev->sysdata = dn;
161 return dn; 178 return dn;
@@ -165,11 +182,13 @@ EXPORT_SYMBOL(fetch_dev_dn);
165static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 182static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
166{ 183{
167 struct device_node *np = node; 184 struct device_node *np = node;
185 struct pci_dn *pci;
168 int err = NOTIFY_OK; 186 int err = NOTIFY_OK;
169 187
170 switch (action) { 188 switch (action) {
171 case PSERIES_RECONFIG_ADD: 189 case PSERIES_RECONFIG_ADD:
172 update_dn_pci_info(np, np->parent->phb); 190 pci = np->parent->data;
191 update_dn_pci_info(np, pci->phb);
173 break; 192 break;
174 default: 193 default:
175 err = NOTIFY_DONE; 194 err = NOTIFY_DONE;
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
index ef0a62b916be..14647e09c9cd 100644
--- a/arch/ppc64/kernel/pci_iommu.c
+++ b/arch/ppc64/kernel/pci_iommu.c
@@ -66,7 +66,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
66#endif /* CONFIG_PPC_ISERIES */ 66#endif /* CONFIG_PPC_ISERIES */
67 67
68#ifdef CONFIG_PPC_MULTIPLATFORM 68#ifdef CONFIG_PPC_MULTIPLATFORM
69 return PCI_GET_DN(pdev)->iommu_table; 69 return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
70#endif /* CONFIG_PPC_MULTIPLATFORM */ 70#endif /* CONFIG_PPC_MULTIPLATFORM */
71} 71}
72 72
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
index 98ed2bccab1a..eb4e6c3f694d 100644
--- a/arch/ppc64/kernel/pmac_feature.c
+++ b/arch/ppc64/kernel/pmac_feature.c
@@ -674,6 +674,7 @@ void __init pmac_check_ht_link(void)
674#if 0 /* Disabled for now */ 674#if 0 /* Disabled for now */
675 u32 ufreq, freq, ucfg, cfg; 675 u32 ufreq, freq, ucfg, cfg;
676 struct device_node *pcix_node; 676 struct device_node *pcix_node;
677 struct pci_dn *pdn;
677 u8 px_bus, px_devfn; 678 u8 px_bus, px_devfn;
678 struct pci_controller *px_hose; 679 struct pci_controller *px_hose;
679 680
@@ -687,9 +688,10 @@ void __init pmac_check_ht_link(void)
687 printk("No PCI-X bridge found\n"); 688 printk("No PCI-X bridge found\n");
688 return; 689 return;
689 } 690 }
690 px_hose = pcix_node->phb; 691 pdn = pcix_node->data;
691 px_bus = pcix_node->busno; 692 px_hose = pdn->phb;
692 px_devfn = pcix_node->devfn; 693 px_bus = pdn->busno;
694 px_devfn = pdn->devfn;
693 695
694 early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); 696 early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
695 early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); 697 early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
index 71fe911ad183..d37bff2d7d40 100644
--- a/arch/ppc64/kernel/pmac_pci.c
+++ b/arch/ppc64/kernel/pmac_pci.c
@@ -242,7 +242,7 @@ static int u3_ht_skip_device(struct pci_controller *hose,
242 else 242 else
243 busdn = hose->arch_data; 243 busdn = hose->arch_data;
244 for (dn = busdn->child; dn; dn = dn->sibling) 244 for (dn = busdn->child; dn; dn = dn->sibling)
245 if (dn->devfn == devfn) 245 if (dn->data && PCI_DN(dn)->devfn == devfn)
246 break; 246 break;
247 if (dn == NULL) 247 if (dn == NULL)
248 return -1; 248 return -1;
@@ -746,9 +746,9 @@ void __init pmac_pci_init(void)
746 */ 746 */
747 if (u3_agp) { 747 if (u3_agp) {
748 struct device_node *np = u3_agp->arch_data; 748 struct device_node *np = u3_agp->arch_data;
749 np->busno = 0xf0; 749 PCI_DN(np)->busno = 0xf0;
750 for (np = np->child; np; np = np->sibling) 750 for (np = np->child; np; np = np->sibling)
751 np->busno = 0xf0; 751 PCI_DN(np)->busno = 0xf0;
752 } 752 }
753 753
754 pmac_check_ht_link(); 754 pmac_check_ht_link();
diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c
index cdfec7438d01..63d9481c3ec2 100644
--- a/arch/ppc64/kernel/pmc.c
+++ b/arch/ppc64/kernel/pmc.c
@@ -26,7 +26,7 @@ static void dummy_perf(struct pt_regs *regs)
26 mtspr(SPRN_MMCR0, mmcr0); 26 mtspr(SPRN_MMCR0, mmcr0);
27} 27}
28 28
29static spinlock_t pmc_owner_lock = SPIN_LOCK_UNLOCKED; 29static DEFINE_SPINLOCK(pmc_owner_lock);
30static void *pmc_owner_caller; /* mostly for debugging */ 30static void *pmc_owner_caller; /* mostly for debugging */
31perf_irq_t perf_irq = dummy_perf; 31perf_irq_t perf_irq = dummy_perf;
32 32
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 6ad5a8467f87..7035deb6de92 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -1733,6 +1733,7 @@ static void of_node_release(struct kref *kref)
1733 kfree(node->intrs); 1733 kfree(node->intrs);
1734 kfree(node->addrs); 1734 kfree(node->addrs);
1735 kfree(node->full_name); 1735 kfree(node->full_name);
1736 kfree(node->data);
1736 kfree(node); 1737 kfree(node);
1737} 1738}
1738 1739
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 1dccadaddd1d..4a9719b48abe 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@ static int write_pci_config;
48static int ibm_read_pci_config; 48static int ibm_read_pci_config;
49static int ibm_write_pci_config; 49static int ibm_write_pci_config;
50 50
51static int config_access_valid(struct device_node *dn, int where) 51static int config_access_valid(struct pci_dn *dn, int where)
52{ 52{
53 if (where < 256) 53 if (where < 256)
54 return 1; 54 return 1;
@@ -78,15 +78,17 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
78 int returnval = -1; 78 int returnval = -1;
79 unsigned long buid, addr; 79 unsigned long buid, addr;
80 int ret; 80 int ret;
81 struct pci_dn *pdn;
81 82
82 if (!dn) 83 if (!dn || !dn->data)
83 return PCIBIOS_DEVICE_NOT_FOUND; 84 return PCIBIOS_DEVICE_NOT_FOUND;
84 if (!config_access_valid(dn, where)) 85 pdn = dn->data;
86 if (!config_access_valid(pdn, where))
85 return PCIBIOS_BAD_REGISTER_NUMBER; 87 return PCIBIOS_BAD_REGISTER_NUMBER;
86 88
87 addr = ((where & 0xf00) << 20) | (dn->busno << 16) | 89 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
88 (dn->devfn << 8) | (where & 0xff); 90 (pdn->devfn << 8) | (where & 0xff);
89 buid = dn->phb->buid; 91 buid = pdn->phb->buid;
90 if (buid) { 92 if (buid) {
91 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, 93 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
92 addr, buid >> 32, buid & 0xffffffff, size); 94 addr, buid >> 32, buid & 0xffffffff, size);
@@ -98,8 +100,8 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
98 if (ret) 100 if (ret)
99 return PCIBIOS_DEVICE_NOT_FOUND; 101 return PCIBIOS_DEVICE_NOT_FOUND;
100 102
101 if (returnval == EEH_IO_ERROR_VALUE(size) 103 if (returnval == EEH_IO_ERROR_VALUE(size) &&
102 && eeh_dn_check_failure (dn, NULL)) 104 eeh_dn_check_failure (dn, NULL))
103 return PCIBIOS_DEVICE_NOT_FOUND; 105 return PCIBIOS_DEVICE_NOT_FOUND;
104 106
105 return PCIBIOS_SUCCESSFUL; 107 return PCIBIOS_SUCCESSFUL;
@@ -118,24 +120,28 @@ static int rtas_pci_read_config(struct pci_bus *bus,
118 120
119 /* Search only direct children of the bus */ 121 /* Search only direct children of the bus */
120 for (dn = busdn->child; dn; dn = dn->sibling) 122 for (dn = busdn->child; dn; dn = dn->sibling)
121 if (dn->devfn == devfn && of_device_available(dn)) 123 if (dn->data && PCI_DN(dn)->devfn == devfn
124 && of_device_available(dn))
122 return rtas_read_config(dn, where, size, val); 125 return rtas_read_config(dn, where, size, val);
126
123 return PCIBIOS_DEVICE_NOT_FOUND; 127 return PCIBIOS_DEVICE_NOT_FOUND;
124} 128}
125 129
126static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) 130int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
127{ 131{
128 unsigned long buid, addr; 132 unsigned long buid, addr;
129 int ret; 133 int ret;
134 struct pci_dn *pdn;
130 135
131 if (!dn) 136 if (!dn || !dn->data)
132 return PCIBIOS_DEVICE_NOT_FOUND; 137 return PCIBIOS_DEVICE_NOT_FOUND;
133 if (!config_access_valid(dn, where)) 138 pdn = dn->data;
139 if (!config_access_valid(pdn, where))
134 return PCIBIOS_BAD_REGISTER_NUMBER; 140 return PCIBIOS_BAD_REGISTER_NUMBER;
135 141
136 addr = ((where & 0xf00) << 20) | (dn->busno << 16) | 142 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
137 (dn->devfn << 8) | (where & 0xff); 143 (pdn->devfn << 8) | (where & 0xff);
138 buid = dn->phb->buid; 144 buid = pdn->phb->buid;
139 if (buid) { 145 if (buid) {
140 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); 146 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
141 } else { 147 } else {
@@ -161,7 +167,8 @@ static int rtas_pci_write_config(struct pci_bus *bus,
161 167
162 /* Search only direct children of the bus */ 168 /* Search only direct children of the bus */
163 for (dn = busdn->child; dn; dn = dn->sibling) 169 for (dn = busdn->child; dn; dn = dn->sibling)
164 if (dn->devfn == devfn && of_device_available(dn)) 170 if (dn->data && PCI_DN(dn)->devfn == devfn
171 && of_device_available(dn))
165 return rtas_write_config(dn, where, size, val); 172 return rtas_write_config(dn, where, size, val);
166 return PCIBIOS_DEVICE_NOT_FOUND; 173 return PCIBIOS_DEVICE_NOT_FOUND;
167} 174}
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index d0bb68af0ea4..bfa8791c9807 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -1283,7 +1283,7 @@ void __init generic_find_legacy_serial_ports(u64 *physport,
1283 1283
1284static struct platform_device serial_device = { 1284static struct platform_device serial_device = {
1285 .name = "serial8250", 1285 .name = "serial8250",
1286 .id = 0, 1286 .id = PLAT8250_DEV_PLATFORM,
1287 .dev = { 1287 .dev = {
1288 .platform_data = serial_ports, 1288 .platform_data = serial_ports,
1289 }, 1289 },
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 214914a95a50..e93c13458910 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -708,62 +708,9 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu
708 compat_ptr(ubuf)); 708 compat_ptr(ubuf));
709} 709}
710 710
711#define IOBASE_BRIDGE_NUMBER 0
712#define IOBASE_MEMORY 1
713#define IOBASE_IO 2
714#define IOBASE_ISA_IO 3
715#define IOBASE_ISA_MEM 4
716
717asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) 711asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
718{ 712{
719#ifdef CONFIG_PCI 713 return sys_pciconfig_iobase(which, in_bus, in_devfn);
720 struct pci_controller* hose;
721 struct list_head *ln;
722 struct pci_bus *bus = NULL;
723 struct device_node *hose_node;
724
725 /* Argh ! Please forgive me for that hack, but that's the
726 * simplest way to get existing XFree to not lockup on some
727 * G5 machines... So when something asks for bus 0 io base
728 * (bus 0 is HT root), we return the AGP one instead.
729 */
730#ifdef CONFIG_PPC_PMAC
731 if (systemcfg->platform == PLATFORM_POWERMAC &&
732 machine_is_compatible("MacRISC4"))
733 if (in_bus == 0)
734 in_bus = 0xf0;
735#endif /* CONFIG_PPC_PMAC */
736
737 /* That syscall isn't quite compatible with PCI domains, but it's
738 * used on pre-domains setup. We return the first match
739 */
740
741 for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
742 bus = pci_bus_b(ln);
743 if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
744 break;
745 bus = NULL;
746 }
747 if (bus == NULL || bus->sysdata == NULL)
748 return -ENODEV;
749
750 hose_node = (struct device_node *)bus->sysdata;
751 hose = hose_node->phb;
752
753 switch (which) {
754 case IOBASE_BRIDGE_NUMBER:
755 return (long)hose->first_busno;
756 case IOBASE_MEMORY:
757 return (long)hose->pci_mem_offset;
758 case IOBASE_IO:
759 return (long)hose->io_base_phys;
760 case IOBASE_ISA_IO:
761 return (long)isa_io_base;
762 case IOBASE_ISA_MEM:
763 return -EINVAL;
764 }
765#endif /* CONFIG_PCI */
766 return -EOPNOTSUPP;
767} 714}
768 715
769 716
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index a8cbb202b8cd..05f16633bd2c 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -46,10 +46,6 @@
46 46
47extern unsigned long wall_jiffies; 47extern unsigned long wall_jiffies;
48 48
49void
50check_bugs(void)
51{
52}
53 49
54/* 50/*
55 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 51 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
index b6e3bca4102d..41ea09cb9ac7 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/ppc64/kernel/u3_iommu.c
@@ -276,7 +276,7 @@ static void iommu_dev_setup_u3(struct pci_dev *dev)
276 dn = pci_device_to_OF_node(dev); 276 dn = pci_device_to_OF_node(dev);
277 277
278 if (dn) 278 if (dn)
279 dn->iommu_table = &iommu_table_u3; 279 PCI_DN(dn)->iommu_table = &iommu_table_u3;
280} 280}
281 281
282static void iommu_bus_setup_u3(struct pci_bus *bus) 282static void iommu_bus_setup_u3(struct pci_bus *bus)
@@ -291,7 +291,7 @@ static void iommu_bus_setup_u3(struct pci_bus *bus)
291 dn = pci_bus_to_OF_node(bus); 291 dn = pci_bus_to_OF_node(bus);
292 292
293 if (dn) 293 if (dn)
294 dn->iommu_table = &iommu_table_u3; 294 PCI_DN(dn)->iommu_table = &iommu_table_u3;
295} 295}
296 296
297static void iommu_dev_setup_null(struct pci_dev *dev) { } 297static void iommu_dev_setup_null(struct pci_dev *dev) { }
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
index ed6766e21f5a..d49c3613c8ec 100644
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/ppc64/kernel/udbg.c
@@ -158,14 +158,20 @@ static struct console udbg_console = {
158 .index = -1, 158 .index = -1,
159}; 159};
160 160
161static int early_console_initialized;
162
161void __init disable_early_printk(void) 163void __init disable_early_printk(void)
162{ 164{
165 if (!early_console_initialized)
166 return;
163 unregister_console(&udbg_console); 167 unregister_console(&udbg_console);
168 early_console_initialized = 0;
164} 169}
165 170
166/* called by setup_system */ 171/* called by setup_system */
167void register_early_udbg_console(void) 172void register_early_udbg_console(void)
168{ 173{
174 early_console_initialized = 1;
169 register_console(&udbg_console); 175 register_console(&udbg_console);
170} 176}
171 177
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a14ab87df491..c2157c9c3acb 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -554,12 +554,12 @@ void __init do_init_bootmem(void)
554 * present. 554 * present.
555 */ 555 */
556 for (i=0; i < lmb.memory.cnt; i++) 556 for (i=0; i < lmb.memory.cnt; i++)
557 free_bootmem(lmb_start_pfn(&lmb.memory, i), 557 free_bootmem(lmb.memory.region[i].base,
558 lmb_size_bytes(&lmb.memory, i)); 558 lmb_size_bytes(&lmb.memory, i));
559 559
560 /* reserve the sections we're already using */ 560 /* reserve the sections we're already using */
561 for (i=0; i < lmb.reserved.cnt; i++) 561 for (i=0; i < lmb.reserved.cnt; i++)
562 reserve_bootmem(lmb_start_pfn(&lmb.reserved, i), 562 reserve_bootmem(lmb.reserved.region[i].base,
563 lmb_size_bytes(&lmb.reserved, i)); 563 lmb_size_bytes(&lmb.reserved, i));
564 564
565 for (i=0; i < lmb.memory.cnt; i++) 565 for (i=0; i < lmb.memory.cnt; i++)
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 189c8f3a369c..98db30481d97 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -19,6 +19,7 @@ CFLAGS += -m31
19AFLAGS += -m31 19AFLAGS += -m31
20UTS_MACHINE := s390 20UTS_MACHINE := s390
21STACK_SIZE := 8192 21STACK_SIZE := 8192
22CHECKFLAGS += -D__s390__
22endif 23endif
23 24
24ifdef CONFIG_ARCH_S390X 25ifdef CONFIG_ARCH_S390X
@@ -28,6 +29,7 @@ CFLAGS += -m64
28AFLAGS += -m64 29AFLAGS += -m64
29UTS_MACHINE := s390x 30UTS_MACHINE := s390x
30STACK_SIZE := 16384 31STACK_SIZE := 16384
32CHECKFLAGS += -D__s390__ -D__s390x__
31endif 33endif
32 34
33cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) 35cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5)
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 19724c5800a7..2e64e8c3e8e5 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -20,7 +20,7 @@ spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
20 20
21#else /* SMP */ 21#else /* SMP */
22 22
23static spinlock_t dummy = SPIN_LOCK_UNLOCKED; 23static DEFINE_SPINLOCK(dummy);
24#define ATOMIC_HASH_SIZE 1 24#define ATOMIC_HASH_SIZE 1
25#define ATOMIC_HASH(a) (&dummy) 25#define ATOMIC_HASH(a) (&dummy)
26 26
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index ec8bf4012c0c..2ff7c32ab0ce 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -359,134 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus)
359 pbus->resource[1] = &pbm->mem_space; 359 pbus->resource[1] = &pbm->mem_space;
360} 360}
361 361
362int pci_claim_resource(struct pci_dev *pdev, int resource) 362struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r)
363{ 363{
364 struct pci_pbm_info *pbm = pdev->bus->sysdata; 364 struct pci_pbm_info *pbm = pdev->bus->sysdata;
365 struct resource *res = &pdev->resource[resource]; 365 struct resource *root = NULL;
366 struct resource *root;
367
368 if (!pbm)
369 return -EINVAL;
370 366
371 if (res->flags & IORESOURCE_IO) 367 if (r->flags & IORESOURCE_IO)
372 root = &pbm->io_space; 368 root = &pbm->io_space;
373 else 369 if (r->flags & IORESOURCE_MEM)
374 root = &pbm->mem_space; 370 root = &pbm->mem_space;
375 371
376 pbm->parent->resource_adjust(pdev, res, root); 372 return root;
377
378 return request_resource(root, res);
379}
380
381/*
382 * Given the PCI bus a device resides on, try to
383 * find an acceptable resource allocation for a
384 * specific device resource..
385 */
386static int pci_assign_bus_resource(const struct pci_bus *bus,
387 struct pci_dev *dev,
388 struct resource *res,
389 unsigned long size,
390 unsigned long min,
391 int resno)
392{
393 unsigned int type_mask;
394 int i;
395
396 type_mask = IORESOURCE_IO | IORESOURCE_MEM;
397 for (i = 0 ; i < 4; i++) {
398 struct resource *r = bus->resource[i];
399 if (!r)
400 continue;
401
402 /* type_mask must match */
403 if ((res->flags ^ r->flags) & type_mask)
404 continue;
405
406 /* Ok, try it out.. */
407 if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
408 continue;
409
410 /* PCI config space updated by caller. */
411 return 0;
412 }
413 return -EBUSY;
414}
415
416int pci_assign_resource(struct pci_dev *pdev, int resource)
417{
418 struct pcidev_cookie *pcp = pdev->sysdata;
419 struct pci_pbm_info *pbm = pcp->pbm;
420 struct resource *res = &pdev->resource[resource];
421 unsigned long min, size;
422 int err;
423
424 if (res->flags & IORESOURCE_IO)
425 min = pbm->io_space.start + 0x400UL;
426 else
427 min = pbm->mem_space.start;
428
429 size = res->end - res->start + 1;
430
431 err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
432
433 if (err < 0) {
434 printk("PCI: Failed to allocate resource %d for %s\n",
435 resource, pci_name(pdev));
436 } else {
437 /* Update PCI config space. */
438 pbm->parent->base_address_update(pdev, resource);
439 }
440
441 return err;
442}
443
444/* Sort resources by alignment */
445void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
446{
447 int i;
448
449 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
450 struct resource *r;
451 struct resource_list *list, *tmp;
452 unsigned long r_align;
453
454 r = &dev->resource[i];
455 r_align = r->end - r->start;
456
457 if (!(r->flags) || r->parent)
458 continue;
459 if (!r_align) {
460 printk(KERN_WARNING "PCI: Ignore bogus resource %d "
461 "[%lx:%lx] of %s\n",
462 i, r->start, r->end, pci_name(dev));
463 continue;
464 }
465 r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
466 for (list = head; ; list = list->next) {
467 unsigned long align = 0;
468 struct resource_list *ln = list->next;
469 int idx;
470
471 if (ln) {
472 idx = ln->res - &ln->dev->resource[0];
473 align = (idx < PCI_BRIDGE_RESOURCES) ?
474 ln->res->end - ln->res->start + 1 :
475 ln->res->start;
476 }
477 if (r_align > align) {
478 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
479 if (!tmp)
480 panic("pdev_sort_resources(): "
481 "kmalloc() failed!\n");
482 tmp->next = ln;
483 tmp->res = r;
484 tmp->dev = dev;
485 list->next = tmp;
486 break;
487 }
488 }
489 }
490} 373}
491 374
492void pcibios_update_irq(struct pci_dev *pdev, int irq) 375void pcibios_update_irq(struct pci_dev *pdev, int irq)
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 91ab466d6c66..6ed1ef25e0ac 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -307,7 +307,7 @@ static unsigned char psycho_pil_table[] = {
307/*0x32*/15, /* Power Management */ 307/*0x32*/15, /* Power Management */
308}; 308};
309 309
310static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) 310static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
311{ 311{
312 int ret; 312 int ret;
313 313
@@ -344,9 +344,9 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
344 return ret; 344 return ret;
345} 345}
346 346
347static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm, 347static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
348 struct pci_dev *pdev, 348 struct pci_dev *pdev,
349 unsigned int ino) 349 unsigned int ino)
350{ 350{
351 struct ino_bucket *bucket; 351 struct ino_bucket *bucket;
352 unsigned long imap, iclr; 352 unsigned long imap, iclr;
@@ -1024,7 +1024,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
1024#define PSYCHO_CE_INO 0x2f 1024#define PSYCHO_CE_INO 0x2f
1025#define PSYCHO_PCIERR_A_INO 0x30 1025#define PSYCHO_PCIERR_A_INO 0x30
1026#define PSYCHO_PCIERR_B_INO 0x31 1026#define PSYCHO_PCIERR_B_INO 0x31
1027static void __init psycho_register_error_handlers(struct pci_controller_info *p) 1027static void psycho_register_error_handlers(struct pci_controller_info *p)
1028{ 1028{
1029 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 1029 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
1030 unsigned long base = p->pbm_A.controller_regs; 1030 unsigned long base = p->pbm_A.controller_regs;
@@ -1091,15 +1091,15 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
1091} 1091}
1092 1092
1093/* PSYCHO boot time probing and initialization. */ 1093/* PSYCHO boot time probing and initialization. */
1094static void __init psycho_resource_adjust(struct pci_dev *pdev, 1094static void psycho_resource_adjust(struct pci_dev *pdev,
1095 struct resource *res, 1095 struct resource *res,
1096 struct resource *root) 1096 struct resource *root)
1097{ 1097{
1098 res->start += root->start; 1098 res->start += root->start;
1099 res->end += root->start; 1099 res->end += root->start;
1100} 1100}
1101 1101
1102static void __init psycho_base_address_update(struct pci_dev *pdev, int resource) 1102static void psycho_base_address_update(struct pci_dev *pdev, int resource)
1103{ 1103{
1104 struct pcidev_cookie *pcp = pdev->sysdata; 1104 struct pcidev_cookie *pcp = pdev->sysdata;
1105 struct pci_pbm_info *pbm = pcp->pbm; 1105 struct pci_pbm_info *pbm = pcp->pbm;
@@ -1144,7 +1144,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
1144 pci_write_config_dword(pdev, where + 4, 0); 1144 pci_write_config_dword(pdev, where + 4, 0);
1145} 1145}
1146 1146
1147static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) 1147static void pbm_config_busmastering(struct pci_pbm_info *pbm)
1148{ 1148{
1149 u8 *addr; 1149 u8 *addr;
1150 1150
@@ -1161,8 +1161,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
1161 pci_config_write8(addr, 64); 1161 pci_config_write8(addr, 64);
1162} 1162}
1163 1163
1164static void __init pbm_scan_bus(struct pci_controller_info *p, 1164static void pbm_scan_bus(struct pci_controller_info *p,
1165 struct pci_pbm_info *pbm) 1165 struct pci_pbm_info *pbm)
1166{ 1166{
1167 struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); 1167 struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
1168 1168
@@ -1189,7 +1189,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
1189 pci_setup_busmastering(pbm, pbm->pci_bus); 1189 pci_setup_busmastering(pbm, pbm->pci_bus);
1190} 1190}
1191 1191
1192static void __init psycho_scan_bus(struct pci_controller_info *p) 1192static void psycho_scan_bus(struct pci_controller_info *p)
1193{ 1193{
1194 pbm_config_busmastering(&p->pbm_B); 1194 pbm_config_busmastering(&p->pbm_B);
1195 p->pbm_B.is_66mhz_capable = 0; 1195 p->pbm_B.is_66mhz_capable = 0;
@@ -1204,7 +1204,7 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
1204 psycho_register_error_handlers(p); 1204 psycho_register_error_handlers(p);
1205} 1205}
1206 1206
1207static void __init psycho_iommu_init(struct pci_controller_info *p) 1207static void psycho_iommu_init(struct pci_controller_info *p)
1208{ 1208{
1209 struct pci_iommu *iommu = p->pbm_A.iommu; 1209 struct pci_iommu *iommu = p->pbm_A.iommu;
1210 unsigned long tsbbase, i; 1210 unsigned long tsbbase, i;
@@ -1327,8 +1327,8 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
1327 psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); 1327 psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
1328} 1328}
1329 1329
1330static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, 1330static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1331 struct pci_pbm_info *pbm) 1331 struct pci_pbm_info *pbm)
1332{ 1332{
1333 char *name = pbm->name; 1333 char *name = pbm->name;
1334 1334
@@ -1481,7 +1481,7 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1481 1481
1482#define PSYCHO_CONFIGSPACE 0x001000000UL 1482#define PSYCHO_CONFIGSPACE 0x001000000UL
1483 1483
1484void __init psycho_init(int node, char *model_name) 1484void psycho_init(int node, char *model_name)
1485{ 1485{
1486 struct linux_prom64_registers pr_regs[3]; 1486 struct linux_prom64_registers pr_regs[3];
1487 struct pci_controller_info *p; 1487 struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 52bf3431a422..0ee6bd5b9ac6 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -554,7 +554,7 @@ static unsigned char sabre_pil_table[] = {
554/*0x32*/15, /* Power Management */ 554/*0x32*/15, /* Power Management */
555}; 555};
556 556
557static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) 557static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
558{ 558{
559 int ret; 559 int ret;
560 560
@@ -612,9 +612,9 @@ static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_a
612 sabre_read(sync_reg); 612 sabre_read(sync_reg);
613} 613}
614 614
615static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, 615static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
616 struct pci_dev *pdev, 616 struct pci_dev *pdev,
617 unsigned int ino) 617 unsigned int ino)
618{ 618{
619 struct ino_bucket *bucket; 619 struct ino_bucket *bucket;
620 unsigned long imap, iclr; 620 unsigned long imap, iclr;
@@ -1009,7 +1009,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
1009#define SABRE_UE_INO 0x2e 1009#define SABRE_UE_INO 0x2e
1010#define SABRE_CE_INO 0x2f 1010#define SABRE_CE_INO 0x2f
1011#define SABRE_PCIERR_INO 0x30 1011#define SABRE_PCIERR_INO 0x30
1012static void __init sabre_register_error_handlers(struct pci_controller_info *p) 1012static void sabre_register_error_handlers(struct pci_controller_info *p)
1013{ 1013{
1014 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 1014 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
1015 unsigned long base = pbm->controller_regs; 1015 unsigned long base = pbm->controller_regs;
@@ -1056,9 +1056,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
1056 sabre_write(base + SABRE_PCICTRL, tmp); 1056 sabre_write(base + SABRE_PCICTRL, tmp);
1057} 1057}
1058 1058
1059static void __init sabre_resource_adjust(struct pci_dev *pdev, 1059static void sabre_resource_adjust(struct pci_dev *pdev,
1060 struct resource *res, 1060 struct resource *res,
1061 struct resource *root) 1061 struct resource *root)
1062{ 1062{
1063 struct pci_pbm_info *pbm = pdev->bus->sysdata; 1063 struct pci_pbm_info *pbm = pdev->bus->sysdata;
1064 unsigned long base; 1064 unsigned long base;
@@ -1072,7 +1072,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev,
1072 res->end += base; 1072 res->end += base;
1073} 1073}
1074 1074
1075static void __init sabre_base_address_update(struct pci_dev *pdev, int resource) 1075static void sabre_base_address_update(struct pci_dev *pdev, int resource)
1076{ 1076{
1077 struct pcidev_cookie *pcp = pdev->sysdata; 1077 struct pcidev_cookie *pcp = pdev->sysdata;
1078 struct pci_pbm_info *pbm = pcp->pbm; 1078 struct pci_pbm_info *pbm = pcp->pbm;
@@ -1118,7 +1118,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
1118 pci_write_config_dword(pdev, where + 4, 0); 1118 pci_write_config_dword(pdev, where + 4, 0);
1119} 1119}
1120 1120
1121static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) 1121static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
1122{ 1122{
1123 struct pci_dev *pdev; 1123 struct pci_dev *pdev;
1124 1124
@@ -1181,7 +1181,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
1181 return cookie; 1181 return cookie;
1182} 1182}
1183 1183
1184static void __init sabre_scan_bus(struct pci_controller_info *p) 1184static void sabre_scan_bus(struct pci_controller_info *p)
1185{ 1185{
1186 static int once; 1186 static int once;
1187 struct pci_bus *sabre_bus, *pbus; 1187 struct pci_bus *sabre_bus, *pbus;
@@ -1262,9 +1262,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
1262 sabre_register_error_handlers(p); 1262 sabre_register_error_handlers(p);
1263} 1263}
1264 1264
1265static void __init sabre_iommu_init(struct pci_controller_info *p, 1265static void sabre_iommu_init(struct pci_controller_info *p,
1266 int tsbsize, unsigned long dvma_offset, 1266 int tsbsize, unsigned long dvma_offset,
1267 u32 dma_mask) 1267 u32 dma_mask)
1268{ 1268{
1269 struct pci_iommu *iommu = p->pbm_A.iommu; 1269 struct pci_iommu *iommu = p->pbm_A.iommu;
1270 unsigned long tsbbase, i, order; 1270 unsigned long tsbbase, i, order;
@@ -1345,8 +1345,8 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
1345 } 1345 }
1346} 1346}
1347 1347
1348static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, 1348static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1349 struct pci_pbm_info *pbm) 1349 struct pci_pbm_info *pbm)
1350{ 1350{
1351 char *name = pbm->name; 1351 char *name = pbm->name;
1352 unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; 1352 unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
@@ -1415,7 +1415,7 @@ static void __init pbm_register_toplevel_resources(struct pci_controller_info *p
1415 &pbm->mem_space); 1415 &pbm->mem_space);
1416} 1416}
1417 1417
1418static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) 1418static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
1419{ 1419{
1420 struct pci_pbm_info *pbm; 1420 struct pci_pbm_info *pbm;
1421 char namebuf[128]; 1421 char namebuf[128];
@@ -1552,7 +1552,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node,
1552 } 1552 }
1553} 1553}
1554 1554
1555void __init sabre_init(int pnode, char *model_name) 1555void sabre_init(int pnode, char *model_name)
1556{ 1556{
1557 struct linux_prom64_registers pr_regs[2]; 1557 struct linux_prom64_registers pr_regs[2];
1558 struct pci_controller_info *p; 1558 struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index 6a182bb66281..331382e1a75d 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -285,7 +285,7 @@ static unsigned char schizo_pil_table[] = {
285/*0x3f*/0, /* Reserved for NewLink */ 285/*0x3f*/0, /* Reserved for NewLink */
286}; 286};
287 287
288static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) 288static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
289{ 289{
290 int ret; 290 int ret;
291 291
@@ -1221,7 +1221,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
1221 * PCI bus units of the same Tomatillo. I still have not really 1221 * PCI bus units of the same Tomatillo. I still have not really
1222 * figured this out... 1222 * figured this out...
1223 */ 1223 */
1224static void __init tomatillo_register_error_handlers(struct pci_controller_info *p) 1224static void tomatillo_register_error_handlers(struct pci_controller_info *p)
1225{ 1225{
1226 struct pci_pbm_info *pbm; 1226 struct pci_pbm_info *pbm;
1227 unsigned int irq; 1227 unsigned int irq;
@@ -1359,7 +1359,7 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info
1359 (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); 1359 (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
1360} 1360}
1361 1361
1362static void __init schizo_register_error_handlers(struct pci_controller_info *p) 1362static void schizo_register_error_handlers(struct pci_controller_info *p)
1363{ 1363{
1364 struct pci_pbm_info *pbm; 1364 struct pci_pbm_info *pbm;
1365 unsigned int irq; 1365 unsigned int irq;
@@ -1505,7 +1505,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
1505 (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); 1505 (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
1506} 1506}
1507 1507
1508static void __init pbm_config_busmastering(struct pci_pbm_info *pbm) 1508static void pbm_config_busmastering(struct pci_pbm_info *pbm)
1509{ 1509{
1510 u8 *addr; 1510 u8 *addr;
1511 1511
@@ -1522,8 +1522,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
1522 pci_config_write8(addr, 64); 1522 pci_config_write8(addr, 64);
1523} 1523}
1524 1524
1525static void __init pbm_scan_bus(struct pci_controller_info *p, 1525static void pbm_scan_bus(struct pci_controller_info *p,
1526 struct pci_pbm_info *pbm) 1526 struct pci_pbm_info *pbm)
1527{ 1527{
1528 struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); 1528 struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
1529 1529
@@ -1550,8 +1550,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
1550 pci_setup_busmastering(pbm, pbm->pci_bus); 1550 pci_setup_busmastering(pbm, pbm->pci_bus);
1551} 1551}
1552 1552
1553static void __init __schizo_scan_bus(struct pci_controller_info *p, 1553static void __schizo_scan_bus(struct pci_controller_info *p,
1554 int chip_type) 1554 int chip_type)
1555{ 1555{
1556 if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) { 1556 if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {
1557 printk("PCI: Only one PCI bus module of controller found.\n"); 1557 printk("PCI: Only one PCI bus module of controller found.\n");
@@ -1577,17 +1577,17 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p,
1577 schizo_register_error_handlers(p); 1577 schizo_register_error_handlers(p);
1578} 1578}
1579 1579
1580static void __init schizo_scan_bus(struct pci_controller_info *p) 1580static void schizo_scan_bus(struct pci_controller_info *p)
1581{ 1581{
1582 __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO); 1582 __schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);
1583} 1583}
1584 1584
1585static void __init tomatillo_scan_bus(struct pci_controller_info *p) 1585static void tomatillo_scan_bus(struct pci_controller_info *p)
1586{ 1586{
1587 __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO); 1587 __schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);
1588} 1588}
1589 1589
1590static void __init schizo_base_address_update(struct pci_dev *pdev, int resource) 1590static void schizo_base_address_update(struct pci_dev *pdev, int resource)
1591{ 1591{
1592 struct pcidev_cookie *pcp = pdev->sysdata; 1592 struct pcidev_cookie *pcp = pdev->sysdata;
1593 struct pci_pbm_info *pbm = pcp->pbm; 1593 struct pci_pbm_info *pbm = pcp->pbm;
@@ -1632,9 +1632,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
1632 pci_write_config_dword(pdev, where + 4, 0); 1632 pci_write_config_dword(pdev, where + 4, 0);
1633} 1633}
1634 1634
1635static void __init schizo_resource_adjust(struct pci_dev *pdev, 1635static void schizo_resource_adjust(struct pci_dev *pdev,
1636 struct resource *res, 1636 struct resource *res,
1637 struct resource *root) 1637 struct resource *root)
1638{ 1638{
1639 res->start += root->start; 1639 res->start += root->start;
1640 res->end += root->start; 1640 res->end += root->start;
@@ -1702,8 +1702,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
1702 pbm->mem_space.start); 1702 pbm->mem_space.start);
1703} 1703}
1704 1704
1705static void __init pbm_register_toplevel_resources(struct pci_controller_info *p, 1705static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1706 struct pci_pbm_info *pbm) 1706 struct pci_pbm_info *pbm)
1707{ 1707{
1708 pbm->io_space.name = pbm->mem_space.name = pbm->name; 1708 pbm->io_space.name = pbm->mem_space.name = pbm->name;
1709 1709
@@ -1932,7 +1932,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1932#define TOMATILLO_PCI_IOC_TDIAG (0x2250UL) 1932#define TOMATILLO_PCI_IOC_TDIAG (0x2250UL)
1933#define TOMATILLO_PCI_IOC_DDIAG (0x2290UL) 1933#define TOMATILLO_PCI_IOC_DDIAG (0x2290UL)
1934 1934
1935static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) 1935static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1936{ 1936{
1937 u64 tmp; 1937 u64 tmp;
1938 1938
@@ -1986,9 +1986,9 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1986 } 1986 }
1987} 1987}
1988 1988
1989static void __init schizo_pbm_init(struct pci_controller_info *p, 1989static void schizo_pbm_init(struct pci_controller_info *p,
1990 int prom_node, u32 portid, 1990 int prom_node, u32 portid,
1991 int chip_type) 1991 int chip_type)
1992{ 1992{
1993 struct linux_prom64_registers pr_regs[4]; 1993 struct linux_prom64_registers pr_regs[4];
1994 unsigned int busrange[2]; 1994 unsigned int busrange[2];
@@ -2145,7 +2145,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
2145 return (x == y); 2145 return (x == y);
2146} 2146}
2147 2147
2148static void __init __schizo_init(int node, char *model_name, int chip_type) 2148static void __schizo_init(int node, char *model_name, int chip_type)
2149{ 2149{
2150 struct pci_controller_info *p; 2150 struct pci_controller_info *p;
2151 struct pci_iommu *iommu; 2151 struct pci_iommu *iommu;
@@ -2213,17 +2213,17 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
2213 schizo_pbm_init(p, node, portid, chip_type); 2213 schizo_pbm_init(p, node, portid, chip_type);
2214} 2214}
2215 2215
2216void __init schizo_init(int node, char *model_name) 2216void schizo_init(int node, char *model_name)
2217{ 2217{
2218 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); 2218 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO);
2219} 2219}
2220 2220
2221void __init schizo_plus_init(int node, char *model_name) 2221void schizo_plus_init(int node, char *model_name)
2222{ 2222{
2223 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); 2223 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
2224} 2224}
2225 2225
2226void __init tomatillo_init(int node, char *model_name) 2226void tomatillo_init(int node, char *model_name)
2227{ 2227{
2228 __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); 2228 __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO);
2229} 2229}
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d89fc24808d3..7d9a0f6c437d 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -403,12 +403,3 @@ EXPORT_SYMBOL(xor_vis_4);
403EXPORT_SYMBOL(xor_vis_5); 403EXPORT_SYMBOL(xor_vis_5);
404 404
405EXPORT_SYMBOL(prom_palette); 405EXPORT_SYMBOL(prom_palette);
406
407/* memory barriers */
408EXPORT_SYMBOL(mb);
409EXPORT_SYMBOL(rmb);
410EXPORT_SYMBOL(wmb);
411EXPORT_SYMBOL(membar_storeload);
412EXPORT_SYMBOL(membar_storeload_storestore);
413EXPORT_SYMBOL(membar_storeload_loadload);
414EXPORT_SYMBOL(membar_storestore_loadstore);
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index 6201f1040982..40dbeec7e5d6 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -12,7 +12,7 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \
12 U1memcpy.o U1copy_from_user.o U1copy_to_user.o \ 12 U1memcpy.o U1copy_from_user.o U1copy_to_user.o \
13 U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \ 13 U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
14 copy_in_user.o user_fixup.o memmove.o \ 14 copy_in_user.o user_fixup.o memmove.o \
15 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o mb.o 15 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
16 16
17lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o 17lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
18lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o 18lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff --git a/arch/sparc64/lib/mb.S b/arch/sparc64/lib/mb.S
deleted file mode 100644
index 4004f748619f..000000000000
--- a/arch/sparc64/lib/mb.S
+++ /dev/null
@@ -1,73 +0,0 @@
1/* mb.S: Out of line memory barriers.
2 *
3 * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
4 */
5
6 /* These are here in an effort to more fully work around
7 * Spitfire Errata #51. Essentially, if a memory barrier
8 * occurs soon after a mispredicted branch, the chip can stop
9 * executing instructions until a trap occurs. Therefore, if
10 * interrupts are disabled, the chip can hang forever.
11 *
12 * It used to be believed that the memory barrier had to be
13 * right in the delay slot, but a case has been traced
14 * recently wherein the memory barrier was one instruction
15 * after the branch delay slot and the chip still hung. The
16 * offending sequence was the following in sym_wakeup_done()
17 * of the sym53c8xx_2 driver:
18 *
19 * call sym_ccb_from_dsa, 0
20 * movge %icc, 0, %l0
21 * brz,pn %o0, .LL1303
22 * mov %o0, %l2
23 * membar #LoadLoad
24 *
25 * The branch has to be mispredicted for the bug to occur.
26 * Therefore, we put the memory barrier explicitly into a
27 * "branch always, predicted taken" delay slot to avoid the
28 * problem case.
29 */
30
31 .text
32
3399: retl
34 nop
35
36 .globl mb
37mb: ba,pt %xcc, 99b
38 membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad
39 .size mb, .-mb
40
41 .globl rmb
42rmb: ba,pt %xcc, 99b
43 membar #LoadLoad
44 .size rmb, .-rmb
45
46 .globl wmb
47wmb: ba,pt %xcc, 99b
48 membar #StoreStore
49 .size wmb, .-wmb
50
51 .globl membar_storeload
52membar_storeload:
53 ba,pt %xcc, 99b
54 membar #StoreLoad
55 .size membar_storeload, .-membar_storeload
56
57 .globl membar_storeload_storestore
58membar_storeload_storestore:
59 ba,pt %xcc, 99b
60 membar #StoreLoad | #StoreStore
61 .size membar_storeload_storestore, .-membar_storeload_storestore
62
63 .globl membar_storeload_loadload
64membar_storeload_loadload:
65 ba,pt %xcc, 99b
66 membar #StoreLoad | #LoadLoad
67 .size membar_storeload_loadload, .-membar_storeload_loadload
68
69 .globl membar_storestore_loadstore
70membar_storestore_loadstore:
71 ba,pt %xcc, 99b
72 membar #StoreStore | #LoadStore
73 .size membar_storestore_loadstore, .-membar_storestore_loadstore
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
index cac0a1cf0050..be0a054e3ed6 100644
--- a/arch/sparc64/solaris/ioctl.c
+++ b/arch/sparc64/solaris/ioctl.c
@@ -24,6 +24,7 @@
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/mtio.h> 25#include <linux/mtio.h>
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/rcupdate.h>
27#include <linux/compat.h> 28#include <linux/compat.h>
28 29
29#include <net/sock.h> 30#include <net/sock.h>
@@ -293,16 +294,18 @@ static struct module_info {
293static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) 294static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
294{ 295{
295 struct inode *ino; 296 struct inode *ino;
297 struct fdtable *fdt;
296 /* I wonder which of these tests are superfluous... --patrik */ 298 /* I wonder which of these tests are superfluous... --patrik */
297 spin_lock(&current->files->file_lock); 299 rcu_read_lock();
298 if (! current->files->fd[fd] || 300 fdt = files_fdtable(current->files);
299 ! current->files->fd[fd]->f_dentry || 301 if (! fdt->fd[fd] ||
300 ! (ino = current->files->fd[fd]->f_dentry->d_inode) || 302 ! fdt->fd[fd]->f_dentry ||
303 ! (ino = fdt->fd[fd]->f_dentry->d_inode) ||
301 ! S_ISSOCK(ino->i_mode)) { 304 ! S_ISSOCK(ino->i_mode)) {
302 spin_unlock(&current->files->file_lock); 305 rcu_read_unlock();
303 return TBADF; 306 return TBADF;
304 } 307 }
305 spin_unlock(&current->files->file_lock); 308 rcu_read_unlock();
306 309
307 switch (cmd & 0xff) { 310 switch (cmd & 0xff) {
308 case 109: /* SI_SOCKPARAMS */ 311 case 109: /* SI_SOCKPARAMS */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 022c80f43392..aaad29c35c83 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -143,9 +143,11 @@ static struct T_primsg *timod_mkctl(int size)
143static void timod_wake_socket(unsigned int fd) 143static void timod_wake_socket(unsigned int fd)
144{ 144{
145 struct socket *sock; 145 struct socket *sock;
146 struct fdtable *fdt;
146 147
147 SOLD("wakeing socket"); 148 SOLD("wakeing socket");
148 sock = SOCKET_I(current->files->fd[fd]->f_dentry->d_inode); 149 fdt = files_fdtable(current->files);
150 sock = SOCKET_I(fdt->fd[fd]->f_dentry->d_inode);
149 wake_up_interruptible(&sock->wait); 151 wake_up_interruptible(&sock->wait);
150 read_lock(&sock->sk->sk_callback_lock); 152 read_lock(&sock->sk->sk_callback_lock);
151 if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) 153 if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
@@ -157,9 +159,11 @@ static void timod_wake_socket(unsigned int fd)
157static void timod_queue(unsigned int fd, struct T_primsg *it) 159static void timod_queue(unsigned int fd, struct T_primsg *it)
158{ 160{
159 struct sol_socket_struct *sock; 161 struct sol_socket_struct *sock;
162 struct fdtable *fdt;
160 163
161 SOLD("queuing primsg"); 164 SOLD("queuing primsg");
162 sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; 165 fdt = files_fdtable(current->files);
166 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
163 it->next = sock->pfirst; 167 it->next = sock->pfirst;
164 sock->pfirst = it; 168 sock->pfirst = it;
165 if (!sock->plast) 169 if (!sock->plast)
@@ -171,9 +175,11 @@ static void timod_queue(unsigned int fd, struct T_primsg *it)
171static void timod_queue_end(unsigned int fd, struct T_primsg *it) 175static void timod_queue_end(unsigned int fd, struct T_primsg *it)
172{ 176{
173 struct sol_socket_struct *sock; 177 struct sol_socket_struct *sock;
178 struct fdtable *fdt;
174 179
175 SOLD("queuing primsg at end"); 180 SOLD("queuing primsg at end");
176 sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data; 181 fdt = files_fdtable(current->files);
182 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
177 it->next = NULL; 183 it->next = NULL;
178 if (sock->plast) 184 if (sock->plast)
179 sock->plast->next = it; 185 sock->plast->next = it;
@@ -344,6 +350,7 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
344 char *buf; 350 char *buf;
345 struct file *filp; 351 struct file *filp;
346 struct inode *ino; 352 struct inode *ino;
353 struct fdtable *fdt;
347 struct sol_socket_struct *sock; 354 struct sol_socket_struct *sock;
348 mm_segment_t old_fs = get_fs(); 355 mm_segment_t old_fs = get_fs();
349 long args[6]; 356 long args[6];
@@ -351,7 +358,9 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
351 (int (*)(int, unsigned long __user *))SYS(socketcall); 358 (int (*)(int, unsigned long __user *))SYS(socketcall);
352 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) = 359 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) =
353 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto); 360 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto);
354 filp = current->files->fd[fd]; 361
362 fdt = files_fdtable(current->files);
363 filp = fdt->fd[fd];
355 ino = filp->f_dentry->d_inode; 364 ino = filp->f_dentry->d_inode;
356 sock = (struct sol_socket_struct *)filp->private_data; 365 sock = (struct sol_socket_struct *)filp->private_data;
357 SOLD("entry"); 366 SOLD("entry");
@@ -620,6 +629,7 @@ int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __us
620 int oldflags; 629 int oldflags;
621 struct file *filp; 630 struct file *filp;
622 struct inode *ino; 631 struct inode *ino;
632 struct fdtable *fdt;
623 struct sol_socket_struct *sock; 633 struct sol_socket_struct *sock;
624 struct T_unitdata_ind udi; 634 struct T_unitdata_ind udi;
625 mm_segment_t old_fs = get_fs(); 635 mm_segment_t old_fs = get_fs();
@@ -632,7 +642,8 @@ int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __us
632 642
633 SOLD("entry"); 643 SOLD("entry");
634 SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); 644 SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
635 filp = current->files->fd[fd]; 645 fdt = files_fdtable(current->files);
646 filp = fdt->fd[fd];
636 ino = filp->f_dentry->d_inode; 647 ino = filp->f_dentry->d_inode;
637 sock = (struct sol_socket_struct *)filp->private_data; 648 sock = (struct sol_socket_struct *)filp->private_data;
638 SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); 649 SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
@@ -844,12 +855,14 @@ asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
844 int __user *flgptr; 855 int __user *flgptr;
845 int flags; 856 int flags;
846 int error = -EBADF; 857 int error = -EBADF;
858 struct fdtable *fdt;
847 859
848 SOLD("entry"); 860 SOLD("entry");
849 lock_kernel(); 861 lock_kernel();
850 if(fd >= NR_OPEN) goto out; 862 if(fd >= NR_OPEN) goto out;
851 863
852 filp = current->files->fd[fd]; 864 fdt = files_fdtable(current->files);
865 filp = fdt->fd[fd];
853 if(!filp) goto out; 866 if(!filp) goto out;
854 867
855 ino = filp->f_dentry->d_inode; 868 ino = filp->f_dentry->d_inode;
@@ -910,12 +923,14 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
910 struct strbuf ctl, dat; 923 struct strbuf ctl, dat;
911 int flags = (int) arg3; 924 int flags = (int) arg3;
912 int error = -EBADF; 925 int error = -EBADF;
926 struct fdtable *fdt;
913 927
914 SOLD("entry"); 928 SOLD("entry");
915 lock_kernel(); 929 lock_kernel();
916 if(fd >= NR_OPEN) goto out; 930 if(fd >= NR_OPEN) goto out;
917 931
918 filp = current->files->fd[fd]; 932 fdt = files_fdtable(current->files);
933 filp = fdt->fd[fd];
919 if(!filp) goto out; 934 if(!filp) goto out;
920 935
921 ino = filp->f_dentry->d_inode; 936 ino = filp->f_dentry->d_inode;
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index baddb5d64ca5..436abbba409b 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -8,6 +8,7 @@ START := 0x60000000
8#it's needed for headers to work! 8#it's needed for headers to work!
9CFLAGS += -U__$(SUBARCH)__ -fno-builtin 9CFLAGS += -U__$(SUBARCH)__ -fno-builtin
10USER_CFLAGS += -fno-builtin 10USER_CFLAGS += -fno-builtin
11CHECKFLAGS += -m64
11 12
12ELF_ARCH := i386:x86-64 13ELF_ARCH := i386:x86-64
13ELF_FORMAT := elf64-x86-64 14ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index cd6c280482cb..6ee3f3902e68 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,18 +18,18 @@
18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ 18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) 19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
20 20
21static inline int verify_area_skas(int type, const void * addr, 21static inline int verify_area_skas(int type, const void __user * addr,
22 unsigned long size) 22 unsigned long size)
23{ 23{
24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); 24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
25} 25}
26 26
27extern int copy_from_user_skas(void *to, const void *from, int n); 27extern int copy_from_user_skas(void *to, const void __user *from, int n);
28extern int copy_to_user_skas(void *to, const void *from, int n); 28extern int copy_to_user_skas(void __user *to, const void *from, int n);
29extern int strncpy_from_user_skas(char *dst, const char *src, int count); 29extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
30extern int __clear_user_skas(void *mem, int len); 30extern int __clear_user_skas(void __user *mem, int len);
31extern int clear_user_skas(void *mem, int len); 31extern int clear_user_skas(void __user *mem, int len);
32extern int strnlen_user_skas(const void *str, int len); 32extern int strnlen_user_skas(const void __user *str, int len);
33 33
34#endif 34#endif
35 35
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index 3fbb5fe26f49..aa6db384af80 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -33,7 +33,7 @@ extern unsigned long uml_physmem;
33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ 33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
34 (under_task_size(addr, size) || is_stack(addr, size)))) 34 (under_task_size(addr, size) || is_stack(addr, size))))
35 35
36static inline int verify_area_tt(int type, const void * addr, 36static inline int verify_area_tt(int type, const void __user * addr,
37 unsigned long size) 37 unsigned long size)
38{ 38{
39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); 39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
@@ -50,12 +50,12 @@ extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
50extern int __do_strnlen_user(const char *str, unsigned long n, 50extern int __do_strnlen_user(const char *str, unsigned long n,
51 void **fault_addr, void **fault_catcher); 51 void **fault_addr, void **fault_catcher);
52 52
53extern int copy_from_user_tt(void *to, const void *from, int n); 53extern int copy_from_user_tt(void *to, const void __user *from, int n);
54extern int copy_to_user_tt(void *to, const void *from, int n); 54extern int copy_to_user_tt(void __user *to, const void *from, int n);
55extern int strncpy_from_user_tt(char *dst, const char *src, int count); 55extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
56extern int __clear_user_tt(void *mem, int len); 56extern int __clear_user_tt(void __user *mem, int len);
57extern int clear_user_tt(void *mem, int len); 57extern int clear_user_tt(void __user *mem, int len);
58extern int strnlen_user_tt(const void *str, int len); 58extern int strnlen_user_tt(const void __user *str, int len);
59 59
60#endif 60#endif
61 61
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 17f305b6bade..59a1291f477e 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -9,6 +9,11 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9 9
10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ 10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
11 $(CFLAGS_$(notdir $@)) 11 $(CFLAGS_$(notdir $@))
12$(USER_OBJS): cmd_checksrc =
13$(USER_OBJS): quiet_cmd_checksrc =
14$(USER_OBJS): cmd_force_checksrc =
15$(USER_OBJS): quiet_cmd_force_checksrc =
16
12 17
13# The stubs and unmap.o can't try to call mcount or update basic block data 18# The stubs and unmap.o can't try to call mcount or update basic block data
14define unprofile 19define unprofile
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index d259f8a6f811..419758f19ca4 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -24,17 +24,26 @@
24static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr) 24static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr)
25{ 25{
26 26
27 struct file *file = fget(fd); 27 struct file *file;
28 struct tty_struct *real_tty; 28 struct tty_struct *real_tty;
29 int fput_needed, ret;
29 30
31 file = fget_light(fd, &fput_needed);
30 if (!file) 32 if (!file)
31 return -EBADF; 33 return -EBADF;
34
35 ret = -EINVAL;
32 if (file->f_op->ioctl != tty_ioctl) 36 if (file->f_op->ioctl != tty_ioctl)
33 return -EINVAL; 37 goto out;
34 real_tty = (struct tty_struct *)file->private_data; 38 real_tty = (struct tty_struct *)file->private_data;
35 if (!real_tty) 39 if (!real_tty)
36 return -EINVAL; 40 goto out;
37 return put_user(new_encode_dev(tty_devnum(real_tty)), ptr); 41
42 ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr);
43
44out:
45 fput_light(file, fput_needed);
46 return ret;
38} 47}
39 48
40#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */ 49#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 116ac5f53dce..bb0ae18ec02b 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -567,7 +567,7 @@ unsigned long pci_mem_start = 0xaeedbabe;
567 */ 567 */
568__init void e820_setup_gap(void) 568__init void e820_setup_gap(void)
569{ 569{
570 unsigned long gapstart, gapsize; 570 unsigned long gapstart, gapsize, round;
571 unsigned long last; 571 unsigned long last;
572 int i; 572 int i;
573 int found = 0; 573 int found = 0;
@@ -604,14 +604,14 @@ __init void e820_setup_gap(void)
604 } 604 }
605 605
606 /* 606 /*
607 * Start allocating dynamic PCI memory a bit into the gap, 607 * See how much we want to round up: start off with
608 * aligned up to the nearest megabyte. 608 * rounding to the next 1MB area.
609 *
610 * Question: should we try to pad it up a bit (do something
611 * like " + (gapsize >> 3)" in there too?). We now have the
612 * technology.
613 */ 609 */
614 pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; 610 round = 0x100000;
611 while ((gapsize >> 4) > round)
612 round += round;
613 /* Fun with two's complement */
614 pci_mem_start = (gapstart + round) & -round;
615 615
616 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", 616 printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
617 pci_mem_start, gapstart, gapsize); 617 pci_mem_start, gapstart, gapsize);
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index adc96282a9e2..6d57da96bf8c 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -78,8 +78,18 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
78 78
79static void flat_send_IPI_allbutself(int vector) 79static void flat_send_IPI_allbutself(int vector)
80{ 80{
81#ifndef CONFIG_HOTPLUG_CPU
81 if (((num_online_cpus()) - 1) >= 1) 82 if (((num_online_cpus()) - 1) >= 1)
82 __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); 83 __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL);
84#else
85 cpumask_t allbutme = cpu_online_map;
86 int me = get_cpu(); /* Ensure we are not preempted when we clear */
87 cpu_clear(me, allbutme);
88
89 if (!cpus_empty(allbutme))
90 flat_send_IPI_mask(allbutme, vector);
91 put_cpu();
92#endif
83} 93}
84 94
85static void flat_send_IPI_all(int vector) 95static void flat_send_IPI_all(int vector)
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 40e0aca088fb..5f1529be1237 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1167,9 +1167,9 @@ void disable_IO_APIC(void)
1167 clear_IO_APIC(); 1167 clear_IO_APIC();
1168 1168
1169 /* 1169 /*
1170 * If the i82559 is routed through an IOAPIC 1170 * If the i8259 is routed through an IOAPIC
1171 * Put that IOAPIC in virtual wire mode 1171 * Put that IOAPIC in virtual wire mode
1172 * so legacy interrups can be delivered. 1172 * so legacy interrupts can be delivered.
1173 */ 1173 */
1174 pin = find_isa_irq_pin(0, mp_ExtINT); 1174 pin = find_isa_irq_pin(0, mp_ExtINT);
1175 if (pin != -1) { 1175 if (pin != -1) {
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 90aeccd15190..4fb34b5cb1f9 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -894,23 +894,6 @@ static __init void disable_smp(void)
894 cpu_set(0, cpu_core_map[0]); 894 cpu_set(0, cpu_core_map[0]);
895} 895}
896 896
897/*
898 * Handle user cpus=... parameter.
899 */
900static __init void enforce_max_cpus(unsigned max_cpus)
901{
902 int i, k;
903 k = 0;
904 for (i = 0; i < NR_CPUS; i++) {
905 if (!cpu_possible(i))
906 continue;
907 if (++k > max_cpus) {
908 cpu_clear(i, cpu_possible_map);
909 cpu_clear(i, cpu_present_map);
910 }
911 }
912}
913
914#ifdef CONFIG_HOTPLUG_CPU 897#ifdef CONFIG_HOTPLUG_CPU
915/* 898/*
916 * cpu_possible_map should be static, it cannot change as cpu's 899 * cpu_possible_map should be static, it cannot change as cpu's
@@ -999,8 +982,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
999 current_cpu_data = boot_cpu_data; 982 current_cpu_data = boot_cpu_data;
1000 current_thread_info()->cpu = 0; /* needed? */ 983 current_thread_info()->cpu = 0; /* needed? */
1001 984
1002 enforce_max_cpus(max_cpus);
1003
1004#ifdef CONFIG_HOTPLUG_CPU 985#ifdef CONFIG_HOTPLUG_CPU
1005 prefill_possible_map(); 986 prefill_possible_map();
1006#endif 987#endif
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index c0a37d98b4f3..048542341204 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -376,19 +376,15 @@ static void do_fd_request(request_queue_t *);
376 376
377/************************* End of Prototypes **************************/ 377/************************* End of Prototypes **************************/
378 378
379static struct timer_list motor_off_timer = 379static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
380 TIMER_INITIALIZER(fd_motor_off_timer, 0, 0);
381 380
382#ifdef TRACKBUFFER 381#ifdef TRACKBUFFER
383static struct timer_list readtrack_timer = 382static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
384 TIMER_INITIALIZER(fd_readtrack_check, 0, 0);
385#endif 383#endif
386 384
387static struct timer_list timeout_timer = 385static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
388 TIMER_INITIALIZER(fd_times_out, 0, 0);
389 386
390static struct timer_list fd_timer = 387static DEFINE_TIMER(fd_timer, check_change, 0, 0);
391 TIMER_INITIALIZER(check_change, 0, 0);
392 388
393/* DAG: Haven't got a clue what this is? */ 389/* DAG: Haven't got a clue what this is? */
394int stdma_islocked(void) 390int stdma_islocked(void)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3998c9d35fe1..fe1e8126fbae 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -250,8 +250,7 @@ config ACPI_CUSTOM_DSDT_FILE
250 Enter the full path name to the file wich includes the AmlCode declaration. 250 Enter the full path name to the file wich includes the AmlCode declaration.
251 251
252config ACPI_BLACKLIST_YEAR 252config ACPI_BLACKLIST_YEAR
253 int "Disable ACPI for systems before Jan 1st this year" 253 int "Disable ACPI for systems before Jan 1st this year" if X86
254 depends on X86
255 default 0 254 default 0
256 help 255 help
257 enter a 4-digit year, eg. 2001 to disable ACPI by default 256 enter a 4-digit year, eg. 2001 to disable ACPI by default
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
index b8c260ed4b27..0aabfc2a59d9 100644
--- a/drivers/atm/idt77105.c
+++ b/drivers/atm/idt77105.c
@@ -50,10 +50,8 @@ static void idt77105_stats_timer_func(unsigned long);
50static void idt77105_restart_timer_func(unsigned long); 50static void idt77105_restart_timer_func(unsigned long);
51 51
52 52
53static struct timer_list stats_timer = 53static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func, 0, 0);
54 TIMER_INITIALIZER(idt77105_stats_timer_func, 0, 0); 54static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func, 0, 0);
55static struct timer_list restart_timer =
56 TIMER_INITIALIZER(idt77105_restart_timer_func, 0, 0);
57static int start_timer = 1; 55static int start_timer = 1;
58static struct idt77105_priv *idt77105_all = NULL; 56static struct idt77105_priv *idt77105_all = NULL;
59 57
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index a43575acb2c1..2e2e50e1167a 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -79,7 +79,7 @@ static IADEV *ia_dev[8];
79static struct atm_dev *_ia_dev[8]; 79static struct atm_dev *_ia_dev[8];
80static int iadev_count; 80static int iadev_count;
81static void ia_led_timer(unsigned long arg); 81static void ia_led_timer(unsigned long arg);
82static struct timer_list ia_timer = TIMER_INITIALIZER(ia_led_timer, 0, 0); 82static DEFINE_TIMER(ia_timer, ia_led_timer, 0, 0);
83static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ; 83static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
84static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ; 84static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
85static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER 85static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index ce933de48084..0e1f34fef0c8 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -371,7 +371,7 @@ static int acsi_revalidate (struct gendisk *disk);
371/************************* End of Prototypes **************************/ 371/************************* End of Prototypes **************************/
372 372
373 373
374struct timer_list acsi_timer = TIMER_INITIALIZER(acsi_times_out, 0, 0); 374DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0);
375 375
376 376
377#ifdef CONFIG_ATARI_SLM 377#ifdef CONFIG_ATARI_SLM
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e3be8c31a74c..a5c1c8e871ec 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -268,7 +268,7 @@ static int slm_get_pagesize( int device, int *w, int *h );
268/************************* End of Prototypes **************************/ 268/************************* End of Prototypes **************************/
269 269
270 270
271static struct timer_list slm_timer = TIMER_INITIALIZER(slm_test_ready, 0, 0); 271static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0);
272 272
273static struct file_operations slm_fops = { 273static struct file_operations slm_fops = {
274 .owner = THIS_MODULE, 274 .owner = THIS_MODULE,
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index db05a5a99f35..22bda05fc693 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -371,16 +371,10 @@ static int floppy_release( struct inode * inode, struct file * filp );
371 371
372/************************* End of Prototypes **************************/ 372/************************* End of Prototypes **************************/
373 373
374static struct timer_list motor_off_timer = 374static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
375 TIMER_INITIALIZER(fd_motor_off_timer, 0, 0); 375static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
376static struct timer_list readtrack_timer = 376static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
377 TIMER_INITIALIZER(fd_readtrack_check, 0, 0); 377static DEFINE_TIMER(fd_timer, check_change, 0, 0);
378
379static struct timer_list timeout_timer =
380 TIMER_INITIALIZER(fd_times_out, 0, 0);
381
382static struct timer_list fd_timer =
383 TIMER_INITIALIZER(check_change, 0, 0);
384 378
385static inline void start_motor_off_timer(void) 379static inline void start_motor_off_timer(void)
386{ 380{
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 24594c57c323..52a3ae5289a0 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -512,7 +512,10 @@ static int deadline_dispatch_requests(struct deadline_data *dd)
512 /* 512 /*
513 * batches are currently reads XOR writes 513 * batches are currently reads XOR writes
514 */ 514 */
515 drq = dd->next_drq[WRITE] ? : dd->next_drq[READ]; 515 if (dd->next_drq[WRITE])
516 drq = dd->next_drq[WRITE];
517 else
518 drq = dd->next_drq[READ];
516 519
517 if (drq) { 520 if (drq) {
518 /* we have a "next request" */ 521 /* we have a "next request" */
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 888dad5eef34..00895477155e 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -628,7 +628,7 @@ static inline void debugt(const char *message) { }
628#endif /* DEBUGT */ 628#endif /* DEBUGT */
629 629
630typedef void (*timeout_fn) (unsigned long); 630typedef void (*timeout_fn) (unsigned long);
631static struct timer_list fd_timeout = TIMER_INITIALIZER(floppy_shutdown, 0, 0); 631static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
632 632
633static const char *timeout_message; 633static const char *timeout_message;
634 634
@@ -1012,7 +1012,7 @@ static void schedule_bh(void (*handler) (void))
1012 schedule_work(&floppy_work); 1012 schedule_work(&floppy_work);
1013} 1013}
1014 1014
1015static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0); 1015static DEFINE_TIMER(fd_timer, NULL, 0, 0);
1016 1016
1017static void cancel_activity(void) 1017static void cancel_activity(void)
1018{ 1018{
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29548784cb7b..29d1518be72a 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -99,8 +99,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
99static int no_int_yet; 99static int no_int_yet;
100static int ps2esdi_drives; 100static int ps2esdi_drives;
101static u_short io_base; 101static u_short io_base;
102static struct timer_list esdi_timer = 102static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0);
103 TIMER_INITIALIZER(ps2esdi_reset_timer, 0, 0);
104static int reset_status; 103static int reset_status;
105static int ps2esdi_slot = -1; 104static int ps2esdi_slot = -1;
106static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */ 105static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index a026567f5d18..aa0bf7ee008d 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -16,9 +16,10 @@
16 * -- verify the 13 conditions and do bulk resets 16 * -- verify the 13 conditions and do bulk resets
17 * -- kill last_pipe and simply do two-state clearing on both pipes 17 * -- kill last_pipe and simply do two-state clearing on both pipes
18 * -- verify protocol (bulk) from USB descriptors (maybe...) 18 * -- verify protocol (bulk) from USB descriptors (maybe...)
19 * -- highmem and sg 19 * -- highmem
20 * -- move top_sense and work_bcs into separate allocations (if they survive) 20 * -- move top_sense and work_bcs into separate allocations (if they survive)
21 * for cache purists and esoteric architectures. 21 * for cache purists and esoteric architectures.
22 * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ?
22 * -- prune comments, they are too volumnous 23 * -- prune comments, they are too volumnous
23 * -- Exterminate P3 printks 24 * -- Exterminate P3 printks
24 * -- Resove XXX's 25 * -- Resove XXX's
@@ -171,7 +172,7 @@ struct bulk_cs_wrap {
171 */ 172 */
172struct ub_dev; 173struct ub_dev;
173 174
174#define UB_MAX_REQ_SG 1 175#define UB_MAX_REQ_SG 4
175#define UB_MAX_SECTORS 64 176#define UB_MAX_SECTORS 64
176 177
177/* 178/*
@@ -234,13 +235,10 @@ struct ub_scsi_cmd {
234 235
235 int stat_count; /* Retries getting status. */ 236 int stat_count; /* Retries getting status. */
236 237
237 /*
238 * We do not support transfers from highmem pages
239 * because the underlying USB framework does not do what we need.
240 */
241 char *data; /* Requested buffer */
242 unsigned int len; /* Requested length */ 238 unsigned int len; /* Requested length */
243 // struct scatterlist sgv[UB_MAX_REQ_SG]; 239 unsigned int current_sg;
240 unsigned int nsg; /* sgv[nsg] */
241 struct scatterlist sgv[UB_MAX_REQ_SG];
244 242
245 struct ub_lun *lun; 243 struct ub_lun *lun;
246 void (*done)(struct ub_dev *, struct ub_scsi_cmd *); 244 void (*done)(struct ub_dev *, struct ub_scsi_cmd *);
@@ -389,17 +387,18 @@ struct ub_dev {
389 struct bulk_cs_wrap work_bcs; 387 struct bulk_cs_wrap work_bcs;
390 struct usb_ctrlrequest work_cr; 388 struct usb_ctrlrequest work_cr;
391 389
390 int sg_stat[UB_MAX_REQ_SG+1];
392 struct ub_scsi_trace tr; 391 struct ub_scsi_trace tr;
393}; 392};
394 393
395/* 394/*
396 */ 395 */
397static void ub_cleanup(struct ub_dev *sc); 396static void ub_cleanup(struct ub_dev *sc);
398static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq); 397static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
399static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, 398static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
400 struct ub_scsi_cmd *cmd, struct request *rq); 399 struct ub_scsi_cmd *cmd, struct request *rq);
401static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, 400static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
402 struct request *rq); 401 struct ub_scsi_cmd *cmd, struct request *rq);
403static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); 402static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
404static void ub_end_rq(struct request *rq, int uptodate); 403static void ub_end_rq(struct request *rq, int uptodate);
405static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); 404static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -407,6 +406,7 @@ static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
407static void ub_scsi_action(unsigned long _dev); 406static void ub_scsi_action(unsigned long _dev);
408static void ub_scsi_dispatch(struct ub_dev *sc); 407static void ub_scsi_dispatch(struct ub_dev *sc);
409static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd); 408static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
409static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
410static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc); 410static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
411static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); 411static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
412static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); 412static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -500,7 +500,8 @@ static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
500 } 500 }
501} 501}
502 502
503static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page) 503static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
504 char *page)
504{ 505{
505 struct usb_interface *intf; 506 struct usb_interface *intf;
506 struct ub_dev *sc; 507 struct ub_dev *sc;
@@ -523,6 +524,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, c
523 cnt += sprintf(page + cnt, 524 cnt += sprintf(page + cnt,
524 "qlen %d qmax %d\n", 525 "qlen %d qmax %d\n",
525 sc->cmd_queue.qlen, sc->cmd_queue.qmax); 526 sc->cmd_queue.qlen, sc->cmd_queue.qmax);
527 cnt += sprintf(page + cnt,
528 "sg %d %d %d %d %d\n",
529 sc->sg_stat[0],
530 sc->sg_stat[1],
531 sc->sg_stat[2],
532 sc->sg_stat[3],
533 sc->sg_stat[4]);
526 534
527 list_for_each (p, &sc->luns) { 535 list_for_each (p, &sc->luns) {
528 lun = list_entry(p, struct ub_lun, link); 536 lun = list_entry(p, struct ub_lun, link);
@@ -744,20 +752,20 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc)
744 * The request function is our main entry point 752 * The request function is our main entry point
745 */ 753 */
746 754
747static void ub_bd_rq_fn(request_queue_t *q) 755static void ub_request_fn(request_queue_t *q)
748{ 756{
749 struct ub_lun *lun = q->queuedata; 757 struct ub_lun *lun = q->queuedata;
750 struct request *rq; 758 struct request *rq;
751 759
752 while ((rq = elv_next_request(q)) != NULL) { 760 while ((rq = elv_next_request(q)) != NULL) {
753 if (ub_bd_rq_fn_1(lun, rq) != 0) { 761 if (ub_request_fn_1(lun, rq) != 0) {
754 blk_stop_queue(q); 762 blk_stop_queue(q);
755 break; 763 break;
756 } 764 }
757 } 765 }
758} 766}
759 767
760static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) 768static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
761{ 769{
762 struct ub_dev *sc = lun->udev; 770 struct ub_dev *sc = lun->udev;
763 struct ub_scsi_cmd *cmd; 771 struct ub_scsi_cmd *cmd;
@@ -774,9 +782,8 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
774 memset(cmd, 0, sizeof(struct ub_scsi_cmd)); 782 memset(cmd, 0, sizeof(struct ub_scsi_cmd));
775 783
776 blkdev_dequeue_request(rq); 784 blkdev_dequeue_request(rq);
777
778 if (blk_pc_request(rq)) { 785 if (blk_pc_request(rq)) {
779 rc = ub_cmd_build_packet(sc, cmd, rq); 786 rc = ub_cmd_build_packet(sc, lun, cmd, rq);
780 } else { 787 } else {
781 rc = ub_cmd_build_block(sc, lun, cmd, rq); 788 rc = ub_cmd_build_block(sc, lun, cmd, rq);
782 } 789 }
@@ -791,7 +798,7 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
791 cmd->back = rq; 798 cmd->back = rq;
792 799
793 cmd->tag = sc->tagcnt++; 800 cmd->tag = sc->tagcnt++;
794 if ((rc = ub_submit_scsi(sc, cmd)) != 0) { 801 if (ub_submit_scsi(sc, cmd) != 0) {
795 ub_put_cmd(lun, cmd); 802 ub_put_cmd(lun, cmd);
796 ub_end_rq(rq, 0); 803 ub_end_rq(rq, 0);
797 return 0; 804 return 0;
@@ -804,58 +811,31 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
804 struct ub_scsi_cmd *cmd, struct request *rq) 811 struct ub_scsi_cmd *cmd, struct request *rq)
805{ 812{
806 int ub_dir; 813 int ub_dir;
807#if 0 /* We use rq->buffer for now */
808 struct scatterlist *sg;
809 int n_elem; 814 int n_elem;
810#endif
811 unsigned int block, nblks; 815 unsigned int block, nblks;
812 816
813 if (rq_data_dir(rq) == WRITE) 817 if (rq_data_dir(rq) == WRITE)
814 ub_dir = UB_DIR_WRITE; 818 ub_dir = UB_DIR_WRITE;
815 else 819 else
816 ub_dir = UB_DIR_READ; 820 ub_dir = UB_DIR_READ;
821 cmd->dir = ub_dir;
817 822
818 /* 823 /*
819 * get scatterlist from block layer 824 * get scatterlist from block layer
820 */ 825 */
821#if 0 /* We use rq->buffer for now */ 826 n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
822 sg = &cmd->sgv[0];
823 n_elem = blk_rq_map_sg(q, rq, sg);
824 if (n_elem <= 0) { 827 if (n_elem <= 0) {
825 ub_put_cmd(lun, cmd); 828 printk(KERN_INFO "%s: failed request map (%d)\n",
826 ub_end_rq(rq, 0); 829 sc->name, n_elem); /* P3 */
827 blk_start_queue(q); 830 return -1; /* request with no s/g entries? */
828 return 0; /* request with no s/g entries? */
829 } 831 }
830 832 if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
831 if (n_elem != 1) { /* Paranoia */
832 printk(KERN_WARNING "%s: request with %d segments\n", 833 printk(KERN_WARNING "%s: request with %d segments\n",
833 sc->name, n_elem); 834 sc->name, n_elem);
834 ub_put_cmd(lun, cmd);
835 ub_end_rq(rq, 0);
836 blk_start_queue(q);
837 return 0;
838 }
839#endif
840
841 /*
842 * XXX Unfortunately, this check does not work. It is quite possible
843 * to get bogus non-null rq->buffer if you allow sg by mistake.
844 */
845 if (rq->buffer == NULL) {
846 /*
847 * This must not happen if we set the queue right.
848 * The block level must create bounce buffers for us.
849 */
850 static int do_print = 1;
851 if (do_print) {
852 printk(KERN_WARNING "%s: unmapped block request"
853 " flags 0x%lx sectors %lu\n",
854 sc->name, rq->flags, rq->nr_sectors);
855 do_print = 0;
856 }
857 return -1; 835 return -1;
858 } 836 }
837 cmd->nsg = n_elem;
838 sc->sg_stat[n_elem]++;
859 839
860 /* 840 /*
861 * build the command 841 * build the command
@@ -876,30 +856,15 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
876 cmd->cdb[8] = nblks; 856 cmd->cdb[8] = nblks;
877 cmd->cdb_len = 10; 857 cmd->cdb_len = 10;
878 858
879 cmd->dir = ub_dir;
880 cmd->data = rq->buffer;
881 cmd->len = rq->nr_sectors * 512; 859 cmd->len = rq->nr_sectors * 512;
882 860
883 return 0; 861 return 0;
884} 862}
885 863
886static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, 864static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
887 struct request *rq) 865 struct ub_scsi_cmd *cmd, struct request *rq)
888{ 866{
889 867 int n_elem;
890 if (rq->data_len != 0 && rq->data == NULL) {
891 static int do_print = 1;
892 if (do_print) {
893 printk(KERN_WARNING "%s: unmapped packet request"
894 " flags 0x%lx length %d\n",
895 sc->name, rq->flags, rq->data_len);
896 do_print = 0;
897 }
898 return -1;
899 }
900
901 memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
902 cmd->cdb_len = rq->cmd_len;
903 868
904 if (rq->data_len == 0) { 869 if (rq->data_len == 0) {
905 cmd->dir = UB_DIR_NONE; 870 cmd->dir = UB_DIR_NONE;
@@ -908,8 +873,29 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
908 cmd->dir = UB_DIR_WRITE; 873 cmd->dir = UB_DIR_WRITE;
909 else 874 else
910 cmd->dir = UB_DIR_READ; 875 cmd->dir = UB_DIR_READ;
876
877 }
878
879 /*
880 * get scatterlist from block layer
881 */
882 n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
883 if (n_elem < 0) {
884 printk(KERN_INFO "%s: failed request map (%d)\n",
885 sc->name, n_elem); /* P3 */
886 return -1;
911 } 887 }
912 cmd->data = rq->data; 888 if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
889 printk(KERN_WARNING "%s: request with %d segments\n",
890 sc->name, n_elem);
891 return -1;
892 }
893 cmd->nsg = n_elem;
894 sc->sg_stat[n_elem]++;
895
896 memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
897 cmd->cdb_len = rq->cmd_len;
898
913 cmd->len = rq->data_len; 899 cmd->len = rq->data_len;
914 900
915 return 0; 901 return 0;
@@ -919,24 +905,34 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
919{ 905{
920 struct request *rq = cmd->back; 906 struct request *rq = cmd->back;
921 struct ub_lun *lun = cmd->lun; 907 struct ub_lun *lun = cmd->lun;
922 struct gendisk *disk = lun->disk;
923 request_queue_t *q = disk->queue;
924 int uptodate; 908 int uptodate;
925 909
926 if (blk_pc_request(rq)) { 910 if (cmd->error == 0) {
927 /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
928 memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
929 rq->sense_len = UB_SENSE_SIZE;
930 }
931
932 if (cmd->error == 0)
933 uptodate = 1; 911 uptodate = 1;
934 else 912
913 if (blk_pc_request(rq)) {
914 if (cmd->act_len >= rq->data_len)
915 rq->data_len = 0;
916 else
917 rq->data_len -= cmd->act_len;
918 }
919 } else {
935 uptodate = 0; 920 uptodate = 0;
936 921
922 if (blk_pc_request(rq)) {
923 /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
924 memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
925 rq->sense_len = UB_SENSE_SIZE;
926 if (sc->top_sense[0] != 0)
927 rq->errors = SAM_STAT_CHECK_CONDITION;
928 else
929 rq->errors = DID_ERROR << 16;
930 }
931 }
932
937 ub_put_cmd(lun, cmd); 933 ub_put_cmd(lun, cmd);
938 ub_end_rq(rq, uptodate); 934 ub_end_rq(rq, uptodate);
939 blk_start_queue(q); 935 blk_start_queue(lun->disk->queue);
940} 936}
941 937
942static void ub_end_rq(struct request *rq, int uptodate) 938static void ub_end_rq(struct request *rq, int uptodate)
@@ -1014,7 +1010,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1014 sc->last_pipe = sc->send_bulk_pipe; 1010 sc->last_pipe = sc->send_bulk_pipe;
1015 usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, 1011 usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
1016 bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); 1012 bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
1017 sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; 1013 sc->work_urb.transfer_flags = 0;
1018 1014
1019 /* Fill what we shouldn't be filling, because usb-storage did so. */ 1015 /* Fill what we shouldn't be filling, because usb-storage did so. */
1020 sc->work_urb.actual_length = 0; 1016 sc->work_urb.actual_length = 0;
@@ -1103,7 +1099,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1103{ 1099{
1104 struct urb *urb = &sc->work_urb; 1100 struct urb *urb = &sc->work_urb;
1105 struct bulk_cs_wrap *bcs; 1101 struct bulk_cs_wrap *bcs;
1106 int pipe;
1107 int rc; 1102 int rc;
1108 1103
1109 if (atomic_read(&sc->poison)) { 1104 if (atomic_read(&sc->poison)) {
@@ -1204,38 +1199,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1204 goto Bad_End; 1199 goto Bad_End;
1205 } 1200 }
1206 1201
1207 if (cmd->dir == UB_DIR_NONE) { 1202 if (cmd->dir == UB_DIR_NONE || cmd->nsg < 1) {
1208 ub_state_stat(sc, cmd); 1203 ub_state_stat(sc, cmd);
1209 return; 1204 return;
1210 } 1205 }
1211 1206
1212 UB_INIT_COMPLETION(sc->work_done); 1207 // udelay(125); // usb-storage has this
1213 1208 ub_data_start(sc, cmd);
1214 if (cmd->dir == UB_DIR_READ)
1215 pipe = sc->recv_bulk_pipe;
1216 else
1217 pipe = sc->send_bulk_pipe;
1218 sc->last_pipe = pipe;
1219 usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
1220 cmd->data, cmd->len, ub_urb_complete, sc);
1221 sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
1222 sc->work_urb.actual_length = 0;
1223 sc->work_urb.error_count = 0;
1224 sc->work_urb.status = 0;
1225
1226 if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
1227 /* XXX Clear stalls */
1228 printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
1229 ub_complete(&sc->work_done);
1230 ub_state_done(sc, cmd, rc);
1231 return;
1232 }
1233
1234 sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
1235 add_timer(&sc->work_timer);
1236
1237 cmd->state = UB_CMDST_DATA;
1238 ub_cmdtr_state(sc, cmd);
1239 1209
1240 } else if (cmd->state == UB_CMDST_DATA) { 1210 } else if (cmd->state == UB_CMDST_DATA) {
1241 if (urb->status == -EPIPE) { 1211 if (urb->status == -EPIPE) {
@@ -1257,16 +1227,22 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1257 if (urb->status == -EOVERFLOW) { 1227 if (urb->status == -EOVERFLOW) {
1258 /* 1228 /*
1259 * A babble? Failure, but we must transfer CSW now. 1229 * A babble? Failure, but we must transfer CSW now.
1230 * XXX This is going to end in perpetual babble. Reset.
1260 */ 1231 */
1261 cmd->error = -EOVERFLOW; /* A cheap trick... */ 1232 cmd->error = -EOVERFLOW; /* A cheap trick... */
1262 } else { 1233 ub_state_stat(sc, cmd);
1263 if (urb->status != 0) 1234 return;
1264 goto Bad_End;
1265 } 1235 }
1236 if (urb->status != 0)
1237 goto Bad_End;
1266 1238
1267 cmd->act_len = urb->actual_length; 1239 cmd->act_len += urb->actual_length;
1268 ub_cmdtr_act_len(sc, cmd); 1240 ub_cmdtr_act_len(sc, cmd);
1269 1241
1242 if (++cmd->current_sg < cmd->nsg) {
1243 ub_data_start(sc, cmd);
1244 return;
1245 }
1270 ub_state_stat(sc, cmd); 1246 ub_state_stat(sc, cmd);
1271 1247
1272 } else if (cmd->state == UB_CMDST_STAT) { 1248 } else if (cmd->state == UB_CMDST_STAT) {
@@ -1401,6 +1377,46 @@ Bad_End: /* Little Excel is dead */
1401 1377
1402/* 1378/*
1403 * Factorization helper for the command state machine: 1379 * Factorization helper for the command state machine:
1380 * Initiate a data segment transfer.
1381 */
1382static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1383{
1384 struct scatterlist *sg = &cmd->sgv[cmd->current_sg];
1385 int pipe;
1386 int rc;
1387
1388 UB_INIT_COMPLETION(sc->work_done);
1389
1390 if (cmd->dir == UB_DIR_READ)
1391 pipe = sc->recv_bulk_pipe;
1392 else
1393 pipe = sc->send_bulk_pipe;
1394 sc->last_pipe = pipe;
1395 usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
1396 page_address(sg->page) + sg->offset, sg->length,
1397 ub_urb_complete, sc);
1398 sc->work_urb.transfer_flags = 0;
1399 sc->work_urb.actual_length = 0;
1400 sc->work_urb.error_count = 0;
1401 sc->work_urb.status = 0;
1402
1403 if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
1404 /* XXX Clear stalls */
1405 printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
1406 ub_complete(&sc->work_done);
1407 ub_state_done(sc, cmd, rc);
1408 return;
1409 }
1410
1411 sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
1412 add_timer(&sc->work_timer);
1413
1414 cmd->state = UB_CMDST_DATA;
1415 ub_cmdtr_state(sc, cmd);
1416}
1417
1418/*
1419 * Factorization helper for the command state machine:
1404 * Finish the command. 1420 * Finish the command.
1405 */ 1421 */
1406static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc) 1422static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc)
@@ -1426,7 +1442,7 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1426 sc->last_pipe = sc->recv_bulk_pipe; 1442 sc->last_pipe = sc->recv_bulk_pipe;
1427 usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, 1443 usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
1428 &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); 1444 &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
1429 sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; 1445 sc->work_urb.transfer_flags = 0;
1430 sc->work_urb.actual_length = 0; 1446 sc->work_urb.actual_length = 0;
1431 sc->work_urb.error_count = 0; 1447 sc->work_urb.error_count = 0;
1432 sc->work_urb.status = 0; 1448 sc->work_urb.status = 0;
@@ -1484,6 +1500,7 @@ static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1484static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) 1500static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1485{ 1501{
1486 struct ub_scsi_cmd *scmd; 1502 struct ub_scsi_cmd *scmd;
1503 struct scatterlist *sg;
1487 int rc; 1504 int rc;
1488 1505
1489 if (cmd->cdb[0] == REQUEST_SENSE) { 1506 if (cmd->cdb[0] == REQUEST_SENSE) {
@@ -1492,12 +1509,17 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1492 } 1509 }
1493 1510
1494 scmd = &sc->top_rqs_cmd; 1511 scmd = &sc->top_rqs_cmd;
1512 memset(scmd, 0, sizeof(struct ub_scsi_cmd));
1495 scmd->cdb[0] = REQUEST_SENSE; 1513 scmd->cdb[0] = REQUEST_SENSE;
1496 scmd->cdb[4] = UB_SENSE_SIZE; 1514 scmd->cdb[4] = UB_SENSE_SIZE;
1497 scmd->cdb_len = 6; 1515 scmd->cdb_len = 6;
1498 scmd->dir = UB_DIR_READ; 1516 scmd->dir = UB_DIR_READ;
1499 scmd->state = UB_CMDST_INIT; 1517 scmd->state = UB_CMDST_INIT;
1500 scmd->data = sc->top_sense; 1518 scmd->nsg = 1;
1519 sg = &scmd->sgv[0];
1520 sg->page = virt_to_page(sc->top_sense);
1521 sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1);
1522 sg->length = UB_SENSE_SIZE;
1501 scmd->len = UB_SENSE_SIZE; 1523 scmd->len = UB_SENSE_SIZE;
1502 scmd->lun = cmd->lun; 1524 scmd->lun = cmd->lun;
1503 scmd->done = ub_top_sense_done; 1525 scmd->done = ub_top_sense_done;
@@ -1541,7 +1563,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
1541 1563
1542 usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, 1564 usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
1543 (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); 1565 (unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
1544 sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; 1566 sc->work_urb.transfer_flags = 0;
1545 sc->work_urb.actual_length = 0; 1567 sc->work_urb.actual_length = 0;
1546 sc->work_urb.error_count = 0; 1568 sc->work_urb.error_count = 0;
1547 sc->work_urb.status = 0; 1569 sc->work_urb.status = 0;
@@ -1560,7 +1582,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
1560 */ 1582 */
1561static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) 1583static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
1562{ 1584{
1563 unsigned char *sense = scmd->data; 1585 unsigned char *sense = sc->top_sense;
1564 struct ub_scsi_cmd *cmd; 1586 struct ub_scsi_cmd *cmd;
1565 1587
1566 /* 1588 /*
@@ -1852,6 +1874,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
1852 struct ub_capacity *ret) 1874 struct ub_capacity *ret)
1853{ 1875{
1854 struct ub_scsi_cmd *cmd; 1876 struct ub_scsi_cmd *cmd;
1877 struct scatterlist *sg;
1855 char *p; 1878 char *p;
1856 enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) + 8 }; 1879 enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) + 8 };
1857 unsigned long flags; 1880 unsigned long flags;
@@ -1872,7 +1895,11 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
1872 cmd->cdb_len = 10; 1895 cmd->cdb_len = 10;
1873 cmd->dir = UB_DIR_READ; 1896 cmd->dir = UB_DIR_READ;
1874 cmd->state = UB_CMDST_INIT; 1897 cmd->state = UB_CMDST_INIT;
1875 cmd->data = p; 1898 cmd->nsg = 1;
1899 sg = &cmd->sgv[0];
1900 sg->page = virt_to_page(p);
1901 sg->offset = (unsigned int)p & (PAGE_SIZE-1);
1902 sg->length = 8;
1876 cmd->len = 8; 1903 cmd->len = 8;
1877 cmd->lun = lun; 1904 cmd->lun = lun;
1878 cmd->done = ub_probe_done; 1905 cmd->done = ub_probe_done;
@@ -2289,7 +2316,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2289 disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ 2316 disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */
2290 2317
2291 rc = -ENOMEM; 2318 rc = -ENOMEM;
2292 if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) 2319 if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
2293 goto err_blkqinit; 2320 goto err_blkqinit;
2294 2321
2295 disk->queue = q; 2322 disk->queue = q;
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 43bf1e5dc38a..ce4a1ce59d6a 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -297,7 +297,7 @@ static char azt_auto_eject = AZT_AUTO_EJECT;
297 297
298static int AztTimeout, AztTries; 298static int AztTimeout, AztTries;
299static DECLARE_WAIT_QUEUE_HEAD(azt_waitq); 299static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
300static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0); 300static DEFINE_TIMER(delay_timer, NULL, 0, 0);
301 301
302static struct azt_DiskInfo DiskInfo; 302static struct azt_DiskInfo DiskInfo;
303static struct azt_Toc Toc[MAX_TRACKS]; 303static struct azt_Toc Toc[MAX_TRACKS];
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
index 7eac10e63b23..ad5464ab99bc 100644
--- a/drivers/cdrom/gscd.c
+++ b/drivers/cdrom/gscd.c
@@ -146,7 +146,7 @@ static int AudioStart_f;
146static int AudioEnd_m; 146static int AudioEnd_m;
147static int AudioEnd_f; 147static int AudioEnd_f;
148 148
149static struct timer_list gscd_timer = TIMER_INITIALIZER(NULL, 0, 0); 149static DEFINE_TIMER(gscd_timer, NULL, 0, 0);
150static DEFINE_SPINLOCK(gscd_lock); 150static DEFINE_SPINLOCK(gscd_lock);
151static struct request_queue *gscd_queue; 151static struct request_queue *gscd_queue;
152 152
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
index 351a01dd503a..0b0eab4f40fa 100644
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -264,7 +264,7 @@ static inline int flag_low(int flag, unsigned long timeout)
264static int sleep_timeout; /* max # of ticks to sleep */ 264static int sleep_timeout; /* max # of ticks to sleep */
265static DECLARE_WAIT_QUEUE_HEAD(waitq); 265static DECLARE_WAIT_QUEUE_HEAD(waitq);
266static void sleep_timer(unsigned long data); 266static void sleep_timer(unsigned long data);
267static struct timer_list delay_timer = TIMER_INITIALIZER(sleep_timer, 0, 0); 267static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0);
268static DEFINE_SPINLOCK(optcd_lock); 268static DEFINE_SPINLOCK(optcd_lock);
269static struct request_queue *opt_queue; 269static struct request_queue *opt_queue;
270 270
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index 452d34675159..30a897755361 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -742,13 +742,10 @@ static struct sbpcd_drive *current_drive = D_S;
742unsigned long cli_sti; /* for saving the processor flags */ 742unsigned long cli_sti; /* for saving the processor flags */
743#endif 743#endif
744/*==========================================================================*/ 744/*==========================================================================*/
745static struct timer_list delay_timer = 745static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
746 TIMER_INITIALIZER(mark_timeout_delay, 0, 0); 746static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
747static struct timer_list data_timer =
748 TIMER_INITIALIZER(mark_timeout_data, 0, 0);
749#if 0 747#if 0
750static struct timer_list audio_timer = 748static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
751 TIMER_INITIALIZER(mark_timeout_audio, 0, 0);
752#endif 749#endif
753/*==========================================================================*/ 750/*==========================================================================*/
754/* 751/*
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index 4e7a342ec36f..74b1cadbf161 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -151,7 +151,7 @@ static struct sjcd_stat statistic;
151/* 151/*
152 * Timer. 152 * Timer.
153 */ 153 */
154static struct timer_list sjcd_delay_timer = TIMER_INITIALIZER(NULL, 0, 0); 154static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0);
155 155
156#define SJCD_SET_TIMER( func, tmout ) \ 156#define SJCD_SET_TIMER( func, tmout ) \
157 ( sjcd_delay_timer.expires = jiffies+tmout, \ 157 ( sjcd_delay_timer.expires = jiffies+tmout, \
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 2bc9d64db106..c29365d5b524 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
80 80
81config COMPUTONE 81config COMPUTONE
82 tristate "Computone IntelliPort Plus serial support" 82 tristate "Computone IntelliPort Plus serial support"
83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32) 83 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
84 ---help--- 84 ---help---
85 This driver supports the entire family of Intelliport II/Plus 85 This driver supports the entire family of Intelliport II/Plus
86 controllers with the exception of the MicroChannel controllers and 86 controllers with the exception of the MicroChannel controllers and
@@ -208,7 +208,7 @@ config SYNCLINK
208 208
209config SYNCLINKMP 209config SYNCLINKMP
210 tristate "SyncLink Multiport support" 210 tristate "SyncLink Multiport support"
211 depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32) 211 depends on SERIAL_NONSTANDARD
212 help 212 help
213 Enable support for the SyncLink Multiport (2 or 4 ports) 213 Enable support for the SyncLink Multiport (2 or 4 ports)
214 serial adapter, running asynchronous and HDLC communications up 214 serial adapter, running asynchronous and HDLC communications up
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 59f589d733f9..0a7624a9b1c1 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -429,7 +429,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
429 struct pci_dev *dev1; 429 struct pci_dev *dev1;
430 int i; 430 int i;
431 unsigned size = amd64_fetch_size(); 431 unsigned size = amd64_fetch_size();
432 printk(KERN_INFO "Setting up ULi AGP. \n"); 432 printk(KERN_INFO "Setting up ULi AGP.\n");
433 dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0)); 433 dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));
434 if (dev1 == NULL) { 434 if (dev1 == NULL) {
435 printk(KERN_INFO PFX "Detected a ULi chipset, " 435 printk(KERN_INFO PFX "Detected a ULi chipset, "
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index f0079e991bdc..ac9da0ca36b7 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -319,7 +319,6 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info)
319 info->mode = bridge->mode & ~AGP3_RESERVED_MASK; 319 info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
320 else 320 else
321 info->mode = bridge->mode & ~AGP2_RESERVED_MASK; 321 info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
322 info->mode = bridge->mode;
323 info->aper_base = bridge->gart_bus_addr; 322 info->aper_base = bridge->gart_bus_addr;
324 info->aper_size = agp_return_size(); 323 info->aper_size = agp_return_size();
325 info->max_memory = bridge->max_memory_agp; 324 info->max_memory = bridge->max_memory_agp;
@@ -356,7 +355,7 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
356 return -EINVAL; 355 return -EINVAL;
357 356
358 if (curr->is_bound == TRUE) { 357 if (curr->is_bound == TRUE) {
359 printk (KERN_INFO PFX "memory %p is already bound!\n", curr); 358 printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
360 return -EINVAL; 359 return -EINVAL;
361 } 360 }
362 if (curr->is_flushed == FALSE) { 361 if (curr->is_flushed == FALSE) {
@@ -391,7 +390,7 @@ int agp_unbind_memory(struct agp_memory *curr)
391 return -EINVAL; 390 return -EINVAL;
392 391
393 if (curr->is_bound != TRUE) { 392 if (curr->is_bound != TRUE) {
394 printk (KERN_INFO PFX "memory %p was not bound!\n", curr); 393 printk(KERN_INFO PFX "memory %p was not bound!\n", curr);
395 return -EINVAL; 394 return -EINVAL;
396 } 395 }
397 396
@@ -415,7 +414,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
415 u32 tmp; 414 u32 tmp;
416 415
417 if (*requested_mode & AGP2_RESERVED_MASK) { 416 if (*requested_mode & AGP2_RESERVED_MASK) {
418 printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode); 417 printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
419 *requested_mode &= ~AGP2_RESERVED_MASK; 418 *requested_mode &= ~AGP2_RESERVED_MASK;
420 } 419 }
421 420
@@ -423,7 +422,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
423 tmp = *requested_mode & 7; 422 tmp = *requested_mode & 7;
424 switch (tmp) { 423 switch (tmp) {
425 case 0: 424 case 0:
426 printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm); 425 printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
427 *requested_mode |= AGPSTAT2_1X; 426 *requested_mode |= AGPSTAT2_1X;
428 break; 427 break;
429 case 1: 428 case 1:
@@ -493,18 +492,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
493 u32 tmp; 492 u32 tmp;
494 493
495 if (*requested_mode & AGP3_RESERVED_MASK) { 494 if (*requested_mode & AGP3_RESERVED_MASK) {
496 printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode); 495 printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
497 *requested_mode &= ~AGP3_RESERVED_MASK; 496 *requested_mode &= ~AGP3_RESERVED_MASK;
498 } 497 }
499 498
500 /* Check the speed bits make sense. */ 499 /* Check the speed bits make sense. */
501 tmp = *requested_mode & 7; 500 tmp = *requested_mode & 7;
502 if (tmp == 0) { 501 if (tmp == 0) {
503 printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm); 502 printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
504 *requested_mode |= AGPSTAT3_4X; 503 *requested_mode |= AGPSTAT3_4X;
505 } 504 }
506 if (tmp >= 3) { 505 if (tmp >= 3) {
507 printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4); 506 printk(KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
508 *requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X; 507 *requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
509 } 508 }
510 509
@@ -533,7 +532,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
533 * AGP2.x 4x -> AGP3.0 4x. 532 * AGP2.x 4x -> AGP3.0 4x.
534 */ 533 */
535 if (*requested_mode & AGPSTAT2_4X) { 534 if (*requested_mode & AGPSTAT2_4X) {
536 printk (KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n", 535 printk(KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
537 current->comm, *requested_mode); 536 current->comm, *requested_mode);
538 *requested_mode &= ~AGPSTAT2_4X; 537 *requested_mode &= ~AGPSTAT2_4X;
539 *requested_mode |= AGPSTAT3_4X; 538 *requested_mode |= AGPSTAT3_4X;
@@ -544,7 +543,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
544 * but have been passed an AGP 2.x mode. 543 * but have been passed an AGP 2.x mode.
545 * Convert AGP 1x,2x,4x -> AGP 3.0 4x. 544 * Convert AGP 1x,2x,4x -> AGP 3.0 4x.
546 */ 545 */
547 printk (KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n", 546 printk(KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
548 current->comm, *requested_mode); 547 current->comm, *requested_mode);
549 *requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X); 548 *requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X);
550 *requested_mode |= AGPSTAT3_4X; 549 *requested_mode |= AGPSTAT3_4X;
@@ -554,13 +553,13 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
554 if (!(*bridge_agpstat & AGPSTAT3_8X)) { 553 if (!(*bridge_agpstat & AGPSTAT3_8X)) {
555 *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); 554 *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
556 *bridge_agpstat |= AGPSTAT3_4X; 555 *bridge_agpstat |= AGPSTAT3_4X;
557 printk ("%s requested AGPx8 but bridge not capable.\n", current->comm); 556 printk(KERN_INFO PFX "%s requested AGPx8 but bridge not capable.\n", current->comm);
558 return; 557 return;
559 } 558 }
560 if (!(*vga_agpstat & AGPSTAT3_8X)) { 559 if (!(*vga_agpstat & AGPSTAT3_8X)) {
561 *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); 560 *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
562 *bridge_agpstat |= AGPSTAT3_4X; 561 *bridge_agpstat |= AGPSTAT3_4X;
563 printk ("%s requested AGPx8 but graphic card not capable.\n", current->comm); 562 printk(KERN_INFO PFX "%s requested AGPx8 but graphic card not capable.\n", current->comm);
564 return; 563 return;
565 } 564 }
566 /* All set, bridge & device can do AGP x8*/ 565 /* All set, bridge & device can do AGP x8*/
@@ -578,13 +577,13 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
578 if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X)) 577 if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X))
579 *bridge_agpstat |= AGPSTAT3_4X; 578 *bridge_agpstat |= AGPSTAT3_4X;
580 else { 579 else {
581 printk (KERN_INFO PFX "Badness. Don't know which AGP mode to set. " 580 printk(KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
582 "[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n", 581 "[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n",
583 origbridge, origvga, *bridge_agpstat, *vga_agpstat); 582 origbridge, origvga, *bridge_agpstat, *vga_agpstat);
584 if (!(*bridge_agpstat & AGPSTAT3_4X)) 583 if (!(*bridge_agpstat & AGPSTAT3_4X))
585 printk (KERN_INFO PFX "Bridge couldn't do AGP x4.\n"); 584 printk(KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
586 if (!(*vga_agpstat & AGPSTAT3_4X)) 585 if (!(*vga_agpstat & AGPSTAT3_4X))
587 printk (KERN_INFO PFX "Graphic card couldn't do AGP x4.\n"); 586 printk(KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
588 return; 587 return;
589 } 588 }
590 } 589 }
@@ -622,7 +621,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
622 for (;;) { 621 for (;;) {
623 device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device); 622 device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device);
624 if (!device) { 623 if (!device) {
625 printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n"); 624 printk(KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
626 return 0; 625 return 0;
627 } 626 }
628 cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP); 627 cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
@@ -734,7 +733,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
734 pci_write_config_dword(bridge->dev, 733 pci_write_config_dword(bridge->dev,
735 bridge->capndx+AGPCTRL, temp); 734 bridge->capndx+AGPCTRL, temp);
736 735
737 printk (KERN_INFO PFX "Device is in legacy mode," 736 printk(KERN_INFO PFX "Device is in legacy mode,"
738 " falling back to 2.x\n"); 737 " falling back to 2.x\n");
739 } 738 }
740 } 739 }
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a5337bf0936..cf4c3648463d 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -865,7 +865,7 @@ static void cyz_poll(unsigned long);
865static long cyz_polling_cycle = CZ_DEF_POLL; 865static long cyz_polling_cycle = CZ_DEF_POLL;
866 866
867static int cyz_timeron = 0; 867static int cyz_timeron = 0;
868static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0); 868static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
869 869
870#else /* CONFIG_CYZ_INTR */ 870#else /* CONFIG_CYZ_INTR */
871static void cyz_rx_restart(unsigned long); 871static void cyz_rx_restart(unsigned long);
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 6f98701dfe15..121cc85f347e 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -1071,5 +1071,9 @@ extern void *drm_calloc(size_t nmemb, size_t size, int area);
1071extern unsigned long drm_core_get_map_ofs(drm_map_t *map); 1071extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
1072extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); 1072extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
1073 1073
1074#ifndef pci_pretty_name
1075#define pci_pretty_name(dev) ""
1076#endif
1077
1074#endif /* __KERNEL__ */ 1078#endif /* __KERNEL__ */
1075#endif 1079#endif
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 81d811edf3c5..a54bc93353af 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -149,8 +149,7 @@ static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;
149 149
150static void hangcheck_fire(unsigned long); 150static void hangcheck_fire(unsigned long);
151 151
152static struct timer_list hangcheck_ticktock = 152static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0);
153 TIMER_INITIALIZER(hangcheck_fire, 0, 0);
154 153
155 154
156static void hangcheck_fire(unsigned long data) 155static void hangcheck_fire(unsigned long data)
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index cf0cd58d6305..9e4e26aef94e 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -120,7 +120,6 @@
120 120
121#include <linux/vmalloc.h> 121#include <linux/vmalloc.h>
122#include <linux/init.h> 122#include <linux/init.h>
123#include <asm/serial.h>
124 123
125#include <asm/uaccess.h> 124#include <asm/uaccess.h>
126 125
@@ -255,7 +254,7 @@ static unsigned long bh_counter = 0;
255 * selected, the board is serviced periodically to see if anything needs doing. 254 * selected, the board is serviced periodically to see if anything needs doing.
256 */ 255 */
257#define POLL_TIMEOUT (jiffies + 1) 256#define POLL_TIMEOUT (jiffies + 1)
258static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0); 257static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
259static char TimerOn; 258static char TimerOn;
260 259
261#ifdef IP2DEBUG_TRACE 260#ifdef IP2DEBUG_TRACE
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 883ac4352be4..a09ff1080687 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -735,7 +735,8 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
735 case COMPAT_IPMICTL_RECEIVE_MSG: 735 case COMPAT_IPMICTL_RECEIVE_MSG:
736 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC: 736 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
737 { 737 {
738 struct ipmi_recv *precv64, recv64; 738 struct ipmi_recv __user *precv64;
739 struct ipmi_recv recv64;
739 740
740 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg))) 741 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
741 return -EFAULT; 742 return -EFAULT;
@@ -748,7 +749,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
748 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) 749 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
749 ? IPMICTL_RECEIVE_MSG 750 ? IPMICTL_RECEIVE_MSG
750 : IPMICTL_RECEIVE_MSG_TRUNC), 751 : IPMICTL_RECEIVE_MSG_TRUNC),
751 (long) precv64); 752 (unsigned long) precv64);
752 if (rc != 0) 753 if (rc != 0)
753 return rc; 754 return rc;
754 755
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 52a073eee201..9c19e5435a11 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -780,7 +780,7 @@ static struct file_operations stli_fsiomem = {
780 * much cheaper on host cpu than using interrupts. It turns out to 780 * much cheaper on host cpu than using interrupts. It turns out to
781 * not increase character latency by much either... 781 * not increase character latency by much either...
782 */ 782 */
783static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0); 783static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0);
784 784
785static int stli_timeron; 785static int stli_timeron;
786 786
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 523fd3c8bbaa..1745065d8f78 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -233,8 +233,7 @@ static void kd_nosound(unsigned long ignored)
233 } 233 }
234} 234}
235 235
236static struct timer_list kd_mksound_timer = 236static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
237 TIMER_INITIALIZER(kd_nosound, 0, 0);
238 237
239void kd_mksound(unsigned int hz, unsigned int ticks) 238void kd_mksound(unsigned int hz, unsigned int ticks)
240{ 239{
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index da32889d22c0..49f3997fd251 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -149,15 +149,14 @@ static int pty_write_room(struct tty_struct *tty)
149static int pty_chars_in_buffer(struct tty_struct *tty) 149static int pty_chars_in_buffer(struct tty_struct *tty)
150{ 150{
151 struct tty_struct *to = tty->link; 151 struct tty_struct *to = tty->link;
152 ssize_t (*chars_in_buffer)(struct tty_struct *);
153 int count; 152 int count;
154 153
155 /* We should get the line discipline lock for "tty->link" */ 154 /* We should get the line discipline lock for "tty->link" */
156 if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer)) 155 if (!to || !to->ldisc.chars_in_buffer)
157 return 0; 156 return 0;
158 157
159 /* The ldisc must report 0 if no characters available to be read */ 158 /* The ldisc must report 0 if no characters available to be read */
160 count = chars_in_buffer(to); 159 count = to->ldisc.chars_in_buffer(to);
161 160
162 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; 161 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
163 162
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 37c8bea8e2b0..ea2d54be4843 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/char/synclink.c 2 * linux/drivers/char/synclink.c
3 * 3 *
4 * $Id: synclink.c,v 4.28 2004/08/11 19:30:01 paulkf Exp $ 4 * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
5 * 5 *
6 * Device driver for Microgate SyncLink ISA and PCI 6 * Device driver for Microgate SyncLink ISA and PCI
7 * high speed multiprotocol serial adapters. 7 * high speed multiprotocol serial adapters.
@@ -141,9 +141,9 @@ static MGSL_PARAMS default_params = {
141typedef struct _DMABUFFERENTRY 141typedef struct _DMABUFFERENTRY
142{ 142{
143 u32 phys_addr; /* 32-bit flat physical address of data buffer */ 143 u32 phys_addr; /* 32-bit flat physical address of data buffer */
144 u16 count; /* buffer size/data count */ 144 volatile u16 count; /* buffer size/data count */
145 u16 status; /* Control/status field */ 145 volatile u16 status; /* Control/status field */
146 u16 rcc; /* character count field */ 146 volatile u16 rcc; /* character count field */
147 u16 reserved; /* padding required by 16C32 */ 147 u16 reserved; /* padding required by 16C32 */
148 u32 link; /* 32-bit flat link to next buffer entry */ 148 u32 link; /* 32-bit flat link to next buffer entry */
149 char *virt_addr; /* virtual address of data buffer */ 149 char *virt_addr; /* virtual address of data buffer */
@@ -896,7 +896,7 @@ module_param_array(txdmabufs, int, NULL, 0);
896module_param_array(txholdbufs, int, NULL, 0); 896module_param_array(txholdbufs, int, NULL, 0);
897 897
898static char *driver_name = "SyncLink serial driver"; 898static char *driver_name = "SyncLink serial driver";
899static char *driver_version = "$Revision: 4.28 $"; 899static char *driver_version = "$Revision: 4.37 $";
900 900
901static int synclink_init_one (struct pci_dev *dev, 901static int synclink_init_one (struct pci_dev *dev,
902 const struct pci_device_id *ent); 902 const struct pci_device_id *ent);
@@ -1814,6 +1814,8 @@ static int startup(struct mgsl_struct * info)
1814 1814
1815 info->pending_bh = 0; 1815 info->pending_bh = 0;
1816 1816
1817 memset(&info->icount, 0, sizeof(info->icount));
1818
1817 init_timer(&info->tx_timer); 1819 init_timer(&info->tx_timer);
1818 info->tx_timer.data = (unsigned long)info; 1820 info->tx_timer.data = (unsigned long)info;
1819 info->tx_timer.function = mgsl_tx_timeout; 1821 info->tx_timer.function = mgsl_tx_timeout;
@@ -2470,12 +2472,12 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *
2470 printk("%s(%d):mgsl_get_params(%s)\n", 2472 printk("%s(%d):mgsl_get_params(%s)\n",
2471 __FILE__,__LINE__, info->device_name); 2473 __FILE__,__LINE__, info->device_name);
2472 2474
2473 COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); 2475 if (!user_icount) {
2474 if (err) { 2476 memset(&info->icount, 0, sizeof(info->icount));
2475 if ( debug_level >= DEBUG_LEVEL_INFO ) 2477 } else {
2476 printk( "%s(%d):mgsl_get_stats(%s) user buffer copy failed\n", 2478 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2477 __FILE__,__LINE__,info->device_name); 2479 if (err)
2478 return -EFAULT; 2480 return -EFAULT;
2479 } 2481 }
2480 2482
2481 return 0; 2483 return 0;
@@ -6149,6 +6151,11 @@ static void usc_set_async_mode( struct mgsl_struct *info )
6149 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); 6151 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12));
6150 } 6152 }
6151 6153
6154 if (info->params.loopback) {
6155 info->loopback_bits = 0x300;
6156 outw(0x0300, info->io_base + CCAR);
6157 }
6158
6152} /* end of usc_set_async_mode() */ 6159} /* end of usc_set_async_mode() */
6153 6160
6154/* usc_loopback_frame() 6161/* usc_loopback_frame()
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index ec949e4c070f..6fb165cf8a61 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: synclinkmp.c,v 4.34 2005/03/04 15:07:10 paulkf Exp $ 2 * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
3 * 3 *
4 * Device driver for Microgate SyncLink Multiport 4 * Device driver for Microgate SyncLink Multiport
5 * high speed multiprotocol serial adapter. 5 * high speed multiprotocol serial adapter.
@@ -55,7 +55,6 @@
55#include <linux/netdevice.h> 55#include <linux/netdevice.h>
56#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
57#include <linux/init.h> 57#include <linux/init.h>
58#include <asm/serial.h>
59#include <linux/delay.h> 58#include <linux/delay.h>
60#include <linux/ioctl.h> 59#include <linux/ioctl.h>
61 60
@@ -487,7 +486,7 @@ module_param_array(maxframe, int, NULL, 0);
487module_param_array(dosyncppp, int, NULL, 0); 486module_param_array(dosyncppp, int, NULL, 0);
488 487
489static char *driver_name = "SyncLink MultiPort driver"; 488static char *driver_name = "SyncLink MultiPort driver";
490static char *driver_version = "$Revision: 4.34 $"; 489static char *driver_version = "$Revision: 4.38 $";
491 490
492static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); 491static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
493static void synclinkmp_remove_one(struct pci_dev *dev); 492static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -556,7 +555,6 @@ static int set_txidle(SLMP_INFO *info, int idle_mode);
556static int tx_enable(SLMP_INFO *info, int enable); 555static int tx_enable(SLMP_INFO *info, int enable);
557static int tx_abort(SLMP_INFO *info); 556static int tx_abort(SLMP_INFO *info);
558static int rx_enable(SLMP_INFO *info, int enable); 557static int rx_enable(SLMP_INFO *info, int enable);
559static int map_status(int signals);
560static int modem_input_wait(SLMP_INFO *info,int arg); 558static int modem_input_wait(SLMP_INFO *info,int arg);
561static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); 559static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
562static int tiocmget(struct tty_struct *tty, struct file *file); 560static int tiocmget(struct tty_struct *tty, struct file *file);
@@ -645,7 +643,7 @@ static unsigned char tx_active_fifo_level = 16; // tx request FIFO activation le
645static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes 643static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes
646 644
647static u32 misc_ctrl_value = 0x007e4040; 645static u32 misc_ctrl_value = 0x007e4040;
648static u32 lcr1_brdr_value = 0x00800029; 646static u32 lcr1_brdr_value = 0x00800028;
649 647
650static u32 read_ahead_count = 8; 648static u32 read_ahead_count = 8;
651 649
@@ -2750,6 +2748,8 @@ static int startup(SLMP_INFO * info)
2750 2748
2751 info->pending_bh = 0; 2749 info->pending_bh = 0;
2752 2750
2751 memset(&info->icount, 0, sizeof(info->icount));
2752
2753 /* program hardware for current parameters */ 2753 /* program hardware for current parameters */
2754 reset_port(info); 2754 reset_port(info);
2755 2755
@@ -2953,12 +2953,12 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
2953 printk("%s(%d):%s get_params()\n", 2953 printk("%s(%d):%s get_params()\n",
2954 __FILE__,__LINE__, info->device_name); 2954 __FILE__,__LINE__, info->device_name);
2955 2955
2956 COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount)); 2956 if (!user_icount) {
2957 if (err) { 2957 memset(&info->icount, 0, sizeof(info->icount));
2958 if ( debug_level >= DEBUG_LEVEL_INFO ) 2958 } else {
2959 printk( "%s(%d):%s get_stats() user buffer copy failed\n", 2959 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2960 __FILE__,__LINE__,info->device_name); 2960 if (err)
2961 return -EFAULT; 2961 return -EFAULT;
2962 } 2962 }
2963 2963
2964 return 0; 2964 return 0;
@@ -3109,16 +3109,6 @@ static int rx_enable(SLMP_INFO * info, int enable)
3109 return 0; 3109 return 0;
3110} 3110}
3111 3111
3112static int map_status(int signals)
3113{
3114 /* Map status bits to API event bits */
3115
3116 return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) +
3117 ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) +
3118 ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) +
3119 ((signals & SerialSignal_RI) ? MgslEvent_RiActive : MgslEvent_RiInactive);
3120}
3121
3122/* wait for specified event to occur 3112/* wait for specified event to occur
3123 */ 3113 */
3124static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr) 3114static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
@@ -3145,7 +3135,7 @@ static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
3145 3135
3146 /* return immediately if state matches requested events */ 3136 /* return immediately if state matches requested events */
3147 get_signals(info); 3137 get_signals(info);
3148 s = map_status(info->serial_signals); 3138 s = info->serial_signals;
3149 3139
3150 events = mask & 3140 events = mask &
3151 ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + 3141 ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
@@ -4489,11 +4479,13 @@ void async_mode(SLMP_INFO *info)
4489 /* MD2, Mode Register 2 4479 /* MD2, Mode Register 2
4490 * 4480 *
4491 * 07..02 Reserved, must be 0 4481 * 07..02 Reserved, must be 0
4492 * 01..00 CNCT<1..0> Channel connection, 0=normal 4482 * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback
4493 * 4483 *
4494 * 0000 0000 4484 * 0000 0000
4495 */ 4485 */
4496 RegValue = 0x00; 4486 RegValue = 0x00;
4487 if (info->params.loopback)
4488 RegValue |= (BIT1 + BIT0);
4497 write_reg(info, MD2, RegValue); 4489 write_reg(info, MD2, RegValue);
4498 4490
4499 /* RXS, Receive clock source 4491 /* RXS, Receive clock source
@@ -4574,9 +4566,6 @@ void async_mode(SLMP_INFO *info)
4574 write_reg(info, IE2, info->ie2_value); 4566 write_reg(info, IE2, info->ie2_value);
4575 4567
4576 set_rate( info, info->params.data_rate * 16 ); 4568 set_rate( info, info->params.data_rate * 16 );
4577
4578 if (info->params.loopback)
4579 enable_loopback(info,1);
4580} 4569}
4581 4570
4582/* Program the SCA for HDLC communications. 4571/* Program the SCA for HDLC communications.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9d657127f313..e5953f3433f3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -469,21 +469,19 @@ static void tty_ldisc_enable(struct tty_struct *tty)
469 469
470static int tty_set_ldisc(struct tty_struct *tty, int ldisc) 470static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
471{ 471{
472 int retval = 0; 472 int retval = 0;
473 struct tty_ldisc o_ldisc; 473 struct tty_ldisc o_ldisc;
474 char buf[64]; 474 char buf[64];
475 int work; 475 int work;
476 unsigned long flags; 476 unsigned long flags;
477 struct tty_ldisc *ld; 477 struct tty_ldisc *ld;
478 struct tty_struct *o_tty;
478 479
479 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) 480 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
480 return -EINVAL; 481 return -EINVAL;
481 482
482restart: 483restart:
483 484
484 if (tty->ldisc.num == ldisc)
485 return 0; /* We are already in the desired discipline */
486
487 ld = tty_ldisc_get(ldisc); 485 ld = tty_ldisc_get(ldisc);
488 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ 486 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
489 /* Cyrus Durgin <cider@speakeasy.org> */ 487 /* Cyrus Durgin <cider@speakeasy.org> */
@@ -494,45 +492,74 @@ restart:
494 if (ld == NULL) 492 if (ld == NULL)
495 return -EINVAL; 493 return -EINVAL;
496 494
497 o_ldisc = tty->ldisc;
498
499 tty_wait_until_sent(tty, 0); 495 tty_wait_until_sent(tty, 0);
500 496
497 if (tty->ldisc.num == ldisc) {
498 tty_ldisc_put(ldisc);
499 return 0;
500 }
501
502 o_ldisc = tty->ldisc;
503 o_tty = tty->link;
504
501 /* 505 /*
502 * Make sure we don't change while someone holds a 506 * Make sure we don't change while someone holds a
503 * reference to the line discipline. The TTY_LDISC bit 507 * reference to the line discipline. The TTY_LDISC bit
504 * prevents anyone taking a reference once it is clear. 508 * prevents anyone taking a reference once it is clear.
505 * We need the lock to avoid racing reference takers. 509 * We need the lock to avoid racing reference takers.
506 */ 510 */
507 511
508 spin_lock_irqsave(&tty_ldisc_lock, flags); 512 spin_lock_irqsave(&tty_ldisc_lock, flags);
509 if(tty->ldisc.refcount) 513 if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
510 { 514 if(tty->ldisc.refcount) {
511 /* Free the new ldisc we grabbed. Must drop the lock 515 /* Free the new ldisc we grabbed. Must drop the lock
512 first. */ 516 first. */
517 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
518 tty_ldisc_put(ldisc);
519 /*
520 * There are several reasons we may be busy, including
521 * random momentary I/O traffic. We must therefore
522 * retry. We could distinguish between blocking ops
523 * and retries if we made tty_ldisc_wait() smarter. That
524 * is up for discussion.
525 */
526 if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
527 return -ERESTARTSYS;
528 goto restart;
529 }
530 if(o_tty && o_tty->ldisc.refcount) {
531 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
532 tty_ldisc_put(ldisc);
533 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
534 return -ERESTARTSYS;
535 goto restart;
536 }
537 }
538
539 /* if the TTY_LDISC bit is set, then we are racing against another ldisc change */
540
541 if (!test_bit(TTY_LDISC, &tty->flags)) {
513 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 542 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
514 tty_ldisc_put(ldisc); 543 tty_ldisc_put(ldisc);
515 /* 544 ld = tty_ldisc_ref_wait(tty);
516 * There are several reasons we may be busy, including 545 tty_ldisc_deref(ld);
517 * random momentary I/O traffic. We must therefore
518 * retry. We could distinguish between blocking ops
519 * and retries if we made tty_ldisc_wait() smarter. That
520 * is up for discussion.
521 */
522 if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
523 return -ERESTARTSYS;
524 goto restart; 546 goto restart;
525 } 547 }
526 clear_bit(TTY_LDISC, &tty->flags); 548
549 clear_bit(TTY_LDISC, &tty->flags);
527 clear_bit(TTY_DONT_FLIP, &tty->flags); 550 clear_bit(TTY_DONT_FLIP, &tty->flags);
551 if (o_tty) {
552 clear_bit(TTY_LDISC, &o_tty->flags);
553 clear_bit(TTY_DONT_FLIP, &o_tty->flags);
554 }
528 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 555 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
529 556
530 /* 557 /*
531 * From this point on we know nobody has an ldisc 558 * From this point on we know nobody has an ldisc
532 * usage reference, nor can they obtain one until 559 * usage reference, nor can they obtain one until
533 * we say so later on. 560 * we say so later on.
534 */ 561 */
535 562
536 work = cancel_delayed_work(&tty->flip.work); 563 work = cancel_delayed_work(&tty->flip.work);
537 /* 564 /*
538 * Wait for ->hangup_work and ->flip.work handlers to terminate 565 * Wait for ->hangup_work and ->flip.work handlers to terminate
@@ -583,10 +610,12 @@ restart:
583 */ 610 */
584 611
585 tty_ldisc_enable(tty); 612 tty_ldisc_enable(tty);
613 if (o_tty)
614 tty_ldisc_enable(o_tty);
586 615
587 /* Restart it in case no characters kick it off. Safe if 616 /* Restart it in case no characters kick it off. Safe if
588 already running */ 617 already running */
589 if(work) 618 if (work)
590 schedule_delayed_work(&tty->flip.work, 1); 619 schedule_delayed_work(&tty->flip.work, 1);
591 return retval; 620 return retval;
592} 621}
@@ -2425,6 +2454,7 @@ static void __do_SAK(void *arg)
2425 int i; 2454 int i;
2426 struct file *filp; 2455 struct file *filp;
2427 struct tty_ldisc *disc; 2456 struct tty_ldisc *disc;
2457 struct fdtable *fdt;
2428 2458
2429 if (!tty) 2459 if (!tty)
2430 return; 2460 return;
@@ -2450,8 +2480,9 @@ static void __do_SAK(void *arg)
2450 } 2480 }
2451 task_lock(p); 2481 task_lock(p);
2452 if (p->files) { 2482 if (p->files) {
2453 spin_lock(&p->files->file_lock); 2483 rcu_read_lock();
2454 for (i=0; i < p->files->max_fds; i++) { 2484 fdt = files_fdtable(p->files);
2485 for (i=0; i < fdt->max_fds; i++) {
2455 filp = fcheck_files(p->files, i); 2486 filp = fcheck_files(p->files, i);
2456 if (!filp) 2487 if (!filp)
2457 continue; 2488 continue;
@@ -2464,7 +2495,7 @@ static void __do_SAK(void *arg)
2464 break; 2495 break;
2465 } 2496 }
2466 } 2497 }
2467 spin_unlock(&p->files->file_lock); 2498 rcu_read_unlock();
2468 } 2499 }
2469 task_unlock(p); 2500 task_unlock(p);
2470 } while_each_task_pid(session, PIDTYPE_SID, p); 2501 } while_each_task_pid(session, PIDTYPE_SID, p);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index b8d0c290b0db..1e33cb032e07 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -751,6 +751,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
752 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 752 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
753 unsigned int new_cols, new_rows, new_row_size, new_screen_size; 753 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
754 unsigned int end;
754 unsigned short *newscreen; 755 unsigned short *newscreen;
755 756
756 WARN_CONSOLE_UNLOCKED(); 757 WARN_CONSOLE_UNLOCKED();
@@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
794 old_origin = vc->vc_origin; 795 old_origin = vc->vc_origin;
795 new_origin = (long) newscreen; 796 new_origin = (long) newscreen;
796 new_scr_end = new_origin + new_screen_size; 797 new_scr_end = new_origin + new_screen_size;
797 if (new_rows < old_rows) 798
798 old_origin += (old_rows - new_rows) * old_row_size; 799 if (vc->vc_y > new_rows) {
800 if (old_rows - vc->vc_y < new_rows) {
801 /*
802 * Cursor near the bottom, copy contents from the
803 * bottom of buffer
804 */
805 old_origin += (old_rows - new_rows) * old_row_size;
806 end = vc->vc_scr_end;
807 } else {
808 /*
809 * Cursor is in no man's land, copy 1/2 screenful
810 * from the top and bottom of cursor position
811 */
812 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
813 end = old_origin + new_screen_size;
814 }
815 } else
816 /*
817 * Cursor near the top, copy contents from the top of buffer
818 */
819 end = (old_rows > new_rows) ? old_origin + new_screen_size :
820 vc->vc_scr_end;
799 821
800 update_attr(vc); 822 update_attr(vc);
801 823
802 while (old_origin < vc->vc_scr_end) { 824 while (old_origin < end) {
803 scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth); 825 scr_memcpyw((unsigned short *) new_origin,
826 (unsigned short *) old_origin, rlth);
804 if (rrem) 827 if (rrem)
805 scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem); 828 scr_memsetw((void *)(new_origin + rlth),
829 vc->vc_video_erase_char, rrem);
806 old_origin += old_row_size; 830 old_origin += old_row_size;
807 new_origin += new_row_size; 831 new_origin += new_row_size;
808 } 832 }
809 if (new_scr_end > new_origin) 833 if (new_scr_end > new_origin)
810 scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin); 834 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
835 new_scr_end - new_origin);
811 if (vc->vc_kmalloced) 836 if (vc->vc_kmalloced)
812 kfree(vc->vc_screenbuf); 837 kfree(vc->vc_screenbuf);
813 vc->vc_screenbuf = newscreen; 838 vc->vc_screenbuf = newscreen;
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c9b301dccec3..7fc2188386d9 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -59,7 +59,7 @@ static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
59 59
60static int watchdog_port; 60static int watchdog_port;
61static int mixcomwd_timer_alive; 61static int mixcomwd_timer_alive;
62static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); 62static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0);
63static char expect_close; 63static char expect_close;
64 64
65static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 10b014982381..109d62ccf651 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -627,7 +627,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
627 627
628 ret = kobject_register(&policy->kobj); 628 ret = kobject_register(&policy->kobj);
629 if (ret) 629 if (ret)
630 goto err_out; 630 goto err_out_driver_exit;
631 631
632 /* set up files for this cpu device */ 632 /* set up files for this cpu device */
633 drv_attr = cpufreq_driver->attr; 633 drv_attr = cpufreq_driver->attr;
@@ -673,6 +673,10 @@ err_out_unregister:
673 kobject_unregister(&policy->kobj); 673 kobject_unregister(&policy->kobj);
674 wait_for_completion(&policy->kobj_unregister); 674 wait_for_completion(&policy->kobj_unregister);
675 675
676err_out_driver_exit:
677 if (cpufreq_driver->exit)
678 cpufreq_driver->exit(policy);
679
676err_out: 680err_out:
677 kfree(policy); 681 kfree(policy);
678 682
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6e9da1372225..8334496a7e0a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -144,6 +144,22 @@ config I2C_I810
144 This driver can also be built as a module. If so, the module 144 This driver can also be built as a module. If so, the module
145 will be called i2c-i810. 145 will be called i2c-i810.
146 146
147config I2C_PXA
148 tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
149 depends on I2C && EXPERIMENTAL && ARCH_PXA
150 help
151 If you have devices in the PXA I2C bus, say yes to this option.
152 This driver can also be built as a module. If so, the module
153 will be called i2c-pxa.
154
155config I2C_PXA_SLAVE
156 bool "Intel PXA2XX I2C Slave comms support"
157 depends on I2C_PXA
158 help
159 Support I2C slave mode communications on the PXA I2C bus. This
160 is necessary for systems where the PXA may be a target on the
161 I2C bus.
162
147config I2C_PIIX4 163config I2C_PIIX4
148 tristate "Intel PIIX4" 164 tristate "Intel PIIX4"
149 depends on I2C && PCI 165 depends on I2C && PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 42d6d814da72..980b3e983670 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
28obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o 28obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
29obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o 29obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
30obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o 30obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
31obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
31obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o 32obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
32obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o 33obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
33obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o 34obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
new file mode 100644
index 000000000000..fdf53ce04248
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -0,0 +1,1022 @@
1/*
2 * i2c_adap_pxa.c
3 *
4 * I2C adapter for the PXA I2C bus access.
5 *
6 * Copyright (C) 2002 Intrinsyc Software Inc.
7 * Copyright (C) 2004-2005 Deep Blue Solutions Ltd.
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 * History:
14 * Apr 2002: Initial version [CS]
15 * Jun 2002: Properly seperated algo/adap [FB]
16 * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
17 * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
18 * Sep 2004: Major rework to ensure efficient bus handling [RMK]
19 * Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
20 * Feb 2005: Rework slave mode handling [RMK]
21 */
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/i2c.h>
25#include <linux/i2c-id.h>
26#include <linux/init.h>
27#include <linux/time.h>
28#include <linux/sched.h>
29#include <linux/delay.h>
30#include <linux/errno.h>
31#include <linux/interrupt.h>
32#include <linux/i2c-pxa.h>
33
34#include <asm/hardware.h>
35#include <asm/irq.h>
36#include <asm/arch/i2c.h>
37#include <asm/arch/pxa-regs.h>
38
39struct pxa_i2c {
40 spinlock_t lock;
41 wait_queue_head_t wait;
42 struct i2c_msg *msg;
43 unsigned int msg_num;
44 unsigned int msg_idx;
45 unsigned int msg_ptr;
46 unsigned int slave_addr;
47
48 struct i2c_adapter adap;
49#ifdef CONFIG_I2C_PXA_SLAVE
50 struct i2c_slave_client *slave;
51#endif
52
53 unsigned int irqlogidx;
54 u32 isrlog[32];
55 u32 icrlog[32];
56};
57
58/*
59 * I2C Slave mode address
60 */
61#define I2C_PXA_SLAVE_ADDR 0x1
62
63#ifdef DEBUG
64
65struct bits {
66 u32 mask;
67 const char *set;
68 const char *unset;
69};
70#define BIT(m, s, u) { .mask = m, .set = s, .unset = u }
71
72static inline void
73decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
74{
75 printk("%s %08x: ", prefix, val);
76 while (num--) {
77 const char *str = val & bits->mask ? bits->set : bits->unset;
78 if (str)
79 printk("%s ", str);
80 bits++;
81 }
82}
83
84static const struct bits isr_bits[] = {
85 BIT(ISR_RWM, "RX", "TX"),
86 BIT(ISR_ACKNAK, "NAK", "ACK"),
87 BIT(ISR_UB, "Bsy", "Rdy"),
88 BIT(ISR_IBB, "BusBsy", "BusRdy"),
89 BIT(ISR_SSD, "SlaveStop", NULL),
90 BIT(ISR_ALD, "ALD", NULL),
91 BIT(ISR_ITE, "TxEmpty", NULL),
92 BIT(ISR_IRF, "RxFull", NULL),
93 BIT(ISR_GCAD, "GenCall", NULL),
94 BIT(ISR_SAD, "SlaveAddr", NULL),
95 BIT(ISR_BED, "BusErr", NULL),
96};
97
98static void decode_ISR(unsigned int val)
99{
100 decode_bits(KERN_DEBUG "ISR", isr_bits, ARRAY_SIZE(isr_bits), val);
101 printk("\n");
102}
103
104static const struct bits icr_bits[] = {
105 BIT(ICR_START, "START", NULL),
106 BIT(ICR_STOP, "STOP", NULL),
107 BIT(ICR_ACKNAK, "ACKNAK", NULL),
108 BIT(ICR_TB, "TB", NULL),
109 BIT(ICR_MA, "MA", NULL),
110 BIT(ICR_SCLE, "SCLE", "scle"),
111 BIT(ICR_IUE, "IUE", "iue"),
112 BIT(ICR_GCD, "GCD", NULL),
113 BIT(ICR_ITEIE, "ITEIE", NULL),
114 BIT(ICR_IRFIE, "IRFIE", NULL),
115 BIT(ICR_BEIE, "BEIE", NULL),
116 BIT(ICR_SSDIE, "SSDIE", NULL),
117 BIT(ICR_ALDIE, "ALDIE", NULL),
118 BIT(ICR_SADIE, "SADIE", NULL),
119 BIT(ICR_UR, "UR", "ur"),
120};
121
122static void decode_ICR(unsigned int val)
123{
124 decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
125 printk("\n");
126}
127
128static unsigned int i2c_debug = DEBUG;
129
130static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
131{
132 dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR);
133}
134
135#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
136#else
137#define i2c_debug 0
138
139#define show_state(i2c) do { } while (0)
140#define decode_ISR(val) do { } while (0)
141#define decode_ICR(val) do { } while (0)
142#endif
143
144#define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
145
146static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
147
148static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
149{
150 unsigned int i;
151 printk("i2c: error: %s\n", why);
152 printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
153 i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
154 printk("i2c: ICR: %08x ISR: %08x\n"
155 "i2c: log: ", ICR, ISR);
156 for (i = 0; i < i2c->irqlogidx; i++)
157 printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
158 printk("\n");
159}
160
161static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
162{
163 return !(ICR & ICR_SCLE);
164}
165
166static void i2c_pxa_abort(struct pxa_i2c *i2c)
167{
168 unsigned long timeout = jiffies + HZ/4;
169
170 if (i2c_pxa_is_slavemode(i2c)) {
171 dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__);
172 return;
173 }
174
175 while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) {
176 unsigned long icr = ICR;
177
178 icr &= ~ICR_START;
179 icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
180
181 ICR = icr;
182
183 show_state(i2c);
184
185 msleep(1);
186 }
187
188 ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
189}
190
191static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
192{
193 int timeout = DEF_TIMEOUT;
194
195 while (timeout-- && ISR & (ISR_IBB | ISR_UB)) {
196 if ((ISR & ISR_SAD) != 0)
197 timeout += 4;
198
199 msleep(2);
200 show_state(i2c);
201 }
202
203 if (timeout <= 0)
204 show_state(i2c);
205
206 return timeout <= 0 ? I2C_RETRY : 0;
207}
208
209static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
210{
211 unsigned long timeout = jiffies + HZ*4;
212
213 while (time_before(jiffies, timeout)) {
214 if (i2c_debug > 1)
215 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
216 __func__, (long)jiffies, ISR, ICR, IBMR);
217
218 if (ISR & ISR_SAD) {
219 if (i2c_debug > 0)
220 dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
221 goto out;
222 }
223
224 /* wait for unit and bus being not busy, and we also do a
225 * quick check of the i2c lines themselves to ensure they've
226 * gone high...
227 */
228 if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) {
229 if (i2c_debug > 0)
230 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
231 return 1;
232 }
233
234 msleep(1);
235 }
236
237 if (i2c_debug > 0)
238 dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
239 out:
240 return 0;
241}
242
243static int i2c_pxa_set_master(struct pxa_i2c *i2c)
244{
245 if (i2c_debug)
246 dev_dbg(&i2c->adap.dev, "setting to bus master\n");
247
248 if ((ISR & (ISR_UB | ISR_IBB)) != 0) {
249 dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
250 if (!i2c_pxa_wait_master(i2c)) {
251 dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
252 return I2C_RETRY;
253 }
254 }
255
256 ICR |= ICR_SCLE;
257 return 0;
258}
259
260#ifdef CONFIG_I2C_PXA_SLAVE
261static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
262{
263 unsigned long timeout = jiffies + HZ*1;
264
265 /* wait for stop */
266
267 show_state(i2c);
268
269 while (time_before(jiffies, timeout)) {
270 if (i2c_debug > 1)
271 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
272 __func__, (long)jiffies, ISR, ICR, IBMR);
273
274 if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD ||
275 (ICR & ICR_SCLE) == 0) {
276 if (i2c_debug > 1)
277 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
278 return 1;
279 }
280
281 msleep(1);
282 }
283
284 if (i2c_debug > 0)
285 dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
286 return 0;
287}
288
289/*
290 * clear the hold on the bus, and take of anything else
291 * that has been configured
292 */
293static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
294{
295 show_state(i2c);
296
297 if (errcode < 0) {
298 udelay(100); /* simple delay */
299 } else {
300 /* we need to wait for the stop condition to end */
301
302 /* if we where in stop, then clear... */
303 if (ICR & ICR_STOP) {
304 udelay(100);
305 ICR &= ~ICR_STOP;
306 }
307
308 if (!i2c_pxa_wait_slave(i2c)) {
309 dev_err(&i2c->adap.dev, "%s: wait timedout\n",
310 __func__);
311 return;
312 }
313 }
314
315 ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA);
316 ICR &= ~ICR_SCLE;
317
318 if (i2c_debug) {
319 dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR);
320 decode_ICR(ICR);
321 }
322}
323#else
324#define i2c_pxa_set_slave(i2c, err) do { } while (0)
325#endif
326
327static void i2c_pxa_reset(struct pxa_i2c *i2c)
328{
329 pr_debug("Resetting I2C Controller Unit\n");
330
331 /* abort any transfer currently under way */
332 i2c_pxa_abort(i2c);
333
334 /* reset according to 9.8 */
335 ICR = ICR_UR;
336 ISR = I2C_ISR_INIT;
337 ICR &= ~ICR_UR;
338
339 ISAR = i2c->slave_addr;
340
341 /* set control register values */
342 ICR = I2C_ICR_INIT;
343
344#ifdef CONFIG_I2C_PXA_SLAVE
345 dev_info(&i2c->adap.dev, "Enabling slave mode\n");
346 ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE;
347#endif
348
349 i2c_pxa_set_slave(i2c, 0);
350
351 /* enable unit */
352 ICR |= ICR_IUE;
353 udelay(100);
354}
355
356
357#ifdef CONFIG_I2C_PXA_SLAVE
358/*
359 * I2C EEPROM emulation.
360 */
361static struct i2c_eeprom_emu eeprom = {
362 .size = I2C_EEPROM_EMU_SIZE,
363 .watch = LIST_HEAD_INIT(eeprom.watch),
364};
365
366struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void)
367{
368 return &eeprom;
369}
370
371int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *emu, void *data,
372 unsigned int addr, unsigned int size,
373 struct i2c_eeprom_emu_watcher *watcher)
374{
375 struct i2c_eeprom_emu_watch *watch;
376 unsigned long flags;
377
378 if (addr + size > emu->size)
379 return -EINVAL;
380
381 watch = kmalloc(sizeof(struct i2c_eeprom_emu_watch), GFP_KERNEL);
382 if (watch) {
383 watch->start = addr;
384 watch->end = addr + size - 1;
385 watch->ops = watcher;
386 watch->data = data;
387
388 local_irq_save(flags);
389 list_add(&watch->node, &emu->watch);
390 local_irq_restore(flags);
391 }
392
393 return watch ? 0 : -ENOMEM;
394}
395
396void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *emu, void *data,
397 struct i2c_eeprom_emu_watcher *watcher)
398{
399 struct i2c_eeprom_emu_watch *watch, *n;
400 unsigned long flags;
401
402 list_for_each_entry_safe(watch, n, &emu->watch, node) {
403 if (watch->ops == watcher && watch->data == data) {
404 local_irq_save(flags);
405 list_del(&watch->node);
406 local_irq_restore(flags);
407 kfree(watch);
408 }
409 }
410}
411
412static void i2c_eeprom_emu_event(void *ptr, i2c_slave_event_t event)
413{
414 struct i2c_eeprom_emu *emu = ptr;
415
416 eedbg(3, "i2c_eeprom_emu_event: %d\n", event);
417
418 switch (event) {
419 case I2C_SLAVE_EVENT_START_WRITE:
420 emu->seen_start = 1;
421 eedbg(2, "i2c_eeprom: write initiated\n");
422 break;
423
424 case I2C_SLAVE_EVENT_START_READ:
425 emu->seen_start = 0;
426 eedbg(2, "i2c_eeprom: read initiated\n");
427 break;
428
429 case I2C_SLAVE_EVENT_STOP:
430 emu->seen_start = 0;
431 eedbg(2, "i2c_eeprom: received stop\n");
432 break;
433
434 default:
435 eedbg(0, "i2c_eeprom: unhandled event\n");
436 break;
437 }
438}
439
440static int i2c_eeprom_emu_read(void *ptr)
441{
442 struct i2c_eeprom_emu *emu = ptr;
443 int ret;
444
445 ret = emu->bytes[emu->ptr];
446 emu->ptr = (emu->ptr + 1) % emu->size;
447
448 return ret;
449}
450
451static void i2c_eeprom_emu_write(void *ptr, unsigned int val)
452{
453 struct i2c_eeprom_emu *emu = ptr;
454 struct i2c_eeprom_emu_watch *watch;
455
456 if (emu->seen_start != 0) {
457 eedbg(2, "i2c_eeprom_emu_write: setting ptr %02x\n", val);
458 emu->ptr = val;
459 emu->seen_start = 0;
460 return;
461 }
462
463 emu->bytes[emu->ptr] = val;
464
465 eedbg(1, "i2c_eeprom_emu_write: ptr=0x%02x, val=0x%02x\n",
466 emu->ptr, val);
467
468 list_for_each_entry(watch, &emu->watch, node) {
469 if (!watch->ops || !watch->ops->write)
470 continue;
471 if (watch->start <= emu->ptr && watch->end >= emu->ptr)
472 watch->ops->write(watch->data, emu->ptr, val);
473 }
474
475 emu->ptr = (emu->ptr + 1) % emu->size;
476}
477
478struct i2c_slave_client eeprom_client = {
479 .data = &eeprom,
480 .event = i2c_eeprom_emu_event,
481 .read = i2c_eeprom_emu_read,
482 .write = i2c_eeprom_emu_write
483};
484
485/*
486 * PXA I2C Slave mode
487 */
488
489static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
490{
491 if (isr & ISR_BED) {
492 /* what should we do here? */
493 } else {
494 int ret = i2c->slave->read(i2c->slave->data);
495
496 IDBR = ret;
497 ICR |= ICR_TB; /* allow next byte */
498 }
499}
500
501static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
502{
503 unsigned int byte = IDBR;
504
505 if (i2c->slave != NULL)
506 i2c->slave->write(i2c->slave->data, byte);
507
508 ICR |= ICR_TB;
509}
510
511static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
512{
513 int timeout;
514
515 if (i2c_debug > 0)
516 dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",
517 (isr & ISR_RWM) ? 'r' : 't');
518
519 if (i2c->slave != NULL)
520 i2c->slave->event(i2c->slave->data,
521 (isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE);
522
523 /*
524 * slave could interrupt in the middle of us generating a
525 * start condition... if this happens, we'd better back off
526 * and stop holding the poor thing up
527 */
528 ICR &= ~(ICR_START|ICR_STOP);
529 ICR |= ICR_TB;
530
531 timeout = 0x10000;
532
533 while (1) {
534 if ((IBMR & 2) == 2)
535 break;
536
537 timeout--;
538
539 if (timeout <= 0) {
540 dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
541 break;
542 }
543 }
544
545 ICR &= ~ICR_SCLE;
546}
547
548static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
549{
550 if (i2c_debug > 2)
551 dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");
552
553 if (i2c->slave != NULL)
554 i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP);
555
556 if (i2c_debug > 2)
557 dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n");
558
559 /*
560 * If we have a master-mode message waiting,
561 * kick it off now that the slave has completed.
562 */
563 if (i2c->msg)
564 i2c_pxa_master_complete(i2c, I2C_RETRY);
565}
566#else
567static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
568{
569 if (isr & ISR_BED) {
570 /* what should we do here? */
571 } else {
572 IDBR = 0;
573 ICR |= ICR_TB;
574 }
575}
576
577static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
578{
579 ICR |= ICR_TB | ICR_ACKNAK;
580}
581
582static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
583{
584 int timeout;
585
586 /*
587 * slave could interrupt in the middle of us generating a
588 * start condition... if this happens, we'd better back off
589 * and stop holding the poor thing up
590 */
591 ICR &= ~(ICR_START|ICR_STOP);
592 ICR |= ICR_TB | ICR_ACKNAK;
593
594 timeout = 0x10000;
595
596 while (1) {
597 if ((IBMR & 2) == 2)
598 break;
599
600 timeout--;
601
602 if (timeout <= 0) {
603 dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
604 break;
605 }
606 }
607
608 ICR &= ~ICR_SCLE;
609}
610
611static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
612{
613 if (i2c->msg)
614 i2c_pxa_master_complete(i2c, I2C_RETRY);
615}
616#endif
617
618/*
619 * PXA I2C Master mode
620 */
621
622static inline unsigned int i2c_pxa_addr_byte(struct i2c_msg *msg)
623{
624 unsigned int addr = (msg->addr & 0x7f) << 1;
625
626 if (msg->flags & I2C_M_RD)
627 addr |= 1;
628
629 return addr;
630}
631
632static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
633{
634 u32 icr;
635
636 /*
637 * Step 1: target slave address into IDBR
638 */
639 IDBR = i2c_pxa_addr_byte(i2c->msg);
640
641 /*
642 * Step 2: initiate the write.
643 */
644 icr = ICR & ~(ICR_STOP | ICR_ALDIE);
645 ICR = icr | ICR_START | ICR_TB;
646}
647
648/*
649 * We are protected by the adapter bus semaphore.
650 */
651static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
652{
653 long timeout;
654 int ret;
655
656 /*
657 * Wait for the bus to become free.
658 */
659 ret = i2c_pxa_wait_bus_not_busy(i2c);
660 if (ret) {
661 dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
662 goto out;
663 }
664
665 /*
666 * Set master mode.
667 */
668 ret = i2c_pxa_set_master(i2c);
669 if (ret) {
670 dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
671 goto out;
672 }
673
674 spin_lock_irq(&i2c->lock);
675
676 i2c->msg = msg;
677 i2c->msg_num = num;
678 i2c->msg_idx = 0;
679 i2c->msg_ptr = 0;
680 i2c->irqlogidx = 0;
681
682 i2c_pxa_start_message(i2c);
683
684 spin_unlock_irq(&i2c->lock);
685
686 /*
687 * The rest of the processing occurs in the interrupt handler.
688 */
689 timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
690
691 /*
692 * We place the return code in i2c->msg_idx.
693 */
694 ret = i2c->msg_idx;
695
696 if (timeout == 0)
697 i2c_pxa_scream_blue_murder(i2c, "timeout");
698
699 out:
700 return ret;
701}
702
703/*
704 * i2c_pxa_master_complete - complete the message and wake up.
705 */
706static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
707{
708 i2c->msg_ptr = 0;
709 i2c->msg = NULL;
710 i2c->msg_idx ++;
711 i2c->msg_num = 0;
712 if (ret)
713 i2c->msg_idx = ret;
714 wake_up(&i2c->wait);
715}
716
717static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
718{
719 u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
720
721 again:
722 /*
723 * If ISR_ALD is set, we lost arbitration.
724 */
725 if (isr & ISR_ALD) {
726 /*
727 * Do we need to do anything here? The PXA docs
728 * are vague about what happens.
729 */
730 i2c_pxa_scream_blue_murder(i2c, "ALD set");
731
732 /*
733 * We ignore this error. We seem to see spurious ALDs
734 * for seemingly no reason. If we handle them as I think
735 * they should, we end up causing an I2C error, which
736 * is painful for some systems.
737 */
738 return; /* ignore */
739 }
740
741 if (isr & ISR_BED) {
742 int ret = BUS_ERROR;
743
744 /*
745 * I2C bus error - either the device NAK'd us, or
746 * something more serious happened. If we were NAK'd
747 * on the initial address phase, we can retry.
748 */
749 if (isr & ISR_ACKNAK) {
750 if (i2c->msg_ptr == 0 && i2c->msg_idx == 0)
751 ret = I2C_RETRY;
752 else
753 ret = XFER_NAKED;
754 }
755 i2c_pxa_master_complete(i2c, ret);
756 } else if (isr & ISR_RWM) {
757 /*
758 * Read mode. We have just sent the address byte, and
759 * now we must initiate the transfer.
760 */
761 if (i2c->msg_ptr == i2c->msg->len - 1 &&
762 i2c->msg_idx == i2c->msg_num - 1)
763 icr |= ICR_STOP | ICR_ACKNAK;
764
765 icr |= ICR_ALDIE | ICR_TB;
766 } else if (i2c->msg_ptr < i2c->msg->len) {
767 /*
768 * Write mode. Write the next data byte.
769 */
770 IDBR = i2c->msg->buf[i2c->msg_ptr++];
771
772 icr |= ICR_ALDIE | ICR_TB;
773
774 /*
775 * If this is the last byte of the last message, send
776 * a STOP.
777 */
778 if (i2c->msg_ptr == i2c->msg->len &&
779 i2c->msg_idx == i2c->msg_num - 1)
780 icr |= ICR_STOP;
781 } else if (i2c->msg_idx < i2c->msg_num - 1) {
782 /*
783 * Next segment of the message.
784 */
785 i2c->msg_ptr = 0;
786 i2c->msg_idx ++;
787 i2c->msg++;
788
789 /*
790 * If we aren't doing a repeated start and address,
791 * go back and try to send the next byte. Note that
792 * we do not support switching the R/W direction here.
793 */
794 if (i2c->msg->flags & I2C_M_NOSTART)
795 goto again;
796
797 /*
798 * Write the next address.
799 */
800 IDBR = i2c_pxa_addr_byte(i2c->msg);
801
802 /*
803 * And trigger a repeated start, and send the byte.
804 */
805 icr &= ~ICR_ALDIE;
806 icr |= ICR_START | ICR_TB;
807 } else {
808 if (i2c->msg->len == 0) {
809 /*
810 * Device probes have a message length of zero
811 * and need the bus to be reset before it can
812 * be used again.
813 */
814 i2c_pxa_reset(i2c);
815 }
816 i2c_pxa_master_complete(i2c, 0);
817 }
818
819 i2c->icrlog[i2c->irqlogidx-1] = icr;
820
821 ICR = icr;
822 show_state(i2c);
823}
824
825static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
826{
827 u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
828
829 /*
830 * Read the byte.
831 */
832 i2c->msg->buf[i2c->msg_ptr++] = IDBR;
833
834 if (i2c->msg_ptr < i2c->msg->len) {
835 /*
836 * If this is the last byte of the last
837 * message, send a STOP.
838 */
839 if (i2c->msg_ptr == i2c->msg->len - 1)
840 icr |= ICR_STOP | ICR_ACKNAK;
841
842 icr |= ICR_ALDIE | ICR_TB;
843 } else {
844 i2c_pxa_master_complete(i2c, 0);
845 }
846
847 i2c->icrlog[i2c->irqlogidx-1] = icr;
848
849 ICR = icr;
850}
851
852static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
853{
854 struct pxa_i2c *i2c = dev_id;
855 u32 isr = ISR;
856
857 if (i2c_debug > 2 && 0) {
858 dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
859 __func__, isr, ICR, IBMR);
860 decode_ISR(isr);
861 }
862
863 if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
864 i2c->isrlog[i2c->irqlogidx++] = isr;
865
866 show_state(i2c);
867
868 /*
869 * Always clear all pending IRQs.
870 */
871 ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED);
872
873 if (isr & ISR_SAD)
874 i2c_pxa_slave_start(i2c, isr);
875 if (isr & ISR_SSD)
876 i2c_pxa_slave_stop(i2c);
877
878 if (i2c_pxa_is_slavemode(i2c)) {
879 if (isr & ISR_ITE)
880 i2c_pxa_slave_txempty(i2c, isr);
881 if (isr & ISR_IRF)
882 i2c_pxa_slave_rxfull(i2c, isr);
883 } else if (i2c->msg) {
884 if (isr & ISR_ITE)
885 i2c_pxa_irq_txempty(i2c, isr);
886 if (isr & ISR_IRF)
887 i2c_pxa_irq_rxfull(i2c, isr);
888 } else {
889 i2c_pxa_scream_blue_murder(i2c, "spurious irq");
890 }
891
892 return IRQ_HANDLED;
893}
894
895
896static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
897{
898 struct pxa_i2c *i2c = adap->algo_data;
899 int ret, i;
900
901 for (i = adap->retries; i >= 0; i--) {
902 ret = i2c_pxa_do_xfer(i2c, msgs, num);
903 if (ret != I2C_RETRY)
904 goto out;
905
906 if (i2c_debug)
907 dev_dbg(&adap->dev, "Retrying transmission\n");
908 udelay(100);
909 }
910 i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
911 ret = -EREMOTEIO;
912 out:
913 i2c_pxa_set_slave(i2c, ret);
914 return ret;
915}
916
917static struct i2c_algorithm i2c_pxa_algorithm = {
918 .name = "PXA-I2C-Algorithm",
919 .id = I2C_ALGO_PXA,
920 .master_xfer = i2c_pxa_xfer,
921};
922
923static struct pxa_i2c i2c_pxa = {
924 .lock = SPIN_LOCK_UNLOCKED,
925 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
926 .adap = {
927 .name = "pxa2xx-i2c",
928 .id = I2C_ALGO_PXA,
929 .algo = &i2c_pxa_algorithm,
930 .retries = 5,
931 },
932};
933
934static int i2c_pxa_probe(struct device *dev)
935{
936 struct pxa_i2c *i2c = &i2c_pxa;
937 struct i2c_pxa_platform_data *plat = dev->platform_data;
938 int ret;
939
940#ifdef CONFIG_PXA27x
941 pxa_gpio_mode(GPIO117_I2CSCL_MD);
942 pxa_gpio_mode(GPIO118_I2CSDA_MD);
943 udelay(100);
944#endif
945
946 i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
947
948#ifdef CONFIG_I2C_PXA_SLAVE
949 i2c->slave = &eeprom_client;
950 if (plat) {
951 i2c->slave_addr = plat->slave_addr;
952 if (plat->slave)
953 i2c->slave = plat->slave;
954 }
955#endif
956
957 pxa_set_cken(CKEN14_I2C, 1);
958 ret = request_irq(IRQ_I2C, i2c_pxa_handler, SA_INTERRUPT,
959 "pxa2xx-i2c", i2c);
960 if (ret)
961 goto out;
962
963 i2c_pxa_reset(i2c);
964
965 i2c->adap.algo_data = i2c;
966 i2c->adap.dev.parent = dev;
967
968 ret = i2c_add_adapter(&i2c->adap);
969 if (ret < 0) {
970 printk(KERN_INFO "I2C: Failed to add bus\n");
971 goto err_irq;
972 }
973
974 dev_set_drvdata(dev, i2c);
975
976#ifdef CONFIG_I2C_PXA_SLAVE
977 printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
978 i2c->adap.dev.bus_id, i2c->slave_addr);
979#else
980 printk(KERN_INFO "I2C: %s: PXA I2C adapter\n",
981 i2c->adap.dev.bus_id);
982#endif
983 return 0;
984
985 err_irq:
986 free_irq(IRQ_I2C, i2c);
987 out:
988 return ret;
989}
990
991static int i2c_pxa_remove(struct device *dev)
992{
993 struct pxa_i2c *i2c = dev_get_drvdata(dev);
994
995 dev_set_drvdata(dev, NULL);
996
997 i2c_del_adapter(&i2c->adap);
998 free_irq(IRQ_I2C, i2c);
999 pxa_set_cken(CKEN14_I2C, 0);
1000
1001 return 0;
1002}
1003
1004static struct device_driver i2c_pxa_driver = {
1005 .name = "pxa2xx-i2c",
1006 .bus = &platform_bus_type,
1007 .probe = i2c_pxa_probe,
1008 .remove = i2c_pxa_remove,
1009};
1010
1011static int __init i2c_adap_pxa_init(void)
1012{
1013 return driver_register(&i2c_pxa_driver);
1014}
1015
1016static void i2c_adap_pxa_exit(void)
1017{
1018 return driver_unregister(&i2c_pxa_driver);
1019}
1020
1021module_init(i2c_adap_pxa_init);
1022module_exit(i2c_adap_pxa_exit);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index f1d1ec4e9677..dc0841b2721c 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -454,9 +454,12 @@ int ide_event(event_t event, int priority,
454static struct pcmcia_device_id ide_ids[] = { 454static struct pcmcia_device_id ide_ids[] = {
455 PCMCIA_DEVICE_FUNC_ID(4), 455 PCMCIA_DEVICE_FUNC_ID(4),
456 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), 456 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
457 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
458 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
457 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), 459 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
460 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
458 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001), 461 PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
459 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), 462 PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
460 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), 463 PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
461 PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74), 464 PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
462 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), 465 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
@@ -481,6 +484,7 @@ static struct pcmcia_device_id ide_ids[] = {
481 PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), 484 PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
482 PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), 485 PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
483 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), 486 PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
487 PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
484 PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), 488 PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
485 PCMCIA_DEVICE_NULL, 489 PCMCIA_DEVICE_NULL,
486}; 490};
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 06759b36afea..9d6facf2f78f 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -883,7 +883,7 @@ static int __video1394_ioctl(struct file *file,
883 v.channel); 883 v.channel);
884 } 884 }
885 885
886 if (copy_to_user((void *)arg, &v, sizeof(v))) { 886 if (copy_to_user(argp, &v, sizeof(v))) {
887 /* FIXME : free allocated dma resources */ 887 /* FIXME : free allocated dma resources */
888 return -EFAULT; 888 return -EFAULT;
889 } 889 }
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 3241d6c9dc11..ffbcd40418d5 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -937,12 +937,12 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
937 ++mthca_version_printed; 937 ++mthca_version_printed;
938 } 938 }
939 939
940 printk(KERN_INFO PFX "Initializing %s (%s)\n", 940 printk(KERN_INFO PFX "Initializing %s\n",
941 pci_pretty_name(pdev), pci_name(pdev)); 941 pci_name(pdev));
942 942
943 if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) { 943 if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
944 printk(KERN_ERR PFX "%s (%s) has invalid driver data %lx\n", 944 printk(KERN_ERR PFX "%s has invalid driver data %lx\n",
945 pci_pretty_name(pdev), pci_name(pdev), id->driver_data); 945 pci_name(pdev), id->driver_data);
946 return -ENODEV; 946 return -ENODEV;
947 } 947 }
948 948
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 8ea801271a41..4f995391dd1d 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -71,8 +71,8 @@ int mthca_reset(struct mthca_dev *mdev)
71 bridge)) != NULL) { 71 bridge)) != NULL) {
72 if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE && 72 if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
73 bridge->subordinate == mdev->pdev->bus) { 73 bridge->subordinate == mdev->pdev->bus) {
74 mthca_dbg(mdev, "Found bridge: %s (%s)\n", 74 mthca_dbg(mdev, "Found bridge: %s\n",
75 pci_pretty_name(bridge), pci_name(bridge)); 75 pci_name(bridge));
76 break; 76 break;
77 } 77 }
78 } 78 }
@@ -83,8 +83,8 @@ int mthca_reset(struct mthca_dev *mdev)
83 * assume we're in no-bridge mode and hope for 83 * assume we're in no-bridge mode and hope for
84 * the best. 84 * the best.
85 */ 85 */
86 mthca_warn(mdev, "No bridge found for %s (%s)\n", 86 mthca_warn(mdev, "No bridge found for %s\n",
87 pci_pretty_name(mdev->pdev), pci_name(mdev->pdev)); 87 pci_name(mdev->pdev));
88 } 88 }
89 89
90 } 90 }
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 19c14c4beb44..60b696e9336b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -509,7 +509,7 @@ do { \
509 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \ 509 int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
510 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \ 510 if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
511 for (i = 0; i < len / sizeof(compat_long_t); i++) \ 511 for (i = 0; i < len / sizeof(compat_long_t); i++) \
512 if (copy_to_user((compat_long_t*) p + i, \ 512 if (copy_to_user((compat_long_t __user *) p + i, \
513 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \ 513 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
514 sizeof(compat_long_t))) \ 514 sizeof(compat_long_t))) \
515 return -EFAULT; \ 515 return -EFAULT; \
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 20ca80b7dc20..373ab92e367b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2087,7 +2087,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
2087 return 0; 2087 return 0;
2088} 2088}
2089 2089
2090static int get_bitmap_file(mddev_t * mddev, void * arg) 2090static int get_bitmap_file(mddev_t * mddev, void __user * arg)
2091{ 2091{
2092 mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */ 2092 mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */
2093 char *ptr, *buf = NULL; 2093 char *ptr, *buf = NULL;
@@ -2781,7 +2781,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
2781 goto done_unlock; 2781 goto done_unlock;
2782 2782
2783 case GET_BITMAP_FILE: 2783 case GET_BITMAP_FILE:
2784 err = get_bitmap_file(mddev, (void *)arg); 2784 err = get_bitmap_file(mddev, argp);
2785 goto done_unlock; 2785 goto done_unlock;
2786 2786
2787 case GET_DISK_INFO: 2787 case GET_DISK_INFO:
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 772d6112fb3b..c578a529e7a8 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,4 +2,7 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := video/ radio/ dvb/ common/ 5obj-y := common/
6obj-$(CONFIG_VIDEO_DEV) += video/
7obj-$(CONFIG_VIDEO_DEV) += radio/
8obj-$(CONFIG_DVB) += dvb/
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index ab7a1fba4427..a0e700d7a4a4 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: ir-common.c,v 1.11 2005/07/07 14:44:43 mchehab Exp $
3 * 2 *
4 * some common structs and functions to handle infrared remotes via 3 * some common structs and functions to handle infrared remotes via
5 * input layer ... 4 * input layer ...
@@ -335,6 +334,72 @@ int ir_dump_samples(u32 *samples, int count)
335 return 0; 334 return 0;
336} 335}
337 336
337/* decode raw samples, pulse distance coding used by NEC remotes */
338int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
339{
340 int i,last,bit,len;
341 u32 curBit;
342 u32 value;
343
344 /* find start burst */
345 for (i = len = 0; i < count * 32; i++) {
346 bit = getbit(samples,i);
347 if (bit) {
348 len++;
349 } else {
350 if (len >= 29)
351 break;
352 len = 0;
353 }
354 }
355
356 /* start burst to short */
357 if (len < 29)
358 return 0xffffffff;
359
360 /* find start silence */
361 for (len = 0; i < count * 32; i++) {
362 bit = getbit(samples,i);
363 if (bit) {
364 break;
365 } else {
366 len++;
367 }
368 }
369
370 /* silence to short */
371 if (len < 7)
372 return 0xffffffff;
373
374 /* go decoding */
375 len = 0;
376 last = 1;
377 value = 0; curBit = 1;
378 for (; i < count * 32; i++) {
379 bit = getbit(samples,i);
380 if (last) {
381 if(bit) {
382 continue;
383 } else {
384 len = 1;
385 }
386 } else {
387 if (bit) {
388 if (len > (low + high) /2)
389 value |= curBit;
390 curBit <<= 1;
391 if (curBit == 1)
392 break;
393 } else {
394 len++;
395 }
396 }
397 last = bit;
398 }
399
400 return value;
401}
402
338/* decode raw samples, biphase coding, used by rc5 for example */ 403/* decode raw samples, biphase coding, used by rc5 for example */
339int ir_decode_biphase(u32 *samples, int count, int low, int high) 404int ir_decode_biphase(u32 *samples, int count, int low, int high)
340{ 405{
@@ -383,6 +448,7 @@ EXPORT_SYMBOL_GPL(ir_input_keydown);
383EXPORT_SYMBOL_GPL(ir_extract_bits); 448EXPORT_SYMBOL_GPL(ir_extract_bits);
384EXPORT_SYMBOL_GPL(ir_dump_samples); 449EXPORT_SYMBOL_GPL(ir_dump_samples);
385EXPORT_SYMBOL_GPL(ir_decode_biphase); 450EXPORT_SYMBOL_GPL(ir_decode_biphase);
451EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
386 452
387/* 453/*
388 * Local variables: 454 * Local variables:
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index c04fd11526e0..37888989ea2e 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -1,5 +1,4 @@
1#include <media/saa7146_vv.h> 1#include <media/saa7146_vv.h>
2#include <linux/version.h>
3 2
4#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1) 3#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
5 4
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index 6284894505c6..fec6beab8c28 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -1,4 +1,3 @@
1#include <linux/version.h>
2#include <media/saa7146_vv.h> 1#include <media/saa7146_vv.h>
3 2
4static u32 saa7146_i2c_func(struct i2c_adapter *adapter) 3static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
@@ -402,12 +401,9 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
402 saa7146_i2c_reset(dev); 401 saa7146_i2c_reset(dev);
403 402
404 if( NULL != i2c_adapter ) { 403 if( NULL != i2c_adapter ) {
405#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
406 i2c_adapter->data = dev;
407#else
408 BUG_ON(!i2c_adapter->class); 404 BUG_ON(!i2c_adapter->class);
409 i2c_set_adapdata(i2c_adapter,dev); 405 i2c_set_adapdata(i2c_adapter,dev);
410#endif 406 i2c_adapter->dev.parent = &dev->pci->dev;
411 i2c_adapter->algo = &saa7146_algo; 407 i2c_adapter->algo = &saa7146_algo;
412 i2c_adapter->algo_data = NULL; 408 i2c_adapter->algo_data = NULL;
413 i2c_adapter->id = I2C_HW_SAA7146; 409 i2c_adapter->id = I2C_HW_SAA7146;
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 0410cc96a48e..47e28b0ee951 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -164,12 +164,11 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate,
164 return 0; 164 return 0;
165} 165}
166 166
167static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 167static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
168{ 168{
169 u8 buf[4]; 169 u8 buf[4];
170 u32 div; 170 u32 div;
171 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 171 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
172 struct flexcop_device *fc = fe->dvb->priv;
173 172
174 div = params->frequency / 125; 173 div = params->frequency / 125;
175 174
@@ -180,7 +179,7 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_fronten
180 179
181 if (params->frequency < 1500000) buf[3] |= 0x10; 180 if (params->frequency < 1500000) buf[3] |= 0x10;
182 181
183 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) 182 if (i2c_transfer(i2c, &msg, 1) != 1)
184 return -EIO; 183 return -EIO;
185 return 0; 184 return 0;
186} 185}
@@ -335,8 +334,103 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
335 .pll_set = skystar23_samsung_tbdu18132_pll_set, 334 .pll_set = skystar23_samsung_tbdu18132_pll_set,
336}; 335};
337 336
337
338static u8 alps_tdee4_stv0297_inittab[] = {
339 0x80, 0x01,
340 0x80, 0x00,
341 0x81, 0x01,
342 0x81, 0x00,
343 0x00, 0x09,
344 0x01, 0x69,
345 0x03, 0x00,
346 0x04, 0x00,
347 0x07, 0x00,
348 0x08, 0x00,
349 0x20, 0x00,
350 0x21, 0x40,
351 0x22, 0x00,
352 0x23, 0x00,
353 0x24, 0x40,
354 0x25, 0x88,
355 0x30, 0xff,
356 0x31, 0x00,
357 0x32, 0xff,
358 0x33, 0x00,
359 0x34, 0x50,
360 0x35, 0x7f,
361 0x36, 0x00,
362 0x37, 0x20,
363 0x38, 0x00,
364 0x40, 0x1c,
365 0x41, 0xff,
366 0x42, 0x29,
367 0x43, 0x00,
368 0x44, 0xff,
369 0x45, 0x00,
370 0x46, 0x00,
371 0x49, 0x04,
372 0x4a, 0x00,
373 0x4b, 0xf8,
374 0x52, 0x30,
375 0x55, 0xae,
376 0x56, 0x47,
377 0x57, 0xe1,
378 0x58, 0x3a,
379 0x5a, 0x1e,
380 0x5b, 0x34,
381 0x60, 0x00,
382 0x63, 0x00,
383 0x64, 0x00,
384 0x65, 0x00,
385 0x66, 0x00,
386 0x67, 0x00,
387 0x68, 0x00,
388 0x69, 0x00,
389 0x6a, 0x02,
390 0x6b, 0x00,
391 0x70, 0xff,
392 0x71, 0x00,
393 0x72, 0x00,
394 0x73, 0x00,
395 0x74, 0x0c,
396 0x80, 0x00,
397 0x81, 0x00,
398 0x82, 0x00,
399 0x83, 0x00,
400 0x84, 0x04,
401 0x85, 0x80,
402 0x86, 0x24,
403 0x87, 0x78,
404 0x88, 0x10,
405 0x89, 0x00,
406 0x90, 0x01,
407 0x91, 0x01,
408 0xa0, 0x04,
409 0xa1, 0x00,
410 0xa2, 0x00,
411 0xb0, 0x91,
412 0xb1, 0x0b,
413 0xc0, 0x53,
414 0xc1, 0x70,
415 0xc2, 0x12,
416 0xd0, 0x00,
417 0xd1, 0x00,
418 0xd2, 0x00,
419 0xd3, 0x00,
420 0xd4, 0x00,
421 0xd5, 0x00,
422 0xde, 0x00,
423 0xdf, 0x00,
424 0x61, 0x49,
425 0x62, 0x0b,
426 0x53, 0x08,
427 0x59, 0x08,
428 0xff, 0xff,
429};
430
338static struct stv0297_config alps_tdee4_stv0297_config = { 431static struct stv0297_config alps_tdee4_stv0297_config = {
339 .demod_address = 0x1c, 432 .demod_address = 0x1c,
433 .inittab = alps_tdee4_stv0297_inittab,
340// .invert = 1, 434// .invert = 1,
341// .pll_set = alps_tdee4_stv0297_pll_set, 435// .pll_set = alps_tdee4_stv0297_pll_set,
342}; 436};
@@ -370,7 +464,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
370 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address); 464 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
371 } else 465 } else
372 /* try the cable dvb (stv0297) */ 466 /* try the cable dvb (stv0297) */
373 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) { 467 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
374 fc->dev_type = FC_CABLE; 468 fc->dev_type = FC_CABLE;
375 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); 469 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
376 } else 470 } else
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 3c5a8e273c4a..f29571450038 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card 2 * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
3 * 3 *
4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
5 * 5 *
6 * large parts based on the bttv driver 6 * large parts based on the bttv driver
7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de) 7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de)
@@ -219,7 +219,7 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
219 controlreg &= ~0x1f; 219 controlreg &= ~0x1f;
220 controlreg |= 0x1b; 220 controlreg |= 0x1b;
221 221
222 btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START); 222 btwrite(bt->risc_dma, BT878_ARISC_START);
223 223
224 /* original int mask had : 224 /* original int mask had :
225 * 6 2 8 4 0 225 * 6 2 8 4 0
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index 837623f7fcdf..a73baf00ca39 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -1,7 +1,7 @@
1/* 1/*
2 bt878.h - Bt878 audio module (register offsets) 2 bt878.h - Bt878 audio module (register offsets)
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
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
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 07a0b0a968a6..34a837a1abf4 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1,5 +1,4 @@
1/* 1/*
2
3 Frontend/Card driver for TwinHan DST Frontend 2 Frontend/Card driver for TwinHan DST Frontend
4 Copyright (C) 2003 Jamie Honan 3 Copyright (C) 2003 Jamie Honan
5 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) 4 Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
@@ -19,7 +18,6 @@
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/ 19*/
21 20
22
23#include <linux/kernel.h> 21#include <linux/kernel.h>
24#include <linux/module.h> 22#include <linux/module.h>
25#include <linux/init.h> 23#include <linux/init.h>
@@ -28,31 +26,45 @@
28#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
29#include <linux/delay.h> 27#include <linux/delay.h>
30#include <asm/div64.h> 28#include <asm/div64.h>
31
32#include "dvb_frontend.h" 29#include "dvb_frontend.h"
33#include "dst_priv.h" 30#include "dst_priv.h"
34#include "dst_common.h" 31#include "dst_common.h"
35 32
36
37static unsigned int verbose = 1; 33static unsigned int verbose = 1;
38module_param(verbose, int, 0644); 34module_param(verbose, int, 0644);
39MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 35MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
40 36
41static unsigned int debug = 1;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
44
45static unsigned int dst_addons; 37static unsigned int dst_addons;
46module_param(dst_addons, int, 0644); 38module_param(dst_addons, int, 0644);
47MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); 39MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
48 40
49#define dprintk if (debug) printk 41#define HAS_LOCK 1
50 42#define ATTEMPT_TUNE 2
51#define HAS_LOCK 1 43#define HAS_POWER 4
52#define ATTEMPT_TUNE 2 44
53#define HAS_POWER 4 45#define DST_ERROR 0
54 46#define DST_NOTICE 1
55static void dst_packsize(struct dst_state* state, int psize) 47#define DST_INFO 2
48#define DST_DEBUG 3
49
50#define dprintk(x, y, z, format, arg...) do { \
51 if (z) { \
52 if ((x > DST_ERROR) && (x > y)) \
53 printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
54 else if ((x > DST_NOTICE) && (x > y)) \
55 printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
56 else if ((x > DST_INFO) && (x > y)) \
57 printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
58 else if ((x > DST_DEBUG) && (x > y)) \
59 printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
60 } else { \
61 if (x > y) \
62 printk(format, ##arg); \
63 } \
64} while(0)
65
66
67static void dst_packsize(struct dst_state *state, int psize)
56{ 68{
57 union dst_gpio_packet bits; 69 union dst_gpio_packet bits;
58 70
@@ -60,7 +72,7 @@ static void dst_packsize(struct dst_state* state, int psize)
60 bt878_device_control(state->bt, DST_IG_TS, &bits); 72 bt878_device_control(state->bt, DST_IG_TS, &bits);
61} 73}
62 74
63int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay) 75int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int delay)
64{ 76{
65 union dst_gpio_packet enb; 77 union dst_gpio_packet enb;
66 union dst_gpio_packet bits; 78 union dst_gpio_packet bits;
@@ -68,63 +80,55 @@ int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int
68 80
69 enb.enb.mask = mask; 81 enb.enb.mask = mask;
70 enb.enb.enable = enbb; 82 enb.enb.enable = enbb;
71 if (verbose > 4)
72 dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
73 83
84 dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
74 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { 85 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
75 dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb); 86 dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
76 return -EREMOTEIO; 87 return -EREMOTEIO;
77 } 88 }
78 udelay(1000); 89 udelay(1000);
79 /* because complete disabling means no output, no need to do output packet */ 90 /* because complete disabling means no output, no need to do output packet */
80 if (enbb == 0) 91 if (enbb == 0)
81 return 0; 92 return 0;
82
83 if (delay) 93 if (delay)
84 msleep(10); 94 msleep(10);
85
86 bits.outp.mask = enbb; 95 bits.outp.mask = enbb;
87 bits.outp.highvals = outhigh; 96 bits.outp.highvals = outhigh;
88
89 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { 97 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
90 dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh); 98 dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
91 return -EREMOTEIO; 99 return -EREMOTEIO;
92 } 100 }
101
93 return 0; 102 return 0;
94} 103}
95EXPORT_SYMBOL(dst_gpio_outb); 104EXPORT_SYMBOL(dst_gpio_outb);
96 105
97int dst_gpio_inb(struct dst_state *state, u8 * result) 106int dst_gpio_inb(struct dst_state *state, u8 *result)
98{ 107{
99 union dst_gpio_packet rd_packet; 108 union dst_gpio_packet rd_packet;
100 int err; 109 int err;
101 110
102 *result = 0; 111 *result = 0;
103
104 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { 112 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
105 dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err); 113 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err);
106 return -EREMOTEIO; 114 return -EREMOTEIO;
107 } 115 }
108
109 *result = (u8) rd_packet.rd.value; 116 *result = (u8) rd_packet.rd.value;
117
110 return 0; 118 return 0;
111} 119}
112EXPORT_SYMBOL(dst_gpio_inb); 120EXPORT_SYMBOL(dst_gpio_inb);
113 121
114int rdc_reset_state(struct dst_state *state) 122int rdc_reset_state(struct dst_state *state)
115{ 123{
116 if (verbose > 1) 124 dprintk(verbose, DST_INFO, 1, "Resetting state machine");
117 dprintk("%s: Resetting state machine\n", __FUNCTION__);
118
119 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { 125 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
120 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 126 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
121 return -1; 127 return -1;
122 } 128 }
123
124 msleep(10); 129 msleep(10);
125
126 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { 130 if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
127 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 131 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
128 msleep(10); 132 msleep(10);
129 return -1; 133 return -1;
130 } 134 }
@@ -135,16 +139,14 @@ EXPORT_SYMBOL(rdc_reset_state);
135 139
136int rdc_8820_reset(struct dst_state *state) 140int rdc_8820_reset(struct dst_state *state)
137{ 141{
138 if (verbose > 1) 142 dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
139 dprintk("%s: Resetting DST\n", __FUNCTION__);
140
141 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { 143 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
142 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 144 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
143 return -1; 145 return -1;
144 } 146 }
145 udelay(1000); 147 udelay(1000);
146 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { 148 if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
147 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 149 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
148 return -1; 150 return -1;
149 } 151 }
150 152
@@ -155,10 +157,11 @@ EXPORT_SYMBOL(rdc_8820_reset);
155int dst_pio_enable(struct dst_state *state) 157int dst_pio_enable(struct dst_state *state)
156{ 158{
157 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { 159 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
158 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 160 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
159 return -1; 161 return -1;
160 } 162 }
161 udelay(1000); 163 udelay(1000);
164
162 return 0; 165 return 0;
163} 166}
164EXPORT_SYMBOL(dst_pio_enable); 167EXPORT_SYMBOL(dst_pio_enable);
@@ -166,7 +169,7 @@ EXPORT_SYMBOL(dst_pio_enable);
166int dst_pio_disable(struct dst_state *state) 169int dst_pio_disable(struct dst_state *state)
167{ 170{
168 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { 171 if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
169 dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); 172 dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
170 return -1; 173 return -1;
171 } 174 }
172 if (state->type_flags & DST_TYPE_HAS_FW_1) 175 if (state->type_flags & DST_TYPE_HAS_FW_1)
@@ -183,19 +186,16 @@ int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
183 186
184 for (i = 0; i < 200; i++) { 187 for (i = 0; i < 200; i++) {
185 if (dst_gpio_inb(state, &reply) < 0) { 188 if (dst_gpio_inb(state, &reply) < 0) {
186 dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__); 189 dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
187 return -1; 190 return -1;
188 } 191 }
189
190 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { 192 if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
191 if (verbose > 4) 193 dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
192 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
193 return 1; 194 return 1;
194 } 195 }
195 msleep(10); 196 msleep(10);
196 } 197 }
197 if (verbose > 1) 198 dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
198 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
199 199
200 return 0; 200 return 0;
201} 201}
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(dst_wait_dst_ready);
203 203
204int dst_error_recovery(struct dst_state *state) 204int dst_error_recovery(struct dst_state *state)
205{ 205{
206 dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__); 206 dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
207 dst_pio_disable(state); 207 dst_pio_disable(state);
208 msleep(10); 208 msleep(10);
209 dst_pio_enable(state); 209 dst_pio_enable(state);
@@ -215,7 +215,7 @@ EXPORT_SYMBOL(dst_error_recovery);
215 215
216int dst_error_bailout(struct dst_state *state) 216int dst_error_bailout(struct dst_state *state)
217{ 217{
218 dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__); 218 dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
219 rdc_8820_reset(state); 219 rdc_8820_reset(state);
220 dst_pio_disable(state); 220 dst_pio_disable(state);
221 msleep(10); 221 msleep(10);
@@ -224,17 +224,15 @@ int dst_error_bailout(struct dst_state *state)
224} 224}
225EXPORT_SYMBOL(dst_error_bailout); 225EXPORT_SYMBOL(dst_error_bailout);
226 226
227 227int dst_comm_init(struct dst_state *state)
228int dst_comm_init(struct dst_state* state)
229{ 228{
230 if (verbose > 1) 229 dprintk(verbose, DST_INFO, 1, "Initializing DST.");
231 dprintk ("%s: Initializing DST..\n", __FUNCTION__);
232 if ((dst_pio_enable(state)) < 0) { 230 if ((dst_pio_enable(state)) < 0) {
233 dprintk("%s: PIO Enable Failed.\n", __FUNCTION__); 231 dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
234 return -1; 232 return -1;
235 } 233 }
236 if ((rdc_reset_state(state)) < 0) { 234 if ((rdc_reset_state(state)) < 0) {
237 dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__); 235 dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
238 return -1; 236 return -1;
239 } 237 }
240 if (state->type_flags & DST_TYPE_HAS_FW_1) 238 if (state->type_flags & DST_TYPE_HAS_FW_1)
@@ -246,36 +244,33 @@ int dst_comm_init(struct dst_state* state)
246} 244}
247EXPORT_SYMBOL(dst_comm_init); 245EXPORT_SYMBOL(dst_comm_init);
248 246
249
250int write_dst(struct dst_state *state, u8 *data, u8 len) 247int write_dst(struct dst_state *state, u8 *data, u8 len)
251{ 248{
252 struct i2c_msg msg = { 249 struct i2c_msg msg = {
253 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len 250 .addr = state->config->demod_address,
251 .flags = 0,
252 .buf = data,
253 .len = len
254 }; 254 };
255 255
256 int err; 256 int err;
257 int cnt; 257 u8 cnt, i;
258 if (debug && (verbose > 4)) { 258
259 u8 i; 259 dprintk(verbose, DST_NOTICE, 0, "writing [ ");
260 if (verbose > 4) { 260 for (i = 0; i < len; i++)
261 dprintk("%s writing [ ", __FUNCTION__); 261 dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
262 for (i = 0; i < len; i++) 262 dprintk(verbose, DST_NOTICE, 0, "]\n");
263 dprintk("%02x ", data[i]); 263
264 dprintk("]\n");
265 }
266 }
267 for (cnt = 0; cnt < 2; cnt++) { 264 for (cnt = 0; cnt < 2; cnt++) {
268 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 265 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
269 dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); 266 dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
270 dst_error_recovery(state); 267 dst_error_recovery(state);
271 continue; 268 continue;
272 } else 269 } else
273 break; 270 break;
274 } 271 }
275
276 if (cnt >= 2) { 272 if (cnt >= 2) {
277 if (verbose > 1) 273 dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
278 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
279 dst_error_bailout(state); 274 dst_error_bailout(state);
280 275
281 return -1; 276 return -1;
@@ -285,36 +280,37 @@ int write_dst(struct dst_state *state, u8 *data, u8 len)
285} 280}
286EXPORT_SYMBOL(write_dst); 281EXPORT_SYMBOL(write_dst);
287 282
288int read_dst(struct dst_state *state, u8 * ret, u8 len) 283int read_dst(struct dst_state *state, u8 *ret, u8 len)
289{ 284{
290 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; 285 struct i2c_msg msg = {
286 .addr = state->config->demod_address,
287 .flags = I2C_M_RD,
288 .buf = ret,
289 .len = len
290 };
291
291 int err; 292 int err;
292 int cnt; 293 int cnt;
293 294
294 for (cnt = 0; cnt < 2; cnt++) { 295 for (cnt = 0; cnt < 2; cnt++) {
295 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { 296 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
296 297 dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
297 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
298 dst_error_recovery(state); 298 dst_error_recovery(state);
299
300 continue; 299 continue;
301 } else 300 } else
302 break; 301 break;
303 } 302 }
304 if (cnt >= 2) { 303 if (cnt >= 2) {
305 if (verbose > 1) 304 dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
306 printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
307 dst_error_bailout(state); 305 dst_error_bailout(state);
308 306
309 return -1; 307 return -1;
310 } 308 }
311 if (debug && (verbose > 4)) { 309 dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
312 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); 310 for (err = 1; err < len; err++)
313 for (err = 1; err < len; err++) 311 dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
314 dprintk(" 0x%x", ret[err]); 312 if (err > 1)
315 if (err > 1) 313 dprintk(verbose, DST_DEBUG, 0, "\n");
316 dprintk("\n");
317 }
318 314
319 return 0; 315 return 0;
320} 316}
@@ -323,19 +319,16 @@ EXPORT_SYMBOL(read_dst);
323static int dst_set_polarization(struct dst_state *state) 319static int dst_set_polarization(struct dst_state *state)
324{ 320{
325 switch (state->voltage) { 321 switch (state->voltage) {
326 case SEC_VOLTAGE_13: // vertical 322 case SEC_VOLTAGE_13: /* Vertical */
327 printk("%s: Polarization=[Vertical]\n", __FUNCTION__); 323 dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
328 state->tx_tuna[8] &= ~0x40; //1 324 state->tx_tuna[8] &= ~0x40;
329 break; 325 break;
330 326 case SEC_VOLTAGE_18: /* Horizontal */
331 case SEC_VOLTAGE_18: // horizontal 327 dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
332 printk("%s: Polarization=[Horizontal]\n", __FUNCTION__); 328 state->tx_tuna[8] |= 0x40;
333 state->tx_tuna[8] |= 0x40; // 0 329 break;
334 break; 330 case SEC_VOLTAGE_OFF:
335 331 break;
336 case SEC_VOLTAGE_OFF:
337
338 break;
339 } 332 }
340 333
341 return 0; 334 return 0;
@@ -344,14 +337,12 @@ static int dst_set_polarization(struct dst_state *state)
344static int dst_set_freq(struct dst_state *state, u32 freq) 337static int dst_set_freq(struct dst_state *state, u32 freq)
345{ 338{
346 state->frequency = freq; 339 state->frequency = freq;
347 if (debug > 4) 340 dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
348 dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
349 341
350 if (state->dst_type == DST_TYPE_IS_SAT) { 342 if (state->dst_type == DST_TYPE_IS_SAT) {
351 freq = freq / 1000; 343 freq = freq / 1000;
352 if (freq < 950 || freq > 2150) 344 if (freq < 950 || freq > 2150)
353 return -EINVAL; 345 return -EINVAL;
354
355 state->tx_tuna[2] = (freq >> 8); 346 state->tx_tuna[2] = (freq >> 8);
356 state->tx_tuna[3] = (u8) freq; 347 state->tx_tuna[3] = (u8) freq;
357 state->tx_tuna[4] = 0x01; 348 state->tx_tuna[4] = 0x01;
@@ -360,27 +351,25 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
360 if (freq < 1531) 351 if (freq < 1531)
361 state->tx_tuna[8] |= 0x04; 352 state->tx_tuna[8] |= 0x04;
362 } 353 }
363
364 } else if (state->dst_type == DST_TYPE_IS_TERR) { 354 } else if (state->dst_type == DST_TYPE_IS_TERR) {
365 freq = freq / 1000; 355 freq = freq / 1000;
366 if (freq < 137000 || freq > 858000) 356 if (freq < 137000 || freq > 858000)
367 return -EINVAL; 357 return -EINVAL;
368
369 state->tx_tuna[2] = (freq >> 16) & 0xff; 358 state->tx_tuna[2] = (freq >> 16) & 0xff;
370 state->tx_tuna[3] = (freq >> 8) & 0xff; 359 state->tx_tuna[3] = (freq >> 8) & 0xff;
371 state->tx_tuna[4] = (u8) freq; 360 state->tx_tuna[4] = (u8) freq;
372
373 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 361 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
362 freq = freq / 1000;
374 state->tx_tuna[2] = (freq >> 16) & 0xff; 363 state->tx_tuna[2] = (freq >> 16) & 0xff;
375 state->tx_tuna[3] = (freq >> 8) & 0xff; 364 state->tx_tuna[3] = (freq >> 8) & 0xff;
376 state->tx_tuna[4] = (u8) freq; 365 state->tx_tuna[4] = (u8) freq;
377
378 } else 366 } else
379 return -EINVAL; 367 return -EINVAL;
368
380 return 0; 369 return 0;
381} 370}
382 371
383static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth) 372static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
384{ 373{
385 state->bandwidth = bandwidth; 374 state->bandwidth = bandwidth;
386 375
@@ -388,103 +377,95 @@ static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
388 return 0; 377 return 0;
389 378
390 switch (bandwidth) { 379 switch (bandwidth) {
391 case BANDWIDTH_6_MHZ: 380 case BANDWIDTH_6_MHZ:
392 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 381 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
393 state->tx_tuna[7] = 0x06; 382 state->tx_tuna[7] = 0x06;
394 else { 383 else {
395 state->tx_tuna[6] = 0x06; 384 state->tx_tuna[6] = 0x06;
396 state->tx_tuna[7] = 0x00; 385 state->tx_tuna[7] = 0x00;
397 } 386 }
398 break; 387 break;
399 388 case BANDWIDTH_7_MHZ:
400 case BANDWIDTH_7_MHZ: 389 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
401 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 390 state->tx_tuna[7] = 0x07;
402 state->tx_tuna[7] = 0x07; 391 else {
403 else { 392 state->tx_tuna[6] = 0x07;
404 state->tx_tuna[6] = 0x07; 393 state->tx_tuna[7] = 0x00;
405 state->tx_tuna[7] = 0x00; 394 }
406 } 395 break;
407 break; 396 case BANDWIDTH_8_MHZ:
408 397 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
409 case BANDWIDTH_8_MHZ: 398 state->tx_tuna[7] = 0x08;
410 if (state->dst_hw_cap & DST_TYPE_HAS_CA) 399 else {
411 state->tx_tuna[7] = 0x08; 400 state->tx_tuna[6] = 0x08;
412 else { 401 state->tx_tuna[7] = 0x00;
413 state->tx_tuna[6] = 0x08; 402 }
414 state->tx_tuna[7] = 0x00; 403 break;
415 } 404 default:
416 break; 405 return -EINVAL;
417
418 default:
419 return -EINVAL;
420 } 406 }
407
421 return 0; 408 return 0;
422} 409}
423 410
424static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion) 411static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
425{ 412{
426 state->inversion = inversion; 413 state->inversion = inversion;
427 switch (inversion) { 414 switch (inversion) {
428 case INVERSION_OFF: // Inversion = Normal 415 case INVERSION_OFF: /* Inversion = Normal */
429 state->tx_tuna[8] &= ~0x80; 416 state->tx_tuna[8] &= ~0x80;
430 break; 417 break;
431 418 case INVERSION_ON:
432 case INVERSION_ON: 419 state->tx_tuna[8] |= 0x80;
433 state->tx_tuna[8] |= 0x80; 420 break;
434 break; 421 default:
435 default: 422 return -EINVAL;
436 return -EINVAL;
437 } 423 }
424
438 return 0; 425 return 0;
439} 426}
440 427
441static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec) 428static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
442{ 429{
443 state->fec = fec; 430 state->fec = fec;
444 return 0; 431 return 0;
445} 432}
446 433
447static fe_code_rate_t dst_get_fec(struct dst_state* state) 434static fe_code_rate_t dst_get_fec(struct dst_state *state)
448{ 435{
449 return state->fec; 436 return state->fec;
450} 437}
451 438
452static int dst_set_symbolrate(struct dst_state* state, u32 srate) 439static int dst_set_symbolrate(struct dst_state *state, u32 srate)
453{ 440{
454 u8 *val;
455 u32 symcalc; 441 u32 symcalc;
456 u64 sval; 442 u64 sval;
457 443
458 state->symbol_rate = srate; 444 state->symbol_rate = srate;
459
460 if (state->dst_type == DST_TYPE_IS_TERR) { 445 if (state->dst_type == DST_TYPE_IS_TERR) {
461 return 0; 446 return 0;
462 } 447 }
463 if (debug > 4) 448 dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
464 dprintk("%s: set symrate %u\n", __FUNCTION__, srate);
465 srate /= 1000; 449 srate /= 1000;
466 val = &state->tx_tuna[0];
467
468 if (state->type_flags & DST_TYPE_HAS_SYMDIV) { 450 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
469 sval = srate; 451 sval = srate;
470 sval <<= 20; 452 sval <<= 20;
471 do_div(sval, 88000); 453 do_div(sval, 88000);
472 symcalc = (u32) sval; 454 symcalc = (u32) sval;
473 455 dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
474 if (debug > 4) 456 state->tx_tuna[5] = (u8) (symcalc >> 12);
475 dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc); 457 state->tx_tuna[6] = (u8) (symcalc >> 4);
476 458 state->tx_tuna[7] = (u8) (symcalc << 4);
477 val[5] = (u8) (symcalc >> 12);
478 val[6] = (u8) (symcalc >> 4);
479 val[7] = (u8) (symcalc << 4);
480 } else { 459 } else {
481 val[5] = (u8) (srate >> 16) & 0x7f; 460 state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
482 val[6] = (u8) (srate >> 8); 461 state->tx_tuna[6] = (u8) (srate >> 8);
483 val[7] = (u8) srate; 462 state->tx_tuna[7] = (u8) srate;
463 }
464 state->tx_tuna[8] &= ~0x20;
465 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
466 if (srate > 8000)
467 state->tx_tuna[8] |= 0x20;
484 } 468 }
485 val[8] &= ~0x20;
486 if (srate > 8000)
487 val[8] |= 0x20;
488 return 0; 469 return 0;
489} 470}
490 471
@@ -496,32 +477,27 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio
496 477
497 state->modulation = modulation; 478 state->modulation = modulation;
498 switch (modulation) { 479 switch (modulation) {
499 case QAM_16: 480 case QAM_16:
500 state->tx_tuna[8] = 0x10; 481 state->tx_tuna[8] = 0x10;
501 break; 482 break;
502 483 case QAM_32:
503 case QAM_32: 484 state->tx_tuna[8] = 0x20;
504 state->tx_tuna[8] = 0x20; 485 break;
505 break; 486 case QAM_64:
506 487 state->tx_tuna[8] = 0x40;
507 case QAM_64: 488 break;
508 state->tx_tuna[8] = 0x40; 489 case QAM_128:
509 break; 490 state->tx_tuna[8] = 0x80;
510 491 break;
511 case QAM_128: 492 case QAM_256:
512 state->tx_tuna[8] = 0x80; 493 state->tx_tuna[8] = 0x00;
513 break; 494 break;
514 495 case QPSK:
515 case QAM_256: 496 case QAM_AUTO:
516 state->tx_tuna[8] = 0x00; 497 case VSB_8:
517 break; 498 case VSB_16:
518 499 default:
519 case QPSK: 500 return -EINVAL;
520 case QAM_AUTO:
521 case VSB_8:
522 case VSB_16:
523 default:
524 return -EINVAL;
525 501
526 } 502 }
527 503
@@ -534,7 +510,7 @@ static fe_modulation_t dst_get_modulation(struct dst_state *state)
534} 510}
535 511
536 512
537u8 dst_check_sum(u8 * buf, u32 len) 513u8 dst_check_sum(u8 *buf, u32 len)
538{ 514{
539 u32 i; 515 u32 i;
540 u8 val = 0; 516 u8 val = 0;
@@ -549,26 +525,24 @@ EXPORT_SYMBOL(dst_check_sum);
549 525
550static void dst_type_flags_print(u32 type_flags) 526static void dst_type_flags_print(u32 type_flags)
551{ 527{
552 printk("DST type flags :"); 528 dprintk(verbose, DST_ERROR, 0, "DST type flags :");
553 if (type_flags & DST_TYPE_HAS_NEWTUNE) 529 if (type_flags & DST_TYPE_HAS_NEWTUNE)
554 printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); 530 dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
555 if (type_flags & DST_TYPE_HAS_TS204) 531 if (type_flags & DST_TYPE_HAS_TS204)
556 printk(" 0x%x ts204", DST_TYPE_HAS_TS204); 532 dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
557 if (type_flags & DST_TYPE_HAS_SYMDIV) 533 if (type_flags & DST_TYPE_HAS_SYMDIV)
558 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); 534 dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
559 if (type_flags & DST_TYPE_HAS_FW_1) 535 if (type_flags & DST_TYPE_HAS_FW_1)
560 printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); 536 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
561 if (type_flags & DST_TYPE_HAS_FW_2) 537 if (type_flags & DST_TYPE_HAS_FW_2)
562 printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); 538 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
563 if (type_flags & DST_TYPE_HAS_FW_3) 539 if (type_flags & DST_TYPE_HAS_FW_3)
564 printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); 540 dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
565// if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw) 541 dprintk(verbose, DST_ERROR, 0, "\n");
566
567 printk("\n");
568} 542}
569 543
570 544
571static int dst_type_print (u8 type) 545static int dst_type_print(u8 type)
572{ 546{
573 char *otype; 547 char *otype;
574 switch (type) { 548 switch (type) {
@@ -585,10 +559,10 @@ static int dst_type_print (u8 type)
585 break; 559 break;
586 560
587 default: 561 default:
588 printk("%s: invalid dst type %d\n", __FUNCTION__, type); 562 dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
589 return -EINVAL; 563 return -EINVAL;
590 } 564 }
591 printk("DST type : %s\n", otype); 565 dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
592 566
593 return 0; 567 return 0;
594} 568}
@@ -700,7 +674,7 @@ struct dst_types dst_tlist[] = {
700 .offset = 1, 674 .offset = 1,
701 .dst_type = DST_TYPE_IS_CABLE, 675 .dst_type = DST_TYPE_IS_CABLE,
702 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 676 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1
703 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, 677 | DST_TYPE_HAS_FW_2,
704 .dst_feature = DST_TYPE_HAS_CA 678 .dst_feature = DST_TYPE_HAS_CA
705 }, 679 },
706 680
@@ -708,7 +682,7 @@ struct dst_types dst_tlist[] = {
708 .device_id = "DCTNEW", 682 .device_id = "DCTNEW",
709 .offset = 1, 683 .offset = 1,
710 .dst_type = DST_TYPE_IS_CABLE, 684 .dst_type = DST_TYPE_IS_CABLE,
711 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3, 685 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD,
712 .dst_feature = 0 686 .dst_feature = 0
713 }, 687 },
714 688
@@ -716,7 +690,7 @@ struct dst_types dst_tlist[] = {
716 .device_id = "DTT-CI", 690 .device_id = "DTT-CI",
717 .offset = 1, 691 .offset = 1,
718 .dst_type = DST_TYPE_IS_TERR, 692 .dst_type = DST_TYPE_IS_TERR,
719 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, 693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
720 .dst_feature = 0 694 .dst_feature = 0
721 }, 695 },
722 696
@@ -756,6 +730,71 @@ struct dst_types dst_tlist[] = {
756 730
757}; 731};
758 732
733static int dst_get_mac(struct dst_state *state)
734{
735 u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
736 get_mac[7] = dst_check_sum(get_mac, 7);
737 if (dst_command(state, get_mac, 8) < 0) {
738 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
739 return -1;
740 }
741 memset(&state->mac_address, '\0', 8);
742 memcpy(&state->mac_address, &state->rxbuffer, 6);
743 dprintk(verbose, DST_ERROR, 1, "MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
744 state->mac_address[0], state->mac_address[1], state->mac_address[2],
745 state->mac_address[4], state->mac_address[5], state->mac_address[6]);
746
747 return 0;
748}
749
750static int dst_fw_ver(struct dst_state *state)
751{
752 u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
753 get_ver[7] = dst_check_sum(get_ver, 7);
754 if (dst_command(state, get_ver, 8) < 0) {
755 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
756 return -1;
757 }
758 memset(&state->fw_version, '\0', 8);
759 memcpy(&state->fw_version, &state->rxbuffer, 8);
760 dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
761 state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
762 state->fw_version[1],
763 state->fw_version[5], state->fw_version[6],
764 state->fw_version[4], state->fw_version[3], state->fw_version[2]);
765
766 return 0;
767}
768
769static int dst_card_type(struct dst_state *state)
770{
771 u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
772 get_type[7] = dst_check_sum(get_type, 7);
773 if (dst_command(state, get_type, 8) < 0) {
774 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
775 return -1;
776 }
777 memset(&state->card_info, '\0', 8);
778 memcpy(&state->card_info, &state->rxbuffer, 8);
779 dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
780
781 return 0;
782}
783
784static int dst_get_vendor(struct dst_state *state)
785{
786 u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
787 get_vendor[7] = dst_check_sum(get_vendor, 7);
788 if (dst_command(state, get_vendor, 8) < 0) {
789 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
790 return -1;
791 }
792 memset(&state->vendor, '\0', 8);
793 memcpy(&state->vendor, &state->rxbuffer, 8);
794 dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
795
796 return 0;
797}
759 798
760static int dst_get_device_id(struct dst_state *state) 799static int dst_get_device_id(struct dst_state *state)
761{ 800{
@@ -772,53 +811,45 @@ static int dst_get_device_id(struct dst_state *state)
772 811
773 if (write_dst(state, device_type, FIXED_COMM)) 812 if (write_dst(state, device_type, FIXED_COMM))
774 return -1; /* Write failed */ 813 return -1; /* Write failed */
775
776 if ((dst_pio_disable(state)) < 0) 814 if ((dst_pio_disable(state)) < 0)
777 return -1; 815 return -1;
778
779 if (read_dst(state, &reply, GET_ACK)) 816 if (read_dst(state, &reply, GET_ACK))
780 return -1; /* Read failure */ 817 return -1; /* Read failure */
781
782 if (reply != ACK) { 818 if (reply != ACK) {
783 dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply); 819 dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
784 return -1; /* Unack'd write */ 820 return -1; /* Unack'd write */
785 } 821 }
786
787 if (!dst_wait_dst_ready(state, DEVICE_INIT)) 822 if (!dst_wait_dst_ready(state, DEVICE_INIT))
788 return -1; /* DST not ready yet */ 823 return -1; /* DST not ready yet */
789
790 if (read_dst(state, state->rxbuffer, FIXED_COMM)) 824 if (read_dst(state, state->rxbuffer, FIXED_COMM))
791 return -1; 825 return -1;
792 826
793 dst_pio_disable(state); 827 dst_pio_disable(state);
794
795 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 828 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
796 dprintk("%s: Checksum failure! \n", __FUNCTION__); 829 dprintk(verbose, DST_INFO, 1, "Checksum failure!");
797 return -1; /* Checksum failure */ 830 return -1; /* Checksum failure */
798 } 831 }
799
800 state->rxbuffer[7] = '\0'; 832 state->rxbuffer[7] = '\0';
801 833
802 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) { 834 for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
803 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { 835 if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
804 use_type_flags = p_dst_type->type_flags; 836 use_type_flags = p_dst_type->type_flags;
805 use_dst_type = p_dst_type->dst_type; 837 use_dst_type = p_dst_type->dst_type;
806 838
807 /* Card capabilities */ 839 /* Card capabilities */
808 state->dst_hw_cap = p_dst_type->dst_feature; 840 state->dst_hw_cap = p_dst_type->dst_feature;
809 printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id); 841 dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id);
810 842
811 break; 843 break;
812 } 844 }
813 } 845 }
814 846
815 if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) { 847 if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
816 printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]); 848 dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
817 printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); 849 dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
818 use_dst_type = DST_TYPE_IS_SAT; 850 use_dst_type = DST_TYPE_IS_SAT;
819 use_type_flags = DST_TYPE_HAS_SYMDIV; 851 use_type_flags = DST_TYPE_HAS_SYMDIV;
820 } 852 }
821
822 dst_type_print(use_dst_type); 853 dst_type_print(use_dst_type);
823 state->type_flags = use_type_flags; 854 state->type_flags = use_type_flags;
824 state->dst_type = use_dst_type; 855 state->dst_type = use_dst_type;
@@ -834,7 +865,7 @@ static int dst_get_device_id(struct dst_state *state)
834static int dst_probe(struct dst_state *state) 865static int dst_probe(struct dst_state *state)
835{ 866{
836 if ((rdc_8820_reset(state)) < 0) { 867 if ((rdc_8820_reset(state)) < 0) {
837 dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__); 868 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
838 return -1; 869 return -1;
839 } 870 }
840 if (dst_addons & DST_TYPE_HAS_CA) 871 if (dst_addons & DST_TYPE_HAS_CA)
@@ -843,80 +874,87 @@ static int dst_probe(struct dst_state *state)
843 msleep(100); 874 msleep(100);
844 875
845 if ((dst_comm_init(state)) < 0) { 876 if ((dst_comm_init(state)) < 0) {
846 dprintk("%s: DST Initialization Failed.\n", __FUNCTION__); 877 dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
847 return -1; 878 return -1;
848 } 879 }
849 msleep(100); 880 msleep(100);
850 if (dst_get_device_id(state) < 0) { 881 if (dst_get_device_id(state) < 0) {
851 dprintk("%s: unknown device.\n", __FUNCTION__); 882 dprintk(verbose, DST_ERROR, 1, "unknown device.");
852 return -1; 883 return -1;
853 } 884 }
885 if (dst_get_mac(state) < 0) {
886 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
887 return 0;
888 }
889 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
890 if (dst_fw_ver(state) < 0) {
891 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
892 return 0;
893 }
894 if (dst_card_type(state) < 0) {
895 dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
896 return 0;
897 }
898 if (dst_get_vendor(state) < 0) {
899 dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
900 return 0;
901 }
902 }
854 903
855 return 0; 904 return 0;
856} 905}
857 906
858int dst_command(struct dst_state* state, u8 * data, u8 len) 907int dst_command(struct dst_state *state, u8 *data, u8 len)
859{ 908{
860 u8 reply; 909 u8 reply;
861 if ((dst_comm_init(state)) < 0) { 910 if ((dst_comm_init(state)) < 0) {
862 dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__); 911 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
863 return -1; 912 return -1;
864 } 913 }
865
866 if (write_dst(state, data, len)) { 914 if (write_dst(state, data, len)) {
867 if (verbose > 1) 915 dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
868 dprintk("%s: Tring to recover.. \n", __FUNCTION__);
869 if ((dst_error_recovery(state)) < 0) { 916 if ((dst_error_recovery(state)) < 0) {
870 dprintk("%s: Recovery Failed.\n", __FUNCTION__); 917 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
871 return -1; 918 return -1;
872 } 919 }
873 return -1; 920 return -1;
874 } 921 }
875 if ((dst_pio_disable(state)) < 0) { 922 if ((dst_pio_disable(state)) < 0) {
876 dprintk("%s: PIO Disable Failed.\n", __FUNCTION__); 923 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
877 return -1; 924 return -1;
878 } 925 }
879 if (state->type_flags & DST_TYPE_HAS_FW_1) 926 if (state->type_flags & DST_TYPE_HAS_FW_1)
880 udelay(3000); 927 udelay(3000);
881
882 if (read_dst(state, &reply, GET_ACK)) { 928 if (read_dst(state, &reply, GET_ACK)) {
883 if (verbose > 1) 929 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
884 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
885 if ((dst_error_recovery(state)) < 0) { 930 if ((dst_error_recovery(state)) < 0) {
886 dprintk("%s: Recovery Failed.\n", __FUNCTION__); 931 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
887 return -1; 932 return -1;
888 } 933 }
889 return -1; 934 return -1;
890 } 935 }
891
892 if (reply != ACK) { 936 if (reply != ACK) {
893 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); 937 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
894 return -1; 938 return -1;
895 } 939 }
896 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 940 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
897 return 0; 941 return 0;
898
899// udelay(3000);
900 if (state->type_flags & DST_TYPE_HAS_FW_1) 942 if (state->type_flags & DST_TYPE_HAS_FW_1)
901 udelay(3000); 943 udelay(3000);
902 else 944 else
903 udelay(2000); 945 udelay(2000);
904
905 if (!dst_wait_dst_ready(state, NO_DELAY)) 946 if (!dst_wait_dst_ready(state, NO_DELAY))
906 return -1; 947 return -1;
907
908 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 948 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
909 if (verbose > 1) 949 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
910 dprintk("%s: Trying to recover.. \n", __FUNCTION__);
911 if ((dst_error_recovery(state)) < 0) { 950 if ((dst_error_recovery(state)) < 0) {
912 dprintk("%s: Recovery failed.\n", __FUNCTION__); 951 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
913 return -1; 952 return -1;
914 } 953 }
915 return -1; 954 return -1;
916 } 955 }
917
918 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 956 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
919 dprintk("%s: checksum failure\n", __FUNCTION__); 957 dprintk(verbose, DST_INFO, 1, "checksum failure");
920 return -1; 958 return -1;
921 } 959 }
922 960
@@ -924,11 +962,11 @@ int dst_command(struct dst_state* state, u8 * data, u8 len)
924} 962}
925EXPORT_SYMBOL(dst_command); 963EXPORT_SYMBOL(dst_command);
926 964
927static int dst_get_signal(struct dst_state* state) 965static int dst_get_signal(struct dst_state *state)
928{ 966{
929 int retval; 967 int retval;
930 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; 968 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
931 dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__); 969 //dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
932 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { 970 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
933 state->decode_lock = state->decode_strength = state->decode_snr = 0; 971 state->decode_lock = state->decode_strength = state->decode_snr = 0;
934 return 0; 972 return 0;
@@ -955,13 +993,12 @@ static int dst_get_signal(struct dst_state* state)
955 return 0; 993 return 0;
956} 994}
957 995
958static int dst_tone_power_cmd(struct dst_state* state) 996static int dst_tone_power_cmd(struct dst_state *state)
959{ 997{
960 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 }; 998 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
961 999
962 if (state->dst_type == DST_TYPE_IS_TERR) 1000 if (state->dst_type == DST_TYPE_IS_TERR)
963 return 0; 1001 return 0;
964
965 paket[4] = state->tx_tuna[4]; 1002 paket[4] = state->tx_tuna[4];
966 paket[2] = state->tx_tuna[2]; 1003 paket[2] = state->tx_tuna[2];
967 paket[3] = state->tx_tuna[3]; 1004 paket[3] = state->tx_tuna[3];
@@ -971,61 +1008,53 @@ static int dst_tone_power_cmd(struct dst_state* state)
971 return 0; 1008 return 0;
972} 1009}
973 1010
974static int dst_get_tuna(struct dst_state* state) 1011static int dst_get_tuna(struct dst_state *state)
975{ 1012{
976 int retval; 1013 int retval;
977 1014
978 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) 1015 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
979 return 0; 1016 return 0;
980
981 state->diseq_flags &= ~(HAS_LOCK); 1017 state->diseq_flags &= ~(HAS_LOCK);
982 if (!dst_wait_dst_ready(state, NO_DELAY)) 1018 if (!dst_wait_dst_ready(state, NO_DELAY))
983 return 0; 1019 return 0;
984 1020 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
985 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
986 /* how to get variable length reply ???? */ 1021 /* how to get variable length reply ???? */
987 retval = read_dst(state, state->rx_tuna, 10); 1022 retval = read_dst(state, state->rx_tuna, 10);
988 } else { 1023 else
989 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1024 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
990 }
991
992 if (retval < 0) { 1025 if (retval < 0) {
993 dprintk("%s: read not successful\n", __FUNCTION__); 1026 dprintk(verbose, DST_DEBUG, 1, "read not successful");
994 return 0; 1027 return 0;
995 } 1028 }
996
997 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1029 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
998 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1030 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
999 dprintk("%s: checksum failure?\n", __FUNCTION__); 1031 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1000 return 0; 1032 return 0;
1001 } 1033 }
1002 } else { 1034 } else {
1003 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1035 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1004 dprintk("%s: checksum failure?\n", __FUNCTION__); 1036 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1005 return 0; 1037 return 0;
1006 } 1038 }
1007 } 1039 }
1008 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1040 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1009 return 0; 1041 return 0;
1010 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1042 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1011
1012 state->decode_lock = 1; 1043 state->decode_lock = 1;
1013 state->diseq_flags |= HAS_LOCK; 1044 state->diseq_flags |= HAS_LOCK;
1014 1045
1015 return 1; 1046 return 1;
1016} 1047}
1017 1048
1018static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage); 1049static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
1019 1050
1020static int dst_write_tuna(struct dvb_frontend* fe) 1051static int dst_write_tuna(struct dvb_frontend *fe)
1021{ 1052{
1022 struct dst_state* state = fe->demodulator_priv; 1053 struct dst_state *state = fe->demodulator_priv;
1023 int retval; 1054 int retval;
1024 u8 reply; 1055 u8 reply;
1025 1056
1026 if (debug > 4) 1057 dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
1027 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
1028
1029 state->decode_freq = 0; 1058 state->decode_freq = 0;
1030 state->decode_lock = state->decode_strength = state->decode_snr = 0; 1059 state->decode_lock = state->decode_strength = state->decode_snr = 0;
1031 if (state->dst_type == DST_TYPE_IS_SAT) { 1060 if (state->dst_type == DST_TYPE_IS_SAT) {
@@ -1035,35 +1064,31 @@ static int dst_write_tuna(struct dvb_frontend* fe)
1035 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1064 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1036 1065
1037 if ((dst_comm_init(state)) < 0) { 1066 if ((dst_comm_init(state)) < 0) {
1038 dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__); 1067 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1039 return -1; 1068 return -1;
1040 } 1069 }
1041
1042 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1070 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1043 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1071 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
1044 retval = write_dst(state, &state->tx_tuna[0], 10); 1072 retval = write_dst(state, &state->tx_tuna[0], 10);
1045
1046 } else { 1073 } else {
1047 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); 1074 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
1048 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); 1075 retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
1049 } 1076 }
1050 if (retval < 0) { 1077 if (retval < 0) {
1051 dst_pio_disable(state); 1078 dst_pio_disable(state);
1052 dprintk("%s: write not successful\n", __FUNCTION__); 1079 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1053 return retval; 1080 return retval;
1054 } 1081 }
1055
1056 if ((dst_pio_disable(state)) < 0) { 1082 if ((dst_pio_disable(state)) < 0) {
1057 dprintk("%s: DST PIO disable failed !\n", __FUNCTION__); 1083 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1058 return -1; 1084 return -1;
1059 } 1085 }
1060
1061 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1086 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1062 dprintk("%s: read verify not successful.\n", __FUNCTION__); 1087 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1063 return -1; 1088 return -1;
1064 } 1089 }
1065 if (reply != ACK) { 1090 if (reply != ACK) {
1066 dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); 1091 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1067 return 0; 1092 return 0;
1068 } 1093 }
1069 state->diseq_flags |= ATTEMPT_TUNE; 1094 state->diseq_flags |= ATTEMPT_TUNE;
@@ -1085,14 +1110,13 @@ static int dst_write_tuna(struct dvb_frontend* fe)
1085 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0 1110 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
1086 */ 1111 */
1087 1112
1088static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) 1113static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
1089{ 1114{
1090 struct dst_state* state = fe->demodulator_priv; 1115 struct dst_state *state = fe->demodulator_priv;
1091 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; 1116 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
1092 1117
1093 if (state->dst_type != DST_TYPE_IS_SAT) 1118 if (state->dst_type != DST_TYPE_IS_SAT)
1094 return 0; 1119 return 0;
1095
1096 if (cmd->msg_len == 0 || cmd->msg_len > 4) 1120 if (cmd->msg_len == 0 || cmd->msg_len > 4)
1097 return -EINVAL; 1121 return -EINVAL;
1098 memcpy(&paket[3], cmd->msg, cmd->msg_len); 1122 memcpy(&paket[3], cmd->msg, cmd->msg_len);
@@ -1101,65 +1125,61 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd*
1101 return 0; 1125 return 0;
1102} 1126}
1103 1127
1104static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) 1128static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
1105{ 1129{
1106 int need_cmd; 1130 int need_cmd;
1107 struct dst_state* state = fe->demodulator_priv; 1131 struct dst_state *state = fe->demodulator_priv;
1108 1132
1109 state->voltage = voltage; 1133 state->voltage = voltage;
1110
1111 if (state->dst_type != DST_TYPE_IS_SAT) 1134 if (state->dst_type != DST_TYPE_IS_SAT)
1112 return 0; 1135 return 0;
1113 1136
1114 need_cmd = 0; 1137 need_cmd = 0;
1115 switch (voltage) {
1116 case SEC_VOLTAGE_13:
1117 case SEC_VOLTAGE_18:
1118 if ((state->diseq_flags & HAS_POWER) == 0)
1119 need_cmd = 1;
1120 state->diseq_flags |= HAS_POWER;
1121 state->tx_tuna[4] = 0x01;
1122 break;
1123 1138
1124 case SEC_VOLTAGE_OFF: 1139 switch (voltage) {
1140 case SEC_VOLTAGE_13:
1141 case SEC_VOLTAGE_18:
1142 if ((state->diseq_flags & HAS_POWER) == 0)
1125 need_cmd = 1; 1143 need_cmd = 1;
1126 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); 1144 state->diseq_flags |= HAS_POWER;
1127 state->tx_tuna[4] = 0x00; 1145 state->tx_tuna[4] = 0x01;
1128 break; 1146 break;
1129 1147 case SEC_VOLTAGE_OFF:
1130 default: 1148 need_cmd = 1;
1131 return -EINVAL; 1149 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
1150 state->tx_tuna[4] = 0x00;
1151 break;
1152 default:
1153 return -EINVAL;
1132 } 1154 }
1155
1133 if (need_cmd) 1156 if (need_cmd)
1134 dst_tone_power_cmd(state); 1157 dst_tone_power_cmd(state);
1135 1158
1136 return 0; 1159 return 0;
1137} 1160}
1138 1161
1139static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 1162static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1140{ 1163{
1141 struct dst_state* state = fe->demodulator_priv; 1164 struct dst_state *state = fe->demodulator_priv;
1142 1165
1143 state->tone = tone; 1166 state->tone = tone;
1144
1145 if (state->dst_type != DST_TYPE_IS_SAT) 1167 if (state->dst_type != DST_TYPE_IS_SAT)
1146 return 0; 1168 return 0;
1147 1169
1148 switch (tone) { 1170 switch (tone) {
1149 case SEC_TONE_OFF: 1171 case SEC_TONE_OFF:
1150 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1172 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1151 state->tx_tuna[2] = 0x00; 1173 state->tx_tuna[2] = 0x00;
1152 else 1174 else
1153 state->tx_tuna[2] = 0xff; 1175 state->tx_tuna[2] = 0xff;
1154 1176 break;
1155 break;
1156
1157 case SEC_TONE_ON:
1158 state->tx_tuna[2] = 0x02;
1159 break;
1160 1177
1161 default: 1178 case SEC_TONE_ON:
1162 return -EINVAL; 1179 state->tx_tuna[2] = 0x02;
1180 break;
1181 default:
1182 return -EINVAL;
1163 } 1183 }
1164 dst_tone_power_cmd(state); 1184 dst_tone_power_cmd(state);
1165 1185
@@ -1172,16 +1192,14 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
1172 1192
1173 if (state->dst_type != DST_TYPE_IS_SAT) 1193 if (state->dst_type != DST_TYPE_IS_SAT)
1174 return 0; 1194 return 0;
1175
1176 state->minicmd = minicmd; 1195 state->minicmd = minicmd;
1177
1178 switch (minicmd) { 1196 switch (minicmd) {
1179 case SEC_MINI_A: 1197 case SEC_MINI_A:
1180 state->tx_tuna[3] = 0x02; 1198 state->tx_tuna[3] = 0x02;
1181 break; 1199 break;
1182 case SEC_MINI_B: 1200 case SEC_MINI_B:
1183 state->tx_tuna[3] = 0xff; 1201 state->tx_tuna[3] = 0xff;
1184 break; 1202 break;
1185 } 1203 }
1186 dst_tone_power_cmd(state); 1204 dst_tone_power_cmd(state);
1187 1205
@@ -1189,42 +1207,37 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
1189} 1207}
1190 1208
1191 1209
1192static int dst_init(struct dvb_frontend* fe) 1210static int dst_init(struct dvb_frontend *fe)
1193{ 1211{
1194 struct dst_state* state = fe->demodulator_priv; 1212 struct dst_state *state = fe->demodulator_priv;
1195 static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; 1213
1196 static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; 1214 static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
1197 static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1215 static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
1198 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1216 static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1199 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1217 static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1200 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1218 static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1201// state->inversion = INVERSION_ON; 1219 static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
1220
1202 state->inversion = INVERSION_OFF; 1221 state->inversion = INVERSION_OFF;
1203 state->voltage = SEC_VOLTAGE_13; 1222 state->voltage = SEC_VOLTAGE_13;
1204 state->tone = SEC_TONE_OFF; 1223 state->tone = SEC_TONE_OFF;
1205 state->symbol_rate = 29473000;
1206 state->fec = FEC_AUTO;
1207 state->diseq_flags = 0; 1224 state->diseq_flags = 0;
1208 state->k22 = 0x02; 1225 state->k22 = 0x02;
1209 state->bandwidth = BANDWIDTH_7_MHZ; 1226 state->bandwidth = BANDWIDTH_7_MHZ;
1210 state->cur_jiff = jiffies; 1227 state->cur_jiff = jiffies;
1211 if (state->dst_type == DST_TYPE_IS_SAT) { 1228 if (state->dst_type == DST_TYPE_IS_SAT)
1212 state->frequency = 950000; 1229 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
1213 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna)); 1230 else if (state->dst_type == DST_TYPE_IS_TERR)
1214 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1231 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
1215 state->frequency = 137000000; 1232 else if (state->dst_type == DST_TYPE_IS_CABLE)
1216 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna)); 1233 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
1217 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1218 state->frequency = 51000000;
1219 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
1220 }
1221 1234
1222 return 0; 1235 return 0;
1223} 1236}
1224 1237
1225static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) 1238static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
1226{ 1239{
1227 struct dst_state* state = fe->demodulator_priv; 1240 struct dst_state *state = fe->demodulator_priv;
1228 1241
1229 *status = 0; 1242 *status = 0;
1230 if (state->diseq_flags & HAS_LOCK) { 1243 if (state->diseq_flags & HAS_LOCK) {
@@ -1236,9 +1249,9 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
1236 return 0; 1249 return 0;
1237} 1250}
1238 1251
1239static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) 1252static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1240{ 1253{
1241 struct dst_state* state = fe->demodulator_priv; 1254 struct dst_state *state = fe->demodulator_priv;
1242 1255
1243 dst_get_signal(state); 1256 dst_get_signal(state);
1244 *strength = state->decode_strength; 1257 *strength = state->decode_strength;
@@ -1246,9 +1259,9 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
1246 return 0; 1259 return 0;
1247} 1260}
1248 1261
1249static int dst_read_snr(struct dvb_frontend* fe, u16* snr) 1262static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
1250{ 1263{
1251 struct dst_state* state = fe->demodulator_priv; 1264 struct dst_state *state = fe->demodulator_priv;
1252 1265
1253 dst_get_signal(state); 1266 dst_get_signal(state);
1254 *snr = state->decode_snr; 1267 *snr = state->decode_snr;
@@ -1256,28 +1269,24 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
1256 return 0; 1269 return 0;
1257} 1270}
1258 1271
1259static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 1272static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1260{ 1273{
1261 struct dst_state* state = fe->demodulator_priv; 1274 struct dst_state *state = fe->demodulator_priv;
1262 1275
1263 dst_set_freq(state, p->frequency); 1276 dst_set_freq(state, p->frequency);
1264 if (verbose > 4) 1277 dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
1265 dprintk("Set Frequency=[%d]\n", p->frequency);
1266 1278
1267// dst_set_inversion(state, p->inversion);
1268 if (state->dst_type == DST_TYPE_IS_SAT) { 1279 if (state->dst_type == DST_TYPE_IS_SAT) {
1269 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1280 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1270 dst_set_inversion(state, p->inversion); 1281 dst_set_inversion(state, p->inversion);
1271
1272 dst_set_fec(state, p->u.qpsk.fec_inner); 1282 dst_set_fec(state, p->u.qpsk.fec_inner);
1273 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1283 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1274 dst_set_polarization(state); 1284 dst_set_polarization(state);
1275 if (verbose > 4) 1285 dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
1276 dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
1277 1286
1278 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1287 } else if (state->dst_type == DST_TYPE_IS_TERR)
1279 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1288 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1280 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1289 else if (state->dst_type == DST_TYPE_IS_CABLE) {
1281 dst_set_fec(state, p->u.qam.fec_inner); 1290 dst_set_fec(state, p->u.qam.fec_inner);
1282 dst_set_symbolrate(state, p->u.qam.symbol_rate); 1291 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1283 dst_set_modulation(state, p->u.qam.modulation); 1292 dst_set_modulation(state, p->u.qam.modulation);
@@ -1287,16 +1296,14 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
1287 return 0; 1296 return 0;
1288} 1297}
1289 1298
1290static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 1299static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1291{ 1300{
1292 struct dst_state* state = fe->demodulator_priv; 1301 struct dst_state *state = fe->demodulator_priv;
1293 1302
1294 p->frequency = state->decode_freq; 1303 p->frequency = state->decode_freq;
1295// p->inversion = state->inversion;
1296 if (state->dst_type == DST_TYPE_IS_SAT) { 1304 if (state->dst_type == DST_TYPE_IS_SAT) {
1297 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) 1305 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1298 p->inversion = state->inversion; 1306 p->inversion = state->inversion;
1299
1300 p->u.qpsk.symbol_rate = state->symbol_rate; 1307 p->u.qpsk.symbol_rate = state->symbol_rate;
1301 p->u.qpsk.fec_inner = dst_get_fec(state); 1308 p->u.qpsk.fec_inner = dst_get_fec(state);
1302 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1309 } else if (state->dst_type == DST_TYPE_IS_TERR) {
@@ -1304,16 +1311,15 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
1304 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1311 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1305 p->u.qam.symbol_rate = state->symbol_rate; 1312 p->u.qam.symbol_rate = state->symbol_rate;
1306 p->u.qam.fec_inner = dst_get_fec(state); 1313 p->u.qam.fec_inner = dst_get_fec(state);
1307// p->u.qam.modulation = QAM_AUTO;
1308 p->u.qam.modulation = dst_get_modulation(state); 1314 p->u.qam.modulation = dst_get_modulation(state);
1309 } 1315 }
1310 1316
1311 return 0; 1317 return 0;
1312} 1318}
1313 1319
1314static void dst_release(struct dvb_frontend* fe) 1320static void dst_release(struct dvb_frontend *fe)
1315{ 1321{
1316 struct dst_state* state = fe->demodulator_priv; 1322 struct dst_state *state = fe->demodulator_priv;
1317 kfree(state); 1323 kfree(state);
1318} 1324}
1319 1325
@@ -1321,9 +1327,8 @@ static struct dvb_frontend_ops dst_dvbt_ops;
1321static struct dvb_frontend_ops dst_dvbs_ops; 1327static struct dvb_frontend_ops dst_dvbs_ops;
1322static struct dvb_frontend_ops dst_dvbc_ops; 1328static struct dvb_frontend_ops dst_dvbc_ops;
1323 1329
1324struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) 1330struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
1325{ 1331{
1326
1327 /* check if the ASIC is there */ 1332 /* check if the ASIC is there */
1328 if (dst_probe(state) < 0) { 1333 if (dst_probe(state) < 0) {
1329 if (state) 1334 if (state)
@@ -1336,17 +1341,14 @@ struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
1336 case DST_TYPE_IS_TERR: 1341 case DST_TYPE_IS_TERR:
1337 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); 1342 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
1338 break; 1343 break;
1339
1340 case DST_TYPE_IS_CABLE: 1344 case DST_TYPE_IS_CABLE:
1341 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); 1345 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
1342 break; 1346 break;
1343
1344 case DST_TYPE_IS_SAT: 1347 case DST_TYPE_IS_SAT:
1345 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); 1348 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
1346 break; 1349 break;
1347
1348 default: 1350 default:
1349 printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__); 1351 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1350 if (state) 1352 if (state)
1351 kfree(state); 1353 kfree(state);
1352 1354
@@ -1374,12 +1376,9 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
1374 }, 1376 },
1375 1377
1376 .release = dst_release, 1378 .release = dst_release,
1377
1378 .init = dst_init, 1379 .init = dst_init,
1379
1380 .set_frontend = dst_set_frontend, 1380 .set_frontend = dst_set_frontend,
1381 .get_frontend = dst_get_frontend, 1381 .get_frontend = dst_get_frontend,
1382
1383 .read_status = dst_read_status, 1382 .read_status = dst_read_status,
1384 .read_signal_strength = dst_read_signal_strength, 1383 .read_signal_strength = dst_read_signal_strength,
1385 .read_snr = dst_read_snr, 1384 .read_snr = dst_read_snr,
@@ -1401,16 +1400,12 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
1401 }, 1400 },
1402 1401
1403 .release = dst_release, 1402 .release = dst_release,
1404
1405 .init = dst_init, 1403 .init = dst_init,
1406
1407 .set_frontend = dst_set_frontend, 1404 .set_frontend = dst_set_frontend,
1408 .get_frontend = dst_get_frontend, 1405 .get_frontend = dst_get_frontend,
1409
1410 .read_status = dst_read_status, 1406 .read_status = dst_read_status,
1411 .read_signal_strength = dst_read_signal_strength, 1407 .read_signal_strength = dst_read_signal_strength,
1412 .read_snr = dst_read_snr, 1408 .read_snr = dst_read_snr,
1413
1414 .diseqc_send_burst = dst_send_burst, 1409 .diseqc_send_burst = dst_send_burst,
1415 .diseqc_send_master_cmd = dst_set_diseqc, 1410 .diseqc_send_master_cmd = dst_set_diseqc,
1416 .set_voltage = dst_set_voltage, 1411 .set_voltage = dst_set_voltage,
@@ -1432,18 +1427,14 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
1432 }, 1427 },
1433 1428
1434 .release = dst_release, 1429 .release = dst_release,
1435
1436 .init = dst_init, 1430 .init = dst_init,
1437
1438 .set_frontend = dst_set_frontend, 1431 .set_frontend = dst_set_frontend,
1439 .get_frontend = dst_get_frontend, 1432 .get_frontend = dst_get_frontend,
1440
1441 .read_status = dst_read_status, 1433 .read_status = dst_read_status,
1442 .read_signal_strength = dst_read_signal_strength, 1434 .read_signal_strength = dst_read_signal_strength,
1443 .read_snr = dst_read_snr, 1435 .read_snr = dst_read_snr,
1444}; 1436};
1445 1437
1446
1447MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); 1438MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1448MODULE_AUTHOR("Jamie Honan, Manu Abraham"); 1439MODULE_AUTHOR("Jamie Honan, Manu Abraham");
1449MODULE_LICENSE("GPL"); 1440MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index bfaacd5fc20f..6776a592045f 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -18,30 +18,42 @@
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/ 19*/
20 20
21
22
23#include <linux/kernel.h> 21#include <linux/kernel.h>
24#include <linux/module.h> 22#include <linux/module.h>
25#include <linux/init.h> 23#include <linux/init.h>
26#include <linux/string.h> 24#include <linux/string.h>
27
28#include <linux/dvb/ca.h> 25#include <linux/dvb/ca.h>
29#include "dvbdev.h" 26#include "dvbdev.h"
30#include "dvb_frontend.h" 27#include "dvb_frontend.h"
31
32#include "dst_ca.h" 28#include "dst_ca.h"
33#include "dst_common.h" 29#include "dst_common.h"
34 30
31#define DST_CA_ERROR 0
32#define DST_CA_NOTICE 1
33#define DST_CA_INFO 2
34#define DST_CA_DEBUG 3
35
36#define dprintk(x, y, z, format, arg...) do { \
37 if (z) { \
38 if ((x > DST_CA_ERROR) && (x > y)) \
39 printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
40 else if ((x > DST_CA_NOTICE) && (x > y)) \
41 printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
42 else if ((x > DST_CA_INFO) && (x > y)) \
43 printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
44 else if ((x > DST_CA_DEBUG) && (x > y)) \
45 printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
46 } else { \
47 if (x > y) \
48 printk(format, ## arg); \
49 } \
50} while(0)
51
52
35static unsigned int verbose = 5; 53static unsigned int verbose = 5;
36module_param(verbose, int, 0644); 54module_param(verbose, int, 0644);
37MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 55MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
38 56
39static unsigned int debug = 1;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)");
42
43#define dprintk if (debug) printk
44
45/* Need some more work */ 57/* Need some more work */
46static int ca_set_slot_descr(void) 58static int ca_set_slot_descr(void)
47{ 59{
@@ -61,27 +73,20 @@ static int put_checksum(u8 *check_string, int length)
61{ 73{
62 u8 i = 0, checksum = 0; 74 u8 i = 0, checksum = 0;
63 75
64 if (verbose > 3) { 76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ===========================");
65 dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__); 77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length);
66 dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length); 78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
67 79
68 dprintk("%s: String=[", __FUNCTION__);
69 }
70 while (i < length) { 80 while (i < length) {
71 if (verbose > 3) 81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
72 dprintk(" %02x", check_string[i]);
73 checksum += check_string[i]; 82 checksum += check_string[i];
74 i++; 83 i++;
75 } 84 }
76 if (verbose > 3) { 85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
77 dprintk(" ]\n"); 86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
78 dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
79 }
80 check_string[length] = ~checksum + 1; 87 check_string[length] = ~checksum + 1;
81 if (verbose > 3) { 88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
82 dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]); 89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
83 dprintk("%s: ==========================================================================\n", __FUNCTION__);
84 }
85 90
86 return 0; 91 return 0;
87} 92}
@@ -94,30 +99,26 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
94 msleep(65); 99 msleep(65);
95 100
96 if (write_dst(state, data, len)) { 101 if (write_dst(state, data, len)) {
97 dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__); 102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
98 dst_error_recovery(state); 103 dst_error_recovery(state);
99 return -1; 104 return -1;
100 } 105 }
101
102 if ((dst_pio_disable(state)) < 0) { 106 if ((dst_pio_disable(state)) < 0) {
103 dprintk("%s: DST PIO disable failed.\n", __FUNCTION__); 107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
104 return -1; 108 return -1;
105 } 109 }
106
107 if (read_dst(state, &reply, GET_ACK) < 0) { 110 if (read_dst(state, &reply, GET_ACK) < 0) {
108 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); 111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
109 dst_error_recovery(state); 112 dst_error_recovery(state);
110 return -1; 113 return -1;
111 } 114 }
112
113 if (read) { 115 if (read) {
114 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 116 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
115 dprintk("%s: 8820 not ready\n", __FUNCTION__); 117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
116 return -1; 118 return -1;
117 } 119 }
118
119 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
120 dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); 121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
121 dst_error_recovery(state); 122 dst_error_recovery(state);
122 return -1; 123 return -1;
123 } 124 }
@@ -133,8 +134,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string,
133 134
134 while (dst_ca_comm_err < RETRIES) { 135 while (dst_ca_comm_err < RETRIES) {
135 dst_comm_init(state); 136 dst_comm_init(state);
136 if (verbose > 2) 137 dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
137 dprintk("%s: Put Command\n", __FUNCTION__);
138 if (dst_ci_command(state, data, ca_string, len, read)) { // If error 138 if (dst_ci_command(state, data, ca_string, len, read)) { // If error
139 dst_error_recovery(state); 139 dst_error_recovery(state);
140 dst_ca_comm_err++; // work required here. 140 dst_ca_comm_err++; // work required here.
@@ -153,18 +153,15 @@ static int ca_get_app_info(struct dst_state *state)
153 153
154 put_checksum(&command[0], command[0]); 154 put_checksum(&command[0], command[0]);
155 if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { 155 if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
156 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 156 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
157 return -1; 157 return -1;
158 } 158 }
159 if (verbose > 1) { 159 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
160 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); 160 dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
161 161 dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
162 dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__); 162 state->messages[7], (state->messages[8] << 8) | state->messages[9],
163 dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n", 163 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
164 __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9], 164 dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
165 (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
166 dprintk("%s: ==================================================================================================\n", __FUNCTION__);
167 }
168 165
169 return 0; 166 return 0;
170} 167}
@@ -177,31 +174,26 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
177 174
178 put_checksum(&slot_command[0], slot_command[0]); 175 put_checksum(&slot_command[0], slot_command[0]);
179 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { 176 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
180 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 177 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
181 return -1; 178 return -1;
182 } 179 }
183 if (verbose > 1) 180 dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
184 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
185 181
186 /* Will implement the rest soon */ 182 /* Will implement the rest soon */
187 183
188 if (verbose > 1) { 184 dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
189 dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]); 185 dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
190 dprintk("===================================\n"); 186 for (i = 0; i < 8; i++)
191 for (i = 0; i < 8; i++) 187 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
192 dprintk(" %d", slot_cap[i]); 188 dprintk(verbose, DST_CA_INFO, 0, "\n");
193 dprintk("\n");
194 }
195 189
196 p_ca_caps->slot_num = 1; 190 p_ca_caps->slot_num = 1;
197 p_ca_caps->slot_type = 1; 191 p_ca_caps->slot_type = 1;
198 p_ca_caps->descr_num = slot_cap[7]; 192 p_ca_caps->descr_num = slot_cap[7];
199 p_ca_caps->descr_type = 1; 193 p_ca_caps->descr_type = 1;
200 194
201 195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps)))
202 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
203 return -EFAULT; 196 return -EFAULT;
204 }
205 197
206 return 0; 198 return 0;
207} 199}
@@ -222,46 +214,37 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
222 214
223 put_checksum(&slot_command[0], 7); 215 put_checksum(&slot_command[0], 7);
224 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
225 dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); 217 dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
226 return -1; 218 return -1;
227 } 219 }
228 if (verbose > 1) 220 dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
229 dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
230 221
231 /* Will implement the rest soon */ 222 /* Will implement the rest soon */
232 223
233 if (verbose > 1) { 224 dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
234 dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]); 225 dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
235 dprintk("===================================\n"); 226 for (i = 0; i < 8; i++)
236 for (i = 0; i < 8; i++) 227 dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
237 dprintk(" %d", slot_info[i]); 228 dprintk(verbose, DST_CA_INFO, 0, "\n");
238 dprintk("\n");
239 }
240 229
241 if (slot_info[4] & 0x80) { 230 if (slot_info[4] & 0x80) {
242 p_ca_slot_info->flags = CA_CI_MODULE_PRESENT; 231 p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
243 p_ca_slot_info->num = 1; 232 p_ca_slot_info->num = 1;
244 p_ca_slot_info->type = CA_CI; 233 p_ca_slot_info->type = CA_CI;
245 } 234 } else if (slot_info[4] & 0x40) {
246 else if (slot_info[4] & 0x40) {
247 p_ca_slot_info->flags = CA_CI_MODULE_READY; 235 p_ca_slot_info->flags = CA_CI_MODULE_READY;
248 p_ca_slot_info->num = 1; 236 p_ca_slot_info->num = 1;
249 p_ca_slot_info->type = CA_CI; 237 p_ca_slot_info->type = CA_CI;
250 } 238 } else
251 else {
252 p_ca_slot_info->flags = 0; 239 p_ca_slot_info->flags = 0;
253 }
254 240
255 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) { 241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
256 return -EFAULT; 242 return -EFAULT;
257 }
258 243
259 return 0; 244 return 0;
260} 245}
261 246
262 247
263
264
265static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
266{ 249{
267 u8 i = 0; 250 u8 i = 0;
@@ -270,24 +253,21 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
270 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
271 return -EFAULT; 254 return -EFAULT;
272 255
273
274 if (p_ca_message->msg) { 256 if (p_ca_message->msg) {
275 if (verbose > 3) 257 dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%02x %02x %02x]", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
276 dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
277 258
278 for (i = 0; i < 3; i++) { 259 for (i = 0; i < 3; i++) {
279 command = command | p_ca_message->msg[i]; 260 command = command | p_ca_message->msg[i];
280 if (i < 2) 261 if (i < 2)
281 command = command << 8; 262 command = command << 8;
282 } 263 }
283 if (verbose > 3) 264 dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
284 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
285 265
286 switch (command) { 266 switch (command) {
287 case CA_APP_INFO: 267 case CA_APP_INFO:
288 memcpy(p_ca_message->msg, state->messages, 128); 268 memcpy(p_ca_message->msg, state->messages, 128);
289 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
290 return -EFAULT; 270 return -EFAULT;
291 break; 271 break;
292 } 272 }
293 } 273 }
@@ -298,10 +278,13 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
298static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length) 278static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
299{ 279{
300 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { 280 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
301 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ 281 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
302 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ 282 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
303 } 283 } else {
304 else { 284 if (length > 247) {
285 dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
286 return -1;
287 }
305 hw_buffer->msg[0] = (length & 0xff) + 7; 288 hw_buffer->msg[0] = (length & 0xff) + 7;
306 hw_buffer->msg[1] = 0x40; 289 hw_buffer->msg[1] = 0x40;
307 hw_buffer->msg[2] = 0x03; 290 hw_buffer->msg[2] = 0x03;
@@ -309,6 +292,11 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
309 hw_buffer->msg[4] = 0x03; 292 hw_buffer->msg[4] = 0x03;
310 hw_buffer->msg[5] = length & 0xff; 293 hw_buffer->msg[5] = length & 0xff;
311 hw_buffer->msg[6] = 0x00; 294 hw_buffer->msg[6] = 0x00;
295 /*
296 * Need to compute length for EN50221 section 8.3.2, for the time being
297 * assuming 8.3.2 is not applicable
298 */
299 memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
312 } 300 }
313 return 0; 301 return 0;
314} 302}
@@ -317,13 +305,12 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
317static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) 305static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
318{ 306{
319 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { 307 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
320 dprintk("%s: DST-CI Command failed.\n", __FUNCTION__); 308 dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
321 dprintk("%s: Resetting DST.\n", __FUNCTION__); 309 dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
322 rdc_reset_state(state); 310 rdc_reset_state(state);
323 return -1; 311 return -1;
324 } 312 }
325 if (verbose > 2) 313 dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes.");
326 dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
327 314
328 return 0; 315 return 0;
329} 316}
@@ -334,130 +321,47 @@ u32 asn_1_decode(u8 *asn_1_array)
334 u32 length = 0; 321 u32 length = 0;
335 322
336 length_field = asn_1_array[0]; 323 length_field = asn_1_array[0];
337 dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
338 if (length_field < 0x80) { 325 if (length_field < 0x80) {
339 length = length_field & 0x7f; 326 length = length_field & 0x7f;
340 dprintk("%s: Length=[%02x]\n", __FUNCTION__, length); 327 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
341 } else { 328 } else {
342 word_count = length_field & 0x7f; 329 word_count = length_field & 0x7f;
343 for (count = 0; count < word_count; count++) { 330 for (count = 0; count < word_count; count++) {
344 length = (length | asn_1_array[count + 1]) << 8; 331 length = (length | asn_1_array[count + 1]) << 8;
345 dprintk("%s: Length=[%04x]\n", __FUNCTION__, length); 332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
346 } 333 }
347 } 334 }
348 return length; 335 return length;
349} 336}
350 337
351static int init_buffer(u8 *buffer, u32 length)
352{
353 u32 i;
354 for (i = 0; i < length; i++)
355 buffer[i] = 0;
356
357 return 0;
358}
359
360static int debug_string(u8 *msg, u32 length, u32 offset) 338static int debug_string(u8 *msg, u32 length, u32 offset)
361{ 339{
362 u32 i; 340 u32 i;
363 341
364 dprintk(" String=[ "); 342 dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
365 for (i = offset; i < length; i++) 343 for (i = offset; i < length; i++)
366 dprintk("%02x ", msg[i]); 344 dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
367 dprintk("]\n"); 345 dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
368
369 return 0;
370}
371
372static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
373{
374 u32 i;
375 dprintk("%s: Copying [", __FUNCTION__);
376 for (i = 0; i < length; i++) {
377 destination[i + dest_offset] = source[i + source_offset];
378 dprintk(" %02x", source[i + source_offset]);
379 }
380 dprintk("]\n");
381
382 return i;
383}
384
385static int modify_4_bits(u8 *message, u32 pos)
386{
387 message[pos] &= 0x0f;
388 346
389 return 0; 347 return 0;
390} 348}
391 349
392
393
394static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) 350static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
395{ 351{
396 u32 length = 0, count = 0; 352 u32 length = 0;
397 u8 asn_1_words, program_header_length; 353 u8 tag_length = 8;
398 u16 program_info_length = 0, es_info_length = 0;
399 u32 hw_offset = 0, buf_offset = 0, i;
400 u8 dst_tag_length;
401 354
402 length = asn_1_decode(&p_ca_message->msg[3]); 355 length = asn_1_decode(&p_ca_message->msg[3]);
403 dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length); 356 dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
404 dprintk("%s: ASN.1 ", __FUNCTION__); 357 debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
405 debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
406 358
407 init_buffer(hw_buffer->msg, length); 359 memset(hw_buffer->msg, '\0', length);
408 handle_dst_tag(state, p_ca_message, hw_buffer, length); 360 handle_dst_tag(state, p_ca_message, hw_buffer, length);
361 put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
409 362
410 hw_offset = 7; 363 debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
411 asn_1_words = 1; // just a hack to test, should compute this one 364 write_to_8820(state, hw_buffer, (length + tag_length), reply);
412 buf_offset = 3;
413 program_header_length = 6;
414 dst_tag_length = 7;
415
416// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
417// dprintk("%s: Program Header(BUF)", __FUNCTION__);
418// debug_string(&p_ca_message->msg[4], program_header_length, 0);
419// dprintk("%s: Copying Program header\n", __FUNCTION__);
420 copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
421 buf_offset += program_header_length, hw_offset += program_header_length;
422 modify_4_bits(hw_buffer->msg, (hw_offset - 2));
423 if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
424 dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
425 debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
426 hw_buffer->msg[hw_offset - 1] += 1;
427 }
428
429// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
430// debug_string(hw_buffer->msg, hw_offset, 0);
431
432 program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
433 dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
434 if (program_info_length) {
435 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
436 buf_offset += count, hw_offset += count;
437// dprintk("%s: Program level ", __FUNCTION__);
438// debug_string(hw_buffer->msg, hw_offset, 0);
439 }
440
441 buf_offset += 1;// hw_offset += 1;
442 for (i = buf_offset; i < length; i++) {
443// dprintk("%s: Stream Header ", __FUNCTION__);
444 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
445 modify_4_bits(hw_buffer->msg, (hw_offset + 3));
446
447 hw_offset += 5, buf_offset += 5, i += 4;
448// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
449 es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
450 dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
451 if (es_info_length) {
452 // copy descriptors @ STREAM level
453 dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
454 }
455
456 }
457 hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
458// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
459 debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
460 write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
461 365
462 return 0; 366 return 0;
463} 367}
@@ -471,26 +375,24 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
471 /* Do test board */ 375 /* Do test board */
472 /* Not there yet but soon */ 376 /* Not there yet but soon */
473 377
474
475 /* CA PMT Reply capable */ 378 /* CA PMT Reply capable */
476 if (ca_pmt_reply_test) { 379 if (ca_pmt_reply_test) {
477 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { 380 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
478 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); 381 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
479 return -1; 382 return -1;
480 } 383 }
481 384
482 /* Process CA PMT Reply */ 385 /* Process CA PMT Reply */
483 /* will implement soon */ 386 /* will implement soon */
484 dprintk("%s: Not there yet\n", __FUNCTION__); 387 dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
485 } 388 }
486 /* CA PMT Reply not capable */ 389 /* CA PMT Reply not capable */
487 if (!ca_pmt_reply_test) { 390 if (!ca_pmt_reply_test) {
488 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { 391 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
489 dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); 392 dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
490 return -1; 393 return -1;
491 } 394 }
492 if (verbose > 3) 395 dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
493 dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
494 /* put a dummy message */ 396 /* put a dummy message */
495 397
496 } 398 }
@@ -506,11 +408,10 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
506 struct ca_msg *hw_buffer; 408 struct ca_msg *hw_buffer;
507 409
508 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
509 dprintk("%s: Memory allocation failure\n", __FUNCTION__); 411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
510 return -ENOMEM; 412 return -ENOMEM;
511 } 413 }
512 if (verbose > 3) 414 dprintk(verbose, DST_CA_DEBUG, 1, " ");
513 dprintk("%s\n", __FUNCTION__);
514 415
515 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
516 return -EFAULT; 417 return -EFAULT;
@@ -525,51 +426,35 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
525 if (i < 2) 426 if (i < 2)
526 command = command << 8; 427 command = command << 8;
527 } 428 }
528 if (verbose > 3) 429 dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
529 dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
530 430
531 switch (command) { 431 switch (command) {
532 case CA_PMT: 432 case CA_PMT:
533 if (verbose > 3) 433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
534// dprintk("Command = SEND_CA_PMT\n"); 434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
535 dprintk("Command = SEND_CA_PMT\n"); 435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
536// if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { 436 return -1;
537 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 437 }
538 dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__); 438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
539 return -1; 439 break;
540 } 440 case CA_PMT_REPLY:
541 if (verbose > 3) 441 dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
542 dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__); 442 /* Have to handle the 2 basic types of cards here */
543// retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0); 443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
544 444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
545 break; 445 return -1;
546 446 }
547 case CA_PMT_REPLY: 447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
548 if (verbose > 3) 448 break;
549 dprintk("Command = CA_PMT_REPLY\n"); 449 case CA_APP_INFO_ENQUIRY: // only for debugging
550 /* Have to handle the 2 basic types of cards here */ 450 dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
551 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 451
552 dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__); 452 if ((ca_get_app_info(state)) < 0) {
553 return -1; 453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
554 } 454 return -1;
555 if (verbose > 3) 455 }
556 dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__); 456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
557 457 break;
558 /* Certain boards do behave different ? */
559// retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
560
561 case CA_APP_INFO_ENQUIRY: // only for debugging
562 if (verbose > 3)
563 dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
564
565 if ((ca_get_app_info(state)) < 0) {
566 dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
567 return -1;
568 }
569 if (verbose > 3)
570 dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
571
572 break;
573 } 458 }
574 } 459 }
575 return 0; 460 return 0;
@@ -584,121 +469,88 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
584 struct ca_msg *p_ca_message; 469 struct ca_msg *p_ca_message;
585 470
586 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
587 dprintk("%s: Memory allocation failure\n", __FUNCTION__); 472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
588 return -ENOMEM; 473 return -ENOMEM;
589 } 474 }
590
591 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { 475 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
592 dprintk("%s: Memory allocation failure\n", __FUNCTION__); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
593 return -ENOMEM; 477 return -ENOMEM;
594 } 478 }
595
596 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { 479 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
597 dprintk("%s: Memory allocation failure\n", __FUNCTION__); 480 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
598 return -ENOMEM; 481 return -ENOMEM;
599 } 482 }
600
601 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ 483 /* We have now only the standard ioctl's, the driver is upposed to handle internals. */
602 switch (cmd) { 484 switch (cmd) {
603 case CA_SEND_MSG: 485 case CA_SEND_MSG:
604 if (verbose > 1) 486 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
605 dprintk("%s: Sending message\n", __FUNCTION__); 487 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
606 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
607 dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__); 489 return -1;
608 return -1; 490 }
609 } 491 break;
610 492 case CA_GET_MSG:
611 break; 493 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
612 494 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
613 case CA_GET_MSG: 495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
614 if (verbose > 1) 496 return -1;
615 dprintk("%s: Getting message\n", __FUNCTION__); 497 }
616 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
617 dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__); 499 break;
618 return -1; 500 case CA_RESET:
619 } 501 dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
620 if (verbose > 1) 502 dst_error_bailout(state);
621 dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__); 503 msleep(4000);
622 504 break;
623 break; 505 case CA_GET_SLOT_INFO:
624 506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
625 case CA_RESET: 507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
626 if (verbose > 1) 508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
627 dprintk("%s: Resetting DST\n", __FUNCTION__); 509 return -1;
628 dst_error_bailout(state); 510 }
629 msleep(4000); 511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
630 512 break;
631 break; 513 case CA_GET_CAP:
632 514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
633 case CA_GET_SLOT_INFO: 515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
634 if (verbose > 1) 516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
635 dprintk("%s: Getting Slot info\n", __FUNCTION__); 517 return -1;
636 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 518 }
637 dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__); 519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
638 return -1; 520 break;
639 } 521 case CA_GET_DESCR_INFO:
640 if (verbose > 1) 522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
641 dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__); 523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
642 524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
643 break; 525 return -1;
644 526 }
645 case CA_GET_CAP: 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
646 if (verbose > 1) 528 break;
647 dprintk("%s: Getting Slot capabilities\n", __FUNCTION__); 529 case CA_SET_DESCR:
648 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
649 dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__); 531 if ((ca_set_slot_descr()) < 0) {
650 return -1; 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
651 } 533 return -1;
652 if (verbose > 1) 534 }
653 dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__); 535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
654 536 break;
655 break; 537 case CA_SET_PID:
656 538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
657 case CA_GET_DESCR_INFO: 539 if ((ca_set_pid()) < 0) {
658 if (verbose > 1) 540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
659 dprintk("%s: Getting descrambler description\n", __FUNCTION__); 541 return -1;
660 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 542 }
661 dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__); 543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
662 return -1; 544 default:
663 } 545 return -EOPNOTSUPP;
664 if (verbose > 1) 546 };
665 dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
666
667 break;
668
669 case CA_SET_DESCR:
670 if (verbose > 1)
671 dprintk("%s: Setting descrambler\n", __FUNCTION__);
672 if ((ca_set_slot_descr()) < 0) {
673 dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
674 return -1;
675 }
676 if (verbose > 1)
677 dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
678
679 break;
680
681 case CA_SET_PID:
682 if (verbose > 1)
683 dprintk("%s: Setting PID\n", __FUNCTION__);
684 if ((ca_set_pid()) < 0) {
685 dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
686 return -1;
687 }
688 if (verbose > 1)
689 dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
690
691 default:
692 return -EOPNOTSUPP;
693 };
694 547
695 return 0; 548 return 0;
696} 549}
697 550
698static int dst_ca_open(struct inode *inode, struct file *file) 551static int dst_ca_open(struct inode *inode, struct file *file)
699{ 552{
700 if (verbose > 4) 553 dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
701 dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
702 try_module_get(THIS_MODULE); 554 try_module_get(THIS_MODULE);
703 555
704 return 0; 556 return 0;
@@ -706,27 +558,24 @@ static int dst_ca_open(struct inode *inode, struct file *file)
706 558
707static int dst_ca_release(struct inode *inode, struct file *file) 559static int dst_ca_release(struct inode *inode, struct file *file)
708{ 560{
709 if (verbose > 4) 561 dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
710 dprintk("%s:Device closed.\n", __FUNCTION__);
711 module_put(THIS_MODULE); 562 module_put(THIS_MODULE);
712 563
713 return 0; 564 return 0;
714} 565}
715 566
716static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset) 567static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
717{ 568{
718 int bytes_read = 0; 569 int bytes_read = 0;
719 570
720 if (verbose > 4) 571 dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
721 dprintk("%s:Device read.\n", __FUNCTION__);
722 572
723 return bytes_read; 573 return bytes_read;
724} 574}
725 575
726static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset) 576static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
727{ 577{
728 if (verbose > 4) 578 dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
729 dprintk("%s:Device write.\n", __FUNCTION__);
730 579
731 return 0; 580 return 0;
732} 581}
@@ -751,8 +600,7 @@ static struct dvb_device dvbdev_ca = {
751int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) 600int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
752{ 601{
753 struct dvb_device *dvbdev; 602 struct dvb_device *dvbdev;
754 if (verbose > 4) 603 dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
755 dprintk("%s:registering DST-CA device\n", __FUNCTION__);
756 dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA); 604 dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
757 return 0; 605 return 0;
758} 606}
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index ef532a6aceaa..3281a6ca3685 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -61,7 +61,6 @@
61#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ 61#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
62#define DST_TYPE_HAS_SESSION 128 62#define DST_TYPE_HAS_SESSION 128
63 63
64
65#define RDC_8820_PIO_0_DISABLE 0 64#define RDC_8820_PIO_0_DISABLE 0
66#define RDC_8820_PIO_0_ENABLE 1 65#define RDC_8820_PIO_0_ENABLE 1
67#define RDC_8820_INT 2 66#define RDC_8820_INT 2
@@ -114,6 +113,10 @@ struct dst_state {
114 fe_sec_mini_cmd_t minicmd; 113 fe_sec_mini_cmd_t minicmd;
115 fe_modulation_t modulation; 114 fe_modulation_t modulation;
116 u8 messages[256]; 115 u8 messages[256];
116 u8 mac_address[8];
117 u8 fw_version[8];
118 u8 card_info[8];
119 u8 vendor[8];
117}; 120};
118 121
119struct dst_types { 122struct dst_types {
@@ -124,15 +127,12 @@ struct dst_types {
124 u32 dst_feature; 127 u32 dst_feature;
125}; 128};
126 129
127
128
129struct dst_config 130struct dst_config
130{ 131{
131 /* the ASIC i2c address */ 132 /* the ASIC i2c address */
132 u8 demod_address; 133 u8 demod_address;
133}; 134};
134 135
135
136int rdc_reset_state(struct dst_state *state); 136int rdc_reset_state(struct dst_state *state);
137int rdc_8820_reset(struct dst_state *state); 137int rdc_8820_reset(struct dst_state *state);
138 138
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 6f857c6091f3..c5c7672cd538 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -32,9 +32,7 @@
32#include "dvbdev.h" 32#include "dvbdev.h"
33#include "dvb_demux.h" 33#include "dvb_demux.h"
34#include "dvb_frontend.h" 34#include "dvb_frontend.h"
35
36#include "dvb-bt8xx.h" 35#include "dvb-bt8xx.h"
37
38#include "bt878.h" 36#include "bt878.h"
39 37
40static int debug; 38static int debug;
@@ -43,9 +41,11 @@ module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44 42
45#define dprintk( args... ) \ 43#define dprintk( args... ) \
46 do { \ 44 do \
47 if (debug) printk(KERN_DEBUG args); \ 45 if (debug) printk(KERN_DEBUG args); \
48 } while (0) 46 while (0)
47
48#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
49 49
50static void dvb_bt8xx_task(unsigned long data) 50static void dvb_bt8xx_task(unsigned long data)
51{ 51{
@@ -119,14 +119,12 @@ static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci
119 unsigned int card_nr; 119 unsigned int card_nr;
120 120
121 /* Hmm, n squared. Hope n is small */ 121 /* Hmm, n squared. Hope n is small */
122 for (card_nr = 0; card_nr < bt878_num; card_nr++) { 122 for (card_nr = 0; card_nr < bt878_num; card_nr++)
123 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev)) 123 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
124 return &bt878[card_nr]; 124 return &bt878[card_nr];
125 }
126 return NULL; 125 return NULL;
127} 126}
128 127
129
130static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) 128static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
131{ 129{
132 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 }; 130 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
@@ -154,16 +152,21 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
154 unsigned char bs = 0; 152 unsigned char bs = 0;
155 unsigned char cp = 0; 153 unsigned char cp = 0;
156 154
157 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
158 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 155 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
159 156
160 if (params->frequency < 542000000) cp = 0xb4; 157 if (params->frequency < 542000000)
161 else if (params->frequency < 771000000) cp = 0xbc; 158 cp = 0xb4;
162 else cp = 0xf4; 159 else if (params->frequency < 771000000)
160 cp = 0xbc;
161 else
162 cp = 0xf4;
163 163
164 if (params->frequency == 0) bs = 0x03; 164 if (params->frequency == 0)
165 else if (params->frequency < 443250000) bs = 0x02; 165 bs = 0x03;
166 else bs = 0x08; 166 else if (params->frequency < 443250000)
167 bs = 0x02;
168 else
169 bs = 0x08;
167 170
168 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address 171 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
169 pllbuf[1] = div >> 8; 172 pllbuf[1] = div >> 8;
@@ -175,7 +178,6 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
175} 178}
176 179
177static struct mt352_config thomson_dtt7579_config = { 180static struct mt352_config thomson_dtt7579_config = {
178
179 .demod_address = 0x0f, 181 .demod_address = 0x0f,
180 .demod_init = thomson_dtt7579_demod_init, 182 .demod_init = thomson_dtt7579_demod_init,
181 .pll_set = thomson_dtt7579_pll_set, 183 .pll_set = thomson_dtt7579_pll_set,
@@ -183,25 +185,26 @@ static struct mt352_config thomson_dtt7579_config = {
183 185
184static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 186static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
185{ 187{
186 u32 freq = params->frequency; 188 u32 freq = params->frequency;
187
188 int i, a, n, pump;
189 u32 band, pll;
190 189
190 int i, a, n, pump;
191 u32 band, pll;
191 192
192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, 193 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
193 1576000,1718000,1856000,2036000,2150000}; 194 1576000,1718000,1856000,2036000,2150000};
194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, 195 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
195 0x00102000,0x00104000,0x00108000,0x00110000, 196 0x00102000,0x00104000,0x00108000,0x00110000,
196 0x00120000,0x00140000}; 197 0x00120000,0x00140000};
197 198
198#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ 199 #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
199 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); 200 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
200 201
201 /* This is really the bit driving the tuner chip cx24108 */ 202 /* This is really the bit driving the tuner chip cx24108 */
202 203
203 if(freq<950000) freq=950000; /* kHz */ 204 if (freq<950000)
204 if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ 205 freq = 950000; /* kHz */
206 else if (freq>2150000)
207 freq = 2150000; /* satellite IF is 950..2150MHz */
205 208
206 /* decide which VCO to use for the input frequency */ 209 /* decide which VCO to use for the input frequency */
207 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); 210 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
@@ -228,25 +231,22 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
228 cx24110_pll_write(fe,0x500c0000); 231 cx24110_pll_write(fe,0x500c0000);
229 cx24110_pll_write(fe,0x83f1f800); 232 cx24110_pll_write(fe,0x83f1f800);
230 cx24110_pll_write(fe,pll); 233 cx24110_pll_write(fe,pll);
231/* writereg(client,0x56,0x7f);*/ 234 //writereg(client,0x56,0x7f);
232 235
233 return 0; 236 return 0;
234} 237}
235 238
236static int pinnsat_pll_init(struct dvb_frontend* fe) 239static int pinnsat_pll_init(struct dvb_frontend* fe)
237{ 240{
238 return 0; 241 return 0;
239} 242}
240 243
241
242static struct cx24110_config pctvsat_config = { 244static struct cx24110_config pctvsat_config = {
243
244 .demod_address = 0x55, 245 .demod_address = 0x55,
245 .pll_init = pinnsat_pll_init, 246 .pll_init = pinnsat_pll_init,
246 .pll_set = cx24108_pll_set, 247 .pll_set = cx24108_pll_set,
247}; 248};
248 249
249
250static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 250static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
251{ 251{
252 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 252 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
@@ -258,15 +258,23 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
258 div = (36000000 + params->frequency + 83333) / 166666; 258 div = (36000000 + params->frequency + 83333) / 166666;
259 cfg = 0x88; 259 cfg = 0x88;
260 260
261 if (params->frequency < 175000000) cpump = 2; 261 if (params->frequency < 175000000)
262 else if (params->frequency < 390000000) cpump = 1; 262 cpump = 2;
263 else if (params->frequency < 470000000) cpump = 2; 263 else if (params->frequency < 390000000)
264 else if (params->frequency < 750000000) cpump = 2; 264 cpump = 1;
265 else cpump = 3; 265 else if (params->frequency < 470000000)
266 cpump = 2;
267 else if (params->frequency < 750000000)
268 cpump = 2;
269 else
270 cpump = 3;
266 271
267 if (params->frequency < 175000000) band_select = 0x0e; 272 if (params->frequency < 175000000)
268 else if (params->frequency < 470000000) band_select = 0x05; 273 band_select = 0x0e;
269 else band_select = 0x03; 274 else if (params->frequency < 470000000)
275 band_select = 0x05;
276 else
277 band_select = 0x03;
270 278
271 data[0] = (div >> 8) & 0x7f; 279 data[0] = (div >> 8) & 0x7f;
272 data[1] = div & 0xff; 280 data[1] = div & 0xff;
@@ -285,14 +293,11 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s
285} 293}
286 294
287static struct sp887x_config microtune_mt7202dtf_config = { 295static struct sp887x_config microtune_mt7202dtf_config = {
288
289 .demod_address = 0x70, 296 .demod_address = 0x70,
290 .pll_set = microtune_mt7202dtf_pll_set, 297 .pll_set = microtune_mt7202dtf_pll_set,
291 .request_firmware = microtune_mt7202dtf_request_firmware, 298 .request_firmware = microtune_mt7202dtf_request_firmware,
292}; 299};
293 300
294
295
296static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) 301static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
297{ 302{
298 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; 303 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
@@ -303,7 +308,6 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; 308 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; 309 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
305 310
306
307 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); 311 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
308 udelay(2000); 312 udelay(2000);
309 mt352_write(fe, mt352_reset, sizeof(mt352_reset)); 313 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
@@ -323,28 +327,45 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
323 unsigned char bs = 0; 327 unsigned char bs = 0;
324 unsigned char cp = 0; 328 unsigned char cp = 0;
325 329
326 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
327 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; 330 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
328 331
329 if (params->frequency < 150000000) cp = 0xB4; 332 if (params->frequency < 150000000)
330 else if (params->frequency < 173000000) cp = 0xBC; 333 cp = 0xB4;
331 else if (params->frequency < 250000000) cp = 0xB4; 334 else if (params->frequency < 173000000)
332 else if (params->frequency < 400000000) cp = 0xBC; 335 cp = 0xBC;
333 else if (params->frequency < 420000000) cp = 0xF4; 336 else if (params->frequency < 250000000)
334 else if (params->frequency < 470000000) cp = 0xFC; 337 cp = 0xB4;
335 else if (params->frequency < 600000000) cp = 0xBC; 338 else if (params->frequency < 400000000)
336 else if (params->frequency < 730000000) cp = 0xF4; 339 cp = 0xBC;
337 else cp = 0xFC; 340 else if (params->frequency < 420000000)
338 341 cp = 0xF4;
339 if (params->frequency < 150000000) bs = 0x01; 342 else if (params->frequency < 470000000)
340 else if (params->frequency < 173000000) bs = 0x01; 343 cp = 0xFC;
341 else if (params->frequency < 250000000) bs = 0x02; 344 else if (params->frequency < 600000000)
342 else if (params->frequency < 400000000) bs = 0x02; 345 cp = 0xBC;
343 else if (params->frequency < 420000000) bs = 0x02; 346 else if (params->frequency < 730000000)
344 else if (params->frequency < 470000000) bs = 0x02; 347 cp = 0xF4;
345 else if (params->frequency < 600000000) bs = 0x08; 348 else
346 else if (params->frequency < 730000000) bs = 0x08; 349 cp = 0xFC;
347 else bs = 0x08; 350
351 if (params->frequency < 150000000)
352 bs = 0x01;
353 else if (params->frequency < 173000000)
354 bs = 0x01;
355 else if (params->frequency < 250000000)
356 bs = 0x02;
357 else if (params->frequency < 400000000)
358 bs = 0x02;
359 else if (params->frequency < 420000000)
360 bs = 0x02;
361 else if (params->frequency < 470000000)
362 bs = 0x02;
363 else if (params->frequency < 600000000)
364 bs = 0x08;
365 else if (params->frequency < 730000000)
366 bs = 0x08;
367 else
368 bs = 0x08;
348 369
349 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address 370 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
350 pllbuf[1] = div >> 8; 371 pllbuf[1] = div >> 8;
@@ -356,19 +377,15 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
356} 377}
357 378
358static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { 379static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
359
360 .demod_address = 0x0f, 380 .demod_address = 0x0f,
361 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, 381 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
362 .pll_set = advbt771_samsung_tdtc9251dh0_pll_set, 382 .pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
363}; 383};
364 384
365
366static struct dst_config dst_config = { 385static struct dst_config dst_config = {
367
368 .demod_address = 0x55, 386 .demod_address = 0x55,
369}; 387};
370 388
371
372static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) 389static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
373{ 390{
374 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; 391 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
@@ -398,10 +415,8 @@ static void or51211_reset(struct dvb_frontend * fe)
398 */ 415 */
399 /* reset & PRM1,2&4 are outputs */ 416 /* reset & PRM1,2&4 are outputs */
400 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F); 417 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
401 if (ret != 0) { 418 if (ret != 0)
402 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR " 419 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
403 "(%i)\n", ret);
404 }
405 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */ 420 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
406 msleep(20); 421 msleep(20);
407 /* Now set for normal operation */ 422 /* Now set for normal operation */
@@ -417,7 +432,6 @@ static void or51211_sleep(struct dvb_frontend * fe)
417} 432}
418 433
419static struct or51211_config or51211_config = { 434static struct or51211_config or51211_config = {
420
421 .demod_address = 0x15, 435 .demod_address = 0x15,
422 .request_firmware = or51211_request_firmware, 436 .request_firmware = or51211_request_firmware,
423 .setmode = or51211_setmode, 437 .setmode = or51211_setmode,
@@ -425,7 +439,6 @@ static struct or51211_config or51211_config = {
425 .sleep = or51211_sleep, 439 .sleep = or51211_sleep,
426}; 440};
427 441
428
429static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 442static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
430{ 443{
431 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 444 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
@@ -454,12 +467,84 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten
454} 467}
455 468
456static struct nxt6000_config vp3021_alps_tded4_config = { 469static struct nxt6000_config vp3021_alps_tded4_config = {
457
458 .demod_address = 0x0a, 470 .demod_address = 0x0a,
459 .clock_inversion = 1, 471 .clock_inversion = 1,
460 .pll_set = vp3021_alps_tded4_pll_set, 472 .pll_set = vp3021_alps_tded4_pll_set,
461}; 473};
462 474
475static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
476{
477 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
478 static u8 mt352_reset [] = { 0x50, 0x80 };
479 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
480 static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
481 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
482
483 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
484 udelay(2000);
485 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
486 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
487 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
488 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
489
490 return 0;
491}
492
493static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
494{
495 u32 div;
496 struct dvb_ofdm_parameters *op = &params->u.ofdm;
497
498 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
499
500 pllbuf[0] = 0xc2;
501 pllbuf[1] = (div >> 8) & 0x7F;
502 pllbuf[2] = div & 0xFF;
503 pllbuf[3] = 0x85;
504
505 dprintk("frequency %u, div %u\n", params->frequency, div);
506
507 if (params->frequency < 470000000)
508 pllbuf[4] = 0x02;
509 else if (params->frequency > 823000000)
510 pllbuf[4] = 0x88;
511 else
512 pllbuf[4] = 0x08;
513
514 if (op->bandwidth == 8)
515 pllbuf[4] |= 0x04;
516
517 return 0;
518}
519
520static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
521{
522 /*
523 * Reset the frontend, must be called before trying
524 * to initialise the MT352 or mt352_attach
525 * will fail.
526 *
527 * Presumably not required for the NXT6000 frontend.
528 *
529 */
530
531 int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
532 if (ret != 0)
533 printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
534
535 /* Pulse the reset line */
536 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
537 bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */
538 msleep(100);
539
540 bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
541}
542
543static struct mt352_config digitv_alps_tded4_config = {
544 .demod_address = 0x0a,
545 .demod_init = digitv_alps_tded4_demod_init,
546 .pll_set = digitv_alps_tded4_pll_set,
547};
463 548
464static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 549static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
465{ 550{
@@ -473,7 +558,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
473 if (card->fe != NULL) { 558 if (card->fe != NULL) {
474 card->fe->ops->info.frequency_min = 174000000; 559 card->fe->ops->info.frequency_min = 174000000;
475 card->fe->ops->info.frequency_max = 862000000; 560 card->fe->ops->info.frequency_max = 862000000;
476 break;
477 } 561 }
478 break; 562 break;
479#endif 563#endif
@@ -483,17 +567,28 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
483#else 567#else
484 case BTTV_NEBULA_DIGITV: 568 case BTTV_NEBULA_DIGITV:
485#endif 569#endif
570 /*
571 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
572 * this would be a cleaner solution than trying each frontend in turn.
573 */
574
575 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
486 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 576 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
487 if (card->fe != NULL) { 577 if (card->fe != NULL) {
578 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
488 break; 579 break;
489 } 580 }
581
582 /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
583 digitv_alps_tded4_reset(card);
584 card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
585
586 if (card->fe != NULL)
587 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
490 break; 588 break;
491 589
492 case BTTV_AVDVBT_761: 590 case BTTV_AVDVBT_761:
493 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 591 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
494 if (card->fe != NULL) {
495 break;
496 }
497 break; 592 break;
498 593
499 case BTTV_AVDVBT_771: 594 case BTTV_AVDVBT_771:
@@ -501,7 +596,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
501 if (card->fe != NULL) { 596 if (card->fe != NULL) {
502 card->fe->ops->info.frequency_min = 174000000; 597 card->fe->ops->info.frequency_min = 174000000;
503 card->fe->ops->info.frequency_max = 862000000; 598 card->fe->ops->info.frequency_max = 862000000;
504 break;
505 } 599 }
506 break; 600 break;
507 601
@@ -522,54 +616,41 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
522 616
523 /* Attach other DST peripherals if any */ 617 /* Attach other DST peripherals if any */
524 /* Conditional Access device */ 618 /* Conditional Access device */
525 if (state->dst_hw_cap & DST_TYPE_HAS_CA) { 619 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
526 ret = dst_ca_attach(state, &card->dvb_adapter); 620 ret = dst_ca_attach(state, &card->dvb_adapter);
527 }
528 if (card->fe != NULL) {
529 break;
530 }
531 break; 621 break;
532 622
533 case BTTV_PINNACLESAT: 623 case BTTV_PINNACLESAT:
534 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 624 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
535 if (card->fe != NULL) {
536 break;
537 }
538 break; 625 break;
539 626
540 case BTTV_PC_HDTV: 627 case BTTV_PC_HDTV:
541 card->fe = or51211_attach(&or51211_config, card->i2c_adapter); 628 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
542 if (card->fe != NULL) {
543 break;
544 }
545 break; 629 break;
546 } 630 }
547 631
548 if (card->fe == NULL) { 632 if (card->fe == NULL)
549 printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 633 printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
550 card->bt->dev->vendor, 634 card->bt->dev->vendor,
551 card->bt->dev->device, 635 card->bt->dev->device,
552 card->bt->dev->subsystem_vendor, 636 card->bt->dev->subsystem_vendor,
553 card->bt->dev->subsystem_device); 637 card->bt->dev->subsystem_device);
554 } else { 638 else
555 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { 639 if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
556 printk("dvb-bt8xx: Frontend registration failed!\n"); 640 printk("dvb-bt8xx: Frontend registration failed!\n");
557 if (card->fe->ops->release) 641 if (card->fe->ops->release)
558 card->fe->ops->release(card->fe); 642 card->fe->ops->release(card->fe);
559 card->fe = NULL; 643 card->fe = NULL;
560 } 644 }
561 }
562} 645}
563 646
564static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) 647static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
565{ 648{
566 int result; 649 int result;
567 650
568 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, 651 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
569 THIS_MODULE)) < 0) {
570 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); 652 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
571 return result; 653 return result;
572
573 } 654 }
574 card->dvb_adapter.priv = card; 655 card->dvb_adapter.priv = card;
575 656
@@ -664,8 +745,7 @@ static int dvb_bt8xx_probe(struct device *dev)
664 strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); 745 strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
665 card->i2c_adapter = &sub->core->i2c_adap; 746 card->i2c_adapter = &sub->core->i2c_adap;
666 747
667 switch(sub->core->type) 748 switch(sub->core->type) {
668 {
669 case BTTV_PINNACLESAT: 749 case BTTV_PINNACLESAT:
670 card->gpio_mode = 0x0400c060; 750 card->gpio_mode = 0x0400c060;
671 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 751 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
@@ -751,7 +831,6 @@ static int dvb_bt8xx_probe(struct device *dev)
751 831
752 kfree(card); 832 kfree(card);
753 return -EFAULT; 833 return -EFAULT;
754
755 } 834 }
756 835
757 init_MUTEX(&card->bt->gpio_lock); 836 init_MUTEX(&card->bt->gpio_lock);
@@ -779,7 +858,8 @@ static int dvb_bt8xx_remove(struct device *dev)
779 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); 858 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
780 dvb_dmxdev_release(&card->dmxdev); 859 dvb_dmxdev_release(&card->dmxdev);
781 dvb_dmx_release(&card->demux); 860 dvb_dmx_release(&card->demux);
782 if (card->fe) dvb_unregister_frontend(card->fe); 861 if (card->fe)
862 dvb_unregister_frontend(card->fe);
783 dvb_unregister_adapter(&card->dvb_adapter); 863 dvb_unregister_adapter(&card->dvb_adapter);
784 864
785 kfree(card); 865 kfree(card);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 2923b3b0dd3c..9ec8e5bd6c1f 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -2,7 +2,7 @@
2 * Bt8xx based DVB adapter driver 2 * Bt8xx based DVB adapter driver
3 * 3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org> 4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
5 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> 5 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
6 * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH 6 * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
7 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> 7 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
8 * 8 *
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 226714085f58..7cf4c4a888ec 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
77config DVB_CINERGYT2_RC_QUERY_INTERVAL 77config DVB_CINERGYT2_RC_QUERY_INTERVAL
78 int "Infrared Remote Controller update interval [milliseconds]" 78 int "Infrared Remote Controller update interval [milliseconds]"
79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
80 default "100" 80 default "50"
81 help 81 help
82 If you have a very fast-repeating remote control you can try lower 82 If you have a very fast-repeating remote control you can try lower
83 values, for normal consumer receivers the default value should be 83 values, for normal consumer receivers the default value should be
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 9ea5747b1211..6db0929ef53d 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -25,7 +25,6 @@
25#include <linux/config.h> 25#include <linux/config.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <linux/usb.h> 29#include <linux/usb.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
@@ -36,7 +35,6 @@
36#include "dvb_demux.h" 35#include "dvb_demux.h"
37#include "dvb_net.h" 36#include "dvb_net.h"
38 37
39
40#ifdef CONFIG_DVB_CINERGYT2_TUNING 38#ifdef CONFIG_DVB_CINERGYT2_TUNING
41 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT) 39 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
42 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE) 40 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
@@ -49,7 +47,7 @@
49 #define STREAM_URB_COUNT (32) 47 #define STREAM_URB_COUNT (32)
50 #define STREAM_BUF_SIZE (512) /* bytes */ 48 #define STREAM_BUF_SIZE (512) /* bytes */
51 #define ENABLE_RC (1) 49 #define ENABLE_RC (1)
52 #define RC_QUERY_INTERVAL (100) /* milliseconds */ 50 #define RC_QUERY_INTERVAL (50) /* milliseconds */
53 #define QUERY_INTERVAL (333) /* milliseconds */ 51 #define QUERY_INTERVAL (333) /* milliseconds */
54#endif 52#endif
55 53
@@ -142,6 +140,8 @@ struct cinergyt2 {
142 struct input_dev rc_input_dev; 140 struct input_dev rc_input_dev;
143 struct work_struct rc_query_work; 141 struct work_struct rc_query_work;
144 int rc_input_event; 142 int rc_input_event;
143 u32 rc_last_code;
144 unsigned long last_event_jiffies;
145#endif 145#endif
146}; 146};
147 147
@@ -156,7 +156,7 @@ struct cinergyt2_rc_event {
156 uint32_t value; 156 uint32_t value;
157} __attribute__((packed)); 157} __attribute__((packed));
158 158
159static const uint32_t rc_keys [] = { 159static const uint32_t rc_keys[] = {
160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER, 160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1, 161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
162 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2, 162 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
@@ -685,52 +685,68 @@ static struct dvb_device cinergyt2_fe_template = {
685#ifdef ENABLE_RC 685#ifdef ENABLE_RC
686static void cinergyt2_query_rc (void *data) 686static void cinergyt2_query_rc (void *data)
687{ 687{
688 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; 688 struct cinergyt2 *cinergyt2 = data;
689 char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS }; 689 char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
690 struct cinergyt2_rc_event rc_events[12]; 690 struct cinergyt2_rc_event rc_events[12];
691 int n, len; 691 int n, len, i;
692 692
693 if (down_interruptible(&cinergyt2->sem)) 693 if (down_interruptible(&cinergyt2->sem))
694 return; 694 return;
695 695
696 len = cinergyt2_command(cinergyt2, buf, sizeof(buf), 696 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
697 (char *) rc_events, sizeof(rc_events)); 697 (char *) rc_events, sizeof(rc_events));
698 698 if (len < 0)
699 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) { 699 goto out;
700 int i; 700 if (len == 0) {
701 if (time_after(jiffies, cinergyt2->last_event_jiffies +
702 msecs_to_jiffies(150))) {
703 /* stop key repeat */
704 if (cinergyt2->rc_input_event != KEY_MAX) {
705 dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
706 input_report_key(&cinergyt2->rc_input_dev,
707 cinergyt2->rc_input_event, 0);
708 cinergyt2->rc_input_event = KEY_MAX;
709 }
710 cinergyt2->rc_last_code = ~0;
711 }
712 goto out;
713 }
714 cinergyt2->last_event_jiffies = jiffies;
701 715
702/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/ 716 for (n = 0; n < (len / sizeof(rc_events[0])); n++) {
717 dprintk(1, "rc_events[%d].value = %x, type=%x\n",
718 n, le32_to_cpu(rc_events[n].value), rc_events[n].type);
703 719
704 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && 720 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
705 rc_events[n].value == ~0) 721 rc_events[n].value == ~0) {
706 { 722 /* keyrepeat bit -> just repeat last rc_input_event */
707 /**
708 * keyrepeat bit. If we would handle this properly
709 * we would need to emit down events as long the
710 * keyrepeat goes, a up event if no further
711 * repeat bits occur. Would need a timer to implement
712 * and no other driver does this, so we simply
713 * emit the last key up/down sequence again.
714 */
715 } else { 723 } else {
716 cinergyt2->rc_input_event = KEY_MAX; 724 cinergyt2->rc_input_event = KEY_MAX;
717 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) { 725 for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
718 if (rc_keys[i+0] == rc_events[n].type && 726 if (rc_keys[i + 0] == rc_events[n].type &&
719 rc_keys[i+1] == le32_to_cpu(rc_events[n].value)) 727 rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
720 { 728 cinergyt2->rc_input_event = rc_keys[i + 2];
721 cinergyt2->rc_input_event = rc_keys[i+2];
722 break; 729 break;
723 } 730 }
724 } 731 }
725 } 732 }
726 733
727 if (cinergyt2->rc_input_event != KEY_MAX) { 734 if (cinergyt2->rc_input_event != KEY_MAX) {
728 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1); 735 if (rc_events[n].value == cinergyt2->rc_last_code &&
729 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0); 736 cinergyt2->rc_last_code != ~0) {
730 input_sync(&cinergyt2->rc_input_dev); 737 /* emit a key-up so the double event is recognized */
738 dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
739 input_report_key(&cinergyt2->rc_input_dev,
740 cinergyt2->rc_input_event, 0);
741 }
742 dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
743 input_report_key(&cinergyt2->rc_input_dev,
744 cinergyt2->rc_input_event, 1);
745 cinergyt2->rc_last_code = rc_events[n].value;
731 } 746 }
732 } 747 }
733 748
749out:
734 schedule_delayed_work(&cinergyt2->rc_query_work, 750 schedule_delayed_work(&cinergyt2->rc_query_work,
735 msecs_to_jiffies(RC_QUERY_INTERVAL)); 751 msecs_to_jiffies(RC_QUERY_INTERVAL));
736 752
@@ -772,7 +788,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
772 const struct usb_device_id *id) 788 const struct usb_device_id *id)
773{ 789{
774 struct cinergyt2 *cinergyt2; 790 struct cinergyt2 *cinergyt2;
775 int i, err; 791 int err;
792#ifdef ENABLE_RC
793 int i;
794#endif
776 795
777 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { 796 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
778 dprintk(1, "out of memory?!?\n"); 797 dprintk(1, "out of memory?!?\n");
@@ -828,19 +847,18 @@ static int cinergyt2_probe (struct usb_interface *intf,
828 DVB_DEVICE_FRONTEND); 847 DVB_DEVICE_FRONTEND);
829 848
830#ifdef ENABLE_RC 849#ifdef ENABLE_RC
831 init_input_dev(&cinergyt2->rc_input_dev); 850 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
832 851 cinergyt2->rc_input_dev.keycodesize = 0;
833 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY); 852 cinergyt2->rc_input_dev.keycodemax = 0;
834 cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
835 cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
836 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control"; 853 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
837 854
838 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) 855 for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
839 set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit); 856 set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
840 857
841 input_register_device(&cinergyt2->rc_input_dev); 858 input_register_device(&cinergyt2->rc_input_dev);
842 859
843 cinergyt2->rc_input_event = KEY_MAX; 860 cinergyt2->rc_input_event = KEY_MAX;
861 cinergyt2->rc_last_code = ~0;
844 862
845 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); 863 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
846 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); 864 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index fb55eaa5c8e7..9719a3b30f78 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -30,6 +30,7 @@
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/time.h> 32#include <linux/time.h>
33#include <linux/dvb/dmx.h>
33 34
34/*--------------------------------------------------------------------------*/ 35/*--------------------------------------------------------------------------*/
35/* Common definitions */ 36/* Common definitions */
@@ -124,9 +125,7 @@ struct dmx_ts_feed {
124 u16 pid, 125 u16 pid,
125 int type, 126 int type,
126 enum dmx_ts_pes pes_type, 127 enum dmx_ts_pes pes_type,
127 size_t callback_length,
128 size_t circular_buffer_size, 128 size_t circular_buffer_size,
129 int descramble,
130 struct timespec timeout); 129 struct timespec timeout);
131 int (*start_filtering) (struct dmx_ts_feed* feed); 130 int (*start_filtering) (struct dmx_ts_feed* feed);
132 int (*stop_filtering) (struct dmx_ts_feed* feed); 131 int (*stop_filtering) (struct dmx_ts_feed* feed);
@@ -159,7 +158,6 @@ struct dmx_section_feed {
159 int (*set) (struct dmx_section_feed* feed, 158 int (*set) (struct dmx_section_feed* feed,
160 u16 pid, 159 u16 pid,
161 size_t circular_buffer_size, 160 size_t circular_buffer_size,
162 int descramble,
163 int check_crc); 161 int check_crc);
164 int (*allocate_filter) (struct dmx_section_feed* feed, 162 int (*allocate_filter) (struct dmx_section_feed* feed,
165 struct dmx_section_filter** filter); 163 struct dmx_section_filter** filter);
@@ -207,7 +205,6 @@ struct dmx_frontend {
207 struct list_head connectivity_list; /* List of front-ends that can 205 struct list_head connectivity_list; /* List of front-ends that can
208 be connected to a particular 206 be connected to a particular
209 demux */ 207 demux */
210 void* priv; /* Pointer to private data of the API client */
211 enum dmx_frontend_source source; 208 enum dmx_frontend_source source;
212}; 209};
213 210
@@ -225,8 +222,6 @@ struct dmx_frontend {
225#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ 222#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
226#define DMX_CRC_CHECKING 16 223#define DMX_CRC_CHECKING 16
227#define DMX_TS_DESCRAMBLING 32 224#define DMX_TS_DESCRAMBLING 32
228#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
229#define DMX_MAC_ADDRESS_DESCRAMBLING 128
230 225
231/* 226/*
232 * Demux resource type identifier. 227 * Demux resource type identifier.
@@ -244,9 +239,7 @@ struct dmx_frontend {
244struct dmx_demux { 239struct dmx_demux {
245 u32 capabilities; /* Bitfield of capability flags */ 240 u32 capabilities; /* Bitfield of capability flags */
246 struct dmx_frontend* frontend; /* Front-end connected to the demux */ 241 struct dmx_frontend* frontend; /* Front-end connected to the demux */
247 struct list_head reg_list; /* List of registered demuxes */
248 void* priv; /* Pointer to private data of the API client */ 242 void* priv; /* Pointer to private data of the API client */
249 int users; /* Number of users */
250 int (*open) (struct dmx_demux* demux); 243 int (*open) (struct dmx_demux* demux);
251 int (*close) (struct dmx_demux* demux); 244 int (*close) (struct dmx_demux* demux);
252 int (*write) (struct dmx_demux* demux, const char* buf, size_t count); 245 int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
@@ -260,17 +253,6 @@ struct dmx_demux {
260 dmx_section_cb callback); 253 dmx_section_cb callback);
261 int (*release_section_feed) (struct dmx_demux* demux, 254 int (*release_section_feed) (struct dmx_demux* demux,
262 struct dmx_section_feed* feed); 255 struct dmx_section_feed* feed);
263 int (*descramble_mac_address) (struct dmx_demux* demux,
264 u8* buffer1,
265 size_t buffer1_length,
266 u8* buffer2,
267 size_t buffer2_length,
268 u16 pid);
269 int (*descramble_section_payload) (struct dmx_demux* demux,
270 u8* buffer1,
271 size_t buffer1_length,
272 u8* buffer2, size_t buffer2_length,
273 u16 pid);
274 int (*add_frontend) (struct dmx_demux* demux, 256 int (*add_frontend) (struct dmx_demux* demux,
275 struct dmx_frontend* frontend); 257 struct dmx_frontend* frontend);
276 int (*remove_frontend) (struct dmx_demux* demux, 258 int (*remove_frontend) (struct dmx_demux* demux,
@@ -282,20 +264,12 @@ struct dmx_demux {
282 264
283 int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids); 265 int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
284 266
267 int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
268
269 int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
270
285 int (*get_stc) (struct dmx_demux* demux, unsigned int num, 271 int (*get_stc) (struct dmx_demux* demux, unsigned int num,
286 u64 *stc, unsigned int *base); 272 u64 *stc, unsigned int *base);
287}; 273};
288 274
289/*--------------------------------------------------------------------------*/
290/* Demux directory */
291/*--------------------------------------------------------------------------*/
292
293/*
294 * DMX_DIR_ENTRY(): Casts elements in the list of registered
295 * demuxes from the generic type struct list_head* to the type struct dmx_demux
296 *.
297 */
298
299#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list)
300
301#endif /* #ifndef __DEMUX_H */ 275#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 68050cd527cb..8028c3a5e287 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -571,7 +571,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
571 return ret; 571 return ret;
572 } 572 }
573 573
574 ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0, 574 ret=(*secfeed)->set(*secfeed, para->pid, 32768,
575 (para->flags & DMX_CHECK_CRC) ? 1 : 0); 575 (para->flags & DMX_CHECK_CRC) ? 1 : 0);
576 576
577 if (ret<0) { 577 if (ret<0) {
@@ -654,7 +654,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
654 (*tsfeed)->priv = (void *) filter; 654 (*tsfeed)->priv = (void *) filter;
655 655
656 ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, 656 ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
657 188, 32768, 0, timeout); 657 32768, timeout);
658 658
659 if (ret < 0) { 659 if (ret < 0) {
660 dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed); 660 dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
@@ -929,6 +929,22 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
929 dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg); 929 dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
930 break; 930 break;
931 931
932 case DMX_GET_CAPS:
933 if (!dmxdev->demux->get_caps) {
934 ret = -EINVAL;
935 break;
936 }
937 ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
938 break;
939
940 case DMX_SET_SOURCE:
941 if (!dmxdev->demux->set_source) {
942 ret = -EINVAL;
943 break;
944 }
945 ret = dmxdev->demux->set_source(dmxdev->demux, parg);
946 break;
947
932 case DMX_GET_STC: 948 case DMX_GET_STC:
933 if (!dmxdev->demux->get_stc) { 949 if (!dmxdev->demux->get_stc) {
934 ret=-EINVAL; 950 ret=-EINVAL;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 0eb9aa711fb0..88757e2634e5 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -47,7 +47,7 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
47 47
48#define dprintk if (dvb_ca_en50221_debug) printk 48#define dprintk if (dvb_ca_en50221_debug) printk
49 49
50#define INIT_TIMEOUT_SECS 5 50#define INIT_TIMEOUT_SECS 10
51 51
52#define HOST_LINK_BUF_SIZE 0x200 52#define HOST_LINK_BUF_SIZE 0x200
53 53
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index ac9889d22288..dc476dda2b71 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -38,82 +38,52 @@
38*/ 38*/
39// #define DVB_DEMUX_SECTION_LOSS_LOG 39// #define DVB_DEMUX_SECTION_LOSS_LOG
40 40
41
42static LIST_HEAD(dmx_muxs);
43
44
45static int dmx_register_demux(struct dmx_demux *demux)
46{
47 demux->users = 0;
48 list_add(&demux->reg_list, &dmx_muxs);
49 return 0;
50}
51
52static int dmx_unregister_demux(struct dmx_demux* demux)
53{
54 struct list_head *pos, *n, *head=&dmx_muxs;
55
56 list_for_each_safe (pos, n, head) {
57 if (DMX_DIR_ENTRY(pos) == demux) {
58 if (demux->users>0)
59 return -EINVAL;
60 list_del(pos);
61 return 0;
62 }
63 }
64
65 return -ENODEV;
66}
67
68
69/****************************************************************************** 41/******************************************************************************
70 * static inlined helper functions 42 * static inlined helper functions
71 ******************************************************************************/ 43 ******************************************************************************/
72 44
73
74static inline u16 section_length(const u8 *buf) 45static inline u16 section_length(const u8 *buf)
75{ 46{
76 return 3+((buf[1]&0x0f)<<8)+buf[2]; 47 return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
77} 48}
78 49
79
80static inline u16 ts_pid(const u8 *buf) 50static inline u16 ts_pid(const u8 *buf)
81{ 51{
82 return ((buf[1]&0x1f)<<8)+buf[2]; 52 return ((buf[1] & 0x1f) << 8) + buf[2];
83} 53}
84 54
85
86static inline u8 payload(const u8 *tsp) 55static inline u8 payload(const u8 *tsp)
87{ 56{
88 if (!(tsp[3] & 0x10)) // no payload? 57 if (!(tsp[3] & 0x10)) // no payload?
89 return 0; 58 return 0;
90 if (tsp[3] & 0x20) { // adaptation field? 59
91 if (tsp[4] > 183) // corrupted data? 60 if (tsp[3] & 0x20) { // adaptation field?
61 if (tsp[4] > 183) // corrupted data?
92 return 0; 62 return 0;
93 else 63 else
94 return 184-1-tsp[4]; 64 return 184 - 1 - tsp[4];
95 } 65 }
66
96 return 184; 67 return 184;
97} 68}
98 69
99 70static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len)
100static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
101{ 71{
102 return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len)); 72 return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len));
103} 73}
104 74
105 75static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s,
106static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len) 76 size_t len)
107{ 77{
108 memcpy (d, s, len); 78 memcpy(d, s, len);
109} 79}
110 80
111
112/****************************************************************************** 81/******************************************************************************
113 * Software filter functions 82 * Software filter functions
114 ******************************************************************************/ 83 ******************************************************************************/
115 84
116static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf) 85static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
86 const u8 *buf)
117{ 87{
118 int count = payload(buf); 88 int count = payload(buf);
119 int p; 89 int p;
@@ -123,32 +93,31 @@ static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u
123 if (count == 0) 93 if (count == 0)
124 return -1; 94 return -1;
125 95
126 p = 188-count; 96 p = 188 - count;
127 97
128 /* 98 /*
129 cc=buf[3]&0x0f; 99 cc = buf[3] & 0x0f;
130 ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0; 100 ccok = ((feed->cc + 1) & 0x0f) == cc;
131 dvbdmxfeed->cc=cc; 101 feed->cc = cc;
132 if (!ccok) 102 if (!ccok)
133 printk("missed packet!\n"); 103 printk("missed packet!\n");
134 */ 104 */
135 105
136 if (buf[1] & 0x40) // PUSI ? 106 if (buf[1] & 0x40) // PUSI ?
137 feed->peslen = 0xfffa; 107 feed->peslen = 0xfffa;
138 108
139 feed->peslen += count; 109 feed->peslen += count;
140 110
141 return feed->cb.ts (&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK); 111 return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
142} 112}
143 113
144 114static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
145static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed, 115 struct dvb_demux_filter *f)
146 struct dvb_demux_filter *f)
147{ 116{
148 u8 neq = 0; 117 u8 neq = 0;
149 int i; 118 int i;
150 119
151 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) { 120 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
152 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i]; 121 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
153 122
154 if (f->maskandmode[i] & xor) 123 if (f->maskandmode[i] & xor)
@@ -160,12 +129,11 @@ static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
160 if (f->doneq && !neq) 129 if (f->doneq && !neq)
161 return 0; 130 return 0;
162 131
163 return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen, 132 return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
164 NULL, 0, &f->filter, DMX_OK); 133 NULL, 0, &f->filter, DMX_OK);
165} 134}
166 135
167 136static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
168static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
169{ 137{
170 struct dvb_demux *demux = feed->demux; 138 struct dvb_demux *demux = feed->demux;
171 struct dvb_demux_filter *f = feed->filter; 139 struct dvb_demux_filter *f = feed->filter;
@@ -195,26 +163,24 @@ static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
195 return 0; 163 return 0;
196} 164}
197 165
198
199static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) 166static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
200{ 167{
201 struct dmx_section_feed *sec = &feed->feed.sec; 168 struct dmx_section_feed *sec = &feed->feed.sec;
202 169
203#ifdef DVB_DEMUX_SECTION_LOSS_LOG 170#ifdef DVB_DEMUX_SECTION_LOSS_LOG
204 if(sec->secbufp < sec->tsfeedp) 171 if (sec->secbufp < sec->tsfeedp) {
205 {
206 int i, n = sec->tsfeedp - sec->secbufp; 172 int i, n = sec->tsfeedp - sec->secbufp;
207 173
208 /* section padding is done with 0xff bytes entirely. 174 /*
209 ** due to speed reasons, we won't check all of them 175 * Section padding is done with 0xff bytes entirely.
210 ** but just first and last 176 * Due to speed reasons, we won't check all of them
211 */ 177 * but just first and last.
212 if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff) 178 */
213 { 179 if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
214 printk("dvb_demux.c section ts padding loss: %d/%d\n", 180 printk("dvb_demux.c section ts padding loss: %d/%d\n",
215 n, sec->tsfeedp); 181 n, sec->tsfeedp);
216 printk("dvb_demux.c pad data:"); 182 printk("dvb_demux.c pad data:");
217 for(i = 0; i < n; i++) 183 for (i = 0; i < n; i++)
218 printk(" %02x", sec->secbuf[i]); 184 printk(" %02x", sec->secbuf[i]);
219 printk("\n"); 185 printk("\n");
220 } 186 }
@@ -226,82 +192,81 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
226} 192}
227 193
228/* 194/*
229** Losless Section Demux 1.4.1 by Emard 195 * Losless Section Demux 1.4.1 by Emard
230** Valsecchi Patrick: 196 * Valsecchi Patrick:
231** - middle of section A (no PUSI) 197 * - middle of section A (no PUSI)
232** - end of section A and start of section B 198 * - end of section A and start of section B
233** (with PUSI pointing to the start of the second section) 199 * (with PUSI pointing to the start of the second section)
234** 200 *
235** In this case, without feed->pusi_seen you'll receive a garbage section 201 * In this case, without feed->pusi_seen you'll receive a garbage section
236** consisting of the end of section A. Basically because tsfeedp 202 * consisting of the end of section A. Basically because tsfeedp
237** is incemented and the use=0 condition is not raised 203 * is incemented and the use=0 condition is not raised
238** when the second packet arrives. 204 * when the second packet arrives.
239** 205 *
240** Fix: 206 * Fix:
241** when demux is started, let feed->pusi_seen = 0 to 207 * when demux is started, let feed->pusi_seen = 0 to
242** prevent initial feeding of garbage from the end of 208 * prevent initial feeding of garbage from the end of
243** previous section. When you for the first time see PUSI=1 209 * previous section. When you for the first time see PUSI=1
244** then set feed->pusi_seen = 1 210 * then set feed->pusi_seen = 1
245*/ 211 */
246static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len) 212static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
213 const u8 *buf, u8 len)
247{ 214{
248 struct dvb_demux *demux = feed->demux; 215 struct dvb_demux *demux = feed->demux;
249 struct dmx_section_feed *sec = &feed->feed.sec; 216 struct dmx_section_feed *sec = &feed->feed.sec;
250 u16 limit, seclen, n; 217 u16 limit, seclen, n;
251 218
252 if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE) 219 if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
253 return 0; 220 return 0;
254 221
255 if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) 222 if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
256 {
257#ifdef DVB_DEMUX_SECTION_LOSS_LOG 223#ifdef DVB_DEMUX_SECTION_LOSS_LOG
258 printk("dvb_demux.c section buffer full loss: %d/%d\n", 224 printk("dvb_demux.c section buffer full loss: %d/%d\n",
259 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE); 225 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
226 DMX_MAX_SECFEED_SIZE);
260#endif 227#endif
261 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; 228 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
262 } 229 }
263 230
264 if(len <= 0) 231 if (len <= 0)
265 return 0; 232 return 0;
266 233
267 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len); 234 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
268 sec->tsfeedp += len; 235 sec->tsfeedp += len;
269 236
270 /* ----------------------------------------------------- 237 /*
271 ** Dump all the sections we can find in the data (Emard) 238 * Dump all the sections we can find in the data (Emard)
272 */ 239 */
273
274 limit = sec->tsfeedp; 240 limit = sec->tsfeedp;
275 if(limit > DMX_MAX_SECFEED_SIZE) 241 if (limit > DMX_MAX_SECFEED_SIZE)
276 return -1; /* internal error should never happen */ 242 return -1; /* internal error should never happen */
277 243
278 /* to be sure always set secbuf */ 244 /* to be sure always set secbuf */
279 sec->secbuf = sec->secbuf_base + sec->secbufp; 245 sec->secbuf = sec->secbuf_base + sec->secbufp;
280 246
281 for(n = 0; sec->secbufp + 2 < limit; n++) 247 for (n = 0; sec->secbufp + 2 < limit; n++) {
282 {
283 seclen = section_length(sec->secbuf); 248 seclen = section_length(sec->secbuf);
284 if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 249 if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
285 || seclen + sec->secbufp > limit) 250 || seclen + sec->secbufp > limit)
286 return 0; 251 return 0;
287 sec->seclen = seclen; 252 sec->seclen = seclen;
288 sec->crc_val = ~0; 253 sec->crc_val = ~0;
289 /* dump [secbuf .. secbuf+seclen) */ 254 /* dump [secbuf .. secbuf+seclen) */
290 if(feed->pusi_seen) 255 if (feed->pusi_seen)
291 dvb_dmx_swfilter_section_feed(feed); 256 dvb_dmx_swfilter_section_feed(feed);
292#ifdef DVB_DEMUX_SECTION_LOSS_LOG 257#ifdef DVB_DEMUX_SECTION_LOSS_LOG
293 else 258 else
294 printk("dvb_demux.c pusi not seen, discarding section data\n"); 259 printk("dvb_demux.c pusi not seen, discarding section data\n");
295#endif 260#endif
296 sec->secbufp += seclen; /* secbufp and secbuf moving together is */ 261 sec->secbufp += seclen; /* secbufp and secbuf moving together is */
297 sec->secbuf += seclen; /* redundand but saves pointer arithmetic */ 262 sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
298 } 263 }
299 264
300 return 0; 265 return 0;
301} 266}
302 267
303 268static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
304static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 269 const u8 *buf)
305{ 270{
306 u8 p, count; 271 u8 p, count;
307 int ccok, dc_i = 0; 272 int ccok, dc_i = 0;
@@ -309,10 +274,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
309 274
310 count = payload(buf); 275 count = payload(buf);
311 276
312 if (count == 0) /* count == 0 if no payload or out of range */ 277 if (count == 0) /* count == 0 if no payload or out of range */
313 return -1; 278 return -1;
314 279
315 p = 188 - count; /* payload start */ 280 p = 188 - count; /* payload start */
316 281
317 cc = buf[3] & 0x0f; 282 cc = buf[3] & 0x0f;
318 ccok = ((feed->cc + 1) & 0x0f) == cc; 283 ccok = ((feed->cc + 1) & 0x0f) == cc;
@@ -326,52 +291,53 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
326 291
327 if (!ccok || dc_i) { 292 if (!ccok || dc_i) {
328#ifdef DVB_DEMUX_SECTION_LOSS_LOG 293#ifdef DVB_DEMUX_SECTION_LOSS_LOG
329 printk("dvb_demux.c discontinuity detected %d bytes lost\n", count); 294 printk("dvb_demux.c discontinuity detected %d bytes lost\n",
330 /* those bytes under sume circumstances will again be reported 295 count);
331 ** in the following dvb_dmx_swfilter_section_new 296 /*
332 */ 297 * those bytes under sume circumstances will again be reported
298 * in the following dvb_dmx_swfilter_section_new
299 */
333#endif 300#endif
334 /* Discontinuity detected. Reset pusi_seen = 0 to 301 /*
335 ** stop feeding of suspicious data until next PUSI=1 arrives 302 * Discontinuity detected. Reset pusi_seen = 0 to
336 */ 303 * stop feeding of suspicious data until next PUSI=1 arrives
304 */
337 feed->pusi_seen = 0; 305 feed->pusi_seen = 0;
338 dvb_dmx_swfilter_section_new(feed); 306 dvb_dmx_swfilter_section_new(feed);
339 return 0;
340 } 307 }
341 308
342 if (buf[1] & 0x40) { 309 if (buf[1] & 0x40) {
343 // PUSI=1 (is set), section boundary is here 310 /* PUSI=1 (is set), section boundary is here */
344 if (count > 1 && buf[p] < count) { 311 if (count > 1 && buf[p] < count) {
345 const u8 *before = buf+p+1; 312 const u8 *before = &buf[p + 1];
346 u8 before_len = buf[p]; 313 u8 before_len = buf[p];
347 const u8 *after = before+before_len; 314 const u8 *after = &before[before_len];
348 u8 after_len = count-1-before_len; 315 u8 after_len = count - 1 - before_len;
349 316
350 dvb_dmx_swfilter_section_copy_dump(feed, before, before_len); 317 dvb_dmx_swfilter_section_copy_dump(feed, before,
318 before_len);
351 /* before start of new section, set pusi_seen = 1 */ 319 /* before start of new section, set pusi_seen = 1 */
352 feed->pusi_seen = 1; 320 feed->pusi_seen = 1;
353 dvb_dmx_swfilter_section_new(feed); 321 dvb_dmx_swfilter_section_new(feed);
354 dvb_dmx_swfilter_section_copy_dump(feed, after, after_len); 322 dvb_dmx_swfilter_section_copy_dump(feed, after,
323 after_len);
355 } 324 }
356#ifdef DVB_DEMUX_SECTION_LOSS_LOG 325#ifdef DVB_DEMUX_SECTION_LOSS_LOG
357 else 326 else if (count > 0)
358 if (count > 0) 327 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
359 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
360#endif 328#endif
361 } else { 329 } else {
362 // PUSI=0 (is not set), no section boundary 330 /* PUSI=0 (is not set), no section boundary */
363 const u8 *entire = buf+p; 331 dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
364 u8 entire_len = count;
365
366 dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
367 } 332 }
333
368 return 0; 334 return 0;
369} 335}
370 336
371 337static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
372static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf) 338 const u8 *buf)
373{ 339{
374 switch(feed->type) { 340 switch (feed->type) {
375 case DMX_TYPE_TS: 341 case DMX_TYPE_TS:
376 if (!feed->feed.ts.is_filtering) 342 if (!feed->feed.ts.is_filtering)
377 break; 343 break;
@@ -379,7 +345,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
379 if (feed->ts_type & TS_PAYLOAD_ONLY) 345 if (feed->ts_type & TS_PAYLOAD_ONLY)
380 dvb_dmx_swfilter_payload(feed, buf); 346 dvb_dmx_swfilter_payload(feed, buf);
381 else 347 else
382 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 348 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
349 DMX_OK);
383 } 350 }
384 if (feed->ts_type & TS_DECODER) 351 if (feed->ts_type & TS_DECODER)
385 if (feed->demux->write_to_decoder) 352 if (feed->demux->write_to_decoder)
@@ -390,7 +357,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
390 if (!feed->feed.sec.is_filtering) 357 if (!feed->feed.sec.is_filtering)
391 break; 358 break;
392 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0) 359 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
393 feed->feed.sec.seclen = feed->feed.sec.secbufp=0; 360 feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
394 break; 361 break;
395 362
396 default: 363 default:
@@ -406,7 +373,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
406static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) 373static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
407{ 374{
408 struct dvb_demux_feed *feed; 375 struct dvb_demux_feed *feed;
409 struct list_head *pos, *head=&demux->feed_list; 376 struct list_head *pos, *head = &demux->feed_list;
410 u16 pid = ts_pid(buf); 377 u16 pid = ts_pid(buf);
411 int dvr_done = 0; 378 int dvr_done = 0;
412 379
@@ -432,21 +399,21 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
432 } 399 }
433} 400}
434 401
435void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) 402void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
403 size_t count)
436{ 404{
437 spin_lock(&demux->lock); 405 spin_lock(&demux->lock);
438 406
439 while (count--) { 407 while (count--) {
440 if(buf[0] == 0x47) { 408 if (buf[0] == 0x47)
441 dvb_dmx_swfilter_packet(demux, buf); 409 dvb_dmx_swfilter_packet(demux, buf);
442 }
443 buf += 188; 410 buf += 188;
444 } 411 }
445 412
446 spin_unlock(&demux->lock); 413 spin_unlock(&demux->lock);
447} 414}
448EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
449 415
416EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
450 417
451void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) 418void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
452{ 419{
@@ -454,8 +421,10 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
454 421
455 spin_lock(&demux->lock); 422 spin_lock(&demux->lock);
456 423
457 if ((i = demux->tsbufp)) { 424 if (demux->tsbufp) {
458 if (count < (j=188-i)) { 425 i = demux->tsbufp;
426 j = 188 - i;
427 if (count < j) {
459 memcpy(&demux->tsbuf[i], buf, count); 428 memcpy(&demux->tsbuf[i], buf, count);
460 demux->tsbufp += count; 429 demux->tsbufp += count;
461 goto bailout; 430 goto bailout;
@@ -469,13 +438,13 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
469 438
470 while (p < count) { 439 while (p < count) {
471 if (buf[p] == 0x47) { 440 if (buf[p] == 0x47) {
472 if (count-p >= 188) { 441 if (count - p >= 188) {
473 dvb_dmx_swfilter_packet(demux, buf+p); 442 dvb_dmx_swfilter_packet(demux, &buf[p]);
474 p += 188; 443 p += 188;
475 } else { 444 } else {
476 i = count-p; 445 i = count - p;
477 memcpy(demux->tsbuf, buf+p, i); 446 memcpy(demux->tsbuf, &buf[p], i);
478 demux->tsbufp=i; 447 demux->tsbufp = i;
479 goto bailout; 448 goto bailout;
480 } 449 }
481 } else 450 } else
@@ -485,24 +454,29 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
485bailout: 454bailout:
486 spin_unlock(&demux->lock); 455 spin_unlock(&demux->lock);
487} 456}
457
488EXPORT_SYMBOL(dvb_dmx_swfilter); 458EXPORT_SYMBOL(dvb_dmx_swfilter);
489 459
490void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) 460void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
491{ 461{
492 int p = 0,i, j; 462 int p = 0, i, j;
493 u8 tmppack[188]; 463 u8 tmppack[188];
464
494 spin_lock(&demux->lock); 465 spin_lock(&demux->lock);
495 466
496 if ((i = demux->tsbufp)) { 467 if (demux->tsbufp) {
497 if (count < (j=204-i)) { 468 i = demux->tsbufp;
469 j = 204 - i;
470 if (count < j) {
498 memcpy(&demux->tsbuf[i], buf, count); 471 memcpy(&demux->tsbuf[i], buf, count);
499 demux->tsbufp += count; 472 demux->tsbufp += count;
500 goto bailout; 473 goto bailout;
501 } 474 }
502 memcpy(&demux->tsbuf[i], buf, j); 475 memcpy(&demux->tsbuf[i], buf, j);
503 if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8)) { 476 if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) {
504 memcpy(tmppack, demux->tsbuf, 188); 477 memcpy(tmppack, demux->tsbuf, 188);
505 if (tmppack[0] == 0xB8) tmppack[0] = 0x47; 478 if (tmppack[0] == 0xB8)
479 tmppack[0] = 0x47;
506 dvb_dmx_swfilter_packet(demux, tmppack); 480 dvb_dmx_swfilter_packet(demux, tmppack);
507 } 481 }
508 demux->tsbufp = 0; 482 demux->tsbufp = 0;
@@ -510,16 +484,17 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
510 } 484 }
511 485
512 while (p < count) { 486 while (p < count) {
513 if ((buf[p] == 0x47)|(buf[p] == 0xB8)) { 487 if ((buf[p] == 0x47) | (buf[p] == 0xB8)) {
514 if (count-p >= 204) { 488 if (count - p >= 204) {
515 memcpy(tmppack, buf+p, 188); 489 memcpy(tmppack, &buf[p], 188);
516 if (tmppack[0] == 0xB8) tmppack[0] = 0x47; 490 if (tmppack[0] == 0xB8)
491 tmppack[0] = 0x47;
517 dvb_dmx_swfilter_packet(demux, tmppack); 492 dvb_dmx_swfilter_packet(demux, tmppack);
518 p += 204; 493 p += 204;
519 } else { 494 } else {
520 i = count-p; 495 i = count - p;
521 memcpy(demux->tsbuf, buf+p, i); 496 memcpy(demux->tsbuf, &buf[p], i);
522 demux->tsbufp=i; 497 demux->tsbufp = i;
523 goto bailout; 498 goto bailout;
524 } 499 }
525 } else { 500 } else {
@@ -530,14 +505,14 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
530bailout: 505bailout:
531 spin_unlock(&demux->lock); 506 spin_unlock(&demux->lock);
532} 507}
533EXPORT_SYMBOL(dvb_dmx_swfilter_204);
534 508
509EXPORT_SYMBOL(dvb_dmx_swfilter_204);
535 510
536static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux) 511static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
537{ 512{
538 int i; 513 int i;
539 514
540 for (i=0; i<demux->filternum; i++) 515 for (i = 0; i < demux->filternum; i++)
541 if (demux->filter[i].state == DMX_STATE_FREE) 516 if (demux->filter[i].state == DMX_STATE_FREE)
542 break; 517 break;
543 518
@@ -549,11 +524,11 @@ static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
549 return &demux->filter[i]; 524 return &demux->filter[i];
550} 525}
551 526
552static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux) 527static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux)
553{ 528{
554 int i; 529 int i;
555 530
556 for (i=0; i<demux->feednum; i++) 531 for (i = 0; i < demux->feednum; i++)
557 if (demux->feed[i].state == DMX_STATE_FREE) 532 if (demux->feed[i].state == DMX_STATE_FREE)
558 break; 533 break;
559 534
@@ -581,7 +556,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
581 spin_lock_irq(&feed->demux->lock); 556 spin_lock_irq(&feed->demux->lock);
582 if (dvb_demux_feed_find(feed)) { 557 if (dvb_demux_feed_find(feed)) {
583 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n", 558 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
584 __FUNCTION__, feed->type, feed->state, feed->pid); 559 __FUNCTION__, feed->type, feed->state, feed->pid);
585 goto out; 560 goto out;
586 } 561 }
587 562
@@ -595,7 +570,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
595 spin_lock_irq(&feed->demux->lock); 570 spin_lock_irq(&feed->demux->lock);
596 if (!(dvb_demux_feed_find(feed))) { 571 if (!(dvb_demux_feed_find(feed))) {
597 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n", 572 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
598 __FUNCTION__, feed->type, feed->state, feed->pid); 573 __FUNCTION__, feed->type, feed->state, feed->pid);
599 goto out; 574 goto out;
600 } 575 }
601 576
@@ -604,18 +579,17 @@ out:
604 spin_unlock_irq(&feed->demux->lock); 579 spin_unlock_irq(&feed->demux->lock);
605} 580}
606 581
607static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type, 582static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
608 enum dmx_ts_pes pes_type, size_t callback_length, 583 enum dmx_ts_pes pes_type,
609 size_t circular_buffer_size, int descramble, 584 size_t circular_buffer_size, struct timespec timeout)
610 struct timespec timeout)
611{ 585{
612 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; 586 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
613 struct dvb_demux *demux = feed->demux; 587 struct dvb_demux *demux = feed->demux;
614 588
615 if (pid > DMX_MAX_PID) 589 if (pid > DMX_MAX_PID)
616 return -EINVAL; 590 return -EINVAL;
617 591
618 if (down_interruptible (&demux->mutex)) 592 if (down_interruptible(&demux->mutex))
619 return -ERESTARTSYS; 593 return -ERESTARTSYS;
620 594
621 if (ts_type & TS_DECODER) { 595 if (ts_type & TS_DECODER) {
@@ -638,20 +612,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
638 612
639 feed->pid = pid; 613 feed->pid = pid;
640 feed->buffer_size = circular_buffer_size; 614 feed->buffer_size = circular_buffer_size;
641 feed->descramble = descramble;
642 feed->timeout = timeout; 615 feed->timeout = timeout;
643 feed->cb_length = callback_length;
644 feed->ts_type = ts_type; 616 feed->ts_type = ts_type;
645 feed->pes_type = pes_type; 617 feed->pes_type = pes_type;
646 618
647 if (feed->descramble) {
648 up(&demux->mutex);
649 return -ENOSYS;
650 }
651
652 if (feed->buffer_size) { 619 if (feed->buffer_size) {
653#ifdef NOBUFS 620#ifdef NOBUFS
654 feed->buffer=NULL; 621 feed->buffer = NULL;
655#else 622#else
656 feed->buffer = vmalloc(feed->buffer_size); 623 feed->buffer = vmalloc(feed->buffer_size);
657 if (!feed->buffer) { 624 if (!feed->buffer) {
@@ -667,14 +634,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
667 return 0; 634 return 0;
668} 635}
669 636
670 637static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
671static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
672{ 638{
673 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; 639 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
674 struct dvb_demux *demux = feed->demux; 640 struct dvb_demux *demux = feed->demux;
675 int ret; 641 int ret;
676 642
677 if (down_interruptible (&demux->mutex)) 643 if (down_interruptible(&demux->mutex))
678 return -ERESTARTSYS; 644 return -ERESTARTSYS;
679 645
680 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { 646 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
@@ -701,13 +667,13 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
701 return 0; 667 return 0;
702} 668}
703 669
704static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed) 670static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
705{ 671{
706 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; 672 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
707 struct dvb_demux *demux = feed->demux; 673 struct dvb_demux *demux = feed->demux;
708 int ret; 674 int ret;
709 675
710 if (down_interruptible (&demux->mutex)) 676 if (down_interruptible(&demux->mutex))
711 return -ERESTARTSYS; 677 return -ERESTARTSYS;
712 678
713 if (feed->state < DMX_STATE_GO) { 679 if (feed->state < DMX_STATE_GO) {
@@ -731,13 +697,14 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
731 return ret; 697 return ret;
732} 698}
733 699
734static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed, 700static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
735 dmx_ts_cb callback) 701 struct dmx_ts_feed **ts_feed,
702 dmx_ts_cb callback)
736{ 703{
737 struct dvb_demux *demux = (struct dvb_demux *) dmx; 704 struct dvb_demux *demux = (struct dvb_demux *)dmx;
738 struct dvb_demux_feed *feed; 705 struct dvb_demux_feed *feed;
739 706
740 if (down_interruptible (&demux->mutex)) 707 if (down_interruptible(&demux->mutex))
741 return -ERESTARTSYS; 708 return -ERESTARTSYS;
742 709
743 if (!(feed = dvb_dmx_feed_alloc(demux))) { 710 if (!(feed = dvb_dmx_feed_alloc(demux))) {
@@ -760,7 +727,6 @@ static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **
760 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering; 727 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
761 (*ts_feed)->set = dmx_ts_feed_set; 728 (*ts_feed)->set = dmx_ts_feed_set;
762 729
763
764 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { 730 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
765 feed->state = DMX_STATE_FREE; 731 feed->state = DMX_STATE_FREE;
766 up(&demux->mutex); 732 up(&demux->mutex);
@@ -776,22 +742,22 @@ static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **
776 return 0; 742 return 0;
777} 743}
778 744
779static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed) 745static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
746 struct dmx_ts_feed *ts_feed)
780{ 747{
781 struct dvb_demux *demux = (struct dvb_demux *) dmx; 748 struct dvb_demux *demux = (struct dvb_demux *)dmx;
782 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; 749 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
783 750
784 if (down_interruptible (&demux->mutex)) 751 if (down_interruptible(&demux->mutex))
785 return -ERESTARTSYS; 752 return -ERESTARTSYS;
786 753
787 if (feed->state == DMX_STATE_FREE) { 754 if (feed->state == DMX_STATE_FREE) {
788 up(&demux->mutex); 755 up(&demux->mutex);
789 return -EINVAL; 756 return -EINVAL;
790 } 757 }
791
792#ifndef NOBUFS 758#ifndef NOBUFS
793 vfree(feed->buffer); 759 vfree(feed->buffer);
794 feed->buffer=0; 760 feed->buffer = NULL;
795#endif 761#endif
796 762
797 feed->state = DMX_STATE_FREE; 763 feed->state = DMX_STATE_FREE;
@@ -808,19 +774,18 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_
808 return 0; 774 return 0;
809} 775}
810 776
811
812/****************************************************************************** 777/******************************************************************************
813 * dmx_section_feed API calls 778 * dmx_section_feed API calls
814 ******************************************************************************/ 779 ******************************************************************************/
815 780
816static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed, 781static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
817 struct dmx_section_filter** filter) 782 struct dmx_section_filter **filter)
818{ 783{
819 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 784 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
820 struct dvb_demux *dvbdemux = dvbdmxfeed->demux; 785 struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
821 struct dvb_demux_filter *dvbdmxfilter; 786 struct dvb_demux_filter *dvbdmxfilter;
822 787
823 if (down_interruptible (&dvbdemux->mutex)) 788 if (down_interruptible(&dvbdemux->mutex))
824 return -ERESTARTSYS; 789 return -ERESTARTSYS;
825 790
826 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); 791 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
@@ -844,36 +809,29 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
844 return 0; 809 return 0;
845} 810}
846 811
847 812static int dmx_section_feed_set(struct dmx_section_feed *feed,
848static int dmx_section_feed_set(struct dmx_section_feed* feed, 813 u16 pid, size_t circular_buffer_size,
849 u16 pid, size_t circular_buffer_size, 814 int check_crc)
850 int descramble, int check_crc)
851{ 815{
852 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 816 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
853 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 817 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
854 818
855 if (pid > 0x1fff) 819 if (pid > 0x1fff)
856 return -EINVAL; 820 return -EINVAL;
857 821
858 if (down_interruptible (&dvbdmx->mutex)) 822 if (down_interruptible(&dvbdmx->mutex))
859 return -ERESTARTSYS; 823 return -ERESTARTSYS;
860 824
861 dvb_demux_feed_add(dvbdmxfeed); 825 dvb_demux_feed_add(dvbdmxfeed);
862 826
863 dvbdmxfeed->pid = pid; 827 dvbdmxfeed->pid = pid;
864 dvbdmxfeed->buffer_size = circular_buffer_size; 828 dvbdmxfeed->buffer_size = circular_buffer_size;
865 dvbdmxfeed->descramble = descramble;
866 if (dvbdmxfeed->descramble) {
867 up(&dvbdmx->mutex);
868 return -ENOSYS;
869 }
870
871 dvbdmxfeed->feed.sec.check_crc = check_crc; 829 dvbdmxfeed->feed.sec.check_crc = check_crc;
872 830
873#ifdef NOBUFS 831#ifdef NOBUFS
874 dvbdmxfeed->buffer = NULL; 832 dvbdmxfeed->buffer = NULL;
875#else 833#else
876 dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size); 834 dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
877 if (!dvbdmxfeed->buffer) { 835 if (!dvbdmxfeed->buffer) {
878 up(&dvbdmx->mutex); 836 up(&dvbdmx->mutex);
879 return -ENOMEM; 837 return -ENOMEM;
@@ -885,7 +843,6 @@ static int dmx_section_feed_set(struct dmx_section_feed* feed,
885 return 0; 843 return 0;
886} 844}
887 845
888
889static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed) 846static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
890{ 847{
891 int i; 848 int i;
@@ -893,12 +850,12 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
893 struct dmx_section_filter *sf; 850 struct dmx_section_filter *sf;
894 u8 mask, mode, doneq; 851 u8 mask, mode, doneq;
895 852
896 if (!(f=dvbdmxfeed->filter)) 853 if (!(f = dvbdmxfeed->filter))
897 return; 854 return;
898 do { 855 do {
899 sf = &f->filter; 856 sf = &f->filter;
900 doneq = 0; 857 doneq = 0;
901 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) { 858 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
902 mode = sf->filter_mode[i]; 859 mode = sf->filter_mode[i];
903 mask = sf->filter_mask[i]; 860 mask = sf->filter_mask[i];
904 f->maskandmode[i] = mask & mode; 861 f->maskandmode[i] = mask & mode;
@@ -908,14 +865,13 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
908 } while ((f = f->next)); 865 } while ((f = f->next));
909} 866}
910 867
911
912static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) 868static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
913{ 869{
914 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 870 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
915 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 871 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
916 int ret; 872 int ret;
917 873
918 if (down_interruptible (&dvbdmx->mutex)) 874 if (down_interruptible(&dvbdmx->mutex))
919 return -ERESTARTSYS; 875 return -ERESTARTSYS;
920 876
921 if (feed->is_filtering) { 877 if (feed->is_filtering) {
@@ -954,14 +910,13 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
954 return 0; 910 return 0;
955} 911}
956 912
957 913static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
958static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
959{ 914{
960 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 915 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
961 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 916 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
962 int ret; 917 int ret;
963 918
964 if (down_interruptible (&dvbdmx->mutex)) 919 if (down_interruptible(&dvbdmx->mutex))
965 return -ERESTARTSYS; 920 return -ERESTARTSYS;
966 921
967 if (!dvbdmx->stop_feed) { 922 if (!dvbdmx->stop_feed) {
@@ -980,15 +935,14 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
980 return ret; 935 return ret;
981} 936}
982 937
983
984static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, 938static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
985 struct dmx_section_filter* filter) 939 struct dmx_section_filter *filter)
986{ 940{
987 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *) filter, *f; 941 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f;
988 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 942 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
989 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 943 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
990 944
991 if (down_interruptible (&dvbdmx->mutex)) 945 if (down_interruptible(&dvbdmx->mutex))
992 return -ERESTARTSYS; 946 return -ERESTARTSYS;
993 947
994 if (dvbdmxfilter->feed != dvbdmxfeed) { 948 if (dvbdmxfilter->feed != dvbdmxfeed) {
@@ -1005,7 +959,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
1005 if (f == dvbdmxfilter) { 959 if (f == dvbdmxfilter) {
1006 dvbdmxfeed->filter = dvbdmxfilter->next; 960 dvbdmxfeed->filter = dvbdmxfilter->next;
1007 } else { 961 } else {
1008 while(f->next != dvbdmxfilter) 962 while (f->next != dvbdmxfilter)
1009 f = f->next; 963 f = f->next;
1010 f->next = f->next->next; 964 f->next = f->next->next;
1011 } 965 }
@@ -1020,10 +974,10 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1020 struct dmx_section_feed **feed, 974 struct dmx_section_feed **feed,
1021 dmx_section_cb callback) 975 dmx_section_cb callback)
1022{ 976{
1023 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux; 977 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
1024 struct dvb_demux_feed *dvbdmxfeed; 978 struct dvb_demux_feed *dvbdmxfeed;
1025 979
1026 if (down_interruptible (&dvbdmx->mutex)) 980 if (down_interruptible(&dvbdmx->mutex))
1027 return -ERESTARTSYS; 981 return -ERESTARTSYS;
1028 982
1029 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { 983 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
@@ -1041,7 +995,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1041 dvbdmxfeed->filter = NULL; 995 dvbdmxfeed->filter = NULL;
1042 dvbdmxfeed->buffer = NULL; 996 dvbdmxfeed->buffer = NULL;
1043 997
1044 (*feed)=&dvbdmxfeed->feed.sec; 998 (*feed) = &dvbdmxfeed->feed.sec;
1045 (*feed)->is_filtering = 0; 999 (*feed)->is_filtering = 0;
1046 (*feed)->parent = demux; 1000 (*feed)->parent = demux;
1047 (*feed)->priv = NULL; 1001 (*feed)->priv = NULL;
@@ -1059,21 +1013,21 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1059static int dvbdmx_release_section_feed(struct dmx_demux *demux, 1013static int dvbdmx_release_section_feed(struct dmx_demux *demux,
1060 struct dmx_section_feed *feed) 1014 struct dmx_section_feed *feed)
1061{ 1015{
1062 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed; 1016 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
1063 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux; 1017 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
1064 1018
1065 if (down_interruptible (&dvbdmx->mutex)) 1019 if (down_interruptible(&dvbdmx->mutex))
1066 return -ERESTARTSYS; 1020 return -ERESTARTSYS;
1067 1021
1068 if (dvbdmxfeed->state==DMX_STATE_FREE) { 1022 if (dvbdmxfeed->state == DMX_STATE_FREE) {
1069 up(&dvbdmx->mutex); 1023 up(&dvbdmx->mutex);
1070 return -EINVAL; 1024 return -EINVAL;
1071 } 1025 }
1072#ifndef NOBUFS 1026#ifndef NOBUFS
1073 vfree(dvbdmxfeed->buffer); 1027 vfree(dvbdmxfeed->buffer);
1074 dvbdmxfeed->buffer=0; 1028 dvbdmxfeed->buffer = NULL;
1075#endif 1029#endif
1076 dvbdmxfeed->state=DMX_STATE_FREE; 1030 dvbdmxfeed->state = DMX_STATE_FREE;
1077 1031
1078 dvb_demux_feed_del(dvbdmxfeed); 1032 dvb_demux_feed_del(dvbdmxfeed);
1079 1033
@@ -1083,14 +1037,13 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
1083 return 0; 1037 return 0;
1084} 1038}
1085 1039
1086
1087/****************************************************************************** 1040/******************************************************************************
1088 * dvb_demux kernel data API calls 1041 * dvb_demux kernel data API calls
1089 ******************************************************************************/ 1042 ******************************************************************************/
1090 1043
1091static int dvbdmx_open(struct dmx_demux *demux) 1044static int dvbdmx_open(struct dmx_demux *demux)
1092{ 1045{
1093 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1046 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1094 1047
1095 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS) 1048 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
1096 return -EUSERS; 1049 return -EUSERS;
@@ -1099,10 +1052,9 @@ static int dvbdmx_open(struct dmx_demux *demux)
1099 return 0; 1052 return 0;
1100} 1053}
1101 1054
1102
1103static int dvbdmx_close(struct dmx_demux *demux) 1055static int dvbdmx_close(struct dmx_demux *demux)
1104{ 1056{
1105 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1057 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1106 1058
1107 if (dvbdemux->users == 0) 1059 if (dvbdemux->users == 0)
1108 return -ENODEV; 1060 return -ENODEV;
@@ -1112,15 +1064,14 @@ static int dvbdmx_close(struct dmx_demux *demux)
1112 return 0; 1064 return 0;
1113} 1065}
1114 1066
1115
1116static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) 1067static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
1117{ 1068{
1118 struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; 1069 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1119 1070
1120 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) 1071 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1121 return -EINVAL; 1072 return -EINVAL;
1122 1073
1123 if (down_interruptible (&dvbdemux->mutex)) 1074 if (down_interruptible(&dvbdemux->mutex))
1124 return -ERESTARTSYS; 1075 return -ERESTARTSYS;
1125 dvb_dmx_swfilter(dvbdemux, buf, count); 1076 dvb_dmx_swfilter(dvbdemux, buf, count);
1126 up(&dvbdemux->mutex); 1077 up(&dvbdemux->mutex);
@@ -1130,10 +1081,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
1130 return count; 1081 return count;
1131} 1082}
1132 1083
1133 1084static int dvbdmx_add_frontend(struct dmx_demux *demux,
1134static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) 1085 struct dmx_frontend *frontend)
1135{ 1086{
1136 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1087 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1137 struct list_head *head = &dvbdemux->frontend_list; 1088 struct list_head *head = &dvbdemux->frontend_list;
1138 1089
1139 list_add(&(frontend->connectivity_list), head); 1090 list_add(&(frontend->connectivity_list), head);
@@ -1141,13 +1092,13 @@ static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *fro
1141 return 0; 1092 return 0;
1142} 1093}
1143 1094
1144 1095static int dvbdmx_remove_frontend(struct dmx_demux *demux,
1145static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) 1096 struct dmx_frontend *frontend)
1146{ 1097{
1147 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1098 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1148 struct list_head *pos, *n, *head = &dvbdemux->frontend_list; 1099 struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
1149 1100
1150 list_for_each_safe (pos, n, head) { 1101 list_for_each_safe(pos, n, head) {
1151 if (DMX_FE_ENTRY(pos) == frontend) { 1102 if (DMX_FE_ENTRY(pos) == frontend) {
1152 list_del(pos); 1103 list_del(pos);
1153 return 0; 1104 return 0;
@@ -1157,25 +1108,25 @@ static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *
1157 return -ENODEV; 1108 return -ENODEV;
1158} 1109}
1159 1110
1160 1111static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux)
1161static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
1162{ 1112{
1163 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1113 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1164 1114
1165 if (list_empty(&dvbdemux->frontend_list)) 1115 if (list_empty(&dvbdemux->frontend_list))
1166 return NULL; 1116 return NULL;
1117
1167 return &dvbdemux->frontend_list; 1118 return &dvbdemux->frontend_list;
1168} 1119}
1169 1120
1170 1121static int dvbdmx_connect_frontend(struct dmx_demux *demux,
1171static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) 1122 struct dmx_frontend *frontend)
1172{ 1123{
1173 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1124 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1174 1125
1175 if (demux->frontend) 1126 if (demux->frontend)
1176 return -EINVAL; 1127 return -EINVAL;
1177 1128
1178 if (down_interruptible (&dvbdemux->mutex)) 1129 if (down_interruptible(&dvbdemux->mutex))
1179 return -ERESTARTSYS; 1130 return -ERESTARTSYS;
1180 1131
1181 demux->frontend = frontend; 1132 demux->frontend = frontend;
@@ -1183,12 +1134,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend
1183 return 0; 1134 return 0;
1184} 1135}
1185 1136
1186
1187static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) 1137static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1188{ 1138{
1189 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1139 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1190 1140
1191 if (down_interruptible (&dvbdemux->mutex)) 1141 if (down_interruptible(&dvbdemux->mutex))
1192 return -ERESTARTSYS; 1142 return -ERESTARTSYS;
1193 1143
1194 demux->frontend = NULL; 1144 demux->frontend = NULL;
@@ -1196,44 +1146,42 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1196 return 0; 1146 return 0;
1197} 1147}
1198 1148
1199 1149static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids)
1200static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
1201{ 1150{
1202 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux; 1151 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1203 1152
1204 memcpy(pids, dvbdemux->pids, 5*sizeof(u16)); 1153 memcpy(pids, dvbdemux->pids, 5 * sizeof(u16));
1205 return 0; 1154 return 0;
1206} 1155}
1207 1156
1208
1209int dvb_dmx_init(struct dvb_demux *dvbdemux) 1157int dvb_dmx_init(struct dvb_demux *dvbdemux)
1210{ 1158{
1211 int i, err; 1159 int i;
1212 struct dmx_demux *dmx = &dvbdemux->dmx; 1160 struct dmx_demux *dmx = &dvbdemux->dmx;
1213 1161
1214 dvbdemux->users = 0; 1162 dvbdemux->users = 0;
1215 dvbdemux->filter = vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter)); 1163 dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter));
1216 1164
1217 if (!dvbdemux->filter) 1165 if (!dvbdemux->filter)
1218 return -ENOMEM; 1166 return -ENOMEM;
1219 1167
1220 dvbdemux->feed = vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed)); 1168 dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed));
1221 if (!dvbdemux->feed) { 1169 if (!dvbdemux->feed) {
1222 vfree(dvbdemux->filter); 1170 vfree(dvbdemux->filter);
1223 return -ENOMEM; 1171 return -ENOMEM;
1224 } 1172 }
1225 for (i=0; i<dvbdemux->filternum; i++) { 1173 for (i = 0; i < dvbdemux->filternum; i++) {
1226 dvbdemux->filter[i].state = DMX_STATE_FREE; 1174 dvbdemux->filter[i].state = DMX_STATE_FREE;
1227 dvbdemux->filter[i].index = i; 1175 dvbdemux->filter[i].index = i;
1228 } 1176 }
1229 for (i=0; i<dvbdemux->feednum; i++) { 1177 for (i = 0; i < dvbdemux->feednum; i++) {
1230 dvbdemux->feed[i].state = DMX_STATE_FREE; 1178 dvbdemux->feed[i].state = DMX_STATE_FREE;
1231 dvbdemux->feed[i].index = i; 1179 dvbdemux->feed[i].index = i;
1232 } 1180 }
1233 dvbdemux->frontend_list.next= 1181
1234 dvbdemux->frontend_list.prev= 1182 INIT_LIST_HEAD(&dvbdemux->frontend_list);
1235 &dvbdemux->frontend_list; 1183
1236 for (i=0; i<DMX_TS_PES_OTHER; i++) { 1184 for (i = 0; i < DMX_TS_PES_OTHER; i++) {
1237 dvbdemux->pesfilter[i] = NULL; 1185 dvbdemux->pesfilter[i] = NULL;
1238 dvbdemux->pids[i] = 0xffff; 1186 dvbdemux->pids[i] = 0xffff;
1239 } 1187 }
@@ -1247,12 +1195,11 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1247 if (!dvbdemux->check_crc32) 1195 if (!dvbdemux->check_crc32)
1248 dvbdemux->check_crc32 = dvb_dmx_crc32; 1196 dvbdemux->check_crc32 = dvb_dmx_crc32;
1249 1197
1250 if (!dvbdemux->memcopy) 1198 if (!dvbdemux->memcopy)
1251 dvbdemux->memcopy = dvb_dmx_memcopy; 1199 dvbdemux->memcopy = dvb_dmx_memcopy;
1252 1200
1253 dmx->frontend = NULL; 1201 dmx->frontend = NULL;
1254 dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list; 1202 dmx->priv = dvbdemux;
1255 dmx->priv = (void *) dvbdemux;
1256 dmx->open = dvbdmx_open; 1203 dmx->open = dvbdmx_open;
1257 dmx->close = dvbdmx_close; 1204 dmx->close = dvbdmx_close;
1258 dmx->write = dvbdmx_write; 1205 dmx->write = dvbdmx_write;
@@ -1261,9 +1208,6 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1261 dmx->allocate_section_feed = dvbdmx_allocate_section_feed; 1208 dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
1262 dmx->release_section_feed = dvbdmx_release_section_feed; 1209 dmx->release_section_feed = dvbdmx_release_section_feed;
1263 1210
1264 dmx->descramble_mac_address = NULL;
1265 dmx->descramble_section_payload = NULL;
1266
1267 dmx->add_frontend = dvbdmx_add_frontend; 1211 dmx->add_frontend = dvbdmx_add_frontend;
1268 dmx->remove_frontend = dvbdmx_remove_frontend; 1212 dmx->remove_frontend = dvbdmx_remove_frontend;
1269 dmx->get_frontends = dvbdmx_get_frontends; 1213 dmx->get_frontends = dvbdmx_get_frontends;
@@ -1274,21 +1218,15 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1274 sema_init(&dvbdemux->mutex, 1); 1218 sema_init(&dvbdemux->mutex, 1);
1275 spin_lock_init(&dvbdemux->lock); 1219 spin_lock_init(&dvbdemux->lock);
1276 1220
1277 if ((err = dmx_register_demux(dmx)) < 0)
1278 return err;
1279
1280 return 0; 1221 return 0;
1281} 1222}
1282EXPORT_SYMBOL(dvb_dmx_init);
1283 1223
1224EXPORT_SYMBOL(dvb_dmx_init);
1284 1225
1285int dvb_dmx_release(struct dvb_demux *dvbdemux) 1226void dvb_dmx_release(struct dvb_demux *dvbdemux)
1286{ 1227{
1287 struct dmx_demux *dmx = &dvbdemux->dmx;
1288
1289 dmx_unregister_demux(dmx);
1290 vfree(dvbdemux->filter); 1228 vfree(dvbdemux->filter);
1291 vfree(dvbdemux->feed); 1229 vfree(dvbdemux->feed);
1292 return 0;
1293} 1230}
1231
1294EXPORT_SYMBOL(dvb_dmx_release); 1232EXPORT_SYMBOL(dvb_dmx_release);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index c09beb391622..0cc888339d52 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23
24#ifndef _DVB_DEMUX_H_ 23#ifndef _DVB_DEMUX_H_
25#define _DVB_DEMUX_H_ 24#define _DVB_DEMUX_H_
26 25
@@ -44,103 +43,98 @@
44#define DVB_DEMUX_MASK_MAX 18 43#define DVB_DEMUX_MASK_MAX 18
45 44
46struct dvb_demux_filter { 45struct dvb_demux_filter {
47 struct dmx_section_filter filter; 46 struct dmx_section_filter filter;
48 u8 maskandmode [DMX_MAX_FILTER_SIZE]; 47 u8 maskandmode[DMX_MAX_FILTER_SIZE];
49 u8 maskandnotmode [DMX_MAX_FILTER_SIZE]; 48 u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
50 int doneq; 49 int doneq;
51 50
52 struct dvb_demux_filter *next; 51 struct dvb_demux_filter *next;
53 struct dvb_demux_feed *feed; 52 struct dvb_demux_feed *feed;
54 int index; 53 int index;
55 int state; 54 int state;
56 int type; 55 int type;
57 int pesto;
58
59 u16 handle;
60 u16 hw_handle;
61 struct timer_list timer;
62 int ts_state;
63};
64 56
57 u16 hw_handle;
58 struct timer_list timer;
59};
65 60
66#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head) 61#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
67 62
68struct dvb_demux_feed { 63struct dvb_demux_feed {
69 union { 64 union {
70 struct dmx_ts_feed ts; 65 struct dmx_ts_feed ts;
71 struct dmx_section_feed sec; 66 struct dmx_section_feed sec;
72 } feed; 67 } feed;
73 68
74 union { 69 union {
75 dmx_ts_cb ts; 70 dmx_ts_cb ts;
76 dmx_section_cb sec; 71 dmx_section_cb sec;
77 } cb; 72 } cb;
78 73
79 struct dvb_demux *demux; 74 struct dvb_demux *demux;
80 void *priv; 75 void *priv;
81 int type; 76 int type;
82 int state; 77 int state;
83 u16 pid; 78 u16 pid;
84 u8 *buffer; 79 u8 *buffer;
85 int buffer_size; 80 int buffer_size;
86 int descramble;
87 81
88 struct timespec timeout; 82 struct timespec timeout;
89 struct dvb_demux_filter *filter; 83 struct dvb_demux_filter *filter;
90 int cb_length;
91 84
92 int ts_type; 85 int ts_type;
93 enum dmx_ts_pes pes_type; 86 enum dmx_ts_pes pes_type;
94 87
95 int cc; 88 int cc;
96 int pusi_seen; /* prevents feeding of garbage from previous section */ 89 int pusi_seen; /* prevents feeding of garbage from previous section */
97 90
98 u16 peslen; 91 u16 peslen;
99 92
100 struct list_head list_head; 93 struct list_head list_head;
101 int index; /* a unique index for each feed (can be used as hardware pid filter index) */ 94 unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
102}; 95};
103 96
104struct dvb_demux { 97struct dvb_demux {
105 struct dmx_demux dmx; 98 struct dmx_demux dmx;
106 void *priv; 99 void *priv;
107 int filternum; 100 int filternum;
108 int feednum; 101 int feednum;
109 int (*start_feed) (struct dvb_demux_feed *feed); 102 int (*start_feed)(struct dvb_demux_feed *feed);
110 int (*stop_feed) (struct dvb_demux_feed *feed); 103 int (*stop_feed)(struct dvb_demux_feed *feed);
111 int (*write_to_decoder) (struct dvb_demux_feed *feed, 104 int (*write_to_decoder)(struct dvb_demux_feed *feed,
112 const u8 *buf, size_t len); 105 const u8 *buf, size_t len);
113 u32 (*check_crc32) (struct dvb_demux_feed *feed, 106 u32 (*check_crc32)(struct dvb_demux_feed *feed,
114 const u8 *buf, size_t len); 107 const u8 *buf, size_t len);
115 void (*memcopy) (struct dvb_demux_feed *feed, u8 *dst, 108 void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
116 const u8 *src, size_t len); 109 const u8 *src, size_t len);
117 110
118 int users; 111 int users;
119#define MAX_DVB_DEMUX_USERS 10 112#define MAX_DVB_DEMUX_USERS 10
120 struct dvb_demux_filter *filter; 113 struct dvb_demux_filter *filter;
121 struct dvb_demux_feed *feed; 114 struct dvb_demux_feed *feed;
122 115
123 struct list_head frontend_list; 116 struct list_head frontend_list;
124 117
125 struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER]; 118 struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
126 u16 pids[DMX_TS_PES_OTHER]; 119 u16 pids[DMX_TS_PES_OTHER];
127 int playing; 120 int playing;
128 int recording; 121 int recording;
129 122
130#define DMX_MAX_PID 0x2000 123#define DMX_MAX_PID 0x2000
131 struct list_head feed_list; 124 struct list_head feed_list;
132 u8 tsbuf[204]; 125 u8 tsbuf[204];
133 int tsbufp; 126 int tsbufp;
134 127
135 struct semaphore mutex; 128 struct semaphore mutex;
136 spinlock_t lock; 129 spinlock_t lock;
137}; 130};
138 131
139
140int dvb_dmx_init(struct dvb_demux *dvbdemux); 132int dvb_dmx_init(struct dvb_demux *dvbdemux);
141int dvb_dmx_release(struct dvb_demux *dvbdemux); 133void dvb_dmx_release(struct dvb_demux *dvbdemux);
142void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count); 134void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
135 size_t count);
143void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); 136void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
144void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count); 137void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
138 size_t count);
145 139
146#endif /* _DVB_DEMUX_H_ */ 140#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 6a968c346a36..87935490bfb2 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -62,7 +62,6 @@
62#include <linux/uio.h> 62#include <linux/uio.h>
63#include <asm/uaccess.h> 63#include <asm/uaccess.h>
64#include <linux/crc32.h> 64#include <linux/crc32.h>
65#include <linux/version.h>
66 65
67#include "dvb_demux.h" 66#include "dvb_demux.h"
68#include "dvb_net.h" 67#include "dvb_net.h"
@@ -171,11 +170,7 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
171 170
172 skb->mac.raw=skb->data; 171 skb->mac.raw=skb->data;
173 skb_pull(skb,dev->hard_header_len); 172 skb_pull(skb,dev->hard_header_len);
174#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
175 eth = skb->mac.ethernet;
176#else
177 eth = eth_hdr(skb); 173 eth = eth_hdr(skb);
178#endif
179 174
180 if (*eth->h_dest & 1) { 175 if (*eth->h_dest & 1) {
181 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) 176 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
@@ -908,7 +903,7 @@ static int dvb_net_feed_start(struct net_device *dev)
908 return ret; 903 return ret;
909 } 904 }
910 905
911 ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1); 906 ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
912 907
913 if (ret<0) { 908 if (ret<0) {
914 printk("%s: could not set section feed\n", dev->name); 909 printk("%s: could not set section feed\n", dev->name);
@@ -960,9 +955,7 @@ static int dvb_net_feed_start(struct net_device *dev)
960 priv->tsfeed->priv = (void *)dev; 955 priv->tsfeed->priv = (void *)dev;
961 ret = priv->tsfeed->set(priv->tsfeed, priv->pid, 956 ret = priv->tsfeed->set(priv->tsfeed, priv->pid,
962 TS_PACKET, DMX_TS_PES_OTHER, 957 TS_PACKET, DMX_TS_PES_OTHER,
963 188 * 100, /* nr. of bytes delivered per callback */
964 32768, /* circular buffer size */ 958 32768, /* circular buffer size */
965 0, /* descramble */
966 timeout); 959 timeout);
967 960
968 if (ret < 0) { 961 if (ret < 0) {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 612e5b087b1c..54e2b29076b1 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -93,13 +93,30 @@ config DVB_USB_DIGITV
93 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. 93 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
94 94
95config DVB_USB_VP7045 95config DVB_USB_VP7045
96 tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support" 96 tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
97 depends on DVB_USB 97 depends on DVB_USB
98 help 98 help
99 Say Y here to support the 99 Say Y here to support the
100
100 TwinhanDTV Alpha (stick) (VP-7045), 101 TwinhanDTV Alpha (stick) (VP-7045),
101 TwinhanDTV MagicBox II (VP-7046) and 102 TwinhanDTV MagicBox II (VP-7046),
102 DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers. 103 DigitalNow TinyUSB 2 DVB-t,
104 DigitalRise USB 2.0 Ter (Beetle) and
105 TYPHOON DVB-T USB DRIVE
106
107 DVB-T USB2.0 receivers.
108
109config DVB_USB_VP702X
110 tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
111 depends on DVB_USB
112 help
113 Say Y here to support the
114
115 TwinhanDTV StarBox,
116 DigitalRise USB Starbox and
117 TYPHOON DVB-S USB 2.0 BOX
118
119 DVB-S USB2.0 receivers.
103 120
104config DVB_USB_NOVA_T_USB2 121config DVB_USB_NOVA_T_USB2
105 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" 122 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 746d87ed6f32..2dc9aad9681e 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -4,6 +4,9 @@ obj-$(CONFIG_DVB_USB) += dvb-usb.o
4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o 4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o 5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
6 6
7dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
8obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
9
7dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o 10dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
8obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o 11obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
9 12
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index f2fcc2f1f846..e55322ef76b3 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -90,7 +90,7 @@ static struct dvb_usb_properties a800_properties;
90static int a800_probe(struct usb_interface *intf, 90static int a800_probe(struct usb_interface *intf,
91 const struct usb_device_id *id) 91 const struct usb_device_id *id)
92{ 92{
93 return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE); 93 return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL);
94} 94}
95 95
96/* do not change the order of the ID table */ 96/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 9e96a188f1e9..3fe383f4bb4c 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -48,35 +48,26 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
48 return 0; 48 return 0;
49} 49}
50 50
51/* I2C */ 51/* GPIO */
52static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path) 52static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
53{ 53{
54 struct cxusb_state *st = d->priv; 54 struct cxusb_state *st = d->priv;
55 u8 o[2],i; 55 u8 o[2],i;
56 56
57 if (path == st->cur_i2c_path) 57 if (st->gpio_write_state[GPIO_TUNER] == onoff)
58 return; 58 return;
59 59
60 o[0] = IOCTL_SET_I2C_PATH; 60 o[0] = GPIO_TUNER;
61 switch (path) { 61 o[1] = onoff;
62 case PATH_CX22702: 62 cxusb_ctrl_msg(d,CMD_GPIO_WRITE,o,2,&i,1);
63 o[1] = 0;
64 break;
65 case PATH_TUNER_OTHER:
66 o[1] = 1;
67 break;
68 default:
69 err("unkown i2c path");
70 return;
71 }
72 cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
73 63
74 if (i != 0x01) 64 if (i != 0x01)
75 deb_info("i2c_path setting failed.\n"); 65 deb_info("gpio_write failed.\n");
76 66
77 st->cur_i2c_path = path; 67 st->gpio_write_state[GPIO_TUNER] = onoff;
78} 68}
79 69
70/* I2C */
80static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) 71static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
81{ 72{
82 struct dvb_usb_device *d = i2c_get_adapdata(adap); 73 struct dvb_usb_device *d = i2c_get_adapdata(adap);
@@ -92,10 +83,10 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
92 83
93 switch (msg[i].addr) { 84 switch (msg[i].addr) {
94 case 0x63: 85 case 0x63:
95 cxusb_set_i2c_path(d,PATH_CX22702); 86 cxusb_gpio_tuner(d,0);
96 break; 87 break;
97 default: 88 default:
98 cxusb_set_i2c_path(d,PATH_TUNER_OTHER); 89 cxusb_gpio_tuner(d,1);
99 break; 90 break;
100 } 91 }
101 92
@@ -147,16 +138,20 @@ static struct i2c_algorithm cxusb_i2c_algo = {
147 138
148static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) 139static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
149{ 140{
150 return 0; 141 u8 b = 0;
142 if (onoff)
143 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
144 else
145 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
151} 146}
152 147
153static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) 148static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
154{ 149{
155 u8 buf[2] = { 0x03, 0x00 }; 150 u8 buf[2] = { 0x03, 0x00 };
156 if (onoff) 151 if (onoff)
157 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); 152 cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0);
158 else 153 else
159 cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0); 154 cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0);
160 155
161 return 0; 156 return 0;
162} 157}
@@ -182,22 +177,11 @@ static int cxusb_tuner_attach(struct dvb_usb_device *d)
182 177
183static int cxusb_frontend_attach(struct dvb_usb_device *d) 178static int cxusb_frontend_attach(struct dvb_usb_device *d)
184{ 179{
185 u8 buf[2] = { 0x03, 0x00 }; 180 u8 b;
186 u8 b = 0;
187
188 if (usb_set_interface(d->udev,0,0) < 0)
189 err("set interface to alts=0 failed");
190
191 cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
192 cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
193 cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
194
195 if (usb_set_interface(d->udev,0,6) < 0) 181 if (usb_set_interface(d->udev,0,6) < 0)
196 err("set interface failed"); 182 err("set interface failed");
197 183
198 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); 184 cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
199 cxusb_set_i2c_path(d,PATH_CX22702);
200 cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
201 185
202 if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL) 186 if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
203 return 0; 187 return 0;
@@ -211,7 +195,7 @@ static struct dvb_usb_properties cxusb_properties;
211static int cxusb_probe(struct usb_interface *intf, 195static int cxusb_probe(struct usb_interface *intf,
212 const struct usb_device_id *id) 196 const struct usb_device_id *id)
213{ 197{
214 return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE); 198 return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL);
215} 199}
216 200
217static struct usb_device_id cxusb_table [] = { 201static struct usb_device_id cxusb_table [] = {
@@ -237,14 +221,12 @@ static struct dvb_usb_properties cxusb_properties = {
237 .generic_bulk_ctrl_endpoint = 0x01, 221 .generic_bulk_ctrl_endpoint = 0x01,
238 /* parameter for the MPEG2-data transfer */ 222 /* parameter for the MPEG2-data transfer */
239 .urb = { 223 .urb = {
240 .type = DVB_USB_ISOC, 224 .type = DVB_USB_BULK,
241 .count = 5, 225 .count = 5,
242 .endpoint = 0x02, 226 .endpoint = 0x02,
243 .u = { 227 .u = {
244 .isoc = { 228 .bulk = {
245 .framesperurb = 32, 229 .buffersize = 8192,
246 .framesize = 940,
247 .interval = 5,
248 } 230 }
249 } 231 }
250 }, 232 },
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 1d79016e3195..135c2a81f581 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -1,30 +1,31 @@
1#ifndef _DVB_USB_CXUSB_H_ 1#ifndef _DVB_USB_CXUSB_H_
2#define _DVB_USB_CXUSB_H_ 2#define _DVB_USB_CXUSB_H_
3 3
4#define DVB_USB_LOG_PREFIX "digitv" 4#define DVB_USB_LOG_PREFIX "cxusb"
5#include "dvb-usb.h" 5#include "dvb-usb.h"
6 6
7extern int dvb_usb_cxusb_debug; 7extern int dvb_usb_cxusb_debug;
8#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) 8#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
9 9
10/* usb commands - some of it are guesses, don't have a reference yet */ 10/* usb commands - some of it are guesses, don't have a reference yet */
11#define CMD_I2C_WRITE 0x08 11#define CMD_I2C_WRITE 0x08
12#define CMD_I2C_READ 0x09 12#define CMD_I2C_READ 0x09
13 13
14#define CMD_IOCTL 0x0e 14#define CMD_GPIO_READ 0x0d
15#define IOCTL_SET_I2C_PATH 0x02 15#define CMD_GPIO_WRITE 0x0e
16#define GPIO_TUNER 0x02
16 17
17#define CMD_POWER_OFF 0x50 18#define CMD_POWER_OFF 0xdc
18#define CMD_POWER_ON 0x51 19#define CMD_POWER_ON 0xde
19 20
20enum cxusb_i2c_pathes { 21#define CMD_STREAMING_ON 0x36
21 PATH_UNDEF = 0x00, 22#define CMD_STREAMING_OFF 0x37
22 PATH_CX22702 = 0x01, 23
23 PATH_TUNER_OTHER = 0x02, 24#define CMD_ANALOG 0x50
24}; 25#define CMD_DIGITAL 0x51
25 26
26struct cxusb_state { 27struct cxusb_state {
27 enum cxusb_i2c_pathes cur_i2c_path; 28 u8 gpio_write_state[3];
28}; 29};
29 30
30#endif 31#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 828b5182e16c..0058505634a0 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -86,9 +86,9 @@ static struct dvb_usb_properties dibusb2_0b_properties;
86static int dibusb_probe(struct usb_interface *intf, 86static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id) 87 const struct usb_device_id *id)
88{ 88{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || 89 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) == 0 || 90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) 91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0)
92 return 0; 92 return 0;
93 93
94 return -EINVAL; 94 return -EINVAL;
@@ -126,10 +126,12 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
126/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, 126/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
127/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, 127/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
128 128
129/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
130
129// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 131// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
130 132
131#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 133#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 134/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
133#endif 135#endif
134 { } /* Terminating entry */ 136 { } /* Terminating entry */
135}; 137};
@@ -262,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
262 }, 264 },
263#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 265#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
264 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 266 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
265 { &dibusb_dib3000mb_table[27], NULL }, 267 { &dibusb_dib3000mb_table[28], NULL },
266 { NULL }, 268 { NULL },
267 }, 269 },
268#endif 270#endif
@@ -306,12 +308,16 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
306 } 308 }
307 }, 309 },
308 310
309 .num_device_descs = 1, 311 .num_device_descs = 2,
310 .devices = { 312 .devices = {
311 { "KWorld/ADSTech Instant DVB-T USB 2.0", 313 { "KWorld/ADSTech Instant DVB-T USB2.0",
312 { &dibusb_dib3000mb_table[23], NULL }, 314 { &dibusb_dib3000mb_table[23], NULL },
313 { &dibusb_dib3000mb_table[24], NULL }, 315 { &dibusb_dib3000mb_table[24], NULL },
314 }, 316 },
317 { "KWorld Xpert DVB-T USB2.0",
318 { &dibusb_dib3000mb_table[27], NULL },
319 { NULL }
320 },
315 } 321 }
316}; 322};
317 323
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index e9dac430f37d..6a0912eab396 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -20,7 +20,7 @@ static struct dvb_usb_properties dibusb_mc_properties;
20static int dibusb_mc_probe(struct usb_interface *intf, 20static int dibusb_mc_probe(struct usb_interface *intf,
21 const struct usb_device_id *id) 21 const struct usb_device_id *id)
22{ 22{
23 return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE); 23 return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL);
24} 24}
25 25
26/* do not change the order of the ID table */ 26/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index f70e0be0920a..74545f82eff1 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -111,31 +111,28 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
111} 111}
112 112
113static struct mt352_config digitv_mt352_config = { 113static struct mt352_config digitv_mt352_config = {
114 .demod_address = 0x0, /* ignored by the digitv anyway */
115 .demod_init = digitv_mt352_demod_init, 114 .demod_init = digitv_mt352_demod_init,
116 .pll_set = dvb_usb_pll_set, 115 .pll_set = dvb_usb_pll_set,
117}; 116};
118 117
119static struct nxt6000_config digitv_nxt6000_config = { 118static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
120 .demod_address = 0x0, /* ignored by the digitv anyway */ 119{
121 .clock_inversion = 0x0, 120 struct dvb_usb_device *d = fe->dvb->priv;
121 u8 b[5];
122 dvb_usb_pll_set(fe,fep,b);
123 return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
124}
122 125
123 .pll_init = NULL, 126static struct nxt6000_config digitv_nxt6000_config = {
124 .pll_set = NULL, 127 .clock_inversion = 1,
128 .pll_set = digitv_nxt6000_pll_set,
125}; 129};
126 130
127static int digitv_frontend_attach(struct dvb_usb_device *d) 131static int digitv_frontend_attach(struct dvb_usb_device *d)
128{ 132{
129 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) 133 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL ||
134 (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL)
130 return 0; 135 return 0;
131 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
132
133 warn("nxt6000 support is not done yet, in fact you are one of the first "
134 "person who wants to use this device in Linux. Please report to "
135 "linux-dvb@linuxtv.org");
136
137 return 0;
138 }
139 return -EIO; 136 return -EIO;
140} 137}
141 138
@@ -173,7 +170,18 @@ static struct dvb_usb_properties digitv_properties;
173static int digitv_probe(struct usb_interface *intf, 170static int digitv_probe(struct usb_interface *intf,
174 const struct usb_device_id *id) 171 const struct usb_device_id *id)
175{ 172{
176 return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE); 173 struct dvb_usb_device *d;
174 int ret;
175 if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
176 u8 b[4] = { 0 };
177
178 b[0] = 1;
179 digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
180
181 b[0] = 0;
182 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
183 }
184 return ret;
177} 185}
178 186
179static struct usb_device_id digitv_table [] = { 187static struct usb_device_id digitv_table [] = {
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index b032523b07bc..0a94ec22aeb8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -18,6 +18,7 @@ struct dtt200u_fe_state {
18 18
19 struct dvb_frontend_parameters fep; 19 struct dvb_frontend_parameters fep;
20 struct dvb_frontend frontend; 20 struct dvb_frontend frontend;
21 struct dvb_frontend_ops ops;
21}; 22};
22 23
23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) 24static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
@@ -163,8 +164,9 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
163 deb_info("attaching frontend dtt200u\n"); 164 deb_info("attaching frontend dtt200u\n");
164 165
165 state->d = d; 166 state->d = d;
167 memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
166 168
167 state->frontend.ops = &dtt200u_fe_ops; 169 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state; 170 state->frontend.demodulator_priv = state;
169 171
170 goto success; 172 goto success;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 47dba6e45968..5aa12ebab34f 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -98,20 +98,19 @@ static struct dvb_usb_properties wt220u_properties;
98static int dtt200u_usb_probe(struct usb_interface *intf, 98static int dtt200u_usb_probe(struct usb_interface *intf,
99 const struct usb_device_id *id) 99 const struct usb_device_id *id)
100{ 100{
101 if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 || 101 if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
102 dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0) 102 dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0)
103 return 0; 103 return 0;
104 104
105 return -ENODEV; 105 return -ENODEV;
106} 106}
107 107
108static struct usb_device_id dtt200u_usb_table [] = { 108static struct usb_device_id dtt200u_usb_table [] = {
109// { USB_DEVICE(0x04b4,0x8613) }, 109 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
110 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, 110 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
111 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, 111 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
112 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, 112 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
113 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, 113 { 0 },
114 { 0 },
115}; 114};
116MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); 115MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
117 116
@@ -189,7 +188,7 @@ static struct dvb_usb_properties wt220u_properties = {
189 188
190 .num_device_descs = 1, 189 .num_device_descs = 1,
191 .devices = { 190 .devices = {
192 { .name = "WideView WT-220U PenType Receiver (and clones)", 191 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
193 .cold_ids = { &dtt200u_usb_table[2], NULL }, 192 .cold_ids = { &dtt200u_usb_table[2], NULL },
194 .warm_ids = { &dtt200u_usb_table[3], NULL }, 193 .warm_ids = { &dtt200u_usb_table[3], NULL },
195 }, 194 },
@@ -201,9 +200,9 @@ static struct dvb_usb_properties wt220u_properties = {
201static struct usb_driver dtt200u_usb_driver = { 200static struct usb_driver dtt200u_usb_driver = {
202 .owner = THIS_MODULE, 201 .owner = THIS_MODULE,
203 .name = "dvb_usb_dtt200u", 202 .name = "dvb_usb_dtt200u",
204 .probe = dtt200u_usb_probe, 203 .probe = dtt200u_usb_probe,
205 .disconnect = dvb_usb_device_exit, 204 .disconnect = dvb_usb_device_exit,
206 .id_table = dtt200u_usb_table, 205 .id_table = dtt200u_usb_table,
207}; 206};
208 207
209/* module stuff */ 208/* module stuff */
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 794d513a8480..0818996bf150 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -24,8 +24,10 @@
24#define USB_VID_HANFTEK 0x15f4 24#define USB_VID_HANFTEK 0x15f4
25#define USB_VID_HAUPPAUGE 0x2040 25#define USB_VID_HAUPPAUGE 0x2040
26#define USB_VID_HYPER_PALTEK 0x1025 26#define USB_VID_HYPER_PALTEK 0x1025
27#define USB_VID_KWORLD 0xeb2a
27#define USB_VID_KYE 0x0458 28#define USB_VID_KYE 0x0458
28#define USB_VID_MEDION 0x1660 29#define USB_VID_MEDION 0x1660
30#define USB_VID_PINNACLE 0x2304
29#define USB_VID_VISIONPLUS 0x13d3 31#define USB_VID_VISIONPLUS 0x13d3
30#define USB_VID_TWINHAN 0x1822 32#define USB_VID_TWINHAN 0x1822
31#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 33#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -52,12 +54,14 @@
52#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 54#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
53#define USB_PID_TWINHAN_VP7041_COLD 0x3201 55#define USB_PID_TWINHAN_VP7041_COLD 0x3201
54#define USB_PID_TWINHAN_VP7041_WARM 0x3202 56#define USB_PID_TWINHAN_VP7041_WARM 0x3202
57#define USB_PID_TWINHAN_VP7020_COLD 0x3203
58#define USB_PID_TWINHAN_VP7020_WARM 0x3204
55#define USB_PID_TWINHAN_VP7045_COLD 0x3205 59#define USB_PID_TWINHAN_VP7045_COLD 0x3205
56#define USB_PID_TWINHAN_VP7045_WARM 0x3206 60#define USB_PID_TWINHAN_VP7045_WARM 0x3206
57#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
58#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
59#define USB_PID_TWINHAN_VP7021_COLD 0x3207 61#define USB_PID_TWINHAN_VP7021_COLD 0x3207
60#define USB_PID_TWINHAN_VP7021_WARM 0x3208 62#define USB_PID_TWINHAN_VP7021_WARM 0x3208
63#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
64#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
61#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 65#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
62#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 66#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
63#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 67#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
@@ -85,5 +89,7 @@
85#define USB_PID_MEDION_MD95700 0x0932 89#define USB_PID_MEDION_MD95700 0x0932
86#define USB_PID_KYE_DVB_T_COLD 0x701e 90#define USB_PID_KYE_DVB_T_COLD 0x701e
87#define USB_PID_KYE_DVB_T_WARM 0x701f 91#define USB_PID_KYE_DVB_T_WARM 0x701f
92#define USB_PID_PCTV_200E 0x020e
93#define USB_PID_PCTV_400E 0x020f
88 94
89#endif 95#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 65f0c095abc9..a902059812a2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -128,7 +128,9 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
128/* 128/*
129 * USB 129 * USB
130 */ 130 */
131int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner) 131
132int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
133 *props, struct module *owner,struct dvb_usb_device **du)
132{ 134{
133 struct usb_device *udev = interface_to_usbdev(intf); 135 struct usb_device *udev = interface_to_usbdev(intf);
134 struct dvb_usb_device *d = NULL; 136 struct dvb_usb_device *d = NULL;
@@ -170,6 +172,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *p
170 172
171 usb_set_intfdata(intf, d); 173 usb_set_intfdata(intf, d);
172 174
175 if (du != NULL)
176 *du = d;
177
173 ret = dvb_usb_init(d); 178 ret = dvb_usb_init(d);
174 } 179 }
175 180
@@ -196,19 +201,6 @@ void dvb_usb_device_exit(struct usb_interface *intf)
196} 201}
197EXPORT_SYMBOL(dvb_usb_device_exit); 202EXPORT_SYMBOL(dvb_usb_device_exit);
198 203
199/* module stuff */
200static int __init dvb_usb_module_init(void)
201{
202 return 0;
203}
204
205static void __exit dvb_usb_module_exit(void)
206{
207}
208
209module_init (dvb_usb_module_init);
210module_exit (dvb_usb_module_exit);
211
212MODULE_VERSION("0.3"); 204MODULE_VERSION("0.3");
213MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); 205MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
214MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); 206MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index a80567caf508..0e4f1035b0dd 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -127,7 +127,7 @@ struct dvb_usb_device;
127 * helper functions. 127 * helper functions.
128 * 128 *
129 * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming. 129 * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
130 * Currently only BULK is implemented 130 * (BULK or ISOC)
131 * 131 *
132 * @num_device_descs: number of struct dvb_usb_device_description in @devices 132 * @num_device_descs: number of struct dvb_usb_device_description in @devices
133 * @devices: array of struct dvb_usb_device_description compatibles with these 133 * @devices: array of struct dvb_usb_device_description compatibles with these
@@ -310,7 +310,7 @@ struct dvb_usb_device {
310 void *priv; 310 void *priv;
311}; 311};
312 312
313extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *); 313extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
314extern void dvb_usb_device_exit(struct usb_interface *); 314extern void dvb_usb_device_exit(struct usb_interface *);
315 315
316/* the generic read/write method for device control */ 316/* the generic read/write method for device control */
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 258a92bfbcc7..1841a66427bf 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -144,7 +144,7 @@ static struct dvb_usb_properties nova_t_properties;
144static int nova_t_probe(struct usb_interface *intf, 144static int nova_t_probe(struct usb_interface *intf,
145 const struct usb_device_id *id) 145 const struct usb_device_id *id)
146{ 146{
147 return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE); 147 return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL);
148} 148}
149 149
150/* do not change the order of the ID table */ 150/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 2112ac3cf5e2..6fd67657c269 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -77,7 +77,7 @@ static struct dvb_usb_properties umt_properties;
77static int umt_probe(struct usb_interface *intf, 77static int umt_probe(struct usb_interface *intf,
78 const struct usb_device_id *id) 78 const struct usb_device_id *id)
79{ 79{
80 if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0) 80 if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0)
81 return 0; 81 return 0;
82 return -EINVAL; 82 return -EINVAL;
83} 83}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
new file mode 100644
index 000000000000..f20d8dbd0be8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,339 @@
1/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
2 * DVB-S receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This file can be removed soon, after the DST-driver is rewritten to provice
12 * the frontend-controlling separately.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation, version 2.
17 *
18 * see Documentation/dvb/README.dvb-usb for more information
19 *
20 */
21#include "vp702x.h"
22
23struct vp702x_fe_state {
24 struct dvb_frontend fe;
25 struct dvb_usb_device *d;
26
27 fe_sec_voltage_t voltage;
28 fe_sec_tone_mode_t tone_mode;
29
30 u8 lnb_buf[8];
31
32 u8 lock;
33 u8 sig;
34 u8 snr;
35
36 unsigned long next_status_check;
37 unsigned long status_check_interval;
38};
39
40static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
41{
42 u8 buf[10];
43 if (time_after(jiffies,st->next_status_check)) {
44 vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
45
46 st->lock = buf[4];
47 vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
48 vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
49
50 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
51 }
52 return 0;
53}
54
55static u8 vp702x_chksum(u8 *buf,int f, int count)
56{
57 u8 s = 0;
58 int i;
59 for (i = f; i < f+count; i++)
60 s += buf[i];
61 return ~s+1;
62}
63
64static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
65{
66 struct vp702x_fe_state *st = fe->demodulator_priv;
67 vp702x_fe_refresh_state(st);
68 deb_fe("%s\n",__FUNCTION__);
69
70 if (st->lock == 0)
71 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
72 else
73 *status = 0;
74
75 deb_fe("real state: %x\n",*status);
76 *status = 0x1f;
77
78 if (*status & FE_HAS_LOCK)
79 st->status_check_interval = 1000;
80 else
81 st->status_check_interval = 250;
82 return 0;
83}
84
85/* not supported by this Frontend */
86static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
87{
88 struct vp702x_fe_state *st = fe->demodulator_priv;
89 vp702x_fe_refresh_state(st);
90 *ber = 0;
91 return 0;
92}
93
94/* not supported by this Frontend */
95static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
96{
97 struct vp702x_fe_state *st = fe->demodulator_priv;
98 vp702x_fe_refresh_state(st);
99 *unc = 0;
100 return 0;
101}
102
103static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
104{
105 struct vp702x_fe_state *st = fe->demodulator_priv;
106 vp702x_fe_refresh_state(st);
107
108 *strength = (st->sig << 8) | st->sig;
109 return 0;
110}
111
112static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
113{
114 u8 _snr;
115 struct vp702x_fe_state *st = fe->demodulator_priv;
116 vp702x_fe_refresh_state(st);
117
118 _snr = (st->snr & 0x1f) * 0xff / 0x1f;
119 *snr = (_snr << 8) | _snr;
120 return 0;
121}
122
123static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
124{
125 deb_fe("%s\n",__FUNCTION__);
126 tune->min_delay_ms = 2000;
127 return 0;
128}
129
130static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
131 struct dvb_frontend_parameters *fep)
132{
133 struct vp702x_fe_state *st = fe->demodulator_priv;
134 u32 freq = fep->frequency/1000;
135 /*CalFrequency*/
136/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
137 u64 sr;
138 u8 cmd[8] = { 0 },ibuf[10];
139
140 cmd[0] = (freq >> 8) & 0x7f;
141 cmd[1] = freq & 0xff;
142 cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
143
144 sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20;
145 do_div(sr,88000);
146 cmd[3] = (sr >> 12) & 0xff;
147 cmd[4] = (sr >> 4) & 0xff;
148 cmd[5] = (sr << 4) & 0xf0;
149
150 deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %Lu (%Lx)\n",
151 fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, sr, sr);
152
153/* if (fep->inversion == INVERSION_ON)
154 cmd[6] |= 0x80; */
155
156 if (st->voltage == SEC_VOLTAGE_18)
157 cmd[6] |= 0x40;
158
159/* if (fep->u.qpsk.symbol_rate > 8000000)
160 cmd[6] |= 0x20;
161
162 if (fep->frequency < 1531000)
163 cmd[6] |= 0x04;
164
165 if (st->tone_mode == SEC_TONE_ON)
166 cmd[6] |= 0x01;*/
167
168 cmd[7] = vp702x_chksum(cmd,0,7);
169
170 st->status_check_interval = 250;
171 st->next_status_check = jiffies;
172
173 vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
174 msleep(30);
175 vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
176
177 if (ibuf[2] == 0 && ibuf[3] == 0)
178 deb_fe("tuning failed.\n");
179 else
180 deb_fe("tuning succeeded.\n");
181
182 return 0;
183}
184
185static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
186 struct dvb_frontend_parameters *fep)
187{
188 deb_fe("%s\n",__FUNCTION__);
189 return 0;
190}
191
192static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
193 struct dvb_diseqc_master_cmd *m)
194{
195 struct vp702x_fe_state *st = fe->demodulator_priv;
196 u8 cmd[8],ibuf[10];
197 memset(cmd,0,8);
198
199 deb_fe("%s\n",__FUNCTION__);
200
201 if (m->msg_len > 4)
202 return -EINVAL;
203
204 cmd[1] = SET_DISEQC_CMD;
205 cmd[2] = m->msg_len;
206 memcpy(&cmd[3], m->msg, m->msg_len);
207 cmd[7] = vp702x_chksum(cmd,0,7);
208
209 vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
210
211 if (ibuf[2] == 0 && ibuf[3] == 0)
212 deb_fe("diseqc cmd failed.\n");
213 else
214 deb_fe("diseqc cmd succeeded.\n");
215
216 return 0;
217}
218
219static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
220{
221 deb_fe("%s\n",__FUNCTION__);
222 return 0;
223}
224
225static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
226{
227 struct vp702x_fe_state *st = fe->demodulator_priv;
228 u8 ibuf[10];
229 deb_fe("%s\n",__FUNCTION__);
230
231 st->tone_mode = tone;
232
233 if (tone == SEC_TONE_ON)
234 st->lnb_buf[2] = 0x02;
235 else
236 st->lnb_buf[2] = 0x00;
237
238 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
239
240 vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
241 if (ibuf[2] == 0 && ibuf[3] == 0)
242 deb_fe("set_tone cmd failed.\n");
243 else
244 deb_fe("set_tone cmd succeeded.\n");
245
246 return 0;
247}
248
249static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
250 voltage)
251{
252 struct vp702x_fe_state *st = fe->demodulator_priv;
253 u8 ibuf[10];
254 deb_fe("%s\n",__FUNCTION__);
255
256 st->voltage = voltage;
257
258 if (voltage != SEC_VOLTAGE_OFF)
259 st->lnb_buf[4] = 0x01;
260 else
261 st->lnb_buf[4] = 0x00;
262
263 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
264
265 vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
266 if (ibuf[2] == 0 && ibuf[3] == 0)
267 deb_fe("set_voltage cmd failed.\n");
268 else
269 deb_fe("set_voltage cmd succeeded.\n");
270
271 return 0;
272}
273
274static void vp702x_fe_release(struct dvb_frontend* fe)
275{
276 struct vp702x_fe_state *st = fe->demodulator_priv;
277 kfree(st);
278}
279
280static struct dvb_frontend_ops vp702x_fe_ops;
281
282struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
283{
284 struct vp702x_fe_state *s = kmalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
285 if (s == NULL)
286 goto error;
287 memset(s,0,sizeof(struct vp702x_fe_state));
288
289 s->d = d;
290 s->fe.ops = &vp702x_fe_ops;
291 s->fe.demodulator_priv = s;
292
293 s->lnb_buf[1] = SET_LNB_POWER;
294 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
295
296 goto success;
297error:
298 return NULL;
299success:
300 return &s->fe;
301}
302
303
304static struct dvb_frontend_ops vp702x_fe_ops = {
305 .info = {
306 .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
307 .type = FE_QPSK,
308 .frequency_min = 950000,
309 .frequency_max = 2150000,
310 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
311 .frequency_tolerance = 0,
312 .symbol_rate_min = 1000000,
313 .symbol_rate_max = 45000000,
314 .symbol_rate_tolerance = 500, /* ppm */
315 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
316 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
317 FE_CAN_QPSK |
318 FE_CAN_FEC_AUTO
319 },
320 .release = vp702x_fe_release,
321
322 .init = NULL,
323 .sleep = NULL,
324
325 .set_frontend = vp702x_fe_set_frontend,
326 .get_frontend = vp702x_fe_get_frontend,
327 .get_tune_settings = vp702x_fe_get_tune_settings,
328
329 .read_status = vp702x_fe_read_status,
330 .read_ber = vp702x_fe_read_ber,
331 .read_signal_strength = vp702x_fe_read_signal_strength,
332 .read_snr = vp702x_fe_read_snr,
333 .read_ucblocks = vp702x_fe_read_unc_blocks,
334
335 .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
336 .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
337 .set_tone = vp702x_fe_set_tone,
338 .set_voltage = vp702x_fe_set_voltage,
339};
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
new file mode 100644
index 000000000000..de13c04e8e64
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -0,0 +1,290 @@
1/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
2 * receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "vp702x.h"
18
19/* debug */
20int dvb_usb_vp702x_debug;
21module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
22MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
23
24struct vp702x_state {
25 u8 pid_table[17]; /* [16] controls the pid_table state */
26};
27
28/* check for mutex FIXME */
29int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
30{
31 int ret = 0,try = 0;
32
33 while (ret >= 0 && ret != blen && try < 3) {
34 ret = usb_control_msg(d->udev,
35 usb_rcvctrlpipe(d->udev,0),
36 req,
37 USB_TYPE_VENDOR | USB_DIR_IN,
38 value,index,b,blen,
39 2000);
40 deb_info("reading number %d (ret: %d)\n",try,ret);
41 try++;
42 }
43
44 if (ret < 0 || ret != blen) {
45 warn("usb in operation failed.");
46 ret = -EIO;
47 } else
48 ret = 0;
49
50 deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
51 debug_dump(b,blen,deb_xfer);
52
53 return ret;
54}
55
56int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
57{
58 deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
59 debug_dump(b,blen,deb_xfer);
60
61 if (usb_control_msg(d->udev,
62 usb_sndctrlpipe(d->udev,0),
63 req,
64 USB_TYPE_VENDOR | USB_DIR_OUT,
65 value,index,b,blen,
66 2000) != blen) {
67 warn("usb out operation failed.");
68 return -EIO;
69 } else
70 return 0;
71}
72
73int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
74{
75 int ret;
76
77 if ((ret = down_interruptible(&d->usb_sem)))
78 return ret;
79
80 if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
81 goto unlock;
82 msleep(msec);
83 ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
84
85unlock:
86 up(&d->usb_sem);
87
88 return ret;
89}
90
91int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
92{
93 u8 bout[olen+2];
94 u8 bin[ilen+1];
95 int ret = 0;
96
97 bout[0] = 0x00;
98 bout[1] = cmd;
99 memcpy(&bout[2],o,olen);
100
101 ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec);
102
103 if (ret == 0)
104 memcpy(i,&bin[1],ilen);
105
106 return ret;
107}
108
109static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
110{
111 struct vp702x_state *st = d->priv;
112 u8 buf[9];
113
114 if (onoff) {
115 st->pid_table[16] |= 1 << index;
116 st->pid_table[index*2] = (pid >> 8) & 0xff;
117 st->pid_table[index*2+1] = pid & 0xff;
118 } else {
119 st->pid_table[16] &= ~(1 << index);
120 st->pid_table[index*2] = st->pid_table[index*2+1] = 0;
121 }
122
123 return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10);
124}
125
126static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
127{
128 vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0);
129
130 vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
131 return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
132}
133
134/* keys for the enclosed remote control */
135static struct dvb_usb_rc_key vp702x_rc_keys[] = {
136 { 0x00, 0x01, KEY_1 },
137 { 0x00, 0x02, KEY_2 },
138};
139
140/* remote control stuff (does not work with my box) */
141static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
142{
143 u8 key[10];
144 int i;
145
146/* remove the following return to enabled remote querying */
147 return 0;
148
149 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
150
151 deb_rc("remote query key: %x %d\n",key[1],key[1]);
152
153 if (key[1] == 0x44) {
154 *state = REMOTE_NO_KEY_PRESSED;
155 return 0;
156 }
157
158 for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
159 if (vp702x_rc_keys[i].custom == key[1]) {
160 *state = REMOTE_KEY_PRESSED;
161 *event = vp702x_rc_keys[i].event;
162 break;
163 }
164 return 0;
165}
166
167static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
168{
169 u8 macb[9];
170 if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10))
171 return -EIO;
172 memcpy(mac,&macb[3],6);
173 return 0;
174}
175
176static int vp702x_frontend_attach(struct dvb_usb_device *d)
177{
178 u8 buf[9] = { 0 };
179
180 if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10))
181 return -EIO;
182
183 buf[8] = '\0';
184 info("system string: %s",&buf[1]);
185
186 d->fe = vp702x_fe_attach(d);
187 return 0;
188}
189
190static struct dvb_usb_properties vp702x_properties;
191
192static int vp702x_usb_probe(struct usb_interface *intf,
193 const struct usb_device_id *id)
194{
195 struct usb_device *udev = interface_to_usbdev(intf);
196
197 usb_clear_halt(udev,usb_sndctrlpipe(udev,0));
198 usb_clear_halt(udev,usb_rcvctrlpipe(udev,0));
199
200 return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
201}
202
203static struct usb_device_id vp702x_usb_table [] = {
204 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
205 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) },
206 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
207 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
208 { 0 },
209};
210MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
211
212static struct dvb_usb_properties vp702x_properties = {
213 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
214 .pid_filter_count = 8, /* !!! */
215
216 .usb_ctrl = CYPRESS_FX2,
217 .firmware = "dvb-usb-vp702x-01.fw",
218
219 .pid_filter = vp702x_pid_filter,
220 .power_ctrl = vp702x_power_ctrl,
221 .frontend_attach = vp702x_frontend_attach,
222 .read_mac_address = vp702x_read_mac_addr,
223
224 .rc_key_map = vp702x_rc_keys,
225 .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys),
226 .rc_interval = 400,
227 .rc_query = vp702x_rc_query,
228
229 .size_of_priv = sizeof(struct vp702x_state),
230
231 /* parameter for the MPEG2-data transfer */
232 .urb = {
233 .type = DVB_USB_BULK,
234 .count = 7,
235 .endpoint = 0x02,
236 .u = {
237 .bulk = {
238 .buffersize = 4096,
239 }
240 }
241 },
242
243 .num_device_descs = 2,
244 .devices = {
245 { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
246 .cold_ids = { &vp702x_usb_table[0], NULL },
247 .warm_ids = { &vp702x_usb_table[1], NULL },
248 },
249 { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
250 .cold_ids = { &vp702x_usb_table[2], NULL },
251 .warm_ids = { &vp702x_usb_table[3], NULL },
252 },
253 { 0 },
254 }
255};
256
257/* usb specific object needed to register this driver with the usb subsystem */
258static struct usb_driver vp702x_usb_driver = {
259 .owner = THIS_MODULE,
260 .name = "dvb-usb-vp702x",
261 .probe = vp702x_usb_probe,
262 .disconnect = dvb_usb_device_exit,
263 .id_table = vp702x_usb_table,
264};
265
266/* module stuff */
267static int __init vp702x_usb_module_init(void)
268{
269 int result;
270 if ((result = usb_register(&vp702x_usb_driver))) {
271 err("usb_register failed. (%d)",result);
272 return result;
273 }
274
275 return 0;
276}
277
278static void __exit vp702x_usb_module_exit(void)
279{
280 /* deregister this driver from the USB subsystem */
281 usb_deregister(&vp702x_usb_driver);
282}
283
284module_init(vp702x_usb_module_init);
285module_exit(vp702x_usb_module_exit);
286
287MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
288MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
289MODULE_VERSION("1.0-alpha");
290MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
new file mode 100644
index 000000000000..4a3e8c7eca2b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -0,0 +1,109 @@
1#ifndef _DVB_USB_VP7021_H_
2#define _DVB_USB_VP7021_H_
3
4#define DVB_USB_LOG_PREFIX "vp702x"
5#include "dvb-usb.h"
6
7extern int dvb_usb_vp702x_debug;
8#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
9#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
10#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args)
11#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args)
12
13/* commands are read and written with USB control messages */
14
15/* consecutive read/write operation */
16#define REQUEST_OUT 0xB2
17#define REQUEST_IN 0xB3
18
19/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
20 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
21 * the returning buffer looks as follows
22 * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
23
24#define GET_TUNER_STATUS 0x05
25/* additional in buffer:
26 * 0 1 2 3 4 5 6 7 8
27 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
28
29#define GET_SYSTEM_STRING 0x06
30/* additional in buffer:
31 * 0 1 2 3 4 5 6 7 8
32 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
33
34#define SET_DISEQC_CMD 0x08
35/* additional out buffer:
36 * 0 1 2 3 4
37 * len X1 X2 X3 X4
38 * additional in buffer:
39 * 0 1 2
40 * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
41
42#define SET_LNB_POWER 0x09
43/* additional out buffer:
44 * 0 1 2
45 * 0x00 0xff 1 = on, 0 = off
46 * additional in buffer:
47 * 0 1 2
48 * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
49
50#define GET_MAC_ADDRESS 0x0A
51/* #define GET_MAC_ADDRESS 0x0B */
52/* additional in buffer:
53 * 0 1 2 3 4 5 6 7 8
54 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
55
56#define SET_PID_FILTER 0x11
57/* additional in buffer:
58 * 0 1 ... 14 15 16
59 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
60
61/* request: 0xB2; i: 0; v: 0;
62 * b[0] != 0 -> tune and lock a channel
63 * 0 1 2 3 4 5 6 7
64 * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
65 */
66
67
68/* one direction requests */
69#define READ_REMOTE_REQ 0xB4
70/* IN i: 0; v: 0; b[0] == request, b[1] == key */
71
72#define READ_PID_NUMBER_REQ 0xB5
73/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
74
75#define WRITE_EEPROM_REQ 0xB6
76/* OUT i: offset; v: value to write; no extra buffer */
77
78#define READ_EEPROM_REQ 0xB7
79/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
80
81#define READ_STATUS 0xB8
82/* IN i: 0; v: 0; bufferlen 10 */
83
84#define READ_TUNER_REG_REQ 0xB9
85/* IN i: 0; v: register; b[0] = value */
86
87#define READ_FX2_REG_REQ 0xBA
88/* IN i: offset; v: 0; b[0] = value */
89
90#define WRITE_FX2_REG_REQ 0xBB
91/* OUT i: offset; v: value to write; 1 byte extra buffer */
92
93#define SET_TUNER_POWER_REQ 0xBC
94/* IN i: 0 = power off, 1 = power on */
95
96#define WRITE_TUNER_REG_REQ 0xBD
97/* IN i: register, v: value to write, no extra buffer */
98
99#define RESET_TUNER 0xBE
100/* IN i: 0, v: 0, no extra buffer */
101
102extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
103
104extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
105extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
106extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
107extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
108
109#endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 9ac95f54f9fc..0f57abeb6d6b 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -164,7 +164,6 @@ static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int off
164 return 0; 164 return 0;
165} 165}
166 166
167
168static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) 167static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
169{ 168{
170 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR); 169 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
@@ -199,7 +198,7 @@ static struct dvb_usb_properties vp7045_properties;
199static int vp7045_usb_probe(struct usb_interface *intf, 198static int vp7045_usb_probe(struct usb_interface *intf,
200 const struct usb_device_id *id) 199 const struct usb_device_id *id)
201{ 200{
202 return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE); 201 return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL);
203} 202}
204 203
205static struct usb_device_id vp7045_usb_table [] = { 204static struct usb_device_id vp7045_usb_table [] = {
@@ -256,9 +255,9 @@ static struct dvb_usb_properties vp7045_properties = {
256static struct usb_driver vp7045_usb_driver = { 255static struct usb_driver vp7045_usb_driver = {
257 .owner = THIS_MODULE, 256 .owner = THIS_MODULE,
258 .name = "dvb_usb_vp7045", 257 .name = "dvb_usb_vp7045",
259 .probe = vp7045_usb_probe, 258 .probe = vp7045_usb_probe,
260 .disconnect = dvb_usb_device_exit, 259 .disconnect = dvb_usb_device_exit,
261 .id_table = vp7045_usb_table, 260 .id_table = vp7045_usb_table,
262}; 261};
263 262
264/* module stuff */ 263/* module stuff */
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 8222b88cb486..d4b97989e3ed 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,7 +1,7 @@
1/* 1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module 2 cx24110 - Single Chip Satellite Channel Receiver driver module
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
5 work 5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7 7
@@ -387,8 +387,9 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
387 387
388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
389{ 389{
390 int rv, bit, i; 390 int rv, bit;
391 struct cx24110_state *state = fe->demodulator_priv; 391 struct cx24110_state *state = fe->demodulator_priv;
392 unsigned long timeout;
392 393
393 if (burst == SEC_MINI_A) 394 if (burst == SEC_MINI_A)
394 bit = 0x00; 395 bit = 0x00;
@@ -398,12 +399,14 @@ static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
398 return -EINVAL; 399 return -EINVAL;
399 400
400 rv = cx24110_readreg(state, 0x77); 401 rv = cx24110_readreg(state, 0x77);
401 cx24110_writereg(state, 0x77, rv|0x04); 402 if (!(rv & 0x04))
403 cx24110_writereg(state, 0x77, rv | 0x04);
402 404
403 rv = cx24110_readreg(state, 0x76); 405 rv = cx24110_readreg(state, 0x76);
404 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit)); 406 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
405 for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; ) 407 timeout = jiffies + msecs_to_jiffies(100);
406 ; /* wait for LNB ready */ 408 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
409 ; /* wait for LNB ready */
407 410
408 return 0; 411 return 0;
409} 412}
@@ -413,17 +416,22 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
413{ 416{
414 int i, rv; 417 int i, rv;
415 struct cx24110_state *state = fe->demodulator_priv; 418 struct cx24110_state *state = fe->demodulator_priv;
419 unsigned long timeout;
416 420
417 for (i = 0; i < cmd->msg_len; i++) 421 for (i = 0; i < cmd->msg_len; i++)
418 cx24110_writereg(state, 0x79 + i, cmd->msg[i]); 422 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
419 423
420 rv = cx24110_readreg(state, 0x77); 424 rv = cx24110_readreg(state, 0x77);
421 cx24110_writereg(state, 0x77, rv|0x04); 425 if (rv & 0x04) {
426 cx24110_writereg(state, 0x77, rv & ~0x04);
427 msleep(30); /* reportedly fixes switching problems */
428 }
422 429
423 rv = cx24110_readreg(state, 0x76); 430 rv = cx24110_readreg(state, 0x76);
424 431
425 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); 432 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
426 for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);) 433 timeout = jiffies + msecs_to_jiffies(100);
434 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
427 ; /* wait for LNB ready */ 435 ; /* wait for LNB ready */
428 436
429 return 0; 437 return 0;
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 6b663f4744e0..b63ecf26421a 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -1,7 +1,7 @@
1/* 1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module 2 cx24110 - Single Chip Satellite Channel Receiver driver module
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
5 work 5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7 7
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index cd434b7cf9db..21433e1831e7 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -23,7 +23,6 @@
23 23
24#include <linux/config.h> 24#include <linux/config.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
29#include <linux/init.h> 28#include <linux/init.h>
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index cd33705a4320..441de665fec3 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -22,7 +22,6 @@
22 */ 22 */
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/version.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
28#include <linux/init.h> 27#include <linux/init.h>
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index d32dc4de9e7f..cc1bc0edd65e 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -462,9 +462,11 @@ static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
462{ 462{
463 struct mt352_state* state = fe->demodulator_priv; 463 struct mt352_state* state = fe->demodulator_priv;
464 464
465 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) | 465 /* align the 12 bit AGC gain with the most significant bits */
466 (mt352_read_register(state, AGC_GAIN_0)); 466 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
467 (mt352_read_register(state, AGC_GAIN_0) << 4);
467 468
469 /* inverse of gain is signal strength */
468 *strength = ~signal; 470 *strength = ~signal;
469 return 0; 471 return 0;
470} 472}
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index 966de9853d18..88a57b791112 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -482,6 +482,7 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
482 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0) 482 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
483 return result; 483 return result;
484 484
485 msleep(500);
485 return 0; 486 return 0;
486} 487}
487 488
@@ -525,6 +526,12 @@ static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
525 return 0; 526 return 0;
526} 527}
527 528
529static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
530{
531 tune->min_delay_ms = 500;
532 return 0;
533}
534
528static struct dvb_frontend_ops nxt6000_ops; 535static struct dvb_frontend_ops nxt6000_ops;
529 536
530struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, 537struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
@@ -578,6 +585,8 @@ static struct dvb_frontend_ops nxt6000_ops = {
578 585
579 .init = nxt6000_init, 586 .init = nxt6000_init,
580 587
588 .get_tune_settings = nxt6000_fe_get_tune_settings,
589
581 .set_frontend = nxt6000_set_frontend, 590 .set_frontend = nxt6000_set_frontend,
582 591
583 .read_status = nxt6000_read_status, 592 .read_status = nxt6000_read_status,
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index cc0a77c790f1..b6d0eecc59eb 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -370,22 +370,19 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
370 or51132_setmode(fe); 370 or51132_setmode(fe);
371 } 371 }
372 372
373 /* Change only if we are actually changing the channel */ 373 dvb_pll_configure(state->config->pll_desc, buf,
374 if (state->current_frequency != param->frequency) { 374 param->frequency, 0);
375 dvb_pll_configure(state->config->pll_desc, buf, 375 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
376 param->frequency, 0); 376 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
377 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " 377 if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
378 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); 378 printk(KERN_WARNING "or51132: set_parameters error "
379 if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) 379 "writing to tuner\n");
380 printk(KERN_WARNING "or51132: set_parameters error " 380
381 "writing to tuner\n"); 381 /* Set to current mode */
382 382 or51132_setmode(fe);
383 /* Set to current mode */ 383
384 or51132_setmode(fe); 384 /* Update current frequency */
385 385 state->current_frequency = param->frequency;
386 /* Update current frequency */
387 state->current_frequency = param->frequency;
388 }
389 return 0; 386 return 0;
390} 387}
391 388
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 4f396ac8de77..c7fe27fd530c 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -48,7 +48,8 @@ struct s5h1420_state {
48}; 48};
49 49
50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); 50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
51static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings); 51static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
52 struct dvb_frontend_tune_settings* fesettings);
52 53
53 54
54static int debug = 0; 55static int debug = 0;
@@ -91,7 +92,8 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
91 92
92 switch(voltage) { 93 switch(voltage) {
93 case SEC_VOLTAGE_13: 94 case SEC_VOLTAGE_13:
94 s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02); 95 s5h1420_writereg(state, 0x3c,
96 (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
95 break; 97 break;
96 98
97 case SEC_VOLTAGE_18: 99 case SEC_VOLTAGE_18:
@@ -112,18 +114,21 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
112 114
113 switch(tone) { 115 switch(tone) {
114 case SEC_TONE_ON: 116 case SEC_TONE_ON:
115 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08); 117 s5h1420_writereg(state, 0x3b,
118 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
116 break; 119 break;
117 120
118 case SEC_TONE_OFF: 121 case SEC_TONE_OFF:
119 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01); 122 s5h1420_writereg(state, 0x3b,
123 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
120 break; 124 break;
121 } 125 }
122 126
123 return 0; 127 return 0;
124} 128}
125 129
126static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) 130static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
131 struct dvb_diseqc_master_cmd* cmd)
127{ 132{
128 struct s5h1420_state* state = fe->demodulator_priv; 133 struct s5h1420_state* state = fe->demodulator_priv;
129 u8 val; 134 u8 val;
@@ -131,6 +136,9 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
131 unsigned long timeout; 136 unsigned long timeout;
132 int result = 0; 137 int result = 0;
133 138
139 if (cmd->msg_len > 8)
140 return -EINVAL;
141
134 /* setup for DISEQC */ 142 /* setup for DISEQC */
135 val = s5h1420_readreg(state, 0x3b); 143 val = s5h1420_readreg(state, 0x3b);
136 s5h1420_writereg(state, 0x3b, 0x02); 144 s5h1420_writereg(state, 0x3b, 0x02);
@@ -138,16 +146,17 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
138 146
139 /* write the DISEQC command bytes */ 147 /* write the DISEQC command bytes */
140 for(i=0; i< cmd->msg_len; i++) { 148 for(i=0; i< cmd->msg_len; i++) {
141 s5h1420_writereg(state, 0x3c + i, cmd->msg[i]); 149 s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
142 } 150 }
143 151
144 /* kick off transmission */ 152 /* kick off transmission */
145 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08); 153 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
154 ((cmd->msg_len-1) << 4) | 0x08);
146 155
147 /* wait for transmission to complete */ 156 /* wait for transmission to complete */
148 timeout = jiffies + ((100*HZ) / 1000); 157 timeout = jiffies + ((100*HZ) / 1000);
149 while(time_before(jiffies, timeout)) { 158 while(time_before(jiffies, timeout)) {
150 if (s5h1420_readreg(state, 0x3b) & 0x08) 159 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
151 break; 160 break;
152 161
153 msleep(5); 162 msleep(5);
@@ -161,7 +170,8 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
161 return result; 170 return result;
162} 171}
163 172
164static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply) 173static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
174 struct dvb_diseqc_slave_reply* reply)
165{ 175{
166 struct s5h1420_state* state = fe->demodulator_priv; 176 struct s5h1420_state* state = fe->demodulator_priv;
167 u8 val; 177 u8 val;
@@ -205,7 +215,7 @@ static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_
205 215
206 /* extract data */ 216 /* extract data */
207 for(i=0; i< length; i++) { 217 for(i=0; i< length; i++) {
208 reply->msg[i] = s5h1420_readreg(state, 0x3c + i); 218 reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
209 } 219 }
210 220
211exit: 221exit:
@@ -236,7 +246,7 @@ static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicm
236 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08); 246 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
237 247
238 /* wait for transmission to complete */ 248 /* wait for transmission to complete */
239 timeout = jiffies + ((20*HZ) / 1000); 249 timeout = jiffies + ((100*HZ) / 1000);
240 while(time_before(jiffies, timeout)) { 250 while(time_before(jiffies, timeout)) {
241 if (!(s5h1420_readreg(state, 0x3b) & 0x08)) 251 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
242 break; 252 break;
@@ -259,9 +269,9 @@ static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
259 269
260 val = s5h1420_readreg(state, 0x14); 270 val = s5h1420_readreg(state, 0x14);
261 if (val & 0x02) 271 if (val & 0x02)
262 status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right 272 status |= FE_HAS_SIGNAL;
263 if (val & 0x01) 273 if (val & 0x01)
264 status |= FE_HAS_CARRIER; // FIXME: not sure if this is right 274 status |= FE_HAS_CARRIER;
265 val = s5h1420_readreg(state, 0x36); 275 val = s5h1420_readreg(state, 0x36);
266 if (val & 0x01) 276 if (val & 0x01)
267 status |= FE_HAS_VITERBI; 277 status |= FE_HAS_VITERBI;
@@ -284,8 +294,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
284 /* determine lock state */ 294 /* determine lock state */
285 *status = s5h1420_get_status_bits(state); 295 *status = s5h1420_get_status_bits(state);
286 296
287 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion, 297 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
288 wait a bit and check again */ 298 the inversion, wait a bit and check again */
289 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) { 299 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
290 val = s5h1420_readreg(state, 0x32); 300 val = s5h1420_readreg(state, 0x32);
291 if ((val & 0x07) == 0x03) { 301 if ((val & 0x07) == 0x03) {
@@ -330,6 +340,10 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
330 tmp = (tmp * 2 * 7) / 8; 340 tmp = (tmp * 2 * 7) / 8;
331 break; 341 break;
332 } 342 }
343 if (tmp == 0) {
344 printk("s5h1420: avoided division by 0\n");
345 tmp = 1;
346 }
333 tmp = state->fclk / tmp; 347 tmp = state->fclk / tmp;
334 348
335 /* set the MPEG_CLK_INTL for the calculated data rate */ 349 /* set the MPEG_CLK_INTL for the calculated data rate */
@@ -368,16 +382,21 @@ static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
368 382
369 s5h1420_writereg(state, 0x46, 0x1d); 383 s5h1420_writereg(state, 0x46, 0x1d);
370 mdelay(25); 384 mdelay(25);
371 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); 385
386 *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
387
388 return 0;
372} 389}
373 390
374static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength) 391static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
375{ 392{
376 struct s5h1420_state* state = fe->demodulator_priv; 393 struct s5h1420_state* state = fe->demodulator_priv;
377 394
378 u8 val = 0xff - s5h1420_readreg(state, 0x15); 395 u8 val = s5h1420_readreg(state, 0x15);
379 396
380 return (int) ((val << 8) | val); 397 *strength = (u16) ((val << 8) | val);
398
399 return 0;
381} 400}
382 401
383static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 402static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
@@ -386,7 +405,10 @@ static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
386 405
387 s5h1420_writereg(state, 0x46, 0x1f); 406 s5h1420_writereg(state, 0x46, 0x1f);
388 mdelay(25); 407 mdelay(25);
389 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); 408
409 *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
410
411 return 0;
390} 412}
391 413
392static void s5h1420_reset(struct s5h1420_state* state) 414static void s5h1420_reset(struct s5h1420_state* state)
@@ -396,11 +418,12 @@ static void s5h1420_reset(struct s5h1420_state* state)
396 udelay(10); 418 udelay(10);
397} 419}
398 420
399static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p) 421static void s5h1420_setsymbolrate(struct s5h1420_state* state,
422 struct dvb_frontend_parameters *p)
400{ 423{
401 u64 val; 424 u64 val;
402 425
403 val = (p->u.qpsk.symbol_rate / 1000) * (1<<24); 426 val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
404 if (p->u.qpsk.symbol_rate <= 21000000) { 427 if (p->u.qpsk.symbol_rate <= 21000000) {
405 val *= 2; 428 val *= 2;
406 } 429 }
@@ -415,7 +438,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_fronte
415 438
416static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) 439static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
417{ 440{
418 u64 val; 441 u64 val = 0;
419 int sampling = 2; 442 int sampling = 2;
420 443
421 if (s5h1420_readreg(state, 0x05) & 0x2) 444 if (s5h1420_readreg(state, 0x05) & 0x2)
@@ -427,10 +450,10 @@ static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
427 val |= s5h1420_readreg(state, 0x13); 450 val |= s5h1420_readreg(state, 0x13);
428 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); 451 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
429 452
430 val *= (state->fclk / 1000); 453 val *= (state->fclk / 1000ULL);
431 do_div(val, ((1<<24) * sampling)); 454 do_div(val, ((1<<24) * sampling));
432 455
433 return (u32) (val * 1000); 456 return (u32) (val * 1000ULL);
434} 457}
435 458
436static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) 459static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
@@ -463,46 +486,55 @@ static int s5h1420_getfreqoffset(struct s5h1420_state* state)
463 486
464 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so 487 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
465 * divide fclk by 1000000 to get the correct value. */ 488 * divide fclk by 1000000 to get the correct value. */
466 val = - ((val * (state->fclk/1000000)) / (1<<24)); 489 val = (((-val) * (state->fclk/1000000)) / (1<<24));
467 490
468 return val; 491 return val;
469} 492}
470 493
471static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p) 494static void s5h1420_setfec_inversion(struct s5h1420_state* state,
495 struct dvb_frontend_parameters *p)
472{ 496{
497 u8 inversion = 0;
498
499 if (p->inversion == INVERSION_OFF) {
500 inversion = state->config->invert ? 0x08 : 0;
501 } else if (p->inversion == INVERSION_ON) {
502 inversion = state->config->invert ? 0 : 0x08;
503 }
504
473 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { 505 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
474 s5h1420_writereg(state, 0x31, 0x00);
475 s5h1420_writereg(state, 0x30, 0x3f); 506 s5h1420_writereg(state, 0x30, 0x3f);
507 s5h1420_writereg(state, 0x31, 0x00 | inversion);
476 } else { 508 } else {
477 switch(p->u.qpsk.fec_inner) { 509 switch(p->u.qpsk.fec_inner) {
478 case FEC_1_2: 510 case FEC_1_2:
479 s5h1420_writereg(state, 0x31, 0x10);
480 s5h1420_writereg(state, 0x30, 0x01); 511 s5h1420_writereg(state, 0x30, 0x01);
512 s5h1420_writereg(state, 0x31, 0x10 | inversion);
481 break; 513 break;
482 514
483 case FEC_2_3: 515 case FEC_2_3:
484 s5h1420_writereg(state, 0x31, 0x11);
485 s5h1420_writereg(state, 0x30, 0x02); 516 s5h1420_writereg(state, 0x30, 0x02);
517 s5h1420_writereg(state, 0x31, 0x11 | inversion);
486 break; 518 break;
487 519
488 case FEC_3_4: 520 case FEC_3_4:
489 s5h1420_writereg(state, 0x31, 0x12);
490 s5h1420_writereg(state, 0x30, 0x04); 521 s5h1420_writereg(state, 0x30, 0x04);
491 break; 522 s5h1420_writereg(state, 0x31, 0x12 | inversion);
523 break;
492 524
493 case FEC_5_6: 525 case FEC_5_6:
494 s5h1420_writereg(state, 0x31, 0x13);
495 s5h1420_writereg(state, 0x30, 0x08); 526 s5h1420_writereg(state, 0x30, 0x08);
527 s5h1420_writereg(state, 0x31, 0x13 | inversion);
496 break; 528 break;
497 529
498 case FEC_6_7: 530 case FEC_6_7:
499 s5h1420_writereg(state, 0x31, 0x14);
500 s5h1420_writereg(state, 0x30, 0x10); 531 s5h1420_writereg(state, 0x30, 0x10);
532 s5h1420_writereg(state, 0x31, 0x14 | inversion);
501 break; 533 break;
502 534
503 case FEC_7_8: 535 case FEC_7_8:
504 s5h1420_writereg(state, 0x31, 0x15);
505 s5h1420_writereg(state, 0x30, 0x20); 536 s5h1420_writereg(state, 0x30, 0x20);
537 s5h1420_writereg(state, 0x31, 0x15 | inversion);
506 break; 538 break;
507 539
508 default: 540 default:
@@ -536,22 +568,6 @@ static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
536 return FEC_NONE; 568 return FEC_NONE;
537} 569}
538 570
539static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
540{
541 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
542 s5h1420_writereg(state, 0x31, 0x00);
543 s5h1420_writereg(state, 0x30, 0x3f);
544 } else {
545 u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
546 tmp |= 0x10;
547
548 if (p->inversion == INVERSION_ON)
549 tmp |= 0x80;
550
551 s5h1420_writereg(state, 0x31, tmp);
552 }
553}
554
555static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) 571static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
556{ 572{
557 if (s5h1420_readreg(state, 0x32) & 0x08) 573 if (s5h1420_readreg(state, 0x32) & 0x08)
@@ -560,35 +576,35 @@ static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
560 return INVERSION_OFF; 576 return INVERSION_OFF;
561} 577}
562 578
563static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 579static int s5h1420_set_frontend(struct dvb_frontend* fe,
580 struct dvb_frontend_parameters *p)
564{ 581{
565 struct s5h1420_state* state = fe->demodulator_priv; 582 struct s5h1420_state* state = fe->demodulator_priv;
566 u32 frequency_delta; 583 int frequency_delta;
567 struct dvb_frontend_tune_settings fesettings; 584 struct dvb_frontend_tune_settings fesettings;
585 u32 tmp;
568 586
569 /* check if we should do a fast-tune */ 587 /* check if we should do a fast-tune */
570 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); 588 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
571 s5h1420_get_tune_settings(fe, &fesettings); 589 s5h1420_get_tune_settings(fe, &fesettings);
572 frequency_delta = p->frequency - state->tunedfreq; 590 frequency_delta = p->frequency - state->tunedfreq;
573 if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) && 591 if ((frequency_delta > -fesettings.max_drift) &&
592 (frequency_delta < fesettings.max_drift) &&
574 (frequency_delta != 0) && 593 (frequency_delta != 0) &&
575 (state->fec_inner == p->u.qpsk.fec_inner) && 594 (state->fec_inner == p->u.qpsk.fec_inner) &&
576 (state->symbol_rate == p->u.qpsk.symbol_rate)) { 595 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
577 596
578 s5h1420_setfreqoffset(state, frequency_delta); 597 if (state->config->pll_set) {
598 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
599 state->config->pll_set(fe, p, &tmp);
600 s5h1420_setfreqoffset(state, p->frequency - tmp);
601 }
579 return 0; 602 return 0;
580 } 603 }
581 604
582 /* first of all, software reset */ 605 /* first of all, software reset */
583 s5h1420_reset(state); 606 s5h1420_reset(state);
584 607
585 /* set tuner PLL */
586 if (state->config->pll_set) {
587 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
588 state->config->pll_set(fe, p, &state->tunedfreq);
589 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
590 }
591
592 /* set s5h1420 fclk PLL according to desired symbol rate */ 608 /* set s5h1420 fclk PLL according to desired symbol rate */
593 if (p->u.qpsk.symbol_rate > 28000000) { 609 if (p->u.qpsk.symbol_rate > 28000000) {
594 state->fclk = 88000000; 610 state->fclk = 88000000;
@@ -609,8 +625,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
609 625
610 /* set misc registers */ 626 /* set misc registers */
611 s5h1420_writereg(state, 0x02, 0x00); 627 s5h1420_writereg(state, 0x02, 0x00);
628 s5h1420_writereg(state, 0x06, 0x00);
612 s5h1420_writereg(state, 0x07, 0xb0); 629 s5h1420_writereg(state, 0x07, 0xb0);
613 s5h1420_writereg(state, 0x0a, 0x67); 630 s5h1420_writereg(state, 0x0a, 0xe7);
614 s5h1420_writereg(state, 0x0b, 0x78); 631 s5h1420_writereg(state, 0x0b, 0x78);
615 s5h1420_writereg(state, 0x0c, 0x48); 632 s5h1420_writereg(state, 0x0c, 0x48);
616 s5h1420_writereg(state, 0x0d, 0x6b); 633 s5h1420_writereg(state, 0x0d, 0x6b);
@@ -626,21 +643,26 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
626 /* start QPSK */ 643 /* start QPSK */
627 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); 644 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
628 645
629 /* set the frequency offset to adjust for PLL inaccuracy */ 646 /* set tuner PLL */
630 s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq); 647 if (state->config->pll_set) {
648 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
649 state->config->pll_set(fe, p, &tmp);
650 s5h1420_setfreqoffset(state, 0);
651 }
631 652
632 /* set the reset of the parameters */ 653 /* set the reset of the parameters */
633 s5h1420_setsymbolrate(state, p); 654 s5h1420_setsymbolrate(state, p);
634 s5h1420_setinversion(state, p); 655 s5h1420_setfec_inversion(state, p);
635 s5h1420_setfec(state, p);
636 656
637 state->fec_inner = p->u.qpsk.fec_inner; 657 state->fec_inner = p->u.qpsk.fec_inner;
638 state->symbol_rate = p->u.qpsk.symbol_rate; 658 state->symbol_rate = p->u.qpsk.symbol_rate;
639 state->postlocked = 0; 659 state->postlocked = 0;
660 state->tunedfreq = p->frequency;
640 return 0; 661 return 0;
641} 662}
642 663
643static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 664static int s5h1420_get_frontend(struct dvb_frontend* fe,
665 struct dvb_frontend_parameters *p)
644{ 666{
645 struct s5h1420_state* state = fe->demodulator_priv; 667 struct s5h1420_state* state = fe->demodulator_priv;
646 668
@@ -652,7 +674,8 @@ static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
652 return 0; 674 return 0;
653} 675}
654 676
655static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 677static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
678 struct dvb_frontend_tune_settings* fesettings)
656{ 679{
657 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { 680 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
658 fesettings->min_delay_ms = 50; 681 fesettings->min_delay_ms = 50;
@@ -717,7 +740,8 @@ static void s5h1420_release(struct dvb_frontend* fe)
717 740
718static struct dvb_frontend_ops s5h1420_ops; 741static struct dvb_frontend_ops s5h1420_ops;
719 742
720struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c) 743struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
744 struct i2c_adapter* i2c)
721{ 745{
722 struct s5h1420_state* state = NULL; 746 struct s5h1420_state* state = NULL;
723 u8 identity; 747 u8 identity;
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index b687fc77ceb3..872028ddf2a2 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -30,6 +30,9 @@ struct s5h1420_config
30 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
31 u8 demod_address; 31 u8 demod_address;
32 32
33 /* does the inversion require inversion? */
34 u8 invert:1;
35
33 /* PLL maintenance */ 36 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe); 37 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout); 38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 928aca052afe..8d09afd7545d 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -35,7 +35,6 @@ struct stv0297_state {
35 struct dvb_frontend frontend; 35 struct dvb_frontend frontend;
36 36
37 unsigned long base_freq; 37 unsigned long base_freq;
38 u8 pwm;
39}; 38};
40 39
41#if 1 40#if 1
@@ -46,94 +45,6 @@ struct stv0297_state {
46 45
47#define STV0297_CLOCK_KHZ 28900 46#define STV0297_CLOCK_KHZ 28900
48 47
49static u8 init_tab[] = {
50 0x00, 0x09,
51 0x01, 0x69,
52 0x03, 0x00,
53 0x04, 0x00,
54 0x07, 0x00,
55 0x08, 0x00,
56 0x20, 0x00,
57 0x21, 0x40,
58 0x22, 0x00,
59 0x23, 0x00,
60 0x24, 0x40,
61 0x25, 0x88,
62 0x30, 0xff,
63 0x31, 0x00,
64 0x32, 0xff,
65 0x33, 0x00,
66 0x34, 0x50,
67 0x35, 0x7f,
68 0x36, 0x00,
69 0x37, 0x20,
70 0x38, 0x00,
71 0x40, 0x1c,
72 0x41, 0xff,
73 0x42, 0x29,
74 0x43, 0x00,
75 0x44, 0xff,
76 0x45, 0x00,
77 0x46, 0x00,
78 0x49, 0x04,
79 0x4a, 0xff,
80 0x4b, 0x7f,
81 0x52, 0x30,
82 0x55, 0xae,
83 0x56, 0x47,
84 0x57, 0xe1,
85 0x58, 0x3a,
86 0x5a, 0x1e,
87 0x5b, 0x34,
88 0x60, 0x00,
89 0x63, 0x00,
90 0x64, 0x00,
91 0x65, 0x00,
92 0x66, 0x00,
93 0x67, 0x00,
94 0x68, 0x00,
95 0x69, 0x00,
96 0x6a, 0x02,
97 0x6b, 0x00,
98 0x70, 0xff,
99 0x71, 0x00,
100 0x72, 0x00,
101 0x73, 0x00,
102 0x74, 0x0c,
103 0x80, 0x00,
104 0x81, 0x00,
105 0x82, 0x00,
106 0x83, 0x00,
107 0x84, 0x04,
108 0x85, 0x80,
109 0x86, 0x24,
110 0x87, 0x78,
111 0x88, 0x00,
112 0x89, 0x00,
113 0x90, 0x01,
114 0x91, 0x01,
115 0xa0, 0x00,
116 0xa1, 0x00,
117 0xa2, 0x00,
118 0xb0, 0x91,
119 0xb1, 0x0b,
120 0xc0, 0x53,
121 0xc1, 0x70,
122 0xc2, 0x12,
123 0xd0, 0x00,
124 0xd1, 0x00,
125 0xd2, 0x00,
126 0xd3, 0x00,
127 0xd4, 0x00,
128 0xd5, 0x00,
129 0xde, 0x00,
130 0xdf, 0x00,
131 0x61, 0x49,
132 0x62, 0x0b,
133 0x53, 0x08,
134 0x59, 0x08,
135};
136
137 48
138static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) 49static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
139{ 50{
@@ -378,34 +289,9 @@ static int stv0297_init(struct dvb_frontend *fe)
378 struct stv0297_state *state = fe->demodulator_priv; 289 struct stv0297_state *state = fe->demodulator_priv;
379 int i; 290 int i;
380 291
381 /* soft reset */
382 stv0297_writereg_mask(state, 0x80, 1, 1);
383 stv0297_writereg_mask(state, 0x80, 1, 0);
384
385 /* reset deinterleaver */
386 stv0297_writereg_mask(state, 0x81, 1, 1);
387 stv0297_writereg_mask(state, 0x81, 1, 0);
388
389 /* load init table */ 292 /* load init table */
390 for (i = 0; i < sizeof(init_tab); i += 2) { 293 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
391 stv0297_writereg(state, init_tab[i], init_tab[i + 1]); 294 stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
392 }
393
394 /* set a dummy symbol rate */
395 stv0297_set_symbolrate(state, 6900);
396
397 /* invert AGC1 polarity */
398 stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
399
400 /* setup bit error counting */
401 stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
402 stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
403 stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
404 stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
405
406 /* min + max PWM */
407 stv0297_writereg(state, 0x4a, 0x00);
408 stv0297_writereg(state, 0x4b, state->pwm);
409 msleep(200); 295 msleep(200);
410 296
411 if (state->config->pll_init) 297 if (state->config->pll_init)
@@ -606,7 +492,13 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
606 stv0297_set_inversion(state, inversion); 492 stv0297_set_inversion(state, inversion);
607 493
608 /* kick off lock */ 494 /* kick off lock */
609 stv0297_writereg_mask(state, 0x88, 0x08, 0x08); 495 /* Disable corner detection for higher QAMs */
496 if (p->u.qam.modulation == QAM_128 ||
497 p->u.qam.modulation == QAM_256)
498 stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
499 else
500 stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
501
610 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00); 502 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
611 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01); 503 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
612 stv0297_writereg_mask(state, 0x43, 0x40, 0x40); 504 stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
@@ -732,7 +624,7 @@ static void stv0297_release(struct dvb_frontend *fe)
732static struct dvb_frontend_ops stv0297_ops; 624static struct dvb_frontend_ops stv0297_ops;
733 625
734struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, 626struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
735 struct i2c_adapter *i2c, int pwm) 627 struct i2c_adapter *i2c)
736{ 628{
737 struct stv0297_state *state = NULL; 629 struct stv0297_state *state = NULL;
738 630
@@ -746,7 +638,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
746 state->i2c = i2c; 638 state->i2c = i2c;
747 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); 639 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
748 state->base_freq = 0; 640 state->base_freq = 0;
749 state->pwm = pwm;
750 641
751 /* check if the demod is there */ 642 /* check if the demod is there */
752 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20) 643 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 3be535989302..9e53f019db71 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -29,6 +29,12 @@ struct stv0297_config
29 /* the demodulator's i2c address */ 29 /* the demodulator's i2c address */
30 u8 demod_address; 30 u8 demod_address;
31 31
32 /* inittab - array of pairs of values.
33 * First of each pair is the register, second is the value.
34 * List should be terminated with an 0xff, 0xff pair.
35 */
36 u8* inittab;
37
32 /* does the "inversion" need inverted? */ 38 /* does the "inversion" need inverted? */
33 u8 invert:1; 39 u8 invert:1;
34 40
@@ -38,7 +44,7 @@ struct stv0297_config
38}; 44};
39 45
40extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, 46extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
41 struct i2c_adapter* i2c, int pwm); 47 struct i2c_adapter* i2c);
42extern int stv0297_enable_plli2c(struct dvb_frontend* fe); 48extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
43 49
44#endif // STV0297_H 50#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index cfa3928bb487..2d62931f20b5 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -63,12 +63,8 @@ struct stv0299_state {
63 u32 tuner_frequency; 63 u32 tuner_frequency;
64 u32 symbol_rate; 64 u32 symbol_rate;
65 fe_code_rate_t fec_inner; 65 fe_code_rate_t fec_inner;
66 int errmode;
67}; 66};
68 67
69#define STATUS_BER 0
70#define STATUS_UCBLOCKS 1
71
72static int debug; 68static int debug;
73static int debug_legacy_dish_switch; 69static int debug_legacy_dish_switch;
74#define dprintk(args...) \ 70#define dprintk(args...) \
@@ -481,7 +477,7 @@ static int stv0299_init (struct dvb_frontend* fe)
481 477
482 if (state->config->pll_init) { 478 if (state->config->pll_init) {
483 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ 479 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
484 state->config->pll_init(fe); 480 state->config->pll_init(fe, state->i2c);
485 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ 481 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
486 } 482 }
487 483
@@ -520,7 +516,8 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
520{ 516{
521 struct stv0299_state* state = fe->demodulator_priv; 517 struct stv0299_state* state = fe->demodulator_priv;
522 518
523 if (state->errmode != STATUS_BER) return 0; 519 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10);
520 msleep(100);
524 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 521 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
525 522
526 return 0; 523 return 0;
@@ -559,8 +556,9 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
559{ 556{
560 struct stv0299_state* state = fe->demodulator_priv; 557 struct stv0299_state* state = fe->demodulator_priv;
561 558
562 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; 559 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30);
563 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 560 msleep(100);
561 *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
564 562
565 return 0; 563 return 0;
566} 564}
@@ -603,7 +601,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
603 } else { 601 } else {
604 /* A "normal" tune is requested */ 602 /* A "normal" tune is requested */
605 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ 603 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
606 state->config->pll_set(fe, p); 604 state->config->pll_set(fe, state->i2c, p);
607 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ 605 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
608 606
609 stv0299_writeregI(state, 0x32, 0x80); 607 stv0299_writeregI(state, 0x32, 0x80);
@@ -615,7 +613,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
615 } 613 }
616 } else { 614 } else {
617 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ 615 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
618 state->config->pll_set(fe, p); 616 state->config->pll_set(fe, state->i2c, p);
619 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ 617 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
620 618
621 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 619 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
@@ -709,7 +707,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
709 state->tuner_frequency = 0; 707 state->tuner_frequency = 0;
710 state->symbol_rate = 0; 708 state->symbol_rate = 0;
711 state->fec_inner = 0; 709 state->fec_inner = 0;
712 state->errmode = STATUS_BER;
713 710
714 /* check if the demod is there */ 711 /* check if the demod is there */
715 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 712 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 79457a80a11f..d0c4484861e1 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -92,8 +92,8 @@ struct stv0299_config
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); 92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
93 93
94 /* PLL maintenance */ 94 /* PLL maintenance */
95 int (*pll_init)(struct dvb_frontend* fe); 95 int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c);
96 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 96 int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params);
97}; 97};
98 98
99extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); 99extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index ab0c032472cc..74cea9f8d721 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -1046,8 +1046,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
1046 tmp = tda1004x_read_byte(state, TDA1004X_SNR); 1046 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
1047 if (tmp < 0) 1047 if (tmp < 0)
1048 return -EIO; 1048 return -EIO;
1049 if (tmp) 1049 tmp = 255 - tmp;
1050 tmp = 255 - tmp;
1051 1050
1052 *snr = ((tmp << 8) | tmp); 1051 *snr = ((tmp << 8) | tmp);
1053 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); 1052 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index 70fb44b391a7..c6d276618e86 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -194,19 +194,18 @@ static int ves1820_init(struct dvb_frontend* fe)
194{ 194{
195 struct ves1820_state* state = fe->demodulator_priv; 195 struct ves1820_state* state = fe->demodulator_priv;
196 int i; 196 int i;
197 int val;
198 197
199 ves1820_writereg(state, 0, 0); 198 ves1820_writereg(state, 0, 0);
200 199
201 for (i = 0; i < 53; i++) { 200 for (i = 0; i < sizeof(ves1820_inittab); i++)
202 val = ves1820_inittab[i]; 201 ves1820_writereg(state, i, ves1820_inittab[i]);
203 if ((i == 2) && (state->config->selagc)) val |= 0x08; 202 if (state->config->selagc)
204 ves1820_writereg(state, i, val); 203 ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
205 }
206 204
207 ves1820_writereg(state, 0x34, state->pwm); 205 ves1820_writereg(state, 0x34, state->pwm);
208 206
209 if (state->config->pll_init) state->config->pll_init(fe); 207 if (state->config->pll_init)
208 state->config->pll_init(fe);
210 209
211 return 0; 210 return 0;
212} 211}
@@ -234,7 +233,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p
234 ves1820_writereg(state, 0x09, reg0x09[real_qam]); 233 ves1820_writereg(state, 0x09, reg0x09[real_qam]);
235 234
236 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion); 235 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
237 236 ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
238 return 0; 237 return 0;
239} 238}
240 239
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index e4c6e87f6c5d..22b203f8ff27 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -168,7 +168,9 @@ static void init_av7110_av(struct av7110 *av7110)
168 if (ret < 0) 168 if (ret < 0)
169 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret); 169 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
170 if (rgb_on && 170 if (rgb_on &&
171 (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { 171 ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
172 (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
173 (av7110->dev->pci->subsystem_device == 0x0000)) {
172 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 174 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
173 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 175 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
174 } 176 }
@@ -177,9 +179,6 @@ static void init_av7110_av(struct av7110 *av7110)
177 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); 179 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
178 if (ret < 0) 180 if (ret < 0)
179 printk("dvb-ttpci:cannot set volume :%d\n",ret); 181 printk("dvb-ttpci:cannot set volume :%d\n",ret);
180 ret = av7110_setup_irc_config(av7110, 0);
181 if (ret < 0)
182 printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
183} 182}
184 183
185static void recover_arm(struct av7110 *av7110) 184static void recover_arm(struct av7110 *av7110)
@@ -265,60 +264,6 @@ static int arm_thread(void *data)
265} 264}
266 265
267 266
268/**
269 * Hack! we save the last av7110 ptr. This should be ok, since
270 * you rarely will use more then one IR control.
271 *
272 * If we want to support multiple controls we would have to do much more...
273 */
274int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
275{
276 int ret = 0;
277 static struct av7110 *last;
278
279 dprintk(4, "%p\n", av7110);
280
281 if (!av7110)
282 av7110 = last;
283 else
284 last = av7110;
285
286 if (av7110) {
287 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
288 av7110->ir_config = ir_config;
289 }
290 return ret;
291}
292
293static void (*irc_handler)(u32);
294
295void av7110_register_irc_handler(void (*func)(u32))
296{
297 dprintk(4, "registering %p\n", func);
298 irc_handler = func;
299}
300
301void av7110_unregister_irc_handler(void (*func)(u32))
302{
303 dprintk(4, "unregistering %p\n", func);
304 irc_handler = NULL;
305}
306
307static void run_handlers(unsigned long ircom)
308{
309 if (irc_handler != NULL)
310 (*irc_handler)((u32) ircom);
311}
312
313static DECLARE_TASKLET(irtask, run_handlers, 0);
314
315static void IR_handle(struct av7110 *av7110, u32 ircom)
316{
317 dprintk(4, "ircommand = %08x\n", ircom);
318 irtask.data = (unsigned long) ircom;
319 tasklet_schedule(&irtask);
320}
321
322/**************************************************************************** 267/****************************************************************************
323 * IRQ handling 268 * IRQ handling
324 ****************************************************************************/ 269 ****************************************************************************/
@@ -711,8 +656,9 @@ static void gpioirq(unsigned long data)
711 return; 656 return;
712 657
713 case DATA_IRCOMMAND: 658 case DATA_IRCOMMAND:
714 IR_handle(av7110, 659 if (av7110->ir_handler)
715 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); 660 av7110->ir_handler(av7110,
661 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
716 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); 662 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
717 break; 663 break;
718 664
@@ -1668,9 +1614,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
1668 return 0; 1614 return 0;
1669} 1615}
1670 1616
1671static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1617static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
1672{ 1618{
1673 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1674 int ret; 1619 int ret;
1675 u8 data[4]; 1620 u8 data[4];
1676 u32 div; 1621 u32 div;
@@ -1687,7 +1632,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1687 1632
1688 if (params->frequency > 1530000) data[3] = 0xc0; 1633 if (params->frequency > 1530000) data[3] = 0xc0;
1689 1634
1690 ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); 1635 ret = i2c_transfer(i2c, &msg, 1);
1691 if (ret != 1) 1636 if (ret != 1)
1692 return -EIO; 1637 return -EIO;
1693 return 0; 1638 return 0;
@@ -1751,9 +1696,8 @@ static u8 alps_bsbe1_inittab[] = {
1751 0xff, 0xff 1696 0xff, 0xff
1752}; 1697};
1753 1698
1754static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1699static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
1755{ 1700{
1756 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1757 int ret; 1701 int ret;
1758 u8 data[4]; 1702 u8 data[4];
1759 u32 div; 1703 u32 div;
@@ -1768,7 +1712,7 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
1768 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; 1712 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1769 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; 1713 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
1770 1714
1771 ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); 1715 ret = i2c_transfer(i2c, &msg, 1);
1772 return (ret != 1) ? -EIO : 0; 1716 return (ret != 1) ? -EIO : 0;
1773} 1717}
1774 1718
@@ -1936,6 +1880,98 @@ static struct sp8870_config alps_tdlb7_config = {
1936}; 1880};
1937 1881
1938 1882
1883static u8 nexusca_stv0297_inittab[] = {
1884 0x80, 0x01,
1885 0x80, 0x00,
1886 0x81, 0x01,
1887 0x81, 0x00,
1888 0x00, 0x09,
1889 0x01, 0x69,
1890 0x03, 0x00,
1891 0x04, 0x00,
1892 0x07, 0x00,
1893 0x08, 0x00,
1894 0x20, 0x00,
1895 0x21, 0x40,
1896 0x22, 0x00,
1897 0x23, 0x00,
1898 0x24, 0x40,
1899 0x25, 0x88,
1900 0x30, 0xff,
1901 0x31, 0x00,
1902 0x32, 0xff,
1903 0x33, 0x00,
1904 0x34, 0x50,
1905 0x35, 0x7f,
1906 0x36, 0x00,
1907 0x37, 0x20,
1908 0x38, 0x00,
1909 0x40, 0x1c,
1910 0x41, 0xff,
1911 0x42, 0x29,
1912 0x43, 0x00,
1913 0x44, 0xff,
1914 0x45, 0x00,
1915 0x46, 0x00,
1916 0x49, 0x04,
1917 0x4a, 0x00,
1918 0x4b, 0x7b,
1919 0x52, 0x30,
1920 0x55, 0xae,
1921 0x56, 0x47,
1922 0x57, 0xe1,
1923 0x58, 0x3a,
1924 0x5a, 0x1e,
1925 0x5b, 0x34,
1926 0x60, 0x00,
1927 0x63, 0x00,
1928 0x64, 0x00,
1929 0x65, 0x00,
1930 0x66, 0x00,
1931 0x67, 0x00,
1932 0x68, 0x00,
1933 0x69, 0x00,
1934 0x6a, 0x02,
1935 0x6b, 0x00,
1936 0x70, 0xff,
1937 0x71, 0x00,
1938 0x72, 0x00,
1939 0x73, 0x00,
1940 0x74, 0x0c,
1941 0x80, 0x00,
1942 0x81, 0x00,
1943 0x82, 0x00,
1944 0x83, 0x00,
1945 0x84, 0x04,
1946 0x85, 0x80,
1947 0x86, 0x24,
1948 0x87, 0x78,
1949 0x88, 0x10,
1950 0x89, 0x00,
1951 0x90, 0x01,
1952 0x91, 0x01,
1953 0xa0, 0x04,
1954 0xa1, 0x00,
1955 0xa2, 0x00,
1956 0xb0, 0x91,
1957 0xb1, 0x0b,
1958 0xc0, 0x53,
1959 0xc1, 0x70,
1960 0xc2, 0x12,
1961 0xd0, 0x00,
1962 0xd1, 0x00,
1963 0xd2, 0x00,
1964 0xd3, 0x00,
1965 0xd4, 0x00,
1966 0xd5, 0x00,
1967 0xde, 0x00,
1968 0xdf, 0x00,
1969 0x61, 0x49,
1970 0x62, 0x0b,
1971 0x53, 0x08,
1972 0x59, 0x08,
1973 0xff, 0xff,
1974};
1939 1975
1940static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1976static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1941{ 1977{
@@ -1984,6 +2020,7 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
1984static struct stv0297_config nexusca_stv0297_config = { 2020static struct stv0297_config nexusca_stv0297_config = {
1985 2021
1986 .demod_address = 0x1C, 2022 .demod_address = 0x1C,
2023 .inittab = nexusca_stv0297_inittab,
1987 .invert = 1, 2024 .invert = 1,
1988 .pll_set = nexusca_stv0297_pll_set, 2025 .pll_set = nexusca_stv0297_pll_set,
1989}; 2026};
@@ -2261,7 +2298,7 @@ static int frontend_init(struct av7110 *av7110)
2261 2298
2262 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X 2299 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2263 2300
2264 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b); 2301 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
2265 if (av7110->fe) { 2302 if (av7110->fe) {
2266 /* set TDA9819 into DVB mode */ 2303 /* set TDA9819 into DVB mode */
2267 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) 2304 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
@@ -2692,7 +2729,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
2692 goto err_av7110_exit_v4l_12; 2729 goto err_av7110_exit_v4l_12;
2693 2730
2694#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) 2731#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2695 av7110_ir_init(); 2732 av7110_ir_init(av7110);
2696#endif 2733#endif
2697 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num); 2734 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2698 av7110_num++; 2735 av7110_num++;
@@ -2734,6 +2771,9 @@ static int av7110_detach(struct saa7146_dev* saa)
2734 struct av7110 *av7110 = saa->ext_priv; 2771 struct av7110 *av7110 = saa->ext_priv;
2735 dprintk(4, "%p\n", av7110); 2772 dprintk(4, "%p\n", av7110);
2736 2773
2774#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2775 av7110_ir_exit(av7110);
2776#endif
2737 if (budgetpatch) { 2777 if (budgetpatch) {
2738 /* Disable RPS1 */ 2778 /* Disable RPS1 */
2739 saa7146_write(saa, MC1, MASK_29); 2779 saa7146_write(saa, MC1, MASK_29);
@@ -2830,7 +2870,7 @@ static struct saa7146_pci_extension_data x_var = { \
2830 .ext_priv = x_name, \ 2870 .ext_priv = x_name, \
2831 .ext = &av7110_extension } 2871 .ext = &av7110_extension }
2832 2872
2833MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X"); 2873MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
2834MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); 2874MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2835MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); 2875MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2836MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); 2876MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
@@ -2842,16 +2882,16 @@ MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2842MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); 2882MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
2843 2883
2844static struct pci_device_id pci_tbl[] = { 2884static struct pci_device_id pci_tbl[] = {
2845 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), 2885 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2846 MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000), 2886 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2847 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), 2887 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2848 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), 2888 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2849 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), 2889 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
2850 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), 2890 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2851 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), 2891 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2852 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), 2892 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2853 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), 2893 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2854 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), 2894 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
2855 2895
2856/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte 2896/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
2857/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 2897/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
@@ -2889,9 +2929,6 @@ static int __init av7110_init(void)
2889 2929
2890static void __exit av7110_exit(void) 2930static void __exit av7110_exit(void)
2891{ 2931{
2892#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2893 av7110_ir_exit();
2894#endif
2895 saa7146_unregister_extension(&av7110_extension); 2932 saa7146_unregister_extension(&av7110_extension);
2896} 2933}
2897 2934
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 508b7739c609..cce00ef293e9 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -228,7 +228,10 @@ struct av7110 {
228 struct dvb_video_events video_events; 228 struct dvb_video_events video_events;
229 video_size_t video_size; 229 video_size_t video_size;
230 230
231 u32 ir_config; 231 u32 ir_config;
232 u32 ir_command;
233 void (*ir_handler)(struct av7110 *av7110, u32 ircom);
234 struct tasklet_struct ir_tasklet;
232 235
233 /* firmware stuff */ 236 /* firmware stuff */
234 unsigned char *bin_fw; 237 unsigned char *bin_fw;
@@ -257,12 +260,10 @@ struct av7110 {
257extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 260extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
258 u16 subpid, u16 pcrpid); 261 u16 subpid, u16 pcrpid);
259 262
260extern void av7110_register_irc_handler(void (*func)(u32));
261extern void av7110_unregister_irc_handler(void (*func)(u32));
262extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); 263extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
263 264
264extern int av7110_ir_init (void); 265extern int av7110_ir_init(struct av7110 *av7110);
265extern void av7110_ir_exit (void); 266extern void av7110_ir_exit(struct av7110 *av7110);
266 267
267/* msp3400 i2c subaddresses */ 268/* msp3400 i2c subaddresses */
268#define MSP_WR_DEM 0x10 269#define MSP_WR_DEM 0x10
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 1220826696c5..7442f56a72ec 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -41,6 +41,8 @@
41#include "av7110.h" 41#include "av7110.h"
42#include "av7110_hw.h" 42#include "av7110_hw.h"
43 43
44#define _NOHANDSHAKE
45
44/**************************************************************************** 46/****************************************************************************
45 * DEBI functions 47 * DEBI functions
46 ****************************************************************************/ 48 ****************************************************************************/
@@ -364,7 +366,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
364 msleep(1); 366 msleep(1);
365 } 367 }
366 368
367 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2); 369 if (FW_VERSION(av7110->arm_app) <= 0x261f)
370 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
368 371
369#ifndef _NOHANDSHAKE 372#ifndef _NOHANDSHAKE
370 start = jiffies; 373 start = jiffies;
@@ -437,7 +440,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
437 440
438 wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2); 441 wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
439 442
440 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2); 443 if (FW_VERSION(av7110->arm_app) <= 0x261f)
444 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
441 445
442#ifdef COM_DEBUG 446#ifdef COM_DEBUG
443 start = jiffies; 447 start = jiffies;
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 665cdb8a3f71..357a3728ec68 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -7,16 +7,16 @@
7#include <asm/bitops.h> 7#include <asm/bitops.h>
8 8
9#include "av7110.h" 9#include "av7110.h"
10#include "av7110_hw.h"
10 11
11#define UP_TIMEOUT (HZ/4) 12#define UP_TIMEOUT (HZ*7/25)
12 13
13/* enable ir debugging by or'ing debug with 16 */ 14/* enable ir debugging by or'ing debug with 16 */
14 15
15static int ir_initialized; 16static int av_cnt;
17static struct av7110 *av_list[4];
16static struct input_dev input_dev; 18static struct input_dev input_dev;
17 19
18static u32 ir_config;
19
20static u16 key_map [256] = { 20static u16 key_map [256] = {
21 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 21 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
22 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, 22 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
@@ -53,8 +53,11 @@ static void av7110_emit_keyup(unsigned long data)
53static struct timer_list keyup_timer = { .function = av7110_emit_keyup }; 53static struct timer_list keyup_timer = { .function = av7110_emit_keyup };
54 54
55 55
56static void av7110_emit_key(u32 ircom) 56static void av7110_emit_key(unsigned long parm)
57{ 57{
58 struct av7110 *av7110 = (struct av7110 *) parm;
59 u32 ir_config = av7110->ir_config;
60 u32 ircom = av7110->ir_command;
58 u8 data; 61 u8 data;
59 u8 addr; 62 u8 addr;
60 static u16 old_toggle = 0; 63 static u16 old_toggle = 0;
@@ -62,19 +65,33 @@ static void av7110_emit_key(u32 ircom)
62 u16 keycode; 65 u16 keycode;
63 66
64 /* extract device address and data */ 67 /* extract device address and data */
65 if (ir_config & 0x0001) { 68 switch (ir_config & 0x0003) {
66 /* TODO RCMM: ? bits device address, 8 bits data */ 69 case 0: /* RC5: 5 bits device address, 6 bits data */
70 data = ircom & 0x3f;
71 addr = (ircom >> 6) & 0x1f;
72 break;
73
74 case 1: /* RCMM: 8(?) bits device address, 8(?) bits data */
67 data = ircom & 0xff; 75 data = ircom & 0xff;
68 addr = (ircom >> 8) & 0xff; 76 addr = (ircom >> 8) & 0xff;
69 } else { 77 break;
70 /* RC5: 5 bits device address, 6 bits data */ 78
79 case 2: /* extended RC5: 5 bits device address, 7 bits data */
71 data = ircom & 0x3f; 80 data = ircom & 0x3f;
72 addr = (ircom >> 6) & 0x1f; 81 addr = (ircom >> 6) & 0x1f;
82 /* invert 7th data bit for backward compatibility with RC5 keymaps */
83 if (!(ircom & 0x1000))
84 data |= 0x40;
85 break;
86
87 default:
88 printk("invalid ir_config %x\n", ir_config);
89 return;
73 } 90 }
74 91
75 keycode = key_map[data]; 92 keycode = key_map[data];
76 93
77 dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n", 94 dprintk(16, "code %08x -> addr %i data 0x%02x -> keycode %i\n",
78 ircom, addr, data, keycode); 95 ircom, addr, data, keycode);
79 96
80 /* check device address (if selected) */ 97 /* check device address (if selected) */
@@ -87,10 +104,10 @@ static void av7110_emit_key(u32 ircom)
87 return; 104 return;
88 } 105 }
89 106
90 if (ir_config & 0x0001) 107 if ((ir_config & 0x0003) == 1)
91 new_toggle = 0; /* RCMM */ 108 new_toggle = 0; /* RCMM */
92 else 109 else
93 new_toggle = (ircom & 0x800); /* RC5 */ 110 new_toggle = (ircom & 0x800); /* RC5, extended RC5 */
94 111
95 if (timer_pending(&keyup_timer)) { 112 if (timer_pending(&keyup_timer)) {
96 del_timer(&keyup_timer); 113 del_timer(&keyup_timer);
@@ -137,6 +154,8 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
137{ 154{
138 char *page; 155 char *page;
139 int size = 4 + 256 * sizeof(u16); 156 int size = 4 + 256 * sizeof(u16);
157 u32 ir_config;
158 int i;
140 159
141 if (count < size) 160 if (count < size)
142 return -EINVAL; 161 return -EINVAL;
@@ -153,60 +172,95 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
153 memcpy(&ir_config, page, 4); 172 memcpy(&ir_config, page, 4);
154 memcpy(&key_map, page + 4, 256 * sizeof(u16)); 173 memcpy(&key_map, page + 4, 256 * sizeof(u16));
155 vfree(page); 174 vfree(page);
156 av7110_setup_irc_config(NULL, ir_config); 175 if (FW_VERSION(av_list[0]->arm_app) >= 0x2620 && !(ir_config & 0x0001))
176 ir_config |= 0x0002; /* enable extended RC5 */
177 for (i = 0; i < av_cnt; i++)
178 av7110_setup_irc_config(av_list[i], ir_config);
157 input_register_keys(); 179 input_register_keys();
158 return count; 180 return count;
159} 181}
160 182
161 183
162int __init av7110_ir_init(void) 184int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
163{ 185{
164 static struct proc_dir_entry *e; 186 int ret = 0;
165 187
166 if (ir_initialized) 188 dprintk(4, "%p\n", av7110);
167 return 0; 189 if (av7110) {
190 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
191 av7110->ir_config = ir_config;
192 }
193 return ret;
194}
168 195
169 init_timer(&keyup_timer);
170 keyup_timer.data = 0;
171 196
172 input_dev.name = "DVB on-card IR receiver"; 197static void ir_handler(struct av7110 *av7110, u32 ircom)
198{
199 dprintk(4, "ircommand = %08x\n", ircom);
200 av7110->ir_command = ircom;
201 tasklet_schedule(&av7110->ir_tasklet);
202}
173 203
174 /**
175 * enable keys
176 */
177 set_bit(EV_KEY, input_dev.evbit);
178 set_bit(EV_REP, input_dev.evbit);
179 204
180 input_register_keys(); 205int __init av7110_ir_init(struct av7110 *av7110)
206{
207 static struct proc_dir_entry *e;
181 208
182 input_register_device(&input_dev); 209 if (av_cnt >= sizeof av_list/sizeof av_list[0])
183 input_dev.timer.function = input_repeat_key; 210 return -ENOSPC;
184 211
185 av7110_setup_irc_config(NULL, 0x0001); 212 av7110_setup_irc_config(av7110, 0x0001);
186 av7110_register_irc_handler(av7110_emit_key); 213 av_list[av_cnt++] = av7110;
187 214
188 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); 215 if (av_cnt == 1) {
189 if (e) { 216 init_timer(&keyup_timer);
190 e->write_proc = av7110_ir_write_proc; 217 keyup_timer.data = 0;
191 e->size = 4 + 256 * sizeof(u16); 218
219 input_dev.name = "DVB on-card IR receiver";
220 set_bit(EV_KEY, input_dev.evbit);
221 set_bit(EV_REP, input_dev.evbit);
222 input_register_keys();
223 input_register_device(&input_dev);
224 input_dev.timer.function = input_repeat_key;
225
226 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
227 if (e) {
228 e->write_proc = av7110_ir_write_proc;
229 e->size = 4 + 256 * sizeof(u16);
230 }
192 } 231 }
193 232
194 ir_initialized = 1; 233 tasklet_init(&av7110->ir_tasklet, av7110_emit_key, (unsigned long) av7110);
234 av7110->ir_handler = ir_handler;
235
195 return 0; 236 return 0;
196} 237}
197 238
198 239
199void __exit av7110_ir_exit(void) 240void __exit av7110_ir_exit(struct av7110 *av7110)
200{ 241{
201 if (ir_initialized == 0) 242 int i;
243
244 if (av_cnt == 0)
202 return; 245 return;
203 del_timer_sync(&keyup_timer); 246
204 remove_proc_entry("av7110_ir", NULL); 247 av7110->ir_handler = NULL;
205 av7110_unregister_irc_handler(av7110_emit_key); 248 tasklet_kill(&av7110->ir_tasklet);
206 input_unregister_device(&input_dev); 249 for (i = 0; i < av_cnt; i++)
207 ir_initialized = 0; 250 if (av_list[i] == av7110) {
251 av_list[i] = av_list[av_cnt-1];
252 av_list[av_cnt-1] = NULL;
253 break;
254 }
255
256 if (av_cnt == 1) {
257 del_timer_sync(&keyup_timer);
258 remove_proc_entry("av7110_ir", NULL);
259 input_unregister_device(&input_dev);
260 }
261
262 av_cnt--;
208} 263}
209 264
210//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); 265//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
211//MODULE_LICENSE("GPL"); 266//MODULE_LICENSE("GPL");
212
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index e65fc36e2ce8..6af74f78b3e5 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -70,7 +70,7 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
70 return 0; 70 return 0;
71} 71}
72 72
73static struct v4l2_input inputs[2] = { 73static struct v4l2_input inputs[4] = {
74 { 74 {
75 .index = 0, 75 .index = 0,
76 .name = "DVB", 76 .name = "DVB",
@@ -87,6 +87,22 @@ static struct v4l2_input inputs[2] = {
87 .tuner = 0, 87 .tuner = 0,
88 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 88 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
89 .status = 0, 89 .status = 0,
90 }, {
91 .index = 2,
92 .name = "Video",
93 .type = V4L2_INPUT_TYPE_CAMERA,
94 .audioset = 0,
95 .tuner = 0,
96 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
97 .status = 0,
98 }, {
99 .index = 3,
100 .name = "Y/C",
101 .type = V4L2_INPUT_TYPE_CAMERA,
102 .audioset = 0,
103 .tuner = 0,
104 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
105 .status = 0,
90 } 106 }
91}; 107};
92 108
@@ -212,24 +228,44 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
212 } 228 }
213 229
214 if (0 != av7110->current_input) { 230 if (0 != av7110->current_input) {
231 dprintk(1, "switching to analog TV:\n");
215 adswitch = 1; 232 adswitch = 1;
216 source = SAA7146_HPS_SOURCE_PORT_B; 233 source = SAA7146_HPS_SOURCE_PORT_B;
217 sync = SAA7146_HPS_SYNC_PORT_B; 234 sync = SAA7146_HPS_SYNC_PORT_B;
218 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2); 235 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
219 dprintk(1, "switching to analog TV\n");
220 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
221 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
222 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
223 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
224 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
225 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
226 236
227 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { 237 switch (av7110->current_input) {
228 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) 238 case 1:
229 dprintk(1, "setting band in demodulator failed.\n"); 239 dprintk(1, "switching SAA7113 to Analog Tuner Input.\n");
230 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { 240 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
231 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD) 241 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
232 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF) 242 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
243 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
244 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
245 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
246
247 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
248 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
249 dprintk(1, "setting band in demodulator failed.\n");
250 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
251 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
252 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
253 }
254 if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
255 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
256 break;
257 case 2:
258 dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n");
259 if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
260 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
261 break;
262 case 3:
263 dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n");
264 if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
265 dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
266 break;
267 default:
268 dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n");
233 } 269 }
234 } else { 270 } else {
235 adswitch = 0; 271 adswitch = 0;
@@ -300,7 +336,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
300 // FIXME: standard / stereo detection is still broken 336 // FIXME: standard / stereo detection is still broken
301 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); 337 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
302 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); 338 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
303
304 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); 339 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
305 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); 340 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
306 stereo = (s8)(stereo_det >> 8); 341 stereo = (s8)(stereo_det >> 8);
@@ -310,7 +345,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
310 t->audmode = V4L2_TUNER_MODE_STEREO; 345 t->audmode = V4L2_TUNER_MODE_STEREO;
311 } 346 }
312 else if (stereo < -0x10) { 347 else if (stereo < -0x10) {
313 /* bilingual*/ 348 /* bilingual */
314 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 349 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
315 t->audmode = V4L2_TUNER_MODE_LANG1; 350 t->audmode = V4L2_TUNER_MODE_LANG1;
316 } 351 }
@@ -344,7 +379,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
344 fm_matrix = 0x3000; // mono 379 fm_matrix = 0x3000; // mono
345 src = 0x0010; 380 src = 0x0010;
346 break; 381 break;
347 default: /* case V4L2_TUNER_MODE_MONO: {*/ 382 default: /* case V4L2_TUNER_MODE_MONO: */
348 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); 383 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
349 fm_matrix = 0x3000; // mono 384 fm_matrix = 0x3000; // mono
350 src = 0x0030; 385 src = 0x0030;
@@ -406,7 +441,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
406 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); 441 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
407 442
408 if (av7110->analog_tuner_flags) { 443 if (av7110->analog_tuner_flags) {
409 if (i->index < 0 || i->index >= 2) 444 if (i->index < 0 || i->index >= 4)
410 return -EINVAL; 445 return -EINVAL;
411 } else { 446 } else {
412 if (i->index != 0) 447 if (i->index != 0)
@@ -433,10 +468,9 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
433 if (!av7110->analog_tuner_flags) 468 if (!av7110->analog_tuner_flags)
434 return 0; 469 return 0;
435 470
436 if (input < 0 || input >= 2) 471 if (input < 0 || input >= 4)
437 return -EINVAL; 472 return -EINVAL;
438 473
439 /* FIXME: switch inputs here */
440 av7110->current_input = input; 474 av7110->current_input = input;
441 return av7110_dvb_c_switch(fh); 475 return av7110_dvb_c_switch(fh);
442 } 476 }
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 9746d2bb916f..7692cd23f839 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
192{ 192{
193 struct budget_av *budget_av = (struct budget_av *) ca->data; 193 struct budget_av *budget_av = (struct budget_av *) ca->data;
194 struct saa7146_dev *saa = budget_av->budget.dev; 194 struct saa7146_dev *saa = budget_av->budget.dev;
195 int timeout = 50; // 5 seconds (4.4.6 Ready) 195 int timeout = 500; // 5 seconds (4.4.6 Ready)
196 196
197 if (slot != 0) 197 if (slot != 0)
198 return -EINVAL; 198 return -EINVAL;
@@ -217,7 +217,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
217 { 217 {
218 printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); 218 printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
219 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 219 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
220 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
221 return -ETIMEDOUT; 220 return -ETIMEDOUT;
222 } 221 }
223 222
@@ -276,7 +275,6 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
276 { 275 {
277 printk(KERN_INFO "budget-av: cam ejected\n"); 276 printk(KERN_INFO "budget-av: cam ejected\n");
278 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 277 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
279 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
280 budget_av->slot_status = 0; 278 budget_av->slot_status = 0;
281 } 279 }
282 } 280 }
@@ -453,9 +451,9 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra
453} 451}
454 452
455static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, 453static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
454 struct i2c_adapter *i2c,
456 struct dvb_frontend_parameters *params) 455 struct dvb_frontend_parameters *params)
457{ 456{
458 struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
459 u32 div; 457 u32 div;
460 u8 buf[4]; 458 u8 buf[4];
461 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; 459 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -481,7 +479,7 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
481 else if (params->frequency < 2150000) 479 else if (params->frequency < 2150000)
482 buf[3] |= 0xC0; 480 buf[3] |= 0xC0;
483 481
484 if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1) 482 if (i2c_transfer(i2c, &msg, 1) != 1)
485 return -EIO; 483 return -EIO;
486 return 0; 484 return 0;
487} 485}
@@ -745,6 +743,7 @@ static void frontend_init(struct budget_av *budget_av)
745 case SUBID_DVBC_KNC1_PLUS: 743 case SUBID_DVBC_KNC1_PLUS:
746 case SUBID_DVBT_KNC1_PLUS: 744 case SUBID_DVBT_KNC1_PLUS:
747 // Enable / PowerON Frontend 745 // Enable / PowerON Frontend
746 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
748 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); 747 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
749 break; 748 break;
750 } 749 }
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index a1267054bc01..2980db3ef22f 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -40,6 +40,7 @@
40 40
41#include "dvb_ca_en50221.h" 41#include "dvb_ca_en50221.h"
42#include "stv0299.h" 42#include "stv0299.h"
43#include "stv0297.h"
43#include "tda1004x.h" 44#include "tda1004x.h"
44 45
45#define DEBIADDR_IR 0x1234 46#define DEBIADDR_IR 0x1234
@@ -548,9 +549,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra
548 return 0; 549 return 0;
549} 550}
550 551
551static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 552static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
552{ 553{
553 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
554 u8 buf[4]; 554 u8 buf[4];
555 u32 div; 555 u32 div;
556 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; 556 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -567,7 +567,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_param
567 if (params->frequency > 1530000) 567 if (params->frequency > 1530000)
568 buf[3] = 0xc0; 568 buf[3] = 0xc0;
569 569
570 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) 570 if (i2c_transfer(i2c, &msg, 1) != 1)
571 return -EIO; 571 return -EIO;
572 return 0; 572 return 0;
573} 573}
@@ -669,9 +669,9 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
669} 669}
670 670
671static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, 671static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
672 struct i2c_adapter *i2c,
672 struct dvb_frontend_parameters *params) 673 struct dvb_frontend_parameters *params)
673{ 674{
674 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
675 u32 div; 675 u32 div;
676 u8 buf[4]; 676 u8 buf[4];
677 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; 677 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -697,7 +697,7 @@ static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
697 else if (params->frequency < 2150000) 697 else if (params->frequency < 2150000)
698 buf[3] |= 0xC0; 698 buf[3] |= 0xC0;
699 699
700 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) 700 if (i2c_transfer(i2c, &msg, 1) != 1)
701 return -EIO; 701 return -EIO;
702 return 0; 702 return 0;
703} 703}
@@ -848,6 +848,180 @@ static struct tda1004x_config philips_tdm1316l_config = {
848 .request_firmware = philips_tdm1316l_request_firmware, 848 .request_firmware = philips_tdm1316l_request_firmware,
849}; 849};
850 850
851static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
852{
853 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
854 u8 tuner_buf[5];
855 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
856 .flags = 0,
857 .buf = tuner_buf,
858 .len = sizeof(tuner_buf) };
859 int tuner_frequency = 0;
860 u8 band, cp, filter;
861
862 // determine charge pump
863 tuner_frequency = params->frequency + 36125000;
864 if (tuner_frequency < 87000000)
865 return -EINVAL;
866 else if (tuner_frequency < 130000000) {
867 cp = 3;
868 band = 1;
869 } else if (tuner_frequency < 160000000) {
870 cp = 5;
871 band = 1;
872 } else if (tuner_frequency < 200000000) {
873 cp = 6;
874 band = 1;
875 } else if (tuner_frequency < 290000000) {
876 cp = 3;
877 band = 2;
878 } else if (tuner_frequency < 420000000) {
879 cp = 5;
880 band = 2;
881 } else if (tuner_frequency < 480000000) {
882 cp = 6;
883 band = 2;
884 } else if (tuner_frequency < 620000000) {
885 cp = 3;
886 band = 4;
887 } else if (tuner_frequency < 830000000) {
888 cp = 5;
889 band = 4;
890 } else if (tuner_frequency < 895000000) {
891 cp = 7;
892 band = 4;
893 } else
894 return -EINVAL;
895
896 // assume PLL filter should always be 8MHz for the moment.
897 filter = 1;
898
899 // calculate divisor
900 tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
901
902 // setup tuner buffer
903 tuner_buf[0] = tuner_frequency >> 8;
904 tuner_buf[1] = tuner_frequency & 0xff;
905 tuner_buf[2] = 0xc8;
906 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
907 tuner_buf[4] = 0x80;
908
909 stv0297_enable_plli2c(fe);
910 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
911 return -EIO;
912
913 msleep(50);
914
915 stv0297_enable_plli2c(fe);
916 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
917 return -EIO;
918
919 msleep(1);
920
921 return 0;
922}
923
924static u8 dvbc_philips_tdm1316l_inittab[] = {
925 0x80, 0x01,
926 0x80, 0x00,
927 0x81, 0x01,
928 0x81, 0x00,
929 0x00, 0x09,
930 0x01, 0x69,
931 0x03, 0x00,
932 0x04, 0x00,
933 0x07, 0x00,
934 0x08, 0x00,
935 0x20, 0x00,
936 0x21, 0x40,
937 0x22, 0x00,
938 0x23, 0x00,
939 0x24, 0x40,
940 0x25, 0x88,
941 0x30, 0xff,
942 0x31, 0x00,
943 0x32, 0xff,
944 0x33, 0x00,
945 0x34, 0x50,
946 0x35, 0x7f,
947 0x36, 0x00,
948 0x37, 0x20,
949 0x38, 0x00,
950 0x40, 0x1c,
951 0x41, 0xff,
952 0x42, 0x29,
953 0x43, 0x20,
954 0x44, 0xff,
955 0x45, 0x00,
956 0x46, 0x00,
957 0x49, 0x04,
958 0x4a, 0x00,
959 0x4b, 0x7b,
960 0x52, 0x30,
961 0x55, 0xae,
962 0x56, 0x47,
963 0x57, 0xe1,
964 0x58, 0x3a,
965 0x5a, 0x1e,
966 0x5b, 0x34,
967 0x60, 0x00,
968 0x63, 0x00,
969 0x64, 0x00,
970 0x65, 0x00,
971 0x66, 0x00,
972 0x67, 0x00,
973 0x68, 0x00,
974 0x69, 0x00,
975 0x6a, 0x02,
976 0x6b, 0x00,
977 0x70, 0xff,
978 0x71, 0x00,
979 0x72, 0x00,
980 0x73, 0x00,
981 0x74, 0x0c,
982 0x80, 0x00,
983 0x81, 0x00,
984 0x82, 0x00,
985 0x83, 0x00,
986 0x84, 0x04,
987 0x85, 0x80,
988 0x86, 0x24,
989 0x87, 0x78,
990 0x88, 0x10,
991 0x89, 0x00,
992 0x90, 0x01,
993 0x91, 0x01,
994 0xa0, 0x04,
995 0xa1, 0x00,
996 0xa2, 0x00,
997 0xb0, 0x91,
998 0xb1, 0x0b,
999 0xc0, 0x53,
1000 0xc1, 0x70,
1001 0xc2, 0x12,
1002 0xd0, 0x00,
1003 0xd1, 0x00,
1004 0xd2, 0x00,
1005 0xd3, 0x00,
1006 0xd4, 0x00,
1007 0xd5, 0x00,
1008 0xde, 0x00,
1009 0xdf, 0x00,
1010 0x61, 0x38,
1011 0x62, 0x0a,
1012 0x53, 0x13,
1013 0x59, 0x08,
1014 0xff, 0xff,
1015};
1016
1017static struct stv0297_config dvbc_philips_tdm1316l_config = {
1018 .demod_address = 0x1c,
1019 .inittab = dvbc_philips_tdm1316l_inittab,
1020 .invert = 0,
1021 .pll_set = dvbc_philips_tdm1316l_pll_set,
1022};
1023
1024
851 1025
852 1026
853static void frontend_init(struct budget_ci *budget_ci) 1027static void frontend_init(struct budget_ci *budget_ci)
@@ -869,6 +1043,15 @@ static void frontend_init(struct budget_ci *budget_ci)
869 } 1043 }
870 break; 1044 break;
871 1045
1046 case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1047 budget_ci->tuner_pll_address = 0x61;
1048 budget_ci->budget.dvb_frontend =
1049 stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1050 if (budget_ci->budget.dvb_frontend) {
1051 break;
1052 }
1053 break;
1054
872 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) 1055 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
873 budget_ci->tuner_pll_address = 0x63; 1056 budget_ci->tuner_pll_address = 0x63;
874 budget_ci->budget.dvb_frontend = 1057 budget_ci->budget.dvb_frontend =
@@ -878,7 +1061,7 @@ static void frontend_init(struct budget_ci *budget_ci)
878 } 1061 }
879 break; 1062 break;
880 1063
881 case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) 1064 case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
882 budget_ci->tuner_pll_address = 0x60; 1065 budget_ci->tuner_pll_address = 0x60;
883 budget_ci->budget.dvb_frontend = 1066 budget_ci->budget.dvb_frontend =
884 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); 1067 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
@@ -966,10 +1149,12 @@ static struct saa7146_extension budget_extension;
966MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); 1149MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
967MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 1150MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
968MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); 1151MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1152MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
969 1153
970static struct pci_device_id pci_tbl[] = { 1154static struct pci_device_id pci_tbl[] = {
971 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 1155 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
972 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), 1156 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1157 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
973 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), 1158 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
974 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), 1159 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
975 { 1160 {
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 8142e26b47f5..b1f21ef0e3b3 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -353,9 +353,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
353 return 0; 353 return 0;
354} 354}
355 355
356static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 356static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
357{ 357{
358 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
359 u8 data[4]; 358 u8 data[4];
360 u32 div; 359 u32 div;
361 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 360 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -370,7 +369,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
370 369
371 if (params->frequency > 1530000) data[3] = 0xc0; 370 if (params->frequency > 1530000) data[3] = 0xc0;
372 371
373 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 372 if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
374 return 0; 373 return 0;
375} 374}
376 375
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 9961917e8a7f..43d6c8268642 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -332,9 +332,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
332 return 0; 332 return 0;
333} 333}
334 334
335static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 335static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
336{ 336{
337 struct budget* budget = (struct budget*) fe->dvb->priv;
338 u8 data[4]; 337 u8 data[4];
339 u32 div; 338 u32 div;
340 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 339 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -349,7 +348,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
349 348
350 if (params->frequency > 1530000) data[3] = 0xc0; 349 if (params->frequency > 1530000) data[3] = 0xc0;
351 350
352 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 351 if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
353 return 0; 352 return 0;
354} 353}
355 354
@@ -481,6 +480,7 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
481 480
482static struct s5h1420_config s5h1420_config = { 481static struct s5h1420_config s5h1420_config = {
483 .demod_address = 0x53, 482 .demod_address = 0x53,
483 .invert = 1,
484 .pll_set = s5h1420_pll_set, 484 .pll_set = s5h1420_pll_set,
485}; 485};
486 486
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 7daf7b1598a0..d200ab0ad9e7 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/time.h> 19#include <linux/time.h>
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/jiffies.h>
21#include <asm/semaphore.h> 22#include <asm/semaphore.h>
22 23
23#include "dvb_frontend.h" 24#include "dvb_frontend.h"
@@ -570,7 +571,8 @@ static void ttusb_handle_sec_data(struct ttusb_channel *channel,
570 const u8 * data, int len); 571 const u8 * data, int len);
571#endif 572#endif
572 573
573static int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid; 574static int numpkt = 0, numts, numstuff, numsec, numinvalid;
575static unsigned long lastj;
574 576
575static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, 577static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
576 int len) 578 int len)
@@ -779,7 +781,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
779 u8 *data; 781 u8 *data;
780 int len; 782 int len;
781 numpkt++; 783 numpkt++;
782 if ((jiffies - lastj) >= HZ) { 784 if (time_after_eq(jiffies, lastj + HZ)) {
783#if DEBUG > 2 785#if DEBUG > 2
784 printk 786 printk
785 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", 787 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
@@ -1299,7 +1301,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32
1299 return 0; 1301 return 0;
1300} 1302}
1301 1303
1302static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) 1304static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
1303{ 1305{
1304 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; 1306 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1305 u8 buf[4]; 1307 u8 buf[4];
@@ -1322,7 +1324,7 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
1322 if (ttusb->revision == TTUSB_REV_2_2) 1324 if (ttusb->revision == TTUSB_REV_2_2)
1323 buf[3] |= 0x20; 1325 buf[3] |= 0x20;
1324 1326
1325 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) 1327 if (i2c_transfer(i2c, &msg, 1) != 1)
1326 return -EIO; 1328 return -EIO;
1327 1329
1328 return 0; 1330 return 0;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 45c9a9a08e4d..3d08fc83a754 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -28,7 +28,6 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/usb.h> 30#include <linux/usb.h>
31#include <linux/version.h>
32#include <linux/interrupt.h> 31#include <linux/interrupt.h>
33#include <linux/firmware.h> 32#include <linux/firmware.h>
34#include <linux/crc32.h> 33#include <linux/crc32.h>
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 16c85c081e6e..93570355819a 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -22,12 +22,21 @@ config VIDEO_BT848
22 the Miro, Hauppauge and STB boards. Please read the material in 22 the Miro, Hauppauge and STB boards. Please read the material in
23 <file:Documentation/video4linux/bttv/> for more information. 23 <file:Documentation/video4linux/bttv/> for more information.
24 24
25 If you say Y or M here, you need to say Y or M to "I2C support" and
26 "I2C bit-banging interfaces" in the device drivers section.
27
28 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
29 module will be called bttv. 26 module will be called bttv.
30 27
28config VIDEO_SAA6588
29 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
30 depends on VIDEO_DEV && I2C && VIDEO_BT848
31
32 help
33 Support for Radio Data System (RDS) decoder. This allows seeing
34 radio station identification transmitted using this standard.
35 Currentlly, it works only with bt8x8 chips.
36
37 To compile this driver as a module, choose M here: the
38 module will be called saa6588.
39
31config VIDEO_PMS 40config VIDEO_PMS
32 tristate "Mediavision Pro Movie Studio Video For Linux" 41 tristate "Mediavision Pro Movie Studio Video For Linux"
33 depends on VIDEO_DEV && ISA 42 depends on VIDEO_DEV && ISA
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3e6f5347da21..046b82de9285 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,6 +5,7 @@
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
8zr36067-objs := zoran_procfs.o zoran_device.o \ 9zr36067-objs := zoran_procfs.o zoran_device.o \
9 zoran_driver.o zoran_card.o 10 zoran_driver.o zoran_card.o
10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
16 17
17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA6588) += rds.o
18obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 20obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
19obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 21obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
20obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o 22obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
index 7f2d515d2873..a48de3c0e3f0 100644
--- a/drivers/media/video/btcx-risc.c
+++ b/drivers/media/video/btcx-risc.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: btcx-risc.c,v 1.6 2005/02/21 13:57:59 kraxel Exp $
3 2
4 btcx-risc.c 3 btcx-risc.c
5 4
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
index 41f60395a520..503e6c6d7b69 100644
--- a/drivers/media/video/btcx-risc.h
+++ b/drivers/media/video/btcx-risc.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 */ 2 */
4struct btcx_riscmem { 3struct btcx_riscmem {
5 unsigned int size; 4 unsigned int size;
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index a97b9b958ed6..190977a1e549 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-cards.c,v 1.54 2005/07/19 18:26:46 mkrufky Exp $
3 2
4 bttv-cards.c 3 bttv-cards.c
5 4
@@ -169,10 +168,10 @@ static struct CARD {
169 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 168 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
170 169
171 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 170 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
172 // some cards ship with byteswapped IDs ... 171 /* some cards ship with byteswapped IDs ... */
173 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 172 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
174 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 173 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
175 // this seems to happen as well ... 174 /* this seems to happen as well ... */
176 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 175 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
177 176
178 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 177 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
@@ -200,12 +199,12 @@ static struct CARD {
200 199
201 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, 200 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" },
202 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, 201 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" },
203 // clashes with FlyVideo 202 /* clashes with FlyVideo
204 //{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, 203 *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */
205 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, 204 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" },
206 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // LR102 205 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
207 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, // ?? 206 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */
208 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // ?? 207 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
209 208
210 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 209 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
211 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 210 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
@@ -287,10 +286,12 @@ static struct CARD {
287 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, 286 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
288 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, 287 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
289 288
290 // likely broken, vendor id doesn't match the other magic views ... 289 { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" },
291 //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
292 290
293 // DVB cards (using pci function .1 for mpeg data xfer) 291 /* likely broken, vendor id doesn't match the other magic views ...
292 * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
293
294 /* DVB cards (using pci function .1 for mpeg data xfer) */
294 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 295 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
295 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 296 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
296 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, 297 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
@@ -298,7 +299,8 @@ static struct CARD {
298 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, 299 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" },
299 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, 300 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
300 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 301 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
301 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" }, 302 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
303 { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
302 304
303 { 0, -1, NULL } 305 { 0, -1, NULL }
304}; 306};
@@ -316,6 +318,7 @@ struct tvcard bttv_tvcards[] = {
316 .svhs = 2, 318 .svhs = 2,
317 .muxsel = { 2, 3, 1, 0}, 319 .muxsel = { 2, 3, 1, 0},
318 .tuner_type = -1, 320 .tuner_type = -1,
321 .tuner_addr = ADDR_UNSET,
319},{ 322},{
320 .name = "MIRO PCTV", 323 .name = "MIRO PCTV",
321 .video_inputs = 4, 324 .video_inputs = 4,
@@ -327,6 +330,7 @@ struct tvcard bttv_tvcards[] = {
327 .audiomux = { 2, 0, 0, 0, 10}, 330 .audiomux = { 2, 0, 0, 0, 10},
328 .needs_tvaudio = 1, 331 .needs_tvaudio = 1,
329 .tuner_type = -1, 332 .tuner_type = -1,
333 .tuner_addr = ADDR_UNSET,
330},{ 334},{
331 .name = "Hauppauge (bt848)", 335 .name = "Hauppauge (bt848)",
332 .video_inputs = 4, 336 .video_inputs = 4,
@@ -338,6 +342,7 @@ struct tvcard bttv_tvcards[] = {
338 .audiomux = { 0, 1, 2, 3, 4}, 342 .audiomux = { 0, 1, 2, 3, 4},
339 .needs_tvaudio = 1, 343 .needs_tvaudio = 1,
340 .tuner_type = -1, 344 .tuner_type = -1,
345 .tuner_addr = ADDR_UNSET,
341},{ 346},{
342 .name = "STB, Gateway P/N 6000699 (bt848)", 347 .name = "STB, Gateway P/N 6000699 (bt848)",
343 .video_inputs = 3, 348 .video_inputs = 3,
@@ -350,6 +355,7 @@ struct tvcard bttv_tvcards[] = {
350 .no_msp34xx = 1, 355 .no_msp34xx = 1,
351 .needs_tvaudio = 1, 356 .needs_tvaudio = 1,
352 .tuner_type = TUNER_PHILIPS_NTSC, 357 .tuner_type = TUNER_PHILIPS_NTSC,
358 .tuner_addr = ADDR_UNSET,
353 .pll = PLL_28, 359 .pll = PLL_28,
354 .has_radio = 1, 360 .has_radio = 1,
355},{ 361},{
@@ -365,6 +371,7 @@ struct tvcard bttv_tvcards[] = {
365 .audiomux = { 0 }, 371 .audiomux = { 0 },
366 .needs_tvaudio = 0, 372 .needs_tvaudio = 0,
367 .tuner_type = 4, 373 .tuner_type = 4,
374 .tuner_addr = ADDR_UNSET,
368},{ 375},{
369 .name = "Diamond DTV2000", 376 .name = "Diamond DTV2000",
370 .video_inputs = 4, 377 .video_inputs = 4,
@@ -376,6 +383,7 @@ struct tvcard bttv_tvcards[] = {
376 .audiomux = { 0, 1, 0, 1, 3}, 383 .audiomux = { 0, 1, 0, 1, 3},
377 .needs_tvaudio = 1, 384 .needs_tvaudio = 1,
378 .tuner_type = -1, 385 .tuner_type = -1,
386 .tuner_addr = ADDR_UNSET,
379},{ 387},{
380 .name = "AVerMedia TVPhone", 388 .name = "AVerMedia TVPhone",
381 .video_inputs = 3, 389 .video_inputs = 3,
@@ -388,6 +396,7 @@ struct tvcard bttv_tvcards[] = {
388 /* 0x04 for some cards ?? */ 396 /* 0x04 for some cards ?? */
389 .needs_tvaudio = 1, 397 .needs_tvaudio = 1,
390 .tuner_type = -1, 398 .tuner_type = -1,
399 .tuner_addr = ADDR_UNSET,
391 .audio_hook = avermedia_tvphone_audio, 400 .audio_hook = avermedia_tvphone_audio,
392 .has_remote = 1, 401 .has_remote = 1,
393},{ 402},{
@@ -401,6 +410,7 @@ struct tvcard bttv_tvcards[] = {
401 .audiomux = {0 }, 410 .audiomux = {0 },
402 .needs_tvaudio = 1, 411 .needs_tvaudio = 1,
403 .tuner_type = -1, 412 .tuner_type = -1,
413 .tuner_addr = ADDR_UNSET,
404},{ 414},{
405 415
406/* ---- card 0x08 ---------------------------------- */ 416/* ---- card 0x08 ---------------------------------- */
@@ -415,6 +425,7 @@ struct tvcard bttv_tvcards[] = {
415 .needs_tvaudio = 1, 425 .needs_tvaudio = 1,
416 .pll = PLL_28, 426 .pll = PLL_28,
417 .tuner_type = -1, 427 .tuner_type = -1,
428 .tuner_addr = ADDR_UNSET,
418},{ 429},{
419 .name = "IMS/IXmicro TurboTV", 430 .name = "IMS/IXmicro TurboTV",
420 .video_inputs = 3, 431 .video_inputs = 3,
@@ -427,6 +438,7 @@ struct tvcard bttv_tvcards[] = {
427 .needs_tvaudio = 0, 438 .needs_tvaudio = 0,
428 .pll = PLL_28, 439 .pll = PLL_28,
429 .tuner_type = TUNER_TEMIC_PAL, 440 .tuner_type = TUNER_TEMIC_PAL,
441 .tuner_addr = ADDR_UNSET,
430},{ 442},{
431 .name = "Hauppauge (bt878)", 443 .name = "Hauppauge (bt878)",
432 .video_inputs = 4, 444 .video_inputs = 4,
@@ -439,6 +451,7 @@ struct tvcard bttv_tvcards[] = {
439 .needs_tvaudio = 1, 451 .needs_tvaudio = 1,
440 .pll = PLL_28, 452 .pll = PLL_28,
441 .tuner_type = -1, 453 .tuner_type = -1,
454 .tuner_addr = ADDR_UNSET,
442},{ 455},{
443 .name = "MIRO PCTV pro", 456 .name = "MIRO PCTV pro",
444 .video_inputs = 3, 457 .video_inputs = 3,
@@ -450,6 +463,7 @@ struct tvcard bttv_tvcards[] = {
450 .audiomux = { 0x20001,0x10001, 0, 0,10}, 463 .audiomux = { 0x20001,0x10001, 0, 0,10},
451 .needs_tvaudio = 1, 464 .needs_tvaudio = 1,
452 .tuner_type = -1, 465 .tuner_type = -1,
466 .tuner_addr = ADDR_UNSET,
453},{ 467},{
454 468
455/* ---- card 0x0c ---------------------------------- */ 469/* ---- card 0x0c ---------------------------------- */
@@ -463,6 +477,7 @@ struct tvcard bttv_tvcards[] = {
463 .audiomux = { 13, 14, 11, 7, 0, 0}, 477 .audiomux = { 13, 14, 11, 7, 0, 0},
464 .needs_tvaudio = 1, 478 .needs_tvaudio = 1,
465 .tuner_type = -1, 479 .tuner_type = -1,
480 .tuner_addr = ADDR_UNSET,
466},{ 481},{
467 .name = "AVerMedia TVCapture 98", 482 .name = "AVerMedia TVCapture 98",
468 .video_inputs = 3, 483 .video_inputs = 3,
@@ -476,6 +491,7 @@ struct tvcard bttv_tvcards[] = {
476 .msp34xx_alt = 1, 491 .msp34xx_alt = 1,
477 .pll = PLL_28, 492 .pll = PLL_28,
478 .tuner_type = TUNER_PHILIPS_PAL, 493 .tuner_type = TUNER_PHILIPS_PAL,
494 .tuner_addr = ADDR_UNSET,
479 .audio_hook = avermedia_tv_stereo_audio, 495 .audio_hook = avermedia_tv_stereo_audio,
480},{ 496},{
481 .name = "Aimslab Video Highway Xtreme (VHX)", 497 .name = "Aimslab Video Highway Xtreme (VHX)",
@@ -489,6 +505,7 @@ struct tvcard bttv_tvcards[] = {
489 .needs_tvaudio = 1, 505 .needs_tvaudio = 1,
490 .pll = PLL_28, 506 .pll = PLL_28,
491 .tuner_type = -1, 507 .tuner_type = -1,
508 .tuner_addr = ADDR_UNSET,
492},{ 509},{
493 .name = "Zoltrix TV-Max", 510 .name = "Zoltrix TV-Max",
494 .video_inputs = 3, 511 .video_inputs = 3,
@@ -500,6 +517,7 @@ struct tvcard bttv_tvcards[] = {
500 .audiomux = {0 , 0, 1 , 0, 10}, 517 .audiomux = {0 , 0, 1 , 0, 10},
501 .needs_tvaudio = 1, 518 .needs_tvaudio = 1,
502 .tuner_type = -1, 519 .tuner_type = -1,
520 .tuner_addr = ADDR_UNSET,
503},{ 521},{
504 522
505/* ---- card 0x10 ---------------------------------- */ 523/* ---- card 0x10 ---------------------------------- */
@@ -510,7 +528,7 @@ struct tvcard bttv_tvcards[] = {
510 .svhs = 2, 528 .svhs = 2,
511 .gpiomask = 0x01fe00, 529 .gpiomask = 0x01fe00,
512 .muxsel = { 2, 3, 1, 1}, 530 .muxsel = { 2, 3, 1, 1},
513 // 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> 531 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
514 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 532 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
515 .needs_tvaudio = 1, 533 .needs_tvaudio = 1,
516 .pll = PLL_28, 534 .pll = PLL_28,
@@ -526,6 +544,7 @@ struct tvcard bttv_tvcards[] = {
526 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, 544 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
527 .needs_tvaudio = 1, 545 .needs_tvaudio = 1,
528 .tuner_type = -1, 546 .tuner_type = -1,
547 .tuner_addr = ADDR_UNSET,
529 .audio_hook = winview_audio, 548 .audio_hook = winview_audio,
530 .has_radio = 1, 549 .has_radio = 1,
531},{ 550},{
@@ -539,6 +558,7 @@ struct tvcard bttv_tvcards[] = {
539 .audiomux = {1, 0, 0, 0, 0}, 558 .audiomux = {1, 0, 0, 0, 0},
540 .needs_tvaudio = 1, 559 .needs_tvaudio = 1,
541 .tuner_type = -1, 560 .tuner_type = -1,
561 .tuner_addr = ADDR_UNSET,
542},{ 562},{
543 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", 563 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
544 .video_inputs = 4, 564 .video_inputs = 4,
@@ -550,6 +570,7 @@ struct tvcard bttv_tvcards[] = {
550 .audiomux = { 0 }, 570 .audiomux = { 0 },
551 .no_msp34xx = 1, 571 .no_msp34xx = 1,
552 .tuner_type = -1, 572 .tuner_type = -1,
573 .tuner_addr = ADDR_UNSET,
553},{ 574},{
554 575
555/* ---- card 0x14 ---------------------------------- */ 576/* ---- card 0x14 ---------------------------------- */
@@ -560,10 +581,11 @@ struct tvcard bttv_tvcards[] = {
560 .svhs = 2, 581 .svhs = 2,
561 .muxsel = {2, 3, 1, 1}, 582 .muxsel = {2, 3, 1, 1},
562 .tuner_type = -1, 583 .tuner_type = -1,
584 .tuner_addr = ADDR_UNSET,
563},{ 585},{
564 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", 586 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
565 .video_inputs = 4, 587 .video_inputs = 4,
566 .audio_inputs = 2, // tuner, line in 588 .audio_inputs = 2, /* tuner, line in */
567 .tuner = 0, 589 .tuner = 0,
568 .svhs = 2, 590 .svhs = 2,
569 .gpiomask = 0x1800, 591 .gpiomask = 0x1800,
@@ -571,6 +593,7 @@ struct tvcard bttv_tvcards[] = {
571 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 593 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
572 .pll = PLL_28, 594 .pll = PLL_28,
573 .tuner_type = TUNER_PHILIPS_PAL_I, 595 .tuner_type = TUNER_PHILIPS_PAL_I,
596 .tuner_addr = ADDR_UNSET,
574},{ 597},{
575 .name = "Askey CPH050/ Phoebe Tv Master + FM", 598 .name = "Askey CPH050/ Phoebe Tv Master + FM",
576 .video_inputs = 3, 599 .video_inputs = 3,
@@ -583,6 +606,7 @@ struct tvcard bttv_tvcards[] = {
583 .needs_tvaudio = 1, 606 .needs_tvaudio = 1,
584 .pll = PLL_28, 607 .pll = PLL_28,
585 .tuner_type = -1, 608 .tuner_type = -1,
609 .tuner_addr = ADDR_UNSET,
586},{ 610},{
587 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", 611 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
588 .video_inputs = 3, 612 .video_inputs = 3,
@@ -591,11 +615,12 @@ struct tvcard bttv_tvcards[] = {
591 .svhs = -1, 615 .svhs = -1,
592 .gpiomask = 7, 616 .gpiomask = 7,
593 .muxsel = { 2, 3, -1 }, 617 .muxsel = { 2, 3, -1 },
594 .digital_mode = DIGITAL_MODE_CAMERA, 618 .digital_mode = DIGITAL_MODE_CAMERA,
595 .audiomux = { 0, 0, 0, 0, 0 }, 619 .audiomux = { 0, 0, 0, 0, 0 },
596 .no_msp34xx = 1, 620 .no_msp34xx = 1,
597 .pll = PLL_28, 621 .pll = PLL_28,
598 .tuner_type = TUNER_ALPS_TSBB5_PAL_I, 622 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
623 .tuner_addr = ADDR_UNSET,
599},{ 624},{
600 625
601/* ---- card 0x18 ---------------------------------- */ 626/* ---- card 0x18 ---------------------------------- */
@@ -610,6 +635,7 @@ struct tvcard bttv_tvcards[] = {
610 .needs_tvaudio = 1, 635 .needs_tvaudio = 1,
611 .pll = PLL_28, 636 .pll = PLL_28,
612 .tuner_type = -1, 637 .tuner_type = -1,
638 .tuner_addr = ADDR_UNSET,
613 .has_remote = 1, 639 .has_remote = 1,
614},{ 640},{
615 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", 641 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
@@ -622,6 +648,7 @@ struct tvcard bttv_tvcards[] = {
622 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, 648 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
623 .needs_tvaudio = 0, 649 .needs_tvaudio = 0,
624 .tuner_type = TUNER_PHILIPS_PAL, 650 .tuner_type = TUNER_PHILIPS_PAL,
651 .tuner_addr = ADDR_UNSET,
625 .audio_hook = terratv_audio, 652 .audio_hook = terratv_audio,
626},{ 653},{
627 .name = "Hauppauge WinCam newer (bt878)", 654 .name = "Hauppauge WinCam newer (bt878)",
@@ -634,6 +661,7 @@ struct tvcard bttv_tvcards[] = {
634 .audiomux = { 0, 1, 2, 3, 4}, 661 .audiomux = { 0, 1, 2, 3, 4},
635 .needs_tvaudio = 1, 662 .needs_tvaudio = 1,
636 .tuner_type = -1, 663 .tuner_type = -1,
664 .tuner_addr = ADDR_UNSET,
637},{ 665},{
638 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", 666 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
639 .video_inputs = 4, 667 .video_inputs = 4,
@@ -645,6 +673,7 @@ struct tvcard bttv_tvcards[] = {
645 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 673 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
646 .pll = PLL_28, 674 .pll = PLL_28,
647 .tuner_type = TUNER_PHILIPS_SECAM, 675 .tuner_type = TUNER_PHILIPS_SECAM,
676 .tuner_addr = ADDR_UNSET,
648},{ 677},{
649 678
650/* ---- card 0x1c ---------------------------------- */ 679/* ---- card 0x1c ---------------------------------- */
@@ -658,37 +687,38 @@ struct tvcard bttv_tvcards[] = {
658 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, 687 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
659 .needs_tvaudio = 0, 688 .needs_tvaudio = 0,
660 .tuner_type = TUNER_PHILIPS_PAL, 689 .tuner_type = TUNER_PHILIPS_PAL,
690 .tuner_addr = ADDR_UNSET,
661 .audio_hook = terratv_audio, 691 .audio_hook = terratv_audio,
662 /* GPIO wiring: 692 /* GPIO wiring:
663 External 20 pin connector (for Active Radio Upgrade board) 693 External 20 pin connector (for Active Radio Upgrade board)
664 gpio00: i2c-sda 694 gpio00: i2c-sda
665 gpio01: i2c-scl 695 gpio01: i2c-scl
666 gpio02: om5610-data 696 gpio02: om5610-data
667 gpio03: om5610-clk 697 gpio03: om5610-clk
668 gpio04: om5610-wre 698 gpio04: om5610-wre
669 gpio05: om5610-stereo 699 gpio05: om5610-stereo
670 gpio06: rds6588-davn 700 gpio06: rds6588-davn
671 gpio07: Pin 7 n.c. 701 gpio07: Pin 7 n.c.
672 gpio08: nIOW 702 gpio08: nIOW
673 gpio09+10: nIOR, nSEL ?? (bt878) 703 gpio09+10: nIOR, nSEL ?? (bt878)
674 gpio09: nIOR (bt848) 704 gpio09: nIOR (bt848)
675 gpio10: nSEL (bt848) 705 gpio10: nSEL (bt848)
676 Sound Routing: 706 Sound Routing:
677 gpio16: u2-A0 (1st 4052bt) 707 gpio16: u2-A0 (1st 4052bt)
678 gpio17: u2-A1 708 gpio17: u2-A1
679 gpio18: u2-nEN 709 gpio18: u2-nEN
680 gpio19: u4-A0 (2nd 4052) 710 gpio19: u4-A0 (2nd 4052)
681 gpio20: u4-A1 711 gpio20: u4-A1
682 u4-nEN - GND 712 u4-nEN - GND
683 Btspy: 713 Btspy:
684 00000 : Cdrom (internal audio input) 714 00000 : Cdrom (internal audio input)
685 10000 : ext. Video audio input 715 10000 : ext. Video audio input
686 20000 : TV Mono 716 20000 : TV Mono
687 a0000 : TV Mono/2 717 a0000 : TV Mono/2
688 1a0000 : TV Stereo 718 1a0000 : TV Stereo
689 30000 : Radio 719 30000 : Radio
690 40000 : Mute 720 40000 : Mute
691 */ 721*/
692 722
693},{ 723},{
694 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ 724 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
@@ -702,6 +732,7 @@ struct tvcard bttv_tvcards[] = {
702 .audiomux = { 0 }, 732 .audiomux = { 0 },
703 .needs_tvaudio = 1, 733 .needs_tvaudio = 1,
704 .tuner_type = -1, 734 .tuner_type = -1,
735 .tuner_addr = ADDR_UNSET,
705 .muxsel_hook = PXC200_muxsel, 736 .muxsel_hook = PXC200_muxsel,
706 737
707},{ 738},{
@@ -710,11 +741,12 @@ struct tvcard bttv_tvcards[] = {
710 .audio_inputs = 1, 741 .audio_inputs = 1,
711 .tuner = 0, 742 .tuner = 0,
712 .svhs = 2, 743 .svhs = 2,
713 .gpiomask = 0x1800, //0x8dfe00 744 .gpiomask = 0x1800, /* 0x8dfe00 */
714 .muxsel = { 2, 3, 1, 1}, 745 .muxsel = { 2, 3, 1, 1},
715 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, 746 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
716 .pll = PLL_28, 747 .pll = PLL_28,
717 .tuner_type = -1, 748 .tuner_type = -1,
749 .tuner_addr = ADDR_UNSET,
718},{ 750},{
719 .name = "Formac iProTV, Formac ProTV I (bt848)", 751 .name = "Formac iProTV, Formac ProTV I (bt848)",
720 .video_inputs = 4, 752 .video_inputs = 4,
@@ -726,6 +758,7 @@ struct tvcard bttv_tvcards[] = {
726 .audiomux = { 1, 0, 0, 0, 0 }, 758 .audiomux = { 1, 0, 0, 0, 0 },
727 .pll = PLL_28, 759 .pll = PLL_28,
728 .tuner_type = TUNER_PHILIPS_PAL, 760 .tuner_type = TUNER_PHILIPS_PAL,
761 .tuner_addr = ADDR_UNSET,
729},{ 762},{
730 763
731/* ---- card 0x20 ---------------------------------- */ 764/* ---- card 0x20 ---------------------------------- */
@@ -739,6 +772,7 @@ struct tvcard bttv_tvcards[] = {
739 .audiomux = { 0 }, 772 .audiomux = { 0 },
740 .needs_tvaudio = 0, 773 .needs_tvaudio = 0,
741 .tuner_type = 4, 774 .tuner_type = 4,
775 .tuner_addr = ADDR_UNSET,
742},{ 776},{
743 .name = "Terratec TerraTValue Version Bt878", 777 .name = "Terratec TerraTValue Version Bt878",
744 .video_inputs = 3, 778 .video_inputs = 3,
@@ -751,31 +785,33 @@ struct tvcard bttv_tvcards[] = {
751 .needs_tvaudio = 1, 785 .needs_tvaudio = 1,
752 .pll = PLL_28, 786 .pll = PLL_28,
753 .tuner_type = TUNER_PHILIPS_PAL, 787 .tuner_type = TUNER_PHILIPS_PAL,
788 .tuner_addr = ADDR_UNSET,
754},{ 789},{
755 .name = "Leadtek WinFast 2000/ WinFast 2000 XP", 790 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
756 .video_inputs = 4, 791 .video_inputs = 4,
757 .audio_inputs = 1, 792 .audio_inputs = 1,
758 .tuner = 0, 793 .tuner = 0,
759 .svhs = 2, 794 .svhs = 2,
760 .muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector 795 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
761 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */ 796 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
762 .gpiomask = 0xb33000, 797 .gpiomask = 0xb33000,
763 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 }, 798 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
764 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) 799 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
765 gpio23 -- hef4052:nEnable (0x800000) 800 gpio23 -- hef4052:nEnable (0x800000)
766 gpio12 -- hef4052:A1 801 gpio12 -- hef4052:A1
767 gpio13 -- hef4052:A0 802 gpio13 -- hef4052:A0
768 0x0000: external audio 803 0x0000: external audio
769 0x1000: FM 804 0x1000: FM
770 0x2000: TV 805 0x2000: TV
771 0x3000: n.c. 806 0x3000: n.c.
772 Note: There exists another variant "Winfast 2000" with tv stereo !? 807 Note: There exists another variant "Winfast 2000" with tv stereo !?
773 Note: eeprom only contains FF and pci subsystem id 107d:6606 808 Note: eeprom only contains FF and pci subsystem id 107d:6606
774 */ 809 */
775 .needs_tvaudio = 0, 810 .needs_tvaudio = 0,
776 .pll = PLL_28, 811 .pll = PLL_28,
777 .has_radio = 1, 812 .has_radio = 1,
778 .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk 813 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
814 .tuner_addr = ADDR_UNSET,
779 .audio_hook = winfast2000_audio, 815 .audio_hook = winfast2000_audio,
780 .has_remote = 1, 816 .has_remote = 1,
781},{ 817},{
@@ -789,6 +825,7 @@ struct tvcard bttv_tvcards[] = {
789 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 825 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
790 .pll = PLL_28, 826 .pll = PLL_28,
791 .tuner_type = -1, 827 .tuner_type = -1,
828 .tuner_addr = ADDR_UNSET,
792},{ 829},{
793 830
794/* ---- card 0x24 ---------------------------------- */ 831/* ---- card 0x24 ---------------------------------- */
@@ -802,6 +839,7 @@ struct tvcard bttv_tvcards[] = {
802 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, 839 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
803 .pll = PLL_28, 840 .pll = PLL_28,
804 .tuner_type = -1, 841 .tuner_type = -1,
842 .tuner_addr = ADDR_UNSET,
805 .has_radio = 1, 843 .has_radio = 1,
806},{ 844},{
807 .name = "Prolink PixelView PlayTV pro", 845 .name = "Prolink PixelView PlayTV pro",
@@ -815,6 +853,7 @@ struct tvcard bttv_tvcards[] = {
815 .no_msp34xx = 1, 853 .no_msp34xx = 1,
816 .pll = PLL_28, 854 .pll = PLL_28,
817 .tuner_type = -1, 855 .tuner_type = -1,
856 .tuner_addr = ADDR_UNSET,
818},{ 857},{
819 .name = "Askey CPH06X TView99", 858 .name = "Askey CPH06X TView99",
820 .video_inputs = 4, 859 .video_inputs = 4,
@@ -827,6 +866,7 @@ struct tvcard bttv_tvcards[] = {
827 .needs_tvaudio = 1, 866 .needs_tvaudio = 1,
828 .pll = PLL_28, 867 .pll = PLL_28,
829 .tuner_type = 1, 868 .tuner_type = 1,
869 .tuner_addr = ADDR_UNSET,
830 .has_remote = 1, 870 .has_remote = 1,
831},{ 871},{
832 .name = "Pinnacle PCTV Studio/Rave", 872 .name = "Pinnacle PCTV Studio/Rave",
@@ -840,6 +880,7 @@ struct tvcard bttv_tvcards[] = {
840 .needs_tvaudio = 0, 880 .needs_tvaudio = 0,
841 .pll = PLL_28, 881 .pll = PLL_28,
842 .tuner_type = -1, 882 .tuner_type = -1,
883 .tuner_addr = ADDR_UNSET,
843},{ 884},{
844 885
845/* ---- card 0x28 ---------------------------------- */ 886/* ---- card 0x28 ---------------------------------- */
@@ -854,6 +895,7 @@ struct tvcard bttv_tvcards[] = {
854 .no_msp34xx = 1, 895 .no_msp34xx = 1,
855 .needs_tvaudio = 1, 896 .needs_tvaudio = 1,
856 .tuner_type = TUNER_PHILIPS_NTSC, 897 .tuner_type = TUNER_PHILIPS_NTSC,
898 .tuner_addr = ADDR_UNSET,
857 .pll = PLL_28, 899 .pll = PLL_28,
858 .has_radio = 1, 900 .has_radio = 1,
859},{ 901},{
@@ -868,6 +910,7 @@ struct tvcard bttv_tvcards[] = {
868 .needs_tvaudio = 1, 910 .needs_tvaudio = 1,
869 .pll = PLL_28, 911 .pll = PLL_28,
870 .tuner_type = -1, 912 .tuner_type = -1,
913 .tuner_addr = ADDR_UNSET,
871 .has_radio = 1, 914 .has_radio = 1,
872 .audio_hook = avermedia_tvphone_audio, 915 .audio_hook = avermedia_tvphone_audio,
873},{ 916},{
@@ -883,6 +926,7 @@ struct tvcard bttv_tvcards[] = {
883 .no_msp34xx = 1, 926 .no_msp34xx = 1,
884 .pll = PLL_28, 927 .pll = PLL_28,
885 .tuner_type = 1, 928 .tuner_type = 1,
929 .tuner_addr = ADDR_UNSET,
886},{ 930},{
887 .name = "Little OnAir TV", 931 .name = "Little OnAir TV",
888 .video_inputs = 3, 932 .video_inputs = 3,
@@ -894,6 +938,7 @@ struct tvcard bttv_tvcards[] = {
894 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc}, 938 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
895 .no_msp34xx = 1, 939 .no_msp34xx = 1,
896 .tuner_type = -1, 940 .tuner_type = -1,
941 .tuner_addr = ADDR_UNSET,
897},{ 942},{
898 943
899/* ---- card 0x2c ---------------------------------- */ 944/* ---- card 0x2c ---------------------------------- */
@@ -908,6 +953,7 @@ struct tvcard bttv_tvcards[] = {
908 .no_msp34xx = 1, 953 .no_msp34xx = 1,
909 .pll = PLL_NONE, 954 .pll = PLL_NONE,
910 .tuner_type = -1, 955 .tuner_type = -1,
956 .tuner_addr = ADDR_UNSET,
911},{ 957},{
912 .name = "MATRIX-Vision MV-Delta 2", 958 .name = "MATRIX-Vision MV-Delta 2",
913 .video_inputs = 5, 959 .video_inputs = 5,
@@ -920,6 +966,7 @@ struct tvcard bttv_tvcards[] = {
920 .no_msp34xx = 1, 966 .no_msp34xx = 1,
921 .pll = PLL_28, 967 .pll = PLL_28,
922 .tuner_type = -1, 968 .tuner_type = -1,
969 .tuner_addr = ADDR_UNSET,
923},{ 970},{
924 .name = "Zoltrix Genie TV/FM", 971 .name = "Zoltrix Genie TV/FM",
925 .video_inputs = 3, 972 .video_inputs = 3,
@@ -932,6 +979,7 @@ struct tvcard bttv_tvcards[] = {
932 .no_msp34xx = 1, 979 .no_msp34xx = 1,
933 .pll = PLL_28, 980 .pll = PLL_28,
934 .tuner_type = 21, 981 .tuner_type = 21,
982 .tuner_addr = ADDR_UNSET,
935},{ 983},{
936 .name = "Terratec TV/Radio+", 984 .name = "Terratec TV/Radio+",
937 .video_inputs = 3, 985 .video_inputs = 3,
@@ -945,6 +993,7 @@ struct tvcard bttv_tvcards[] = {
945 .no_msp34xx = 1, 993 .no_msp34xx = 1,
946 .pll = PLL_35, 994 .pll = PLL_35,
947 .tuner_type = 1, 995 .tuner_type = 1,
996 .tuner_addr = ADDR_UNSET,
948 .has_radio = 1, 997 .has_radio = 1,
949},{ 998},{
950 999
@@ -960,6 +1009,7 @@ struct tvcard bttv_tvcards[] = {
960 .needs_tvaudio = 1, 1009 .needs_tvaudio = 1,
961 .pll = PLL_28, 1010 .pll = PLL_28,
962 .tuner_type = -1, 1011 .tuner_type = -1,
1012 .tuner_addr = ADDR_UNSET,
963},{ 1013},{
964 .name = "IODATA GV-BCTV3/PCI", 1014 .name = "IODATA GV-BCTV3/PCI",
965 .video_inputs = 3, 1015 .video_inputs = 3,
@@ -972,6 +1022,7 @@ struct tvcard bttv_tvcards[] = {
972 .no_msp34xx = 1, 1022 .no_msp34xx = 1,
973 .pll = PLL_28, 1023 .pll = PLL_28,
974 .tuner_type = TUNER_ALPS_TSHC6_NTSC, 1024 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1025 .tuner_addr = ADDR_UNSET,
975 .audio_hook = gvbctv3pci_audio, 1026 .audio_hook = gvbctv3pci_audio,
976},{ 1027},{
977 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", 1028 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
@@ -986,6 +1037,7 @@ struct tvcard bttv_tvcards[] = {
986 .no_msp34xx = 1, 1037 .no_msp34xx = 1,
987 .pll = PLL_28, 1038 .pll = PLL_28,
988 .tuner_type = TUNER_PHILIPS_PAL_I, 1039 .tuner_type = TUNER_PHILIPS_PAL_I,
1040 .tuner_addr = ADDR_UNSET,
989 .has_remote = 1, 1041 .has_remote = 1,
990 /* GPIO wiring: (different from Rev.4C !) 1042 /* GPIO wiring: (different from Rev.4C !)
991 GPIO17: U4.A0 (first hef4052bt) 1043 GPIO17: U4.A0 (first hef4052bt)
@@ -994,8 +1046,8 @@ struct tvcard bttv_tvcards[] = {
994 GPIO21: U4.nEN 1046 GPIO21: U4.nEN
995 GPIO22: BT832 Reset Line 1047 GPIO22: BT832 Reset Line
996 GPIO23: A5,A0, U5,nEN 1048 GPIO23: A5,A0, U5,nEN
997 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22 1049 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
998 */ 1050 */
999},{ 1051},{
1000 .name = "Eagle Wireless Capricorn2 (bt878A)", 1052 .name = "Eagle Wireless Capricorn2 (bt878A)",
1001 .video_inputs = 4, 1053 .video_inputs = 4,
@@ -1007,6 +1059,7 @@ struct tvcard bttv_tvcards[] = {
1007 .audiomux = { 0, 1, 2, 3, 4}, 1059 .audiomux = { 0, 1, 2, 3, 4},
1008 .pll = PLL_28, 1060 .pll = PLL_28,
1009 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, 1061 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1062 .tuner_addr = ADDR_UNSET,
1010},{ 1063},{
1011 1064
1012/* ---- card 0x34 ---------------------------------- */ 1065/* ---- card 0x34 ---------------------------------- */
@@ -1020,20 +1073,21 @@ struct tvcard bttv_tvcards[] = {
1020 .muxsel = { 2, 3, 1, 1}, 1073 .muxsel = { 2, 3, 1, 1},
1021 .audiomux = { 1, 0xd0001, 0, 0, 10}, 1074 .audiomux = { 1, 0xd0001, 0, 0, 10},
1022 /* sound path (5 sources): 1075 /* sound path (5 sources):
1023 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) 1076 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1024 0= ext. Audio IN 1077 0= ext. Audio IN
1025 1= from MUX2 1078 1= from MUX2
1026 2= Mono TV sound from Tuner 1079 2= Mono TV sound from Tuner
1027 3= not connected 1080 3= not connected
1028 MUX2 (mask 0x30000): 1081 MUX2 (mask 0x30000):
1029 0,2,3= from MSP34xx 1082 0,2,3= from MSP34xx
1030 1= FM stereo Radio from Tuner */ 1083 1= FM stereo Radio from Tuner */
1031 .needs_tvaudio = 0, 1084 .needs_tvaudio = 0,
1032 .pll = PLL_28, 1085 .pll = PLL_28,
1033 .tuner_type = -1, 1086 .tuner_type = -1,
1087 .tuner_addr = ADDR_UNSET,
1034},{ 1088},{
1035 /* Claas Langbehn <claas@bigfoot.com>, 1089 /* Claas Langbehn <claas@bigfoot.com>,
1036 Sven Grothklags <sven@upb.de> */ 1090 Sven Grothklags <sven@upb.de> */
1037 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", 1091 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1038 .video_inputs = 4, 1092 .video_inputs = 4,
1039 .audio_inputs = 3, 1093 .audio_inputs = 3,
@@ -1045,10 +1099,11 @@ struct tvcard bttv_tvcards[] = {
1045 .needs_tvaudio = 1, 1099 .needs_tvaudio = 1,
1046 .pll = PLL_28, 1100 .pll = PLL_28,
1047 .tuner_type = TUNER_PHILIPS_PAL, 1101 .tuner_type = TUNER_PHILIPS_PAL,
1102 .tuner_addr = ADDR_UNSET,
1048 .has_radio = 1, 1103 .has_radio = 1,
1049},{ 1104},{
1050 /* Tim Röstermundt <rosterm@uni-muenster.de> 1105 /* Tim Röstermundt <rosterm@uni-muenster.de>
1051 in de.comp.os.unix.linux.hardware: 1106 in de.comp.os.unix.linux.hardware:
1052 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 1107 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1053 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff 1108 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1054 options tuner type=5 */ 1109 options tuner type=5 */
@@ -1060,15 +1115,16 @@ struct tvcard bttv_tvcards[] = {
1060 .gpiomask = 0x18e0, 1115 .gpiomask = 0x18e0,
1061 .muxsel = { 2, 3, 1, 1}, 1116 .muxsel = { 2, 3, 1, 1},
1062 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, 1117 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1063 /* For cards with tda9820/tda9821: 1118 /* For cards with tda9820/tda9821:
1064 0x0000: Tuner normal stereo 1119 0x0000: Tuner normal stereo
1065 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) 1120 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1066 0x0880: Tuner A2 stereo */ 1121 0x0880: Tuner A2 stereo */
1067 .pll = PLL_28, 1122 .pll = PLL_28,
1068 .tuner_type = -1, 1123 .tuner_type = -1,
1124 .tuner_addr = ADDR_UNSET,
1069},{ 1125},{
1070 /* Miguel Angel Alvarez <maacruz@navegalia.com> 1126 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1071 old Easy TV BT848 version (model CPH031) */ 1127 old Easy TV BT848 version (model CPH031) */
1072 .name = "Askey CPH031/ BESTBUY Easy TV", 1128 .name = "Askey CPH031/ BESTBUY Easy TV",
1073 .video_inputs = 4, 1129 .video_inputs = 4,
1074 .audio_inputs = 1, 1130 .audio_inputs = 1,
@@ -1080,6 +1136,7 @@ struct tvcard bttv_tvcards[] = {
1080 .needs_tvaudio = 0, 1136 .needs_tvaudio = 0,
1081 .pll = PLL_28, 1137 .pll = PLL_28,
1082 .tuner_type = TUNER_TEMIC_PAL, 1138 .tuner_type = TUNER_TEMIC_PAL,
1139 .tuner_addr = ADDR_UNSET,
1083},{ 1140},{
1084 1141
1085/* ---- card 0x38 ---------------------------------- */ 1142/* ---- card 0x38 ---------------------------------- */
@@ -1094,10 +1151,11 @@ struct tvcard bttv_tvcards[] = {
1094 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, 1151 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1095 .pll = PLL_28, 1152 .pll = PLL_28,
1096 .tuner_type = 5, 1153 .tuner_type = 5,
1154 .tuner_addr = ADDR_UNSET,
1097},{ 1155},{
1098 /* This is the ultimate cheapo capture card 1156 /* This is the ultimate cheapo capture card
1099 * just a BT848A on a small PCB! 1157 * just a BT848A on a small PCB!
1100 * Steve Hosgood <steve@equiinet.com> */ 1158 * Steve Hosgood <steve@equiinet.com> */
1101 .name = "GrandTec 'Grand Video Capture' (Bt848)", 1159 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1102 .video_inputs = 2, 1160 .video_inputs = 2,
1103 .audio_inputs = 0, 1161 .audio_inputs = 0,
@@ -1110,19 +1168,21 @@ struct tvcard bttv_tvcards[] = {
1110 .no_msp34xx = 1, 1168 .no_msp34xx = 1,
1111 .pll = PLL_35, 1169 .pll = PLL_35,
1112 .tuner_type = -1, 1170 .tuner_type = -1,
1171 .tuner_addr = ADDR_UNSET,
1113},{ 1172},{
1114 /* Daniel Herrington <daniel.herrington@home.com> */ 1173 /* Daniel Herrington <daniel.herrington@home.com> */
1115 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", 1174 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1116 .video_inputs = 3, 1175 .video_inputs = 3,
1117 .audio_inputs = 1, 1176 .audio_inputs = 1,
1118 .tuner = 0, 1177 .tuner = 0,
1119 .svhs = 2, 1178 .svhs = 2,
1120 .gpiomask = 0xe00, 1179 .gpiomask = 0xe00,
1121 .muxsel = { 2, 3, 1, 1}, 1180 .muxsel = { 2, 3, 1, 1},
1122 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, 1181 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1123 .needs_tvaudio = 1, 1182 .needs_tvaudio = 1,
1124 .pll = PLL_28, 1183 .pll = PLL_28,
1125 .tuner_type = TUNER_TEMIC_4036FY5_NTSC, 1184 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1185 .tuner_addr = ADDR_UNSET,
1126},{ 1186},{
1127 /* Matti Mottus <mottus@physic.ut.ee> */ 1187 /* Matti Mottus <mottus@physic.ut.ee> */
1128 .name = "Askey CPH03x TV Capturer", 1188 .name = "Askey CPH03x TV Capturer",
@@ -1130,11 +1190,12 @@ struct tvcard bttv_tvcards[] = {
1130 .audio_inputs = 1, 1190 .audio_inputs = 1,
1131 .tuner = 0, 1191 .tuner = 0,
1132 .svhs = 2, 1192 .svhs = 2,
1133 .gpiomask = 0x03000F, 1193 .gpiomask = 0x03000F,
1134 .muxsel = { 2, 3, 1, 0}, 1194 .muxsel = { 2, 3, 1, 0},
1135 .audiomux = { 2,0,0,0,1 }, 1195 .audiomux = { 2,0,0,0,1 },
1136 .pll = PLL_28, 1196 .pll = PLL_28,
1137 .tuner_type = 0, 1197 .tuner_type = 0,
1198 .tuner_addr = ADDR_UNSET,
1138},{ 1199},{
1139 1200
1140/* ---- card 0x3c ---------------------------------- */ 1201/* ---- card 0x3c ---------------------------------- */
@@ -1149,7 +1210,7 @@ struct tvcard bttv_tvcards[] = {
1149 .audiomux = { 2, 0, 0, 1, 8}, 1210 .audiomux = { 2, 0, 0, 1, 8},
1150 .pll = PLL_35, 1211 .pll = PLL_35,
1151 .tuner_type = TUNER_TEMIC_PAL, 1212 .tuner_type = TUNER_TEMIC_PAL,
1152 1213 .tuner_addr = ADDR_UNSET,
1153},{ 1214},{
1154 /* Adrian Cox <adrian@humboldt.co.uk */ 1215 /* Adrian Cox <adrian@humboldt.co.uk */
1155 .name = "AG Electronics GMV1", 1216 .name = "AG Electronics GMV1",
@@ -1164,10 +1225,11 @@ struct tvcard bttv_tvcards[] = {
1164 .needs_tvaudio = 0, 1225 .needs_tvaudio = 0,
1165 .pll = PLL_28, 1226 .pll = PLL_28,
1166 .tuner_type = -1, 1227 .tuner_type = -1,
1228 .tuner_addr = ADDR_UNSET,
1167},{ 1229},{
1168 /* Miguel Angel Alvarez <maacruz@navegalia.com> 1230 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1169 new Easy TV BT878 version (model CPH061) 1231 new Easy TV BT878 version (model CPH061)
1170 special thanks to Informatica Mieres for providing the card */ 1232 special thanks to Informatica Mieres for providing the card */
1171 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", 1233 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1172 .video_inputs = 3, 1234 .video_inputs = 3,
1173 .audio_inputs = 2, 1235 .audio_inputs = 2,
@@ -1179,6 +1241,7 @@ struct tvcard bttv_tvcards[] = {
1179 .needs_tvaudio = 0, 1241 .needs_tvaudio = 0,
1180 .pll = PLL_28, 1242 .pll = PLL_28,
1181 .tuner_type = TUNER_PHILIPS_PAL, 1243 .tuner_type = TUNER_PHILIPS_PAL,
1244 .tuner_addr = ADDR_UNSET,
1182},{ 1245},{
1183 /* Lukas Gebauer <geby@volny.cz> */ 1246 /* Lukas Gebauer <geby@volny.cz> */
1184 .name = "ATI TV-Wonder", 1247 .name = "ATI TV-Wonder",
@@ -1191,6 +1254,7 @@ struct tvcard bttv_tvcards[] = {
1191 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe}, 1254 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1192 .pll = PLL_28, 1255 .pll = PLL_28,
1193 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, 1256 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1257 .tuner_addr = ADDR_UNSET,
1194},{ 1258},{
1195 1259
1196/* ---- card 0x40 ---------------------------------- */ 1260/* ---- card 0x40 ---------------------------------- */
@@ -1206,6 +1270,7 @@ struct tvcard bttv_tvcards[] = {
1206 .no_msp34xx = 1, 1270 .no_msp34xx = 1,
1207 .pll = PLL_28, 1271 .pll = PLL_28,
1208 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, 1272 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1273 .tuner_addr = ADDR_UNSET,
1209},{ 1274},{
1210 /* DeeJay <deejay@westel900.net (2000S) */ 1275 /* DeeJay <deejay@westel900.net (2000S) */
1211 .name = "Lifeview FlyVideo 2000S LR90", 1276 .name = "Lifeview FlyVideo 2000S LR90",
@@ -1216,7 +1281,7 @@ struct tvcard bttv_tvcards[] = {
1216 .gpiomask = 0x18e0, 1281 .gpiomask = 0x18e0,
1217 .muxsel = { 2, 3, 0, 1}, 1282 .muxsel = { 2, 3, 0, 1},
1218 /* Radio changed from 1e80 to 0x800 to make 1283 /* Radio changed from 1e80 to 0x800 to make
1219 FlyVideo2000S in .hu happy (gm)*/ 1284 FlyVideo2000S in .hu happy (gm)*/
1220 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ 1285 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1221 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, 1286 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1222 .audio_hook = fv2000s_audio, 1287 .audio_hook = fv2000s_audio,
@@ -1225,6 +1290,7 @@ struct tvcard bttv_tvcards[] = {
1225 .needs_tvaudio = 1, 1290 .needs_tvaudio = 1,
1226 .pll = PLL_28, 1291 .pll = PLL_28,
1227 .tuner_type = 5, 1292 .tuner_type = 5,
1293 .tuner_addr = ADDR_UNSET,
1228},{ 1294},{
1229 .name = "Terratec TValueRadio", 1295 .name = "Terratec TValueRadio",
1230 .video_inputs = 3, 1296 .video_inputs = 3,
@@ -1237,6 +1303,7 @@ struct tvcard bttv_tvcards[] = {
1237 .needs_tvaudio = 1, 1303 .needs_tvaudio = 1,
1238 .pll = PLL_28, 1304 .pll = PLL_28,
1239 .tuner_type = TUNER_PHILIPS_PAL, 1305 .tuner_type = TUNER_PHILIPS_PAL,
1306 .tuner_addr = ADDR_UNSET,
1240 .has_radio = 1, 1307 .has_radio = 1,
1241},{ 1308},{
1242 /* TANAKA Kei <peg00625@nifty.com> */ 1309 /* TANAKA Kei <peg00625@nifty.com> */
@@ -1251,25 +1318,27 @@ struct tvcard bttv_tvcards[] = {
1251 .no_msp34xx = 1, 1318 .no_msp34xx = 1,
1252 .pll = PLL_28, 1319 .pll = PLL_28,
1253 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, 1320 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1321 .tuner_addr = ADDR_UNSET,
1254 .audio_hook = gvbctv3pci_audio, 1322 .audio_hook = gvbctv3pci_audio,
1255},{ 1323},{
1256 1324
1257/* ---- card 0x44 ---------------------------------- */ 1325/* ---- card 0x44 ---------------------------------- */
1258 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", 1326 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1259 // try "insmod msp3400 simple=0" if you have 1327 /* try "insmod msp3400 simple=0" if you have
1260 // sound problems with this card. 1328 * sound problems with this card. */
1261 .video_inputs = 4, 1329 .video_inputs = 4,
1262 .audio_inputs = 1, 1330 .audio_inputs = 1,
1263 .tuner = 0, 1331 .tuner = 0,
1264 .svhs = -1, 1332 .svhs = -1,
1265 .gpiomask = 0x4f8a00, 1333 .gpiomask = 0x4f8a00,
1266 // 0x100000: 1=MSP enabled (0=disable again) 1334 /* 0x100000: 1=MSP enabled (0=disable again)
1267 // 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) 1335 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1268 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, 1336 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1269 // tvtuner, radio, external,internal, mute, stereo 1337 /* tvtuner, radio, external,internal, mute, stereo
1270 /* tuner, Composit, SVid, Composit-on-Svid-adapter*/ 1338 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1271 .muxsel = { 2, 3 ,0 ,1}, 1339 .muxsel = { 2, 3 ,0 ,1},
1272 .tuner_type = TUNER_MT2032, 1340 .tuner_type = TUNER_MT2032,
1341 .tuner_addr = ADDR_UNSET,
1273 .pll = PLL_28, 1342 .pll = PLL_28,
1274 .has_radio = 1, 1343 .has_radio = 1,
1275},{ 1344},{
@@ -1279,22 +1348,24 @@ struct tvcard bttv_tvcards[] = {
1279 .audio_inputs = 0, 1348 .audio_inputs = 0,
1280 .tuner = -1, 1349 .tuner = -1,
1281 .tuner_type = -1, 1350 .tuner_type = -1,
1351 .tuner_addr = ADDR_UNSET,
1282 .pll = PLL_28, 1352 .pll = PLL_28,
1283 .muxsel = { 2 }, 1353 .muxsel = { 2 },
1284 .gpiomask = 0 1354 .gpiomask = 0
1285},{ 1355},{
1286 /* Tomasz Pyra <hellfire@sedez.iq.pl> */ 1356 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1287 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", 1357 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1288 .video_inputs = 3, 1358 .video_inputs = 3,
1289 .audio_inputs = 4, 1359 .audio_inputs = 4,
1290 .tuner = 0, 1360 .tuner = 0,
1291 .svhs = 2, 1361 .svhs = 2,
1292 .gpiomask = 15, 1362 .gpiomask = 15,
1293 .muxsel = { 2, 3, 1, 1}, 1363 .muxsel = { 2, 3, 1, 1},
1294 .audiomux = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO ! 1364 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
1295 .needs_tvaudio = 1, 1365 .needs_tvaudio = 1,
1296 .pll = PLL_28, 1366 .pll = PLL_28,
1297 .tuner_type = 25, 1367 .tuner_type = 25,
1368 .tuner_addr = ADDR_UNSET,
1298 .has_remote = 1, 1369 .has_remote = 1,
1299 /* GPIO wiring: 1370 /* GPIO wiring:
1300 GPIO0: U4.A0 (hef4052bt) 1371 GPIO0: U4.A0 (hef4052bt)
@@ -1302,16 +1373,18 @@ struct tvcard bttv_tvcards[] = {
1302 GPIO2: U4.A1 (second hef4052bt) 1373 GPIO2: U4.A1 (second hef4052bt)
1303 GPIO3: U4.nEN, U5.A0, A5.nEN 1374 GPIO3: U4.nEN, U5.A0, A5.nEN
1304 GPIO8-15: vrd866b ? 1375 GPIO8-15: vrd866b ?
1305 */ 1376 */
1306},{ 1377},{
1307 .name = "Lifeview FlyVideo 98EZ (capture only) LR51", 1378 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
1308 .video_inputs = 4, 1379 .video_inputs = 4,
1309 .audio_inputs = 0, 1380 .audio_inputs = 0,
1310 .tuner = -1, 1381 .tuner = -1,
1311 .svhs = 2, 1382 .svhs = 2,
1312 .muxsel = { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS 1383 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
1313 .pll = PLL_28, 1384 .pll = PLL_28,
1314 .no_msp34xx = 1, 1385 .no_msp34xx = 1,
1386 .tuner_type = UNSET,
1387 .tuner_addr = ADDR_UNSET,
1315},{ 1388},{
1316 1389
1317/* ---- card 0x48 ---------------------------------- */ 1390/* ---- card 0x48 ---------------------------------- */
@@ -1329,8 +1402,9 @@ struct tvcard bttv_tvcards[] = {
1329 .no_tda9875 = 1, 1402 .no_tda9875 = 1,
1330 .pll = PLL_28, 1403 .pll = PLL_28,
1331 .tuner_type = 5, 1404 .tuner_type = 5,
1332 .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo 1405 .tuner_addr = ADDR_UNSET,
1333 .has_radio = 1, // Note: not all cards have radio 1406 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
1407 .has_radio = 1, /* Note: not all cards have radio */
1334 .has_remote = 1, 1408 .has_remote = 1,
1335 /* GPIO wiring: 1409 /* GPIO wiring:
1336 GPIO0: A0 hef4052 1410 GPIO0: A0 hef4052
@@ -1338,7 +1412,7 @@ struct tvcard bttv_tvcards[] = {
1338 GPIO3: nEN hef4052 1412 GPIO3: nEN hef4052
1339 GPIO8-15: vrd866b 1413 GPIO8-15: vrd866b
1340 GPIO20,22,23: R30,R29,R28 1414 GPIO20,22,23: R30,R29,R28
1341 */ 1415 */
1342},{ 1416},{
1343 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ 1417 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
1344 /* you must jumper JP5 for the card to work */ 1418 /* you must jumper JP5 for the card to work */
@@ -1352,6 +1426,7 @@ struct tvcard bttv_tvcards[] = {
1352 .audiomux = { 0 }, 1426 .audiomux = { 0 },
1353 .needs_tvaudio = 0, 1427 .needs_tvaudio = 0,
1354 .tuner_type = -1, 1428 .tuner_type = -1,
1429 .tuner_addr = ADDR_UNSET,
1355},{ 1430},{
1356 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ 1431 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
1357 .name = "RemoteVision MX (RV605)", 1432 .name = "RemoteVision MX (RV605)",
@@ -1362,71 +1437,78 @@ struct tvcard bttv_tvcards[] = {
1362 .gpiomask = 0x00, 1437 .gpiomask = 0x00,
1363 .gpiomask2 = 0x07ff, 1438 .gpiomask2 = 0x07ff,
1364 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 1439 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
1365 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, 1440 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
1366 .no_msp34xx = 1, 1441 .no_msp34xx = 1,
1367 .no_tda9875 = 1, 1442 .no_tda9875 = 1,
1368 .tuner_type = -1, 1443 .tuner_type = -1,
1444 .tuner_addr = ADDR_UNSET,
1369 .muxsel_hook = rv605_muxsel, 1445 .muxsel_hook = rv605_muxsel,
1370},{ 1446},{
1371 .name = "Powercolor MTV878/ MTV878R/ MTV878F", 1447 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
1372 .video_inputs = 3, 1448 .video_inputs = 3,
1373 .audio_inputs = 2, 1449 .audio_inputs = 2,
1374 .tuner = 0, 1450 .tuner = 0,
1375 .svhs = 2, 1451 .svhs = 2,
1376 .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset 1452 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
1377 .muxsel = { 2, 1, 1, }, 1453 .muxsel = { 2, 1, 1, },
1378 .audiomux = { 0, 1, 2, 2, 4 }, 1454 .audiomux = { 0, 1, 2, 2, 4 },
1379 .needs_tvaudio = 0, 1455 .needs_tvaudio = 0,
1380 .tuner_type = TUNER_PHILIPS_PAL, 1456 .tuner_type = TUNER_PHILIPS_PAL,
1457 .tuner_addr = ADDR_UNSET,
1381 .pll = PLL_28, 1458 .pll = PLL_28,
1382 .has_radio = 1, 1459 .has_radio = 1,
1383},{ 1460},{
1384 1461
1385/* ---- card 0x4c ---------------------------------- */ 1462/* ---- card 0x4c ---------------------------------- */
1386 /* Masaki Suzuki <masaki@btree.org> */ 1463 /* Masaki Suzuki <masaki@btree.org> */
1387 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", 1464 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
1388 .video_inputs = 3, 1465 .video_inputs = 3,
1389 .audio_inputs = 1, 1466 .audio_inputs = 1,
1390 .tuner = 0, 1467 .tuner = 0,
1391 .svhs = 2, 1468 .svhs = 2,
1392 .gpiomask = 0x140007, 1469 .gpiomask = 0x140007,
1393 .muxsel = { 2, 3, 1, 1 }, 1470 .muxsel = { 2, 3, 1, 1 },
1394 .audiomux = { 0, 1, 2, 3, 4, 0 }, 1471 .audiomux = { 0, 1, 2, 3, 4, 0 },
1395 .tuner_type = TUNER_PHILIPS_NTSC, 1472 .tuner_type = TUNER_PHILIPS_NTSC,
1396 .audio_hook = windvr_audio, 1473 .tuner_addr = ADDR_UNSET,
1397},{ 1474 .audio_hook = windvr_audio,
1398 .name = "GrandTec Multi Capture Card (Bt878)", 1475},{
1399 .video_inputs = 4, 1476 .name = "GrandTec Multi Capture Card (Bt878)",
1400 .audio_inputs = 0, 1477 .video_inputs = 4,
1401 .tuner = -1, 1478 .audio_inputs = 0,
1402 .svhs = -1, 1479 .tuner = -1,
1403 .gpiomask = 0, 1480 .svhs = -1,
1404 .muxsel = { 2, 3, 1, 0 }, 1481 .gpiomask = 0,
1405 .audiomux = { 0 }, 1482 .muxsel = { 2, 3, 1, 0 },
1406 .needs_tvaudio = 0, 1483 .audiomux = { 0 },
1407 .no_msp34xx = 1, 1484 .needs_tvaudio = 0,
1408 .pll = PLL_28, 1485 .no_msp34xx = 1,
1409 .tuner_type = -1, 1486 .pll = PLL_28,
1410},{ 1487 .tuner_type = -1,
1411 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", 1488 .tuner_addr = ADDR_UNSET,
1412 .video_inputs = 4, 1489},{
1413 .audio_inputs = 3, 1490 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
1414 .tuner = 0, 1491 .video_inputs = 4,
1415 .svhs = 2, 1492 .audio_inputs = 3,
1416 .gpiomask = 7, 1493 .tuner = 0,
1417 .muxsel = { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector 1494 .svhs = 2,
1418 .audiomux = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio! 1495 .gpiomask = 7,
1419 // This card lacks external Audio In, so we mute it on Ext. & Int. 1496 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
1420 // The PCB can take a sbx1637/sbx1673, wiring unknown. 1497 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
1421 // This card lacks PCI subsystem ID, sigh. 1498 * This card lacks external Audio In, so we mute it on Ext. & Int.
1422 // audiomux=1: lower volume, 2+3: mute 1499 * The PCB can take a sbx1637/sbx1673, wiring unknown.
1423 // btwincap uses 0x80000/0x80003 1500 * This card lacks PCI subsystem ID, sigh.
1424 .needs_tvaudio = 0, 1501 * audiomux=1: lower volume, 2+3: mute
1425 .no_msp34xx = 1, 1502 * btwincap uses 0x80000/0x80003
1426 .pll = PLL_28, 1503 */
1427 .tuner_type = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and 1504 .needs_tvaudio = 0,
1428 // radio signal strength indicators work fine. 1505 .no_msp34xx = 1,
1429 .has_radio = 1, 1506 .pll = PLL_28,
1507 .tuner_type = 5,
1508 .tuner_addr = ADDR_UNSET,
1509 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
1510 radio signal strength indicators work fine. */
1511 .has_radio = 1,
1430 /* GPIO Info: 1512 /* GPIO Info:
1431 GPIO0,1: HEF4052 A0,A1 1513 GPIO0,1: HEF4052 A0,A1
1432 GPIO2: HEF4052 nENABLE 1514 GPIO2: HEF4052 nENABLE
@@ -1437,25 +1519,27 @@ struct tvcard bttv_tvcards[] = {
1437 GPIO22,23: ?? 1519 GPIO22,23: ??
1438 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ 1520 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
1439},{ 1521},{
1440 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ 1522 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
1441 .name = "DSP Design TCVIDEO", 1523 .name = "DSP Design TCVIDEO",
1442 .video_inputs = 4, 1524 .video_inputs = 4,
1443 .svhs = -1, 1525 .svhs = -1,
1444 .muxsel = { 2, 3, 1, 0}, 1526 .muxsel = { 2, 3, 1, 0},
1445 .pll = PLL_28, 1527 .pll = PLL_28,
1446 .tuner_type = -1, 1528 .tuner_type = -1,
1529 .tuner_addr = ADDR_UNSET,
1447},{ 1530},{
1448 1531
1449 /* ---- card 0x50 ---------------------------------- */ 1532 /* ---- card 0x50 ---------------------------------- */
1450 .name = "Hauppauge WinTV PVR", 1533 .name = "Hauppauge WinTV PVR",
1451 .video_inputs = 4, 1534 .video_inputs = 4,
1452 .audio_inputs = 1, 1535 .audio_inputs = 1,
1453 .tuner = 0, 1536 .tuner = 0,
1454 .svhs = 2, 1537 .svhs = 2,
1455 .muxsel = { 2, 0, 1, 1}, 1538 .muxsel = { 2, 0, 1, 1},
1456 .needs_tvaudio = 1, 1539 .needs_tvaudio = 1,
1457 .pll = PLL_28, 1540 .pll = PLL_28,
1458 .tuner_type = -1, 1541 .tuner_type = -1,
1542 .tuner_addr = ADDR_UNSET,
1459 1543
1460 .gpiomask = 7, 1544 .gpiomask = 7,
1461 .audiomux = {7}, 1545 .audiomux = {7},
@@ -1471,6 +1555,7 @@ struct tvcard bttv_tvcards[] = {
1471 .no_msp34xx = 1, 1555 .no_msp34xx = 1,
1472 .pll = PLL_28, 1556 .pll = PLL_28,
1473 .tuner_type = TUNER_PHILIPS_NTSC_M, 1557 .tuner_type = TUNER_PHILIPS_NTSC_M,
1558 .tuner_addr = ADDR_UNSET,
1474 .audio_hook = gvbctv5pci_audio, 1559 .audio_hook = gvbctv5pci_audio,
1475 .has_radio = 1, 1560 .has_radio = 1,
1476},{ 1561},{
@@ -1482,9 +1567,10 @@ struct tvcard bttv_tvcards[] = {
1482 .muxsel = { 3, 2, 0, 1 }, 1567 .muxsel = { 3, 2, 0, 1 },
1483 .pll = PLL_28, 1568 .pll = PLL_28,
1484 .tuner_type = -1, 1569 .tuner_type = -1,
1485 .no_msp34xx = 1, 1570 .tuner_addr = ADDR_UNSET,
1486 .no_tda9875 = 1, 1571 .no_msp34xx = 1,
1487 .no_tda7432 = 1, 1572 .no_tda9875 = 1,
1573 .no_tda7432 = 1,
1488},{ 1574},{
1489 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ 1575 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
1490 .video_inputs = 3, 1576 .video_inputs = 3,
@@ -1494,9 +1580,10 @@ struct tvcard bttv_tvcards[] = {
1494 .muxsel = { 2, 3, 1 }, 1580 .muxsel = { 2, 3, 1 },
1495 .pll = PLL_28, 1581 .pll = PLL_28,
1496 .tuner_type = -1, 1582 .tuner_type = -1,
1497 .no_msp34xx = 1, 1583 .tuner_addr = ADDR_UNSET,
1498 .no_tda9875 = 1, 1584 .no_msp34xx = 1,
1499 .no_tda7432 = 1, 1585 .no_tda9875 = 1,
1586 .no_tda7432 = 1,
1500},{ 1587},{
1501 1588
1502 /* ---- card 0x54 ---------------------------------- */ 1589 /* ---- card 0x54 ---------------------------------- */
@@ -1508,9 +1595,10 @@ struct tvcard bttv_tvcards[] = {
1508 .muxsel = { 3, 1 }, 1595 .muxsel = { 3, 1 },
1509 .pll = PLL_28, 1596 .pll = PLL_28,
1510 .tuner_type = -1, 1597 .tuner_type = -1,
1511 .no_msp34xx = 1, 1598 .tuner_addr = ADDR_UNSET,
1512 .no_tda9875 = 1, 1599 .no_msp34xx = 1,
1513 .no_tda7432 = 1, 1600 .no_tda9875 = 1,
1601 .no_tda7432 = 1,
1514},{ 1602},{
1515 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ 1603 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1516 .video_inputs = 1, 1604 .video_inputs = 1,
@@ -1520,9 +1608,10 @@ struct tvcard bttv_tvcards[] = {
1520 .muxsel = { 0 }, 1608 .muxsel = { 0 },
1521 .pll = PLL_28, 1609 .pll = PLL_28,
1522 .tuner_type = -1, 1610 .tuner_type = -1,
1523 .no_msp34xx = 1, 1611 .tuner_addr = ADDR_UNSET,
1524 .no_tda9875 = 1, 1612 .no_msp34xx = 1,
1525 .no_tda7432 = 1, 1613 .no_tda9875 = 1,
1614 .no_tda7432 = 1,
1526},{ 1615},{
1527 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ 1616 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1528 .video_inputs = 2, 1617 .video_inputs = 2,
@@ -1532,9 +1621,10 @@ struct tvcard bttv_tvcards[] = {
1532 .muxsel = { 0, 1 }, 1621 .muxsel = { 0, 1 },
1533 .pll = PLL_28, 1622 .pll = PLL_28,
1534 .tuner_type = -1, 1623 .tuner_type = -1,
1535 .no_msp34xx = 1, 1624 .tuner_addr = ADDR_UNSET,
1536 .no_tda9875 = 1, 1625 .no_msp34xx = 1,
1537 .no_tda7432 = 1, 1626 .no_tda9875 = 1,
1627 .no_tda7432 = 1,
1538},{ 1628},{
1539 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ 1629 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1540 .video_inputs = 1, 1630 .video_inputs = 1,
@@ -1543,10 +1633,11 @@ struct tvcard bttv_tvcards[] = {
1543 .svhs = -1, 1633 .svhs = -1,
1544 .muxsel = { 0 }, 1634 .muxsel = { 0 },
1545 .pll = PLL_28, 1635 .pll = PLL_28,
1546 .tuner_type = -1, 1636 .tuner_type = UNSET,
1547 .no_msp34xx = 1, 1637 .tuner_addr = ADDR_UNSET,
1548 .no_tda9875 = 1, 1638 .no_msp34xx = 1,
1549 .no_tda7432 = 1, 1639 .no_tda9875 = 1,
1640 .no_tda7432 = 1,
1550},{ 1641},{
1551 1642
1552 /* ---- card 0x58 ---------------------------------- */ 1643 /* ---- card 0x58 ---------------------------------- */
@@ -1557,10 +1648,11 @@ struct tvcard bttv_tvcards[] = {
1557 .svhs = 1, 1648 .svhs = 1,
1558 .muxsel = { 0, 1 }, 1649 .muxsel = { 0, 1 },
1559 .pll = PLL_28, 1650 .pll = PLL_28,
1560 .tuner_type = -1, 1651 .tuner_type = UNSET,
1561 .no_msp34xx = 1, 1652 .tuner_addr = ADDR_UNSET,
1562 .no_tda9875 = 1, 1653 .no_msp34xx = 1,
1563 .no_tda7432 = 1, 1654 .no_tda9875 = 1,
1655 .no_tda7432 = 1,
1564},{ 1656},{
1565 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1657 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1566 .video_inputs = 2, 1658 .video_inputs = 2,
@@ -1569,10 +1661,11 @@ struct tvcard bttv_tvcards[] = {
1569 .svhs = 1, 1661 .svhs = 1,
1570 .muxsel = { 2, 3 }, 1662 .muxsel = { 2, 3 },
1571 .pll = PLL_28, 1663 .pll = PLL_28,
1572 .tuner_type = -1, 1664 .tuner_type = UNSET,
1573 .no_msp34xx = 1, 1665 .tuner_addr = ADDR_UNSET,
1574 .no_tda9875 = 1, 1666 .no_msp34xx = 1,
1575 .no_tda7432 = 1, 1667 .no_tda9875 = 1,
1668 .no_tda7432 = 1,
1576},{ 1669},{
1577 .name = "Osprey 500", /* 500 */ 1670 .name = "Osprey 500", /* 500 */
1578 .video_inputs = 2, 1671 .video_inputs = 2,
@@ -1582,19 +1675,21 @@ struct tvcard bttv_tvcards[] = {
1582 .muxsel = { 2, 3 }, 1675 .muxsel = { 2, 3 },
1583 .pll = PLL_28, 1676 .pll = PLL_28,
1584 .tuner_type = -1, 1677 .tuner_type = -1,
1585 .no_msp34xx = 1, 1678 .tuner_addr = ADDR_UNSET,
1586 .no_tda9875 = 1, 1679 .no_msp34xx = 1,
1587 .no_tda7432 = 1, 1680 .no_tda9875 = 1,
1681 .no_tda7432 = 1,
1588},{ 1682},{
1589 .name = "Osprey 540", /* 540 */ 1683 .name = "Osprey 540", /* 540 */
1590 .video_inputs = 4, 1684 .video_inputs = 4,
1591 .audio_inputs = 1, 1685 .audio_inputs = 1,
1592 .tuner = -1, 1686 .tuner = -1,
1593 .pll = PLL_28, 1687 .pll = PLL_28,
1594 .tuner_type = -1, 1688 .tuner_type = -1,
1595 .no_msp34xx = 1, 1689 .tuner_addr = ADDR_UNSET,
1596 .no_tda9875 = 1, 1690 .no_msp34xx = 1,
1597 .no_tda7432 = 1, 1691 .no_tda9875 = 1,
1692 .no_tda7432 = 1,
1598},{ 1693},{
1599 1694
1600 /* ---- card 0x5C ---------------------------------- */ 1695 /* ---- card 0x5C ---------------------------------- */
@@ -1605,10 +1700,11 @@ struct tvcard bttv_tvcards[] = {
1605 .svhs = 1, 1700 .svhs = 1,
1606 .muxsel = { 2, 3 }, 1701 .muxsel = { 2, 3 },
1607 .pll = PLL_28, 1702 .pll = PLL_28,
1608 .tuner_type = -1, 1703 .tuner_type = UNSET,
1609 .no_msp34xx = 1, 1704 .tuner_addr = ADDR_UNSET,
1610 .no_tda9875 = 1, 1705 .no_msp34xx = 1,
1611 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ 1706 .no_tda9875 = 1,
1707 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1612},{ 1708},{
1613 /* M G Berberich <berberic@forwiss.uni-passau.de> */ 1709 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1614 .name = "IDS Eagle", 1710 .name = "IDS Eagle",
@@ -1616,6 +1712,7 @@ struct tvcard bttv_tvcards[] = {
1616 .audio_inputs = 0, 1712 .audio_inputs = 0,
1617 .tuner = -1, 1713 .tuner = -1,
1618 .tuner_type = -1, 1714 .tuner_type = -1,
1715 .tuner_addr = ADDR_UNSET,
1619 .svhs = -1, 1716 .svhs = -1,
1620 .gpiomask = 0, 1717 .gpiomask = 0,
1621 .muxsel = { 0, 1, 2, 3 }, 1718 .muxsel = { 0, 1, 2, 3 },
@@ -1630,6 +1727,7 @@ struct tvcard bttv_tvcards[] = {
1630 .svhs = 1, 1727 .svhs = 1,
1631 .tuner = -1, 1728 .tuner = -1,
1632 .tuner_type = -1, 1729 .tuner_type = -1,
1730 .tuner_addr = ADDR_UNSET,
1633 .no_msp34xx = 1, 1731 .no_msp34xx = 1,
1634 .no_tda9875 = 1, 1732 .no_tda9875 = 1,
1635 .no_tda7432 = 1, 1733 .no_tda7432 = 1,
@@ -1641,38 +1739,40 @@ struct tvcard bttv_tvcards[] = {
1641 .no_gpioirq = 1, 1739 .no_gpioirq = 1,
1642 .has_dvb = 1, 1740 .has_dvb = 1,
1643},{ 1741},{
1644 .name = "Formac ProTV II (bt878)", 1742 .name = "Formac ProTV II (bt878)",
1645 .video_inputs = 4, 1743 .video_inputs = 4,
1646 .audio_inputs = 1, 1744 .audio_inputs = 1,
1647 .tuner = 0, 1745 .tuner = 0,
1648 .svhs = 3, 1746 .svhs = 3,
1649 .gpiomask = 2, 1747 .gpiomask = 2,
1650 // TV, Comp1, Composite over SVID con, SVID 1748 /* TV, Comp1, Composite over SVID con, SVID */
1651 .muxsel = { 2, 3, 1, 1}, 1749 .muxsel = { 2, 3, 1, 1},
1652 .audiomux = { 2, 2, 0, 0, 0 }, 1750 .audiomux = { 2, 2, 0, 0, 0 },
1653 .pll = PLL_28, 1751 .pll = PLL_28,
1654 .has_radio = 1, 1752 .has_radio = 1,
1655 .tuner_type = TUNER_PHILIPS_PAL, 1753 .tuner_type = TUNER_PHILIPS_PAL,
1656 /* sound routing: 1754 .tuner_addr = ADDR_UNSET,
1657 GPIO=0x00,0x01,0x03: mute (?) 1755/* sound routing:
1658 0x02: both TV and radio (tuner: FM1216/I) 1756 GPIO=0x00,0x01,0x03: mute (?)
1659 The card has onboard audio connectors labeled "cdrom" and "board", 1757 0x02: both TV and radio (tuner: FM1216/I)
1660 not soldered here, though unknown wiring. 1758 The card has onboard audio connectors labeled "cdrom" and "board",
1661 Card lacks: external audio in, pci subsystem id. 1759 not soldered here, though unknown wiring.
1662 */ 1760 Card lacks: external audio in, pci subsystem id.
1761*/
1663},{ 1762},{
1664 1763
1665 /* ---- card 0x60 ---------------------------------- */ 1764 /* ---- card 0x60 ---------------------------------- */
1666 .name = "MachTV", 1765 .name = "MachTV",
1667 .video_inputs = 3, 1766 .video_inputs = 3,
1668 .audio_inputs = 1, 1767 .audio_inputs = 1,
1669 .tuner = 0, 1768 .tuner = 0,
1670 .svhs = -1, 1769 .svhs = -1,
1671 .gpiomask = 7, 1770 .gpiomask = 7,
1672 .muxsel = { 2, 3, 1, 1}, 1771 .muxsel = { 2, 3, 1, 1},
1673 .audiomux = { 0, 1, 2, 3, 4}, 1772 .audiomux = { 0, 1, 2, 3, 4},
1674 .needs_tvaudio = 1, 1773 .needs_tvaudio = 1,
1675 .tuner_type = 5, 1774 .tuner_type = 5,
1775 .tuner_addr = ADDR_UNSET,
1676 .pll = 1, 1776 .pll = 1,
1677},{ 1777},{
1678 .name = "Euresys Picolo", 1778 .name = "Euresys Picolo",
@@ -1686,6 +1786,8 @@ struct tvcard bttv_tvcards[] = {
1686 .no_tda7432 = 1, 1786 .no_tda7432 = 1,
1687 .muxsel = { 2, 0, 1}, 1787 .muxsel = { 2, 0, 1},
1688 .pll = PLL_28, 1788 .pll = PLL_28,
1789 .tuner_type = UNSET,
1790 .tuner_addr = ADDR_UNSET,
1689},{ 1791},{
1690 /* Luc Van Hoeylandt <luc@e-magic.be> */ 1792 /* Luc Van Hoeylandt <luc@e-magic.be> */
1691 .name = "ProVideo PV150", /* 0x4f */ 1793 .name = "ProVideo PV150", /* 0x4f */
@@ -1699,7 +1801,8 @@ struct tvcard bttv_tvcards[] = {
1699 .needs_tvaudio = 0, 1801 .needs_tvaudio = 0,
1700 .no_msp34xx = 1, 1802 .no_msp34xx = 1,
1701 .pll = PLL_28, 1803 .pll = PLL_28,
1702 .tuner_type = -1, 1804 .tuner_type = UNSET,
1805 .tuner_addr = ADDR_UNSET,
1703},{ 1806},{
1704 /* Hiroshi Takekawa <sian@big.or.jp> */ 1807 /* Hiroshi Takekawa <sian@big.or.jp> */
1705 /* This card lacks subsystem ID */ 1808 /* This card lacks subsystem ID */
@@ -1716,78 +1819,85 @@ struct tvcard bttv_tvcards[] = {
1716 .no_msp34xx = 1, 1819 .no_msp34xx = 1,
1717 .pll = PLL_28, 1820 .pll = PLL_28,
1718 .tuner_type = 2, 1821 .tuner_type = 2,
1822 .tuner_addr = ADDR_UNSET,
1719 .audio_hook = adtvk503_audio, 1823 .audio_hook = adtvk503_audio,
1720},{ 1824},{
1721 1825
1722 /* ---- card 0x64 ---------------------------------- */ 1826 /* ---- card 0x64 ---------------------------------- */
1723 .name = "Hercules Smart TV Stereo", 1827 .name = "Hercules Smart TV Stereo",
1724 .video_inputs = 4, 1828 .video_inputs = 4,
1725 .audio_inputs = 1, 1829 .audio_inputs = 1,
1726 .tuner = 0, 1830 .tuner = 0,
1727 .svhs = 2, 1831 .svhs = 2,
1728 .gpiomask = 0x00, 1832 .gpiomask = 0x00,
1729 .muxsel = { 2, 3, 1, 1 }, 1833 .muxsel = { 2, 3, 1, 1 },
1730 .needs_tvaudio = 1, 1834 .needs_tvaudio = 1,
1731 .no_msp34xx = 1, 1835 .no_msp34xx = 1,
1732 .pll = PLL_28, 1836 .pll = PLL_28,
1733 .tuner_type = 5, 1837 .tuner_type = 5,
1838 .tuner_addr = ADDR_UNSET,
1734 /* Notes: 1839 /* Notes:
1735 - card lacks subsystem ID 1840 - card lacks subsystem ID
1736 - stereo variant w/ daughter board with tda9874a @0xb0 1841 - stereo variant w/ daughter board with tda9874a @0xb0
1737 - Audio Routing: 1842 - Audio Routing:
1738 always from tda9874 independent of GPIO (?) 1843 always from tda9874 independent of GPIO (?)
1739 external line in: unknown 1844 external line in: unknown
1740 - Other chips: em78p156elp @ 0x96 (probably IR remote control) 1845 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
1741 hef4053 (instead 4052) for unknown function 1846 hef4053 (instead 4052) for unknown function
1847 */
1848},{
1849 .name = "Pace TV & Radio Card",
1850 .video_inputs = 4,
1851 .audio_inputs = 1,
1852 .tuner = 0,
1853 .svhs = 2,
1854 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
1855 .gpiomask = 0,
1856 .no_tda9875 = 1,
1857 .no_tda7432 = 1,
1858 .tuner_type = 1,
1859 .tuner_addr = ADDR_UNSET,
1860 .has_radio = 1,
1861 .pll = PLL_28,
1862 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
1863 only internal line out: (4pin header) RGGL
1864 Radio must be decoded by msp3410d (not routed through)*/
1865 /*
1866 .digital_mode = DIGITAL_MODE_CAMERA, todo!
1742 */ 1867 */
1743},{ 1868},{
1744 .name = "Pace TV & Radio Card", 1869 /* Chris Willing <chris@vislab.usyd.edu.au> */
1745 .video_inputs = 4, 1870 .name = "IVC-200",
1746 .audio_inputs = 1, 1871 .video_inputs = 1,
1747 .tuner = 0, 1872 .audio_inputs = 0,
1748 .svhs = 2, 1873 .tuner = -1,
1749 .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector 1874 .tuner_type = -1,
1750 .gpiomask = 0, 1875 .tuner_addr = ADDR_UNSET,
1751 .no_tda9875 = 1, 1876 .svhs = -1,
1752 .no_tda7432 = 1, 1877 .gpiomask = 0xdf,
1753 .tuner_type = 1, 1878 .muxsel = { 2 },
1754 .has_radio = 1, 1879 .pll = PLL_28,
1755 .pll = PLL_28,
1756 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
1757 only internal line out: (4pin header) RGGL
1758 Radio must be decoded by msp3410d (not routed through)*/
1759 // .digital_mode = DIGITAL_MODE_CAMERA, // todo!
1760},{
1761 /* Chris Willing <chris@vislab.usyd.edu.au> */
1762 .name = "IVC-200",
1763 .video_inputs = 1,
1764 .audio_inputs = 0,
1765 .tuner = -1,
1766 .tuner_type = -1,
1767 .svhs = -1,
1768 .gpiomask = 0xdf,
1769 .muxsel = { 2 },
1770 .pll = PLL_28,
1771},{ 1880},{
1772 .name = "Grand X-Guard / Trust 814PCI", 1881 .name = "Grand X-Guard / Trust 814PCI",
1773 .video_inputs = 16, 1882 .video_inputs = 16,
1774 .audio_inputs = 0, 1883 .audio_inputs = 0,
1775 .tuner = -1, 1884 .tuner = -1,
1776 .svhs = -1, 1885 .svhs = -1,
1777 .tuner_type = 4, 1886 .tuner_type = 4,
1778 .gpiomask2 = 0xff, 1887 .tuner_addr = ADDR_UNSET,
1888 .gpiomask2 = 0xff,
1779 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, 1889 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
1780 .muxsel_hook = xguard_muxsel, 1890 .muxsel_hook = xguard_muxsel,
1781 .no_msp34xx = 1, 1891 .no_msp34xx = 1,
1782 .no_tda9875 = 1, 1892 .no_tda9875 = 1,
1783 .no_tda7432 = 1, 1893 .no_tda7432 = 1,
1784 .pll = PLL_28, 1894 .pll = PLL_28,
1785},{ 1895},{
1786 1896
1787 /* ---- card 0x68 ---------------------------------- */ 1897 /* ---- card 0x68 ---------------------------------- */
1788 .name = "Nebula Electronics DigiTV", 1898 .name = "Nebula Electronics DigiTV",
1789 .video_inputs = 1, 1899 .video_inputs = 1,
1790 .tuner = -1, 1900 .tuner = -1,
1791 .svhs = -1, 1901 .svhs = -1,
1792 .muxsel = { 2, 3, 1, 0}, 1902 .muxsel = { 2, 3, 1, 0},
1793 .no_msp34xx = 1, 1903 .no_msp34xx = 1,
@@ -1795,22 +1905,24 @@ struct tvcard bttv_tvcards[] = {
1795 .no_tda7432 = 1, 1905 .no_tda7432 = 1,
1796 .pll = PLL_28, 1906 .pll = PLL_28,
1797 .tuner_type = -1, 1907 .tuner_type = -1,
1908 .tuner_addr = ADDR_UNSET,
1798 .has_dvb = 1, 1909 .has_dvb = 1,
1799 .no_gpioirq = 1, 1910 .no_gpioirq = 1,
1800},{ 1911},{
1801 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 1912 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
1802 .name = "ProVideo PV143", 1913 .name = "ProVideo PV143",
1803 .video_inputs = 4, 1914 .video_inputs = 4,
1804 .audio_inputs = 0, 1915 .audio_inputs = 0,
1805 .tuner = -1, 1916 .tuner = -1,
1806 .svhs = -1, 1917 .svhs = -1,
1807 .gpiomask = 0, 1918 .gpiomask = 0,
1808 .muxsel = { 2, 3, 1, 0 }, 1919 .muxsel = { 2, 3, 1, 0 },
1809 .audiomux = { 0 }, 1920 .audiomux = { 0 },
1810 .needs_tvaudio = 0, 1921 .needs_tvaudio = 0,
1811 .no_msp34xx = 1, 1922 .no_msp34xx = 1,
1812 .pll = PLL_28, 1923 .pll = PLL_28,
1813 .tuner_type = -1, 1924 .tuner_type = -1,
1925 .tuner_addr = ADDR_UNSET,
1814},{ 1926},{
1815 /* M.Klahr@phytec.de */ 1927 /* M.Klahr@phytec.de */
1816 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 1928 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
@@ -1824,6 +1936,7 @@ struct tvcard bttv_tvcards[] = {
1824 .needs_tvaudio = 1, 1936 .needs_tvaudio = 1,
1825 .pll = PLL_28, 1937 .pll = PLL_28,
1826 .tuner_type = -1, 1938 .tuner_type = -1,
1939 .tuner_addr = ADDR_UNSET,
1827},{ 1940},{
1828 .name = "PHYTEC VD-009-X1 Combi (bt878)", 1941 .name = "PHYTEC VD-009-X1 Combi (bt878)",
1829 .video_inputs = 4, 1942 .video_inputs = 4,
@@ -1836,6 +1949,7 @@ struct tvcard bttv_tvcards[] = {
1836 .needs_tvaudio = 1, 1949 .needs_tvaudio = 1,
1837 .pll = PLL_28, 1950 .pll = PLL_28,
1838 .tuner_type = -1, 1951 .tuner_type = -1,
1952 .tuner_addr = ADDR_UNSET,
1839},{ 1953},{
1840 1954
1841 /* ---- card 0x6c ---------------------------------- */ 1955 /* ---- card 0x6c ---------------------------------- */
@@ -1846,13 +1960,14 @@ struct tvcard bttv_tvcards[] = {
1846 .svhs = 9, 1960 .svhs = 9,
1847 .gpiomask = 0x00, 1961 .gpiomask = 0x00,
1848 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1962 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1849 via the upper nibble of muxsel. here: used for 1963 via the upper nibble of muxsel. here: used for
1850 xternal video-mux */ 1964 xternal video-mux */
1851 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, 1965 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
1852 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1966 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1853 .needs_tvaudio = 1, 1967 .needs_tvaudio = 1,
1854 .pll = PLL_28, 1968 .pll = PLL_28,
1855 .tuner_type = -1, 1969 .tuner_type = -1,
1970 .tuner_addr = ADDR_UNSET,
1856},{ 1971},{
1857 .name = "PHYTEC VD-009 Combi (bt878)", 1972 .name = "PHYTEC VD-009 Combi (bt878)",
1858 .video_inputs = 10, 1973 .video_inputs = 10,
@@ -1861,23 +1976,25 @@ struct tvcard bttv_tvcards[] = {
1861 .svhs = 9, 1976 .svhs = 9,
1862 .gpiomask = 0x00, 1977 .gpiomask = 0x00,
1863 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1978 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1864 via the upper nibble of muxsel. here: used for 1979 via the upper nibble of muxsel. here: used for
1865 xternal video-mux */ 1980 xternal video-mux */
1866 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, 1981 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
1867 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1982 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1868 .needs_tvaudio = 1, 1983 .needs_tvaudio = 1,
1869 .pll = PLL_28, 1984 .pll = PLL_28,
1870 .tuner_type = -1, 1985 .tuner_type = -1,
1986 .tuner_addr = ADDR_UNSET,
1871},{ 1987},{
1872 .name = "IVC-100", 1988 .name = "IVC-100",
1873 .video_inputs = 4, 1989 .video_inputs = 4,
1874 .audio_inputs = 0, 1990 .audio_inputs = 0,
1875 .tuner = -1, 1991 .tuner = -1,
1876 .tuner_type = -1, 1992 .tuner_type = -1,
1877 .svhs = -1, 1993 .tuner_addr = ADDR_UNSET,
1878 .gpiomask = 0xdf, 1994 .svhs = -1,
1879 .muxsel = { 2, 3, 1, 0 }, 1995 .gpiomask = 0xdf,
1880 .pll = PLL_28, 1996 .muxsel = { 2, 3, 1, 0 },
1997 .pll = PLL_28,
1881},{ 1998},{
1882 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ 1999 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
1883 .name = "IVC-120G", 2000 .name = "IVC-120G",
@@ -1885,6 +2002,7 @@ struct tvcard bttv_tvcards[] = {
1885 .audio_inputs = 0, /* card has no audio */ 2002 .audio_inputs = 0, /* card has no audio */
1886 .tuner = -1, /* card has no tuner */ 2003 .tuner = -1, /* card has no tuner */
1887 .tuner_type = -1, 2004 .tuner_type = -1,
2005 .tuner_addr = ADDR_UNSET,
1888 .svhs = -1, /* card has no svhs */ 2006 .svhs = -1, /* card has no svhs */
1889 .needs_tvaudio = 0, 2007 .needs_tvaudio = 0,
1890 .no_msp34xx = 1, 2008 .no_msp34xx = 1,
@@ -1892,7 +2010,7 @@ struct tvcard bttv_tvcards[] = {
1892 .no_tda7432 = 1, 2010 .no_tda7432 = 1,
1893 .gpiomask = 0x00, 2011 .gpiomask = 0x00,
1894 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 2012 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1895 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, 2013 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
1896 .muxsel_hook = ivc120_muxsel, 2014 .muxsel_hook = ivc120_muxsel,
1897 .pll = PLL_28, 2015 .pll = PLL_28,
1898},{ 2016},{
@@ -1905,6 +2023,7 @@ struct tvcard bttv_tvcards[] = {
1905 .svhs = 2, 2023 .svhs = 2,
1906 .muxsel = { 2, 3, 1, 0}, 2024 .muxsel = { 2, 3, 1, 0},
1907 .tuner_type = TUNER_PHILIPS_ATSC, 2025 .tuner_type = TUNER_PHILIPS_ATSC,
2026 .tuner_addr = ADDR_UNSET,
1908 .has_dvb = 1, 2027 .has_dvb = 1,
1909},{ 2028},{
1910 .name = "Twinhan DST + clones", 2029 .name = "Twinhan DST + clones",
@@ -1912,19 +2031,21 @@ struct tvcard bttv_tvcards[] = {
1912 .no_tda9875 = 1, 2031 .no_tda9875 = 1,
1913 .no_tda7432 = 1, 2032 .no_tda7432 = 1,
1914 .tuner_type = TUNER_ABSENT, 2033 .tuner_type = TUNER_ABSENT,
2034 .tuner_addr = ADDR_UNSET,
1915 .no_video = 1, 2035 .no_video = 1,
1916 .has_dvb = 1, 2036 .has_dvb = 1,
1917},{ 2037},{
1918 .name = "Winfast VC100", 2038 .name = "Winfast VC100",
1919 .video_inputs = 3, 2039 .video_inputs = 3,
1920 .audio_inputs = 0, 2040 .audio_inputs = 0,
1921 .svhs = 1, 2041 .svhs = 1,
1922 .tuner = -1, // no tuner 2042 .tuner = -1,
1923 .muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector 2043 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
1924 .no_msp34xx = 1, 2044 .no_msp34xx = 1,
1925 .no_tda9875 = 1, 2045 .no_tda9875 = 1,
1926 .no_tda7432 = 1, 2046 .no_tda7432 = 1,
1927 .tuner_type = TUNER_ABSENT, 2047 .tuner_type = TUNER_ABSENT,
2048 .tuner_addr = ADDR_UNSET,
1928 .pll = PLL_28, 2049 .pll = PLL_28,
1929},{ 2050},{
1930 .name = "Teppro TEV-560/InterVision IV-560", 2051 .name = "Teppro TEV-560/InterVision IV-560",
@@ -1937,44 +2058,49 @@ struct tvcard bttv_tvcards[] = {
1937 .audiomux = { 1, 1, 1, 1, 0}, 2058 .audiomux = { 1, 1, 1, 1, 0},
1938 .needs_tvaudio = 1, 2059 .needs_tvaudio = 1,
1939 .tuner_type = TUNER_PHILIPS_PAL, 2060 .tuner_type = TUNER_PHILIPS_PAL,
2061 .tuner_addr = ADDR_UNSET,
1940 .pll = PLL_35, 2062 .pll = PLL_35,
1941},{ 2063},{
1942 2064
1943 /* ---- card 0x74 ---------------------------------- */ 2065 /* ---- card 0x74 ---------------------------------- */
1944 .name = "SIMUS GVC1100", 2066 .name = "SIMUS GVC1100",
1945 .video_inputs = 4, 2067 .video_inputs = 4,
1946 .audio_inputs = 0, 2068 .audio_inputs = 0,
1947 .tuner = -1, 2069 .tuner = -1,
1948 .svhs = -1, 2070 .svhs = -1,
1949 .tuner_type = -1, 2071 .tuner_type = -1,
1950 .pll = PLL_28, 2072 .tuner_addr = ADDR_UNSET,
1951 .muxsel = { 2, 2, 2, 2}, 2073 .pll = PLL_28,
1952 .gpiomask = 0x3F, 2074 .muxsel = { 2, 2, 2, 2},
2075 .gpiomask = 0x3F,
1953 .muxsel_hook = gvc1100_muxsel, 2076 .muxsel_hook = gvc1100_muxsel,
1954},{ 2077},{
1955 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ 2078 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
1956 .name = "NGS NGSTV+", 2079 .name = "NGS NGSTV+",
1957 .video_inputs = 3, 2080 .video_inputs = 3,
1958 .tuner = 0, 2081 .tuner = 0,
1959 .svhs = 2, 2082 .svhs = 2,
1960 .gpiomask = 0x008007, 2083 .gpiomask = 0x008007,
1961 .muxsel = {2, 3, 0, 0}, 2084 .muxsel = {2, 3, 0, 0},
1962 .audiomux = {0, 0, 0, 0, 0x000003, 0}, 2085 .audiomux = {0, 0, 0, 0, 0x000003, 0},
1963 .pll = PLL_28, 2086 .pll = PLL_28,
1964 .tuner_type = TUNER_PHILIPS_PAL, 2087 .tuner_type = TUNER_PHILIPS_PAL,
1965 .has_remote = 1, 2088 .tuner_addr = ADDR_UNSET,
1966},{ 2089 .has_remote = 1,
1967 /* http://linuxmedialabs.com */ 2090},{
1968 .name = "LMLBT4", 2091 /* http://linuxmedialabs.com */
1969 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ 2092 .name = "LMLBT4",
1970 .audio_inputs = 0, 2093 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
1971 .tuner = -1, 2094 .audio_inputs = 0,
1972 .svhs = -1, 2095 .tuner = -1,
1973 .muxsel = { 2, 3, 1, 0 }, 2096 .svhs = -1,
1974 .no_msp34xx = 1, 2097 .muxsel = { 2, 3, 1, 0 },
1975 .no_tda9875 = 1, 2098 .no_msp34xx = 1,
1976 .no_tda7432 = 1, 2099 .no_tda9875 = 1,
1977 .needs_tvaudio = 0, 2100 .no_tda7432 = 1,
2101 .needs_tvaudio = 0,
2102 .tuner_type = -1,
2103 .tuner_addr = ADDR_UNSET,
1978},{ 2104},{
1979 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ 2105 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
1980 .name = "Tekram M205 PRO", 2106 .name = "Tekram M205 PRO",
@@ -1982,6 +2108,7 @@ struct tvcard bttv_tvcards[] = {
1982 .audio_inputs = 1, 2108 .audio_inputs = 1,
1983 .tuner = 0, 2109 .tuner = 0,
1984 .tuner_type = TUNER_PHILIPS_PAL, 2110 .tuner_type = TUNER_PHILIPS_PAL,
2111 .tuner_addr = ADDR_UNSET,
1985 .svhs = 2, 2112 .svhs = 2,
1986 .needs_tvaudio = 0, 2113 .needs_tvaudio = 0,
1987 .gpiomask = 0x68, 2114 .gpiomask = 0x68,
@@ -2004,6 +2131,7 @@ struct tvcard bttv_tvcards[] = {
2004 .needs_tvaudio = 0, 2131 .needs_tvaudio = 0,
2005 .pll = PLL_28, 2132 .pll = PLL_28,
2006 .tuner_type = TUNER_PHILIPS_PAL, 2133 .tuner_type = TUNER_PHILIPS_PAL,
2134 .tuner_addr = ADDR_UNSET,
2007 .has_remote = 1, 2135 .has_remote = 1,
2008 .has_radio = 1, 2136 .has_radio = 1,
2009},{ 2137},{
@@ -2026,6 +2154,8 @@ struct tvcard bttv_tvcards[] = {
2026 .pll = PLL_28, 2154 .pll = PLL_28,
2027 .needs_tvaudio = 0, 2155 .needs_tvaudio = 0,
2028 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ 2156 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2157 .tuner_type = -1,
2158 .tuner_addr = ADDR_UNSET,
2029},{ 2159},{
2030 /* Spirit TV Tuner from http://spiritmodems.com.au */ 2160 /* Spirit TV Tuner from http://spiritmodems.com.au */
2031 /* Stafford Goodsell <surge@goliath.homeunix.org> */ 2161 /* Stafford Goodsell <surge@goliath.homeunix.org> */
@@ -2038,23 +2168,25 @@ struct tvcard bttv_tvcards[] = {
2038 .muxsel = { 2, 1, 1 }, 2168 .muxsel = { 2, 1, 1 },
2039 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, 2169 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2040 .tuner_type = TUNER_TEMIC_PAL, 2170 .tuner_type = TUNER_TEMIC_PAL,
2171 .tuner_addr = ADDR_UNSET,
2041 .no_msp34xx = 1, 2172 .no_msp34xx = 1,
2042 .no_tda9875 = 1, 2173 .no_tda9875 = 1,
2043},{ 2174},{
2044 /* Wolfram Joost <wojo@frokaschwei.de> */ 2175 /* Wolfram Joost <wojo@frokaschwei.de> */
2045 .name = "AVerMedia AVerTV DVB-T 771", 2176 .name = "AVerMedia AVerTV DVB-T 771",
2046 .video_inputs = 2, 2177 .video_inputs = 2,
2047 .svhs = 1, 2178 .svhs = 1,
2048 .tuner = -1, 2179 .tuner = -1,
2049 .tuner_type = TUNER_ABSENT, 2180 .tuner_type = TUNER_ABSENT,
2050 .muxsel = { 3 , 3 }, 2181 .tuner_addr = ADDR_UNSET,
2051 .no_msp34xx = 1, 2182 .muxsel = { 3 , 3 },
2052 .no_tda9875 = 1, 2183 .no_msp34xx = 1,
2053 .no_tda7432 = 1, 2184 .no_tda9875 = 1,
2054 .pll = PLL_28, 2185 .no_tda7432 = 1,
2055 .has_dvb = 1, 2186 .pll = PLL_28,
2056 .no_gpioirq = 1, 2187 .has_dvb = 1,
2057 .has_remote = 1, 2188 .no_gpioirq = 1,
2189 .has_remote = 1,
2058},{ 2190},{
2059 /* ---- card 0x7c ---------------------------------- */ 2191 /* ---- card 0x7c ---------------------------------- */
2060 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ 2192 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
@@ -2069,6 +2201,7 @@ struct tvcard bttv_tvcards[] = {
2069 .no_tda7432 = 1, 2201 .no_tda7432 = 1,
2070 .pll = PLL_28, 2202 .pll = PLL_28,
2071 .tuner_type = -1, 2203 .tuner_type = -1,
2204 .tuner_addr = ADDR_UNSET,
2072 .has_dvb = 1, 2205 .has_dvb = 1,
2073 .no_gpioirq = 1, 2206 .no_gpioirq = 1,
2074 .has_remote = 1, 2207 .has_remote = 1,
@@ -2081,12 +2214,13 @@ struct tvcard bttv_tvcards[] = {
2081 .svhs = -1, 2214 .svhs = -1,
2082 .gpiomask = 0x0, 2215 .gpiomask = 0x0,
2083 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2216 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2084 3, 3, 3, 3, 3, 3, 3, 3 }, 2217 3, 3, 3, 3, 3, 3, 3, 3 },
2085 .muxsel_hook = sigmaSQ_muxsel, 2218 .muxsel_hook = sigmaSQ_muxsel,
2086 .audiomux = { 0 }, 2219 .audiomux = { 0 },
2087 .no_msp34xx = 1, 2220 .no_msp34xx = 1,
2088 .pll = PLL_28, 2221 .pll = PLL_28,
2089 .tuner_type = -1, 2222 .tuner_type = -1,
2223 .tuner_addr = ADDR_UNSET,
2090},{ 2224},{
2091 /* andre.schwarz@matrix-vision.de */ 2225 /* andre.schwarz@matrix-vision.de */
2092 .name = "MATRIX Vision Sigma-SLC", 2226 .name = "MATRIX Vision Sigma-SLC",
@@ -2101,6 +2235,7 @@ struct tvcard bttv_tvcards[] = {
2101 .no_msp34xx = 1, 2235 .no_msp34xx = 1,
2102 .pll = PLL_28, 2236 .pll = PLL_28,
2103 .tuner_type = -1, 2237 .tuner_type = -1,
2238 .tuner_addr = ADDR_UNSET,
2104},{ 2239},{
2105 /* BTTV_APAC_VIEWCOMP */ 2240 /* BTTV_APAC_VIEWCOMP */
2106 /* Attila Kondoros <attila.kondoros@chello.hu> */ 2241 /* Attila Kondoros <attila.kondoros@chello.hu> */
@@ -2116,13 +2251,14 @@ struct tvcard bttv_tvcards[] = {
2116 .needs_tvaudio = 0, 2251 .needs_tvaudio = 0,
2117 .pll = PLL_28, 2252 .pll = PLL_28,
2118 .tuner_type = TUNER_PHILIPS_PAL, 2253 .tuner_type = TUNER_PHILIPS_PAL,
2254 .tuner_addr = ADDR_UNSET,
2119 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ 2255 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2120 .has_radio = 1, /* not every card has radio */ 2256 .has_radio = 1, /* not every card has radio */
2121},{ 2257},{
2122 2258
2123 /* ---- card 0x80 ---------------------------------- */ 2259 /* ---- card 0x80 ---------------------------------- */
2124 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ 2260 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2125 .name = "DVICO FusionHDTV DVB-T Lite", 2261 .name = "DViCO FusionHDTV DVB-T Lite",
2126 .tuner = -1, 2262 .tuner = -1,
2127 .no_msp34xx = 1, 2263 .no_msp34xx = 1,
2128 .no_tda9875 = 1, 2264 .no_tda9875 = 1,
@@ -2131,6 +2267,7 @@ struct tvcard bttv_tvcards[] = {
2131 .no_video = 1, 2267 .no_video = 1,
2132 .has_dvb = 1, 2268 .has_dvb = 1,
2133 .tuner_type = -1, 2269 .tuner_type = -1,
2270 .tuner_addr = ADDR_UNSET,
2134},{ 2271},{
2135 /* Steven <photon38@pchome.com.tw> */ 2272 /* Steven <photon38@pchome.com.tw> */
2136 .name = "V-Gear MyVCD", 2273 .name = "V-Gear MyVCD",
@@ -2144,62 +2281,65 @@ struct tvcard bttv_tvcards[] = {
2144 .no_msp34xx = 1, 2281 .no_msp34xx = 1,
2145 .pll = PLL_28, 2282 .pll = PLL_28,
2146 .tuner_type = TUNER_PHILIPS_NTSC_M, 2283 .tuner_type = TUNER_PHILIPS_NTSC_M,
2284 .tuner_addr = ADDR_UNSET,
2147 .has_radio = 0, 2285 .has_radio = 0,
2148 // .has_remote = 1,
2149},{ 2286},{
2150 /* Rick C <cryptdragoon@gmail.com> */ 2287 /* Rick C <cryptdragoon@gmail.com> */
2151 .name = "Super TV Tuner", 2288 .name = "Super TV Tuner",
2152 .video_inputs = 4, 2289 .video_inputs = 4,
2153 .audio_inputs = 1, 2290 .audio_inputs = 1,
2154 .tuner = 0, 2291 .tuner = 0,
2155 .svhs = 2, 2292 .svhs = 2,
2156 .muxsel = { 2, 3, 1, 0}, 2293 .muxsel = { 2, 3, 1, 0},
2157 .tuner_type = TUNER_PHILIPS_NTSC, 2294 .tuner_type = TUNER_PHILIPS_NTSC,
2158 .gpiomask = 0x008007, 2295 .tuner_addr = ADDR_UNSET,
2159 .audiomux = { 0, 0x000001,0,0, 0}, 2296 .gpiomask = 0x008007,
2160 .needs_tvaudio = 1, 2297 .audiomux = { 0, 0x000001,0,0, 0},
2161 .has_radio = 1, 2298 .needs_tvaudio = 1,
2162},{ 2299 .has_radio = 1,
2163 /* Chris Fanning <video4linux@haydon.net> */ 2300},{
2164 .name = "Tibet Systems 'Progress DVR' CS16", 2301 /* Chris Fanning <video4linux@haydon.net> */
2165 .video_inputs = 16, 2302 .name = "Tibet Systems 'Progress DVR' CS16",
2166 .audio_inputs = 0, 2303 .video_inputs = 16,
2167 .tuner = -1, 2304 .audio_inputs = 0,
2168 .svhs = -1, 2305 .tuner = -1,
2169 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 2306 .svhs = -1,
2170 .pll = PLL_28, 2307 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2171 .no_msp34xx = 1, 2308 .pll = PLL_28,
2172 .no_tda9875 = 1, 2309 .no_msp34xx = 1,
2173 .no_tda7432 = 1, 2310 .no_tda9875 = 1,
2174 .tuner_type = -1, 2311 .no_tda7432 = 1,
2175 .muxsel_hook = tibetCS16_muxsel, 2312 .tuner_type = -1,
2313 .tuner_addr = ADDR_UNSET,
2314 .muxsel_hook = tibetCS16_muxsel,
2176}, 2315},
2177{ 2316{
2178 /* Bill Brack <wbrack@mmm.com.hk> */ 2317 /* Bill Brack <wbrack@mmm.com.hk> */
2179 /* 2318 /*
2180 * Note that, because of the card's wiring, the "master" 2319 * Note that, because of the card's wiring, the "master"
2181 * BT878A chip (i.e. the one which controls the analog switch 2320 * BT878A chip (i.e. the one which controls the analog switch
2182 * and must use this card type) is the 2nd one detected. The 2321 * and must use this card type) is the 2nd one detected. The
2183 * other 3 chips should use card type 0x85, whose description 2322 * other 3 chips should use card type 0x85, whose description
2184 * follows this one. There is a EEPROM on the card (which is 2323 * follows this one. There is a EEPROM on the card (which is
2185 * connected to the I2C of one of those other chips), but is 2324 * connected to the I2C of one of those other chips), but is
2186 * not currently handled. There is also a facility for a 2325 * not currently handled. There is also a facility for a
2187 * "monitor", which is also not currently implemented. 2326 * "monitor", which is also not currently implemented.
2188 */ 2327 */
2189 .name = "Kodicom 4400R (master)", 2328 .name = "Kodicom 4400R (master)",
2190 .video_inputs = 16, 2329 .video_inputs = 16,
2191 .audio_inputs = 0, 2330 .audio_inputs = 0,
2192 .tuner = -1, 2331 .tuner = -1,
2193 .tuner_type = -1, 2332 .tuner_type = -1,
2333 .tuner_addr = ADDR_UNSET,
2194 .svhs = -1, 2334 .svhs = -1,
2195 /* GPIO bits 0-9 used for analog switch: 2335 /* GPIO bits 0-9 used for analog switch:
2196 * 00 - 03: camera selector 2336 * 00 - 03: camera selector
2197 * 04 - 06: channel (controller) selector 2337 * 04 - 06: channel (controller) selector
2198 * 07: data (1->on, 0->off) 2338 * 07: data (1->on, 0->off)
2199 * 08: strobe 2339 * 08: strobe
2200 * 09: reset 2340 * 09: reset
2201 * bit 16 is input from sync separator for the channel 2341 * bit 16 is input from sync separator for the channel
2202 */ 2342 */
2203 .gpiomask = 0x0003ff, 2343 .gpiomask = 0x0003ff,
2204 .no_gpioirq = 1, 2344 .no_gpioirq = 1,
2205 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 2345 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
@@ -2212,15 +2352,16 @@ struct tvcard bttv_tvcards[] = {
2212{ 2352{
2213 /* Bill Brack <wbrack@mmm.com.hk> */ 2353 /* Bill Brack <wbrack@mmm.com.hk> */
2214 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the 2354 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2215 * one which controls the analog switch, and must use the card type) 2355 * one which controls the analog switch, and must use the card type)
2216 * is the 2nd one detected. The other 3 chips should use this card 2356 * is the 2nd one detected. The other 3 chips should use this card
2217 * type 2357 * type
2218 */ 2358 */
2219 .name = "Kodicom 4400R (slave)", 2359 .name = "Kodicom 4400R (slave)",
2220 .video_inputs = 16, 2360 .video_inputs = 16,
2221 .audio_inputs = 0, 2361 .audio_inputs = 0,
2222 .tuner = -1, 2362 .tuner = -1,
2223 .tuner_type = -1, 2363 .tuner_type = -1,
2364 .tuner_addr = ADDR_UNSET,
2224 .svhs = -1, 2365 .svhs = -1,
2225 .gpiomask = 0x010000, 2366 .gpiomask = 0x010000,
2226 .no_gpioirq = 1, 2367 .no_gpioirq = 1,
@@ -2232,18 +2373,51 @@ struct tvcard bttv_tvcards[] = {
2232 .muxsel_hook = kodicom4400r_muxsel, 2373 .muxsel_hook = kodicom4400r_muxsel,
2233}, 2374},
2234{ 2375{
2235 /* ---- card 0x85---------------------------------- */ 2376 /* ---- card 0x86---------------------------------- */
2236 /* Michael Henson <mhenson@clarityvi.com> */ 2377 /* Michael Henson <mhenson@clarityvi.com> */
2237 /* Adlink RTV24 with special unlock codes */ 2378 /* Adlink RTV24 with special unlock codes */
2238 .name = "Adlink RTV24", 2379 .name = "Adlink RTV24",
2239 .video_inputs = 4, 2380 .video_inputs = 4,
2240 .audio_inputs = 1, 2381 .audio_inputs = 1,
2241 .tuner = 0, 2382 .tuner = 0,
2242 .svhs = 2, 2383 .svhs = 2,
2243 .muxsel = { 2, 3, 1, 0}, 2384 .muxsel = { 2, 3, 1, 0},
2244 .tuner_type = -1, 2385 .tuner_type = -1,
2245 .pll = PLL_28, 2386 .tuner_addr = ADDR_UNSET,
2246 2387 .pll = PLL_28,
2388},
2389{
2390 /* ---- card 0x87---------------------------------- */
2391 /* Michael Krufky <mkrufky@m1k.net> */
2392 .name = "DViCO FusionHDTV 5 Lite",
2393 .tuner = 0,
2394 .tuner_type = TUNER_LG_TDVS_H062F,
2395 .tuner_addr = ADDR_UNSET,
2396 .video_inputs = 2,
2397 .audio_inputs = 1,
2398 .svhs = 2,
2399 .muxsel = { 2, 3 },
2400 .gpiomask = 0x00e00007,
2401 .audiomux = { 0x00400005, 0, 0, 0, 0, 0 },
2402 .no_msp34xx = 1,
2403 .no_tda9875 = 1,
2404 .no_tda7432 = 1,
2405},{
2406 /* ---- card 0x88---------------------------------- */
2407 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2408 .name = "Acorp Y878F",
2409 .video_inputs = 3,
2410 .audio_inputs = 1,
2411 .tuner = 0,
2412 .svhs = 2,
2413 .gpiomask = 0x01fe00,
2414 .muxsel = { 2, 3, 1, 1},
2415 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
2416 .needs_tvaudio = 1,
2417 .pll = PLL_28,
2418 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2419 .tuner_addr = 0xc1 >>1,
2420 .has_radio = 1,
2247}}; 2421}};
2248 2422
2249static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2423static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2355,32 +2529,32 @@ static void flyvideo_gpio(struct bttv *btv)
2355 int tuner=-1,ttype; 2529 int tuner=-1,ttype;
2356 2530
2357 gpio_inout(0xffffff, 0); 2531 gpio_inout(0xffffff, 0);
2358 udelay(8); // without this we would see the 0x1800 mask 2532 udelay(8); /* without this we would see the 0x1800 mask */
2359 gpio = gpio_read(); 2533 gpio = gpio_read();
2360 /* FIXME: must restore OUR_EN ??? */ 2534 /* FIXME: must restore OUR_EN ??? */
2361 2535
2362 // all cards provide GPIO info, some have an additional eeprom 2536 /* all cards provide GPIO info, some have an additional eeprom
2363 // LR50: GPIO coding can be found lower right CP1 .. CP9 2537 * LR50: GPIO coding can be found lower right CP1 .. CP9
2364 // CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1. 2538 * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
2365 // GPIO14-12: n.c. 2539 * GPIO14-12: n.c.
2366 // LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878) 2540 * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
2367
2368 // lowest 3 bytes are remote control codes (no handshake needed)
2369 // xxxFFF: No remote control chip soldered
2370 // xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
2371 // Note: Some bits are Audio_Mask !
2372 2541
2542 * lowest 3 bytes are remote control codes (no handshake needed)
2543 * xxxFFF: No remote control chip soldered
2544 * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
2545 * Note: Some bits are Audio_Mask !
2546 */
2373 ttype=(gpio&0x0f0000)>>16; 2547 ttype=(gpio&0x0f0000)>>16;
2374 switch(ttype) { 2548 switch(ttype) {
2375 case 0x0: tuner=2; // NTSC, e.g. TPI8NSR11P 2549 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
2376 break; 2550 break;
2377 case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P 2551 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
2378 break; 2552 break;
2379 case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 2553 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
2380 break; 2554 break;
2381 case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P 2555 case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */
2382 break; 2556 break;
2383 case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF 2557 case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
2384 break; 2558 break;
2385 default: 2559 default:
2386 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr); 2560 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
@@ -2388,15 +2562,16 @@ static void flyvideo_gpio(struct bttv *btv)
2388 2562
2389 has_remote = gpio & 0x800000; 2563 has_remote = gpio & 0x800000;
2390 has_radio = gpio & 0x400000; 2564 has_radio = gpio & 0x400000;
2391 // unknown 0x200000; 2565 /* unknown 0x200000;
2392 // unknown2 0x100000; 2566 * unknown2 0x100000; */
2393 is_capture_only = !(gpio & 0x008000); //GPIO15 2567 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
2394 has_tda9820_tda9821 = !(gpio & 0x004000); 2568 has_tda9820_tda9821 = !(gpio & 0x004000);
2395 is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only) 2569 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
2396 // gpio & 0x001000 // output bit for audio routing 2570 /*
2571 * gpio & 0x001000 output bit for audio routing */
2397 2572
2398 if(is_capture_only) 2573 if(is_capture_only)
2399 tuner=4; // No tuner present 2574 tuner=4; /* No tuner present */
2400 2575
2401 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", 2576 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
2402 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); 2577 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
@@ -2404,15 +2579,15 @@ static void flyvideo_gpio(struct bttv *btv)
2404 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", 2579 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
2405 is_capture_only?"yes":"no "); 2580 is_capture_only?"yes":"no ");
2406 2581
2407 if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through 2582 if(tuner!= -1) /* only set if known tuner autodetected, else let insmod option through */
2408 btv->tuner_type = tuner; 2583 btv->tuner_type = tuner;
2409 btv->has_radio = has_radio; 2584 btv->has_radio = has_radio;
2410 2585
2411 // LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80 2586 /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
2412 // LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00 2587 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
2413 // Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute 2588 * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
2414 if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio; 2589 if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
2415 //todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; 2590 /* todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; */
2416} 2591}
2417 2592
2418static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1, 2593static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
@@ -2633,6 +2808,8 @@ void __devinit bttv_init_card1(struct bttv *btv)
2633void __devinit bttv_init_card2(struct bttv *btv) 2808void __devinit bttv_init_card2(struct bttv *btv)
2634{ 2809{
2635 int tda9887; 2810 int tda9887;
2811 int addr=ADDR_UNSET;
2812
2636 btv->tuner_type = -1; 2813 btv->tuner_type = -1;
2637 2814
2638 if (BTTV_UNKNOWN == btv->c.type) { 2815 if (BTTV_UNKNOWN == btv->c.type) {
@@ -2773,9 +2950,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
2773 btv->pll.pll_current = -1; 2950 btv->pll.pll_current = -1;
2774 2951
2775 /* tuner configuration (from card list / autodetect / insmod option) */ 2952 /* tuner configuration (from card list / autodetect / insmod option) */
2776 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 2953 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
2954 addr = bttv_tvcards[btv->c.type].tuner_addr;
2955
2956 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2777 if(UNSET == btv->tuner_type) 2957 if(UNSET == btv->tuner_type)
2778 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; 2958 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2779 if (UNSET != tuner[btv->c.nr]) 2959 if (UNSET != tuner[btv->c.nr])
2780 btv->tuner_type = tuner[btv->c.nr]; 2960 btv->tuner_type = tuner[btv->c.nr];
2781 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); 2961 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
@@ -2787,7 +2967,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
2787 2967
2788 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 2968 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
2789 tun_setup.type = btv->tuner_type; 2969 tun_setup.type = btv->tuner_type;
2790 tun_setup.addr = ADDR_UNSET; 2970 tun_setup.addr = addr;
2791 2971
2792 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 2972 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
2793 } 2973 }
@@ -2880,7 +3060,7 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
2880{ 3060{
2881 struct tveeprom tv; 3061 struct tveeprom tv;
2882 3062
2883 tveeprom_hauppauge_analog(&tv, eeprom_data); 3063 tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
2884 btv->tuner_type = tv.tuner_type; 3064 btv->tuner_type = tv.tuner_type;
2885 btv->has_radio = tv.has_radio; 3065 btv->has_radio = tv.has_radio;
2886} 3066}
@@ -2902,7 +3082,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
2902 btv->mbox_csel = 1 << 10; 3082 btv->mbox_csel = 1 << 10;
2903 3083
2904 freq=88000/62.5; 3084 freq=88000/62.5;
2905 tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8 3085 tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */
2906 if (0x1ed8 == tea5757_read(btv)) { 3086 if (0x1ed8 == tea5757_read(btv)) {
2907 printk("bttv%d: Terratec Active Radio Upgrade found.\n", 3087 printk("bttv%d: Terratec Active Radio Upgrade found.\n",
2908 btv->c.nr); 3088 btv->c.nr);
@@ -3073,7 +3253,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3073 case 0x0060: 3253 case 0x0060:
3074 case 0x0070: 3254 case 0x0070:
3075 btv->c.type = BTTV_OSPREY2x0; 3255 btv->c.type = BTTV_OSPREY2x0;
3076 //enable output on select control lines 3256 /* enable output on select control lines */
3077 gpio_inout(0xffffff,0x000303); 3257 gpio_inout(0xffffff,0x000303);
3078 break; 3258 break;
3079 default: 3259 default:
@@ -3105,7 +3285,7 @@ static int tuner_1_table[] = {
3105 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, 3285 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3106 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3286 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3107 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3287 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3108 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM 3288 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3109 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; 3289 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3110 3290
3111static void __devinit avermedia_eeprom(struct bttv *btv) 3291static void __devinit avermedia_eeprom(struct bttv *btv)
@@ -3126,7 +3306,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
3126 3306
3127 if (tuner_make == 4) 3307 if (tuner_make == 4)
3128 if(tuner_format == 0x09) 3308 if(tuner_format == 0x09)
3129 tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P 3309 tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
3130 3310
3131 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", 3311 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
3132 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]); 3312 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
@@ -3143,7 +3323,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
3143/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */ 3323/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
3144void bttv_tda9880_setnorm(struct bttv *btv, int norm) 3324void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3145{ 3325{
3146 // fix up our card entry 3326 /* fix up our card entry */
3147 if(norm==VIDEO_MODE_NTSC) { 3327 if(norm==VIDEO_MODE_NTSC) {
3148 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; 3328 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
3149 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; 3329 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
@@ -3154,7 +3334,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3154 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; 3334 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
3155 dprintk("bttv_tda9880_setnorm to PAL\n"); 3335 dprintk("bttv_tda9880_setnorm to PAL\n");
3156 } 3336 }
3157 // set GPIO according 3337 /* set GPIO according */
3158 gpio_bits(bttv_tvcards[btv->c.type].gpiomask, 3338 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
3159 bttv_tvcards[btv->c.type].audiomux[btv->audio]); 3339 bttv_tvcards[btv->c.type].audiomux[btv->audio]);
3160} 3340}
@@ -3447,7 +3627,7 @@ static int tea5757_read(struct bttv *btv)
3447 udelay(10); 3627 udelay(10);
3448 timeout= jiffies + HZ; 3628 timeout= jiffies + HZ;
3449 3629
3450 // wait for DATA line to go low; error if it doesn't 3630 /* wait for DATA line to go low; error if it doesn't */
3451 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout)) 3631 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
3452 schedule(); 3632 schedule();
3453 if (bus_in(btv,btv->mbox_data)) { 3633 if (bus_in(btv,btv->mbox_data)) {
@@ -3574,8 +3754,8 @@ gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
3574 con = 0x300; 3754 con = 0x300;
3575 if (v->mode & VIDEO_SOUND_STEREO) 3755 if (v->mode & VIDEO_SOUND_STEREO)
3576 con = 0x200; 3756 con = 0x200;
3577// if (v->mode & VIDEO_SOUND_MONO) 3757/* if (v->mode & VIDEO_SOUND_MONO)
3578// con = 0x100; 3758 * con = 0x100; */
3579 gpio_bits(0x300, con); 3759 gpio_bits(0x300, con);
3580 } else { 3760 } else {
3581 v->mode = VIDEO_SOUND_STEREO | 3761 v->mode = VIDEO_SOUND_STEREO |
@@ -3718,7 +3898,7 @@ lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3718 } 3898 }
3719} 3899}
3720 3900
3721// TDA9821 on TerraTV+ Bt848, Bt878 3901/* TDA9821 on TerraTV+ Bt848, Bt878 */
3722static void 3902static void
3723terratv_audio(struct bttv *btv, struct video_audio *v, int set) 3903terratv_audio(struct bttv *btv, struct video_audio *v, int set)
3724{ 3904{
@@ -3818,7 +3998,7 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
3818 } 3998 }
3819 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2)) 3999 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
3820 || (v->mode & VIDEO_SOUND_STEREO)) { 4000 || (v->mode & VIDEO_SOUND_STEREO)) {
3821 val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ... 4001 val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
3822 } 4002 }
3823 if (val != 0xffff) { 4003 if (val != 0xffff) {
3824 gpio_bits(0x1800, val); 4004 gpio_bits(0x1800, val);
@@ -3869,10 +4049,10 @@ adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
3869{ 4049{
3870 unsigned int con = 0xffffff; 4050 unsigned int con = 0xffffff;
3871 4051
3872 //btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); 4052 /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
3873 4053
3874 if (set) { 4054 if (set) {
3875 //btor(***, BT848_GPIO_OUT_EN); 4055 /* btor(***, BT848_GPIO_OUT_EN); */
3876 if (v->mode & VIDEO_SOUND_LANG1) 4056 if (v->mode & VIDEO_SOUND_LANG1)
3877 con = 0x00000000; 4057 con = 0x00000000;
3878 if (v->mode & VIDEO_SOUND_LANG2) 4058 if (v->mode & VIDEO_SOUND_LANG2)
@@ -4079,14 +4259,14 @@ static void kodicom4400r_init(struct bttv *btv)
4079 master[btv->c.nr+2] = btv; 4259 master[btv->c.nr+2] = btv;
4080} 4260}
4081 4261
4082// The Grandtec X-Guard framegrabber card uses two Dual 4-channel 4262/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel
4083// video multiplexers to provide up to 16 video inputs. These 4263 * video multiplexers to provide up to 16 video inputs. These
4084// multiplexers are controlled by the lower 8 GPIO pins of the 4264 * multiplexers are controlled by the lower 8 GPIO pins of the
4085// bt878. The multiplexers probably Pericom PI5V331Q or similar. 4265 * bt878. The multiplexers probably Pericom PI5V331Q or similar.
4086
4087// xxx0 is pin xxx of multiplexer U5,
4088// yyy1 is pin yyy of multiplexer U2
4089 4266
4267 * xxx0 is pin xxx of multiplexer U5,
4268 * yyy1 is pin yyy of multiplexer U2
4269 */
4090#define ENA0 0x01 4270#define ENA0 0x01
4091#define ENB0 0x02 4271#define ENB0 0x02
4092#define ENA1 0x04 4272#define ENA1 0x04
@@ -4157,14 +4337,14 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
4157 4337
4158static void ivc120_muxsel(struct bttv *btv, unsigned int input) 4338static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4159{ 4339{
4160 // Simple maths 4340 /* Simple maths */
4161 int key = input % 4; 4341 int key = input % 4;
4162 int matrix = input / 4; 4342 int matrix = input / 4;
4163 4343
4164 dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n", 4344 dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
4165 btv->c.nr, input, matrix, key); 4345 btv->c.nr, input, matrix, key);
4166 4346
4167 // Handles the input selection on the TDA8540's 4347 /* Handles the input selection on the TDA8540's */
4168 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00, 4348 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
4169 ((matrix == 3) ? (key | key << 2) : 0x00), 1); 4349 ((matrix == 3) ? (key | key << 2) : 0x00), 1);
4170 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00, 4350 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
@@ -4174,17 +4354,17 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4174 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00, 4354 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
4175 ((matrix == 2) ? (key | key << 2) : 0x00), 1); 4355 ((matrix == 2) ? (key | key << 2) : 0x00), 1);
4176 4356
4177 // Handles the output enables on the TDA8540's 4357 /* Handles the output enables on the TDA8540's */
4178 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02, 4358 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
4179 ((matrix == 3) ? 0x03 : 0x00), 1); // 13 - 16 4359 ((matrix == 3) ? 0x03 : 0x00), 1); /* 13 - 16 */
4180 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02, 4360 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
4181 ((matrix == 0) ? 0x03 : 0x00), 1); // 1-4 4361 ((matrix == 0) ? 0x03 : 0x00), 1); /* 1-4 */
4182 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02, 4362 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
4183 ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8 4363 ((matrix == 1) ? 0x03 : 0x00), 1); /* 5-8 */
4184 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02, 4364 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
4185 ((matrix == 2) ? 0x03 : 0x00), 1); // 9-12 4365 ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
4186 4366
4187 // Selects MUX0 for input on the 878 4367 /* Selects MUX0 for input on the 878 */
4188 btaor((0)<<5, ~(3<<5), BT848_IFORM); 4368 btaor((0)<<5, ~(3<<5), BT848_IFORM);
4189} 4369}
4190 4370
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 087efb4dea09..a564321db2f0 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $
3 2
4 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
5 4
@@ -42,6 +41,9 @@
42 41
43#include "bttvp.h" 42#include "bttvp.h"
44 43
44#include "rds.h"
45
46
45unsigned int bttv_num; /* number of Bt848s in use */ 47unsigned int bttv_num; /* number of Bt848s in use */
46struct bttv bttvs[BTTV_MAX]; 48struct bttv bttvs[BTTV_MAX];
47 49
@@ -3128,15 +3130,12 @@ static int radio_open(struct inode *inode, struct file *file)
3128 3130
3129 dprintk("bttv%d: open called (radio)\n",btv->c.nr); 3131 dprintk("bttv%d: open called (radio)\n",btv->c.nr);
3130 down(&btv->lock); 3132 down(&btv->lock);
3131 if (btv->radio_user) { 3133
3132 up(&btv->lock);
3133 return -EBUSY;
3134 }
3135 btv->radio_user++; 3134 btv->radio_user++;
3135
3136 file->private_data = btv; 3136 file->private_data = btv;
3137 3137
3138 i2c_vidiocschan(btv); 3138 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
3139 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
3140 audio_mux(btv,AUDIO_RADIO); 3139 audio_mux(btv,AUDIO_RADIO);
3141 3140
3142 up(&btv->lock); 3141 up(&btv->lock);
@@ -3145,9 +3144,13 @@ static int radio_open(struct inode *inode, struct file *file)
3145 3144
3146static int radio_release(struct inode *inode, struct file *file) 3145static int radio_release(struct inode *inode, struct file *file)
3147{ 3146{
3148 struct bttv *btv = file->private_data; 3147 struct bttv *btv = file->private_data;
3148 struct rds_command cmd;
3149 3149
3150 btv->radio_user--; 3150 btv->radio_user--;
3151
3152 bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
3153
3151 return 0; 3154 return 0;
3152} 3155}
3153 3156
@@ -3203,13 +3206,42 @@ static int radio_ioctl(struct inode *inode, struct file *file,
3203 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl); 3206 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
3204} 3207}
3205 3208
3209static ssize_t radio_read(struct file *file, char __user *data,
3210 size_t count, loff_t *ppos)
3211{
3212 struct bttv *btv = file->private_data;
3213 struct rds_command cmd;
3214 cmd.block_count = count/3;
3215 cmd.buffer = data;
3216 cmd.instance = file;
3217 cmd.result = -ENODEV;
3218
3219 bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
3220
3221 return cmd.result;
3222}
3223
3224static unsigned int radio_poll(struct file *file, poll_table *wait)
3225{
3226 struct bttv *btv = file->private_data;
3227 struct rds_command cmd;
3228 cmd.instance = file;
3229 cmd.event_list = wait;
3230 cmd.result = -ENODEV;
3231 bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
3232
3233 return cmd.result;
3234}
3235
3206static struct file_operations radio_fops = 3236static struct file_operations radio_fops =
3207{ 3237{
3208 .owner = THIS_MODULE, 3238 .owner = THIS_MODULE,
3209 .open = radio_open, 3239 .open = radio_open,
3240 .read = radio_read,
3210 .release = radio_release, 3241 .release = radio_release,
3211 .ioctl = radio_ioctl, 3242 .ioctl = radio_ioctl,
3212 .llseek = no_llseek, 3243 .llseek = no_llseek,
3244 .poll = radio_poll,
3213}; 3245};
3214 3246
3215static struct video_device radio_template = 3247static struct video_device radio_template =
@@ -4047,6 +4079,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4047 struct bttv_buffer_set idle; 4079 struct bttv_buffer_set idle;
4048 unsigned long flags; 4080 unsigned long flags;
4049 4081
4082 dprintk("bttv%d: suspend %d\n", btv->c.nr, state.event);
4050 4083
4051 /* stop dma + irqs */ 4084 /* stop dma + irqs */
4052 spin_lock_irqsave(&btv->s_lock,flags); 4085 spin_lock_irqsave(&btv->s_lock,flags);
@@ -4079,15 +4112,29 @@ static int bttv_resume(struct pci_dev *pci_dev)
4079{ 4112{
4080 struct bttv *btv = pci_get_drvdata(pci_dev); 4113 struct bttv *btv = pci_get_drvdata(pci_dev);
4081 unsigned long flags; 4114 unsigned long flags;
4115 int err;
4082 4116
4083 dprintk("bttv%d: resume\n", btv->c.nr); 4117 dprintk("bttv%d: resume\n", btv->c.nr);
4084 4118
4085 /* restore pci state */ 4119 /* restore pci state */
4086 if (btv->state.disabled) { 4120 if (btv->state.disabled) {
4087 pci_enable_device(pci_dev); 4121 err=pci_enable_device(pci_dev);
4122 if (err) {
4123 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4124 btv->c.nr);
4125 return err;
4126 }
4088 btv->state.disabled = 0; 4127 btv->state.disabled = 0;
4089 } 4128 }
4090 pci_set_power_state(pci_dev, PCI_D0); 4129 err=pci_set_power_state(pci_dev, PCI_D0);
4130 if (err) {
4131 pci_disable_device(pci_dev);
4132 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4133 btv->c.nr);
4134 btv->state.disabled = 1;
4135 return err;
4136 }
4137
4091 pci_restore_state(pci_dev); 4138 pci_restore_state(pci_dev);
4092 4139
4093 /* restore bt878 state */ 4140 /* restore bt878 state */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 77320cdf205f..6b280c03e398 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-gpio.c,v 1.7 2005/02/16 12:14:10 kraxel Exp $
3 2
4 bttv-gpio.c -- gpio sub drivers 3 bttv-gpio.c -- gpio sub drivers
5 4
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index 706dc48df962..e684df37eb0e 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-i2c.c,v 1.25 2005/07/05 17:37:35 nsh Exp $
3 2
4 bttv-i2c.c -- all the i2c code is here 3 bttv-i2c.c -- all the i2c code is here
5 4
@@ -381,6 +380,7 @@ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
381} 380}
382 381
383static char *i2c_devs[128] = { 382static char *i2c_devs[128] = {
383 [ 0x1c >> 1 ] = "lgdt330x",
384 [ 0x30 >> 1 ] = "IR (hauppauge)", 384 [ 0x30 >> 1 ] = "IR (hauppauge)",
385 [ 0x80 >> 1 ] = "msp34xx", 385 [ 0x80 >> 1 ] = "msp34xx",
386 [ 0x86 >> 1 ] = "tda9887", 386 [ 0x86 >> 1 ] = "tda9887",
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index f7b5543a96a1..e8aada772b89 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-if.c,v 1.4 2004/11/17 18:47:47 kraxel Exp $
3 2
4 bttv-if.c -- old gpio interface to other kernel modules 3 bttv-if.c -- old gpio interface to other kernel modules
5 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
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index 9ed21fd190c6..a5ed99b89445 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
3 2
4 bttv-risc.c -- interfaces to other kernel modules 3 bttv-risc.c -- interfaces to other kernel modules
5 4
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
index 06f3e62b3e8d..f4f58c60f152 100644
--- a/drivers/media/video/bttv-vbi.c
+++ b/drivers/media/video/bttv-vbi.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $
3 2
4 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
5 vbi interface 4 vbi interface
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index f2af9e1454f0..d254e90e3bb9 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: bttv.h,v 1.22 2005/07/28 18:41:21 mchehab Exp $
3 * 2 *
4 * bttv - Bt848 frame grabber driver 3 * bttv - Bt848 frame grabber driver
5 * 4 *
@@ -218,6 +217,8 @@ struct tvcard
218#define PLL_35 2 217#define PLL_35 2
219 218
220 unsigned int tuner_type; 219 unsigned int tuner_type;
220 unsigned int tuner_addr;
221
221 unsigned int has_radio; 222 unsigned int has_radio;
222 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); 223 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
223 void (*muxsel_hook)(struct bttv *btv, unsigned int input); 224 void (*muxsel_hook)(struct bttv *btv, unsigned int input);
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index aab094bc243d..9b0b7ca035f8 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: bttvp.h,v 1.21 2005/07/15 21:44:14 mchehab Exp $
3 2
4 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
5 4
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 4f39688f780a..0c0c59e94774 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
3 * 2 *
4 * Support for a cx23416 mpeg encoder via cx2388x host port. 3 * Support for a cx23416 mpeg encoder via cx2388x host port.
5 * "blackbird" reference design. 4 * "blackbird" reference design.
@@ -62,7 +61,6 @@ static LIST_HEAD(cx8802_devlist);
62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF 61#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63 62
64/* Firmware API commands */ 63/* Firmware API commands */
65/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
66#define IVTV_API_STD_TIMEOUT 500 64#define IVTV_API_STD_TIMEOUT 500
67 65
68#define BLACKBIRD_API_PING 0x80 66#define BLACKBIRD_API_PING 0x80
@@ -696,7 +694,6 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
696 694
697 /* assign stream type */ 695 /* assign stream type */
698 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
699 /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
700 697
701 /* assign output port */ 698 /* assign output port */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
@@ -824,7 +821,8 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
824 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 821 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
826 823
827 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */ 824 /* initialize the video input */
825 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0);
828 826
829 msleep(1); 827 msleep(1);
830 828
@@ -833,11 +831,12 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
833 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); 831 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
834 msleep(1); 832 msleep(1);
835 833
836 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */ 834 /* start capturing to the host interface */
835 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */
837 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 836 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
838 BLACKBIRD_MPEG_CAPTURE, 837 BLACKBIRD_MPEG_CAPTURE,
839 BLACKBIRD_RAW_BITS_NONE 838 BLACKBIRD_RAW_BITS_NONE
840 ); /* start capturing to the host interface */ 839 );
841 msleep(10); 840 msleep(10);
842 841
843 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); 842 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
@@ -851,8 +850,8 @@ static int bb_buf_setup(struct videobuf_queue *q,
851{ 850{
852 struct cx8802_fh *fh = q->priv_data; 851 struct cx8802_fh *fh = q->priv_data;
853 852
854 fh->dev->ts_packet_size = 512; 853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
855 fh->dev->ts_packet_count = 100; 854 fh->dev->ts_packet_count = 32; /* was: 100 */
856 855
857 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
858 if (0 == *count) 857 if (0 == *count)
@@ -900,12 +899,36 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
900{ 899{
901 struct cx8802_fh *fh = file->private_data; 900 struct cx8802_fh *fh = file->private_data;
902 struct cx8802_dev *dev = fh->dev; 901 struct cx8802_dev *dev = fh->dev;
902 struct cx88_core *core = dev->core;
903 903
904 if (debug > 1) 904 if (debug > 1)
905 cx88_print_ioctl(dev->core->name,cmd); 905 cx88_print_ioctl(core->name,cmd);
906 906
907 switch (cmd) { 907 switch (cmd) {
908 908
909 /* --- capabilities ------------------------------------------ */
910 case VIDIOC_QUERYCAP:
911 {
912 struct v4l2_capability *cap = arg;
913
914 memset(cap,0,sizeof(*cap));
915 strcpy(cap->driver, "cx88_blackbird");
916 strlcpy(cap->card, cx88_boards[core->board].name,sizeof(cap->card));
917 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
918 cap->version = CX88_VERSION_CODE;
919 cap->capabilities =
920 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0;
926 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER;
928
929 return 0;
930 }
931
909 /* --- capture ioctls ---------------------------------------- */ 932 /* --- capture ioctls ---------------------------------------- */
910 case VIDIOC_ENUM_FMT: 933 case VIDIOC_ENUM_FMT:
911 { 934 {
@@ -935,7 +958,11 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
935 f->fmt.pix.width = dev->width; 958 f->fmt.pix.width = dev->width;
936 f->fmt.pix.height = dev->height; 959 f->fmt.pix.height = dev->height;
937 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
938 f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */; 961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */;
964 f->fmt.pix.colorspace = 0;
965 return 0;
939 } 966 }
940 967
941 /* --- streaming capture ------------------------------------- */ 968 /* --- streaming capture ------------------------------------- */
@@ -959,15 +986,25 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
959 return videobuf_streamoff(&fh->mpegq); 986 return videobuf_streamoff(&fh->mpegq);
960 987
961 default: 988 default:
962 return -EINVAL; 989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
963 } 990 }
964 return 0; 991 return 0;
965} 992}
966 993
994int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
995 unsigned int cmd, void *arg);
996unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
997
998static unsigned int mpeg_translate_ioctl(unsigned int cmd)
999{
1000 return cmd;
1001}
1002
967static int mpeg_ioctl(struct inode *inode, struct file *file, 1003static int mpeg_ioctl(struct inode *inode, struct file *file,
968 unsigned int cmd, unsigned long arg) 1004 unsigned int cmd, unsigned long arg)
969{ 1005{
970 return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); 1006 cmd = cx88_ioctl_translator( cmd );
1007 return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook);
971} 1008}
972 1009
973static int mpeg_open(struct inode *inode, struct file *file) 1010static int mpeg_open(struct inode *inode, struct file *file)
@@ -1135,7 +1172,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1135 dev->pci = pci_dev; 1172 dev->pci = pci_dev;
1136 dev->core = core; 1173 dev->core = core;
1137 dev->width = 720; 1174 dev->width = 720;
1138 dev->height = 480; 1175 dev->height = 576;
1139 1176
1140 err = cx8802_init_common(dev); 1177 err = cx8802_init_common(dev);
1141 if (0 != err) 1178 if (0 != err)
@@ -1148,6 +1185,9 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1148 1185
1149 list_add_tail(&dev->devlist,&cx8802_devlist); 1186 list_add_tail(&dev->devlist,&cx8802_devlist);
1150 blackbird_register_video(dev); 1187 blackbird_register_video(dev);
1188
1189 /* initial device configuration: needed ? */
1190
1151 return 0; 1191 return 0;
1152 1192
1153 fail_free: 1193 fail_free:
@@ -1202,6 +1242,8 @@ static int blackbird_init(void)
1202 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", 1242 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1203 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 1243 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1204#endif 1244#endif
1245 cx88_ioctl_hook = mpeg_do_ioctl;
1246 cx88_ioctl_translator = mpeg_translate_ioctl;
1205 return pci_register_driver(&blackbird_pci_driver); 1247 return pci_register_driver(&blackbird_pci_driver);
1206} 1248}
1207 1249
@@ -1213,6 +1255,9 @@ static void blackbird_fini(void)
1213module_init(blackbird_init); 1255module_init(blackbird_init);
1214module_exit(blackbird_fini); 1256module_exit(blackbird_fini);
1215 1257
1258EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator);
1260
1216/* ----------------------------------------------------------- */ 1261/* ----------------------------------------------------------- */
1217/* 1262/*
1218 * Local variables: 1263 * Local variables:
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index ebf02a7f81e8..4da91d535a5b 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-cards.c,v 1.90 2005/07/28 02:47:42 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * card-specific stuff. 4 * card-specific stuff.
@@ -499,9 +498,6 @@ struct cx88_board cx88_boards[] = {
499 .input = {{ 498 .input = {{
500 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
501 .vmux = 0, 500 .vmux = 0,
502 },{
503 .type = CX88_VMUX_SVIDEO,
504 .vmux = 2,
505 }}, 501 }},
506 .dvb = 1, 502 .dvb = 1,
507 }, 503 },
@@ -614,12 +610,12 @@ struct cx88_board cx88_boards[] = {
614 .input = {{ 610 .input = {{
615 .type = CX88_VMUX_TELEVISION, 611 .type = CX88_VMUX_TELEVISION,
616 .vmux = 0, 612 .vmux = 0,
617 .gpio0 = 0xed12, // internal decoder 613 .gpio0 = 0xed12, /* internal decoder */
618 .gpio2 = 0x00ff, 614 .gpio2 = 0x00ff,
619 },{ 615 },{
620 .type = CX88_VMUX_DEBUG, 616 .type = CX88_VMUX_DEBUG,
621 .vmux = 0, 617 .vmux = 0,
622 .gpio0 = 0xff01, // mono from tuner chip 618 .gpio0 = 0xff01, /* mono from tuner chip */
623 },{ 619 },{
624 .type = CX88_VMUX_COMPOSITE1, 620 .type = CX88_VMUX_COMPOSITE1,
625 .vmux = 1, 621 .vmux = 1,
@@ -715,19 +711,18 @@ struct cx88_board cx88_boards[] = {
715 .radio_type = UNSET, 711 .radio_type = UNSET,
716 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
717 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
718 /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
719 .input = {{ 714 .input = {{
720 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
721 .vmux = 0, 716 .vmux = 0,
722 .gpio0 = 0x0f0d, 717 .gpio0 = 0x97ed,
723 },{ 718 },{
724 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
725 .vmux = 1, 720 .vmux = 1,
726 .gpio0 = 0x0f00, 721 .gpio0 = 0x97e9,
727 },{ 722 },{
728 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
729 .vmux = 2, 724 .vmux = 2,
730 .gpio0 = 0x0f00, 725 .gpio0 = 0x97e9,
731 }}, 726 }},
732 .dvb = 1, 727 .dvb = 1,
733 }, 728 },
@@ -765,20 +760,21 @@ struct cx88_board cx88_boards[] = {
765 .radio_type = UNSET, 760 .radio_type = UNSET,
766 .tuner_addr = ADDR_UNSET, 761 .tuner_addr = ADDR_UNSET,
767 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
768 /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */ 763 .tda9887_conf = TDA9887_PRESENT,
769 .input = {{ 764 .input = {{
770 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
771 .vmux = 0, 766 .vmux = 0,
772 .gpio0 = 0x0f0d, 767 .gpio0 = 0x87fd,
773 },{ 768 },{
774 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
775 .vmux = 1, 770 .vmux = 1,
776 .gpio0 = 0x0f00, 771 .gpio0 = 0x87f9,
777 },{ 772 },{
778 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
779 .vmux = 2, 774 .vmux = 2,
780 .gpio0 = 0x0f00, 775 .gpio0 = 0x87f9,
781 }}, 776 }},
777 .dvb = 1,
782 }, 778 },
783}; 779};
784const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -949,7 +945,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
949{ 945{
950 struct tveeprom tv; 946 struct tveeprom tv;
951 947
952 tveeprom_hauppauge_analog(&tv, eeprom_data); 948 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
953 core->tuner_type = tv.tuner_type; 949 core->tuner_type = tv.tuner_type;
954 core->has_radio = tv.has_radio; 950 core->has_radio = tv.has_radio;
955} 951}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 5e868f5cd0c0..dc5c5c1f3461 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * driver core 4 * driver core
@@ -876,7 +875,7 @@ static int set_tvaudio(struct cx88_core *core)
876 875
877 cx_andor(MO_AFECFG_IO, 0x1f, 0x0); 876 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
878 cx88_set_tvaudio(core); 877 cx88_set_tvaudio(core);
879 // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); 878 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
880 879
881 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */ 880 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
882 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */ 881 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
@@ -1087,10 +1086,17 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1087 core->pci_bus = pci->bus->number; 1086 core->pci_bus = pci->bus->number;
1088 core->pci_slot = PCI_SLOT(pci->devfn); 1087 core->pci_slot = PCI_SLOT(pci->devfn);
1089 core->pci_irqmask = 0x00fc00; 1088 core->pci_irqmask = 0x00fc00;
1089 init_MUTEX(&core->lock);
1090 1090
1091 core->nr = cx88_devcount++; 1091 core->nr = cx88_devcount++;
1092 sprintf(core->name,"cx88[%d]",core->nr); 1092 sprintf(core->name,"cx88[%d]",core->nr);
1093 if (0 != get_ressources(core,pci)) { 1093 if (0 != get_ressources(core,pci)) {
1094 printk(KERN_ERR "CORE %s No more PCI ressources for "
1095 "subsystem: %04x:%04x, board: %s\n",
1096 core->name,pci->subsystem_vendor,
1097 pci->subsystem_device,
1098 cx88_boards[core->board].name);
1099
1094 cx88_devcount--; 1100 cx88_devcount--;
1095 goto fail_free; 1101 goto fail_free;
1096 } 1102 }
@@ -1114,11 +1120,11 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1114 core->board = CX88_BOARD_UNKNOWN; 1120 core->board = CX88_BOARD_UNKNOWN;
1115 cx88_card_list(core,pci); 1121 cx88_card_list(core,pci);
1116 } 1122 }
1117 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 1123 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1118 core->name,pci->subsystem_vendor, 1124 core->name,pci->subsystem_vendor,
1119 pci->subsystem_device,cx88_boards[core->board].name, 1125 pci->subsystem_device,cx88_boards[core->board].name,
1120 core->board, card[core->nr] == core->board ? 1126 core->board, card[core->nr] == core->board ?
1121 "insmod option" : "autodetected"); 1127 "insmod option" : "autodetected");
1122 1128
1123 core->tuner_type = tuner[core->nr]; 1129 core->tuner_type = tuner[core->nr];
1124 core->radio_type = radio[core->nr]; 1130 core->radio_type = radio[core->nr];
@@ -1202,4 +1208,5 @@ EXPORT_SYMBOL(cx88_core_put);
1202 * Local variables: 1208 * Local variables:
1203 * c-basic-offset: 8 1209 * c-basic-offset: 8
1204 * End: 1210 * End:
1211 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
1205 */ 1212 */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 78d223257a68..c9106b1d79df 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-dvb.c,v 1.58 2005/08/07 09:24:08 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines 4 * MPEG Transport Stream (DVB) routines
@@ -29,7 +28,7 @@
29#include <linux/kthread.h> 28#include <linux/kthread.h>
30#include <linux/file.h> 29#include <linux/file.h>
31#include <linux/suspend.h> 30#include <linux/suspend.h>
32#include <linux/config.h> 31
33 32
34#include "cx88.h" 33#include "cx88.h"
35#include "dvb-pll.h" 34#include "dvb-pll.h"
@@ -210,16 +209,26 @@ static struct or51132_config pchdtv_hd3000 = {
210static int lgdt330x_pll_set(struct dvb_frontend* fe, 209static int lgdt330x_pll_set(struct dvb_frontend* fe,
211 struct dvb_frontend_parameters* params) 210 struct dvb_frontend_parameters* params)
212{ 211{
212 /* FIXME make this routine use the tuner-simple code.
213 * It could probably be shared with a number of ATSC
214 * frontends. Many share the same tuner with analog TV. */
215
213 struct cx8802_dev *dev= fe->dvb->priv; 216 struct cx8802_dev *dev= fe->dvb->priv;
217 struct cx88_core *core = dev->core;
214 u8 buf[4]; 218 u8 buf[4];
215 struct i2c_msg msg = 219 struct i2c_msg msg =
216 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; 220 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
217 int err; 221 int err;
218 222
219 dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, 0); 223 /* Put the analog decoder in standby to keep it quiet */
224 if (core->tda9887_conf) {
225 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
226 }
227
228 dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
220 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", 229 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
221 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); 230 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
222 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { 231 if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
223 printk(KERN_WARNING "cx88-dvb: %s error " 232 printk(KERN_WARNING "cx88-dvb: %s error "
224 "(addr %02x <- %02x, err = %i)\n", 233 "(addr %02x <- %02x, err = %i)\n",
225 __FUNCTION__, buf[0], buf[1], err); 234 __FUNCTION__, buf[0], buf[1], err);
@@ -228,6 +237,13 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe,
228 else 237 else
229 return -EREMOTEIO; 238 return -EREMOTEIO;
230 } 239 }
240 if (core->tuner_type == TUNER_LG_TDVS_H062F) {
241 /* Set the Auxiliary Byte. */
242 buf[2] &= ~0x20;
243 buf[2] |= 0x18;
244 buf[3] = 0x50;
245 i2c_transfer(&core->i2c_adap, &msg, 1);
246 }
231 return 0; 247 return 0;
232} 248}
233 249
@@ -261,6 +277,14 @@ static struct lgdt330x_config fusionhdtv_3_gold = {
261 .pll_set = lgdt330x_pll_set, 277 .pll_set = lgdt330x_pll_set,
262 .set_ts_params = lgdt330x_set_ts_param, 278 .set_ts_params = lgdt330x_set_ts_param,
263}; 279};
280
281static struct lgdt330x_config fusionhdtv_5_gold = {
282 .demod_address = 0x0e,
283 .demod_chip = LGDT3303,
284 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
285 .pll_set = lgdt330x_pll_set,
286 .set_ts_params = lgdt330x_set_ts_param,
287};
264#endif 288#endif
265 289
266static int dvb_register(struct cx8802_dev *dev) 290static int dvb_register(struct cx8802_dev *dev)
@@ -346,6 +370,22 @@ static int dvb_register(struct cx8802_dev *dev)
346 &dev->core->i2c_adap); 370 &dev->core->i2c_adap);
347 } 371 }
348 break; 372 break;
373 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
374 dev->ts_gen_cntrl = 0x08;
375 {
376 /* Do a hardware reset of chip before using it. */
377 struct cx88_core *core = dev->core;
378
379 cx_clear(MO_GP0_IO, 1);
380 mdelay(100);
381 cx_set(MO_GP0_IO, 1);
382 mdelay(200);
383 dev->core->pll_addr = 0x61;
384 dev->core->pll_desc = &dvb_pll_tdvs_tua6034;
385 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
386 &dev->core->i2c_adap);
387 }
388 break;
349#endif 389#endif
350 default: 390 default:
351 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 391 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
@@ -362,11 +402,6 @@ static int dvb_register(struct cx8802_dev *dev)
362 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max; 402 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
363 } 403 }
364 404
365 /* Copy the board name into the DVB structure */
366 strlcpy(dev->dvb.frontend->ops->info.name,
367 cx88_boards[dev->core->board].name,
368 sizeof(dev->dvb.frontend->ops->info.name));
369
370 /* register everything */ 405 /* register everything */
371 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 406 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
372} 407}
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 7f598039e025..761cebd40dbd 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-i2c.c,v 1.30 2005/07/25 05:10:13 mkrufky Exp $
3 2
4 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
5 4
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 214887798192..d81b21d6e05d 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-input.c,v 1.15 2005/07/07 13:58:38 mchehab Exp $
3 * 2 *
4 * Device driver for GPIO attached remote control interfaces 3 * Device driver for GPIO attached remote control interfaces
5 * on Conexant 2388x based TV/DVB cards. 4 * on Conexant 2388x based TV/DVB cards.
@@ -212,6 +211,53 @@ static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
212 211
213/* ---------------------------------------------------------------------- */ 212/* ---------------------------------------------------------------------- */
214 213
214/* Cinergy 1400 DVB-T */
215static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
216 [0x01] = KEY_POWER,
217 [0x02] = KEY_1,
218 [0x03] = KEY_2,
219 [0x04] = KEY_3,
220 [0x05] = KEY_4,
221 [0x06] = KEY_5,
222 [0x07] = KEY_6,
223 [0x08] = KEY_7,
224 [0x09] = KEY_8,
225 [0x0a] = KEY_9,
226 [0x0c] = KEY_0,
227
228 [0x0b] = KEY_VIDEO,
229 [0x0d] = KEY_REFRESH,
230 [0x0e] = KEY_SELECT,
231 [0x0f] = KEY_EPG,
232 [0x10] = KEY_UP,
233 [0x11] = KEY_LEFT,
234 [0x12] = KEY_OK,
235 [0x13] = KEY_RIGHT,
236 [0x14] = KEY_DOWN,
237 [0x15] = KEY_TEXT,
238 [0x16] = KEY_INFO,
239
240 [0x17] = KEY_RED,
241 [0x18] = KEY_GREEN,
242 [0x19] = KEY_YELLOW,
243 [0x1a] = KEY_BLUE,
244
245 [0x1b] = KEY_CHANNELUP,
246 [0x1c] = KEY_VOLUMEUP,
247 [0x1d] = KEY_MUTE,
248 [0x1e] = KEY_VOLUMEDOWN,
249 [0x1f] = KEY_CHANNELDOWN,
250
251 [0x40] = KEY_PAUSE,
252 [0x4c] = KEY_PLAY,
253 [0x58] = KEY_RECORD,
254 [0x54] = KEY_PREVIOUS,
255 [0x48] = KEY_STOP,
256 [0x5c] = KEY_NEXT,
257};
258
259/* ---------------------------------------------------------------------- */
260
215struct cx88_IR { 261struct cx88_IR {
216 struct cx88_core *core; 262 struct cx88_core *core;
217 struct input_dev input; 263 struct input_dev input;
@@ -241,7 +287,7 @@ module_param(ir_debug, int, 0644); /* debug level [IR] */
241MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 287MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
242 288
243#define ir_dprintk(fmt, arg...) if (ir_debug) \ 289#define ir_dprintk(fmt, arg...) if (ir_debug) \
244 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg) 290 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
245 291
246/* ---------------------------------------------------------------------- */ 292/* ---------------------------------------------------------------------- */
247 293
@@ -329,6 +375,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
329 ir->mask_keyup = 0x60; 375 ir->mask_keyup = 0x60;
330 ir->polling = 50; /* ms */ 376 ir->polling = 50; /* ms */
331 break; 377 break;
378 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
379 ir_codes = ir_codes_cinergy_1400;
380 ir_type = IR_TYPE_PD;
381 ir->sampling = 1;
382 break;
332 case CX88_BOARD_HAUPPAUGE: 383 case CX88_BOARD_HAUPPAUGE:
333 case CX88_BOARD_HAUPPAUGE_DVB_T1: 384 case CX88_BOARD_HAUPPAUGE_DVB_T1:
334 ir_codes = ir_codes_hauppauge_new; 385 ir_codes = ir_codes_hauppauge_new;
@@ -394,6 +445,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
394 ir->input.id.vendor = pci->vendor; 445 ir->input.id.vendor = pci->vendor;
395 ir->input.id.product = pci->device; 446 ir->input.id.product = pci->device;
396 } 447 }
448 ir->input.dev = &pci->dev;
397 449
398 /* record handles to ourself */ 450 /* record handles to ourself */
399 ir->core = core; 451 ir->core = core;
@@ -445,7 +497,7 @@ int cx88_ir_fini(struct cx88_core *core)
445void cx88_ir_irq(struct cx88_core *core) 497void cx88_ir_irq(struct cx88_core *core)
446{ 498{
447 struct cx88_IR *ir = core->ir; 499 struct cx88_IR *ir = core->ir;
448 u32 samples, rc5; 500 u32 samples, ircode;
449 int i; 501 int i;
450 502
451 if (NULL == ir) 503 if (NULL == ir)
@@ -477,13 +529,44 @@ void cx88_ir_irq(struct cx88_core *core)
477 529
478 /* decode it */ 530 /* decode it */
479 switch (core->board) { 531 switch (core->board) {
532 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
533 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
534
535 if (ircode == 0xffffffff) { /* decoding error */
536 ir_dprintk("pulse distance decoding error\n");
537 break;
538 }
539
540 ir_dprintk("pulse distance decoded: %x\n", ircode);
541
542 if (ircode == 0) { /* key still pressed */
543 ir_dprintk("pulse distance decoded repeat code\n");
544 ir->release = jiffies + msecs_to_jiffies(120);
545 break;
546 }
547
548 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
549 ir_dprintk("pulse distance decoded wrong address\n");
550 break;
551 }
552
553 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
554 ir_dprintk("pulse distance decoded wrong check sum\n");
555 break;
556 }
557
558 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
559
560 ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
561 ir->release = jiffies + msecs_to_jiffies(120);
562 break;
480 case CX88_BOARD_HAUPPAUGE: 563 case CX88_BOARD_HAUPPAUGE:
481 case CX88_BOARD_HAUPPAUGE_DVB_T1: 564 case CX88_BOARD_HAUPPAUGE_DVB_T1:
482 rc5 = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 565 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
483 ir_dprintk("biphase decoded: %x\n", rc5); 566 ir_dprintk("biphase decoded: %x\n", ircode);
484 if ((rc5 & 0xfffff000) != 0x3000) 567 if ((ircode & 0xfffff000) != 0x3000)
485 break; 568 break;
486 ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5); 569 ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
487 ir->release = jiffies + msecs_to_jiffies(120); 570 ir->release = jiffies + msecs_to_jiffies(120);
488 break; 571 break;
489 } 572 }
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index fe2767c0ff94..ee2300e1ae0b 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-mpeg.c,v 1.31 2005/07/07 14:17:47 mchehab Exp $
3 * 2 *
4 * Support for the mpeg transport stream transfers 3 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x. 4 * PCI function #2 of the cx2388x.
@@ -73,11 +72,15 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
73 udelay(100); 72 udelay(100);
74 cx_write(MO_PINMUX_IO, 0x00); 73 cx_write(MO_PINMUX_IO, 0x00);
75 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01); 74 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
76 if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) || 75 switch (core->board) {
77 (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) { 76 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
77 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
78 cx_write(TS_SOP_STAT, 1<<13); 79 cx_write(TS_SOP_STAT, 1<<13);
79 } else { 80 break;
81 default:
80 cx_write(TS_SOP_STAT, 0x00); 82 cx_write(TS_SOP_STAT, 0x00);
83 break;
81 } 84 }
82 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); 85 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
83 udelay(100); 86 udelay(100);
@@ -86,12 +89,10 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
86 if (cx88_boards[core->board].blackbird) { 89 if (cx88_boards[core->board].blackbird) {
87 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ 90 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
88 91
89 // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */
90 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ 92 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
91 udelay(100); 93 udelay(100);
92 94
93 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ 95 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
94 //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */
95 cx_write(TS_VALERR_CNTRL, 0x2000); 96 cx_write(TS_VALERR_CNTRL, 0x2000);
96 97
97 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ 98 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
@@ -106,7 +107,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
106 dprintk( 0, "setting the interrupt mask\n" ); 107 dprintk( 0, "setting the interrupt mask\n" );
107 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 108 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
108 cx_set(MO_TS_INTMSK, 0x1f0011); 109 cx_set(MO_TS_INTMSK, 0x1f0011);
109 //cx_write(MO_TS_INTMSK, 0x0f0011);
110 110
111 /* start dma */ 111 /* start dma */
112 cx_set(MO_DEV_CNTRL2, (1<<5)); 112 cx_set(MO_DEV_CNTRL2, (1<<5));
@@ -206,7 +206,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
206 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); 206 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
207 dprintk(0,"[%p/%d] %s - first active\n", 207 dprintk(0,"[%p/%d] %s - first active\n",
208 buf, buf->vb.i, __FUNCTION__); 208 buf, buf->vb.i, __FUNCTION__);
209 //udelay(100);
210 209
211 } else { 210 } else {
212 dprintk( 1, "queue is not empty - append to active\n" ); 211 dprintk( 1, "queue is not empty - append to active\n" );
@@ -217,7 +216,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
217 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 216 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
218 dprintk( 1, "[%p/%d] %s - append to active\n", 217 dprintk( 1, "[%p/%d] %s - append to active\n",
219 buf, buf->vb.i, __FUNCTION__); 218 buf, buf->vb.i, __FUNCTION__);
220 //udelay(100);
221 } 219 }
222} 220}
223 221
@@ -387,7 +385,6 @@ int cx8802_init_common(struct cx8802_dev *dev)
387 dev->pci_lat,pci_resource_start(dev->pci,0)); 385 dev->pci_lat,pci_resource_start(dev->pci,0));
388 386
389 /* initialize driver struct */ 387 /* initialize driver struct */
390 init_MUTEX(&dev->lock);
391 spin_lock_init(&dev->slock); 388 spin_lock_init(&dev->slock);
392 389
393 /* init dma queue */ 390 /* init dma queue */
@@ -458,14 +455,28 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
458 455
459int cx8802_resume_common(struct pci_dev *pci_dev) 456int cx8802_resume_common(struct pci_dev *pci_dev)
460{ 457{
461 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 458 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
462 struct cx88_core *core = dev->core; 459 struct cx88_core *core = dev->core;
460 int err;
463 461
464 if (dev->state.disabled) { 462 if (dev->state.disabled) {
465 pci_enable_device(pci_dev); 463 err=pci_enable_device(pci_dev);
464 if (err) {
465 printk(KERN_ERR "%s: can't enable device\n",
466 dev->core->name);
467 return err;
468 }
466 dev->state.disabled = 0; 469 dev->state.disabled = 0;
467 } 470 }
468 pci_set_power_state(pci_dev, PCI_D0); 471 err=pci_set_power_state(pci_dev, PCI_D0);
472 if (err) {
473 printk(KERN_ERR "%s: can't enable device\n",
474 dev->core->name);
475 pci_disable_device(pci_dev);
476 dev->state.disabled = 1;
477
478 return err;
479 }
469 pci_restore_state(pci_dev); 480 pci_restore_state(pci_dev);
470 481
471 /* FIXME: re-initialize hardware */ 482 /* FIXME: re-initialize hardware */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 37f82662d265..0a3a62fc9bbb 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-reg.h,v 1.8 2005/07/07 13:58:38 mchehab Exp $
3 2
4 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
5 4
@@ -40,6 +39,29 @@
40#define CX88X_EN_TBFX 0x02 39#define CX88X_EN_TBFX 0x02
41#define CX88X_EN_VSFX 0x04 40#define CX88X_EN_VSFX 0x04
42 41
42/* ---------------------------------------------------------------------- */
43/* PCI controller registers */
44
45/* Command and Status Register */
46#define F0_CMD_STAT_MM 0x2f0004
47#define F1_CMD_STAT_MM 0x2f0104
48#define F2_CMD_STAT_MM 0x2f0204
49#define F3_CMD_STAT_MM 0x2f0304
50#define F4_CMD_STAT_MM 0x2f0404
51
52/* Device Control #1 */
53#define F0_DEV_CNTRL1_MM 0x2f0040
54#define F1_DEV_CNTRL1_MM 0x2f0140
55#define F2_DEV_CNTRL1_MM 0x2f0240
56#define F3_DEV_CNTRL1_MM 0x2f0340
57#define F4_DEV_CNTRL1_MM 0x2f0440
58
59/* Device Control #1 */
60#define F0_BAR0_MM 0x2f0010
61#define F1_BAR0_MM 0x2f0110
62#define F2_BAR0_MM 0x2f0210
63#define F3_BAR0_MM 0x2f0310
64#define F4_BAR0_MM 0x2f0410
43 65
44/* ---------------------------------------------------------------------- */ 66/* ---------------------------------------------------------------------- */
45/* DMA Controller registers */ 67/* DMA Controller registers */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 91207f10bae7..2765acee0285 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-tvaudio.c,v 1.37 2005/07/07 13:58:38 mchehab Exp $
3 2
4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver 3 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
5 4
@@ -121,25 +120,19 @@ static void set_audio_registers(struct cx88_core *core,
121} 120}
122 121
123static void set_audio_start(struct cx88_core *core, 122static void set_audio_start(struct cx88_core *core,
124 u32 mode, u32 ctl) 123 u32 mode)
125{ 124{
126 // mute 125 // mute
127 cx_write(AUD_VOL_CTL, (1 << 6)); 126 cx_write(AUD_VOL_CTL, (1 << 6));
128 127
129 // increase level of input by 12dB
130// cx_write(AUD_AFE_12DB_EN, 0x0001);
131 cx_write(AUD_AFE_12DB_EN, 0x0000);
132
133 // start programming 128 // start programming
134 cx_write(AUD_CTL, 0x0000); 129 cx_write(AUD_CTL, 0x0000);
135 cx_write(AUD_INIT, mode); 130 cx_write(AUD_INIT, mode);
136 cx_write(AUD_INIT_LD, 0x0001); 131 cx_write(AUD_INIT_LD, 0x0001);
137 cx_write(AUD_SOFT_RESET, 0x0001); 132 cx_write(AUD_SOFT_RESET, 0x0001);
138
139 cx_write(AUD_CTL, ctl);
140} 133}
141 134
142static void set_audio_finish(struct cx88_core *core) 135static void set_audio_finish(struct cx88_core *core, u32 ctl)
143{ 136{
144 u32 volume; 137 u32 volume;
145 138
@@ -154,25 +147,25 @@ static void set_audio_finish(struct cx88_core *core)
154 cx_write(AUD_I2SOUTPUTCNTL, 1); 147 cx_write(AUD_I2SOUTPUTCNTL, 1);
155 cx_write(AUD_I2SCNTL, 0); 148 cx_write(AUD_I2SCNTL, 0);
156 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 149 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else {
151 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl);
157 } 153 }
158 154
159 // finish programming 155 /* finish programming */
160 cx_write(AUD_SOFT_RESET, 0x0000); 156 cx_write(AUD_SOFT_RESET, 0x0000);
161 157
162 // start audio processing 158 /* unmute */
163 cx_set(AUD_CTL, EN_DAC_ENABLE);
164
165 // unmute
166 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
167 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); 160 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
168} 161}
169 162
170/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
171 164
172static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode)
173{ 166{
174 static const struct rlist btsc[] = { 167 static const struct rlist btsc[] = {
175 /* from dscaler */ 168 { AUD_AFE_12DB_EN, 0x00000001 },
176 { AUD_OUT1_SEL, 0x00000013 }, 169 { AUD_OUT1_SEL, 0x00000013 },
177 { AUD_OUT1_SHIFT, 0x00000000 }, 170 { AUD_OUT1_SHIFT, 0x00000000 },
178 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
@@ -206,9 +199,10 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
206 { AUD_RDSI_SHIFT, 0x00000000 }, 199 { AUD_RDSI_SHIFT, 0x00000000 },
207 { AUD_RDSQ_SHIFT, 0x00000000 }, 200 { AUD_RDSQ_SHIFT, 0x00000000 },
208 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 201 { AUD_POLYPH80SCALEFAC, 0x00000003 },
209 { /* end of list */ }, 202 { /* end of list */ },
210 }; 203 };
211 static const struct rlist btsc_sap[] = { 204 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 },
212 { AUD_DBX_IN_GAIN, 0x00007200 }, 206 { AUD_DBX_IN_GAIN, 0x00007200 },
213 { AUD_DBX_WBE_GAIN, 0x00006200 }, 207 { AUD_DBX_WBE_GAIN, 0x00006200 },
214 { AUD_DBX_SE_GAIN, 0x00006200 }, 208 { AUD_DBX_SE_GAIN, 0x00006200 },
@@ -259,371 +253,400 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
259 { AUD_RDSI_SHIFT, 0x00000000 }, 253 { AUD_RDSI_SHIFT, 0x00000000 },
260 { AUD_RDSQ_SHIFT, 0x00000000 }, 254 { AUD_RDSQ_SHIFT, 0x00000000 },
261 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 255 { AUD_POLYPH80SCALEFAC, 0x00000003 },
262 { /* end of list */ }, 256 { /* end of list */ },
263 }; 257 };
264 258
265 // dscaler: exactly taken from driver, 259 mode |= EN_FMRADIO_EN_RDS;
266 // dscaler: don't know why to set EN_FMRADIO_EN_RDS 260
267 if (sap) { 261 if (sap) {
268 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
269 set_audio_start(core, 0x0001, 263 set_audio_start(core, SEL_SAP);
270 EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
271 set_audio_registers(core, btsc_sap); 264 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode);
272 } else { 266 } else {
273 dprintk("%s (status: known-good)\n",__FUNCTION__); 267 dprintk("%s (status: known-good)\n",__FUNCTION__);
274 set_audio_start(core, 0x0001, 268 set_audio_start(core, SEL_BTSC);
275 EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
276 set_audio_registers(core, btsc); 269 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode);
277 } 271 }
278 set_audio_finish(core);
279} 272}
280 273
281 274
282static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo) 275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
283{ 276{
284 /* This is probably weird.. 277 /* This is probably weird..
285 * Let's operate and find out. */ 278 * Let's operate and find out. */
286 279
287 static const struct rlist nicam_l_mono[] = { 280 static const struct rlist nicam_l_mono[] = {
288 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 { AUD_ERRLOGPERIOD_R, 0x00000064 },
289 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
290 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
291 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
292 285
293 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
294 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
295 { AUD_QAM_MODE, 0x00 }, 288 { AUD_QAM_MODE, 0x00 },
296 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
297 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 { AUD_PHACC_FREQ_8MSB, 0x3a },
298 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 { AUD_PHACC_FREQ_8LSB, 0x4a },
299 292
300 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 { AUD_DEEMPHGAIN_R, 0x6680 },
301 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 { AUD_DEEMPHNUMER1_R, 0x353DE },
302 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 { AUD_DEEMPHNUMER2_R, 0x1B1 },
303 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
304 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 { AUD_DEEMPHDENOM2_R, 0x0 },
305 { AUD_FM_MODE_ENABLE, 0x7 }, 298 { AUD_FM_MODE_ENABLE, 0x7 },
306 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 { AUD_POLYPH80SCALEFAC, 0x3 },
307 { AUD_AFE_12DB_EN, 0x1 }, 300 { AUD_AFE_12DB_EN, 0x1 },
308 { AAGC_GAIN, 0x0 }, 301 { AAGC_GAIN, 0x0 },
309 { AAGC_HYST, 0x18 }, 302 { AAGC_HYST, 0x18 },
310 { AAGC_DEF, 0x20 }, 303 { AAGC_DEF, 0x20 },
311 { AUD_DN0_FREQ, 0x0 }, 304 { AUD_DN0_FREQ, 0x0 },
312 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
313 { AUD_DCOC_0_SRC, 0x21 }, 306 { AUD_DCOC_0_SRC, 0x21 },
314 { AUD_IIR1_0_SEL, 0x0 }, 307 { AUD_IIR1_0_SEL, 0x0 },
315 { AUD_IIR1_0_SHIFT, 0x7 }, 308 { AUD_IIR1_0_SHIFT, 0x7 },
316 { AUD_IIR1_1_SEL, 0x2 }, 309 { AUD_IIR1_1_SEL, 0x2 },
317 { AUD_IIR1_1_SHIFT, 0x0 }, 310 { AUD_IIR1_1_SHIFT, 0x0 },
318 { AUD_DCOC_1_SRC, 0x3 }, 311 { AUD_DCOC_1_SRC, 0x3 },
319 { AUD_DCOC1_SHIFT, 0x0 }, 312 { AUD_DCOC1_SHIFT, 0x0 },
320 { AUD_DCOC_PASS_IN, 0x0 }, 313 { AUD_DCOC_PASS_IN, 0x0 },
321 { AUD_IIR1_2_SEL, 0x23 }, 314 { AUD_IIR1_2_SEL, 0x23 },
322 { AUD_IIR1_2_SHIFT, 0x0 }, 315 { AUD_IIR1_2_SHIFT, 0x0 },
323 { AUD_IIR1_3_SEL, 0x4 }, 316 { AUD_IIR1_3_SEL, 0x4 },
324 { AUD_IIR1_3_SHIFT, 0x7 }, 317 { AUD_IIR1_3_SHIFT, 0x7 },
325 { AUD_IIR1_4_SEL, 0x5 }, 318 { AUD_IIR1_4_SEL, 0x5 },
326 { AUD_IIR1_4_SHIFT, 0x7 }, 319 { AUD_IIR1_4_SHIFT, 0x7 },
327 { AUD_IIR3_0_SEL, 0x7 }, 320 { AUD_IIR3_0_SEL, 0x7 },
328 { AUD_IIR3_0_SHIFT, 0x0 }, 321 { AUD_IIR3_0_SHIFT, 0x0 },
329 { AUD_DEEMPH0_SRC_SEL, 0x11 }, 322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
330 { AUD_DEEMPH0_SHIFT, 0x0 }, 323 { AUD_DEEMPH0_SHIFT, 0x0 },
331 { AUD_DEEMPH0_G0, 0x7000 }, 324 { AUD_DEEMPH0_G0, 0x7000 },
332 { AUD_DEEMPH0_A0, 0x0 }, 325 { AUD_DEEMPH0_A0, 0x0 },
333 { AUD_DEEMPH0_B0, 0x0 }, 326 { AUD_DEEMPH0_B0, 0x0 },
334 { AUD_DEEMPH0_A1, 0x0 }, 327 { AUD_DEEMPH0_A1, 0x0 },
335 { AUD_DEEMPH0_B1, 0x0 }, 328 { AUD_DEEMPH0_B1, 0x0 },
336 { AUD_DEEMPH1_SRC_SEL, 0x11 }, 329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
337 { AUD_DEEMPH1_SHIFT, 0x0 }, 330 { AUD_DEEMPH1_SHIFT, 0x0 },
338 { AUD_DEEMPH1_G0, 0x7000 }, 331 { AUD_DEEMPH1_G0, 0x7000 },
339 { AUD_DEEMPH1_A0, 0x0 }, 332 { AUD_DEEMPH1_A0, 0x0 },
340 { AUD_DEEMPH1_B0, 0x0 }, 333 { AUD_DEEMPH1_B0, 0x0 },
341 { AUD_DEEMPH1_A1, 0x0 }, 334 { AUD_DEEMPH1_A1, 0x0 },
342 { AUD_DEEMPH1_B1, 0x0 }, 335 { AUD_DEEMPH1_B1, 0x0 },
343 { AUD_OUT0_SEL, 0x3F }, 336 { AUD_OUT0_SEL, 0x3F },
344 { AUD_OUT1_SEL, 0x3F }, 337 { AUD_OUT1_SEL, 0x3F },
345 { AUD_DMD_RA_DDS, 0x0F5C285 }, 338 { AUD_DMD_RA_DDS, 0x0F5C285 },
346 { AUD_PLL_INT, 0x1E }, 339 { AUD_PLL_INT, 0x1E },
347 { AUD_PLL_DDS, 0x0 }, 340 { AUD_PLL_DDS, 0x0 },
348 { AUD_PLL_FRAC, 0x0E542 }, 341 { AUD_PLL_FRAC, 0x0E542 },
349 342
350 // setup QAM registers 343 // setup QAM registers
351 { AUD_RATE_ADJ1, 0x00000100 }, 344 { AUD_RATE_ADJ1, 0x00000100 },
352 { AUD_RATE_ADJ2, 0x00000200 }, 345 { AUD_RATE_ADJ2, 0x00000200 },
353 { AUD_RATE_ADJ3, 0x00000300 }, 346 { AUD_RATE_ADJ3, 0x00000300 },
354 { AUD_RATE_ADJ4, 0x00000400 }, 347 { AUD_RATE_ADJ4, 0x00000400 },
355 { AUD_RATE_ADJ5, 0x00000500 }, 348 { AUD_RATE_ADJ5, 0x00000500 },
356 { AUD_RATE_THRES_DMD, 0x000000C0 }, 349 { AUD_RATE_THRES_DMD, 0x000000C0 },
357 { /* end of list */ }, 350 { /* end of list */ },
358 }; 351 };
359
360 static const struct rlist nicam_l[] = {
361 // setup QAM registers
362 { AUD_RATE_ADJ1, 0x00000060 },
363 { AUD_RATE_ADJ2, 0x000000F9 },
364 { AUD_RATE_ADJ3, 0x000001CC },
365 { AUD_RATE_ADJ4, 0x000002B3 },
366 { AUD_RATE_ADJ5, 0x00000726 },
367 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
368 { AUD_DEEMPHDENOM2_R, 0x00000000 },
369 { AUD_ERRLOGPERIOD_R, 0x00000064 },
370 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
371 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
372 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
373 { AUD_POLYPH80SCALEFAC, 0x00000003 },
374 { AUD_DMD_RA_DDS, 0x00C00000 },
375 { AUD_PLL_INT, 0x0000001E },
376 { AUD_PLL_DDS, 0x00000000 },
377 { AUD_PLL_FRAC, 0x0000E542 },
378 { AUD_START_TIMER, 0x00000000 },
379 { AUD_DEEMPHNUMER1_R, 0x000353DE },
380 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
381 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
382 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
383 { AUD_QAM_MODE, 0x05 },
384 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
385 { AUD_PHACC_FREQ_8MSB, 0x34 },
386 { AUD_PHACC_FREQ_8LSB, 0x4C },
387 { AUD_DEEMPHGAIN_R, 0x00006680 },
388 { AUD_RATE_THRES_DMD, 0x000000C0 },
389 { /* end of list */ },
390 } ;
391 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
392
393 if (!stereo) {
394 /* AM mono sound */
395 set_audio_start(core, 0x0004,
396 0x100c /* FIXME again */);
397 set_audio_registers(core, nicam_l_mono);
398 } else {
399 set_audio_start(core, 0x0010,
400 0x1924 /* FIXME again */);
401 set_audio_registers(core, nicam_l);
402 }
403 set_audio_finish(core);
404 352
353 static const struct rlist nicam_l[] = {
354 // setup QAM registers
355 { AUD_RATE_ADJ1, 0x00000060 },
356 { AUD_RATE_ADJ2, 0x000000F9 },
357 { AUD_RATE_ADJ3, 0x000001CC },
358 { AUD_RATE_ADJ4, 0x000002B3 },
359 { AUD_RATE_ADJ5, 0x00000726 },
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 },
362 { AUD_ERRLOGPERIOD_R, 0x00000064 },
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
366 { AUD_POLYPH80SCALEFAC, 0x00000003 },
367 { AUD_DMD_RA_DDS, 0x00C00000 },
368 { AUD_PLL_INT, 0x0000001E },
369 { AUD_PLL_DDS, 0x00000000 },
370 { AUD_PLL_FRAC, 0x0000E542 },
371 { AUD_START_TIMER, 0x00000000 },
372 { AUD_DEEMPHNUMER1_R, 0x000353DE },
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
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 */ },
383 } ;
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 }
405} 397}
406 398
407static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
408{ 400{
409 static const struct rlist pal_i_fm_mono[] = { 401 static const struct rlist pal_i_fm_mono[] = {
410 {AUD_ERRLOGPERIOD_R, 0x00000064}, 402 {AUD_ERRLOGPERIOD_R, 0x00000064},
411 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
412 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
413 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
414 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
415 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
416 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
417 {AUD_QAM_MODE, 0x05}, 409 {AUD_QAM_MODE, 0x05},
418 {AUD_PHACC_FREQ_8MSB, 0x3a}, 410 {AUD_PHACC_FREQ_8MSB, 0x3a},
419 {AUD_PHACC_FREQ_8LSB, 0x93}, 411 {AUD_PHACC_FREQ_8LSB, 0x93},
420 {AUD_DMD_RA_DDS, 0x002a4f2f}, 412 {AUD_DMD_RA_DDS, 0x002a4f2f},
421 {AUD_PLL_INT, 0x0000001e}, 413 {AUD_PLL_INT, 0x0000001e},
422 {AUD_PLL_DDS, 0x00000004}, 414 {AUD_PLL_DDS, 0x00000004},
423 {AUD_PLL_FRAC, 0x0000e542}, 415 {AUD_PLL_FRAC, 0x0000e542},
424 {AUD_RATE_ADJ1, 0x00000100}, 416 {AUD_RATE_ADJ1, 0x00000100},
425 {AUD_RATE_ADJ2, 0x00000200}, 417 {AUD_RATE_ADJ2, 0x00000200},
426 {AUD_RATE_ADJ3, 0x00000300}, 418 {AUD_RATE_ADJ3, 0x00000300},
427 {AUD_RATE_ADJ4, 0x00000400}, 419 {AUD_RATE_ADJ4, 0x00000400},
428 {AUD_RATE_ADJ5, 0x00000500}, 420 {AUD_RATE_ADJ5, 0x00000500},
429 {AUD_THR_FR, 0x00000000}, 421 {AUD_THR_FR, 0x00000000},
430 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
431 {AUD_PILOT_BQD_1_K1, 0x00551340}, 423 {AUD_PILOT_BQD_1_K1, 0x00551340},
432 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
433 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
434 {AUD_PILOT_BQD_1_K4, 0x00400000}, 426 {AUD_PILOT_BQD_1_K4, 0x00400000},
435 {AUD_PILOT_BQD_2_K0, 0x00040000}, 427 {AUD_PILOT_BQD_2_K0, 0x00040000},
436 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
437 {AUD_PILOT_BQD_2_K2, 0x00400000}, 429 {AUD_PILOT_BQD_2_K2, 0x00400000},
438 {AUD_PILOT_BQD_2_K3, 0x00000000}, 430 {AUD_PILOT_BQD_2_K3, 0x00000000},
439 {AUD_PILOT_BQD_2_K4, 0x00000000}, 431 {AUD_PILOT_BQD_2_K4, 0x00000000},
440 {AUD_MODE_CHG_TIMER, 0x00000060}, 432 {AUD_MODE_CHG_TIMER, 0x00000060},
441 {AUD_AFE_12DB_EN, 0x00000001}, 433 {AUD_AFE_12DB_EN, 0x00000001},
442 {AAGC_HYST, 0x0000000a}, 434 {AAGC_HYST, 0x0000000a},
443 {AUD_CORDIC_SHIFT_0, 0x00000007}, 435 {AUD_CORDIC_SHIFT_0, 0x00000007},
444 {AUD_CORDIC_SHIFT_1, 0x00000007}, 436 {AUD_CORDIC_SHIFT_1, 0x00000007},
445 {AUD_C1_UP_THR, 0x00007000}, 437 {AUD_C1_UP_THR, 0x00007000},
446 {AUD_C1_LO_THR, 0x00005400}, 438 {AUD_C1_LO_THR, 0x00005400},
447 {AUD_C2_UP_THR, 0x00005400}, 439 {AUD_C2_UP_THR, 0x00005400},
448 {AUD_C2_LO_THR, 0x00003000}, 440 {AUD_C2_LO_THR, 0x00003000},
449 {AUD_DCOC_0_SRC, 0x0000001a}, 441 {AUD_DCOC_0_SRC, 0x0000001a},
450 {AUD_DCOC0_SHIFT, 0x00000000}, 442 {AUD_DCOC0_SHIFT, 0x00000000},
451 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
452 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
453 {AUD_DCOC_PASS_IN, 0x00000003}, 445 {AUD_DCOC_PASS_IN, 0x00000003},
454 {AUD_IIR3_0_SEL, 0x00000021}, 446 {AUD_IIR3_0_SEL, 0x00000021},
455 {AUD_DN2_AFC, 0x00000002}, 447 {AUD_DN2_AFC, 0x00000002},
456 {AUD_DCOC_1_SRC, 0x0000001b}, 448 {AUD_DCOC_1_SRC, 0x0000001b},
457 {AUD_DCOC1_SHIFT, 0x00000000}, 449 {AUD_DCOC1_SHIFT, 0x00000000},
458 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
459 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
460 {AUD_IIR3_1_SEL, 0x00000023}, 452 {AUD_IIR3_1_SEL, 0x00000023},
461 {AUD_DN0_FREQ, 0x000035a3}, 453 {AUD_DN0_FREQ, 0x000035a3},
462 {AUD_DN2_FREQ, 0x000029c7}, 454 {AUD_DN2_FREQ, 0x000029c7},
463 {AUD_CRDC0_SRC_SEL, 0x00000511}, 455 {AUD_CRDC0_SRC_SEL, 0x00000511},
464 {AUD_IIR1_0_SEL, 0x00000001}, 456 {AUD_IIR1_0_SEL, 0x00000001},
465 {AUD_IIR1_1_SEL, 0x00000000}, 457 {AUD_IIR1_1_SEL, 0x00000000},
466 {AUD_IIR3_2_SEL, 0x00000003}, 458 {AUD_IIR3_2_SEL, 0x00000003},
467 {AUD_IIR3_2_SHIFT, 0x00000000}, 459 {AUD_IIR3_2_SHIFT, 0x00000000},
468 {AUD_IIR3_0_SEL, 0x00000002}, 460 {AUD_IIR3_0_SEL, 0x00000002},
469 {AUD_IIR2_0_SEL, 0x00000021}, 461 {AUD_IIR2_0_SEL, 0x00000021},
470 {AUD_IIR2_0_SHIFT, 0x00000002}, 462 {AUD_IIR2_0_SHIFT, 0x00000002},
471 {AUD_DEEMPH0_SRC_SEL, 0x0000000b}, 463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
472 {AUD_DEEMPH1_SRC_SEL, 0x0000000b}, 464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
473 {AUD_POLYPH80SCALEFAC, 0x00000001}, 465 {AUD_POLYPH80SCALEFAC, 0x00000001},
474 {AUD_START_TIMER, 0x00000000}, 466 {AUD_START_TIMER, 0x00000000},
475 { /* end of list */ }, 467 { /* end of list */ },
476 }; 468 };
477 469
478 static const struct rlist pal_i_nicam[] = { 470 static const struct rlist pal_i_nicam[] = {
479 { AUD_RATE_ADJ1, 0x00000010 }, 471 { AUD_RATE_ADJ1, 0x00000010 },
480 { AUD_RATE_ADJ2, 0x00000040 }, 472 { AUD_RATE_ADJ2, 0x00000040 },
481 { AUD_RATE_ADJ3, 0x00000100 }, 473 { AUD_RATE_ADJ3, 0x00000100 },
482 { AUD_RATE_ADJ4, 0x00000400 }, 474 { AUD_RATE_ADJ4, 0x00000400 },
483 { AUD_RATE_ADJ5, 0x00001000 }, 475 { AUD_RATE_ADJ5, 0x00001000 },
484 // { AUD_DMD_RA_DDS, 0x00c0d5ce }, 476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
485 { AUD_DEEMPHGAIN_R, 0x000023c2 }, 477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
486 { AUD_DEEMPHNUMER1_R, 0x0002a7bc }, 478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
487 { AUD_DEEMPHNUMER2_R, 0x0003023e }, 479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
488 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 }, 480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
489 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
490 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
491 { AUD_ERRLOGPERIOD_R, 0x00000fff }, 483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
492 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff }, 484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
493 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff }, 485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
494 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f }, 486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
495 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
496 { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, 488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
497 { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, 489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
498 { AUD_PDF_DDS_CNST_BYTE0, 0x16 }, 490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
499 { AUD_QAM_MODE, 0x05 }, 491 { AUD_QAM_MODE, 0x05 },
500 { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, 492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
501 { AUD_PHACC_FREQ_8MSB, 0x3a }, 493 { AUD_PHACC_FREQ_8MSB, 0x3a },
502 { AUD_PHACC_FREQ_8LSB, 0x93 }, 494 { AUD_PHACC_FREQ_8LSB, 0x93 },
503 { /* end of list */ }, 495 { /* end of list */ },
504 }; 496 };
505 497
506 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
507 499
508 if (!stereo) { 500 if (!stereo) {
509 // FM mono 501 /* FM Mono */
510 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 502 set_audio_start(core, SEL_A2);
511 set_audio_registers(core, pal_i_fm_mono); 503 set_audio_registers(core, pal_i_fm_mono);
512 } else { 504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
513 // Nicam Stereo 505 } else {
514 set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 506 /* Nicam Stereo */
507 set_audio_start(core, SEL_NICAM);
515 set_audio_registers(core, pal_i_nicam); 508 set_audio_registers(core, pal_i_nicam);
516 } 509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
517 set_audio_finish(core); 510 }
518} 511}
519 512
520static void set_audio_standard_A2(struct cx88_core *core) 513static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
521{ 514{
522 /* from dscaler cvs */
523 static const struct rlist a2_common[] = { 515 static const struct rlist a2_common[] = {
524 { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, 516 {AUD_ERRLOGPERIOD_R, 0x00000064},
525 { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, 517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
526 { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, 518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
527 { AUD_QAM_MODE, 0x05 }, 519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
528 { AUD_PHACC_FREQ_8MSB, 0x34 }, 520 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
529 { AUD_PHACC_FREQ_8LSB, 0x4c }, 521 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
530 522 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
531 { AUD_RATE_ADJ1, 0x00001000 }, 523 {AUD_QAM_MODE, 0x05},
532 { AUD_RATE_ADJ2, 0x00002000 }, 524 {AUD_PHACC_FREQ_8MSB, 0x34},
533 { AUD_RATE_ADJ3, 0x00003000 }, 525 {AUD_PHACC_FREQ_8LSB, 0x4c},
534 { AUD_RATE_ADJ4, 0x00004000 }, 526 {AUD_RATE_ADJ1, 0x00000100},
535 { AUD_RATE_ADJ5, 0x00005000 }, 527 {AUD_RATE_ADJ2, 0x00000200},
536 { AUD_THR_FR, 0x00000000 }, 528 {AUD_RATE_ADJ3, 0x00000300},
537 { AAGC_HYST, 0x0000001a }, 529 {AUD_RATE_ADJ4, 0x00000400},
538 { AUD_PILOT_BQD_1_K0, 0x0000755b }, 530 {AUD_RATE_ADJ5, 0x00000500},
539 { AUD_PILOT_BQD_1_K1, 0x00551340 }, 531 {AUD_THR_FR, 0x00000000},
540 { AUD_PILOT_BQD_1_K2, 0x006d30be }, 532 {AAGC_HYST, 0x0000001a},
541 { AUD_PILOT_BQD_1_K3, 0xffd394af }, 533 {AUD_PILOT_BQD_1_K0, 0x0000755b},
542 { AUD_PILOT_BQD_1_K4, 0x00400000 }, 534 {AUD_PILOT_BQD_1_K1, 0x00551340},
543 { AUD_PILOT_BQD_2_K0, 0x00040000 }, 535 {AUD_PILOT_BQD_1_K2, 0x006d30be},
544 { AUD_PILOT_BQD_2_K1, 0x002a4841 }, 536 {AUD_PILOT_BQD_1_K3, 0xffd394af},
545 { AUD_PILOT_BQD_2_K2, 0x00400000 }, 537 {AUD_PILOT_BQD_1_K4, 0x00400000},
546 { AUD_PILOT_BQD_2_K3, 0x00000000 }, 538 {AUD_PILOT_BQD_2_K0, 0x00040000},
547 { AUD_PILOT_BQD_2_K4, 0x00000000 }, 539 {AUD_PILOT_BQD_2_K1, 0x002a4841},
548 { AUD_MODE_CHG_TIMER, 0x00000040 }, 540 {AUD_PILOT_BQD_2_K2, 0x00400000},
549 { AUD_START_TIMER, 0x00000200 }, 541 {AUD_PILOT_BQD_2_K3, 0x00000000},
550 { AUD_AFE_12DB_EN, 0x00000000 }, 542 {AUD_PILOT_BQD_2_K4, 0x00000000},
551 { AUD_CORDIC_SHIFT_0, 0x00000007 }, 543 {AUD_MODE_CHG_TIMER, 0x00000040},
552 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 544 {AUD_AFE_12DB_EN, 0x00000001},
553 { AUD_DEEMPH0_G0, 0x00000380 }, 545 {AUD_CORDIC_SHIFT_0, 0x00000007},
554 { AUD_DEEMPH1_G0, 0x00000380 }, 546 {AUD_CORDIC_SHIFT_1, 0x00000007},
555 { AUD_DCOC_0_SRC, 0x0000001a }, 547 {AUD_DEEMPH0_G0, 0x00000380},
556 { AUD_DCOC0_SHIFT, 0x00000000 }, 548 {AUD_DEEMPH1_G0, 0x00000380},
557 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 549 {AUD_DCOC_0_SRC, 0x0000001a},
558 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 550 {AUD_DCOC0_SHIFT, 0x00000000},
559 { AUD_DCOC_PASS_IN, 0x00000003 }, 551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
560 { AUD_IIR3_0_SEL, 0x00000021 }, 552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
561 { AUD_DN2_AFC, 0x00000002 }, 553 {AUD_DCOC_PASS_IN, 0x00000003},
562 { AUD_DCOC_1_SRC, 0x0000001b }, 554 {AUD_IIR3_0_SEL, 0x00000021},
563 { AUD_DCOC1_SHIFT, 0x00000000 }, 555 {AUD_DN2_AFC, 0x00000002},
564 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 556 {AUD_DCOC_1_SRC, 0x0000001b},
565 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 557 {AUD_DCOC1_SHIFT, 0x00000000},
566 { AUD_IIR3_1_SEL, 0x00000023 }, 558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
567 { AUD_RDSI_SEL, 0x00000017 }, 559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
568 { AUD_RDSI_SHIFT, 0x00000000 }, 560 {AUD_IIR3_1_SEL, 0x00000023},
569 { AUD_RDSQ_SEL, 0x00000017 }, 561 {AUD_RDSI_SEL, 0x00000017},
570 { AUD_RDSQ_SHIFT, 0x00000000 }, 562 {AUD_RDSI_SHIFT, 0x00000000},
571 { AUD_POLYPH80SCALEFAC, 0x00000001 }, 563 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ },
571 };
572 572
573 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000},
573 { /* end of list */ }, 579 { /* end of list */ },
574 }; 580 };
575 581
576 static const struct rlist a2_table1[] = { 582 static const struct rlist a2_dk[] = {
577 // PAL-BG 583 {AUD_DMD_RA_DDS, 0x002a4f2f},
578 { AUD_DMD_RA_DDS, 0x002a73bd }, 584 {AUD_C1_UP_THR, 0x00007000},
579 { AUD_C1_UP_THR, 0x00007000 }, 585 {AUD_C1_LO_THR, 0x00005400},
580 { AUD_C1_LO_THR, 0x00005400 }, 586 {AUD_C2_UP_THR, 0x00005400},
581 { AUD_C2_UP_THR, 0x00005400 }, 587 {AUD_C2_LO_THR, 0x00003000},
582 { AUD_C2_LO_THR, 0x00003000 }, 588 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0},
583 { /* end of list */ }, 590 { /* end of list */ },
584 }; 591 };
585 static const struct rlist a2_table2[] = { 592/* unknown, probably NTSC-M */
586 // PAL-DK 593 static const struct rlist a2_m[] = {
587 { AUD_DMD_RA_DDS, 0x002a73bd }, 594 {AUD_DMD_RA_DDS, 0x002a0425},
588 { AUD_C1_UP_THR, 0x00007000 }, 595 {AUD_C1_UP_THR, 0x00003c00},
589 { AUD_C1_LO_THR, 0x00005400 }, 596 {AUD_C1_LO_THR, 0x00003000},
590 { AUD_C2_UP_THR, 0x00005400 }, 597 {AUD_C2_UP_THR, 0x00006000},
591 { AUD_C2_LO_THR, 0x00003000 }, 598 {AUD_C2_LO_THR, 0x00003c00},
592 { AUD_DN0_FREQ, 0x00003a1c }, 599 {AUD_DEEMPH0_A0, 0x00007a80},
593 { AUD_DN2_FREQ, 0x0000d2e0 }, 600 {AUD_DEEMPH1_A0, 0x00007a80},
601 {AUD_DEEMPH0_G0, 0x00001200},
602 {AUD_DEEMPH1_G0, 0x00001200},
603 {AUD_DN0_FREQ, 0x0000283b},
604 {AUD_DN1_FREQ, 0x00003418},
605 {AUD_DN2_FREQ, 0x000029c7},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540},
594 { /* end of list */ }, 607 { /* end of list */ },
595 }; 608 };
596 static const struct rlist a2_table3[] = { 609
597 // unknown, probably NTSC-M 610 static const struct rlist a2_deemph50[] = {
598 { AUD_DMD_RA_DDS, 0x002a2873 }, 611 {AUD_DEEMPH0_G0, 0x00000380},
599 { AUD_C1_UP_THR, 0x00003c00 }, 612 {AUD_DEEMPH1_G0, 0x00000380},
600 { AUD_C1_LO_THR, 0x00003000 }, 613 {AUD_DEEMPHGAIN_R, 0x000011e1},
601 { AUD_C2_UP_THR, 0x00006000 }, 614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
602 { AUD_C2_LO_THR, 0x00003c00 }, 615 {AUD_DEEMPHNUMER2_R, 0x0003023c},
603 { AUD_DN0_FREQ, 0x00002836 }, 616 { /* end of list */ },
604 { AUD_DN1_FREQ, 0x00003418 }, 617 };
605 { AUD_DN2_FREQ, 0x000029c7 }, 618
606 { AUD_POLY0_DDS_CONSTANT, 0x000a7540 }, 619 static const struct rlist a2_deemph75[] = {
620 {AUD_DEEMPH0_G0, 0x00000480},
621 {AUD_DEEMPH1_G0, 0x00000480},
622 {AUD_DEEMPHGAIN_R, 0x00009000},
623 {AUD_DEEMPHNUMER1_R, 0x000353de},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1},
607 { /* end of list */ }, 625 { /* end of list */ },
608 }; 626 };
609 627
610 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO); 628 set_audio_start(core, SEL_A2);
611 set_audio_registers(core, a2_common); 629 set_audio_registers(core, a2_common);
612 switch (core->tvaudio) { 630 switch (core->tvaudio) {
613 case WW_A2_BG: 631 case WW_A2_BG:
614 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
615 set_audio_registers(core, a2_table1); 633 set_audio_registers(core, a2_bg);
634 set_audio_registers(core, a2_deemph50);
616 break; 635 break;
617 case WW_A2_DK: 636 case WW_A2_DK:
618 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
619 set_audio_registers(core, a2_table2); 638 set_audio_registers(core, a2_dk);
639 set_audio_registers(core, a2_deemph50);
620 break; 640 break;
621 case WW_A2_M: 641 case WW_A2_M:
622 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
623 set_audio_registers(core, a2_table3); 643 set_audio_registers(core, a2_m);
644 set_audio_registers(core, a2_deemph75);
624 break; 645 break;
625 }; 646 };
626 set_audio_finish(core); 647
648 mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF;
649 set_audio_finish(core, mode);
627} 650}
628 651
629static void set_audio_standard_EIAJ(struct cx88_core *core) 652static void set_audio_standard_EIAJ(struct cx88_core *core)
@@ -635,9 +658,9 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
635 }; 658 };
636 dprintk("%s (status: unknown)\n",__FUNCTION__); 659 dprintk("%s (status: unknown)\n",__FUNCTION__);
637 660
638 set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO); 661 set_audio_start(core, SEL_EIAJ);
639 set_audio_registers(core, eiaj); 662 set_audio_registers(core, eiaj);
640 set_audio_finish(core); 663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
641} 664}
642 665
643static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
@@ -683,7 +706,7 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
683 }; 706 };
684 707
685 dprintk("%s (status: unknown)\n",__FUNCTION__); 708 dprintk("%s (status: unknown)\n",__FUNCTION__);
686 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); 709 set_audio_start(core, SEL_FMRADIO);
687 710
688 switch (deemph) 711 switch (deemph)
689 { 712 {
@@ -700,7 +723,7 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
700 break; 723 break;
701 } 724 }
702 725
703 set_audio_finish(core); 726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
704} 727}
705 728
706/* ----------------------------------------------------------- */ 729/* ----------------------------------------------------------- */
@@ -709,7 +732,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
709{ 732{
710 switch (core->tvaudio) { 733 switch (core->tvaudio) {
711 case WW_BTSC: 734 case WW_BTSC:
712 set_audio_standard_BTSC(core,0); 735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
713 break; 736 break;
714 case WW_NICAM_BGDKL: 737 case WW_NICAM_BGDKL:
715 set_audio_standard_NICAM_L(core,0); 738 set_audio_standard_NICAM_L(core,0);
@@ -720,7 +743,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
720 case WW_A2_BG: 743 case WW_A2_BG:
721 case WW_A2_DK: 744 case WW_A2_DK:
722 case WW_A2_M: 745 case WW_A2_M:
723 set_audio_standard_A2(core); 746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
724 break; 747 break;
725 case WW_EIAJ: 748 case WW_EIAJ:
726 set_audio_standard_EIAJ(core); 749 set_audio_standard_EIAJ(core);
@@ -734,7 +757,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
734 case WW_NONE: 757 case WW_NONE:
735 default: 758 default:
736 printk("%s/0: unknown tv audio mode [%d]\n", 759 printk("%s/0: unknown tv audio mode [%d]\n",
737 core->name, core->tvaudio); 760 core->name, core->tvaudio);
738 break; 761 break;
739 } 762 }
740 return; 763 return;
@@ -769,6 +792,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
769 aud_ctl_names[cx_read(AUD_CTL) & 63]); 792 aud_ctl_names[cx_read(AUD_CTL) & 63]);
770 core->astat = reg; 793 core->astat = reg;
771 794
795/* TODO
796 Reading from AUD_STATUS is not enough
797 for auto-detecting sap/dual-fm/nicam.
798 Add some code here later.
799*/
800
801# if 0
772 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
773 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
774 t->rxsubchans = V4L2_TUNER_SUB_MONO; 804 t->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -779,7 +809,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
779 t->capability = V4L2_TUNER_CAP_STEREO | 809 t->capability = V4L2_TUNER_CAP_STEREO |
780 V4L2_TUNER_CAP_SAP; 810 V4L2_TUNER_CAP_SAP;
781 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 811 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
782 if (1 == pilot) { 812 if (1 == pilot) {
783 /* SAP */ 813 /* SAP */
784 t->rxsubchans |= V4L2_TUNER_SUB_SAP; 814 t->rxsubchans |= V4L2_TUNER_SUB_SAP;
785 } 815 }
@@ -787,13 +817,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
787 case WW_A2_BG: 817 case WW_A2_BG:
788 case WW_A2_DK: 818 case WW_A2_DK:
789 case WW_A2_M: 819 case WW_A2_M:
790 if (1 == pilot) { 820 if (1 == pilot) {
791 /* stereo */ 821 /* stereo */
792 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
793 if (0 == mode) 823 if (0 == mode)
794 t->audmode = V4L2_TUNER_MODE_STEREO; 824 t->audmode = V4L2_TUNER_MODE_STEREO;
795 } 825 }
796 if (2 == pilot) { 826 if (2 == pilot) {
797 /* dual language -- FIXME */ 827 /* dual language -- FIXME */
798 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
799 t->audmode = V4L2_TUNER_MODE_LANG1; 829 t->audmode = V4L2_TUNER_MODE_LANG1;
@@ -805,16 +835,17 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
805 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 835 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
806 } 836 }
807 break; 837 break;
808 case WW_SYSTEM_L_AM: 838 case WW_SYSTEM_L_AM:
809 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) { 839 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
810 t->audmode = V4L2_TUNER_MODE_STEREO; 840 t->audmode = V4L2_TUNER_MODE_STEREO;
811 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
812 } 842 }
813 break ; 843 break ;
814 default: 844 default:
815 /* nothing */ 845 /* nothing */
816 break; 846 break;
817 } 847 }
848# endif
818 return; 849 return;
819} 850}
820 851
@@ -835,16 +866,16 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
835 case WW_BTSC: 866 case WW_BTSC:
836 switch (mode) { 867 switch (mode) {
837 case V4L2_TUNER_MODE_MONO: 868 case V4L2_TUNER_MODE_MONO:
838 ctl = EN_BTSC_FORCE_MONO; 869 set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_MONO);
839 mask = 0x3f;
840 break; 870 break;
841 case V4L2_TUNER_MODE_SAP: 871 case V4L2_TUNER_MODE_LANG1:
842 ctl = EN_BTSC_FORCE_SAP; 872 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
843 mask = 0x3f; 873 break;
874 case V4L2_TUNER_MODE_LANG2:
875 set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
844 break; 876 break;
845 case V4L2_TUNER_MODE_STEREO: 877 case V4L2_TUNER_MODE_STEREO:
846 ctl = EN_BTSC_AUTO_STEREO; 878 set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
847 mask = 0x3f;
848 break; 879 break;
849 } 880 }
850 break; 881 break;
@@ -854,16 +885,13 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
854 switch (mode) { 885 switch (mode) {
855 case V4L2_TUNER_MODE_MONO: 886 case V4L2_TUNER_MODE_MONO:
856 case V4L2_TUNER_MODE_LANG1: 887 case V4L2_TUNER_MODE_LANG1:
857 ctl = EN_A2_FORCE_MONO1; 888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
858 mask = 0x3f;
859 break; 889 break;
860 case V4L2_TUNER_MODE_LANG2: 890 case V4L2_TUNER_MODE_LANG2:
861 ctl = EN_A2_AUTO_MONO2; 891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2);
862 mask = 0x3f;
863 break; 892 break;
864 case V4L2_TUNER_MODE_STEREO: 893 case V4L2_TUNER_MODE_STEREO:
865 ctl = EN_A2_AUTO_STEREO | EN_DMTRX_SUMR; 894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO);
866 mask = 0x8bf;
867 break; 895 break;
868 } 896 }
869 break; 897 break;
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 320d57888bbd..9bc6c8995581 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4#include <linux/kernel.h> 3#include <linux/kernel.h>
5#include <linux/module.h> 4#include <linux/module.h>
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 5f58c103198a..3dbc074fb515 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface 4 * video4linux video interface
@@ -66,7 +65,7 @@ module_param(vid_limit,int,0644);
66MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); 65MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
67 66
68#define dprintk(level,fmt, arg...) if (video_debug >= level) \ 67#define dprintk(level,fmt, arg...) if (video_debug >= level) \
69 printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg) 68 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
70 69
71/* ------------------------------------------------------------------ */ 70/* ------------------------------------------------------------------ */
72 71
@@ -326,22 +325,23 @@ static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
326 325
327static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) 326static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
328{ 327{
328 struct cx88_core *core = dev->core;
329 if (fh->resources & bit) 329 if (fh->resources & bit)
330 /* have it already allocated */ 330 /* have it already allocated */
331 return 1; 331 return 1;
332 332
333 /* is it free? */ 333 /* is it free? */
334 down(&dev->lock); 334 down(&core->lock);
335 if (dev->resources & bit) { 335 if (dev->resources & bit) {
336 /* no, someone else uses it */ 336 /* no, someone else uses it */
337 up(&dev->lock); 337 up(&core->lock);
338 return 0; 338 return 0;
339 } 339 }
340 /* it's free, grab it */ 340 /* it's free, grab it */
341 fh->resources |= bit; 341 fh->resources |= bit;
342 dev->resources |= bit; 342 dev->resources |= bit;
343 dprintk(1,"res: get %d\n",bit); 343 dprintk(1,"res: get %d\n",bit);
344 up(&dev->lock); 344 up(&core->lock);
345 return 1; 345 return 1;
346} 346}
347 347
@@ -360,27 +360,29 @@ int res_locked(struct cx8800_dev *dev, unsigned int bit)
360static 360static
361void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) 361void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
362{ 362{
363 struct cx88_core *core = dev->core;
363 if ((fh->resources & bits) != bits) 364 if ((fh->resources & bits) != bits)
364 BUG(); 365 BUG();
365 366
366 down(&dev->lock); 367 down(&core->lock);
367 fh->resources &= ~bits; 368 fh->resources &= ~bits;
368 dev->resources &= ~bits; 369 dev->resources &= ~bits;
369 dprintk(1,"res: put %d\n",bits); 370 dprintk(1,"res: put %d\n",bits);
370 up(&dev->lock); 371 up(&core->lock);
371} 372}
372 373
373/* ------------------------------------------------------------------ */ 374/* ------------------------------------------------------------------ */
374 375
375static int video_mux(struct cx8800_dev *dev, unsigned int input) 376/* static int video_mux(struct cx8800_dev *dev, unsigned int input) */
377static int video_mux(struct cx88_core *core, unsigned int input)
376{ 378{
377 struct cx88_core *core = dev->core; 379 /* struct cx88_core *core = dev->core; */
378 380
379 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", 381 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
380 input, INPUT(input)->vmux, 382 input, INPUT(input)->vmux,
381 INPUT(input)->gpio0,INPUT(input)->gpio1, 383 INPUT(input)->gpio0,INPUT(input)->gpio1,
382 INPUT(input)->gpio2,INPUT(input)->gpio3); 384 INPUT(input)->gpio2,INPUT(input)->gpio3);
383 dev->core->input = input; 385 core->input = input;
384 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14); 386 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
385 cx_write(MO_GP3_IO, INPUT(input)->gpio3); 387 cx_write(MO_GP3_IO, INPUT(input)->gpio3);
386 cx_write(MO_GP0_IO, INPUT(input)->gpio0); 388 cx_write(MO_GP0_IO, INPUT(input)->gpio0);
@@ -413,9 +415,9 @@ static int start_video_dma(struct cx8800_dev *dev,
413 struct cx88_core *core = dev->core; 415 struct cx88_core *core = dev->core;
414 416
415 /* setup fifo + format */ 417 /* setup fifo + format */
416 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21], 418 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
417 buf->bpl, buf->risc.dma); 419 buf->bpl, buf->risc.dma);
418 cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field); 420 cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field);
419 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); 421 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
420 422
421 /* reset counter */ 423 /* reset counter */
@@ -424,6 +426,14 @@ static int start_video_dma(struct cx8800_dev *dev,
424 426
425 /* enable irqs */ 427 /* enable irqs */
426 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01); 428 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
429
430 /* Enables corresponding bits at PCI_INT_STAT:
431 bits 0 to 4: video, audio, transport stream, VIP, Host
432 bit 7: timer
433 bits 8 and 9: DMA complete for: SRC, DST
434 bits 10 and 11: BERR signal asserted for RISC: RD, WR
435 bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB
436 */
427 cx_set(MO_VID_INTMSK, 0x0f0011); 437 cx_set(MO_VID_INTMSK, 0x0f0011);
428 438
429 /* enable capture */ 439 /* enable capture */
@@ -431,7 +441,7 @@ static int start_video_dma(struct cx8800_dev *dev,
431 441
432 /* start dma */ 442 /* start dma */
433 cx_set(MO_DEV_CNTRL2, (1<<5)); 443 cx_set(MO_DEV_CNTRL2, (1<<5));
434 cx_set(MO_VID_DMACNTRL, 0x11); 444 cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */
435 445
436 return 0; 446 return 0;
437} 447}
@@ -455,6 +465,7 @@ static int stop_video_dma(struct cx8800_dev *dev)
455static int restart_video_queue(struct cx8800_dev *dev, 465static int restart_video_queue(struct cx8800_dev *dev,
456 struct cx88_dmaqueue *q) 466 struct cx88_dmaqueue *q)
457{ 467{
468 struct cx88_core *core = dev->core;
458 struct cx88_buffer *buf, *prev; 469 struct cx88_buffer *buf, *prev;
459 struct list_head *item; 470 struct list_head *item;
460 471
@@ -524,12 +535,13 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
524{ 535{
525 struct cx8800_fh *fh = q->priv_data; 536 struct cx8800_fh *fh = q->priv_data;
526 struct cx8800_dev *dev = fh->dev; 537 struct cx8800_dev *dev = fh->dev;
538 struct cx88_core *core = dev->core;
527 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); 539 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
528 int rc, init_buffer = 0; 540 int rc, init_buffer = 0;
529 541
530 BUG_ON(NULL == fh->fmt); 542 BUG_ON(NULL == fh->fmt);
531 if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) || 543 if (fh->width < 48 || fh->width > norm_maxw(core->tvnorm) ||
532 fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm)) 544 fh->height < 32 || fh->height > norm_maxh(core->tvnorm))
533 return -EINVAL; 545 return -EINVAL;
534 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; 546 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
535 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 547 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
@@ -609,6 +621,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
609 struct cx88_buffer *prev; 621 struct cx88_buffer *prev;
610 struct cx8800_fh *fh = vq->priv_data; 622 struct cx8800_fh *fh = vq->priv_data;
611 struct cx8800_dev *dev = fh->dev; 623 struct cx8800_dev *dev = fh->dev;
624 struct cx88_core *core = dev->core;
612 struct cx88_dmaqueue *q = &dev->vidq; 625 struct cx88_dmaqueue *q = &dev->vidq;
613 626
614 /* add jump to stopper */ 627 /* add jump to stopper */
@@ -701,6 +714,7 @@ static int video_open(struct inode *inode, struct file *file)
701{ 714{
702 int minor = iminor(inode); 715 int minor = iminor(inode);
703 struct cx8800_dev *h,*dev = NULL; 716 struct cx8800_dev *h,*dev = NULL;
717 struct cx88_core *core;
704 struct cx8800_fh *fh; 718 struct cx8800_fh *fh;
705 struct list_head *list; 719 struct list_head *list;
706 enum v4l2_buf_type type = 0; 720 enum v4l2_buf_type type = 0;
@@ -725,6 +739,8 @@ static int video_open(struct inode *inode, struct file *file)
725 if (NULL == dev) 739 if (NULL == dev)
726 return -ENODEV; 740 return -ENODEV;
727 741
742 core = dev->core;
743
728 dprintk(1,"open minor=%d radio=%d type=%s\n", 744 dprintk(1,"open minor=%d radio=%d type=%s\n",
729 minor,radio,v4l2_type_names[type]); 745 minor,radio,v4l2_type_names[type]);
730 746
@@ -755,17 +771,16 @@ static int video_open(struct inode *inode, struct file *file)
755 fh); 771 fh);
756 772
757 if (fh->radio) { 773 if (fh->radio) {
758 struct cx88_core *core = dev->core;
759 int board = core->board; 774 int board = core->board;
760 dprintk(1,"video_open: setting radio device\n"); 775 dprintk(1,"video_open: setting radio device\n");
761 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); 776 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
762 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); 777 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
763 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); 778 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
764 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); 779 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
765 dev->core->tvaudio = WW_FM; 780 core->tvaudio = WW_FM;
766 cx88_set_tvaudio(core); 781 cx88_set_tvaudio(core);
767 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); 782 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
768 cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL); 783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
769 } 784 }
770 785
771 return 0; 786 return 0;
@@ -857,6 +872,9 @@ static int video_release(struct inode *inode, struct file *file)
857 videobuf_mmap_free(&fh->vbiq); 872 videobuf_mmap_free(&fh->vbiq);
858 file->private_data = NULL; 873 file->private_data = NULL;
859 kfree(fh); 874 kfree(fh);
875
876 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
877
860 return 0; 878 return 0;
861} 879}
862 880
@@ -870,9 +888,10 @@ video_mmap(struct file *file, struct vm_area_struct * vma)
870 888
871/* ------------------------------------------------------------------ */ 889/* ------------------------------------------------------------------ */
872 890
873static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) 891/* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
892static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
874{ 893{
875 struct cx88_core *core = dev->core; 894 /* struct cx88_core *core = dev->core; */
876 struct cx88_ctrl *c = NULL; 895 struct cx88_ctrl *c = NULL;
877 u32 value; 896 u32 value;
878 int i; 897 int i;
@@ -898,9 +917,10 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
898 return 0; 917 return 0;
899} 918}
900 919
901static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) 920/* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
921static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
902{ 922{
903 struct cx88_core *core = dev->core; 923 /* struct cx88_core *core = dev->core; */
904 struct cx88_ctrl *c = NULL; 924 struct cx88_ctrl *c = NULL;
905 u32 v_sat_value; 925 u32 v_sat_value;
906 u32 value; 926 u32 value;
@@ -913,9 +933,9 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
913 return -EINVAL; 933 return -EINVAL;
914 934
915 if (ctl->value < c->v.minimum) 935 if (ctl->value < c->v.minimum)
916 return -ERANGE; 936 ctl->value = c->v.minimum;
917 if (ctl->value > c->v.maximum) 937 if (ctl->value > c->v.maximum)
918 return -ERANGE; 938 ctl->value = c->v.maximum;
919 switch (ctl->id) { 939 switch (ctl->id) {
920 case V4L2_CID_AUDIO_BALANCE: 940 case V4L2_CID_AUDIO_BALANCE:
921 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; 941 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
@@ -946,7 +966,8 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
946 return 0; 966 return 0;
947} 967}
948 968
949static void init_controls(struct cx8800_dev *dev) 969/* static void init_controls(struct cx8800_dev *dev) */
970static void init_controls(struct cx88_core *core)
950{ 971{
951 static struct v4l2_control mute = { 972 static struct v4l2_control mute = {
952 .id = V4L2_CID_AUDIO_MUTE, 973 .id = V4L2_CID_AUDIO_MUTE,
@@ -969,11 +990,11 @@ static void init_controls(struct cx8800_dev *dev)
969 .value = 0x80, 990 .value = 0x80,
970 }; 991 };
971 992
972 set_control(dev,&mute); 993 set_control(core,&mute);
973 set_control(dev,&volume); 994 set_control(core,&volume);
974 set_control(dev,&hue); 995 set_control(core,&hue);
975 set_control(dev,&contrast); 996 set_control(core,&contrast);
976 set_control(dev,&brightness); 997 set_control(core,&brightness);
977} 998}
978 999
979/* ------------------------------------------------------------------ */ 1000/* ------------------------------------------------------------------ */
@@ -1004,6 +1025,8 @@ static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1004static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, 1025static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1005 struct v4l2_format *f) 1026 struct v4l2_format *f)
1006{ 1027{
1028 struct cx88_core *core = dev->core;
1029
1007 switch (f->type) { 1030 switch (f->type) {
1008 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1031 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1009 { 1032 {
@@ -1016,8 +1039,8 @@ static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1016 return -EINVAL; 1039 return -EINVAL;
1017 1040
1018 field = f->fmt.pix.field; 1041 field = f->fmt.pix.field;
1019 maxw = norm_maxw(dev->core->tvnorm); 1042 maxw = norm_maxw(core->tvnorm);
1020 maxh = norm_maxh(dev->core->tvnorm); 1043 maxh = norm_maxh(core->tvnorm);
1021 1044
1022 if (V4L2_FIELD_ANY == field) { 1045 if (V4L2_FIELD_ANY == field) {
1023 field = (f->fmt.pix.height > maxh/2) 1046 field = (f->fmt.pix.height > maxh/2)
@@ -1101,12 +1124,14 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1101 if (video_debug > 1) 1124 if (video_debug > 1)
1102 cx88_print_ioctl(core->name,cmd); 1125 cx88_print_ioctl(core->name,cmd);
1103 switch (cmd) { 1126 switch (cmd) {
1127
1128 /* --- capabilities ------------------------------------------ */
1104 case VIDIOC_QUERYCAP: 1129 case VIDIOC_QUERYCAP:
1105 { 1130 {
1106 struct v4l2_capability *cap = arg; 1131 struct v4l2_capability *cap = arg;
1107 1132
1108 memset(cap,0,sizeof(*cap)); 1133 memset(cap,0,sizeof(*cap));
1109 strcpy(cap->driver, "cx8800"); 1134 strcpy(cap->driver, "cx8800");
1110 strlcpy(cap->card, cx88_boards[core->board].name, 1135 strlcpy(cap->card, cx88_boards[core->board].name,
1111 sizeof(cap->card)); 1136 sizeof(cap->card));
1112 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1137 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1116,12 +1141,128 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1116 V4L2_CAP_READWRITE | 1141 V4L2_CAP_READWRITE |
1117 V4L2_CAP_STREAMING | 1142 V4L2_CAP_STREAMING |
1118 V4L2_CAP_VBI_CAPTURE | 1143 V4L2_CAP_VBI_CAPTURE |
1144 V4L2_CAP_VIDEO_OVERLAY |
1119 0; 1145 0;
1120 if (UNSET != core->tuner_type) 1146 if (UNSET != core->tuner_type)
1121 cap->capabilities |= V4L2_CAP_TUNER; 1147 cap->capabilities |= V4L2_CAP_TUNER;
1122 return 0; 1148 return 0;
1123 } 1149 }
1124 1150
1151 /* --- capture ioctls ---------------------------------------- */
1152 case VIDIOC_ENUM_FMT:
1153 {
1154 struct v4l2_fmtdesc *f = arg;
1155 enum v4l2_buf_type type;
1156 unsigned int index;
1157
1158 index = f->index;
1159 type = f->type;
1160 switch (type) {
1161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1162 if (index >= ARRAY_SIZE(formats))
1163 return -EINVAL;
1164 memset(f,0,sizeof(*f));
1165 f->index = index;
1166 f->type = type;
1167 strlcpy(f->description,formats[index].name,sizeof(f->description));
1168 f->pixelformat = formats[index].fourcc;
1169 break;
1170 default:
1171 return -EINVAL;
1172 }
1173 return 0;
1174 }
1175 case VIDIOC_G_FMT:
1176 {
1177 struct v4l2_format *f = arg;
1178 return cx8800_g_fmt(dev,fh,f);
1179 }
1180 case VIDIOC_S_FMT:
1181 {
1182 struct v4l2_format *f = arg;
1183 return cx8800_s_fmt(dev,fh,f);
1184 }
1185 case VIDIOC_TRY_FMT:
1186 {
1187 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f);
1189 }
1190
1191 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF:
1193 {
1194 struct video_mbuf *mbuf = arg;
1195 struct videobuf_queue *q;
1196 struct v4l2_requestbuffers req;
1197 unsigned int i;
1198
1199 q = get_queue(fh);
1200 memset(&req,0,sizeof(req));
1201 req.type = q->type;
1202 req.count = 8;
1203 req.memory = V4L2_MEMORY_MMAP;
1204 err = videobuf_reqbufs(q,&req);
1205 if (err < 0)
1206 return err;
1207 memset(mbuf,0,sizeof(*mbuf));
1208 mbuf->frames = req.count;
1209 mbuf->size = 0;
1210 for (i = 0; i < mbuf->frames; i++) {
1211 mbuf->offsets[i] = q->bufs[i]->boff;
1212 mbuf->size += q->bufs[i]->bsize;
1213 }
1214 return 0;
1215 }
1216 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg);
1218
1219 case VIDIOC_QUERYBUF:
1220 return videobuf_querybuf(get_queue(fh), arg);
1221
1222 case VIDIOC_QBUF:
1223 return videobuf_qbuf(get_queue(fh), arg);
1224
1225 case VIDIOC_DQBUF:
1226 return videobuf_dqbuf(get_queue(fh), arg,
1227 file->f_flags & O_NONBLOCK);
1228
1229 case VIDIOC_STREAMON:
1230 {
1231 int res = get_ressource(fh);
1232
1233 if (!res_get(dev,fh,res))
1234 return -EBUSY;
1235 return videobuf_streamon(get_queue(fh));
1236 }
1237 case VIDIOC_STREAMOFF:
1238 {
1239 int res = get_ressource(fh);
1240
1241 err = videobuf_streamoff(get_queue(fh));
1242 if (err < 0)
1243 return err;
1244 res_free(dev,fh,res);
1245 return 0;
1246 }
1247
1248 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 }
1251 return 0;
1252}
1253
1254int 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)
1256{
1257 int err;
1258
1259 if (video_debug > 1)
1260 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 switch (cmd) {
1125 /* ---------- tv norms ---------- */ 1266 /* ---------- tv norms ---------- */
1126 case VIDIOC_ENUMSTD: 1267 case VIDIOC_ENUMSTD:
1127 { 1268 {
@@ -1156,9 +1297,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1156 if (i == ARRAY_SIZE(tvnorms)) 1297 if (i == ARRAY_SIZE(tvnorms))
1157 return -EINVAL; 1298 return -EINVAL;
1158 1299
1159 down(&dev->lock); 1300 down(&core->lock);
1160 cx88_set_tvnorm(dev->core,&tvnorms[i]); 1301 cx88_set_tvnorm(core,&tvnorms[i]);
1161 up(&dev->lock); 1302 up(&core->lock);
1162 return 0; 1303 return 0;
1163 } 1304 }
1164 1305
@@ -1199,7 +1340,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1199 { 1340 {
1200 unsigned int *i = arg; 1341 unsigned int *i = arg;
1201 1342
1202 *i = dev->core->input; 1343 *i = core->input;
1203 return 0; 1344 return 0;
1204 } 1345 }
1205 case VIDIOC_S_INPUT: 1346 case VIDIOC_S_INPUT:
@@ -1208,55 +1349,15 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1208 1349
1209 if (*i >= 4) 1350 if (*i >= 4)
1210 return -EINVAL; 1351 return -EINVAL;
1211 down(&dev->lock); 1352 down(&core->lock);
1212 cx88_newstation(core); 1353 cx88_newstation(core);
1213 video_mux(dev,*i); 1354 video_mux(core,*i);
1214 up(&dev->lock); 1355 up(&core->lock);
1215 return 0; 1356 return 0;
1216 } 1357 }
1217 1358
1218 1359
1219 1360
1220 /* --- capture ioctls ---------------------------------------- */
1221 case VIDIOC_ENUM_FMT:
1222 {
1223 struct v4l2_fmtdesc *f = arg;
1224 enum v4l2_buf_type type;
1225 unsigned int index;
1226
1227 index = f->index;
1228 type = f->type;
1229 switch (type) {
1230 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1231 if (index >= ARRAY_SIZE(formats))
1232 return -EINVAL;
1233 memset(f,0,sizeof(*f));
1234 f->index = index;
1235 f->type = type;
1236 strlcpy(f->description,formats[index].name,sizeof(f->description));
1237 f->pixelformat = formats[index].fourcc;
1238 break;
1239 default:
1240 return -EINVAL;
1241 }
1242 return 0;
1243 }
1244 case VIDIOC_G_FMT:
1245 {
1246 struct v4l2_format *f = arg;
1247 return cx8800_g_fmt(dev,fh,f);
1248 }
1249 case VIDIOC_S_FMT:
1250 {
1251 struct v4l2_format *f = arg;
1252 return cx8800_s_fmt(dev,fh,f);
1253 }
1254 case VIDIOC_TRY_FMT:
1255 {
1256 struct v4l2_format *f = arg;
1257 return cx8800_try_fmt(dev,fh,f);
1258 }
1259
1260 /* --- controls ---------------------------------------------- */ 1361 /* --- controls ---------------------------------------------- */
1261 case VIDIOC_QUERYCTRL: 1362 case VIDIOC_QUERYCTRL:
1262 { 1363 {
@@ -1277,9 +1378,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1277 return 0; 1378 return 0;
1278 } 1379 }
1279 case VIDIOC_G_CTRL: 1380 case VIDIOC_G_CTRL:
1280 return get_control(dev,arg); 1381 return get_control(core,arg);
1281 case VIDIOC_S_CTRL: 1382 case VIDIOC_S_CTRL:
1282 return set_control(dev,arg); 1383 return set_control(core,arg);
1283 1384
1284 /* --- tuner ioctls ------------------------------------------ */ 1385 /* --- tuner ioctls ------------------------------------------ */
1285 case VIDIOC_G_TUNER: 1386 case VIDIOC_G_TUNER:
@@ -1323,10 +1424,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1323 if (UNSET == core->tuner_type) 1424 if (UNSET == core->tuner_type)
1324 return -EINVAL; 1425 return -EINVAL;
1325 1426
1326 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1427 /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
1327 f->frequency = dev->freq; 1428 f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1429 f->frequency = core->freq;
1328 1430
1329 cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f); 1431 cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
1330 1432
1331 return 0; 1433 return 0;
1332 } 1434 }
@@ -1338,83 +1440,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1338 return -EINVAL; 1440 return -EINVAL;
1339 if (f->tuner != 0) 1441 if (f->tuner != 0)
1340 return -EINVAL; 1442 return -EINVAL;
1341 if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV) 1443 if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV)
1342 return -EINVAL; 1444 return -EINVAL;
1343 if (1 == fh->radio && f->type != V4L2_TUNER_RADIO) 1445 if (1 == radio && f->type != V4L2_TUNER_RADIO)
1344 return -EINVAL; 1446 return -EINVAL;
1345 down(&dev->lock); 1447 down(&core->lock);
1346 dev->freq = f->frequency; 1448 core->freq = f->frequency;
1347 cx88_newstation(core); 1449 cx88_newstation(core);
1348 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); 1450 cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
1349 1451
1350 /* When changing channels it is required to reset TVAUDIO */ 1452 /* When changing channels it is required to reset TVAUDIO */
1351 msleep (10); 1453 msleep (10);
1352 cx88_set_tvaudio(core); 1454 cx88_set_tvaudio(core);
1353 1455
1354 up(&dev->lock); 1456 up(&core->lock);
1355 return 0;
1356 }
1357
1358 /* --- streaming capture ------------------------------------- */
1359 case VIDIOCGMBUF:
1360 {
1361 struct video_mbuf *mbuf = arg;
1362 struct videobuf_queue *q;
1363 struct v4l2_requestbuffers req;
1364 unsigned int i;
1365
1366 q = get_queue(fh);
1367 memset(&req,0,sizeof(req));
1368 req.type = q->type;
1369 req.count = 8;
1370 req.memory = V4L2_MEMORY_MMAP;
1371 err = videobuf_reqbufs(q,&req);
1372 if (err < 0)
1373 return err;
1374 memset(mbuf,0,sizeof(*mbuf));
1375 mbuf->frames = req.count;
1376 mbuf->size = 0;
1377 for (i = 0; i < mbuf->frames; i++) {
1378 mbuf->offsets[i] = q->bufs[i]->boff;
1379 mbuf->size += q->bufs[i]->bsize;
1380 }
1381 return 0;
1382 }
1383 case VIDIOC_REQBUFS:
1384 return videobuf_reqbufs(get_queue(fh), arg);
1385
1386 case VIDIOC_QUERYBUF:
1387 return videobuf_querybuf(get_queue(fh), arg);
1388
1389 case VIDIOC_QBUF:
1390 return videobuf_qbuf(get_queue(fh), arg);
1391
1392 case VIDIOC_DQBUF:
1393 return videobuf_dqbuf(get_queue(fh), arg,
1394 file->f_flags & O_NONBLOCK);
1395
1396 case VIDIOC_STREAMON:
1397 {
1398 int res = get_ressource(fh);
1399
1400 if (!res_get(dev,fh,res))
1401 return -EBUSY;
1402 return videobuf_streamon(get_queue(fh));
1403 }
1404 case VIDIOC_STREAMOFF:
1405 {
1406 int res = get_ressource(fh);
1407
1408 err = videobuf_streamoff(get_queue(fh));
1409 if (err < 0)
1410 return err;
1411 res_free(dev,fh,res);
1412 return 0; 1457 return 0;
1413 } 1458 }
1414 1459
1415 default: 1460 default:
1416 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 1461 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1417 video_do_ioctl); 1462 driver_ioctl);
1418 } 1463 }
1419 return 0; 1464 return 0;
1420} 1465}
@@ -1461,7 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1461 memset(t,0,sizeof(*t)); 1506 memset(t,0,sizeof(*t));
1462 strcpy(t->name, "Radio"); 1507 strcpy(t->name, "Radio");
1463 1508
1464 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t); 1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1465 return 0; 1510 return 0;
1466 } 1511 }
1467 case VIDIOC_ENUMINPUT: 1512 case VIDIOC_ENUMINPUT:
@@ -1501,8 +1546,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1501 if (v->tuner) /* Only tuner 0 */ 1546 if (v->tuner) /* Only tuner 0 */
1502 return -EINVAL; 1547 return -EINVAL;
1503 1548
1504 cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v); 1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1505 return 0; 1550 return 0;
1506 } 1551 }
1507 case VIDIOC_S_TUNER: 1552 case VIDIOC_S_TUNER:
1508 { 1553 {
@@ -1511,7 +1556,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1511 if (0 != t->index) 1556 if (0 != t->index)
1512 return -EINVAL; 1557 return -EINVAL;
1513 1558
1514 cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t); 1559 cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
1515 1560
1516 return 0; 1561 return 0;
1517 } 1562 }
@@ -1569,7 +1614,7 @@ static void cx8800_vid_timeout(unsigned long data)
1569 struct cx88_buffer *buf; 1614 struct cx88_buffer *buf;
1570 unsigned long flags; 1615 unsigned long flags;
1571 1616
1572 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); 1617 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
1573 1618
1574 cx_clear(MO_VID_DMACNTRL, 0x11); 1619 cx_clear(MO_VID_DMACNTRL, 0x11);
1575 cx_clear(VID_CAPTURE_CONTROL, 0x06); 1620 cx_clear(VID_CAPTURE_CONTROL, 0x06);
@@ -1614,14 +1659,14 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
1614 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); 1659 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
1615 cx_clear(MO_VID_DMACNTRL, 0x11); 1660 cx_clear(MO_VID_DMACNTRL, 0x11);
1616 cx_clear(VID_CAPTURE_CONTROL, 0x06); 1661 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1617 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); 1662 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
1618 } 1663 }
1619 1664
1620 /* risc1 y */ 1665 /* risc1 y */
1621 if (status & 0x01) { 1666 if (status & 0x01) {
1622 spin_lock(&dev->slock); 1667 spin_lock(&dev->slock);
1623 count = cx_read(MO_VIDY_GPCNT); 1668 count = cx_read(MO_VIDY_GPCNT);
1624 cx88_wakeup(dev->core, &dev->vidq, count); 1669 cx88_wakeup(core, &dev->vidq, count);
1625 spin_unlock(&dev->slock); 1670 spin_unlock(&dev->slock);
1626 } 1671 }
1627 1672
@@ -1629,7 +1674,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
1629 if (status & 0x08) { 1674 if (status & 0x08) {
1630 spin_lock(&dev->slock); 1675 spin_lock(&dev->slock);
1631 count = cx_read(MO_VBI_GPCNT); 1676 count = cx_read(MO_VBI_GPCNT);
1632 cx88_wakeup(dev->core, &dev->vbiq, count); 1677 cx88_wakeup(core, &dev->vbiq, count);
1633 spin_unlock(&dev->slock); 1678 spin_unlock(&dev->slock);
1634 } 1679 }
1635 1680
@@ -1798,7 +1843,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1798 } 1843 }
1799 1844
1800 /* initialize driver struct */ 1845 /* initialize driver struct */
1801 init_MUTEX(&dev->lock);
1802 spin_lock_init(&dev->slock); 1846 spin_lock_init(&dev->slock);
1803 core->tvnorm = tvnorms; 1847 core->tvnorm = tvnorms;
1804 1848
@@ -1835,6 +1879,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1835 request_module("tuner"); 1879 request_module("tuner");
1836 if (core->tda9887_conf) 1880 if (core->tda9887_conf)
1837 request_module("tda9887"); 1881 request_module("tda9887");
1882
1838 /* register v4l devices */ 1883 /* register v4l devices */
1839 dev->video_dev = cx88_vdev_init(core,dev->pci, 1884 dev->video_dev = cx88_vdev_init(core,dev->pci,
1840 &cx8800_video_template,"video"); 1885 &cx8800_video_template,"video");
@@ -1878,11 +1923,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1878 pci_set_drvdata(pci_dev,dev); 1923 pci_set_drvdata(pci_dev,dev);
1879 1924
1880 /* initial device configuration */ 1925 /* initial device configuration */
1881 down(&dev->lock); 1926 down(&core->lock);
1882 init_controls(dev); 1927 init_controls(core);
1883 cx88_set_tvnorm(dev->core,tvnorms); 1928 cx88_set_tvnorm(core,tvnorms);
1884 video_mux(dev,0); 1929 video_mux(core,0);
1885 up(&dev->lock); 1930 up(&core->lock);
1886 1931
1887 /* start tvaudio thread */ 1932 /* start tvaudio thread */
1888 if (core->tuner_type != TUNER_ABSENT) 1933 if (core->tuner_type != TUNER_ABSENT)
@@ -1902,14 +1947,15 @@ fail_free:
1902static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1903{ 1948{
1904 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core;
1905 1951
1906 /* stop thread */ 1952 /* stop thread */
1907 if (dev->core->kthread) { 1953 if (core->kthread) {
1908 kthread_stop(dev->core->kthread); 1954 kthread_stop(core->kthread);
1909 dev->core->kthread = NULL; 1955 core->kthread = NULL;
1910 } 1956 }
1911 1957
1912 cx88_shutdown(dev->core); /* FIXME */ 1958 cx88_shutdown(core); /* FIXME */
1913 pci_disable_device(pci_dev); 1959 pci_disable_device(pci_dev);
1914 1960
1915 /* unregister stuff */ 1961 /* unregister stuff */
@@ -1921,7 +1967,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1921 /* free memory */ 1967 /* free memory */
1922 btcx_riscmem_free(dev->pci,&dev->vidq.stopper); 1968 btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
1923 list_del(&dev->devlist); 1969 list_del(&dev->devlist);
1924 cx88_core_put(dev->core,dev->pci); 1970 cx88_core_put(core,dev->pci);
1925 kfree(dev); 1971 kfree(dev);
1926} 1972}
1927 1973
@@ -1945,7 +1991,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
1945 spin_unlock(&dev->slock); 1991 spin_unlock(&dev->slock);
1946 1992
1947 /* FIXME -- shutdown device */ 1993 /* FIXME -- shutdown device */
1948 cx88_shutdown(dev->core); 1994 cx88_shutdown(core);
1949 1995
1950 pci_save_state(pci_dev); 1996 pci_save_state(pci_dev);
1951 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { 1997 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -1959,16 +2005,32 @@ static int cx8800_resume(struct pci_dev *pci_dev)
1959{ 2005{
1960 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 2006 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1961 struct cx88_core *core = dev->core; 2007 struct cx88_core *core = dev->core;
2008 int err;
1962 2009
1963 if (dev->state.disabled) { 2010 if (dev->state.disabled) {
1964 pci_enable_device(pci_dev); 2011 err=pci_enable_device(pci_dev);
2012 if (err) {
2013 printk(KERN_ERR "%s: can't enable device\n",
2014 core->name);
2015 return err;
2016 }
2017
1965 dev->state.disabled = 0; 2018 dev->state.disabled = 0;
1966 } 2019 }
1967 pci_set_power_state(pci_dev, PCI_D0); 2020 err= pci_set_power_state(pci_dev, PCI_D0);
2021 if (err) {
2022 printk(KERN_ERR "%s: can't enable device\n",
2023 core->name);
2024
2025 pci_disable_device(pci_dev);
2026 dev->state.disabled = 1;
2027
2028 return err;
2029 }
1968 pci_restore_state(pci_dev); 2030 pci_restore_state(pci_dev);
1969 2031
1970 /* FIXME: re-initialize hardware */ 2032 /* FIXME: re-initialize hardware */
1971 cx88_reset(dev->core); 2033 cx88_reset(core);
1972 2034
1973 /* restart video+vbi capture */ 2035 /* restart video+vbi capture */
1974 spin_lock(&dev->slock); 2036 spin_lock(&dev->slock);
@@ -2030,6 +2092,8 @@ static void cx8800_fini(void)
2030module_init(cx8800_init); 2092module_init(cx8800_init);
2031module_exit(cx8800_fini); 2093module_exit(cx8800_fini);
2032 2094
2095EXPORT_SYMBOL(cx88_do_ioctl);
2096
2033/* ----------------------------------------------------------- */ 2097/* ----------------------------------------------------------- */
2034/* 2098/*
2035 * Local variables: 2099 * Local variables:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index da65dc92787c..f48dd4353568 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88.h,v 1.70 2005/07/24 17:44:09 mkrufky Exp $
3 * 2 *
4 * v4l2 device driver for cx2388x based TV cards 3 * v4l2 device driver for cx2388x based TV cards
5 * 4 *
@@ -35,7 +34,7 @@
35#include "btcx-risc.h" 34#include "btcx-risc.h"
36#include "cx88-reg.h" 35#include "cx88-reg.h"
37 36
38#include <linux/utsname.h> 37#include <linux/version.h>
39#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) 38#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
40 39
41#ifndef TRUE 40#ifndef TRUE
@@ -48,6 +47,9 @@
48 47
49#define CX88_MAXBOARDS 8 48#define CX88_MAXBOARDS 8
50 49
50/* Max number of inputs by card */
51#define MAX_CX88_INPUT 8
52
51/* ----------------------------------------------------------- */ 53/* ----------------------------------------------------------- */
52/* defines and enums */ 54/* defines and enums */
53 55
@@ -199,7 +201,7 @@ struct cx88_board {
199 unsigned char tuner_addr; 201 unsigned char tuner_addr;
200 unsigned char radio_addr; 202 unsigned char radio_addr;
201 int tda9887_conf; 203 int tda9887_conf;
202 struct cx88_input input[8]; 204 struct cx88_input input[MAX_CX88_INPUT];
203 struct cx88_input radio; 205 struct cx88_input radio;
204 int blackbird:1; 206 int blackbird:1;
205 int dvb:1; 207 int dvb:1;
@@ -288,6 +290,11 @@ struct cx88_core {
288 290
289 /* IR remote control state */ 291 /* IR remote control state */
290 struct cx88_IR *ir; 292 struct cx88_IR *ir;
293
294 struct semaphore lock;
295
296 /* various v4l controls */
297 u32 freq;
291}; 298};
292 299
293struct cx8800_dev; 300struct cx8800_dev;
@@ -323,8 +330,7 @@ struct cx8800_suspend_state {
323struct cx8800_dev { 330struct cx8800_dev {
324 struct cx88_core *core; 331 struct cx88_core *core;
325 struct list_head devlist; 332 struct list_head devlist;
326 struct semaphore lock; 333 spinlock_t slock;
327 spinlock_t slock;
328 334
329 /* various device info */ 335 /* various device info */
330 unsigned int resources; 336 unsigned int resources;
@@ -342,7 +348,6 @@ struct cx8800_dev {
342 struct cx88_dmaqueue vbiq; 348 struct cx88_dmaqueue vbiq;
343 349
344 /* various v4l controls */ 350 /* various v4l controls */
345 u32 freq;
346 351
347 /* other global state info */ 352 /* other global state info */
348 struct cx8800_suspend_state state; 353 struct cx8800_suspend_state state;
@@ -350,14 +355,8 @@ struct cx8800_dev {
350 355
351/* ----------------------------------------------------------- */ 356/* ----------------------------------------------------------- */
352/* function 1: audio/alsa stuff */ 357/* function 1: audio/alsa stuff */
358/* =============> moved to cx88-alsa.c <====================== */
353 359
354struct cx8801_dev {
355 struct cx88_core *core;
356
357 /* pci i/o */
358 struct pci_dev *pci;
359 unsigned char pci_rev,pci_lat;
360};
361 360
362/* ----------------------------------------------------------- */ 361/* ----------------------------------------------------------- */
363/* function 2: mpeg stuff */ 362/* function 2: mpeg stuff */
@@ -373,8 +372,7 @@ struct cx8802_suspend_state {
373 372
374struct cx8802_dev { 373struct cx8802_dev {
375 struct cx88_core *core; 374 struct cx88_core *core;
376 struct semaphore lock; 375 spinlock_t slock;
377 spinlock_t slock;
378 376
379 /* pci i/o */ 377 /* pci i/o */
380 struct pci_dev *pci; 378 struct pci_dev *pci;
@@ -553,8 +551,21 @@ void cx8802_fini_common(struct cx8802_dev *dev);
553int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state); 551int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
554int cx8802_resume_common(struct pci_dev *pci_dev); 552int cx8802_resume_common(struct pci_dev *pci_dev);
555 553
554/* ----------------------------------------------------------- */
555/* cx88-video.c */
556extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
557 struct cx88_core *core, unsigned int cmd,
558 void *arg, v4l2_kioctl driver_ioctl);
559
560/* ----------------------------------------------------------- */
561/* cx88-blackbird.c */
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
565
556/* 566/*
557 * Local variables: 567 * Local variables:
558 * c-basic-offset: 8 568 * c-basic-offset: 8
559 * End: 569 * End:
570 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
560 */ 571 */
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index a565823330aa..cf292da8fdd5 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
3 * 2 *
4 * Copyright (c) 2003 Gerd Knorr 3 * Copyright (c) 2003 Gerd Knorr
5 * Copyright (c) 2003 Pavel Machek 4 * Copyright (c) 2003 Pavel Machek
@@ -354,6 +353,7 @@ static int ir_probe(struct device *dev)
354 ir->input.id.vendor = sub->core->pci->vendor; 353 ir->input.id.vendor = sub->core->pci->vendor;
355 ir->input.id.product = sub->core->pci->device; 354 ir->input.id.product = sub->core->pci->device;
356 } 355 }
356 ir->input.dev = &sub->core->pci->dev;
357 357
358 if (ir->polling) { 358 if (ir->polling) {
359 INIT_WORK(&ir->work, ir_work, ir); 359 INIT_WORK(&ir->work, ir_work, ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 1e273ff3f956..67105b9804a2 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: ir-kbd-i2c.c,v 1.11 2005/07/07 16:42:11 mchehab Exp $
3 * 2 *
4 * keyboard input driver for i2c IR remote controls 3 * keyboard input driver for i2c IR remote controls
5 * 4 *
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index ca02f6f14b00..f0d43fc2632f 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -124,10 +124,14 @@ module_param(standard, int, 0644);
124module_param(amsound, int, 0644); 124module_param(amsound, int, 0644);
125module_param(dolby, int, 0644); 125module_param(dolby, int, 0644);
126 126
127MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler");
127MODULE_PARM_DESC(once, "No continuous stereo monitoring"); 128MODULE_PARM_DESC(once, "No continuous stereo monitoring");
128MODULE_PARM_DESC(debug, "Enable debug messages"); 129MODULE_PARM_DESC(debug, "Enable debug messages");
130MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
129MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); 131MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
130MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); 132MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
133MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
134
131 135
132MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); 136MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
133MODULE_AUTHOR("Gerd Knorr"); 137MODULE_AUTHOR("Gerd Knorr");
@@ -1452,7 +1456,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1452 client_template.addr = addr; 1456 client_template.addr = addr;
1453 1457
1454 if (-1 == msp3400c_reset(&client_template)) { 1458 if (-1 == msp3400c_reset(&client_template)) {
1455 dprintk("msp3400: no chip found\n"); 1459 dprintk("msp34xx: no chip found\n");
1456 return -1; 1460 return -1;
1457 } 1461 }
1458 1462
@@ -1478,7 +1482,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1478 if (-1 == msp3400c_reset(c)) { 1482 if (-1 == msp3400c_reset(c)) {
1479 kfree(msp); 1483 kfree(msp);
1480 kfree(c); 1484 kfree(c);
1481 dprintk("msp3400: no chip found\n"); 1485 dprintk("msp34xx: no chip found\n");
1482 return -1; 1486 return -1;
1483 } 1487 }
1484 1488
@@ -1488,7 +1492,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1488 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { 1492 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1489 kfree(msp); 1493 kfree(msp);
1490 kfree(c); 1494 kfree(c);
1491 printk("msp3400: error while reading chip version\n"); 1495 dprintk("msp34xx: error while reading chip version\n");
1492 return -1; 1496 return -1;
1493 } 1497 }
1494 1498
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index 023f33056a4f..2d9ff40f0b09 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4 3
5#ifndef MSP3400_H 4#ifndef MSP3400_H
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 2fb7c2d1787a..972aa5e0aeef 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
3 * 2 *
4 * i2c tv tuner chip device driver 3 * i2c tv tuner chip device driver
5 * controls microtune tuners, mt2032 + mt2050 at the moment. 4 * controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -494,6 +493,7 @@ int microtune_init(struct i2c_client *c)
494 memset(buf,0,sizeof(buf)); 493 memset(buf,0,sizeof(buf));
495 t->tv_freq = NULL; 494 t->tv_freq = NULL;
496 t->radio_freq = NULL; 495 t->radio_freq = 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);
diff --git a/drivers/media/video/rds.h b/drivers/media/video/rds.h
new file mode 100644
index 000000000000..30337d0f1a87
--- /dev/null
+++ b/drivers/media/video/rds.h
@@ -0,0 +1,48 @@
1/*
2
3 Types and defines needed for RDS. This is included by
4 saa6588.c and every driver (e.g. bttv-driver.c) that wants
5 to use the saa6588 module.
6
7 Instead of having a seperate rds.h, I'd prefer to include
8 this stuff in one of the already existing files like tuner.h
9
10 (c) 2005 by Hans J. Koch
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 as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more 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*/
27
28#ifndef _RDS_H
29#define _RDS_H
30
31struct rds_command {
32 unsigned int block_count;
33 int result;
34 unsigned char *buffer;
35 struct file *instance;
36 poll_table *event_list;
37};
38
39#define RDS_CMD_OPEN _IOW('R',1,int)
40#define RDS_CMD_CLOSE _IOW('R',2,int)
41#define RDS_CMD_READ _IOR('R',3,int)
42#define RDS_CMD_POLL _IOR('R',4,int)
43
44#endif
45
46
47
48
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
new file mode 100644
index 000000000000..1a657a70ff43
--- /dev/null
+++ b/drivers/media/video/saa6588.c
@@ -0,0 +1,534 @@
1/*
2 Driver for SAA6588 RDS decoder
3
4 (c) 2005 Hans J. Koch
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
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/i2c.h>
25#include <linux/types.h>
26#include <linux/videodev.h>
27#include <linux/init.h>
28#include <linux/errno.h>
29#include <linux/slab.h>
30#include <linux/poll.h>
31#include <linux/wait.h>
32#include <asm/uaccess.h>
33
34#include <media/id.h>
35
36#include "rds.h"
37
38/* Addresses to scan */
39static unsigned short normal_i2c[] = {
40 0x20 >> 1,
41 0x22 >> 1,
42 I2C_CLIENT_END,
43};
44
45I2C_CLIENT_INSMOD;
46
47/* insmod options */
48static unsigned int debug = 0;
49static unsigned int xtal = 0;
50static unsigned int rbds = 0;
51static unsigned int plvl = 0;
52static unsigned int bufblocks = 100;
53
54MODULE_PARM(debug, "i");
55MODULE_PARM_DESC(debug, "enable debug messages");
56MODULE_PARM(xtal, "i");
57MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
58MODULE_PARM(rbds, "i");
59MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0");
60MODULE_PARM(plvl, "i");
61MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
62MODULE_PARM(bufblocks, "i");
63MODULE_PARM_DESC(bufblocks, "number of buffered blocks, default 100");
64
65MODULE_DESCRIPTION("v4l2 driver module for SAA6588 RDS decoder");
66MODULE_AUTHOR("Hans J. Koch <koch@hjk-az.de>");
67
68MODULE_LICENSE("GPL");
69
70/* ---------------------------------------------------------------------- */
71
72#define UNSET (-1U)
73#define PREFIX "saa6588: "
74#define dprintk if (debug) printk
75
76struct saa6588 {
77 struct i2c_client client;
78 struct work_struct work;
79 struct timer_list timer;
80 spinlock_t lock;
81 unsigned char *buffer;
82 unsigned int buf_size;
83 unsigned int rd_index;
84 unsigned int wr_index;
85 unsigned int block_count;
86 unsigned char last_blocknum;
87 wait_queue_head_t read_queue;
88 int data_available_for_read;
89};
90
91static struct i2c_driver driver;
92static struct i2c_client client_template;
93
94/* ---------------------------------------------------------------------- */
95
96/*
97 * SAA6588 defines
98 */
99
100/* Initialization and mode control byte (0w) */
101
102/* bit 0+1 (DAC0/DAC1) */
103#define cModeStandard 0x00
104#define cModeFastPI 0x01
105#define cModeReducedRequest 0x02
106#define cModeInvalid 0x03
107
108/* bit 2 (RBDS) */
109#define cProcessingModeRDS 0x00
110#define cProcessingModeRBDS 0x04
111
112/* bit 3+4 (SYM0/SYM1) */
113#define cErrCorrectionNone 0x00
114#define cErrCorrection2Bits 0x08
115#define cErrCorrection5Bits 0x10
116#define cErrCorrectionNoneRBDS 0x18
117
118/* bit 5 (NWSY) */
119#define cSyncNormal 0x00
120#define cSyncRestart 0x20
121
122/* bit 6 (TSQD) */
123#define cSigQualityDetectOFF 0x00
124#define cSigQualityDetectON 0x40
125
126/* bit 7 (SQCM) */
127#define cSigQualityTriggered 0x00
128#define cSigQualityContinous 0x80
129
130/* Pause level and flywheel control byte (1w) */
131
132/* bits 0..5 (FEB0..FEB5) */
133#define cFlywheelMaxBlocksMask 0x3F
134#define cFlywheelDefault 0x20
135
136/* bits 6+7 (PL0/PL1) */
137#define cPauseLevel_11mV 0x00
138#define cPauseLevel_17mV 0x40
139#define cPauseLevel_27mV 0x80
140#define cPauseLevel_43mV 0xC0
141
142/* Pause time/oscillator frequency/quality detector control byte (1w) */
143
144/* bits 0..4 (SQS0..SQS4) */
145#define cQualityDetectSensMask 0x1F
146#define cQualityDetectDefault 0x0F
147
148/* bit 5 (SOSC) */
149#define cSelectOscFreqOFF 0x00
150#define cSelectOscFreqON 0x20
151
152/* bit 6+7 (PTF0/PTF1) */
153#define cOscFreq_4332kHz 0x00
154#define cOscFreq_8664kHz 0x40
155#define cOscFreq_12996kHz 0x80
156#define cOscFreq_17328kHz 0xC0
157
158/* ---------------------------------------------------------------------- */
159
160static int block_to_user_buf(struct saa6588 *s, unsigned char *user_buf)
161{
162 int i;
163
164 if (s->rd_index == s->wr_index) {
165 if (debug > 2)
166 dprintk(PREFIX "Read: buffer empty.\n");
167 return 0;
168 }
169
170 if (debug > 2) {
171 dprintk(PREFIX "Read: ");
172 for (i = s->rd_index; i < s->rd_index + 3; i++)
173 dprintk("0x%02x ", s->buffer[i]);
174 }
175
176 if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3))
177 return -EFAULT;
178
179 s->rd_index += 3;
180 if (s->rd_index >= s->buf_size)
181 s->rd_index = 0;
182 s->block_count--;
183
184 if (debug > 2)
185 dprintk("%d blocks total.\n", s->block_count);
186
187 return 1;
188}
189
190static void read_from_buf(struct saa6588 *s, struct rds_command *a)
191{
192 unsigned long flags;
193
194 unsigned char *buf_ptr = a->buffer; /* This is a user space buffer! */
195 unsigned int i;
196 unsigned int rd_blocks;
197
198 a->result = 0;
199 if (!a->buffer)
200 return;
201
202 while (!s->data_available_for_read) {
203 int ret = wait_event_interruptible(s->read_queue,
204 s->data_available_for_read);
205 if (ret == -ERESTARTSYS) {
206 a->result = -EINTR;
207 return;
208 }
209 }
210
211 spin_lock_irqsave(&s->lock, flags);
212 rd_blocks = a->block_count;
213 if (rd_blocks > s->block_count)
214 rd_blocks = s->block_count;
215
216 if (!rd_blocks)
217 return;
218
219 for (i = 0; i < rd_blocks; i++) {
220 if (block_to_user_buf(s, buf_ptr)) {
221 buf_ptr += 3;
222 a->result++;
223 } else
224 break;
225 }
226 a->result *= 3;
227 s->data_available_for_read = (s->block_count > 0);
228 spin_unlock_irqrestore(&s->lock, flags);
229}
230
231static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
232{
233 unsigned int i;
234
235 if (debug > 3)
236 dprintk(PREFIX "New block: ");
237
238 for (i = 0; i < 3; ++i) {
239 if (debug > 3)
240 dprintk("0x%02x ", blockbuf[i]);
241 s->buffer[s->wr_index] = blockbuf[i];
242 s->wr_index++;
243 }
244
245 if (s->wr_index >= s->buf_size)
246 s->wr_index = 0;
247
248 if (s->wr_index == s->rd_index) {
249 s->rd_index++;
250 if (s->rd_index >= s->buf_size)
251 s->rd_index = 0;
252 } else
253 s->block_count++;
254
255 if (debug > 3)
256 dprintk("%d blocks total.\n", s->block_count);
257}
258
259static void saa6588_i2c_poll(struct saa6588 *s)
260{
261 unsigned long flags;
262 unsigned char tmpbuf[6];
263 unsigned char blocknum;
264 unsigned char tmp;
265
266 /* Although we only need 3 bytes, we have to read at least 6.
267 SAA6588 returns garbage otherwise */
268 if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
269 if (debug > 1)
270 dprintk(PREFIX "read error!\n");
271 return;
272 }
273
274 blocknum = tmpbuf[0] >> 5;
275 if (blocknum == s->last_blocknum) {
276 if (debug > 3)
277 dprintk("Saw block %d again.\n", blocknum);
278 return;
279 }
280
281 s->last_blocknum = blocknum;
282
283 /*
284 Byte order according to v4l2 specification:
285
286 Byte 0: Least Significant Byte of RDS Block
287 Byte 1: Most Significant Byte of RDS Block
288 Byte 2 Bit 7: Error bit. Indicates that an uncorrectable error
289 occurred during reception of this block.
290 Bit 6: Corrected bit. Indicates that an error was
291 corrected for this data block.
292 Bits 5-3: Received Offset. Indicates the offset received
293 by the sync system.
294 Bits 2-0: Offset Name. Indicates the offset applied to this data.
295
296 SAA6588 byte order is Status-MSB-LSB, so we have to swap the
297 first and the last of the 3 bytes block.
298 */
299
300 tmp = tmpbuf[2];
301 tmpbuf[2] = tmpbuf[0];
302 tmpbuf[0] = tmp;
303
304 tmp = blocknum;
305 tmp |= blocknum << 3; /* Received offset == Offset Name (OK ?) */
306 if ((tmpbuf[2] & 0x03) == 0x03)
307 tmp |= 0x80; /* uncorrectable error */
308 else if ((tmpbuf[2] & 0x03) != 0x00)
309 tmp |= 0x40; /* corrected error */
310 tmpbuf[2] = tmp; /* Is this enough ? Should we also check other bits ? */
311
312 spin_lock_irqsave(&s->lock, flags);
313 block_to_buf(s, tmpbuf);
314 spin_unlock_irqrestore(&s->lock, flags);
315 s->data_available_for_read = 1;
316 wake_up_interruptible(&s->read_queue);
317}
318
319static void saa6588_timer(unsigned long data)
320{
321 struct saa6588 *s = (struct saa6588 *)data;
322
323 schedule_work(&s->work);
324}
325
326static void saa6588_work(void *data)
327{
328 struct saa6588 *s = (struct saa6588 *)data;
329
330 saa6588_i2c_poll(s);
331 mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */
332}
333
334static int saa6588_configure(struct saa6588 *s)
335{
336 unsigned char buf[3];
337 int rc;
338
339 buf[0] = cSyncRestart;
340 if (rbds)
341 buf[0] |= cProcessingModeRBDS;
342
343 buf[1] = cFlywheelDefault;
344 switch (plvl) {
345 case 0:
346 buf[1] |= cPauseLevel_11mV;
347 break;
348 case 1:
349 buf[1] |= cPauseLevel_17mV;
350 break;
351 case 2:
352 buf[1] |= cPauseLevel_27mV;
353 break;
354 case 3:
355 buf[1] |= cPauseLevel_43mV;
356 break;
357 default: /* nothing */
358 break;
359 }
360
361 buf[2] = cQualityDetectDefault | cSelectOscFreqON;
362
363 switch (xtal) {
364 case 0:
365 buf[2] |= cOscFreq_4332kHz;
366 break;
367 case 1:
368 buf[2] |= cOscFreq_8664kHz;
369 break;
370 case 2:
371 buf[2] |= cOscFreq_12996kHz;
372 break;
373 case 3:
374 buf[2] |= cOscFreq_17328kHz;
375 break;
376 default: /* nothing */
377 break;
378 }
379
380 dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
381 buf[0], buf[1], buf[2]);
382
383 if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
384 printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
385
386 return 0;
387}
388
389/* ---------------------------------------------------------------------- */
390
391static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
392{
393 struct saa6588 *s;
394 client_template.adapter = adap;
395 client_template.addr = addr;
396
397 printk(PREFIX "chip found @ 0x%x\n", addr << 1);
398
399 if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
400 return -ENOMEM;
401
402 s->buf_size = bufblocks * 3;
403
404 if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
405 kfree(s);
406 return -ENOMEM;
407 }
408 s->client = client_template;
409 s->block_count = 0;
410 s->wr_index = 0;
411 s->rd_index = 0;
412 s->last_blocknum = 0xff;
413 init_waitqueue_head(&s->read_queue);
414 s->data_available_for_read = 0;
415 i2c_set_clientdata(&s->client, s);
416 i2c_attach_client(&s->client);
417
418 saa6588_configure(s);
419
420 /* start polling via eventd */
421 INIT_WORK(&s->work, saa6588_work, s);
422 init_timer(&s->timer);
423 s->timer.function = saa6588_timer;
424 s->timer.data = (unsigned long)s;
425 schedule_work(&s->work);
426
427 return 0;
428}
429
430static int saa6588_probe(struct i2c_adapter *adap)
431{
432#ifdef I2C_CLASS_TV_ANALOG
433 if (adap->class & I2C_CLASS_TV_ANALOG)
434 return i2c_probe(adap, &addr_data, saa6588_attach);
435#else
436 switch (adap->id) {
437 case I2C_ALGO_BIT | I2C_HW_B_BT848:
438 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
439 case I2C_ALGO_SAA7134:
440 return i2c_probe(adap, &addr_data, saa6588_attach);
441 break;
442 }
443#endif
444 return 0;
445}
446
447static int saa6588_detach(struct i2c_client *client)
448{
449 struct saa6588 *s = i2c_get_clientdata(client);
450
451 del_timer_sync(&s->timer);
452 flush_scheduled_work();
453
454 i2c_detach_client(client);
455 kfree(s->buffer);
456 kfree(s);
457 return 0;
458}
459
460static int saa6588_command(struct i2c_client *client, unsigned int cmd,
461 void *arg)
462{
463 struct saa6588 *s = i2c_get_clientdata(client);
464 struct rds_command *a = (struct rds_command *)arg;
465
466 switch (cmd) {
467 /* --- open() for /dev/radio --- */
468 case RDS_CMD_OPEN:
469 a->result = 0; /* return error if chip doesn't work ??? */
470 break;
471 /* --- close() for /dev/radio --- */
472 case RDS_CMD_CLOSE:
473 s->data_available_for_read = 1;
474 wake_up_interruptible(&s->read_queue);
475 a->result = 0;
476 break;
477 /* --- read() for /dev/radio --- */
478 case RDS_CMD_READ:
479 read_from_buf(s, a);
480 break;
481 /* --- poll() for /dev/radio --- */
482 case RDS_CMD_POLL:
483 a->result = 0;
484 if (s->data_available_for_read) {
485 a->result |= POLLIN | POLLRDNORM;
486 }
487 poll_wait(a->instance, &s->read_queue, a->event_list);
488 break;
489
490 default:
491 /* nothing */
492 break;
493 }
494 return 0;
495}
496
497/* ----------------------------------------------------------------------- */
498
499static struct i2c_driver driver = {
500 .owner = THIS_MODULE,
501 .name = "i2c saa6588 driver",
502 .id = -1, /* FIXME */
503 .flags = I2C_DF_NOTIFY,
504 .attach_adapter = saa6588_probe,
505 .detach_client = saa6588_detach,
506 .command = saa6588_command,
507};
508
509static struct i2c_client client_template = {
510 .name = "saa6588",
511 .flags = I2C_CLIENT_ALLOW_USE,
512 .driver = &driver,
513};
514
515static int __init saa6588_init_module(void)
516{
517 return i2c_add_driver(&driver);
518}
519
520static void __exit saa6588_cleanup_module(void)
521{
522 i2c_del_driver(&driver);
523}
524
525module_init(saa6588_init_module);
526module_exit(saa6588_cleanup_module);
527
528/*
529 * Overrides for Emacs so that we follow Linus's tabbing style.
530 * ---------------------------------------------------------------------------
531 * Local variables:
532 * c-basic-offset: 8
533 * End:
534 */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 88b71a20b602..acc7a4335e23 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-cards.c,v 1.80 2005/07/07 01:49:30 mkrufky Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * card-specific stuff. 4 * card-specific stuff.
@@ -1373,7 +1372,7 @@ struct saa7134_board saa7134_boards[] = {
1373 .inputs = {{ 1372 .inputs = {{
1374 .name = name_comp1, 1373 .name = name_comp1,
1375 .vmux = 1, 1374 .vmux = 1,
1376 .amux = LINE2, 1375 .amux = LINE1,
1377 },{ 1376 },{
1378 .name = name_tv, 1377 .name = name_tv,
1379 .vmux = 3, 1378 .vmux = 3,
@@ -1382,7 +1381,7 @@ struct saa7134_board saa7134_boards[] = {
1382 },{ 1381 },{
1383 .name = name_svideo, 1382 .name = name_svideo,
1384 .vmux = 8, 1383 .vmux = 8,
1385 .amux = LINE2, 1384 .amux = LINE1,
1386 }}, 1385 }},
1387 .radio = { 1386 .radio = {
1388 .name = name_radio, 1387 .name = name_radio,
@@ -2001,6 +2000,115 @@ struct saa7134_board saa7134_boards[] = {
2001 .gpio = 0x000, 2000 .gpio = 0x000,
2002 }, 2001 },
2003 }, 2002 },
2003 [SAA7134_BOARD_FLYTV_DIGIMATRIX] = {
2004 .name = "FlyTV mini Asus Digimatrix",
2005 .audio_clock = 0x00200000,
2006 .tuner_type = TUNER_LG_NTSC_TALN_MINI,
2007 .radio_type = UNSET,
2008 .tuner_addr = ADDR_UNSET,
2009 .radio_addr = ADDR_UNSET,
2010 .inputs = {{
2011 .name = name_tv,
2012 .vmux = 1,
2013 .amux = TV,
2014 .tv = 1,
2015 },{
2016 .name = name_tv_mono,
2017 .vmux = 1,
2018 .amux = LINE2,
2019 .tv = 1,
2020 },{
2021 .name = name_comp1,
2022 .vmux = 0,
2023 .amux = LINE2,
2024 },{
2025 .name = name_comp2,
2026 .vmux = 3,
2027 .amux = LINE2,
2028 },{
2029 .name = name_svideo,
2030 .vmux = 8,
2031 .amux = LINE2,
2032 }},
2033 .radio = {
2034 .name = name_radio, /* radio unconfirmed */
2035 .amux = LINE2,
2036 },
2037 },
2038 [SAA7134_BOARD_KWORLD_TERMINATOR] = {
2039 /* Kworld V-Stream Studio TV Terminator */
2040 /* "James Webb <jrwebb@qwest.net> */
2041 .name = "V-Stream Studio TV Terminator",
2042 .audio_clock = 0x00187de7,
2043 .tuner_type = TUNER_PHILIPS_TDA8290,
2044 .radio_type = UNSET,
2045 .tuner_addr = ADDR_UNSET,
2046 .radio_addr = ADDR_UNSET,
2047 .gpiomask = 1 << 21,
2048 .inputs = {{
2049 .name = name_tv,
2050 .vmux = 1,
2051 .amux = TV,
2052 .gpio = 0x0000000,
2053 .tv = 1,
2054 },{
2055 .name = name_comp1, /* Composite input */
2056 .vmux = 3,
2057 .amux = LINE2,
2058 .gpio = 0x0000000,
2059 },{
2060 .name = name_svideo, /* S-Video input */
2061 .vmux = 8,
2062 .amux = LINE2,
2063 .gpio = 0x0000000,
2064 }},
2065 .radio = {
2066 .name = name_radio,
2067 .amux = TV,
2068 .gpio = 0x0200000,
2069 },
2070 },
2071 [SAA7134_BOARD_YUAN_TUN900] = {
2072 /* FIXME:
2073 * S-Video and composite sources untested.
2074 * Radio not working.
2075 * Remote control not yet implemented.
2076 * From : codemaster@webgeeks.be */
2077 .name = "Yuan TUN-900 (saa7135)",
2078 .audio_clock = 0x00187de7,
2079 .tuner_type = TUNER_PHILIPS_TDA8290,
2080 .radio_type = UNSET,
2081 .tuner_addr= ADDR_UNSET,
2082 .radio_addr= ADDR_UNSET,
2083 .gpiomask = 0x00010003,
2084 .inputs = {{
2085 .name = name_tv,
2086 .vmux = 1,
2087 .amux = TV,
2088 .tv = 1,
2089 .gpio = 0x01,
2090 },{
2091 .name = name_comp1,
2092 .vmux = 0,
2093 .amux = LINE2,
2094 .gpio = 0x02,
2095 },{
2096 .name = name_svideo,
2097 .vmux = 6,
2098 .amux = LINE2,
2099 .gpio = 0x02,
2100 }},
2101 .radio = {
2102 .name = name_radio,
2103 .amux = LINE1,
2104 .gpio = 0x00010003,
2105 },
2106 .mute = {
2107 .name = name_mute,
2108 .amux = TV,
2109 .gpio = 0x01,
2110 },
2111 },
2004}; 2112};
2005 2113
2006 2114
@@ -2272,12 +2380,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
2272 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR, 2380 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
2273 },{ 2381 },{
2274 .vendor = PCI_VENDOR_ID_PHILIPS, 2382 .vendor = PCI_VENDOR_ID_PHILIPS,
2275 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2276 .subvendor = 0x1131,
2277 .subdevice = 0,
2278 .driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
2279 },{
2280 .vendor = PCI_VENDOR_ID_PHILIPS,
2281 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2383 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2282 .subvendor = 0x1461, /* Avermedia Technologies Inc */ 2384 .subvendor = 0x1461, /* Avermedia Technologies Inc */
2283 .subdevice = 0x9715, 2385 .subdevice = 0x9715,
@@ -2346,6 +2448,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2346 .subvendor = 0x4e42, 2448 .subvendor = 0x4e42,
2347 .subdevice = 0x0502, 2449 .subdevice = 0x0502,
2348 .driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS, 2450 .driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
2451 },{
2452 .vendor = PCI_VENDOR_ID_PHILIPS,
2453 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2454 .subvendor = 0x1043,
2455 .subdevice = 0x0210, /* mini pci NTSC version */
2456 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
2457 },{
2458 .vendor = PCI_VENDOR_ID_PHILIPS,
2459 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2460 .subvendor = 0x1043,
2461 .subdevice = 0x0210, /* mini pci PAL/SECAM version */
2462 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
2349 2463
2350 },{ 2464 },{
2351 /* --- boards without eeprom + subsystem ID --- */ 2465 /* --- boards without eeprom + subsystem ID --- */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 1dbe61755e9f..e5e36f3c6250 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-core.c,v 1.39 2005/07/05 17:37:35 nsh Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * driver core 4 * driver core
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 8be6a90358c8..639ae51a052d 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-dvb.c,v 1.23 2005/07/24 22:12:47 mkrufky Exp $
3 * 2 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 3 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 * 4 *
@@ -29,7 +28,6 @@
29#include <linux/delay.h> 28#include <linux/delay.h>
30#include <linux/kthread.h> 29#include <linux/kthread.h>
31#include <linux/suspend.h> 30#include <linux/suspend.h>
32#include <linux/config.h>
33 31
34 32
35#include "saa7134-reg.h" 33#include "saa7134-reg.h"
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c85348d0239f..77b627eb6483 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $
3 * 2 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 3 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 * 4 *
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index eae6b529713f..711aa8e85fac 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-i2c.c,v 1.22 2005/07/22 04:09:41 mkrufky Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * i2c interface support 4 * i2c interface support
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 213740122fe6..1f456c4d76f2 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-input.c,v 1.21 2005/06/22 23:37:34 nsh Exp $
3 * 2 *
4 * handle saa7134 IR remotes via linux kernel input layer. 3 * handle saa7134 IR remotes via linux kernel input layer.
5 * 4 *
@@ -565,6 +564,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
565 ir->dev.id.vendor = dev->pci->vendor; 564 ir->dev.id.vendor = dev->pci->vendor;
566 ir->dev.id.product = dev->pci->device; 565 ir->dev.id.product = dev->pci->device;
567 } 566 }
567 ir->dev.dev = &dev->pci->dev;
568 568
569 /* all done */ 569 /* all done */
570 dev->remote = ir; 570 dev->remote = ir;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index b5bede95dbf5..c20630c82f1c 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-oss.c,v 1.17 2005/06/28 23:41:47 mkrufky Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * oss dsp interface 4 * oss dsp interface
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index 87734f22af7d..ae0c7a165390 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-reg.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 * 2 *
4 * philips saa7134 registers 3 * philips saa7134 registers
5 */ 4 */
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 4dd9f1b23928..463885601ab4 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-ts.c,v 1.15 2005/06/14 22:48:18 hhackmann Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * video4linux video interface 4 * video4linux video interface
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index eeafa5a71d2b..badf2f9e3072 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-tvaudio.c,v 1.30 2005/06/28 23:41:47 mkrufky Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * tv audio decoder (fm stereo, nicam, ...) 4 * tv audio decoder (fm stereo, nicam, ...)
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index 29e51cad2aaf..f4aee0af80e1 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * video4linux video interface 4 * video4linux video interface
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a4c2f751d097..35e5e85f669a 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134-video.c,v 1.36 2005/06/28 23:41:47 mkrufky Exp $
3 * 2 *
4 * device driver for philips saa7134 based TV cards 3 * device driver for philips saa7134 based TV cards
5 * video4linux video interface 4 * video4linux video interface
@@ -1368,29 +1367,7 @@ static int video_release(struct inode *inode, struct file *file)
1368 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); 1367 saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
1369 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); 1368 saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
1370 1369
1371 if (dev->tuner_type == TUNER_PHILIPS_TDA8290) { 1370 saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1372 u8 data[2];
1373 int ret;
1374 struct i2c_msg msg = {.addr=I2C_ADDR_TDA8290, .flags=0, .buf=data, .len = 2};
1375 data[0] = 0x21;
1376 data[1] = 0xc0;
1377 ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
1378 if (ret != 1)
1379 printk(KERN_ERR "TDA8290 access failure\n");
1380 msg.addr = I2C_ADDR_TDA8275;
1381 data[0] = 0x30;
1382 data[1] = 0xd0;
1383 ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
1384 if (ret != 1)
1385 printk(KERN_ERR "TDA8275 access failure\n");
1386 msg.addr = I2C_ADDR_TDA8290;
1387 data[0] = 0x21;
1388 data[1] = 0x80;
1389 i2c_transfer(&dev->i2c_adap, &msg, 1);
1390 data[0] = 0x00;
1391 data[1] = 0x02;
1392 i2c_transfer(&dev->i2c_adap, &msg, 1);
1393 }
1394 1371
1395 /* free stuff */ 1372 /* free stuff */
1396 videobuf_mmap_free(&fh->cap); 1373 videobuf_mmap_free(&fh->cap);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 2af0cb2a731b..3ea09142ec9c 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: saa7134.h,v 1.49 2005/07/13 17:25:25 mchehab Exp $
3 * 2 *
4 * v4l2 device driver for philips saa7134 based TV cards 3 * v4l2 device driver for philips saa7134 based TV cards
5 * 4 *
@@ -185,6 +184,9 @@ struct saa7134_format {
185#define SAA7134_BOARD_PHILIPS_TOUGH 61 184#define SAA7134_BOARD_PHILIPS_TOUGH 61
186#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62 185#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
187#define SAA7134_BOARD_KWORLD_XPERT 63 186#define SAA7134_BOARD_KWORLD_XPERT 63
187#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
188#define SAA7134_BOARD_KWORLD_TERMINATOR 65
189#define SAA7134_BOARD_YUAN_TUN900 66
188 190
189#define SAA7134_MAXBOARDS 8 191#define SAA7134_MAXBOARDS 8
190#define SAA7134_INPUT_MAX 8 192#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index a8b6a8df5109..c65f0c7680a2 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: tda8290.c,v 1.15 2005/07/08 20:21:33 mchehab Exp $
3 * 2 *
4 * i2c tv tuner chip device driver 3 * i2c tv tuner chip device driver
5 * controls the philips tda8290+75 tuner chip combo. 4 * controls the philips tda8290+75 tuner chip combo.
@@ -9,6 +8,9 @@
9#include <linux/delay.h> 8#include <linux/delay.h>
10#include <media/tuner.h> 9#include <media/tuner.h>
11 10
11#define I2C_ADDR_TDA8290 0x4b
12#define I2C_ADDR_TDA8275 0x61
13
12/* ---------------------------------------------------------------------- */ 14/* ---------------------------------------------------------------------- */
13 15
14struct freq_entry { 16struct freq_entry {
@@ -75,10 +77,12 @@ static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
75static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; 77static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
76static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B }; 78static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
77static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 }; 79static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
80static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
78static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 }; 81static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
79static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 }; 82static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
80static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 }; 83static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
81static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF }; 84static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
85static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
82static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 }; 86static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
83static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 }; 87static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
84static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 }; 88static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
@@ -117,6 +121,13 @@ static struct i2c_msg i2c_msg_epilog[] = {
117 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, 121 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on },
118}; 122};
119 123
124static struct i2c_msg i2c_msg_standby[] = {
125 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
126 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 },
127 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
128 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby },
129};
130
120static int tda8290_tune(struct i2c_client *c) 131static int tda8290_tune(struct i2c_client *c)
121{ 132{
122 struct tuner *t = i2c_get_clientdata(c); 133 struct tuner *t = i2c_get_clientdata(c);
@@ -205,6 +216,11 @@ static int has_signal(struct i2c_client *c)
205 return (afc & 0x80)? 65535:0; 216 return (afc & 0x80)? 65535:0;
206} 217}
207 218
219static void standby(struct i2c_client *c)
220{
221 i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby));
222}
223
208int tda8290_init(struct i2c_client *c) 224int tda8290_init(struct i2c_client *c)
209{ 225{
210 struct tuner *t = i2c_get_clientdata(c); 226 struct tuner *t = i2c_get_clientdata(c);
@@ -214,6 +230,7 @@ int tda8290_init(struct i2c_client *c)
214 t->tv_freq = set_tv_freq; 230 t->tv_freq = set_tv_freq;
215 t->radio_freq = set_radio_freq; 231 t->radio_freq = set_radio_freq;
216 t->has_signal = has_signal; 232 t->has_signal = has_signal;
233 t->standby = standby;
217 234
218 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); 235 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge));
219 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); 236 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init));
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index d60fc562aecd..0456dda2624d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -23,6 +23,7 @@
23 TDA9887 (world), TDA9885 (USA) 23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled! 24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134) 25 - KNC One TV-Station RDS (saa7134)
26 - Hauppauge PVR-150/500 (possibly more)
26*/ 27*/
27 28
28 29
@@ -49,7 +50,7 @@ MODULE_LICENSE("GPL");
49struct tda9887 { 50struct tda9887 {
50 struct i2c_client client; 51 struct i2c_client client;
51 v4l2_std_id std; 52 v4l2_std_id std;
52 unsigned int radio; 53 enum tuner_mode mode;
53 unsigned int config; 54 unsigned int config;
54 unsigned int pinnacle_id; 55 unsigned int pinnacle_id;
55 unsigned int using_v4l2; 56 unsigned int using_v4l2;
@@ -196,7 +197,7 @@ static struct tvnorm tvnorms[] = {
196 .b = ( cNegativeFmTV | 197 .b = ( cNegativeFmTV |
197 cQSS ), 198 cQSS ),
198 .c = ( cDeemphasisON | 199 .c = ( cDeemphasisON |
199 cDeemphasis50 ), 200 cDeemphasis75 ),
200 .e = ( cGating_36 | 201 .e = ( cGating_36 |
201 cAudioIF_4_5 | 202 cAudioIF_4_5 |
202 cVideoIF_45_75 ), 203 cVideoIF_45_75 ),
@@ -364,7 +365,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
364 struct tvnorm *norm = NULL; 365 struct tvnorm *norm = NULL;
365 int i; 366 int i;
366 367
367 if (t->radio) { 368 if (t->mode == T_RADIO) {
368 if (t->radio_mode == V4L2_TUNER_MODE_MONO) 369 if (t->radio_mode == V4L2_TUNER_MODE_MONO)
369 norm = &radio_mono; 370 norm = &radio_mono;
370 else 371 else
@@ -378,7 +379,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
378 } 379 }
379 } 380 }
380 if (NULL == norm) { 381 if (NULL == norm) {
381 dprintk(PREFIX "Oops: no tvnorm entry found\n"); 382 dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n");
382 return -1; 383 return -1;
383 } 384 }
384 385
@@ -519,6 +520,12 @@ static int tda9887_fixup_std(struct tda9887 *t)
519 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); 520 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
520 t->std = V4L2_STD_PAL_DK; 521 t->std = V4L2_STD_PAL_DK;
521 break; 522 break;
523 case '-':
524 /* default parameter, do nothing */
525 break;
526 default:
527 printk(PREFIX "pal= argument not recognised\n");
528 break;
522 } 529 }
523 } 530 }
524 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 531 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
@@ -535,6 +542,12 @@ static int tda9887_fixup_std(struct tda9887 *t)
535 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); 542 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
536 t->std = V4L2_STD_SECAM_L; 543 t->std = V4L2_STD_SECAM_L;
537 break; 544 break;
545 case '-':
546 /* default parameter, do nothing */
547 break;
548 default:
549 printk(PREFIX "secam= argument not recognised\n");
550 break;
538 } 551 }
539 } 552 }
540 return 0; 553 return 0;
@@ -569,6 +582,10 @@ static int tda9887_configure(struct tda9887 *t)
569 tda9887_set_config(t,buf); 582 tda9887_set_config(t,buf);
570 tda9887_set_insmod(t,buf); 583 tda9887_set_insmod(t,buf);
571 584
585 if (t->mode == T_STANDBY) {
586 buf[1] |= cForcedMuteAudioON;
587 }
588
572 589
573 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 590 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
574 buf[1],buf[2],buf[3]); 591 buf[1],buf[2],buf[3]);
@@ -653,10 +670,17 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
653 670
654 /* --- configuration --- */ 671 /* --- configuration --- */
655 case AUDC_SET_RADIO: 672 case AUDC_SET_RADIO:
656 t->radio = 1; 673 {
674 t->mode = T_RADIO;
657 tda9887_configure(t); 675 tda9887_configure(t);
658 break; 676 break;
659 677 }
678 case TUNER_SET_STANDBY:
679 {
680 t->mode = T_STANDBY;
681 tda9887_configure(t);
682 break;
683 }
660 case AUDC_CONFIG_PINNACLE: 684 case AUDC_CONFIG_PINNACLE:
661 { 685 {
662 int *i = arg; 686 int *i = arg;
@@ -689,7 +713,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
689 struct video_channel *vc = arg; 713 struct video_channel *vc = arg;
690 714
691 CHECK_V4L2; 715 CHECK_V4L2;
692 t->radio = 0; 716 t->mode = T_ANALOG_TV;
693 if (vc->norm < ARRAY_SIZE(map)) 717 if (vc->norm < ARRAY_SIZE(map))
694 t->std = map[vc->norm]; 718 t->std = map[vc->norm];
695 tda9887_fixup_std(t); 719 tda9887_fixup_std(t);
@@ -701,7 +725,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
701 v4l2_std_id *id = arg; 725 v4l2_std_id *id = arg;
702 726
703 SWITCH_V4L2; 727 SWITCH_V4L2;
704 t->radio = 0; 728 t->mode = T_ANALOG_TV;
705 t->std = *id; 729 t->std = *id;
706 tda9887_fixup_std(t); 730 tda9887_fixup_std(t);
707 tda9887_configure(t); 731 tda9887_configure(t);
@@ -713,14 +737,14 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
713 737
714 SWITCH_V4L2; 738 SWITCH_V4L2;
715 if (V4L2_TUNER_ANALOG_TV == f->type) { 739 if (V4L2_TUNER_ANALOG_TV == f->type) {
716 if (t->radio == 0) 740 if (t->mode == T_ANALOG_TV)
717 return 0; 741 return 0;
718 t->radio = 0; 742 t->mode = T_ANALOG_TV;
719 } 743 }
720 if (V4L2_TUNER_RADIO == f->type) { 744 if (V4L2_TUNER_RADIO == f->type) {
721 if (t->radio == 1) 745 if (t->mode == T_RADIO)
722 return 0; 746 return 0;
723 t->radio = 1; 747 t->mode = T_RADIO;
724 } 748 }
725 tda9887_configure(t); 749 tda9887_configure(t);
726 break; 750 break;
@@ -735,7 +759,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
735 }; 759 };
736 struct v4l2_tuner* tuner = arg; 760 struct v4l2_tuner* tuner = arg;
737 761
738 if (t->radio) { 762 if (t->mode == T_RADIO) {
739 __u8 reg = 0; 763 __u8 reg = 0;
740 tuner->afc=0; 764 tuner->afc=0;
741 if (1 == i2c_master_recv(&t->client,&reg,1)) 765 if (1 == i2c_master_recv(&t->client,&reg,1))
@@ -747,7 +771,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
747 { 771 {
748 struct v4l2_tuner* tuner = arg; 772 struct v4l2_tuner* tuner = arg;
749 773
750 if (t->radio) { 774 if (t->mode == T_RADIO) {
751 t->radio_mode = tuner->audmode; 775 t->radio_mode = tuner->audmode;
752 tda9887_configure (t); 776 tda9887_configure (t);
753 } 777 }
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index cebcc1fa68d1..38bf50943798 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -2,7 +2,6 @@
2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview 2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
3 * I2C address is allways 0xC0. 3 * I2C address is allways 0xC0.
4 * 4 *
5 * $Id: tea5767.c,v 1.27 2005/07/31 12:10:56 mchehab Exp $
6 * 5 *
7 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) 6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
8 * This code is placed under the terms of the GNU General Public License 7 * This code is placed under the terms of the GNU General Public License
@@ -205,11 +204,6 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
205 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; 204 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
206 buffer[4] = 0; 205 buffer[4] = 0;
207 206
208 if (t->mode == T_STANDBY) {
209 tuner_dbg("TEA5767 set to standby mode\n");
210 buffer[3] |= TEA5767_STDBY;
211 }
212
213 if (t->audmode == V4L2_TUNER_MODE_MONO) { 207 if (t->audmode == V4L2_TUNER_MODE_MONO) {
214 tuner_dbg("TEA5767 set to mono\n"); 208 tuner_dbg("TEA5767 set to mono\n");
215 buffer[2] |= TEA5767_MONO; 209 buffer[2] |= TEA5767_MONO;
@@ -290,13 +284,31 @@ static int tea5767_stereo(struct i2c_client *c)
290 return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0); 284 return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
291} 285}
292 286
287static void tea5767_standby(struct i2c_client *c)
288{
289 unsigned char buffer[5];
290 struct tuner *t = i2c_get_clientdata(c);
291 unsigned div, rc;
292
293 div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
294 buffer[0] = (div >> 8) & 0x3f;
295 buffer[1] = div & 0xff;
296 buffer[2] = TEA5767_PORT1_HIGH;
297 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
298 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
299 buffer[4] = 0;
300
301 if (5 != (rc = i2c_master_send(c, buffer, 5)))
302 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
303}
304
293int tea5767_autodetection(struct i2c_client *c) 305int tea5767_autodetection(struct i2c_client *c)
294{ 306{
295 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 307 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
296 int rc; 308 int rc;
297 struct tuner *t = i2c_get_clientdata(c); 309 struct tuner *t = i2c_get_clientdata(c);
298 310
299 if (7 != (rc = i2c_master_recv(c, buffer, 7))) { 311 if ((rc = i2c_master_recv(c, buffer, 7))< 5) {
300 tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc); 312 tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
301 return EINVAL; 313 return EINVAL;
302 } 314 }
@@ -313,15 +325,10 @@ int tea5767_autodetection(struct i2c_client *c)
313 * bit 0 : internally set to 0 325 * bit 0 : internally set to 0
314 * Byte 5: bit 7:0 : == 0 326 * Byte 5: bit 7:0 : == 0
315 */ 327 */
316 if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { 328 if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
317 tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); 329 tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
318 return EINVAL; 330 return EINVAL;
319 } 331 }
320 /* It seems that tea5767 returns 0xff after the 5th byte */
321 if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
322 tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n");
323 return EINVAL;
324 }
325 332
326 /* It seems that tea5767 returns 0xff after the 5th byte */ 333 /* It seems that tea5767 returns 0xff after the 5th byte */
327 if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) { 334 if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
@@ -337,14 +344,14 @@ int tea5767_tuner_init(struct i2c_client *c)
337{ 344{
338 struct tuner *t = i2c_get_clientdata(c); 345 struct tuner *t = i2c_get_clientdata(c);
339 346
340 tuner_info("type set to %d (%s)\n", t->type, 347 tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
341 "Philips TEA5767HN FM Radio");
342 strlcpy(c->name, "tea5767", sizeof(c->name)); 348 strlcpy(c->name, "tea5767", sizeof(c->name));
343 349
344 t->tv_freq = set_tv_freq; 350 t->tv_freq = set_tv_freq;
345 t->radio_freq = set_radio_freq; 351 t->radio_freq = set_radio_freq;
346 t->has_signal = tea5767_signal; 352 t->has_signal = tea5767_signal;
347 t->is_stereo = tea5767_stereo; 353 t->is_stereo = tea5767_stereo;
354 t->standby = tea5767_standby;
348 355
349 return (0); 356 return (0);
350} 357}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 3b1893c2ae3b..05572020af4d 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: tuner-core.c,v 1.63 2005/07/28 18:19:55 mchehab Exp $
3 * 2 *
4 * i2c tv tuner chip device driver 3 * i2c tv tuner chip device driver
5 * core core, i.e. kernel interfaces, registering and so on 4 * core core, i.e. kernel interfaces, registering and so on
@@ -182,6 +181,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
182 i2c_master_send(c, buffer, 4); 181 i2c_master_send(c, buffer, 4);
183 default_tuner_init(c); 182 default_tuner_init(c);
184 break; 183 break;
184 case TUNER_LG_TDVS_H062F:
185 /* Set the Auxiliary Byte. */
186 buffer[2] &= ~0x20;
187 buffer[2] |= 0x18;
188 buffer[3] = 0x20;
189 i2c_master_send(c, buffer, 4);
190 default_tuner_init(c);
191 break;
185 default: 192 default:
186 default_tuner_init(c); 193 default_tuner_init(c);
187 break; 194 break;
@@ -208,31 +215,31 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
208{ 215{
209 struct tuner *t = i2c_get_clientdata(c); 216 struct tuner *t = i2c_get_clientdata(c);
210 217
211 if (tun_setup->addr == ADDR_UNSET) { 218 if ((tun_setup->addr == ADDR_UNSET &&
212 if (t->mode_mask & tun_setup->mode_mask) 219 (t->mode_mask & tun_setup->mode_mask)) ||
220 tun_setup->addr == c->addr) {
213 set_type(c, tun_setup->type, tun_setup->mode_mask); 221 set_type(c, tun_setup->type, tun_setup->mode_mask);
214 } else if (tun_setup->addr == c->addr) {
215 set_type(c, tun_setup->type, tun_setup->mode_mask);
216 } 222 }
217} 223}
218 224
219static inline int check_mode(struct tuner *t, char *cmd) 225static inline int check_mode(struct tuner *t, char *cmd)
220{ 226{
221 if (1 << t->mode & t->mode_mask) { 227 if ((1 << t->mode & t->mode_mask) == 0) {
222 switch (t->mode) { 228 return EINVAL;
223 case V4L2_TUNER_RADIO: 229 }
224 tuner_dbg("Cmd %s accepted for radio\n", cmd); 230
225 break; 231 switch (t->mode) {
226 case V4L2_TUNER_ANALOG_TV: 232 case V4L2_TUNER_RADIO:
227 tuner_dbg("Cmd %s accepted for analog TV\n", cmd); 233 tuner_dbg("Cmd %s accepted for radio\n", cmd);
228 break; 234 break;
229 case V4L2_TUNER_DIGITAL_TV: 235 case V4L2_TUNER_ANALOG_TV:
230 tuner_dbg("Cmd %s accepted for digital TV\n", cmd); 236 tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
231 break; 237 break;
232 } 238 case V4L2_TUNER_DIGITAL_TV:
233 return 0; 239 tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
240 break;
234 } 241 }
235 return EINVAL; 242 return 0;
236} 243}
237 244
238static char pal[] = "-"; 245static char pal[] = "-";
@@ -274,6 +281,12 @@ static int tuner_fixup_std(struct tuner *t)
274 tuner_dbg ("insmod fixup: PAL => PAL-N\n"); 281 tuner_dbg ("insmod fixup: PAL => PAL-N\n");
275 t->std = V4L2_STD_PAL_N; 282 t->std = V4L2_STD_PAL_N;
276 break; 283 break;
284 case '-':
285 /* default parameter, do nothing */
286 break;
287 default:
288 tuner_warn ("pal= argument not recognised\n");
289 break;
277 } 290 }
278 } 291 }
279 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 292 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
@@ -290,6 +303,12 @@ static int tuner_fixup_std(struct tuner *t)
290 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n"); 303 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
291 t->std = V4L2_STD_SECAM_L; 304 t->std = V4L2_STD_SECAM_L;
292 break; 305 break;
306 case '-':
307 /* default parameter, do nothing */
308 break;
309 default:
310 tuner_warn ("secam= argument not recognised\n");
311 break;
293 } 312 }
294 } 313 }
295 314
@@ -406,20 +425,18 @@ static int tuner_detach(struct i2c_client *client)
406 425
407static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) 426static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
408{ 427{
409 if (mode != t->mode) { 428 if (mode == t->mode)
410 429 return 0;
411 t->mode = mode; 430
412 if (check_mode(t, cmd) == EINVAL) { 431 t->mode = mode;
413 t->mode = T_STANDBY; 432
414 if (V4L2_TUNER_RADIO == mode) { 433 if (check_mode(t, cmd) == EINVAL) {
415 set_tv_freq(client, 400 * 16); 434 t->mode = T_STANDBY;
416 } else { 435 if (t->standby)
417 set_radio_freq(client, 87.5 * 16000); 436 t->standby (client);
418 } 437 return EINVAL;
419 return EINVAL; 438 }
420 } 439 return 0;
421 }
422 return 0;
423} 440}
424 441
425#define switch_v4l2() if (!t->using_v4l2) \ 442#define switch_v4l2() if (!t->using_v4l2) \
@@ -453,6 +470,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
453 case AUDC_SET_RADIO: 470 case AUDC_SET_RADIO:
454 set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO"); 471 set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO");
455 break; 472 break;
473 case TUNER_SET_STANDBY:
474 {
475 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
476 return 0;
477 if (t->standby)
478 t->standby (client);
479 break;
480 }
456 case AUDC_CONFIG_PINNACLE: 481 case AUDC_CONFIG_PINNACLE:
457 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL) 482 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
458 return 0; 483 return 0;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index de0c93aeb75d..8edd73abe1d8 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: tuner-simple.c,v 1.43 2005/07/28 18:41:21 mchehab Exp $
3 * 2 *
4 * i2c tv tuner chip device driver 3 * i2c tv tuner chip device driver
5 * controls all those simple 4-control-bytes style tuners. 4 * controls all those simple 4-control-bytes style tuners.
@@ -102,6 +101,7 @@ struct tunertype
102 * "no float in kernel" rule. 101 * "no float in kernel" rule.
103 */ 102 */
104static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
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,
@@ -110,7 +110,6 @@ static struct tunertype tuners[] = {
110 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, 110 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
111 { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, 111 { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
112 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, 112 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
113
114 { "NoTuner", NoTuner, NOTUNER, 113 { "NoTuner", NoTuner, NOTUNER,
115 0,0,0x00,0x00,0x00,0x00,0x00}, 114 0,0,0x00,0x00,0x00,0x00,0x00},
116 { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, 115 { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
@@ -119,34 +118,34 @@ static struct tunertype tuners[] = {
119 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
120 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
121 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
122
123 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
124 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
125 { "Alps HSBH1", TEMIC, NTSC, 123 { "Alps HSBH1", TEMIC, NTSC,
126 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
127 { "Alps TSBE1",TEMIC,PAL, 125
126 /* 10-19 */
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
132 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
133 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
134 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
135 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
136 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
137 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
138 { "Alps TSCH6",Alps,NTSC, 137 { "Alps TSCH6", Alps, NTSC,
139 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
140 139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
141 { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
142 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
143 { "Philips NTSC_M (MK2)",Philips,NTSC, 141 { "Philips NTSC_M (MK2)", Philips, NTSC,
144 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
145 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
147 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
148 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
149 147
148 /* 20-29 */
150 { "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,
151 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
152 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
@@ -155,7 +154,6 @@ static struct tunertype tuners[] = {
155 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
156 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
157 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
158
159 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
160 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
161 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, 159 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
@@ -164,25 +162,24 @@ static struct tunertype tuners[] = {
164 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 162 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
165 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, 163 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
166 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, 164 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
167
168 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, 165 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
169 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 166 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
170 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, 167 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
171 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 168 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
169
170 /* 30-39 */
172 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, 171 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
173 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 172 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
174 { "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 */
175 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
176 175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
177 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
178 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 176 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
179 { "MT20xx universal", Microtune,PAL|NTSC, 177 { "MT20xx universal", Microtune, PAL|NTSC,
180 /* see mt20xx.c for details */ }, 178 /* see mt20xx.c for details */ },
181 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
182 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
183 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
184 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
185
186 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
187 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
188 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
@@ -192,42 +189,41 @@ static struct tunertype tuners[] = {
192 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
193 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
194 191
192 /* 40-49 */
195 { "HITACHI V7-J180AT", HITACHI, NTSC, 193 { "HITACHI V7-J180AT", HITACHI, NTSC,
196 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, 194 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 },
197 { "Philips PAL_MK (FI1216 MK)", Philips, PAL, 195 { "Philips PAL_MK (FI1216 MK)", Philips, PAL,
198 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
199 { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC, 197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
200 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
201 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
203
204 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
205 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
206 { "Microtune 4049 FM5",Microtune,PAL, 203 { "Microtune 4049 FM5", Microtune, PAL,
207 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
208 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
209 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
210 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
211 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
212
213 { "Tenna TNF 8831 BGFF)", Philips, PAL, 209 { "Tenna TNF 8831 BGFF)", Philips, PAL,
214 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
215 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
216 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
213
214 /* 50-59 */
217 { "TCL 2002N", TCL, NTSC, 215 { "TCL 2002N", TCL, NTSC,
218 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
219 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
220 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
221
222 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
223 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 220 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
224 { "Philips FQ1286", Philips, NTSC, 221 { "Philips FQ1286", Philips, NTSC,
225 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 */
226 { "tda8290+75", Philips,PAL|NTSC, 223 { "tda8290+75", Philips, PAL|NTSC,
227 /* see tda8290.c for details */ }, 224 /* see tda8290.c for details */ },
228 { "LG PAL (TAPE series)", LGINNOTEK, PAL, 225 { "LG PAL (TAPE series)", LGINNOTEK, PAL,
229 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
230
231 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
232 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
233 { "Philips FQ1236A MK4", Philips, NTSC, 229 { "Philips FQ1236A MK4", Philips, NTSC,
@@ -237,6 +233,7 @@ static struct tunertype tuners[] = {
237 { "Ymec TVision TVF-5533MF", Philips, NTSC, 233 { "Ymec TVision TVF-5533MF", Philips, NTSC,
238 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
239 235
236 /* 60-66 */
240 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
241 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
242 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
@@ -245,12 +242,12 @@ static struct tunertype tuners[] = {
245 /* see tea5767.c for details */}, 242 /* see tea5767.c for details */},
246 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
247 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
248 245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
249 { "LG TDVS-H062F/TUA6034", LGINNOTEK, NTSC,
250 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
251
252 { "Ymec TVF66T5-B/DFF", Philips, PAL, 247 { "Ymec TVF66T5-B/DFF", Philips, PAL,
253 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,
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
254}; 251};
255 252
256unsigned const int tuner_count = ARRAY_SIZE(tuners); 253unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -471,6 +468,10 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
471 case TUNER_LG_PAL_FM: 468 case TUNER_LG_PAL_FM:
472 buffer[3] = 0xa5; 469 buffer[3] = 0xa5;
473 break; 470 break;
471 case TUNER_MICROTUNE_4049FM5:
472 div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
473 buffer[3] = 0xa4;
474 break;
474 default: 475 default:
475 buffer[3] = 0xa4; 476 buffer[3] = 0xa4;
476 break; 477 break;
@@ -497,6 +498,7 @@ int default_tuner_init(struct i2c_client *c)
497 t->radio_freq = default_set_radio_freq; 498 t->radio_freq = default_set_radio_freq;
498 t->has_signal = tuner_signal; 499 t->has_signal = tuner_signal;
499 t->is_stereo = tuner_stereo; 500 t->is_stereo = tuner_stereo;
501 t->standby = NULL;
500 502
501 return 0; 503 return 0;
502} 504}
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 258724b2d6d2..1c31ef52f863 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -46,7 +46,17 @@ MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47 47
48#define UNSET (-1U) 48#define UNSET (-1U)
49#define dprintk if (debug) printk 49
50#define tvaudio_info(fmt, arg...) do {\
51 printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
52 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
53#define tvaudio_warn(fmt, arg...) do {\
54 printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \
55 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
56#define tvaudio_dbg(fmt, arg...) do {\
57 if (debug) \
58 printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
59 chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
50 60
51/* ---------------------------------------------------------------------- */ 61/* ---------------------------------------------------------------------- */
52/* our structs */ 62/* our structs */
@@ -162,23 +172,24 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
162 unsigned char buffer[2]; 172 unsigned char buffer[2];
163 173
164 if (-1 == subaddr) { 174 if (-1 == subaddr) {
165 dprintk("%s: chip_write: 0x%x\n", chip->c.name, val); 175 tvaudio_dbg("%s: chip_write: 0x%x\n",
176 chip->c.name, val);
166 chip->shadow.bytes[1] = val; 177 chip->shadow.bytes[1] = val;
167 buffer[0] = val; 178 buffer[0] = val;
168 if (1 != i2c_master_send(&chip->c,buffer,1)) { 179 if (1 != i2c_master_send(&chip->c,buffer,1)) {
169 printk(KERN_WARNING "%s: I/O error (write 0x%x)\n", 180 tvaudio_warn("%s: I/O error (write 0x%x)\n",
170 chip->c.name, val); 181 chip->c.name, val);
171 return -1; 182 return -1;
172 } 183 }
173 } else { 184 } else {
174 dprintk("%s: chip_write: reg%d=0x%x\n", 185 tvaudio_dbg("%s: chip_write: reg%d=0x%x\n",
175 chip->c.name, subaddr, val); 186 chip->c.name, subaddr, val);
176 chip->shadow.bytes[subaddr+1] = val; 187 chip->shadow.bytes[subaddr+1] = val;
177 buffer[0] = subaddr; 188 buffer[0] = subaddr;
178 buffer[1] = val; 189 buffer[1] = val;
179 if (2 != i2c_master_send(&chip->c,buffer,2)) { 190 if (2 != i2c_master_send(&chip->c,buffer,2)) {
180 printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n", 191 tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n",
181 chip->c.name, subaddr, val); 192 chip->c.name, subaddr, val);
182 return -1; 193 return -1;
183 } 194 }
184 } 195 }
@@ -202,29 +213,30 @@ static int chip_read(struct CHIPSTATE *chip)
202 unsigned char buffer; 213 unsigned char buffer;
203 214
204 if (1 != i2c_master_recv(&chip->c,&buffer,1)) { 215 if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
205 printk(KERN_WARNING "%s: I/O error (read)\n", chip->c.name); 216 tvaudio_warn("%s: I/O error (read)\n",
217 chip->c.name);
206 return -1; 218 return -1;
207 } 219 }
208 dprintk("%s: chip_read: 0x%x\n", chip->c.name, buffer); 220 tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name,buffer);
209 return buffer; 221 return buffer;
210} 222}
211 223
212static int chip_read2(struct CHIPSTATE *chip, int subaddr) 224static int chip_read2(struct CHIPSTATE *chip, int subaddr)
213{ 225{
214 unsigned char write[1]; 226 unsigned char write[1];
215 unsigned char read[1]; 227 unsigned char read[1];
216 struct i2c_msg msgs[2] = { 228 struct i2c_msg msgs[2] = {
217 { chip->c.addr, 0, 1, write }, 229 { chip->c.addr, 0, 1, write },
218 { chip->c.addr, I2C_M_RD, 1, read } 230 { chip->c.addr, I2C_M_RD, 1, read }
219 }; 231 };
220 write[0] = subaddr; 232 write[0] = subaddr;
221 233
222 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { 234 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
223 printk(KERN_WARNING "%s: I/O error (read2)\n", chip->c.name); 235 tvaudio_warn("%s: I/O error (read2)\n", chip->c.name);
224 return -1; 236 return -1;
225 } 237 }
226 dprintk("%s: chip_read2: reg%d=0x%x\n", 238 tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n",
227 chip->c.name, subaddr, read[0]); 239 chip->c.name,subaddr,read[0]);
228 return read[0]; 240 return read[0];
229} 241}
230 242
@@ -236,17 +248,19 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
236 return 0; 248 return 0;
237 249
238 /* update our shadow register set; print bytes if (debug > 0) */ 250 /* update our shadow register set; print bytes if (debug > 0) */
239 dprintk("%s: chip_cmd(%s): reg=%d, data:", 251 tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:",
240 chip->c.name, name, cmd->bytes[0]); 252 chip->c.name,name,cmd->bytes[0]);
241 for (i = 1; i < cmd->count; i++) { 253 for (i = 1; i < cmd->count; i++) {
242 dprintk(" 0x%x",cmd->bytes[i]); 254 if (debug)
255 printk(" 0x%x",cmd->bytes[i]);
243 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i]; 256 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
244 } 257 }
245 dprintk("\n"); 258 if (debug)
259 printk("\n");
246 260
247 /* send data to the chip */ 261 /* send data to the chip */
248 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { 262 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
249 printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.name, name); 263 tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name);
250 return -1; 264 return -1;
251 } 265 }
252 return 0; 266 return 0;
@@ -261,19 +275,19 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
261 275
262static void chip_thread_wake(unsigned long data) 276static void chip_thread_wake(unsigned long data)
263{ 277{
264 struct CHIPSTATE *chip = (struct CHIPSTATE*)data; 278 struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
265 wake_up_interruptible(&chip->wq); 279 wake_up_interruptible(&chip->wq);
266} 280}
267 281
268static int chip_thread(void *data) 282static int chip_thread(void *data)
269{ 283{
270 DECLARE_WAITQUEUE(wait, current); 284 DECLARE_WAITQUEUE(wait, current);
271 struct CHIPSTATE *chip = data; 285 struct CHIPSTATE *chip = data;
272 struct CHIPDESC *desc = chiplist + chip->type; 286 struct CHIPDESC *desc = chiplist + chip->type;
273 287
274 daemonize("%s", chip->c.name); 288 daemonize("%s", chip->c.name);
275 allow_signal(SIGTERM); 289 allow_signal(SIGTERM);
276 dprintk("%s: thread started\n", chip->c.name); 290 tvaudio_dbg("%s: thread started\n", chip->c.name);
277 291
278 for (;;) { 292 for (;;) {
279 add_wait_queue(&chip->wq, &wait); 293 add_wait_queue(&chip->wq, &wait);
@@ -285,7 +299,7 @@ static int chip_thread(void *data)
285 try_to_freeze(); 299 try_to_freeze();
286 if (chip->done || signal_pending(current)) 300 if (chip->done || signal_pending(current))
287 break; 301 break;
288 dprintk("%s: thread wakeup\n", chip->c.name); 302 tvaudio_dbg("%s: thread wakeup\n", chip->c.name);
289 303
290 /* don't do anything for radio or if mode != auto */ 304 /* don't do anything for radio or if mode != auto */
291 if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) 305 if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
@@ -298,8 +312,8 @@ static int chip_thread(void *data)
298 mod_timer(&chip->wt, jiffies+2*HZ); 312 mod_timer(&chip->wt, jiffies+2*HZ);
299 } 313 }
300 314
301 dprintk("%s: thread exiting\n", chip->c.name); 315 tvaudio_dbg("%s: thread exiting\n", chip->c.name);
302 complete_and_exit(&chip->texit, 0); 316 complete_and_exit(&chip->texit, 0);
303 return 0; 317 return 0;
304} 318}
305 319
@@ -309,9 +323,9 @@ static void generic_checkmode(struct CHIPSTATE *chip)
309 int mode = desc->getmode(chip); 323 int mode = desc->getmode(chip);
310 324
311 if (mode == chip->prevmode) 325 if (mode == chip->prevmode)
312 return; 326 return;
313 327
314 dprintk("%s: thread checkmode\n", chip->c.name); 328 tvaudio_dbg("%s: thread checkmode\n", chip->c.name);
315 chip->prevmode = mode; 329 chip->prevmode = mode;
316 330
317 if (mode & VIDEO_SOUND_STEREO) 331 if (mode & VIDEO_SOUND_STEREO)
@@ -358,8 +372,8 @@ static int tda9840_getmode(struct CHIPSTATE *chip)
358 if (val & TDA9840_ST_STEREO) 372 if (val & TDA9840_ST_STEREO)
359 mode |= VIDEO_SOUND_STEREO; 373 mode |= VIDEO_SOUND_STEREO;
360 374
361 dprintk ("tda9840_getmode(): raw chip read: %d, return: %d\n", 375 tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n",
362 val, mode); 376 val, mode);
363 return mode; 377 return mode;
364} 378}
365 379
@@ -654,8 +668,8 @@ static int tda9873_getmode(struct CHIPSTATE *chip)
654 mode |= VIDEO_SOUND_STEREO; 668 mode |= VIDEO_SOUND_STEREO;
655 if (val & TDA9873_DUAL) 669 if (val & TDA9873_DUAL)
656 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 670 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
657 dprintk ("tda9873_getmode(): raw chip read: %d, return: %d\n", 671 tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n",
658 val, mode); 672 val, mode);
659 return mode; 673 return mode;
660} 674}
661 675
@@ -665,12 +679,12 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
665 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ 679 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
666 680
667 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { 681 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
668 dprintk("tda9873_setmode(): external input\n"); 682 tvaudio_dbg("tda9873_setmode(): external input\n");
669 return; 683 return;
670 } 684 }
671 685
672 dprintk("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); 686 tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
673 dprintk("tda9873_setmode(): sw_data = %d\n", sw_data); 687 tvaudio_dbg("tda9873_setmode(): sw_data = %d\n", sw_data);
674 688
675 switch (mode) { 689 switch (mode) {
676 case VIDEO_SOUND_MONO: 690 case VIDEO_SOUND_MONO:
@@ -691,7 +705,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
691 } 705 }
692 706
693 chip_write(chip, TDA9873_SW, sw_data); 707 chip_write(chip, TDA9873_SW, sw_data);
694 dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n", 708 tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n",
695 mode, sw_data); 709 mode, sw_data);
696} 710}
697 711
@@ -828,9 +842,9 @@ static int tda9874a_setup(struct CHIPSTATE *chip)
828 } else { /* dic == 0x07 */ 842 } else { /* dic == 0x07 */
829 chip_write(chip, TDA9874A_AMCONR, 0xfb); 843 chip_write(chip, TDA9874A_AMCONR, 0xfb);
830 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); 844 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
831 chip_write(chip, TDA9874A_AOSR, 0x00); // or 0x10 845 chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
832 } 846 }
833 dprintk("tda9874a_setup(): %s [0x%02X].\n", 847 tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n",
834 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); 848 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
835 return 1; 849 return 1;
836} 850}
@@ -873,7 +887,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip)
873 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 887 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
874 } 888 }
875 889
876 dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", 890 tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
877 dsr, nsr, necr, mode); 891 dsr, nsr, necr, mode);
878 return mode; 892 return mode;
879} 893}
@@ -919,7 +933,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
919 chip_write(chip, TDA9874A_AOSR, aosr); 933 chip_write(chip, TDA9874A_AOSR, aosr);
920 chip_write(chip, TDA9874A_MDACOSR, mdacosr); 934 chip_write(chip, TDA9874A_MDACOSR, mdacosr);
921 935
922 dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", 936 tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
923 mode, aosr, mdacosr); 937 mode, aosr, mdacosr);
924 938
925 } else { /* dic == 0x07 */ 939 } else { /* dic == 0x07 */
@@ -954,7 +968,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
954 chip_write(chip, TDA9874A_FMMR, fmmr); 968 chip_write(chip, TDA9874A_FMMR, fmmr);
955 chip_write(chip, TDA9874A_AOSR, aosr); 969 chip_write(chip, TDA9874A_AOSR, aosr);
956 970
957 dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", 971 tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
958 mode, fmmr, aosr); 972 mode, fmmr, aosr);
959 } 973 }
960} 974}
@@ -968,10 +982,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
968 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) 982 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
969 return 0; 983 return 0;
970 984
971 dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); 985 tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
972 986
973 if((dic == 0x11)||(dic == 0x07)) { 987 if((dic == 0x11)||(dic == 0x07)) {
974 printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h"); 988 tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h");
975 tda9874a_dic = dic; /* remember device id. */ 989 tda9874a_dic = dic; /* remember device id. */
976 return 1; 990 return 1;
977 } 991 }
@@ -1146,7 +1160,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1146/* ---------------------------------------------------------------------- */ 1160/* ---------------------------------------------------------------------- */
1147/* audio chip descriptions - defines+functions for TA8874Z */ 1161/* audio chip descriptions - defines+functions for TA8874Z */
1148 1162
1149// write 1st byte 1163/* write 1st byte */
1150#define TA8874Z_LED_STE 0x80 1164#define TA8874Z_LED_STE 0x80
1151#define TA8874Z_LED_BIL 0x40 1165#define TA8874Z_LED_BIL 0x40
1152#define TA8874Z_LED_EXT 0x20 1166#define TA8874Z_LED_EXT 0x20
@@ -1156,21 +1170,22 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1156#define TA8874Z_MODE_SUB 0x02 1170#define TA8874Z_MODE_SUB 0x02
1157#define TA8874Z_MODE_MAIN 0x01 1171#define TA8874Z_MODE_MAIN 0x01
1158 1172
1159// write 2nd byte 1173/* write 2nd byte */
1160//#define TA8874Z_TI 0x80 // test mode 1174/*#define TA8874Z_TI 0x80 */ /* test mode */
1161#define TA8874Z_SEPARATION 0x3f 1175#define TA8874Z_SEPARATION 0x3f
1162#define TA8874Z_SEPARATION_DEFAULT 0x10 1176#define TA8874Z_SEPARATION_DEFAULT 0x10
1163 1177
1164// read 1178/* read */
1165#define TA8874Z_B1 0x80 1179#define TA8874Z_B1 0x80
1166#define TA8874Z_B0 0x40 1180#define TA8874Z_B0 0x40
1167#define TA8874Z_CHAG_FLAG 0x20 1181#define TA8874Z_CHAG_FLAG 0x20
1168 1182
1169// B1 B0 1183/*
1170// mono L H 1184 * B1 B0
1171// stereo L L 1185 * mono L H
1172// BIL H L 1186 * stereo L L
1173 1187 * BIL H L
1188 */
1174static int ta8874z_getmode(struct CHIPSTATE *chip) 1189static int ta8874z_getmode(struct CHIPSTATE *chip)
1175{ 1190{
1176 int val, mode; 1191 int val, mode;
@@ -1182,7 +1197,7 @@ static int ta8874z_getmode(struct CHIPSTATE *chip)
1182 }else if (!(val & TA8874Z_B0)){ 1197 }else if (!(val & TA8874Z_B0)){
1183 mode |= VIDEO_SOUND_STEREO; 1198 mode |= VIDEO_SOUND_STEREO;
1184 } 1199 }
1185 //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); 1200 /* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */
1186 return mode; 1201 return mode;
1187} 1202}
1188 1203
@@ -1195,7 +1210,7 @@ static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
1195{ 1210{
1196 int update = 1; 1211 int update = 1;
1197 audiocmd *t = NULL; 1212 audiocmd *t = NULL;
1198 dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode); 1213 tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode);
1199 1214
1200 switch(mode){ 1215 switch(mode){
1201 case VIDEO_SOUND_MONO: 1216 case VIDEO_SOUND_MONO:
@@ -1235,11 +1250,11 @@ static int tda9850 = 1;
1235static int tda9855 = 1; 1250static int tda9855 = 1;
1236static int tda9873 = 1; 1251static int tda9873 = 1;
1237static int tda9874a = 1; 1252static int tda9874a = 1;
1238static int tea6300 = 0; // address clash with msp34xx 1253static int tea6300 = 0; /* address clash with msp34xx */
1239static int tea6320 = 0; // address clash with msp34xx 1254static int tea6320 = 0; /* address clash with msp34xx */
1240static int tea6420 = 1; 1255static int tea6420 = 1;
1241static int pic16c54 = 1; 1256static int pic16c54 = 1;
1242static int ta8874z = 0; // address clash with tda9840 1257static int ta8874z = 0; /* address clash with tda9840 */
1243 1258
1244module_param(tda8425, int, 0444); 1259module_param(tda8425, int, 0444);
1245module_param(tda9840, int, 0444); 1260module_param(tda9840, int, 0444);
@@ -1441,7 +1456,7 @@ static struct CHIPDESC chiplist[] = {
1441 { 1456 {
1442 .name = "ta8874z", 1457 .name = "ta8874z",
1443 .id = -1, 1458 .id = -1,
1444 //.id = I2C_DRIVERID_TA8874Z, 1459 /*.id = I2C_DRIVERID_TA8874Z, */
1445 .checkit = ta8874z_checkit, 1460 .checkit = ta8874z_checkit,
1446 .insmodopt = &ta8874z, 1461 .insmodopt = &ta8874z,
1447 .addr_lo = I2C_TDA9840 >> 1, 1462 .addr_lo = I2C_TDA9840 >> 1,
@@ -1476,7 +1491,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1476 i2c_set_clientdata(&chip->c, chip); 1491 i2c_set_clientdata(&chip->c, chip);
1477 1492
1478 /* find description for the chip */ 1493 /* find description for the chip */
1479 dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1); 1494 tvaudio_dbg("chip found @ 0x%x\n", addr<<1);
1480 for (desc = chiplist; desc->name != NULL; desc++) { 1495 for (desc = chiplist; desc->name != NULL; desc++) {
1481 if (0 == *(desc->insmodopt)) 1496 if (0 == *(desc->insmodopt))
1482 continue; 1497 continue;
@@ -1488,17 +1503,19 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1488 break; 1503 break;
1489 } 1504 }
1490 if (desc->name == NULL) { 1505 if (desc->name == NULL) {
1491 dprintk("tvaudio: no matching chip description found\n"); 1506 tvaudio_dbg("no matching chip description found\n");
1492 return -EIO; 1507 return -EIO;
1493 } 1508 }
1494 printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1); 1509 tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
1495 dprintk("tvaudio: matches:%s%s%s.\n", 1510 if (desc->flags) {
1496 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", 1511 tvaudio_dbg("matches:%s%s%s.\n",
1497 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", 1512 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1498 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); 1513 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1514 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
1515 }
1499 1516
1500 /* fill required data structures */ 1517 /* fill required data structures */
1501 strcpy(chip->c.name, desc->name); 1518 strcpy(chip->c.name,desc->name);
1502 chip->type = desc-chiplist; 1519 chip->type = desc-chiplist;
1503 chip->shadow.count = desc->registers+1; 1520 chip->shadow.count = desc->registers+1;
1504 chip->prevmode = -1; 1521 chip->prevmode = -1;
@@ -1534,7 +1551,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1534 init_completion(&chip->texit); 1551 init_completion(&chip->texit);
1535 chip->tpid = kernel_thread(chip_thread,(void *)chip,0); 1552 chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
1536 if (chip->tpid < 0) 1553 if (chip->tpid < 0)
1537 printk(KERN_WARNING "%s: kernel_thread() failed\n", 1554 tvaudio_warn("%s: kernel_thread() failed\n",
1538 chip->c.name); 1555 chip->c.name);
1539 wake_up_interruptible(&chip->wq); 1556 wake_up_interruptible(&chip->wq);
1540 } 1557 }
@@ -1545,7 +1562,7 @@ static int chip_probe(struct i2c_adapter *adap)
1545{ 1562{
1546 /* don't attach on saa7146 based cards, 1563 /* don't attach on saa7146 based cards,
1547 because dedicated drivers are used */ 1564 because dedicated drivers are used */
1548 if (adap->id == I2C_HW_SAA7146) 1565 if ((adap->id == I2C_HW_SAA7146))
1549 return 0; 1566 return 0;
1550#ifdef I2C_CLASS_TV_ANALOG 1567#ifdef I2C_CLASS_TV_ANALOG
1551 if (adap->class & I2C_CLASS_TV_ANALOG) 1568 if (adap->class & I2C_CLASS_TV_ANALOG)
@@ -1584,11 +1601,11 @@ static int chip_detach(struct i2c_client *client)
1584static int chip_command(struct i2c_client *client, 1601static int chip_command(struct i2c_client *client,
1585 unsigned int cmd, void *arg) 1602 unsigned int cmd, void *arg)
1586{ 1603{
1587 __u16 *sarg = arg; 1604 __u16 *sarg = arg;
1588 struct CHIPSTATE *chip = i2c_get_clientdata(client); 1605 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1589 struct CHIPDESC *desc = chiplist + chip->type; 1606 struct CHIPDESC *desc = chiplist + chip->type;
1590 1607
1591 dprintk("%s: chip_command 0x%x\n", chip->c.name, cmd); 1608 tvaudio_dbg("%s: chip_command 0x%x\n",chip->c.name,cmd);
1592 1609
1593 switch (cmd) { 1610 switch (cmd) {
1594 case AUDC_SET_INPUT: 1611 case AUDC_SET_INPUT:
@@ -1601,7 +1618,6 @@ static int chip_command(struct i2c_client *client,
1601 break; 1618 break;
1602 1619
1603 case AUDC_SET_RADIO: 1620 case AUDC_SET_RADIO:
1604 dprintk(KERN_DEBUG "tvaudio: AUDC_SET_RADIO\n");
1605 chip->norm = VIDEO_MODE_RADIO; 1621 chip->norm = VIDEO_MODE_RADIO;
1606 chip->watch_stereo = 0; 1622 chip->watch_stereo = 0;
1607 /* del_timer(&chip->wt); */ 1623 /* del_timer(&chip->wt); */
@@ -1609,7 +1625,7 @@ static int chip_command(struct i2c_client *client,
1609 1625
1610 /* --- v4l ioctls --- */ 1626 /* --- v4l ioctls --- */
1611 /* take care: bttv does userspace copying, we'll get a 1627 /* take care: bttv does userspace copying, we'll get a
1612 kernel pointer here... */ 1628 kernel pointer here... */
1613 case VIDIOCGAUDIO: 1629 case VIDIOCGAUDIO:
1614 { 1630 {
1615 struct video_audio *va = arg; 1631 struct video_audio *va = arg;
@@ -1643,9 +1659,9 @@ static int chip_command(struct i2c_client *client,
1643 1659
1644 if (desc->flags & CHIP_HAS_VOLUME) { 1660 if (desc->flags & CHIP_HAS_VOLUME) {
1645 chip->left = (min(65536 - va->balance,32768) * 1661 chip->left = (min(65536 - va->balance,32768) *
1646 va->volume) / 32768; 1662 va->volume) / 32768;
1647 chip->right = (min(va->balance,(__u16)32768) * 1663 chip->right = (min(va->balance,(__u16)32768) *
1648 va->volume) / 32768; 1664 va->volume) / 32768;
1649 chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); 1665 chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
1650 chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); 1666 chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
1651 } 1667 }
@@ -1667,17 +1683,16 @@ static int chip_command(struct i2c_client *client,
1667 { 1683 {
1668 struct video_channel *vc = arg; 1684 struct video_channel *vc = arg;
1669 1685
1670 dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n");
1671 chip->norm = vc->norm; 1686 chip->norm = vc->norm;
1672 break; 1687 break;
1673 } 1688 }
1674 case VIDIOCSFREQ: 1689 case VIDIOCSFREQ:
1675 { 1690 {
1676 chip->mode = 0; /* automatic */ 1691 chip->mode = 0; /* automatic */
1677 if (desc->checkmode) { 1692 if (desc->checkmode) {
1678 desc->setmode(chip,VIDEO_SOUND_MONO); 1693 desc->setmode(chip,VIDEO_SOUND_MONO);
1679 if (chip->prevmode != VIDEO_SOUND_MONO) 1694 if (chip->prevmode != VIDEO_SOUND_MONO)
1680 chip->prevmode = -1; /* reset previous mode */ 1695 chip->prevmode = -1; /* reset previous mode */
1681 mod_timer(&chip->wt, jiffies+2*HZ); 1696 mod_timer(&chip->wt, jiffies+2*HZ);
1682 /* the thread will call checkmode() later */ 1697 /* the thread will call checkmode() later */
1683 } 1698 }
@@ -1689,29 +1704,32 @@ static int chip_command(struct i2c_client *client,
1689 1704
1690static struct i2c_driver driver = { 1705static struct i2c_driver driver = {
1691 .owner = THIS_MODULE, 1706 .owner = THIS_MODULE,
1692 .name = "generic i2c audio driver", 1707 .name = "generic i2c audio driver",
1693 .id = I2C_DRIVERID_TVAUDIO, 1708 .id = I2C_DRIVERID_TVAUDIO,
1694 .flags = I2C_DF_NOTIFY, 1709 .flags = I2C_DF_NOTIFY,
1695 .attach_adapter = chip_probe, 1710 .attach_adapter = chip_probe,
1696 .detach_client = chip_detach, 1711 .detach_client = chip_detach,
1697 .command = chip_command, 1712 .command = chip_command,
1698}; 1713};
1699 1714
1700static struct i2c_client client_template = 1715static struct i2c_client client_template =
1701{ 1716{
1702 .name = "(unset)", 1717 .name = "(unset)",
1703 .flags = I2C_CLIENT_ALLOW_USE, 1718 .flags = I2C_CLIENT_ALLOW_USE,
1704 .driver = &driver, 1719 .driver = &driver,
1705}; 1720};
1706 1721
1707static int __init audiochip_init_module(void) 1722static int __init audiochip_init_module(void)
1708{ 1723{
1709 struct CHIPDESC *desc; 1724 struct CHIPDESC *desc;
1710 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n"); 1725
1711 printk(KERN_INFO "tvaudio: known chips: "); 1726 if (debug) {
1712 for (desc = chiplist; desc->name != NULL; desc++) 1727 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
1713 printk("%s%s", (desc == chiplist) ? "" : ",",desc->name); 1728 printk(KERN_INFO "tvaudio: known chips: ");
1714 printk("\n"); 1729 for (desc = chiplist; desc->name != NULL; desc++)
1730 printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name);
1731 printk("\n");
1732 }
1715 1733
1716 return i2c_add_driver(&driver); 1734 return i2c_add_driver(&driver);
1717} 1735}
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3c3356a01cc6..5344d5592199 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -47,18 +47,21 @@ MODULE_LICENSE("GPL");
47 47
48static int debug = 0; 48static int debug = 0;
49module_param(debug, int, 0644); 49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-2)"); 50MODULE_PARM_DESC(debug, "Debug level (0-1)");
51 51
52#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown") 52#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
53 53
54#define dprintk(num, args...) \ 54#define tveeprom_info(fmt, arg...) do {\
55 do { \ 55 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
56 if (debug >= num) \ 56 c->adapter->nr, c->addr , ##arg); } while (0)
57 printk(KERN_INFO "tveeprom: " args); \ 57#define tveeprom_warn(fmt, arg...) do {\
58 } while (0) 58 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
59 c->adapter->nr, c->addr , ##arg); } while (0)
60#define tveeprom_dbg(fmt, arg...) do {\
61 if (debug) \
62 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
63 c->adapter->nr, c->addr , ##arg); } while (0)
59 64
60#define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
61#define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
62 65
63/* ----------------------------------------------------------------------- */ 66/* ----------------------------------------------------------------------- */
64/* some hauppauge specific stuff */ 67/* some hauppauge specific stuff */
@@ -70,14 +73,14 @@ static struct HAUPPAUGE_TUNER_FMT
70} 73}
71hauppauge_tuner_fmt[] = 74hauppauge_tuner_fmt[] =
72{ 75{
73 { 0x00000000, "unknown1" }, 76 { 0x00000000, " unknown1" },
74 { 0x00000000, "unknown2" }, 77 { 0x00000000, " unknown2" },
75 { 0x00000007, "PAL(B/G)" }, 78 { 0x00000007, " PAL(B/G)" },
76 { 0x00001000, "NTSC(M)" }, 79 { 0x00001000, " NTSC(M)" },
77 { 0x00000010, "PAL(I)" }, 80 { 0x00000010, " PAL(I)" },
78 { 0x00400000, "SECAM(L/L´)" }, 81 { 0x00400000, " SECAM(L/L')" },
79 { 0x00000e00, "PAL(D/K)" }, 82 { 0x00000e00, " PAL(D/K)" },
80 { 0x03000000, "ATSC Digital" }, 83 { 0x03000000, " ATSC Digital" },
81}; 84};
82 85
83/* This is the full list of possible tuners. Many thanks to Hauppauge for 86/* This is the full list of possible tuners. Many thanks to Hauppauge for
@@ -152,13 +155,13 @@ hauppauge_tuner[] =
152 { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"}, 155 { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
153 { TUNER_ABSENT, "LG TPI8NSR11F"}, 156 { TUNER_ABSENT, "LG TPI8NSR11F"},
154 { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"}, 157 { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
155 { TUNER_ABSENT, "Philips FQ1216ME MK3"}, 158 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
156 { TUNER_ABSENT, "Philips FI1236 MK3"}, 159 { TUNER_ABSENT, "Philips FI1236 MK3"},
157 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"}, 160 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
158 { TUNER_ABSENT, "Philips FM1236 MK3"}, 161 { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
159 { TUNER_ABSENT, "Philips FM1216MP MK3"}, 162 { TUNER_ABSENT, "Philips FM1216MP MK3"},
160 /* 60-69 */ 163 /* 60-69 */
161 { TUNER_ABSENT, "LG S001D MK3"}, 164 { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
162 { TUNER_ABSENT, "LG M001D MK3"}, 165 { TUNER_ABSENT, "LG M001D MK3"},
163 { TUNER_ABSENT, "LG S701D MK3"}, 166 { TUNER_ABSENT, "LG S701D MK3"},
164 { TUNER_ABSENT, "LG M701D MK3"}, 167 { TUNER_ABSENT, "LG M701D MK3"},
@@ -167,7 +170,7 @@ hauppauge_tuner[] =
167 { TUNER_ABSENT, "Temic 4106FH5"}, 170 { TUNER_ABSENT, "Temic 4106FH5"},
168 { TUNER_ABSENT, "Philips FQ1216LMP MK3"}, 171 { TUNER_ABSENT, "Philips FQ1216LMP MK3"},
169 { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"}, 172 { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
170 { TUNER_ABSENT, "LG TAPE H701F MK3"}, 173 { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"},
171 /* 70-79 */ 174 /* 70-79 */
172 { TUNER_ABSENT, "LG TALN H200T"}, 175 { TUNER_ABSENT, "LG TALN H200T"},
173 { TUNER_ABSENT, "LG TALN H250T"}, 176 { TUNER_ABSENT, "LG TALN H250T"},
@@ -183,8 +186,8 @@ hauppauge_tuner[] =
183 { TUNER_ABSENT, "Philips FQ1216LME MK3"}, 186 { TUNER_ABSENT, "Philips FQ1216LME MK3"},
184 { TUNER_ABSENT, "LG TAPC G701D"}, 187 { TUNER_ABSENT, "LG TAPC G701D"},
185 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, 188 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
186 { TUNER_ABSENT, "TCL 2002MB 3"}, 189 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
187 { TUNER_ABSENT, "TCL 2002MI 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
188 { TUNER_TCL_2002N, "TCL 2002N 6A"}, 191 { TUNER_TCL_2002N, "TCL 2002N 6A"},
189 { TUNER_ABSENT, "Philips FQ1236 MK3"}, 192 { TUNER_ABSENT, "Philips FQ1236 MK3"},
190 { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, 193 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
@@ -199,17 +202,51 @@ hauppauge_tuner[] =
199 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 202 { TUNER_ABSENT, "Philips FQ1236 MK5"},
200 { TUNER_ABSENT, "Unspecified"}, 203 { TUNER_ABSENT, "Unspecified"},
201 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, 204 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"},
205 { TUNER_ABSENT, "Unspecified"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"},
207 /* 100-103 */
208 { TUNER_ABSENT, "Unspecified"},
209 { TUNER_TEA5767, "Philips TEA5767HN FM Radio"},
210 { TUNER_ABSENT, "Unspecified"},
211 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"},
202}; 212};
203 213
204static char *sndtype[] = { 214/* This list is supplied by Hauppauge. Thanks! */
205 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D", 215static const char *audioIC[] = {
206 "MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440", 216 /* 0-4 */
207 "MSP3445", "MSP3411", "MSP3416", "MSP3425", 217 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C",
218 /* 5-9 */
219 "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331",
220 /* 10-14 */
221 "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416",
222 /* 15-19 */
223 "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716",
224 /* 20-24 */
225 "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408",
226 /* 25-29 */
227 "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d",
228 /* 30-34 */
229 "CX880", "CX881", "CX883", "CX882", "CX25840",
230 /* 35-38 */
231 "CX25841", "CX25842", "CX25843", "CX23418",
232};
208 233
209 "Type 0x10","Type 0x11","Type 0x12","Type 0x13", 234/* This list is supplied by Hauppauge. Thanks! */
210 "Type 0x14","Type 0x15","Type 0x16","Type 0x17", 235static const char *decoderIC[] = {
211 "Type 0x18","MSP4418","Type 0x1a","MSP4448", 236 /* 0-4 */
212 "Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f", 237 "None", "BT815", "BT817", "BT819", "BT815A",
238 /* 5-9 */
239 "BT817A", "BT819A", "BT827", "BT829", "BT848",
240 /* 10-14 */
241 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
242 /* 15-19 */
243 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
244 /* 20-24 */
245 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
246 /* 25-29 */
247 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
248 /* 30-31 */
249 "CX25843", "CX23418",
213}; 250};
214 251
215static int hasRadioTuner(int tunerType) 252static int hasRadioTuner(int tunerType)
@@ -250,7 +287,8 @@ static int hasRadioTuner(int tunerType)
250 return 0; 287 return 0;
251} 288}
252 289
253void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data) 290void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
291 unsigned char *eeprom_data)
254{ 292{
255 /* ---------------------------------------------- 293 /* ----------------------------------------------
256 ** The hauppauge eeprom format is tagged 294 ** The hauppauge eeprom format is tagged
@@ -260,10 +298,11 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
260 ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum 298 ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
261 ** 299 **
262 ** In our (ivtv) case we're interested in the following: 300 ** In our (ivtv) case we're interested in the following:
263 ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner) 301 ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
264 ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt) 302 ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
265 ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM) 303 ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
266 ** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?) 304 ** audio proc: tag [02].01 or [05].00 (mask with 0x7f)
305 ** decoder proc: tag [09].01)
267 306
268 ** Fun info: 307 ** Fun info:
269 ** model: tag [00].07-08 or [06].00-01 308 ** model: tag [00].07-08 or [06].00-01
@@ -273,20 +312,24 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
273 ** # of inputs/outputs ??? 312 ** # of inputs/outputs ???
274 */ 313 */
275 314
276 int i, j, len, done, beenhere, tag, tuner = 0, t_format = 0; 315 int i, j, len, done, beenhere, tag;
277 char *t_name = NULL, *t_fmt_name = NULL;
278 316
279 dprintk(1, "%s\n",__FUNCTION__); 317 int tuner1 = 0, t_format1 = 0;
280 tvee->revision = done = len = beenhere = 0; 318 char *t_name1 = NULL;
281 for (i = 0; !done && i < 256; i += len) { 319 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
282 dprintk(2, "processing pos = %02x (%02x, %02x)\n",
283 i, eeprom_data[i], eeprom_data[i + 1]);
284 320
321 int tuner2 = 0, t_format2 = 0;
322 char *t_name2 = NULL;
323 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
324
325 memset(tvee, 0, sizeof(*tvee));
326 done = len = beenhere = 0;
327 for (i = 0; !done && i < 256; i += len) {
285 if (eeprom_data[i] == 0x84) { 328 if (eeprom_data[i] == 0x84) {
286 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 329 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
287 i+=3; 330 i += 3;
288 } else if ((eeprom_data[i] & 0xf0) == 0x70) { 331 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
289 if ((eeprom_data[i] & 0x08)) { 332 if (eeprom_data[i] & 0x08) {
290 /* verify checksum! */ 333 /* verify checksum! */
291 done = 1; 334 done = 1;
292 break; 335 break;
@@ -294,24 +337,30 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
294 len = eeprom_data[i] & 0x07; 337 len = eeprom_data[i] & 0x07;
295 ++i; 338 ++i;
296 } else { 339 } else {
297 TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. " 340 tveeprom_warn("Encountered bad packet header [%02x]. "
298 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); 341 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
299 return; 342 return;
300 } 343 }
301 344
302 dprintk(1, "%3d [%02x] ", len, eeprom_data[i]); 345 if (debug) {
303 for(j = 1; j < len; j++) { 346 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
304 dprintk(1, "%02x ", eeprom_data[i + j]); 347 for(j = 1; j < len; j++) {
305 } 348 printk(" %02x", eeprom_data[i + j]);
306 dprintk(1, "\n"); 349 }
350 printk("\n");
351 }
307 352
308 /* process by tag */ 353 /* process by tag */
309 tag = eeprom_data[i]; 354 tag = eeprom_data[i];
310 switch (tag) { 355 switch (tag) {
311 case 0x00: 356 case 0x00:
312 tuner = eeprom_data[i+6]; 357 /* tag: 'Comprehensive' */
313 t_format = eeprom_data[i+5]; 358 tuner1 = eeprom_data[i+6];
359 t_format1 = eeprom_data[i+5];
314 tvee->has_radio = eeprom_data[i+len-1]; 360 tvee->has_radio = eeprom_data[i+len-1];
361 /* old style tag, don't know how to detect
362 IR presence, mark as unknown. */
363 tvee->has_ir = 2;
315 tvee->model = 364 tvee->model =
316 eeprom_data[i+8] + 365 eeprom_data[i+8] +
317 (eeprom_data[i+9] << 8); 366 (eeprom_data[i+9] << 8);
@@ -319,25 +368,43 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
319 (eeprom_data[i+11] << 8) + 368 (eeprom_data[i+11] << 8) +
320 (eeprom_data[i+12] << 16); 369 (eeprom_data[i+12] << 16);
321 break; 370 break;
371
322 case 0x01: 372 case 0x01:
373 /* tag: 'SerialID' */
323 tvee->serial_number = 374 tvee->serial_number =
324 eeprom_data[i+6] + 375 eeprom_data[i+6] +
325 (eeprom_data[i+7] << 8) + 376 (eeprom_data[i+7] << 8) +
326 (eeprom_data[i+8] << 16); 377 (eeprom_data[i+8] << 16);
327 break; 378 break;
379
328 case 0x02: 380 case 0x02:
329 tvee->audio_processor = eeprom_data[i+2] & 0x0f; 381 /* tag 'AudioInfo'
382 Note mask with 0x7F, high bit used on some older models
383 to indicate 4052 mux was removed in favor of using MSP
384 inputs directly. */
385 tvee->audio_processor = eeprom_data[i+2] & 0x7f;
330 break; 386 break;
387
388 /* case 0x03: tag 'EEInfo' */
389
331 case 0x04: 390 case 0x04:
391 /* tag 'SerialID2' */
332 tvee->serial_number = 392 tvee->serial_number =
333 eeprom_data[i+5] + 393 eeprom_data[i+5] +
334 (eeprom_data[i+6] << 8) + 394 (eeprom_data[i+6] << 8) +
335 (eeprom_data[i+7] << 16); 395 (eeprom_data[i+7] << 16);
336 break; 396 break;
397
337 case 0x05: 398 case 0x05:
338 tvee->audio_processor = eeprom_data[i+1] & 0x0f; 399 /* tag 'Audio2'
400 Note mask with 0x7F, high bit used on some older models
401 to indicate 4052 mux was removed in favor of using MSP
402 inputs directly. */
403 tvee->audio_processor = eeprom_data[i+1] & 0x7f;
339 break; 404 break;
405
340 case 0x06: 406 case 0x06:
407 /* tag 'ModelRev' */
341 tvee->model = 408 tvee->model =
342 eeprom_data[i+1] + 409 eeprom_data[i+1] +
343 (eeprom_data[i+2] << 8); 410 (eeprom_data[i+2] << 8);
@@ -345,27 +412,66 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
345 (eeprom_data[i+6] << 8) + 412 (eeprom_data[i+6] << 8) +
346 (eeprom_data[i+7] << 16); 413 (eeprom_data[i+7] << 16);
347 break; 414 break;
415
416 case 0x07:
417 /* tag 'Details': according to Hauppauge not interesting
418 on any PCI-era or later boards. */
419 break;
420
421 /* there is no tag 0x08 defined */
422
423 case 0x09:
424 /* tag 'Video' */
425 tvee->decoder_processor = eeprom_data[i + 1];
426 break;
427
348 case 0x0a: 428 case 0x0a:
349 if(beenhere == 0) { 429 /* tag 'Tuner' */
350 tuner = eeprom_data[i+2]; 430 if (beenhere == 0) {
351 t_format = eeprom_data[i+1]; 431 tuner1 = eeprom_data[i+2];
432 t_format1 = eeprom_data[i+1];
352 beenhere = 1; 433 beenhere = 1;
353 break;
354 } else { 434 } else {
355 break; 435 /* a second (radio) tuner may be present */
356 } 436 tuner2 = eeprom_data[i+2];
437 t_format2 = eeprom_data[i+1];
438 if (t_format2 == 0) { /* not a TV tuner? */
439 tvee->has_radio = 1; /* must be radio */
440 }
441 }
442 break;
443
444 case 0x0b:
445 /* tag 'Inputs': according to Hauppauge this is specific
446 to each driver family, so no good assumptions can be
447 made. */
448 break;
449
450 /* case 0x0c: tag 'Balun' */
451 /* case 0x0d: tag 'Teletext' */
452
357 case 0x0e: 453 case 0x0e:
454 /* tag: 'Radio' */
358 tvee->has_radio = eeprom_data[i+1]; 455 tvee->has_radio = eeprom_data[i+1];
359 break; 456 break;
457
458 case 0x0f:
459 /* tag 'IRInfo' */
460 tvee->has_ir = eeprom_data[i+1];
461 break;
462
463 /* case 0x10: tag 'VBIInfo' */
464 /* case 0x11: tag 'QCInfo' */
465 /* case 0x12: tag 'InfoBits' */
466
360 default: 467 default:
361 dprintk(1, "Not sure what to do with tag [%02x]\n", tag); 468 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
362 /* dump the rest of the packet? */ 469 /* dump the rest of the packet? */
363 } 470 }
364
365 } 471 }
366 472
367 if (!done) { 473 if (!done) {
368 TVEEPROM_KERN_ERR("Ran out of data!\n"); 474 tveeprom_warn("Ran out of data!\n");
369 return; 475 return;
370 } 476 }
371 477
@@ -377,47 +483,72 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
377 tvee->rev_str[4] = 0; 483 tvee->rev_str[4] = 0;
378 } 484 }
379 485
380 if (hasRadioTuner(tuner) && !tvee->has_radio) { 486 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
381 TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n"); 487 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
382 TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n"); 488 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
383 tvee->has_radio = 1; 489 tvee->has_radio = 1;
384 } 490 }
385 491
386 if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 492 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
387 tvee->tuner_type = hauppauge_tuner[tuner].id; 493 tvee->tuner_type = hauppauge_tuner[tuner1].id;
388 t_name = hauppauge_tuner[tuner].name; 494 t_name1 = hauppauge_tuner[tuner1].name;
389 } else { 495 } else {
390 t_name = "<unknown>"; 496 t_name1 = "unknown";
497 }
498
499 if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
500 tvee->tuner2_type = hauppauge_tuner[tuner2].id;
501 t_name2 = hauppauge_tuner[tuner2].name;
502 } else {
503 t_name2 = "unknown";
391 } 504 }
392 505
393 tvee->tuner_formats = 0; 506 tvee->tuner_formats = 0;
394 t_fmt_name = "<none>"; 507 tvee->tuner2_formats = 0;
395 for (i = 0; i < 8; i++) { 508 for (i = j = 0; i < 8; i++) {
396 if (t_format & (1<<i)) { 509 if (t_format1 & (1 << i)) {
397 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 510 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
398 /* yuck */ 511 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
399 t_fmt_name = hauppauge_tuner_fmt[i].name;
400 } 512 }
513 if (t_format2 & (1 << i)) {
514 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
515 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
516 }
401 } 517 }
402 518
403 519 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
404 TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n", 520 tvee->model, tvee->rev_str, tvee->serial_number);
405 tvee->model, 521 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
406 tvee->rev_str, 522 t_name1, tuner1, tvee->tuner_type);
407 tvee->serial_number); 523 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
408 TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n", 524 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
409 t_name, 525 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
410 tuner, 526 t_format1);
411 tvee->tuner_type); 527 if (tuner2) {
412 TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n", 528 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
413 t_fmt_name, 529 t_name2, tuner2, tvee->tuner2_type);
414 t_format, 530 }
415 tvee->tuner_formats); 531 if (t_format2) {
416 532 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
417 TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n", 533 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
418 STRM(sndtype,tvee->audio_processor), 534 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
535 t_format2);
536 }
537 tveeprom_info("audio processor is %s (idx %d)\n",
538 STRM(audioIC, tvee->audio_processor),
419 tvee->audio_processor); 539 tvee->audio_processor);
420 540 if (tvee->decoder_processor) {
541 tveeprom_info("decoder processor is %s (idx %d)\n",
542 STRM(decoderIC, tvee->decoder_processor),
543 tvee->decoder_processor);
544 }
545 if (tvee->has_ir == 2)
546 tveeprom_info("has %sradio\n",
547 tvee->has_radio ? "" : "no ");
548 else
549 tveeprom_info("has %sradio, has %sIR remote\n",
550 tvee->has_radio ? "" : "no ",
551 tvee->has_ir ? "" : "no ");
421} 552}
422EXPORT_SYMBOL(tveeprom_hauppauge_analog); 553EXPORT_SYMBOL(tveeprom_hauppauge_analog);
423 554
@@ -429,40 +560,31 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
429 unsigned char buf; 560 unsigned char buf;
430 int err; 561 int err;
431 562
432 dprintk(1, "%s\n",__FUNCTION__);
433 buf = 0; 563 buf = 0;
434 if (1 != (err = i2c_master_send(c,&buf,1))) { 564 if (1 != (err = i2c_master_send(c, &buf, 1))) {
435 printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n", 565 tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
436 c->name,err);
437 return -1; 566 return -1;
438 } 567 }
439 if (len != (err = i2c_master_recv(c,eedata,len))) { 568 if (len != (err = i2c_master_recv(c, eedata, len))) {
440 printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n", 569 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
441 c->name,err);
442 return -1; 570 return -1;
443 } 571 }
572 if (debug) {
573 int i;
574
575 tveeprom_info("full 256-byte eeprom dump:\n");
576 for (i = 0; i < len; i++) {
577 if (0 == (i % 16))
578 tveeprom_info("%02x:", i);
579 printk(" %02x", eedata[i]);
580 if (15 == (i % 16))
581 printk("\n");
582 }
583 }
444 return 0; 584 return 0;
445} 585}
446EXPORT_SYMBOL(tveeprom_read); 586EXPORT_SYMBOL(tveeprom_read);
447 587
448#if 0
449int tveeprom_dump(unsigned char *eedata, int len)
450{
451 int i;
452
453 dprintk(1, "%s\n",__FUNCTION__);
454 for (i = 0; i < len; i++) {
455 if (0 == (i % 16))
456 printk(KERN_INFO "tveeprom: %02x:",i);
457 printk(" %02x",eedata[i]);
458 if (15 == (i % 16))
459 printk("\n");
460 }
461 return 0;
462}
463EXPORT_SYMBOL(tveeprom_dump);
464#endif /* 0 */
465
466/* ----------------------------------------------------------------------- */ 588/* ----------------------------------------------------------------------- */
467/* needed for ivtv.sf.net at the moment. Should go away in the long */ 589/* needed for ivtv.sf.net at the moment. Should go away in the long */
468/* run, just call the exported tveeprom_* directly, there is no point in */ 590/* run, just call the exported tveeprom_* directly, there is no point in */
@@ -495,12 +617,13 @@ tveeprom_command(struct i2c_client *client,
495 buf = kmalloc(256,GFP_KERNEL); 617 buf = kmalloc(256,GFP_KERNEL);
496 memset(buf,0,256); 618 memset(buf,0,256);
497 tveeprom_read(client,buf,256); 619 tveeprom_read(client,buf,256);
498 tveeprom_hauppauge_analog(&eeprom,buf); 620 tveeprom_hauppauge_analog(client, &eeprom,buf);
499 kfree(buf); 621 kfree(buf);
500 eeprom_props[0] = eeprom.tuner_type; 622 eeprom_props[0] = eeprom.tuner_type;
501 eeprom_props[1] = eeprom.tuner_formats; 623 eeprom_props[1] = eeprom.tuner_formats;
502 eeprom_props[2] = eeprom.model; 624 eeprom_props[2] = eeprom.model;
503 eeprom_props[3] = eeprom.revision; 625 eeprom_props[3] = eeprom.revision;
626 eeprom_props[4] = eeprom.has_radio;
504 break; 627 break;
505 default: 628 default:
506 return -EINVAL; 629 return -EINVAL;
@@ -515,8 +638,6 @@ tveeprom_detect_client(struct i2c_adapter *adapter,
515{ 638{
516 struct i2c_client *client; 639 struct i2c_client *client;
517 640
518 dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
519 adapter->id, address << 1);
520 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); 641 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
521 if (NULL == client) 642 if (NULL == client)
522 return -ENOMEM; 643 return -ENOMEM;
@@ -533,7 +654,6 @@ tveeprom_detect_client(struct i2c_adapter *adapter,
533static int 654static int
534tveeprom_attach_adapter (struct i2c_adapter *adapter) 655tveeprom_attach_adapter (struct i2c_adapter *adapter)
535{ 656{
536 dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
537 if (adapter->id != I2C_HW_B_BT848) 657 if (adapter->id != I2C_HW_B_BT848)
538 return 0; 658 return 0;
539 return i2c_probe(adapter, &addr_data, tveeprom_detect_client); 659 return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index a43301a154af..d86e08ebddfc 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4 3
5#include <linux/module.h> 4#include <linux/module.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 70ecbdb80277..59bb71381a1b 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $
3 * 2 *
4 * Video for Linux Two 3 * Video for Linux Two
5 * Backward Compatibility Layer 4 * Backward Compatibility Layer
@@ -604,9 +603,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
604 dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err); 603 dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
605 break; 604 break;
606 } 605 }
607#if 0 /* FIXME */
608 pict->depth = fmt2->fmt.pix.depth;
609#endif
610 pict->palette = pixelformat_to_palette( 606 pict->palette = pixelformat_to_palette(
611 fmt2->fmt.pix.pixelformat); 607 fmt2->fmt.pix.pixelformat);
612 break; 608 break;
@@ -707,13 +703,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
707 } 703 }
708 case VIDIOCSTUNER: /* select a tuner input */ 704 case VIDIOCSTUNER: /* select a tuner input */
709 { 705 {
710#if 0 /* FIXME */
711 err = drv(inode, file, VIDIOC_S_INPUT, &i);
712 if (err < 0)
713 dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
714#else
715 err = 0; 706 err = 0;
716#endif
717 break; 707 break;
718 } 708 }
719 case VIDIOCGFREQ: /* get frequency */ 709 case VIDIOCGFREQ: /* get frequency */
@@ -852,12 +842,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
852 err = 0; 842 err = 0;
853 break; 843 break;
854 } 844 }
855#if 0
856 case VIDIOCGMBUF:
857 /* v4l2 drivers must implement that themself. The
858 mmap() differences can't be translated fully
859 transparent, thus there is no point to try that */
860#endif
861 case VIDIOCMCAPTURE: /* capture a frame */ 845 case VIDIOCMCAPTURE: /* capture a frame */
862 { 846 {
863 struct video_mmap *mm = arg; 847 struct video_mmap *mm = arg;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b5e0cf3448f4..597b8db35a13 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -84,20 +84,6 @@ MODULE_LICENSE("GPL");
84 * Video Standard Operations (contributed by Michael Schimek) 84 * Video Standard Operations (contributed by Michael Schimek)
85 */ 85 */
86 86
87#if 0 /* seems to have no users */
88/* This is the recommended method to deal with the framerate fields. More
89 sophisticated drivers will access the fields directly. */
90unsigned int
91v4l2_video_std_fps(struct v4l2_standard *vs)
92{
93 if (vs->frameperiod.numerator > 0)
94 return (((vs->frameperiod.denominator << 8) /
95 vs->frameperiod.numerator) +
96 (1 << 7)) / (1 << 8);
97 return 0;
98}
99EXPORT_SYMBOL(v4l2_video_std_fps);
100#endif
101 87
102/* Fill in the fields of a v4l2_standard structure according to the 88/* Fill in the fields of a v4l2_standard structure according to the
103 'id' and 'transmission' parameters. Returns negative on error. */ 89 'id' and 'transmission' parameters. Returns negative on error. */
@@ -213,10 +199,6 @@ char *v4l2_ioctl_names[256] = {
213 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", 199 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
214 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", 200 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
215 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", 201 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
216#if 0
217 [_IOC_NR(VIDIOC_G_COMP)] = "VIDIOC_G_COMP",
218 [_IOC_NR(VIDIOC_S_COMP)] = "VIDIOC_S_COMP",
219#endif
220 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", 202 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
221 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", 203 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
222 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", 204 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index 15f5bb486963..55f129e964eb 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: video-buf-dvb.c,v 1.7 2004/12/09 12:51:35 kraxel Exp $
3 * 2 *
4 * some helper function for simple DVB cards which simply DMA the 3 * some helper function for simple DVB cards which simply DMA the
5 * complete transport stream and let the computer sort everything else 4 * complete transport stream and let the computer sort everything else
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 5afdc7852610..97354f253a80 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: video-buf.c,v 1.18 2005/02/24 13:32:30 kraxel Exp $
3 * 2 *
4 * generic helper functions for video4linux capture buffers, to handle 3 * generic helper functions for video4linux capture buffers, to handle
5 * memory management and PCI DMA. Right now bttv + saa7134 use it. 4 * memory management and PCI DMA. Right now bttv + saa7134 use it.
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0a117c61cd18..ceae379a4d4c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1079,13 +1079,17 @@ static void mmc_setup(struct mmc_host *host)
1079/** 1079/**
1080 * mmc_detect_change - process change of state on a MMC socket 1080 * mmc_detect_change - process change of state on a MMC socket
1081 * @host: host which changed state. 1081 * @host: host which changed state.
1082 * @delay: optional delay to wait before detection (jiffies)
1082 * 1083 *
1083 * All we know is that card(s) have been inserted or removed 1084 * All we know is that card(s) have been inserted or removed
1084 * from the socket(s). We don't know which socket or cards. 1085 * from the socket(s). We don't know which socket or cards.
1085 */ 1086 */
1086void mmc_detect_change(struct mmc_host *host) 1087void mmc_detect_change(struct mmc_host *host, unsigned long delay)
1087{ 1088{
1088 schedule_work(&host->detect); 1089 if (delay)
1090 schedule_delayed_work(&host->detect, delay);
1091 else
1092 schedule_work(&host->detect);
1089} 1093}
1090 1094
1091EXPORT_SYMBOL(mmc_detect_change); 1095EXPORT_SYMBOL(mmc_detect_change);
@@ -1189,7 +1193,7 @@ int mmc_add_host(struct mmc_host *host)
1189 ret = mmc_add_host_sysfs(host); 1193 ret = mmc_add_host_sysfs(host);
1190 if (ret == 0) { 1194 if (ret == 0) {
1191 mmc_power_off(host); 1195 mmc_power_off(host);
1192 mmc_detect_change(host); 1196 mmc_detect_change(host, 0);
1193 } 1197 }
1194 1198
1195 return ret; 1199 return ret;
@@ -1259,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
1259 */ 1263 */
1260int mmc_resume_host(struct mmc_host *host) 1264int mmc_resume_host(struct mmc_host *host)
1261{ 1265{
1262 mmc_detect_change(host); 1266 mmc_detect_change(host, 0);
1263 1267
1264 return 0; 1268 return 0;
1265} 1269}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 716c4ef4faf6..91c74843dc0d 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -442,7 +442,7 @@ static void mmci_check_status(unsigned long data)
442 442
443 status = host->plat->status(mmc_dev(host->mmc)); 443 status = host->plat->status(mmc_dev(host->mmc));
444 if (status ^ host->oldstat) 444 if (status ^ host->oldstat)
445 mmc_detect_change(host->mmc); 445 mmc_detect_change(host->mmc, 0);
446 446
447 host->oldstat = status; 447 host->oldstat = status;
448 mod_timer(&host->timer, jiffies + HZ); 448 mod_timer(&host->timer, jiffies + HZ);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index e99a53b09e32..b53af57074e3 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -423,7 +423,9 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
423 423
424static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs) 424static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
425{ 425{
426 mmc_detect_change(devid); 426 struct pxamci_host *host = mmc_priv(devid);
427
428 mmc_detect_change(devid, host->pdata->detect_delay);
427 return IRQ_HANDLED; 429 return IRQ_HANDLED;
428} 430}
429 431
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index dec01d38c782..a62c86fef5cc 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1122,7 +1122,7 @@ static void wbsd_detect_card(unsigned long data)
1122 1122
1123 DBG("Executing card detection\n"); 1123 DBG("Executing card detection\n");
1124 1124
1125 mmc_detect_change(host->mmc); 1125 mmc_detect_change(host->mmc, 0);
1126} 1126}
1127 1127
1128/* 1128/*
@@ -1198,7 +1198,7 @@ static void wbsd_tasklet_card(unsigned long param)
1198 */ 1198 */
1199 spin_unlock(&host->lock); 1199 spin_unlock(&host->lock);
1200 1200
1201 mmc_detect_change(host->mmc); 1201 mmc_detect_change(host->mmc, 0);
1202 } 1202 }
1203 else 1203 else
1204 spin_unlock(&host->lock); 1204 spin_unlock(&host->lock);
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index 1798ce7262c9..0095384ff454 100644
--- a/drivers/net/atari_bionet.c
+++ b/drivers/net/atari_bionet.c
@@ -155,7 +155,7 @@ static int bionet_close(struct net_device *dev);
155static struct net_device_stats *net_get_stats(struct net_device *dev); 155static struct net_device_stats *net_get_stats(struct net_device *dev);
156static void bionet_tick(unsigned long); 156static void bionet_tick(unsigned long);
157 157
158static struct timer_list bionet_timer = TIMER_INITIALIZER(bionet_tick, 0, 0); 158static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0);
159 159
160#define STRAM_ADDR(a) (((a) & 0xff000000) == 0) 160#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
161 161
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 81c362c8cb97..8b997809f9de 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -165,7 +165,7 @@ static void pamsnet_tick(unsigned long);
165 165
166static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp); 166static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp);
167 167
168static struct timer_list pamsnet_timer = TIMER_INITIALIZER(pamsnet_tick, 0, 0); 168static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0);
169 169
170#define STRAM_ADDR(a) (((a) & 0xff000000) == 0) 170#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
171 171
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 55a72c7ad001..83598e32179c 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
14 14
15#define DRV_MODULE_NAME "bnx2" 15#define DRV_MODULE_NAME "bnx2"
16#define PFX DRV_MODULE_NAME ": " 16#define PFX DRV_MODULE_NAME ": "
17#define DRV_MODULE_VERSION "1.2.20" 17#define DRV_MODULE_VERSION "1.2.21"
18#define DRV_MODULE_RELDATE "August 22, 2005" 18#define DRV_MODULE_RELDATE "September 7, 2005"
19 19
20#define RUN_AT(x) (jiffies + (x)) 20#define RUN_AT(x) (jiffies + (x))
21 21
@@ -1533,6 +1533,7 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
1533 struct net_device *dev = dev_instance; 1533 struct net_device *dev = dev_instance;
1534 struct bnx2 *bp = dev->priv; 1534 struct bnx2 *bp = dev->priv;
1535 1535
1536 prefetch(bp->status_blk);
1536 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 1537 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
1537 BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | 1538 BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
1538 BNX2_PCICFG_INT_ACK_CMD_MASK_INT); 1539 BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -1558,7 +1559,7 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1558 * When using MSI, the MSI message will always complete after 1559 * When using MSI, the MSI message will always complete after
1559 * the status block write. 1560 * the status block write.
1560 */ 1561 */
1561 if ((bp->status_blk->status_idx == bp->last_status_idx) || 1562 if ((bp->status_blk->status_idx == bp->last_status_idx) &&
1562 (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & 1563 (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
1563 BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) 1564 BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
1564 return IRQ_NONE; 1565 return IRQ_NONE;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 9ad3f5740cd8..62857b6a6ee4 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -50,6 +50,7 @@
50#endif 50#endif
51#include <linux/workqueue.h> 51#include <linux/workqueue.h>
52#include <linux/crc32.h> 52#include <linux/crc32.h>
53#include <linux/prefetch.h>
53 54
54/* Hardware data structures and register definitions automatically 55/* Hardware data structures and register definitions automatically
55 * generated from RTL code. Do not modify. 56 * generated from RTL code. Do not modify.
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 442670860fca..b68b9cad76e9 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -384,8 +384,8 @@ static unsigned int mdio_phy_addr; /* Transciever address */
384static unsigned int network_tr_ctrl_shadow = 0; 384static unsigned int network_tr_ctrl_shadow = 0;
385 385
386/* Network speed indication. */ 386/* Network speed indication. */
387static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0); 387static DEFINE_TIMER(speed_timer, NULL, 0, 0);
388static struct timer_list clear_led_timer = TIMER_INITIALIZER(NULL, 0, 0); 388static DEFINE_TIMER(clear_led_timer, NULL, 0, 0);
389static int current_speed; /* Speed read from transceiver */ 389static int current_speed; /* Speed read from transceiver */
390static int current_speed_selection; /* Speed selected by user */ 390static int current_speed_selection; /* Speed selected by user */
391static unsigned long led_next_time; 391static unsigned long led_next_time;
@@ -393,7 +393,7 @@ static int led_active;
393static int rx_queue_len; 393static int rx_queue_len;
394 394
395/* Duplex */ 395/* Duplex */
396static struct timer_list duplex_timer = TIMER_INITIALIZER(NULL, 0, 0); 396static DEFINE_TIMER(duplex_timer, NULL, 0, 0);
397static int full_duplex; 397static int full_duplex;
398static enum duplex current_duplex; 398static enum duplex current_duplex;
399 399
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index b780307093eb..cdc07ccd7332 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -247,6 +247,9 @@ static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer
247static int get_eeprom_cksum(int off, int len, int *buffer); 247static int get_eeprom_cksum(int off, int len, int *buffer);
248static int set_mac_address(struct net_device *dev, void *addr); 248static int set_mac_address(struct net_device *dev, void *addr);
249static void count_rx_errors(int status, struct net_local *lp); 249static void count_rx_errors(int status, struct net_local *lp);
250#ifdef CONFIG_NET_POLL_CONTROLLER
251static void net_poll_controller(struct net_device *dev);
252#endif
250#if ALLOW_DMA 253#if ALLOW_DMA
251static void get_dma_channel(struct net_device *dev); 254static void get_dma_channel(struct net_device *dev);
252static void release_dma_buff(struct net_local *lp); 255static void release_dma_buff(struct net_local *lp);
@@ -405,6 +408,19 @@ get_eeprom_cksum(int off, int len, int *buffer)
405 return -1; 408 return -1;
406} 409}
407 410
411#ifdef CONFIG_NET_POLL_CONTROLLER
412/*
413 * Polling receive - used by netconsole and other diagnostic tools
414 * to allow network i/o with interrupts disabled.
415 */
416static void net_poll_controller(struct net_device *dev)
417{
418 disable_irq(dev->irq);
419 net_interrupt(dev->irq, dev, NULL);
420 enable_irq(dev->irq);
421}
422#endif
423
408/* This is the real probe routine. Linux has a history of friendly device 424/* This is the real probe routine. Linux has a history of friendly device
409 probes on the ISA bus. A good device probes avoids doing writes, and 425 probes on the ISA bus. A good device probes avoids doing writes, and
410 verifies that the correct device exists and functions. 426 verifies that the correct device exists and functions.
@@ -760,6 +776,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
760 dev->get_stats = net_get_stats; 776 dev->get_stats = net_get_stats;
761 dev->set_multicast_list = set_multicast_list; 777 dev->set_multicast_list = set_multicast_list;
762 dev->set_mac_address = set_mac_address; 778 dev->set_mac_address = set_mac_address;
779#ifdef CONFIG_NET_POLL_CONTROLLER
780 dev->poll_controller = net_poll_controller;
781#endif
763 782
764 printk("\n"); 783 printk("\n");
765 if (net_debug) 784 if (net_debug)
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 41213ef602dc..f52ee3162c51 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -170,7 +170,7 @@ static char ax25_bcast[7] =
170static char ax25_test[7] = 170static char ax25_test[7] =
171{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1}; 171{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
172 172
173static struct timer_list yam_timer = TIMER_INITIALIZER(NULL, 0, 0); 173static DEFINE_TIMER(yam_timer, NULL, 0, 0);
174 174
175/* --------------------------------------------------------------------- */ 175/* --------------------------------------------------------------------- */
176 176
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 46e0022d3258..6c766fdc51a6 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -267,7 +267,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
267 frame, IRDA_USB_SPEED_MTU, 267 frame, IRDA_USB_SPEED_MTU,
268 speed_bulk_callback, self); 268 speed_bulk_callback, self);
269 urb->transfer_buffer_length = USB_IRDA_HEADER; 269 urb->transfer_buffer_length = USB_IRDA_HEADER;
270 urb->transfer_flags = URB_ASYNC_UNLINK; 270 urb->transfer_flags = 0;
271 271
272 /* Irq disabled -> GFP_ATOMIC */ 272 /* Irq disabled -> GFP_ATOMIC */
273 if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) { 273 if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) {
@@ -401,15 +401,12 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
401 skb->data, IRDA_SKB_MAX_MTU, 401 skb->data, IRDA_SKB_MAX_MTU,
402 write_bulk_callback, skb); 402 write_bulk_callback, skb);
403 urb->transfer_buffer_length = skb->len; 403 urb->transfer_buffer_length = skb->len;
404 /* Note : unlink *must* be Asynchronous because of the code in
405 * irda_usb_net_timeout() -> call in irq - Jean II */
406 urb->transfer_flags = URB_ASYNC_UNLINK;
407 /* This flag (URB_ZERO_PACKET) indicates that what we send is not 404 /* This flag (URB_ZERO_PACKET) indicates that what we send is not
408 * a continuous stream of data but separate packets. 405 * a continuous stream of data but separate packets.
409 * In this case, the USB layer will insert an empty USB frame (TD) 406 * In this case, the USB layer will insert an empty USB frame (TD)
410 * after each of our packets that is exact multiple of the frame size. 407 * after each of our packets that is exact multiple of the frame size.
411 * This is how the dongle will detect the end of packet - Jean II */ 408 * This is how the dongle will detect the end of packet - Jean II */
412 urb->transfer_flags |= URB_ZERO_PACKET; 409 urb->transfer_flags = URB_ZERO_PACKET;
413 410
414 /* Generate min turn time. FIXME: can we do better than this? */ 411 /* Generate min turn time. FIXME: can we do better than this? */
415 /* Trying to a turnaround time at this level is trying to measure 412 /* Trying to a turnaround time at this level is trying to measure
@@ -630,8 +627,6 @@ static void irda_usb_net_timeout(struct net_device *netdev)
630 * in completion handler, because urb->status will 627 * in completion handler, because urb->status will
631 * be -ENOENT. We will fix that at the next watchdog, 628 * be -ENOENT. We will fix that at the next watchdog,
632 * leaving more time to USB to recover... 629 * leaving more time to USB to recover...
633 * Also, we are in interrupt, so we need to have
634 * URB_ASYNC_UNLINK to work properly...
635 * Jean II */ 630 * Jean II */
636 done = 1; 631 done = 1;
637 break; 632 break;
@@ -1008,9 +1003,7 @@ static int irda_usb_net_close(struct net_device *netdev)
1008 } 1003 }
1009 } 1004 }
1010 /* Cancel Tx and speed URB - need to be synchronous to avoid races */ 1005 /* Cancel Tx and speed URB - need to be synchronous to avoid races */
1011 self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1012 usb_kill_urb(self->tx_urb); 1006 usb_kill_urb(self->tx_urb);
1013 self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1014 usb_kill_urb(self->speed_urb); 1007 usb_kill_urb(self->speed_urb);
1015 1008
1016 /* Stop and remove instance of IrLAP */ 1009 /* Stop and remove instance of IrLAP */
@@ -1521,9 +1514,7 @@ static void irda_usb_disconnect(struct usb_interface *intf)
1521 usb_kill_urb(self->rx_urb[i]); 1514 usb_kill_urb(self->rx_urb[i]);
1522 /* Cancel Tx and speed URB. 1515 /* Cancel Tx and speed URB.
1523 * Toggle flags to make sure it's synchronous. */ 1516 * Toggle flags to make sure it's synchronous. */
1524 self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1525 usb_kill_urb(self->tx_urb); 1517 usb_kill_urb(self->tx_urb);
1526 self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1527 usb_kill_urb(self->speed_urb); 1518 usb_kill_urb(self->speed_urb);
1528 } 1519 }
1529 1520
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 414694abf588..741aecc655df 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -69,14 +69,8 @@ typedef void irqreturn_t;
69 69
70#else /* 2.5 or later */ 70#else /* 2.5 or later */
71 71
72/* recent 2.5/2.6 stores pci device names at varying places ;-) */
73#ifdef CONFIG_PCI_NAMES
74/* human readable name */
75#define PCIDEV_NAME(pdev) ((pdev)->pretty_name)
76#else
77/* whatever we get from the associated struct device - bus:slot:dev.fn id */ 72/* whatever we get from the associated struct device - bus:slot:dev.fn id */
78#define PCIDEV_NAME(pdev) (pci_name(pdev)) 73#define PCIDEV_NAME(pdev) (pci_name(pdev))
79#endif
80 74
81#endif 75#endif
82 76
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7c9dbc8c9423..25c9a99c377b 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -94,7 +94,7 @@ static char mv643xx_driver_version[] = "1.0";
94static void __iomem *mv643xx_eth_shared_base; 94static void __iomem *mv643xx_eth_shared_base;
95 95
96/* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */ 96/* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */
97static spinlock_t mv643xx_eth_phy_lock = SPIN_LOCK_UNLOCKED; 97static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
98 98
99static inline u32 mv_read(int offset) 99static inline u32 mv_read(int offset)
100{ 100{
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 91df0bf181dd..7a57c1b8373f 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -215,7 +215,7 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va
215#define IOSAPIC_IRDT_ID_EID_SHIFT 0x10 215#define IOSAPIC_IRDT_ID_EID_SHIFT 0x10
216 216
217 217
218static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; 218static DEFINE_SPINLOCK(iosapic_lock);
219 219
220static inline void iosapic_eoi(void __iomem *addr, unsigned int data) 220static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
221{ 221{
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 97f723179f62..1b938bb9be3c 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3010,7 +3010,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma)
3010 struct pci_dev *pdev = NULL; 3010 struct pci_dev *pdev = NULL;
3011 int ret = 0; 3011 int ret = 0;
3012 3012
3013 while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { 3013 for_each_pci_dev(pdev) {
3014 id = pci_match_id(parport_pc_pci_tbl, pdev); 3014 id = pci_match_id(parport_pc_pci_tbl, pdev);
3015 if (id == NULL || id->driver_data >= last_sio) 3015 if (id == NULL || id->driver_data >= last_sio)
3016 continue; 3016 continue;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7f31991772ea..f187fd8aeed6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -30,23 +30,6 @@ config PCI_LEGACY_PROC
30 30
31 When in doubt, say N. 31 When in doubt, say N.
32 32
33config PCI_NAMES
34 bool "PCI device name database"
35 depends on PCI
36 ---help---
37 By default, the kernel contains a database of all known PCI device
38 names to make the information in /proc/pci, /proc/ioports and
39 similar files comprehensible to the user.
40
41 This database increases size of the kernel image by about 80KB. This
42 memory is freed after the system boots up if CONFIG_HOTPLUG is not set.
43
44 Anyway, if you are building an installation floppy or kernel for an
45 embedded system where kernel image size really matters, you can disable
46 this feature and you'll get device ID numbers instead of names.
47
48 When in doubt, say Y.
49
50config PCI_DEBUG 33config PCI_DEBUG
51 bool "PCI Debugging" 34 bool "PCI Debugging"
52 depends on PCI && DEBUG_KERNEL 35 depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3657f6199c48..716df015f8d0 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -3,14 +3,9 @@
3# 3#
4 4
5obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ 5obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
6 names.o pci-driver.o search.o pci-sysfs.o \ 6 pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
7 rom.o
8obj-$(CONFIG_PROC_FS) += proc.o 7obj-$(CONFIG_PROC_FS) += proc.o
9 8
10ifndef CONFIG_SPARC64
11obj-y += setup-res.o
12endif
13
14obj-$(CONFIG_HOTPLUG) += hotplug.o 9obj-$(CONFIG_HOTPLUG) += hotplug.o
15 10
16# Build the PCI Hotplug drivers if we were asked to 11# Build the PCI Hotplug drivers if we were asked to
@@ -46,21 +41,6 @@ ifeq ($(CONFIG_PCI_DEBUG),y)
46EXTRA_CFLAGS += -DDEBUG 41EXTRA_CFLAGS += -DDEBUG
47endif 42endif
48 43
49hostprogs-y := gen-devlist
50
51# Dependencies on generated files need to be listed explicitly
52$(obj)/names.o: $(obj)/devlist.h $(obj)/classlist.h
53$(obj)/classlist.h: $(obj)/devlist.h
54
55# And that's how to generate them
56quiet_cmd_devlist = DEVLIST $@
57 cmd_devlist = ( cd $(obj); ./gen-devlist ) < $<
58$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
59 $(call cmd,devlist)
60
61# Files generated that shall be removed upon make clean
62clean-files := devlist.h classlist.h
63
64# Build PCI Express stuff if needed 44# Build PCI Express stuff if needed
65obj-$(CONFIG_PCIEPORTBUS) += pcie/ 45obj-$(CONFIG_PCIEPORTBUS) += pcie/
66 46
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index fb9a11243d2a..eed67d9e73bc 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -140,16 +140,65 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
140void pci_enable_bridges(struct pci_bus *bus) 140void pci_enable_bridges(struct pci_bus *bus)
141{ 141{
142 struct pci_dev *dev; 142 struct pci_dev *dev;
143 int retval;
143 144
144 list_for_each_entry(dev, &bus->devices, bus_list) { 145 list_for_each_entry(dev, &bus->devices, bus_list) {
145 if (dev->subordinate) { 146 if (dev->subordinate) {
146 pci_enable_device(dev); 147 retval = pci_enable_device(dev);
147 pci_set_master(dev); 148 pci_set_master(dev);
148 pci_enable_bridges(dev->subordinate); 149 pci_enable_bridges(dev->subordinate);
149 } 150 }
150 } 151 }
151} 152}
152 153
154/** pci_walk_bus - walk devices on/under bus, calling callback.
155 * @top bus whose devices should be walked
156 * @cb callback to be called for each device found
157 * @userdata arbitrary pointer to be passed to callback.
158 *
159 * Walk the given bus, including any bridged devices
160 * on buses under this bus. Call the provided callback
161 * on each device found.
162 */
163void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
164 void *userdata)
165{
166 struct pci_dev *dev;
167 struct pci_bus *bus;
168 struct list_head *next;
169
170 bus = top;
171 spin_lock(&pci_bus_lock);
172 next = top->devices.next;
173 for (;;) {
174 if (next == &bus->devices) {
175 /* end of this bus, go up or finish */
176 if (bus == top)
177 break;
178 next = bus->self->bus_list.next;
179 bus = bus->self->bus;
180 continue;
181 }
182 dev = list_entry(next, struct pci_dev, bus_list);
183 pci_dev_get(dev);
184 if (dev->subordinate) {
185 /* this is a pci-pci bridge, do its devices next */
186 next = dev->subordinate->devices.next;
187 bus = dev->subordinate;
188 } else
189 next = dev->bus_list.next;
190 spin_unlock(&pci_bus_lock);
191
192 /* Run device routines with the bus unlocked */
193 cb(dev, userdata);
194
195 spin_lock(&pci_bus_lock);
196 pci_dev_put(dev);
197 }
198 spin_unlock(&pci_bus_lock);
199}
200EXPORT_SYMBOL_GPL(pci_walk_bus);
201
153EXPORT_SYMBOL(pci_bus_alloc_resource); 202EXPORT_SYMBOL(pci_bus_alloc_resource);
154EXPORT_SYMBOL_GPL(pci_bus_add_device); 203EXPORT_SYMBOL_GPL(pci_bus_add_device);
155EXPORT_SYMBOL(pci_bus_add_devices); 204EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c
deleted file mode 100644
index 8abfc499fdef..000000000000
--- a/drivers/pci/gen-devlist.c
+++ /dev/null
@@ -1,132 +0,0 @@
1/*
2 * Generate devlist.h and classlist.h from the PCI ID file.
3 *
4 * (c) 1999--2002 Martin Mares <mj@ucw.cz>
5 */
6
7#include <stdio.h>
8#include <string.h>
9
10#define MAX_NAME_SIZE 200
11
12static void
13pq(FILE *f, const char *c, int len)
14{
15 int i = 1;
16 while (*c && i != len) {
17 if (*c == '"')
18 fprintf(f, "\\\"");
19 else {
20 fputc(*c, f);
21 if (*c == '?' && c[1] == '?') {
22 /* Avoid trigraphs */
23 fprintf(f, "\" \"");
24 }
25 }
26 c++;
27 i++;
28 }
29}
30
31int
32main(void)
33{
34 char line[1024], *c, *bra, vend[8];
35 int vendors = 0;
36 int mode = 0;
37 int lino = 0;
38 int vendor_len = 0;
39 FILE *devf, *clsf;
40
41 devf = fopen("devlist.h", "w");
42 clsf = fopen("classlist.h", "w");
43 if (!devf || !clsf) {
44 fprintf(stderr, "Cannot create output file!\n");
45 return 1;
46 }
47
48 while (fgets(line, sizeof(line)-1, stdin)) {
49 lino++;
50 if ((c = strchr(line, '\n')))
51 *c = 0;
52 if (!line[0] || line[0] == '#')
53 continue;
54 if (line[1] == ' ') {
55 if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
56 vend[0] = line[2];
57 vend[1] = line[3];
58 vend[2] = 0;
59 mode = 2;
60 } else goto err;
61 }
62 else if (line[0] == '\t') {
63 if (line[1] == '\t')
64 continue;
65 switch (mode) {
66 case 1:
67 if (strlen(line) > 5 && line[5] == ' ') {
68 c = line + 5;
69 while (*c == ' ')
70 *c++ = 0;
71 if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
72 /* Too long, try cutting off long description */
73 bra = strchr(c, '[');
74 if (bra && bra > c && bra[-1] == ' ')
75 bra[-1] = 0;
76 if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
77 fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino);
78 fprintf(stderr, "%s\n", c);
79 /*return 1;*/
80 }
81 }
82 fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
83 pq(devf, c, MAX_NAME_SIZE - vendor_len - 1);
84 fputs("\")\n", devf);
85 } else goto err;
86 break;
87 case 2:
88 if (strlen(line) > 3 && line[3] == ' ') {
89 c = line + 3;
90 while (*c == ' ')
91 *c++ = 0;
92 fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
93 } else goto err;
94 break;
95 default:
96 goto err;
97 }
98 } else if (strlen(line) > 4 && line[4] == ' ') {
99 c = line + 4;
100 while (*c == ' ')
101 *c++ = 0;
102 if (vendors)
103 fputs("ENDVENDOR()\n\n", devf);
104 vendors++;
105 strcpy(vend, line);
106 vendor_len = strlen(c);
107 if (vendor_len + 24 > MAX_NAME_SIZE) {
108 fprintf(stderr, "Line %d: Vendor name too long\n", lino);
109 return 1;
110 }
111 fprintf(devf, "VENDOR(%s,\"", vend);
112 pq(devf, c, 0);
113 fputs("\")\n", devf);
114 mode = 1;
115 } else {
116 err:
117 fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line);
118 return 1;
119 }
120 }
121 fputs("ENDVENDOR()\n\
122\n\
123#undef VENDOR\n\
124#undef DEVICE\n\
125#undef ENDVENDOR\n", devf);
126 fputs("\n#undef CLASS\n", clsf);
127
128 fclose(devf);
129 fclose(clsf);
130
131 return 0;
132}
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index b844bc972324..10444988a10b 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -20,46 +20,35 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
20 20
21 scratch = buffer; 21 scratch = buffer;
22 22
23 /* stuff we want to pass to /sbin/hotplug */ 23
24 envp[i++] = scratch; 24 if (add_hotplug_env_var(envp, num_envp, &i,
25 length += scnprintf (scratch, buffer_size - length, "PCI_CLASS=%04X", 25 buffer, buffer_size, &length,
26 pdev->class); 26 "PCI_CLASS=%04X", pdev->class))
27 if ((buffer_size - length <= 0) || (i >= num_envp))
28 return -ENOMEM; 27 return -ENOMEM;
29 ++length;
30 scratch += length;
31 28
32 envp[i++] = scratch; 29 if (add_hotplug_env_var(envp, num_envp, &i,
33 length += scnprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X", 30 buffer, buffer_size, &length,
34 pdev->vendor, pdev->device); 31 "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
35 if ((buffer_size - length <= 0) || (i >= num_envp))
36 return -ENOMEM; 32 return -ENOMEM;
37 ++length;
38 scratch += length;
39 33
40 envp[i++] = scratch; 34 if (add_hotplug_env_var(envp, num_envp, &i,
41 length += scnprintf (scratch, buffer_size - length, 35 buffer, buffer_size, &length,
42 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, 36 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
43 pdev->subsystem_device); 37 pdev->subsystem_device))
44 if ((buffer_size - length <= 0) || (i >= num_envp))
45 return -ENOMEM; 38 return -ENOMEM;
46 ++length;
47 scratch += length;
48 39
49 envp[i++] = scratch; 40 if (add_hotplug_env_var(envp, num_envp, &i,
50 length += scnprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s", 41 buffer, buffer_size, &length,
51 pci_name(pdev)); 42 "PCI_SLOT_NAME=%s", pci_name(pdev)))
52 if ((buffer_size - length <= 0) || (i >= num_envp))
53 return -ENOMEM; 43 return -ENOMEM;
54 44
55 envp[i++] = scratch; 45 if (add_hotplug_env_var(envp, num_envp, &i,
56 length += scnprintf (scratch, buffer_size - length, 46 buffer, buffer_size, &length,
57 "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", 47 "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
58 pdev->vendor, pdev->device, 48 pdev->vendor, pdev->device,
59 pdev->subsystem_vendor, pdev->subsystem_device, 49 pdev->subsystem_vendor, pdev->subsystem_device,
60 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), 50 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
61 (u8)(pdev->class)); 51 (u8)(pdev->class)))
62 if ((buffer_size - length <= 0) || (i >= num_envp))
63 return -ENOMEM; 52 return -ENOMEM;
64 53
65 envp[i] = NULL; 54 envp[i] = NULL;
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 246586a3d91a..3c71e3077ff1 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -41,8 +41,7 @@ acpiphp-objs := acpiphp_core.o \
41 41
42rpaphp-objs := rpaphp_core.o \ 42rpaphp-objs := rpaphp_core.o \
43 rpaphp_pci.o \ 43 rpaphp_pci.o \
44 rpaphp_slot.o \ 44 rpaphp_slot.o
45 rpaphp_vio.o
46 45
47rpadlpar_io-objs := rpadlpar_core.o \ 46rpadlpar_io-objs := rpadlpar_core.o \
48 rpadlpar_sysfs.o 47 rpadlpar_sysfs.o
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 2b92b9e8c910..061ead21ef14 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -302,7 +302,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
302 302
303static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) 303static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
304{ 304{
305 snprintf(buffer, buffer_size, "%d", slot->number); 305 snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
306} 306}
307 307
308enum php_ctlr_type { 308enum php_ctlr_type {
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 305b47ec2f2c..1406db35b089 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -1696,15 +1696,15 @@ void pciehprm_enable_card(
1696 pci_bus->number = func->bus; 1696 pci_bus->number = func->bus;
1697 devfn = PCI_DEVFN(func->device, func->function); 1697 devfn = PCI_DEVFN(func->device, func->function);
1698 1698
1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command); 1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
1700 1700
1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) { 1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand); 1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
1703 } 1703 }
1704 1704
1705 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE 1705 command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; 1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; 1707 bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
1708 1708
1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); 1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710 if (ab) { 1710 if (ab) {
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 86b384e42717..ad1017da8656 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -19,33 +19,36 @@
19#include <asm/pci-bridge.h> 19#include <asm/pci-bridge.h>
20#include <asm/semaphore.h> 20#include <asm/semaphore.h>
21#include <asm/rtas.h> 21#include <asm/rtas.h>
22#include <asm/vio.h>
22#include "../pci.h" 23#include "../pci.h"
23#include "rpaphp.h" 24#include "rpaphp.h"
24#include "rpadlpar.h" 25#include "rpadlpar.h"
25 26
26static DECLARE_MUTEX(rpadlpar_sem); 27static DECLARE_MUTEX(rpadlpar_sem);
27 28
29#define DLPAR_MODULE_NAME "rpadlpar_io"
30
28#define NODE_TYPE_VIO 1 31#define NODE_TYPE_VIO 1
29#define NODE_TYPE_SLOT 2 32#define NODE_TYPE_SLOT 2
30#define NODE_TYPE_PHB 3 33#define NODE_TYPE_PHB 3
31 34
32static struct device_node *find_php_slot_vio_node(char *drc_name) 35static struct device_node *find_vio_slot_node(char *drc_name)
33{ 36{
34 struct device_node *child;
35 struct device_node *parent = of_find_node_by_name(NULL, "vdevice"); 37 struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
36 char *loc_code; 38 struct device_node *dn = NULL;
39 char *name;
40 int rc;
37 41
38 if (!parent) 42 if (!parent)
39 return NULL; 43 return NULL;
40 44
41 for (child = of_get_next_child(parent, NULL); 45 while ((dn = of_get_next_child(parent, dn))) {
42 child; child = of_get_next_child(parent, child)) { 46 rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
43 loc_code = get_property(child, "ibm,loc-code", NULL); 47 if ((rc == 0) && (!strcmp(drc_name, name)))
44 if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name))) 48 break;
45 return child;
46 } 49 }
47 50
48 return NULL; 51 return dn;
49} 52}
50 53
51/* Find dlpar-capable pci node that contains the specified name and type */ 54/* Find dlpar-capable pci node that contains the specified name and type */
@@ -67,7 +70,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name,
67 return np; 70 return np;
68} 71}
69 72
70static struct device_node *find_newly_added_node(char *drc_name, int *node_type) 73static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
71{ 74{
72 struct device_node *dn; 75 struct device_node *dn;
73 76
@@ -83,7 +86,7 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
83 return dn; 86 return dn;
84 } 87 }
85 88
86 dn = find_php_slot_vio_node(drc_name); 89 dn = find_vio_slot_node(drc_name);
87 if (dn) { 90 if (dn) {
88 *node_type = NODE_TYPE_VIO; 91 *node_type = NODE_TYPE_VIO;
89 return dn; 92 return dn;
@@ -92,14 +95,14 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
92 return NULL; 95 return NULL;
93} 96}
94 97
95static struct slot *find_slot(char *drc_name) 98static struct slot *find_slot(struct device_node *dn)
96{ 99{
97 struct list_head *tmp, *n; 100 struct list_head *tmp, *n;
98 struct slot *slot; 101 struct slot *slot;
99 102
100 list_for_each_safe(tmp, n, &rpaphp_slot_head) { 103 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
101 slot = list_entry(tmp, struct slot, rpaphp_slot_list); 104 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
102 if (strcmp(slot->location, drc_name) == 0) 105 if (slot->dn == dn)
103 return slot; 106 return slot;
104 } 107 }
105 108
@@ -131,7 +134,8 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
131static int pci_add_secondary_bus(struct device_node *dn, 134static int pci_add_secondary_bus(struct device_node *dn,
132 struct pci_dev *bridge_dev) 135 struct pci_dev *bridge_dev)
133{ 136{
134 struct pci_controller *hose = dn->phb; 137 struct pci_dn *pdn = dn->data;
138 struct pci_controller *hose = pdn->phb;
135 struct pci_bus *child; 139 struct pci_bus *child;
136 u8 sec_busno; 140 u8 sec_busno;
137 141
@@ -156,7 +160,7 @@ static int pci_add_secondary_bus(struct device_node *dn,
156 if (hose->last_busno < child->number) 160 if (hose->last_busno < child->number)
157 hose->last_busno = child->number; 161 hose->last_busno = child->number;
158 162
159 dn->bussubno = child->number; 163 pdn->bussubno = child->number;
160 164
161 /* ioremap() for child bus, which may or may not succeed */ 165 /* ioremap() for child bus, which may or may not succeed */
162 remap_bus_range(child); 166 remap_bus_range(child);
@@ -164,13 +168,28 @@ static int pci_add_secondary_bus(struct device_node *dn,
164 return 0; 168 return 0;
165} 169}
166 170
171static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
172 struct device_node *dev_dn)
173{
174 struct pci_dev *tmp = NULL;
175 struct device_node *child_dn;
176
177 list_for_each_entry(tmp, &parent->devices, bus_list) {
178 child_dn = pci_device_to_OF_node(tmp);
179 if (child_dn == dev_dn)
180 return tmp;
181 }
182 return NULL;
183}
184
167static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) 185static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
168{ 186{
169 struct pci_controller *hose = dn->phb; 187 struct pci_dn *pdn = dn->data;
188 struct pci_controller *hose = pdn->phb;
170 struct pci_dev *dev = NULL; 189 struct pci_dev *dev = NULL;
171 190
172 /* Scan phb bus for EADS device, adding new one to bus->devices */ 191 /* Scan phb bus for EADS device, adding new one to bus->devices */
173 if (!pci_scan_single_device(hose->bus, dn->devfn)) { 192 if (!pci_scan_single_device(hose->bus, pdn->devfn)) {
174 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__); 193 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
175 return NULL; 194 return NULL;
176 } 195 }
@@ -179,49 +198,28 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
179 pci_bus_add_devices(hose->bus); 198 pci_bus_add_devices(hose->bus);
180 199
181 /* Confirm new bridge dev was created */ 200 /* Confirm new bridge dev was created */
182 dev = rpaphp_find_pci_dev(dn); 201 dev = dlpar_find_new_dev(hose->bus, dn);
183 if (!dev) { 202 if (dev) {
184 printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__); 203 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
185 return NULL; 204 printk(KERN_ERR "%s: unexpected header type %d\n",
186 } 205 __FUNCTION__, dev->hdr_type);
206 return NULL;
207 }
187 208
188 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { 209 if (pci_add_secondary_bus(dn, dev))
189 printk(KERN_ERR "%s: unexpected header type %d\n", 210 return NULL;
190 __FUNCTION__, dev->hdr_type);
191 return NULL;
192 } 211 }
193 212
194 if (pci_add_secondary_bus(dn, dev))
195 return NULL;
196
197 return dev; 213 return dev;
198} 214}
199 215
200static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev) 216static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
201{ 217{
202 struct pci_bus *secondary_bus; 218 struct pci_dev *dev;
219 int rc;
203 220
204 if (!bridge_dev) { 221 if (rpaphp_find_pci_bus(dn))
205 printk(KERN_ERR "%s: unexpected null device\n",
206 __FUNCTION__);
207 return -EINVAL; 222 return -EINVAL;
208 }
209
210 secondary_bus = bridge_dev->subordinate;
211
212 if (unmap_bus_range(secondary_bus)) {
213 printk(KERN_ERR "%s: failed to unmap bus range\n",
214 __FUNCTION__);
215 return -ERANGE;
216 }
217
218 pci_remove_bus_device(bridge_dev);
219 return 0;
220}
221
222static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
223{
224 struct pci_dev *dev;
225 223
226 /* Add pci bus */ 224 /* Add pci bus */
227 dev = dlpar_pci_add_bus(dn); 225 dev = dlpar_pci_add_bus(dn);
@@ -231,6 +229,21 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
231 return -EIO; 229 return -EIO;
232 } 230 }
233 231
232 if (dn->child) {
233 rc = rpaphp_config_pci_adapter(dev->subordinate);
234 if (rc < 0) {
235 printk(KERN_ERR "%s: unable to enable slot %s\n",
236 __FUNCTION__, drc_name);
237 return -EIO;
238 }
239 }
240
241 /* Add hotplug slot */
242 if (rpaphp_add_slot(dn)) {
243 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
244 __FUNCTION__, drc_name);
245 return -EIO;
246 }
234 return 0; 247 return 0;
235} 248}
236 249
@@ -255,47 +268,69 @@ static int dlpar_remove_root_bus(struct pci_controller *phb)
255 return 0; 268 return 0;
256} 269}
257 270
258static int dlpar_remove_phb(struct slot *slot) 271static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
259{ 272{
260 struct pci_controller *phb; 273 struct slot *slot;
261 struct device_node *dn; 274 struct pci_dn *pdn;
262 int rc = 0; 275 int rc = 0;
263 276
264 dn = slot->dn; 277 if (!rpaphp_find_pci_bus(dn))
265 if (!dn) { 278 return -EINVAL;
266 printk(KERN_ERR "%s: unexpected NULL slot device node\n",
267 __FUNCTION__);
268 return -EIO;
269 }
270
271 phb = dn->phb;
272 if (!phb) {
273 printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
274 __FUNCTION__);
275 return -EIO;
276 }
277 279
278 if (rpaphp_remove_slot(slot)) { 280 slot = find_slot(dn);
279 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", 281 if (slot) {
280 __FUNCTION__, slot->location); 282 /* Remove hotplug slot */
281 return -EIO; 283 if (rpaphp_remove_slot(slot)) {
284 printk(KERN_ERR
285 "%s: unable to remove hotplug slot %s\n",
286 __FUNCTION__, drc_name);
287 return -EIO;
288 }
282 } 289 }
283 290
284 rc = dlpar_remove_root_bus(phb); 291 pdn = dn->data;
292 BUG_ON(!pdn || !pdn->phb);
293 rc = dlpar_remove_root_bus(pdn->phb);
285 if (rc < 0) 294 if (rc < 0)
286 return rc; 295 return rc;
287 296
297 pdn->phb = NULL;
298
288 return 0; 299 return 0;
289} 300}
290 301
291static int dlpar_add_phb(struct device_node *dn) 302static int dlpar_add_phb(char *drc_name, struct device_node *dn)
292{ 303{
293 struct pci_controller *phb; 304 struct pci_controller *phb;
294 305
306 if (PCI_DN(dn)->phb) {
307 /* PHB already exists */
308 return -EINVAL;
309 }
310
295 phb = init_phb_dynamic(dn); 311 phb = init_phb_dynamic(dn);
296 if (!phb) 312 if (!phb)
313 return -EIO;
314
315 if (rpaphp_add_slot(dn)) {
316 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
317 __FUNCTION__, drc_name);
318 return -EIO;
319 }
320 return 0;
321}
322
323static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
324{
325 if (vio_find_node(dn))
297 return -EINVAL; 326 return -EINVAL;
298 327
328 if (!vio_register_device_node(dn)) {
329 printk(KERN_ERR
330 "%s: failed to register vio node %s\n",
331 __FUNCTION__, drc_name);
332 return -EIO;
333 }
299 return 0; 334 return 0;
300} 335}
301 336
@@ -316,18 +351,13 @@ int dlpar_add_slot(char *drc_name)
316{ 351{
317 struct device_node *dn = NULL; 352 struct device_node *dn = NULL;
318 int node_type; 353 int node_type;
319 int rc = 0; 354 int rc = -EIO;
320 355
321 if (down_interruptible(&rpadlpar_sem)) 356 if (down_interruptible(&rpadlpar_sem))
322 return -ERESTARTSYS; 357 return -ERESTARTSYS;
323 358
324 /* Check for existing hotplug slot */ 359 /* Find newly added node */
325 if (find_slot(drc_name)) { 360 dn = find_dlpar_node(drc_name, &node_type);
326 rc = -EINVAL;
327 goto exit;
328 }
329
330 dn = find_newly_added_node(drc_name, &node_type);
331 if (!dn) { 361 if (!dn) {
332 rc = -ENODEV; 362 rc = -ENODEV;
333 goto exit; 363 goto exit;
@@ -335,24 +365,17 @@ int dlpar_add_slot(char *drc_name)
335 365
336 switch (node_type) { 366 switch (node_type) {
337 case NODE_TYPE_VIO: 367 case NODE_TYPE_VIO:
338 /* Just add hotplug slot */ 368 rc = dlpar_add_vio_slot(drc_name, dn);
339 break; 369 break;
340 case NODE_TYPE_SLOT: 370 case NODE_TYPE_SLOT:
341 rc = dlpar_add_pci_slot(drc_name, dn); 371 rc = dlpar_add_pci_slot(drc_name, dn);
342 break; 372 break;
343 case NODE_TYPE_PHB: 373 case NODE_TYPE_PHB:
344 rc = dlpar_add_phb(dn); 374 rc = dlpar_add_phb(drc_name, dn);
345 break; 375 break;
346 default:
347 printk("%s: unexpected node type\n", __FUNCTION__);
348 return -EIO;
349 } 376 }
350 377
351 if (!rc && rpaphp_add_slot(dn)) { 378 printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name);
352 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
353 __FUNCTION__, drc_name);
354 rc = -EIO;
355 }
356exit: 379exit:
357 up(&rpadlpar_sem); 380 up(&rpadlpar_sem);
358 return rc; 381 return rc;
@@ -366,17 +389,17 @@ exit:
366 * of an I/O Slot. 389 * of an I/O Slot.
367 * Return Codes: 390 * Return Codes:
368 * 0 Success 391 * 0 Success
369 * -EIO Internal Error 392 * -EINVAL Vio dev doesn't exist
370 */ 393 */
371int dlpar_remove_vio_slot(struct slot *slot, char *drc_name) 394static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
372{ 395{
373 /* Remove hotplug slot */ 396 struct vio_dev *vio_dev;
374 397
375 if (rpaphp_remove_slot(slot)) { 398 vio_dev = vio_find_node(dn);
376 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", 399 if (!vio_dev)
377 __FUNCTION__, drc_name); 400 return -EINVAL;
378 return -EIO; 401
379 } 402 vio_unregister_device(vio_dev);
380 return 0; 403 return 0;
381} 404}
382 405
@@ -391,31 +414,34 @@ int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
391 * -ENODEV Not a valid drc_name 414 * -ENODEV Not a valid drc_name
392 * -EIO Internal PCI Error 415 * -EIO Internal PCI Error
393 */ 416 */
394int dlpar_remove_pci_slot(struct slot *slot, char *drc_name) 417int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
395{ 418{
396 struct pci_dev *bridge_dev; 419 struct pci_bus *bus;
420 struct slot *slot;
397 421
398 bridge_dev = slot->bridge; 422 bus = rpaphp_find_pci_bus(dn);
399 if (!bridge_dev) { 423 if (!bus)
400 printk(KERN_ERR "%s: unexpected null bridge device\n", 424 return -EINVAL;
401 __FUNCTION__);
402 return -EIO;
403 }
404 425
405 /* Remove hotplug slot */ 426 slot = find_slot(dn);
406 if (rpaphp_remove_slot(slot)) { 427 if (slot) {
407 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", 428 /* Remove hotplug slot */
408 __FUNCTION__, drc_name); 429 if (rpaphp_remove_slot(slot)) {
409 return -EIO; 430 printk(KERN_ERR
431 "%s: unable to remove hotplug slot %s\n",
432 __FUNCTION__, drc_name);
433 return -EIO;
434 }
410 } 435 }
411 436
412 /* Remove pci bus */ 437 if (unmap_bus_range(bus)) {
413 438 printk(KERN_ERR "%s: failed to unmap bus range\n",
414 if (dlpar_pci_remove_bus(bridge_dev)) { 439 __FUNCTION__);
415 printk(KERN_ERR "%s: unable to remove pci bus %s\n", 440 return -ERANGE;
416 __FUNCTION__, drc_name);
417 return -EIO;
418 } 441 }
442
443 BUG_ON(!bus->self);
444 pci_remove_bus_device(bus->self);
419 return 0; 445 return 0;
420} 446}
421 447
@@ -434,38 +460,31 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
434 */ 460 */
435int dlpar_remove_slot(char *drc_name) 461int dlpar_remove_slot(char *drc_name)
436{ 462{
437 struct slot *slot; 463 struct device_node *dn;
464 int node_type;
438 int rc = 0; 465 int rc = 0;
439 466
440 if (down_interruptible(&rpadlpar_sem)) 467 if (down_interruptible(&rpadlpar_sem))
441 return -ERESTARTSYS; 468 return -ERESTARTSYS;
442 469
443 if (!find_php_slot_vio_node(drc_name) && 470 dn = find_dlpar_node(drc_name, &node_type);
444 !find_php_slot_pci_node(drc_name, "SLOT") && 471 if (!dn) {
445 !find_php_slot_pci_node(drc_name, "PHB")) {
446 rc = -ENODEV; 472 rc = -ENODEV;
447 goto exit; 473 goto exit;
448 } 474 }
449 475
450 slot = find_slot(drc_name); 476 switch (node_type) {
451 if (!slot) { 477 case NODE_TYPE_VIO:
452 rc = -EINVAL; 478 rc = dlpar_remove_vio_slot(drc_name, dn);
453 goto exit; 479 break;
454 } 480 case NODE_TYPE_PHB:
455 481 rc = dlpar_remove_phb(drc_name, dn);
456 if (slot->type == PHB) { 482 break;
457 rc = dlpar_remove_phb(slot); 483 case NODE_TYPE_SLOT:
458 } else { 484 rc = dlpar_remove_pci_slot(drc_name, dn);
459 switch (slot->dev_type) { 485 break;
460 case PCI_DEV:
461 rc = dlpar_remove_pci_slot(slot, drc_name);
462 break;
463
464 case VIO_DEV:
465 rc = dlpar_remove_vio_slot(slot, drc_name);
466 break;
467 }
468 } 486 }
487 printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
469exit: 488exit:
470 up(&rpadlpar_sem); 489 up(&rpadlpar_sem);
471 return rc; 490 return rc;
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 81746e6e0e0f..61d94d1e29cb 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -30,10 +30,6 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include "pci_hotplug.h" 31#include "pci_hotplug.h"
32 32
33#define PHB 2
34#define HOTPLUG 1
35#define EMBEDDED 0
36
37#define DR_INDICATOR 9002 33#define DR_INDICATOR 9002
38#define DR_ENTITY_SENSE 9003 34#define DR_ENTITY_SENSE 9003
39 35
@@ -61,10 +57,6 @@ extern int debug;
61#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 57#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
62#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 58#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
63 59
64/* slot types */
65#define VIO_DEV 1
66#define PCI_DEV 2
67
68/* slot states */ 60/* slot states */
69 61
70#define NOT_VALID 3 62#define NOT_VALID 3
@@ -72,11 +64,6 @@ extern int debug;
72#define CONFIGURED 1 64#define CONFIGURED 1
73#define EMPTY 0 65#define EMPTY 0
74 66
75struct rpaphp_pci_func {
76 struct pci_dev *pci_dev;
77 struct list_head sibling;
78};
79
80/* 67/*
81 * struct slot - slot information for each *physical* slot 68 * struct slot - slot information for each *physical* slot
82 */ 69 */
@@ -88,15 +75,9 @@ struct slot {
88 u32 power_domain; 75 u32 power_domain;
89 char *name; 76 char *name;
90 char *location; 77 char *location;
91 u8 removable; 78 struct device_node *dn;
92 u8 dev_type; /* VIO or PCI */ 79 struct pci_bus *bus;
93 struct device_node *dn; /* slot's device_node in OFDT */ 80 struct list_head *pci_devs;
94 /* dn has phb info */
95 struct pci_dev *bridge; /* slot's pci_dev in pci_devices */
96 union {
97 struct list_head *pci_devs; /* pci_devs in PCI slot */
98 struct vio_dev *vio_dev; /* vio_dev in VIO slot */
99 } dev;
100 struct hotplug_slot *hotplug_slot; 81 struct hotplug_slot *hotplug_slot;
101}; 82};
102 83
@@ -107,13 +88,13 @@ extern int num_slots;
107/* function prototypes */ 88/* function prototypes */
108 89
109/* rpaphp_pci.c */ 90/* rpaphp_pci.c */
110extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn); 91extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
111extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); 92extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
112extern int rpaphp_enable_pci_slot(struct slot *slot); 93extern int rpaphp_enable_pci_slot(struct slot *slot);
113extern int register_pci_slot(struct slot *slot); 94extern int register_pci_slot(struct slot *slot);
114extern int rpaphp_unconfig_pci_adapter(struct slot *slot); 95extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
115extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); 96extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
116extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev); 97extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
117 98
118/* rpaphp_core.c */ 99/* rpaphp_core.c */
119extern int rpaphp_add_slot(struct device_node *dn); 100extern int rpaphp_add_slot(struct device_node *dn);
@@ -121,12 +102,6 @@ extern int rpaphp_remove_slot(struct slot *slot);
121extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, 102extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
122 char **drc_name, char **drc_type, int *drc_power_domain); 103 char **drc_name, char **drc_type, int *drc_power_domain);
123 104
124/* rpaphp_vio.c */
125extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
126extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
127extern int register_vio_slot(struct device_node *dn);
128extern int rpaphp_enable_vio_slot(struct slot *slot);
129
130/* rpaphp_slot.c */ 105/* rpaphp_slot.c */
131extern void dealloc_slot_struct(struct slot *slot); 106extern void dealloc_slot_struct(struct slot *slot);
132extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); 107extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 29117a3a3287..c830ff0acdc3 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -152,17 +152,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
152 int retval = 0; 152 int retval = 0;
153 153
154 down(&rpaphp_sem); 154 down(&rpaphp_sem);
155 /* have to go through this */ 155 retval = rpaphp_get_pci_adapter_status(slot, 0, value);
156 switch (slot->dev_type) {
157 case PCI_DEV:
158 retval = rpaphp_get_pci_adapter_status(slot, 0, value);
159 break;
160 case VIO_DEV:
161 retval = rpaphp_get_vio_adapter_status(slot, 0, value);
162 break;
163 default:
164 retval = -EINVAL;
165 }
166 up(&rpaphp_sem); 156 up(&rpaphp_sem);
167 return retval; 157 return retval;
168} 158}
@@ -317,34 +307,6 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names,
317 return 0; 307 return 0;
318} 308}
319 309
320static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
321 int **types, int **power_domains, int **my_drc_index)
322{
323 int rc;
324
325 *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
326 if(!*my_drc_index)
327 return (0);
328
329 if (!dn->parent)
330 return (0);
331
332 rc = get_children_props(dn->parent, indexes, names, types,
333 power_domains);
334 return (rc >= 0);
335}
336
337static inline int is_vdevice_root(struct device_node *dn)
338{
339 return !strcmp(dn->name, "vdevice");
340}
341
342int is_dlpar_type(const char *type_str)
343{
344 /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
345 return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
346}
347
348/**************************************************************** 310/****************************************************************
349 * rpaphp not only registers PCI hotplug slots(HOTPLUG), 311 * rpaphp not only registers PCI hotplug slots(HOTPLUG),
350 * but also logical DR slots(EMBEDDED). 312 * but also logical DR slots(EMBEDDED).
@@ -356,54 +318,33 @@ int rpaphp_add_slot(struct device_node *dn)
356{ 318{
357 struct slot *slot; 319 struct slot *slot;
358 int retval = 0; 320 int retval = 0;
359 int i, *my_drc_index, slot_type; 321 int i;
360 int *indexes, *names, *types, *power_domains; 322 int *indexes, *names, *types, *power_domains;
361 char *name, *type; 323 char *name, *type;
362 324
363 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name); 325 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
364 326
365 if (dn->parent && is_vdevice_root(dn->parent)) {
366 /* register a VIO device */
367 retval = register_vio_slot(dn);
368 goto exit;
369 }
370
371 /* register PCI devices */ 327 /* register PCI devices */
372 if (dn->name != 0 && strcmp(dn->name, "pci") == 0) { 328 if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
373 if (is_php_dn(dn, &indexes, &names, &types, &power_domains)) 329 if (!is_php_dn(dn, &indexes, &names, &types, &power_domains))
374 slot_type = HOTPLUG; 330 goto exit;
375 else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index))
376 slot_type = EMBEDDED;
377 else goto exit;
378 331
379 name = (char *) &names[1]; 332 name = (char *) &names[1];
380 type = (char *) &types[1]; 333 type = (char *) &types[1];
381 for (i = 0; i < indexes[0]; i++, 334 for (i = 0; i < indexes[0]; i++,
382 name += (strlen(name) + 1), type += (strlen(type) + 1)) { 335 name += (strlen(name) + 1), type += (strlen(type) + 1)) {
383 336
384 if (slot_type == HOTPLUG || 337 if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
385 (slot_type == EMBEDDED && 338 power_domains[i + 1]))) {
386 indexes[i + 1] == my_drc_index[0] && 339 retval = -ENOMEM;
387 is_dlpar_type(type))) { 340 goto exit;
388 if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, 341 }
389 power_domains[i + 1]))) { 342 slot->type = simple_strtoul(type, NULL, 10);
390 retval = -ENOMEM;
391 goto exit;
392 }
393 if (!strcmp(type, "PHB"))
394 slot->type = PHB;
395 else if (slot_type == EMBEDDED)
396 slot->type = EMBEDDED;
397 else
398 slot->type = simple_strtoul(type, NULL, 10);
399 343
400 dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n", 344 dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
401 indexes[i + 1], name, type); 345 indexes[i + 1], name, type);
402 346
403 retval = register_pci_slot(slot); 347 retval = register_pci_slot(slot);
404 if (slot_type == EMBEDDED)
405 goto exit;
406 }
407 } 348 }
408 } 349 }
409exit: 350exit:
@@ -412,31 +353,6 @@ exit:
412 return retval; 353 return retval;
413} 354}
414 355
415/*
416 * init_slots - initialize 'struct slot' structures for each slot
417 *
418 */
419static void init_slots(void)
420{
421 struct device_node *dn;
422
423 for (dn = find_all_nodes(); dn; dn = dn->next)
424 rpaphp_add_slot(dn);
425}
426
427static int __init init_rpa(void)
428{
429
430 init_MUTEX(&rpaphp_sem);
431
432 /* initialize internal data structure etc. */
433 init_slots();
434 if (!num_slots)
435 return -ENODEV;
436
437 return 0;
438}
439
440static void __exit cleanup_slots(void) 356static void __exit cleanup_slots(void)
441{ 357{
442 struct list_head *tmp, *n; 358 struct list_head *tmp, *n;
@@ -458,10 +374,18 @@ static void __exit cleanup_slots(void)
458 374
459static int __init rpaphp_init(void) 375static int __init rpaphp_init(void)
460{ 376{
377 struct device_node *dn = NULL;
378
461 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 379 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
380 init_MUTEX(&rpaphp_sem);
462 381
463 /* read all the PRA info from the system */ 382 while ((dn = of_find_node_by_type(dn, "pci")))
464 return init_rpa(); 383 rpaphp_add_slot(dn);
384
385 if (!num_slots)
386 return -ENODEV;
387
388 return 0;
465} 389}
466 390
467static void __exit rpaphp_exit(void) 391static void __exit rpaphp_exit(void)
@@ -481,16 +405,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
481 405
482 dbg("ENABLING SLOT %s\n", slot->name); 406 dbg("ENABLING SLOT %s\n", slot->name);
483 down(&rpaphp_sem); 407 down(&rpaphp_sem);
484 switch (slot->dev_type) { 408 retval = rpaphp_enable_pci_slot(slot);
485 case PCI_DEV:
486 retval = rpaphp_enable_pci_slot(slot);
487 break;
488 case VIO_DEV:
489 retval = rpaphp_enable_vio_slot(slot);
490 break;
491 default:
492 retval = -EINVAL;
493 }
494 up(&rpaphp_sem); 409 up(&rpaphp_sem);
495exit: 410exit:
496 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); 411 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
@@ -511,16 +426,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
511 426
512 dbg("DISABLING SLOT %s\n", slot->name); 427 dbg("DISABLING SLOT %s\n", slot->name);
513 down(&rpaphp_sem); 428 down(&rpaphp_sem);
514 switch (slot->dev_type) { 429 retval = rpaphp_unconfig_pci_adapter(slot);
515 case PCI_DEV:
516 retval = rpaphp_unconfig_pci_adapter(slot);
517 break;
518 case VIO_DEV:
519 retval = rpaphp_unconfig_vio_adapter(slot);
520 break;
521 default:
522 retval = -ENODEV;
523 }
524 up(&rpaphp_sem); 430 up(&rpaphp_sem);
525exit: 431exit:
526 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); 432 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index d8305a935aab..49e4d10a6488 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -30,22 +30,35 @@
30 30
31#include "rpaphp.h" 31#include "rpaphp.h"
32 32
33struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) 33static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
34 struct device_node *dn)
34{ 35{
35 struct pci_dev *dev = NULL; 36 struct pci_bus *child = NULL;
36 char bus_id[BUS_ID_SIZE]; 37 struct list_head *tmp;
38 struct device_node *busdn;
39
40 busdn = pci_bus_to_OF_node(bus);
41 if (busdn == dn)
42 return bus;
37 43
38 sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number, 44 list_for_each(tmp, &bus->children) {
39 dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); 45 child = find_bus_among_children(pci_bus_b(tmp), dn);
40 for_each_pci_dev(dev) { 46 if (child)
41 if (!strcmp(pci_name(dev), bus_id)) {
42 break; 47 break;
43 }
44 } 48 }
45 return dev; 49 return child;
46} 50}
47 51
48EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); 52struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
53{
54 struct pci_dn *pdn = dn->data;
55
56 if (!pdn || !pdn->phb || !pdn->phb->bus)
57 return NULL;
58
59 return find_bus_among_children(pdn->phb->bus, dn);
60}
61EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
49 62
50int rpaphp_claim_resource(struct pci_dev *dev, int resource) 63int rpaphp_claim_resource(struct pci_dev *dev, int resource)
51{ 64{
@@ -69,11 +82,6 @@ int rpaphp_claim_resource(struct pci_dev *dev, int resource)
69 82
70EXPORT_SYMBOL_GPL(rpaphp_claim_resource); 83EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
71 84
72static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot)
73{
74 return rpaphp_find_pci_dev(slot->dn);
75}
76
77static int rpaphp_get_sensor_state(struct slot *slot, int *state) 85static int rpaphp_get_sensor_state(struct slot *slot, int *state)
78{ 86{
79 int rc; 87 int rc;
@@ -116,39 +124,27 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state)
116 */ 124 */
117int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) 125int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
118{ 126{
127 struct pci_bus *bus;
119 int state, rc; 128 int state, rc;
120 struct device_node *child_dn;
121 struct pci_dev *child_dev = NULL;
122 129
123 *value = NOT_VALID; 130 *value = NOT_VALID;
124 rc = rpaphp_get_sensor_state(slot, &state); 131 rc = rpaphp_get_sensor_state(slot, &state);
125 if (rc) 132 if (rc)
126 goto exit; 133 goto exit;
127 134
128 if ((state == EMPTY) || (slot->type == PHB)) { 135 if (state == EMPTY)
129 dbg("slot is empty\n");
130 *value = EMPTY; 136 *value = EMPTY;
131 }
132 else if (state == PRESENT) { 137 else if (state == PRESENT) {
133 if (!is_init) { 138 if (!is_init) {
134 /* at run-time slot->state can be changed by */ 139 /* at run-time slot->state can be changed by */
135 /* config/unconfig adapter */ 140 /* config/unconfig adapter */
136 *value = slot->state; 141 *value = slot->state;
137 } else { 142 } else {
138 child_dn = slot->dn->child; 143 bus = rpaphp_find_pci_bus(slot->dn);
139 if (child_dn) 144 if (bus && !list_empty(&bus->devices))
140 child_dev = rpaphp_find_pci_dev(child_dn); 145 *value = CONFIGURED;
141 146 else
142 if (child_dev)
143 *value = CONFIGURED;
144 else if (!child_dn)
145 dbg("%s: %s is not valid OFDT node\n",
146 __FUNCTION__, slot->dn->full_name);
147 else {
148 err("%s: can't find pdev of adapter in slot[%s]\n",
149 __FUNCTION__, slot->dn->full_name);
150 *value = NOT_CONFIGURED; 147 *value = NOT_CONFIGURED;
151 }
152 } 148 }
153 } 149 }
154exit: 150exit:
@@ -186,39 +182,6 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
186 } 182 }
187} 183}
188 184
189static int rpaphp_pci_config_bridge(struct pci_dev *dev);
190
191/*****************************************************************************
192 rpaphp_pci_config_slot() will configure all devices under the
193 given slot->dn and return the the first pci_dev.
194 *****************************************************************************/
195static struct pci_dev *
196rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus)
197{
198 struct device_node *eads_first_child = dn->child;
199 struct pci_dev *dev = NULL;
200 int num;
201
202 dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
203
204 if (eads_first_child) {
205 /* pci_scan_slot should find all children of EADs */
206 num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0));
207 if (num) {
208 rpaphp_fixup_new_pci_devices(bus, 1);
209 pci_bus_add_devices(bus);
210 }
211 dev = rpaphp_find_pci_dev(eads_first_child);
212 if (!dev) {
213 err("No new device found\n");
214 return NULL;
215 }
216 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
217 rpaphp_pci_config_bridge(dev);
218 }
219 return dev;
220}
221
222static int rpaphp_pci_config_bridge(struct pci_dev *dev) 185static int rpaphp_pci_config_bridge(struct pci_dev *dev)
223{ 186{
224 u8 sec_busno; 187 u8 sec_busno;
@@ -252,6 +215,42 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
252 return 0; 215 return 0;
253} 216}
254 217
218/*****************************************************************************
219 rpaphp_pci_config_slot() will configure all devices under the
220 given slot->dn and return the the first pci_dev.
221 *****************************************************************************/
222static struct pci_dev *
223rpaphp_pci_config_slot(struct pci_bus *bus)
224{
225 struct device_node *dn = pci_bus_to_OF_node(bus);
226 struct pci_dev *dev = NULL;
227 int slotno;
228 int num;
229
230 dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
231 if (!dn || !dn->child)
232 return NULL;
233
234 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
235
236 /* pci_scan_slot should find all children */
237 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
238 if (num) {
239 rpaphp_fixup_new_pci_devices(bus, 1);
240 pci_bus_add_devices(bus);
241 }
242 if (list_empty(&bus->devices)) {
243 err("%s: No new device found\n", __FUNCTION__);
244 return NULL;
245 }
246 list_for_each_entry(dev, &bus->devices, bus_list) {
247 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
248 rpaphp_pci_config_bridge(dev);
249 }
250
251 return dev;
252}
253
255static void enable_eeh(struct device_node *dn) 254static void enable_eeh(struct device_node *dn)
256{ 255{
257 struct device_node *sib; 256 struct device_node *sib;
@@ -263,49 +262,44 @@ static void enable_eeh(struct device_node *dn)
263 262
264} 263}
265 264
266static void print_slot_pci_funcs(struct slot *slot) 265static void print_slot_pci_funcs(struct pci_bus *bus)
267{ 266{
267 struct device_node *dn;
268 struct pci_dev *dev; 268 struct pci_dev *dev;
269 269
270 if (slot->dev_type == PCI_DEV) { 270 dn = pci_bus_to_OF_node(bus);
271 dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name); 271 if (!dn)
272 list_for_each_entry (dev, slot->dev.pci_devs, bus_list) 272 return;
273 dbg("\t%s\n", pci_name(dev)); 273
274 } 274 dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name);
275 list_for_each_entry (dev, &bus->devices, bus_list)
276 dbg("\t%s\n", pci_name(dev));
275 return; 277 return;
276} 278}
277 279
278static int rpaphp_config_pci_adapter(struct slot *slot) 280int rpaphp_config_pci_adapter(struct pci_bus *bus)
279{ 281{
280 struct pci_bus *pci_bus; 282 struct device_node *dn = pci_bus_to_OF_node(bus);
281 struct pci_dev *dev; 283 struct pci_dev *dev;
282 int rc = -ENODEV; 284 int rc = -ENODEV;
283 285
284 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name); 286 dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
285 287 if (!dn)
286 if (slot->bridge) { 288 goto exit;
287 289
288 pci_bus = slot->bridge->subordinate; 290 enable_eeh(dn);
289 if (!pci_bus) { 291 dev = rpaphp_pci_config_slot(bus);
290 err("%s: can't find bus structure\n", __FUNCTION__); 292 if (!dev) {
291 goto exit; 293 err("%s: can't find any devices.\n", __FUNCTION__);
292 } 294 goto exit;
293 enable_eeh(slot->dn);
294 dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
295 if (!dev) {
296 err("%s: can't find any devices.\n", __FUNCTION__);
297 goto exit;
298 }
299 print_slot_pci_funcs(slot);
300 rc = 0;
301 } else {
302 /* slot is not enabled */
303 err("slot doesn't have pci_dev structure\n");
304 } 295 }
296 print_slot_pci_funcs(bus);
297 rc = 0;
305exit: 298exit:
306 dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); 299 dbg("Exit %s: rc=%d\n", __FUNCTION__, rc);
307 return rc; 300 return rc;
308} 301}
302EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
309 303
310static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) 304static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
311{ 305{
@@ -327,13 +321,14 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
327 321
328int rpaphp_unconfig_pci_adapter(struct slot *slot) 322int rpaphp_unconfig_pci_adapter(struct slot *slot)
329{ 323{
330 struct pci_dev *dev; 324 struct pci_dev *dev, *tmp;
331 int retval = 0; 325 int retval = 0;
332 326
333 list_for_each_entry(dev, slot->dev.pci_devs, bus_list) 327 list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
334 rpaphp_eeh_remove_bus_device(dev); 328 rpaphp_eeh_remove_bus_device(dev);
329 pci_remove_bus_device(dev);
330 }
335 331
336 pci_remove_behind_bridge(slot->bridge);
337 slot->state = NOT_CONFIGURED; 332 slot->state = NOT_CONFIGURED;
338 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, 333 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
339 slot->name); 334 slot->name);
@@ -356,66 +351,41 @@ static int setup_pci_hotplug_slot_info(struct slot *slot)
356 return 0; 351 return 0;
357} 352}
358 353
359static int set_phb_slot_name(struct slot *slot) 354static void set_slot_name(struct slot *slot)
360{ 355{
361 struct device_node *dn; 356 struct pci_bus *bus = slot->bus;
362 struct pci_controller *phb; 357 struct pci_dev *bridge;
363 struct pci_bus *bus;
364
365 dn = slot->dn;
366 if (!dn) {
367 return -EINVAL;
368 }
369 phb = dn->phb;
370 if (!phb) {
371 return -EINVAL;
372 }
373 bus = phb->bus;
374 if (!bus) {
375 return -EINVAL;
376 }
377 358
378 sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus), 359 bridge = bus->self;
379 bus->number, 0, 0); 360 if (bridge)
380 return 0; 361 strcpy(slot->name, pci_name(bridge));
362 else
363 sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
364 bus->number);
381} 365}
382 366
383static int setup_pci_slot(struct slot *slot) 367static int setup_pci_slot(struct slot *slot)
384{ 368{
369 struct device_node *dn = slot->dn;
385 struct pci_bus *bus; 370 struct pci_bus *bus;
386 int rc;
387 371
388 if (slot->type == PHB) { 372 BUG_ON(!dn);
389 rc = set_phb_slot_name(slot); 373 bus = rpaphp_find_pci_bus(dn);
390 if (rc < 0) { 374 if (!bus) {
391 err("%s: failed to set phb slot name\n", __FUNCTION__); 375 err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
392 goto exit_rc; 376 goto exit_rc;
393 }
394 } else {
395 slot->bridge = rpaphp_find_bridge_pdev(slot);
396 if (!slot->bridge) {
397 /* slot being added doesn't have pci_dev yet */
398 err("%s: no pci_dev for bridge dn %s\n",
399 __FUNCTION__, slot->name);
400 goto exit_rc;
401 }
402
403 bus = slot->bridge->subordinate;
404 if (!bus)
405 goto exit_rc;
406 slot->dev.pci_devs = &bus->devices;
407
408 dbg("%s set slot->name to %s\n", __FUNCTION__,
409 pci_name(slot->bridge));
410 strcpy(slot->name, pci_name(slot->bridge));
411 } 377 }
412 378
379 slot->bus = bus;
380 slot->pci_devs = &bus->devices;
381 set_slot_name(slot);
382
413 /* find slot's pci_dev if it's not empty */ 383 /* find slot's pci_dev if it's not empty */
414 if (slot->hotplug_slot->info->adapter_status == EMPTY) { 384 if (slot->hotplug_slot->info->adapter_status == EMPTY) {
415 slot->state = EMPTY; /* slot is empty */ 385 slot->state = EMPTY; /* slot is empty */
416 } else { 386 } else {
417 /* slot is occupied */ 387 /* slot is occupied */
418 if (!(slot->dn->child)) { 388 if (!dn->child) {
419 /* non-empty slot has to have child */ 389 /* non-empty slot has to have child */
420 err("%s: slot[%s]'s device_node doesn't have child for adapter\n", 390 err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
421 __FUNCTION__, slot->name); 391 __FUNCTION__, slot->name);
@@ -425,7 +395,7 @@ static int setup_pci_slot(struct slot *slot)
425 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { 395 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
426 dbg("%s CONFIGURING pci adapter in slot[%s]\n", 396 dbg("%s CONFIGURING pci adapter in slot[%s]\n",
427 __FUNCTION__, slot->name); 397 __FUNCTION__, slot->name);
428 if (rpaphp_config_pci_adapter(slot)) { 398 if (rpaphp_config_pci_adapter(slot->bus)) {
429 err("%s: CONFIG pci adapter failed\n", __FUNCTION__); 399 err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
430 goto exit_rc; 400 goto exit_rc;
431 } 401 }
@@ -435,8 +405,8 @@ static int setup_pci_slot(struct slot *slot)
435 __FUNCTION__, slot->name); 405 __FUNCTION__, slot->name);
436 goto exit_rc; 406 goto exit_rc;
437 } 407 }
438 print_slot_pci_funcs(slot); 408 print_slot_pci_funcs(slot->bus);
439 if (!list_empty(slot->dev.pci_devs)) { 409 if (!list_empty(slot->pci_devs)) {
440 slot->state = CONFIGURED; 410 slot->state = CONFIGURED;
441 } else { 411 } else {
442 /* DLPAR add as opposed to 412 /* DLPAR add as opposed to
@@ -454,11 +424,6 @@ int register_pci_slot(struct slot *slot)
454{ 424{
455 int rc = -EINVAL; 425 int rc = -EINVAL;
456 426
457 slot->dev_type = PCI_DEV;
458 if ((slot->type == EMBEDDED) || (slot->type == PHB))
459 slot->removable = 0;
460 else
461 slot->removable = 1;
462 if (setup_pci_hotplug_slot_info(slot)) 427 if (setup_pci_hotplug_slot_info(slot))
463 goto exit_rc; 428 goto exit_rc;
464 if (setup_pci_slot(slot)) 429 if (setup_pci_slot(slot))
@@ -479,7 +444,7 @@ int rpaphp_enable_pci_slot(struct slot *slot)
479 /* if slot is not empty, enable the adapter */ 444 /* if slot is not empty, enable the adapter */
480 if (state == PRESENT) { 445 if (state == PRESENT) {
481 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); 446 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
482 retval = rpaphp_config_pci_adapter(slot); 447 retval = rpaphp_config_pci_adapter(slot->bus);
483 if (!retval) { 448 if (!retval) {
484 slot->state = CONFIGURED; 449 slot->state = CONFIGURED;
485 dbg("%s: PCI devices in slot[%s] has been configured\n", 450 dbg("%s: PCI devices in slot[%s] has been configured\n",
@@ -502,37 +467,3 @@ exit:
502 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); 467 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
503 return retval; 468 return retval;
504} 469}
505
506struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev)
507{
508 struct list_head *tmp, *n;
509 struct slot *slot;
510
511 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
512 struct pci_bus *bus;
513 struct list_head *ln;
514
515 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
516 if (slot->bridge == NULL) {
517 if (slot->dev_type == PCI_DEV) {
518 printk(KERN_WARNING "PCI slot missing bridge %s %s \n",
519 slot->name, slot->location);
520 }
521 continue;
522 }
523
524 bus = slot->bridge->subordinate;
525 if (!bus) {
526 continue; /* should never happen? */
527 }
528 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
529 struct pci_dev *pdev = pci_dev_b(ln);
530 if (pdev == dev)
531 return slot->hotplug_slot;
532 }
533 }
534
535 return NULL;
536}
537
538EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot);
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index ff2cbf0652d8..0e8815495083 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -30,35 +30,6 @@
30#include <asm/rtas.h> 30#include <asm/rtas.h>
31#include "rpaphp.h" 31#include "rpaphp.h"
32 32
33static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf)
34{
35 u8 value;
36 int retval = -ENOENT;
37 struct slot *slot = (struct slot *)php_slot->private;
38
39 if (!slot)
40 return retval;
41
42 value = slot->removable;
43 retval = sprintf (buf, "%d\n", value);
44 return retval;
45}
46
47static struct hotplug_slot_attribute hotplug_slot_attr_removable = {
48 .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO},
49 .show = removable_read_file,
50};
51
52static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot)
53{
54 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
55}
56
57static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot)
58{
59 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
60}
61
62static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) 33static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
63{ 34{
64 char *value; 35 char *value;
@@ -176,9 +147,6 @@ int deregister_slot(struct slot *slot)
176 /* remove "phy_location" file */ 147 /* remove "phy_location" file */
177 rpaphp_sysfs_remove_attr_location(php_slot); 148 rpaphp_sysfs_remove_attr_location(php_slot);
178 149
179 /* remove "phy_removable" file */
180 rpaphp_sysfs_remove_attr_removable(php_slot);
181
182 retval = pci_hp_deregister(php_slot); 150 retval = pci_hp_deregister(php_slot);
183 if (retval) 151 if (retval)
184 err("Problem unregistering a slot %s\n", slot->name); 152 err("Problem unregistering a slot %s\n", slot->name);
@@ -212,21 +180,13 @@ int register_slot(struct slot *slot)
212 /* create "phy_locatoin" file */ 180 /* create "phy_locatoin" file */
213 rpaphp_sysfs_add_attr_location(slot->hotplug_slot); 181 rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
214 182
215 /* create "phy_removable" file */
216 rpaphp_sysfs_add_attr_removable(slot->hotplug_slot);
217
218 /* add slot to our internal list */ 183 /* add slot to our internal list */
219 dbg("%s adding slot[%s] to rpaphp_slot_list\n", 184 dbg("%s adding slot[%s] to rpaphp_slot_list\n",
220 __FUNCTION__, slot->name); 185 __FUNCTION__, slot->name);
221 186
222 list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); 187 list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
223 188 info("Slot [%s](PCI location=%s) registered\n", slot->name,
224 if (slot->dev_type == VIO_DEV) 189 slot->location);
225 info("Slot [%s](VIO location=%s) registered\n",
226 slot->name, slot->location);
227 else
228 info("Slot [%s](PCI location=%s) registered\n",
229 slot->name, slot->location);
230 num_slots++; 190 num_slots++;
231 return 0; 191 return 0;
232} 192}
@@ -235,21 +195,17 @@ int rpaphp_get_power_status(struct slot *slot, u8 * value)
235{ 195{
236 int rc = 0, level; 196 int rc = 0, level;
237 197
238 if (slot->type == HOTPLUG) { 198 rc = rtas_get_power_level(slot->power_domain, &level);
239 rc = rtas_get_power_level(slot->power_domain, &level); 199 if (rc < 0) {
240 if (!rc) { 200 err("failed to get power-level for slot(%s), rc=0x%x\n",
241 dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n", 201 slot->location, rc);
242 __FUNCTION__, slot->name, slot->power_domain, level); 202 return rc;
243 *value = level;
244 } else
245 err("failed to get power-level for slot(%s), rc=0x%x\n",
246 slot->location, rc);
247 } else {
248 dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
249 __FUNCTION__, slot->location);
250 *value = (u8) POWER_ON;
251 } 203 }
252 204
205 dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
206 __FUNCTION__, slot->name, slot->power_domain, level);
207 *value = level;
208
253 return rc; 209 return rc;
254} 210}
255 211
diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
deleted file mode 100644
index 74df6a305e64..000000000000
--- a/drivers/pci/hotplug/rpaphp_vio.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 * RPA Hot Plug Virtual I/O device functions
3 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
4 *
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * 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 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <asm/vio.h>
26#include "rpaphp.h"
27
28/*
29 * get_vio_adapter_status - get the status of a slot
30 *
31 * status:
32 *
33 * 1-- adapter is configured
34 * 2-- adapter is not configured
35 * 3-- not valid
36 */
37inline int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 *value)
38{
39 *value = slot->state;
40 return 0;
41}
42
43int rpaphp_unconfig_vio_adapter(struct slot *slot)
44{
45 int retval = 0;
46
47 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
48 if (!slot->dev.vio_dev) {
49 info("%s: no VIOA in slot[%s]\n", __FUNCTION__, slot->name);
50 retval = -EINVAL;
51 goto exit;
52 }
53 /* remove the device from the vio core */
54 vio_unregister_device(slot->dev.vio_dev);
55 slot->state = NOT_CONFIGURED;
56 info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, slot->name);
57exit:
58 dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
59 return retval;
60}
61
62static int setup_vio_hotplug_slot_info(struct slot *slot)
63{
64 slot->hotplug_slot->info->power_status = 1;
65 rpaphp_get_vio_adapter_status(slot, 1,
66 &slot->hotplug_slot->info->adapter_status);
67 return 0;
68}
69
70int register_vio_slot(struct device_node *dn)
71{
72 u32 *index;
73 char *name;
74 int rc = -EINVAL;
75 struct slot *slot = NULL;
76
77 rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
78 if (rc < 0)
79 goto exit_rc;
80 index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
81 if (!index)
82 goto exit_rc;
83 if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
84 rc = -ENOMEM;
85 goto exit_rc;
86 }
87 slot->dev_type = VIO_DEV;
88 slot->dev.vio_dev = vio_find_node(dn);
89 if (slot->dev.vio_dev) {
90 /*
91 * rpaphp is the only owner of vio devices and
92 * does not need extra reference taken by
93 * vio_find_node
94 */
95 put_device(&slot->dev.vio_dev->dev);
96 } else
97 slot->dev.vio_dev = vio_register_device_node(dn);
98 if (slot->dev.vio_dev)
99 slot->state = CONFIGURED;
100 else
101 slot->state = NOT_CONFIGURED;
102 if (setup_vio_hotplug_slot_info(slot))
103 goto exit_rc;
104 strcpy(slot->name, slot->dev.vio_dev->dev.bus_id);
105 info("%s: registered VIO device[name=%s vio_dev=%p]\n",
106 __FUNCTION__, slot->name, slot->dev.vio_dev);
107 rc = register_slot(slot);
108exit_rc:
109 if (rc && slot)
110 dealloc_slot_struct(slot);
111 return (rc);
112}
113
114int rpaphp_enable_vio_slot(struct slot *slot)
115{
116 int retval = 0;
117
118 if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) {
119 info("%s: VIO adapter %s in slot[%s] has been configured\n",
120 __FUNCTION__, slot->dn->name, slot->name);
121 slot->state = CONFIGURED;
122 } else {
123 info("%s: no vio_dev struct for adapter in slot[%s]\n",
124 __FUNCTION__, slot->name);
125 slot->state = NOT_CONFIGURED;
126 }
127
128 return retval;
129}
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 323041fd41dc..b1409441c1cd 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -32,14 +32,15 @@ MODULE_LICENSE("GPL");
32MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); 32MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
33MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver"); 33MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
34 34
35#define PCIIO_ASIC_TYPE_TIOCA 4 35#define PCIIO_ASIC_TYPE_TIOCA 4
36#define PCI_SLOT_ALREADY_UP 2 /* slot already up */ 36#define PCI_SLOT_ALREADY_UP 2 /* slot already up */
37#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */ 37#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */
38#define PCI_L1_ERR 7 /* L1 console command error */ 38#define PCI_L1_ERR 7 /* L1 console command error */
39#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */ 39#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */
40#define PCI_L1_QSIZE 128 /* our L1 message buffer size */ 40#define PCI_L1_QSIZE 128 /* our L1 message buffer size */
41#define SN_MAX_HP_SLOTS 32 /* max number of hotplug slots */ 41#define SN_MAX_HP_SLOTS 32 /* max hotplug slots */
42#define SGI_HOTPLUG_PROM_REV 0x0420 /* Min. required PROM version */ 42#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */
43#define SN_SLOT_NAME_SIZE 33 /* size of name string */
43 44
44/* internal list head */ 45/* internal list head */
45static struct list_head sn_hp_list; 46static struct list_head sn_hp_list;
@@ -51,6 +52,7 @@ struct slot {
51 /* this struct for glue internal only */ 52 /* this struct for glue internal only */
52 struct hotplug_slot *hotplug_slot; 53 struct hotplug_slot *hotplug_slot;
53 struct list_head hp_list; 54 struct list_head hp_list;
55 char physical_path[SN_SLOT_NAME_SIZE];
54}; 56};
55 57
56struct pcibr_slot_enable_resp { 58struct pcibr_slot_enable_resp {
@@ -70,7 +72,7 @@ enum sn_pci_req_e {
70 72
71static int enable_slot(struct hotplug_slot *slot); 73static int enable_slot(struct hotplug_slot *slot);
72static int disable_slot(struct hotplug_slot *slot); 74static int disable_slot(struct hotplug_slot *slot);
73static int get_power_status(struct hotplug_slot *slot, u8 *value); 75static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
74 76
75static struct hotplug_slot_ops sn_hotplug_slot_ops = { 77static struct hotplug_slot_ops sn_hotplug_slot_ops = {
76 .owner = THIS_MODULE, 78 .owner = THIS_MODULE,
@@ -81,6 +83,21 @@ static struct hotplug_slot_ops sn_hotplug_slot_ops = {
81 83
82static DECLARE_MUTEX(sn_hotplug_sem); 84static DECLARE_MUTEX(sn_hotplug_sem);
83 85
86static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot,
87 char *buf)
88{
89 int retval = -ENOENT;
90 struct slot *slot = bss_hotplug_slot->private;
91
92 if (!slot)
93 return retval;
94
95 retval = sprintf (buf, "%s\n", slot->physical_path);
96 return retval;
97}
98
99static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
100
84static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) 101static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
85{ 102{
86 struct pcibus_info *pcibus_info; 103 struct pcibus_info *pcibus_info;
@@ -120,15 +137,15 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
120 /* Only register slots in I/O Bricks that support hotplug */ 137 /* Only register slots in I/O Bricks that support hotplug */
121 bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); 138 bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
122 switch (bricktype) { 139 switch (bricktype) {
123 case L1_BRICKTYPE_IX: 140 case L1_BRICKTYPE_IX:
124 case L1_BRICKTYPE_PX: 141 case L1_BRICKTYPE_PX:
125 case L1_BRICKTYPE_IA: 142 case L1_BRICKTYPE_IA:
126 case L1_BRICKTYPE_PA: 143 case L1_BRICKTYPE_PA:
127 return 1; 144 return 1;
128 break; 145 break;
129 default: 146 default:
130 return -EPERM; 147 return -EPERM;
131 break; 148 break;
132 } 149 }
133 150
134 return -EIO; 151 return -EIO;
@@ -142,13 +159,12 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
142 159
143 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus); 160 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
144 161
145 bss_hotplug_slot->private = kcalloc(1, sizeof(struct slot), 162 slot = kcalloc(1, sizeof(*slot), GFP_KERNEL);
146 GFP_KERNEL); 163 if (!slot)
147 if (!bss_hotplug_slot->private)
148 return -ENOMEM; 164 return -ENOMEM;
149 slot = (struct slot *)bss_hotplug_slot->private; 165 bss_hotplug_slot->private = slot;
150 166
151 bss_hotplug_slot->name = kmalloc(33, GFP_KERNEL); 167 bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
152 if (!bss_hotplug_slot->name) { 168 if (!bss_hotplug_slot->name) {
153 kfree(bss_hotplug_slot->private); 169 kfree(bss_hotplug_slot->private);
154 return -ENOMEM; 170 return -ENOMEM;
@@ -156,16 +172,16 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
156 172
157 slot->device_num = device; 173 slot->device_num = device;
158 slot->pci_bus = pci_bus; 174 slot->pci_bus = pci_bus;
159 175 sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
160 sprintf(bss_hotplug_slot->name, "module_%c%c%c%c%.2d_b_%d_s_%d", 176 pci_domain_nr(pci_bus),
177 ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
178 device + 1);
179 sprintf(slot->physical_path, "module_%c%c%c%c%.2d",
161 '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), 180 '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
162 '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), 181 '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
163 '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), 182 '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
164 MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid), 183 MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
165 MODULE_GET_BPOS(pcibus_info->pbi_moduleid), 184 MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
166 ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
167 device + 1);
168
169 slot->hotplug_slot = bss_hotplug_slot; 185 slot->hotplug_slot = bss_hotplug_slot;
170 list_add(&slot->hp_list, &sn_hp_list); 186 list_add(&slot->hp_list, &sn_hp_list);
171 187
@@ -175,14 +191,14 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
175static struct hotplug_slot * sn_hp_destroy(void) 191static struct hotplug_slot * sn_hp_destroy(void)
176{ 192{
177 struct slot *slot; 193 struct slot *slot;
178 struct list_head *list;
179 struct hotplug_slot *bss_hotplug_slot = NULL; 194 struct hotplug_slot *bss_hotplug_slot = NULL;
180 195
181 list_for_each(list, &sn_hp_list) { 196 list_for_each_entry(slot, &sn_hp_list, hp_list) {
182 slot = list_entry(list, struct slot, hp_list);
183 bss_hotplug_slot = slot->hotplug_slot; 197 bss_hotplug_slot = slot->hotplug_slot;
184 list_del(&((struct slot *)bss_hotplug_slot->private)-> 198 list_del(&((struct slot *)bss_hotplug_slot->private)->
185 hp_list); 199 hp_list);
200 sysfs_remove_file(&bss_hotplug_slot->kobj,
201 &sn_slot_path_attr.attr);
186 break; 202 break;
187 } 203 }
188 return bss_hotplug_slot; 204 return bss_hotplug_slot;
@@ -190,7 +206,6 @@ static struct hotplug_slot * sn_hp_destroy(void)
190 206
191static void sn_bus_alloc_data(struct pci_dev *dev) 207static void sn_bus_alloc_data(struct pci_dev *dev)
192{ 208{
193 struct list_head *node;
194 struct pci_bus *subordinate_bus; 209 struct pci_bus *subordinate_bus;
195 struct pci_dev *child; 210 struct pci_dev *child;
196 211
@@ -199,66 +214,29 @@ static void sn_bus_alloc_data(struct pci_dev *dev)
199 /* Recursively sets up the sn_irq_info structs */ 214 /* Recursively sets up the sn_irq_info structs */
200 if (dev->subordinate) { 215 if (dev->subordinate) {
201 subordinate_bus = dev->subordinate; 216 subordinate_bus = dev->subordinate;
202 list_for_each(node, &subordinate_bus->devices) { 217 list_for_each_entry(child, &subordinate_bus->devices, bus_list)
203 child = list_entry(node, struct pci_dev, bus_list);
204 sn_bus_alloc_data(child); 218 sn_bus_alloc_data(child);
205 }
206 } 219 }
207} 220}
208 221
209static void sn_bus_free_data(struct pci_dev *dev) 222static void sn_bus_free_data(struct pci_dev *dev)
210{ 223{
211 struct list_head *node;
212 struct pci_bus *subordinate_bus; 224 struct pci_bus *subordinate_bus;
213 struct pci_dev *child; 225 struct pci_dev *child;
214 226
215 /* Recursively clean up sn_irq_info structs */ 227 /* Recursively clean up sn_irq_info structs */
216 if (dev->subordinate) { 228 if (dev->subordinate) {
217 subordinate_bus = dev->subordinate; 229 subordinate_bus = dev->subordinate;
218 list_for_each(node, &subordinate_bus->devices) { 230 list_for_each_entry(child, &subordinate_bus->devices, bus_list)
219 child = list_entry(node, struct pci_dev, bus_list);
220 sn_bus_free_data(child); 231 sn_bus_free_data(child);
221 }
222 } 232 }
223 sn_pci_unfixup_slot(dev); 233 sn_pci_unfixup_slot(dev);
224} 234}
225 235
226static u8 sn_power_status_get(struct hotplug_slot *bss_hotplug_slot)
227{
228 struct slot *slot = (struct slot *)bss_hotplug_slot->private;
229 struct pcibus_info *pcibus_info;
230 u8 retval;
231
232 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
233 retval = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
234
235 return retval ? 1 : 0;
236}
237
238static void sn_slot_mark_enable(struct hotplug_slot *bss_hotplug_slot,
239 int device_num)
240{
241 struct slot *slot = (struct slot *)bss_hotplug_slot->private;
242 struct pcibus_info *pcibus_info;
243
244 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
245 pcibus_info->pbi_enabled_devices |= (1 << device_num);
246}
247
248static void sn_slot_mark_disable(struct hotplug_slot *bss_hotplug_slot,
249 int device_num)
250{
251 struct slot *slot = (struct slot *)bss_hotplug_slot->private;
252 struct pcibus_info *pcibus_info;
253
254 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
255 pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
256}
257
258static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, 236static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
259 int device_num) 237 int device_num)
260{ 238{
261 struct slot *slot = (struct slot *)bss_hotplug_slot->private; 239 struct slot *slot = bss_hotplug_slot->private;
262 struct pcibus_info *pcibus_info; 240 struct pcibus_info *pcibus_info;
263 struct pcibr_slot_enable_resp resp; 241 struct pcibr_slot_enable_resp resp;
264 int rc; 242 int rc;
@@ -273,7 +251,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
273 251
274 if (rc == PCI_SLOT_ALREADY_UP) { 252 if (rc == PCI_SLOT_ALREADY_UP) {
275 dev_dbg(slot->pci_bus->self, "is already active\n"); 253 dev_dbg(slot->pci_bus->self, "is already active\n");
276 return -EPERM; 254 return 1; /* return 1 to user */
277 } 255 }
278 256
279 if (rc == PCI_L1_ERR) { 257 if (rc == PCI_L1_ERR) {
@@ -290,7 +268,8 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
290 return -EIO; 268 return -EIO;
291 } 269 }
292 270
293 sn_slot_mark_enable(bss_hotplug_slot, device_num); 271 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
272 pcibus_info->pbi_enabled_devices |= (1 << device_num);
294 273
295 return 0; 274 return 0;
296} 275}
@@ -298,7 +277,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
298static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, 277static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
299 int device_num, int action) 278 int device_num, int action)
300{ 279{
301 struct slot *slot = (struct slot *)bss_hotplug_slot->private; 280 struct slot *slot = bss_hotplug_slot->private;
302 struct pcibus_info *pcibus_info; 281 struct pcibus_info *pcibus_info;
303 struct pcibr_slot_disable_resp resp; 282 struct pcibr_slot_disable_resp resp;
304 int rc; 283 int rc;
@@ -307,43 +286,44 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
307 286
308 rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp); 287 rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
309 288
310 if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_SLOT_ALREADY_DOWN) { 289 if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
290 (rc == PCI_SLOT_ALREADY_DOWN)) {
311 dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n"); 291 dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
312 return -ENODEV; 292 return 1; /* return 1 to user */
313 } 293 }
314 294
315 if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_EMPTY_33MHZ) { 295 if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
316 dev_dbg(slot->pci_bus->self, 296 dev_dbg(slot->pci_bus->self,
317 "Cannot remove last 33MHz card\n"); 297 "Cannot remove last 33MHz card\n");
318 return -EPERM; 298 return -EPERM;
319 } 299 }
320 300
321 if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_L1_ERR) { 301 if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
322 dev_dbg(slot->pci_bus->self, 302 dev_dbg(slot->pci_bus->self,
323 "L1 failure %d with message \n%s\n", 303 "L1 failure %d with message \n%s\n",
324 resp.resp_sub_errno, resp.resp_l1_msg); 304 resp.resp_sub_errno, resp.resp_l1_msg);
325 return -EPERM; 305 return -EPERM;
326 } 306 }
327 307
328 if (action == PCI_REQ_SLOT_ELIGIBLE && rc) { 308 if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
329 dev_dbg(slot->pci_bus->self, 309 dev_dbg(slot->pci_bus->self,
330 "remove failed with error %d sub-error %d\n", 310 "remove failed with error %d sub-error %d\n",
331 rc, resp.resp_sub_errno); 311 rc, resp.resp_sub_errno);
332 return -EIO; 312 return -EIO;
333 } 313 }
334 314
335 if (action == PCI_REQ_SLOT_ELIGIBLE && !rc) 315 if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
336 return 0; 316 return 0;
337 317
338 if (action == PCI_REQ_SLOT_DISABLE && !rc) { 318 if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
339 sn_slot_mark_disable(bss_hotplug_slot, device_num); 319 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
320 pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
340 dev_dbg(slot->pci_bus->self, "remove successful\n"); 321 dev_dbg(slot->pci_bus->self, "remove successful\n");
341 return 0; 322 return 0;
342 } 323 }
343 324
344 if (action == PCI_REQ_SLOT_DISABLE && rc) { 325 if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
345 dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc); 326 dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
346 return rc;
347 } 327 }
348 328
349 return rc; 329 return rc;
@@ -351,7 +331,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
351 331
352static int enable_slot(struct hotplug_slot *bss_hotplug_slot) 332static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
353{ 333{
354 struct slot *slot = (struct slot *)bss_hotplug_slot->private; 334 struct slot *slot = bss_hotplug_slot->private;
355 struct pci_bus *new_bus = NULL; 335 struct pci_bus *new_bus = NULL;
356 struct pci_dev *dev; 336 struct pci_dev *dev;
357 int func, num_funcs; 337 int func, num_funcs;
@@ -371,8 +351,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
371 return rc; 351 return rc;
372 } 352 }
373 353
374 num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num+1, 354 num_funcs = pci_scan_slot(slot->pci_bus,
375 PCI_FUNC(0))); 355 PCI_DEVFN(slot->device_num + 1, 0));
376 if (!num_funcs) { 356 if (!num_funcs) {
377 dev_dbg(slot->pci_bus->self, "no device in slot\n"); 357 dev_dbg(slot->pci_bus->self, "no device in slot\n");
378 up(&sn_hotplug_sem); 358 up(&sn_hotplug_sem);
@@ -391,8 +371,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
391 dev = pci_get_slot(slot->pci_bus, 371 dev = pci_get_slot(slot->pci_bus,
392 PCI_DEVFN(slot->device_num + 1, 372 PCI_DEVFN(slot->device_num + 1,
393 PCI_FUNC(func))); 373 PCI_FUNC(func)));
394
395
396 if (dev) { 374 if (dev) {
397 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 375 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
398 unsigned char sec_bus; 376 unsigned char sec_bus;
@@ -431,7 +409,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
431 409
432static int disable_slot(struct hotplug_slot *bss_hotplug_slot) 410static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
433{ 411{
434 struct slot *slot = (struct slot *)bss_hotplug_slot->private; 412 struct slot *slot = bss_hotplug_slot->private;
435 struct pci_dev *dev; 413 struct pci_dev *dev;
436 int func; 414 int func;
437 int rc; 415 int rc;
@@ -448,7 +426,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
448 /* Free the SN resources assigned to the Linux device.*/ 426 /* Free the SN resources assigned to the Linux device.*/
449 for (func = 0; func < 8; func++) { 427 for (func = 0; func < 8; func++) {
450 dev = pci_get_slot(slot->pci_bus, 428 dev = pci_get_slot(slot->pci_bus,
451 PCI_DEVFN(slot->device_num+1, 429 PCI_DEVFN(slot->device_num + 1,
452 PCI_FUNC(func))); 430 PCI_FUNC(func)));
453 if (dev) { 431 if (dev) {
454 /* 432 /*
@@ -477,10 +455,15 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
477 return rc; 455 return rc;
478} 456}
479 457
480static int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value) 458static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
459 u8 *value)
481{ 460{
461 struct slot *slot = bss_hotplug_slot->private;
462 struct pcibus_info *pcibus_info;
463
464 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
482 down(&sn_hotplug_sem); 465 down(&sn_hotplug_sem);
483 *value = sn_power_status_get(bss_hotplug_slot); 466 *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
484 up(&sn_hotplug_sem); 467 up(&sn_hotplug_sem);
485 return 0; 468 return 0;
486} 469}
@@ -508,7 +491,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
508 if (sn_pci_slot_valid(pci_bus, device) != 1) 491 if (sn_pci_slot_valid(pci_bus, device) != 1)
509 continue; 492 continue;
510 493
511 bss_hotplug_slot = kcalloc(1,sizeof(struct hotplug_slot), 494 bss_hotplug_slot = kcalloc(1, sizeof(*bss_hotplug_slot),
512 GFP_KERNEL); 495 GFP_KERNEL);
513 if (!bss_hotplug_slot) { 496 if (!bss_hotplug_slot) {
514 rc = -ENOMEM; 497 rc = -ENOMEM;
@@ -516,7 +499,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
516 } 499 }
517 500
518 bss_hotplug_slot->info = 501 bss_hotplug_slot->info =
519 kcalloc(1,sizeof(struct hotplug_slot_info), 502 kcalloc(1, sizeof(struct hotplug_slot_info),
520 GFP_KERNEL); 503 GFP_KERNEL);
521 if (!bss_hotplug_slot->info) { 504 if (!bss_hotplug_slot->info) {
522 rc = -ENOMEM; 505 rc = -ENOMEM;
@@ -535,6 +518,11 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
535 rc = pci_hp_register(bss_hotplug_slot); 518 rc = pci_hp_register(bss_hotplug_slot);
536 if (rc) 519 if (rc)
537 goto register_err; 520 goto register_err;
521
522 rc = sysfs_create_file(&bss_hotplug_slot->kobj,
523 &sn_slot_path_attr.attr);
524 if (rc)
525 goto register_err;
538 } 526 }
539 dev_dbg(pci_bus->self, "Registered bus with hotplug\n"); 527 dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
540 return rc; 528 return rc;
@@ -564,14 +552,14 @@ static int sn_pci_hotplug_init(void)
564 int rc; 552 int rc;
565 int registered = 0; 553 int registered = 0;
566 554
567 INIT_LIST_HEAD(&sn_hp_list);
568
569 if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) { 555 if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
570 printk(KERN_ERR "%s: PROM version must be greater than 4.05\n", 556 printk(KERN_ERR "%s: PROM version must be greater than 4.30\n",
571 __FUNCTION__); 557 __FUNCTION__);
572 return -EPERM; 558 return -EPERM;
573 } 559 }
574 560
561 INIT_LIST_HEAD(&sn_hp_list);
562
575 while ((pci_bus = pci_find_next_bus(pci_bus))) { 563 while ((pci_bus = pci_find_next_bus(pci_bus))) {
576 if (!pci_bus->sysdata) 564 if (!pci_bus->sysdata)
577 continue; 565 continue;
@@ -584,9 +572,9 @@ static int sn_pci_hotplug_init(void)
584 dev_dbg(pci_bus->self, "valid hotplug bus\n"); 572 dev_dbg(pci_bus->self, "valid hotplug bus\n");
585 573
586 rc = sn_hotplug_slot_register(pci_bus); 574 rc = sn_hotplug_slot_register(pci_bus);
587 if (!rc) 575 if (!rc) {
588 registered = 1; 576 registered = 1;
589 else { 577 } else {
590 registered = 0; 578 registered = 0;
591 break; 579 break;
592 } 580 }
@@ -599,9 +587,8 @@ static void sn_pci_hotplug_exit(void)
599{ 587{
600 struct hotplug_slot *bss_hotplug_slot; 588 struct hotplug_slot *bss_hotplug_slot;
601 589
602 while ((bss_hotplug_slot = sn_hp_destroy())) { 590 while ((bss_hotplug_slot = sn_hp_destroy()))
603 pci_hp_deregister(bss_hotplug_slot); 591 pci_hp_deregister(bss_hotplug_slot);
604 }
605 592
606 if (!list_empty(&sn_hp_list)) 593 if (!list_empty(&sn_hp_list))
607 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__); 594 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index fe4d653da188..b7d1c61d6bbb 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -411,7 +411,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
411 411
412static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) 412static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
413{ 413{
414 snprintf(buffer, buffer_size, "%d", slot->number); 414 snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
415} 415}
416 416
417enum php_ctlr_type { 417enum php_ctlr_type {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 532f73bb2224..ee8677bda950 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -439,10 +439,7 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
439 } 439 }
440 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 440 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
441 /* PCI Express Endpoint device detected */ 441 /* PCI Express Endpoint device detected */
442 u16 cmd; 442 pci_intx(dev, 0); /* disable intx */
443 pci_read_config_word(dev, PCI_COMMAND, &cmd);
444 cmd |= PCI_COMMAND_INTX_DISABLE;
445 pci_write_config_word(dev, PCI_COMMAND, cmd);
446 } 443 }
447} 444}
448 445
@@ -461,10 +458,7 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
461 } 458 }
462 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 459 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
463 /* PCI Express Endpoint device detected */ 460 /* PCI Express Endpoint device detected */
464 u16 cmd; 461 pci_intx(dev, 1); /* enable intx */
465 pci_read_config_word(dev, PCI_COMMAND, &cmd);
466 cmd &= ~PCI_COMMAND_INTX_DISABLE;
467 pci_write_config_word(dev, PCI_COMMAND, cmd);
468 } 462 }
469} 463}
470 464
diff --git a/drivers/pci/names.c b/drivers/pci/names.c
deleted file mode 100644
index ad224aada7c9..000000000000
--- a/drivers/pci/names.c
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * PCI Class and Device Name Tables
3 *
4 * Copyright 1993--1999 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang, Martin Mares
6 */
7
8#include <linux/config.h>
9#include <linux/types.h>
10#include <linux/kernel.h>
11#include <linux/pci.h>
12#include <linux/init.h>
13
14#ifdef CONFIG_PCI_NAMES
15
16struct pci_device_info {
17 unsigned short device;
18 unsigned short seen;
19 const char *name;
20};
21
22struct pci_vendor_info {
23 unsigned short vendor;
24 unsigned short nr;
25 const char *name;
26 struct pci_device_info *devices;
27};
28
29/*
30 * This is ridiculous, but we want the strings in
31 * the .init section so that they don't take up
32 * real memory.. Parse the same file multiple times
33 * to get all the info.
34 */
35#define VENDOR( vendor, name ) static char __vendorstr_##vendor[] __devinitdata = name;
36#define ENDVENDOR()
37#define DEVICE( vendor, device, name ) static char __devicestr_##vendor##device[] __devinitdata = name;
38#include "devlist.h"
39
40
41#define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __devinitdata = {
42#define ENDVENDOR() };
43#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device },
44#include "devlist.h"
45
46static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
47#define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
48#define ENDVENDOR()
49#define DEVICE( vendor, device, name )
50#include "devlist.h"
51};
52
53#define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info))
54
55void __devinit pci_name_device(struct pci_dev *dev)
56{
57 const struct pci_vendor_info *vendor_p = pci_vendor_list;
58 int i = VENDORS;
59 char *name = dev->pretty_name;
60
61 do {
62 if (vendor_p->vendor == dev->vendor)
63 goto match_vendor;
64 vendor_p++;
65 } while (--i);
66
67 /* Couldn't find either the vendor nor the device */
68 sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device);
69 return;
70
71 match_vendor: {
72 struct pci_device_info *device_p = vendor_p->devices;
73 int i = vendor_p->nr;
74
75 while (i > 0) {
76 if (device_p->device == dev->device)
77 goto match_device;
78 device_p++;
79 i--;
80 }
81
82 /* Ok, found the vendor, but unknown device */
83 sprintf(name, "PCI device %04x:%04x (%." PCI_NAME_HALF "s)",
84 dev->vendor, dev->device, vendor_p->name);
85 return;
86
87 /* Full match */
88 match_device: {
89 char *n = name + sprintf(name, "%s %s",
90 vendor_p->name, device_p->name);
91 int nr = device_p->seen + 1;
92 device_p->seen = nr;
93 if (nr > 1)
94 sprintf(n, " (#%d)", nr);
95 }
96 }
97}
98
99/*
100 * Class names. Not in .init section as they are needed in runtime.
101 */
102
103static u16 pci_class_numbers[] = {
104#define CLASS(x,y) 0x##x,
105#include "classlist.h"
106};
107
108static char *pci_class_names[] = {
109#define CLASS(x,y) y,
110#include "classlist.h"
111};
112
113char *
114pci_class_name(u32 class)
115{
116 int i;
117
118 for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++)
119 if (pci_class_numbers[i] == class)
120 return pci_class_names[i];
121 return NULL;
122}
123
124#else
125
126void __devinit pci_name_device(struct pci_dev *dev)
127{
128}
129
130char *
131pci_class_name(u32 class)
132{
133 return NULL;
134}
135
136#endif /* CONFIG_PCI_NAMES */
137
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e4115a0d5ba6..0d0d533894e0 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,6 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/mempolicy.h>
10#include "pci.h" 11#include "pci.h"
11 12
12/* 13/*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
163 return NULL; 164 return NULL;
164} 165}
165 166
167static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
168 const struct pci_device_id *id)
169{
170 int error;
171#ifdef CONFIG_NUMA
172 /* Execute driver initialization on node where the
173 device's bus is attached to. This way the driver likely
174 allocates its local memory on the right node without
175 any need to change it. */
176 struct mempolicy *oldpol;
177 cpumask_t oldmask = current->cpus_allowed;
178 int node = pcibus_to_node(dev->bus);
179 if (node >= 0 && node_online(node))
180 set_cpus_allowed(current, node_to_cpumask(node));
181 /* And set default memory allocation policy */
182 oldpol = current->mempolicy;
183 current->mempolicy = &default_policy;
184 mpol_get(current->mempolicy);
185#endif
186 error = drv->probe(dev, id);
187#ifdef CONFIG_NUMA
188 set_cpus_allowed(current, oldmask);
189 mpol_free(current->mempolicy);
190 current->mempolicy = oldpol;
191#endif
192 return error;
193}
194
166/** 195/**
167 * __pci_device_probe() 196 * __pci_device_probe()
168 * 197 *
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
180 209
181 id = pci_match_device(drv, pci_dev); 210 id = pci_match_device(drv, pci_dev);
182 if (id) 211 if (id)
183 error = drv->probe(pci_dev, id); 212 error = pci_call_probe(drv, pci_dev, id);
184 if (error >= 0) { 213 if (error >= 0) {
185 pci_dev->driver = drv; 214 pci_dev->driver = drv;
186 error = 0; 215 error = 0;
@@ -243,17 +272,19 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
243} 272}
244 273
245 274
246/* 275/*
247 * Default resume method for devices that have no driver provided resume, 276 * Default resume method for devices that have no driver provided resume,
248 * or not even a driver at all. 277 * or not even a driver at all.
249 */ 278 */
250static void pci_default_resume(struct pci_dev *pci_dev) 279static void pci_default_resume(struct pci_dev *pci_dev)
251{ 280{
281 int retval;
282
252 /* restore the PCI config space */ 283 /* restore the PCI config space */
253 pci_restore_state(pci_dev); 284 pci_restore_state(pci_dev);
254 /* if the device was enabled before suspend, reenable */ 285 /* if the device was enabled before suspend, reenable */
255 if (pci_dev->is_enabled) 286 if (pci_dev->is_enabled)
256 pci_enable_device(pci_dev); 287 retval = pci_enable_device(pci_dev);
257 /* if the device was busmaster before the suspend, make it busmaster again */ 288 /* if the device was busmaster before the suspend, make it busmaster again */
258 if (pci_dev->is_busmaster) 289 if (pci_dev->is_busmaster)
259 pci_set_master(pci_dev); 290 pci_set_master(pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c62d2f043397..992db89adce7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -222,6 +222,37 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
222} 222}
223 223
224/** 224/**
225 * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
226 * @dev: PCI device to have its BARs restored
227 *
228 * Restore the BAR values for a given device, so as to make it
229 * accessible by its driver.
230 */
231void
232pci_restore_bars(struct pci_dev *dev)
233{
234 int i, numres;
235
236 switch (dev->hdr_type) {
237 case PCI_HEADER_TYPE_NORMAL:
238 numres = 6;
239 break;
240 case PCI_HEADER_TYPE_BRIDGE:
241 numres = 2;
242 break;
243 case PCI_HEADER_TYPE_CARDBUS:
244 numres = 1;
245 break;
246 default:
247 /* Should never get here, but just in case... */
248 return;
249 }
250
251 for (i = 0; i < numres; i ++)
252 pci_update_resource(dev, &dev->resource[i], i);
253}
254
255/**
225 * pci_set_power_state - Set the power state of a PCI device 256 * pci_set_power_state - Set the power state of a PCI device
226 * @dev: PCI device to be suspended 257 * @dev: PCI device to be suspended
227 * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering 258 * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +270,7 @@ int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
239int 270int
240pci_set_power_state(struct pci_dev *dev, pci_power_t state) 271pci_set_power_state(struct pci_dev *dev, pci_power_t state)
241{ 272{
242 int pm; 273 int pm, need_restore = 0;
243 u16 pmcsr, pmc; 274 u16 pmcsr, pmc;
244 275
245 /* bound the state we're entering */ 276 /* bound the state we're entering */
@@ -263,7 +294,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
263 return -EIO; 294 return -EIO;
264 295
265 pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc); 296 pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
266 if ((pmc & PCI_PM_CAP_VER_MASK) > 2) { 297 if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
267 printk(KERN_DEBUG 298 printk(KERN_DEBUG
268 "PCI: %s has unsupported PM cap regs version (%u)\n", 299 "PCI: %s has unsupported PM cap regs version (%u)\n",
269 pci_name(dev), pmc & PCI_PM_CAP_VER_MASK); 300 pci_name(dev), pmc & PCI_PM_CAP_VER_MASK);
@@ -271,21 +302,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
271 } 302 }
272 303
273 /* check if this device supports the desired state */ 304 /* check if this device supports the desired state */
274 if (state == PCI_D1 || state == PCI_D2) { 305 if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
275 if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1)) 306 return -EIO;
276 return -EIO; 307 else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
277 else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2)) 308 return -EIO;
278 return -EIO; 309
279 } 310 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
280 311
281 /* If we're in D3, force entire word to 0. 312 /* If we're in D3, force entire word to 0.
282 * This doesn't affect PME_Status, disables PME_En, and 313 * This doesn't affect PME_Status, disables PME_En, and
283 * sets PowerState to 0. 314 * sets PowerState to 0.
284 */ 315 */
285 if (dev->current_state >= PCI_D3hot) 316 if (dev->current_state >= PCI_D3hot) {
317 if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
318 need_restore = 1;
286 pmcsr = 0; 319 pmcsr = 0;
287 else { 320 } else {
288 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
289 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 321 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
290 pmcsr |= state; 322 pmcsr |= state;
291 } 323 }
@@ -308,6 +340,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
308 platform_pci_set_power_state(dev, state); 340 platform_pci_set_power_state(dev, state);
309 341
310 dev->current_state = state; 342 dev->current_state = state;
343
344 /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
345 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
346 * from D3hot to D0 _may_ perform an internal reset, thereby
347 * going to "D0 Uninitialized" rather than "D0 Initialized".
348 * For example, at least some versions of the 3c905B and the
349 * 3c556B exhibit this behaviour.
350 *
351 * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
352 * devices in a D3hot state at boot. Consequently, we need to
353 * restore at least the BARs so that the device will be
354 * accessible to its driver.
355 */
356 if (need_restore)
357 pci_restore_bars(dev);
358
311 return 0; 359 return 0;
312} 360}
313 361
@@ -394,8 +442,11 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
394{ 442{
395 int err; 443 int err;
396 444
397 pci_set_power_state(dev, PCI_D0); 445 err = pci_set_power_state(dev, PCI_D0);
398 if ((err = pcibios_enable_device(dev, bars)) < 0) 446 if (err < 0 && err != -EIO)
447 return err;
448 err = pcibios_enable_device(dev, bars);
449 if (err < 0)
399 return err; 450 return err;
400 return 0; 451 return 0;
401} 452}
@@ -747,6 +798,31 @@ pci_clear_mwi(struct pci_dev *dev)
747 } 798 }
748} 799}
749 800
801/**
802 * pci_intx - enables/disables PCI INTx for device dev
803 * @dev: the PCI device to operate on
804 * @enable: boolean
805 *
806 * Enables/disables PCI INTx for device dev
807 */
808void
809pci_intx(struct pci_dev *pdev, int enable)
810{
811 u16 pci_command, new;
812
813 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
814
815 if (enable) {
816 new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
817 } else {
818 new = pci_command | PCI_COMMAND_INTX_DISABLE;
819 }
820
821 if (new != pci_command) {
822 pci_write_config_word(pdev, PCI_COMMAND, new);
823 }
824}
825
750#ifndef HAVE_ARCH_PCI_SET_DMA_MASK 826#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
751/* 827/*
752 * These can be overridden by arch-specific implementations 828 * These can be overridden by arch-specific implementations
@@ -809,6 +885,7 @@ struct pci_dev *isa_bridge;
809EXPORT_SYMBOL(isa_bridge); 885EXPORT_SYMBOL(isa_bridge);
810#endif 886#endif
811 887
888EXPORT_SYMBOL_GPL(pci_restore_bars);
812EXPORT_SYMBOL(pci_enable_device_bars); 889EXPORT_SYMBOL(pci_enable_device_bars);
813EXPORT_SYMBOL(pci_enable_device); 890EXPORT_SYMBOL(pci_enable_device);
814EXPORT_SYMBOL(pci_disable_device); 891EXPORT_SYMBOL(pci_disable_device);
@@ -823,6 +900,7 @@ EXPORT_SYMBOL(pci_request_region);
823EXPORT_SYMBOL(pci_set_master); 900EXPORT_SYMBOL(pci_set_master);
824EXPORT_SYMBOL(pci_set_mwi); 901EXPORT_SYMBOL(pci_set_mwi);
825EXPORT_SYMBOL(pci_clear_mwi); 902EXPORT_SYMBOL(pci_clear_mwi);
903EXPORT_SYMBOL_GPL(pci_intx);
826EXPORT_SYMBOL(pci_set_dma_mask); 904EXPORT_SYMBOL(pci_set_dma_mask);
827EXPORT_SYMBOL(pci_set_consistent_dma_mask); 905EXPORT_SYMBOL(pci_set_consistent_dma_mask);
828EXPORT_SYMBOL(pci_assign_resource); 906EXPORT_SYMBOL(pci_assign_resource);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d00168b1f662..d3f3dd42240d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -29,7 +29,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
29#endif 29#endif
30 30
31/* Functions for PCI Hotplug drivers to use */ 31/* Functions for PCI Hotplug drivers to use */
32extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
33extern unsigned int pci_do_scan_bus(struct pci_bus *bus); 32extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
34extern int pci_remove_device_safe(struct pci_dev *dev); 33extern int pci_remove_device_safe(struct pci_dev *dev);
35extern unsigned char pci_max_busnr(void); 34extern unsigned char pci_max_busnr(void);
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
deleted file mode 100644
index 1d2ef1e2ffc6..000000000000
--- a/drivers/pci/pci.ids
+++ /dev/null
@@ -1,10180 +0,0 @@
1#
2# List of PCI ID's
3#
4# Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
5# Linux PCI ID's Project at http://pciids.sf.net/. New data are always
6# welcome (if they are accurate), we're eagerly expecting new entries,
7# so if you have anything to contribute, please visit the home page or
8# send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
9#
10# Daily snapshot on Tue 2005-03-08 10:11:48
11#
12
13# Vendors, devices and subsystems. Please keep sorted.
14
15# Syntax:
16# vendor vendor_name
17# device device_name <-- single tab
18# subvendor subdevice subsystem_name <-- two tabs
19
200000 Gammagraphx, Inc.
21001a Ascend Communications, Inc.
220033 Paradyne corp.
23003d Lockheed Martin-Marietta Corp
24# Real TJN ID is e159, but they got it wrong several times --mj
250059 Tiger Jet Network Inc. (Wrong ID)
260070 Hauppauge computer works Inc.
27 4000 WinTV PVR-350
28 4001 WinTV PVR-250 (v1)
29 4009 WinTV PVR-250
30 4801 WinTV PVR-250 MCE
310071 Nebula Electronics Ltd.
320095 Silicon Image, Inc. (Wrong ID)
33 0680 Ultra ATA/133 IDE RAID CONTROLLER CARD
340100 Ncipher Corp Ltd
35# 018a is not LevelOne but there is a board misprogrammed
36018a LevelOne
37 0106 FPC-0106TX misprogrammed [RTL81xx]
38# 021b is not Compaq but there is a board misprogrammed
39021b Compaq Computer Corporation
40 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking]
41# http://www.davicom.com.tw/
420291 Davicom Semiconductor, Inc.
43 8212 DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
44# SpeedStream is Efficient Networks, Inc, a Siemens Company
4502ac SpeedStream
46 1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
470357 TTTech AG
48 000a TTP-Monitoring Card V2.0
490432 SCM Microsystems, Inc.
50 0001 Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
5105e3 CyberDoor
52 0701 CBD516
530675 Dynalink
54 1700 IS64PH ISDN Adapter
55 1702 IS64PH ISDN Adapter
56# Wrong ID used in subsystem ID of VIA USB controllers.
570925 VIA Technologies, Inc. (Wrong ID)
5809c1 Arris
59 0704 CM 200E Cable Modem
600a89 BREA Technologies Inc
610b49 ASCII Corporation
62# see http://homepage1.nifty.com/mcn/lab/machines/trance_vibrator/usbview.vib.txt
63 064f Trance Vibrator
640e11 Compaq Computer Corporation
65 0001 PCI to EISA Bridge
66 0002 PCI to ISA Bridge
67 0046 Smart Array 64xx
68 0e11 409a Smart Array 641
69 0e11 409b Smart Array 642
70 0e11 409c Smart Array 6400
71 0e11 409d Smart Array 6400 EM
72 0049 NC7132 Gigabit Upgrade Module
73 004a NC6136 Gigabit Server Adapter
74 007c NC7770 1000BaseTX
75 007d NC6770 1000BaseTX
76 0085 NC7780 1000BaseTX
77 00bb NC7760
78 00ca NC7771
79 00cb NC7781
80 00cf NC7772
81 00d0 NC7782
82 00d1 NC7783
83 00e3 NC7761
84 0508 Netelligent 4/16 Token Ring
85 1000 Triflex/Pentium Bridge, Model 1000
86 2000 Triflex/Pentium Bridge, Model 2000
87 3032 QVision 1280/p
88 3033 QVision 1280/p
89 3034 QVision 1280/p
90 4000 4000 [Triflex]
91 4030 SMART-2/P
92 4031 SMART-2SL
93 4032 Smart Array 3200
94 4033 Smart Array 3100ES
95 4034 Smart Array 221
96 4040 Integrated Array
97 4048 Compaq Raid LC2
98 4050 Smart Array 4200
99 4051 Smart Array 4250ES
100 4058 Smart Array 431
101 4070 Smart Array 5300
102 4080 Smart Array 5i
103 4082 Smart Array 532
104 4083 Smart Array 5312
105 4091 Smart Array 6i
106 409a Smart Array 641
107 409b Smart Array 642
108 409c Smart Array 6400
109 409d Smart Array 6400 EM
110 6010 HotPlug PCI Bridge 6010
111 7020 USB Controller
112 a0ec Fibre Channel Host Controller
113 a0f0 Advanced System Management Controller
114 a0f3 Triflex PCI to ISA Bridge
115 a0f7 PCI Hotplug Controller
116 8086 002a PCI Hotplug Controller A
117 8086 002b PCI Hotplug Controller B
118 a0f8 ZFMicro Chipset USB
119 a0fc FibreChannel HBA Tachyon
120 ae10 Smart-2/P RAID Controller
121 0e11 4030 Smart-2/P Array Controller
122 0e11 4031 Smart-2SL Array Controller
123 0e11 4032 Smart Array Controller
124 0e11 4033 Smart 3100ES Array Controller
125 ae29 MIS-L
126 ae2a MPC
127 ae2b MIS-E
128 ae31 System Management Controller
129 ae32 Netelligent 10/100 TX PCI UTP
130 ae33 Triflex Dual EIDE Controller
131 ae34 Netelligent 10 T PCI UTP
132 ae35 Integrated NetFlex-3/P
133 ae40 Netelligent Dual 10/100 TX PCI UTP
134 ae43 Netelligent Integrated 10/100 TX UTP
135 ae69 CETUS-L
136 ae6c Northstar
137 ae6d NorthStar CPU to PCI Bridge
138 b011 Netelligent 10/100 TX Embedded UTP
139 b012 Netelligent 10 T/2 PCI UTP/Coax
140 b01e NC3120 Fast Ethernet NIC
141 b01f NC3122 Fast Ethernet NIC
142 b02f NC1120 Ethernet NIC
143 b030 Netelligent 10/100 TX UTP
144 b04a 10/100 TX PCI Intel WOL UTP Controller
145 b060 Smart Array 5300 Controller
146 b0c6 NC3161 Fast Ethernet NIC
147 b0c7 NC3160 Fast Ethernet NIC
148 b0d7 NC3121 Fast Ethernet NIC
149 b0dd NC3131 Fast Ethernet NIC
150 b0de NC3132 Fast Ethernet Module
151 b0df NC6132 Gigabit Module
152 b0e0 NC6133 Gigabit Module
153 b0e1 NC3133 Fast Ethernet Module
154 b123 NC6134 Gigabit NIC
155 b134 NC3163 Fast Ethernet NIC
156 b13c NC3162 Fast Ethernet NIC
157 b144 NC3123 Fast Ethernet NIC
158 b163 NC3134 Fast Ethernet NIC
159 b164 NC3165 Fast Ethernet Upgrade Module
160 b178 Smart Array 5i/532
161 0e11 4080 Smart Array 5i
162 0e11 4082 Smart Array 532
163 0e11 4083 Smart Array 5312
164 b1a4 NC7131 Gigabit Server Adapter
165# HP Memory Hot-Plug Controller
166 b200 Memory Hot-Plug Controller
167 b203 Integrated Lights Out Controller
168 b204 Integrated Lights Out Processor
169 f130 NetFlex-3/P ThunderLAN 1.0
170 f150 NetFlex-3/P ThunderLAN 2.3
1710e55 HaSoTec GmbH
172# Formerly NCR
1731000 LSI Logic / Symbios Logic
174 0001 53c810
175 1000 1000 LSI53C810AE PCI to SCSI I/O Processor
176 0002 53c820
177 0003 53c825
178 1000 1000 LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
179 0004 53c815
180 0005 53c810AP
181 0006 53c860
182 1000 1000 LSI53C860E PCI to Ultra SCSI I/O Processor
183 000a 53c1510
184 1000 1000 LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
185 000b 53C896/897
186 0e11 6004 EOB003 Series SCSI host adapter
187 1000 1000 LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
188 1000 1010 LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
189 1000 1020 LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
190# multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics
191 13e9 1000 6221L-4U
192 000c 53c895
193 1000 1010 LSI8951U PCI to Ultra2 SCSI host adapter
194 1000 1020 LSI8952U PCI to Ultra2 SCSI host adapter
195 1de1 3906 DC-390U2B SCSI adapter
196 1de1 3907 DC-390U2W
197 000d 53c885
198 000f 53c875
199 0e11 7004 Embedded Ultra Wide SCSI Controller
200 1000 1000 LSI53C876/E PCI to Dual Channel SCSI Controller
201 1000 1010 LSI22801 PCI to Dual Channel Ultra SCSI host adapter
202 1000 1020 LSI22802 PCI to Dual Channel Ultra SCSI host adapter
203 1092 8760 FirePort 40 Dual SCSI Controller
204 1de1 3904 DC390F/U Ultra Wide SCSI Adapter
205 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
206 4c53 1050 CT7 mainboard
207 0010 53C1510
208 0e11 4040 Integrated Array Controller
209 0e11 4048 RAID LC2 Controller
210 1000 1000 53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
211 0012 53c895a
212 1000 1000 LSI53C895A PCI to Ultra2 SCSI Controller
213 0013 53c875a
214 1000 1000 LSI53C875A PCI to Ultra SCSI Controller
215 0020 53c1010 Ultra3 SCSI Adapter
216 1000 1000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
217 1de1 1020 DC-390U3W
218 0021 53c1010 66MHz Ultra3 SCSI Adapter
219 1000 1000 LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
220 1000 1010 Asus TR-DLS onboard 53C1010-66
221 124b 1070 PMC-USCSI3
222 4c53 1080 CT8 mainboard
223 4c53 1300 P017 mezzanine (32-bit PMC)
224 4c53 1310 P017 mezzanine (64-bit PMC)
225 0030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
226 1028 0123 PowerEdge 2600
227 1028 014a PowerEdge 1750
228 1028 016c PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
229 1028 0183 PowerEdge 1800
230 1028 1010 LSI U320 SCSI Controller
231 0031 53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
232 0032 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
233 1000 1000 LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
234 0033 1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
235 0040 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
236 1000 0033 MegaRAID SCSI 320-2XR
237 1000 0066 MegaRAID SCSI 320-2XRWS
238 0041 53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
239 008f 53c875J
240 1092 8000 FirePort 40 SCSI Controller
241 1092 8760 FirePort 40 Dual SCSI Host Adapter
242 0407 MegaRAID
243 1000 0530 MegaRAID 530 SCSI 320-0X RAID Controller
244 1000 0531 MegaRAID 531 SCSI 320-4X RAID Controller
245 1000 0532 MegaRAID 532 SCSI 320-2X RAID Controller
246 1028 0531 PowerEdge Expandable RAID Controller 4/QC
247 1028 0533 PowerEdge Expandable RAID Controller 4/QC
248 8086 0530 MegaRAID Intel RAID Controller SRCZCRX
249 8086 0532 MegaRAID Intel RAID Controller SRCU42X
250 0408 MegaRAID
251 1000 0001 MegaRAID SCSI 320-1E RAID Controller
252 1000 0002 MegaRAID SCSI 320-2E RAID Controller
253 1025 004d MegaRAID ACER ROMB-2E RAID Controller
254 1028 0001 PowerEdge RAID Controller PERC4e/SC
255 1028 0002 PowerEdge RAID Controller PERC4e/DC
256 1734 1065 FSC MegaRAID PCI Express ROMB
257 8086 0002 MegaRAID Intel RAID Controller SRCU42E
258 0409 MegaRAID
259 1000 3004 MegaRAID SATA 300-4X RAID Controller
260 1000 3008 MegaRAID SATA 300-8X RAID Controller
261 8086 3008 MegaRAID RAID Controller SRCS28X
262 8086 3431 MegaRAID RAID Controller Alief SROMBU42E
263 8086 3499 MegaRAID RAID Controller Harwich SROMBU42E
264 0621 FC909 Fibre Channel Adapter
265 0622 FC929 Fibre Channel Adapter
266 1000 1020 44929 O Dual Fibre Channel card
267 0623 FC929 LAN
268 0624 FC919 Fibre Channel Adapter
269 0625 FC919 LAN
270 0626 FC929X Fibre Channel Adapter
271 1000 1010 7202-XP-LC Dual Fibre Channel card
272 0627 FC929X LAN
273 0628 FC919X Fibre Channel Adapter
274 0629 FC919X LAN
275 0701 83C885 NT50 DigitalScape Fast Ethernet
276 0702 Yellowfin G-NIC gigabit ethernet
277 1318 0000 PEI100X
278 0804 SA2010
279 0805 SA2010ZC
280 0806 SA2020
281 0807 SA2020ZC
282 0901 61C102
283 1000 63C815
284 1960 MegaRAID
285 1000 0518 MegaRAID 518 SCSI 320-2 Controller
286 1000 0520 MegaRAID 520 SCSI 320-1 Controller
287 1000 0522 MegaRAID 522 i4 133 RAID Controller
288 1000 0523 MegaRAID SATA 150-6 RAID Controller
289 1000 4523 MegaRAID SATA 150-4 RAID Controller
290 1000 a520 MegaRAID ZCR SCSI 320-0 Controller
291 1028 0518 MegaRAID 518 DELL PERC 4/DC RAID Controller
292 1028 0520 MegaRAID 520 DELL PERC 4/SC RAID Controller
293 1028 0531 PowerEdge Expandable RAID Controller 4/QC
294 1028 0533 PowerEdge Expandable RAID Controller 4/QC
295 8086 0520 MegaRAIDRAID Controller SRCU41L
296 8086 0523 MegaRAID RAID Controller SRCS16
2971001 Kolter Electronic
298 0010 PCI 1616 Measurement card with 32 digital I/O lines
299 0011 OPTO-PCI Opto-Isolated digital I/O board
300 0012 PCI-AD/DA Analogue I/O board
301 0013 PCI-OPTO-RELAIS Digital I/O board with relay outputs
302 0014 PCI-Counter/Timer Counter Timer board
303 0015 PCI-DAC416 Analogue output board
304 0016 PCI-MFB Analogue I/O board
305 0017 PROTO-3 PCI Prototyping board
306 9100 INI-9100/9100W SCSI Host
3071002 ATI Technologies Inc
308 3150 M24 1P [Radeon Mobility X600]
309 3154 M24 1T [FireGL M24 GL]
310 3e50 RV380 0x3e50 [Radeon X600]
311 3e54 RV380 0x3e54 [FireGL V3200]
312 3e70 RV380 [Radeon X600] Secondary
313 4136 Radeon IGP 320 M
314 4137 Radeon IGP330/340/350
315 4144 R300 AD [Radeon 9500 Pro]
316# New PCI ID provided by ATI developer relations (correction to above)
317 4145 R300 AE [Radeon 9700 Pro]
318# New PCI ID provided by ATI developer relations (oops, correction to above)
319 4146 R300 AF [Radeon 9700 Pro]
320 4147 R300 AG [FireGL Z1/X1]
321 4148 R350 AH [Radeon 9800]
322 4149 R350 AI [Radeon 9800]
323 414a R350 AJ [Radeon 9800]
324 414b R350 AK [Fire GL X2]
325# New PCI ID provided by ATI developer relations
326 4150 RV350 AP [Radeon 9600]
327 1002 0002 R9600 Pro primary (Asus OEM for HP)
328 1002 0003 R9600 Pro secondary (Asus OEM for HP)
329 1458 4024 Giga-Byte GV-R96128D Primary
330 148c 2064 PowerColor R96A-C3N
331 148c 2066 PowerColor R96A-C3N
332 174b 7c19 Sapphire Atlantis Radeon 9600 Pro
333 174b 7c29 GC-R9600PRO Primary [Sapphire]
334 17ee 2002 Radeon 9600 256Mb Primary
335 18bc 0101 GC-R9600PRO Primary
336# New PCI ID provided by ATI developer relations
337 4151 RV350 AQ [Radeon 9600]
338 1043 c004 A9600SE
339# New PCI ID provided by ATI developer relations
340 4152 RV350 AR [Radeon 9600]
341 1002 0002 Radeon 9600XT
342 1043 c002 Radeon 9600 XT TVD
343 174b 7c29 Sapphire Radeon 9600XT
344 1787 4002 Radeon 9600 XT
345 4153 RV350 AS [Radeon 9600 AS]
346 4154 RV350 AT [Fire GL T2]
347 4155 RV350 AU [Fire GL T2]
348 4156 RV350 AV [Fire GL T2]
349 4157 RV350 AW [Fire GL T2]
350 4158 68800AX [Mach32]
351# The PCI ID is unrelated to any DVI output.
352 4164 R300 AD [Radeon 9500 Pro] (Secondary)
353# New PCI ID info provided by ATI developer relations
354 4165 R300 AE [Radeon 9700 Pro] (Secondary)
355# New PCI ID info provided by ATI developer relations
356 4166 R300 AF [Radeon 9700 Pro] (Secondary)
357# New PCI ID provided by ATI developer relations
358 4168 Radeon R350 [Radeon 9800] (Secondary)
359# New PCI ID provided by ATI developer relations (correction to above)
360 4170 RV350 AP [Radeon 9600] (Secondary)
361 1458 4025 Giga-Byte GV-R96128D Secondary
362 148c 2067 PowerColor R96A-C3N (Secondary)
363 174b 7c28 GC-R9600PRO Secondary [Sapphire]
364 17ee 2003 Radeon 9600 256Mb Secondary
365 18bc 0100 GC-R9600PRO Secondary
366# New PCI ID provided by ATI developer relations (correction to above)
367 4171 RV350 AQ [Radeon 9600] (Secondary)
368 1043 c005 A9600SE (Secondary)
369# New PCI ID provided by ATI developer relations (correction to above)
370 4172 RV350 AR [Radeon 9600] (Secondary)
371 1002 0003 Radeon 9600XT (Secondary)
372 1043 c003 A9600XT (Secondary)
373 174b 7c28 Sapphire Radeon 9600XT (Secondary)
374 1787 4003 Radeon 9600 XT (Secondary)
375 4173 RV350 ?? [Radeon 9550] (Secondary)
376 4237 Radeon 7000 IGP
377 4242 R200 BB [Radeon All in Wonder 8500DV]
378 1002 02aa Radeon 8500 AIW DV Edition
379 4243 R200 BC [Radeon All in Wonder 8500]
380 4336 Radeon Mobility U1
381 103c 0024 Pavilion ze4400 builtin Video
382 4337 Radeon IGP 330M/340M/350M
383 1014 053a ThinkPad R40e (2684-HVG) builtin VGA controller
384 103c 0850 Radeon IGP 345M
385 4341 IXP150 AC'97 Audio Controller
386 4345 EHCI USB Controller
387 4347 OHCI USB Controller #1
388 4348 OHCI USB Controller #2
389 4349 ATI Dual Channel Bus Master PCI IDE Controller
390 434d IXP AC'97 Modem
391 4353 ATI SMBus
392 4354 215CT [Mach64 CT]
393 4358 210888CX [Mach64 CX]
394 4363 ATI SMBus
395 436e ATI 436E Serial ATA Controller
396 4372 ATI SMBus
397 4376 Standard Dual Channel PCI IDE Controller ATI
398 4379 ATI 4379 Serial ATA Controller
399 437a ATI 437A Serial ATA Controller
400 4437 Radeon Mobility 7000 IGP
401 4554 210888ET [Mach64 ET]
402 4654 Mach64 VT
403 4742 3D Rage Pro AGP 1X/2X
404 1002 0040 Rage Pro Turbo AGP 2X
405 1002 0044 Rage Pro Turbo AGP 2X
406 1002 0061 Rage Pro AIW AGP 2X
407 1002 0062 Rage Pro AIW AGP 2X
408 1002 0063 Rage Pro AIW AGP 2X
409 1002 0080 Rage Pro Turbo AGP 2X
410 1002 0084 Rage Pro Turbo AGP 2X
411 1002 4742 Rage Pro Turbo AGP 2X
412 1002 8001 Rage Pro Turbo AGP 2X
413 1028 0082 Rage Pro Turbo AGP 2X
414 1028 4082 Optiplex GX1 Onboard Display Adapter
415 1028 8082 Rage Pro Turbo AGP 2X
416 1028 c082 Rage Pro Turbo AGP 2X
417 8086 4152 Xpert 98D AGP 2X
418 8086 464a Rage Pro Turbo AGP 2X
419 4744 3D Rage Pro AGP 1X
420 1002 4744 Rage Pro Turbo AGP
421 4747 3D Rage Pro
422 4749 3D Rage Pro
423 1002 0061 Rage Pro AIW
424 1002 0062 Rage Pro AIW
425 474c Rage XC
426 474d Rage XL AGP 2X
427 1002 0004 Xpert 98 RXL AGP 2X
428 1002 0008 Xpert 98 RXL AGP 2X
429 1002 0080 Rage XL AGP 2X
430 1002 0084 Xpert 98 AGP 2X
431 1002 474d Rage XL AGP
432 1033 806a Rage XL AGP
433 474e Rage XC AGP
434 1002 474e Rage XC AGP
435 474f Rage XL
436 1002 0008 Rage XL
437 1002 474f Rage XL
438 4750 3D Rage Pro 215GP
439 1002 0040 Rage Pro Turbo
440 1002 0044 Rage Pro Turbo
441 1002 0080 Rage Pro Turbo
442 1002 0084 Rage Pro Turbo
443 1002 4750 Rage Pro Turbo
444 4751 3D Rage Pro 215GQ
445 4752 Rage XL
446 1002 0008 Rage XL
447 1002 4752 Rage XL
448 1002 8008 Rage XL
449 1028 00ce PowerEdge 1400
450 1028 00d1 PowerEdge 2550
451 1028 00d9 PowerEdge 2500
452 8086 3411 SDS2 Mainboard
453 8086 3427 S875WP1-E mainboard
454 4753 Rage XC
455 1002 4753 Rage XC
456 4754 3D Rage I/II 215GT [Mach64 GT]
457 4755 3D Rage II+ 215GTB [Mach64 GTB]
458 4756 3D Rage IIC 215IIC [Mach64 GT IIC]
459 1002 4756 Rage IIC
460 4757 3D Rage IIC AGP
461 1002 4757 Rage IIC AGP
462 1028 0089 Rage 3D IIC
463 1028 4082 Rage 3D IIC
464 1028 8082 Rage 3D IIC
465 1028 c082 Rage 3D IIC
466 4758 210888GX [Mach64 GX]
467 4759 3D Rage IIC
468 475a 3D Rage IIC AGP
469 1002 0084 Rage 3D Pro AGP 2x XPERT 98
470 1002 0087 Rage 3D IIC
471 1002 475a Rage IIC AGP
472 4964 Radeon RV250 Id [Radeon 9000]
473 4965 Radeon RV250 Ie [Radeon 9000]
474 4966 Radeon RV250 If [Radeon 9000]
475 10f1 0002 RV250 If [Tachyon G9000 PRO]
476 148c 2039 RV250 If [Radeon 9000 Pro "Evil Commando"]
477 1509 9a00 RV250 If [Radeon 9000 "AT009"]
478# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified.
479 1681 0040 RV250 If [3D prophet 9000]
480 174b 7176 RV250 If [Sapphire Radeon 9000 Pro]
481 174b 7192 RV250 If [Radeon 9000 "Atlantis"]
482 17af 2005 RV250 If [Excalibur Radeon 9000 Pro]
483 17af 2006 RV250 If [Excalibur Radeon 9000]
484 4967 Radeon RV250 Ig [Radeon 9000]
485 496e Radeon RV250 [Radeon 9000] (Secondary)
486 4a48 R420 JH [Radeon X800]
487 4a49 R420 JI [Radeon X800PRO]
488 4a4a R420 JJ [Radeon X800SE]
489 4a4b R420 JK [Radeon X800]
490 4a4c R420 JL [Radeon X800]
491 4a4d R420 JM [FireGL X3]
492 4a4e M18 JN [Radeon Mobility 9800]
493 4a50 R420 JP [Radeon X800XT]
494 4a70 R420 [X800XT-PE] (Secondary)
495 4c42 3D Rage LT Pro AGP-133
496 0e11 b0e7 Rage LT Pro (Compaq Presario 5240)
497 0e11 b0e8 Rage 3D LT Pro
498 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750)
499 1002 0040 Rage LT Pro AGP 2X
500 1002 0044 Rage LT Pro AGP 2X
501 1002 4c42 Rage LT Pro AGP 2X
502 1002 8001 Rage LT Pro AGP 2X
503 1028 0085 Rage 3D LT Pro
504 4c44 3D Rage LT Pro AGP-66
505 4c45 Rage Mobility M3 AGP
506 4c46 Rage Mobility M3 AGP 2x
507 1028 00b1 Latitude C600
508 4c47 3D Rage LT-G 215LG
509 4c49 3D Rage LT Pro
510 1002 0004 Rage LT Pro
511 1002 0040 Rage LT Pro
512 1002 0044 Rage LT Pro
513 1002 4c49 Rage LT Pro
514 4c4d Rage Mobility P/M AGP 2x
515 0e11 b111 Armada M700
516 0e11 b160 Armada E500
517 1002 0084 Xpert 98 AGP 2X (Mobility)
518 1014 0154 ThinkPad A20m
519 1028 00aa Latitude CPt
520 1028 00bb Latitude CPx
521 4c4e Rage Mobility L AGP 2x
522 4c50 3D Rage LT Pro
523 1002 4c50 Rage LT Pro
524 4c51 3D Rage LT Pro
525 4c52 Rage Mobility P/M
526 1033 8112 Versa Note VXi
527 4c53 Rage Mobility L
528 4c54 264LT [Mach64 LT]
529 4c57 Radeon Mobility M7 LW [Radeon Mobility 7500]
530 1014 0517 ThinkPad T30
531 1028 00e6 Radeon Mobility M7 LW (Dell Inspiron 8100)
532 1028 012a Latitude C640
533 144d c006 Radeon Mobility M7 LW in vpr Matrix 170B4
534 4c58 Radeon RV200 LX [Mobility FireGL 7800 M7]
535 4c59 Radeon Mobility M6 LY
536 1014 0235 ThinkPad A30/A30p (2652/2653)
537 1014 0239 ThinkPad X22/X23/X24
538 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
539 4c5a Radeon Mobility M6 LZ
540 4c64 Radeon R250 Ld [Radeon Mobility 9000 M9]
541 4c65 Radeon R250 Le [Radeon Mobility 9000 M9]
542 4c66 Radeon R250 Lf [FireGL 9000]
543 4c67 Radeon R250 Lg [Radeon Mobility 9000 M9]
544# Secondary chip to the Lf
545 4c6e Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary]
546 4d46 Rage Mobility M4 AGP
547 4d4c Rage Mobility M4 AGP
548 4e44 Radeon R300 ND [Radeon 9700 Pro]
549 4e45 Radeon R300 NE [Radeon 9500 Pro]
550 1002 0002 Radeon R300 NE [Radeon 9500 Pro]
551 1681 0002 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
552# New PCI ID provided by ATI developer relations (correction to above)
553 4e46 RV350 NF [Radeon 9600]
554 4e47 Radeon R300 NG [FireGL X1]
555# (added pro)
556 4e48 Radeon R350 [Radeon 9800 Pro]
557# New PCI ID provided by ATI developer relations
558 4e49 Radeon R350 [Radeon 9800]
559 4e4a RV350 NJ [Radeon 9800 XT]
560 4e4b R350 NK [Fire GL X2]
561# New PCI ID provided by ATI developer relations
562 4e50 RV350 [Mobility Radeon 9600 M10]
563 1025 005a TravelMate 290
564 103c 088c nc8000 laptop
565 103c 0890 nc6000 laptop
566 1734 1055 Amilo M1420W
567 4e51 M10 NQ [Radeon Mobility 9600]
568 4e52 RV350 [Mobility Radeon 9600 M10]
569 4e53 M10 NS [Radeon Mobility 9600]
570 4e54 M10 NT [FireGL Mobility T2]
571 4e56 M11 NV [FireGL Mobility T2e]
572 4e64 Radeon R300 [Radeon 9700 Pro] (Secondary)
573 4e65 Radeon R300 [Radeon 9500 Pro] (Secondary)
574 1002 0003 Radeon R300 NE [Radeon 9500 Pro]
575 1681 0003 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
576# New PCI ID provided by ATI developer relations (correction to above)
577 4e66 RV350 NF [Radeon 9600] (Secondary)
578 4e67 Radeon R300 [FireGL X1] (Secondary)
579# (added pro)
580 4e68 Radeon R350 [Radeon 9800 Pro] (Secondary)
581# New PCI ID provided by ATI developer relations
582 4e69 Radeon R350 [Radeon 9800] (Secondary)
583 4e6a RV350 NJ [Radeon 9800 XT] (Secondary)
584 1002 4e71 ATI Technologies Inc M10 NQ [Radeon Mobility 9600]
585 5041 Rage 128 PA/PRO
586 5042 Rage 128 PB/PRO AGP 2x
587 5043 Rage 128 PC/PRO AGP 4x
588 5044 Rage 128 PD/PRO TMDS
589 1002 0028 Rage 128 AIW
590 1002 0029 Rage 128 AIW
591 5045 Rage 128 PE/PRO AGP 2x TMDS
592 5046 Rage 128 PF/PRO AGP 4x TMDS
593 1002 0004 Rage Fury Pro
594 1002 0008 Rage Fury Pro/Xpert 2000 Pro
595 1002 0014 Rage Fury Pro
596 1002 0018 Rage Fury Pro/Xpert 2000 Pro
597 1002 0028 Rage 128 Pro AIW AGP
598 1002 002a Rage 128 Pro AIW AGP
599 1002 0048 Rage Fury Pro
600 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)
601 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
602 5047 Rage 128 PG/PRO
603 5048 Rage 128 PH/PRO AGP 2x
604 5049 Rage 128 PI/PRO AGP 4x
605 504a Rage 128 PJ/PRO TMDS
606 504b Rage 128 PK/PRO AGP 2x TMDS
607 504c Rage 128 PL/PRO AGP 4x TMDS
608 504d Rage 128 PM/PRO
609 504e Rage 128 PN/PRO AGP 2x
610 504f Rage 128 PO/PRO AGP 4x
611 5050 Rage 128 PP/PRO TMDS [Xpert 128]
612 1002 0008 Xpert 128
613 5051 Rage 128 PQ/PRO AGP 2x TMDS
614 5052 Rage 128 PR/PRO AGP 4x TMDS
615 5053 Rage 128 PS/PRO
616 5054 Rage 128 PT/PRO AGP 2x
617 5055 Rage 128 PU/PRO AGP 4x
618 5056 Rage 128 PV/PRO TMDS
619 5057 Rage 128 PW/PRO AGP 2x TMDS
620 5058 Rage 128 PX/PRO AGP 4x TMDS
621 5144 Radeon R100 QD [Radeon 7200]
622 1002 0008 Radeon 7000/Radeon VE
623 1002 0009 Radeon 7000/Radeon
624 1002 000a Radeon 7000/Radeon
625 1002 001a Radeon 7000/Radeon
626 1002 0029 Radeon AIW
627 1002 0038 Radeon 7000/Radeon
628 1002 0039 Radeon 7000/Radeon
629 1002 008a Radeon 7000/Radeon
630 1002 00ba Radeon 7000/Radeon
631 1002 0139 Radeon 7000/Radeon
632 1002 028a Radeon 7000/Radeon
633 1002 02aa Radeon AIW
634 1002 053a Radeon 7000/Radeon
635 5145 Radeon R100 QE
636 5146 Radeon R100 QF
637 5147 Radeon R100 QG
638 5148 Radeon R200 QH [Radeon 8500]
639 1002 010a FireGL 8800 64Mb
640 1002 0152 FireGL 8800 128Mb
641 1002 0162 FireGL 8700 32Mb
642 1002 0172 FireGL 8700 64Mb
643 5149 Radeon R200 QI
644 514a Radeon R200 QJ
645 514b Radeon R200 QK
646 514c Radeon R200 QL [Radeon 8500 LE]
647 1002 003a Radeon R200 QL [Radeon 8500 LE]
648 1002 013a Radeon 8500
649 148c 2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
650 1681 0010 Radeon 8500 [3D Prophet 8500 128Mb]
651 174b 7149 Radeon R200 QL [Sapphire Radeon 8500 LE]
652 514d Radeon R200 QM [Radeon 9100]
653 514e Radeon R200 QN [Radeon 8500LE]
654 514f Radeon R200 QO [Radeon 8500LE]
655 5154 R200 QT [Radeon 8500]
656 5155 R200 QU [Radeon 9100]
657 5157 Radeon RV200 QW [Radeon 7500]
658 1002 013a Radeon 7500
659 1002 103a Dell Optiplex GX260
660 1458 4000 RV200 QW [RADEON 7500 PRO MAYA AR]
661 148c 2024 RV200 QW [Radeon 7500LE Dual Display]
662 148c 2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
663 148c 2036 RV200 QW [Radeon 7500 PCI Dual Display]
664 174b 7146 RV200 QW [Radeon 7500 LE]
665 174b 7147 RV200 QW [Sapphire Radeon 7500LE]
666 174b 7161 Radeon RV200 QW [Radeon 7500 LE]
667 17af 0202 RV200 QW [Excalibur Radeon 7500LE]
668 5158 Radeon RV200 QX [Radeon 7500]
669 5159 Radeon RV100 QY [Radeon 7000/VE]
670 1002 000a Radeon 7000/Radeon VE
671 1002 000b Radeon 7000
672 1002 0038 Radeon 7000/Radeon VE
673 1002 003a Radeon 7000/Radeon VE
674 1002 00ba Radeon 7000/Radeon VE
675 1002 013a Radeon 7000/Radeon VE
676 1458 4002 RV100 QY [RADEON 7000 PRO MAYA AV Series]
677 148c 2003 RV100 QY [Radeon 7000 Multi-Display Edition]
678 148c 2023 RV100 QY [Radeon 7000 Evil Master Multi-Display]
679 174b 7112 RV100 QY [Sapphire Radeon VE 7000]
680 174b 7c28 Sapphire Radeon VE 7000 DDR
681 1787 0202 RV100 QY [Excalibur Radeon 7000]
682 515a Radeon RV100 QZ [Radeon 7000/VE]
683 5168 Radeon R200 Qh
684 5169 Radeon R200 Qi
685 516a Radeon R200 Qj
686 516b Radeon R200 Qk
687# This one is not in ATI documentation, but is in XFree86 source code
688 516c Radeon R200 Ql
689 5245 Rage 128 RE/SG
690 1002 0008 Xpert 128
691 1002 0028 Rage 128 AIW
692 1002 0029 Rage 128 AIW
693 1002 0068 Rage 128 AIW
694 5246 Rage 128 RF/SG AGP
695 1002 0004 Magnum/Xpert 128/Xpert 99
696 1002 0008 Magnum/Xpert128/X99/Xpert2000
697 1002 0028 Rage 128 AIW AGP
698 1002 0044 Rage Fury/Xpert 128/Xpert 2000
699 1002 0068 Rage 128 AIW AGP
700 1002 0448 Rage Fury
701 5247 Rage 128 RG
702 524b Rage 128 RK/VR
703 524c Rage 128 RL/VR AGP
704 1002 0008 Xpert 99/Xpert 2000
705 1002 0088 Xpert 99
706 5345 Rage 128 SE/4x
707 5346 Rage 128 SF/4x AGP 2x
708 1002 0048 RAGE 128 16MB VGA TVOUT AMC PAL
709 5347 Rage 128 SG/4x AGP 4x
710 5348 Rage 128 SH
711 534b Rage 128 SK/4x
712 534c Rage 128 SL/4x AGP 2x
713 534d Rage 128 SM/4x AGP 4x
714 1002 0008 Xpert 99/Xpert 2000
715 1002 0018 Xpert 2000
716 534e Rage 128 4x
717 5354 Mach 64 VT
718 1002 5654 Mach 64 reference
719 5446 Rage 128 Pro Ultra TF
720 1002 0004 Rage Fury Pro
721 1002 0008 Rage Fury Pro/Xpert 2000 Pro
722 1002 0018 Rage Fury Pro/Xpert 2000 Pro
723 1002 0028 Rage 128 AIW Pro AGP
724 1002 0029 Rage 128 AIW
725 1002 002a Rage 128 AIW Pro AGP
726 1002 002b Rage 128 AIW
727 1002 0048 Xpert 2000 Pro
728 544c Rage 128 Pro Ultra TL
729 5452 Rage 128 Pro Ultra TR
730 1002 001c Rage 128 Pro 4XL
731 103c 1279 Rage 128 Pro 4XL
732 5453 Rage 128 Pro Ultra TS
733 5454 Rage 128 Pro Ultra TT
734 5455 Rage 128 Pro Ultra TU
735 5460 M22 [Radeon Mobility M300]
736 5464 M22 [FireGL GL]
737 5548 R423 UH [Radeon X800 (PCIE)]
738 5549 R423 UI [Radeon X800PRO (PCIE)]
739 554a R423 UJ [Radeon X800LE (PCIE)]
740 554b R423 UK [Radeon X800SE (PCIE)]
741 5551 R423 UQ [FireGL V7200 (PCIE)]
742 5552 R423 UR [FireGL V5100 (PCIE)]
743 5554 R423 UT [FireGL V7100 (PCIE)]
744 556b Radeon R423 UK (PCIE) [X800 SE] (Secondary)
745 5654 264VT [Mach64 VT]
746 1002 5654 Mach64VT Reference
747 5655 264VT3 [Mach64 VT3]
748 5656 264VT4 [Mach64 VT4]
749 5830 RS300 Host Bridge
750 5831 RS300 Host Bridge
751 5832 RS300 Host Bridge
752 5833 Radeon 9100 IGP Host Bridge
753 5834 Radeon 9100 IGP
754 5835 RS300M AGP [Radeon Mobility 9100IGP]
755 5838 Radeon 9100 IGP AGP Bridge
756 5941 RV280 [Radeon 9200] (Secondary)
757 1458 4019 Gigabyte Radeon 9200
758 174b 7c12 Sapphire Radeon 9200
759# http://www.hightech.com.hk/html/9200.htm
760 17af 200d Excalibur Radeon 9200
761 18bc 0050 GeXcube GC-R9200-C3 (Secondary)
762 5944 RV280 [Radeon 9200 SE (PCI)]
763 5960 RV280 [Radeon 9200 PRO]
764 5961 RV280 [Radeon 9200]
765 1002 2f72 All-in-Wonder 9200 Series
766 1019 4c30 Radeon 9200 VIVO
767 12ab 5961 YUAN SMARTVGA Radeon 9200
768 1458 4018 Gigabyte Radeon 9200
769 174b 7c13 Sapphire Radeon 9200
770# http://www.hightech.com.hk/html/9200.htm
771 17af 200c Excalibur Radeon 9200
772 18bc 0050 Radeon 9200 Game Buster
773 18bc 0051 GeXcube GC-R9200-C3
774 18bc 0053 Radeon 9200 Game Buster VIVO
775 5962 RV280 [Radeon 9200]
776 5964 RV280 [Radeon 9200 SE]
777 1043 c006 ASUS Radeon 9200 SE / TD / 128M
778 1458 4018 Radeon 9200 SE
779 148c 2073 CN-AG92E
780 174b 7c13 Sapphire Radeon 9200 SE
781 1787 5964 Excalibur 9200SE VIVO 128M
782 17af 2012 Radeon 9200 SE Excalibur
783 18bc 0170 Sapphire Radeon 9200 SE 128MB Game Buster
784# 128MB DDR, DVI/VGA/TV out
785 18bc 0173 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
786 5b60 RV370 5B60 [Radeon X300 (PCIE)]
787 1043 002a Extreme AX300SE-X
788 1043 032e Extreme AX300/TD
789 5b62 RV370 5B62 [Radeon X600 (PCIE)]
790 5b64 RV370 5B64 [FireGL V3100 (PCIE)]
791 5b65 RV370 5B65 [FireGL D1100 (PCIE)]
792 5c61 M9+ 5C61 [Radeon Mobility 9200 (AGP)]
793 5c63 M9+ 5C63 [Radeon Mobility 9200 (AGP)]
794 5d44 RV280 [Radeon 9200 SE] (Secondary)
795 1458 4019 Radeon 9200 SE (Secondary)
796 174b 7c12 Sapphire Radeon 9200 SE (Secondary)
797 1787 5965 Excalibur 9200SE VIVO 128M (Secondary)
798 17af 2013 Radeon 9200 SE Excalibur (Secondary)
799 18bc 0171 Radeon 9200 SE 128MB Game Buster (Secondary)
800 18bc 0172 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
801 5d4d R480 [Radeon X850XT Platinum]
802 5d57 R423 5F57 [Radeon X800XT (PCIE)]
803 700f PCI Bridge [IGP 320M]
804 7010 PCI Bridge [IGP 340M]
805 7834 Radeon 9100 PRO IGP
806 7835 Radeon Mobility 9200 IGP
807 7c37 RV350 AQ [Radeon 9600 SE]
808 cab0 AGP Bridge [IGP 320M]
809 cab2 RS200/RS200M AGP Bridge [IGP 340M]
810 cbb2 RS200/RS200M AGP Bridge [IGP 340M]
8111003 ULSI Systems
812 0201 US201
8131004 VLSI Technology Inc
814 0005 82C592-FC1
815 0006 82C593-FC1
816 0007 82C594-AFC2
817 0008 82C596/7 [Wildcat]
818 0009 82C597-AFC2
819 000c 82C541 [Lynx]
820 000d 82C543 [Lynx]
821 0101 82C532
822 0102 82C534 [Eagle]
823 0103 82C538
824 0104 82C535
825 0105 82C147
826 0200 82C975
827 0280 82C925
828 0304 QSound ThunderBird PCI Audio
829 1004 0304 QSound ThunderBird PCI Audio
830 122d 1206 DSP368 Audio
831 1483 5020 XWave Thunder 3D Audio
832 0305 QSound ThunderBird PCI Audio Gameport
833 1004 0305 QSound ThunderBird PCI Audio Gameport
834 122d 1207 DSP368 Audio Gameport
835 1483 5021 XWave Thunder 3D Audio Gameport
836 0306 QSound ThunderBird PCI Audio Support Registers
837 1004 0306 QSound ThunderBird PCI Audio Support Registers
838 122d 1208 DSP368 Audio Support Registers
839 1483 5022 XWave Thunder 3D Audio Support Registers
840 0307 Thunderbird
841 0308 Thunderbird
842 0702 VAS96011 [Golden Gate II]
843 0703 Tollgate
8441005 Avance Logic Inc. [ALI]
845 2064 ALG2032/2064
846 2128 ALG2364A
847 2301 ALG2301
848 2302 ALG2302
849 2364 ALG2364
850 2464 ALG2364A
851 2501 ALG2564A/25128A
8521006 Reply Group
8531007 NetFrame Systems Inc
8541008 Epson
855100a Phoenix Technologies
856100b National Semiconductor Corporation
857 0001 DP83810
858 0002 87415/87560 IDE
859 000e 87560 Legacy I/O
860 000f FireWire Controller
861 0011 NS87560 National PCI System I/O
862 0012 USB Controller
863 0020 DP83815 (MacPhyter) Ethernet Controller
864 103c 0024 Pavilion ze4400 builtin Network
865 1385 f311 FA311 / FA312 (FA311 with WoL HW)
866 0022 DP83820 10/100/1000 Ethernet Controller
867 0028 Geode GX2 Host Bridge
868 002a CS5535 South Bridge
869 002b CS5535 ISA bridge
870 002d CS5535 IDE
871 002e CS5535 Audio
872 002f CS5535 USB
873 0030 Geode GX2 Graphics Processor
874 0035 DP83065 [Saturn] 10/100/1000 Ethernet Controller
875 0500 SCx200 Bridge
876 0501 SCx200 SMI
877 0502 SCx200 IDE
878 0503 SCx200 Audio
879 0504 SCx200 Video
880 0505 SCx200 XBus
881 0510 SC1100 Bridge
882 0511 SC1100 SMI
883 0515 SC1100 XBus
884 d001 87410 IDE
885100c Tseng Labs Inc
886 3202 ET4000/W32p rev A
887 3205 ET4000/W32p rev B
888 3206 ET4000/W32p rev C
889 3207 ET4000/W32p rev D
890 3208 ET6000
891 4702 ET6300
892100d AST Research Inc
893100e Weitek
894 9000 P9000 Viper
895 9001 P9000 Viper
896 9002 P9000 Viper
897 9100 P9100 Viper Pro/SE
8981010 Video Logic, Ltd.
8991011 Digital Equipment Corporation
900 0001 DECchip 21050
901 0002 DECchip 21040 [Tulip]
902 0004 DECchip 21030 [TGA]
903 0007 NVRAM [Zephyr NVRAM]
904 0008 KZPSA [KZPSA]
905 0009 DECchip 21140 [FasterNet]
906 1025 0310 21140 Fast Ethernet
907 10b8 2001 SMC9332BDT EtherPower 10/100
908 10b8 2002 SMC9332BVT EtherPower T4 10/100
909 10b8 2003 SMC9334BDT EtherPower 10/100 (1-port)
910 1109 2400 ANA-6944A/TX Fast Ethernet
911 1112 2300 RNS2300 Fast Ethernet
912 1112 2320 RNS2320 Fast Ethernet
913 1112 2340 RNS2340 Fast Ethernet
914 1113 1207 EN-1207-TX Fast Ethernet
915 1186 1100 DFE-500TX Fast Ethernet
916 1186 1112 DFE-570TX Fast Ethernet
917 1186 1140 DFE-660 Cardbus Ethernet 10/100
918 1186 1142 DFE-660 Cardbus Ethernet 10/100
919 11f6 0503 Freedomline Fast Ethernet
920 1282 9100 AEF-380TXD Fast Ethernet
921 1385 1100 FA310TX Fast Ethernet
922 2646 0001 KNE100TX Fast Ethernet
923 000a 21230 Video Codec
924 000d PBXGB [TGA2]
925 000f DEFPA
926 0014 DECchip 21041 [Tulip Pass 3]
927 1186 0100 DE-530+
928 0016 DGLPB [OPPO]
929 0017 PV-PCI Graphics Controller (ZLXp-L)
930 0019 DECchip 21142/43
931 1011 500a DE500A Fast Ethernet
932 1011 500b DE500B Fast Ethernet
933 1014 0001 10/100 EtherJet Cardbus
934 1025 0315 ALN315 Fast Ethernet
935 1033 800c PC-9821-CS01 100BASE-TX Interface Card
936 1033 800d PC-9821NR-B06 100BASE-TX Interface Card
937 108d 0016 Rapidfire 2327 10/100 Ethernet
938 108d 0017 GoCard 2250 Ethernet 10/100 Cardbus
939 10b8 2005 SMC8032DT Extreme Ethernet 10/100
940 10b8 8034 SMC8034 Extreme Ethernet 10/100
941 10ef 8169 Cardbus Fast Ethernet
942 1109 2a00 ANA-6911A/TX Fast Ethernet
943 1109 2b00 ANA-6911A/TXC Fast Ethernet
944 1109 3000 ANA-6922/TX Fast Ethernet
945 1113 1207 Cheetah Fast Ethernet
946 1113 2220 Cardbus Fast Ethernet
947 115d 0002 Cardbus Ethernet 10/100
948 1179 0203 Fast Ethernet
949 1179 0204 Cardbus Fast Ethernet
950 1186 1100 DFE-500TX Fast Ethernet
951 1186 1101 DFE-500TX Fast Ethernet
952 1186 1102 DFE-500TX Fast Ethernet
953 1186 1112 DFE-570TX Quad Fast Ethernet
954 1259 2800 AT-2800Tx Fast Ethernet
955 1266 0004 Eagle Fast EtherMAX
956 12af 0019 NetFlyer Cardbus Fast Ethernet
957 1374 0001 Cardbus Ethernet Card 10/100
958 1374 0002 Cardbus Ethernet Card 10/100
959 1374 0007 Cardbus Ethernet Card 10/100
960 1374 0008 Cardbus Ethernet Card 10/100
961 1385 2100 FA510
962 1395 0001 10/100 Ethernet CardBus PC Card
963 13d1 ab01 EtherFast 10/100 Cardbus (PCMPC200)
964 14cb 0100 LNDL-100N 100Base-TX Ethernet PC Card
965 8086 0001 EtherExpress PRO/100 Mobile CardBus 32
966 001a Farallon PN9000SX Gigabit Ethernet
967 0021 DECchip 21052
968 0022 DECchip 21150
969 0023 DECchip 21150
970 0024 DECchip 21152
971 0025 DECchip 21153
972 0026 DECchip 21154
973 0034 56k Modem Cardbus
974 1374 0003 56k Modem Cardbus
975 0045 DECchip 21553
976 0046 DECchip 21554
977 0e11 4050 Integrated Smart Array
978 0e11 4051 Integrated Smart Array
979 0e11 4058 Integrated Smart Array
980 103c 10c2 Hewlett-Packard NetRAID-4M
981 12d9 000a IP Telephony card
982 4c53 1050 CT7 mainboard
983 4c53 1051 CE7 mainboard
984 9005 0364 5400S (Mustang)
985 9005 0365 5400S (Mustang)
986 9005 1364 Dell PowerEdge RAID Controller 2
987 9005 1365 Dell PowerEdge RAID Controller 2
988 e4bf 1000 CC8-1-BLUES
989 1065 StrongARM DC21285
990 1069 0020 DAC960P / DAC1164P
9911012 Micronics Computers Inc
9921013 Cirrus Logic
993 0038 GD 7548
994 0040 GD 7555 Flat Panel GUI Accelerator
995 004c GD 7556 Video/Graphics LCD/CRT Ctrlr
996 00a0 GD 5430/40 [Alpine]
997 00a2 GD 5432 [Alpine]
998 00a4 GD 5434-4 [Alpine]
999 00a8 GD 5434-8 [Alpine]
1000 00ac GD 5436 [Alpine]
1001 00b0 GD 5440
1002 00b8 GD 5446
1003 00bc GD 5480
1004 1013 00bc CL-GD5480
1005 00d0 GD 5462
1006 00d2 GD 5462 [Laguna I]
1007 00d4 GD 5464 [Laguna]
1008 00d5 GD 5464 BD [Laguna]
1009 00d6 GD 5465 [Laguna]
1010 13ce 8031 Barco Metheus 2 Megapixel, Dual Head
1011 13cf 8031 Barco Metheus 2 Megapixel, Dual Head
1012 00e8 GD 5436U
1013 1100 CL 6729
1014 1110 PD 6832 PCMCIA/CardBus Ctrlr
1015 1112 PD 6834 PCMCIA/CardBus Ctrlr
1016 1113 PD 6833 PCMCIA/CardBus Ctrlr
1017 1200 GD 7542 [Nordic]
1018 1202 GD 7543 [Viking]
1019 1204 GD 7541 [Nordic Light]
1020 4000 MD 5620 [CLM Data Fax Voice]
1021 4400 CD 4400
1022 6001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
1023 1014 1010 CS4610 SoundFusion Audio Accelerator
1024 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
1025 1013 4280 Crystal SoundFusion PCI Audio Accelerator
1026 153b 1136 SiXPack 5.1+
1027 1681 0050 Game Theater XP
1028 1681 a011 Fortissimo III 7.1
1029 6004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
1030 6005 Crystal CS4281 PCI Audio
1031 1013 4281 Crystal CS4281 PCI Audio
1032 10cf 10a8 Crystal CS4281 PCI Audio
1033 10cf 10a9 Crystal CS4281 PCI Audio
1034 10cf 10aa Crystal CS4281 PCI Audio
1035 10cf 10ab Crystal CS4281 PCI Audio
1036 10cf 10ac Crystal CS4281 PCI Audio
1037 10cf 10ad Crystal CS4281 PCI Audio
1038 10cf 10b4 Crystal CS4281 PCI Audio
1039 1179 0001 Crystal CS4281 PCI Audio
1040 14c0 000c Crystal CS4281 PCI Audio
10411014 IBM
1042 0002 PCI to MCA Bridge
1043 0005 Alta Lite
1044 0007 Alta MP
1045 000a Fire Coral
1046 0017 CPU to PCI Bridge
1047 0018 TR Auto LANstreamer
1048 001b GXT-150P
1049 001c Carrera
1050 001d 82G2675
1051 0020 GXT1000 Graphics Adapter
1052 0022 IBM27-82351
1053 002d Python
1054# [official name in AIX 5]
1055 002e SCSI RAID Adapter [ServeRAID]
1056 1014 002e ServeRAID-3x
1057 1014 022e ServeRAID-4H
1058 0031 2 Port Serial Adapter
1059# AS400 iSeries PCI sync serial card
1060 1014 0031 2721 WAN IOA - 2 Port Sync Serial Adapter
1061 0036 Miami
1062 0037 82660 CPU to PCI Bridge
1063 003a CPU to PCI Bridge
1064 003c GXT250P/GXT255P Graphics Adapter
1065 003e 16/4 Token ring UTP/STP controller
1066 1014 003e Token-Ring Adapter
1067 1014 00cd Token-Ring Adapter + Wake-On-LAN
1068 1014 00ce 16/4 Token-Ring Adapter 2
1069 1014 00cf 16/4 Token-Ring Adapter Special
1070 1014 00e4 High-Speed 100/16/4 Token-Ring Adapter
1071 1014 00e5 16/4 Token-Ring Adapter 2 + Wake-On-LAN
1072 1014 016d iSeries 2744 Card
1073 0045 SSA Adapter
1074 0046 MPIC interrupt controller
1075 0047 PCI to PCI Bridge
1076 0048 PCI to PCI Bridge
1077 0049 Warhead SCSI Controller
1078 004e ATM Controller (14104e00)
1079 004f ATM Controller (14104f00)
1080 0050 ATM Controller (14105000)
1081 0053 25 MBit ATM Controller
1082 0054 GXT500P/GXT550P Graphics Adapter
1083 0057 MPEG PCI Bridge
1084 005c i82557B 10/100
1085 005e GXT800P Graphics Adapter
1086 007c ATM Controller (14107c00)
1087 007d 3780IDSP [MWave]
1088 008b EADS PCI to PCI Bridge
1089 008e GXT3000P Graphics Adapter
1090 0090 GXT 3000P
1091 1014 008e GXT-3000P
1092 0091 SSA Adapter
1093 0095 20H2999 PCI Docking Bridge
1094 0096 Chukar chipset SCSI controller
1095 1014 0097 iSeries 2778 DASD IOA
1096 1014 0098 iSeries 2763 DASD IOA
1097 1014 0099 iSeries 2748 DASD IOA
1098 009f PCI 4758 Cryptographic Accelerator
1099 00a5 ATM Controller (1410a500)
1100 00a6 ATM 155MBPS MM Controller (1410a600)
1101 00b7 256-bit Graphics Rasterizer [Fire GL1]
1102 1092 00b8 FireGL1 AGP 32Mb
1103 00b8 GXT2000P Graphics Adapter
1104 00be ATM 622MBPS Controller (1410be00)
1105 00dc Advanced Systems Management Adapter (ASMA)
1106 00fc CPC710 Dual Bridge and Memory Controller (PCI-64)
1107 0104 Gigabit Ethernet-SX Adapter
1108 0105 CPC710 Dual Bridge and Memory Controller (PCI-32)
1109 010f Remote Supervisor Adapter (RSA)
1110 0142 Yotta Video Compositor Input
1111 1014 0143 Yotta Input Controller (ytin)
1112 0144 Yotta Video Compositor Output
1113 1014 0145 Yotta Output Controller (ytout)
1114 0156 405GP PLB to PCI Bridge
1115 015e 622Mbps ATM PCI Adapter
1116 0160 64bit/66MHz PCI ATM 155 MMF
1117 016e GXT4000P Graphics Adapter
1118 0170 GXT6000P Graphics Adapter
1119 017d GXT300P Graphics Adapter
1120 0180 Snipe chipset SCSI controller
1121 1014 0241 iSeries 2757 DASD IOA
1122 1014 0264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
1123 0188 EADS-X PCI-X to PCI-X Bridge
1124 01a7 PCI-X to PCI-X Bridge
1125 01bd ServeRAID Controller
1126 1014 01be ServeRAID-4M
1127 1014 01bf ServeRAID-4L
1128 1014 0208 ServeRAID-4Mx
1129 1014 020e ServeRAID-4Lx
1130 1014 022e ServeRAID-4H
1131 1014 0258 ServeRAID-5i
1132 1014 0259 ServeRAID-5i
1133 01c1 64bit/66MHz PCI ATM 155 UTP
1134 01e6 Cryptographic Accelerator
1135 01ff 10/100 Mbps Ethernet
1136 0219 Multiport Serial Adapter
1137 1014 021a Dual RVX
1138 1014 0251 Internal Modem/RVX
1139 1014 0252 Quad Internal Modem
1140 021b GXT6500P Graphics Adapter
1141 021c GXT4500P Graphics Adapter
1142 0233 GXT135P Graphics Adapter
1143 0266 PCI-X Dual Channel SCSI
1144 0268 Gigabit Ethernet-SX Adapter (PCI-X)
1145 0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
1146 028c Citrine chipset SCSI controller
1147 1014 028D Dual Channel PCI-X DDR SAS RAID Adapter (572E)
1148 1014 02BE Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
1149 1014 02C0 Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
1150 0302 X-Architecture Bridge [Summit]
1151 0314 ZISC 036 Neural accelerator card
1152 ffff MPIC-2 interrupt controller
11531015 LSI Logic Corp of Canada
11541016 ICL Personal Systems
11551017 SPEA Software AG
1156 5343 SPEA 3D Accelerator
11571018 Unisys Systems
11581019 Elitegroup Computer Systems
1159101a AT&T GIS (NCR)
1160 0005 100VG ethernet
1161101b Vitesse Semiconductor
1162101c Western Digital
1163 0193 33C193A
1164 0196 33C196A
1165 0197 33C197A
1166 0296 33C296A
1167 3193 7193
1168 3197 7197
1169 3296 33C296A
1170 4296 34C296
1171 9710 Pipeline 9710
1172 9712 Pipeline 9712
1173 c24a 90C
1174101e American Megatrends Inc.
1175 1960 MegaRAID
1176 101e 0471 MegaRAID 471 Enterprise 1600 RAID Controller
1177 101e 0475 MegaRAID 475 Express 500/500LC RAID Controller
1178 101e 0477 MegaRAID 477 Elite 3100 RAID Controller
1179 101e 0493 MegaRAID 493 Elite 1600 RAID Controller
1180 101e 0494 MegaRAID 494 Elite 1650 RAID Controller
1181 101e 0503 MegaRAID 503 Enterprise 1650 RAID Controller
1182 101e 0511 MegaRAID 511 i4 IDE RAID Controller
1183 101e 0522 MegaRAID 522 i4133 RAID Controller
1184 1028 0471 PowerEdge RAID Controller 3/QC
1185 1028 0475 PowerEdge RAID Controller 3/SC
1186 1028 0493 PowerEdge RAID Controller 3/DC
1187 1028 0511 PowerEdge Cost Effective RAID Controller ATA100/4Ch
1188 9010 MegaRAID 428 Ultra RAID Controller
1189 9030 EIDE Controller
1190 9031 EIDE Controller
1191 9032 EIDE & SCSI Controller
1192 9033 SCSI Controller
1193 9040 Multimedia card
1194 9060 MegaRAID 434 Ultra GT RAID Controller
1195 9063 MegaRAC
1196 101e 0767 Dell Remote Assistant Card 2
1197101f PictureTel
11981020 Hitachi Computer Products
11991021 OKI Electric Industry Co. Ltd.
12001022 Advanced Micro Devices [AMD]
1201 1100 K8 [Athlon64/Opteron] HyperTransport Technology Configuration
1202 1101 K8 [Athlon64/Opteron] Address Map
1203 1102 K8 [Athlon64/Opteron] DRAM Controller
1204 1103 K8 [Athlon64/Opteron] Miscellaneous Control
1205 2000 79c970 [PCnet32 LANCE]
1206 1014 2000 NetFinity 10/100 Fast Ethernet
1207 1022 2000 PCnet - Fast 79C971
1208 103c 104c Ethernet with LAN remote power Adapter
1209 103c 1064 Ethernet with LAN remote power Adapter
1210 103c 1065 Ethernet with LAN remote power Adapter
1211 103c 106c Ethernet with LAN remote power Adapter
1212 103c 106e Ethernet with LAN remote power Adapter
1213 103c 10ea Ethernet with LAN remote power Adapter
1214 1113 1220 EN1220 10/100 Fast Ethernet
1215 1259 2450 AT-2450 10/100 Fast Ethernet
1216 1259 2454 AT-2450v4 10Mb Ethernet Adapter
1217 1259 2700 AT-2700TX 10/100 Fast Ethernet
1218 1259 2701 AT-2700FX 100Mb Ethernet
1219 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1220 4c53 1010 CP5/CR6 mainboard
1221 4c53 1020 VR6 mainboard
1222 4c53 1030 PC5 mainboard
1223 4c53 1040 CL7 mainboard
1224 4c53 1060 PC7 mainboard
1225 2001 79c978 [HomePNA]
1226 1092 0a78 Multimedia Home Network Adapter
1227 1668 0299 ActionLink Home Network Adapter
1228 2003 Am 1771 MBW [Alchemy]
1229 2020 53c974 [PCscsi]
1230 2040 79c974
1231 3000 ELanSC520 Microcontroller
1232 7006 AMD-751 [Irongate] System Controller
1233 7007 AMD-751 [Irongate] AGP Bridge
1234 700a AMD-IGR4 AGP Host to PCI Bridge
1235 700b AMD-IGR4 PCI to PCI Bridge
1236 700c AMD-760 MP [IGD4-2P] System Controller
1237 700d AMD-760 MP [IGD4-2P] AGP Bridge
1238 700e AMD-760 [IGD4-1P] System Controller
1239 700f AMD-760 [IGD4-1P] AGP Bridge
1240 7400 AMD-755 [Cobra] ISA
1241 7401 AMD-755 [Cobra] IDE
1242 7403 AMD-755 [Cobra] ACPI
1243 7404 AMD-755 [Cobra] USB
1244 7408 AMD-756 [Viper] ISA
1245 7409 AMD-756 [Viper] IDE
1246 740b AMD-756 [Viper] ACPI
1247 740c AMD-756 [Viper] USB
1248 7410 AMD-766 [ViperPlus] ISA
1249 7411 AMD-766 [ViperPlus] IDE
1250 7413 AMD-766 [ViperPlus] ACPI
1251 7414 AMD-766 [ViperPlus] USB
1252 7440 AMD-768 [Opus] ISA
1253 1043 8044 A7M-D Mainboard
1254 7441 AMD-768 [Opus] IDE
1255 7443 AMD-768 [Opus] ACPI
1256 1043 8044 A7M-D Mainboard
1257 7445 AMD-768 [Opus] Audio
1258 7446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
1259 7448 AMD-768 [Opus] PCI
1260 7449 AMD-768 [Opus] USB
1261 7450 AMD-8131 PCI-X Bridge
1262 7451 AMD-8131 PCI-X APIC
1263 7454 AMD-8151 System Controller
1264 7455 AMD-8151 AGP Bridge
1265 7460 AMD-8111 PCI
1266 161f 3017 HDAMB
1267 7461 AMD-8111 USB
1268 7462 AMD-8111 Ethernet
1269 7464 AMD-8111 USB
1270 161f 3017 HDAMB
1271 7468 AMD-8111 LPC
1272 161f 3017 HDAMB
1273 7469 AMD-8111 IDE
1274 161f 3017 HDAMB
1275 746a AMD-8111 SMBus 2.0
1276 746b AMD-8111 ACPI
1277 161f 3017 HDAMB
1278 746d AMD-8111 AC97 Audio
1279 161f 3017 HDAMB
1280 746e AMD-8111 MC97 Modem
1281 756b AMD-8111 ACPI
12821023 Trident Microsystems
1283 0194 82C194
1284 2000 4DWave DX
1285 2001 4DWave NX
1286 122d 1400 Trident PCI288-Q3DII (NX)
1287 2100 CyberBlade XP4m32
1288 2200 XGI Volari XP5
1289 8400 CyberBlade/i7
1290 1023 8400 CyberBlade i7 AGP
1291 8420 CyberBlade/i7d
1292 0e11 b15a CyberBlade i7 AGP
1293 8500 CyberBlade/i1
1294 8520 CyberBlade i1
1295 0e11 b16e CyberBlade i1 AGP
1296 1023 8520 CyberBlade i1 AGP
1297 8620 CyberBlade/i1
1298 1014 0502 ThinkPad R30/T30
1299 8820 CyberBlade XPAi1
1300 9320 TGUI 9320
1301 9350 GUI Accelerator
1302 9360 Flat panel GUI Accelerator
1303 9382 Cyber 9382 [Reference design]
1304 9383 Cyber 9383 [Reference design]
1305 9385 Cyber 9385 [Reference design]
1306 9386 Cyber 9386
1307 9388 Cyber 9388
1308 9397 Cyber 9397
1309 939a Cyber 9397DVD
1310 9420 TGUI 9420
1311 9430 TGUI 9430
1312 9440 TGUI 9440
1313 9460 TGUI 9460
1314 9470 TGUI 9470
1315 9520 Cyber 9520
1316 9525 Cyber 9525
1317 10cf 1094 Lifebook C6155
1318 9540 Cyber 9540
1319 9660 TGUI 9660/938x/968x
1320 9680 TGUI 9680
1321 9682 TGUI 9682
1322 9683 TGUI 9683
1323 9685 ProVIDIA 9685
1324 9750 3DImage 9750
1325 1014 9750 3DImage 9750
1326 1023 9750 3DImage 9750
1327 9753 TGUI 9753
1328 9754 TGUI 9754
1329 9759 TGUI 975
1330 9783 TGUI 9783
1331 9785 TGUI 9785
1332 9850 3DImage 9850
1333 9880 Blade 3D PCI/AGP
1334 1023 9880 Blade 3D
1335 9910 CyberBlade/XP
1336 9930 CyberBlade/XPm
13371024 Zenith Data Systems
13381025 Acer Incorporated [ALI]
1339 1435 M1435
1340 1445 M1445
1341 1449 M1449
1342 1451 M1451
1343 1461 M1461
1344 1489 M1489
1345 1511 M1511
1346 1512 ALI M1512 Aladdin
1347 1513 M1513
1348 1521 ALI M1521 Aladdin III CPU Bridge
1349 10b9 1521 ALI M1521 Aladdin III CPU Bridge
1350 1523 ALI M1523 ISA Bridge
1351 10b9 1523 ALI M1523 ISA Bridge
1352 1531 M1531 Northbridge [Aladdin IV/IV+]
1353 1533 M1533 PCI-to-ISA Bridge
1354 10b9 1533 ALI M1533 Aladdin IV/V ISA South Bridge
1355 1535 M1535 PCI Bridge + Super I/O + FIR
1356 1541 M1541 Northbridge [Aladdin V]
1357 10b9 1541 ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
1358 1542 M1542 Northbridge [Aladdin V]
1359 1543 M1543 PCI-to-ISA Bridge + Super I/O + FIR
1360 1561 M1561 Northbridge [Aladdin 7]
1361 1621 M1621 Northbridge [Aladdin-Pro II]
1362 1631 M1631 Northbridge+3D Graphics [Aladdin TNT2]
1363 1641 M1641 Northbridge [Aladdin-Pro IV]
1364 1647 M1647 [MaGiK1] PCI North Bridge
1365 1671 M1671 Northbridge [ALADDiN-P4]
1366 1672 Northbridge [CyberALADDiN-P4]
1367 3141 M3141
1368 3143 M3143
1369 3145 M3145
1370 3147 M3147
1371 3149 M3149
1372 3151 M3151
1373 3307 M3307 MPEG-I Video Controller
1374 3309 M3309 MPEG-II Video w/ Software Audio Decoder
1375 3321 M3321 MPEG-II Audio/Video Decoder
1376 5212 M4803
1377 5215 ALI PCI EIDE Controller
1378 5217 M5217H
1379 5219 M5219
1380 5225 M5225
1381 5229 M5229
1382 5235 M5235
1383 5237 M5237 PCI USB Host Controller
1384 5240 EIDE Controller
1385 5241 PCMCIA Bridge
1386 5242 General Purpose Controller
1387 5243 PCI to PCI Bridge Controller
1388 5244 Floppy Disk Controller
1389 5247 M1541 PCI to PCI Bridge
1390 5251 M5251 P1394 Controller
1391 5427 PCI to AGP Bridge
1392 5451 M5451 PCI AC-Link Controller Audio Device
1393 5453 M5453 PCI AC-Link Controller Modem Device
1394 7101 M7101 PCI PMU Power Management Controller
1395 10b9 7101 M7101 PCI PMU Power Management Controller
13961028 Dell
1397 0001 PowerEdge Expandable RAID Controller 2/Si
1398 1028 0001 PowerEdge 2400
1399 0002 PowerEdge Expandable RAID Controller 3/Di
1400 1028 0002 PowerEdge 4400
1401 0003 PowerEdge Expandable RAID Controller 3/Si
1402 1028 0003 PowerEdge 2450
1403 0006 PowerEdge Expandable RAID Controller 3/Di
1404 0007 Remote Access Card III
1405 0008 Remote Access Card III
1406 0009 Remote Access Card III: BMC/SMIC device not present
1407 000a PowerEdge Expandable RAID Controller 3/Di
1408 000c Embedded Remote Access or ERA/O
1409 000d Embedded Remote Access: BMC/SMIC device
1410 000e PowerEdge Expandable RAID controller 4/Di
1411 000f PowerEdge Expandable RAID controller 4/Di
1412 0010 Remote Access Card 4
1413 0011 Remote Access Card 4 Daughter Card
1414 0012 Remote Access Card 4 Daughter Card Virtual UART
1415 0013 PowerEdge Expandable RAID controller 4
1416 1028 016c PowerEdge Expandable RAID Controller 4e/Si
1417 1028 016d PowerEdge Expandable RAID Controller 4e/Di
1418 1028 016e PowerEdge Expandable RAID Controller 4e/Di
1419 1028 016f PowerEdge Expandable RAID Controller 4e/Di
1420 1028 0170 PowerEdge Expandable RAID Controller 4e/Di
1421 0014 Remote Access Card 4 Daughter Card SMIC interface
14221029 Siemens Nixdorf IS
1423102a LSI Logic
1424 0000 HYDRA
1425 0010 ASPEN
1426 001f AHA-2940U2/U2W /7890/7891 SCSI Controllers
1427 9005 000f 2940U2W SCSI Controller
1428 9005 0106 2940U2W SCSI Controller
1429 9005 a180 2940U2W SCSI Controller
1430 00c5 AIC-7899 U160/m SCSI Controller
1431 1028 00c5 PowerEdge 2550/2650/4600
1432 00cf AIC-7899P U160/m
1433 1028 0106 PowerEdge 4600
1434 1028 0121 PowerEdge 2650
1435102b Matrox Graphics, Inc.
1436# DJ: I've a suspicion that 0010 is a duplicate of 0d10.
1437 0010 MGA-I [Impression?]
1438 0100 MGA 1064SG [Mystique]
1439 0518 MGA-II [Athena]
1440 0519 MGA 2064W [Millennium]
1441 051a MGA 1064SG [Mystique]
1442 102b 0100 MGA-1064SG Mystique
1443 102b 1100 MGA-1084SG Mystique
1444 102b 1200 MGA-1084SG Mystique
1445 1100 102b MGA-1084SG Mystique
1446 110a 0018 Scenic Pro C5 (D1025)
1447 051b MGA 2164W [Millennium II]
1448 102b 051b MGA-2164W Millennium II
1449 102b 1100 MGA-2164W Millennium II
1450 102b 1200 MGA-2164W Millennium II
1451 051e MGA 1064SG [Mystique] AGP
1452 051f MGA 2164W [Millennium II] AGP
1453 0520 MGA G200
1454 102b dbc2 G200 Multi-Monitor
1455 102b dbc8 G200 Multi-Monitor
1456 102b dbe2 G200 Multi-Monitor
1457 102b dbe8 G200 Multi-Monitor
1458 102b ff03 Millennium G200 SD
1459 102b ff04 Marvel G200
1460 0521 MGA G200 AGP
1461 1014 ff03 Millennium G200 AGP
1462 102b 48e9 Mystique G200 AGP
1463 102b 48f8 Millennium G200 SD AGP
1464 102b 4a60 Millennium G200 LE AGP
1465 102b 4a64 Millennium G200 AGP
1466 102b c93c Millennium G200 AGP
1467 102b c9b0 Millennium G200 AGP
1468 102b c9bc Millennium G200 AGP
1469 102b ca60 Millennium G250 LE AGP
1470 102b ca6c Millennium G250 AGP
1471 102b dbbc Millennium G200 AGP
1472 102b dbc2 Millennium G200 MMS (Dual G200)
1473 102b dbc3 G200 Multi-Monitor
1474 102b dbc8 Millennium G200 MMS (Dual G200)
1475 102b dbd2 G200 Multi-Monitor
1476 102b dbd3 G200 Multi-Monitor
1477 102b dbd4 G200 Multi-Monitor
1478 102b dbd5 G200 Multi-Monitor
1479 102b dbd8 G200 Multi-Monitor
1480 102b dbd9 G200 Multi-Monitor
1481 102b dbe2 Millennium G200 MMS (Quad G200)
1482 102b dbe3 G200 Multi-Monitor
1483 102b dbe8 Millennium G200 MMS (Quad G200)
1484 102b dbf2 G200 Multi-Monitor
1485 102b dbf3 G200 Multi-Monitor
1486 102b dbf4 G200 Multi-Monitor
1487 102b dbf5 G200 Multi-Monitor
1488 102b dbf8 G200 Multi-Monitor
1489 102b dbf9 G200 Multi-Monitor
1490 102b f806 Mystique G200 Video AGP
1491 102b ff00 MGA-G200 AGP
1492 102b ff02 Mystique G200 AGP
1493 102b ff03 Millennium G200 AGP
1494 102b ff04 Marvel G200 AGP
1495 110a 0032 MGA-G200 AGP
1496 0525 MGA G400 AGP
1497 0e11 b16f MGA-G400 AGP
1498 102b 0328 Millennium G400 16Mb SDRAM
1499 102b 0338 Millennium G400 16Mb SDRAM
1500 102b 0378 Millennium G400 32Mb SDRAM
1501 102b 0541 Millennium G450 Dual Head
1502 102b 0542 Millennium G450 Dual Head LX
1503 102b 0543 Millennium G450 Single Head LX
1504 102b 0641 Millennium G450 32Mb SDRAM Dual Head
1505 102b 0642 Millennium G450 32Mb SDRAM Dual Head LX
1506 102b 0643 Millennium G450 32Mb SDRAM Single Head LX
1507 102b 07c0 Millennium G450 Dual Head LE
1508 102b 07c1 Millennium G450 SDR Dual Head LE
1509 102b 0d41 Millennium G450 Dual Head PCI
1510 102b 0d42 Millennium G450 Dual Head LX PCI
1511 102b 0d43 Millennium G450 32Mb Dual Head PCI
1512 102b 0e00 Marvel G450 eTV
1513 102b 0e01 Marvel G450 eTV
1514 102b 0e02 Marvel G450 eTV
1515 102b 0e03 Marvel G450 eTV
1516 102b 0f80 Millennium G450 Low Profile
1517 102b 0f81 Millennium G450 Low Profile
1518 102b 0f82 Millennium G450 Low Profile DVI
1519 102b 0f83 Millennium G450 Low Profile DVI
1520 102b 19d8 Millennium G400 16Mb SGRAM
1521 102b 19f8 Millennium G400 32Mb SGRAM
1522 102b 2159 Millennium G400 Dual Head 16Mb
1523 102b 2179 Millennium G400 MAX/Dual Head 32Mb
1524 102b 217d Millennium G400 Dual Head Max
1525 102b 23c0 Millennium G450
1526 102b 23c1 Millennium G450
1527 102b 23c2 Millennium G450 DVI
1528 102b 23c3 Millennium G450 DVI
1529 102b 2f58 Millennium G400
1530 102b 2f78 Millennium G400
1531 102b 3693 Marvel G400 AGP
1532 102b 5dd0 4Sight II
1533 102b 5f50 4Sight II
1534 102b 5f51 4Sight II
1535 102b 5f52 4Sight II
1536 102b 9010 Millennium G400 Dual Head
1537 1458 0400 GA-G400
1538 1705 0001 Millennium G450 32MB SGRAM
1539 1705 0002 Millennium G450 16MB SGRAM
1540 1705 0003 Millennium G450 32MB
1541 1705 0004 Millennium G450 16MB
1542 0527 MGA Parhelia AGP
1543 102b 0840 Parhelia 128Mb
1544 0d10 MGA Ultima/Impression
1545 1000 MGA G100 [Productiva]
1546 102b ff01 Productiva G100
1547 102b ff05 Productiva G100 Multi-Monitor
1548 1001 MGA G100 [Productiva] AGP
1549 102b 1001 MGA-G100 AGP
1550 102b ff00 MGA-G100 AGP
1551 102b ff01 MGA-G100 Productiva AGP
1552 102b ff03 Millennium G100 AGP
1553 102b ff04 MGA-G100 AGP
1554 102b ff05 MGA-G100 Productiva AGP Multi-Monitor
1555 110a 001e MGA-G100 AGP
1556 2007 MGA Mistral
1557 2527 MGA G550 AGP
1558 102b 0f83 Millennium G550
1559 102b 0f84 Millennium G550 Dual Head DDR 32Mb
1560 102b 1e41 Millennium G550
1561 2537 MGA G650 AGP
1562 4536 VIA Framegrabber
1563 6573 Shark 10/100 Multiport SwitchNIC
1564102c Chips and Technologies
1565 00b8 F64310
1566 00c0 F69000 HiQVideo
1567 102c 00c0 F69000 HiQVideo
1568 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1569 4c53 1010 CP5/CR6 mainboard
1570 4c53 1020 VR6 mainboard
1571 4c53 1030 PC5 mainboard
1572 4c53 1050 CT7 mainboard
1573 4c53 1051 CE7 mainboard
1574 00d0 F65545
1575 00d8 F65545
1576 00dc F65548
1577 00e0 F65550
1578 00e4 F65554
1579 00e5 F65555 HiQVPro
1580 0e11 b049 Armada 1700 Laptop Display Controller
1581 00f0 F68554
1582 00f4 F68554 HiQVision
1583 00f5 F68555
1584 0c30 F69030
1585 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1586 4c53 1050 CT7 mainboard
1587 4c53 1051 CE7 mainboard
1588# C5C project cancelled
1589 4c53 1080 CT8 mainboard
1590102d Wyse Technology Inc.
1591 50dc 3328 Audio
1592102e Olivetti Advanced Technology
1593102f Toshiba America
1594 0009 r4x00
1595 000a TX3927 MIPS RISC PCI Controller
1596 0020 ATM Meteor 155
1597 102f 00f8 ATM Meteor 155
1598 0030 TC35815CF PCI 10/100 Mbit Ethernet Controller
1599 0031 TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
1600 0105 TC86C001 [goku-s] IDE
1601 0106 TC86C001 [goku-s] USB 1.1 Host
1602 0107 TC86C001 [goku-s] USB Device Controller
1603 0108 TC86C001 [goku-s] I2C/SIO/GPIO Controller
1604 0180 TX4927/38 MIPS RISC PCI Controller
1605 0181 TX4925 MIPS RISC PCI Controller
1606 0182 TX4937 MIPS RISC PCI Controller
16071030 TMC Research
16081031 Miro Computer Products AG
1609 5601 DC20 ASIC
1610 5607 Video I/O & motion JPEG compressor
1611 5631 Media 3D
1612 6057 MiroVideo DC10/DC30+
16131032 Compaq
16141033 NEC Corporation
1615 0000 Vr4181A USB Host or Function Control Unit
1616 0001 PCI to 486-like bus Bridge
1617 0002 PCI to VL98 Bridge
1618 0003 ATM Controller
1619 0004 R4000 PCI Bridge
1620 0005 PCI to 486-like bus Bridge
1621 0006 PC-9800 Graphic Accelerator
1622 0007 PCI to UX-Bus Bridge
1623 0008 PC-9800 Graphic Accelerator
1624 0009 PCI to PC9800 Core-Graph Bridge
1625 0016 PCI to VL Bridge
1626 001a [Nile II]
1627 0021 Vrc4373 [Nile I]
1628 0029 PowerVR PCX1
1629 002a PowerVR 3D
1630 002c Star Alpha 2
1631 002d PCI to C-bus Bridge
1632 0035 USB
1633 1179 0001 USB
1634 12ee 7000 Root Hub
1635 1799 0001 Root Hub
1636 807d 0035 PCI-USB2 (OHCI subsystem)
1637 003b PCI to C-bus Bridge
1638 003e NAPCCARD Cardbus Controller
1639 0046 PowerVR PCX2 [midas]
1640 005a Vrc5074 [Nile 4]
1641 0063 Firewarden
1642 0067 PowerVR Neon 250 Chipset
1643 1010 0020 PowerVR Neon 250 AGP 32Mb
1644 1010 0080 PowerVR Neon 250 AGP 16Mb
1645 1010 0088 PowerVR Neon 250 16Mb
1646 1010 0090 PowerVR Neon 250 AGP 16Mb
1647 1010 0098 PowerVR Neon 250 16Mb
1648 1010 00a0 PowerVR Neon 250 AGP 32Mb
1649 1010 00a8 PowerVR Neon 250 32Mb
1650 1010 0120 PowerVR Neon 250 AGP 32Mb
1651 0072 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
1652 0074 56k Voice Modem
1653 1033 8014 RCV56ACF 56k Voice Modem
1654 009b Vrc5476
1655 00a5 VRC4173
1656 00a6 VRC5477 AC97
1657 00cd IEEE 1394 [OrangeLink] Host Controller
1658 12ee 8011 Root hub
1659 00ce IEEE 1394 Host Controller
1660 00df Vr4131
1661 00e0 USB 2.0
1662 0ee4 3383 Sitecom IEEE 1394 / USB2.0 Combo Card
1663 12ee 7001 Root hub
1664 1799 0002 Root Hub
1665 807d 1043 PCI-USB2 (EHCI subsystem)
1666 00e7 IEEE 1394 Host Controller
1667 00f2 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
1668 00f3 uPD6113x Multimedia Decoder/Processor [EMMA2]
1669 010c VR7701
16701034 Framatome Connectors USA Inc.
16711035 Comp. & Comm. Research Lab
16721036 Future Domain Corp.
1673 0000 TMC-18C30 [36C70]
16741037 Hitachi Micro Systems
16751038 AMP, Inc
16761039 Silicon Integrated Systems [SiS]
1677 0001 Virtual PCI-to-PCI bridge (AGP)
1678 0002 SG86C202
1679 0006 85C501/2/3
1680 0008 SiS85C503/5513 (LPC Bridge)
1681 0009 ACPI
1682# source: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
1683 0016 SiS961/2 SMBus Controller
1684 0018 SiS85C503/5513 (LPC Bridge)
1685# Controller for 2 PATA and 2 SATA channels
1686 0180 RAID bus controller 180 SATA/PATA [SiS]
1687 0181 SiS SATA
1688 0200 5597/5598/6326 VGA
1689 1039 0000 SiS5597 SVGA (Shared RAM)
1690 0204 82C204
1691 0205 SG86C205
1692 0300 300/305 PCI/AGP VGA Display Adapter
1693 107d 2720 Leadtek WinFast VR300
1694 0310 315H PCI/AGP VGA Display Adapter
1695 0315 315 PCI/AGP VGA Display Adapter
1696 0325 315PRO PCI/AGP VGA Display Adapter
1697 0330 330 [Xabre] PCI/AGP VGA Display Adapter
1698 0406 85C501/2
1699 0496 85C496
1700 0530 530 Host
1701 0540 540 Host
1702 0550 550 Host
1703 0597 5513C
1704 0601 85C601
1705 0620 620 Host
1706 0630 630 Host
1707 0633 633 Host
1708 0635 635 Host
1709 0645 SiS645 Host & Memory & AGP Controller
1710 0646 SiS645DX Host & Memory & AGP Controller
1711 0648 SiS 645xx
1712 0650 650/M650 Host
1713 0651 651 Host
1714 0655 655 Host
1715 0660 660 Host
1716 0661 661FX/M661FX/M661MX Host
1717 0730 730 Host
1718 0733 733 Host
1719 0735 735 Host
1720 0740 740 Host
1721 0741 741/741GX/M741 Host
1722 0745 745 Host
1723 0746 746 Host
1724 0755 755 Host
1725 0760 760/M760 Host
1726 0900 SiS900 PCI Fast Ethernet
1727 1019 0a14 K7S5A motherboard
1728 1039 0900 SiS900 10/100 Ethernet Adapter
1729 1043 8035 CUSI-FX motherboard
1730 0961 SiS961 [MuTIOL Media IO]
1731 0962 SiS962 [MuTIOL Media IO]
1732 0963 SiS963 [MuTIOL Media IO]
1733 0964 SiS964 [MuTIOL Media IO]
1734 0965 SiS965 [MuTIOL Media IO]
1735 3602 83C602
1736 5107 5107
1737 5300 SiS540 PCI Display Adapter
1738 5315 550 PCI/AGP VGA Display Adapter
1739 5401 486 PCI Chipset
1740 5511 5511/5512
1741 5513 5513 [IDE]
1742 1019 0970 P6STP-FL motherboard
1743 1039 5513 SiS5513 EIDE Controller (A,B step)
1744 1043 8035 CUSI-FX motherboard
1745 5517 5517
1746 5571 5571
1747 5581 5581 Pentium Chipset
1748 5582 5582
1749 5591 5591/5592 Host
1750 5596 5596 Pentium Chipset
1751 5597 5597 [SiS5582]
1752 5600 5600 Host
1753 6204 Video decoder & MPEG interface
1754 6205 VGA Controller
1755 6236 6236 3D-AGP
1756 6300 630/730 PCI/AGP VGA Display Adapter
1757 1019 0970 P6STP-FL motherboard
1758 1043 8035 CUSI-FX motherboard
1759 6306 530/620 PCI/AGP VGA Display Adapter
1760 1039 6306 SiS530,620 GUI Accelerator+3D
1761 6325 65x/M650/740 PCI/AGP VGA Display Adapter
1762 6326 86C326 5598/6326
1763 1039 6326 SiS6326 GUI Accelerator
1764 1092 0a50 SpeedStar A50
1765 1092 0a70 SpeedStar A70
1766 1092 4910 SpeedStar A70
1767 1092 4920 SpeedStar A70
1768 1569 6326 SiS6326 GUI Accelerator
1769 6330 661/741/760 PCI/AGP VGA Display Adapter
1770 1039 6330 [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
1771 7001 USB 1.0 Controller
1772 1019 0a14 K7S5A motherboard
1773 1039 7000 Onboard USB Controller
1774 7002 USB 2.0 Controller
1775 1509 7002 Onboard USB Controller
1776 7007 FireWire Controller
1777 7012 Sound Controller
1778# There are may be different modem codecs here (Intel537 compatible and incompatible)
1779 7013 AC'97 Modem Controller
1780 7016 SiS7016 PCI Fast Ethernet Adapter
1781 1039 7016 SiS7016 10/100 Ethernet Adapter
1782 7018 SiS PCI Audio Accelerator
1783 1014 01b6 SiS PCI Audio Accelerator
1784 1014 01b7 SiS PCI Audio Accelerator
1785 1019 7018 SiS PCI Audio Accelerator
1786 1025 000e SiS PCI Audio Accelerator
1787 1025 0018 SiS PCI Audio Accelerator
1788 1039 7018 SiS PCI Audio Accelerator
1789 1043 800b SiS PCI Audio Accelerator
1790 1054 7018 SiS PCI Audio Accelerator
1791 107d 5330 SiS PCI Audio Accelerator
1792 107d 5350 SiS PCI Audio Accelerator
1793 1170 3209 SiS PCI Audio Accelerator
1794 1462 400a SiS PCI Audio Accelerator
1795 14a4 2089 SiS PCI Audio Accelerator
1796 14cd 2194 SiS PCI Audio Accelerator
1797 14ff 1100 SiS PCI Audio Accelerator
1798 152d 8808 SiS PCI Audio Accelerator
1799 1558 1103 SiS PCI Audio Accelerator
1800 1558 2200 SiS PCI Audio Accelerator
1801 1563 7018 SiS PCI Audio Accelerator
1802 15c5 0111 SiS PCI Audio Accelerator
1803 270f a171 SiS PCI Audio Accelerator
1804 a0a0 0022 SiS PCI Audio Accelerator
1805 7019 SiS7019 Audio Accelerator
1806103a Seiko Epson Corporation
1807103b Tatung Co. of America
1808103c Hewlett-Packard Company
1809 1005 A4977A Visualize EG
1810 1006 Visualize FX6
1811 1008 Visualize FX4
1812 100a Visualize FX2
1813 1028 Tach TL Fibre Channel Host Adapter
1814 1029 Tach XL2 Fibre Channel Host Adapter
1815 107e 000f Interphase 5560 Fibre Channel Adapter
1816 9004 9210 1Gb/2Gb Family Fibre Channel Controller
1817 9004 9211 1Gb/2Gb Family Fibre Channel Controller
1818 102a Tach TS Fibre Channel Host Adapter
1819 107e 000e Interphase 5540/5541 Fibre Channel Adapter
1820 9004 9110 1Gb/2Gb Family Fibre Channel Controller
1821 9004 9111 1Gb/2Gb Family Fibre Channel Controller
1822 1030 J2585A DeskDirect 10/100VG NIC
1823 1031 J2585B HP 10/100VG PCI LAN Adapter
1824 103c 1040 J2973A DeskDirect 10BaseT NIC
1825 103c 1041 J2585B DeskDirect 10/100VG NIC
1826 103c 1042 J2970A DeskDirect 10BaseT/2 NIC
1827 1040 J2973A DeskDirect 10BaseT NIC
1828 1041 J2585B DeskDirect 10/100 NIC
1829 1042 J2970A DeskDirect 10BaseT/2 NIC
1830 1048 Diva Serial [GSP] Multiport UART
1831 103c 1049 Tosca Console
1832 103c 104a Tosca Secondary
1833 103c 104b Maestro SP2
1834 103c 1223 Superdome Console
1835 103c 1226 Keystone SP2
1836 103c 1227 Powerbar SP2
1837 103c 1282 Everest SP2
1838 103c 1301 Diva RMP3
1839 1054 PCI Local Bus Adapter
1840 1064 79C970 PCnet Ethernet Controller
1841 108b Visualize FXe
1842 10c1 NetServer Smart IRQ Router
1843 10ed TopTools Remote Control
1844 10f0 rio System Bus Adapter
1845 10f1 rio I/O Controller
1846 1200 82557B 10/100 NIC
1847 1219 NetServer PCI Hot-Plug Controller
1848 121a NetServer SMIC Controller
1849 121b NetServer Legacy COM Port Decoder
1850 121c NetServer PCI COM Port Decoder
1851 1229 zx1 System Bus Adapter
1852 122a zx1 I/O Controller
1853 122e zx1 Local Bus Adapter
1854 127c sx1000 I/O Controller
1855 1290 Auxiliary Diva Serial Port
1856 12b4 zx1 QuickSilver AGP8x Local Bus Adapter
1857 2910 E2910A PCIBus Exerciser
1858 2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
1859103e Solliday Engineering
1860103f Synopsys/Logic Modeling Group
18611040 Accelgraphics Inc.
18621041 Computrend
18631042 Micron
1864 1000 PC Tech RZ1000
1865 1001 PC Tech RZ1001
1866 3000 Samurai_0
1867 3010 Samurai_1
1868 3020 Samurai_IDE
18691043 ASUSTeK Computer Inc.
1870 0675 ISDNLink P-IN100-ST-D
1871 4015 v7100 SDRAM [GeForce2 MX]
1872 4021 v7100 Combo Deluxe [GeForce2 MX + TV tuner]
1873 4057 v8200 GeForce 3
1874 8043 v8240 PAL 128M [P4T] Motherboard
1875 807b v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI]
1876 80bb v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
1877 80c5 nForce3 chipset motherboard [SK8N]
1878 80df v9520 Magic/T
18791044 Adaptec (formerly DPT)
1880 1012 Domino RAID Engine
1881 a400 SmartCache/Raid I-IV Controller
1882 a500 PCI Bridge
1883 a501 SmartRAID V Controller
1884 1044 c001 PM1554U2 Ultra2 Single Channel
1885 1044 c002 PM1654U2 Ultra2 Single Channel
1886 1044 c003 PM1564U3 Ultra3 Single Channel
1887 1044 c004 PM1564U3 Ultra3 Dual Channel
1888 1044 c005 PM1554U2 Ultra2 Single Channel (NON ACPI)
1889 1044 c00a PM2554U2 Ultra2 Single Channel
1890 1044 c00b PM2654U2 Ultra2 Single Channel
1891 1044 c00c PM2664U3 Ultra3 Single Channel
1892 1044 c00d PM2664U3 Ultra3 Dual Channel
1893 1044 c00e PM2554U2 Ultra2 Single Channel (NON ACPI)
1894 1044 c00f PM2654U2 Ultra2 Single Channel (NON ACPI)
1895 1044 c014 PM3754U2 Ultra2 Single Channel (NON ACPI)
1896 1044 c015 PM3755U2B Ultra2 Single Channel (NON ACPI)
1897 1044 c016 PM3755F Fibre Channel (NON ACPI)
1898 1044 c01e PM3757U2 Ultra2 Single Channel
1899 1044 c01f PM3757U2 Ultra2 Dual Channel
1900 1044 c020 PM3767U3 Ultra3 Dual Channel
1901 1044 c021 PM3767U3 Ultra3 Quad Channel
1902 1044 c028 PM2865U3 Ultra3 Single Channel
1903 1044 c029 PM2865U3 Ultra3 Dual Channel
1904 1044 c02a PM2865F Fibre Channel
1905 1044 c03c 2000S Ultra3 Single Channel
1906 1044 c03d 2000S Ultra3 Dual Channel
1907 1044 c03e 2000F Fibre Channel
1908 1044 c046 3000S Ultra3 Single Channel
1909 1044 c047 3000S Ultra3 Dual Channel
1910 1044 c048 3000F Fibre Channel
1911 1044 c050 5000S Ultra3 Single Channel
1912 1044 c051 5000S Ultra3 Dual Channel
1913 1044 c052 5000F Fibre Channel
1914 1044 c05a 2400A UDMA Four Channel
1915 1044 c05b 2400A UDMA Four Channel DAC
1916 1044 c064 3010S Ultra3 Dual Channel
1917 1044 c065 3410S Ultra160 Four Channel
1918 1044 c066 3010S Fibre Channel
1919 a511 SmartRAID V Controller
1920 1044 c032 ASR-2005S I2O Zero Channel
19211045 OPTi Inc.
1922 a0f8 82C750 [Vendetta] USB Controller
1923 c101 92C264
1924 c178 92C178
1925 c556 82X556 [Viper]
1926 c557 82C557 [Viper-M]
1927 c558 82C558 [Viper-M ISA+IDE]
1928 c567 82C750 [Vendetta], device 0
1929 c568 82C750 [Vendetta], device 1
1930 c569 82C579 [Viper XPress+ Chipset]
1931 c621 82C621 [Viper-M/N+]
1932 c700 82C700 [FireStar]
1933 c701 82C701 [FireStar Plus]
1934 c814 82C814 [Firebridge 1]
1935 c822 82C822
1936 c824 82C824
1937 c825 82C825 [Firebridge 2]
1938 c832 82C832
1939 c861 82C861
1940 c895 82C895
1941 c935 EV1935 ECTIVA MachOne PCIAudio
1942 d568 82C825 [Firebridge 2]
1943 d721 IDE [FireStar]
19441046 IPC Corporation, Ltd.
19451047 Genoa Systems Corp
19461048 Elsa AG
1947 0c60 Gladiac MX
1948 0d22 Quadro4 900XGL [ELSA GLoria4 900XGL]
1949 1000 QuickStep 1000
1950 3000 QuickStep 3000
1951 8901 Gloria XL
19521049 Fountain Technologies, Inc.
1953# # nee SGS Thomson Microelectronics
1954104a STMicroelectronics
1955 0008 STG 2000X
1956 0009 STG 1764X
1957 0010 STG4000 [3D Prophet Kyro Series]
1958 0209 STPC Consumer/Industrial North- and Southbridge
1959 020a STPC Atlas/ConsumerS/Consumer IIA Northbridge
1960# From <http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/share/misc/pci_vendors>
1961 0210 STPC Atlas ISA Bridge
1962 021a STPC Consumer S Southbridge
1963 021b STPC Consumer IIA Southbridge
1964 0500 ST70137 [Unicorn] ADSL DMT Transceiver
1965 0564 STPC Client Northbridge
1966 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
1967 1746 STG 1764X
1968 2774 21x4x DEC-Tulip compatible 10/100 Ethernet
1969 3520 MPEG-II decoder card
1970 55cc STPC Client Southbridge
1971104b BusLogic
1972 0140 BT-946C (old) [multimaster 01]
1973 1040 BT-946C (BA80C30) [MultiMaster 10]
1974 8130 Flashpoint LT
1975104c Texas Instruments
1976 0500 100 MBit LAN Controller
1977 0508 TMS380C2X Compressor Interface
1978 1000 Eagle i/f AS
1979 104c PCI1510 PC card Cardbus Controller
1980 3d04 TVP4010 [Permedia]
1981 3d07 TVP4020 [Permedia 2]
1982 1011 4d10 Comet
1983 1040 000f AccelStar II
1984 1040 0011 AccelStar II
1985 1048 0a31 WINNER 2000
1986 1048 0a32 GLoria Synergy
1987 1048 0a35 GLoria Synergy
1988 107d 2633 WinFast 3D L2300
1989 1092 0127 FIRE GL 1000 PRO
1990 1092 0136 FIRE GL 1000 PRO
1991 1092 0141 FIRE GL 1000 PRO
1992 1092 0146 FIRE GL 1000 PRO
1993 1092 0148 FIRE GL 1000 PRO
1994 1092 0149 FIRE GL 1000 PRO
1995 1092 0152 FIRE GL 1000 PRO
1996 1092 0154 FIRE GL 1000 PRO
1997 1092 0155 FIRE GL 1000 PRO
1998 1092 0156 FIRE GL 1000 PRO
1999 1092 0157 FIRE GL 1000 PRO
2000 1097 3d01 Jeronimo Pro
2001 1102 100f Graphics Blaster Extreme
2002 3d3d 0100 Reference Permedia 2 3D
2003 8000 PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
2004 e4bf 1010 CF1-1-SNARE
2005 e4bf 1020 CF1-2-SNARE
2006 8009 FireWire Controller
2007 104d 8032 8032 OHCI i.LINK (IEEE 1394) Controller
2008 8017 PCI4410 FireWire Controller
2009 8019 TSB12LV23 IEEE-1394 Controller
2010 11bd 000a Studio DV500-1394
2011 11bd 000e Studio DV
2012 e4bf 1010 CF2-1-CYMBAL
2013 8020 TSB12LV26 IEEE-1394 Controller (Link)
2014 11bd 000f Studio DV500-1394
2015 8021 TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
2016 104d 80df Vaio PCG-FX403
2017 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
2018 8022 TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link)
2019 8023 TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
2020 103c 088c nc8000 laptop
2021 8024 TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
2022 8025 TSB82AA2 IEEE-1394b Link Layer Controller
2023 55aa 55aa FireWire 800 PCI Card
2024 8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
2025 8027 PCI4451 IEEE-1394 Controller
2026 1028 00e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
2027 8029 PCI4510 IEEE-1394 Controller
2028 1028 0163 Latitude D505
2029 1071 8160 MIM2900
2030 802b PCI7410,7510,7610 OHCI-Lynx Controller
2031 1028 014e PCI7410,7510,7610 OHCI-Lynx Controller (Dell Latitude D800)
2032 802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
2033 8031 Texas Instruments PCIxx21/x515 Cardbus Controller
2034 8032 Texas Instruments OHCI Compliant IEEE 1394 Host Controller
2035 8033 Texas Instruments PCIxx21 Integrated FlashMedia Controller
2036 8034 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Secure Digital (SD) Controller
2037 8035 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Smart Card Controller (SMC)
2038 8201 PCI1620 Firmware Loading Function
2039 8204 PCI7410,7510,7610 PCI Firmware Loading Function
2040 1028 014e Latitude D800
2041 8400 ACX 100 22Mbps Wireless Interface
2042 00fc 16ec U.S. Robotics 22 Mbps Wireless PC Card (model 2210)
2043 00fd 16ec U.S. Robotics 22Mbps Wireless PCI Adapter (model 2216)
2044 1186 3b00 DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
2045 1186 3b01 DWL-520+ 22Mbps PCI Wireless Adapter
2046 8401 ACX 100 22Mbps Wireless Interface
2047# OK, this info is almost useless as is, but at least it's known that it's a wireless card. More info requested from reporter (whi
2048 9000 Wireless Interface (of unknown type)
2049 9066 ACX 111 54Mbps Wireless Interface
2050 a001 TDC1570
2051 a100 TDC1561
2052 a102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
2053 a106 TMS320C6205 Fixed Point DSP
2054 175c 5000 ASI50xx Audio Adapter
2055 175c 8700 ASI87xx Radio Tuner card
2056 ac10 PCI1050
2057 ac11 PCI1053
2058 ac12 PCI1130
2059 ac13 PCI1031
2060 ac15 PCI1131
2061 ac16 PCI1250
2062 1014 0092 ThinkPad 600
2063 ac17 PCI1220
2064 ac18 PCI1260
2065 ac19 PCI1221
2066 ac1a PCI1210
2067 ac1b PCI1450
2068 0e11 b113 Armada M700
2069 ac1c PCI1225
2070 0e11 b121 Armada E500
2071 1028 0088 Dell Computer Corporation Latitude CPi A400XT
2072 ac1d PCI1251A
2073 ac1e PCI1211
2074 ac1f PCI1251B
2075 ac20 TI 2030
2076 ac21 PCI2031
2077 ac22 PCI2032 PCI Docking Bridge
2078 ac23 PCI2250 PCI-to-PCI Bridge
2079 ac28 PCI2050 PCI-to-PCI Bridge
2080 ac30 PCI1260 PC card Cardbus Controller
2081 ac40 PCI4450 PC card Cardbus Controller
2082 ac41 PCI4410 PC card Cardbus Controller
2083 ac42 PCI4451 PC card Cardbus Controller
2084 1028 00e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
2085 ac44 PCI4510 PC card Cardbus Controller
2086 1028 0163 Latitude D505
2087 1071 8160 MIM2000
2088 ac46 PCI4520 PC card Cardbus Controller
2089 ac47 PCI7510 PC card Cardbus Controller
2090 1028 014e Latitude D800
2091 ac4a PCI7510,7610 PC card Cardbus Controller
2092 1028 014e Latitude D800
2093 ac50 PCI1410 PC card Cardbus Controller
2094 ac51 PCI1420
2095 1014 023b ThinkPad T23 (2647-4MG)
2096 1028 00b1 Latitude C600
2097 1028 012a Latitude C640
2098 1033 80cd Versa Note VXi
2099 10cf 1095 Lifebook C6155
2100 e4bf 1000 CP2-2-HIPHOP
2101 ac52 PCI1451 PC card Cardbus Controller
2102 ac53 PCI1421 PC card Cardbus Controller
2103 ac54 PCI1620 PC Card Controller
2104 ac55 PCI1520 PC card Cardbus Controller
2105 1014 0512 ThinkPad T30/T40
2106 ac56 PCI1510 PC card Cardbus Controller
2107 1014 0528 ThinkPad R40e (2684-HVG) Cardbus Controller
2108 ac60 PCI2040 PCI to DSP Bridge Controller
2109 175c 5100 ASI51xx Audio Adapter
2110 175c 6100 ASI61xx Audio Adapter
2111 175c 6200 ASI62xx Audio Adapter
2112 ac8d PCI 7620
2113 ac8e PCI7420 CardBus Controller
2114 ac8f PCI7420/PCI7620 Dual Socket CardBus and Smart Card Cont. w/ 1394a-2000 OHCI Two-Port PHY/Link-Layer Cont. and SD/MS-Pro Sockets
2115 fe00 FireWire Host Controller
2116 fe03 12C01A FireWire Host Controller
2117104d Sony Corporation
2118 8004 DTL-H2500 [Playstation development board]
2119 8009 CXD1947Q i.LINK Controller
2120 8039 CXD3222 i.LINK Controller
2121 8056 Rockwell HCF 56K modem
2122 808a Memory Stick Controller
2123104e Oak Technology, Inc
2124 0017 OTI-64017
2125 0107 OTI-107 [Spitfire]
2126 0109 Video Adapter
2127 0111 OTI-64111 [Spitfire]
2128 0217 OTI-64217
2129 0317 OTI-64317
2130104f Co-time Computer Ltd
21311050 Winbond Electronics Corp
2132 0000 NE2000
2133 0001 W83769F
2134 0105 W82C105
2135 0840 W89C840
2136 1050 0001 W89C840 Ethernet Adapter
2137 1050 0840 W89C840 Ethernet Adapter
2138 0940 W89C940
2139 5a5a W89C940F
2140 6692 W6692
2141 9921 W99200F MPEG-1 Video Encoder
2142 9922 W99200F/W9922PF MPEG-1/2 Video Encoder
2143 9970 W9970CF
21441051 Anigma, Inc.
21451052 ?Young Micro Systems
21461053 Young Micro Systems
21471054 Hitachi, Ltd
21481055 Efar Microsystems
2149 9130 SLC90E66 [Victory66] IDE
2150 9460 SLC90E66 [Victory66] ISA
2151 9462 SLC90E66 [Victory66] USB
2152 9463 SLC90E66 [Victory66] ACPI
21531056 ICL
2154# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
21551057 Motorola
2156 0001 MPC105 [Eagle]
2157 0002 MPC106 [Grackle]
2158 0003 MPC8240 [Kahlua]
2159 0004 MPC107
2160 0006 MPC8245 [Unity]
2161 0008 MPC8540
2162 0009 MPC8560
2163 0100 MC145575 [HFC-PCI]
2164 0431 KTI829c 100VG
2165 1801 DSP56301 Digital Signal Processor
2166 14fb 0101 Transas Radar Imitator Board [RIM]
2167 14fb 0102 Transas Radar Imitator Board [RIM-2]
2168 14fb 0202 Transas Radar Integrator Board [RIB-2]
2169 14fb 0611 1 channel CAN bus Controller [CanPci-1]
2170 14fb 0612 2 channels CAN bus Controller [CanPci-2]
2171 14fb 0613 3 channels CAN bus Controller [CanPci-3]
2172 14fb 0614 4 channels CAN bus Controller [CanPci-4]
2173 14fb 0621 1 channel CAN bus Controller [CanPci2-1]
2174 14fb 0622 2 channels CAN bus Controller [CanPci2-2]
2175 14fb 0810 Transas VTS Radar Integrator Board [RIB-4]
2176 175c 4200 ASI4215 Audio Adapter
2177 175c 4300 ASI43xx Audio Adapter
2178 175c 4400 ASI4401 Audio Adapter
2179 ecc0 0010 Darla
2180 ecc0 0020 Gina
2181 ecc0 0030 Layla rev.0
2182 ecc0 0031 Layla rev.1
2183 ecc0 0040 Darla24 rev.0
2184 ecc0 0041 Darla24 rev.1
2185 ecc0 0050 Gina24 rev.0
2186 ecc0 0051 Gina24 rev.1
2187 ecc0 0070 Mona rev.0
2188 ecc0 0071 Mona rev.1
2189 ecc0 0072 Mona rev.2
2190 18c0 MPC8265A/MPC8266
2191 18c1 MPC8271/MPC8272
2192 3410 DSP56361 Digital Signal Processor
2193 ecc0 0050 Gina24 rev.0
2194 ecc0 0051 Gina24 rev.1
2195 ecc0 0060 Layla24
2196 ecc0 0070 Mona rev.0
2197 ecc0 0071 Mona rev.1
2198 ecc0 0072 Mona rev.2
2199 ecc0 0080 Mia rev.0
2200 ecc0 0081 Mia rev.1
2201 ecc0 0090 Indigo
2202 ecc0 00a0 Indigo IO
2203 ecc0 00b0 Indigo DJ
2204 ecc0 0100 3G
2205 4801 Raven
2206 4802 Falcon
2207 4803 Hawk
2208 4806 CPX8216
2209 4d68 20268
2210 5600 SM56 PCI Modem
2211 1057 0300 SM56 PCI Speakerphone Modem
2212 1057 0301 SM56 PCI Voice Modem
2213 1057 0302 SM56 PCI Fax Modem
2214 1057 5600 SM56 PCI Voice modem
2215 13d2 0300 SM56 PCI Speakerphone Modem
2216 13d2 0301 SM56 PCI Voice modem
2217 13d2 0302 SM56 PCI Fax Modem
2218 1436 0300 SM56 PCI Speakerphone Modem
2219 1436 0301 SM56 PCI Voice modem
2220 1436 0302 SM56 PCI Fax Modem
2221 144f 100c SM56 PCI Fax Modem
2222 1494 0300 SM56 PCI Speakerphone Modem
2223 1494 0301 SM56 PCI Voice modem
2224 14c8 0300 SM56 PCI Speakerphone Modem
2225 14c8 0302 SM56 PCI Fax Modem
2226 1668 0300 SM56 PCI Speakerphone Modem
2227 1668 0302 SM56 PCI Fax Modem
2228 5803 MPC5200
2229 6400 MPC190 Security Processor (S1 family, encryption)
2230 6405 MPC184 Security Processor (S1 family)
22311058 Electronics & Telecommunications RSH
22321059 Teknor Industrial Computers Inc
2233105a Promise Technology, Inc.
2234# more correct description from promise linux sources
2235 0d30 PDC20265 (FastTrak100 Lite/Ultra100)
2236 105a 4d33 Ultra100
2237 0d38 20263
2238 105a 4d39 Fasttrak66
2239 1275 20275
2240 3318 PDC20318 (SATA150 TX4)
2241 3319 PDC20319 (FastTrak S150 TX4)
2242 8086 3427 S875WP1-E mainboard
2243 3371 PDC20371 (FastTrak S150 TX2plus)
2244 3373 PDC20378 (FastTrak 378/SATA 378)
2245 1043 80f5 K8V Deluxe/PC-DL Deluxe motherboard
2246 1462 702e K8T NEO FIS2R motherboard
2247 3375 PDC20375 (SATA150 TX2plus)
2248 3376 PDC20376 (FastTrak 376)
2249 1043 809e A7V8X motherboard
2250 3574 PDC20579 SATAII 150 IDE Controller
2251 3d18 PDC20518/PDC40518 (SATAII 150 TX4)
2252 3d75 PDC20575 (SATAII150 TX2plus)
2253 4d30 PDC20267 (FastTrak100/Ultra100)
2254 105a 4d33 Ultra100
2255 105a 4d39 FastTrak100
2256 4d33 20246
2257 105a 4d33 20246 IDE Controller
2258 4d38 PDC20262 (FastTrak66/Ultra66)
2259 105a 4d30 Ultra Device on SuperTrak
2260 105a 4d33 Ultra66
2261 105a 4d39 FastTrak66
2262 4d68 PDC20268 (Ultra100 TX2)
2263 105a 4d68 Ultra100TX2
2264 4d69 20269
2265 105a 4d68 Ultra133TX2
2266 5275 PDC20276 (MBFastTrak133 Lite)
2267 105a 0275 SuperTrak SX6000 IDE
2268 105a 1275 MBFastTrak133 Lite (tm) Controller (RAID mode)
2269 1458 b001 MBUltra 133
2270 5300 DC5300
2271 6268 PDC20270 (FastTrak100 LP/TX2/TX4)
2272 105a 4d68 FastTrak100 TX2
2273 6269 PDC20271 (FastTrak TX2000)
2274 105a 6269 FastTrak TX2/TX2000
2275 6621 PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
2276 6622 PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
2277 6626 PDC20618 (Ultra 618)
2278 6629 PDC20619 (FastTrak TX4000)
2279 7275 PDC20277 (SBFastTrak133 Lite)
2280105b Foxconn International, Inc.
2281105c Wipro Infotech Limited
2282105d Number 9 Computer Company
2283 2309 Imagine 128
2284 2339 Imagine 128-II
2285 105d 0000 Imagine 128 series 2 4Mb VRAM
2286 105d 0001 Imagine 128 series 2 4Mb VRAM
2287 105d 0002 Imagine 128 series 2 4Mb VRAM
2288 105d 0003 Imagine 128 series 2 4Mb VRAM
2289 105d 0004 Imagine 128 series 2 4Mb VRAM
2290 105d 0005 Imagine 128 series 2 4Mb VRAM
2291 105d 0006 Imagine 128 series 2 4Mb VRAM
2292 105d 0007 Imagine 128 series 2 4Mb VRAM
2293 105d 0008 Imagine 128 series 2e 4Mb DRAM
2294 105d 0009 Imagine 128 series 2e 4Mb DRAM
2295 105d 000a Imagine 128 series 2 8Mb VRAM
2296 105d 000b Imagine 128 series 2 8Mb H-VRAM
2297 11a4 000a Barco Metheus 5 Megapixel
2298 13cc 0000 Barco Metheus 5 Megapixel
2299 13cc 0004 Barco Metheus 5 Megapixel
2300 13cc 0005 Barco Metheus 5 Megapixel
2301 13cc 0006 Barco Metheus 5 Megapixel
2302 13cc 0008 Barco Metheus 5 Megapixel
2303 13cc 0009 Barco Metheus 5 Megapixel
2304 13cc 000a Barco Metheus 5 Megapixel
2305 13cc 000c Barco Metheus 5 Megapixel
2306 493d Imagine 128 T2R [Ticket to Ride]
2307 11a4 000a Barco Metheus 5 Megapixel, Dual Head
2308 11a4 000b Barco Metheus 5 Megapixel, Dual Head
2309 13cc 0002 Barco Metheus 4 Megapixel, Dual Head
2310 13cc 0003 Barco Metheus 5 Megapixel, Dual Head
2311 13cc 0007 Barco Metheus 5 Megapixel, Dual Head
2312 13cc 0008 Barco Metheus 5 Megapixel, Dual Head
2313 13cc 0009 Barco Metheus 5 Megapixel, Dual Head
2314 13cc 000a Barco Metheus 5 Megapixel, Dual Head
2315 5348 Revolution 4
2316 105d 0037 Revolution IV-FP AGP (For SGI 1600SW)
2317105e Vtech Computers Ltd
2318105f Infotronic America Inc
23191060 United Microelectronics [UMC]
2320 0001 UM82C881
2321 0002 UM82C886
2322 0101 UM8673F
2323 0881 UM8881
2324 0886 UM8886F
2325 0891 UM8891A
2326 1001 UM886A
2327 673a UM8886BF
2328 673b EIDE Master/DMA
2329 8710 UM8710
2330 886a UM8886A
2331 8881 UM8881F
2332 8886 UM8886F
2333 888a UM8886A
2334 8891 UM8891A
2335 9017 UM9017F
2336 9018 UM9018
2337 9026 UM9026
2338 e881 UM8881N
2339 e886 UM8886N
2340 e88a UM8886N
2341 e891 UM8891N
23421061 I.I.T.
2343 0001 AGX016
2344 0002 IIT3204/3501
23451062 Maspar Computer Corp
23461063 Ocean Office Automation
23471064 Alcatel
23481065 Texas Microsystems
23491066 PicoPower Technology
2350 0000 PT80C826
2351 0001 PT86C521 [Vesuvius v1] Host Bridge
2352 0002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
2353 0003 PT86C524 [Nile] PCI-to-PCI Bridge
2354 0004 PT86C525 [Nile-II] PCI-to-PCI Bridge
2355 0005 National PC87550 System Controller
2356 8002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
23571067 Mitsubishi Electric
2358 0301 AccelGraphics AccelECLIPSE
2359 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
2360 0308 Tornado 3000 [OEM Evans & Sutherland]
2361 1002 VG500 [VolumePro Volume Rendering Accelerator]
23621068 Diversified Technology
23631069 Mylex Corporation
2364 0001 DAC960P
2365 0002 DAC960PD
2366 0010 DAC960PG
2367 0020 DAC960LA
2368 0050 AcceleRAID 352/170/160 support Device
2369 b166 Gemstone chipset SCSI controller
2370 1014 0242 iSeries 2872 DASD IOA
2371 1014 0266 Dual Channel PCI-X U320 SCSI Adapter
2372 1014 0278 Dual Channel PCI-X U320 SCSI RAID Adapter
2373 1014 02d3 Dual Channel PCI-X U320 SCSI Adapter
2374 1014 02d4 Dual Channel PCI-X U320 SCSI RAID Adapter
2375 ba55 eXtremeRAID 1100 support Device
2376 ba56 eXtremeRAID 2000/3000 support Device
2377106a Aten Research Inc
2378106b Apple Computer Inc.
2379 0001 Bandit PowerPC host bridge
2380 0002 Grand Central I/O
2381 0003 Control Video
2382 0004 PlanB Video-In
2383 0007 O'Hare I/O
2384 000c DOS on Mac
2385 000e Hydra Mac I/O
2386 0010 Heathrow Mac I/O
2387 0017 Paddington Mac I/O
2388 0018 UniNorth FireWire
2389 0019 KeyLargo USB
2390 001e UniNorth Internal PCI
2391 001f UniNorth PCI
2392 0020 UniNorth AGP
2393 0021 UniNorth GMAC (Sun GEM)
2394 0022 KeyLargo Mac I/O
2395 0024 UniNorth/Pangea GMAC (Sun GEM)
2396 0025 KeyLargo/Pangea Mac I/O
2397 0026 KeyLargo/Pangea USB
2398 0027 UniNorth/Pangea AGP
2399 0028 UniNorth/Pangea PCI
2400 0029 UniNorth/Pangea Internal PCI
2401 002d UniNorth 1.5 AGP
2402 002e UniNorth 1.5 PCI
2403 002f UniNorth 1.5 Internal PCI
2404 0030 UniNorth/Pangea FireWire
2405 0031 UniNorth 2 FireWire
2406 0032 UniNorth 2 GMAC (Sun GEM)
2407 0033 UniNorth 2 ATA/100
2408 0034 UniNorth 2 AGP
2409 0035 UniNorth 2 PCI
2410 0036 UniNorth 2 Internal PCI
2411 003b UniNorth/Intrepid ATA/100
2412 003e KeyLargo/Intrepid Mac I/O
2413 003f KeyLargo/Intrepid USB
2414 0040 K2 KeyLargo USB
2415 0041 K2 KeyLargo Mac/IO
2416 0042 K2 FireWire
2417 0043 K2 ATA/100
2418 0045 K2 HT-PCI Bridge
2419 0046 K2 HT-PCI Bridge
2420 0047 K2 HT-PCI Bridge
2421 0048 K2 HT-PCI Bridge
2422 0049 K2 HT-PCI Bridge
2423 004b U3 AGP
2424 004c K2 GMAC (Sun GEM)
2425 004f Shasta Mac I/O
2426 0050 Shasta IDE
2427 0051 Shasta (Sun GEM)
2428 0052 Shasta Firewire
2429 0053 Shasta PCI Bridge
2430 0054 Shasta PCI Bridge
2431 0055 Shasta PCI Bridge
2432 0058 U3L AGP Bridge
2433 1645 Tigon3 Gigabit Ethernet NIC (BCM5701)
2434106c Hynix Semiconductor
2435 8801 Dual Pentium ISA/PCI Motherboard
2436 8802 PowerPC ISA/PCI Motherboard
2437 8803 Dual Window Graphics Accelerator
2438 8804 LAN Controller
2439 8805 100-BaseT LAN
2440106d Sequent Computer Systems
2441106e DFI, Inc
2442106f City Gate Development Ltd
24431070 Daewoo Telecom Ltd
24441071 Mitac
2445 8160 Mitac 8060B Mobile Platform
24461072 GIT Co Ltd
24471073 Yamaha Corporation
2448 0001 3D GUI Accelerator
2449 0002 YGV615 [RPA3 3D-Graphics Controller]
2450 0003 YMF-740
2451 0004 YMF-724
2452 1073 0004 YMF724-Based PCI Audio Adapter
2453 0005 DS1 Audio
2454 1073 0005 DS-XG PCI Audio CODEC
2455 0006 DS1 Audio
2456 0008 DS1 Audio
2457 1073 0008 DS-XG PCI Audio CODEC
2458 000a DS1L Audio
2459 1073 0004 DS-XG PCI Audio CODEC
2460 1073 000a DS-XG PCI Audio CODEC
2461 000c YMF-740C [DS-1L Audio Controller]
2462 107a 000c DS-XG PCI Audio CODEC
2463 000d YMF-724F [DS-1 Audio Controller]
2464 1073 000d DS-XG PCI Audio CODEC
2465 0010 YMF-744B [DS-1S Audio Controller]
2466 1073 0006 DS-XG PCI Audio CODEC
2467 1073 0010 DS-XG PCI Audio CODEC
2468 0012 YMF-754 [DS-1E Audio Controller]
2469 1073 0012 DS-XG PCI Audio Codec
2470 0020 DS-1 Audio
2471 2000 DS2416 Digital Mixing Card
2472 1073 2000 DS2416 Digital Mixing Card
24731074 NexGen Microsystems
2474 4e78 82c500/1
24751075 Advanced Integrations Research
24761076 Chaintech Computer Co. Ltd
24771077 QLogic Corp.
2478 1016 ISP10160 Single Channel Ultra3 SCSI Processor
2479 1020 ISP1020 Fast-wide SCSI
2480 1022 ISP1022 Fast-wide SCSI
2481 1080 ISP1080 SCSI Host Adapter
2482 1216 ISP12160 Dual Channel Ultra3 SCSI Processor
2483 101e 8471 QLA12160 on AMI MegaRAID
2484 101e 8493 QLA12160 on AMI MegaRAID
2485 1240 ISP1240 SCSI Host Adapter
2486 1280 ISP1280 SCSI Host Adapter
2487 2020 ISP2020A Fast!SCSI Basic Adapter
2488 2100 QLA2100 64-bit Fibre Channel Adapter
2489 1077 0001 QLA2100 64-bit Fibre Channel Adapter
2490 2200 QLA2200 64-bit Fibre Channel Adapter
2491 1077 0002 QLA2200
2492 2300 QLA2300 64-bit Fibre Channel Adapter
2493 2312 QLA2312 Fibre Channel Adapter
24941078 Cyrix Corporation
2495 0000 5510 [Grappa]
2496 0001 PCI Master
2497 0002 5520 [Cognac]
2498 0100 5530 Legacy [Kahlua]
2499 0101 5530 SMI [Kahlua]
2500 0102 5530 IDE [Kahlua]
2501 0103 5530 Audio [Kahlua]
2502 0104 5530 Video [Kahlua]
2503 0400 ZFMicro PCI Bridge
2504 0401 ZFMicro Chipset SMI
2505 0402 ZFMicro Chipset IDE
2506 0403 ZFMicro Expansion Bus
25071079 I-Bus
2508107a NetWorth
2509107b Gateway 2000
2510107c LG Electronics [Lucky Goldstar Co. Ltd]
2511107d LeadTek Research Inc.
2512 0000 P86C850
2513 2134 WinFast 3D S320 II
2514 2971 [GeForce FX 5900] WinFast A350 TDH MyViVo
2515107e Interphase Corporation
2516 0001 5515 ATM Adapter [Flipper]
2517 0002 100 VG AnyLan Controller
2518 0004 5526 Fibre Channel Host Adapter
2519 0005 x526 Fibre Channel Host Adapter
2520 0008 5525/5575 ATM Adapter (155 Mbit) [Atlantic]
2521 9003 5535-4P-BRI-ST
2522 9007 5535-4P-BRI-U
2523 9008 5535-1P-SR
2524 900c 5535-1P-SR-ST
2525 900e 5535-1P-SR-U
2526 9011 5535-1P-PRI
2527 9013 5535-2P-PRI
2528 9023 5536-4P-BRI-ST
2529 9027 5536-4P-BRI-U
2530 9031 5536-1P-PRI
2531 9033 5536-2P-PRI
2532107f Data Technology Corporation
2533 0802 SL82C105
25341080 Contaq Microsystems
2535 0600 82C599
2536 c691 Cypress CY82C691
2537 c693 82c693
25381081 Supermac Technology
2539 0d47 Radius PCI to NuBUS Bridge
25401082 EFA Corporation of America
25411083 Forex Computer Corporation
2542 0001 FR710
25431084 Parador
25441085 Tulip Computers Int.B.V.
25451086 J. Bond Computer Systems
25461087 Cache Computer
25471088 Microcomputer Systems (M) Son
25481089 Data General Corporation
2549# Formerly Bit3 Computer Corp.
2550108a SBS Technologies
2551 0001 VME Bridge Model 617
2552 0010 VME Bridge Model 618
2553 0040 dataBLIZZARD
2554 3000 VME Bridge Model 2706
2555108c Oakleigh Systems Inc.
2556108d Olicom
2557 0001 Token-Ring 16/4 PCI Adapter (3136/3137)
2558 0002 16/4 Token Ring
2559 0004 RapidFire 3139 Token-Ring 16/4 PCI Adapter
2560 108d 0004 OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
2561 0005 GoCard 3250 Token-Ring 16/4 CardBus PC Card
2562 0006 OC-3530 RapidFire Token-Ring 100
2563 0007 RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
2564 108d 0007 OC-3141 RapidFire Token-Ring 16/4 Adapter
2565 0008 RapidFire 3540 HSTR 100/16/4 PCI Adapter
2566 108d 0008 OC-3540 RapidFire HSTR 100/16/4 Adapter
2567 0011 OC-2315
2568 0012 OC-2325
2569 0013 OC-2183/2185
2570 0014 OC-2326
2571 0019 OC-2327/2250 10/100 Ethernet Adapter
2572 108d 0016 OC-2327 Rapidfire 10/100 Ethernet Adapter
2573 108d 0017 OC-2250 GoCard 10/100 Ethernet Adapter
2574 0021 OC-6151/6152 [RapidFire ATM 155]
2575 0022 ATM Adapter
2576108e Sun Microsystems Computer Corp.
2577 0001 EBUS
2578 1000 EBUS
2579 1001 Happy Meal
2580 1100 RIO EBUS
2581 1101 RIO GEM
2582 1102 RIO 1394
2583 1103 RIO USB
2584 1648 [bge] Gigabit Ethernet
2585 2bad GEM
2586 5000 Simba Advanced PCI Bridge
2587 5043 SunPCI Co-processor
2588 8000 Psycho PCI Bus Module
2589 8001 Schizo PCI Bus Module
2590 8002 Schizo+ PCI Bus Module
2591 a000 Ultra IIi
2592 a001 Ultra IIe
2593 a801 Tomatillo PCI Bus Module
2594 abba Cassini 10/100/1000
2595108f Systemsoft
25961090 Encore Computer Corporation
25971091 Intergraph Corporation
2598 0020 3D graphics processor
2599 0021 3D graphics processor w/Texturing
2600 0040 3D graphics frame buffer
2601 0041 3D graphics frame buffer
2602 0060 Proprietary bus bridge
2603 00e4 Powerstorm 4D50T
2604 0720 Motion JPEG codec
2605 07a0 Sun Expert3D-Lite Graphics Accelerator
2606 1091 Sun Expert3D Graphics Accelerator
26071092 Diamond Multimedia Systems
2608 00a0 Speedstar Pro SE
2609 00a8 Speedstar 64
2610 0550 Viper V550
2611 08d4 Supra 2260 Modem
2612 094c SupraExpress 56i Pro
2613 1092 Viper V330
2614 6120 Maximum DVD
2615 8810 Stealth SE
2616 8811 Stealth 64/SE
2617 8880 Stealth
2618 8881 Stealth
2619 88b0 Stealth 64
2620 88b1 Stealth 64
2621 88c0 Stealth 64
2622 88c1 Stealth 64
2623 88d0 Stealth 64
2624 88d1 Stealth 64
2625 88f0 Stealth 64
2626 88f1 Stealth 64
2627 9999 DMD-I0928-1 "Monster sound" sound chip
26281093 National Instruments
2629 0160 PCI-DIO-96
2630 0162 PCI-MIO-16XE-50
2631 1170 PCI-MIO-16XE-10
2632 1180 PCI-MIO-16E-1
2633 1190 PCI-MIO-16E-4
2634 1310 PCI-6602
2635 1330 PCI-6031E
2636 1350 PCI-6071E
2637 14e0 PCI-6110
2638 14f0 PCI-6111
2639 17d0 PCI-6503
2640 1870 PCI-6713
2641 1880 PCI-6711
2642 18b0 PCI-6052E
2643 2410 PCI-6733
2644 2890 PCI-6036E
2645 2a60 PCI-6023E
2646 2a70 PCI-6024E
2647 2a80 PCI-6025E
2648 2c80 PCI-6035E
2649 2ca0 PCI-6034E
2650 70b8 PCI-6251 [M Series - High Speed Multifunction DAQ]
2651 b001 IMAQ-PCI-1408
2652 b011 IMAQ-PXI-1408
2653 b021 IMAQ-PCI-1424
2654 b031 IMAQ-PCI-1413
2655 b041 IMAQ-PCI-1407
2656 b051 IMAQ-PXI-1407
2657 b061 IMAQ-PCI-1411
2658 b071 IMAQ-PCI-1422
2659 b081 IMAQ-PXI-1422
2660 b091 IMAQ-PXI-1411
2661 c801 PCI-GPIB
2662 c831 PCI-GPIB bridge
26631094 First International Computers [FIC]
26641095 Silicon Image, Inc. (formerly CMD Technology Inc)
2665 0240 Adaptec AAR-1210SA SATA HostRAID Controller
2666 0640 PCI0640
2667 0643 PCI0643
2668 0646 PCI0646
2669 0647 PCI0647
2670 0648 PCI0648
2671 0649 SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
2672 0e11 005d Integrated Ultra ATA-100 Dual Channel Controller
2673 0e11 007e Integrated Ultra ATA-100 IDE RAID Controller
2674 101e 0649 AMI MegaRAID IDE 100 Controller
2675 0650 PBC0650A
2676 0670 USB0670
2677 1095 0670 USB0670
2678 0673 USB0673
2679 0680 PCI0680 Ultra ATA-133 Host Controller
2680 1095 3680 Winic W-680 (Silicon Image 680 based)
2681 3112 SiI 3112 [SATALink/SATARaid] Serial ATA Controller
2682 1095 3112 SiI 3112 SATALink Controller
2683 1095 6112 SiI 3112 SATARaid Controller
2684 3114 SiI 3114 [SATALink/SATARaid] Serial ATA Controller
2685 1095 3114 SiI 3114 SATALink Controller
2686 1095 6114 SiI 3114 SATARaid Controller
2687 3124 SiI 3124 PCI-X Serial ATA Controller
2688 1095 3124 SiI 3124 PCI-X Serial ATA Controller
2689 3512 SiI 3512 [SATALink/SATARaid] Serial ATA Controller
2690 1095 3512 SiI 3512 SATALink Controller
2691 1095 6512 SiI 3512 SATARaid Controller
26921096 Alacron
26931097 Appian Technology
26941098 Quantum Designs (H.K.) Ltd
2695 0001 QD-8500
2696 0002 QD-8580
26971099 Samsung Electronics Co., Ltd
2698109a Packard Bell
2699109b Gemlight Computer Ltd.
2700109c Megachips Corporation
2701109d Zida Technologies Ltd.
2702109e Brooktree Corporation
2703 0350 Bt848 Video Capture
2704 0351 Bt849A Video capture
2705 0369 Bt878 Video Capture
2706 1002 0001 TV-Wonder
2707 1002 0003 TV-Wonder/VE
2708 036c Bt879(??) Video Capture
2709 13e9 0070 Win/TV (Video Section)
2710 036e Bt878 Video Capture
2711 0070 13eb WinTV Series
2712 0070 ff01 Viewcast Osprey 200
2713 0071 0101 DigiTV PCI
2714 107d 6606 WinFast TV 2000
2715 11bd 0012 PCTV pro (TV + FM stereo receiver)
2716 11bd 001c PCTV Sat (DBC receiver)
2717 127a 0001 Bt878 Mediastream Controller NTSC
2718 127a 0002 Bt878 Mediastream Controller PAL BG
2719 127a 0003 Bt878a Mediastream Controller PAL BG
2720 127a 0048 Bt878/832 Mediastream Controller
2721 144f 3000 MagicTView CPH060 - Video
2722 1461 0002 TV98 Series (TV/No FM/Remote)
2723 1461 0003 AverMedia UltraTV PCI 350
2724 1461 0004 AVerTV WDM Video Capture
2725 1461 0761 AverTV DVB-T
2726 14f1 0001 Bt878 Mediastream Controller NTSC
2727 14f1 0002 Bt878 Mediastream Controller PAL BG
2728 14f1 0003 Bt878a Mediastream Controller PAL BG
2729 14f1 0048 Bt878/832 Mediastream Controller
2730 1822 0001 VisionPlus DVB card
2731 1851 1850 FlyVideo'98 - Video
2732 1851 1851 FlyVideo II
2733 1852 1852 FlyVideo'98 - Video (with FM Tuner)
2734 270f fc00 Digitop DTT-1000
2735 bd11 1200 PCTV pro (TV + FM stereo receiver)
2736 036f Bt879 Video Capture
2737 127a 0044 Bt879 Video Capture NTSC
2738 127a 0122 Bt879 Video Capture PAL I
2739 127a 0144 Bt879 Video Capture NTSC
2740 127a 0222 Bt879 Video Capture PAL BG
2741 127a 0244 Bt879a Video Capture NTSC
2742 127a 0322 Bt879 Video Capture NTSC
2743 127a 0422 Bt879 Video Capture NTSC
2744 127a 1122 Bt879 Video Capture PAL I
2745 127a 1222 Bt879 Video Capture PAL BG
2746 127a 1322 Bt879 Video Capture NTSC
2747 127a 1522 Bt879a Video Capture PAL I
2748 127a 1622 Bt879a Video Capture PAL BG
2749 127a 1722 Bt879a Video Capture NTSC
2750 14f1 0044 Bt879 Video Capture NTSC
2751 14f1 0122 Bt879 Video Capture PAL I
2752 14f1 0144 Bt879 Video Capture NTSC
2753 14f1 0222 Bt879 Video Capture PAL BG
2754 14f1 0244 Bt879a Video Capture NTSC
2755 14f1 0322 Bt879 Video Capture NTSC
2756 14f1 0422 Bt879 Video Capture NTSC
2757 14f1 1122 Bt879 Video Capture PAL I
2758 14f1 1222 Bt879 Video Capture PAL BG
2759 14f1 1322 Bt879 Video Capture NTSC
2760 14f1 1522 Bt879a Video Capture PAL I
2761 14f1 1622 Bt879a Video Capture PAL BG
2762 14f1 1722 Bt879a Video Capture NTSC
2763 1851 1850 FlyVideo'98 - Video
2764 1851 1851 FlyVideo II
2765 1852 1852 FlyVideo'98 - Video (with FM Tuner)
2766 0370 Bt880 Video Capture
2767 1851 1850 FlyVideo'98
2768 1851 1851 FlyVideo'98 EZ - video
2769 1852 1852 FlyVideo'98 (with FM Tuner)
2770 0878 Bt878 Audio Capture
2771 0070 13eb WinTV Series
2772 0070 ff01 Viewcast Osprey 200
2773 0071 0101 DigiTV PCI
2774 1002 0001 TV-Wonder
2775 1002 0003 TV-Wonder/VE
2776 11bd 0012 PCTV pro (TV + FM stereo receiver, audio section)
2777 11bd 001c PCTV Sat (DBC receiver)
2778 127a 0001 Bt878 Video Capture (Audio Section)
2779 127a 0002 Bt878 Video Capture (Audio Section)
2780 127a 0003 Bt878 Video Capture (Audio Section)
2781 127a 0048 Bt878 Video Capture (Audio Section)
2782 13e9 0070 Win/TV (Audio Section)
2783 144f 3000 MagicTView CPH060 - Audio
2784 1461 0004 AVerTV WDM Audio Capture
2785 1461 0761 AVerTV DVB-T
2786 14f1 0001 Bt878 Video Capture (Audio Section)
2787 14f1 0002 Bt878 Video Capture (Audio Section)
2788 14f1 0003 Bt878 Video Capture (Audio Section)
2789 14f1 0048 Bt878 Video Capture (Audio Section)
2790 1822 0001 VisionPlus DVB Card
2791 270f fc00 Digitop DTT-1000
2792 bd11 1200 PCTV pro (TV + FM stereo receiver, audio section)
2793 0879 Bt879 Audio Capture
2794 127a 0044 Bt879 Video Capture (Audio Section)
2795 127a 0122 Bt879 Video Capture (Audio Section)
2796 127a 0144 Bt879 Video Capture (Audio Section)
2797 127a 0222 Bt879 Video Capture (Audio Section)
2798 127a 0244 Bt879 Video Capture (Audio Section)
2799 127a 0322 Bt879 Video Capture (Audio Section)
2800 127a 0422 Bt879 Video Capture (Audio Section)
2801 127a 1122 Bt879 Video Capture (Audio Section)
2802 127a 1222 Bt879 Video Capture (Audio Section)
2803 127a 1322 Bt879 Video Capture (Audio Section)
2804 127a 1522 Bt879 Video Capture (Audio Section)
2805 127a 1622 Bt879 Video Capture (Audio Section)
2806 127a 1722 Bt879 Video Capture (Audio Section)
2807 14f1 0044 Bt879 Video Capture (Audio Section)
2808 14f1 0122 Bt879 Video Capture (Audio Section)
2809 14f1 0144 Bt879 Video Capture (Audio Section)
2810 14f1 0222 Bt879 Video Capture (Audio Section)
2811 14f1 0244 Bt879 Video Capture (Audio Section)
2812 14f1 0322 Bt879 Video Capture (Audio Section)
2813 14f1 0422 Bt879 Video Capture (Audio Section)
2814 14f1 1122 Bt879 Video Capture (Audio Section)
2815 14f1 1222 Bt879 Video Capture (Audio Section)
2816 14f1 1322 Bt879 Video Capture (Audio Section)
2817 14f1 1522 Bt879 Video Capture (Audio Section)
2818 14f1 1622 Bt879 Video Capture (Audio Section)
2819 14f1 1722 Bt879 Video Capture (Audio Section)
2820 0880 Bt880 Audio Capture
2821 2115 BtV 2115 Mediastream controller
2822 2125 BtV 2125 Mediastream controller
2823 2164 BtV 2164
2824 2165 BtV 2165
2825 8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
2826 8472 Bt8472
2827 8474 Bt8474
2828109f Trigem Computer Inc.
282910a0 Meidensha Corporation
283010a1 Juko Electronics Ind. Co. Ltd
283110a2 Quantum Corporation
283210a3 Everex Systems Inc
283310a4 Globe Manufacturing Sales
283410a5 Smart Link Ltd.
2835 3052 SmartPCI562 56K Modem
2836 5449 SmartPCI561 modem
283710a6 Informtech Industrial Ltd.
283810a7 Benchmarq Microelectronics
283910a8 Sierra Semiconductor
2840 0000 STB Horizon 64
284110a9 Silicon Graphics, Inc.
2842 0001 Crosstalk to PCI Bridge
2843 0002 Linc I/O controller
2844 0003 IOC3 I/O controller
2845 0004 O2 MACE
2846 0005 RAD Audio
2847 0006 HPCEX
2848 0007 RPCEX
2849 0008 DiVO VIP
2850 0009 AceNIC Gigabit Ethernet
2851 10a9 8002 AceNIC Gigabit Ethernet
2852 0010 AMP Video I/O
2853 0011 GRIP
2854 0012 SGH PSHAC GSN
2855 1001 Magic Carpet
2856 1002 Lithium
2857 1003 Dual JPEG 1
2858 1004 Dual JPEG 2
2859 1005 Dual JPEG 3
2860 1006 Dual JPEG 4
2861 1007 Dual JPEG 5
2862 1008 Cesium
2863 100a IOC4 I/O controller
2864 2001 Fibre Channel
2865 2002 ASDE
2866 8001 O2 1394
2867 8002 G-net NT
286810aa ACC Microelectronics
2869 0000 ACCM 2188
287010ab Digicom
287110ac Honeywell IAC
287210ad Symphony Labs
2873 0001 W83769F
2874 0003 SL82C103
2875 0005 SL82C105
2876 0103 SL82c103
2877 0105 SL82c105
2878 0565 W83C553
287910ae Cornerstone Technology
288010af Micro Computer Systems Inc
288110b0 CardExpert Technology
288210b1 Cabletron Systems Inc
288310b2 Raytheon Company
288410b3 Databook Inc
2885 3106 DB87144
2886 b106 DB87144
288710b4 STB Systems Inc
2888 1b1d Velocity 128 3D
2889 10b4 237e Velocity 4400
289010b5 PLX Technology, Inc.
2891 0001 i960 PCI bus interface
2892 1076 VScom 800 8 port serial adaptor
2893 1077 VScom 400 4 port serial adaptor
2894 1078 VScom 210 2 port serial and 1 port parallel adaptor
2895 1103 VScom 200 2 port serial adaptor
2896 1146 VScom 010 1 port parallel adaptor
2897 1147 VScom 020 2 port parallel adaptor
2898 2724 Thales PCSM Security Card
2899 8516 PEX 8516 Versatile PCI Express Switch
2900 8532 PEX 8532 Versatile PCI Express Switch
2901 9030 PCI <-> IOBus Bridge Hot Swap
2902 10b5 2862 Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
2903 10b5 2906 Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
2904 10b5 2940 Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
2905 10b5 3025 Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
2906 10b5 3068 Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
2907 15ed 1002 MCCS 8-port Serial Hot Swap
2908 15ed 1003 MCCS 16-port Serial Hot Swap
2909 9036 9036
2910 9050 PCI <-> IOBus Bridge
2911 10b5 1067 IXXAT CAN i165
2912 10b5 1172 IK220 (Heidenhain)
2913 10b5 2036 SatPak GPS
2914 10b5 2221 Alpermann+Velte PCL PCI LV: Timecode Reader Board
2915 10b5 2273 SH-ARC SoHard ARCnet card
2916 10b5 2431 Alpermann+Velte PCL PCI D: Timecode Reader Board
2917 10b5 2905 Alpermann+Velte PCI TS: Time Synchronisation Board
2918 10b5 9050 MP9050
2919 1498 0362 TPMC866 8 Channel Serial Card
2920 1522 0001 RockForce 4 Port V.90 Data/Fax/Voice Modem
2921 1522 0002 RockForce 2 Port V.90 Data/Fax/Voice Modem
2922 1522 0003 RockForce 6 Port V.90 Data/Fax/Voice Modem
2923 1522 0004 RockForce 8 Port V.90 Data/Fax/Voice Modem
2924 1522 0010 RockForce2000 4 Port V.90 Data/Fax/Voice Modem
2925 1522 0020 RockForce2000 2 Port V.90 Data/Fax/Voice Modem
2926 15ed 1000 Macrolink MCCS 8-port Serial
2927 15ed 1001 Macrolink MCCS 16-port Serial
2928 15ed 1002 Macrolink MCCS 8-port Serial Hot Swap
2929 15ed 1003 Macrolink MCCS 16-port Serial Hot Swap
2930# Sorry, there was a typo
2931 5654 2036 OpenSwitch 6 Telephony card
2932# Sorry, there was a typo
2933 5654 3132 OpenSwitch 12 Telephony card
2934 5654 5634 OpenLine4 Telephony Card
2935 d531 c002 PCIntelliCAN 2xSJA1000 CAN bus
2936 d84d 4006 EX-4006 1P
2937 d84d 4008 EX-4008 1P EPP/ECP
2938 d84d 4014 EX-4014 2P
2939 d84d 4018 EX-4018 3P EPP/ECP
2940 d84d 4025 EX-4025 1S(16C550) RS-232
2941 d84d 4027 EX-4027 1S(16C650) RS-232
2942 d84d 4028 EX-4028 1S(16C850) RS-232
2943 d84d 4036 EX-4036 2S(16C650) RS-232
2944 d84d 4037 EX-4037 2S(16C650) RS-232
2945 d84d 4038 EX-4038 2S(16C850) RS-232
2946 d84d 4052 EX-4052 1S(16C550) RS-422/485
2947 d84d 4053 EX-4053 2S(16C550) RS-422/485
2948 d84d 4055 EX-4055 4S(16C550) RS-232
2949 d84d 4058 EX-4055 4S(16C650) RS-232
2950 d84d 4065 EX-4065 8S(16C550) RS-232
2951 d84d 4068 EX-4068 8S(16C650) RS-232
2952 d84d 4078 EX-4078 2S(16C552) RS-232+1P
2953 9054 PCI <-> IOBus Bridge
2954 10b5 2455 Wessex Techology PHIL-PCI
2955 10b5 2696 Innes Corp AM Radcap card
2956 10b5 2717 Innes Corp Auricon card
2957 10b5 2844 Innes Corp TVS Encoder card
2958 12d9 0002 PCI Prosody Card rev 1.5
2959 16df 0011 PIKA PrimeNet MM PCI
2960 16df 0012 PIKA PrimeNet MM cPCI 8
2961 16df 0013 PIKA PrimeNet MM cPCI 8 (without CAS Signaling Option)
2962 16df 0014 PIKA PrimeNet MM cPCI 4
2963 16df 0015 PIKA Daytona MM
2964 16df 0016 PIKA InLine MM
2965 9056 Francois
2966 10b5 2979 CellinkBlade 11 - CPCI board VoATM AAL1
2967 9060 9060
2968 906d 9060SD
2969 125c 0640 Aries 16000P
2970 906e 9060ES
2971 9080 9080
2972 103c 10eb (Agilent) E2777B 83K Series PCI based Optical Communication Interface
2973 103c 10ec (Agilent) E6978-66442 PCI CIC
2974 10b5 9080 9080 [real subsystem ID not set]
2975 129d 0002 Aculab PCI Prosidy card
2976 12d9 0002 PCI Prosody Card
2977 12df 4422 4422PCI ["Do-All" Telemetry Data Aquisition System]
2978 bb04 B&B 3PCIOSD1A Isolated PCI Serial
297910b6 Madge Networks
2980 0001 Smart 16/4 PCI Ringnode
2981 0002 Smart 16/4 PCI Ringnode Mk2
2982 10b6 0002 Smart 16/4 PCI Ringnode Mk2
2983 10b6 0006 16/4 CardBus Adapter
2984 0003 Smart 16/4 PCI Ringnode Mk3
2985 0e11 b0fd Compaq NC4621 PCI, 4/16, WOL
2986 10b6 0003 Smart 16/4 PCI Ringnode Mk3
2987 10b6 0007 Presto PCI Plus Adapter
2988 0004 Smart 16/4 PCI Ringnode Mk1
2989 0006 16/4 Cardbus Adapter
2990 10b6 0006 16/4 CardBus Adapter
2991 0007 Presto PCI Adapter
2992 10b6 0007 Presto PCI
2993 0009 Smart 100/16/4 PCI-HS Ringnode
2994 10b6 0009 Smart 100/16/4 PCI-HS Ringnode
2995 000a Smart 100/16/4 PCI Ringnode
2996 10b6 000a Smart 100/16/4 PCI Ringnode
2997 000b 16/4 CardBus Adapter Mk2
2998 10b6 0008 16/4 CardBus Adapter Mk2
2999 10b6 000b 16/4 Cardbus Adapter Mk2
3000 000c RapidFire 3140V2 16/4 TR Adapter
3001 10b6 000c RapidFire 3140V2 16/4 TR Adapter
3002 1000 Collage 25/155 ATM Client Adapter
3003 1001 Collage 155 ATM Server Adapter
300410b7 3Com Corporation
3005 0001 3c985 1000BaseSX (SX/TX)
3006 0013 AR5212 802.11abg NIC (3CRDAG675)
3007 10b7 2031 3CRDAG675 11a/b/g Wireless PCI Adapter
3008 0910 3C910-A01
3009 1006 MINI PCI type 3B Data Fax Modem
3010 1007 Mini PCI 56k Winmodem
3011 10b7 615c Mini PCI 56K Modem
3012 1201 3c982-TXM 10/100baseTX Dual Port A [Hydra]
3013 1202 3c982-TXM 10/100baseTX Dual Port B [Hydra]
3014 1700 3c940 10/100/1000Base-T [Marvell]
3015 1043 80eb P4P800/K8V Deluxe motherboard
3016 10b7 0010 3C940 Gigabit LOM Ethernet Adapter
3017 10b7 0020 3C941 Gigabit LOM Ethernet Adapter
3018 147b 1407 KV8-MAX3 motherboard
3019 3390 3c339 TokenLink Velocity
3020 3590 3c359 TokenLink Velocity XL
3021 10b7 3590 TokenLink Velocity XL Adapter (3C359/359B)
3022 4500 3c450 HomePNA [Tornado]
3023 5055 3c555 Laptop Hurricane
3024 5057 3c575 Megahertz 10/100 LAN CardBus [Boomerang]
3025 10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3026 5157 3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
3027 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3028 5257 3cCFE575CT CardBus [Cyclone]
3029 10b7 5c57 FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
3030 5900 3c590 10BaseT [Vortex]
3031 5920 3c592 EISA 10mbps Demon/Vortex
3032 5950 3c595 100BaseTX [Vortex]
3033 5951 3c595 100BaseT4 [Vortex]
3034 5952 3c595 100Base-MII [Vortex]
3035 5970 3c597 EISA Fast Demon/Vortex
3036 5b57 3c595 Megahertz 10/100 LAN CardBus [Boomerang]
3037 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3038 6000 3CRSHPW796 [OfficeConnect Wireless CardBus]
3039 6001 3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
3040 6055 3c556 Hurricane CardBus [Cyclone]
3041 6056 3c556B CardBus [Tornado]
3042 10b7 6556 10/100 Mini PCI Ethernet Adapter
3043 6560 3cCFE656 CardBus [Cyclone]
3044 10b7 656a 3CCFEM656 10/100 LAN+56K Modem CardBus
3045 6561 3cCFEM656 10/100 LAN+56K Modem CardBus
3046 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
3047 6562 3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
3048 10b7 656b 3CCFEM656B 10/100 LAN+56K Modem CardBus
3049 6563 3cCFEM656B 10/100 LAN+56K Modem CardBus
3050 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
3051 6564 3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
3052 7646 3cSOHO100-TX Hurricane
3053 7770 3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
3054 7940 3c803 FDDILink UTP Controller
3055 7980 3c804 FDDILink SAS Controller
3056 7990 3c805 FDDILink DAS Controller
3057 80eb 3c940B 10/100/1000Base-T
3058 8811 Token ring
3059 9000 3c900 10BaseT [Boomerang]
3060 9001 3c900 10Mbps Combo [Boomerang]
3061 9004 3c900B-TPO Etherlink XL [Cyclone]
3062 10b7 9004 3C900B-TPO Etherlink XL TPO 10Mb
3063 9005 3c900B-Combo Etherlink XL [Cyclone]
3064 10b7 9005 3C900B-Combo Etherlink XL Combo
3065 9006 3c900B-TPC Etherlink XL [Cyclone]
3066 900a 3c900B-FL 10base-FL [Cyclone]
3067 9050 3c905 100BaseTX [Boomerang]
3068 9051 3c905 100BaseT4 [Boomerang]
3069 9055 3c905B 100BaseTX [Cyclone]
3070 1028 0080 3C905B Fast Etherlink XL 10/100
3071 1028 0081 3C905B Fast Etherlink XL 10/100
3072 1028 0082 3C905B Fast Etherlink XL 10/100
3073 1028 0083 3C905B Fast Etherlink XL 10/100
3074 1028 0084 3C905B Fast Etherlink XL 10/100
3075 1028 0085 3C905B Fast Etherlink XL 10/100
3076 1028 0086 3C905B Fast Etherlink XL 10/100
3077 1028 0087 3C905B Fast Etherlink XL 10/100
3078 1028 0088 3C905B Fast Etherlink XL 10/100
3079 1028 0089 3C905B Fast Etherlink XL 10/100
3080 1028 0090 3C905B Fast Etherlink XL 10/100
3081 1028 0091 3C905B Fast Etherlink XL 10/100
3082 1028 0092 3C905B Fast Etherlink XL 10/100
3083 1028 0093 3C905B Fast Etherlink XL 10/100
3084 1028 0094 3C905B Fast Etherlink XL 10/100
3085 1028 0095 3C905B Fast Etherlink XL 10/100
3086 1028 0096 3C905B Fast Etherlink XL 10/100
3087 1028 0097 3C905B Fast Etherlink XL 10/100
3088 1028 0098 3C905B Fast Etherlink XL 10/100
3089 1028 0099 3C905B Fast Etherlink XL 10/100
3090 10b7 9055 3C905B Fast Etherlink XL 10/100
3091 9056 3c905B-T4 Fast EtherLink XL [Cyclone]
3092 9058 3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
3093 905a 3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
3094 9200 3c905C-TX/TX-M [Tornado]
3095 1028 0095 3C920 Integrated Fast Ethernet Controller
3096 1028 0097 3C920 Integrated Fast Ethernet Controller
3097 1028 00fe Optiplex GX240
3098 1028 012a 3C920 Integrated Fast Ethernet Controller [Latitude C640]
3099 10b7 1000 3C905C-TX Fast Etherlink for PC Management NIC
3100 10b7 7000 10/100 Mini PCI Ethernet Adapter
3101 10f1 2466 Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
3102 9201 3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
3103 1043 80ab A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
3104 9202 3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
3105 9210 3C920B-EMB-WNM Integrated Fast Ethernet Controller
3106 9300 3CSOHO100B-TX 910-A01 [tulip]
3107 9800 3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
3108 10b7 9800 3c980-TX Fast Etherlink XL Server Adapter
3109 9805 3c980-C 10/100baseTX NIC [Python-T]
3110 10b7 1201 EtherLink Server 10/100 Dual Port A
3111 10b7 1202 EtherLink Server 10/100 Dual Port B
3112 10b7 9805 3c980 10/100baseTX NIC [Python-T]
3113 10f1 2462 Thunder K7 S2462
3114 9900 3C990-TX [Typhoon]
3115 9902 3CR990-TX-95 [Typhoon 56-bit]
3116 9903 3CR990-TX-97 [Typhoon 168-bit]
3117 9904 3C990B-TX-M/3C990BSVR [Typhoon2]
3118 10b7 1000 3CR990B-TX-M [Typhoon2]
3119 10b7 2000 3CR990BSVR [Typhoon2 Server]
3120 9905 3CR990-FX-95/97/95 [Typhon Fiber]
3121 10b7 1101 3CR990-FX-95 [Typhoon Fiber 56-bit]
3122 10b7 1102 3CR990-FX-97 [Typhoon Fiber 168-bit]
3123 10b7 2101 3CR990-FX-95 Server [Typhoon Fiber 56-bit]
3124 10b7 2102 3CR990-FX-97 Server [Typhoon Fiber 168-bit]
3125 9908 3CR990SVR95 [Typhoon Server 56-bit]
3126 9909 3CR990SVR97 [Typhoon Server 168-bit]
3127 990a 3C990SVR [Typhoon Server]
3128 990b 3C990SVR [Typhoon Server]
312910b8 Standard Microsystems Corp [SMC]
3130 0005 83c170 EPIC/100 Fast Ethernet Adapter
3131 1055 e000 LANEPIC 10/100 [EVB171Q-PCI]
3132 1055 e002 LANEPIC 10/100 [EVB171G-PCI]
3133 10b8 a011 EtherPower II 10/100
3134 10b8 a014 EtherPower II 10/100
3135 10b8 a015 EtherPower II 10/100
3136 10b8 a016 EtherPower II 10/100
3137 10b8 a017 EtherPower II 10/100
3138 0006 83c175 EPIC/100 Fast Ethernet Adapter
3139 1055 e100 LANEPIC Cardbus Fast Ethernet Adapter
3140 1055 e102 LANEPIC Cardbus Fast Ethernet Adapter
3141 1055 e300 LANEPIC Cardbus Fast Ethernet Adapter
3142 1055 e302 LANEPIC Cardbus Fast Ethernet Adapter
3143 10b8 a012 LANEPIC Cardbus Fast Ethernet Adapter
3144 13a2 8002 LANEPIC Cardbus Fast Ethernet Adapter
3145 13a2 8006 LANEPIC Cardbus Fast Ethernet Adapter
3146 1000 FDC 37c665
3147 1001 FDC 37C922
3148# 802.11g card
3149 2802 SMC2802W [EZ Connect g]
3150 a011 83C170QF
3151 b106 SMC34C90
315210b9 ALi Corporation
3153 0101 CMI8338/C3DX PCI Audio Device
3154 0111 C-Media CMI8738/C3DX Audio Device (OEM)
3155 10b9 0111 C-Media CMI8738/C3DX Audio Device (OEM)
3156 0780 Multi-IO Card
3157 0782 Multi-IO Card
3158 1435 M1435
3159 1445 M1445
3160 1449 M1449
3161 1451 M1451
3162 1461 M1461
3163 1489 M1489
3164 1511 M1511 [Aladdin]
3165 1512 M1512 [Aladdin]
3166 1513 M1513 [Aladdin]
3167 1521 M1521 [Aladdin III]
3168 10b9 1521 ALI M1521 Aladdin III CPU Bridge
3169 1523 M1523
3170 10b9 1523 ALI M1523 ISA Bridge
3171 1531 M1531 [Aladdin IV]
3172 1533 M1533 PCI to ISA Bridge [Aladdin IV]
3173 1014 053b ThinkPad R40e (2684-HVG) PCI to ISA Bridge
3174 10b9 1533 ALI M1533 Aladdin IV ISA Bridge
3175 1541 M1541
3176 10b9 1541 ALI M1541 Aladdin V/V+ AGP System Controller
3177 1543 M1543
3178 1563 M1563 HyperTransport South Bridge
3179 1621 M1621
3180 1631 ALI M1631 PCI North Bridge Aladdin Pro III
3181 1632 M1632M Northbridge+Trident
3182 1641 ALI M1641 PCI North Bridge Aladdin Pro IV
3183 1644 M1644/M1644T Northbridge+Trident
3184 1646 M1646 Northbridge+Trident
3185 1647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
3186 1651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
3187 1671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
3188 1672 M1672 Northbridge [CyberALADDiN-P4]
3189 1681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
3190 1687 M1687 K8 Northbridge [AGP8X and HyperTransport]
3191 1689 M1689 K8 Northbridge [Super K8 Single Chip]
3192 3141 M3141
3193 3143 M3143
3194 3145 M3145
3195 3147 M3147
3196 3149 M3149
3197 3151 M3151
3198 3307 M3307
3199 3309 M3309
3200 3323 M3325 Video/Audio Decoder
3201 5212 M4803
3202 5215 MS4803
3203 5217 M5217H
3204 5219 M5219
3205 5225 M5225
3206 5228 M5228 ALi ATA/RAID Controller
3207 5229 M5229 IDE
3208 1014 050f ThinkPad R30
3209 1014 053d ThinkPad R40e (2684-HVG) builtin IDE
3210 103c 0024 Pavilion ze4400 builtin IDE
3211 1043 8053 A7A266 Motherboard IDE
3212 5235 M5225
3213 5237 USB 1.1 Controller
3214 1014 0540 ThinkPad R40e (2684-HVG) builtin USB
3215 103c 0024 Pavilion ze4400 builtin USB
3216 5239 USB 2.0 Controller
3217 5243 M1541 PCI to AGP Controller
3218 5246 AGP8X Controller
3219 5247 PCI to AGP Controller
3220 5249 M5249 HTT to PCI Bridge
3221 5251 M5251 P1394 OHCI 1.0 Controller
3222 5253 M5253 P1394 OHCI 1.1 Controller
3223 5261 M5261 Ethernet Controller
3224 5263 M5263 Ethernet Controller
3225 5281 ALi M5281 Serial ATA / RAID Host Controller
3226 5287 ULi 5287 SATA
3227 5289 ULi 5289 SATA
3228 5450 Lucent Technologies Soft Modem AMR
3229 5451 M5451 PCI AC-Link Controller Audio Device
3230 1014 0506 ThinkPad R30
3231 1014 053e ThinkPad R40e (2684-HVG) builtin Audio
3232 103c 0024 Pavilion ze4400 builtin Audio
3233 10b9 5451 HP Compaq nc4010 (DY885AA#ABN)
3234 5453 M5453 PCI AC-Link Controller Modem Device
3235 5455 M5455 PCI AC-Link Controller Audio Device
3236 5457 M5457 AC'97 Modem Controller
3237 1014 0535 ThinkPad R40e (2684-HVG) builtin modem
3238 103c 0024 Pavilion ze4400 builtin Modem Device
3239# Same but more usefull for driver's lookup
3240 5459 SmartLink SmartPCI561 56K Modem
3241# SmartLink PCI SoftModem
3242 545a SmartLink SmartPCI563 56K Modem
3243 5471 M5471 Memory Stick Controller
3244 5473 M5473 SD-MMC Controller
3245 7101 M7101 Power Management Controller [PMU]
3246 1014 0510 ThinkPad R30
3247 1014 053c ThinkPad R40e (2684-HVG) Power Management Controller
3248 103c 0024 Pavilion ze4400
324910ba Mitsubishi Electric Corp.
3250 0301 AccelGraphics AccelECLIPSE
3251 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
3252 0308 Tornado 3000 [OEM Evans & Sutherland]
3253 1002 VG500 [VolumePro Volume Rendering Accelerator]
325410bb Dapha Electronics Corporation
325510bc Advanced Logic Research
325610bd Surecom Technology
3257 0e34 NE-34
325810be Tseng Labs International Co.
325910bf Most Inc
326010c0 Boca Research Inc.
326110c1 ICM Co., Ltd.
326210c2 Auspex Systems Inc.
326310c3 Samsung Semiconductors, Inc.
3264 1100 Smartether100 SC1100 LAN Adapter (i82557B)
326510c4 Award Software International Inc.
326610c5 Xerox Corporation
326710c6 Rambus Inc.
326810c7 Media Vision
326910c8 Neomagic Corporation
3270 0001 NM2070 [MagicGraph 128]
3271 0002 NM2090 [MagicGraph 128V]
3272 0003 NM2093 [MagicGraph 128ZV]
3273 0004 NM2160 [MagicGraph 128XD]
3274 1014 00ba MagicGraph 128XD
3275 1025 1007 MagicGraph 128XD
3276 1028 0074 MagicGraph 128XD
3277 1028 0075 MagicGraph 128XD
3278 1028 007d MagicGraph 128XD
3279 1028 007e MagicGraph 128XD
3280 1033 802f MagicGraph 128XD
3281 104d 801b MagicGraph 128XD
3282 104d 802f MagicGraph 128XD
3283 104d 830b MagicGraph 128XD
3284 10ba 0e00 MagicGraph 128XD
3285 10c8 0004 MagicGraph 128XD
3286 10cf 1029 MagicGraph 128XD
3287 10f7 8308 MagicGraph 128XD
3288 10f7 8309 MagicGraph 128XD
3289 10f7 830b MagicGraph 128XD
3290 10f7 830d MagicGraph 128XD
3291 10f7 8312 MagicGraph 128XD
3292 0005 NM2200 [MagicGraph 256AV]
3293 1014 00dd ThinkPad 570
3294 1028 0088 Latitude CPi A
3295 0006 NM2360 [MagicMedia 256ZX]
3296 0016 NM2380 [MagicMedia 256XL+]
3297 10c8 0016 MagicMedia 256XL+
3298 0025 NM2230 [MagicGraph 256AV+]
3299 0083 NM2093 [MagicGraph 128ZV+]
3300 8005 NM2200 [MagicMedia 256AV Audio]
3301 0e11 b0d1 MagicMedia 256AV Audio Device on Discovery
3302 0e11 b126 MagicMedia 256AV Audio Device on Durango
3303 1014 00dd MagicMedia 256AV Audio Device on BlackTip Thinkpad
3304 1025 1003 MagicMedia 256AV Audio Device on TravelMate 720
3305 1028 0088 Latitude CPi A
3306 1028 008f MagicMedia 256AV Audio Device on Colorado Inspiron
3307 103c 0007 MagicMedia 256AV Audio Device on Voyager II
3308 103c 0008 MagicMedia 256AV Audio Device on Voyager III
3309 103c 000d MagicMedia 256AV Audio Device on Omnibook 900
3310 10c8 8005 MagicMedia 256AV Audio Device on FireAnt
3311 110a 8005 MagicMedia 256AV Audio Device
3312 14c0 0004 MagicMedia 256AV Audio Device
3313 8006 NM2360 [MagicMedia 256ZX Audio]
3314 8016 NM2380 [MagicMedia 256XL+ Audio]
331510c9 Dataexpert Corporation
331610ca Fujitsu Microelectr., Inc.
331710cb Omron Corporation
3318# nee Mentor ARC Inc
331910cc Mai Logic Incorporated
3320 0660 Articia S Host Bridge
3321 0661 Articia S PCI Bridge
332210cd Advanced System Products, Inc
3323 1100 ASC1100
3324 1200 ASC1200 [(abp940) Fast SCSI-II]
3325 1300 ABP940-U / ABP960-U
3326 10cd 1310 ASC1300 SCSI Adapter
3327 2300 ABP940-UW
3328 2500 ABP940-U2W
332910ce Radius
3330# nee Citicorp TTI
333110cf Fujitsu Limited.
3332 2001 mb86605
333310d1 FuturePlus Systems Corp.
333410d2 Molex Incorporated
333510d3 Jabil Circuit Inc
333610d4 Hualon Microelectronics
333710d5 Autologic Inc.
333810d6 Cetia
333910d7 BCM Advanced Research
334010d8 Advanced Peripherals Labs
334110d9 Macronix, Inc. [MXIC]
3342 0431 MX98715
3343 0512 MX98713
3344 0531 MX987x5
3345 1186 1200 DFE-540TX ProFAST 10/100 Adapter
3346 8625 MX86250
3347 8888 MX86200
334810da Compaq IPG-Austin
3349 0508 TC4048 Token Ring 4/16
3350 3390 Tl3c3x9
335110db Rohm LSI Systems, Inc.
335210dc CERN/ECP/EDU
3353 0001 STAR/RD24 SCI-PCI (PMC)
3354 0002 TAR/RD24 SCI-PCI (PMC)
3355 0021 HIPPI destination
3356 0022 HIPPI source
3357 10dc ATT2C15-3 FPGA
335810dd Evans & Sutherland
335910de nVidia Corporation
3360 0008 NV1 [EDGE 3D]
3361 0009 NV1 [EDGE 3D]
3362 0010 NV2 [Mutara V08]
3363 0020 NV4 [RIVA TNT]
3364 1043 0200 V3400 TNT
3365 1048 0c18 Erazor II SGRAM
3366 1048 0c1b Erazor II
3367 1092 0550 Viper V550
3368 1092 0552 Viper V550
3369 1092 4804 Viper V550
3370 1092 4808 Viper V550
3371 1092 4810 Viper V550
3372 1092 4812 Viper V550
3373 1092 4815 Viper V550
3374 1092 4820 Viper V550 with TV out
3375 1092 4822 Viper V550
3376 1092 4904 Viper V550
3377 1092 4914 Viper V550
3378 1092 8225 Viper V550
3379 10b4 273d Velocity 4400
3380 10b4 273e Velocity 4400
3381 10b4 2740 Velocity 4400
3382 10de 0020 Riva TNT
3383 1102 1015 Graphics Blaster CT6710
3384 1102 1016 Graphics Blaster RIVA TNT
3385 0028 NV5 [RIVA TNT2/TNT2 Pro]
3386 1043 0200 AGP-V3800 SGRAM
3387 1043 0201 AGP-V3800 SDRAM
3388 1043 0205 PCI-V3800
3389 1043 4000 AGP-V3800PRO
3390 1048 0c21 Synergy II
3391 1048 0c31 Erazor III
3392 107d 2134 WinFast 3D S320 II + TV-Out
3393 1092 4804 Viper V770
3394 1092 4a00 Viper V770
3395 1092 4a02 Viper V770 Ultra
3396 1092 5a00 RIVA TNT2/TNT2 Pro
3397 1092 6a02 Viper V770 Ultra
3398 1092 7a02 Viper V770 Ultra
3399 10de 0005 RIVA TNT2 Pro
3400 10de 000f Compaq NVIDIA TNT2 Pro
3401 1102 1020 3D Blaster RIVA TNT2
3402 1102 1026 3D Blaster RIVA TNT2 Digital
3403 14af 5810 Maxi Gamer Xentor
3404 0029 NV5 [RIVA TNT2 Ultra]
3405 1043 0200 AGP-V3800 Deluxe
3406 1043 0201 AGP-V3800 Ultra SDRAM
3407 1043 0205 PCI-V3800 Ultra
3408 1102 1021 3D Blaster RIVA TNT2 Ultra
3409 1102 1029 3D Blaster RIVA TNT2 Ultra
3410 1102 102f 3D Blaster RIVA TNT2 Ultra
3411 14af 5820 Maxi Gamer Xentor 32
3412 002a NV5 [Riva TnT2]
3413 002b NV5 [Riva TnT2]
3414 002c NV6 [Vanta/Vanta LT]
3415 1043 0200 AGP-V3800 Combat SDRAM
3416 1043 0201 AGP-V3800 Combat
3417 1092 6820 Viper V730
3418 1102 1031 CT6938 VANTA 8MB
3419 1102 1034 CT6894 VANTA 16MB
3420 14af 5008 Maxi Gamer Phoenix 2
3421 002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
3422 1043 0200 AGP-V3800M
3423 1043 0201 AGP-V3800M
3424 1048 0c3a Erazor III LT
3425 10de 001e M64 AGP4x
3426 1102 1023 CT6892 RIVA TNT2 Value
3427 1102 1024 CT6932 RIVA TNT2 Value 32Mb
3428 1102 102c CT6931 RIVA TNT2 Value [Jumper]
3429 1462 8808 MSI-8808
3430 1554 1041 Pixelview RIVA TNT2 M64
3431 1569 002d Palit Microsystems Daytona TNT2 M64
3432 002e NV6 [Vanta]
3433 002f NV6 [Vanta]
3434 0034 MCP04 SMBus
3435 0035 MCP04 IDE
3436 0036 MCP04 Serial ATA Controller
3437 0037 MCP04 Ethernet Controller
3438 0038 MCP04 Ethernet Controller
3439 003a MCP04 AC'97 Audio Controller
3440 003b MCP04 USB Controller
3441 003c MCP04 USB Controller
3442 003d MCP04 PCI Bridge
3443 003e MCP04 Serial ATA Controller
3444 0040 nv40 [GeForce 6800 Ultra]
3445 0041 NV40 [GeForce 6800]
3446 0042 NV40.2
3447 0043 NV40.3
3448 0045 NV40 [GeForce 6800 GT]
3449 0049 NV40GL
3450 004e NV40GL [Quadro FX 4000]
3451 0051 CK804 ISA Bridge
3452 0052 CK804 SMBus
3453 0053 CK804 IDE
3454 0054 CK804 Serial ATA Controller
3455 0055 CK804 Serial ATA Controller
3456 0056 CK804 Ethernet Controller
3457 0057 CK804 Ethernet Controller
3458 0059 CK804 AC'97 Audio Controller
3459 005a CK804 USB Controller
3460 005b CK804 USB Controller
3461 005c CK804 PCI Bridge
3462 005d CK804 PCIE Bridge
3463 005e CK804 Memory Controller
3464 0060 nForce2 ISA Bridge
3465 1043 80ad A7N8X Mainboard
3466 0064 nForce2 SMBus (MCP)
3467 0065 nForce2 IDE
3468 0066 nForce2 Ethernet Controller
3469 1043 80a7 A7N8X Mainboard onboard nForce2 Ethernet
3470 0067 nForce2 USB Controller
3471 1043 0c11 A7N8X Mainboard
3472 0068 nForce2 USB Controller
3473 1043 0c11 A7N8X Mainboard
3474 006a nForce2 AC97 Audio Controler (MCP)
3475 006b nForce Audio Processing Unit
3476 10de 006b nForce2 MCP Audio Processing Unit
3477 006c nForce2 External PCI Bridge
3478 006d nForce2 PCI Bridge
3479 006e nForce2 FireWire (IEEE 1394) Controller
3480 0084 MCP2A SMBus
3481 0085 MCP2A IDE
3482 0086 MCP2A Ethernet Controller
3483 0087 MCP2A USB Controller
3484 0088 MCP2A USB Controller
3485 008a MCP2S AC'97 Audio Controller
3486 008b MCP2A PCI Bridge
3487 008c MCP2A Ethernet Controller
3488 008e nForce2 Serial ATA Controller
3489 00a0 NV5 [Aladdin TNT2]
3490 14af 5810 Maxi Gamer Xentor
3491 00c0 NV41.0
3492 00c1 NV41.1
3493 00c2 NV41.2
3494 00c8 NV41.8
3495 00ce NV41GL
3496 00d0 nForce3 LPC Bridge
3497 00d1 nForce3 Host Bridge
3498 00d2 nForce3 AGP Bridge
3499 00d3 CK804 Memory Controller
3500 00d4 nForce3 SMBus
3501 00d5 nForce3 IDE
3502 00d6 nForce3 Ethernet
3503 00d7 nForce3 USB 1.1
3504 00d8 nForce3 USB 2.0
3505 00da nForce3 Audio
3506 00dd nForce3 PCI Bridge
3507 00df CK8S Ethernet Controller
3508 00e0 nForce3 250Gb LPC Bridge
3509 00e1 nForce3 250Gb Host Bridge
3510 00e2 nForce3 250Gb AGP Host to PCI Bridge
3511 00e3 CK8S Serial ATA Controller (v2.5)
3512 00e4 nForce 250Gb PCI System Management
3513 00e5 CK8S Parallel ATA Controller (v2.5)
3514 00e6 CK8S Ethernet Controller
3515 00e7 CK8S USB Controller
3516 00e8 nForce3 EHCI USB 2.0 Controller
3517 00ea nForce3 250Gb AC'97 Audio Controller
3518 00ed nForce3 250Gb PCI-to-PCI Bridge
3519 00ee CK8S Serial ATA Controller (v2.5)
3520 00f0 NV40 [GeForce 6800/GeForce 6800 Ultra]
3521 00f1 NV43 [GeForce 6600/GeForce 6600 GT]
3522 00f2 NV43 [GeForce 6600 GT]
3523 00f8 NV45GL [Quadro FX 3400]
3524 00f9 NV40 [GeForce 6800 Ultra/GeForce 6800 GT]
3525 1682 2120 GEFORCE 6800 GT PCI-E
3526 00fa NV36 [GeForce PCX 5750]
3527 00fb NV35 [GeForce PCX 5900]
3528 00fc NV37GL [Quadro FX 330/GeForce PCX 5300]
3529 00fd NV37GL [Quadro FX 330]
3530 00fe NV38GL [Quadro FX 1300]
3531 00ff NV18 [GeForce PCX 4300]
3532 0100 NV10 [GeForce 256 SDR]
3533 1043 0200 AGP-V6600 SGRAM
3534 1043 0201 AGP-V6600 SDRAM
3535 1043 4008 AGP-V6600 SGRAM
3536 1043 4009 AGP-V6600 SDRAM
3537 1102 102d CT6941 GeForce 256
3538 14af 5022 3D Prophet SE
3539 0101 NV10DDR [GeForce 256 DDR]
3540 1043 0202 AGP-V6800 DDR
3541 1043 400a AGP-V6800 DDR SGRAM
3542 1043 400b AGP-V6800 DDR SDRAM
3543 107d 2822 WinFast GeForce 256
3544 1102 102e CT6971 GeForce 256 DDR
3545 14af 5021 3D Prophet DDR-DVI
3546 0103 NV10GL [Quadro]
3547 0110 NV11 [GeForce2 MX/MX 400]
3548 1043 4015 AGP-V7100 Pro
3549 1043 4031 V7100 Pro with TV output
3550 10de 0091 Dell OEM GeForce 2 MX 400
3551 1462 8817 MSI GeForce2 MX400 Pro32S [MS-8817]
3552 14af 7102 3D Prophet II MX
3553 14af 7103 3D Prophet II MX Dual-Display
3554 0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR]
3555 0112 NV11 [GeForce2 Go]
3556 0113 NV11GL [Quadro2 MXR/EX]
3557 0140 NV43 [MSI NX6600GT-TD128E]
3558 014f NV43 [GeForce 6200]
3559 0150 NV15 [GeForce2 GTS/Pro]
3560 1043 4016 V7700 AGP Video Card
3561 107d 2840 WinFast GeForce2 GTS with TV output
3562 107d 2842 WinFast GeForce 2 Pro
3563 1462 8831 Creative GeForce2 Pro
3564 0151 NV15DDR [GeForce2 Ti]
3565 1043 405f V7700Ti
3566 1462 5506 Creative 3D Blaster Geforce2 Titanium
3567 0152 NV15BR [GeForce2 Ultra, Bladerunner]
3568 1048 0c56 GLADIAC Ultra
3569 0153 NV15GL [Quadro2 Pro]
3570 0170 NV17 [GeForce4 MX 460]
3571 0171 NV17 [GeForce4 MX 440]
3572 10b0 0002 Gainward Pro/600 TV
3573 1462 8661 G4MX440-VTP
3574 1462 8730 MX440SES-T (MS-8873)
3575 147b 8f00 Abit Siluro GeForce4MX440
3576 0172 NV17 [GeForce4 MX 420]
3577 0173 NV17 [GeForce4 MX 440-SE]
3578 0174 NV17 [GeForce4 440 Go]
3579 0175 NV17 [GeForce4 420 Go]
3580 0176 NV17 [GeForce4 420 Go 32M]
3581 4c53 1090 Cx9 / Vx9 mainboard
3582 0177 NV17 [GeForce4 460 Go]
3583 0178 NV17GL [Quadro4 550 XGL]
3584 0179 NV17 [GeForce4 440 Go 64M]
3585 10de 0179 GeForce4 MX (Mac)
3586 017a NV17GL [Quadro4 200/400 NVS]
3587 017b NV17GL [Quadro4 550 XGL]
3588 017c NV17GL [Quadro4 550 GoGL]
3589 017d NV17 [GeForce4 410 Go 16M]
3590 0181 NV18 [GeForce4 MX 440 AGP 8x]
3591 1043 806f V9180 Magic
3592 1462 8880 MS-StarForce GeForce4 MX 440 with AGP8X
3593 1462 8900 MS-8890 GeForce 4 MX440 AGP8X
3594 1462 9350 MSI Geforce4 MX T8X with AGP8X
3595 147b 8f0d Siluro GF4 MX-8X
3596 0182 NV18 [GeForce4 MX 440SE AGP 8x]
3597 0183 NV18 [GeForce4 MX 420 AGP 8x]
3598 0185 NV18 [GeForce4 MX 4000 AGP 8x]
3599 0186 NV18M [GeForce4 448 Go]
3600 0187 NV18M [GeForce4 488 Go]
3601 0188 NV18GL [Quadro4 580 XGL]
3602 018a NV18GL [Quadro4 NVS AGP 8x]
3603 018b NV18GL [Quadro4 380 XGL]
3604 018d NV18M [GeForce4 448 Go]
3605 01a0 NVCrush11 [GeForce2 MX Integrated Graphics]
3606 01a4 nForce CPU bridge
3607 01ab nForce 420 Memory Controller (DDR)
3608 01ac nForce 220/420 Memory Controller
3609 01ad nForce 220/420 Memory Controller
3610 01b0 nForce Audio
3611 01b1 nForce Audio
3612 01b2 nForce ISA Bridge
3613 01b4 nForce PCI System Management
3614 01b7 nForce AGP to PCI Bridge
3615 01b8 nForce PCI-to-PCI bridge
3616 01bc nForce IDE
3617 01c1 nForce AC'97 Modem Controller
3618 01c2 nForce USB Controller
3619 01c3 nForce Ethernet Controller
3620 01e0 nForce2 AGP (different version?)
3621 01e8 nForce2 AGP
3622 01ea nForce2 Memory Controller 0
3623 01eb nForce2 Memory Controller 1
3624 01ec nForce2 Memory Controller 2
3625 01ed nForce2 Memory Controller 3
3626 01ee nForce2 Memory Controller 4
3627 01ef nForce2 Memory Controller 5
3628 01f0 NV18 [GeForce4 MX - nForce GPU]
3629 0200 NV20 [GeForce3]
3630 1043 402f AGP-V8200 DDR
3631 0201 NV20 [GeForce3 Ti 200]
3632 0202 NV20 [GeForce3 Ti 500]
3633 1043 405b V8200 T5
3634 1545 002f Xtasy 6964
3635 0203 NV20DCC [Quadro DCC]
3636 0240 C51 PCI Express Bridge
3637 0241 C51 PCI Express Bridge
3638 0242 C51 PCI Express Bridge
3639 0243 C51 PCI Express Bridge
3640 0244 C51 PCI Express Bridge
3641 0245 C51 PCI Express Bridge
3642 0246 C51 PCI Express Bridge
3643 0247 C51 PCI Express Bridge
3644 0248 C51 PCI Express Bridge
3645 0249 C51 PCI Express Bridge
3646 024a C51 PCI Express Bridge
3647 024b C51 PCI Express Bridge
3648 024c C51 PCI Express Bridge
3649 024d C51 PCI Express Bridge
3650 024e C51 PCI Express Bridge
3651 024f C51 PCI Express Bridge
3652 0250 NV25 [GeForce4 Ti 4600]
3653 0251 NV25 [GeForce4 Ti 4400]
3654 1043 8023 v8440 GeForce 4 Ti4400
3655 0252 NV25 [GeForce4 Ti]
3656 0253 NV25 [GeForce4 Ti 4200]
3657 107d 2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI)
3658 147b 8f09 Siluro (Dual VGA/TV-out/DVI)
3659 0258 NV25GL [Quadro4 900 XGL]
3660 0259 NV25GL [Quadro4 750 XGL]
3661 025b NV25GL [Quadro4 700 XGL]
3662 0260 MCP51 LPC Bridge
3663 0261 MCP51 LPC Bridge
3664 0262 MCP51 LPC Bridge
3665 0263 MCP51 LPC Bridge
3666 0264 MCP51 SMBus
3667 0265 MCP51 IDE
3668 0266 MCP51 Serial ATA Controller
3669 0267 MCP51 Serial ATA Controller
3670 0268 MCP51 Ethernet Controller
3671 0269 MCP51 Ethernet Controller
3672 026a MCP51 MCI
3673 026b MCP51 AC97 Audio Controller
3674 026c MCP51 High Definition Audio
3675 026d MCP51 USB Controller
3676 026e MCP51 USB Controller
3677 026f MCP51 PCI Bridge
3678 0270 MCP51 Host Bridge
3679 0271 MCP51 PMU
3680 0272 MCP51 Memory Controller 0
3681 027e C51 Memory Controller 2
3682 027f C51 Memory Controller 3
3683 0280 NV28 [GeForce4 Ti 4800]
3684 0281 NV28 [GeForce4 Ti 4200 AGP 8x]
3685 0282 NV28 [GeForce4 Ti 4800 SE]
3686 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x]
3687 0288 NV28GL [Quadro4 980 XGL]
3688 0289 NV28GL [Quadro4 780 XGL]
3689 028c NV28GLM [Quadro4 700 GoGL]
3690 02f0 C51 Host Bridge
3691 02f1 C51 Host Bridge
3692 02f2 C51 Host Bridge
3693 02f3 C51 Host Bridge
3694 02f4 C51 Host Bridge
3695 02f5 C51 Host Bridge
3696 02f6 C51 Host Bridge
3697 02f7 C51 Host Bridge
3698 02f8 C51 Memory Controller 5
3699 02f9 C51 Memory Controller 4
3700 02fa C51 Memory Controller 0
3701 02fb C51 PCI Express Bridge
3702 02fc C51 PCI Express Bridge
3703 02fd C51 PCI Express Bridge
3704 02fe C51 Memory Controller 1
3705 02ff C51 Host Bridge
3706 0300 NV30 [GeForce FX]
3707 0301 NV30 [GeForce FX 5800 Ultra]
3708 0302 NV30 [GeForce FX 5800]
3709 0308 NV30GL [Quadro FX 2000]
3710 0309 NV30GL [Quadro FX 1000]
3711 0311 NV31 [GeForce FX 5600 Ultra]
3712 0312 NV31 [GeForce FX 5600]
3713 0313 NV31
3714 0314 NV31 [GeForce FX 5600XT]
3715 1043 814a V9560XT/TD
3716 0316 NV31
3717 0317 NV31
3718 031a NV31M [GeForce FX Go 5600]
3719 031b NV31M [GeForce FX Go5650]
3720 031c NVIDIA Quadro FX 700 Go
3721 031d NV31
3722 031e NV31
3723 031f NV31
3724 0320 NV34 [GeForce FX 5200]
3725 0321 NV34 [GeForce FX 5200 Ultra]
3726 0322 NV34 [GeForce FX 5200]
3727 1462 9171 MS-8917 (FX5200-T128)
3728 0323 NV34 [GeForce FX 5200LE]
3729 0324 NV34M [GeForce FX Go 5200]
3730 1071 8160 MIM2000
3731 0325 NV34M [GeForce FX Go5250]
3732 0326 NV34 [GeForce FX 5500]
3733 0327 NV34 [GeForce FX 5100]
3734 0328 NV34M [GeForce FX Go 5200]
3735 0329 NV34M [GeForce FX Go5200]
3736 032a NV34GL [Quadro NVS 280 PCI]
3737 032b NV34GL [Quadro FX 500/600 PCI]
3738 032c NV34GLM [GeForce FX Go 5300]
3739 032d NV34 [GeForce FX Go5100]
3740 032f NV34
3741 0330 NV35 [GeForce FX 5900 Ultra]
3742 0331 NV35 [GeForce FX 5900]
3743 1043 8145 V9950GE
3744 0332 NV35 [GeForce FX 5900XT]
3745 0333 NV38 [GeForce FX 5950 Ultra]
3746 0334 NV35 [GeForce FX 5900ZT]
3747 0338 NV35GL [Quadro FX 3000]
3748 033f NV35GL [Quadro FX 700]
3749 0341 NV36.1 [GeForce FX 5700 Ultra]
3750 0342 NV36.2 [GeForce FX 5700]
3751 0343 NV36 [GeForce FX 5700LE]
3752 0344 NV36.4 [GeForce FX 5700VE]
3753 0345 NV36.5
3754 0347 NV36 [GeForce FX Go5700]
3755 0348 NV36 [GeForce FX Go5700]
3756 0349 NV36
3757 034b NV36
3758 034c NV36 [Quadro FX Go1000]
3759 034e NV36GL [Quadro FX 1100]
3760 034f NV36GL
376110df Emulex Corporation
3762 1ae5 LP6000 Fibre Channel Host Adapter
3763 1ae6 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3764 1ae7 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:2-3)
3765 f005 LP1150e Fibre Channel Host Adapter
3766 f085 LP850 Fibre Channel Host Adapter
3767 f095 LP952 Fibre Channel Host Adapter
3768 f098 LP982 Fibre Channel Host Adapter
3769 f0a5 LP1050 Fibre Channel Host Adapter
3770 f0d5 LP1150 Fibre Channel Host Adapter
3771 f100 LP11000e Fibre Channel Host Adapter
3772 f700 LP7000 Fibre Channel Host Adapter
3773 f701 LP 7000EFibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3774 f800 LP8000 Fibre Channel Host Adapter
3775 f801 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3776 f900 LP9000 Fibre Channel Host Adapter
3777 f901 LP 9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3778 f980 LP9802 Fibre Channel Host Adapter
3779 f981 LP 9802 Fibre Channel Host Adapter Alternate ID
3780 f982 LP 9802 Fibre Channel Host Adapter Alternate ID
3781 fa00 LP10000 Fibre Channel Host Adapter
3782 fa01 LP101 Fibre Channel Host Adapter
3783 fd00 LP11000 Fibre Channel Host Adapter
378410e0 Integrated Micro Solutions Inc.
3785 5026 IMS5026/27/28
3786 5027 IMS5027
3787 5028 IMS5028
3788 8849 IMS8849
3789 8853 IMS8853
3790 9128 IMS9128 [Twin turbo 128]
379110e1 Tekram Technology Co.,Ltd.
3792 0391 TRM-S1040
3793 10e1 0391 DC-315U SCSI-3 Host Adapter
3794 690c DC-690c
3795 dc29 DC-290
379610e2 Aptix Corporation
379710e3 Tundra Semiconductor Corp.
3798 0000 CA91C042 [Universe]
3799 0860 CA91C860 [QSpan]
3800 0862 CA91C862A [QSpan-II]
3801 8260 CA91L8200B [Dual PCI PowerSpan II]
3802 8261 CA91L8260B [Single PCI PowerSpan II]
380310e4 Tandem Computers
380410e5 Micro Industries Corporation
380510e6 Gainbery Computer Products Inc.
380610e7 Vadem
380710e8 Applied Micro Circuits Corp.
3808 1072 INES GPIB-PCI (AMCC5920 based)
3809 2011 Q-Motion Video Capture/Edit board
3810 4750 S5930 [Matchmaker]
3811 5920 S5920
3812 8043 LANai4.x [Myrinet LANai interface chip]
3813 8062 S5933_PARASTATION
3814 807d S5933 [Matchmaker]
3815 8088 Kongsberg Spacetec Format Synchronizer
3816 8089 Kongsberg Spacetec Serial Output Board
3817 809c S5933_HEPC3
3818 80d7 PCI-9112
3819 80d9 PCI-9118
3820 80da PCI-9812
3821 811a PCI-IEEE1355-DS-DE Interface
3822 814c Fastcom ESCC-PCI (Commtech, Inc.)
3823 8170 S5933 [Matchmaker] (Chipset Development Tool)
3824# sold with Roper Scientifc(Photometrics) CoolSnap HQ camera
3825 81e6 Multimedia video controller
3826 8291 Fastcom 232/8-PCI (Commtech, Inc.)
3827 82c4 Fastcom 422/4-PCI (Commtech, Inc.)
3828 82c5 Fastcom 422/2-PCI (Commtech, Inc.)
3829 82c6 Fastcom IG422/1-PCI (Commtech, Inc.)
3830 82c7 Fastcom IG232/2-PCI (Commtech, Inc.)
3831 82ca Fastcom 232/4-PCI (Commtech, Inc.)
3832 82db AJA HDNTV HD SDI Framestore
3833 82e2 Fastcom DIO24H-PCI (Commtech, Inc.)
3834 8851 S5933 on Innes Corp FM Radio Capture card
383510e9 Alps Electric Co., Ltd.
383610ea Intergraphics Systems
3837 1680 IGA-1680
3838 1682 IGA-1682
3839 1683 IGA-1683
3840 2000 CyberPro 2000
3841 2010 CyberPro 2000A
3842 5000 CyberPro 5000
3843 5050 CyberPro 5050
3844 5202 CyberPro 5202
3845# CyberPro5202 Audio Function
3846 5252 CyberPro5252
384710eb Artists Graphics
3848 0101 3GA
3849 8111 Twist3 Frame Grabber
385010ec Realtek Semiconductor Co., Ltd.
3851 8029 RTL-8029(AS)
3852 10b8 2011 EZ-Card (SMC1208)
3853 10ec 8029 RTL-8029(AS)
3854 1113 1208 EN1208
3855 1186 0300 DE-528
3856 1259 2400 AT-2400
3857 8129 RTL-8129
3858 10ec 8129 RT8129 Fast Ethernet Adapter
3859 8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter
3860 10ec 8138 RT8139 (B/C) Fast Ethernet Adapter
3861 8139 RTL-8139/8139C/8139C+
3862 0357 000a TTP-Monitoring Card V2.0
3863 1025 005a TravelMate 290
3864 1025 8920 ALN-325
3865 1025 8921 ALN-325
3866 1071 8160 MIM2000
3867 10bd 0320 EP-320X-R
3868 10ec 8139 RT8139
3869 1113 ec01 FNC-0107TX
3870 1186 1300 DFE-538TX
3871 1186 1320 SN5200
3872 1186 8139 DRN-32TX
3873 11f6 8139 FN22-3(A) LinxPRO Ethernet Adapter
3874 1259 2500 AT-2500TX
3875 1259 2503 AT-2500TX/ACPI
3876 1429 d010 ND010
3877 1432 9130 EN-9130TX
3878 1436 8139 RT8139
3879 1458 e000 GA-7VM400M/7VT600 Motherboard
3880 146c 1439 FE-1439TX
3881 1489 6001 GF100TXRII
3882 1489 6002 GF100TXRA
3883 149c 139a LFE-8139ATX
3884 149c 8139 LFE-8139TX
3885 14cb 0200 LNR-100 Family 10/100 Base-TX Ethernet
3886 1799 5000 F5D5000 PCI Card/Desktop Network PCI Card
3887 2646 0001 EtheRx
3888 8e2e 7000 KF-230TX
3889 8e2e 7100 KF-230TX/2
3890 a0a0 0007 ALN-325C
3891 8169 RTL-8169 Gigabit Ethernet
3892 1259 c107 CG-LAPCIGT
3893 1371 434e ProG-2000L
3894 1458 e000 GA-K8VT800 Pro Motherboard
3895 1462 702c K8T NEO 2 motherboard
3896 8180 RTL8180L 802.11b MAC
3897 8197 SmartLAN56 56K Modem
389810ed Ascii Corporation
3899 7310 V7310
390010ee Xilinx Corporation
3901 3fc0 RME Digi96
3902 3fc1 RME Digi96/8
3903 3fc2 RME Digi96/8 Pro
3904 3fc3 RME Digi96/8 Pad
3905 3fc4 RME Digi9652 (Hammerfall)
3906 3fc5 RME Hammerfall DSP
3907 3fc6 RME Hammerfall DSP MADI
3908 8381 Ellips Santos Frame Grabber
390910ef Racore Computer Products, Inc.
3910 8154 M815x Token Ring Adapter
391110f0 Peritek Corporation
391210f1 Tyan Computer
391310f2 Achme Computer, Inc.
391410f3 Alaris, Inc.
391510f4 S-MOS Systems, Inc.
391610f5 NKK Corporation
3917 a001 NDR4000 [NR4600 Bridge]
391810f6 Creative Electronic Systems SA
391910f7 Matsushita Electric Industrial Co., Ltd.
392010f8 Altos India Ltd
392110f9 PC Direct
392210fa Truevision
3923 000c TARGA 1000
392410fb Thesys Gesellschaft für Mikroelektronik mbH
3925 186f TH 6255
392610fc I-O Data Device, Inc.
3927# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
3928 0003 Cardbus IDE Controller
3929 0005 Cardbus SCSI CBSC II
393010fd Soyo Computer, Inc
393110fe Fast Multimedia AG
393210ff NCube
39331100 Jazz Multimedia
39341101 Initio Corporation
3935 1060 INI-A100U2W
3936 9100 INI-9100/9100W
3937 9400 INI-940
3938 9401 INI-950
3939 9500 360P
3940 9502 Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip
39411102 Creative Labs
3942 0002 SB Live! EMU10k1
3943 1102 0020 CT4850 SBLive! Value
3944 1102 0021 CT4620 SBLive!
3945 1102 002f SBLive! mainboard implementation
3946 1102 4001 E-mu APS
3947 1102 8022 CT4780 SBLive! Value
3948 1102 8023 CT4790 SoundBlaster PCI512
3949 1102 8024 CT4760 SBLive!
3950 1102 8025 SBLive! Mainboard Implementation
3951 1102 8026 CT4830 SBLive! Value
3952 1102 8027 CT4832 SBLive! Value
3953 1102 8028 CT4760 SBLive! OEM version
3954 1102 8031 CT4831 SBLive! Value
3955 1102 8040 CT4760 SBLive!
3956 1102 8051 CT4850 SBLive! Value
3957 1102 8061 SBLive! Player 5.1
3958 1102 8064 SB Live! 5.1 Model SB0100
3959 1102 8065 SBLive! 5.1 Digital Model SB0220
3960 1102 8067 SBLive! 5.1 eMicro 28028
3961 0004 SB Audigy
3962 1102 0051 SB0090 Audigy Player
3963 1102 0053 SB0090 Audigy Player/OEM
3964 1102 0058 SB0090 Audigy Player/OEM
3965 1102 1007 SB0240 Audigy 2 Platinum 6.1
3966 1102 2002 SB Audigy 2 ZS (SB0350)
3967 0006 [SB Live! Value] EMU10k1X
3968 0007 SB Audigy LS
3969 1102 1001 SB0310 Audigy LS
3970 1102 1002 SB0312 Audigy LS
3971 1102 1006 SB0410 SBLive! 24-bit
3972 0008 SB0400 Audigy2 Value
3973 4001 SB Audigy FireWire Port
3974 1102 0010 SB Audigy FireWire Port
3975 7002 SB Live! MIDI/Game Port
3976 1102 0020 Gameport Joystick
3977 7003 SB Audigy MIDI/Game port
3978 1102 0040 SB Audigy MIDI/Game Port
3979 7004 [SB Live! Value] Input device controller
3980 7005 SB Audigy LS MIDI/Game port
3981 1102 1001 SB0310 Audigy LS MIDI/Game port
3982 1102 1002 SB0312 Audigy LS MIDI/Game port
3983 8064 SB0100 [SBLive! 5.1 OEM]
3984 8938 Ectiva EV1938
3985 1033 80e5 SlimTower-Jim (NEC)
3986 1071 7150 Mitac 7150
3987 110a 5938 Siemens Scenic Mobile 510PIII
3988 13bd 100c Ceres-C (Sharp, Intel BX)
3989 13bd 100d Sharp, Intel Banister
3990 13bd 100e TwinHead P09S/P09S3 (Sharp)
3991 13bd f6f1 Marlin (Sharp)
3992 14ff 0e70 P88TE (TWINHEAD INTERNATIONAL Corp)
3993 14ff c401 Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
3994 156d b400 G400 - Geo (AlphaTop (Taiwan))
3995 156d b550 G560 (AlphaTop (Taiwan))
3996 156d b560 G560 (AlphaTop (Taiwan))
3997 156d b700 G700/U700 (AlphaTop (Taiwan))
3998 156d b795 G795 (AlphaTop (Taiwan))
3999 156d b797 G797 (AlphaTop (Taiwan))
40001103 Triones Technologies, Inc.
4001 0003 HPT343
4002 0004 HPT366/368/370/370A/372/372N
4003 1103 0001 HPT370A
4004 1103 0003 HPT343 / HPT345 / HPT363 UDMA33
4005 1103 0004 HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
4006 1103 0005 HPT370 UDMA100
4007 1103 0006 HPT302
4008 1103 0007 HPT371 UDMA133
4009 1103 0008 HPT374 UDMA/ATA133 RAID Controller
4010 0005 HPT372A/372N
4011 0006 HPT302
4012 0007 HPT371/371N
4013 0008 HPT374
4014 0009 HPT372N
40151104 RasterOps Corp.
40161105 Sigma Designs, Inc.
4017 1105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
4018 8300 REALmagic Hollywood Plus DVD Decoder
4019 8400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
4020 8401 EM8401 REALmagic DVD/MPEG-2 A/V Decoder
4021 8470 EM8470 REALmagic DVD/MPEG-4 A/V Decoder
4022 8471 EM8471 REALmagic DVD/MPEG-4 A/V Decoder
4023 8475 EM8475 REALmagic DVD/MPEG-4 A/V Decoder
4024 8476 EM8476 REALmagic DVD/MPEG-4 A/V Decoder
4025 8485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder
4026 8486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder
40271106 VIA Technologies, Inc.
4028 0102 Embedded VIA Ethernet Controller
4029 0130 VT6305 1394.A Controller
4030 0305 VT8363/8365 [KT133/KM133]
4031 1043 8033 A7V Mainboard
4032 1043 803e A7V-E Mainboard
4033 1043 8042 A7V133/A7V133-C Mainboard
4034 147b a401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
4035 0391 VT8371 [KX133]
4036 0501 VT8501 [Apollo MVP4]
4037 0505 VT82C505
4038# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
4039 0561 VT82C576MV
4040 0571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
4041 1019 0985 P6VXA Motherboard
4042 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4043 1043 8052 VT8233A Bus Master ATA100/66/33 IDE
4044 1043 808c A7V8X motherboard
4045 1043 80a1 A7V8X-X motherboard rev. 1.01
4046 1043 80ed A7V600 motherboard
4047 1106 0571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
4048 1179 0001 Magnia Z310
4049 1297 f641 FX41 motherboard
4050 1458 5002 GA-7VAX Mainboard
4051 1462 7020 K8T NEO 2 motherboard
4052 147b 1407 KV8-MAX3 motherboard
4053 1849 0571 K7VT2 motherboard
4054 0576 VT82C576 3V [Apollo Master]
4055 0585 VT82C585VP [Apollo VP1/VPX]
4056 0586 VT82C586/A/B PCI-to-ISA [Apollo VP]
4057 1106 0000 MVP3 ISA Bridge
4058 0595 VT82C595 [Apollo VP2]
4059 0596 VT82C596 ISA [Mobile South]
4060 1106 0000 VT82C596/A/B PCI to ISA Bridge
4061 1458 0596 VT82C596/A/B PCI to ISA Bridge
4062 0597 VT82C597 [Apollo VP3]
4063 0598 VT82C598 [Apollo MVP3]
4064 0601 VT8601 [Apollo ProMedia]
4065 0605 VT8605 [ProSavage PM133]
4066 1043 802c CUV4X mainboard
4067 0680 VT82C680 [Apollo P6]
4068 0686 VT82C686 [Apollo Super South]
4069 1019 0985 P6VXA Motherboard
4070 1043 802c CUV4X mainboard
4071 1043 8033 A7V Mainboard
4072 1043 803e A7V-E Mainboard
4073 1043 8040 A7M266 Mainboard
4074 1043 8042 A7V133/A7V133-C Mainboard
4075 1106 0000 VT82C686/A PCI to ISA Bridge
4076 1106 0686 VT82C686/A PCI to ISA Bridge
4077 1179 0001 Magnia Z310
4078 147b a702 KG7-Lite Mainboard
4079 0691 VT82C693A/694x [Apollo PRO133x]
4080 1019 0985 P6VXA Motherboard
4081 1179 0001 Magnia Z310
4082 1458 0691 VT82C691 Apollo Pro System Controller
4083 0693 VT82C693 [Apollo Pro Plus]
4084 0698 VT82C693A [Apollo Pro133 AGP]
4085 0926 VT82C926 [Amazon]
4086 1000 VT82C570MV
4087 1106 VT82C570MV
4088 1571 VT82C576M/VT82C586
4089 1595 VT82C595/97 [Apollo VP2/97]
4090 3022 CLE266
4091# This is *not* USB 2.0 as the existing entry suggests
4092 3038 VT82xxxxx UHCI USB 1.1 Controller
4093 0925 1234 USB Controller
4094 1019 0985 P6VXA Motherboard
4095 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4096 1043 808c VT6202 USB2.0 4 port controller
4097 1043 80a1 A7V8X-X motherboard
4098 1043 80ed A7V600 motherboard
4099 1179 0001 Magnia Z310
4100 1458 5004 GA-7VAX Mainboard
4101 1462 7020 K8T NEO 2 motherboard
4102 147b 1407 KV8-MAX3 motherboard
4103 182d 201d CN-029 USB2.0 4 port PCI Card
4104 3040 VT82C586B ACPI
4105 3043 VT86C100A [Rhine]
4106 10bd 0000 VT86C100A Fast Ethernet Adapter
4107 1106 0100 VT86C100A Fast Ethernet Adapter
4108 1186 1400 DFE-530TX rev A
4109 3044 IEEE 1394 Host Controller
4110 1025 005a TravelMate 290
4111 1458 1000 GA-7VT600-1394 Motherboard
4112 1462 702d K8T NEO 2 motherboard
4113 3050 VT82C596 Power Management
4114 3051 VT82C596 Power Management
4115 3053 VT6105M [Rhine-III]
4116 3057 VT82C686 [Apollo Super ACPI]
4117 1019 0985 P6VXA Motherboard
4118 1043 8033 A7V Mainboard
4119 1043 803e A7V-E Mainboard
4120 1043 8040 A7M266 Mainboard
4121 1043 8042 A7V133/A7V133-C Mainboard
4122 1179 0001 Magnia Z310
4123 3058 VT82C686 AC97 Audio Controller
4124 0e11 0097 SoundMax Digital Integrated Audio
4125 0e11 b194 Soundmax integrated digital audio
4126 1019 0985 P6VXA Motherboard
4127 1043 1106 A7V133/A7V133-C Mainboard
4128 1106 4511 Onboard Audio on EP7KXA
4129 1458 7600 Onboard Audio
4130 1462 3091 MS-6309 Onboard Audio
4131 1462 3300 MS-6330 Onboard Audio
4132 15dd 7609 Onboard Audio
4133 3059 VT8233/A/8235/8237 AC97 Audio Controller
4134 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4135 1043 8095 A7V8X Motherboard (Realtek ALC650 codec)
4136 1043 80a1 A7V8X-X Motherboard
4137 1043 80b0 A7V600/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
4138 1106 3059 L7VMM2 Motherboard
4139 1106 4161 K7VT2 motherboard
4140 1297 c160 FX41 motherboard (Realtek ALC650 codec)
4141 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650)
4142 1462 0080 K8T NEO 2 motherboard
4143 1462 3800 KT266 onboard audio
4144 147b 1407 KV8-MAX3 motherboard
4145 3065 VT6102 [Rhine-II]
4146 1043 80a1 A7V8X-X Motherboard
4147 1106 0102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
4148 1186 1400 DFE-530TX rev A
4149 1186 1401 DFE-530TX rev B
4150 13b9 1421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
4151# This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs
4152 3068 AC'97 Modem Controller
4153 1462 309e MS-6309 Saturn Motherboard
4154 3074 VT8233 PCI to ISA Bridge
4155 1043 8052 VT8233A
4156 3091 VT8633 [Apollo Pro266]
4157 3099 VT8366/A/7 [Apollo KT266/A/333]
4158 1043 8064 A7V266-E Mainboard
4159 1043 807f A7V333 Mainboard
4160 1849 3099 K7VT2 motherboard
4161 3101 VT8653 Host Bridge
4162 3102 VT8662 Host Bridge
4163 3103 VT8615 Host Bridge
4164 3104 USB 2.0
4165 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4166 1043 808c A7V8X motherboard
4167 1043 80a1 A7V8X-X motherboard rev 1.01
4168 1043 80ed A7V600 motherboard
4169 1297 f641 FX41 motherboard
4170 1458 5004 GA-7VAX Mainboard
4171 1462 7020 K8T NEO 2 motherboard
4172 147b 1407 KV8-MAX3 motherboard
4173 182d 201d CN-029 USB 2.0 4 port PCI Card
4174 3106 VT6105 [Rhine-III]
4175 1186 1403 DFE-530TX rev C
4176 3108 S3 Unichrome Pro VGA Adapter
4177 3109 VT8233C PCI to ISA Bridge
4178 3112 VT8361 [KLE133] Host Bridge
4179 3116 VT8375 [KM266/KL266] Host Bridge
4180 1297 f641 FX41 motherboard
4181 3118 S3 Unichrome Pro VGA Adapter
4182 3119 VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
4183# found on EPIA M6000/9000 mainboard
4184 3122 VT8623 [Apollo CLE266] integrated CastleRock graphics
4185# found on EPIA M6000/9000 mainboard
4186 3123 VT8623 [Apollo CLE266]
4187 3128 VT8753 [P4X266 AGP]
4188 3133 VT3133 Host Bridge
4189 3147 VT8233A ISA Bridge
4190 3148 P4M266 Host Bridge
4191 3149 VIA VT6420 SATA RAID Controller
4192 1043 80ed A7V600/K8V Deluxe motherboard
4193 1458 b003 GA-7VM400AM(F) Motherboard
4194 1462 7020 K8T Neo 2 Motherboard
4195 147b 1407 KV8-MAX3 motherboard
4196 3156 P/KN266 Host Bridge
4197# on ASUS P4P800
4198 3164 VT6410 ATA133 RAID controller
4199 3168 VT8374 P4X400 Host Controller/AGP Bridge
4200 3177 VT8235 ISA Bridge
4201 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4202 1043 808c A7V8X motherboard
4203 1043 80a1 A7V8X-X motherboard
4204 1297 f641 FX41 motherboard
4205 1458 5001 GA-7VAX Mainboard
4206 1849 3177 K7VT2 motherboard
4207 3178 ProSavageDDR P4N333 Host Bridge
4208 3188 VT8385 [K8T800 AGP] Host Bridge
4209 1043 80a3 K8V Deluxe motherboard
4210 147b 1407 KV8-MAX3 motherboard
4211 3189 VT8377 [KT400/KT600 AGP] Host Bridge
4212 1043 807f A7V8X motherboard
4213 1458 5000 GA-7VAX Mainboard
4214 3204 K8M800
4215 3205 VT8378 [KM400/A] Chipset Host Bridge
4216 1458 5000 GA-7VM400M Motherboard
4217 3218 K8T800M Host Bridge
4218 3227 VT8237 ISA bridge [KT600/K8T800 South]
4219 1043 80ed A7V600 motherboard
4220 1106 3227 DFI KT600-AL Motherboard
4221 1458 5001 GA-7VT600 Motherboard
4222 147b 1407 KV8-MAX3 motherboard
4223 3249 VT6421 IDE RAID Controller
4224 4149 VIA VT6420 (ATA133) Controller
4225 5030 VT82C596 ACPI [Apollo PRO]
4226 6100 VT85C100A [Rhine II]
4227 7204 K8M800
4228# S3 Graphics UniChromeâ„¢ 2D/3D Graphics with motion compensation
4229 7205 VT8378 [S3 UniChrome] Integrated Video
4230 1458 d000 Gigabyte GA-7VM400(A)M(F) Motherboard
4231 8231 VT8231 [PCI-to-ISA Bridge]
4232 8235 VT8235 ACPI
4233 8305 VT8363/8365 [KT133/KM133 AGP]
4234 8391 VT8371 [KX133 AGP]
4235 8501 VT8501 [Apollo MVP4 AGP]
4236 8596 VT82C596 [Apollo PRO AGP]
4237 8597 VT82C597 [Apollo VP3 AGP]
4238 8598 VT82C598/694x [Apollo MVP3/Pro133x AGP]
4239 1019 0985 P6VXA Motherboard
4240 8601 VT8601 [Apollo ProMedia AGP]
4241 8605 VT8605 [PM133 AGP]
4242 8691 VT82C691 [Apollo Pro]
4243 8693 VT82C693 [Apollo Pro Plus] PCI Bridge
4244 b091 VT8633 [Apollo Pro266 AGP]
4245 b099 VT8366/A/7 [Apollo KT266/A/333 AGP]
4246 b101 VT8653 AGP Bridge
4247 b102 VT8362 AGP Bridge
4248 b103 VT8615 AGP Bridge
4249 b112 VT8361 [KLE133] AGP Bridge
4250 b168 VT8235 PCI Bridge
4251 b188 VT8237 PCI bridge [K8T800 South]
4252 147b 1407 KV8-MAX3 motherboard
4253 b198 VT8237 PCI Bridge
4254# 32-Bit PCI bus master Ethernet MAC with standard MII interface
4255 d104 VT8237 Integrated Fast Ethernet Controller
42561107 Stratus Computers
4257 0576 VIA VT82C570MV [Apollo] (Wrong vendor ID!)
42581108 Proteon, Inc.
4259 0100 p1690plus_AA
4260 0101 p1690plus_AB
4261 0105 P1690Plus
4262 0108 P1690Plus
4263 0138 P1690Plus
4264 0139 P1690Plus
4265 013c P1690Plus
4266 013d P1690Plus
42671109 Cogent Data Technologies, Inc.
4268 1400 EM110TX [EX110TX]
4269110a Siemens Nixdorf AG
4270 0002 Pirahna 2-port
4271 0005 Tulip controller, power management, switch extender
4272 0006 FSC PINC (I/O-APIC)
4273 0015 FSC Multiprocessor Interrupt Controller
4274 001d FSC Copernicus Management Controller
4275 007b FSC Remote Service Controller, mailbox device
4276 007c FSC Remote Service Controller, shared memory device
4277 007d FSC Remote Service Controller, SMIC device
4278# Superfastcom-PCI (Commtech, Inc.) or DSCC4 WAN Adapter
4279 2102 DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
4280 2104 Eicon Diva 2.02 compatible passive ISDN card
4281 3142 SIMATIC NET CP 5613A1 (Profibus Adapter)
4282 4021 SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
4283 4029 SIMATIC NET CP 5613A2 (Profibus Adapter)
4284 4942 FPGA I-Bus Tracer for MBD
4285 6120 SZB6120
4286110b Chromatic Research Inc.
4287 0001 Mpact Media Processor
4288 0004 Mpact 2
4289110c Mini-Max Technology, Inc.
4290110d Znyx Advanced Systems
4291110e CPU Technology
4292110f Ross Technology
42931110 Powerhouse Systems
4294 6037 Firepower Powerized SMP I/O ASIC
4295 6073 Firepower Powerized SMP I/O ASIC
42961111 Santa Cruz Operation
4297# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
42981112 Osicom Technologies Inc
4299 2200 FDDI Adapter
4300 2300 Fast Ethernet Adapter
4301 2340 4 Port Fast Ethernet Adapter
4302 2400 ATM Adapter
43031113 Accton Technology Corporation
4304 1211 SMC2-1211TX
4305 103c 1207 EN-1207D Fast Ethernet Adapter
4306 1113 1211 EN-1207D Fast Ethernet Adapter
4307 1216 EN-1216 Ethernet Adapter
4308 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card
4309 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
4310 1217 EN-1217 Ethernet Adapter
4311 5105 10Mbps Network card
4312 9211 EN-1207D Fast Ethernet Adapter
4313 1113 9211 EN-1207D Fast Ethernet Adapter
4314 9511 21x4x DEC-Tulip compatible Fast Ethernet
4315 d301 CPWNA100 (Philips wireless PCMCIA)
4316 ec02 SMC 1244TX v3
43171114 Atmel Corporation
4318 0506 802.11b Wireless Network Adaptor (at76c506)
43191115 3D Labs
43201116 Data Translation
4321 0022 DT3001
4322 0023 DT3002
4323 0024 DT3003
4324 0025 DT3004
4325 0026 DT3005
4326 0027 DT3001-PGL
4327 0028 DT3003-PGL
43281117 Datacube, Inc
4329 9500 Max-1C SVGA card
4330 9501 Max-1C image processing
43311118 Berg Electronics
43321119 ICP Vortex Computersysteme GmbH
4333 0000 GDT 6000/6020/6050
4334 0001 GDT 6000B/6010
4335 0002 GDT 6110/6510
4336 0003 GDT 6120/6520
4337 0004 GDT 6530
4338 0005 GDT 6550
4339 0006 GDT 6117/6517
4340 0007 GDT 6127/6527
4341 0008 GDT 6537
4342 0009 GDT 6557/6557-ECC
4343 000a GDT 6115/6515
4344 000b GDT 6125/6525
4345 000c GDT 6535
4346 000d GDT 6555
4347 0010 GDT 6115/6515
4348 0011 GDT 6125/6525
4349 0012 GDT 6535
4350 0013 GDT 6555/6555-ECC
4351 0100 GDT 6117RP/6517RP
4352 0101 GDT 6127RP/6527RP
4353 0102 GDT 6537RP
4354 0103 GDT 6557RP
4355 0104 GDT 6111RP/6511RP
4356 0105 GDT 6121RP/6521RP
4357 0110 GDT 6117RD/6517RD
4358 0111 GDT 6127RD/6527RD
4359 0112 GDT 6537RD
4360 0113 GDT 6557RD
4361 0114 GDT 6111RD/6511RD
4362 0115 GDT 6121RD/6521RD
4363 0118 GDT 6118RD/6518RD/6618RD
4364 0119 GDT 6128RD/6528RD/6628RD
4365 011a GDT 6538RD/6638RD
4366 011b GDT 6558RD/6658RD
4367 0120 GDT 6117RP2/6517RP2
4368 0121 GDT 6127RP2/6527RP2
4369 0122 GDT 6537RP2
4370 0123 GDT 6557RP2
4371 0124 GDT 6111RP2/6511RP2
4372 0125 GDT 6121RP2/6521RP2
4373 0136 GDT 6113RS/6513RS
4374 0137 GDT 6123RS/6523RS
4375 0138 GDT 6118RS/6518RS/6618RS
4376 0139 GDT 6128RS/6528RS/6628RS
4377 013a GDT 6538RS/6638RS
4378 013b GDT 6558RS/6658RS
4379 013c GDT 6533RS/6633RS
4380 013d GDT 6543RS/6643RS
4381 013e GDT 6553RS/6653RS
4382 013f GDT 6563RS/6663RS
4383 0166 GDT 7113RN/7513RN/7613RN
4384 0167 GDT 7123RN/7523RN/7623RN
4385 0168 GDT 7118RN/7518RN/7518RN
4386 0169 GDT 7128RN/7528RN/7628RN
4387 016a GDT 7538RN/7638RN
4388 016b GDT 7558RN/7658RN
4389 016c GDT 7533RN/7633RN
4390 016d GDT 7543RN/7643RN
4391 016e GDT 7553RN/7653RN
4392 016f GDT 7563RN/7663RN
4393 01d6 GDT 4x13RZ
4394 01d7 GDT 4x23RZ
4395 01f6 GDT 8x13RZ
4396 01f7 GDT 8x23RZ
4397 01fc GDT 8x33RZ
4398 01fd GDT 8x43RZ
4399 01fe GDT 8x53RZ
4400 01ff GDT 8x63RZ
4401 0210 GDT 6519RD/6619RD
4402 0211 GDT 6529RD/6629RD
4403 0260 GDT 7519RN/7619RN
4404 0261 GDT 7529RN/7629RN
4405 02ff GDT MAXRP
4406 0300 GDT NEWRX
4407111a Efficient Networks, Inc
4408 0000 155P-MF1 (FPGA)
4409 0002 155P-MF1 (ASIC)
4410 0003 ENI-25P ATM
4411 111a 0000 ENI-25p Miniport ATM Adapter
4412 0005 SpeedStream (LANAI)
4413 111a 0001 ENI-3010 ATM
4414 111a 0009 ENI-3060 ADSL (VPI=0)
4415 111a 0101 ENI-3010 ATM
4416 111a 0109 ENI-3060CO ADSL (VPI=0)
4417 111a 0809 ENI-3060 ADSL (VPI=0 or 8)
4418 111a 0909 ENI-3060CO ADSL (VPI=0 or 8)
4419 111a 0a09 ENI-3060 ADSL (VPI=<0..15>)
4420 0007 SpeedStream ADSL
4421 111a 1001 ENI-3061 ADSL [ASIC]
4422 1203 SpeedStream 1023 Wireless PCI Adapter
4423111b Teledyne Electronic Systems
4424111c Tricord Systems Inc.
4425 0001 Powerbis Bridge
4426111d Integrated Device Technology, Inc.
4427 0001 IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
4428 0003 IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
4429 0004 IDT77V252 155Mbps ATM MICRO ABR SAR Controller
4430 0005 IDT77V222 155Mbps ATM MICRO ABR SAR Controller
4431111e Eldec
4432111f Precision Digital Images
4433 4a47 Precision MX Video engine interface
4434 5243 Frame capture bus interface
44351120 EMC Corporation
44361121 Zilog
44371122 Multi-tech Systems, Inc.
44381123 Excellent Design, Inc.
44391124 Leutron Vision AG
44401125 Eurocore
44411126 Vigra
44421127 FORE Systems Inc
4443 0200 ForeRunner PCA-200 ATM
4444 0210 PCA-200PC
4445 0250 ATM
4446 0300 ForeRunner PCA-200EPC ATM
4447 0310 ATM
4448 0400 ForeRunnerHE ATM Adapter
4449 1127 0400 ForeRunnerHE ATM
44501129 Firmworks
4451112a Hermes Electronics Company, Ltd.
4452112b Linotype - Hell AG
4453112c Zenith Data Systems
4454112d Ravicad
4455112e Infomedia Microelectronics Inc.
4456112f Imaging Technology Inc
4457 0000 MVC IC-PCI
4458 0001 MVC IM-PCI Video frame grabber/processor
44591130 Computervision
44601131 Philips Semiconductors
4461 1561 USB 1.1 Host Controller
4462 1562 USB 2.0 Host Controller
4463 3400 SmartPCI56(UCB1500) 56K Modem
4464 5400 TriMedia TM1000/1100
4465 5402 TriMedia TM-1300
4466 1244 0f00 Fritz!Card DSL
4467 7130 SAA7130 Video Broadcast Decoder
4468 5168 0138 LiveView FlyVideo 2000
4469 7133 SAA713X Audio+video broadcast decoder
4470 5168 0138 LifeView FlyVideo 3000
4471 5168 0212 LifeView FlyTV Platinum mini
4472 5168 0502 LifeView FlyDVB-T Duo CardBus
4473# PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl)
4474 7134 SAA7134
4475 1043 4842 TV-FM Card 7134
4476 7135 SAA7135 Audio+video broadcast decoder
4477 7145 SAA7145
4478 7146 SAA7146
4479 110a 0000 Fujitsu/Siemens DVB-C card rev1.5
4480 110a ffff Fujitsu/Siemens DVB-C card rev1.5
4481 1131 4f56 KNC1 DVB-S Budget
4482 1131 4f61 Fujitsu-Siemens Activy DVB-S Budget
4483 114b 2003 DVRaptor Video Edit/Capture Card
4484 11bd 0006 DV500 Overlay
4485 11bd 000a DV500 Overlay
4486 11bd 000f DV500 Overlay
4487 13c2 0000 Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
4488 13c2 0001 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
4489 13c2 0002 Technotrend/Hauppauge DVB card rev2.1
4490 13c2 0003 Technotrend/Hauppauge DVB card rev2.1
4491 13c2 0004 Technotrend/Hauppauge DVB card rev2.1
4492 13c2 0006 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
4493 13c2 0008 Technotrend/Hauppauge DVB-T
4494 13c2 000a Octal/Technotrend DVB-C for iTV
4495 13c2 1003 Technotrend-Budget / Hauppauge WinTV-NOVA-S DVB card
4496 13c2 1004 Technotrend-Budget / Hauppauge WinTV-NOVA-C DVB card
4497 13c2 1005 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
4498 13c2 100c Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
4499 13c2 100f Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
4500 13c2 1011 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
4501 13c2 1013 SATELCO Multimedia DVB
4502 13c2 1102 Technotrend/Hauppauge DVB card rev2.1
45031132 Mitel Corp.
4504# This is the new official company name. See disclaimer on www.eicon.com for details!
45051133 Eicon Networks Corporation
4506 7901 EiconCard S90
4507 7902 EiconCard S90
4508 7911 EiconCard S91
4509 7912 EiconCard S91
4510 7941 EiconCard S94
4511 7942 EiconCard S94
4512 7943 EiconCard S94
4513 7944 EiconCard S94
4514 b921 EiconCard P92
4515 b922 EiconCard P92
4516 b923 EiconCard P92
4517 e001 Diva Pro 2.0 S/T
4518 e002 Diva 2.0 S/T PCI
4519 e003 Diva Pro 2.0 U
4520 e004 Diva 2.0 U PCI
4521 e005 Diva 2.01 S/T PCI
4522 e006 Diva CT S/T PCI
4523 e007 Diva CT U PCI
4524 e008 Diva CT Lite S/T PCI
4525 e009 Diva CT Lite U PCI
4526 e00a Diva ISDN+V.90 PCI
4527 e00b Diva 2.02 PCI S/T
4528 e00c Diva 2.02 PCI U
4529 e00d Diva ISDN Pro 3.0 PCI
4530 e00e Diva ISDN+CT S/T PCI Rev 2
4531 e010 Diva Server BRI-2M PCI
4532 110a 0021 Fujitsu Siemens ISDN S0
4533 8001 0014 Diva Server BRI-2M PCI Cornet NQ
4534 e011 Diva Server BRI S/T Rev 2
4535 e012 Diva Server 4BRI-8M PCI
4536 8001 0014 Diva Server 4BRI-8M PCI Cornet NQ
4537 e013 Diva Server 4BRI Rev 2
4538 1133 1300 Diva Server V-4BRI-8
4539 1133 e013 Diva Server 4BRI-8M 2.0 PCI
4540 8001 0014 Diva Server 4BRI-8M 2.0 PCI Cornet NQ
4541 e014 Diva Server PRI-30M PCI
4542 0008 0100 Diva Server PRI-30M PCI
4543 8001 0014 Diva Server PRI-30M PCI Cornet NQ
4544 e015 DIVA Server PRI Rev 2
4545 1133 e015 Diva Server PRI 2.0 PCI
4546 8001 0014 Diva Server PRI 2.0 PCI Cornet NQ
4547 e016 Diva Server Voice 4BRI PCI
4548 8001 0014 Diva Server PRI Cornet NQ
4549 e017 Diva Server Voice 4BRI Rev 2
4550 1133 e017 Diva Server Voice 4BRI-8M 2.0 PCI
4551 8001 0014 Diva Server Voice 4BRI-8M 2.0 PCI Cornet NQ
4552 e018 Diva Server BRI-2M 2.0 PCI
4553 1133 1800 Diva Server V-BRI-2
4554 1133 e018 Diva Server BRI-2M 2.0 PCI
4555 8001 0014 Diva Server BRI-2M 2.0 PCI Cornet NQ
4556 e019 Diva Server Voice PRI Rev 2
4557 1133 e019 Diva Server Voice PRI 2.0 PCI
4558 8001 0014 Diva Server Voice PRI 2.0 PCI Cornet NQ
4559 e01a Diva Server 2FX
4560 e01b Diva Server Voice BRI-2M 2.0 PCI
4561 1133 e01b Diva Server Voice BRI-2M 2.0 PCI
4562 8001 0014 Diva Server Voice BRI-2M 2.0 PCI Cornet NQ
4563 e01c Diva Server PRI Rev 3
4564 1133 1c01 Diva Server PRI/E1/T1-8
4565 1133 1c02 Diva Server PRI/T1-24
4566 1133 1c03 Diva Server PRI/E1-30
4567 1133 1c04 Diva Server PRI/E1/T1
4568 1133 1c05 Diva Server V-PRI/T1-24
4569 1133 1c06 Diva Server V-PRI/E1-30
4570 1133 1c07 Diva Server PRI/E1/T1-8 Cornet NQ
4571 1133 1c08 Diva Server PRI/T1-24 Cornet NQ
4572 1133 1c09 Diva Server PRI/E1-30 Cornet NQ
4573 1133 1c0a Diva Server PRI/E1/T1 Cornet NQ
4574 1133 1c0b Diva Server V-PRI/T1-24 Cornet NQ
4575 1133 1c0c Diva Server V-PRI/E1-30 Cornet NQ
4576 e01e Diva Server 2PRI
4577 1133 1e00 Diva Server V-2PRI/E1-60
4578 1133 1e01 Diva Server V-2PRI/T1-48
4579 1133 1e02 Diva Server 2PRI/E1-60
4580 1133 1e03 Diva Server 2PRI/T1-48
4581 e020 Diva Server 4PRI
4582 1133 2000 Diva Server V-4PRI/E1-120
4583 1133 2001 Diva Server V-4PRI/T1-96
4584 1133 2002 Diva Server 4PRI/E1-120
4585 1133 2003 Diva Server 4PRI/T1-96
4586 e024 Diva Server Analog-4P
4587 1133 2400 Diva Server V-Analog-4P
4588 1133 e024 Diva Server Analog-4P
4589 e028 Diva Server Analog-8P
4590 1133 2800 Diva Server V-Analog-8P
4591 1133 e028 Diva Server Analog-8P
45921134 Mercury Computer Systems
4593 0001 Raceway Bridge
4594 0002 Dual PCI to RapidIO Bridge
45951135 Fuji Xerox Co Ltd
4596 0001 Printer controller
45971136 Momentum Data Systems
45981137 Cisco Systems Inc
45991138 Ziatech Corporation
4600 8905 8905 [STD 32 Bridge]
46011139 Dynamic Pictures, Inc
4602 0001 VGA Compatable 3D Graphics
4603113a FWB Inc
4604113b Network Computing Devices
4605113c Cyclone Microsystems, Inc.
4606 0000 PCI-9060 i960 Bridge
4607 0001 PCI-SDK [PCI i960 Evaluation Platform]
4608 0911 PCI-911 [i960Jx-based Intelligent I/O Controller]
4609 0912 PCI-912 [i960CF-based Intelligent I/O Controller]
4610 0913 PCI-913
4611 0914 PCI-914 [I/O Controller w/ secondary PCI bus]
4612113d Leading Edge Products Inc
4613113e Sanyo Electric Co - Computer Engineering Dept
4614113f Equinox Systems, Inc.
4615 0808 SST-64P Adapter
4616 1010 SST-128P Adapter
4617 80c0 SST-16P DB Adapter
4618 80c4 SST-16P RJ Adapter
4619 80c8 SST-16P Adapter
4620 8888 SST-4P Adapter
4621 9090 SST-8P Adapter
46221140 Intervoice Inc
46231141 Crest Microsystem Inc
46241142 Alliance Semiconductor Corporation
4625 3210 AP6410
4626 6422 ProVideo 6422
4627 6424 ProVideo 6424
4628 6425 ProMotion AT25
4629 643d ProMotion AT3D
46301143 NetPower, Inc
46311144 Cincinnati Milacron
4632 0001 Noservo controller
46331145 Workbit Corporation
4634 8007 NinjaSCSI-32 Workbit
4635 f007 NinjaSCSI-32 KME
4636 f010 NinjaSCSI-32 Workbit
4637 f012 NinjaSCSI-32 Logitec
4638 f013 NinjaSCSI-32 Logitec
4639 f015 NinjaSCSI-32 Melco
46401146 Force Computers
46411147 Interface Corp
4642# Formerly (Schneider & Koch)
46431148 SysKonnect
4644 4000 FDDI Adapter
4645 0e11 b03b Netelligent 100 FDDI DAS Fibre SC
4646 0e11 b03c Netelligent 100 FDDI SAS Fibre SC
4647 0e11 b03d Netelligent 100 FDDI DAS UTP
4648 0e11 b03e Netelligent 100 FDDI SAS UTP
4649 0e11 b03f Netelligent 100 FDDI SAS Fibre MIC
4650 1148 5521 FDDI SK-5521 (SK-NET FDDI-UP)
4651 1148 5522 FDDI SK-5522 (SK-NET FDDI-UP DAS)
4652 1148 5541 FDDI SK-5541 (SK-NET FDDI-FP)
4653 1148 5543 FDDI SK-5543 (SK-NET FDDI-LP)
4654 1148 5544 FDDI SK-5544 (SK-NET FDDI-LP DAS)
4655 1148 5821 FDDI SK-5821 (SK-NET FDDI-UP64)
4656 1148 5822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
4657 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64)
4658 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64)
4659 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
4660 4200 Token Ring adapter
4661 4300 SK-98xx Gigabit Ethernet Server Adapter
4662 1148 9821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
4663 1148 9822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
4664 1148 9841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
4665 1148 9842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
4666 1148 9843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
4667 1148 9844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
4668 1148 9861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
4669 1148 9862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
4670 1148 9871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
4671 1148 9872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
4672 1259 2970 AT-2970SX Gigabit Ethernet Adapter
4673 1259 2971 AT-2970LX Gigabit Ethernet Adapter
4674 1259 2972 AT-2970TX Gigabit Ethernet Adapter
4675 1259 2973 AT-2971SX Gigabit Ethernet Adapter
4676 1259 2974 AT-2971T Gigabit Ethernet Adapter
4677 1259 2975 AT-2970SX/2SC Gigabit Ethernet Adapter
4678 1259 2976 AT-2970LX/2SC Gigabit Ethernet Adapter
4679 1259 2977 AT-2970TX/2TX Gigabit Ethernet Adapter
4680 4320 SK-98xx V2.0 Gigabit Ethernet Adapter
4681 1148 0121 Marvell RDK-8001 Adapter
4682 1148 0221 Marvell RDK-8002 Adapter
4683 1148 0321 Marvell RDK-8003 Adapter
4684 1148 0421 Marvell RDK-8004 Adapter
4685 1148 0621 Marvell RDK-8006 Adapter
4686 1148 0721 Marvell RDK-8007 Adapter
4687 1148 0821 Marvell RDK-8008 Adapter
4688 1148 0921 Marvell RDK-8009 Adapter
4689 1148 1121 Marvell RDK-8011 Adapter
4690 1148 1221 Marvell RDK-8012 Adapter
4691 1148 3221 SK-9521 V2.0 10/100/1000Base-T Adapter
4692 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
4693 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
4694 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4695 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4696 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4697 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
4698 1148 9521 SK-9521 10/100/1000Base-T Adapter
4699 4400 SK-9Dxx Gigabit Ethernet Adapter
4700 4500 SK-9Mxx Gigabit Ethernet Adapter
4701 9000 SK-9Sxx Gigabit Ethernet Server Adapter PCI-X
4702 9843 [Fujitsu] Gigabit Ethernet
4703 9e00 SK-9Exx 10/100/1000Base-T Adapter
4704 1148 2100 SK-9E21 Server Adapter
4705 1148 21d0 SK-9E21D 10/100/1000Base-T Adapter
4706 1148 2200 SK-9E22 Server Adapter
4707 1148 8100 SK-9E81 Server Adapter
4708 1148 8200 SK-9E82 Server Adapter
4709 1148 9100 SK-9E91 Server Adapter
4710 1148 9200 SK-9E92 Server Adapter
47111149 Win System Corporation
4712114a VMIC
4713 5579 VMIPCI-5579 (Reflective Memory Card)
4714 5587 VMIPCI-5587 (Reflective Memory Card)
4715 6504 VMIC PCI 7755 FPGA
4716 7587 VMIVME-7587
4717114b Canopus Co., Ltd
4718114c Annabooks
4719114d IC Corporation
4720114e Nikon Systems Inc
4721114f Digi International
4722 0002 AccelePort EPC
4723 0003 RightSwitch SE-6
4724 0004 AccelePort Xem
4725 0005 AccelePort Xr
4726 0006 AccelePort Xr,C/X
4727 0009 AccelePort Xr/J
4728 000a AccelePort EPC/J
4729 000c DataFirePRIme T1 (1-port)
4730 000d SyncPort 2-Port (x.25/FR)
4731 0011 AccelePort 8r EIA-232 (IBM)
4732 0012 AccelePort 8r EIA-422
4733 0013 AccelePort Xr
4734 0014 AccelePort 8r EIA-422
4735 0015 AccelePort Xem
4736 0016 AccelePort EPC/X
4737 0017 AccelePort C/X
4738 001a DataFirePRIme E1 (1-port)
4739 001b AccelePort C/X (IBM)
4740 001d DataFire RAS T1/E1/PRI
4741 114f 0050 DataFire RAS E1 Adapter
4742 114f 0051 DataFire RAS Dual E1 Adapter
4743 114f 0052 DataFire RAS T1 Adapter
4744 114f 0053 DataFire RAS Dual T1 Adapter
4745 0023 AccelePort RAS
4746 0024 DataFire RAS B4 ST/U
4747 114f 0030 DataFire RAS BRI U Adapter
4748 114f 0031 DataFire RAS BRI S/T Adapter
4749 0026 AccelePort 4r 920
4750 0027 AccelePort Xr 920
4751 0028 ClassicBoard 4
4752 0029 ClassicBoard 8
4753 0034 AccelePort 2r 920
4754 0035 DataFire DSP T1/E1/PRI cPCI
4755 0040 AccelePort Xp
4756 0042 AccelePort 2p
4757 0043 AccelePort 4p
4758 0044 AccelePort 8p
4759 0045 AccelePort 16p
4760 004e AccelePort 32p
4761 0070 Datafire Micro V IOM2 (Europe)
4762 0071 Datafire Micro V (Europe)
4763 0072 Datafire Micro V IOM2 (North America)
4764 0073 Datafire Micro V (North America)
4765 00b0 Digi Neo 4
4766 00b1 Digi Neo 8
4767 00c8 Digi Neo 2 DB9
4768 00c9 Digi Neo 2 DB9 PRI
4769 00ca Digi Neo 2 RJ45
4770 00cb Digi Neo 2 RJ45 PRI
4771 00d0 ClassicBoard 4 422
4772 00d1 ClassicBoard 8 422
4773 6001 Avanstar
47741150 Thinking Machines Corp
47751151 JAE Electronics Inc.
47761152 Megatek
47771153 Land Win Electronic Corp
47781154 Melco Inc
47791155 Pine Technology Ltd
47801156 Periscope Engineering
47811157 Avsys Corporation
47821158 Voarx R & D Inc
4783 3011 Tokenet/vg 1001/10m anylan
4784 9050 Lanfleet/Truevalue
4785 9051 Lanfleet/Truevalue
47861159 Mutech Corp
4787 0001 MV-1000
4788115a Harlequin Ltd
4789115b Parallax Graphics
4790115c Photron Ltd.
4791115d Xircom
4792 0003 Cardbus Ethernet 10/100
4793 1014 0181 10/100 EtherJet Cardbus Adapter
4794 1014 1181 10/100 EtherJet Cardbus Adapter
4795 1014 8181 10/100 EtherJet Cardbus Adapter
4796 1014 9181 10/100 EtherJet Cardbus Adapter
4797 115d 0181 Cardbus Ethernet 10/100
4798 115d 1181 Cardbus Ethernet 10/100
4799 1179 0181 Cardbus Ethernet 10/100
4800 8086 8181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
4801 8086 9181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
4802 0005 Cardbus Ethernet 10/100
4803 1014 0182 10/100 EtherJet Cardbus Adapter
4804 1014 1182 10/100 EtherJet Cardbus Adapter
4805 115d 0182 Cardbus Ethernet 10/100
4806 115d 1182 Cardbus Ethernet 10/100
4807 0007 Cardbus Ethernet 10/100
4808 1014 0182 10/100 EtherJet Cardbus Adapter
4809 1014 1182 10/100 EtherJet Cardbus Adapter
4810 115d 0182 Cardbus Ethernet 10/100
4811 115d 1182 Cardbus Ethernet 10/100
4812 000b Cardbus Ethernet 10/100
4813 1014 0183 10/100 EtherJet Cardbus Adapter
4814 115d 0183 Cardbus Ethernet 10/100
4815 000c Mini-PCI V.90 56k Modem
4816 000f Cardbus Ethernet 10/100
4817 1014 0183 10/100 EtherJet Cardbus Adapter
4818 115d 0183 Cardbus Ethernet 10/100
4819 00d4 Mini-PCI K56Flex Modem
4820 0101 Cardbus 56k modem
4821 115d 1081 Cardbus 56k Modem
4822 0103 Cardbus Ethernet + 56k Modem
4823 1014 9181 Cardbus 56k Modem
4824 1115 1181 Cardbus Ethernet 100 + 56k Modem
4825 115d 1181 CBEM56G-100 Ethernet + 56k Modem
4826 8086 9181 PRO/100 LAN + Modem56 CardBus
4827115e Peer Protocols Inc
4828115f Maxtor Corporation
48291160 Megasoft Inc
48301161 PFU Limited
48311162 OA Laboratory Co Ltd
48321163 Rendition
4833 0001 Verite 1000
4834 2000 Verite V2000/V2100/V2200
4835 1092 2000 Stealth II S220
48361164 Advanced Peripherals Technologies
48371165 Imagraph Corporation
4838 0001 Motion TPEG Recorder/Player with audio
48391166 ServerWorks
4840 0000 CMIC-LE
4841 0005 CNB20-LE Host Bridge
4842 0006 CNB20HE Host Bridge
4843 0007 CNB20-LE Host Bridge
4844 0008 CNB20HE Host Bridge
4845 0009 CNB20LE Host Bridge
4846 0010 CIOB30
4847 0011 CMIC-HE
4848 0012 CMIC-WS Host Bridge (GC-LE chipset)
4849 0013 CNB20-HE Host Bridge
4850 0014 CMIC-LE Host Bridge (GC-LE chipset)
4851 0015 CMIC-GC Host Bridge
4852 0016 CMIC-GC Host Bridge
4853 0017 GCNB-LE Host Bridge
4854 0101 CIOB-X2 PCI-X I/O Bridge
4855 0110 CIOB-E I/O Bridge with Gigabit Ethernet
4856 0200 OSB4 South Bridge
4857 0201 CSB5 South Bridge
4858 4c53 1080 CT8 mainboard
4859 0203 CSB6 South Bridge
4860 0211 OSB4 IDE Controller
4861 0212 CSB5 IDE Controller
4862 4c53 1080 CT8 mainboard
4863 0213 CSB6 RAID/IDE Controller
4864 0217 CSB6 IDE Controller
4865 0220 OSB4/CSB5 OHCI USB Controller
4866 4c53 1080 CT8 mainboard
4867 0221 CSB6 OHCI USB Controller
4868 0225 CSB5 LPC bridge
4869# cancelled
4870 4c53 1080 CT8 mainboard
4871 0227 GCLE-2 Host Bridge
4872 0230 CSB5 LPC bridge
4873 4c53 1080 CT8 mainboard
4874 0240 K2 SATA
4875 0241 K2 SATA
4876 0242 K2 SATA
48771167 Mutoh Industries Inc
48781168 Thine Electronics Inc
48791169 Centre for Development of Advanced Computing
4880116a Polaris Communications
4881 6100 Bus/Tag Channel
4882 6800 Escon Channel
4883 7100 Bus/Tag Channel
4884 7800 Escon Channel
4885116b Connectware Inc
4886116c Intelligent Resources Integrated Systems
4887116d Martin-Marietta
4888116e Electronics for Imaging
4889116f Workstation Technology
48901170 Inventec Corporation
48911171 Loughborough Sound Images Plc
48921172 Altera Corporation
48931173 Adobe Systems, Inc
48941174 Bridgeport Machines
48951175 Mitron Computer Inc.
48961176 SBE Incorporated
48971177 Silicon Engineering
48981178 Alfa, Inc.
4899 afa1 Fast Ethernet Adapter
49001179 Toshiba America Info Systems
4901 0103 EX-IDE Type-B
4902 0404 DVD Decoder card
4903 0406 Tecra Video Capture device
4904 0407 DVD Decoder card (Version 2)
4905 0601 CPU to PCI bridge
4906 0603 ToPIC95 PCI to CardBus Bridge for Notebooks
4907 060a ToPIC95
4908 060f ToPIC97
4909 0617 ToPIC100 PCI to Cardbus Bridge with ZV Support
4910 0618 CPU to PCI and PCI to ISA bridge
4911# Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID?
4912 0701 FIR Port
4913 0804 TC6371AF SmartMedia Controller
4914 0805 SD TypA Controller
4915 0d01 FIR Port Type-DO
4916 1179 0001 FIR Port Type-DO
4917117a A-Trend Technology
4918117b L G Electronics, Inc.
4919117c Atto Technology
4920117d Becton & Dickinson
4921117e T/R Systems
4922117f Integrated Circuit Systems
49231180 Ricoh Co Ltd
4924 0465 RL5c465
4925 0466 RL5c466
4926 0475 RL5c475
4927 144d c006 vpr Matrix 170B4 CardBus bridge
4928 0476 RL5c476 II
4929 1014 0185 ThinkPad A/T/X Series
4930 104d 80df Vaio PCG-FX403
4931 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
4932 14ef 0220 PCD-RP-220S
4933 0477 RL5c477
4934 0478 RL5c478
4935 1014 0184 ThinkPad A30p (2653-64G)
4936 0522 R5C522 IEEE 1394 Controller
4937 1014 01cf ThinkPad A30p (2653-64G)
4938 0551 R5C551 IEEE 1394 Controller
4939 144d c006 vpr Matrix 170B4
4940 0552 R5C552 IEEE 1394 Controller
4941 1014 0511 ThinkPad A/T/X Series
4942 0576 R5C576 SD Bus Host Adapter
4943 0592 R5C592 Memory Stick Bus Host Adapter
49441181 Telmatics International
49451183 Fujikura Ltd
49461184 Forks Inc
49471185 Dataworld International Ltd
49481186 D-Link System Inc
4949 0100 DC21041
4950 1002 DL10050 Sundance Ethernet
4951 1186 1002 DFE-550TX
4952 1186 1012 DFE-580TX
4953 1025 AirPlus Xtreme G DWL-G650 Adapter
4954 1026 AirXpert DWL-AG650 Wireless Cardbus Adapter
4955 1043 AirXpert DWL-AG650 Wireless Cardbus Adapter
4956 1300 RTL8139 Ethernet
4957 1186 1300 DFE-538TX 10/100 Ethernet Adapter
4958 1186 1301 DFE-530TX+ 10/100 Ethernet Adapter
4959 1340 DFE-690TXD CardBus PC Card
4960 1541 DFE-680TXD CardBus PC Card
4961 1561 DRP-32TXD Cardbus PC Card
4962 2027 AirPlus Xtreme G DWL-G520 Adapter
4963 3203 AirPlus Xtreme G DWL-G520 Adapter
4964 3300 DWL-510 2.4GHz Wireless PCI Adapter
4965 3a03 AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
4966 3a04 AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
4967 3a05 AirPro DWL-AB520 Multimode Wireless PCI Adapter
4968 3a07 AirXpert DWL-AG650 Wireless Cardbus Adapter
4969 3a08 AirXpert DWL-AG520 Wireless PCI Adapter
4970 3a10 AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
4971 3a11 AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
4972 3a12 AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
4973 3a13 AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
4974 3a14 AirPremier DWL-AG530 Wireless PCI Adapter
4975 3a63 AirXpert DWL-AG660 Wireless Cardbus Adapter
4976 3b05 DWL-G650+ CardBus PC Card
4977 4000 DL2000-based Gigabit Ethernet
4978 4300 DGE-528T Gigabit Ethernet Adapter
4979 4c00 Gigabit Ethernet Adapter
4980 1186 4c00 DGE-530T Gigabit Ethernet Adapter
4981 8400 D-Link DWL-650+ CardBus PC Card
49821187 Advanced Technology Laboratories, Inc.
49831188 Shima Seiki Manufacturing Ltd.
49841189 Matsushita Electronics Co Ltd
4985118a Hilevel Technology
4986118b Hypertec Pty Limited
4987118c Corollary, Inc
4988 0014 PCIB [C-bus II to PCI bus host bridge chip]
4989 1117 Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
4990118d BitFlow Inc
4991 0001 Raptor-PCI framegrabber
4992 0012 Model 12 Road Runner Frame Grabber
4993 0014 Model 14 Road Runner Frame Grabber
4994 0024 Model 24 Road Runner Frame Grabber
4995 0044 Model 44 Road Runner Frame Grabber
4996 0112 Model 12 Road Runner Frame Grabber
4997 0114 Model 14 Road Runner Frame Grabber
4998 0124 Model 24 Road Runner Frame Grabber
4999 0144 Model 44 Road Runner Frame Grabber
5000 0212 Model 12 Road Runner Frame Grabber
5001 0214 Model 14 Road Runner Frame Grabber
5002 0224 Model 24 Road Runner Frame Grabber
5003 0244 Model 44 Road Runner Frame Grabber
5004 0312 Model 12 Road Runner Frame Grabber
5005 0314 Model 14 Road Runner Frame Grabber
5006 0324 Model 24 Road Runner Frame Grabber
5007 0344 Model 44 Road Runner Frame Grabber
5008118e Hermstedt GmbH
5009118f Green Logic
50101190 Tripace
5011 c731 TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
50121191 Artop Electronic Corp
5013 0003 SCSI Cache Host Adapter
5014 0004 ATP8400
5015 0005 ATP850UF
5016 0006 ATP860 NO-BIOS
5017 0007 ATP860
5018 0008 ATP865 NO-ROM
5019 0009 ATP865
5020 8002 AEC6710 SCSI-2 Host Adapter
5021 8010 AEC6712UW SCSI
5022 8020 AEC6712U SCSI
5023 8030 AEC6712S SCSI
5024 8040 AEC6712D SCSI
5025 8050 AEC6712SUW SCSI
5026 8060 AEC6712 SCSI
5027 8080 AEC67160 SCSI
5028 8081 AEC67160S SCSI
5029 808a AEC67162 2-ch. LVD SCSI
50301192 Densan Company Ltd
50311193 Zeitnet Inc.
5032 0001 1221
5033 0002 1225
50341194 Toucan Technology
50351195 Ratoc System Inc
50361196 Hytec Electronics Ltd
50371197 Gage Applied Sciences, Inc.
5038 010c CompuScope 82G 8bit 2GS/s Analog Input Card
50391198 Lambda Systems Inc
50401199 Attachmate Corporation
5041119a Mind Share, Inc.
5042119b Omega Micro Inc.
5043 1221 82C092G
5044119c Information Technology Inst.
5045119d Bug, Inc. Sapporo Japan
5046119e Fujitsu Microelectronics Ltd.
5047 0001 FireStream 155
5048 0003 FireStream 50
5049119f Bull HN Information Systems
505011a0 Convex Computer Corporation
505111a1 Hamamatsu Photonics K.K.
505211a2 Sierra Research and Technology
505311a3 Deuretzbacher GmbH & Co. Eng. KG
505411a4 Barco Graphics NV
505511a5 Microunity Systems Eng. Inc
505611a6 Pure Data Ltd.
505711a7 Power Computing Corp.
505811a8 Systech Corp.
505911a9 InnoSys Inc.
5060 4240 AMCC S933Q Intelligent Serial Card
506111aa Actel
5062# Formerly Galileo Technology, Inc.
506311ab Marvell Technology Group Ltd.
5064 0146 GT-64010/64010A System Controller
5065 138f W8300 802.11 Adapter (rev 07)
5066 1fa6 Marvell W8300 802.11 Adapter
5067 1fa7 88W8310 and 88W8000G [Libertas] 802.11g client chipset
5068 4320 Gigabit Ethernet Controller
5069 1019 0f38 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
5070 1019 8001 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
5071 1043 173c Marvell 88E8001 Gigabit Ethernet Controller (Asus)
5072 1043 811a Marvell 88E8001 Gigabit Ethernet Controller (Asus)
5073 105b 0c19 Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
5074 10b8 b452 SMC EZ Card 1000 (SMC9452TXV.2)
5075 11ab 0121 Marvell RDK-8001
5076 11ab 0321 Marvell RDK-8003
5077 11ab 1021 Marvell RDK-8010
5078 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
5079 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
5080 1458 e000 Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
5081 147b 1406 Marvell 88E8001 Gigabit Ethernet Controller (Abit)
5082 15d4 0047 Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
5083 1695 9025 Marvell 88E8001 Gigabit Ethernet Controller (Epox)
5084 17f2 1c03 Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
5085 270f 2803 Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
5086 4350 Fast Ethernet Controller
5087 1179 0001 Marvell 88E8035 Fast Ethernet Controller (Toshiba)
5088 11ab 3521 Marvell RDK-8035
5089 1854 000d Marvell 88E8035 Fast Ethernet Controller (LGE)
5090 1854 000e Marvell 88E8035 Fast Ethernet Controller (LGE)
5091 1854 000f Marvell 88E8035 Fast Ethernet Controller (LGE)
5092 1854 0011 Marvell 88E8035 Fast Ethernet Controller (LGE)
5093 1854 0012 Marvell 88E8035 Fast Ethernet Controller (LGE)
5094 1854 0016 Marvell 88E8035 Fast Ethernet Controller (LGE)
5095 1854 0017 Marvell 88E8035 Fast Ethernet Controller (LGE)
5096 1854 0018 Marvell 88E8035 Fast Ethernet Controller (LGE)
5097 1854 0019 Marvell 88E8035 Fast Ethernet Controller (LGE)
5098 1854 001c Marvell 88E8035 Fast Ethernet Controller (LGE)
5099 1854 001e Marvell 88E8035 Fast Ethernet Controller (LGE)
5100 1854 0020 Marvell 88E8035 Fast Ethernet Controller (LGE)
5101 4351 Fast Ethernet Controller
5102 107b 4009 Marvell 88E8036 Fast Ethernet Controller (Wistron)
5103 10f7 8338 Marvell 88E8036 Fast Ethernet Controller (Panasonic)
5104 1179 0001 Marvell 88E8036 Fast Ethernet Controller (Toshiba)
5105 1179 ff00 Marvell 88E8036 Fast Ethernet Controller (Compal)
5106 1179 ff10 Marvell 88E8036 Fast Ethernet Controller (Inventec)
5107 11ab 3621 Marvell RDK-8036
5108 13d1 ac12 Abocom EFE3K - 10/100 Ethernet Expresscard
5109 161f 203d Marvell 88E8036 Fast Ethernet Controller (Arima)
5110 1854 000d Marvell 88E8036 Fast Ethernet Controller (LGE)
5111 1854 000e Marvell 88E8036 Fast Ethernet Controller (LGE)
5112 1854 000f Marvell 88E8036 Fast Ethernet Controller (LGE)
5113 1854 0011 Marvell 88E8036 Fast Ethernet Controller (LGE)
5114 1854 0012 Marvell 88E8036 Fast Ethernet Controller (LGE)
5115 1854 0016 Marvell 88E8036 Fast Ethernet Controller (LGE)
5116 1854 0017 Marvell 88E8036 Fast Ethernet Controller (LGE)
5117 1854 0018 Marvell 88E8036 Fast Ethernet Controller (LGE)
5118 1854 0019 Marvell 88E8036 Fast Ethernet Controller (LGE)
5119 1854 001c Marvell 88E8036 Fast Ethernet Controller (LGE)
5120 1854 001e Marvell 88E8036 Fast Ethernet Controller (LGE)
5121 1854 0020 Marvell 88E8036 Fast Ethernet Controller (LGE)
5122 4360 Gigabit Ethernet Controller
5123 1043 8134 Marvell 88E8052 Gigabit Ethernet Controller (Asus)
5124 107b 4009 Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
5125 11ab 5221 Marvell RDK-8052
5126 1458 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
5127 1462 052c Marvell 88E8052 Gigabit Ethernet Controller (MSI)
5128 1849 8052 Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
5129 1940 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
5130 a0a0 0509 Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
5131 4361 Gigabit Ethernet Controller
5132 107b 3015 Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
5133 11ab 5021 Marvell 88E8050 Gigabit Ethernet Controller (Intel)
5134 8086 3063 D925XCVLK mainboard
5135 4362 Gigabit Ethernet Controller
5136 103c 2a0d Marvell 88E8053 Gigabit Ethernet Controller (Asus)
5137 1043 8142 Marvell 88E8053 Gigabit Ethernet Controller (Asus)
5138 109f 3197 Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
5139 10f7 8338 Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
5140 10fd a430 Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
5141 1179 0001 Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
5142 1179 ff00 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
5143 1179 ff10 Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
5144 11ab 5321 Marvell RDK-8053
5145 1297 c240 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5146 1297 c241 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5147 1297 c242 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5148 1297 c243 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5149 1297 c244 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5150 13d1 ac11 Abocom EGE5K - Giga Ethernet Expresscard
5151 1458 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
5152 1462 058c Marvell 88E8053 Gigabit Ethernet Controller (MSI)
5153 14c0 0012 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
5154 1558 04a0 Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
5155 15bd 1003 Marvell 88E8053 Gigabit Ethernet Controller (DFI)
5156 161f 203c Marvell 88E8053 Gigabit Ethernet Controller (Arima)
5157 161f 203d Marvell 88E8053 Gigabit Ethernet Controller (Arima)
5158 1695 9029 Marvell 88E8053 Gigabit Ethernet Controller (Epox)
5159 17f2 2c08 Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
5160 17ff 0585 Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
5161 1849 8053 Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
5162 1854 000b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5163 1854 000c Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5164 1854 0010 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5165 1854 0013 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5166 1854 0014 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5167 1854 0015 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5168 1854 001a Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5169 1854 001b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5170 1854 001d Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5171 1854 001f Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5172 1854 0021 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5173 1854 0022 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5174 1940 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
5175 270f 2801 Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
5176 a0a0 0506 Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
5177 4611 GT-64115 System Controller
5178 4620 GT-64120/64120A/64121A System Controller
5179 4801 GT-48001
5180 5005 Belkin F5D5005 Gigabit Desktop Network PCI Card
5181 5040 MV88SX5040 4-port SATA I PCI-X Controller
5182 5041 MV88SX5041 4-port SATA I PCI-X Controller
5183 5080 MV88SX5080 8-port SATA I PCI-X Controller
5184 5081 MV88SX5081 8-port SATA I PCI-X Controller
5185 6041 MV88SX6041 4-port SATA II PCI-X Controller
5186 6081 MV88SX6081 8-port SATA II PCI-X Controller
5187 6460 MV64360/64361/64362 System Controller
5188 f003 GT-64010 Primary Image Piranha Image Generator
518911ac Canon Information Systems Research Aust.
519011ad Lite-On Communications Inc
5191 0002 LNE100TX
5192 11ad 0002 LNE100TX
5193 11ad 0003 LNE100TX
5194 11ad f003 LNE100TX
5195 11ad ffff LNE100TX
5196 1385 f004 FA310TX
5197 c115 LNE100TX [Linksys EtherFast 10/100]
5198 11ad c001 LNE100TX [ver 2.0]
519911ae Aztech System Ltd
520011af Avid Technology Inc.
5201 0001 [Cinema]
520211b0 V3 Semiconductor Inc.
5203 0002 V300PSC
5204 0292 V292PBC [Am29030/40 Bridge]
5205 0960 V96xPBC
5206 c960 V96DPC
520711b1 Apricot Computers
520811b2 Eastman Kodak
520911b3 Barr Systems Inc.
521011b4 Leitch Technology International
521111b5 Radstone Technology Plc
521211b6 United Video Corp
521311b7 Motorola
521411b8 XPoint Technologies, Inc
5215 0001 Quad PeerMaster
521611b9 Pathlight Technology Inc.
5217 c0ed SSA Controller
521811ba Videotron Corp
521911bb Pyramid Technology
522011bc Network Peripherals Inc
5221 0001 NP-PCI
522211bd Pinnacle Systems Inc.
522311be International Microcircuits Inc
522411bf Astrodesign, Inc.
522511c0 Hewlett Packard
522611c1 Agere Systems (former Lucent Microelectronics)
5227 0440 56k WinModem
5228 1033 8015 LT WinModem 56k Data+Fax+Voice+Dsvd
5229 1033 8047 LT WinModem 56k Data+Fax+Voice+Dsvd
5230 1033 804f LT WinModem 56k Data+Fax+Voice+Dsvd
5231 10cf 102c LB LT Modem V.90 56k
5232 10cf 104a BIBLO LT Modem 56k
5233 10cf 105f LB2 LT Modem V.90 56k
5234 1179 0001 Internal V.90 Modem
5235 11c1 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5236 122d 4101 MDP7800-U Modem
5237 122d 4102 MDP7800SP-U Modem
5238 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
5239 13e0 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5240 13e0 0441 LT WinModem 56k Data+Fax+Voice+Dsvd
5241 13e0 0450 LT WinModem 56k Data+Fax+Voice+Dsvd
5242 13e0 f100 LT WinModem 56k Data+Fax+Voice+Dsvd
5243 13e0 f101 LT WinModem 56k Data+Fax+Voice+Dsvd
5244 144d 2101 LT56PV Modem
5245 149f 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5246 0441 56k WinModem
5247 1033 804d LT WinModem 56k Data+Fax
5248 1033 8065 LT WinModem 56k Data+Fax
5249 1092 0440 Supra 56i
5250 1179 0001 Internal V.90 Modem
5251 11c1 0440 LT WinModem 56k Data+Fax
5252 11c1 0441 LT WinModem 56k Data+Fax
5253 122d 4100 MDP7800-U Modem
5254 13e0 0040 LT WinModem 56k Data+Fax
5255 13e0 0100 LT WinModem 56k Data+Fax
5256 13e0 0410 LT WinModem 56k Data+Fax
5257 13e0 0420 TelePath Internet 56k WinModem
5258 13e0 0440 LT WinModem 56k Data+Fax
5259 13e0 0443 LT WinModem 56k Data+Fax
5260 13e0 f102 LT WinModem 56k Data+Fax
5261 1416 9804 CommWave 56k Modem
5262 141d 0440 LT WinModem 56k Data+Fax
5263 144f 0441 Lucent 56k V.90 DF Modem
5264 144f 0449 Lucent 56k V.90 DF Modem
5265 144f 110d Lucent Win Modem
5266 1468 0441 Presario 56k V.90 DF Modem
5267 1668 0440 Lucent Win Modem
5268 0442 56k WinModem
5269 11c1 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5270 11c1 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5271 13e0 0412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5272 13e0 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5273 13fc 2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5274 144d 2104 LT56PT Modem
5275 144f 1104 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5276 149f 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5277 1668 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5278 0443 LT WinModem
5279 0444 LT WinModem
5280 0445 LT WinModem
5281 8086 2203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
5282 8086 2204 PRO/100+ MiniPCI on Armada E500
5283 0446 LT WinModem
5284 0447 LT WinModem
5285 0448 WinModem 56k
5286 1014 0131 Lucent Win Modem
5287 1033 8066 LT WinModem 56k Data+Fax+Voice+Dsvd
5288 13e0 0030 56k Voice Modem
5289 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
5290# Actiontech eth+modem card as used by Dell &c.
5291 1668 2400 LT WinModem 56k (MiniPCI Ethernet+Modem)
5292 0449 WinModem 56k
5293 0e11 b14d 56k V.90 Modem
5294 13e0 0020 LT WinModem 56k Data+Fax
5295 13e0 0041 TelePath Internet 56k WinModem
5296 1436 0440 Lucent Win Modem
5297 144f 0449 Lucent 56k V.90 DFi Modem
5298 1468 0410 IBM ThinkPad T23 (2647-4MG)
5299 1468 0440 Lucent Win Modem
5300 1468 0449 Presario 56k V.90 DFi Modem
5301 044a F-1156IV WinModem (V90, 56KFlex)
5302 10cf 1072 LB Global LT Modem
5303 13e0 0012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5304 13e0 0042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5305 144f 1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5306 044b LT WinModem
5307 044c LT WinModem
5308 044d LT WinModem
5309 044e LT WinModem
5310 044f V90 WildWire Modem
5311 0450 LT WinModem
5312 1033 80a8 Versa Note Vxi
5313 144f 4005 Magnia SG20
5314 0451 LT WinModem
5315 0452 LT WinModem
5316 0453 LT WinModem
5317 0454 LT WinModem
5318 0455 LT WinModem
5319 0456 LT WinModem
5320 0457 LT WinModem
5321 0458 LT WinModem
5322 0459 LT WinModem
5323 045a LT WinModem
5324 045c LT WinModem
5325 0461 V90 WildWire Modem
5326 0462 V90 WildWire Modem
5327 0480 Venus Modem (V90, 56KFlex)
5328 048c V.92 56K WinModem
5329# InPorte Home Internal 56k Modem/fax/answering machine/SMS Features
5330 048f V.92 56k WinModem
5331 5801 USB
5332 5802 USS-312 USB Controller
5333# 4 port PCI USB Controller made by Agere (formely Lucent)
5334 5803 USS-344S USB Controller
5335 5811 FW323
5336 8086 524c D865PERL mainboard
5337 dead 0800 FireWire Host Bus Adapter
5338 ab10 WL60010 Wireless LAN MAC
5339 ab11 WL60040 Multimode Wireles LAN MAC
5340 11c1 ab12 WaveLAN 11abg Cardbus card (Model 1102)
5341 11c1 ab13 WaveLAN 11abg MiniPCI card (Model 0512)
5342 11c1 ab15 WaveLAN 11abg Cardbus card (Model 1106)
5343 11c1 ab16 WaveLAN 11abg MiniPCI card (Model 0516)
5344 ab20 ORiNOCO PCI Adapter
5345 ab21 Agere Wireless PCI Adapter
5346 ab30 Hermes2 Mini-PCI WaveLAN a/b/g
5347 14cd 2012 Hermes2 Mini-PCI WaveLAN a/b/g
534811c2 Sand Microelectronics
534911c3 NEC Corporation
535011c4 Document Technologies, Inc
535111c5 Shiva Corporation
535211c6 Dainippon Screen Mfg. Co. Ltd
535311c7 D.C.M. Data Systems
535411c8 Dolphin Interconnect Solutions AS
5355 0658 PSB32 SCI-Adapter D31x
5356 d665 PSB64 SCI-Adapter D32x
5357 d667 PSB66 SCI-Adapter D33x
535811c9 Magma
5359 0010 16-line serial port w/- DMA
5360 0011 4-line serial port w/- DMA
536111ca LSI Systems, Inc
536211cb Specialix Research Ltd.
5363 2000 PCI_9050
5364 11cb 0200 SX
5365 11cb b008 I/O8+
5366 4000 SUPI_1
5367 8000 T225
536811cc Michels & Kleberhoff Computer GmbH
536911cd HAL Computer Systems, Inc.
537011ce Netaccess
537111cf Pioneer Electronic Corporation
537211d0 Lockheed Martin Federal Systems-Manassas
537311d1 Auravision
5374 01f7 VxP524
537511d2 Intercom Inc.
537611d3 Trancell Systems Inc
537711d4 Analog Devices
5378 1535 Blackfin BF535 processor
5379 1805 SM56 PCI modem
5380 1889 AD1889 sound chip
538111d5 Ikon Corporation
5382 0115 10115
5383 0117 10117
538411d6 Tekelec Telecom
538511d7 Trenton Technology, Inc.
538611d8 Image Technologies Development
538711d9 TEC Corporation
538811da Novell
538911db Sega Enterprises Ltd
539011dc Questra Corporation
539111dd Crosfield Electronics Limited
539211de Zoran Corporation
5393 6057 ZR36057PQC Video cutting chipset
5394 1031 7efe DC10 Plus
5395 1031 fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
5396 13ca 4231 JPEG/TV Card
5397 6120 ZR36120
5398 1328 f001 Cinemaster C DVD Decoder
539911df New Wave PDG
540011e0 Cray Communications A/S
540111e1 GEC Plessey Semi Inc.
540211e2 Samsung Information Systems America
540311e3 Quicklogic Corporation
5404 5030 PC Watchdog
540511e4 Second Wave Inc
540611e5 IIX Consulting
540711e6 Mitsui-Zosen System Research
540811e7 Toshiba America, Elec. Company
540911e8 Digital Processing Systems Inc.
541011e9 Highwater Designs Ltd.
541111ea Elsag Bailey
541211eb Formation Inc.
541311ec Coreco Inc
541411ed Mediamatics
541511ee Dome Imaging Systems Inc
541611ef Nicolet Technologies B.V.
541711f0 Compu-Shack
5418 4231 FDDI
5419 4232 FASTline UTP Quattro
5420 4233 FASTline FO
5421 4234 FASTline UTP
5422 4235 FASTline-II UTP
5423 4236 FASTline-II FO
5424 4731 GIGAline
542511f1 Symbios Logic Inc
542611f2 Picture Tel Japan K.K.
542711f3 Keithley Metrabyte
542811f4 Kinetic Systems Corporation
5429 2915 CAMAC controller
543011f5 Computing Devices International
543111f6 Compex
5432 0112 ENet100VG4
5433 0113 FreedomLine 100
5434 1401 ReadyLink 2000
5435 2011 RL100-ATX 10/100
5436 11f6 2011 RL100-ATX
5437 2201 ReadyLink 100TX (Winbond W89C840)
5438 11f6 2011 ReadyLink 100TX
5439 9881 RL100TX Fast Ethernet
544011f7 Scientific Atlanta
544111f8 PMC-Sierra Inc.
5442 7375 PM7375 [LASAR-155 ATM SAR]
544311f9 I-Cube Inc
544411fa Kasan Electronics Company, Ltd.
544511fb Datel Inc
544611fc Silicon Magic
544711fd High Street Consultants
544811fe Comtrol Corporation
5449 0001 RocketPort 32 port w/external I/F
5450 0002 RocketPort 8 port w/external I/F
5451 0003 RocketPort 16 port w/external I/F
5452 0004 RocketPort 4 port w/quad cable
5453 0005 RocketPort 8 port w/octa cable
5454 0006 RocketPort 8 port w/RJ11 connectors
5455 0007 RocketPort 4 port w/RJ11 connectors
5456 0008 RocketPort 8 port w/ DB78 SNI (Siemens) connector
5457 0009 RocketPort 16 port w/ DB78 SNI (Siemens) connector
5458 000a RocketPort Plus 4 port
5459 000b RocketPort Plus 8 port
5460 000c RocketModem 6 port
5461 000d RocketModem 4-port
5462 000e RocketPort Plus 2 port RS232
5463 000f RocketPort Plus 2 port RS422
5464 0801 RocketPort UPCI 32 port w/external I/F
5465 0802 RocketPort UPCI 8 port w/external I/F
5466 0803 RocketPort UPCI 16 port w/external I/F
5467 0805 RocketPort UPCI 8 port w/octa cable
5468 080c RocketModem III 8 port
5469 080d RocketModem III 4 port
5470 0903 RocketPort Compact PCI 16 port w/external I/F
5471 8015 RocketPort 4-port UART 16954
547211ff Scion Corporation
5473 0003 AG-5
54741200 CSS Corporation
54751201 Vista Controls Corp
54761202 Network General Corp.
5477 4300 Gigabit Ethernet Adapter
5478 1202 9841 SK-9841 LX
5479 1202 9842 SK-9841 LX dual link
5480 1202 9843 SK-9843 SX
5481 1202 9844 SK-9843 SX dual link
54821203 Bayer Corporation, Agfa Division
54831204 Lattice Semiconductor Corporation
54841205 Array Corporation
54851206 Amdahl Corporation
54861208 Parsytec GmbH
5487 4853 HS-Link Device
54881209 SCI Systems Inc
5489120a Synaptel
5490120b Adaptive Solutions
5491120c Technical Corp.
5492120d Compression Labs, Inc.
5493120e Cyclades Corporation
5494 0100 Cyclom-Y below first megabyte
5495 0101 Cyclom-Y above first megabyte
5496 0102 Cyclom-4Y below first megabyte
5497 0103 Cyclom-4Y above first megabyte
5498 0104 Cyclom-8Y below first megabyte
5499 0105 Cyclom-8Y above first megabyte
5500 0200 Cyclades-Z below first megabyte
5501 0201 Cyclades-Z above first megabyte
5502 0300 PC300/RSV or /X21 (2 ports)
5503 0301 PC300/RSV or /X21 (1 port)
5504 0310 PC300/TE (2 ports)
5505 0311 PC300/TE (1 port)
5506 0320 PC300/TE-M (2 ports)
5507 0321 PC300/TE-M (1 port)
5508 0400 PC400
5509120f Essential Communications
5510 0001 Roadrunner serial HIPPI
55111210 Hyperparallel Technologies
55121211 Braintech Inc
55131212 Kingston Technology Corp.
55141213 Applied Intelligent Systems, Inc.
55151214 Performance Technologies, Inc.
55161215 Interware Co., Ltd
55171216 Purup Prepress A/S
55181217 O2 Micro, Inc.
5519 6729 OZ6729
5520 673a OZ6730
5521 6832 OZ6832/6833 CardBus Controller
5522 6836 OZ6836/6860 CardBus Controller
5523 6872 OZ6812 CardBus Controller
5524 6925 OZ6922 CardBus Controller
5525 6933 OZ6933/711E1 CardBus/SmartCardBus Controller
5526 1025 1016 Travelmate 612 TX
5527 6972 OZ601/6912/711E0 CardBus/SmartCardBus Controller
5528 1014 020c ThinkPad R30
5529 1179 0001 Magnia Z310
5530 7110 OZ711Mx 4-in-1 MemoryCardBus Accelerator
5531 103c 088c nc8000 laptop
5532 103c 0890 nc6000 laptop
5533 7112 OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
5534 7113 OZ711EC1 SmartCardBus Controller
5535 7114 OZ711M1/MC1 4-in-1 MemoryCardBus Controller
5536 7134 OZ711MP1/MS1 MemoryCardBus Controller
5537 71e2 OZ711E2 SmartCardBus Controller
5538 7212 OZ711M2 4-in-1 MemoryCardBus Controller
5539 7213 OZ6933E CardBus Controller
5540 7223 OZ711M3/MC3 4-in-1 MemoryCardBus Controller
5541 103c 088c nc8000 laptop
5542 103c 0890 nc6000 laptop
5543 7233 OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
55441218 Hybricon Corp.
55451219 First Virtual Corporation
5546121a 3Dfx Interactive, Inc.
5547 0001 Voodoo
5548 0002 Voodoo 2
5549 0003 Voodoo Banshee
5550 1092 0003 Monster Fusion
5551 1092 4000 Monster Fusion
5552 1092 4002 Monster Fusion
5553 1092 4801 Monster Fusion AGP
5554 1092 4803 Monster Fusion AGP
5555 1092 8030 Monster Fusion
5556 1092 8035 Monster Fusion AGP
5557 10b0 0001 Dragon 4000
5558 1102 1018 3D Blaster Banshee VE
5559 121a 0001 Voodoo Banshee AGP
5560 121a 0003 Voodoo Banshee AGP SGRAM
5561 121a 0004 Voodoo Banshee
5562 139c 0016 Raven
5563 139c 0017 Raven
5564 14af 0002 Maxi Gamer Phoenix
5565 0004 Voodoo Banshee [Velocity 100]
5566 0005 Voodoo 3
5567 121a 0004 Voodoo3 AGP
5568 121a 0030 Voodoo3 AGP
5569 121a 0031 Voodoo3 AGP
5570 121a 0034 Voodoo3 AGP
5571 121a 0036 Voodoo3 2000 PCI
5572 121a 0037 Voodoo3 AGP
5573 121a 0038 Voodoo3 AGP
5574 121a 003a Voodoo3 AGP
5575 121a 0044 Voodoo3
5576 121a 004b Velocity 100
5577 121a 004c Velocity 200
5578 121a 004d Voodoo3 AGP
5579 121a 004e Voodoo3 AGP
5580 121a 0051 Voodoo3 AGP
5581 121a 0052 Voodoo3 AGP
5582 121a 0060 Voodoo3 3500 TV (NTSC)
5583 121a 0061 Voodoo3 3500 TV (PAL)
5584 121a 0062 Voodoo3 3500 TV (SECAM)
5585 0009 Voodoo 4 / Voodoo 5
5586 121a 0003 Voodoo5 PCI 5500
5587 121a 0009 Voodoo5 AGP 5500/6000
5588 0057 Voodoo 3/3000 [Avenger]
5589121b Advanced Telecommunications Modules
5590121c Nippon Texaco., Ltd
5591121d Lippert Automationstechnik GmbH
5592121e CSPI
5593121f Arcus Technology, Inc.
55941220 Ariel Corporation
5595 1220 AMCC 5933 TMS320C80 DSP/Imaging board
55961221 Contec Co., Ltd
55971222 Ancor Communications, Inc.
55981223 Artesyn Communication Products
5599 0003 PM/Link
5600 0004 PM/T1
5601 0005 PM/E1
5602 0008 PM/SLS
5603 0009 BajaSpan Resource Target
5604 000a BajaSpan Section 0
5605 000b BajaSpan Section 1
5606 000c BajaSpan Section 2
5607 000d BajaSpan Section 3
5608 000e PM/PPC
56091224 Interactive Images
56101225 Power I/O, Inc.
56111227 Tech-Source
5612 0006 Raptor GFX 8P
56131228 Norsk Elektro Optikk A/S
56141229 Data Kinesis Inc.
5615122a Integrated Telecom
5616122b LG Industrial Systems Co., Ltd
5617122c Sican GmbH
5618122d Aztech System Ltd
5619 1206 368DSP
5620 1400 Trident PCI288-Q3DII (NX)
5621 50dc 3328 Audio
5622 122d 0001 3328 Audio
5623 80da 3328 Audio
5624 122d 0001 3328 Audio
5625122e Xyratex
5626122f Andrew Corporation
56271230 Fishcamp Engineering
56281231 Woodward McCoach, Inc.
56291232 GPT Limited
56301233 Bus-Tech, Inc.
56311234 Technical Corp.
56321235 Risq Modular Systems, Inc.
56331236 Sigma Designs Corporation
5634 0000 RealMagic64/GX
5635 6401 REALmagic 64/GX (SD 6425)
56361237 Alta Technology Corporation
56371238 Adtran
56381239 3DO Company
5639123a Visicom Laboratories, Inc.
5640123b Seeq Technology, Inc.
5641123c Century Systems, Inc.
5642123d Engineering Design Team, Inc.
5643 0000 EasyConnect 8/32
5644 0002 EasyConnect 8/64
5645 0003 EasyIO
5646123e Simutech, Inc.
5647123f C-Cube Microsystems
5648 00e4 MPEG
5649 8120 E4?
5650 11bd 0006 DV500 E4
5651 11bd 000a DV500 E4
5652 11bd 000f DV500 E4
5653 8888 Cinemaster C 3.0 DVD Decoder
5654 1002 0001 Cinemaster C 3.0 DVD Decoder
5655 1002 0002 Cinemaster C 3.0 DVD Decoder
5656 1328 0001 Cinemaster C 3.0 DVD Decoder
56571240 Marathon Technologies Corp.
56581241 DSC Communications
5659# Formerly Jaycor Networks, Inc.
56601242 JNI Corporation
5661 1560 JNIC-1560 PCI-X Fibre Channel Controller
5662 1242 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
5663 1242 656a FCX-6562 PCI-X Fibre Channel Adapter
5664 4643 FCI-1063 Fibre Channel Adapter
5665 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
5666 656a FCX-6562 PCI-X Fibre Channel Adapter
56671243 Delphax
56681244 AVM Audiovisuelles MKTG & Computer System GmbH
5669 0700 B1 ISDN
5670 0800 C4 ISDN
5671 0a00 A1 ISDN [Fritz]
5672 1244 0a00 FRITZ!Card ISDN Controller
5673 0e00 Fritz!PCI v2.0 ISDN
5674 1100 C2 ISDN
5675 1200 T1 ISDN
5676 2700 Fritz!Card DSL SL
5677 2900 Fritz!Card DSL v2.0
56781245 A.P.D., S.A.
56791246 Dipix Technologies, Inc.
56801247 Xylon Research, Inc.
56811248 Central Data Corporation
56821249 Samsung Electronics Co., Ltd.
5683124a AEG Electrocom GmbH
5684124b SBS/Greenspring Modular I/O
5685 0040 PCI-40A or cPCI-200 Quad IndustryPack carrier
5686 124b 9080 PCI9080 Bridge
5687124c Solitron Technologies, Inc.
5688124d Stallion Technologies, Inc.
5689 0000 EasyConnection 8/32
5690 0002 EasyConnection 8/64
5691 0003 EasyIO
5692 0004 EasyConnection/RA
5693124e Cylink
5694124f Infortrend Technology, Inc.
5695 0041 IFT-2000 Series RAID Controller
56961250 Hitachi Microcomputer System Ltd
56971251 VLSI Solutions Oy
56981253 Guzik Technical Enterprises
56991254 Linear Systems Ltd.
57001255 Optibase Ltd
5701 1110 MPEG Forge
5702 1210 MPEG Fusion
5703 2110 VideoPlex
5704 2120 VideoPlex CC
5705 2130 VideoQuest
57061256 Perceptive Solutions, Inc.
5707 4201 PCI-2220I
5708 4401 PCI-2240I
5709 5201 PCI-2000
57101257 Vertex Networks, Inc.
57111258 Gilbarco, Inc.
57121259 Allied Telesyn International
5713 2560 AT-2560 Fast Ethernet Adapter (i82557B)
5714 a117 RTL81xx Fast Ethernet
5715 a120 21x4x DEC-Tulip compatible 10/100 Ethernet
5716125a ABB Power Systems
5717125b Asix Electronics Corporation
5718 1400 ALFA GFC2204 Fast Ethernet
5719125c Aurora Technologies, Inc.
5720 0101 Saturn 4520P
5721 0640 Aries 16000P
5722125d ESS Technology
5723 0000 ES336H Fax Modem (Early Model)
5724 1948 Solo?
5725 1968 ES1968 Maestro 2
5726 1028 0085 ES1968 Maestro-2 PCI
5727 1033 8051 ES1968 Maestro-2 Audiodrive
5728 1969 ES1969 Solo-1 Audiodrive
5729 1014 0166 ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
5730 125d 8888 Solo-1 Audio Adapter
5731 153b 111b Terratec 128i PCI
5732 1978 ES1978 Maestro 2E
5733 0e11 b112 Armada M700/E500
5734 1033 803c ES1978 Maestro-2E Audiodrive
5735 1033 8058 ES1978 Maestro-2E Audiodrive
5736 1092 4000 Monster Sound MX400
5737 1179 0001 ES1978 Maestro-2E Audiodrive
5738 1988 ES1988 Allegro-1
5739 1092 4100 Sonic Impact S100
5740 125d 1988 ESS Allegro-1 Audiodrive
5741 1989 ESS Modem
5742 125d 1989 ESS Modem
5743 1998 ES1983S Maestro-3i PCI Audio Accelerator
5744 1028 00b1 Latitude C600
5745 1028 00e6 ES1983S Maestro-3i (Dell Inspiron 8100)
5746 1999 ES1983S Maestro-3i PCI Modem Accelerator
5747 199a ES1983S Maestro-3i PCI Audio Accelerator
5748 199b ES1983S Maestro-3i PCI Modem Accelerator
5749 2808 ES336H Fax Modem (Later Model)
5750 2838 ES2838/2839 SuperLink Modem
5751 2898 ES2898 Modem
5752 125d 0424 ES56-PI Data Fax Modem
5753 125d 0425 ES56T-PI Data Fax Modem
5754 125d 0426 ES56V-PI Data Fax Modem
5755 125d 0427 VW-PI Data Fax Modem
5756 125d 0428 ES56ST-PI Data Fax Modem
5757 125d 0429 ES56SV-PI Data Fax Modem
5758 147a c001 ES56-PI Data Fax Modem
5759 14fe 0428 ES56-PI Data Fax Modem
5760 14fe 0429 ES56-PI Data Fax Modem
5761125e Specialvideo Engineering SRL
5762125f Concurrent Technologies, Inc.
57631260 Intersil Corporation
5764 3872 Prism 2.5 Wavelan chipset
5765 1468 0202 LAN-Express IEEE 802.11b Wireless LAN
5766 3873 Prism 2.5 Wavelan chipset
5767 1186 3501 DWL-520 Wireless PCI Adapter
5768 1186 3700 DWL-520 Wireless PCI Adapter, Rev E1
5769 1385 4105 MA311 802.11b wireless adapter
5770 1668 0414 HWP01170-01 802.11b PCI Wireless Adapter
5771 16a5 1601 AIR.mate PC-400 PCI Wireless LAN Adapter
5772 1737 3874 WMP11 Wireless 802.11b PCI Adapter
5773 8086 2513 Wireless 802.11b MiniPCI Adapter
5774 3886 ISL3886 [Prism Javelin/Prism Xbow]
5775 17cf 0037 Z-Com XG-901 and clones Wireless Adapter
5776 3890 Intersil ISL3890 [Prism GT/Prism Duette]
5777 10b8 2802 SMC2802W Wireless PCI Adapter
5778 10b8 2835 SMC2835W Wireless Cardbus Adapter
5779 10b8 a835 SMC2835W V2 Wireless Cardbus Adapter
5780 1113 ee03 SMC2802W V2 Wireless PCI Adapter
5781 1113 ee08 SMC2835W V3 EU Wireless Cardbus Adapter
5782 1186 3202 DWL-G650 A1 Wireless Adapter
5783 1259 c104 CG-WLCB54GT Wireless Adapter
5784 1385 4800 WG511 Wireless Adapter
5785 16a5 1605 ALLNET ALL0271 Wireless PCI Adapter
5786 17cf 0014 Z-Com XG-600 and clones Wireless Adapter
5787 17cf 0020 Z-Com XG-900 and clones Wireless Adapter
5788 8130 HMP8130 NTSC/PAL Video Decoder
5789 8131 HMP8131 NTSC/PAL Video Decoder
57901261 Matsushita-Kotobuki Electronics Industries, Ltd.
57911262 ES Computer Company, Ltd.
57921263 Sonic Solutions
57931264 Aval Nagasaki Corporation
57941265 Casio Computer Co., Ltd.
57951266 Microdyne Corporation
5796 0001 NE10/100 Adapter (i82557B)
5797 1910 NE2000Plus (RT8029) Ethernet Adapter
5798 1266 1910 NE2000Plus Ethernet Adapter
57991267 S. A. Telecommunications
5800 5352 PCR2101
5801 5a4b Telsat Turbo
58021268 Tektronix
58031269 Thomson-CSF/TTM
5804126a Lexmark International, Inc.
5805126b Adax, Inc.
5806126c Northern Telecom
5807 1211 10/100BaseTX [RTL81xx]
5808 126c 802.11b Wireless Ethernet Adapter
5809126d Splash Technology, Inc.
5810126e Sumitomo Metal Industries, Ltd.
5811126f Silicon Motion, Inc.
5812 0501 SM501 VoyagerGX
5813 0710 SM710 LynxEM
5814 0712 SM712 LynxEM+
5815 0720 SM720 Lynx3DM
5816 0730 SM731 Cougar3DR
5817 0810 SM810 LynxE
5818 0811 SM811 LynxE
5819 0820 SM820 Lynx3D
5820 0910 SM910
58211270 Olympus Optical Co., Ltd.
58221271 GW Instruments
58231272 Telematics International
58241273 Hughes Network Systems
5825 0002 DirecPC
58261274 Ensoniq
5827 1171 ES1373 [AudioPCI] (also Creative Labs CT5803)
5828 1371 ES1371 [AudioPCI-97]
5829 0e11 0024 AudioPCI on Motherboard Compaq Deskpro
5830 0e11 b1a7 ES1371, ES1373 AudioPCI
5831 1033 80ac ES1371, ES1373 AudioPCI
5832 1042 1854 Tazer
5833 107b 8054 Tabor2
5834 1274 1371 Creative Sound Blaster AudioPCI64V, AudioPCI128
5835 1462 6470 ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
5836 1462 6560 ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
5837 1462 6630 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
5838 1462 6631 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
5839 1462 6632 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
5840 1462 6633 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
5841 1462 6820 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
5842 1462 6822 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
5843 1462 6830 ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
5844 1462 6880 ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
5845 1462 6900 ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
5846 1462 6910 ES1371, ES1373 AudioPCI On Motherboard MS-6191
5847 1462 6930 ES1371, ES1373 AudioPCI On Motherboard MS-6193
5848 1462 6990 ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
5849 1462 6991 ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
5850 14a4 2077 ES1371, ES1373 AudioPCI On Motherboard KR639
5851 14a4 2105 ES1371, ES1373 AudioPCI On Motherboard MR800
5852 14a4 2107 ES1371, ES1373 AudioPCI On Motherboard MR801
5853 14a4 2172 ES1371, ES1373 AudioPCI On Motherboard DR739
5854 1509 9902 ES1371, ES1373 AudioPCI On Motherboard KW11
5855 1509 9903 ES1371, ES1373 AudioPCI On Motherboard KW31
5856 1509 9904 ES1371, ES1373 AudioPCI On Motherboard KA11
5857 1509 9905 ES1371, ES1373 AudioPCI On Motherboard KC13
5858 152d 8801 ES1371, ES1373 AudioPCI On Motherboard CP810E
5859 152d 8802 ES1371, ES1373 AudioPCI On Motherboard CP810
5860 152d 8803 ES1371, ES1373 AudioPCI On Motherboard P3810E
5861 152d 8804 ES1371, ES1373 AudioPCI On Motherboard P3810-S
5862 152d 8805 ES1371, ES1373 AudioPCI On Motherboard P3820-S
5863 270f 2001 ES1371, ES1373 AudioPCI On Motherboard 6CTR
5864 270f 2200 ES1371, ES1373 AudioPCI On Motherboard 6WTX
5865 270f 3000 ES1371, ES1373 AudioPCI On Motherboard 6WSV
5866 270f 3100 ES1371, ES1373 AudioPCI On Motherboard 6WIV2
5867 270f 3102 ES1371, ES1373 AudioPCI On Motherboard 6WIV
5868 270f 7060 ES1371, ES1373 AudioPCI On Motherboard 6ASA2
5869 8086 4249 ES1371, ES1373 AudioPCI On Motherboard BI440ZX
5870 8086 424c ES1371, ES1373 AudioPCI On Motherboard BL440ZX
5871 8086 425a ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
5872 8086 4341 ES1371, ES1373 AudioPCI On Motherboard Cayman
5873 8086 4343 ES1371, ES1373 AudioPCI On Motherboard Cape Cod
5874 8086 4649 ES1371, ES1373 AudioPCI On Motherboard Fire Island
5875 8086 464a ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
5876 8086 4d4f ES1371, ES1373 AudioPCI On Motherboard Montreal
5877 8086 4f43 ES1371, ES1373 AudioPCI On Motherboard OC440LX
5878 8086 5243 ES1371, ES1373 AudioPCI On Motherboard RC440BX
5879 8086 5352 ES1371, ES1373 AudioPCI On Motherboard SunRiver
5880 8086 5643 ES1371, ES1373 AudioPCI On Motherboard Vancouver
5881 8086 5753 ES1371, ES1373 AudioPCI On Motherboard WS440BX
5882 5000 ES1370 [AudioPCI]
5883 5880 5880 AudioPCI
5884 1274 2000 Creative Sound Blaster AudioPCI128
5885 1274 2003 Creative SoundBlaster AudioPCI 128
5886 1274 5880 Creative Sound Blaster AudioPCI128
5887 1274 8001 Sound Blaster 16PCI 4.1ch
5888 1458 a000 5880 AudioPCI On Motherboard 6OXET
5889 1462 6880 5880 AudioPCI On Motherboard MS-6188 1.00
5890 270f 2001 5880 AudioPCI On Motherboard 6CTR
5891 270f 2200 5880 AudioPCI On Motherboard 6WTX
5892 270f 7040 5880 AudioPCI On Motherboard 6ATA4
58931275 Network Appliance Corporation
58941276 Switched Network Technologies, Inc.
58951277 Comstream
58961278 Transtech Parallel Systems Ltd.
5897 0701 TPE3/TM3 PowerPC Node
5898 0710 TPE5 PowerPC PCI board
58991279 Transmeta Corporation
5900 0295 Northbridge
5901 0395 LongRun Northbridge
5902 0396 SDRAM controller
5903 0397 BIOS scratchpad
5904127a Rockwell International
5905 1002 HCF 56k Data/Fax Modem
5906 1092 094c SupraExpress 56i PRO [Diamond SUP2380]
5907 122d 4002 HPG / MDP3858-U
5908 122d 4005 MDP3858-E
5909 122d 4007 MDP3858-A/-NZ
5910 122d 4012 MDP3858-SA
5911 122d 4017 MDP3858-W
5912 122d 4018 MDP3858-W
5913 127a 1002 Rockwell 56K D/F HCF Modem
5914 1003 HCF 56k Data/Fax Modem
5915 0e11 b0bc 229-DF Zephyr
5916 0e11 b114 229-DF Cheetah
5917 1033 802b 229-DF
5918 13df 1003 PCI56RX Modem
5919 13e0 0117 IBM
5920 13e0 0147 IBM F-1156IV+/R3 Spain V.90 Modem
5921 13e0 0197 IBM
5922 13e0 01c7 IBM F-1156IV+/R3 WW V.90 Modem
5923 13e0 01f7 IBM
5924 1436 1003 IBM
5925 1436 1103 IBM 5614PM3G V.90 Modem
5926 1436 1602 Compaq 229-DF Ducati
5927 1004 HCF 56k Data/Fax/Voice Modem
5928 1048 1500 MicroLink 56k Modem
5929 10cf 1059 Fujitsu 229-DFRT
5930 1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5931 1005 127a AOpen FM56-P
5932 1033 8029 229-DFSV
5933 1033 8054 Modem
5934 10cf 103c Fujitsu
5935 10cf 1055 Fujitsu 229-DFSV
5936 10cf 1056 Fujitsu 229-DFSV
5937 122d 4003 MDP3858SP-U
5938 122d 4006 Packard Bell MDP3858V-E
5939 122d 4008 MDP3858SP-A/SP-NZ
5940 122d 4009 MDP3858SP-E
5941 122d 4010 MDP3858V-U
5942 122d 4011 MDP3858SP-SA
5943 122d 4013 MDP3858V-A/V-NZ
5944 122d 4015 MDP3858SP-W
5945 122d 4016 MDP3858V-W
5946 122d 4019 MDP3858V-SA
5947 13df 1005 PCI56RVP Modem
5948 13e0 0187 IBM
5949 13e0 01a7 IBM
5950 13e0 01b7 IBM DF-1156IV+/R3 Spain V.90 Modem
5951 13e0 01d7 IBM DF-1156IV+/R3 WW V.90 Modem
5952 1436 1005 IBM
5953 1436 1105 IBM
5954 1437 1105 IBM 5614PS3G V.90 Modem
5955 1022 HCF 56k Modem
5956 1436 1303 M3-5614PM3G V.90 Modem
5957 1023 HCF 56k Data/Fax Modem
5958 122d 4020 Packard Bell MDP3858-WE
5959 122d 4023 MDP3858-UE
5960 13e0 0247 IBM F-1156IV+/R6 Spain V.90 Modem
5961 13e0 0297 IBM
5962 13e0 02c7 IBM F-1156IV+/R6 WW V.90 Modem
5963 1436 1203 IBM
5964 1436 1303 IBM
5965 1024 HCF 56k Data/Fax/Voice Modem
5966 1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5967 10cf 106a Fujitsu 235-DFSV
5968 122d 4021 Packard Bell MDP3858V-WE
5969 122d 4022 MDP3858SP-WE
5970 122d 4024 MDP3858V-UE
5971 122d 4025 MDP3858SP-UE
5972 1026 HCF 56k PCI Speakerphone Modem
5973 1032 HCF 56k Modem
5974 1033 HCF 56k Modem
5975 1034 HCF 56k Modem
5976 1035 HCF 56k PCI Speakerphone Modem
5977 1036 HCF 56k Modem
5978 1085 HCF 56k Volcano PCI Modem
5979 2005 HCF 56k Data/Fax Modem
5980 104d 8044 229-DFSV
5981 104d 8045 229-DFSV
5982 104d 8055 PBE/Aztech 235W-DFSV
5983 104d 8056 235-DFSV
5984 104d 805a Modem
5985 104d 805f Modem
5986 104d 8074 Modem
5987 2013 HSF 56k Data/Fax Modem
5988 1179 0001 Modem
5989 1179 ff00 Modem
5990 2014 HSF 56k Data/Fax/Voice Modem
5991 10cf 1057 Fujitsu Citicorp III
5992 122d 4050 MSP3880-U
5993 122d 4055 MSP3880-W
5994 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5995 10cf 1063 Fujitsu
5996 10cf 1064 Fujitsu
5997 1468 2015 Fujitsu
5998 2016 HSF 56k Data/Fax/Voice/Spkp Modem
5999 122d 4051 MSP3880V-W
6000 122d 4052 MSP3880SP-W
6001 122d 4054 MSP3880V-U
6002 122d 4056 MSP3880SP-U
6003 122d 4057 MSP3880SP-A
6004 4311 Riptide HSF 56k PCI Modem
6005 127a 4311 Ring Modular? Riptide HSF RT HP Dom
6006 13e0 0210 HP-GVC
6007 4320 Riptide PCI Audio Controller
6008 1235 4320 Riptide PCI Audio Controller
6009 4321 Riptide HCF 56k PCI Modem
6010 1235 4321 Hewlett Packard DF
6011 1235 4324 Hewlett Packard DF
6012 13e0 0210 Hewlett Packard DF
6013 144d 2321 Riptide
6014 4322 Riptide PCI Game Controller
6015 1235 4322 Riptide PCI Game Controller
6016 8234 RapidFire 616X ATM155 Adapter
6017 108d 0022 RapidFire 616X ATM155 Adapter
6018 108d 0027 RapidFire 616X ATM155 Adapter
6019127b Pixera Corporation
6020127c Crosspoint Solutions, Inc.
6021127d Vela Research
6022127e Winnov, L.P.
6023127f Fujifilm
60241280 Photoscript Group Ltd.
60251281 Yokogawa Electric Corporation
60261282 Davicom Semiconductor, Inc.
6027 9009 Ethernet 100/10 MBit
6028 9100 21x4x DEC-Tulip compatible 10/100 Ethernet
6029 9102 21x4x DEC-Tulip compatible 10/100 Ethernet
6030 9132 Ethernet 100/10 MBit
60311283 Integrated Technology Express, Inc.
6032 673a IT8330G
6033 8212 IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212)
6034 1283 0001 IT/ITE8212 Dual channel ATA RAID controller
6035 8330 IT8330G
6036 8872 IT8874F PCI Dual Serial Port Controller
6037 8888 IT8888F PCI to ISA Bridge with SMB
6038 8889 IT8889F PCI to ISA Bridge
6039 e886 IT8330G
60401284 Sahara Networks, Inc.
60411285 Platform Technologies, Inc.
6042 0100 AGOGO sound chip (aka ESS Maestro 1)
60431286 Mazet GmbH
60441287 M-Pact, Inc.
6045 001e LS220D DVD Decoder
6046 001f LS220C DVD Decoder
60471288 Timestep Corporation
60481289 AVC Technology, Inc.
6049128a Asante Technologies, Inc.
6050128b Transwitch Corporation
6051128c Retix Corporation
6052128d G2 Networks, Inc.
6053 0021 ATM155 Adapter
6054128e Hoontech Corporation/Samho Multi Tech Ltd.
6055 0008 ST128 WSS/SB
6056 0009 ST128 SAM9407
6057 000a ST128 Game Port
6058 000b ST128 MPU Port
6059 000c ST128 Ctrl Port
6060128f Tateno Dennou, Inc.
60611290 Sord Computer Corporation
60621291 NCS Computer Italia
60631292 Tritech Microelectronics Inc
60641293 Media Reality Technology
60651294 Rhetorex, Inc.
60661295 Imagenation Corporation
60671296 Kofax Image Products
60681297 Holco Enterprise Co, Ltd/Shuttle Computer
60691298 Spellcaster Telecommunications Inc.
60701299 Knowledge Technology Lab.
6071129a VMetro, inc.
6072 0615 PBT-615 PCI-X Bus Analyzer
6073129b Image Access
6074129c Jaycor
6075129d Compcore Multimedia, Inc.
6076129e Victor Company of Japan, Ltd.
6077129f OEC Medical Systems, Inc.
607812a0 Allen-Bradley Company
607912a1 Simpact Associates, Inc.
608012a2 Newgen Systems Corporation
608112a3 Lucent Technologies
6082 8105 T8105 H100 Digital Switch
608312a4 NTT Electronics Technology Company
608412a5 Vision Dynamics Ltd.
608512a6 Scalable Networks, Inc.
608612a7 AMO GmbH
608712a8 News Datacom
608812a9 Xiotech Corporation
608912aa SDL Communications, Inc.
609012ab Yuan Yuan Enterprise Co., Ltd.
6091 0002 AU8830 [Vortex2] Based Sound Card With A3D Support
6092 3000 MPG-200C PCI DVD Decoder Card
609312ac Measurex Corporation
609412ad Multidata GmbH
609512ae Alteon Networks Inc.
6096 0001 AceNIC Gigabit Ethernet
6097 1014 0104 Gigabit Ethernet-SX PCI Adapter
6098 12ae 0001 Gigabit Ethernet-SX (Universal)
6099 1410 0104 Gigabit Ethernet-SX PCI Adapter
6100 0002 AceNIC Gigabit Ethernet (Copper)
6101 10a9 8002 Acenic Gigabit Ethernet
6102 12ae 0002 Gigabit Ethernet-T (3C986-T)
6103 00fa Farallon PN9100-T Gigabit Ethernet
610412af TDK USA Corp
610512b0 Jorge Scientific Corp
610612b1 GammaLink
610712b2 General Signal Networks
610812b3 Inter-Face Co Ltd
610912b4 FutureTel Inc
611012b5 Granite Systems Inc.
611112b6 Natural Microsystems
611212b7 Cognex Modular Vision Systems Div. - Acumen Inc.
611312b8 Korg
611412b9 3Com Corp, Modem Division (formerly US Robotics)
6115 1006 WinModem
6116 12b9 005c USR 56k Internal Voice WinModem (Model 3472)
6117 12b9 005e USR 56k Internal WinModem (Models 662975)
6118 12b9 0062 USR 56k Internal Voice WinModem (Model 662978)
6119 12b9 0068 USR 56k Internal Voice WinModem (Model 5690)
6120 12b9 007a USR 56k Internal Voice WinModem (Model 662974)
6121 12b9 007f USR 56k Internal WinModem (Models 5698, 5699)
6122 12b9 0080 USR 56k Internal WinModem (Models 2975, 3528)
6123 12b9 0081 USR 56k Internal Voice WinModem (Models 2974, 3529)
6124 12b9 0091 USR 56k Internal Voice WinModem (Model 2978)
6125 1007 USR 56k Internal WinModem
6126 12b9 00a3 USR 56k Internal WinModem (Model 3595)
6127 1008 56K FaxModem Model 5610
6128 12b9 00a2 USR 56k Internal FAX Modem (Model 2977)
6129 12b9 00aa USR 56k Internal Voice Modem (Model 2976)
6130 12b9 00ab USR 56k Internal Voice Modem (Model 5609)
6131 12b9 00ac USR 56k Internal Voice Modem (Model 3298)
6132 12b9 00ad USR 56k Internal FAX Modem (Model 5610)
613312ba BittWare, Inc.
613412bb Nippon Unisoft Corporation
613512bc Array Microsystems
613612bd Computerm Corp.
613712be Anchor Chips Inc.
6138 3041 AN3041Q CO-MEM
6139 3042 AN3042Q CO-MEM Lite
6140 12be 3042 Anchor Chips Lite Evaluation Board
614112bf Fujifilm Microdevices
614212c0 Infimed
614312c1 GMM Research Corp
614412c2 Mentec Limited
614512c3 Holtek Microelectronics Inc
6146 0058 PCI NE2K Ethernet
6147 5598 PCI NE2K Ethernet
614812c4 Connect Tech Inc
6149 0001 Blue HEAT/PCI 8 (RS232/CL/RJ11)
6150 0002 Blue HEAT/PCI 4 (RS232)
6151 0003 Blue HEAT/PCI 2 (RS232)
6152 0004 Blue HEAT/PCI 8 (UNIV, RS485)
6153 0005 Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
6154 0006 Blue HEAT/PCI 4 (OPTO, RS485)
6155 0007 Blue HEAT/PCI 2+2 (RS232/485)
6156 0008 Blue HEAT/PCI 2 (OPTO, Tx, RS485)
6157 0009 Blue HEAT/PCI 2+6 (RS232/485)
6158 000a Blue HEAT/PCI 8 (Tx, RS485)
6159 000b Blue HEAT/PCI 4 (Tx, RS485)
6160 000c Blue HEAT/PCI 2 (20 MHz, RS485)
6161 000d Blue HEAT/PCI 2 PTM
6162 0100 NT960/PCI
6163 0201 cPCI Titan - 2 Port
6164 0202 cPCI Titan - 4 Port
6165 0300 CTI PCI UART 2 (RS232)
6166 0301 CTI PCI UART 4 (RS232)
6167 0302 CTI PCI UART 8 (RS232)
6168 0310 CTI PCI UART 1+1 (RS232/485)
6169 0311 CTI PCI UART 2+2 (RS232/485)
6170 0312 CTI PCI UART 4+4 (RS232/485)
6171 0320 CTI PCI UART 2
6172 0321 CTI PCI UART 4
6173 0322 CTI PCI UART 8
6174 0330 CTI PCI UART 2 (RS485)
6175 0331 CTI PCI UART 4 (RS485)
6176 0332 CTI PCI UART 8 (RS485)
617712c5 Picture Elements Incorporated
6178 007e Imaging/Scanning Subsystem Engine
6179 007f Imaging/Scanning Subsystem Engine
6180 0081 PCIVST [Grayscale Thresholding Engine]
6181 0085 Video Simulator/Sender
6182 0086 THR2 Multi-scale Thresholder
618312c6 Mitani Corporation
618412c7 Dialogic Corp
618512c8 G Force Co, Ltd
618612c9 Gigi Operations
618712ca Integrated Computing Engines
618812cb Antex Electronics Corporation
618912cc Pluto Technologies International
619012cd Aims Lab
619112ce Netspeed Inc.
619212cf Prophet Systems, Inc.
619312d0 GDE Systems, Inc.
619412d1 PSITech
619512d2 NVidia / SGS Thomson (Joint Venture)
6196 0008 NV1
6197 0009 DAC64
6198 0018 Riva128
6199 1048 0c10 VICTORY Erazor
6200 107b 8030 STB Velocity 128
6201 1092 0350 Viper V330
6202 1092 1092 Viper V330
6203 10b4 1b1b STB Velocity 128
6204 10b4 1b1d STB Velocity 128
6205 10b4 1b1e STB Velocity 128, PAL TV-Out
6206 10b4 1b20 STB Velocity 128 Sapphire
6207 10b4 1b21 STB Velocity 128
6208 10b4 1b22 STB Velocity 128 AGP, NTSC TV-Out
6209 10b4 1b23 STB Velocity 128 AGP, PAL TV-Out
6210 10b4 1b27 STB Velocity 128 DVD
6211 10b4 1b88 MVP Pro 128
6212 10b4 222a STB Velocity 128 AGP
6213 10b4 2230 STB Velocity 128
6214 10b4 2232 STB Velocity 128
6215 10b4 2235 STB Velocity 128 AGP
6216 2a15 54a3 3DVision-SAGP / 3DexPlorer 3000
6217 0019 Riva128ZX
6218 0020 TNT
6219 0028 TNT2
6220 0029 UTNT2
6221 002c VTNT2
6222 00a0 ITNT2
622312d3 Vingmed Sound A/S
622412d4 Ulticom (Formerly DGM&S)
6225 0200 T1 Card
622612d5 Equator Technologies Inc
6227 0003 BSP16
6228 1000 BSP15
622912d6 Analogic Corp
623012d7 Biotronic SRL
623112d8 Pericom Semiconductor
623212d9 Aculab PLC
6233 0002 PCI Prosody
6234 0004 cPCI Prosody
6235 0005 Aculab E1/T1 PCI card
623612da True Time Inc.
623712db Annapolis Micro Systems, Inc
623812dc Symicron Computer Communication Ltd.
623912dd Management Graphics
624012de Rainbow Technologies
6241 0200 CryptoSwift CS200
624212df SBS Technologies Inc
624312e0 Chase Research
6244 0010 ST16C654 Quad UART
6245 0020 ST16C654 Quad UART
6246 0030 ST16C654 Quad UART
624712e1 Nintendo Co, Ltd
624812e2 Datum Inc. Bancomm-Timing Division
624912e3 Imation Corp - Medical Imaging Systems
625012e4 Brooktrout Technology Inc
625112e5 Apex Semiconductor Inc
625212e6 Cirel Systems
625312e7 Sunsgroup Corporation
625412e8 Crisc Corp
625512e9 GE Spacenet
625612ea Zuken
625712eb Aureal Semiconductor
6258 0001 Vortex 1
6259 104d 8036 AU8820 Vortex Digital Audio Processor
6260 1092 2000 Sonic Impact A3D
6261 1092 2100 Sonic Impact A3D
6262 1092 2110 Sonic Impact A3D
6263 1092 2200 Sonic Impact A3D
6264 122d 1002 AU8820 Vortex Digital Audio Processor
6265 12eb 0001 AU8820 Vortex Digital Audio Processor
6266 5053 3355 Montego
6267 0002 Vortex 2
6268 104d 8049 AU8830 Vortex 3D Digital Audio Processor
6269 104d 807b AU8830 Vortex 3D Digital Audio Processor
6270 1092 3000 Monster Sound II
6271 1092 3001 Monster Sound II
6272 1092 3002 Monster Sound II
6273 1092 3003 Monster Sound II
6274 1092 3004 Monster Sound II
6275 12eb 0001 AU8830 Vortex 3D Digital Audio Processor
6276 12eb 0002 AU8830 Vortex 3D Digital Audio Processor
6277 12eb 0088 AU8830 Vortex 3D Digital Audio Processor
6278 144d 3510 AU8830 Vortex 3D Digital Audio Processor
6279 5053 3356 Montego II
6280 0003 AU8810 Vortex Digital Audio Processor
6281 104d 8049 AU8810 Vortex Digital Audio Processor
6282 104d 8077 AU8810 Vortex Digital Audio Processor
6283 109f 1000 AU8810 Vortex Digital Audio Processor
6284 12eb 0003 AU8810 Vortex Digital Audio Processor
6285 1462 6780 AU8810 Vortex Digital Audio Processor
6286 14a4 2073 AU8810 Vortex Digital Audio Processor
6287 14a4 2091 AU8810 Vortex Digital Audio Processor
6288 14a4 2104 AU8810 Vortex Digital Audio Processor
6289 14a4 2106 AU8810 Vortex Digital Audio Processor
6290 8803 Vortex 56k Software Modem
6291 12eb 8803 Vortex 56k Software Modem
629212ec 3A International, Inc.
629312ed Optivision Inc.
629412ee Orange Micro
629512ef Vienna Systems
629612f0 Pentek
629712f1 Sorenson Vision Inc
629812f2 Gammagraphx, Inc.
629912f3 Radstone Technology
630012f4 Megatel
630112f5 Forks
630212f6 Dawson France
630312f7 Cognex
630412f8 Electronic Design GmbH
6305 0002 VideoMaker
630612f9 Four Fold Ltd
630712fb Spectrum Signal Processing
630812fc Capital Equipment Corp
630912fd I2S
631012fe ESD Electronic System Design GmbH
631112ff Lexicon
63121300 Harman International Industries Inc
63131302 Computer Sciences Corp
63141303 Innovative Integration
63151304 Juniper Networks
63161305 Netphone, Inc
63171306 Duet Technologies
6318# Formerly ComputerBoards
63191307 Measurement Computing
6320 0001 PCI-DAS1602/16
6321 000b PCI-DIO48H
6322 000c PCI-PDISO8
6323 000d PCI-PDISO16
6324 000f PCI-DAS1200
6325 0010 PCI-DAS1602/12
6326 0014 PCI-DIO24H
6327 0015 PCI-DIO24H/CTR3
6328 0016 PCI-DIO48H/CTR15
6329 0017 PCI-DIO96H
6330 0018 PCI-CTR05
6331 0019 PCI-DAS1200/JR
6332 001a PCI-DAS1001
6333 001b PCI-DAS1002
6334 001c PCI-DAS1602JR/16
6335 001d PCI-DAS6402/16
6336 001e PCI-DAS6402/12
6337 001f PCI-DAS16/M1
6338 0020 PCI-DDA02/12
6339 0021 PCI-DDA04/12
6340 0022 PCI-DDA08/12
6341 0023 PCI-DDA02/16
6342 0024 PCI-DDA04/16
6343 0025 PCI-DDA08/16
6344 0026 PCI-DAC04/12-HS
6345 0027 PCI-DAC04/16-HS
6346 0028 PCI-DIO24
6347 0029 PCI-DAS08
6348 002c PCI-INT32
6349 0033 PCI-DUAL-AC5
6350 0034 PCI-DAS-TC
6351 0035 PCI-DAS64/M1/16
6352 0036 PCI-DAS64/M2/16
6353 0037 PCI-DAS64/M3/16
6354 004c PCI-DAS1000
6355 004d PCI-QUAD04
6356 0052 PCI-DAS4020/12
6357 005e PCI-DAS6025
63581308 Jato Technologies Inc.
6359 0001 NetCelerator Adapter
6360 1308 0001 NetCelerator Adapter
63611309 AB Semiconductor Ltd
6362130a Mitsubishi Electric Microcomputer
6363130b Colorgraphic Communications Corp
6364130c Ambex Technologies, Inc
6365130d Accelerix Inc
6366130e Yamatake-Honeywell Co. Ltd
6367130f Advanet Inc
63681310 Gespac
63691311 Videoserver, Inc
63701312 Acuity Imaging, Inc
63711313 Yaskawa Electric Co.
63721316 Teradyne Inc
63731317 Linksys
6374 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
6375 0985 NC100 Network Everywhere Fast Ethernet 10/100
6376 1985 21x4x DEC-Tulip compatible 10/100 Ethernet
6377 2850 HSP MicroModem 56
6378 8201 ADMtek ADM8211 802.11b Wireless Interface
6379 10b8 2635 SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card
6380 1317 8201 SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card
6381 8211 ADMtek ADM8211 802.11b Wireless Interface
6382 9511 21x4x DEC-Tulip compatible 10/100 Ethernet
63831318 Packet Engines Inc.
6384 0911 GNIC-II PCI Gigabit Ethernet [Hamachi]
63851319 Fortemedia, Inc
6386 0801 Xwave QS3000A [FM801]
6387 0802 Xwave QS3000A [FM801 game port]
6388 1000 FM801 PCI Audio
6389 1001 FM801 PCI Joystick
6390131a Finisar Corp.
6391131c Nippon Electro-Sensory Devices Corp
6392131d Sysmic, Inc.
6393131e Xinex Networks Inc
6394131f Siig Inc
6395 1000 CyberSerial (1-port) 16550
6396 1001 CyberSerial (1-port) 16650
6397 1002 CyberSerial (1-port) 16850
6398 1010 Duet 1S(16550)+1P
6399 1011 Duet 1S(16650)+1P
6400 1012 Duet 1S(16850)+1P
6401 1020 CyberParallel (1-port)
6402 1021 CyberParallel (2-port)
6403 1030 CyberSerial (2-port) 16550
6404 1031 CyberSerial (2-port) 16650
6405 1032 CyberSerial (2-port) 16850
6406 1034 Trio 2S(16550)+1P
6407 1035 Trio 2S(16650)+1P
6408 1036 Trio 2S(16850)+1P
6409 1050 CyberSerial (4-port) 16550
6410 1051 CyberSerial (4-port) 16650
6411 1052 CyberSerial (4-port) 16850
6412 2000 CyberSerial (1-port) 16550
6413 2001 CyberSerial (1-port) 16650
6414 2002 CyberSerial (1-port) 16850
6415 2010 Duet 1S(16550)+1P
6416 2011 Duet 1S(16650)+1P
6417 2012 Duet 1S(16850)+1P
6418 2020 CyberParallel (1-port)
6419 2021 CyberParallel (2-port)
6420 2030 CyberSerial (2-port) 16550
6421 131f 2030 PCI Serial Card
6422 2031 CyberSerial (2-port) 16650
6423 2032 CyberSerial (2-port) 16850
6424 2040 Trio 1S(16550)+2P
6425 2041 Trio 1S(16650)+2P
6426 2042 Trio 1S(16850)+2P
6427 2050 CyberSerial (4-port) 16550
6428 2051 CyberSerial (4-port) 16650
6429 2052 CyberSerial (4-port) 16850
6430 2060 Trio 2S(16550)+1P
6431 2061 Trio 2S(16650)+1P
6432 2062 Trio 2S(16850)+1P
6433 2081 CyberSerial (8-port) ST16654
64341320 Crypto AG
64351321 Arcobel Graphics BV
64361322 MTT Co., Ltd
64371323 Dome Inc
64381324 Sphere Communications
64391325 Salix Technologies, Inc
64401326 Seachange international
64411327 Voss scientific
64421328 quadrant international
64431329 Productivity Enhancement
6444132a Microcom Inc.
6445132b Broadband Technologies
6446132c Micrel Inc
6447132d Integrated Silicon Solution, Inc.
64481330 MMC Networks
64491331 Radisys Corp.
6450 0030 ENP-2611
6451 8200 82600 Host Bridge
6452 8201 82600 IDE
6453 8202 82600 USB
6454 8210 82600 PCI Bridge
64551332 Micro Memory
6456 5415 MM-5415CN PCI Memory Module with Battery Backup
6457 5425 MM-5425CN PCI 64/66 Memory Module with Battery Backup
64581334 Redcreek Communications, Inc
64591335 Videomail, Inc
64601337 Third Planet Publishing
64611338 BT Electronics
6462133a Vtel Corp
6463133b Softcom Microsystems
6464133c Holontech Corp
6465133d SS Technologies
6466133e Virtual Computer Corp
6467133f SCM Microsystems
64681340 Atalla Corp
64691341 Kyoto Microcomputer Co
64701342 Promax Systems Inc
64711343 Phylon Communications Inc
64721344 Crucial Technology
64731345 Arescom Inc
64741347 Odetics
64751349 Sumitomo Electric Industries, Ltd.
6476134a DTC Technology Corp.
6477 0001 Domex 536
6478 0002 Domex DMX3194UP SCSI Adapter
6479134b ARK Research Corp.
6480134c Chori Joho System Co. Ltd
6481134d PCTel Inc
6482 2189 HSP56 MicroModem
6483 2486 2304WT V.92 MDC Modem
6484 7890 HSP MicroModem 56
6485 134d 0001 PCT789 adapter
6486 7891 HSP MicroModem 56
6487 134d 0001 HSP MicroModem 56
6488 7892 HSP MicroModem 56
6489 7893 HSP MicroModem 56
6490 7894 HSP MicroModem 56
6491 7895 HSP MicroModem 56
6492 7896 HSP MicroModem 56
6493 7897 HSP MicroModem 56
6494134e CSTI
6495134f Algo System Co Ltd
64961350 Systec Co. Ltd
64971351 Sonix Inc
64981353 Thales Idatys
6499 0002 Proserver
6500 0003 PCI-FUT
6501 0004 PCI-S0
6502 0005 PCI-FUT-S0
65031354 Dwave System Inc
65041355 Kratos Analytical Ltd
65051356 The Logical Co
65061359 Prisa Networks
6507135a Brain Boxes
6508135b Giganet Inc
6509135c Quatech Inc
6510 0010 QSC-100
6511 0020 DSC-100
6512 0030 DSC-200/300
6513 0040 QSC-200/300
6514 0050 ESC-100D
6515 0060 ESC-100M
6516 00f0 MPAC-100 Syncronous Serial Card (Zilog 85230)
6517 0170 QSCLP-100
6518 0180 DSCLP-100
6519 0190 SSCLP-100
6520 01a0 QSCLP-200/300
6521 01b0 DSCLP-200/300
6522 01c0 SSCLP-200/300
6523135d ABB Network Partner AB
6524135e Sealevel Systems Inc
6525 5101 Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
6526 7101 Single Port RS-232/422/485/530
6527 7201 Dual Port RS-232/422/485 Interface
6528 7202 Dual Port RS-232 Interface
6529 7401 Four Port RS-232 Interface
6530 7402 Four Port RS-422/485 Interface
6531 7801 Eight Port RS-232 Interface
6532 7804 Eight Port RS-232/422/485 Interface
6533 8001 8001 Digital I/O Adapter
6534135f I-Data International A-S
65351360 Meinberg Funkuhren
6536 0101 PCI32 DCF77 Radio Clock
6537 0102 PCI509 DCF77 Radio Clock
6538 0103 PCI510 DCF77 Radio Clock
6539 0201 GPS167PCI GPS Receiver
6540 0202 GPS168PCI GPS Receiver
6541 0203 GPS169PCI GPS Receiver
6542 0301 TCR510PCI IRIG Receiver
65431361 Soliton Systems K.K.
65441362 Fujifacom Corporation
65451363 Phoenix Technology Ltd
65461364 ATM Communications Inc
65471365 Hypercope GmbH
65481366 Teijin Seiki Co. Ltd
65491367 Hitachi Zosen Corporation
65501368 Skyware Corporation
65511369 Digigram
6552136a High Soft Tech
6553136b Kawasaki Steel Corporation
6554 ff01 KL5A72002 Motion JPEG
6555136c Adtek System Science Co Ltd
6556136d Gigalabs Inc
6557136f Applied Magic Inc
65581370 ATL Products
65591371 CNet Technology Inc
6560 434e GigaCard Network Adapter
6561 1371 434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
65621373 Silicon Vision Inc
65631374 Silicom Ltd
65641375 Argosystems Inc
65651376 LMC
65661377 Electronic Equipment Production & Distribution GmbH
65671378 Telemann Co. Ltd
65681379 Asahi Kasei Microsystems Co Ltd
6569137a Mark of the Unicorn Inc
6570 0001 PCI-324 Audiowire Interface
6571137b PPT Vision
6572137c Iwatsu Electric Co Ltd
6573137d Dynachip Corporation
6574137e Patriot Scientific Corporation
6575137f Japan Satellite Systems Inc
65761380 Sanritz Automation Co Ltd
65771381 Brains Co. Ltd
65781382 Marian - Electronic & Software
6579 0001 ARC88 audio recording card
6580 2008 Prodif 96 Pro sound system
6581 2088 Marc 8 Midi sound system
6582 20c8 Marc A sound system
6583 4008 Marc 2 sound system
6584 4010 Marc 2 Pro sound system
6585 4048 Marc 4 MIDI sound system
6586 4088 Marc 4 Digi sound system
6587 4248 Marc X sound system
65881383 Controlnet Inc
65891384 Reality Simulation Systems Inc
65901385 Netgear
6591# Note: This lists as Atheros Communications, Inc. AR5212 802.11abg NIC because of Madwifi
6592 0013 WG311T
6593 311a GA511 Gigabit Ethernet
6594 4100 802.11b Wireless Adapter (MA301)
6595 4105 MA311 802.11b wireless adapter
6596 4400 WAG511 802.11a/b/g Dual Band Wireless PC Card
6597 4600 WAG511 802.11a/b/g Dual Band Wireless PC Card
6598 4601 WAG511 802.11a/b/g Dual Band Wireless PC Card
6599 4610 WAG511 802.11a/b/g Dual Band Wireless PC Card
6600 4a00 WAG311 802.11a/g Wireless PCI Adapter
6601 4c00 WG311v2 54 Mbps Wireless PCI Adapter
6602 620a GA620 Gigabit Ethernet
6603 622a GA622
6604 630a GA630 Gigabit Ethernet
6605 f004 FA310TX
66061386 Video Domain Technologies
66071387 Systran Corp
66081388 Hitachi Information Technology Co Ltd
66091389 Applicom International
6610 0001 PCI1500PFB [Intelligent fieldbus adaptor]
6611138a Fusion Micromedia Corp
6612138b Tokimec Inc
6613138c Silicon Reality
6614138d Future Techno Designs pte Ltd
6615138e Basler GmbH
6616138f Patapsco Designs Inc
66171390 Concept Development Inc
66181391 Development Concepts Inc
66191392 Medialight Inc
66201393 Moxa Technologies Co Ltd
6621 1040 Smartio C104H/PCI
6622 1141 Industrio CP-114
6623 1680 Smartio C168H/PCI
6624 2040 Intellio CP-204J
6625 2180 Intellio C218 Turbo PCI
6626 3200 Intellio C320 Turbo PCI
66271394 Level One Communications
6628 0001 LXT1001 Gigabit Ethernet
6629 1394 0001 NetCelerator Adapter
66301395 Ambicom Inc
66311396 Cipher Systems Inc
66321397 Cologne Chip Designs GmbH
6633 2bd0 ISDN network controller [HFC-PCI]
6634 1397 2bd0 ISDN Board
6635 e4bf 1000 CI1-1-Harp
66361398 Clarion co. Ltd
66371399 Rios systems Co Ltd
6638139a Alacritech Inc
6639 0001 Quad Port 10/100 Server Accelerator
6640 0003 Single Port 10/100 Server Accelerator
6641 0005 Single Port Gigabit Server Accelerator
6642139b Mediasonic Multimedia Systems Ltd
6643139c Quantum 3d Inc
6644139d EPL limited
6645139e Media4
6646139f Aethra s.r.l.
664713a0 Crystal Group Inc
664813a1 Kawasaki Heavy Industries Ltd
664913a2 Ositech Communications Inc
665013a3 Hifn Inc.
6651 0005 7751 Security Processor
6652 0006 6500 Public Key Processor
6653 0007 7811 Security Processor
6654 0012 7951 Security Processor
6655 0014 78XX Security Processor
6656 0016 8065 Security Processor
6657 0017 8165 Security Processor
6658 0018 8154 Security Processor
6659 001d 7956 Security Processor
6660 0020 7955 Security Processor
666113a4 Rascom Inc
666213a5 Audio Digital Imaging Inc
666313a6 Videonics Inc
666413a7 Teles AG
666513a8 Exar Corp.
6666 0154 XR17C154 Quad UART
6667 0158 XR17C158 Octal UART
666813a9 Siemens Medical Systems, Ultrasound Group
666913aa Broadband Networks Inc
667013ab Arcom Control Systems Ltd
667113ac Motion Media Technology Ltd
667213ad Nexus Inc
667313ae ALD Technology Ltd
667413af T.Sqware
667513b0 Maxspeed Corp
667613b1 Tamura corporation
667713b2 Techno Chips Co. Ltd
667813b3 Lanart Corporation
667913b4 Wellbean Co Inc
668013b5 ARM
668113b6 Dlog GmbH
668213b7 Logic Devices Inc
668313b8 Nokia Telecommunications oy
668413b9 Elecom Co Ltd
668513ba Oxford Instruments
668613bb Sanyo Technosound Co Ltd
668713bc Bitran Corporation
668813bd Sharp corporation
668913be Miroku Jyoho Service Co. Ltd
669013bf Sharewave Inc
669113c0 Microgate Corporation
6692 0010 SyncLink Adapter v1
6693 0020 SyncLink SCC Adapter
6694 0030 SyncLink Multiport Adapter
6695 0210 SyncLink Adapter v2
669613c1 3ware Inc
6697 1000 3ware Inc 3ware 5xxx/6xxx-series PATA-RAID
6698 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
6699 13c1 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
6700 1002 3ware Inc 3ware 9xxx-series SATA-RAID
670113c2 Technotrend Systemtechnik GmbH
670213c3 Janz Computer AG
670313c4 Phase Metrics
670413c5 Alphi Technology Corp
670513c6 Condor Engineering Inc
6706 0520 CEI-520 A429 Card
6707 0620 CEI-620 A429 Card
6708 0820 CEI-820 A429 Card
670913c7 Blue Chip Technology Ltd
671013c8 Apptech Inc
671113c9 Eaton Corporation
671213ca Iomega Corporation
671313cb Yano Electric Co Ltd
671413cc Metheus Corporation
671513cd Compatible Systems Corporation
671613ce Cocom A/S
671713cf Studio Audio & Video Ltd
671813d0 Techsan Electronics Co Ltd
6719 2103 B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
6720 2200 B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
672113d1 Abocom Systems Inc
6722 ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
6723 ab03 21x4x DEC-Tulip compatible 10/100 Ethernet
6724 ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
6725 ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
672613d2 Shark Multimedia Inc
672713d3 IMC Networks
672813d4 Graphics Microsystems Inc
672913d5 Media 100 Inc
673013d6 K.I. Technology Co Ltd
673113d7 Toshiba Engineering Corporation
673213d8 Phobos corporation
673313d9 Apex PC Solutions Inc
673413da Intresource Systems pte Ltd
673513db Janich & Klass Computertechnik GmbH
673613dc Netboost Corporation
673713dd Multimedia Bundle Inc
673813de ABB Robotics Products AB
673913df E-Tech Inc
6740 0001 PCI56RVP Modem
6741 13df 0001 PCI56RVP Modem
674213e0 GVC Corporation
674313e1 Silicom Multimedia Systems Inc
674413e2 Dynamics Research Corporation
674513e3 Nest Inc
674613e4 Calculex Inc
674713e5 Telesoft Design Ltd
674813e6 Argosy research Inc
674913e7 NAC Incorporated
675013e8 Chip Express Corporation
675113e9 Intraserver Technology Inc
675213ea Dallas Semiconductor
675313eb Hauppauge Computer Works Inc
675413ec Zydacron Inc
675513ed Raytheion E-Systems
675613ee Hayes Microcomputer Products Inc
675713ef Coppercom Inc
675813f0 Sundance Technology Inc
6759 0201 ST201 Sundance Ethernet
676013f1 Oce' - Technologies B.V.
676113f2 Ford Microelectronics Inc
676213f3 Mcdata Corporation
676313f4 Troika Networks, Inc.
6764 1401 Zentai Fibre Channel Adapter
676513f5 Kansai Electric Co. Ltd
676613f6 C-Media Electronics Inc
6767 0011 CMI8738
6768 0100 CM8338A
6769 13f6 ffff CMI8338/C3DX PCI Audio Device
6770 0101 CM8338B
6771 13f6 0101 CMI8338-031 PCI Audio Device
6772 0111 CM8738
6773 1019 0970 P6STP-FL motherboard
6774 1043 8035 CUSI-FX motherboard
6775 1043 8077 CMI8738 6-channel audio controller
6776 1043 80e2 CMI8738 6ch-MX
6777 13f6 0111 CMI8738/C3DX PCI Audio Device
6778 1681 a000 Gamesurround MUSE XL
6779 0211 CM8738
678013f7 Wildfire Communications
678113f8 Ad Lib Multimedia Inc
678213f9 NTT Advanced Technology Corp.
678313fa Pentland Systems Ltd
678413fb Aydin Corp
678513fc Computer Peripherals International
678613fd Micro Science Inc
678713fe Advantech Co. Ltd
6788 1240 PCI-1240 4-channel stepper motor controller card w. Nova Electronics MCX314
6789 1600 PCI-1612 4-port RS-232/422/485 PCI Communication Card
6790 1752 PCI-1752
6791 1754 PCI-1754
6792 1756 PCI-1756
679313ff Silicon Spice Inc
67941400 Artx Inc
6795 1401 9432 TX
67961401 CR-Systems A/S
67971402 Meilhaus Electronic GmbH
67981403 Ascor Inc
67991404 Fundamental Software Inc
68001405 Excalibur Systems Inc
68011406 Oce' Printing Systems GmbH
68021407 Lava Computer mfg Inc
6803 0100 Lava Dual Serial
6804 0101 Lava Quatro A
6805 0102 Lava Quatro B
6806 0110 Lava DSerial-PCI Port A
6807 0111 Lava DSerial-PCI Port B
6808 0120 Quattro-PCI A
6809 0121 Quattro-PCI B
6810 0180 Lava Octo A
6811 0181 Lava Octo B
6812 0200 Lava Port Plus
6813 0201 Lava Quad A
6814 0202 Lava Quad B
6815 0220 Lava Quattro PCI Ports A/B
6816 0221 Lava Quattro PCI Ports C/D
6817 0500 Lava Single Serial
6818 0600 Lava Port 650
6819 8000 Lava Parallel
6820 8001 Dual parallel port controller A
6821 8002 Lava Dual Parallel port A
6822 8003 Lava Dual Parallel port B
6823 8800 BOCA Research IOPPAR
68241408 Aloka Co. Ltd
68251409 Timedia Technology Co Ltd
6826 7168 PCI2S550 (Dual 16550 UART)
6827140a DSP Research Inc
6828140b Ramix Inc
6829140c Elmic Systems Inc
6830140d Matsushita Electric Works Ltd
6831140e Goepel Electronic GmbH
6832140f Salient Systems Corp
68331410 Midas lab Inc
68341411 Ikos Systems Inc
6835# formerly IC Ensemble Inc.
68361412 VIA Technologies Inc.
6837 1712 ICE1712 [Envy24] PCI Multi-Channel I/O Controller
6838 1412 1712 Hoontech ST Audio DSP 24
6839 1412 d630 M-Audio Delta 1010
6840 1412 d631 M-Audio Delta DiO
6841 1412 d632 M-Audio Delta 66
6842 1412 d633 M-Audio Delta 44
6843 1412 d634 M-Audio Delta Audiophile
6844 1412 d635 M-Audio Delta TDIF
6845 1412 d637 M-Audio Delta RBUS
6846 1412 d638 M-Audio Delta 410
6847 1412 d63b M-Audio Delta 1010LT
6848 1412 d63c Digigram VX442
6849 1416 1712 Hoontech ST Audio DSP 24 Media 7.1
6850 153b 1115 EWS88 MT
6851 153b 1125 EWS88 MT (Master)
6852 153b 112b EWS88 D
6853 153b 112c EWS88 D (Master)
6854 153b 1130 EWX 24/96
6855 153b 1138 DMX 6fire 24/96
6856 153b 1151 PHASE88
6857 16ce 1040 Edirol DA-2496
6858 1724 VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
6859 1412 1724 AMP Ltd AUDIO2000
6860 1412 3630 M-Audio Revolution 7.1
6861 153b 1145 Aureon 7.1 Space
6862 153b 1147 Aureon 5.1 Sky
6863 153b 1153 Aureon 7.1 Universe
6864 270f f641 ZNF3-150
6865 270f f645 ZNF3-250
68661413 Addonics
68671414 Microsoft Corporation
68681415 Oxford Semiconductor Ltd
6869 8403 VScom 011H-EP1 1 port parallel adaptor
6870 9501 OX16PCI954 (Quad 16950 UART) function 0
6871 131f 2050 CyberPro (4-port)
6872# Model IO1085, Part No: JJ-P46012
6873 131f 2051 CyberSerial 4S Plus
6874 15ed 2000 MCCR Serial p0-3 of 8
6875 15ed 2001 MCCR Serial p0-3 of 16
6876 950a EXSYS EX-41092 Dual 16950 Serial adapter
6877 950b OXCB950 Cardbus 16950 UART
6878 9510 OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
6879 9511 OX16PCI954 (Quad 16950 UART) function 1
6880 15ed 2000 MCCR Serial p4-7 of 8
6881 15ed 2001 MCCR Serial p4-15 of 16
6882 9521 OX16PCI952 (Dual 16950 UART)
68831416 Multiwave Innovation pte Ltd
68841417 Convergenet Technologies Inc
68851418 Kyushu electronics systems Inc
68861419 Excel Switching Corp
6887141a Apache Micro Peripherals Inc
6888141b Zoom Telephonics Inc
6889141d Digitan Systems Inc
6890141e Fanuc Ltd
6891141f Visiontech Ltd
68921420 Psion Dacom plc
6893 8002 Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
6894 8003 Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
68951421 Ads Technologies Inc
68961422 Ygrec Systems Co Ltd
68971423 Custom Technology Corp.
68981424 Videoserver Connections
68991425 Chelsio Communications Inc
69001426 Storage Technology Corp.
69011427 Better On-Line Solutions
69021428 Edec Co Ltd
69031429 Unex Technology Corp.
6904142a Kingmax Technology Inc
6905142b Radiolan
6906142c Minton Optic Industry Co Ltd
6907142d Pix stream Inc
6908142e Vitec Multimedia
6909 4020 VM2-2 [Video Maker 2] MPEG1/2 Encoder
6910142f Radicom Research Inc
69111430 ITT Aerospace/Communications Division
69121431 Gilat Satellite Networks
69131432 Edimax Computer Co.
6914 9130 RTL81xx Fast Ethernet
69151433 Eltec Elektronik GmbH
69161435 Real Time Devices US Inc.
69171436 CIS Technology Inc
69181437 Nissin Inc Co
69191438 Atmel-dream
69201439 Outsource Engineering & Mfg. Inc
6921143a Stargate Solutions Inc
6922143b Canon Research Center, America
6923143c Amlogic Inc
6924143d Tamarack Microelectronics Inc
6925143e Jones Futurex Inc
6926143f Lightwell Co Ltd - Zax Division
69271440 ALGOL Corp.
69281441 AGIE Ltd
69291442 Phoenix Contact GmbH & Co.
69301443 Unibrain S.A.
69311444 TRW
69321445 Logical DO Ltd
69331446 Graphin Co Ltd
69341447 AIM GmBH
69351448 Alesis Studio Electronics
69361449 TUT Systems Inc
6937144a Adlink Technology
6938 7296 PCI-7296
6939 7432 PCI-7432
6940 7433 PCI-7433
6941 7434 PCI-7434
6942 7841 PCI-7841
6943 8133 PCI-8133
6944 8164 PCI-8164
6945 8554 PCI-8554
6946 9111 PCI-9111
6947 9113 PCI-9113
6948 9114 PCI-9114
6949144b Loronix Information Systems Inc
6950144c Catalina Research Inc
6951144d Samsung Electronics Co Ltd
6952144e OLITEC
6953144f Askey Computer Corp.
69541450 Octave Communications Ind.
69551451 SP3D Chip Design GmBH
69561453 MYCOM Inc
69571454 Altiga Networks
69581455 Logic Plus Plus Inc
69591456 Advanced Hardware Architectures
69601457 Nuera Communications Inc
69611458 Giga-byte Technology
6962 0c11 K8NS Pro Mainboard
69631459 DOOIN Electronics
6964145a Escalate Networks Inc
6965145b PRAIM SRL
6966145c Cryptek
6967145d Gallant Computer Inc
6968145e Aashima Technology B.V.
6969145f Baldor Electric Company
6970 0001 NextMove PCI
69711460 DYNARC INC
69721461 Avermedia Technologies Inc
69731462 Micro-Star International Co., Ltd.
6974# MSI CB54G Wireless PC Card that seems to use the Broadcom 4306 Chipset
6975 6819 Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
6976 6825 PCI Card wireless 11g [PC54G]
6977 8725 NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
6978# MSI G4Ti4800, 128MB DDR SDRAM, TV-Out, DVI-I
6979 9000 NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
6980 9110 GeFORCE FX5200
6981 9119 NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
6982 9591 nVidia Corporation NV36 [GeForce FX 5700LE]
69831463 Fast Corporation
69841464 Interactive Circuits & Systems Ltd
69851465 GN NETTEST Telecom DIV.
69861466 Designpro Inc.
69871467 DIGICOM SPA
69881468 AMBIT Microsystem Corp.
69891469 Cleveland Motion Controls
6990146a IFR
6991146b Parascan Technologies Ltd
6992146c Ruby Tech Corp.
6993 1430 FE-1430TX Fast Ethernet PCI Adapter
6994146d Tachyon, INC.
6995146e Williams Electronics Games, Inc.
6996146f Multi Dimensional Consulting Inc
69971470 Bay Networks
69981471 Integrated Telecom Express Inc
69991472 DAIKIN Industries, Ltd
70001473 ZAPEX Technologies Inc
70011474 Doug Carson & Associates
70021475 PICAZO Communications
70031476 MORTARA Instrument Inc
70041477 Net Insight
70051478 DIATREND Corporation
70061479 TORAY Industries Inc
7007147a FORMOSA Industrial Computing
7008147b ABIT Computer Corp.
7009147c AWARE, Inc.
7010147d Interworks Computer Products
7011147e Matsushita Graphic Communication Systems, Inc.
7012147f NIHON UNISYS, Ltd.
70131480 SCII Telecom
70141481 BIOPAC Systems Inc
70151482 ISYTEC - Integrierte Systemtechnik GmBH
70161483 LABWAY Corporation
70171484 Logic Corporation
70181485 ERMA - Electronic GmBH
70191486 L3 Communications Telemetry & Instrumentation
70201487 MARQUETTE Medical Systems
70211488 KONTRON Electronik GmBH
70221489 KYE Systems Corporation
7023148a OPTO
7024148b INNOMEDIALOGIC Inc.
7025148c C.P. Technology Co. Ltd
7026148d DIGICOM Systems, Inc.
7027 1003 HCF 56k Data/Fax Modem
7028148e OSI Plus Corporation
7029148f Plant Equipment, Inc.
70301490 Stone Microsystems PTY Ltd.
70311491 ZEAL Corporation
70321492 Time Logic Corporation
70331493 MAKER Communications
70341494 WINTOP Technology, Inc.
70351495 TOKAI Communications Industry Co. Ltd
70361496 JOYTECH Computer Co., Ltd.
70371497 SMA Regelsysteme GmBH
70381498 TEWS Datentechnik GmBH
7039 30c8 TPCI200
70401499 EMTEC CO., Ltd
7041149a ANDOR Technology Ltd
7042149b SEIKO Instruments Inc
7043149c OVISLINK Corp.
7044149d NEWTEK Inc
7045 0001 Video Toaster for PC
7046149e Mapletree Networks Inc.
7047149f LECTRON Co Ltd
704814a0 SOFTING GmBH
704914a1 Systembase Co Ltd
705014a2 Millennium Engineering Inc
705114a3 Maverick Networks
705214a4 GVC/BCM Advanced Research
705314a5 XIONICS Document Technologies Inc
705414a6 INOVA Computers GmBH & Co KG
705514a7 MYTHOS Systems Inc
705614a8 FEATRON Technologies Corporation
705714a9 HIVERTEC Inc
705814aa Advanced MOS Technology Inc
705914ab Mentor Graphics Corp.
706014ac Novaweb Technologies Inc
706114ad Time Space Radio AB
706214ae CTI, Inc
706314af Guillemot Corporation
7064 7102 3D Prophet II MX
706514b0 BST Communication Technology Ltd
706614b1 Nextcom K.K.
706714b2 ENNOVATE Networks Inc
706814b3 XPEED Inc
7069 0000 DSL NIC
707014b4 PHILIPS Business Electronics B.V.
707114b5 Creamware GmBH
7072 0200 Scope
7073 0300 Pulsar
7074 0400 PulsarSRB
7075 0600 Pulsar2
7076 0800 DSP-Board
7077 0900 DSP-Board
7078 0a00 DSP-Board
7079 0b00 DSP-Board
708014b6 Quantum Data Corp.
708114b7 PROXIM Inc
7082 0001 Symphony 4110
708314b8 Techsoft Technology Co Ltd
708414b9 AIRONET Wireless Communications
7085 0001 PC4800
7086 0340 PC4800
7087 0350 PC4800
7088 4500 PC4500
7089 4800 Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
7090 a504 Cisco Aironet Wireless 802.11b
7091 a505 Cisco Aironet CB20a 802.11a Wireless LAN Adapter
7092 a506 Cisco Aironet Mini PCI b/g
709314ba INTERNIX Inc.
709414bb SEMTECH Corporation
709514bc Globespan Semiconductor Inc.
709614bd CARDIO Control N.V.
709714be L3 Communications
709814bf SPIDER Communications Inc.
709914c0 COMPAL Electronics Inc
710014c1 MYRICOM Inc.
7101 8043 Myrinet 2000 Scalable Cluster Interconnect
710214c2 DTK Computer
710314c3 MEDIATEK Corp.
710414c4 IWASAKI Information Systems Co Ltd
710514c5 Automation Products AB
710614c6 Data Race Inc
710714c7 Modular Technology Holdings Ltd
710814c8 Turbocomm Tech. Inc.
710914c9 ODIN Telesystems Inc
711014ca PE Logic Corp.
711114cb Billionton Systems Inc
711214cc NAKAYO Telecommunications Inc
711314cd Universal Scientific Ind.
711414ce Whistle Communications
711514cf TEK Microsystems Inc.
711614d0 Ericsson Axe R & D
711714d1 Computer Hi-Tech Co Ltd
711814d2 Titan Electronics Inc
7119 8001 VScom 010L 1 port parallel adaptor
7120 8002 VScom 020L 2 port parallel adaptor
7121 8010 VScom 100L 1 port serial adaptor
7122 8011 VScom 110L 1 port serial and 1 port parallel adaptor
7123 8020 VScom 200L 1 port serial adaptor
7124 8021 VScom 210L 2 port serial and 1 port parallel adaptor
7125 8040 VScom 400L 4 port serial adaptor
7126 8080 VScom 800L 8 port serial adaptor
7127 a000 VScom 010H 1 port parallel adaptor
7128 a001 VScom 100H 1 port serial adaptor
7129 a003 VScom 400H 4 port serial adaptor
7130 a004 VScom 400HF1 4 port serial adaptor
7131 a005 VScom 200H 2 port serial adaptor
7132 e001 VScom 010HV2 1 port parallel adaptor
7133 e010 VScom 100HV2 1 port serial adaptor
7134 e020 VScom 200HV2 2 port serial adaptor
713514d3 CIRTECH (UK) Ltd
713614d4 Panacom Technology Corp
713714d5 Nitsuko Corporation
713814d6 Accusys Inc
713914d7 Hirakawa Hewtech Corp
714014d8 HOPF Elektronik GmBH
7141# Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
714214d9 Alliance Semiconductor Corporation
7143 0010 AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
7144 9000 AS90L10204/10208 HyperTransport to PCI-X Bridge
714514da National Aerospace Laboratories
714614db AFAVLAB Technology Inc
7147 2120 TK9902
714814dc Amplicon Liveline Ltd
7149 0000 PCI230
7150 0001 PCI242
7151 0002 PCI244
7152 0003 PCI247
7153 0004 PCI248
7154 0005 PCI249
7155 0006 PCI260
7156 0007 PCI224
7157 0008 PCI234
7158 0009 PCI236
7159 000a PCI272
7160 000b PCI215
716114dd Boulder Design Labs Inc
716214de Applied Integration Corporation
716314df ASIC Communications Corp
716414e1 INVERTEX
716514e2 INFOLIBRIA
716614e3 AMTELCO
716714e4 Broadcom Corporation
7168 0800 Sentry5 Chipcommon I/O Controller
7169 0804 Sentry5 PCI Bridge
7170 0805 Sentry5 MIPS32 CPU
7171 0806 Sentry5 Ethernet Controller
7172 080b Sentry5 Crypto Accelerator
7173 080f Sentry5 DDR/SDR RAM Controller
7174 0811 Sentry5 External Interface Core
7175 0816 BCM3302 Sentry5 MIPS32 CPU
7176 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express
7177 1644 NetXtreme BCM5700 Gigabit Ethernet
7178 1014 0277 Broadcom Vigil B5700 1000Base-T
7179 1028 00d1 Broadcom BCM5700
7180 1028 0106 Broadcom BCM5700
7181 1028 0109 Broadcom BCM5700 1000Base-T
7182 1028 010a Broadcom BCM5700 1000BaseTX
7183 10b7 1000 3C996-T 1000Base-T
7184 10b7 1001 3C996B-T 1000Base-T
7185 10b7 1002 3C996C-T 1000Base-T
7186 10b7 1003 3C997-T 1000Base-T Dual Port
7187 10b7 1004 3C996-SX 1000Base-SX
7188 10b7 1005 3C997-SX 1000Base-SX Dual Port
7189 10b7 1008 3C942 Gigabit LOM (31X31)
7190 14e4 0002 NetXtreme 1000Base-SX
7191 14e4 0003 NetXtreme 1000Base-SX
7192 14e4 0004 NetXtreme 1000Base-T
7193 14e4 1028 NetXtreme 1000BaseTX
7194 14e4 1644 BCM5700 1000Base-T
7195 1645 NetXtreme BCM5701 Gigabit Ethernet
7196 0e11 007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7197 0e11 007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
7198 0e11 0085 NC7780 Gigabit Server Adapter (embedded, WOL)
7199 0e11 0099 NC7780 Gigabit Server Adapter (embedded, WOL)
7200 0e11 009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7201 0e11 00c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
7202 1028 0121 Broadcom BCM5701 1000Base-T
7203 103c 128a HP 1000Base-T (PCI) [A7061A]
7204 103c 128b HP 1000Base-SX (PCI) [A7073A]
7205 103c 12a4 HP Core Lan 1000Base-T
7206 103c 12c1 HP IOX Core Lan 1000Base-T [A7109AX]
7207 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
7208 10a9 8011 SGI Gigabit Ethernet (Copper)
7209 10a9 8012 SGI Gigabit Ethernet (Fiber)
7210 10b7 1004 3C996-SX 1000Base-SX
7211 10b7 1006 3C996B-T 1000Base-T
7212 10b7 1007 3C1000-T 1000Base-T
7213 10b7 1008 3C940-BR01 1000Base-T
7214 14e4 0001 BCM5701 1000Base-T
7215 14e4 0005 BCM5701 1000Base-T
7216 14e4 0006 BCM5701 1000Base-T
7217 14e4 0007 BCM5701 1000Base-SX
7218 14e4 0008 BCM5701 1000Base-T
7219 14e4 8008 BCM5701 1000Base-T
7220 1646 NetXtreme BCM5702 Gigabit Ethernet
7221 0e11 00bb NC7760 1000BaseTX
7222 1028 0126 Broadcom BCM5702 1000BaseTX
7223 14e4 8009 BCM5702 1000BaseTX
7224 1647 NetXtreme BCM5703 Gigabit Ethernet
7225 0e11 0099 NC7780 1000BaseTX
7226 0e11 009a NC7770 1000BaseTX
7227 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
7228 14e4 0009 BCM5703 1000BaseTX
7229 14e4 000a BCM5703 1000BaseSX
7230 14e4 000b BCM5703 1000BaseTX
7231 14e4 8009 BCM5703 1000BaseTX
7232 14e4 800a BCM5703 1000BaseTX
7233 1648 NetXtreme BCM5704 Gigabit Ethernet
7234 0e11 00cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7235 0e11 00d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7236 0e11 00d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7237 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X
7238 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X
7239 1166 1648 NetXtreme CIOB-E 1000Base-T
7240 164a NetXtreme II BCM5706 Gigabit Ethernet
7241 164d NetXtreme BCM5702FE Gigabit Ethernet
7242 1653 NetXtreme BCM5705 Gigabit Ethernet
7243 0e11 00e3 NC7761 Gigabit Server Adapter
7244 1654 NetXtreme BCM5705_2 Gigabit Ethernet
7245 0e11 00e3 NC7761 Gigabit Server Adapter
7246 103c 3100 NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
7247 1659 NetXtreme BCM5721 Gigabit Ethernet PCI Express
7248 165d NetXtreme BCM5705M Gigabit Ethernet
7249 165e NetXtreme BCM5705M_2 Gigabit Ethernet
7250 103c 088c nc8000 laptop
7251 103c 0890 nc6000 laptop
7252 166e 570x 10/100 Integrated Controller
7253 1677 NetXtreme BCM5751 Gigabit Ethernet PCI Express
7254 1028 0179 Optiplex GX280
7255 167d NetXtreme BCM5751M Gigabit Ethernet PCI Express
7256 167e NetXtreme BCM5751F Fast Ethernet PCI Express
7257 1696 NetXtreme BCM5782 Gigabit Ethernet
7258 103c 12bc HP d530 CMT (DG746A)
7259 14e4 000d NetXtreme BCM5782 1000Base-T
7260 169c NetXtreme BCM5788 Gigabit Ethernet
7261 169d NetLink BCM5789 Gigabit Ethernet PCI Express
7262 16a6 NetXtreme BCM5702X Gigabit Ethernet
7263 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7264 1028 0126 BCM5702 1000Base-T
7265 14e4 000c BCM5702 1000Base-T
7266 14e4 8009 BCM5702 1000Base-T
7267 16a7 NetXtreme BCM5703X Gigabit Ethernet
7268 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7269 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7270 14e4 0009 NetXtreme BCM5703 1000Base-T
7271 14e4 000a NetXtreme BCM5703 1000Base-SX
7272 14e4 000b NetXtreme BCM5703 1000Base-T
7273 14e4 800a NetXtreme BCM5703 1000Base-T
7274 16a8 NetXtreme BCM5704S Gigabit Ethernet
7275 10b7 2001 3C998-SX Dual Port 1000-SX PCI-X
7276 16aa NetXtreme II BCM5706S Gigabit Ethernet
7277 16c6 NetXtreme BCM5702A3 Gigabit Ethernet
7278 10b7 1100 3C1000B-T 10/100/1000 PCI
7279 14e4 000c BCM5702 1000Base-T
7280 14e4 8009 BCM5702 1000Base-T
7281 16c7 NetXtreme BCM5703 Gigabit Ethernet
7282 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7283 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7284 103c 12c3 HP Combo FC/GigE-SX [A9782A]
7285 103c 12ca HP Combo FC/GigE-T [A9784A]
7286 14e4 0009 NetXtreme BCM5703 1000Base-T
7287 14e4 000a NetXtreme BCM5703 1000Base-SX
7288 16dd NetLink BCM5781 Gigabit Ethernet PCI Express
7289 16f7 NetXtreme BCM5753 Gigabit Ethernet PCI Express
7290 16fd NetXtreme BCM5753M Gigabit Ethernet PCI Express
7291 16fe NetXtreme BCM5753F Fast Ethernet PCI Express
7292 170c BCM4401-B0 100Base-TX
7293 170d NetXtreme BCM5901 100Base-TX
7294 1014 0545 ThinkPad R40e (2684-HVG) builtin ethernet controller
7295 170e NetXtreme BCM5901 100Base-TX
7296 3352 BCM3352
7297 3360 BCM3360
7298 4210 BCM4210 iLine10 HomePNA 2.0
7299 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
7300 4212 BCM4212 v.90 56k modem
7301 4301 BCM4303 802.11b Wireless LAN Controller
7302 1028 0407 TrueMobile 1180 Onboard WLAN
7303 1043 0120 WL-103b Wireless LAN PC Card
7304 4305 BCM4307 V.90 56k Modem
7305 4306 BCM4307 Ethernet Controller
7306 4307 BCM4307 802.11b Wireless LAN Controller
7307 4310 BCM4310 Chipcommon I/OController
7308 4312 BCM4310 UART
7309 4313 BCM4310 Ethernet Controller
7310 4315 BCM4310 USB Controller
7311 4320 BCM4306 802.11b/g Wireless LAN Controller
7312 1028 0001 TrueMobile 1300 WLAN Mini-PCI Card
7313 1028 0003 Wireless 1350 WLAN Mini-PCI Card
7314 1043 100f WL-100G
7315 14e4 4320 Linksys WMP54G PCI
7316 1737 4320 WPC54G
7317 1799 7010 Belkin F5D7010 54g Wireless Network card
7318 4321 BCM4306 802.11a Wireless LAN Controller
7319 4322 BCM4306 UART
7320 4324 BCM4309 802.11a/b/g
7321 1028 0001 Truemobile 1400
7322 1028 0003 Truemobile 1450 MiniPCI
7323 4325 BCM43xG 802.11b/g
7324 1414 0003 Wireless Notebook Adapter MN-720
7325 1414 0004 Wireless PCI Adapter MN-730
7326# probably this is a correct ID...
7327 4326 BCM4307 Chipcommon I/O Controller?
7328 4401 BCM4401 100Base-T
7329 1043 80a8 A7V8X motherboard
7330 4402 BCM4402 Integrated 10/100BaseT
7331 4403 BCM4402 V.90 56k Modem
7332 4410 BCM4413 iLine32 HomePNA 2.0
7333 4411 BCM4413 V.90 56k modem
7334 4412 BCM4412 10/100BaseT
7335 4430 BCM44xx CardBus iLine32 HomePNA 2.0
7336 4432 BCM4432 CardBus 10/100BaseT
7337 4610 BCM4610 Sentry5 PCI to SB Bridge
7338 4611 BCM4610 Sentry5 iLine32 HomePNA 1.0
7339 4612 BCM4610 Sentry5 V.90 56k Modem
7340 4613 BCM4610 Sentry5 Ethernet Controller
7341 4614 BCM4610 Sentry5 External Interface
7342 4615 BCM4610 Sentry5 USB Controller
7343 4704 BCM4704 PCI to SB Bridge
7344 4705 BCM4704 Sentry5 802.11b Wireless LAN Controller
7345 4706 BCM4704 Sentry5 Ethernet Controller
7346 4707 BCM4704 Sentry5 USB Controller
7347 4708 BCM4704 Crypto Accelerator
7348 4710 BCM4710 Sentry5 PCI to SB Bridge
7349 4711 BCM47xx Sentry5 iLine32 HomePNA 2.0
7350 4712 BCM47xx V.92 56k modem
7351 4713 Sentry5 Ethernet Controller
7352 4714 BCM47xx Sentry5 External Interface
7353 4715 Sentry5 USB Controller
7354 4716 BCM47xx Sentry5 USB Host Controller
7355 4717 BCM47xx Sentry5 USB Device Controller
7356 4718 Sentry5 Crypto Accelerator
7357 4720 BCM4712 MIPS CPU
7358 5365 BCM5365P Sentry5 Host Bridge
7359 5600 BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
7360 5605 BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
7361 5615 BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
7362 5625 BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
7363 5645 BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
7364 5670 BCM5670 8-Port 10GE Ethernet Switch Fabric
7365 5680 BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
7366 5690 BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
7367 5691 BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
7368 5820 BCM5820 Crypto Accelerator
7369 5821 BCM5821 Crypto Accelerator
7370 5822 BCM5822 Crypto Accelerator
7371 5823 BCM5823 Crypto Accelerator
7372 5824 BCM5824 Crypto Accelerator
7373 5840 BCM5840 Crypto Accelerator
7374 5841 BCM5841 Crypto Accelerator
7375 5850 BCM5850 Crypto Accelerator
737614e5 Pixelfusion Ltd
737714e6 SHINING Technology Inc
737814e7 3CX
737914e8 RAYCER Inc
738014e9 GARNETS System CO Ltd
738114ea Planex Communications, Inc
7382 ab06 FNW-3603-TX CardBus Fast Ethernet
7383 ab07 RTL81xx RealTek Ethernet
738414eb SEIKO EPSON Corp
738514ec ACQIRIS
738614ed DATAKINETICS Ltd
738714ee MASPRO KENKOH Corp
738814ef CARRY Computer ENG. CO Ltd
738914f0 CANON RESEACH CENTRE FRANCE
739014f1 Conexant
7391 1002 HCF 56k Modem
7392 1003 HCF 56k Modem
7393 1004 HCF 56k Modem
7394 1005 HCF 56k Modem
7395 1006 HCF 56k Modem
7396 1022 HCF 56k Modem
7397 1023 HCF 56k Modem
7398 1024 HCF 56k Modem
7399 1025 HCF 56k Modem
7400 1026 HCF 56k Modem
7401 1032 HCF 56k Modem
7402 1033 HCF 56k Data/Fax Modem
7403 1033 8077 NEC
7404 122d 4027 Dell Zeus - MDP3880-W(B) Data Fax Modem
7405 122d 4030 Dell Mercury - MDP3880-U(B) Data Fax Modem
7406 122d 4034 Dell Thor - MDP3880-W(U) Data Fax Modem
7407 13e0 020d Dell Copper
7408 13e0 020e Dell Silver
7409 13e0 0261 IBM
7410 13e0 0290 Compaq Goldwing
7411 13e0 02a0 IBM
7412 13e0 02b0 IBM
7413 13e0 02c0 Compaq Scooter
7414 13e0 02d0 IBM
7415 144f 1500 IBM P85-DF (1)
7416 144f 1501 IBM P85-DF (2)
7417 144f 150a IBM P85-DF (3)
7418 144f 150b IBM P85-DF Low Profile (1)
7419 144f 1510 IBM P85-DF Low Profile (2)
7420 1034 HCF 56k Data/Fax/Voice Modem
7421 1035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7422 10cf 1098 Fujitsu P85-DFSV
7423 1036 HCF 56k Data/Fax/Voice/Spkp Modem
7424 104d 8067 HCF 56k Modem
7425 122d 4029 MDP3880SP-W
7426 122d 4031 MDP3880SP-U
7427 13e0 0209 Dell Titanium
7428 13e0 020a Dell Graphite
7429 13e0 0260 Gateway Red Owl
7430 13e0 0270 Gateway White Horse
7431 1052 HCF 56k Data/Fax Modem (Worldwide)
7432 1053 HCF 56k Data/Fax Modem (Worldwide)
7433 1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
7434 1055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
7435 1056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
7436 1057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
7437 1059 HCF 56k Data/Fax/Voice Modem (Worldwide)
7438 1063 HCF 56k Data/Fax Modem
7439 1064 HCF 56k Data/Fax/Voice Modem
7440 1065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7441 1066 HCF 56k Data/Fax/Voice/Spkp Modem
7442 122d 4033 Dell Athena - MDP3900V-U
7443 1433 HCF 56k Data/Fax Modem
7444 1434 HCF 56k Data/Fax/Voice Modem
7445 1435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7446 1436 HCF 56k Data/Fax Modem
7447 1453 HCF 56k Data/Fax Modem
7448 13e0 0240 IBM
7449 13e0 0250 IBM
7450 144f 1502 IBM P95-DF (1)
7451 144f 1503 IBM P95-DF (2)
7452 1454 HCF 56k Data/Fax/Voice Modem
7453 1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7454 1456 HCF 56k Data/Fax/Voice/Spkp Modem
7455 122d 4035 Dell Europa - MDP3900V-W
7456 122d 4302 Dell MP3930V-W(C) MiniPCI
7457 1610 ADSL AccessRunner PCI Arbitration Device
7458 1611 AccessRunner PCI ADSL Interface Device
7459 1620 ADSL AccessRunner V2 PCI Arbitration Device
7460 1621 AccessRunner V2 PCI ADSL Interface Device
7461 1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter
7462 1803 HCF 56k Modem
7463 0e11 0023 623-LAN Grizzly
7464 0e11 0043 623-LAN Yogi
7465 1815 HCF 56k Modem
7466 0e11 0022 Grizzly
7467 0e11 0042 Yogi
7468 2003 HSF 56k Data/Fax Modem
7469 2004 HSF 56k Data/Fax/Voice Modem
7470 2005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7471 2006 HSF 56k Data/Fax/Voice/Spkp Modem
7472 2013 HSF 56k Data/Fax Modem
7473 0e11 b195 Bear
7474 0e11 b196 Seminole 1
7475 0e11 b1be Seminole 2
7476 1025 8013 Acer
7477 1033 809d NEC
7478 1033 80bc NEC
7479 155d 6793 HP
7480 155d 8850 E Machines
7481 2014 HSF 56k Data/Fax/Voice Modem
7482 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7483 2016 HSF 56k Data/Fax/Voice/Spkp Modem
7484 2043 HSF 56k Data/Fax Modem (WorldW SmartDAA)
7485 2044 HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
7486 2045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
7487 2046 HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
7488 2063 HSF 56k Data/Fax Modem (SmartDAA)
7489 2064 HSF 56k Data/Fax/Voice Modem (SmartDAA)
7490 2065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
7491 2066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
7492 2093 HSF 56k Modem
7493 155d 2f07 Legend
7494 2143 HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
7495 2144 HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
7496 2145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
7497 2146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
7498 2163 HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
7499 2164 HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
7500 2165 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
7501 2166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
7502 2343 HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
7503 2344 HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
7504 2345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
7505 2346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
7506 2363 HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
7507 2364 HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
7508 2365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
7509 2366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
7510 2443 HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
7511 104d 8075 Modem
7512 104d 8083 Modem
7513 104d 8097 Modem
7514 2444 HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
7515 2445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
7516 2446 HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
7517 2463 HSF 56k Data/Fax Modem (Mob SmartDAA)
7518 2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
7519 2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
7520 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
7521 2f00 HSF 56k HSFi Modem
7522 13e0 8d84 IBM HSFi V.90
7523 13e0 8d85 Compaq Stinger
7524 14f1 2004 Dynalink 56PMi
7525 2f02 HSF 56k HSFi Data/Fax
7526 2f11 HSF 56k HSFi Modem
7527 8234 RS8234 ATM SAR Controller [ServiceSAR Plus]
7528 8800 CX22702 DVB-T 2k/8k
7529 17de 08a1 XPert DVB-T PCI BDA DVBT 23880 Video Capture
7530 8802 CX23883 Broadcast Decoder
7531 17de 08a1 Xpert DVB-T PCI 2388x Transport Stream Capture
753214f2 MOBILITY Electronics
7533 0120 EV1000 bridge
7534 0121 EV1000 Parallel port
7535 0122 EV1000 Serial port
7536 0123 EV1000 Keyboard controller
7537 0124 EV1000 Mouse controller
753814f3 BroadLogic
7539 2030 2030 DVB-S Satellite Reciever
7540 2050 2050 DVB-T Terrestrial (Cable) Reciever
7541 2060 2060 ATSC Terrestrial (Cable) Reciever
754214f4 TOKYO Electronic Industry CO Ltd
754314f5 SOPAC Ltd
754414f6 COYOTE Technologies LLC
754514f7 WOLF Technology Inc
754614f8 AUDIOCODES Inc
7547 2077 TP-240 dual span E1 VoIP PCI card
754814f9 AG COMMUNICATIONS
754914fa WANDEL & GOCHERMANN
755014fb TRANSAS MARINE (UK) Ltd
755114fc Quadrics Ltd
7552 0000 QsNet Elan3 Network Adapter
7553 0001 QsNetII Elan4 Network Adapter
755414fd JAPAN Computer Industry Inc
755514fe ARCHTEK TELECOM Corp
755614ff TWINHEAD INTERNATIONAL Corp
75571500 DELTA Electronics, Inc
7558 1360 RTL81xx RealTek Ethernet
75591501 BANKSOFT CANADA Ltd
75601502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
75611503 KAWASAKI LSI USA Inc
75621504 KAISER Electronics
75631505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
75641506 CHAMELEON Systems Inc
7565# Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057).
75661507 Motorola ?? / HTEC
7567 0001 MPC105 [Eagle]
7568 0002 MPC106 [Grackle]
7569 0003 MPC8240 [Kahlua]
7570 0100 MC145575 [HFC-PCI]
7571 0431 KTI829c 100VG
7572 4801 Raven
7573 4802 Falcon
7574 4803 Hawk
7575 4806 CPX8216
75761508 HONDA CONNECTORS/MHOTRONICS Inc
75771509 FIRST INTERNATIONAL Computer Inc
7578150a FORVUS RESEARCH Inc
7579150b YAMASHITA Systems Corp
7580150c KYOPAL CO Ltd
7581150d WARPSPPED Inc
7582150e C-PORT Corp
7583150f INTEC GmbH
75841510 BEHAVIOR TECH Computer Corp
75851511 CENTILLIUM Technology Corp
75861512 ROSUN Technologies Inc
75871513 Raychem
75881514 TFL LAN Inc
75891515 Advent design
75901516 MYSON Technology Inc
7591 0800 MTD-8xx 100/10M Ethernet PCI Adapter
7592 0803 SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
7593 1320 10bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
7594 0891 MTD-8xx 100/10M Ethernet PCI Adapter
75951517 ECHOTEK Corp
75961518 PEP MODULAR Computers GmbH
75971519 TELEFON AKTIEBOLAGET LM Ericsson
7598151a Globetek
7599 1002 PCI-1002
7600 1004 PCI-1004
7601 1008 PCI-1008
7602151b COMBOX Ltd
7603151c DIGITAL AUDIO LABS Inc
7604 0003 Prodif T 2496
7605 4000 Prodif 88
7606151d Fujitsu Computer Products Of America
7607151e MATRIX Corp
7608151f TOPIC SEMICONDUCTOR Corp
7609 0000 TP560 Data/Fax/Voice 56k modem
76101520 CHAPLET System Inc
76111521 BELL Corp
76121522 MainPine Ltd
7613 0100 PCI <-> IOBus Bridge
7614 1522 0200 RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
7615 1522 0300 RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
7616 1522 0400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
7617 1522 0500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
7618 1522 0600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem
7619 1522 0700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem
7620 1522 0800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
7621 1522 0c00 RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
7622 1522 0d00 RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
7623# this is a correction to a recent entry. 1522:0E00 should be 1522:1D00
7624 1522 1d00 RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
76251523 MUSIC Semiconductors
76261524 ENE Technology Inc
7627 0510 CB710 Memory Card Reader Controller
7628 0610 PCI Smart Card Reader Controller
7629 1211 CB1211 Cardbus Controller
7630 1225 CB1225 Cardbus Controller
7631 1410 CB1410 Cardbus Controller
7632 1025 005a TravelMate 290
7633 1411 CB-710/2/4 Cardbus Controller
7634 1412 CB-712/4 Cardbus Controller
7635 1420 CB1420 Cardbus Controller
7636 1421 CB-720/2/4 Cardbus Controller
7637 1422 CB-722/4 Cardbus Controller
76381525 IMPACT Technologies
76391526 ISS, Inc
76401527 SOLECTRON
76411528 ACKSYS
76421529 AMERICAN MICROSystems Inc
7643152a QUICKTURN DESIGN Systems
7644152b FLYTECH Technology CO Ltd
7645152c MACRAIGOR Systems LLC
7646152d QUANTA Computer Inc
7647152e MELEC Inc
7648152f PHILIPS - CRYPTO
76491530 ACQIS Technology Inc
76501531 CHRYON Corp
76511532 ECHELON Corp
76521533 BALTIMORE
76531534 ROAD Corp
76541535 EVERGREEN Technologies Inc
76551537 DATALEX COMMUNCATIONS
76561538 ARALION Inc
7657 0303 ARS106S Ultra ATA 133/100/66 Host Controller
76581539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
7659153a ONO SOKKI
7660153b TERRATEC Electronic GmbH
7661 1144 Aureon 5.1
7662# Terratec seems to use several IDs for the same card.
7663 1147 Aureon 5.1 Sky
7664 1158 Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
7665153c ANTAL Electronic
7666153d FILANET Corp
7667153e TECHWELL Inc
7668153f MIPS DENMARK
76691540 PROVIDEO MULTIMEDIA Co Ltd
76701541 MACHONE Communications
76711542 VIVID Technology Inc
76721543 SILICON Laboratories
7673 3052 Intel 537 [Winmodem]
7674 4c22 Si3036 MC'97 DAA
76751544 DCM DATA Systems
76761545 VISIONTEK
76771546 IOI Technology Corp
76781547 MITUTOYO Corp
76791548 JET PROPULSION Laboratory
76801549 INTERCONNECT Systems Solutions
7681154a MAX Technologies Inc
7682154b COMPUTEX Co Ltd
7683154c VISUAL Technology Inc
7684154d PAN INTERNATIONAL Industrial Corp
7685154e SERVOTEST Ltd
7686154f STRATABEAM Technology
76871550 OPEN NETWORK Co Ltd
76881551 SMART Electronic DEVELOPMENT GmBH
76891552 RACAL AIRTECH Ltd
76901553 CHICONY Electronics Co Ltd
76911554 PROLINK Microsystems Corp
76921555 GESYTEC GmBH
76931556 PLD APPLICATIONS
76941557 MEDIASTAR Co Ltd
76951558 CLEVO/KAPOK Computer
76961559 SI LOGIC Ltd
7697155a INNOMEDIA Inc
7698155b PROTAC INTERNATIONAL Corp
7699155c Cemax-Icon Inc
7700155d Mac System Co Ltd
7701155e LP Elektronik GmbH
7702155f Perle Systems Ltd
77031560 Terayon Communications Systems
77041561 Viewgraphics Inc
77051562 Symbol Technologies
77061563 A-Trend Technology Co Ltd
77071564 Yamakatsu Electronics Industry Co Ltd
77081565 Biostar Microtech Int'l Corp
77091566 Ardent Technologies Inc
77101567 Jungsoft
77111568 DDK Electronics Inc
77121569 Palit Microsystems Inc.
7713156a Avtec Systems
7714156b 2wire Inc
7715156c Vidac Electronics GmbH
7716156d Alpha-Top Corp
7717156e Alfa Inc
7718156f M-Systems Flash Disk Pioneers Ltd
77191570 Lecroy Corp
77201571 Contemporary Controls
7721 a001 CCSI PCI20-485 ARCnet
7722 a002 CCSI PCI20-485D ARCnet
7723 a003 CCSI PCI20-485X ARCnet
7724 a004 CCSI PCI20-CXB ARCnet
7725 a005 CCSI PCI20-CXS ARCnet
7726 a006 CCSI PCI20-FOG-SMA ARCnet
7727 a007 CCSI PCI20-FOG-ST ARCnet
7728 a008 CCSI PCI20-TB5 ARCnet
7729 a009 CCSI PCI20-5-485 5Mbit ARCnet
7730 a00a CCSI PCI20-5-485D 5Mbit ARCnet
7731 a00b CCSI PCI20-5-485X 5Mbit ARCnet
7732 a00c CCSI PCI20-5-FOG-ST 5Mbit ARCnet
7733 a00d CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
7734 a201 CCSI PCI22-485 10Mbit ARCnet
7735 a202 CCSI PCI22-485D 10Mbit ARCnet
7736 a203 CCSI PCI22-485X 10Mbit ARCnet
7737 a204 CCSI PCI22-CHB 10Mbit ARCnet
7738 a205 CCSI PCI22-FOG_ST 10Mbit ARCnet
7739 a206 CCSI PCI22-THB 10Mbit ARCnet
77401572 Otis Elevator Company
77411573 Lattice - Vantis
77421574 Fairchild Semiconductor
77431575 Voltaire Advanced Data Security Ltd
77441576 Viewcast COM
77451578 HITT
7746 5615 VPMK3 [Video Processor Mk III]
77471579 Dual Technology Corp
7748157a Japan Elecronics Ind Inc
7749157b Star Multimedia Corp
7750157c Eurosoft (UK)
7751 8001 Fix2000 PCI Y2K Compliance Card
7752157d Gemflex Networks
7753157e Transition Networks
7754157f PX Instruments Technology Ltd
77551580 Primex Aerospace Co
77561581 SEH Computertechnik GmbH
77571582 Cytec Corp
77581583 Inet Technologies Inc
77591584 Uniwill Computer Corp
77601585 Logitron
77611586 Lancast Inc
77621587 Konica Corp
77631588 Solidum Systems Corp
77641589 Atlantek Microsystems Pty Ltd
7765158a Digalog Systems Inc
7766158b Allied Data Technologies
7767158c Hitachi Semiconductor & Devices Sales Co Ltd
7768158d Point Multimedia Systems
7769158e Lara Technology Inc
7770158f Ditect Coop
77711590 3pardata Inc
77721591 ARN
77731592 Syba Tech Ltd
7774 0781 Multi-IO Card
7775 0782 Parallel Port Card 2xEPP
7776 0783 Multi-IO Card
7777 0785 Multi-IO Card
7778 0786 Multi-IO Card
7779 0787 Multi-IO Card
7780 0788 Multi-IO Card
7781 078a Multi-IO Card
77821593 Bops Inc
77831594 Netgame Ltd
77841595 Diva Systems Corp
77851596 Folsom Research Inc
77861597 Memec Design Services
77871598 Granite Microsystems
77881599 Delta Electronics Inc
7789159a General Instrument
7790159b Faraday Technology Corp
7791159c Stratus Computer Systems
7792159d Ningbo Harrison Electronics Co Ltd
7793159e A-Max Technology Co Ltd
7794159f Galea Network Security
779515a0 Compumaster SRL
779615a1 Geocast Network Systems
779715a2 Catalyst Enterprises Inc
7798 0001 TA700 PCI Bus Analyzer/Exerciser
779915a3 Italtel
780015a4 X-Net OY
780115a5 Toyota Macs Inc
780215a6 Sunlight Ultrasound Technologies Ltd
780315a7 SSE Telecom Inc
780415a8 Shanghai Communications Technologies Center
780515aa Moreton Bay
780615ab Bluesteel Networks Inc
780715ac North Atlantic Instruments
780815ad VMware Inc
7809 0405 [VMware SVGA II] PCI Display Adapter
7810 0710 Virtual SVGA
7811 0720 VMware High-Speed Virtual NIC [vmxnet]
781215ae Amersham Pharmacia Biotech
781315b0 Zoltrix International Ltd
781415b1 Source Technology Inc
781515b2 Mosaid Technologies Inc
781615b3 Mellanox Technologies
7817 5274 MT21108 InfiniBridge
7818 5a44 MT23108 InfiniHost
7819 5a45 MT23108 [Infinihost HCA Flash Recovery]
7820 5a46 MT23108 PCI Bridge
7821 5e8c MT24204 [InfiniHost III Lx HCA]
7822 5e8d MT24204 [InfiniHost III Lx HCA Flash Recovery]
7823 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
7824 6279 MT25208 [InfiniHost III Ex HCA Flash Recovery]
7825 6282 MT25208 InfiniHost III Ex
782615b4 CCI/TRIAD
782715b5 Cimetrics Inc
782815b6 Texas Memory Systems Inc
782915b7 Sandisk Corp
783015b8 ADDI-DATA GmbH
783115b9 Maestro Digital Communications
783215ba Impacct Technology Corp
783315bb Portwell Inc
783415bc Agilent Technologies
7835 2922 64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
7836 2928 64 Bit, 66MHz PCI Exerciser & Analyzer
7837 2929 64 Bit, 133MHz PCI-X Analyzer & Exerciser
783815bd DFI Inc
783915be Sola Electronics
784015bf High Tech Computer Corp (HTC)
784115c0 BVM Ltd
784215c1 Quantel
784315c2 Newer Technology Inc
784415c3 Taiwan Mycomp Co Ltd
784515c4 EVSX Inc
784615c5 Procomp Informatics Ltd
7847 8010 1394b - 1394 Firewire 3-Port Host Adapter Card
784815c6 Technical University of Budapest
784915c7 Tateyama System Laboratory Co Ltd
7850 0349 Tateyama C-PCI PLC/NC card Rev.01A
785115c8 Penta Media Co Ltd
785215c9 Serome Technology Inc
785315ca Bitboys OY
785415cb AG Electronics Ltd
785515cc Hotrail Inc
785615cd Dreamtech Co Ltd
785715ce Genrad Inc
785815cf Hilscher GmbH
785915d1 Infineon Technologies AG
786015d2 FIC (First International Computer Inc)
786115d3 NDS Technologies Israel Ltd
786215d4 Iwill Corp
786315d5 Tatung Co
786415d6 Entridia Corp
786515d7 Rockwell-Collins Inc
786615d8 Cybernetics Technology Co Ltd
786715d9 Super Micro Computer Inc
786815da Cyberfirm Inc
786915db Applied Computing Systems Inc
787015dc Litronic Inc
7871 0001 Argus 300 PCI Cryptography Module
787215dd Sigmatel Inc
787315de Malleable Technologies Inc
787415df Infinilink Corp
787515e0 Cacheflow Inc
787615e1 Voice Technologies Group Inc
787715e2 Quicknet Technologies Inc
787815e3 Networth Technologies Inc
787915e4 VSN Systemen BV
788015e5 Valley technologies Inc
788115e6 Agere Inc
788215e7 Get Engineering Corp
788315e8 National Datacomm Corp
7884 0130 Wireless PCI Card
788515e9 Pacific Digital Corp
7886 1841 ADMA-100 DiscStaQ ATA Controller
788715ea Tokyo Denshi Sekei K.K.
788815eb Drsearch GmbH
788915ec Beckhoff GmbH
7890 3101 FC3101 Profibus DP 1 Channel PCI
7891 5102 FC5102
789215ed Macrolink Inc
789315ee In Win Development Inc
789415ef Intelligent Paradigm Inc
789515f0 B-Tree Systems Inc
789615f1 Times N Systems Inc
789715f2 Diagnostic Instruments Inc
789815f3 Digitmedia Corp
789915f4 Valuesoft
790015f5 Power Micro Research
790115f6 Extreme Packet Device Inc
790215f7 Banctec
790315f8 Koga Electronics Co
790415f9 Zenith Electronics Corp
790515fa J.P. Axzam Corp
790615fb Zilog Inc
790715fc Techsan Electronics Co Ltd
790815fd N-CUBED.NET
790915fe Kinpo Electronics Inc
791015ff Fastpoint Technologies Inc
79111600 Northrop Grumman - Canada Ltd
79121601 Tenta Technology
79131602 Prosys-tec Inc
79141603 Nokia Wireless Communications
79151604 Central System Research Co Ltd
79161605 Pairgain Technologies
79171606 Europop AG
79181607 Lava Semiconductor Manufacturing Inc
79191608 Automated Wagering International
79201609 Scimetric Instruments Inc
79211612 Telesynergy Research Inc.
79221619 FarSite Communications Ltd
7923 0400 FarSync T2P (2 port X.21/V.35/V.24)
7924 0440 FarSync T4P (4 port X.21/V.35/V.24)
7925# www.rioworks.com
7926161f Rioworks
79271626 TDK Semiconductor Corp.
7928 8410 RTL81xx Fast Ethernet
79291629 Kongsberg Spacetec AS
7930 1003 Format synchronizer v3.0
7931 2002 Fast Universal Data Output
7932# This seems to occur on their 802.11b Wireless card WMP-11
79331637 Linksys
7934 3874 Linksys 802.11b WMP11 PCI Wireless card
79351638 Standard Microsystems Corp [SMC]
7936 1100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
7937163c Smart Link Ltd.
7938 3052 SmartLink SmartPCI562 56K Modem
7939 5449 SmartPCI561 Modem
79401657 Brocade Communications Systems, Inc.
7941165a Epix Inc
7942 c100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
7943 d200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
7944 d300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
7945165d Hsing Tech. Enterprise Co., Ltd.
79461661 Worldspace Corp.
79471668 Actiontec Electronics Inc
7948 0100 Mini-PCI bridge
7949# Formerly SiByte, Inc.
7950166d Broadcom Corporation
7951 0001 SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
7952 0002 SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
79531677 Bernecker + Rainer
7954 104e 5LS172.6 B&R Dual CAN Interface Card
7955 12d7 5LS172.61 B&R Dual CAN Interface Card
7956167b ZyDAS Technology Corp.
7957 2102 ZyDAS ZD1202
7958 187e 3406 ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
79591681 Hercules
7960# More specs, more accurate desc.
7961 0010 Hercules 3d Prophet II Ultra 64MB [ 350 MHz NV15BR core, 128-bit DDR @ 460 MHz, 1.5v AGP4x ]
79621682 XFX Pine Group Inc.
79631688 CastleNet Technology Inc.
7964 1170 WLAN 802.11b card
7965168c Atheros Communications, Inc.
7966 0007 AR5000 802.11a Wireless Adapter
7967 0011 AR5210 802.11a NIC
7968 0012 AR5211 802.11ab NIC
7969 0013 AR5212 802.11abg NIC
7970 1113 d301 Philips CPWNA100 Wireless CardBus adapter
7971 1186 3202 D-link DWL-G650 B3 Wireless cardbus adapter
7972 1186 3203 DWL-G520 Wireless PCI Adapter
7973 1186 3a13 DWL-G520 Wireless PCI Adapter rev. B
7974 1186 3a94 C54C Wireless 801.11g cardbus
7975 1385 4d00 Netgear WG311T Wireless PCI Adapter
7976 14b7 0a60 8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
7977 168c 0013 WG511T Wireless CardBus Adapter
7978 168c 1025 DWL-G650B2 Wireless CardBus Adapter
7979 168c 1027 Netgate NL-3054CB ARIES b/g CardBus Adapter
7980 168c 2026 Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
7981 168c 2041 Netgate 5354MP Plus ARIES2 b/g MiniPCI Adapter
7982 168c 2042 Netgate 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
7983 1014 AR5212 802.11abg NIC
7984169c Netcell Corporation
7985 0044 SyncRAID SR3000/5000 Series SATA RAID Controllers
798616a5 Tekram Technology Co.,Ltd.
798716ab Global Sun Technology Inc
7988 1100 GL24110P
7989 1101 PLX9052 PCMCIA-to-PCI Wireless LAN
7990 1102 PCMCIA-to-PCI Wireless Network Bridge
7991 8501 WL-8305 Wireless LAN PCI Adapter
799216ae Safenet Inc
7993 1141 SafeXcel-1141
799416b4 Aspex Semiconductor Ltd
799516be Creatix Polymedia GmbH
799616ca CENATEK Inc
7997 0001 Rocket Drive DL
799816cd Densitron Technologies
799916ce Roland Corp.
8000# www.pikatechnologies.com
800116df PIKA Technologies Inc.
800216e3 European Space Agency
8003 1e0f LEON2FT Processor
800416ec U.S. Robotics
8005 00ff USR997900 10/100 Mbps PCI Network Card
8006 0116 USR997902 10/100/1000 Mbps PCI Network Card
8007 3685 Wireless Access PCI Adapter Model 022415
800816ed Sycron N. V.
8009 1001 UMIO communication card
801016f3 Jetway Information Co., Ltd.
801116f4 Vweb Corp
8012 8000 VW2010
801316f6 VideoTele.com, Inc.
8014# www.internetmachines.com
80151702 Internet Machines Corporation (IMC)
80161705 Digital First, Inc.
8017170b NetOctave
8018 0100 NSP2000-SSL crypto accelerator
8019170c YottaYotta Inc.
8020# Seems to be a 2nd ID for Vitesse Semiconductor
80211725 Vitesse Semiconductor
8022 7174 VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
8023172a Accelerated Encryption
80241734 Fujitsu Siemens Computer GmbH
80251737 Linksys
8026 0013 WMP54G Wireless Pci Card
8027 0015 WMP54GS Wireless Pci Card
8028 1032 Gigabit Network Adapter
8029 1737 0015 EG1032 v2 Instant Gigabit Network Adapter
8030 1064 Gigabit Network Adapter
8031 1737 0016 EG1064 v2 Instant Gigabit Network Adapter
8032 ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
8033 ab09 21x4x DEC-Tulip compatible 10/100 Ethernet
8034173b Altima (nee Broadcom)
8035 03e8 AC1000 Gigabit Ethernet
8036 03e9 AC1001 Gigabit Ethernet
8037 03ea AC9100 Gigabit Ethernet
8038 173b 0001 AC1002
8039 03eb AC1003 Gigabit Ethernet
80401743 Peppercon AG
8041 8139 ROL/F-100 Fast Ethernet Adapter with ROL
80421749 RLX Technologies
8043174b PC Partner Limited
8044174d WellX Telecom SA
8045175c AudioScience Inc
8046175e Sanera Systems, Inc.
80471787 Hightech Information System Ltd.
8048# also used by Struck Innovative Systeme for joint developments
80491796 Research Centre Juelich
8050 0001 SIS1100 [Gigabit link]
8051 0002 HOTlink
8052 0003 Counter Timer
8053 0004 CAMAC Controller
8054 0005 PROFIBUS
8055 0006 AMCC HOTlink
80561797 JumpTec h, GMBH
80571799 Belkin
8058 6001 Wireless PCI Card - F5D6001
8059 6020 Wireless PCMCIA Card - F5D6020
8060 6060 Wireless PDA Card - F5D6060
8061 7000 Wireless PCI Card - F5D7000
806217a0 Genesys Logic, Inc
8063 8033 GL880S USB 1.1 controller
8064 8034 GL880S USB 2.0 controller
806517af Hightech Information System Ltd.
806617b3 Hawking Technologies
8067 ab08 PN672TX 10/100 Ethernet
806817b4 Indra Networks, Inc.
8069 0011 WebEnhance 100 GZIP Compression Card
807017c0 Wistron Corp.
807117c2 Newisys, Inc.
807217cc NetChip Technology, Inc
8073 2280 USB 2.0
807417d3 Areca Technology Corp.
8075 1110 ARC-1110 4-Port PCI-X to SATA RAID Controller
8076 1120 ARC-1120 8-Port PCI-X to SATA RAID Controller
8077 1130 ARC-1130 12-Port PCI-X to SATA RAID Controller
8078 1160 ARC-1160 16-Port PCI-X to SATA RAID Controller
8079 1210 ARC-1210 4-Port PCI-Express to SATA RAID Controller
8080 1220 ARC-1220 8-Port PCI-Express to SATA RAID Controller
8081 1230 ARC-1230 12-Port PCI-Express to SATA RAID Controller
8082 1260 ARC-1260 16-Port PCI-Express to SATA RAID Controller
8083# S2io ships 10Gb PCI-X Ethernet adapters www.s2io.com
808417d5 S2io Inc.
8085 5831 Xframe 10 Gigabit Ethernet PCI-X
8086 103c 12d5 HP PCI-X 133MHz 10GbE SR Fiber [AB287A]
808717de KWorld Computer Co. Ltd.
8088# http://www.connect3d.com
808917ee Connect Components Ltd
809017fe Linksys, A Division of Cisco Systems
8091 2120 WMP11v4 802.11b PCI card
8092 2220 [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01)
80931813 Ambient Technologies Inc
8094 4000 HaM controllerless modem
8095 16be 0001 V9x HAM Data Fax Modem
8096 4100 HaM plus Data Fax Modem
8097 16be 0002 V9x HAM 1394
80981814 RaLink
8099 0101 Wireless PCI Adpator RT2400 / RT2460
8100 3306 1113 Quidway WL100M
8101 0201 Ralink RT2500 802.11 Cardbus Reference Card
8102 1371 001e CWC-854 Wireless-G CardBus Adapter
8103 1371 001f CWM-854 Wireless-G Mini PCI Adapter
8104 1371 0020 CWP-854 Wireless-G PCI Adapter
8105 1458 e381 GN-WMKG 802.11b/g Wireless CardBus Adapter
81061820 InfiniCon Systems Inc.
81071822 Twinhan Technology Co. Ltd
8108182d SiteCom Europe BV
8109# HFC-based ISDN card
8110 3069 ISDN PCI DC-105V2
8111 9790 WL-121 Wireless Network Adapter 100g+ [Ver.3]
81121830 Credence Systems Corporation
8113183b MikroM GmbH
8114 08a7 MVC100 DVI
8115 08a8 MVC101 SDI
8116 08a9 MVC102 DVI+Audio
81171849 ASRock Incorporation
81181851 Microtune, Inc.
81191852 Anritsu Corp.
8120185f Wistron NeWeb Corp.
81211867 Topspin Communications
8122 5a44 MT23108 PCI-X HCA
8123 5a45 MT23108 PCI-X HCA flash recovery
8124 5a46 MT23108 PCI-X HCA bridge
8125 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
8126 6282 MT25208 InfiniHost III Ex
8127187e ZyXEL Communication Corporation
81281888 Varisys Ltd
8129 0301 VMFX1 FPGA PMC module
8130 0601 VSM2 dual PMC carrier
8131 0710 VS14x series PowerPC PCI board
8132 0720 VS24x series PowerPC PCI board
8133# found e.g. on KNC DVB-S card
81341894 KNC One
81351896 B&B Electronics Manufacturing Company, Inc.
813618a1 Astute Networks Inc.
813718ac DViCO Corporation
8138 d810 FusionHDTV 3 Gold
813918b8 Ammasso
8140 b001 AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
814118bc Info-Tek Corp.
8142# assigned to Octigabay System, which has been acquired by Cray
814318c8 Cray Inc
814418c9 ARVOO Engineering BV
814518ca XGI - Xabre Graphics Inc
8146 0040 Volari V8
814718e6 MPL AG
8148 0001 OSCI [Octal Serial Communication Interface]
814918f7 Commtech, Inc.
8150 0001 Fastcom ESCC-PCI-335
8151 0002 Fastcom 422/4-PCI-335
8152 0004 Fastcom 422/2-PCI-335
8153 0005 Fastcom IGESCC-PCI-ISO/1
8154 000a Fastcom 232/4-PCI-335
815518fb Resilience Corporation
81561924 Level 5 Networks Inc.
81571966 Orad Hi-Tec Systems
8158 1975 DVG64 family
81591993 Innominate Security Technologies AG
8160# http://www.progeny.net
816119ae Progeny Systems Corporation
81621a08 Sierra semiconductor
8163 0000 SC15064
81641b13 Jaton Corp
81651c1c Symphony
8166 0001 82C101
81671d44 DPT
8168 a400 PM2x24/PM3224
81691de1 Tekram Technology Co.,Ltd.
8170 0391 TRM-S1040
8171 2020 DC-390
8172 690c 690c
8173 dc29 DC290
81741fc0 Tumsan Oy
8175 0300 E2200 Dual E1/Rawpipe Card
81762000 Smart Link Ltd.
81772001 Temporal Research Ltd
81782003 Smart Link Ltd.
81792004 Smart Link Ltd.
818021c3 21st Century Computer Corp.
81812348 Racore
8182 2010 8142 100VG/AnyLAN
81832646 Kingston Technologies
8184270b Xantel Corporation
8185270f Chaintech Computer Co. Ltd
81862711 AVID Technology Inc.
81872a15 3D Vision(???)
81883000 Hansol Electronics Inc.
81893142 Post Impression Systems.
81903388 Hint Corp
8191 0013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
8192 0014 HiNT HC4 PCI to ISDN bridge, Network controller
8193 0020 HB6 Universal PCI-PCI bridge (transparent mode)
8194 0021 HB6 Universal PCI-PCI bridge (non-transparent mode)
8195 4c53 1050 CT7 mainboard
8196 4c53 1080 CT8 mainboard
8197 4c53 10a0 CA3/CR3 mainboard
8198 4c53 3010 PPCI mezzanine (32-bit PMC)
8199 4c53 3011 PPCI mezzanine (64-bit PMC)
8200 0022 HiNT HB4 PCI-PCI Bridge (PCI6150)
8201 0026 HB2 PCI-PCI Bridge
8202 101a E.Band [AudioTrak Inca88]
8203 101b E.Band [AudioTrak Inca88]
8204 8011 VXPro II Chipset
8205 3388 8011 VXPro II Chipset CPU to PCI Bridge
8206 8012 VXPro II Chipset
8207 3388 8012 VXPro II Chipset PCI to ISA Bridge
8208 8013 VXPro II IDE
8209 3388 8013 VXPro II Chipset EIDE Controller
82103411 Quantum Designs (H.K.) Inc
82113513 ARCOM Control Systems Ltd
82123842 eVga.com. Corp.
821338ef 4Links
82143d3d 3DLabs
8215 0001 GLINT 300SX
8216 0002 GLINT 500TX
8217 0003 GLINT Delta
8218 0004 Permedia
8219 0005 Permedia
8220 0006 GLINT MX
8221 0007 3D Extreme
8222 0008 GLINT Gamma G1
8223 0009 Permedia II 2D+3D
8224 1040 0011 AccelStar II
8225 13e9 1000 6221L-4U
8226 3d3d 0100 AccelStar II 3D Accelerator
8227 3d3d 0111 Permedia 3:16
8228 3d3d 0114 Santa Ana
8229 3d3d 0116 Oxygen GVX1
8230 3d3d 0119 Scirocco
8231 3d3d 0120 Santa Ana PCL
8232 3d3d 0125 Oxygen VX1
8233 3d3d 0127 Permedia3 Create!
8234 000a GLINT R3
8235 3d3d 0121 Oxygen VX1
8236 000c GLINT R3 [Oxygen VX1]
8237 3d3d 0144 Oxygen VX1-4X AGP [Permedia 4]
8238 000d GLint R4 rev A
8239 0011 GLint R4 rev B
8240 0012 GLint R5 rev A
8241 0013 GLint R5 rev B
8242 0020 VP10 visual processor
8243# P10 generic II
8244 0022 VP10 visual processor
8245 0024 VP9 visual processor
8246 0100 Permedia II 2D+3D
8247 07a1 Wildcat III 6210
8248 07a2 Sun XVR-500 Graphics Accelerator
8249 07a3 Wildcat IV 7210
8250 1004 Permedia
8251 3d04 Permedia
8252 ffff Glint VGA
82534005 Avance Logic Inc.
8254 0300 ALS300 PCI Audio Device
8255 0308 ALS300+ PCI Audio Device
8256 0309 PCI Input Controller
8257 1064 ALG-2064
8258 2064 ALG-2064i
8259 2128 ALG-2364A GUI Accelerator
8260 2301 ALG-2301
8261 2302 ALG-2302
8262 2303 AVG-2302 GUI Accelerator
8263 2364 ALG-2364A
8264 2464 ALG-2464
8265 2501 ALG-2564A/25128A
8266 4000 ALS4000 Audio Chipset
8267 4005 4000 ALS4000 Audio Chipset
8268 4710 ALC200/200P
82694033 Addtron Technology Co, Inc.
8270 1360 RTL8139 Ethernet
82714143 Digital Equipment Corp
82724144 Alpha Data
8273 0044 ADM-XRCIIPro
8274416c Aladdin Knowledge Systems
8275 0100 AladdinCARD
8276 0200 CPC
82774444 Internext Compression Inc
8278 0016 iTVC16 (CX23416) MPEG-2 Encoder
8279 0070 4009 WinTV PVR 250
8280 0070 8003 WinTV PVR 150
8281 0803 iTVC15 MPEG-2 Encoder
8282 0070 4000 WinTV PVR-350
8283 0070 4001 WinTV PVR-250
8284# video capture card
8285 1461 a3cf M179
82864468 Bridgeport machines
82874594 Cogetec Informatique Inc
828845fb Baldor Electric Company
82894680 Umax Computer Corp
82904843 Hercules Computer Technology Inc
82914916 RedCreek Communications Inc
8292 1960 RedCreek PCI adapter
82934943 Growth Networks
8294494f ACCES I/O Products, Inc.
8295 10e8 LPCI-COM-8SM
82964978 Axil Computer Inc
82974a14 NetVin
8298 5000 NV5000SC
8299 4a14 5000 RT8029-Based Ethernet Adapter
83004b10 Buslogic Inc.
83014c48 LUNG HWA Electronics
83024c53 SBS Technologies
8303 0000 PLUSTEST device
8304 4c53 3000 PLUSTEST card (PC104+)
8305 4c53 3001 PLUSTEST card (PMC)
8306 0001 PLUSTEST-MM device
8307 4c53 3002 PLUSTEST-MM card (PMC)
83084ca1 Seanix Technology Inc
83094d51 MediaQ Inc.
8310 0200 MQ-200
83114d54 Microtechnica Co Ltd
83124ddc ILC Data Device Corp
8313 0100 DD-42924I5-300 (ARINC 429 Data Bus)
8314 0801 BU-65570I1 MIL-STD-1553 Test and Simulation
8315 0802 BU-65570I2 MIL-STD-1553 Test and Simulation
8316 0811 BU-65572I1 MIL-STD-1553 Test and Simulation
8317 0812 BU-65572I2 MIL-STD-1553 Test and Simulation
8318 0881 BU-65570T1 MIL-STD-1553 Test and Simulation
8319 0882 BU-65570T2 MIL-STD-1553 Test and Simulation
8320 0891 BU-65572T1 MIL-STD-1553 Test and Simulation
8321 0892 BU-65572T2 MIL-STD-1553 Test and Simulation
8322 0901 BU-65565C1 MIL-STD-1553 Data Bus
8323 0902 BU-65565C2 MIL-STD-1553 Data Bus
8324 0903 BU-65565C3 MIL-STD-1553 Data Bus
8325 0904 BU-65565C4 MIL-STD-1553 Data Bus
8326 0b01 BU-65569I1 MIL-STD-1553 Data Bus
8327 0b02 BU-65569I2 MIL-STD-1553 Data Bus
8328 0b03 BU-65569I3 MIL-STD-1553 Data Bus
8329 0b04 BU-65569I4 MIL-STD-1553 Data Bus
83305046 GemTek Technology Corporation
8331 1001 PCI Radio
83325053 Voyetra Technologies
8333 2010 Daytona Audio Adapter
83345136 S S Technologies
83355143 Qualcomm Inc
83365145 Ensoniq (Old)
8337 3031 Concert AudioPCI
83385168 Animation Technologies Inc.
83395301 Alliance Semiconductor Corp.
8340 0001 ProMotion aT3D
83415333 S3 Inc.
8342 0551 Plato/PX (system)
8343 5631 86c325 [ViRGE]
8344 8800 86c866 [Vision 866]
8345 8801 86c964 [Vision 964]
8346 8810 86c764_0 [Trio 32 vers 0]
8347 8811 86c764/765 [Trio32/64/64V+]
8348 8812 86cM65 [Aurora64V+]
8349 8813 86c764_3 [Trio 32/64 vers 3]
8350 8814 86c767 [Trio 64UV+]
8351 8815 86cM65 [Aurora 128]
8352 883d 86c988 [ViRGE/VX]
8353 8870 FireGL
8354 8880 86c868 [Vision 868 VRAM] vers 0
8355 8881 86c868 [Vision 868 VRAM] vers 1
8356 8882 86c868 [Vision 868 VRAM] vers 2
8357 8883 86c868 [Vision 868 VRAM] vers 3
8358 88b0 86c928 [Vision 928 VRAM] vers 0
8359 88b1 86c928 [Vision 928 VRAM] vers 1
8360 88b2 86c928 [Vision 928 VRAM] vers 2
8361 88b3 86c928 [Vision 928 VRAM] vers 3
8362 88c0 86c864 [Vision 864 DRAM] vers 0
8363 88c1 86c864 [Vision 864 DRAM] vers 1
8364 88c2 86c864 [Vision 864-P DRAM] vers 2
8365 88c3 86c864 [Vision 864-P DRAM] vers 3
8366 88d0 86c964 [Vision 964 VRAM] vers 0
8367 88d1 86c964 [Vision 964 VRAM] vers 1
8368 88d2 86c964 [Vision 964-P VRAM] vers 2
8369 88d3 86c964 [Vision 964-P VRAM] vers 3
8370 88f0 86c968 [Vision 968 VRAM] rev 0
8371 88f1 86c968 [Vision 968 VRAM] rev 1
8372 88f2 86c968 [Vision 968 VRAM] rev 2
8373 88f3 86c968 [Vision 968 VRAM] rev 3
8374 8900 86c755 [Trio 64V2/DX]
8375 5333 8900 86C775 Trio64V2/DX
8376 8901 86c775/86c785 [Trio 64V2/DX or /GX]
8377 5333 8901 86C775 Trio64V2/DX, 86C785 Trio64V2/GX
8378 8902 Plato/PX
8379 8903 Trio 3D business multimedia
8380 8904 Trio 64 3D
8381 1014 00db Integrated Trio3D
8382 5333 8904 86C365 Trio3D AGP
8383 8905 Trio 64V+ family
8384 8906 Trio 64V+ family
8385 8907 Trio 64V+ family
8386 8908 Trio 64V+ family
8387 8909 Trio 64V+ family
8388 890a Trio 64V+ family
8389 890b Trio 64V+ family
8390 890c Trio 64V+ family
8391 890d Trio 64V+ family
8392 890e Trio 64V+ family
8393 890f Trio 64V+ family
8394 8a01 ViRGE/DX or /GX
8395 0e11 b032 ViRGE/GX
8396 10b4 1617 Nitro 3D
8397 10b4 1717 Nitro 3D
8398 5333 8a01 ViRGE/DX
8399 8a10 ViRGE/GX2
8400 1092 8a10 Stealth 3D 4000
8401 8a13 86c368 [Trio 3D/2X]
8402 5333 8a13 Trio3D/2X
8403 8a20 86c794 [Savage 3D]
8404 5333 8a20 86C391 Savage3D
8405 8a21 86c390 [Savage 3D/MV]
8406 5333 8a21 86C390 Savage3D/MV
8407 8a22 Savage 4
8408 1033 8068 Savage 4
8409 1033 8069 Savage 4
8410 1033 8110 Savage4 LT
8411 105d 0018 SR9 8Mb SDRAM
8412 105d 002a SR9 Pro 16Mb SDRAM
8413 105d 003a SR9 Pro 32Mb SDRAM
8414 105d 092f SR9 Pro+ 16Mb SGRAM
8415 1092 4207 Stealth III S540
8416 1092 4800 Stealth III S540
8417 1092 4807 SpeedStar A90
8418 1092 4808 Stealth III S540
8419 1092 4809 Stealth III S540
8420 1092 480e Stealth III S540
8421 1092 4904 Stealth III S520
8422 1092 4905 SpeedStar A200
8423 1092 4a09 Stealth III S540
8424 1092 4a0b Stealth III S540 Xtreme
8425 1092 4a0f Stealth III S540
8426 1092 4e01 Stealth III S540
8427 1102 101d 3d Blaster Savage 4
8428 1102 101e 3d Blaster Savage 4
8429 5333 8100 86C394-397 Savage4 SDRAM 100
8430 5333 8110 86C394-397 Savage4 SDRAM 110
8431 5333 8125 86C394-397 Savage4 SDRAM 125
8432 5333 8143 86C394-397 Savage4 SDRAM 143
8433 5333 8a22 86C394-397 Savage4
8434 5333 8a2e 86C394-397 Savage4 32bit
8435 5333 9125 86C394-397 Savage4 SGRAM 125
8436 5333 9143 86C394-397 Savage4 SGRAM 143
8437 8a23 Savage 4
8438 8a25 ProSavage PM133
8439 8a26 ProSavage KM133
8440 8c00 ViRGE/M3
8441 8c01 ViRGE/MX
8442 1179 0001 ViRGE/MX
8443 8c02 ViRGE/MX+
8444 8c03 ViRGE/MX+MV
8445 8c10 86C270-294 Savage/MX-MV
8446 8c11 82C270-294 Savage/MX
8447 8c12 86C270-294 Savage/IX-MV
8448 1014 017f ThinkPad T20
8449 1179 0001 86C584 SuperSavage/IXC Toshiba
8450 8c13 86C270-294 Savage/IX
8451 1179 0001 Magnia Z310
8452 8c22 SuperSavage MX/128
8453 8c24 SuperSavage MX/64
8454 8c26 SuperSavage MX/64C
8455 8c2a SuperSavage IX/128 SDR
8456 8c2b SuperSavage IX/128 DDR
8457 8c2c SuperSavage IX/64 SDR
8458 8c2d SuperSavage IX/64 DDR
8459 8c2e SuperSavage IX/C SDR
8460 1014 01fc ThinkPad T23 (2647-4MG)
8461 8c2f SuperSavage IX/C DDR
8462 8d01 86C380 [ProSavageDDR K4M266]
8463 8d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
8464 8d03 VT8751 [ProSavageDDR P4M266]
8465 8d04 VT8375 [ProSavage8 KM266/KL266]
8466 9102 86C410 Savage 2000
8467 1092 5932 Viper II Z200
8468 1092 5934 Viper II Z200
8469 1092 5952 Viper II Z200
8470 1092 5954 Viper II Z200
8471 1092 5a35 Viper II Z200
8472 1092 5a37 Viper II Z200
8473 1092 5a55 Viper II Z200
8474 1092 5a57 Viper II Z200
8475 ca00 SonicVibes
8476544c Teralogic Inc
8477 0350 TL880-based HDTV/ATSC tuner
84785455 Technische University Berlin
8479 4458 S5933
84805519 Cnet Technologies, Inc.
84815544 Dunord Technologies
8482 0001 I-30xx Scanner Interface
84835555 Genroco, Inc
8484 0003 TURBOstor HFP-832 [HiPPI NIC]
84855654 VoiceTronix Pty Ltd
8486 3132 OpenSwitch12
84875700 Netpower
84885851 Exacq Technologies
84896356 UltraStor
84906374 c't Magazin für Computertechnik
8491 6773 GPPCI
84926409 Logitec Corp.
84936666 Decision Computer International Co.
8494 0001 PCCOM4
8495 0002 PCCOM8
84967604 O.N. Electronic Co Ltd.
84977bde MIDAC Corporation
84987fed PowerTV
84998008 Quancom Electronic GmbH
8500 0010 WDOG1 [PCI-Watchdog 1]
8501 0011 PWDOG2 [PCI-Watchdog 2]
8502# Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card.
8503807d Asustek Computer, Inc.
85048086 Intel Corporation
8505 0007 82379AB
8506 0008 Extended Express System Support Controller
8507 0008 1000 WorldMark 4300 INCA ASIC
8508 0039 21145 Fast Ethernet
8509 0122 82437FX
8510 0309 80303 I/O Processor PCI-to-PCI Bridge
8511 030d 80312 I/O Companion Chip PCI-to-PCI Bridge
8512 0326 6700/6702PXH I/OxAPIC Interrupt Controller A
8513 0327 6700PXH I/OxAPIC Interrupt Controller B
8514 0329 6700PXH PCI Express-to-PCI Bridge A
8515 032a 6700PXH PCI Express-to-PCI Bridge B
8516 032c 6702PXH PCI Express-to-PCI Bridge A
8517# A-segment bridge
8518 0330 80332 [Dobson] I/O processor
8519# A-segment IOAPIC
8520 0331 80332 [Dobson] I/O processor
8521# B-segment bridge
8522 0332 80332 [Dobson] I/O processor
8523# B-segment IOAPIC
8524 0333 80332 [Dobson] I/O processor
8525# Address Translation Unit (ATU)
8526 0334 80332 [Dobson] I/O processor
8527# PCI-X bridge
8528 0335 80331 [Lindsay] I/O processor
8529# Address Translation Unit (ATU)
8530 0336 80331 [Lindsay] I/O processor
8531# A-segment bridge
8532 0340 41210 [Lanai] Serial to Parallel PCI Bridge
8533# B-segment bridge
8534 0341 41210 [Lanai] Serial to Parallel PCI Bridge
8535 0482 82375EB/SB PCI to EISA Bridge
8536 0483 82424TX/ZX [Saturn] CPU to PCI bridge
8537 0484 82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
8538 0486 82425EX/ZX [Aries] PCIset with ISA bridge
8539 04a3 82434LX/NX [Mercury/Neptune] Processor to PCI bridge
8540 04d0 82437FX [Triton FX]
8541 0500 E8870 Processor bus control
8542 0501 E8870 Memory controller
8543# and registers common to both SPs
8544 0502 E8870 Scalability Port 0
8545# and global performance monitoring
8546 0503 E8870 Scalability Port 1
8547 0510 E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
8548 0511 E8870IO Hub Interface Port 1 registers
8549 0512 E8870IO Hub Interface Port 2 registers
8550 0513 E8870IO Hub Interface Port 3 registers
8551 0514 E8870IO Hub Interface Port 4 registers
8552 0515 E8870IO General SIOH registers
8553 0516 E8870IO RAS registers
8554 0530 E8870SP Scalability Port 0 registers
8555 0531 E8870SP Scalability Port 1 registers
8556 0532 E8870SP Scalability Port 2 registers
8557 0533 E8870SP Scalability Port 3 registers
8558 0534 E8870SP Scalability Port 4 registers
8559 0535 E8870SP Scalability Port 5 registers
8560# (bi-interleave 0) and global registers that are neither per-port nor per-interleave
8561 0536 E8870SP Interleave registers 0 and 1
8562# (bi-interleave 1)
8563 0537 E8870SP Interleave registers 2 and 3
8564 0600 RAID Controller
8565 8086 01c1 ICP Vortex GDT8546RZ
8566 8086 01f7 SCRU32
8567# uninitialized SRCU32 RAID Controller
8568 061f 80303 I/O Processor
8569 0960 80960RP [i960 RP Microprocessor/Bridge]
8570 0962 80960RM [i960RM Bridge]
8571 0964 80960RP [i960 RP Microprocessor/Bridge]
8572 1000 82542 Gigabit Ethernet Controller
8573 0e11 b0df NC1632 Gigabit Ethernet Adapter (1000-SX)
8574 0e11 b0e0 NC1633 Gigabit Ethernet Adapter (1000-LX)
8575 0e11 b123 NC1634 Gigabit Ethernet Adapter (1000-SX)
8576 1014 0119 Netfinity Gigabit Ethernet SX Adapter
8577 8086 1000 PRO/1000 Gigabit Server Adapter
8578 1001 82543GC Gigabit Ethernet Controller (Fiber)
8579 0e11 004a NC6136 Gigabit Server Adapter
8580 1014 01ea Netfinity Gigabit Ethernet SX Adapter
8581 8086 1002 PRO/1000 F Server Adapter
8582 8086 1003 PRO/1000 F Server Adapter
8583 1002 Pro 100 LAN+Modem 56 Cardbus II
8584 8086 200e Pro 100 LAN+Modem 56 Cardbus II
8585 8086 2013 Pro 100 SR Mobile Combo Adapter
8586 8086 2017 Pro 100 S Combo Mobile Adapter
8587 1004 82543GC Gigabit Ethernet Controller (Copper)
8588 0e11 0049 NC7132 Gigabit Upgrade Module
8589 0e11 b1a4 NC7131 Gigabit Server Adapter
8590 1014 10f2 Gigabit Ethernet Server Adapter
8591 8086 1004 PRO/1000 T Server Adapter
8592 8086 2004 PRO/1000 T Server Adapter
8593 1008 82544EI Gigabit Ethernet Controller (Copper)
8594 1014 0269 iSeries 1000/100/10 Ethernet Adapter
8595 1028 011c PRO/1000 XT Network Connection
8596 8086 1107 PRO/1000 XT Server Adapter
8597 8086 2107 PRO/1000 XT Server Adapter
8598 8086 2110 PRO/1000 XT Server Adapter
8599 8086 3108 PRO/1000 XT Network Connection
8600 1009 82544EI Gigabit Ethernet Controller (Fiber)
8601 1014 0268 iSeries Gigabit Ethernet Adapter
8602 8086 1109 PRO/1000 XF Server Adapter
8603 8086 2109 PRO/1000 XF Server Adapter
8604 100c 82544GC Gigabit Ethernet Controller (Copper)
8605 8086 1112 PRO/1000 T Desktop Adapter
8606 8086 2112 PRO/1000 T Desktop Adapter
8607 100d 82544GC Gigabit Ethernet Controller (LOM)
8608 1028 0123 PRO/1000 XT Network Connection
8609 1079 891f 82544GC Based Network Connection
8610 4c53 1080 CT8 mainboard
8611 8086 110d 82544GC Based Network Connection
8612 100e 82540EM Gigabit Ethernet Controller
8613 1014 0265 PRO/1000 MT Network Connection
8614 1014 0267 PRO/1000 MT Network Connection
8615 1014 026a PRO/1000 MT Network Connection
8616 1028 002e Optiplex GX260
8617 1028 0151 PRO/1000 MT Network Connection
8618 107b 8920 PRO/1000 MT Desktop Adapter
8619 8086 001e PRO/1000 MT Desktop Adapter
8620 8086 002e PRO/1000 MT Desktop Adapter
8621 100f 82545EM Gigabit Ethernet Controller (Copper)
8622 1014 0269 iSeries 1000/100/10 Ethernet Adapter
8623 1014 028e PRO/1000 MT Network Connection
8624 8086 1000 PRO/1000 MT Network Connection
8625 8086 1001 PRO/1000 MT Server Adapter
8626 1010 82546EB Gigabit Ethernet Controller (Copper)
8627 1014 027c PRO/1000 MT Dual Port Network Adapter
8628 18fb 7872 RESlink-X
8629 4c53 1080 CT8 mainboard
8630 4c53 10a0 CA3/CR3 mainboard
8631 8086 1011 PRO/1000 MT Dual Port Server Adapter
8632 8086 101a PRO/1000 MT Dual Port Network Adapter
8633 8086 3424 SE7501HG2 Mainboard
8634 1011 82545EM Gigabit Ethernet Controller (Fiber)
8635 1014 0268 iSeries Gigabit Ethernet Adapter
8636 8086 1002 PRO/1000 MF Server Adapter
8637 8086 1003 PRO/1000 MF Server Adapter (LX)
8638 1012 82546EB Gigabit Ethernet Controller (Fiber)
8639 8086 1012 PRO/1000 MF Dual Port Server Adapter
8640 1013 82541EI Gigabit Ethernet Controller (Copper)
8641 8086 0013 PRO/1000 MT Network Connection
8642 8086 1013 IBM ThinkCentre Network Card
8643 8086 1113 PRO/1000 MT Desktop Adapter
8644 1014 82541ER Gigabit Ethernet Controller
8645 1015 82540EM Gigabit Ethernet Controller (LOM)
8646 1016 82540EP Gigabit Ethernet Controller (LOM)
8647 1014 052c PRO/1000 MT Mobile Connection
8648 1179 0001 PRO/1000 MT Mobile Connection
8649 8086 1016 PRO/1000 MT Mobile Connection
8650 1017 82540EP Gigabit Ethernet Controller (LOM)
8651 8086 1017 PR0/1000 MT Desktop Connection
8652# Update controller name from 82541EP to 82541EI
8653 1018 82541EI Gigabit Ethernet Controller
8654 8086 1018 PRO/1000 MT Desktop Adapter
8655 1019 82547EI Gigabit Ethernet Controller (LOM)
8656 1458 1019 GA-8IPE1000 Pro2 motherboard (865PE)
8657 1458 e000 Intel Gigabit Ethernet (Kenai II)
8658 8086 1019 PRO/1000 CT Desktop Connection
8659 8086 301f D865PERL mainboard
8660 8086 3427 S875WP1-E mainboard
8661 101d 82546EB Gigabit Ethernet Controller
8662 8086 1000 PRO/1000 MT Quad Port Server Adapter
8663 101e 82540EP Gigabit Ethernet Controller (Mobile)
8664 1014 0549 PRO/1000 MT Mobile Connection
8665 1179 0001 PRO/1000 MT Mobile Connection
8666 8086 101e PRO/1000 MT Mobile Connection
8667 1026 82545GM Gigabit Ethernet Controller
8668 8086 1000 PRO/1000 MT Server Connection
8669 8086 1001 PRO/1000 MT Server Adapter
8670 8086 1002 PRO/1000 MT Server Adapter
8671 8086 1026 PRO/1000 MT Server Connection
8672 1027 82545GM Gigabit Ethernet Controller
8673 8086 1001 PRO/1000 MF Server Adapter(LX)
8674 8086 1002 PRO/1000 MF Server Adapter(LX)
8675 8086 1003 PRO/1000 MF Server Adapter(LX)
8676 8086 1027 PRO/1000 MF Server Adapter
8677 1028 82545GM Gigabit Ethernet Controller
8678 8086 1028 PRO/1000 MB Server Adapter
8679 1029 82559 Ethernet Controller
8680 1030 82559 InBusiness 10/100
8681 1031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
8682 1014 0209 ThinkPad A/T/X Series
8683 104d 80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
8684 107b 5350 EtherExpress PRO/100 VE
8685 1179 0001 EtherExpress PRO/100 VE
8686 144d c000 EtherExpress PRO/100 VE
8687 144d c001 EtherExpress PRO/100 VE
8688 144d c003 EtherExpress PRO/100 VE
8689 144d c006 vpr Matrix 170B4
8690 1032 82801CAM (ICH3) PRO/100 VE Ethernet Controller
8691 1033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
8692 1034 82801CAM (ICH3) PRO/100 VM Ethernet Controller
8693 1035 82801CAM (ICH3)/82562EH (LOM) Ethernet Controller
8694 1036 82801CAM (ICH3) 82562EH Ethernet Controller
8695 1037 82801CAM (ICH3) Chipset Ethernet Controller
8696 1038 82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
8697 1039 82801DB PRO/100 VE (LOM) Ethernet Controller
8698 1014 0267 NetVista A30p
8699 103a 82801DB PRO/100 VE (CNR) Ethernet Controller
8700 103b 82801DB PRO/100 VM (LOM) Ethernet Controller
8701 103c 82801DB PRO/100 VM (CNR) Ethernet Controller
8702 103d 82801DB PRO/100 VE (MOB) Ethernet Controller
8703 103e 82801DB PRO/100 VM (MOB) Ethernet Controller
8704 1040 536EP Data Fax Modem
8705 16be 1040 V.9X DSP Data Fax Modem
8706 1043 PRO/Wireless LAN 2100 3B Mini PCI Adapter
8707 8086 2527 MIM2000/Centrino
8708 1048 PRO/10GbE LR Server Adapter
8709 8086 a01f PRO/10GbE LR Server Adapter
8710 8086 a11f PRO/10GbE LR Server Adapter
8711 1050 82562EZ 10/100 Ethernet Controller
8712 1462 728c 865PE Neo2 (MS-6728)
8713 1462 758c MS-6758 (875P Neo)
8714 8086 3020 D865PERL mainboard
8715 8086 3427 S875WP1-E mainboard
8716 1051 82801EB/ER (ICH5/ICH5R) integrated LAN Controller
8717 1059 82551QM Ethernet Controller
8718# ICH-6 Component
8719 1064 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
8720# ICH-6 Component
8721 1065 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
8722# ICH-6 Component
8723 1066 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
8724# ICH-6 Component
8725 1067 82562 EM/EX/GX - PRO/100 VM Ethernet Controller
8726# ICH-6 Component
8727 1068 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
8728# ICH-6 Component
8729 1069 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
8730# ICH-6 Component
8731 106a 82562G \t- PRO/100 VE (LOM) Ethernet Controller
8732# ICH-6 Component
8733 106b 82562G \t- PRO/100 VE Ethernet Controller Mobile
8734 1075 82547GI Gigabit Ethernet Controller
8735 1028 0165 PowerEdge 750
8736 8086 0075 PRO/1000 CT Network Connection
8737 8086 1075 PRO/1000 CT Network Connection
8738 1076 82541GI/PI Gigabit Ethernet Controller
8739 1028 0165 PowerEdge 750
8740 8086 0076 PRO/1000 MT Network Connection
8741 8086 1076 PRO/1000 MT Network Connection
8742 8086 1176 PRO/1000 MT Desktop Adapter
8743 8086 1276 PRO/1000 MT Desktop Adapter
8744 1077 82541GI Gigabit Ethernet Controller
8745 1179 0001 PRO/1000 MT Mobile Connection
8746 8086 0077 PRO/1000 MT Mobile Connection
8747 8086 1077 PRO/1000 MT Mobile Connection
8748 1078 82541EI Gigabit Ethernet Controller
8749 8086 1078 PRO/1000 MT Network Connection
8750 1079 82546GB Gigabit Ethernet Controller
8751 103c 12a6 HP Dual Port 1000Base-T [A9900A]
8752 103c 12cf HP Core Dual Port 1000Base-T [AB352A]
8753 4c53 1090 Cx9 / Vx9 mainboard
8754 4c53 10b0 CL9 mainboard
8755 8086 0079 PRO/1000 MT Dual Port Network Connection
8756 8086 1079 PRO/1000 MT Dual Port Network Connection
8757 8086 1179 PRO/1000 MT Dual Port Network Connection
8758 8086 117a PRO/1000 MT Dual Port Server Adapter
8759 107a 82546GB Gigabit Ethernet Controller
8760 103c 12a8 HP Dual Port 1000base-SX [A9899A]
8761 8086 107a PRO/1000 MF Dual Port Server Adapter
8762 8086 127a PRO/1000 MF Dual Port Server Adapter
8763 107b 82546GB Gigabit Ethernet Controller
8764 8086 007b PRO/1000 MB Dual Port Server Connection
8765 8086 107b PRO/1000 MB Dual Port Server Connection
8766 1107 PRO/1000 MF Server Adapter (LX)
8767 1130 82815 815 Chipset Host Bridge and Memory Controller Hub
8768 1025 1016 Travelmate 612 TX
8769 1043 8027 TUSL2-C Mainboard
8770 104d 80df Vaio PCG-FX403
8771 8086 4532 D815EEA2 mainboard
8772 8086 4557 D815EGEW Mainboard
8773 1131 82815 815 Chipset AGP Bridge
8774 1132 82815 CGC [Chipset Graphics Controller]
8775 1025 1016 Travelmate 612 TX
8776 104d 80df Vaio PCG-FX403
8777 8086 4532 D815EEA2 Mainboard
8778 8086 4557 D815EGEW Mainboard
8779 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller
8780 8086 1161 82806AA PCI64 Hub APIC
8781 1162 Xscale 80200 Big Endian Companion Chip
8782 1200 Intel IXP1200 Network Processor
8783 172a 0000 AEP SSL Accelerator
8784 1209 8255xER/82551IT Fast Ethernet Controller
8785 4c53 1050 CT7 mainboard
8786 4c53 1051 CE7 mainboard
8787 4c53 1070 PC6 mainboard
8788 1221 82092AA PCI to PCMCIA Bridge
8789 1222 82092AA IDE Controller
8790 1223 SAA7116
8791 1225 82452KX/GX [Orion]
8792 1226 82596 PRO/10 PCI
8793 1227 82865 EtherExpress PRO/100A
8794 1228 82556 EtherExpress PRO/100 Smart
8795# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
8796 1229 82557/8/9 [Ethernet Pro 100]
8797 0e11 3001 82559 Fast Ethernet LOM with Alert on LAN*
8798 0e11 3002 82559 Fast Ethernet LOM with Alert on LAN*
8799 0e11 3003 82559 Fast Ethernet LOM with Alert on LAN*
8800 0e11 3004 82559 Fast Ethernet LOM with Alert on LAN*
8801 0e11 3005 82559 Fast Ethernet LOM with Alert on LAN*
8802 0e11 3006 82559 Fast Ethernet LOM with Alert on LAN*
8803 0e11 3007 82559 Fast Ethernet LOM with Alert on LAN*
8804 0e11 b01e NC3120 Fast Ethernet NIC
8805 0e11 b01f NC3122 Fast Ethernet NIC (dual port)
8806 0e11 b02f NC1120 Ethernet NIC
8807 0e11 b04a Netelligent 10/100TX NIC with Wake on LAN
8808 0e11 b0c6 NC3161 Fast Ethernet NIC (embedded, WOL)
8809 0e11 b0c7 NC3160 Fast Ethernet NIC (embedded)
8810 0e11 b0d7 NC3121 Fast Ethernet NIC (WOL)
8811 0e11 b0dd NC3131 Fast Ethernet NIC (dual port)
8812 0e11 b0de NC3132 Fast Ethernet Module (dual port)
8813 0e11 b0e1 NC3133 Fast Ethernet Module (100-FX)
8814 0e11 b134 NC3163 Fast Ethernet NIC (embedded, WOL)
8815 0e11 b13c NC3162 Fast Ethernet NIC (embedded)
8816 0e11 b144 NC3123 Fast Ethernet NIC (WOL)
8817 0e11 b163 NC3134 Fast Ethernet NIC (dual port)
8818 0e11 b164 NC3135 Fast Ethernet Upgrade Module (dual port)
8819 0e11 b1a4 NC7131 Gigabit Server Adapter
8820 1014 005c 82558B Ethernet Pro 10/100
8821 1014 01bc 82559 Fast Ethernet LAN On Motherboard
8822 1014 01f1 10/100 Ethernet Server Adapter
8823 1014 01f2 10/100 Ethernet Server Adapter
8824 1014 0207 Ethernet Pro/100 S
8825 1014 0232 10/100 Dual Port Server Adapter
8826 1014 023a ThinkPad R30
8827 1014 105c Netfinity 10/100
8828 1014 2205 ThinkPad A22p
8829 1014 305c 10/100 EtherJet Management Adapter
8830 1014 405c 10/100 EtherJet Adapter with Alert on LAN
8831 1014 505c 10/100 EtherJet Secure Management Adapter
8832 1014 605c 10/100 EtherJet Secure Management Adapter
8833 1014 705c 10/100 Netfinity 10/100 Ethernet Security Adapter
8834 1014 805c 10/100 Netfinity 10/100 Ethernet Security Adapter
8835 1028 009b PowerEdge 2500/2550
8836 1028 00ce PowerEdge 1400
8837 1033 8000 PC-9821X-B06
8838 1033 8016 PK-UG-X006
8839 1033 801f PK-UG-X006
8840 1033 8026 PK-UG-X006
8841 1033 8063 82559-based Fast Ethernet Adapter
8842 1033 8064 82559-based Fast Ethernet Adapter
8843 103c 10c0 NetServer 10/100TX
8844 103c 10c3 NetServer 10/100TX
8845 103c 10ca NetServer 10/100TX
8846 103c 10cb NetServer 10/100TX
8847 103c 10e3 NetServer 10/100TX
8848 103c 10e4 NetServer 10/100TX
8849 103c 1200 NetServer 10/100TX
8850 10c3 1100 SmartEther100 SC1100
8851 10cf 1115 8255x-based Ethernet Adapter (10/100)
8852 10cf 1143 8255x-based Ethernet Adapter (10/100)
8853 1179 0001 8255x-based Ethernet Adapter (10/100)
8854 1179 0002 PCI FastEther LAN on Docker
8855 1179 0003 8255x-based Fast Ethernet
8856 1259 2560 AT-2560 100
8857 1259 2561 AT-2560 100 FX Ethernet Adapter
8858 1266 0001 NE10/100 Adapter
8859 13e9 1000 6221L-4U
8860 144d 2501 SEM-2000 MiniPCI LAN Adapter
8861 144d 2502 SEM-2100IL MiniPCI LAN Adapter
8862 1668 1100 EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
8863 4c53 1080 CT8 mainboard
8864 8086 0001 EtherExpress PRO/100B (TX)
8865 8086 0002 EtherExpress PRO/100B (T4)
8866 8086 0003 EtherExpress PRO/10+
8867 8086 0004 EtherExpress PRO/100 WfM
8868 8086 0005 82557 10/100
8869 8086 0006 82557 10/100 with Wake on LAN
8870 8086 0007 82558 10/100 Adapter
8871 8086 0008 82558 10/100 with Wake on LAN
8872 8086 0009 EtherExpress PRO/100+
8873 8086 000a EtherExpress PRO/100+ Management Adapter
8874 8086 000b EtherExpress PRO/100+
8875 8086 000c EtherExpress PRO/100+ Management Adapter
8876 8086 000d EtherExpress PRO/100+ Alert On LAN II* Adapter
8877 8086 000e EtherExpress PRO/100+ Management Adapter with Alert On LAN*
8878 8086 000f EtherExpress PRO/100 Desktop Adapter
8879 8086 0010 EtherExpress PRO/100 S Management Adapter
8880 8086 0011 EtherExpress PRO/100 S Management Adapter
8881 8086 0012 EtherExpress PRO/100 S Advanced Management Adapter (D)
8882 8086 0013 EtherExpress PRO/100 S Advanced Management Adapter (E)
8883 8086 0030 EtherExpress PRO/100 Management Adapter with Alert On LAN* GC
8884 8086 0031 EtherExpress PRO/100 Desktop Adapter
8885 8086 0040 EtherExpress PRO/100 S Desktop Adapter
8886 8086 0041 EtherExpress PRO/100 S Desktop Adapter
8887 8086 0042 EtherExpress PRO/100 Desktop Adapter
8888 8086 0050 EtherExpress PRO/100 S Desktop Adapter
8889 8086 1009 EtherExpress PRO/100+ Server Adapter
8890 8086 100c EtherExpress PRO/100+ Server Adapter (PILA8470B)
8891 8086 1012 EtherExpress PRO/100 S Server Adapter (D)
8892 8086 1013 EtherExpress PRO/100 S Server Adapter (E)
8893 8086 1015 EtherExpress PRO/100 S Dual Port Server Adapter
8894 8086 1017 EtherExpress PRO/100+ Dual Port Server Adapter
8895 8086 1030 EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
8896 8086 1040 EtherExpress PRO/100 S Server Adapter
8897 8086 1041 EtherExpress PRO/100 S Server Adapter
8898 8086 1042 EtherExpress PRO/100 Server Adapter
8899 8086 1050 EtherExpress PRO/100 S Server Adapter
8900 8086 1051 EtherExpress PRO/100 Server Adapter
8901 8086 1052 EtherExpress PRO/100 Server Adapter
8902 8086 10f0 EtherExpress PRO/100+ Dual Port Adapter
8903 8086 2009 EtherExpress PRO/100 S Mobile Adapter
8904 8086 200d EtherExpress PRO/100 Cardbus
8905 8086 200e EtherExpress PRO/100 LAN+V90 Cardbus Modem
8906 8086 200f EtherExpress PRO/100 SR Mobile Adapter
8907 8086 2010 EtherExpress PRO/100 S Mobile Combo Adapter
8908 8086 2013 EtherExpress PRO/100 SR Mobile Combo Adapter
8909 8086 2016 EtherExpress PRO/100 S Mobile Adapter
8910 8086 2017 EtherExpress PRO/100 S Combo Mobile Adapter
8911 8086 2018 EtherExpress PRO/100 SR Mobile Adapter
8912 8086 2019 EtherExpress PRO/100 SR Combo Mobile Adapter
8913 8086 2101 EtherExpress PRO/100 P Mobile Adapter
8914 8086 2102 EtherExpress PRO/100 SP Mobile Adapter
8915 8086 2103 EtherExpress PRO/100 SP Mobile Adapter
8916 8086 2104 EtherExpress PRO/100 SP Mobile Adapter
8917 8086 2105 EtherExpress PRO/100 SP Mobile Adapter
8918 8086 2106 EtherExpress PRO/100 P Mobile Adapter
8919 8086 2107 EtherExpress PRO/100 Network Connection
8920 8086 2108 EtherExpress PRO/100 Network Connection
8921 8086 2200 EtherExpress PRO/100 P Mobile Combo Adapter
8922 8086 2201 EtherExpress PRO/100 P Mobile Combo Adapter
8923 8086 2202 EtherExpress PRO/100 SP Mobile Combo Adapter
8924 8086 2203 EtherExpress PRO/100+ MiniPCI
8925 8086 2204 EtherExpress PRO/100+ MiniPCI
8926 8086 2205 EtherExpress PRO/100 SP Mobile Combo Adapter
8927 8086 2206 EtherExpress PRO/100 SP Mobile Combo Adapter
8928 8086 2207 EtherExpress PRO/100 SP Mobile Combo Adapter
8929 8086 2208 EtherExpress PRO/100 P Mobile Combo Adapter
8930 8086 2402 EtherExpress PRO/100+ MiniPCI
8931 8086 2407 EtherExpress PRO/100+ MiniPCI
8932 8086 2408 EtherExpress PRO/100+ MiniPCI
8933 8086 2409 EtherExpress PRO/100+ MiniPCI
8934 8086 240f EtherExpress PRO/100+ MiniPCI
8935 8086 2410 EtherExpress PRO/100+ MiniPCI
8936 8086 2411 EtherExpress PRO/100+ MiniPCI
8937 8086 2412 EtherExpress PRO/100+ MiniPCI
8938 8086 2413 EtherExpress PRO/100+ MiniPCI
8939 8086 3000 82559 Fast Ethernet LAN on Motherboard
8940 8086 3001 82559 Fast Ethernet LOM with Basic Alert on LAN*
8941 8086 3002 82559 Fast Ethernet LOM with Alert on LAN II*
8942 8086 3006 EtherExpress PRO/100 S Network Connection
8943 8086 3007 EtherExpress PRO/100 S Network Connection
8944 8086 3008 EtherExpress PRO/100 Network Connection
8945 8086 3010 EtherExpress PRO/100 S Network Connection
8946 8086 3011 EtherExpress PRO/100 S Network Connection
8947 8086 3012 EtherExpress PRO/100 Network Connection
8948 8086 3411 SDS2 Mainboard
8949 122d 430FX - 82437FX TSC [Triton I]
8950 122e 82371FB PIIX ISA [Triton I]
8951 1230 82371FB PIIX IDE [Triton I]
8952 1231 DSVD Modem
8953 1234 430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
8954 1235 430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
8955 1237 440FX - 82441FX PMC [Natoma]
8956 1239 82371FB PIIX IDE Interface
8957 123b 82380PB PCI to PCI Docking Bridge
8958 123c 82380AB (MISA) Mobile PCI-to-ISA Bridge
8959 123d 683053 Programmable Interrupt Device
8960# in" hidden" mode
8961 123e 82466GX (IHPC) Integrated Hot-Plug Controller
8962 123f 82466GX Integrated Hot-Plug Controller (IHPC)
8963 1240 82752 (752) AGP Graphics Accelerator
8964 124b 82380FB (MPCI2) Mobile Docking Controller
8965 1250 430HX - 82439HX TXC [Triton II]
8966 1360 82806AA PCI64 Hub PCI Bridge
8967 1361 82806AA PCI64 Hub Controller (HRes)
8968 8086 1361 82806AA PCI64 Hub Controller (HRes)
8969 8086 8000 82806AA PCI64 Hub Controller (HRes)
8970 1460 82870P2 P64H2 Hub PCI Bridge
8971 1461 82870P2 P64H2 I/OxAPIC
8972 15d9 3480 P4DP6
8973 4c53 1090 Cx9 / Vx9 mainboard
8974 1462 82870P2 P64H2 Hot Plug Controller
8975 1960 80960RP [i960RP Microprocessor]
8976 101e 0431 MegaRAID 431 RAID Controller
8977 101e 0438 MegaRAID 438 Ultra2 LVD RAID Controller
8978 101e 0466 MegaRAID 466 Express Plus RAID Controller
8979 101e 0467 MegaRAID 467 Enterprise 1500 RAID Controller
8980 101e 0490 MegaRAID 490 Express 300 RAID Controller
8981 101e 0762 MegaRAID 762 Express RAID Controller
8982 101e 09a0 PowerEdge Expandable RAID Controller 2/SC
8983 1028 0467 PowerEdge Expandable RAID Controller 2/DC
8984 1028 1111 PowerEdge Expandable RAID Controller 2/SC
8985 103c 03a2 MegaRAID
8986 103c 10c6 MegaRAID 438, HP NetRAID-3Si
8987 103c 10c7 MegaRAID T5, Integrated HP NetRAID
8988 103c 10cc MegaRAID, Integrated HP NetRAID
8989 103c 10cd HP NetRAID-1Si
8990 105a 0000 SuperTrak
8991 105a 2168 SuperTrak Pro
8992 105a 5168 SuperTrak66/100
8993 1111 1111 MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
8994 1111 1112 PowerEdge Expandable RAID Controller 2/SC
8995 113c 03a2 MegaRAID
8996 e4bf 1010 CG1-RADIO
8997 e4bf 1020 CU2-QUARTET
8998 e4bf 1040 CU1-CHORUS
8999 e4bf 3100 CX1-BAND
9000 1962 80960RM [i960RM Microprocessor]
9001 105a 0000 SuperTrak SX6000 I2O CPU
9002 1a21 82840 840 (Carmel) Chipset Host Bridge (Hub A)
9003 1a23 82840 840 (Carmel) Chipset AGP Bridge
9004 1a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B)
9005 1a30 82845 845 (Brookdale) Chipset Host Bridge
9006 1028 010e Optiplex GX240
9007 1a31 82845 845 (Brookdale) Chipset AGP Bridge
9008 2410 82801AA ISA Bridge (LPC)
9009 2411 82801AA IDE
9010 2412 82801AA USB
9011 2413 82801AA SMBus
9012 2415 82801AA AC'97 Audio
9013 1028 0095 Precision Workstation 220 Integrated Digital Audio
9014 11d4 0040 SoundMAX Integrated Digital Audio
9015 11d4 0048 SoundMAX Integrated Digital Audio
9016 11d4 5340 SoundMAX Integrated Digital Audio
9017 2416 82801AA AC'97 Modem
9018 2418 82801AA PCI Bridge
9019 2420 82801AB ISA Bridge (LPC)
9020 2421 82801AB IDE
9021 2422 82801AB USB
9022 2423 82801AB SMBus
9023 2425 82801AB AC'97 Audio
9024 11d4 0040 SoundMAX Integrated Digital Audio
9025 11d4 0048 SoundMAX Integrated Digital Audio
9026 2426 82801AB AC'97 Modem
9027 2428 82801AB PCI Bridge
9028 2440 82801BA ISA Bridge (LPC)
9029 2442 82801BA/BAM USB (Hub #1)
9030 1014 01c6 Netvista A40/A40p
9031 1025 1016 Travelmate 612 TX
9032 1028 010e Optiplex GX240
9033 1043 8027 TUSL2-C Mainboard
9034 104d 80df Vaio PCG-FX403
9035 147b 0507 TH7II-RAID
9036 8086 4532 D815EEA2 mainboard
9037 8086 4557 D815EGEW Mainboard
9038 2443 82801BA/BAM SMBus
9039 1014 01c6 Netvista A40/A40p
9040 1025 1016 Travelmate 612 TX
9041 1028 010e Optiplex GX240
9042 1043 8027 TUSL2-C Mainboard
9043 104d 80df Vaio PCG-FX403
9044 147b 0507 TH7II-RAID
9045 8086 4532 D815EEA2 mainboard
9046 8086 4557 D815EGEW Mainboard
9047 2444 82801BA/BAM USB (Hub #2)
9048 1025 1016 Travelmate 612 TX
9049 1028 010e Optiplex GX240
9050 1043 8027 TUSL2-C Mainboard
9051 104d 80df Vaio PCG-FX403
9052 147b 0507 TH7II-RAID
9053 8086 4532 D815EEA2 mainboard
9054 2445 82801BA/BAM AC'97 Audio
9055 1014 01c6 Netvista A40/A40p
9056 1025 1016 Travelmate 612 TX
9057 104d 80df Vaio PCG-FX403
9058 1462 3370 STAC9721 AC
9059 147b 0507 TH7II-RAID
9060 8086 4557 D815EGEW Mainboard
9061 2446 82801BA/BAM AC'97 Modem
9062 1025 1016 Travelmate 612 TX
9063 104d 80df Vaio PCG-FX403
9064 2448 82801 Mobile PCI Bridge
9065 2449 82801BA/BAM/CA/CAM Ethernet Controller
9066 0e11 0012 EtherExpress PRO/100 VM
9067 0e11 0091 EtherExpress PRO/100 VE
9068 1014 01ce EtherExpress PRO/100 VE
9069 1014 01dc EtherExpress PRO/100 VE
9070 1014 01eb EtherExpress PRO/100 VE
9071 1014 01ec EtherExpress PRO/100 VE
9072 1014 0202 EtherExpress PRO/100 VE
9073 1014 0205 EtherExpress PRO/100 VE
9074 1014 0217 EtherExpress PRO/100 VE
9075 1014 0234 EtherExpress PRO/100 VE
9076 1014 023d EtherExpress PRO/100 VE
9077 1014 0244 EtherExpress PRO/100 VE
9078 1014 0245 EtherExpress PRO/100 VE
9079 1014 0265 PRO/100 VE Desktop Connection
9080 1014 0267 PRO/100 VE Desktop Connection
9081 1014 026a PRO/100 VE Desktop Connection
9082 109f 315d EtherExpress PRO/100 VE
9083 109f 3181 EtherExpress PRO/100 VE
9084 1179 ff01 PRO/100 VE Network Connection
9085 1186 7801 EtherExpress PRO/100 VE
9086 144d 2602 HomePNA 1M CNR
9087 8086 3010 EtherExpress PRO/100 VE
9088 8086 3011 EtherExpress PRO/100 VM
9089 8086 3012 82562EH based Phoneline
9090 8086 3013 EtherExpress PRO/100 VE
9091 8086 3014 EtherExpress PRO/100 VM
9092 8086 3015 82562EH based Phoneline
9093 8086 3016 EtherExpress PRO/100 P Mobile Combo
9094 8086 3017 EtherExpress PRO/100 P Mobile
9095 8086 3018 EtherExpress PRO/100
9096 244a 82801BAM IDE U100
9097 1025 1016 Travelmate 612TX
9098 104d 80df Vaio PCG-FX403
9099 244b 82801BA IDE U100
9100 1014 01c6 Netvista A40/A40p
9101 1028 010e Optiplex GX240
9102 1043 8027 TUSL2-C Mainboard
9103 147b 0507 TH7II-RAID
9104 8086 4532 D815EEA2 mainboard
9105 8086 4557 D815EGEW Mainboard
9106 244c 82801BAM ISA Bridge (LPC)
9107 244e 82801 PCI Bridge
9108 1014 0267 NetVista A30p
9109 2450 82801E ISA Bridge (LPC)
9110 2452 82801E USB
9111 2453 82801E SMBus
9112 2459 82801E Ethernet Controller 0
9113 245b 82801E IDE U100
9114 245d 82801E Ethernet Controller 1
9115 245e 82801E PCI Bridge
9116 2480 82801CA LPC Interface Controller
9117 2482 82801CA/CAM USB (Hub #1)
9118 1014 0220 ThinkPad A/T/X Series
9119 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9120 15d9 3480 P4DP6
9121 8086 1958 vpr Matrix 170B4
9122 8086 3424 SE7501HG2 Mainboard
9123 8086 4541 Latitude C640
9124 2483 82801CA/CAM SMBus Controller
9125 1014 0220 ThinkPad A/T/X Series
9126 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9127 15d9 3480 P4DP6
9128 8086 1958 vpr Matrix 170B4
9129 2484 82801CA/CAM USB (Hub #2)
9130 1014 0220 ThinkPad A/T/X Series
9131 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9132 15d9 3480 P4DP6
9133 8086 1958 vpr Matrix 170B4
9134 2485 82801CA/CAM AC'97 Audio Controller
9135 1013 5959 Crystal WMD Audio Codec
9136 1014 0222 ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653)
9137 1014 0508 ThinkPad T30
9138 1014 051c ThinkPad A/T/X Series
9139 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9140 144d c006 vpr Matrix 170B4
9141 2486 82801CA/CAM AC'97 Modem Controller
9142 1014 0223 ThinkPad A/T/X Series
9143 1014 0503 ThinkPad R31 2656BBG
9144 1014 051a ThinkPad A/T/X Series
9145 101f 1025 Acer 620 Series
9146 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9147 1179 0001 Toshiba Satellite 1110 Z15 internal Modem
9148 134d 4c21 Dell Inspiron 2100 internal modem
9149 144d 2115 vpr Matrix 170B4 internal modem
9150 14f1 5421 MD56ORD V.92 MDC Modem
9151 2487 82801CA/CAM USB (Hub #3)
9152 1014 0220 ThinkPad A/T/X Series
9153 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9154 15d9 3480 P4DP6
9155 8086 1958 vpr Matrix 170B4
9156 248a 82801CAM IDE U100
9157 1014 0220 ThinkPad A/T/X Series
9158 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9159 8086 1958 vpr Matrix 170B4
9160 8086 4541 Latitude C640
9161 248b 82801CA Ultra ATA Storage Controller
9162 15d9 3480 P4DP6
9163 248c 82801CAM ISA Bridge (LPC)
9164 24c0 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
9165 1014 0267 NetVista A30p
9166 1462 5800 845PE Max (MS-6580)
9167 24c1 82801DBL (ICH4-L) IDE Controller
9168 24c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
9169 1014 0267 NetVista A30p
9170 1025 005a TravelMate 290
9171 1028 0126 Optiplex GX260
9172 1028 0163 Latitude D505
9173 103c 088c nc8000 laptop
9174 103c 0890 nc6000 laptop
9175 1071 8160 MIM2000
9176 1462 5800 845PE Max (MS-6580)
9177 1509 2990 Averatec 5110H laptop
9178 4c53 1090 Cx9 / Vx9 mainboard
9179 24c3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
9180 1014 0267 NetVista A30p
9181 1025 005a TravelMate 290
9182 1028 0126 Optiplex GX260
9183 103c 088c nc8000 laptop
9184 103c 0890 nc6000 laptop
9185 1071 8160 MIM2000
9186 1458 24c2 GA-8PE667 Ultra
9187 1462 5800 845PE Max (MS-6580)
9188 4c53 1090 Cx9 / Vx9 mainboard
9189 24c4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
9190 1014 0267 NetVista A30p
9191 1025 005a TravelMate 290
9192 1028 0126 Optiplex GX260
9193 1028 0163 Latitude D505
9194 103c 088c nc8000 laptop
9195 103c 0890 nc6000 laptop
9196 1071 8160 MIM2000
9197 1462 5800 845PE Max (MS-6580)
9198 1509 2990 Averatec 5110H
9199 4c53 1090 Cx9 / Vx9 mainboard
9200 24c5 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
9201 0e11 00b8 Analog Devices Inc. codec [SoundMAX]
9202 1014 0267 NetVista A30p
9203 1025 005a TravelMate 290
9204 1028 0163 Latitude D505
9205 103c 088c nc8000 laptop
9206 103c 0890 nc6000 laptop
9207 1071 8160 MIM2000
9208 1458 a002 GA-8PE667 Ultra
9209 1462 5800 845PE Max (MS-6580)
9210 24c6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
9211 1025 005a TravelMate 290
9212 103c 088c nc8000 laptop
9213 103c 0890 nc6000 laptop
9214 1071 8160 MIM2000
9215 24c7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
9216 1014 0267 NetVista A30p
9217 1025 005a TravelMate 290
9218 1028 0126 Optiplex GX260
9219 1028 0163 Latitude D505
9220 103c 088c nc8000 laptop
9221 103c 0890 nc6000 laptop
9222 1071 8160 MIM2000
9223 1462 5800 845PE Max (MS-6580)
9224 1509 2990 Averatec 5110H
9225 4c53 1090 Cx9 / Vx9 mainboard
9226 24ca 82801DBM (ICH4-M) IDE Controller
9227 1025 005a TravelMate 290
9228 1028 0163 Latitude D505
9229 103c 088c nc8000 laptop
9230 103c 0890 nc6000 laptop
9231 1071 8160 MIM2000
9232 24cb 82801DB (ICH4) IDE Controller
9233 1014 0267 NetVista A30p
9234 1028 0126 Optiplex GX260
9235 1458 24c2 GA-8PE667 Ultra
9236 1462 5800 845PE Max (MS-6580)
9237 4c53 1090 Cx9 / Vx9 mainboard
9238 24cc 82801DBM (ICH4-M) LPC Interface Bridge
9239 24cd 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
9240 1014 0267 NetVista A30p
9241 1025 005a TravelMate 290
9242 1028 0126 Optiplex GX260
9243 1028 0163 Latitude D505
9244 103c 088c nc8000 laptop
9245 103c 0890 nc6000 laptop
9246 1071 8160 MIM2000
9247 1462 3981 845PE Max (MS-6580)
9248 1509 1968 Averatec 5110H
9249 4c53 1090 Cx9 / Vx9 mainboard
9250 24d0 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
9251 24d1 82801EB (ICH5) SATA Controller
9252 103c 12bc d530 CMT (DG746A)
9253 1458 24d1 GA-8IPE1000 Pro2 motherboard (865PE)
9254 1462 7280 865PE Neo2 (MS-6728)
9255 8086 3427 S875WP1-E mainboard
9256 8086 524c D865PERL mainboard
9257 24d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
9258 1028 0183 PowerEdge 1800
9259 103c 12bc d530 CMT (DG746A)
9260 1043 80a6 P4P800 Mainboard
9261 1458 24d2 GA-8IPE1000/8KNXP motherboard
9262 1462 7280 865PE Neo2 (MS-6728)
9263 8086 3427 S875WP1-E mainboard
9264 8086 524c D865PERL mainboard
9265 24d3 82801EB/ER (ICH5/ICH5R) SMBus Controller
9266 1043 80a6 P4P800 Mainboard
9267 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9268 1462 7280 865PE Neo2 (MS-6728)
9269 8086 3427 S875WP1-E mainboard
9270 8086 524c D865PERL mainboard
9271 24d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
9272 1028 0183 PowerEdge 1800
9273 103c 12bc d530 CMT (DG746A)
9274 1043 80a6 P4P800 Mainboard
9275 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9276 1462 7280 865PE Neo2 (MS-6728)
9277 8086 3427 S875WP1-E mainboard
9278 8086 524c D865PERL mainboard
9279 24d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
9280 103c 12bc Analog Devices codec [SoundMAX Integrated Digital Audio]
9281 1043 80f3 P4P800 Mainboard
9282# Again, I suppose they use the same in different subsystems
9283 1458 a002 GA-8IPE1000/8KNXP motherboard
9284 1462 7280 865PE Neo2 (MS-6728)
9285 8086 a000 D865PERL mainboard
9286 8086 e000 D865PERL mainboard
9287 24d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
9288 24d7 82801EB/ER (ICH5/ICH5R) USB UHCI #3
9289 1028 0183 PowerEdge 1800
9290 103c 12bc d530 CMT (DG746A)
9291 1043 80a6 P4P800 Mainboard
9292 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9293 1462 7280 865PE Neo2 (MS-6728)
9294 8086 3427 S875WP1-E mainboard
9295 8086 524c D865PERL mainboard
9296 24db 82801EB/ER (ICH5/ICH5R) IDE Controller
9297 103c 12bc d530 CMT (DG746A)
9298 1043 80a6 P4P800 Mainboard
9299 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9300 1462 7280 865PE Neo2 (MS-6728)
9301 1462 7580 MSI 875P
9302 8086 24db P4C800 Mainboard
9303 8086 3427 S875WP1-E mainboard
9304 8086 524c D865PERL mainboard
9305 24dc 82801EB (ICH5) LPC Interface Bridge
9306 24dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
9307 1028 0183 PowerEdge 1800
9308 103c 12bc d530 CMT (DG746A)
9309 1043 80a6 P4P800 Mainboard
9310 1458 5006 GA-8IPE1000 Pro2 motherboard (865PE)
9311 1462 7280 865PE Neo2 (MS-6728)
9312 8086 3427 S875WP1-E mainboard
9313 8086 524c D865PERL mainboard
9314 24de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
9315 1043 80a6 P4P800 Mainboard
9316 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9317 1462 7280 865PE Neo2 (MS-6728)
9318 8086 3427 S875WP1-E mainboard
9319 8086 524c D865PERL mainboard
9320 24df 82801ER (ICH5R) SATA Controller
9321 2500 82820 820 (Camino) Chipset Host Bridge (MCH)
9322 1028 0095 Precision Workstation 220 Chipset
9323 1043 801c P3C-2000 system chipset
9324 2501 82820 820 (Camino) Chipset Host Bridge (MCH)
9325 1043 801c P3C-2000 system chipset
9326 250b 82820 820 (Camino) Chipset Host Bridge
9327 250f 82820 820 (Camino) Chipset AGP Bridge
9328 2520 82805AA MTH Memory Translator Hub
9329 2521 82804AA MRH-S Memory Repeater Hub for SDRAM
9330 2530 82850 850 (Tehama) Chipset Host Bridge (MCH)
9331 147b 0507 TH7II-RAID
9332 2531 82860 860 (Wombat) Chipset Host Bridge (MCH)
9333 2532 82850 850 (Tehama) Chipset AGP Bridge
9334 2533 82860 860 (Wombat) Chipset AGP Bridge
9335 2534 82860 860 (Wombat) Chipset PCI Bridge
9336 2540 E7500 Memory Controller Hub
9337 15d9 3480 P4DP6
9338 2541 E7500/E7501 Host RASUM Controller
9339 15d9 3480 P4DP6
9340 4c53 1090 Cx9 / Vx9 mainboard
9341 8086 3424 SE7501HG2 Mainboard
9342 2543 E7500/E7501 Hub Interface B PCI-to-PCI Bridge
9343 2544 E7500/E7501 Hub Interface B RASUM Controller
9344 4c53 1090 Cx9 / Vx9 mainboard
9345 2545 E7500/E7501 Hub Interface C PCI-to-PCI Bridge
9346 2546 E7500/E7501 Hub Interface C RASUM Controller
9347 2547 E7500/E7501 Hub Interface D PCI-to-PCI Bridge
9348 2548 E7500/E7501 Hub Interface D RASUM Controller
9349 254c E7501 Memory Controller Hub
9350 4c53 1090 Cx9 / Vx9 mainboard
9351 8086 3424 SE7501HG2 Mainboard
9352 2550 E7505 Memory Controller Hub
9353 2551 E7505/E7205 Series RAS Controller
9354 2552 E7505/E7205 PCI-to-AGP Bridge
9355 2553 E7505 Hub Interface B PCI-to-PCI Bridge
9356 2554 E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
9357 255d E7205 Memory Controller Hub
9358 2560 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
9359 1028 0126 Optiplex GX260
9360 1458 2560 GA-8PE667 Ultra
9361 1462 5800 845PE Max (MS-6580)
9362 2561 82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
9363 2562 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
9364 1014 0267 NetVista A30p
9365 2570 82865G/PE/P DRAM Controller/Host-Hub Interface
9366 1043 80f2 P4P800 Mainboard
9367 1458 2570 GA-8IPE1000 Pro2 motherboard (865PE)
9368 2571 82865G/PE/P PCI to AGP Controller
9369 2572 82865G Integrated Graphics Controller
9370 2573 82865G/PE/P PCI to CSA Bridge
9371 2576 82865G/PE/P Processor to I/O Memory Interface
9372 2578 82875P/E7210 Memory Controller Hub
9373 1458 2578 GA-8KNXP motherboard (875P)
9374 1462 7580 MS-6758 (875P Neo)
9375# Motherboard P4SCE
9376 15d9 4580 Super Micro Computer Inc. P4SCE
9377 2579 82875P Processor to AGP Controller
9378 257b 82875P/E7210 Processor to PCI to CSA Bridge
9379 257e 82875P/E7210 Processor to I/O Memory Interface
9380 2580 915G/P/GV/GL/PL/910GL Processor to I/O Controller
9381 2581 915G/P/GV/GL/PL/910GL PCI Express Root Port
9382 2582 82915G/GV/910GL Express Chipset Family Graphics Controller
9383 1028 1079 Optiplex GX280
9384 2584 925X/XE Memory Controller Hub
9385 2585 925X/XE PCI Express Root Port
9386 2588 E7220/E7221 Memory Controller Hub
9387 2589 E7220/E7221 PCI Express Root Port
9388 258a E7221 Integrated Graphics Controller
9389 2590 Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
9390 2591 Mobile 915GM/PM Express PCI Express Root Port
9391 2592 Mobile 915GM/GMS/910GML Express Graphics Controller
9392 25a1 6300ESB LPC Interface Controller
9393 25a2 6300ESB PATA Storage Controller
9394 4c53 10b0 CL9 mainboard
9395 25a3 6300ESB SATA Storage Controller
9396 4c53 10b0 CL9 mainboard
9397 25a4 6300ESB SMBus Controller
9398 4c53 10b0 CL9 mainboard
9399 25a6 6300ESB AC'97 Audio Controller
9400 4c53 10b0 CL9 mainboard
9401 25a7 6300ESB AC'97 Modem Controller
9402 25a9 6300ESB USB Universal Host Controller
9403 4c53 10b0 CL9 mainboard
9404 25aa 6300ESB USB Universal Host Controller
9405 4c53 10b0 CL9 mainboard
9406 25ab 6300ESB Watchdog Timer
9407 4c53 10b0 CL9 mainboard
9408 25ac 6300ESB I/O Advanced Programmable Interrupt Controller
9409 4c53 10b0 CL9 mainboard
9410 25ad 6300ESB USB2 Enhanced Host Controller
9411 25ae 6300ESB 64-bit PCI-X Bridge
9412 25b0 6300ESB SATA RAID Controller
9413 2600 E8500 Hub Interface
9414 2601 E8500 PCI Express x4 Port D
9415 2602 E8500 PCI Express x4 Port C0
9416 2603 E8500 PCI Express x4 Port C1
9417 2604 E8500 PCI Express x4 Port B0
9418 2605 E8500 PCI Express x4 Port B1
9419 2606 E8500 PCI Express x4 Port A0
9420 2607 E8500 PCI Express x4 Port A1
9421 2608 E8500 PCI Express x8 Port C
9422 2609 E8500 PCI Express x8 Port B
9423 260a E8500 PCI Express x8 Port A
9424 260c E8500 IMI Registers
9425 2610 E8500 System Bus, Boot, and Interrupt Registers
9426 2611 E8500 Address Mapping Registers
9427 2612 E8500 RAS Registers
9428 2613 E8500 Reserved Registers
9429 2614 E8500 Reserved Registers
9430 2615 E8500 Miscellaneous Registers
9431 2617 E8500 Reserved Registers
9432 2618 E8500 Reserved Registers
9433 2619 E8500 Reserved Registers
9434 261a E8500 Reserved Registers
9435 261b E8500 Reserved Registers
9436 261c E8500 Reserved Registers
9437 261d E8500 Reserved Registers
9438 261e E8500 Reserved Registers
9439 2620 E8500 eXternal Memory Bridge
9440 2621 E8500 XMB Miscellaneous Registers
9441 2622 E8500 XMB Memory Interleaving Registers
9442 2623 E8500 XMB DDR Initialization and Calibration
9443 2624 E8500 XMB Reserved Registers
9444 2625 E8500 XMB Reserved Registers
9445 2626 E8500 XMB Reserved Registers
9446 2627 E8500 XMB Reserved Registers
9447 2640 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
9448 2641 82801FBM (ICH6M) LPC Interface Bridge
9449 2642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
9450 2651 82801FB/FW (ICH6/ICH6W) SATA Controller
9451 1028 0179 Optiplex GX280
9452 2652 82801FR/FRW (ICH6R/ICH6RW) SATA Controller
9453 2653 82801FBM (ICH6M) SATA Controller
9454 2658 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
9455 1028 0179 Optiplex GX280
9456 2659 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
9457 1028 0179 Optiplex GX280
9458 265a 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
9459 1028 0179 Optiplex GX280
9460 265b 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
9461 1028 0179 Optiplex GX280
9462 265c 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
9463 1028 0179 Optiplex GX280
9464 2660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
9465 2662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
9466 2664 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
9467 2666 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
9468 2668 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
9469 266a 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
9470 1028 0179 Optiplex GX280
9471 266c 82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
9472 266d 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
9473 266e 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
9474 1028 0179 Optiplex GX280
9475 266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
9476 2770 Memory Controller Hub
9477 2771 PCI Express Graphics Port
9478 2772 Integrated Graphics Controller
9479 2774 Workstation Memory Controller Hub
9480 2775 PCI Express Graphics Port
9481 2776 Integrated Graphics Controller
9482 2778 Server Memory Controller Hub
9483 2779 PCI Express Root Port
9484 2782 82915G Express Chipset Family Graphics Controller
9485 2792 Mobile 915GM/GMS/910GML Express Graphics Controller
9486 27b8 I/O Controller Hub LPC
9487 27b9 Mobile I/O Controller Hub LPC
9488 27c0 I/O Controller Hub SATA cc=IDE
9489 27c1 I/O Controller Hub SATA cc=AHCI
9490 27c3 I/O Controller Hub SATA cc=RAID
9491 27c4 Mobile I/O Controller Hub SATA cc=IDE
9492 27c5 Mobile I/O Controller Hub SATA cc=AHCI
9493 27c8 I/O Controller Hub UHCI USB #1
9494 27c9 I/O Controller Hub UHCI USB #2
9495 27ca I/O Controller Hub UHCI USB #3
9496 27cb I/O Controller Hub UHCI USB #4
9497 27cc I/O Controller Hub EHCI USB
9498 27d0 I/O Controller Hub PCI Express Port 1
9499 27d2 I/O Controller Hub PCI Express Port 2
9500 27d4 I/O Controller Hub PCI Express Port 3
9501 27d6 I/O Controller Hub PCI Express Port 4
9502 27d8 I/O Controller Hub High Definition Audio
9503 27da I/O Controller Hub SMBus
9504 27dc I/O Controller Hub LAN
9505 27dd I/O Controller Hub AC'97 Modem
9506 27de I/O Controller Hub AC'97 Audio
9507 27df I/O Controller Hub PATA
9508 27e0 I/O Controller Hub PCI Express Port 5
9509 27e2 I/O Controller Hub PCI Express Port 6
9510 3092 Integrated RAID
9511 3200 GD31244 PCI-X SATA HBA
9512 3340 82855PM Processor to I/O Controller
9513 1025 005a TravelMate 290
9514 103c 088c nc8000 laptop
9515 103c 0890 nc6000 laptop
9516 3341 82855PM Processor to AGP Controller
9517 3575 82830 830 Chipset Host Bridge
9518 1014 021d ThinkPad A/T/X Series
9519 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9520 3576 82830 830 Chipset AGP Bridge
9521 3577 82830 CGC [Chipset Graphics Controller]
9522 1014 0513 ThinkPad A/T/X Series
9523 3578 82830 830 Chipset Host Bridge
9524 3580 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9525 1028 0163 Latitude D505
9526 4c53 10b0 CL9 mainboard
9527 3581 82852/82855 GM/GME/PM/GMV Processor to AGP Controller
9528 3582 82852/855GM Integrated Graphics Device
9529 1028 0163 Latitude D505
9530 4c53 10b0 CL9 mainboard
9531 3584 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9532 1028 0163 Latitude D505
9533 4c53 10b0 CL9 mainboard
9534 3585 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9535 1028 0163 Latitude D505
9536 4c53 10b0 CL9 mainboard
9537 3590 E7520 Memory Controller Hub
9538 3591 E7525/E7520 Error Reporting Registers
9539 3592 E7320 Memory Controller Hub
9540 3593 E7320 Error Reporting Registers
9541 3594 E7520 DMA Controller
9542 3595 E7525/E7520/E7320 PCI Express Port A
9543 3596 E7525/E7520/E7320 PCI Express Port A1
9544 3597 E7525/E7520 PCI Express Port B
9545 3598 E7520 PCI Express Port B1
9546 3599 E7520 PCI Express Port C
9547 359a E7520 PCI Express Port C1
9548 359b E7525/E7520/E7320 Extended Configuration Registers
9549 359e E7525 Memory Controller Hub
9550 4220 PRO/Wireless 2200BG
9551 4223 PRO/Wireless 2915ABG MiniPCI Adapter
9552 5200 EtherExpress PRO/100 Intelligent Server
9553 5201 EtherExpress PRO/100 Intelligent Server
9554 8086 0001 EtherExpress PRO/100 Server Ethernet Adapter
9555 530d 80310 IOP [IO Processor]
9556 7000 82371SB PIIX3 ISA [Natoma/Triton II]
9557 7010 82371SB PIIX3 IDE [Natoma/Triton II]
9558 7020 82371SB PIIX3 USB [Natoma/Triton II]
9559 7030 430VX - 82437VX TVX [Triton VX]
9560 7050 Intel Intercast Video Capture Card
9561 7100 430TX - 82439TX MTXC
9562 7110 82371AB/EB/MB PIIX4 ISA
9563 15ad 1976 virtualHW v3
9564 7111 82371AB/EB/MB PIIX4 IDE
9565 15ad 1976 virtualHW v3
9566 7112 82371AB/EB/MB PIIX4 USB
9567 15ad 1976 virtualHW v3
9568 7113 82371AB/EB/MB PIIX4 ACPI
9569 15ad 1976 virtualHW v3
9570 7120 82810 GMCH [Graphics Memory Controller Hub]
9571 4c53 1040 CL7 mainboard
9572 4c53 1060 PC7 mainboard
9573 7121 82810 CGC [Chipset Graphics Controller]
9574 4c53 1040 CL7 mainboard
9575 4c53 1060 PC7 mainboard
9576 8086 4341 Cayman (CA810) Mainboard
9577 7122 82810 DC-100 GMCH [Graphics Memory Controller Hub]
9578 7123 82810 DC-100 CGC [Chipset Graphics Controller]
9579 7124 82810E DC-133 GMCH [Graphics Memory Controller Hub]
9580 7125 82810E DC-133 CGC [Chipset Graphics Controller]
9581 7126 82810 DC-133 System and Graphics Controller
9582 7128 82810-M DC-100 System and Graphics Controller
9583 712a 82810-M DC-133 System and Graphics Controller
9584 7180 440LX/EX - 82443LX/EX Host bridge
9585 7181 440LX/EX - 82443LX/EX AGP bridge
9586 7190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge
9587 0e11 0500 Armada 1750 Laptop System Chipset
9588 0e11 b110 Armada M700/E500
9589 1179 0001 Toshiba Tecra 8100 Laptop System Chipset
9590 15ad 1976 virtualHW v3
9591 4c53 1050 CT7 mainboard
9592 4c53 1051 CE7 mainboard
9593 7191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
9594 7192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
9595 0e11 0460 Armada 1700 Laptop System Chipset
9596 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
9597 7194 82440MX Host Bridge
9598 1033 0000 Versa Note Vxi
9599 4c53 10a0 CA3/CR3 mainboard
9600 7195 82440MX AC'97 Audio Controller
9601 1033 80cc Versa Note VXi
9602 10cf 1099 QSound_SigmaTel Stac97 PCI Audio
9603 11d4 0040 SoundMAX Integrated Digital Audio
9604 11d4 0048 SoundMAX Integrated Digital Audio
9605 7196 82440MX AC'97 Modem Controller
9606 7198 82440MX ISA Bridge
9607 7199 82440MX EIDE Controller
9608 719a 82440MX USB Universal Host Controller
9609 719b 82440MX Power Management Controller
9610 71a0 440GX - 82443GX Host bridge
9611 4c53 1050 CT7 mainboard
9612 4c53 1051 CE7 mainboard
9613 71a1 440GX - 82443GX AGP bridge
9614 71a2 440GX - 82443GX Host bridge (AGP disabled)
9615 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
9616 7600 82372FB PIIX5 ISA
9617 7601 82372FB PIIX5 IDE
9618 7602 82372FB PIIX5 USB
9619 7603 82372FB PIIX5 SMBus
9620 7800 82740 (i740) AGP Graphics Accelerator
9621 003d 0008 Starfighter AGP
9622 003d 000b Starfighter AGP
9623 1092 0100 Stealth II G460
9624 10b4 201a Lightspeed 740
9625 10b4 202f Lightspeed 740
9626 8086 0000 Terminator 2x/i
9627 8086 0100 Intel740 Graphics Accelerator
9628 84c4 450KX/GX [Orion] - 82454KX/GX PCI bridge
9629 84c5 450KX/GX [Orion] - 82453KX/GX Memory controller
9630 84ca 450NX - 82451NX Memory & I/O Controller
9631 84cb 450NX - 82454NX/84460GX PCI Expander Bridge
9632 84e0 460GX - 84460GX System Address Controller (SAC)
9633 84e1 460GX - 84460GX System Data Controller (SDC)
9634 84e2 460GX - 84460GX AGP Bridge (GXB function 2)
9635 84e3 460GX - 84460GX Memory Address Controller (MAC)
9636 84e4 460GX - 84460GX Memory Data Controller (MDC)
9637 84e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
9638 84ea 460GX - 84460GX AGP Bridge (GXB function 1)
9639 8500 IXP4XX - Intel Network Processor family. IXP420, IXP421, IXP422, IXP425 and IXC1100
9640 1993 0dee mGuard-PCI AV#1
9641 1993 0def mGuard-PCI AV#0
9642 9000 IXP2000 Family Network Processor
9643 9001 IXP2400 Network Processor
9644 9004 IXP2800 Network Processor
9645 9621 Integrated RAID
9646 9622 Integrated RAID
9647 9641 Integrated RAID
9648 96a1 Integrated RAID
9649# retail verson
9650 a01f PRO/10GbE LR Server Adapter
9651# OEM version
9652 a11f PRO/10GbE LR Server Adapter
9653 b152 21152 PCI-to-PCI Bridge
9654# observed, and documented in Intel revision note; new mask of 1011:0026
9655 b154 21154 PCI-to-PCI Bridge
9656 b555 21555 Non transparent PCI-to-PCI Bridge
9657 12d9 000a PCI VoIP Gateway
9658 4c53 1050 CT7 mainboard
9659 4c53 1051 CE7 mainboard
9660 e4bf 1000 CC8-1-BLUES
9661 ffff 450NX/GX [Orion] - 82453KX/GX Memory controller [BUG]
96628401 TRENDware International Inc.
96638800 Trigem Computer Inc.
9664 2008 Video assistent component
96658866 T-Square Design Inc.
96668888 Silicon Magic
9667# 8c4a is not Winbond but there is a board misprogrammed
96688c4a Winbond
9669 1980 W89C940 misprogrammed [ne2k]
96708e0e Computone Corporation
96718e2e KTI
9672 3000 ET32P2
96739004 Adaptec
9674 0078 AHA-2940U_CN
9675 1078 AIC-7810
9676 1160 AIC-1160 [Family Fibre Channel Adapter]
9677 2178 AIC-7821
9678 3860 AHA-2930CU
9679 3b78 AHA-4844W/4844UW
9680 5075 AIC-755x
9681 5078 AHA-7850
9682 9004 7850 AHA-2904/Integrated AIC-7850
9683 5175 AIC-755x
9684 5178 AIC-7851
9685 5275 AIC-755x
9686 5278 AIC-7852
9687 5375 AIC-755x
9688 5378 AIC-7850
9689 5475 AIC-755x
9690 5478 AIC-7850
9691 5575 AVA-2930
9692 5578 AIC-7855
9693 5647 ANA-7711 TCP Offload Engine
9694 9004 7710 ANA-7711F TCP Offload Engine - Optical
9695 9004 7711 ANA-7711LP TCP Offload Engine - Copper
9696 5675 AIC-755x
9697 5678 AIC-7856
9698 5775 AIC-755x
9699 5778 AIC-7850
9700 5800 AIC-5800
9701 5900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
9702 5905 ANA-5910A/5930A/5940A ATM Adapter
9703 6038 AIC-3860
9704 6075 AIC-1480 / APA-1480
9705 9004 7560 AIC-1480 / APA-1480 Cardbus
9706 6078 AIC-7860
9707 6178 AIC-7861
9708 9004 7861 AHA-2940AU Single
9709 6278 AIC-7860
9710 6378 AIC-7860
9711 6478 AIC-786x
9712 6578 AIC-786x
9713 6678 AIC-786x
9714 6778 AIC-786x
9715 6915 ANA620xx/ANA69011A
9716 9004 0008 ANA69011A/TX 10/100
9717 9004 0009 ANA69011A/TX 10/100
9718 9004 0010 ANA62022 2-port 10/100
9719 9004 0018 ANA62044 4-port 10/100
9720 9004 0019 ANA62044 4-port 10/100
9721 9004 0020 ANA62022 2-port 10/100
9722 9004 0028 ANA69011A/TX 10/100
9723 9004 8008 ANA69011A/TX 64 bit 10/100
9724 9004 8009 ANA69011A/TX 64 bit 10/100
9725 9004 8010 ANA62022 2-port 64 bit 10/100
9726 9004 8018 ANA62044 4-port 64 bit 10/100
9727 9004 8019 ANA62044 4-port 64 bit 10/100
9728 9004 8020 ANA62022 2-port 64 bit 10/100
9729 9004 8028 ANA69011A/TX 64 bit 10/100
9730 7078 AHA-294x / AIC-7870
9731 7178 AHA-2940/2940W / AIC-7871
9732 7278 AHA-3940/3940W / AIC-7872
9733 7378 AHA-3985 / AIC-7873
9734 7478 AHA-2944/2944W / AIC-7874
9735 7578 AHA-3944/3944W / AIC-7875
9736 7678 AHA-4944W/UW / AIC-7876
9737 7710 ANA-7711F Network Accelerator Card (NAC) - Optical
9738 7711 ANA-7711C Network Accelerator Card (NAC) - Copper
9739 7778 AIC-787x
9740 7810 AIC-7810
9741 7815 AIC-7815 RAID+Memory Controller IC
9742 9004 7815 ARO-1130U2 RAID Controller
9743 9004 7840 AIC-7815 RAID+Memory Controller IC
9744 7850 AIC-7850
9745 7855 AHA-2930
9746 7860 AIC-7860
9747 7870 AIC-7870
9748 7871 AHA-2940
9749 7872 AHA-3940
9750 7873 AHA-3980
9751 7874 AHA-2944
9752 7880 AIC-7880P
9753 7890 AIC-7890
9754 7891 AIC-789x
9755 7892 AIC-789x
9756 7893 AIC-789x
9757 7894 AIC-789x
9758 7895 AHA-2940U/UW / AHA-39xx / AIC-7895
9759 9004 7890 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9760 9004 7891 AHA-2940U/2940UW Dual
9761 9004 7892 AHA-3940AU/AUW/AUWD/UWD
9762 9004 7894 AHA-3944AUWD
9763 9004 7895 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9764 9004 7896 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9765 9004 7897 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9766 7896 AIC-789x
9767 7897 AIC-789x
9768 8078 AIC-7880U
9769 9004 7880 AIC-7880P Ultra/Ultra Wide SCSI Chipset
9770 8178 AHA-2940U/UW/D / AIC-7881U
9771 9004 7881 AHA-2940UW SCSI Host Adapter
9772 8278 AHA-3940U/UW/UWD / AIC-7882U
9773 8378 AHA-3940U/UW / AIC-7883U
9774 8478 AHA-2944UW / AIC-7884U
9775 8578 AHA-3944U/UWD / AIC-7885
9776 8678 AHA-4944UW / AIC-7886
9777 8778 AHA-2940UW Pro / AIC-788x
9778 9004 7887 2940UW Pro Ultra-Wide SCSI Controller
9779 8878 AHA-2930UW / AIC-7888
9780 9004 7888 AHA-2930UW SCSI Controller
9781 8b78 ABA-1030
9782 ec78 AHA-4944W/UW
97839005 Adaptec
9784 0010 AHA-2940U2/U2W
9785 9005 2180 AHA-2940U2 SCSI Controller
9786 9005 8100 AHA-2940U2B SCSI Controller
9787 9005 a100 AHA-2940U2B SCSI Controller
9788 9005 a180 AHA-2940U2W SCSI Controller
9789 9005 e100 AHA-2950U2B SCSI Controller
9790 0011 AHA-2930U2
9791 0013 78902
9792 9005 0003 AAA-131U2 Array1000 1 Channel RAID Controller
9793 9005 000f AIC7890_ARO
9794 001f AHA-2940U2/U2W / 7890/7891
9795 9005 000f 2940U2W SCSI Controller
9796 9005 a180 2940U2W SCSI Controller
9797 0020 AIC-7890
9798 002f AIC-7890
9799 0030 AIC-7890
9800 003f AIC-7890
9801 0050 AHA-3940U2x/395U2x
9802 9005 f500 AHA-3950U2B
9803 9005 ffff AHA-3950U2B
9804 0051 AHA-3950U2D
9805 9005 b500 AHA-3950U2D
9806 0053 AIC-7896 SCSI Controller
9807 9005 ffff AIC-7896 SCSI Controller mainboard implementation
9808 005f AIC-7896U2/7897U2
9809 0080 AIC-7892A U160/m
9810 0e11 e2a0 Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
9811 9005 6220 AHA-29160C
9812 9005 62a0 29160N Ultra160 SCSI Controller
9813 9005 e220 29160LP Low Profile Ultra160 SCSI Controller
9814 9005 e2a0 29160 Ultra160 SCSI Controller
9815 0081 AIC-7892B U160/m
9816 9005 62a1 19160 Ultra160 SCSI Controller
9817 0083 AIC-7892D U160/m
9818 008f AIC-7892P U160/m
9819 1179 0001 Magnia Z310
9820 15d9 9005 Onboard SCSI Host Adapter
9821 00c0 AHA-3960D / AIC-7899A U160/m
9822 0e11 f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
9823 9005 f620 AHA-3960D U160/m
9824 00c1 AIC-7899B U160/m
9825 00c3 AIC-7899D U160/m
9826 00c5 RAID subsystem HBA
9827 1028 00c5 PowerEdge 2400,2500,2550,4400
9828 00cf AIC-7899P U160/m
9829 1028 00ce PowerEdge 1400
9830 1028 00d1 PowerEdge 2550
9831 1028 00d9 PowerEdge 2500
9832 10f1 2462 Thunder K7 S2462
9833 15d9 9005 Onboard SCSI Host Adapter
9834 8086 3411 SDS2 Mainboard
9835 0250 ServeRAID Controller
9836 1014 0279 ServeRAID-xx
9837 1014 028c ServeRAID-xx
9838# from kernel sources
9839 0279 ServeRAID 6M
9840 0283 AAC-RAID
9841 9005 0283 Catapult
9842 0284 AAC-RAID
9843 9005 0284 Tomcat
9844 0285 AAC-RAID
9845 0e11 0295 SATA 6Ch (Bearcat)
9846 1014 02f2 ServeRAID 8i
9847 1028 0287 PowerEdge Expandable RAID Controller 320/DC
9848 1028 0291 CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
9849 103c 3227 AAR-2610SA
9850 17aa 0286 Legend S220 (Legend Crusader)
9851 17aa 0287 Legend S230 (Legend Vulcan)
9852 9005 0285 2200S (Vulcan)
9853 9005 0286 2120S (Crusader)
9854 9005 0287 2200S (Vulcan-2m)
9855 9005 0288 3230S (Harrier)
9856 9005 0289 3240S (Tornado)
9857 9005 028a ASR-2020S PCI-X ZCR (Skyhawk)
9858 9005 028b ASR-2020S SO-DIMM PCI-X ZCR (Terminator)
9859 9005 0290 AAR-2410SA PCI SATA 4ch (Jaguar II)
9860 9005 0292 AAR-2810SA PCI SATA 8ch (Corsair-8)
9861 9005 0293 AAR-21610SA PCI SATA 16ch (Corsair-16)
9862 9005 0294 ESD SO-DIMM PCI-X SATA ZCR (Prowler)
9863 0286 AAC-RAID (Rocket)
9864 9005 028c ASR-2230S + ASR-2230SLP PCI-X (Lancer)
9865 0503 Scamp chipset SCSI controller
9866 1014 02BF Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
9867 8000 ASC-29320A U320
9868 800f AIC-7901 U320
9869 8010 ASC-39320 U320
9870 8011 ASC-32320D U320
9871 0e11 00ac ASC-39320D U320
9872 9005 0041 ASC-39320D U320
9873 8012 ASC-29320 U320
9874 8013 ASC-29320B U320
9875 8014 ASC-29320LP U320
9876 8015 ASC-39320B U320
9877 8016 ASC-39320A U320
9878 8017 ASC-29320ALP U320
9879 801c ASC-39320D U320
9880 801d AIC-7902B U320
9881 801e AIC-7901A U320
9882 801f AIC-7902 U320
9883 8080 ASC-29320A U320 w/HostRAID
9884 808f AIC-7901 U320 w/HostRAID
9885 8090 ASC-39320 U320 w/HostRAID
9886 8091 ASC-39320D U320 w/HostRAID
9887 8092 ASC-29320 U320 w/HostRAID
9888 8093 ASC-29320B U320 w/HostRAID
9889 8094 ASC-29320LP U320 w/HostRAID
9890 8095 ASC-39320(B) U320 w/HostRAID
9891 8096 ASC-39320A U320 w/HostRAID
9892 8097 ASC-29320ALP U320 w/HostRAID
9893 809c ASC-39320D(B) U320 w/HostRAID
9894 809d AIC-7902(B) U320 w/HostRAID
9895 809e AIC-7901A U320 w/HostRAID
9896 809f AIC-7902 U320 w/HostRAID
9897907f Atronics
9898 2015 IDE-2015PL
9899919a Gigapixel Corp
99009412 Holtek
9901 6565 6565
99029699 Omni Media Technology Inc
9903 6565 6565
99049710 NetMos Technology
9905 7780 USB IRDA-port
9906 9705 PCI 9705 Parallel Port
9907 9715 PCI 9715 Dual Parallel Port
9908 9735 PCI 9735 Multi-I/O Controller
9909 1000 0002 0P2S (2 serial)
9910 1000 0012 1P2S (1 parallel + 2 serial)
9911 9745 PCI 9745 Multi-I/O Controller
9912 1000 0002 0P2S (2 serial)
9913 1000 0012 1P2S (1 parallel + 2 serial)
9914 9755 PCI 9755 Parallel Port and ISA Bridge
9915 9805 PCI 9805 Parallel Port
9916 9815 PCI 9815 Dual Parallel Port
9917 1000 0020 2P0S (2 port parallel adaptor)
9918 9835 PCI 9835 Multi-I/O Controller
9919 1000 0002 0P2S (16C550 UART)
9920 1000 0012 1P2S
9921 9845 PCI 9845 Multi-I/O Controller
9922 1000 0004 0P4S (4 port 16550A serial card)
9923 1000 0006 0P6S (6 port 16550A serial card)
9924 1000 0014 1P4S (4 port 16550A serial card + parallel)
9925 9855 PCI 9855 Multi-I/O Controller
9926 1000 0014 1P4S
99279902 Stargen Inc.
9928 0001 SG2010 PCI over Starfabric Bridge
9929 0002 SG2010 PCI to Starfabric Gateway
9930 0003 SG1010 Starfabric Switch and PCI Bridge
9931a0a0 AOPEN Inc.
9932a0f1 UNISYS Corporation
9933a200 NEC Corporation
9934a259 Hewlett Packard
9935a25b Hewlett Packard GmbH PL24-MKT
9936a304 Sony
9937a727 3Com Corporation
9938 0013 3CRPAG175 Wireless PC Card
9939aa42 Scitex Digital Video
9940ac1e Digital Receiver Technology Inc
9941ac3d Actuality Systems
9942aecb Adrienne Electronics Corporation
9943b1b3 Shiva Europe Limited
9944# Pinnacle should be 11bd, but they got it wrong several times --mj
9945bd11 Pinnacle Systems, Inc. (Wrong ID)
9946c001 TSI Telsys
9947c0a9 Micron/Crucial Technology
9948c0de Motorola
9949c0fe Motion Engineering, Inc.
9950ca50 Varian Australia Pty Ltd
9951cafe Chrysalis-ITS
9952cccc Catapult Communications
9953cddd Tyzx, Inc.
9954 0101 DeepSea 1 High Speed Stereo Vision Frame Grabber
9955 0200 DeepSea 2 High Speed Stereo Vision Frame Grabber
9956d4d4 Dy4 Systems Inc
9957 0601 PCI Mezzanine Card
9958d531 I+ME ACTIA GmbH
9959d84d Exsys
9960dead Indigita Corporation
9961deaf Middle Digital Inc.
9962 9050 PC Weasel Virtual VGA
9963 9051 PC Weasel Serial Port
9964 9052 PC Weasel Watchdog Timer
9965e000 Winbond
9966 e000 W89C940
9967# see also : http://www.schoenfeld.de/inside/Inside_CWMK3.txt maybe a misuse of TJN id or it use the TJN 3XX chip for other applic
9968e159 Tiger Jet Network Inc.
9969 0001 Tiger3XX Modem/ISDN interface
9970 0059 0001 128k ISDN-S/T Adapter
9971 0059 0003 128k ISDN-U Adapter
9972 0002 Tiger100APC ISDN chipset
9973e4bf EKF Elektronik GmbH
9974# Innovative and scalable network IC vendor
9975e55e Essence Technology, Inc.
9976ea01 Eagle Technology
9977# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
9978ea60 RME
9979 9896 Digi32
9980 9897 Digi32 Pro
9981 9898 Digi32/8
9982eabb Aashima Technology B.V.
9983eace Endace Measurement Systems, Ltd
9984 3100 DAG 3.10 OC-3/OC-12
9985 3200 DAG 3.2x OC-3/OC-12
9986 320e DAG 3.2E Fast Ethernet
9987 340e DAG 3.4E Fast Ethernet
9988 341e DAG 3.41E Fast Ethernet
9989 3500 DAG 3.5 OC-3/OC-12
9990 351c DAG 3.5ECM Fast Ethernet
9991 4100 DAG 4.10 OC-48
9992 4110 DAG 4.11 OC-48
9993 4220 DAG 4.2 OC-48
9994 422e DAG 4.2E Dual Gigabit Ethernet
9995ec80 Belkin Corporation
9996 ec00 F5D6000
9997ecc0 Echo Digital Audio Corporation
9998edd8 ARK Logic Inc
9999 a091 1000PV [Stingray]
10000 a099 2000PV [Stingray]
10001 a0a1 2000MT
10002 a0a9 2000MI
10003f1d0 AJA Video
10004# All boards I have seen have this ID not efac, though all docs say efac...
10005 cafe KONA SD SMPTE 259M I/O
10006 efac KONA SD SMPTE 259M I/O
10007 facd KONA HD SMPTE 292M I/O
10008fa57 Interagon AS
10009 0001 PMC [Pattern Matching Chip]
10010febd Ultraview Corp.
10011feda Broadcom Inc (nee Epigram)
10012 a0fa BCM4210 iLine10 HomePNA 2.0
10013 a10e BCM4230 iLine10 HomePNA 2.0
10014# IT & Telecom company, develops PCI Trunk cards <www.fedetec.es>
10015fede Fedetec Inc.
10016 0003 TABIC PCI v3
10017fffe VMWare Inc
10018 0405 Virtual SVGA 4.0
10019 0710 Virtual SVGA
10020ffff Illegal Vendor ID
10021
10022
10023# List of known device classes, subclasses and programming interfaces
10024
10025# Syntax:
10026# C class class_name
10027# subclass subclass_name <-- single tab
10028# prog-if prog-if_name <-- two tabs
10029
10030C 00 Unclassified device
10031 00 Non-VGA unclassified device
10032 01 VGA compatible unclassified device
10033C 01 Mass storage controller
10034 00 SCSI storage controller
10035 01 IDE interface
10036 02 Floppy disk controller
10037 03 IPI bus controller
10038 04 RAID bus controller
10039 80 Unknown mass storage controller
10040C 02 Network controller
10041 00 Ethernet controller
10042 01 Token ring network controller
10043 02 FDDI network controller
10044 03 ATM network controller
10045 04 ISDN controller
10046 80 Network controller
10047C 03 Display controller
10048 00 VGA compatible controller
10049 00 VGA
10050 01 8514
10051 01 XGA compatible controller
10052 02 3D controller
10053 80 Display controller
10054C 04 Multimedia controller
10055 00 Multimedia video controller
10056 01 Multimedia audio controller
10057 02 Computer telephony device
10058 80 Multimedia controller
10059C 05 Memory controller
10060 00 RAM memory
10061 01 FLASH memory
10062 80 Memory controller
10063C 06 Bridge
10064 00 Host bridge
10065 01 ISA bridge
10066 02 EISA bridge
10067 03 MicroChannel bridge
10068 04 PCI bridge
10069 00 Normal decode
10070 01 Subtractive decode
10071 05 PCMCIA bridge
10072 06 NuBus bridge
10073 07 CardBus bridge
10074 08 RACEway bridge
10075 00 Transparent mode
10076 01 Endpoint mode
10077 09 Semi-transparent PCI-to-PCI bridge
10078 40 Primary bus towards host CPU
10079 80 Secondary bus towards host CPU
10080 0a InfiniBand to PCI host bridge
10081 80 Bridge
10082C 07 Communication controller
10083 00 Serial controller
10084 00 8250
10085 01 16450
10086 02 16550
10087 03 16650
10088 04 16750
10089 05 16850
10090 06 16950
10091 01 Parallel controller
10092 00 SPP
10093 01 BiDir
10094 02 ECP
10095 03 IEEE1284
10096 fe IEEE1284 Target
10097 02 Multiport serial controller
10098 03 Modem
10099 00 Generic
10100 01 Hayes/16450
10101 02 Hayes/16550
10102 03 Hayes/16650
10103 04 Hayes/16750
10104 80 Communication controller
10105C 08 Generic system peripheral
10106 00 PIC
10107 00 8259
10108 01 ISA PIC
10109 02 EISA PIC
10110 10 IO-APIC
10111 20 IO(X)-APIC
10112 01 DMA controller
10113 00 8237
10114 01 ISA DMA
10115 02 EISA DMA
10116 02 Timer
10117 00 8254
10118 01 ISA Timer
10119 02 EISA Timers
10120 03 RTC
10121 00 Generic
10122 01 ISA RTC
10123 04 PCI Hot-plug controller
10124 80 System peripheral
10125C 09 Input device controller
10126 00 Keyboard controller
10127 01 Digitizer Pen
10128 02 Mouse controller
10129 03 Scanner controller
10130 04 Gameport controller
10131 00 Generic
10132 10 Extended
10133 80 Input device controller
10134C 0a Docking station
10135 00 Generic Docking Station
10136 80 Docking Station
10137C 0b Processor
10138 00 386
10139 01 486
10140 02 Pentium
10141 10 Alpha
10142 20 Power PC
10143 30 MIPS
10144 40 Co-processor
10145C 0c Serial bus controller
10146 00 FireWire (IEEE 1394)
10147 00 Generic
10148 10 OHCI
10149 01 ACCESS Bus
10150 02 SSA
10151 03 USB Controller
10152 00 UHCI
10153 10 OHCI
10154 20 EHCI
10155 80 Unspecified
10156 fe USB Device
10157 04 Fibre Channel
10158 05 SMBus
10159 06 InfiniBand
10160C 0d Wireless controller
10161 00 IRDA controller
10162 01 Consumer IR controller
10163 10 RF controller
10164 80 Wireless controller
10165C 0e Intelligent controller
10166 00 I2O
10167C 0f Satellite communications controller
10168 00 Satellite TV controller
10169 01 Satellite audio communication controller
10170 03 Satellite voice communication controller
10171 04 Satellite data communication controller
10172C 10 Encryption controller
10173 00 Network and computing encryption device
10174 10 Entertainment encryption device
10175 80 Encryption controller
10176C 11 Signal processing controller
10177 00 DPIO module
10178 01 Performance counters
10179 10 Communication synchronizer
10180 80 Signal processing controller
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 30bac7ed7c16..3c565ce7f77b 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -90,15 +90,19 @@ static void pcie_portdrv_save_config(struct pci_dev *dev)
90 pci_save_msi_state(dev); 90 pci_save_msi_state(dev);
91} 91}
92 92
93static void pcie_portdrv_restore_config(struct pci_dev *dev) 93static int pcie_portdrv_restore_config(struct pci_dev *dev)
94{ 94{
95 struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); 95 struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
96 int retval;
96 97
97 pci_restore_state(dev); 98 pci_restore_state(dev);
98 if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) 99 if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
99 pci_restore_msi_state(dev); 100 pci_restore_msi_state(dev);
100 pci_enable_device(dev); 101 retval = pci_enable_device(dev);
102 if (retval)
103 return retval;
101 pci_set_master(dev); 104 pci_set_master(dev);
105 return 0;
102} 106}
103 107
104/* 108/*
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 93e8a878ea95..35caec13023a 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -584,7 +584,7 @@ static int pci_setup_device(struct pci_dev * dev)
584 dev->vendor, dev->device, class, dev->hdr_type); 584 dev->vendor, dev->device, class, dev->hdr_type);
585 585
586 /* "Unknown power state" */ 586 /* "Unknown power state" */
587 dev->current_state = 4; 587 dev->current_state = PCI_UNKNOWN;
588 588
589 /* Early fixups, before probing the BARs */ 589 /* Early fixups, before probing the BARs */
590 pci_fixup_device(pci_fixup_early, dev); 590 pci_fixup_device(pci_fixup_early, dev);
@@ -753,29 +753,19 @@ pci_scan_device(struct pci_bus *bus, int devfn)
753 kfree(dev); 753 kfree(dev);
754 return NULL; 754 return NULL;
755 } 755 }
756 device_initialize(&dev->dev);
757 dev->dev.release = pci_release_dev;
758 pci_dev_get(dev);
759
760 pci_name_device(dev);
761
762 dev->dev.dma_mask = &dev->dma_mask;
763 dev->dev.coherent_dma_mask = 0xffffffffull;
764 756
765 return dev; 757 return dev;
766} 758}
767 759
768struct pci_dev * __devinit 760void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
769pci_scan_single_device(struct pci_bus *bus, int devfn)
770{ 761{
771 struct pci_dev *dev; 762 device_initialize(&dev->dev);
763 dev->dev.release = pci_release_dev;
764 pci_dev_get(dev);
772 765
773 dev = pci_scan_device(bus, devfn); 766 dev->dev.dma_mask = &dev->dma_mask;
774 pci_scan_msi_device(dev); 767 dev->dev.coherent_dma_mask = 0xffffffffull;
775 768
776 if (!dev)
777 return NULL;
778
779 /* Fix up broken headers */ 769 /* Fix up broken headers */
780 pci_fixup_device(pci_fixup_header, dev); 770 pci_fixup_device(pci_fixup_header, dev);
781 771
@@ -787,6 +777,19 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
787 spin_lock(&pci_bus_lock); 777 spin_lock(&pci_bus_lock);
788 list_add_tail(&dev->bus_list, &bus->devices); 778 list_add_tail(&dev->bus_list, &bus->devices);
789 spin_unlock(&pci_bus_lock); 779 spin_unlock(&pci_bus_lock);
780}
781
782struct pci_dev * __devinit
783pci_scan_single_device(struct pci_bus *bus, int devfn)
784{
785 struct pci_dev *dev;
786
787 dev = pci_scan_device(bus, devfn);
788 if (!dev)
789 return NULL;
790
791 pci_device_add(dev, bus);
792 pci_scan_msi_device(dev);
790 793
791 return dev; 794 return dev;
792} 795}
@@ -883,7 +886,8 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
883 return max; 886 return max;
884} 887}
885 888
886struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) 889struct pci_bus * __devinit pci_create_bus(struct device *parent,
890 int bus, struct pci_ops *ops, void *sysdata)
887{ 891{
888 int error; 892 int error;
889 struct pci_bus *b; 893 struct pci_bus *b;
@@ -940,8 +944,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
940 b->resource[0] = &ioport_resource; 944 b->resource[0] = &ioport_resource;
941 b->resource[1] = &iomem_resource; 945 b->resource[1] = &iomem_resource;
942 946
943 b->subordinate = pci_scan_child_bus(b);
944
945 return b; 947 return b;
946 948
947sys_create_link_err: 949sys_create_link_err:
@@ -959,6 +961,18 @@ err_out:
959 kfree(b); 961 kfree(b);
960 return NULL; 962 return NULL;
961} 963}
964EXPORT_SYMBOL_GPL(pci_create_bus);
965
966struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
967 int bus, struct pci_ops *ops, void *sysdata)
968{
969 struct pci_bus *b;
970
971 b = pci_create_bus(parent, bus, ops, sysdata);
972 if (b)
973 b->subordinate = pci_scan_child_bus(b);
974 return b;
975}
962EXPORT_SYMBOL(pci_scan_bus_parented); 976EXPORT_SYMBOL(pci_scan_bus_parented);
963 977
964#ifdef CONFIG_HOTPLUG 978#ifdef CONFIG_HOTPLUG
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 7988fc8df3fd..9613f666c110 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -474,7 +474,7 @@ static int show_dev_config(struct seq_file *m, void *v)
474 struct pci_dev *first_dev; 474 struct pci_dev *first_dev;
475 struct pci_driver *drv; 475 struct pci_driver *drv;
476 u32 class_rev; 476 u32 class_rev;
477 unsigned char latency, min_gnt, max_lat, *class; 477 unsigned char latency, min_gnt, max_lat;
478 int reg; 478 int reg;
479 479
480 first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 480 first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
@@ -490,16 +490,8 @@ static int show_dev_config(struct seq_file *m, void *v)
490 pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat); 490 pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
491 seq_printf(m, " Bus %2d, device %3d, function %2d:\n", 491 seq_printf(m, " Bus %2d, device %3d, function %2d:\n",
492 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 492 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
493 class = pci_class_name(class_rev >> 16); 493 seq_printf(m, " Class %04x", class_rev >> 16);
494 if (class)
495 seq_printf(m, " %s", class);
496 else
497 seq_printf(m, " Class %04x", class_rev >> 16);
498#ifdef CONFIG_PCI_NAMES
499 seq_printf(m, ": %s", dev->pretty_name);
500#else
501 seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device); 494 seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device);
502#endif
503 seq_printf(m, " (rev %d).\n", class_rev & 0xff); 495 seq_printf(m, " (rev %d).\n", class_rev & 0xff);
504 496
505 if (dev->irq) 497 if (dev->irq)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 140354a2aa72..11ca44387cb0 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -245,12 +245,19 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, unsi
245{ 245{
246 region &= ~(size-1); 246 region &= ~(size-1);
247 if (region) { 247 if (region) {
248 struct pci_bus_region bus_region;
248 struct resource *res = dev->resource + nr; 249 struct resource *res = dev->resource + nr;
249 250
250 res->name = pci_name(dev); 251 res->name = pci_name(dev);
251 res->start = region; 252 res->start = region;
252 res->end = region + size - 1; 253 res->end = region + size - 1;
253 res->flags = IORESOURCE_IO; 254 res->flags = IORESOURCE_IO;
255
256 /* Convert from PCI bus to resource space. */
257 bus_region.start = res->start;
258 bus_region.end = res->end;
259 pcibios_bus_to_resource(dev, res, &bus_region);
260
254 pci_claim_resource(dev, nr); 261 pci_claim_resource(dev, nr);
255 } 262 }
256} 263}
@@ -869,6 +876,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
869 case 0xC00C: /* Samsung P35 notebook */ 876 case 0xC00C: /* Samsung P35 notebook */
870 asus_hides_smbus = 1; 877 asus_hides_smbus = 1;
871 } 878 }
879 } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ)) {
880 if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
881 switch(dev->subsystem_device) {
882 case 0x0058: /* Compaq Evo N620c */
883 asus_hides_smbus = 1;
884 }
872 } 885 }
873} 886}
874DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge ); 887DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge );
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6b0e6464eb39..657be948baf7 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -77,8 +77,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
77 } 77 }
78} 78}
79 79
80static void __devinit 80void pci_setup_cardbus(struct pci_bus *bus)
81pci_setup_cardbus(struct pci_bus *bus)
82{ 81{
83 struct pci_dev *bridge = bus->self; 82 struct pci_dev *bridge = bus->self;
84 struct pci_bus_region region; 83 struct pci_bus_region region;
@@ -130,6 +129,7 @@ pci_setup_cardbus(struct pci_bus *bus)
130 region.end); 129 region.end);
131 } 130 }
132} 131}
132EXPORT_SYMBOL(pci_setup_cardbus);
133 133
134/* Initialize bridges with base/limit values we have collected. 134/* Initialize bridges with base/limit values we have collected.
135 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998) 135 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 5598b4714f77..50d6685dcbcc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -26,7 +26,7 @@
26#include "pci.h" 26#include "pci.h"
27 27
28 28
29static void 29void
30pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) 30pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
31{ 31{
32 struct pci_bus_region region; 32 struct pci_bus_region region;
@@ -97,10 +97,7 @@ pci_claim_resource(struct pci_dev *dev, int resource)
97 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; 97 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
98 int err; 98 int err;
99 99
100 if (res->flags & IORESOURCE_IO) 100 root = pcibios_select_root(dev, res);
101 root = &ioport_resource;
102 if (res->flags & IORESOURCE_MEM)
103 root = &iomem_resource;
104 101
105 err = -EINVAL; 102 err = -EINVAL;
106 if (root != NULL) 103 if (root != NULL)
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 6485f75d2fb3..ddc741e6ecbf 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -221,6 +221,13 @@ config PCMCIA_VRC4173
221 tristate "NEC VRC4173 CARDU support" 221 tristate "NEC VRC4173 CARDU support"
222 depends on CPU_VR41XX && PCI && PCMCIA 222 depends on CPU_VR41XX && PCI && PCMCIA
223 223
224config OMAP_CF
225 tristate "OMAP CompactFlash Controller"
226 depends on PCMCIA && ARCH_OMAP16XX
227 help
228 Say Y here to support the CompactFlash controller on OMAP.
229 Note that this doesn't support "True IDE" mode.
230
224config PCCARD_NONSTATIC 231config PCCARD_NONSTATIC
225 tristate 232 tristate
226 233
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index ef694c74dfb7..a41fbb38fdcb 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
34obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o 34obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
35obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o 35obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
36obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o 36obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
37obj-$(CONFIG_OMAP_CF) += omap_cf.o
37 38
38sa11xx_core-y += soc_common.o sa11xx_base.o 39sa11xx_core-y += soc_common.o sa11xx_base.o
39pxa2xx_core-y += soc_common.o pxa2xx_base.o 40pxa2xx_core-y += soc_common.o pxa2xx_base.o
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e39178fc59d0..fabd3529cebc 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -654,9 +654,10 @@ static int pccardd(void *__skt)
654 skt->thread = NULL; 654 skt->thread = NULL;
655 complete_and_exit(&skt->thread_done, 0); 655 complete_and_exit(&skt->thread_done, 0);
656 } 656 }
657 complete(&skt->thread_done);
658 657
659 add_wait_queue(&skt->thread_wait, &wait); 658 add_wait_queue(&skt->thread_wait, &wait);
659 complete(&skt->thread_done);
660
660 for (;;) { 661 for (;;) {
661 unsigned long flags; 662 unsigned long flags;
662 unsigned int events; 663 unsigned int events;
@@ -682,11 +683,11 @@ static int pccardd(void *__skt)
682 continue; 683 continue;
683 } 684 }
684 685
685 schedule();
686 try_to_freeze();
687
688 if (!skt->thread) 686 if (!skt->thread)
689 break; 687 break;
688
689 schedule();
690 try_to_freeze();
690 } 691 }
691 remove_wait_queue(&skt->thread_wait, &wait); 692 remove_wait_queue(&skt->thread_wait, &wait);
692 693
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 6bbfbd0e02a5..55867bc7f199 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -17,9 +17,6 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19 19
20#define CLIENT_MAGIC 0x51E6
21typedef struct client_t client_t;
22
23/* Flags in client state */ 20/* Flags in client state */
24#define CLIENT_CONFIG_LOCKED 0x0001 21#define CLIENT_CONFIG_LOCKED 0x0001
25#define CLIENT_IRQ_REQ 0x0002 22#define CLIENT_IRQ_REQ 0x0002
@@ -45,7 +42,6 @@ typedef struct region_t {
45typedef struct config_t { 42typedef struct config_t {
46 u_int state; 43 u_int state;
47 u_int Attributes; 44 u_int Attributes;
48 u_int Vcc, Vpp1, Vpp2;
49 u_int IntType; 45 u_int IntType;
50 u_int ConfigBase; 46 u_int ConfigBase;
51 u_char Status, Pin, Copy, Option, ExtStatus; 47 u_char Status, Pin, Copy, Option, ExtStatus;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 43da2e92d50f..080608c7381a 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -354,6 +354,7 @@ static void pcmcia_release_dev(struct device *dev)
354 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 354 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
355 ds_dbg(1, "releasing dev %p\n", p_dev); 355 ds_dbg(1, "releasing dev %p\n", p_dev);
356 pcmcia_put_socket(p_dev->socket); 356 pcmcia_put_socket(p_dev->socket);
357 kfree(p_dev->devname);
357 kfree(p_dev); 358 kfree(p_dev);
358} 359}
359 360
@@ -424,9 +425,13 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
424{ 425{
425 cistpl_manfid_t manf_id; 426 cistpl_manfid_t manf_id;
426 cistpl_funcid_t func_id; 427 cistpl_funcid_t func_id;
427 cistpl_vers_1_t vers1; 428 cistpl_vers_1_t *vers1;
428 unsigned int i; 429 unsigned int i;
429 430
431 vers1 = kmalloc(sizeof(*vers1), GFP_KERNEL);
432 if (!vers1)
433 return -ENOMEM;
434
430 if (!pccard_read_tuple(p_dev->socket, p_dev->func, 435 if (!pccard_read_tuple(p_dev->socket, p_dev->func,
431 CISTPL_MANFID, &manf_id)) { 436 CISTPL_MANFID, &manf_id)) {
432 p_dev->manf_id = manf_id.manf; 437 p_dev->manf_id = manf_id.manf;
@@ -443,23 +448,30 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
443 /* rule of thumb: cards with no FUNCID, but with 448 /* rule of thumb: cards with no FUNCID, but with
444 * common memory device geometry information, are 449 * common memory device geometry information, are
445 * probably memory cards (from pcmcia-cs) */ 450 * probably memory cards (from pcmcia-cs) */
446 cistpl_device_geo_t devgeo; 451 cistpl_device_geo_t *devgeo;
452
453 devgeo = kmalloc(sizeof(*devgeo), GFP_KERNEL);
454 if (!devgeo) {
455 kfree(vers1);
456 return -ENOMEM;
457 }
447 if (!pccard_read_tuple(p_dev->socket, p_dev->func, 458 if (!pccard_read_tuple(p_dev->socket, p_dev->func,
448 CISTPL_DEVICE_GEO, &devgeo)) { 459 CISTPL_DEVICE_GEO, devgeo)) {
449 ds_dbg(0, "mem device geometry probably means " 460 ds_dbg(0, "mem device geometry probably means "
450 "FUNCID_MEMORY\n"); 461 "FUNCID_MEMORY\n");
451 p_dev->func_id = CISTPL_FUNCID_MEMORY; 462 p_dev->func_id = CISTPL_FUNCID_MEMORY;
452 p_dev->has_func_id = 1; 463 p_dev->has_func_id = 1;
453 } 464 }
465 kfree(devgeo);
454 } 466 }
455 467
456 if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1, 468 if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1,
457 &vers1)) { 469 vers1)) {
458 for (i=0; i < vers1.ns; i++) { 470 for (i=0; i < vers1->ns; i++) {
459 char *tmp; 471 char *tmp;
460 unsigned int length; 472 unsigned int length;
461 473
462 tmp = vers1.str + vers1.ofs[i]; 474 tmp = vers1->str + vers1->ofs[i];
463 475
464 length = strlen(tmp) + 1; 476 length = strlen(tmp) + 1;
465 if ((length < 3) || (length > 255)) 477 if ((length < 3) || (length > 255))
@@ -475,6 +487,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
475 } 487 }
476 } 488 }
477 489
490 kfree(vers1);
478 return 0; 491 return 0;
479} 492}
480 493
@@ -492,6 +505,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
492{ 505{
493 struct pcmcia_device *p_dev; 506 struct pcmcia_device *p_dev;
494 unsigned long flags; 507 unsigned long flags;
508 int bus_id_len;
495 509
496 s = pcmcia_get_socket(s); 510 s = pcmcia_get_socket(s);
497 if (!s) 511 if (!s)
@@ -515,7 +529,12 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
515 p_dev->dev.bus = &pcmcia_bus_type; 529 p_dev->dev.bus = &pcmcia_bus_type;
516 p_dev->dev.parent = s->dev.dev; 530 p_dev->dev.parent = s->dev.dev;
517 p_dev->dev.release = pcmcia_release_dev; 531 p_dev->dev.release = pcmcia_release_dev;
518 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); 532 bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
533
534 p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
535 if (!p_dev->devname)
536 goto err_free;
537 sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
519 538
520 /* compat */ 539 /* compat */
521 p_dev->state = CLIENT_UNBOUND; 540 p_dev->state = CLIENT_UNBOUND;
@@ -540,6 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
540 return p_dev; 559 return p_dev;
541 560
542 err_free: 561 err_free:
562 kfree(p_dev->devname);
543 kfree(p_dev); 563 kfree(p_dev);
544 s->device_count--; 564 s->device_count--;
545 err_put: 565 err_put:
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
new file mode 100644
index 000000000000..08d1c9288264
--- /dev/null
+++ b/drivers/pcmcia/omap_cf.c
@@ -0,0 +1,373 @@
1/*
2 * omap_cf.c -- OMAP 16xx CompactFlash controller driver
3 *
4 * Copyright (c) 2005 David Brownell
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/module.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/device.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/interrupt.h>
20
21#include <pcmcia/ss.h>
22
23#include <asm/hardware.h>
24#include <asm/io.h>
25#include <asm/mach-types.h>
26#include <asm/sizes.h>
27
28#include <asm/arch/mux.h>
29#include <asm/arch/tc.h>
30
31
32/* NOTE: don't expect this to support many I/O cards. The 16xx chips have
33 * hard-wired timings to support Compact Flash memory cards; they won't work
34 * with various other devices (like WLAN adapters) without some external
35 * logic to help out.
36 *
37 * NOTE: CF controller docs disagree with address space docs as to where
38 * CF_BASE really lives; this is a doc erratum.
39 */
40#define CF_BASE 0xfffe2800
41
42/* status; read after IRQ */
43#define CF_STATUS_REG __REG16(CF_BASE + 0x00)
44# define CF_STATUS_BAD_READ (1 << 2)
45# define CF_STATUS_BAD_WRITE (1 << 1)
46# define CF_STATUS_CARD_DETECT (1 << 0)
47
48/* which chipselect (CS0..CS3) is used for CF (active low) */
49#define CF_CFG_REG __REG16(CF_BASE + 0x02)
50
51/* card reset */
52#define CF_CONTROL_REG __REG16(CF_BASE + 0x04)
53# define CF_CONTROL_RESET (1 << 0)
54
55#define omap_cf_present() (!(CF_STATUS_REG & CF_STATUS_CARD_DETECT))
56
57/*--------------------------------------------------------------------------*/
58
59static const char driver_name[] = "omap_cf";
60
61struct omap_cf_socket {
62 struct pcmcia_socket socket;
63
64 struct timer_list timer;
65 unsigned present:1;
66 unsigned active:1;
67
68 struct platform_device *pdev;
69 unsigned long phys_cf;
70 u_int irq;
71};
72
73#define POLL_INTERVAL (2 * HZ)
74
75#define SZ_2K (2 * SZ_1K)
76
77/*--------------------------------------------------------------------------*/
78
79static int omap_cf_ss_init(struct pcmcia_socket *s)
80{
81 return 0;
82}
83
84/* the timer is primarily to kick this socket's pccardd */
85static void omap_cf_timer(unsigned long _cf)
86{
87 struct omap_cf_socket *cf = (void *) _cf;
88 unsigned present = omap_cf_present();
89
90 if (present != cf->present) {
91 cf->present = present;
92 pr_debug("%s: card %s\n", driver_name,
93 present ? "present" : "gone");
94 pcmcia_parse_events(&cf->socket, SS_DETECT);
95 }
96
97 if (cf->active)
98 mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
99}
100
101/* This irq handler prevents "irqNNN: nobody cared" messages as drivers
102 * claim the card's IRQ. It may also detect some card insertions, but
103 * not removals; it can't always eliminate timer irqs.
104 */
105static irqreturn_t omap_cf_irq(int irq, void *_cf, struct pt_regs *r)
106{
107 omap_cf_timer((unsigned long)_cf);
108 return IRQ_HANDLED;
109}
110
111static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp)
112{
113 if (!sp)
114 return -EINVAL;
115
116 /* FIXME power management should probably be board-specific:
117 * - 3VCARD vs XVCARD (OSK only handles 3VCARD)
118 * - POWERON (switched on/off by set_socket)
119 */
120 if (omap_cf_present()) {
121 struct omap_cf_socket *cf;
122
123 *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
124 cf = container_of(s, struct omap_cf_socket, socket);
125 s->irq.AssignedIRQ = cf->irq;
126 } else
127 *sp = 0;
128 return 0;
129}
130
131static int
132omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
133{
134 u16 control;
135
136 /* FIXME some non-OSK boards will support power switching */
137 switch (s->Vcc) {
138 case 0:
139 case 33:
140 break;
141 default:
142 return -EINVAL;
143 }
144
145 control = CF_CONTROL_REG;
146 if (s->flags & SS_RESET)
147 CF_CONTROL_REG = CF_CONTROL_RESET;
148 else
149 CF_CONTROL_REG = 0;
150
151 pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
152 driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
153
154 return 0;
155}
156
157static int omap_cf_ss_suspend(struct pcmcia_socket *s)
158{
159 pr_debug("%s: %s\n", driver_name, __FUNCTION__);
160 return omap_cf_set_socket(s, &dead_socket);
161}
162
163/* regions are 2K each: mem, attrib, io (and reserved-for-ide) */
164
165static int
166omap_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
167{
168 struct omap_cf_socket *cf;
169
170 cf = container_of(s, struct omap_cf_socket, socket);
171 io->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
172 io->start = cf->phys_cf + SZ_4K;
173 io->stop = io->start + SZ_2K - 1;
174 return 0;
175}
176
177static int
178omap_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
179{
180 struct omap_cf_socket *cf;
181
182 if (map->card_start)
183 return -EINVAL;
184 cf = container_of(s, struct omap_cf_socket, socket);
185 map->static_start = cf->phys_cf;
186 map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
187 if (map->flags & MAP_ATTRIB)
188 map->static_start += SZ_2K;
189 return 0;
190}
191
192static struct pccard_operations omap_cf_ops = {
193 .init = omap_cf_ss_init,
194 .suspend = omap_cf_ss_suspend,
195 .get_status = omap_cf_get_status,
196 .set_socket = omap_cf_set_socket,
197 .set_io_map = omap_cf_set_io_map,
198 .set_mem_map = omap_cf_set_mem_map,
199};
200
201/*--------------------------------------------------------------------------*/
202
203/*
204 * NOTE: right now the only board-specific platform_data is
205 * "what chipselect is used". Boards could want more.
206 */
207
208static int __init omap_cf_probe(struct device *dev)
209{
210 unsigned seg;
211 struct omap_cf_socket *cf;
212 struct platform_device *pdev = to_platform_device(dev);
213 int irq;
214 int status;
215
216 seg = (int) dev->platform_data;
217 if (seg == 0 || seg > 3)
218 return -ENODEV;
219
220 /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */
221 irq = platform_get_irq(pdev, 0);
222 if (!irq)
223 return -EINVAL;
224
225 cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
226 if (!cf)
227 return -ENOMEM;
228 init_timer(&cf->timer);
229 cf->timer.function = omap_cf_timer;
230 cf->timer.data = (unsigned long) cf;
231
232 cf->pdev = pdev;
233 dev_set_drvdata(dev, cf);
234
235 /* this primarily just shuts up irq handling noise */
236 status = request_irq(irq, omap_cf_irq, SA_SHIRQ,
237 driver_name, cf);
238 if (status < 0)
239 goto fail0;
240 cf->irq = irq;
241 cf->socket.pci_irq = irq;
242
243 switch (seg) {
244 /* NOTE: CS0 could be configured too ... */
245 case 1:
246 cf->phys_cf = OMAP_CS1_PHYS;
247 break;
248 case 2:
249 cf->phys_cf = OMAP_CS2_PHYS;
250 break;
251 case 3:
252 cf->phys_cf = omap_cs3_phys();
253 break;
254 default:
255 goto fail1;
256 }
257
258 /* pcmcia layer only remaps "real" memory */
259 cf->socket.io_offset = (unsigned long)
260 ioremap(cf->phys_cf + SZ_4K, SZ_2K);
261 if (!cf->socket.io_offset)
262 goto fail1;
263
264 if (!request_mem_region(cf->phys_cf, SZ_8K, driver_name))
265 goto fail1;
266
267 /* NOTE: CF conflicts with MMC1 */
268 omap_cfg_reg(W11_1610_CF_CD1);
269 omap_cfg_reg(P11_1610_CF_CD2);
270 omap_cfg_reg(R11_1610_CF_IOIS16);
271 omap_cfg_reg(V10_1610_CF_IREQ);
272 omap_cfg_reg(W10_1610_CF_RESET);
273
274 CF_CFG_REG = ~(1 << seg);
275
276 pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq);
277
278 /* NOTE: better EMIFS setup might support more cards; but the
279 * TRM only shows how to affect regular flash signals, not their
280 * CF/PCMCIA variants...
281 */
282 pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name,
283 seg, EMIFS_CCS(seg), EMIFS_ACS(seg));
284 EMIFS_CCS(seg) = 0x0004a1b3; /* synch mode 4 etc */
285 EMIFS_ACS(seg) = 0x00000000; /* OE hold/setup */
286
287 /* CF uses armxor_ck, which is "always" available */
288
289 pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name,
290 CF_STATUS_REG, CF_CFG_REG, CF_CONTROL_REG,
291 omap_cf_present() ? "present" : "(not present)");
292
293 cf->socket.owner = THIS_MODULE;
294 cf->socket.dev.dev = dev;
295 cf->socket.ops = &omap_cf_ops;
296 cf->socket.resource_ops = &pccard_static_ops;
297 cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
298 | SS_CAP_MEM_ALIGN;
299 cf->socket.map_size = SZ_2K;
300
301 status = pcmcia_register_socket(&cf->socket);
302 if (status < 0)
303 goto fail2;
304
305 cf->active = 1;
306 mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
307 return 0;
308
309fail2:
310 iounmap((void __iomem *) cf->socket.io_offset);
311 release_mem_region(cf->phys_cf, SZ_8K);
312fail1:
313 free_irq(irq, cf);
314fail0:
315 kfree(cf);
316 return status;
317}
318
319static int __devexit omap_cf_remove(struct device *dev)
320{
321 struct omap_cf_socket *cf = dev_get_drvdata(dev);
322
323 cf->active = 0;
324 pcmcia_unregister_socket(&cf->socket);
325 del_timer_sync(&cf->timer);
326 iounmap((void __iomem *) cf->socket.io_offset);
327 release_mem_region(cf->phys_cf, SZ_8K);
328 free_irq(cf->irq, cf);
329 kfree(cf);
330 return 0;
331}
332
333static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level)
334{
335 if (level != SUSPEND_SAVE_STATE)
336 return 0;
337 return pcmcia_socket_dev_suspend(dev, mesg);
338}
339
340static int omap_cf_resume(struct device *dev, u32 level)
341{
342 if (level != RESUME_RESTORE_STATE)
343 return 0;
344 return pcmcia_socket_dev_resume(dev);
345}
346
347static struct device_driver omap_cf_driver = {
348 .name = (char *) driver_name,
349 .bus = &platform_bus_type,
350 .probe = omap_cf_probe,
351 .remove = __devexit_p(omap_cf_remove),
352 .suspend = omap_cf_suspend,
353 .resume = omap_cf_resume,
354};
355
356static int __init omap_cf_init(void)
357{
358 if (cpu_is_omap16xx())
359 driver_register(&omap_cf_driver);
360 return 0;
361}
362
363static void __exit omap_cf_exit(void)
364{
365 if (cpu_is_omap16xx())
366 driver_unregister(&omap_cf_driver);
367}
368
369module_init(omap_cf_init);
370module_exit(omap_cf_exit);
371
372MODULE_DESCRIPTION("OMAP CF Driver");
373MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 599b116d9747..89022ad5b520 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -447,7 +447,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
447 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { 447 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
448 if (mod->Vpp1 != mod->Vpp2) 448 if (mod->Vpp1 != mod->Vpp2)
449 return CS_BAD_VPP; 449 return CS_BAD_VPP;
450 c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1; 450 s->socket.Vpp = mod->Vpp1;
451 if (s->ops->set_socket(s, &s->socket)) 451 if (s->ops->set_socket(s, &s->socket))
452 return CS_BAD_VPP; 452 return CS_BAD_VPP;
453 } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || 453 } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
@@ -623,8 +623,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
623 if (s->ops->set_socket(s, &s->socket)) 623 if (s->ops->set_socket(s, &s->socket))
624 return CS_BAD_VPP; 624 return CS_BAD_VPP;
625 625
626 c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
627
628 /* Pick memory or I/O card, DMA mode, interrupt */ 626 /* Pick memory or I/O card, DMA mode, interrupt */
629 c->IntType = req->IntType; 627 c->IntType = req->IntType;
630 c->Attributes = req->Attributes; 628 c->Attributes = req->Attributes;
@@ -822,7 +820,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
822 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 820 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
823 (s->functions > 1) || 821 (s->functions > 1) ||
824 (irq == s->pci_irq)) ? SA_SHIRQ : 0, 822 (irq == s->pci_irq)) ? SA_SHIRQ : 0,
825 p_dev->dev.bus_id, 823 p_dev->devname,
826 (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); 824 (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
827 if (!ret) { 825 if (!ret) {
828 if (!(req->Attributes & IRQ_HANDLE_PRESENT)) 826 if (!(req->Attributes & IRQ_HANDLE_PRESENT))
@@ -832,7 +830,8 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
832 } 830 }
833 } 831 }
834#endif 832#endif
835 if (ret) { 833 /* only assign PCI irq if no IRQ already assigned */
834 if (ret && !s->irq.AssignedIRQ) {
836 if (!s->pci_irq) 835 if (!s->pci_irq)
837 return ret; 836 return ret;
838 irq = s->pci_irq; 837 irq = s->pci_irq;
@@ -843,7 +842,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
843 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 842 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
844 (s->functions > 1) || 843 (s->functions > 1) ||
845 (irq == s->pci_irq)) ? SA_SHIRQ : 0, 844 (irq == s->pci_irq)) ? SA_SHIRQ : 0,
846 p_dev->dev.bus_id, req->Instance)) 845 p_dev->devname, req->Instance))
847 return CS_IN_USE; 846 return CS_IN_USE;
848 } 847 }
849 848
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0347a29f297b..f0997c36c9b7 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -72,6 +72,7 @@ static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
72{ 72{
73 debug("%p %04x %08x\n", socket, reg, val); 73 debug("%p %04x %08x\n", socket, reg, val);
74 writel(val, socket->base + reg); 74 writel(val, socket->base + reg);
75 readl(socket->base + reg); /* avoid problems with PCI write posting */
75} 76}
76 77
77static inline u8 config_readb(struct yenta_socket *socket, unsigned offset) 78static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
@@ -136,6 +137,7 @@ static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val
136{ 137{
137 debug("%p %04x %02x\n", socket, reg, val); 138 debug("%p %04x %02x\n", socket, reg, val);
138 writeb(val, socket->base + 0x800 + reg); 139 writeb(val, socket->base + 0x800 + reg);
140 readb(socket->base + 0x800 + reg); /* PCI write posting... */
139} 141}
140 142
141static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val) 143static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
@@ -143,6 +145,10 @@ static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
143 debug("%p %04x %04x\n", socket, reg, val); 145 debug("%p %04x %04x\n", socket, reg, val);
144 writeb(val, socket->base + 0x800 + reg); 146 writeb(val, socket->base + 0x800 + reg);
145 writeb(val >> 8, socket->base + 0x800 + reg + 1); 147 writeb(val >> 8, socket->base + 0x800 + reg + 1);
148
149 /* PCI write posting... */
150 readb(socket->base + 0x800 + reg);
151 readb(socket->base + 0x800 + reg + 1);
146} 152}
147 153
148/* 154/*
@@ -667,7 +673,7 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
667 return 0; 673 return 0;
668} 674}
669 675
670static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) 676static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
671{ 677{
672 struct resource *root, *res; 678 struct resource *root, *res;
673 struct pci_bus_region region; 679 struct pci_bus_region region;
@@ -676,7 +682,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
676 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; 682 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
677 /* Already allocated? */ 683 /* Already allocated? */
678 if (res->parent) 684 if (res->parent)
679 return; 685 return 0;
680 686
681 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */ 687 /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
682 mask = ~0xfff; 688 mask = ~0xfff;
@@ -692,7 +698,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
692 pcibios_bus_to_resource(socket->dev, res, &region); 698 pcibios_bus_to_resource(socket->dev, res, &region);
693 root = pci_find_parent_resource(socket->dev, res); 699 root = pci_find_parent_resource(socket->dev, res);
694 if (root && (request_resource(root, res) == 0)) 700 if (root && (request_resource(root, res) == 0))
695 return; 701 return 0;
696 printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n", 702 printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
697 pci_name(socket->dev), nr); 703 pci_name(socket->dev), nr);
698 } 704 }
@@ -700,35 +706,27 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
700 if (type & IORESOURCE_IO) { 706 if (type & IORESOURCE_IO) {
701 if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) || 707 if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
702 (yenta_search_res(socket, res, BRIDGE_IO_ACC)) || 708 (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
703 (yenta_search_res(socket, res, BRIDGE_IO_MIN))) { 709 (yenta_search_res(socket, res, BRIDGE_IO_MIN)))
704 config_writel(socket, addr_start, res->start); 710 return 1;
705 config_writel(socket, addr_end, res->end);
706 return;
707 }
708 } else { 711 } else {
709 if (type & IORESOURCE_PREFETCH) { 712 if (type & IORESOURCE_PREFETCH) {
710 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 713 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
711 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 714 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
712 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { 715 (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
713 config_writel(socket, addr_start, res->start); 716 return 1;
714 config_writel(socket, addr_end, res->end);
715 return;
716 }
717 /* Approximating prefetchable by non-prefetchable */ 717 /* Approximating prefetchable by non-prefetchable */
718 res->flags = IORESOURCE_MEM; 718 res->flags = IORESOURCE_MEM;
719 } 719 }
720 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) || 720 if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
721 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) || 721 (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
722 (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { 722 (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
723 config_writel(socket, addr_start, res->start); 723 return 1;
724 config_writel(socket, addr_end, res->end);
725 return;
726 }
727 } 724 }
728 725
729 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n", 726 printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
730 pci_name(socket->dev), type); 727 pci_name(socket->dev), type);
731 res->start = res->end = res->flags = 0; 728 res->start = res->end = res->flags = 0;
729 return 0;
732} 730}
733 731
734/* 732/*
@@ -736,14 +734,17 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
736 */ 734 */
737static void yenta_allocate_resources(struct yenta_socket *socket) 735static void yenta_allocate_resources(struct yenta_socket *socket)
738{ 736{
739 yenta_allocate_res(socket, 0, IORESOURCE_IO, 737 int program = 0;
738 program += yenta_allocate_res(socket, 0, IORESOURCE_IO,
740 PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0); 739 PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
741 yenta_allocate_res(socket, 1, IORESOURCE_IO, 740 program += yenta_allocate_res(socket, 1, IORESOURCE_IO,
742 PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1); 741 PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
743 yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH, 742 program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
744 PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0); 743 PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
745 yenta_allocate_res(socket, 3, IORESOURCE_MEM, 744 program += yenta_allocate_res(socket, 3, IORESOURCE_MEM,
746 PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1); 745 PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
746 if (program)
747 pci_setup_cardbus(socket->dev->subordinate);
747} 748}
748 749
749 750
@@ -758,7 +759,7 @@ static void yenta_free_resources(struct yenta_socket *socket)
758 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i; 759 res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
759 if (res->start != 0 && res->end != 0) 760 if (res->start != 0 && res->end != 0)
760 release_resource(res); 761 release_resource(res);
761 res->start = res->end = 0; 762 res->start = res->end = res->flags = 0;
762 } 763 }
763} 764}
764 765
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index d96cc47de566..672f9f2b2163 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -871,8 +871,7 @@ static irqreturn_t aurora_interrupt(int irq, void * dev_id, struct pt_regs * reg
871#ifdef AURORA_INT_DEBUG 871#ifdef AURORA_INT_DEBUG
872static void aurora_timer (unsigned long ignored); 872static void aurora_timer (unsigned long ignored);
873 873
874static struct timer_list aurora_poll_timer = 874static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);
875 TIMER_INITIALIZER(aurora_timer, 0, 0);
876 875
877static void 876static void
878aurora_timer (unsigned long ignored) 877aurora_timer (unsigned long ignored)
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 320df6cd3def..c2c8fa828e24 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -865,22 +865,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
865 return 0; 865 return 0;
866} 866}
867 867
868/* move to PCI layer, integrate w/ MSI stuff */
869static void pci_intx(struct pci_dev *pdev, int enable)
870{
871 u16 pci_command, new;
872
873 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
874
875 if (enable)
876 new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
877 else
878 new = pci_command | PCI_COMMAND_INTX_DISABLE;
879
880 if (new != pci_command)
881 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
882}
883
884static void ahci_print_info(struct ata_probe_ent *probe_ent) 868static void ahci_print_info(struct ata_probe_ent *probe_ent)
885{ 869{
886 struct ahci_host_priv *hpriv = probe_ent->private_data; 870 struct ahci_host_priv *hpriv = probe_ent->private_data;
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index deec0cef88d9..87e0c36f1554 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -68,8 +68,8 @@ enum {
68 PIIX_COMB_PATA_P0 = (1 << 1), 68 PIIX_COMB_PATA_P0 = (1 << 1),
69 PIIX_COMB = (1 << 2), /* combined mode enabled? */ 69 PIIX_COMB = (1 << 2), /* combined mode enabled? */
70 70
71 PIIX_PORT_PRESENT = (1 << 0), 71 PIIX_PORT_ENABLED = (1 << 0),
72 PIIX_PORT_ENABLED = (1 << 4), 72 PIIX_PORT_PRESENT = (1 << 4),
73 73
74 PIIX_80C_PRI = (1 << 5) | (1 << 4), 74 PIIX_80C_PRI = (1 << 5) | (1 << 4),
75 PIIX_80C_SEC = (1 << 7) | (1 << 6), 75 PIIX_80C_SEC = (1 << 7) | (1 << 6),
@@ -377,7 +377,9 @@ static void piix_pata_phy_reset(struct ata_port *ap)
377 * None (inherited from caller). 377 * None (inherited from caller).
378 * 378 *
379 * RETURNS: 379 * RETURNS:
380 * Non-zero if device detected, zero otherwise. 380 * Non-zero if port is enabled, it may or may not have a device
381 * attached in that case (PRESENT bit would only be set if BIOS probe
382 * was done). Zero is returned if port is disabled.
381 */ 383 */
382static int piix_sata_probe (struct ata_port *ap) 384static int piix_sata_probe (struct ata_port *ap)
383{ 385{
@@ -401,7 +403,7 @@ static int piix_sata_probe (struct ata_port *ap)
401 */ 403 */
402 404
403 for (i = 0; i < 4; i++) { 405 for (i = 0; i < 4; i++) {
404 mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i); 406 mask = (PIIX_PORT_ENABLED << i);
405 407
406 if ((orig_mask & mask) == mask) 408 if ((orig_mask & mask) == mask)
407 if (combined || (i == ap->hard_port_no)) 409 if (combined || (i == ap->hard_port_no))
@@ -566,18 +568,6 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
566 } 568 }
567} 569}
568 570
569/* move to PCI layer, integrate w/ MSI stuff */
570static void pci_enable_intx(struct pci_dev *pdev)
571{
572 u16 pci_command;
573
574 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
575 if (pci_command & PCI_COMMAND_INTX_DISABLE) {
576 pci_command &= ~PCI_COMMAND_INTX_DISABLE;
577 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
578 }
579}
580
581#define AHCI_PCI_BAR 5 571#define AHCI_PCI_BAR 5
582#define AHCI_GLOBAL_CTL 0x04 572#define AHCI_GLOBAL_CTL 0x04
583#define AHCI_ENABLE (1 << 31) 573#define AHCI_ENABLE (1 << 31)
@@ -675,7 +665,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
675 * message-signalled interrupts currently). 665 * message-signalled interrupts currently).
676 */ 666 */
677 if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR) 667 if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
678 pci_enable_intx(pdev); 668 pci_intx(pdev, 1);
679 669
680 if (combined) { 670 if (combined) {
681 port_info[sata_chan] = &piix_port_info[ent->driver_data]; 671 port_info[sata_chan] = &piix_port_info[ent->driver_data];
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index bd0e1b6be1ea..13ecd0c47404 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -116,7 +116,7 @@ typedef struct {
116} scsi_changer; 116} scsi_changer;
117 117
118static LIST_HEAD(ch_devlist); 118static LIST_HEAD(ch_devlist);
119static spinlock_t ch_devlist_lock = SPIN_LOCK_UNLOCKED; 119static DEFINE_SPINLOCK(ch_devlist_lock);
120static int ch_devcount; 120static int ch_devcount;
121 121
122static struct scsi_driver ch_template = 122static struct scsi_driver ch_template =
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 623082d3a83f..c89da7d5b6df 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -95,8 +95,7 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
95 int i, retry, nplutos; 95 int i, retry, nplutos;
96 fc_channel *fc; 96 fc_channel *fc;
97 Scsi_Device dev; 97 Scsi_Device dev;
98 struct timer_list fc_timer = 98 DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
99 TIMER_INITIALIZER(pluto_detect_timeout, 0, 0);
100 99
101 tpnt->proc_name = "pluto"; 100 tpnt->proc_name = "pluto";
102 fcscount = 0; 101 fcscount = 0;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 72bbaa91dc77..9791496fa788 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1334,7 +1334,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
1334 1334
1335 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); 1335 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
1336 WRT_REG_DWORD(dmp_reg, 0xB0200000); 1336 WRT_REG_DWORD(dmp_reg, 0xB0200000);
1337 dmp_reg = (uint32_t *)((uint8_t *)reg + 0xFC); 1337 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
1338 fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg); 1338 fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
1339 1339
1340 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); 1340 dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index f97e3afa97d9..ea76fe44585e 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -699,22 +699,6 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
699 return rc; 699 return rc;
700} 700}
701 701
702/* move to PCI layer, integrate w/ MSI stuff */
703static void pci_intx(struct pci_dev *pdev, int enable)
704{
705 u16 pci_command, new;
706
707 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
708
709 if (enable)
710 new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
711 else
712 new = pci_command | PCI_COMMAND_INTX_DISABLE;
713
714 if (new != pci_command)
715 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
716}
717
718static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 702static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
719{ 703{
720 static int printed_version = 0; 704 static int printed_version = 0;
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 43af445b3ad2..a63f93186e41 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -52,7 +52,10 @@ enum {
52 /* PCI configuration registers */ 52 /* PCI configuration registers */
53 SIS_GENCTL = 0x54, /* IDE General Control register */ 53 SIS_GENCTL = 0x54, /* IDE General Control register */
54 SIS_SCR_BASE = 0xc0, /* sata0 phy SCR registers */ 54 SIS_SCR_BASE = 0xc0, /* sata0 phy SCR registers */
55 SIS_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */ 55 SIS180_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */
56 SIS182_SATA1_OFS = 0x20, /* offset from sata0->sata1 phy regs */
57 SIS_PMR = 0x90, /* port mapping register */
58 SIS_PMR_COMBINED = 0x30,
56 59
57 /* random bits */ 60 /* random bits */
58 SIS_FLAG_CFGSCR = (1 << 30), /* host flag: SCRs via PCI cfg */ 61 SIS_FLAG_CFGSCR = (1 << 30), /* host flag: SCRs via PCI cfg */
@@ -67,6 +70,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
67static struct pci_device_id sis_pci_tbl[] = { 70static struct pci_device_id sis_pci_tbl[] = {
68 { PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, 71 { PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
69 { PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, 72 { PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
73 { PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
70 { } /* terminate list */ 74 { } /* terminate list */
71}; 75};
72 76
@@ -139,67 +143,95 @@ MODULE_LICENSE("GPL");
139MODULE_DEVICE_TABLE(pci, sis_pci_tbl); 143MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
140MODULE_VERSION(DRV_VERSION); 144MODULE_VERSION(DRV_VERSION);
141 145
142static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg) 146static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
143{ 147{
144 unsigned int addr = SIS_SCR_BASE + (4 * sc_reg); 148 unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
145 149
146 if (port_no) 150 if (port_no) {
147 addr += SIS_SATA1_OFS; 151 if (device == 0x182)
152 addr += SIS182_SATA1_OFS;
153 else
154 addr += SIS180_SATA1_OFS;
155 }
156
148 return addr; 157 return addr;
149} 158}
150 159
151static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) 160static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
152{ 161{
153 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); 162 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
154 unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg); 163 unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
155 u32 val; 164 u32 val, val2;
165 u8 pmr;
156 166
157 if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ 167 if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
158 return 0xffffffff; 168 return 0xffffffff;
169
170 pci_read_config_byte(pdev, SIS_PMR, &pmr);
171
159 pci_read_config_dword(pdev, cfg_addr, &val); 172 pci_read_config_dword(pdev, cfg_addr, &val);
160 return val; 173
174 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
175 pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
176
177 return val|val2;
161} 178}
162 179
163static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) 180static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
164{ 181{
165 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); 182 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
166 unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr); 183 unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
184 u8 pmr;
167 185
168 if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */ 186 if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
169 return; 187 return;
188
189 pci_read_config_byte(pdev, SIS_PMR, &pmr);
190
170 pci_write_config_dword(pdev, cfg_addr, val); 191 pci_write_config_dword(pdev, cfg_addr, val);
192
193 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
194 pci_write_config_dword(pdev, cfg_addr+0x10, val);
171} 195}
172 196
173static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) 197static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
174{ 198{
199 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
200 u32 val, val2 = 0;
201 u8 pmr;
202
175 if (sc_reg > SCR_CONTROL) 203 if (sc_reg > SCR_CONTROL)
176 return 0xffffffffU; 204 return 0xffffffffU;
177 205
178 if (ap->flags & SIS_FLAG_CFGSCR) 206 if (ap->flags & SIS_FLAG_CFGSCR)
179 return sis_scr_cfg_read(ap, sc_reg); 207 return sis_scr_cfg_read(ap, sc_reg);
180 return inl(ap->ioaddr.scr_addr + (sc_reg * 4)); 208
209 pci_read_config_byte(pdev, SIS_PMR, &pmr);
210
211 val = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
212
213 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
214 val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
215
216 return val | val2;
181} 217}
182 218
183static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) 219static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
184{ 220{
221 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
222 u8 pmr;
223
185 if (sc_reg > SCR_CONTROL) 224 if (sc_reg > SCR_CONTROL)
186 return; 225 return;
187 226
227 pci_read_config_byte(pdev, SIS_PMR, &pmr);
228
188 if (ap->flags & SIS_FLAG_CFGSCR) 229 if (ap->flags & SIS_FLAG_CFGSCR)
189 sis_scr_cfg_write(ap, sc_reg, val); 230 sis_scr_cfg_write(ap, sc_reg, val);
190 else 231 else {
191 outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)); 232 outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
192} 233 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
193 234 outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
194/* move to PCI layer, integrate w/ MSI stuff */
195static void pci_enable_intx(struct pci_dev *pdev)
196{
197 u16 pci_command;
198
199 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
200 if (pci_command & PCI_COMMAND_INTX_DISABLE) {
201 pci_command &= ~PCI_COMMAND_INTX_DISABLE;
202 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
203 } 235 }
204} 236}
205 237
@@ -210,6 +242,8 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
210 u32 genctl; 242 u32 genctl;
211 struct ata_port_info *ppi; 243 struct ata_port_info *ppi;
212 int pci_dev_busy = 0; 244 int pci_dev_busy = 0;
245 u8 pmr;
246 u8 port2_start;
213 247
214 rc = pci_enable_device(pdev); 248 rc = pci_enable_device(pdev);
215 if (rc) 249 if (rc)
@@ -251,15 +285,31 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
251 probe_ent->host_flags |= SIS_FLAG_CFGSCR; 285 probe_ent->host_flags |= SIS_FLAG_CFGSCR;
252 } 286 }
253 287
288 pci_read_config_byte(pdev, SIS_PMR, &pmr);
289 if (ent->device != 0x182) {
290 if ((pmr & SIS_PMR_COMBINED) == 0) {
291 printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
292 port2_start=0x64;
293 }
294 else {
295 printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
296 port2_start=0;
297 }
298 }
299 else {
300 printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
301 port2_start = 0x20;
302 }
303
254 if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) { 304 if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) {
255 probe_ent->port[0].scr_addr = 305 probe_ent->port[0].scr_addr =
256 pci_resource_start(pdev, SIS_SCR_PCI_BAR); 306 pci_resource_start(pdev, SIS_SCR_PCI_BAR);
257 probe_ent->port[1].scr_addr = 307 probe_ent->port[1].scr_addr =
258 pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64; 308 pci_resource_start(pdev, SIS_SCR_PCI_BAR) + port2_start;
259 } 309 }
260 310
261 pci_set_master(pdev); 311 pci_set_master(pdev);
262 pci_enable_intx(pdev); 312 pci_intx(pdev, 1);
263 313
264 /* FIXME: check ata_device_add return value */ 314 /* FIXME: check ata_device_add return value */
265 ata_device_add(probe_ent); 315 ata_device_add(probe_ent);
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 42e13ed8eb5b..4c9fb8b71be1 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -176,18 +176,6 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
176 uli_scr_cfg_write(ap, sc_reg, val); 176 uli_scr_cfg_write(ap, sc_reg, val);
177} 177}
178 178
179/* move to PCI layer, integrate w/ MSI stuff */
180static void pci_enable_intx(struct pci_dev *pdev)
181{
182 u16 pci_command;
183
184 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
185 if (pci_command & PCI_COMMAND_INTX_DISABLE) {
186 pci_command &= ~PCI_COMMAND_INTX_DISABLE;
187 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
188 }
189}
190
191static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 179static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
192{ 180{
193 struct ata_probe_ent *probe_ent; 181 struct ata_probe_ent *probe_ent;
@@ -260,7 +248,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
260 } 248 }
261 249
262 pci_set_master(pdev); 250 pci_set_master(pdev);
263 pci_enable_intx(pdev); 251 pci_intx(pdev, 1);
264 252
265 /* FIXME: check ata_device_add return value */ 253 /* FIXME: check ata_device_add return value */
266 ata_device_add(probe_ent); 254 ata_device_add(probe_ent);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30a0a3d10145..5b65e208893b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2536,7 +2536,7 @@ static int __init serial8250_init(void)
2536 goto out; 2536 goto out;
2537 2537
2538 serial8250_isa_devs = platform_device_register_simple("serial8250", 2538 serial8250_isa_devs = platform_device_register_simple("serial8250",
2539 -1, NULL, 0); 2539 PLAT8250_DEV_LEGACY, NULL, 0);
2540 if (IS_ERR(serial8250_isa_devs)) { 2540 if (IS_ERR(serial8250_isa_devs)) {
2541 ret = PTR_ERR(serial8250_isa_devs); 2541 ret = PTR_ERR(serial8250_isa_devs);
2542 goto unreg; 2542 goto unreg;
diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c
index 1f2c276063ef..9c10262f2469 100644
--- a/drivers/serial/8250_accent.c
+++ b/drivers/serial/8250_accent.c
@@ -29,7 +29,7 @@ static struct plat_serial8250_port accent_data[] = {
29 29
30static struct platform_device accent_device = { 30static struct platform_device accent_device = {
31 .name = "serial8250", 31 .name = "serial8250",
32 .id = 2, 32 .id = PLAT8250_DEV_ACCENT,
33 .dev = { 33 .dev = {
34 .platform_data = accent_data, 34 .platform_data = accent_data,
35 }, 35 },
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c
index 465c9ea1e7a3..3bfe0f7b26fb 100644
--- a/drivers/serial/8250_boca.c
+++ b/drivers/serial/8250_boca.c
@@ -43,7 +43,7 @@ static struct plat_serial8250_port boca_data[] = {
43 43
44static struct platform_device boca_device = { 44static struct platform_device boca_device = {
45 .name = "serial8250", 45 .name = "serial8250",
46 .id = 3, 46 .id = PLAT8250_DEV_BOCA,
47 .dev = { 47 .dev = {
48 .platform_data = boca_data, 48 .platform_data = boca_data,
49 }, 49 },
diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c
index e9b4d908ef42..6375d68b7913 100644
--- a/drivers/serial/8250_fourport.c
+++ b/drivers/serial/8250_fourport.c
@@ -35,7 +35,7 @@ static struct plat_serial8250_port fourport_data[] = {
35 35
36static struct platform_device fourport_device = { 36static struct platform_device fourport_device = {
37 .name = "serial8250", 37 .name = "serial8250",
38 .id = 1, 38 .id = PLAT8250_DEV_FOURPORT,
39 .dev = { 39 .dev = {
40 .platform_data = fourport_data, 40 .platform_data = fourport_data,
41 }, 41 },
diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c
index 77f396f84b4c..daf569cd3c8f 100644
--- a/drivers/serial/8250_hub6.c
+++ b/drivers/serial/8250_hub6.c
@@ -40,7 +40,7 @@ static struct plat_serial8250_port hub6_data[] = {
40 40
41static struct platform_device hub6_device = { 41static struct platform_device hub6_device = {
42 .name = "serial8250", 42 .name = "serial8250",
43 .id = 4, 43 .id = PLAT8250_DEV_HUB6,
44 .dev = { 44 .dev = {
45 .platform_data = hub6_data, 45 .platform_data = hub6_data,
46 }, 46 },
diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c
index f0c40d68b8c1..ac205256d5f3 100644
--- a/drivers/serial/8250_mca.c
+++ b/drivers/serial/8250_mca.c
@@ -44,7 +44,7 @@ static struct plat_serial8250_port mca_data[] = {
44 44
45static struct platform_device mca_device = { 45static struct platform_device mca_device = {
46 .name = "serial8250", 46 .name = "serial8250",
47 .id = 5, 47 .id = PLAT8250_DEV_MCA,
48 .dev = { 48 .dev = {
49 .platform_data = mca_data, 49 .platform_data = mca_data,
50 }, 50 },
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 49afadbe461b..f10c86d60b64 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -31,6 +31,8 @@
31 * 1.01 Set fifosize to make tx_empry called properly. 31 * 1.01 Set fifosize to make tx_empry called properly.
32 * Use standard uart_get_divisor. 32 * Use standard uart_get_divisor.
33 * 1.02 Cleanup. (import 8250.c changes) 33 * 1.02 Cleanup. (import 8250.c changes)
34 * 1.03 Fix low-latency mode. (import 8250.c changes)
35 * 1.04 Remove usage of deprecated functions, cleanup.
34 */ 36 */
35#include <linux/config.h> 37#include <linux/config.h>
36 38
@@ -54,7 +56,7 @@
54#include <asm/io.h> 56#include <asm/io.h>
55#include <asm/irq.h> 57#include <asm/irq.h>
56 58
57static char *serial_version = "1.02"; 59static char *serial_version = "1.04";
58static char *serial_name = "TX39/49 Serial driver"; 60static char *serial_name = "TX39/49 Serial driver";
59 61
60#define PASS_LIMIT 256 62#define PASS_LIMIT 256
@@ -86,9 +88,9 @@ static char *serial_name = "TX39/49 Serial driver";
86 */ 88 */
87#ifdef ENABLE_SERIAL_TXX9_PCI 89#ifdef ENABLE_SERIAL_TXX9_PCI
88#define NR_PCI_BOARDS 4 90#define NR_PCI_BOARDS 4
89#define UART_NR (2 + NR_PCI_BOARDS) 91#define UART_NR (4 + NR_PCI_BOARDS)
90#else 92#else
91#define UART_NR 2 93#define UART_NR 4
92#endif 94#endif
93 95
94struct uart_txx9_port { 96struct uart_txx9_port {
@@ -304,8 +306,11 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
304 /* The following is not allowed by the tty layer and 306 /* The following is not allowed by the tty layer and
305 unsafe. It should be fixed ASAP */ 307 unsafe. It should be fixed ASAP */
306 if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { 308 if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
307 if(tty->low_latency) 309 if (tty->low_latency) {
310 spin_unlock(&up->port.lock);
308 tty_flip_buffer_push(tty); 311 tty_flip_buffer_push(tty);
312 spin_lock(&up->port.lock);
313 }
309 /* If this failed then we will throw away the 314 /* If this failed then we will throw away the
310 bytes but must do so to clear interrupts */ 315 bytes but must do so to clear interrupts */
311 } 316 }
@@ -356,7 +361,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
356 ignore_char: 361 ignore_char:
357 disr = sio_in(up, TXX9_SIDISR); 362 disr = sio_in(up, TXX9_SIDISR);
358 } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); 363 } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
364 spin_unlock(&up->port.lock);
359 tty_flip_buffer_push(tty); 365 tty_flip_buffer_push(tty);
366 spin_lock(&up->port.lock);
360 *status = disr; 367 *status = disr;
361} 368}
362 369
@@ -667,17 +674,8 @@ serial_txx9_pm(struct uart_port *port, unsigned int state,
667 unsigned int oldstate) 674 unsigned int oldstate)
668{ 675{
669 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 676 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
670 if (state) { 677 if (up->pm)
671 /* sleep */ 678 up->pm(port, state, oldstate);
672
673 if (up->pm)
674 up->pm(port, state, oldstate);
675 } else {
676 /* wake */
677
678 if (up->pm)
679 up->pm(port, state, oldstate);
680 }
681} 679}
682 680
683static int serial_txx9_request_resource(struct uart_txx9_port *up) 681static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -979,14 +977,6 @@ static int __init serial_txx9_console_init(void)
979} 977}
980console_initcall(serial_txx9_console_init); 978console_initcall(serial_txx9_console_init);
981 979
982static int __init serial_txx9_late_console_init(void)
983{
984 if (!(serial_txx9_console.flags & CON_ENABLED))
985 register_console(&serial_txx9_console);
986 return 0;
987}
988late_initcall(serial_txx9_late_console_init);
989
990#define SERIAL_TXX9_CONSOLE &serial_txx9_console 980#define SERIAL_TXX9_CONSOLE &serial_txx9_console
991#else 981#else
992#define SERIAL_TXX9_CONSOLE NULL 982#define SERIAL_TXX9_CONSOLE NULL
@@ -1039,6 +1029,73 @@ static void serial_txx9_resume_port(int line)
1039 uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port); 1029 uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
1040} 1030}
1041 1031
1032static DECLARE_MUTEX(serial_txx9_sem);
1033
1034/**
1035 * serial_txx9_register_port - register a serial port
1036 * @port: serial port template
1037 *
1038 * Configure the serial port specified by the request.
1039 *
1040 * The port is then probed and if necessary the IRQ is autodetected
1041 * If this fails an error is returned.
1042 *
1043 * On success the port is ready to use and the line number is returned.
1044 */
1045static int __devinit serial_txx9_register_port(struct uart_port *port)
1046{
1047 int i;
1048 struct uart_txx9_port *uart;
1049 int ret = -ENOSPC;
1050
1051 down(&serial_txx9_sem);
1052 for (i = 0; i < UART_NR; i++) {
1053 uart = &serial_txx9_ports[i];
1054 if (uart->port.type == PORT_UNKNOWN)
1055 break;
1056 }
1057 if (i < UART_NR) {
1058 uart_remove_one_port(&serial_txx9_reg, &uart->port);
1059 uart->port.iobase = port->iobase;
1060 uart->port.membase = port->membase;
1061 uart->port.irq = port->irq;
1062 uart->port.uartclk = port->uartclk;
1063 uart->port.iotype = port->iotype;
1064 uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
1065 uart->port.mapbase = port->mapbase;
1066 if (port->dev)
1067 uart->port.dev = port->dev;
1068 ret = uart_add_one_port(&serial_txx9_reg, &uart->port);
1069 if (ret == 0)
1070 ret = uart->port.line;
1071 }
1072 up(&serial_txx9_sem);
1073 return ret;
1074}
1075
1076/**
1077 * serial_txx9_unregister_port - remove a txx9 serial port at runtime
1078 * @line: serial line number
1079 *
1080 * Remove one serial port. This may not be called from interrupt
1081 * context. We hand the port back to the our control.
1082 */
1083static void __devexit serial_txx9_unregister_port(int line)
1084{
1085 struct uart_txx9_port *uart = &serial_txx9_ports[line];
1086
1087 down(&serial_txx9_sem);
1088 uart_remove_one_port(&serial_txx9_reg, &uart->port);
1089 uart->port.flags = 0;
1090 uart->port.type = PORT_UNKNOWN;
1091 uart->port.iobase = 0;
1092 uart->port.mapbase = 0;
1093 uart->port.membase = 0;
1094 uart->port.dev = NULL;
1095 uart_add_one_port(&serial_txx9_reg, &uart->port);
1096 up(&serial_txx9_sem);
1097}
1098
1042/* 1099/*
1043 * Probe one serial board. Unfortunately, there is no rhyme nor reason 1100 * Probe one serial board. Unfortunately, there is no rhyme nor reason
1044 * to the arrangement of serial ports on a PCI card. 1101 * to the arrangement of serial ports on a PCI card.
@@ -1056,13 +1113,13 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
1056 1113
1057 memset(&port, 0, sizeof(port)); 1114 memset(&port, 0, sizeof(port));
1058 port.ops = &serial_txx9_pops; 1115 port.ops = &serial_txx9_pops;
1059 port.flags |= UPF_BOOT_AUTOCONF; /* uart_ops.config_port will be called */
1060 port.flags |= UPF_TXX9_HAVE_CTS_LINE; 1116 port.flags |= UPF_TXX9_HAVE_CTS_LINE;
1061 port.uartclk = 66670000; 1117 port.uartclk = 66670000;
1062 port.irq = dev->irq; 1118 port.irq = dev->irq;
1063 port.iotype = UPIO_PORT; 1119 port.iotype = UPIO_PORT;
1064 port.iobase = pci_resource_start(dev, 1); 1120 port.iobase = pci_resource_start(dev, 1);
1065 line = uart_register_port(&serial_txx9_reg, &port); 1121 port.dev = &dev->dev;
1122 line = serial_txx9_register_port(&port);
1066 if (line < 0) { 1123 if (line < 0) {
1067 printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line); 1124 printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
1068 } 1125 }
@@ -1078,7 +1135,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
1078 pci_set_drvdata(dev, NULL); 1135 pci_set_drvdata(dev, NULL);
1079 1136
1080 if (line) { 1137 if (line) {
1081 uart_unregister_port(&serial_txx9_reg, line); 1138 serial_txx9_unregister_port(line);
1082 pci_disable_device(dev); 1139 pci_disable_device(dev);
1083 } 1140 }
1084} 1141}
@@ -1089,6 +1146,8 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
1089 1146
1090 if (line) 1147 if (line)
1091 serial_txx9_suspend_port(line); 1148 serial_txx9_suspend_port(line);
1149 pci_save_state(dev);
1150 pci_set_power_state(dev, pci_choose_state(dev, state));
1092 return 0; 1151 return 0;
1093} 1152}
1094 1153
@@ -1096,8 +1155,13 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev)
1096{ 1155{
1097 int line = (int)(long)pci_get_drvdata(dev); 1156 int line = (int)(long)pci_get_drvdata(dev);
1098 1157
1099 if (line) 1158 pci_set_power_state(dev, PCI_D0);
1159 pci_restore_state(dev);
1160
1161 if (line) {
1162 pci_enable_device(dev);
1100 serial_txx9_resume_port(line); 1163 serial_txx9_resume_port(line);
1164 }
1101 return 0; 1165 return 0;
1102} 1166}
1103 1167
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 8e184e2641cb..79861ee12a29 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -715,13 +715,11 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
715 usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), 715 usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
716 instance->rcv_buf, PAGE_SIZE, 716 instance->rcv_buf, PAGE_SIZE,
717 cxacru_blocking_completion, &instance->rcv_done, 1); 717 cxacru_blocking_completion, &instance->rcv_done, 1);
718 instance->rcv_urb->transfer_flags |= URB_ASYNC_UNLINK;
719 718
720 usb_fill_int_urb(instance->snd_urb, 719 usb_fill_int_urb(instance->snd_urb,
721 usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), 720 usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
722 instance->snd_buf, PAGE_SIZE, 721 instance->snd_buf, PAGE_SIZE,
723 cxacru_blocking_completion, &instance->snd_done, 4); 722 cxacru_blocking_completion, &instance->snd_done, 4);
724 instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
725 723
726 init_MUTEX(&instance->cm_serialize); 724 init_MUTEX(&instance->cm_serialize);
727 725
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 0561d0234f23..333e39bb105f 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -4,9 +4,22 @@
4comment "USB Device Class drivers" 4comment "USB Device Class drivers"
5 depends on USB 5 depends on USB
6 6
7config OBSOLETE_OSS_USB_DRIVER
8 bool "Obsolete OSS USB drivers"
9 depends on USB && SOUND
10 help
11 This option enables support for the obsolete USB Audio and Midi
12 drivers that are scheduled for removal in the near future since
13 there are ALSA drivers for the same hardware.
14
15 Please contact Adrian Bunk <bunk@stusta.de> if you had to
16 say Y here because of missing support in the ALSA drivers.
17
18 If unsure, say N.
19
7config USB_AUDIO 20config USB_AUDIO
8 tristate "USB Audio support" 21 tristate "USB Audio support"
9 depends on USB && SOUND 22 depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
10 help 23 help
11 Say Y here if you want to connect USB audio equipment such as 24 Say Y here if you want to connect USB audio equipment such as
12 speakers to your computer's USB port. You only need this if you use 25 speakers to your computer's USB port. You only need this if you use
@@ -40,10 +53,12 @@ config USB_BLUETOOTH_TTY
40 53
41config USB_MIDI 54config USB_MIDI
42 tristate "USB MIDI support" 55 tristate "USB MIDI support"
43 depends on USB && SOUND 56 depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
44 ---help--- 57 ---help---
45 Say Y here if you want to connect a USB MIDI device to your 58 Say Y here if you want to connect a USB MIDI device to your
46 computer's USB port. This driver is for devices that comply with 59 computer's USB port. You only need this if you use the OSS
60 sound system; USB MIDI devices are supported by ALSA's USB
61 audio driver. This driver is for devices that comply with
47 'Universal Serial Bus Device Class Definition for MIDI Device'. 62 'Universal Serial Bus Device Class Definition for MIDI Device'.
48 63
49 The following devices are known to work: 64 The following devices are known to work:
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 7ce43fb8118a..e195709c9c7f 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -310,8 +310,9 @@ static int usblp_check_status(struct usblp *usblp, int err)
310 310
311 error = usblp_read_status (usblp, usblp->statusbuf); 311 error = usblp_read_status (usblp, usblp->statusbuf);
312 if (error < 0) { 312 if (error < 0) {
313 err("usblp%d: error %d reading printer status", 313 if (printk_ratelimit())
314 usblp->minor, error); 314 err("usblp%d: error %d reading printer status",
315 usblp->minor, error);
315 return 0; 316 return 0;
316 } 317 }
317 318
@@ -604,7 +605,9 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
604 605
605 case LPGETSTATUS: 606 case LPGETSTATUS:
606 if (usblp_read_status(usblp, usblp->statusbuf)) { 607 if (usblp_read_status(usblp, usblp->statusbuf)) {
607 err("usblp%d: failed reading printer status", usblp->minor); 608 if (printk_ratelimit())
609 err("usblp%d: failed reading printer status",
610 usblp->minor);
608 retval = -EIO; 611 retval = -EIO;
609 goto done; 612 goto done;
610 } 613 }
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 9e8c377b8161..d5503cf0bf74 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -3,14 +3,14 @@
3# 3#
4 4
5usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ 5usbcore-objs := usb.o hub.o hcd.o urb.o message.o \
6 config.o file.o buffer.o sysfs.o 6 config.o file.o buffer.o sysfs.o devio.o
7 7
8ifeq ($(CONFIG_PCI),y) 8ifeq ($(CONFIG_PCI),y)
9 usbcore-objs += hcd-pci.o 9 usbcore-objs += hcd-pci.o
10endif 10endif
11 11
12ifeq ($(CONFIG_USB_DEVICEFS),y) 12ifeq ($(CONFIG_USB_DEVICEFS),y)
13 usbcore-objs += devio.o inode.o devices.o 13 usbcore-objs += inode.o devices.o
14endif 14endif
15 15
16obj-$(CONFIG_USB) += usbcore.o 16obj-$(CONFIG_USB) += usbcore.o
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index f86bf1454e21..b4265aa7d45e 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/usb.h> 44#include <linux/usb.h>
45#include <linux/usbdevice_fs.h> 45#include <linux/usbdevice_fs.h>
46#include <linux/cdev.h>
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47#include <asm/byteorder.h> 48#include <asm/byteorder.h>
48#include <linux/moduleparam.h> 49#include <linux/moduleparam.h>
@@ -50,6 +51,10 @@
50#include "hcd.h" /* for usbcore internals */ 51#include "hcd.h" /* for usbcore internals */
51#include "usb.h" 52#include "usb.h"
52 53
54#define USB_MAXBUS 64
55#define USB_DEVICE_MAX USB_MAXBUS * 128
56static struct class *usb_device_class;
57
53struct async { 58struct async {
54 struct list_head asynclist; 59 struct list_head asynclist;
55 struct dev_state *ps; 60 struct dev_state *ps;
@@ -71,6 +76,8 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic");
71 dev_info( dev , format , ## arg); \ 76 dev_info( dev , format , ## arg); \
72 } while (0) 77 } while (0)
73 78
79#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)
80
74 81
75#define MAX_USBFS_BUFFER_SIZE 16384 82#define MAX_USBFS_BUFFER_SIZE 16384
76 83
@@ -487,7 +494,7 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
487 */ 494 */
488static int usbdev_open(struct inode *inode, struct file *file) 495static int usbdev_open(struct inode *inode, struct file *file)
489{ 496{
490 struct usb_device *dev; 497 struct usb_device *dev = NULL;
491 struct dev_state *ps; 498 struct dev_state *ps;
492 int ret; 499 int ret;
493 500
@@ -501,11 +508,16 @@ static int usbdev_open(struct inode *inode, struct file *file)
501 508
502 lock_kernel(); 509 lock_kernel();
503 ret = -ENOENT; 510 ret = -ENOENT;
504 dev = usb_get_dev(inode->u.generic_ip); 511 /* check if we are called from a real node or usbfs */
512 if (imajor(inode) == USB_DEVICE_MAJOR)
513 dev = usbdev_lookup_minor(iminor(inode));
514 if (!dev)
515 dev = inode->u.generic_ip;
505 if (!dev) { 516 if (!dev) {
506 kfree(ps); 517 kfree(ps);
507 goto out; 518 goto out;
508 } 519 }
520 usb_get_dev(dev);
509 ret = 0; 521 ret = 0;
510 ps->dev = dev; 522 ps->dev = dev;
511 ps->file = file; 523 ps->file = file;
@@ -1226,7 +1238,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
1226 int retval = 0; 1238 int retval = 0;
1227 struct usb_interface *intf = NULL; 1239 struct usb_interface *intf = NULL;
1228 struct usb_driver *driver = NULL; 1240 struct usb_driver *driver = NULL;
1229 int i;
1230 1241
1231 /* get input parameters and alloc buffer */ 1242 /* get input parameters and alloc buffer */
1232 if (copy_from_user(&ctrl, arg, sizeof (ctrl))) 1243 if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
@@ -1258,15 +1269,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
1258 /* disconnect kernel driver from interface */ 1269 /* disconnect kernel driver from interface */
1259 case USBDEVFS_DISCONNECT: 1270 case USBDEVFS_DISCONNECT:
1260 1271
1261 /* don't allow the user to unbind the hub driver from
1262 * a hub with children to manage */
1263 for (i = 0; i < ps->dev->maxchild; ++i) {
1264 if (ps->dev->children[i])
1265 retval = -EBUSY;
1266 }
1267 if (retval)
1268 break;
1269
1270 down_write(&usb_bus_type.subsys.rwsem); 1272 down_write(&usb_bus_type.subsys.rwsem);
1271 if (intf->dev.driver) { 1273 if (intf->dev.driver) {
1272 driver = to_usb_driver(intf->dev.driver); 1274 driver = to_usb_driver(intf->dev.driver);
@@ -1477,3 +1479,79 @@ struct file_operations usbfs_device_file_operations = {
1477 .open = usbdev_open, 1479 .open = usbdev_open,
1478 .release = usbdev_release, 1480 .release = usbdev_release,
1479}; 1481};
1482
1483struct usb_device *usbdev_lookup_minor(int minor)
1484{
1485 struct class_device *class_dev;
1486 struct usb_device *dev = NULL;
1487
1488 down(&usb_device_class->sem);
1489 list_for_each_entry(class_dev, &usb_device_class->children, node) {
1490 if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
1491 dev = class_dev->class_data;
1492 break;
1493 }
1494 }
1495 up(&usb_device_class->sem);
1496
1497 return dev;
1498};
1499
1500void usbdev_add(struct usb_device *dev)
1501{
1502 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
1503
1504 dev->class_dev = class_device_create(usb_device_class,
1505 MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
1506 "usbdev%d.%d", dev->bus->busnum, dev->devnum);
1507
1508 dev->class_dev->class_data = dev;
1509}
1510
1511void usbdev_remove(struct usb_device *dev)
1512{
1513 class_device_unregister(dev->class_dev);
1514}
1515
1516static struct cdev usb_device_cdev = {
1517 .kobj = {.name = "usb_device", },
1518 .owner = THIS_MODULE,
1519};
1520
1521int __init usbdev_init(void)
1522{
1523 int retval;
1524
1525 retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
1526 "usb_device");
1527 if (retval) {
1528 err("unable to register minors for usb_device");
1529 goto out;
1530 }
1531 cdev_init(&usb_device_cdev, &usbfs_device_file_operations);
1532 retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
1533 if (retval) {
1534 err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
1535 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1536 goto out;
1537 }
1538 usb_device_class = class_create(THIS_MODULE, "usb_device");
1539 if (IS_ERR(usb_device_class)) {
1540 err("unable to register usb_device class");
1541 retval = PTR_ERR(usb_device_class);
1542 usb_device_class = NULL;
1543 cdev_del(&usb_device_cdev);
1544 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1545 }
1546
1547out:
1548 return retval;
1549}
1550
1551void usbdev_cleanup(void)
1552{
1553 class_destroy(usb_device_class);
1554 cdev_del(&usb_device_cdev);
1555 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
1556}
1557
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index fc056062c960..cbb451d227d2 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -121,10 +121,6 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
121 } 121 }
122 } 122 }
123 123
124#ifdef CONFIG_PCI_NAMES
125 hcd->product_desc = dev->pretty_name;
126#endif
127
128 pci_set_master (dev); 124 pci_set_master (dev);
129 125
130 retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ); 126 retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ);
@@ -264,8 +260,10 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
264 retval = pci_set_power_state (dev, PCI_D3hot); 260 retval = pci_set_power_state (dev, PCI_D3hot);
265 if (retval == 0) { 261 if (retval == 0) {
266 dev_dbg (hcd->self.controller, "--> PCI D3\n"); 262 dev_dbg (hcd->self.controller, "--> PCI D3\n");
267 pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); 263 retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
268 pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); 264 if (retval)
265 break;
266 retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
269 } else if (retval < 0) { 267 } else if (retval < 0) {
270 dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", 268 dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
271 retval); 269 retval);
@@ -339,8 +337,20 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
339 dev->current_state); 337 dev->current_state);
340 } 338 }
341#endif 339#endif
342 pci_enable_wake (dev, dev->current_state, 0); 340 retval = pci_enable_wake (dev, dev->current_state, 0);
343 pci_enable_wake (dev, PCI_D3cold, 0); 341 if (retval) {
342 dev_err(hcd->self.controller,
343 "can't enable_wake to %d, %d!\n",
344 dev->current_state, retval);
345 return retval;
346 }
347 retval = pci_enable_wake (dev, PCI_D3cold, 0);
348 if (retval) {
349 dev_err(hcd->self.controller,
350 "can't enable_wake to %d, %d!\n",
351 PCI_D3cold, retval);
352 return retval;
353 }
344 } else { 354 } else {
345 /* Same basic cases: clean (powered/not), dirty */ 355 /* Same basic cases: clean (powered/not), dirty */
346 dev_dbg(hcd->self.controller, "PCI legacy resume\n"); 356 dev_dbg(hcd->self.controller, "PCI legacy resume\n");
@@ -380,7 +390,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
380 usb_hc_died (hcd); 390 usb_hc_died (hcd);
381 } 391 }
382 392
383 pci_enable_device(dev); 393 retval = pci_enable_device(dev);
384 return retval; 394 return retval;
385} 395}
386EXPORT_SYMBOL (usb_hcd_pci_resume); 396EXPORT_SYMBOL (usb_hcd_pci_resume);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 28055f95645b..ac451fa7e4d2 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -339,11 +339,11 @@ extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
339 * to preallocate bandwidth) 339 * to preallocate bandwidth)
340 */ 340 */
341#define USB2_HOST_DELAY 5 /* nsec, guess */ 341#define USB2_HOST_DELAY 5 /* nsec, guess */
342#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \ 342#define HS_NSECS(bytes) ( ((55 * 8 * 2083) \
343 + ((2083UL * (3167 + BitTime (bytes)))/1000) \ 343 + (2083UL * (3 + BitTime(bytes))))/1000 \
344 + USB2_HOST_DELAY) 344 + USB2_HOST_DELAY)
345#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \ 345#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \
346 + ((2083UL * (3167 + BitTime (bytes)))/1000) \ 346 + (2083UL * (3 + BitTime(bytes))))/1000 \
347 + USB2_HOST_DELAY) 347 + USB2_HOST_DELAY)
348#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) 348#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
349#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) 349#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c9412daff682..758c7f0ed159 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -492,6 +492,23 @@ static int hub_hub_status(struct usb_hub *hub,
492 return ret; 492 return ret;
493} 493}
494 494
495static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
496{
497 struct usb_device *hdev = hub->hdev;
498 int ret;
499
500 if (hdev->children[port1-1] && set_state) {
501 usb_set_device_state(hdev->children[port1-1],
502 USB_STATE_NOTATTACHED);
503 }
504 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
505 if (ret)
506 dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
507 port1, ret);
508
509 return ret;
510}
511
495static int hub_configure(struct usb_hub *hub, 512static int hub_configure(struct usb_hub *hub,
496 struct usb_endpoint_descriptor *endpoint) 513 struct usb_endpoint_descriptor *endpoint)
497{ 514{
@@ -610,19 +627,33 @@ static int hub_configure(struct usb_hub *hub,
610 break; 627 break;
611 } 628 }
612 629
630 /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
613 switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { 631 switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
614 case 0x00: 632 case HUB_TTTT_8_BITS:
615 if (hdev->descriptor.bDeviceProtocol != 0) 633 if (hdev->descriptor.bDeviceProtocol != 0) {
616 dev_dbg(hub_dev, "TT requires at most 8 FS bit times\n"); 634 hub->tt.think_time = 666;
635 dev_dbg(hub_dev, "TT requires at most %d "
636 "FS bit times (%d ns)\n",
637 8, hub->tt.think_time);
638 }
617 break; 639 break;
618 case 0x20: 640 case HUB_TTTT_16_BITS:
619 dev_dbg(hub_dev, "TT requires at most 16 FS bit times\n"); 641 hub->tt.think_time = 666 * 2;
642 dev_dbg(hub_dev, "TT requires at most %d "
643 "FS bit times (%d ns)\n",
644 16, hub->tt.think_time);
620 break; 645 break;
621 case 0x40: 646 case HUB_TTTT_24_BITS:
622 dev_dbg(hub_dev, "TT requires at most 24 FS bit times\n"); 647 hub->tt.think_time = 666 * 3;
648 dev_dbg(hub_dev, "TT requires at most %d "
649 "FS bit times (%d ns)\n",
650 24, hub->tt.think_time);
623 break; 651 break;
624 case 0x60: 652 case HUB_TTTT_32_BITS:
625 dev_dbg(hub_dev, "TT requires at most 32 FS bit times\n"); 653 hub->tt.think_time = 666 * 4;
654 dev_dbg(hub_dev, "TT requires at most %d "
655 "FS bit times (%d ns)\n",
656 32, hub->tt.think_time);
626 break; 657 break;
627 } 658 }
628 659
@@ -712,20 +743,36 @@ fail:
712 743
713static unsigned highspeed_hubs; 744static unsigned highspeed_hubs;
714 745
746/* Called after the hub driver is unbound from a hub with children */
747static void hub_remove_children_work(void *__hub)
748{
749 struct usb_hub *hub = __hub;
750 struct usb_device *hdev = hub->hdev;
751 int i;
752
753 kfree(hub);
754
755 usb_lock_device(hdev);
756 for (i = 0; i < hdev->maxchild; ++i) {
757 if (hdev->children[i])
758 usb_disconnect(&hdev->children[i]);
759 }
760 usb_unlock_device(hdev);
761 usb_put_dev(hdev);
762}
763
715static void hub_disconnect(struct usb_interface *intf) 764static void hub_disconnect(struct usb_interface *intf)
716{ 765{
717 struct usb_hub *hub = usb_get_intfdata (intf); 766 struct usb_hub *hub = usb_get_intfdata (intf);
718 struct usb_device *hdev; 767 struct usb_device *hdev;
768 int n, port1;
719 769
720 if (!hub) 770 usb_set_intfdata (intf, NULL);
721 return;
722 hdev = hub->hdev; 771 hdev = hub->hdev;
723 772
724 if (hdev->speed == USB_SPEED_HIGH) 773 if (hdev->speed == USB_SPEED_HIGH)
725 highspeed_hubs--; 774 highspeed_hubs--;
726 775
727 usb_set_intfdata (intf, NULL);
728
729 hub_quiesce(hub); 776 hub_quiesce(hub);
730 usb_free_urb(hub->urb); 777 usb_free_urb(hub->urb);
731 hub->urb = NULL; 778 hub->urb = NULL;
@@ -746,8 +793,27 @@ static void hub_disconnect(struct usb_interface *intf)
746 hub->buffer = NULL; 793 hub->buffer = NULL;
747 } 794 }
748 795
749 /* Free the memory */ 796 /* If there are any children then this is an unbind only, not a
750 kfree(hub); 797 * physical disconnection. The active ports must be disabled
798 * and later on we must call usb_disconnect(). We can't call
799 * it now because we may not hold the hub's device lock.
800 */
801 n = 0;
802 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
803 if (hdev->children[port1 - 1]) {
804 ++n;
805 hub_port_disable(hub, port1, 1);
806 }
807 }
808
809 if (n == 0)
810 kfree(hub);
811 else {
812 /* Reuse the hub->leds work_struct for our own purposes */
813 INIT_WORK(&hub->leds, hub_remove_children_work, hub);
814 schedule_work(&hub->leds);
815 usb_get_dev(hdev);
816 }
751} 817}
752 818
753static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) 819static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1051,6 +1117,7 @@ void usb_disconnect(struct usb_device **pdev)
1051 dev_dbg (&udev->dev, "unregistering device\n"); 1117 dev_dbg (&udev->dev, "unregistering device\n");
1052 release_address(udev); 1118 release_address(udev);
1053 usbfs_remove_device(udev); 1119 usbfs_remove_device(udev);
1120 usbdev_remove(udev);
1054 usb_remove_sysfs_dev_files(udev); 1121 usb_remove_sysfs_dev_files(udev);
1055 1122
1056 /* Avoid races with recursively_mark_NOTATTACHED() */ 1123 /* Avoid races with recursively_mark_NOTATTACHED() */
@@ -1290,6 +1357,7 @@ int usb_new_device(struct usb_device *udev)
1290 /* USB device state == configured ... usable */ 1357 /* USB device state == configured ... usable */
1291 1358
1292 /* add a /proc/bus/usb entry */ 1359 /* add a /proc/bus/usb entry */
1360 usbdev_add(udev);
1293 usbfs_add_device(udev); 1361 usbfs_add_device(udev);
1294 return 0; 1362 return 0;
1295 1363
@@ -1428,23 +1496,6 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
1428 return status; 1496 return status;
1429} 1497}
1430 1498
1431static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
1432{
1433 struct usb_device *hdev = hub->hdev;
1434 int ret;
1435
1436 if (hdev->children[port1-1] && set_state) {
1437 usb_set_device_state(hdev->children[port1-1],
1438 USB_STATE_NOTATTACHED);
1439 }
1440 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
1441 if (ret)
1442 dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
1443 port1, ret);
1444
1445 return ret;
1446}
1447
1448/* 1499/*
1449 * Disable a port and mark a logical connnect-change event, so that some 1500 * Disable a port and mark a logical connnect-change event, so that some
1450 * time later khubd will disconnect() any existing usb_device on the port 1501 * time later khubd will disconnect() any existing usb_device on the port
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 53bf5649621e..e7fa9b5a521e 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -157,6 +157,12 @@ enum hub_led_mode {
157 157
158struct usb_device; 158struct usb_device;
159 159
160/* Transaction Translator Think Times, in bits */
161#define HUB_TTTT_8_BITS 0x00
162#define HUB_TTTT_16_BITS 0x20
163#define HUB_TTTT_24_BITS 0x40
164#define HUB_TTTT_32_BITS 0x60
165
160/* 166/*
161 * As of USB 2.0, full/low speed devices are segregated into trees. 167 * As of USB 2.0, full/low speed devices are segregated into trees.
162 * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). 168 * One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
@@ -170,6 +176,7 @@ struct usb_device;
170struct usb_tt { 176struct usb_tt {
171 struct usb_device *hub; /* upstream highspeed hub */ 177 struct usb_device *hub; /* upstream highspeed hub */
172 int multi; /* true means one TT per port */ 178 int multi; /* true means one TT per port */
179 unsigned think_time; /* think time in ns */
173 180
174 /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ 181 /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
175 spinlock_t lock; 182 spinlock_t lock;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index c3e3a95d3804..640f41e47029 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -728,15 +728,9 @@ int __init usbfs_init(void)
728{ 728{
729 int retval; 729 int retval;
730 730
731 retval = usb_register(&usbfs_driver);
732 if (retval)
733 return retval;
734
735 retval = register_filesystem(&usb_fs_type); 731 retval = register_filesystem(&usb_fs_type);
736 if (retval) { 732 if (retval)
737 usb_deregister(&usbfs_driver);
738 return retval; 733 return retval;
739 }
740 734
741 /* create mount point for usbfs */ 735 /* create mount point for usbfs */
742 usbdir = proc_mkdir("usb", proc_bus); 736 usbdir = proc_mkdir("usb", proc_bus);
@@ -746,7 +740,6 @@ int __init usbfs_init(void)
746 740
747void usbfs_cleanup(void) 741void usbfs_cleanup(void)
748{ 742{
749 usb_deregister(&usbfs_driver);
750 unregister_filesystem(&usb_fs_type); 743 unregister_filesystem(&usb_fs_type);
751 if (usbdir) 744 if (usbdir)
752 remove_proc_entry("usb", proc_bus); 745 remove_proc_entry("usb", proc_bus);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 88d1b376f67c..c47c8052b486 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -48,7 +48,6 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
48 48
49 init_completion(&done); 49 init_completion(&done);
50 urb->context = &done; 50 urb->context = &done;
51 urb->transfer_flags |= URB_ASYNC_UNLINK;
52 urb->actual_length = 0; 51 urb->actual_length = 0;
53 status = usb_submit_urb(urb, GFP_NOIO); 52 status = usb_submit_urb(urb, GFP_NOIO);
54 53
@@ -266,7 +265,9 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
266 continue; 265 continue;
267 if (found) { 266 if (found) {
268 status = usb_unlink_urb (io->urbs [i]); 267 status = usb_unlink_urb (io->urbs [i]);
269 if (status != -EINPROGRESS && status != -EBUSY) 268 if (status != -EINPROGRESS
269 && status != -ENODEV
270 && status != -EBUSY)
270 dev_err (&io->dev->dev, 271 dev_err (&io->dev->dev,
271 "%s, unlink --> %d\n", 272 "%s, unlink --> %d\n",
272 __FUNCTION__, status); 273 __FUNCTION__, status);
@@ -357,8 +358,7 @@ int usb_sg_init (
357 if (!io->urbs) 358 if (!io->urbs)
358 goto nomem; 359 goto nomem;
359 360
360 urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP 361 urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
361 | URB_NO_INTERRUPT;
362 if (usb_pipein (pipe)) 362 if (usb_pipein (pipe))
363 urb_flags |= URB_SHORT_NOT_OK; 363 urb_flags |= URB_SHORT_NOT_OK;
364 364
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c0feee25ff0a..c846fefb7386 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -309,9 +309,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
309 unsigned int allowed; 309 unsigned int allowed;
310 310
311 /* enforce simple/standard policy */ 311 /* enforce simple/standard policy */
312 allowed = URB_ASYNC_UNLINK; // affects later unlinks 312 allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
313 allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); 313 URB_NO_INTERRUPT);
314 allowed |= URB_NO_INTERRUPT;
315 switch (temp) { 314 switch (temp) {
316 case PIPE_BULK: 315 case PIPE_BULK:
317 if (is_out) 316 if (is_out)
@@ -400,14 +399,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
400 * canceled (rather than any other code) and will quickly be removed 399 * canceled (rather than any other code) and will quickly be removed
401 * from host controller data structures. 400 * from host controller data structures.
402 * 401 *
403 * In the past, clearing the URB_ASYNC_UNLINK transfer flag for the 402 * This request is always asynchronous.
404 * URB indicated that the request was synchronous. This usage is now 403 * Success is indicated by returning -EINPROGRESS,
405 * deprecated; if the flag is clear the call will be forwarded to
406 * usb_kill_urb() and the return value will be 0. In the future, drivers
407 * should call usb_kill_urb() directly for synchronous unlinking.
408 *
409 * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
410 * request is asynchronous. Success is indicated by returning -EINPROGRESS,
411 * at which time the URB will normally have been unlinked but not yet 404 * at which time the URB will normally have been unlinked but not yet
412 * given back to the device driver. When it is called, the completion 405 * given back to the device driver. When it is called, the completion
413 * function will see urb->status == -ECONNRESET. Failure is indicated 406 * function will see urb->status == -ECONNRESET. Failure is indicated
@@ -453,17 +446,6 @@ int usb_unlink_urb(struct urb *urb)
453{ 446{
454 if (!urb) 447 if (!urb)
455 return -EINVAL; 448 return -EINVAL;
456 if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) {
457#ifdef CONFIG_DEBUG_KERNEL
458 if (printk_ratelimit()) {
459 printk(KERN_NOTICE "usb_unlink_urb() is deprecated for "
460 "synchronous unlinks. Use usb_kill_urb() instead.\n");
461 WARN_ON(1);
462 }
463#endif
464 usb_kill_urb(urb);
465 return 0;
466 }
467 if (!(urb->dev && urb->dev->bus && urb->dev->bus->op)) 449 if (!(urb->dev && urb->dev->bus && urb->dev->bus->op))
468 return -ENODEV; 450 return -ENODEV;
469 return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET); 451 return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 2cddd8a00437..087af73a59dd 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -65,6 +65,16 @@ static int generic_probe (struct device *dev)
65} 65}
66static int generic_remove (struct device *dev) 66static int generic_remove (struct device *dev)
67{ 67{
68 struct usb_device *udev = to_usb_device(dev);
69
70 /* if this is only an unbind, not a physical disconnect, then
71 * unconfigure the device */
72 if (udev->state == USB_STATE_CONFIGURED)
73 usb_set_configuration(udev, 0);
74
75 /* in case the call failed or the device was suspended */
76 if (udev->state >= USB_STATE_CONFIGURED)
77 usb_disable_device(udev, 0);
68 return 0; 78 return 0;
69} 79}
70 80
@@ -912,7 +922,7 @@ int usb_trylock_device(struct usb_device *udev)
912 * is neither BINDING nor BOUND. Rather than sleeping to wait for the 922 * is neither BINDING nor BOUND. Rather than sleeping to wait for the
913 * lock, the routine polls repeatedly. This is to prevent deadlock with 923 * lock, the routine polls repeatedly. This is to prevent deadlock with
914 * disconnect; in some drivers (such as usb-storage) the disconnect() 924 * disconnect; in some drivers (such as usb-storage) the disconnect()
915 * callback will block waiting for a device reset to complete. 925 * or suspend() method will block waiting for a device reset to complete.
916 * 926 *
917 * Returns a negative error code for failure, otherwise 1 or 0 to indicate 927 * Returns a negative error code for failure, otherwise 1 or 0 to indicate
918 * that the device will or will not have to be unlocked. (0 can be 928 * that the device will or will not have to be unlocked. (0 can be
@@ -922,6 +932,8 @@ int usb_trylock_device(struct usb_device *udev)
922int usb_lock_device_for_reset(struct usb_device *udev, 932int usb_lock_device_for_reset(struct usb_device *udev,
923 struct usb_interface *iface) 933 struct usb_interface *iface)
924{ 934{
935 unsigned long jiffies_expire = jiffies + HZ;
936
925 if (udev->state == USB_STATE_NOTATTACHED) 937 if (udev->state == USB_STATE_NOTATTACHED)
926 return -ENODEV; 938 return -ENODEV;
927 if (udev->state == USB_STATE_SUSPENDED) 939 if (udev->state == USB_STATE_SUSPENDED)
@@ -938,6 +950,12 @@ int usb_lock_device_for_reset(struct usb_device *udev,
938 } 950 }
939 951
940 while (!usb_trylock_device(udev)) { 952 while (!usb_trylock_device(udev)) {
953
954 /* If we can't acquire the lock after waiting one second,
955 * we're probably deadlocked */
956 if (time_after(jiffies, jiffies_expire))
957 return -EBUSY;
958
941 msleep(15); 959 msleep(15);
942 if (udev->state == USB_STATE_NOTATTACHED) 960 if (udev->state == USB_STATE_NOTATTACHED)
943 return -ENODEV; 961 return -ENODEV;
@@ -1478,13 +1496,18 @@ static int __init usb_init(void)
1478 retval = usb_major_init(); 1496 retval = usb_major_init();
1479 if (retval) 1497 if (retval)
1480 goto major_init_failed; 1498 goto major_init_failed;
1499 retval = usb_register(&usbfs_driver);
1500 if (retval)
1501 goto driver_register_failed;
1502 retval = usbdev_init();
1503 if (retval)
1504 goto usbdevice_init_failed;
1481 retval = usbfs_init(); 1505 retval = usbfs_init();
1482 if (retval) 1506 if (retval)
1483 goto fs_init_failed; 1507 goto fs_init_failed;
1484 retval = usb_hub_init(); 1508 retval = usb_hub_init();
1485 if (retval) 1509 if (retval)
1486 goto hub_init_failed; 1510 goto hub_init_failed;
1487
1488 retval = driver_register(&usb_generic_driver); 1511 retval = driver_register(&usb_generic_driver);
1489 if (!retval) 1512 if (!retval)
1490 goto out; 1513 goto out;
@@ -1493,7 +1516,11 @@ static int __init usb_init(void)
1493hub_init_failed: 1516hub_init_failed:
1494 usbfs_cleanup(); 1517 usbfs_cleanup();
1495fs_init_failed: 1518fs_init_failed:
1496 usb_major_cleanup(); 1519 usbdev_cleanup();
1520usbdevice_init_failed:
1521 usb_deregister(&usbfs_driver);
1522driver_register_failed:
1523 usb_major_cleanup();
1497major_init_failed: 1524major_init_failed:
1498 usb_host_cleanup(); 1525 usb_host_cleanup();
1499host_init_failed: 1526host_init_failed:
@@ -1514,6 +1541,8 @@ static void __exit usb_exit(void)
1514 driver_unregister(&usb_generic_driver); 1541 driver_unregister(&usb_generic_driver);
1515 usb_major_cleanup(); 1542 usb_major_cleanup();
1516 usbfs_cleanup(); 1543 usbfs_cleanup();
1544 usb_deregister(&usbfs_driver);
1545 usbdev_cleanup();
1517 usb_hub_cleanup(); 1546 usb_hub_cleanup();
1518 usb_host_cleanup(); 1547 usb_host_cleanup();
1519 bus_unregister(&usb_bus_type); 1548 bus_unregister(&usb_bus_type);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 2c690f6d4c18..83d48c8133af 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -37,6 +37,11 @@ extern struct file_operations usbfs_devices_fops;
37extern struct file_operations usbfs_device_file_operations; 37extern struct file_operations usbfs_device_file_operations;
38extern void usbfs_conn_disc_event(void); 38extern void usbfs_conn_disc_event(void);
39 39
40extern int usbdev_init(void);
41extern void usbdev_cleanup(void);
42extern void usbdev_add(struct usb_device *dev);
43extern void usbdev_remove(struct usb_device *dev);
44extern struct usb_device *usbdev_lookup_minor(int minor);
40 45
41struct dev_state { 46struct dev_state {
42 struct list_head list; /* state list */ 47 struct list_head list; /* state list */
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8509e955007d..49459e33e952 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2181,6 +2181,7 @@ eth_bind (struct usb_gadget *gadget)
2181 u8 cdc = 1, zlp = 1, rndis = 1; 2181 u8 cdc = 1, zlp = 1, rndis = 1;
2182 struct usb_ep *in_ep, *out_ep, *status_ep = NULL; 2182 struct usb_ep *in_ep, *out_ep, *status_ep = NULL;
2183 int status = -ENOMEM; 2183 int status = -ENOMEM;
2184 int gcnum;
2184 2185
2185 /* these flags are only ever cleared; compiler take note */ 2186 /* these flags are only ever cleared; compiler take note */
2186#ifndef DEV_CONFIG_CDC 2187#ifndef DEV_CONFIG_CDC
@@ -2194,44 +2195,26 @@ eth_bind (struct usb_gadget *gadget)
2194 * standard protocol is _strongly_ preferred for interop purposes. 2195 * standard protocol is _strongly_ preferred for interop purposes.
2195 * (By everyone except Microsoft.) 2196 * (By everyone except Microsoft.)
2196 */ 2197 */
2197 if (gadget_is_net2280 (gadget)) { 2198 if (gadget_is_pxa (gadget)) {
2198 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
2199 } else if (gadget_is_dummy (gadget)) {
2200 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0202);
2201 } else if (gadget_is_pxa (gadget)) {
2202 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
2203 /* pxa doesn't support altsettings */ 2199 /* pxa doesn't support altsettings */
2204 cdc = 0; 2200 cdc = 0;
2205 } else if (gadget_is_sh(gadget)) { 2201 } else if (gadget_is_sh(gadget)) {
2206 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
2207 /* sh doesn't support multiple interfaces or configs */ 2202 /* sh doesn't support multiple interfaces or configs */
2208 cdc = 0; 2203 cdc = 0;
2209 rndis = 0; 2204 rndis = 0;
2210 } else if (gadget_is_sa1100 (gadget)) { 2205 } else if (gadget_is_sa1100 (gadget)) {
2211 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
2212 /* hardware can't write zlps */ 2206 /* hardware can't write zlps */
2213 zlp = 0; 2207 zlp = 0;
2214 /* sa1100 CAN do CDC, without status endpoint ... we use 2208 /* sa1100 CAN do CDC, without status endpoint ... we use
2215 * non-CDC to be compatible with ARM Linux-2.4 "usb-eth". 2209 * non-CDC to be compatible with ARM Linux-2.4 "usb-eth".
2216 */ 2210 */
2217 cdc = 0; 2211 cdc = 0;
2218 } else if (gadget_is_goku (gadget)) { 2212 }
2219 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206); 2213
2220 } else if (gadget_is_mq11xx (gadget)) { 2214 gcnum = usb_gadget_controller_number (gadget);
2221 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207); 2215 if (gcnum >= 0)
2222 } else if (gadget_is_omap (gadget)) { 2216 device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
2223 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208); 2217 else {
2224 } else if (gadget_is_lh7a40x(gadget)) {
2225 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
2226 } else if (gadget_is_n9604(gadget)) {
2227 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
2228 } else if (gadget_is_pxa27x(gadget)) {
2229 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
2230 } else if (gadget_is_s3c2410(gadget)) {
2231 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
2232 } else if (gadget_is_at91(gadget)) {
2233 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
2234 } else {
2235 /* can't assume CDC works. don't want to default to 2218 /* can't assume CDC works. don't want to default to
2236 * anything less functional on CDC-capable hardware, 2219 * anything less functional on CDC-capable hardware,
2237 * so we fail in this case. 2220 * so we fail in this case.
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 4f57085619b4..a41d9d4baee3 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3713,6 +3713,7 @@ static void fsg_unbind(struct usb_gadget *gadget)
3713static int __init check_parameters(struct fsg_dev *fsg) 3713static int __init check_parameters(struct fsg_dev *fsg)
3714{ 3714{
3715 int prot; 3715 int prot;
3716 int gcnum;
3716 3717
3717 /* Store the default values */ 3718 /* Store the default values */
3718 mod_data.transport_type = USB_PR_BULK; 3719 mod_data.transport_type = USB_PR_BULK;
@@ -3724,33 +3725,13 @@ static int __init check_parameters(struct fsg_dev *fsg)
3724 mod_data.can_stall = 0; 3725 mod_data.can_stall = 0;
3725 3726
3726 if (mod_data.release == 0xffff) { // Parameter wasn't set 3727 if (mod_data.release == 0xffff) { // Parameter wasn't set
3727 if (gadget_is_net2280(fsg->gadget))
3728 mod_data.release = 0x0301;
3729 else if (gadget_is_dummy(fsg->gadget))
3730 mod_data.release = 0x0302;
3731 else if (gadget_is_pxa(fsg->gadget))
3732 mod_data.release = 0x0303;
3733 else if (gadget_is_sh(fsg->gadget))
3734 mod_data.release = 0x0304;
3735
3736 /* The sa1100 controller is not supported */ 3728 /* The sa1100 controller is not supported */
3737 3729 if (gadget_is_sa1100(fsg->gadget))
3738 else if (gadget_is_goku(fsg->gadget)) 3730 gcnum = -1;
3739 mod_data.release = 0x0306; 3731 else
3740 else if (gadget_is_mq11xx(fsg->gadget)) 3732 gcnum = usb_gadget_controller_number(fsg->gadget);
3741 mod_data.release = 0x0307; 3733 if (gcnum >= 0)
3742 else if (gadget_is_omap(fsg->gadget)) 3734 mod_data.release = 0x0300 + gcnum;
3743 mod_data.release = 0x0308;
3744 else if (gadget_is_lh7a40x(fsg->gadget))
3745 mod_data.release = 0x0309;
3746 else if (gadget_is_n9604(fsg->gadget))
3747 mod_data.release = 0x0310;
3748 else if (gadget_is_pxa27x(fsg->gadget))
3749 mod_data.release = 0x0311;
3750 else if (gadget_is_s3c2410(gadget))
3751 mod_data.release = 0x0312;
3752 else if (gadget_is_at91(fsg->gadget))
3753 mod_data.release = 0x0313;
3754 else { 3735 else {
3755 WARN(fsg, "controller '%s' not recognized\n", 3736 WARN(fsg, "controller '%s' not recognized\n",
3756 fsg->gadget->name); 3737 fsg->gadget->name);
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index ea2eb52c766d..8cbae21d84b9 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -5,6 +5,7 @@
5 * 5 *
6 * This could eventually work like the ARM mach_is_*() stuff, driven by 6 * This could eventually work like the ARM mach_is_*() stuff, driven by
7 * some config file that gets updated as new hardware is supported. 7 * some config file that gets updated as new hardware is supported.
8 * (And avoiding the runtime comparisons in typical one-choice cases.)
8 * 9 *
9 * NOTE: some of these controller drivers may not be available yet. 10 * NOTE: some of these controller drivers may not be available yet.
10 */ 11 */
@@ -86,7 +87,61 @@
86#define gadget_is_at91(g) 0 87#define gadget_is_at91(g) 0
87#endif 88#endif
88 89
90#ifdef CONFIG_USB_GADGET_IMX
91#define gadget_is_imx(g) !strcmp("imx_udc", (g)->name)
92#else
93#define gadget_is_imx(g) 0
94#endif
95
89// CONFIG_USB_GADGET_SX2 96// CONFIG_USB_GADGET_SX2
90// CONFIG_USB_GADGET_AU1X00 97// CONFIG_USB_GADGET_AU1X00
91// ... 98// ...
92 99
100
101/**
102 * usb_gadget_controller_number - support bcdDevice id convention
103 * @gadget: the controller being driven
104 *
105 * Return a 2-digit BCD value associated with the peripheral controller,
106 * suitable for use as part of a bcdDevice value, or a negative error code.
107 *
108 * NOTE: this convention is purely optional, and has no meaning in terms of
109 * any USB specification. If you want to use a different convention in your
110 * gadget driver firmware -- maybe a more formal revision ID -- feel free.
111 *
112 * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
113 * to change their behavior accordingly. For example it might help avoiding
114 * some chip bug.
115 */
116static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
117{
118 if (gadget_is_net2280(gadget))
119 return 0x01;
120 else if (gadget_is_dummy(gadget))
121 return 0x02;
122 else if (gadget_is_pxa(gadget))
123 return 0x03;
124 else if (gadget_is_sh(gadget))
125 return 0x04;
126 else if (gadget_is_sa1100(gadget))
127 return 0x05;
128 else if (gadget_is_goku(gadget))
129 return 0x06;
130 else if (gadget_is_mq11xx(gadget))
131 return 0x07;
132 else if (gadget_is_omap(gadget))
133 return 0x08;
134 else if (gadget_is_lh7a40x(gadget))
135 return 0x09;
136 else if (gadget_is_n9604(gadget))
137 return 0x10;
138 else if (gadget_is_pxa27x(gadget))
139 return 0x11;
140 else if (gadget_is_s3c2410(gadget))
141 return 0x12;
142 else if (gadget_is_at91(gadget))
143 return 0x13;
144 else if (gadget_is_imx(gadget))
145 return 0x14;
146 return -ENOENT;
147}
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 9e4f1c6935a5..c925d9222f53 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -1422,49 +1422,20 @@ static int gs_bind(struct usb_gadget *gadget)
1422 int ret; 1422 int ret;
1423 struct usb_ep *ep; 1423 struct usb_ep *ep;
1424 struct gs_dev *dev; 1424 struct gs_dev *dev;
1425 int gcnum;
1425 1426
1426 /* device specific */ 1427 /* Some controllers can't support CDC ACM:
1427 if (gadget_is_net2280(gadget)) { 1428 * - sh doesn't support multiple interfaces or configs;
1428 gs_device_desc.bcdDevice = 1429 * - sa1100 doesn't have a third interrupt endpoint
1429 __constant_cpu_to_le16(GS_VERSION_NUM|0x0001); 1430 */
1430 } else if (gadget_is_pxa(gadget)) { 1431 if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
1431 gs_device_desc.bcdDevice =
1432 __constant_cpu_to_le16(GS_VERSION_NUM|0x0002);
1433 } else if (gadget_is_sh(gadget)) {
1434 gs_device_desc.bcdDevice =
1435 __constant_cpu_to_le16(GS_VERSION_NUM|0x0003);
1436 /* sh doesn't support multiple interfaces or configs */
1437 use_acm = 0; 1432 use_acm = 0;
1438 } else if (gadget_is_sa1100(gadget)) { 1433
1439 gs_device_desc.bcdDevice = 1434 gcnum = usb_gadget_controller_number(gadget);
1440 __constant_cpu_to_le16(GS_VERSION_NUM|0x0004); 1435 if (gcnum >= 0)
1441 /* sa1100 doesn't support necessary endpoints */
1442 use_acm = 0;
1443 } else if (gadget_is_goku(gadget)) {
1444 gs_device_desc.bcdDevice =
1445 __constant_cpu_to_le16(GS_VERSION_NUM|0x0005);
1446 } else if (gadget_is_mq11xx(gadget)) {
1447 gs_device_desc.bcdDevice =
1448 __constant_cpu_to_le16(GS_VERSION_NUM|0x0006);
1449 } else if (gadget_is_omap(gadget)) {
1450 gs_device_desc.bcdDevice =
1451 __constant_cpu_to_le16(GS_VERSION_NUM|0x0007);
1452 } else if (gadget_is_lh7a40x(gadget)) {
1453 gs_device_desc.bcdDevice =
1454 __constant_cpu_to_le16(GS_VERSION_NUM|0x0008);
1455 } else if (gadget_is_n9604(gadget)) {
1456 gs_device_desc.bcdDevice =
1457 __constant_cpu_to_le16(GS_VERSION_NUM|0x0009);
1458 } else if (gadget_is_pxa27x(gadget)) {
1459 gs_device_desc.bcdDevice =
1460 __constant_cpu_to_le16(GS_VERSION_NUM|0x0011);
1461 } else if (gadget_is_s3c2410(gadget)) {
1462 gs_device_desc.bcdDevice =
1463 __constant_cpu_to_le16(GS_VERSION_NUM|0x0012);
1464 } else if (gadget_is_at91(gadget)) {
1465 gs_device_desc.bcdDevice = 1436 gs_device_desc.bcdDevice =
1466 __constant_cpu_to_le16(GS_VERSION_NUM|0x0013); 1437 cpu_to_le16(GS_VERSION_NUM | gcnum);
1467 } else { 1438 else {
1468 printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n", 1439 printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
1469 gadget->name); 1440 gadget->name);
1470 /* unrecognized, but safe unless bulk is REALLY quirky */ 1441 /* unrecognized, but safe unless bulk is REALLY quirky */
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index bb9b2d94eed5..6890e773b2a2 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1139,6 +1139,13 @@ zero_bind (struct usb_gadget *gadget)
1139{ 1139{
1140 struct zero_dev *dev; 1140 struct zero_dev *dev;
1141 struct usb_ep *ep; 1141 struct usb_ep *ep;
1142 int gcnum;
1143
1144 /* FIXME this can't yet work right with SH ... it has only
1145 * one configuration, numbered one.
1146 */
1147 if (gadget_is_sh(gadget))
1148 return -ENODEV;
1142 1149
1143 /* Bulk-only drivers like this one SHOULD be able to 1150 /* Bulk-only drivers like this one SHOULD be able to
1144 * autoconfigure on any sane usb controller driver, 1151 * autoconfigure on any sane usb controller driver,
@@ -1161,43 +1168,10 @@ autoconf_fail:
1161 EP_OUT_NAME = ep->name; 1168 EP_OUT_NAME = ep->name;
1162 ep->driver_data = ep; /* claim */ 1169 ep->driver_data = ep; /* claim */
1163 1170
1164 1171 gcnum = usb_gadget_controller_number (gadget);
1165 /* 1172 if (gcnum >= 0)
1166 * DRIVER POLICY CHOICE: you may want to do this differently. 1173 device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
1167 * One thing to avoid is reusing a bcdDevice revision code 1174 else {
1168 * with different host-visible configurations or behavior
1169 * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc
1170 */
1171 if (gadget_is_net2280 (gadget)) {
1172 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
1173 } else if (gadget_is_pxa (gadget)) {
1174 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
1175#if 0
1176 } else if (gadget_is_sh(gadget)) {
1177 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
1178 /* SH has only one configuration; see "loopdefault" */
1179 device_desc.bNumConfigurations = 1;
1180 /* FIXME make 1 == default.bConfigurationValue */
1181#endif
1182 } else if (gadget_is_sa1100 (gadget)) {
1183 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
1184 } else if (gadget_is_goku (gadget)) {
1185 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
1186 } else if (gadget_is_mq11xx (gadget)) {
1187 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
1188 } else if (gadget_is_omap (gadget)) {
1189 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
1190 } else if (gadget_is_lh7a40x(gadget)) {
1191 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
1192 } else if (gadget_is_n9604(gadget)) {
1193 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
1194 } else if (gadget_is_pxa27x(gadget)) {
1195 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
1196 } else if (gadget_is_s3c2410(gadget)) {
1197 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
1198 } else if (gadget_is_at91(gadget)) {
1199 device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
1200 } else {
1201 /* gadget zero is so simple (for now, no altsettings) that 1175 /* gadget zero is so simple (for now, no altsettings) that
1202 * it SHOULD NOT have problems with bulk-capable hardware. 1176 * it SHOULD NOT have problems with bulk-capable hardware.
1203 * so warn about unrcognized controllers, don't panic. 1177 * so warn about unrcognized controllers, don't panic.
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 149b13fc0a71..2507e898af09 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -549,7 +549,9 @@ static int ehci_start (struct usb_hcd *hcd)
549 hcd->can_wakeup = (port_wake & 1) != 0; 549 hcd->can_wakeup = (port_wake & 1) != 0;
550 550
551 /* help hc dma work well with cachelines */ 551 /* help hc dma work well with cachelines */
552 pci_set_mwi (pdev); 552 retval = pci_set_mwi(pdev);
553 if (retval)
554 ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
553 } 555 }
554#endif 556#endif
555 557
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 20df01a79b2e..940d38ca7d91 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -677,6 +677,9 @@ qh_make (
677 goto done; 677 goto done;
678 } 678 }
679 } else { 679 } else {
680 struct usb_tt *tt = urb->dev->tt;
681 int think_time;
682
680 /* gap is f(FS/LS transfer times) */ 683 /* gap is f(FS/LS transfer times) */
681 qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed, 684 qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
682 is_input, 0, maxp) / (125 * 1000); 685 is_input, 0, maxp) / (125 * 1000);
@@ -690,6 +693,10 @@ qh_make (
690 qh->c_usecs = HS_USECS (0); 693 qh->c_usecs = HS_USECS (0);
691 } 694 }
692 695
696 think_time = tt ? tt->think_time : 0;
697 qh->tt_usecs = NS_TO_US (think_time +
698 usb_calc_bus_time (urb->dev->speed,
699 is_input, 0, max_packet (maxp)));
693 qh->period = urb->interval; 700 qh->period = urb->interval;
694 } 701 }
695 } 702 }
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 4c972b57c7c3..ccc7300baa6d 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -700,6 +700,7 @@ iso_stream_init (
700 700
701 } else { 701 } else {
702 u32 addr; 702 u32 addr;
703 int think_time;
703 704
704 addr = dev->ttport << 24; 705 addr = dev->ttport << 24;
705 if (!ehci_is_TDI(ehci) 706 if (!ehci_is_TDI(ehci)
@@ -709,6 +710,9 @@ iso_stream_init (
709 addr |= epnum << 8; 710 addr |= epnum << 8;
710 addr |= dev->devnum; 711 addr |= dev->devnum;
711 stream->usecs = HS_USECS_ISO (maxp); 712 stream->usecs = HS_USECS_ISO (maxp);
713 think_time = dev->tt ? dev->tt->think_time : 0;
714 stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
715 dev->speed, is_input, 1, maxp));
712 if (is_input) { 716 if (is_input) {
713 u32 tmp; 717 u32 tmp;
714 718
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index a7542157534c..20c9b550097d 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -421,6 +421,7 @@ struct ehci_qh {
421 u8 usecs; /* intr bandwidth */ 421 u8 usecs; /* intr bandwidth */
422 u8 gap_uf; /* uframes split/csplit gap */ 422 u8 gap_uf; /* uframes split/csplit gap */
423 u8 c_usecs; /* ... split completion bw */ 423 u8 c_usecs; /* ... split completion bw */
424 u16 tt_usecs; /* tt downstream bandwidth */
424 unsigned short period; /* polling interval */ 425 unsigned short period; /* polling interval */
425 unsigned short start; /* where polling starts */ 426 unsigned short start; /* where polling starts */
426#define NO_FRAME ((unsigned short)~0) /* pick new start */ 427#define NO_FRAME ((unsigned short)~0) /* pick new start */
@@ -479,6 +480,7 @@ struct ehci_iso_stream {
479 */ 480 */
480 u8 interval; 481 u8 interval;
481 u8 usecs, c_usecs; 482 u8 usecs, c_usecs;
483 u16 tt_usecs;
482 u16 maxp; 484 u16 maxp;
483 u16 raw_mask; 485 u16 raw_mask;
484 unsigned bandwidth; 486 unsigned bandwidth;
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 81f8f6b7fdce..a8267cf17db4 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -178,8 +178,8 @@ static __u8 root_hub_hub_des[] =
178 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ 178 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
179}; 179};
180 180
181static struct timer_list bulk_start_timer = TIMER_INITIALIZER(NULL, 0, 0); 181static DEFINE_TIMER(bulk_start_timer, NULL, 0, 0);
182static struct timer_list bulk_eot_timer = TIMER_INITIALIZER(NULL, 0, 0); 182static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0);
183 183
184/* We want the start timer to expire before the eot timer, because the former might start 184/* We want the start timer to expire before the eot timer, because the former might start
185 traffic, thus making it unnecessary for the latter to time out. */ 185 traffic, thus making it unnecessary for the latter to time out. */
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 75128c371800..41bbae83fc71 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -83,7 +83,7 @@
83#include "../core/hcd.h" 83#include "../core/hcd.h"
84#include "isp116x.h" 84#include "isp116x.h"
85 85
86#define DRIVER_VERSION "08 Apr 2005" 86#define DRIVER_VERSION "05 Aug 2005"
87#define DRIVER_DESC "ISP116x USB Host Controller Driver" 87#define DRIVER_DESC "ISP116x USB Host Controller Driver"
88 88
89MODULE_DESCRIPTION(DRIVER_DESC); 89MODULE_DESCRIPTION(DRIVER_DESC);
@@ -629,14 +629,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
629 ERR("Unrecoverable error\n"); 629 ERR("Unrecoverable error\n");
630 /* What should we do here? Reset? */ 630 /* What should we do here? Reset? */
631 } 631 }
632 if (intstat & HCINT_RHSC) { 632 if (intstat & HCINT_RHSC)
633 isp116x->rhstatus = 633 /* When root hub or any of its ports is going
634 isp116x_read_reg32(isp116x, HCRHSTATUS); 634 to come out of suspend, it may take more
635 isp116x->rhport[0] = 635 than 10ms for status bits to stabilize. */
636 isp116x_read_reg32(isp116x, HCRHPORT1); 636 mod_timer(&hcd->rh_timer, jiffies
637 isp116x->rhport[1] = 637 + msecs_to_jiffies(20) + 1);
638 isp116x_read_reg32(isp116x, HCRHPORT2);
639 }
640 if (intstat & HCINT_RD) { 638 if (intstat & HCINT_RD) {
641 DBG("---- remote wakeup\n"); 639 DBG("---- remote wakeup\n");
642 schedule_work(&isp116x->rh_resume); 640 schedule_work(&isp116x->rh_resume);
@@ -925,20 +923,27 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
925{ 923{
926 struct isp116x *isp116x = hcd_to_isp116x(hcd); 924 struct isp116x *isp116x = hcd_to_isp116x(hcd);
927 int ports, i, changed = 0; 925 int ports, i, changed = 0;
926 unsigned long flags;
928 927
929 if (!HC_IS_RUNNING(hcd->state)) 928 if (!HC_IS_RUNNING(hcd->state))
930 return -ESHUTDOWN; 929 return -ESHUTDOWN;
931 930
932 ports = isp116x->rhdesca & RH_A_NDP; 931 /* Report no status change now, if we are scheduled to be
932 called later */
933 if (timer_pending(&hcd->rh_timer))
934 return 0;
933 935
934 /* init status */ 936 ports = isp116x->rhdesca & RH_A_NDP;
937 spin_lock_irqsave(&isp116x->lock, flags);
938 isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
935 if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) 939 if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
936 buf[0] = changed = 1; 940 buf[0] = changed = 1;
937 else 941 else
938 buf[0] = 0; 942 buf[0] = 0;
939 943
940 for (i = 0; i < ports; i++) { 944 for (i = 0; i < ports; i++) {
941 u32 status = isp116x->rhport[i]; 945 u32 status = isp116x->rhport[i] =
946 isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
942 947
943 if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC 948 if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
944 | RH_PS_OCIC | RH_PS_PRSC)) { 949 | RH_PS_OCIC | RH_PS_PRSC)) {
@@ -947,6 +952,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
947 continue; 952 continue;
948 } 953 }
949 } 954 }
955 spin_unlock_irqrestore(&isp116x->lock, flags);
950 return changed; 956 return changed;
951} 957}
952 958
@@ -1463,10 +1469,6 @@ static int isp116x_sw_reset(struct isp116x *isp116x)
1463 return ret; 1469 return ret;
1464} 1470}
1465 1471
1466/*
1467 Reset. Tries to perform platform-specific hardware
1468 reset first; falls back to software reset.
1469*/
1470static int isp116x_reset(struct usb_hcd *hcd) 1472static int isp116x_reset(struct usb_hcd *hcd)
1471{ 1473{
1472 struct isp116x *isp116x = hcd_to_isp116x(hcd); 1474 struct isp116x *isp116x = hcd_to_isp116x(hcd);
@@ -1474,17 +1476,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
1474 u16 clkrdy = 0; 1476 u16 clkrdy = 0;
1475 int ret = 0, timeout = 15 /* ms */ ; 1477 int ret = 0, timeout = 15 /* ms */ ;
1476 1478
1477 if (isp116x->board && isp116x->board->reset) { 1479 ret = isp116x_sw_reset(isp116x);
1478 /* Hardware reset */
1479 isp116x->board->reset(hcd->self.controller, 1);
1480 msleep(10);
1481 if (isp116x->board->clock)
1482 isp116x->board->clock(hcd->self.controller, 1);
1483 msleep(1);
1484 isp116x->board->reset(hcd->self.controller, 0);
1485 } else
1486 ret = isp116x_sw_reset(isp116x);
1487
1488 if (ret) 1480 if (ret)
1489 return ret; 1481 return ret;
1490 1482
@@ -1501,10 +1493,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
1501 ERR("Clock not ready after 20ms\n"); 1493 ERR("Clock not ready after 20ms\n");
1502 /* After sw_reset the clock won't report to be ready, if 1494 /* After sw_reset the clock won't report to be ready, if
1503 H_WAKEUP pin is high. */ 1495 H_WAKEUP pin is high. */
1504 if (!isp116x->board || !isp116x->board->reset) 1496 ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
1505 ERR("The driver does not support hardware wakeup.\n");
1506 ERR("Please make sure that the H_WAKEUP pin "
1507 "is pulled low!\n");
1508 ret = -ENODEV; 1497 ret = -ENODEV;
1509 } 1498 }
1510 return ret; 1499 return ret;
@@ -1527,15 +1516,7 @@ static void isp116x_stop(struct usb_hcd *hcd)
1527 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS); 1516 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
1528 spin_unlock_irqrestore(&isp116x->lock, flags); 1517 spin_unlock_irqrestore(&isp116x->lock, flags);
1529 1518
1530 /* Put the chip into reset state */ 1519 isp116x_sw_reset(isp116x);
1531 if (isp116x->board && isp116x->board->reset)
1532 isp116x->board->reset(hcd->self.controller, 0);
1533 else
1534 isp116x_sw_reset(isp116x);
1535
1536 /* Stop the clock */
1537 if (isp116x->board && isp116x->board->clock)
1538 isp116x->board->clock(hcd->self.controller, 0);
1539} 1520}
1540 1521
1541/* 1522/*
@@ -1561,6 +1542,9 @@ static int isp116x_start(struct usb_hcd *hcd)
1561 return -ENODEV; 1542 return -ENODEV;
1562 } 1543 }
1563 1544
1545 /* To be removed in future */
1546 hcd->uses_new_polling = 1;
1547
1564 isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE); 1548 isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
1565 isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE); 1549 isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
1566 1550
@@ -1569,7 +1553,7 @@ static int isp116x_start(struct usb_hcd *hcd)
1569 if (board->sel15Kres) 1553 if (board->sel15Kres)
1570 val |= HCHWCFG_15KRSEL; 1554 val |= HCHWCFG_15KRSEL;
1571 /* Remote wakeup won't work without working clock */ 1555 /* Remote wakeup won't work without working clock */
1572 if (board->clknotstop || board->remote_wakeup_enable) 1556 if (board->remote_wakeup_enable)
1573 val |= HCHWCFG_CLKNOTSTOP; 1557 val |= HCHWCFG_CLKNOTSTOP;
1574 if (board->oc_enable) 1558 if (board->oc_enable)
1575 val |= HCHWCFG_ANALOG_OC; 1559 val |= HCHWCFG_ANALOG_OC;
@@ -1580,16 +1564,13 @@ static int isp116x_start(struct usb_hcd *hcd)
1580 isp116x_write_reg16(isp116x, HCHWCFG, val); 1564 isp116x_write_reg16(isp116x, HCHWCFG, val);
1581 1565
1582 /* ----- Root hub conf */ 1566 /* ----- Root hub conf */
1583 val = 0; 1567 val = (25 << 24) & RH_A_POTPGT;
1584 /* AN10003_1.pdf recommends NPS to be always 1 */ 1568 /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
1585 if (board->no_power_switching) 1569 be always set. Yet, instead, we request individual port
1586 val |= RH_A_NPS; 1570 power switching. */
1587 if (board->power_switching_mode) 1571 val |= RH_A_PSM;
1588 val |= RH_A_PSM; 1572 /* Report overcurrent per port */
1589 if (board->potpg) 1573 val |= RH_A_OCPM;
1590 val |= (board->potpg << 24) & RH_A_POTPGT;
1591 else
1592 val |= (25 << 24) & RH_A_POTPGT;
1593 isp116x_write_reg32(isp116x, HCRHDESCA, val); 1574 isp116x_write_reg32(isp116x, HCRHDESCA, val);
1594 isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA); 1575 isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
1595 1576
@@ -1619,9 +1600,6 @@ static int isp116x_start(struct usb_hcd *hcd)
1619 1600
1620 /* Go operational */ 1601 /* Go operational */
1621 val = HCCONTROL_USB_OPER; 1602 val = HCCONTROL_USB_OPER;
1622 /* Remote wakeup connected - NOT SUPPORTED */
1623 /* if (board->remote_wakeup_connected)
1624 val |= HCCONTROL_RWC; */
1625 if (board->remote_wakeup_enable) 1603 if (board->remote_wakeup_enable)
1626 val |= HCCONTROL_RWE; 1604 val |= HCCONTROL_RWE;
1627 isp116x_write_reg32(isp116x, HCCONTROL, val); 1605 isp116x_write_reg32(isp116x, HCCONTROL, val);
@@ -1670,7 +1648,7 @@ static int __init_or_module isp116x_remove(struct device *dev)
1670 struct platform_device *pdev; 1648 struct platform_device *pdev;
1671 struct resource *res; 1649 struct resource *res;
1672 1650
1673 if(!hcd) 1651 if (!hcd)
1674 return 0; 1652 return 0;
1675 isp116x = hcd_to_isp116x(hcd); 1653 isp116x = hcd_to_isp116x(hcd);
1676 pdev = container_of(dev, struct platform_device, dev); 1654 pdev = container_of(dev, struct platform_device, dev);
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 17964c39d06a..251533363028 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -14,8 +14,6 @@
14 * This file is licenced under the GPL. 14 * This file is licenced under the GPL.
15 */ 15 */
16 16
17#include <asm/usb.h>
18
19/* configure so an HC device and id are always provided */ 17/* configure so an HC device and id are always provided */
20/* always called with process context; sleeping is OK */ 18/* always called with process context; sleeping is OK */
21 19
@@ -23,9 +21,7 @@
23 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs 21 * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
24 * Context: !in_interrupt() 22 * Context: !in_interrupt()
25 * 23 *
26 * Allocates basic resources for this USB host controller, and 24 * Allocates basic resources for this USB host controller.
27 * then invokes the start() method for the HCD associated with it
28 * through the hotplug entry's driver_data.
29 * 25 *
30 * Store this function in the HCD's struct pci_driver as probe(). 26 * Store this function in the HCD's struct pci_driver as probe().
31 */ 27 */
@@ -37,7 +33,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
37 struct ohci_hcd *ohci; 33 struct ohci_hcd *ohci;
38 struct resource *res; 34 struct resource *res;
39 int irq; 35 int irq;
40 struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
41 36
42 pr_debug("initializing PPC-SOC USB Controller\n"); 37 pr_debug("initializing PPC-SOC USB Controller\n");
43 38
@@ -73,9 +68,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
73 goto err2; 68 goto err2;
74 } 69 }
75 70
76 if (pd->start && (retval = pd->start(pdev)))
77 goto err3;
78
79 ohci = hcd_to_ohci(hcd); 71 ohci = hcd_to_ohci(hcd);
80 ohci->flags |= OHCI_BIG_ENDIAN; 72 ohci->flags |= OHCI_BIG_ENDIAN;
81 ohci_hcd_init(ohci); 73 ohci_hcd_init(ohci);
@@ -85,9 +77,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
85 return retval; 77 return retval;
86 78
87 pr_debug("Removing PPC-SOC USB Controller\n"); 79 pr_debug("Removing PPC-SOC USB Controller\n");
88 if (pd && pd->stop) 80
89 pd->stop(pdev);
90 err3:
91 iounmap(hcd->regs); 81 iounmap(hcd->regs);
92 err2: 82 err2:
93 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 83 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -105,25 +95,21 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
105 * @pdev: USB Host Controller being removed 95 * @pdev: USB Host Controller being removed
106 * Context: !in_interrupt() 96 * Context: !in_interrupt()
107 * 97 *
108 * Reverses the effect of usb_hcd_ppc_soc_probe(), first invoking 98 * Reverses the effect of usb_hcd_ppc_soc_probe().
109 * the HCD's stop() method. It is always called from a thread 99 * It is always called from a thread
110 * context, normally "rmmod", "apmd", or something similar. 100 * context, normally "rmmod", "apmd", or something similar.
111 * 101 *
112 */ 102 */
113static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd, 103static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
114 struct platform_device *pdev) 104 struct platform_device *pdev)
115{ 105{
116 struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
117
118 usb_remove_hcd(hcd); 106 usb_remove_hcd(hcd);
119 107
120 pr_debug("stopping PPC-SOC USB Controller\n"); 108 pr_debug("stopping PPC-SOC USB Controller\n");
121 if (pd && pd->stop)
122 pd->stop(pdev);
123 109
124 iounmap(hcd->regs); 110 iounmap(hcd->regs);
125 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 111 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
126 usb_hcd_put(hcd); 112 usb_put_hcd(hcd);
127} 113}
128 114
129static int __devinit 115static int __devinit
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e9401662503c..3d9bcf78a9a4 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -129,7 +129,7 @@ static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info,
129 129
130 if (info->power_control != NULL) { 130 if (info->power_control != NULL) {
131 info->port[port-1].power = to; 131 info->port[port-1].power = to;
132 (info->power_control)(port, to); 132 (info->power_control)(port-1, to);
133 } 133 }
134} 134}
135 135
@@ -339,8 +339,8 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
339 struct usb_hcd *hcd = NULL; 339 struct usb_hcd *hcd = NULL;
340 int retval; 340 int retval;
341 341
342 s3c2410_usb_set_power(dev->dev.platform_data, 0, 1);
343 s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); 342 s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
343 s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);
344 344
345 hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); 345 hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
346 if (hcd == NULL) 346 if (hcd == NULL)
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 298e4a25e3d3..482c4be521f5 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -230,6 +230,20 @@ config USB_EGALAX
230 To compile this driver as a module, choose M here: the 230 To compile this driver as a module, choose M here: the
231 module will be called touchkitusb. 231 module will be called touchkitusb.
232 232
233config USB_YEALINK
234 tristate "Yealink usb-p1k voip phone"
235 depends on USB && INPUT && EXPERIMENTAL
236 ---help---
237 Say Y here if you want to enable keyboard and LCD functions of the
238 Yealink usb-p1k usb phones. The audio part is enabled by the generic
239 usb sound driver, so you might want to enable that as well.
240
241 For information about how to use these additional functions, see
242 <file:Documentation/input/yealink.txt>.
243
244 To compile this driver as a module, choose M here: the module will be
245 called yealink.
246
233config USB_XPAD 247config USB_XPAD
234 tristate "X-Box gamepad support" 248 tristate "X-Box gamepad support"
235 depends on USB && INPUT 249 depends on USB && INPUT
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index f1547be632d4..43b2f999edfe 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -39,4 +39,5 @@ obj-$(CONFIG_USB_EGALAX) += touchkitusb.o
39obj-$(CONFIG_USB_POWERMATE) += powermate.o 39obj-$(CONFIG_USB_POWERMATE) += powermate.o
40obj-$(CONFIG_USB_WACOM) += wacom.o 40obj-$(CONFIG_USB_WACOM) += wacom.o
41obj-$(CONFIG_USB_ACECAD) += acecad.o 41obj-$(CONFIG_USB_ACECAD) += acecad.o
42obj-$(CONFIG_USB_YEALINK) += yealink.o
42obj-$(CONFIG_USB_XPAD) += xpad.o 43obj-$(CONFIG_USB_XPAD) += xpad.o
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index b2cb2b35892e..1ab95d24c5e2 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1444,6 +1444,8 @@ void hid_init_reports(struct hid_device *hid)
1444#define USB_DEVICE_ID_NETWORKANALYSER 0x2020 1444#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
1445#define USB_DEVICE_ID_POWERCONTROL 0x2030 1445#define USB_DEVICE_ID_POWERCONTROL 0x2030
1446 1446
1447#define USB_VENDOR_ID_APPLE 0x05ac
1448#define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000
1447 1449
1448/* 1450/*
1449 * Alphabetically sorted blacklist by quirk type. 1451 * Alphabetically sorted blacklist by quirk type.
@@ -1462,6 +1464,7 @@ static struct hid_blacklist {
1462 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, 1464 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
1463 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, 1465 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
1464 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, 1466 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
1467 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_BLUETOOTH, HID_QUIRK_IGNORE },
1465 { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, 1468 { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
1466 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, 1469 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
1467 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, 1470 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
@@ -1685,7 +1688,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1685 usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, 1688 usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
1686 hid_irq_in, hid, interval); 1689 hid_irq_in, hid, interval);
1687 hid->urbin->transfer_dma = hid->inbuf_dma; 1690 hid->urbin->transfer_dma = hid->inbuf_dma;
1688 hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); 1691 hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1689 } else { 1692 } else {
1690 if (hid->urbout) 1693 if (hid->urbout)
1691 continue; 1694 continue;
@@ -1695,7 +1698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1695 usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, 1698 usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
1696 hid_irq_out, hid, interval); 1699 hid_irq_out, hid, interval);
1697 hid->urbout->transfer_dma = hid->outbuf_dma; 1700 hid->urbout->transfer_dma = hid->outbuf_dma;
1698 hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); 1701 hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1699 } 1702 }
1700 } 1703 }
1701 1704
@@ -1747,7 +1750,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1747 hid->ctrlbuf, 1, hid_ctrl, hid); 1750 hid->ctrlbuf, 1, hid_ctrl, hid);
1748 hid->urbctrl->setup_dma = hid->cr_dma; 1751 hid->urbctrl->setup_dma = hid->cr_dma;
1749 hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; 1752 hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
1750 hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK); 1753 hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1751 1754
1752 return hid; 1755 return hid;
1753 1756
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 67dc93685203..99de1b33c07d 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -431,11 +431,6 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
431 struct usb_endpoint_descriptor *endpoint; 431 struct usb_endpoint_descriptor *endpoint;
432 struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); 432 struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
433 433
434 /* See if the offered device matches what we can accept */
435 if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
436 (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
437 return -ENODEV;
438
439 /* allocate memory for our device state and initialize it */ 434 /* allocate memory for our device state and initialize it */
440 remote = kmalloc(sizeof(*remote), GFP_KERNEL); 435 remote = kmalloc(sizeof(*remote), GFP_KERNEL);
441 if (remote == NULL) { 436 if (remote == NULL) {
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h
new file mode 100644
index 000000000000..52ff27f15127
--- /dev/null
+++ b/drivers/usb/input/map_to_7segment.h
@@ -0,0 +1,189 @@
1/*
2 * drivers/usb/input/map_to_7segment.h
3 *
4 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (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 MAP_TO_7SEGMENT_H
22#define MAP_TO_7SEGMENT_H
23
24/* This file provides translation primitives and tables for the conversion
25 * of (ASCII) characters to a 7-segments notation.
26 *
27 * The 7 segment's wikipedia notation below is used as standard.
28 * See: http://en.wikipedia.org/wiki/Seven_segment_display
29 *
30 * Notation: +-a-+
31 * f b
32 * +-g-+
33 * e c
34 * +-d-+
35 *
36 * Usage:
37 *
38 * Register a map variable, and fill it with a character set:
39 * static SEG7_DEFAULT_MAP(map_seg7);
40 *
41 *
42 * Then use for conversion:
43 * seg7 = map_to_seg7(&map_seg7, some_char);
44 * ...
45 *
46 * In device drivers it is recommended, if required, to make the char map
47 * accessible via the sysfs interface using the following scheme:
48 *
49 * static ssize_t show_map(struct device *dev, char *buf) {
50 * memcpy(buf, &map_seg7, sizeof(map_seg7));
51 * return sizeof(map_seg7);
52 * }
53 * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) {
54 * if(cnt != sizeof(map_seg7))
55 * return -EINVAL;
56 * memcpy(&map_seg7, buf, cnt);
57 * return cnt;
58 * }
59 * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map);
60 *
61 * History:
62 * 2005-05-31 RFC linux-kernel@vger.kernel.org
63 */
64#include <linux/errno.h>
65
66
67#define BIT_SEG7_A 0
68#define BIT_SEG7_B 1
69#define BIT_SEG7_C 2
70#define BIT_SEG7_D 3
71#define BIT_SEG7_E 4
72#define BIT_SEG7_F 5
73#define BIT_SEG7_G 6
74#define BIT_SEG7_RESERVED 7
75
76struct seg7_conversion_map {
77 unsigned char table[128];
78};
79
80static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
81{
82 return c & 0x7f ? map->table[c] : -EINVAL;
83}
84
85#define SEG7_CONVERSION_MAP(_name, _map) \
86 struct seg7_conversion_map _name = { .table = { _map } }
87
88/*
89 * It is recommended to use a facility that allows user space to redefine
90 * custom character sets for LCD devices. Please use a sysfs interface
91 * as described above.
92 */
93#define MAP_TO_SEG7_SYSFS_FILE "map_seg7"
94
95/*******************************************************************************
96 * ASCII conversion table
97 ******************************************************************************/
98
99#define _SEG7(l,a,b,c,d,e,f,g) \
100 ( a<<BIT_SEG7_A | b<<BIT_SEG7_B | c<<BIT_SEG7_C | d<<BIT_SEG7_D | \
101 e<<BIT_SEG7_E | f<<BIT_SEG7_F | g<<BIT_SEG7_G )
102
103#define _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
104 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105
106#define _MAP_33_47_ASCII_SEG7_SYMBOL \
107 _SEG7('!',0,0,0,0,1,1,0), _SEG7('"',0,1,0,0,0,1,0), _SEG7('#',0,1,1,0,1,1,0),\
108 _SEG7('$',1,0,1,1,0,1,1), _SEG7('%',0,0,1,0,0,1,0), _SEG7('&',1,0,1,1,1,1,1),\
109 _SEG7('\'',0,0,0,0,0,1,0),_SEG7('(',1,0,0,1,1,1,0), _SEG7(')',1,1,1,1,0,0,0),\
110 _SEG7('*',0,1,1,0,1,1,1), _SEG7('+',0,1,1,0,0,0,1), _SEG7(',',0,0,0,0,1,0,0),\
111 _SEG7('-',0,0,0,0,0,0,1), _SEG7('.',0,0,0,0,1,0,0), _SEG7('/',0,1,0,0,1,0,1),
112
113#define _MAP_48_57_ASCII_SEG7_NUMERIC \
114 _SEG7('0',1,1,1,1,1,1,0), _SEG7('1',0,1,1,0,0,0,0), _SEG7('2',1,1,0,1,1,0,1),\
115 _SEG7('3',1,1,1,1,0,0,1), _SEG7('4',0,1,1,0,0,1,1), _SEG7('5',1,0,1,1,0,1,1),\
116 _SEG7('6',1,0,1,1,1,1,1), _SEG7('7',1,1,1,0,0,0,0), _SEG7('8',1,1,1,1,1,1,1),\
117 _SEG7('9',1,1,1,1,0,1,1),
118
119#define _MAP_58_64_ASCII_SEG7_SYMBOL \
120 _SEG7(':',0,0,0,1,0,0,1), _SEG7(';',0,0,0,1,0,0,1), _SEG7('<',1,0,0,0,0,1,1),\
121 _SEG7('=',0,0,0,1,0,0,1), _SEG7('>',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\
122 _SEG7('@',1,1,0,1,1,1,1),
123
124#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
125 _SEG7('A',1,1,1,0,1,1,1), _SEG7('B',1,1,1,1,1,1,1), _SEG7('C',1,0,0,1,1,1,0),\
126 _SEG7('D',1,1,1,1,1,1,0), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
127 _SEG7('G',1,1,1,1,0,1,1), _SEG7('H',0,1,1,0,1,1,1), _SEG7('I',0,1,1,0,0,0,0),\
128 _SEG7('J',0,1,1,1,0,0,0), _SEG7('K',0,1,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
129 _SEG7('M',1,1,1,0,1,1,0), _SEG7('N',1,1,1,0,1,1,0), _SEG7('O',1,1,1,1,1,1,0),\
130 _SEG7('P',1,1,0,0,1,1,1), _SEG7('Q',1,1,1,1,1,1,0), _SEG7('R',1,1,1,0,1,1,1),\
131 _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('U',0,1,1,1,1,1,0),\
132 _SEG7('V',0,1,1,1,1,1,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
133 _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
134
135#define _MAP_91_96_ASCII_SEG7_SYMBOL \
136 _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\
137 _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0),
138
139#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
140 _SEG7('A',1,1,1,0,1,1,1), _SEG7('b',0,0,1,1,1,1,1), _SEG7('c',0,0,0,1,1,0,1),\
141 _SEG7('d',0,1,1,1,1,0,1), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
142 _SEG7('G',1,1,1,1,0,1,1), _SEG7('h',0,0,1,0,1,1,1), _SEG7('i',0,0,1,0,0,0,0),\
143 _SEG7('j',0,0,1,1,0,0,0), _SEG7('k',0,0,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
144 _SEG7('M',1,1,1,0,1,1,0), _SEG7('n',0,0,1,0,1,0,1), _SEG7('o',0,0,1,1,1,0,1),\
145 _SEG7('P',1,1,0,0,1,1,1), _SEG7('q',1,1,1,0,0,1,1), _SEG7('r',0,0,0,0,1,0,1),\
146 _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('u',0,0,1,1,1,0,0),\
147 _SEG7('v',0,0,1,1,1,0,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
148 _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
149
150#define _MAP_123_126_ASCII_SEG7_SYMBOL \
151 _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\
152 _SEG7('~',1,0,0,0,0,0,0),
153
154/* Maps */
155
156/* This set tries to map as close as possible to the visible characteristics
157 * of the ASCII symbol, lowercase and uppercase letters may differ in
158 * presentation on the display.
159 */
160#define MAP_ASCII7SEG_ALPHANUM \
161 _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
162 _MAP_33_47_ASCII_SEG7_SYMBOL \
163 _MAP_48_57_ASCII_SEG7_NUMERIC \
164 _MAP_58_64_ASCII_SEG7_SYMBOL \
165 _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
166 _MAP_91_96_ASCII_SEG7_SYMBOL \
167 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
168 _MAP_123_126_ASCII_SEG7_SYMBOL
169
170/* This set tries to map as close as possible to the symbolic characteristics
171 * of the ASCII character for maximum discrimination.
172 * For now this means all alpha chars are in lower case representations.
173 * (This for example facilitates the use of hex numbers with uppercase input.)
174 */
175#define MAP_ASCII7SEG_ALPHANUM_LC \
176 _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
177 _MAP_33_47_ASCII_SEG7_SYMBOL \
178 _MAP_48_57_ASCII_SEG7_NUMERIC \
179 _MAP_58_64_ASCII_SEG7_SYMBOL \
180 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
181 _MAP_91_96_ASCII_SEG7_SYMBOL \
182 _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
183 _MAP_123_126_ASCII_SEG7_SYMBOL
184
185#define SEG7_DEFAULT_MAP(_name) \
186 SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM)
187
188#endif /* MAP_TO_7SEGMENT_H */
189
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
new file mode 100644
index 000000000000..58a176ef96a5
--- /dev/null
+++ b/drivers/usb/input/yealink.c
@@ -0,0 +1,1013 @@
1/*
2 * drivers/usb/input/yealink.c
3 *
4 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (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 * Description:
22 * Driver for the USB-P1K voip usb phone.
23 * This device is produced by Yealink Network Technology Co Ltd
24 * but may be branded under several names:
25 * - Yealink usb-p1k
26 * - Tiptel 115
27 * - ...
28 *
29 * This driver is based on:
30 * - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/
31 * - information from http://memeteau.free.fr/usbb2k
32 * - the xpad-driver drivers/usb/input/xpad.c
33 *
34 * Thanks to:
35 * - Olivier Vandorpe, for providing the usbb2k-api.
36 * - Martin Diehl, for spotting my memory allocation bug.
37 *
38 * History:
39 * 20050527 henk First version, functional keyboard. Keyboard events
40 * will pop-up on the ../input/eventX bus.
41 * 20050531 henk Added led, LCD, dialtone and sysfs interface.
42 * 20050610 henk Cleanups, make it ready for public consumption.
43 * 20050630 henk Cleanups, fixes in response to comments.
44 * 20050701 henk sysfs write serialisation, fix potential unload races
45 * 20050801 henk Added ringtone, restructure USB
46 * 20050816 henk Merge 2.6.13-rc6
47 */
48
49#include <linux/config.h>
50#include <linux/kernel.h>
51#include <linux/input.h>
52#include <linux/init.h>
53#include <linux/slab.h>
54#include <linux/module.h>
55#include <linux/rwsem.h>
56#include <linux/usb.h>
57
58#include "map_to_7segment.h"
59#include "yealink.h"
60
61#define DRIVER_VERSION "yld-20050816"
62#define DRIVER_AUTHOR "Henk Vergonet"
63#define DRIVER_DESC "Yealink phone driver"
64
65#define YEALINK_POLLING_FREQUENCY 10 /* in [Hz] */
66
67struct yld_status {
68 u8 lcd[24];
69 u8 led;
70 u8 dialtone;
71 u8 ringtone;
72 u8 keynum;
73} __attribute__ ((packed));
74
75/*
76 * Register the LCD segment and icon map
77 */
78#define _LOC(k,l) { .a = (k), .m = (l) }
79#define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm) \
80 { .type = (t), \
81 .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm), \
82 _LOC(d, dm), _LOC(e, em), _LOC(g, gm), \
83 _LOC(f, fm) } } }
84#define _PIC(t, h, hm, n) \
85 { .type = (t), \
86 .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
87
88static const struct lcd_segment_map {
89 char type;
90 union {
91 struct pictogram_map {
92 u8 a,m;
93 char name[10];
94 } p;
95 struct segment_map {
96 u8 a,m;
97 } s[7];
98 } u;
99} lcdMap[] = {
100#include "yealink.h"
101};
102
103struct yealink_dev {
104 struct input_dev idev; /* input device */
105 struct usb_device *udev; /* usb device */
106
107 /* irq input channel */
108 struct yld_ctl_packet *irq_data;
109 dma_addr_t irq_dma;
110 struct urb *urb_irq;
111
112 /* control output channel */
113 struct yld_ctl_packet *ctl_data;
114 dma_addr_t ctl_dma;
115 struct usb_ctrlrequest *ctl_req;
116 dma_addr_t ctl_req_dma;
117 struct urb *urb_ctl;
118
119 char phys[64]; /* physical device path */
120
121 u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */
122 int key_code; /* last reported key */
123
124 int stat_ix;
125 union {
126 struct yld_status s;
127 u8 b[sizeof(struct yld_status)];
128 } master, copy;
129};
130
131
132/*******************************************************************************
133 * Yealink lcd interface
134 ******************************************************************************/
135
136/*
137 * Register a default 7 segment character set
138 */
139static SEG7_DEFAULT_MAP(map_seg7);
140
141 /* Display a char,
142 * char '\9' and '\n' are placeholders and do not overwrite the original text.
143 * A space will always hide an icon.
144 */
145static int setChar(struct yealink_dev *yld, int el, int chr)
146{
147 int i, a, m, val;
148
149 if (el >= ARRAY_SIZE(lcdMap))
150 return -EINVAL;
151
152 if (chr == '\t' || chr == '\n')
153 return 0;
154
155 yld->lcdMap[el] = chr;
156
157 if (lcdMap[el].type == '.') {
158 a = lcdMap[el].u.p.a;
159 m = lcdMap[el].u.p.m;
160 if (chr != ' ')
161 yld->master.b[a] |= m;
162 else
163 yld->master.b[a] &= ~m;
164 return 0;
165 }
166
167 val = map_to_seg7(&map_seg7, chr);
168 for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
169 m = lcdMap[el].u.s[i].m;
170
171 if (m == 0)
172 continue;
173
174 a = lcdMap[el].u.s[i].a;
175 if (val & 1)
176 yld->master.b[a] |= m;
177 else
178 yld->master.b[a] &= ~m;
179 val = val >> 1;
180 }
181 return 0;
182};
183
184/*******************************************************************************
185 * Yealink key interface
186 ******************************************************************************/
187
188/* Map device buttons to internal key events.
189 *
190 * USB-P1K button layout:
191 *
192 * up
193 * IN OUT
194 * down
195 *
196 * pickup C hangup
197 * 1 2 3
198 * 4 5 6
199 * 7 8 9
200 * * 0 #
201 *
202 * The "up" and "down" keys, are symbolised by arrows on the button.
203 * The "pickup" and "hangup" keys are symbolised by a green and red phone
204 * on the button.
205 */
206static int map_p1k_to_key(int scancode)
207{
208 switch(scancode) { /* phone key: */
209 case 0x23: return KEY_LEFT; /* IN */
210 case 0x33: return KEY_UP; /* up */
211 case 0x04: return KEY_RIGHT; /* OUT */
212 case 0x24: return KEY_DOWN; /* down */
213 case 0x03: return KEY_ENTER; /* pickup */
214 case 0x14: return KEY_BACKSPACE; /* C */
215 case 0x13: return KEY_ESC; /* hangup */
216 case 0x00: return KEY_1; /* 1 */
217 case 0x01: return KEY_2; /* 2 */
218 case 0x02: return KEY_3; /* 3 */
219 case 0x10: return KEY_4; /* 4 */
220 case 0x11: return KEY_5; /* 5 */
221 case 0x12: return KEY_6; /* 6 */
222 case 0x20: return KEY_7; /* 7 */
223 case 0x21: return KEY_8; /* 8 */
224 case 0x22: return KEY_9; /* 9 */
225 case 0x30: return KEY_KPASTERISK; /* * */
226 case 0x31: return KEY_0; /* 0 */
227 case 0x32: return KEY_LEFTSHIFT |
228 KEY_3 << 8; /* # */
229 }
230 return -EINVAL;
231}
232
233/* Completes a request by converting the data into events for the
234 * input subsystem.
235 *
236 * The key parameter can be cascaded: key2 << 8 | key1
237 */
238static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
239{
240 struct input_dev *idev = &yld->idev;
241
242 input_regs(idev, regs);
243 if (yld->key_code >= 0) {
244 /* old key up */
245 input_report_key(idev, yld->key_code & 0xff, 0);
246 if (yld->key_code >> 8)
247 input_report_key(idev, yld->key_code >> 8, 0);
248 }
249
250 yld->key_code = key;
251 if (key >= 0) {
252 /* new valid key */
253 input_report_key(idev, key & 0xff, 1);
254 if (key >> 8)
255 input_report_key(idev, key >> 8, 1);
256 }
257 input_sync(idev);
258}
259
260/*******************************************************************************
261 * Yealink usb communication interface
262 ******************************************************************************/
263
264static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
265{
266 u8 *buf = (u8 *)p;
267 int i;
268 u8 sum = 0;
269
270 for(i=0; i<USB_PKT_LEN-1; i++)
271 sum -= buf[i];
272 p->sum = sum;
273 return usb_control_msg(yld->udev,
274 usb_sndctrlpipe(yld->udev, 0),
275 USB_REQ_SET_CONFIGURATION,
276 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
277 0x200, 3,
278 p, sizeof(*p),
279 USB_CTRL_SET_TIMEOUT);
280}
281
282static u8 default_ringtone[] = {
283 0xEF, /* volume [0-255] */
284 0xFB, 0x1E, 0x00, 0x0C, /* 1250 [hz], 12/100 [s] */
285 0xFC, 0x18, 0x00, 0x0C, /* 1000 [hz], 12/100 [s] */
286 0xFB, 0x1E, 0x00, 0x0C,
287 0xFC, 0x18, 0x00, 0x0C,
288 0xFB, 0x1E, 0x00, 0x0C,
289 0xFC, 0x18, 0x00, 0x0C,
290 0xFB, 0x1E, 0x00, 0x0C,
291 0xFC, 0x18, 0x00, 0x0C,
292 0xFF, 0xFF, 0x01, 0x90, /* silent, 400/100 [s] */
293 0x00, 0x00 /* end of sequence */
294};
295
296static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
297{
298 struct yld_ctl_packet *p = yld->ctl_data;
299 int ix, len;
300
301 if (size <= 0)
302 return -EINVAL;
303
304 /* Set the ringtone volume */
305 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
306 yld->ctl_data->cmd = CMD_RING_VOLUME;
307 yld->ctl_data->size = 1;
308 yld->ctl_data->data[0] = buf[0];
309 yealink_cmd(yld, p);
310
311 buf++;
312 size--;
313
314 p->cmd = CMD_RING_NOTE;
315 ix = 0;
316 while (size != ix) {
317 len = size - ix;
318 if (len > sizeof(p->data))
319 len = sizeof(p->data);
320 p->size = len;
321 p->offset = cpu_to_be16(ix);
322 memcpy(p->data, &buf[ix], len);
323 yealink_cmd(yld, p);
324 ix += len;
325 }
326 return 0;
327}
328
329/* keep stat_master & stat_copy in sync.
330 */
331static int yealink_do_idle_tasks(struct yealink_dev *yld)
332{
333 u8 val;
334 int i, ix, len;
335
336 ix = yld->stat_ix;
337
338 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
339 yld->ctl_data->cmd = CMD_KEYPRESS;
340 yld->ctl_data->size = 1;
341 yld->ctl_data->sum = 0xff - CMD_KEYPRESS;
342
343 /* If state update pointer wraps do a KEYPRESS first. */
344 if (ix >= sizeof(yld->master)) {
345 yld->stat_ix = 0;
346 return 0;
347 }
348
349 /* find update candidates: copy != master */
350 do {
351 val = yld->master.b[ix];
352 if (val != yld->copy.b[ix])
353 goto send_update;
354 } while (++ix < sizeof(yld->master));
355
356 /* nothing todo, wait a bit and poll for a KEYPRESS */
357 yld->stat_ix = 0;
358 /* TODO how can we wait abit. ??
359 * msleep_interruptible(1000 / YEALINK_POLLING_FREQUENCY);
360 */
361 return 0;
362
363send_update:
364
365 /* Setup an appropriate update request */
366 yld->copy.b[ix] = val;
367 yld->ctl_data->data[0] = val;
368
369 switch(ix) {
370 case offsetof(struct yld_status, led):
371 yld->ctl_data->cmd = CMD_LED;
372 yld->ctl_data->sum = -1 - CMD_LED - val;
373 break;
374 case offsetof(struct yld_status, dialtone):
375 yld->ctl_data->cmd = CMD_DIALTONE;
376 yld->ctl_data->sum = -1 - CMD_DIALTONE - val;
377 break;
378 case offsetof(struct yld_status, ringtone):
379 yld->ctl_data->cmd = CMD_RINGTONE;
380 yld->ctl_data->sum = -1 - CMD_RINGTONE - val;
381 break;
382 case offsetof(struct yld_status, keynum):
383 val--;
384 val &= 0x1f;
385 yld->ctl_data->cmd = CMD_SCANCODE;
386 yld->ctl_data->offset = cpu_to_be16(val);
387 yld->ctl_data->data[0] = 0;
388 yld->ctl_data->sum = -1 - CMD_SCANCODE - val;
389 break;
390 default:
391 len = sizeof(yld->master.s.lcd) - ix;
392 if (len > sizeof(yld->ctl_data->data))
393 len = sizeof(yld->ctl_data->data);
394
395 /* Combine up to <len> consecutive LCD bytes in a singe request
396 */
397 yld->ctl_data->cmd = CMD_LCD;
398 yld->ctl_data->offset = cpu_to_be16(ix);
399 yld->ctl_data->size = len;
400 yld->ctl_data->sum = -CMD_LCD - ix - val - len;
401 for(i=1; i<len; i++) {
402 ix++;
403 val = yld->master.b[ix];
404 yld->copy.b[ix] = val;
405 yld->ctl_data->data[i] = val;
406 yld->ctl_data->sum -= val;
407 }
408 }
409 yld->stat_ix = ix + 1;
410 return 1;
411}
412
413/* Decide on how to handle responses
414 *
415 * The state transition diagram is somethhing like:
416 *
417 * syncState<--+
418 * | |
419 * | idle
420 * \|/ |
421 * init --ok--> waitForKey --ok--> getKey
422 * ^ ^ |
423 * | +-------ok-------+
424 * error,start
425 *
426 */
427static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
428{
429 struct yealink_dev *yld = urb->context;
430 int ret;
431
432 if (urb->status)
433 err("%s - urb status %d", __FUNCTION__, urb->status);
434
435 switch (yld->irq_data->cmd) {
436 case CMD_KEYPRESS:
437
438 yld->master.s.keynum = yld->irq_data->data[0];
439 break;
440
441 case CMD_SCANCODE:
442 dbg("get scancode %x", yld->irq_data->data[0]);
443
444 report_key(yld, map_p1k_to_key(yld->irq_data->data[0]), regs);
445 break;
446
447 default:
448 err("unexpected response %x", yld->irq_data->cmd);
449 }
450
451 yealink_do_idle_tasks(yld);
452
453 ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
454 if (ret)
455 err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
456}
457
458static void urb_ctl_callback(struct urb *urb, struct pt_regs *regs)
459{
460 struct yealink_dev *yld = urb->context;
461 int ret;
462
463 if (urb->status)
464 err("%s - urb status %d", __FUNCTION__, urb->status);
465
466 switch (yld->ctl_data->cmd) {
467 case CMD_KEYPRESS:
468 case CMD_SCANCODE:
469 /* ask for a response */
470 ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
471 break;
472 default:
473 /* send new command */
474 yealink_do_idle_tasks(yld);
475 ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
476 }
477
478 if (ret)
479 err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
480}
481
482/*******************************************************************************
483 * input event interface
484 ******************************************************************************/
485
486/* TODO should we issue a ringtone on a SND_BELL event?
487static int input_ev(struct input_dev *dev, unsigned int type,
488 unsigned int code, int value)
489{
490
491 if (type != EV_SND)
492 return -EINVAL;
493
494 switch (code) {
495 case SND_BELL:
496 case SND_TONE:
497 break;
498 default:
499 return -EINVAL;
500 }
501
502 return 0;
503}
504*/
505
506static int input_open(struct input_dev *dev)
507{
508 struct yealink_dev *yld = dev->private;
509 int i, ret;
510
511 dbg("%s", __FUNCTION__);
512
513 /* force updates to device */
514 for (i = 0; i<sizeof(yld->master); i++)
515 yld->copy.b[i] = ~yld->master.b[i];
516 yld->key_code = -1; /* no keys pressed */
517
518 yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
519
520 /* issue INIT */
521 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
522 yld->ctl_data->cmd = CMD_INIT;
523 yld->ctl_data->size = 10;
524 yld->ctl_data->sum = 0x100-CMD_INIT-10;
525 if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
526 dbg("%s - usb_submit_urb failed with result %d",
527 __FUNCTION__, ret);
528 return ret;
529 }
530 return 0;
531}
532
533static void input_close(struct input_dev *dev)
534{
535 struct yealink_dev *yld = dev->private;
536
537 usb_kill_urb(yld->urb_ctl);
538 usb_kill_urb(yld->urb_irq);
539}
540
541/*******************************************************************************
542 * sysfs interface
543 ******************************************************************************/
544
545static DECLARE_RWSEM(sysfs_rwsema);
546
547/* Interface to the 7-segments translation table aka. char set.
548 */
549static ssize_t show_map(struct device *dev, struct device_attribute *attr,
550 char *buf)
551{
552 memcpy(buf, &map_seg7, sizeof(map_seg7));
553 return sizeof(map_seg7);
554}
555
556static ssize_t store_map(struct device *dev, struct device_attribute *attr,
557 const char *buf, size_t cnt)
558{
559 if (cnt != sizeof(map_seg7))
560 return -EINVAL;
561 memcpy(&map_seg7, buf, sizeof(map_seg7));
562 return sizeof(map_seg7);
563}
564
565/* Interface to the LCD.
566 */
567
568/* Reading /sys/../lineX will return the format string with its settings:
569 *
570 * Example:
571 * cat ./line3
572 * 888888888888
573 * Linux Rocks!
574 */
575static ssize_t show_line(struct device *dev, char *buf, int a, int b)
576{
577 struct yealink_dev *yld;
578 int i;
579
580 down_read(&sysfs_rwsema);
581 yld = dev_get_drvdata(dev);
582 if (yld == NULL) {
583 up_read(&sysfs_rwsema);
584 return -ENODEV;
585 }
586
587 for (i = a; i < b; i++)
588 *buf++ = lcdMap[i].type;
589 *buf++ = '\n';
590 for (i = a; i < b; i++)
591 *buf++ = yld->lcdMap[i];
592 *buf++ = '\n';
593 *buf = 0;
594
595 up_read(&sysfs_rwsema);
596 return 3 + ((b - a) << 1);
597}
598
599static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
600 char *buf)
601{
602 return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
603}
604
605static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
606 char *buf)
607{
608 return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
609}
610
611static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
612 char *buf)
613{
614 return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
615}
616
617/* Writing to /sys/../lineX will set the coresponding LCD line.
618 * - Excess characters are ignored.
619 * - If less characters are written than allowed, the remaining digits are
620 * unchanged.
621 * - The '\n' or '\t' char is a placeholder, it does not overwrite the
622 * original content.
623 */
624static ssize_t store_line(struct device *dev, const char *buf, size_t count,
625 int el, size_t len)
626{
627 struct yealink_dev *yld;
628 int i;
629
630 down_write(&sysfs_rwsema);
631 yld = dev_get_drvdata(dev);
632 if (yld == NULL) {
633 up_write(&sysfs_rwsema);
634 return -ENODEV;
635 }
636
637 if (len > count)
638 len = count;
639 for (i = 0; i < len; i++)
640 setChar(yld, el++, buf[i]);
641
642 up_write(&sysfs_rwsema);
643 return count;
644}
645
646static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
647 const char *buf, size_t count)
648{
649 return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
650}
651
652static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
653 const char *buf, size_t count)
654{
655 return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
656}
657
658static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
659 const char *buf, size_t count)
660{
661 return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
662}
663
664/* Interface to visible and audible "icons", these include:
665 * pictures on the LCD, the LED, and the dialtone signal.
666 */
667
668/* Get a list of "switchable elements" with their current state. */
669static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
670 char *buf)
671{
672 struct yealink_dev *yld;
673 int i, ret = 1;
674
675 down_read(&sysfs_rwsema);
676 yld = dev_get_drvdata(dev);
677 if (yld == NULL) {
678 up_read(&sysfs_rwsema);
679 return -ENODEV;
680 }
681
682 for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
683 if (lcdMap[i].type != '.')
684 continue;
685 ret += sprintf(&buf[ret], "%s %s\n",
686 yld->lcdMap[i] == ' ' ? " " : "on",
687 lcdMap[i].u.p.name);
688 }
689 up_read(&sysfs_rwsema);
690 return ret;
691}
692
693/* Change the visibility of a particular element. */
694static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
695 int chr)
696{
697 struct yealink_dev *yld;
698 int i;
699
700 down_write(&sysfs_rwsema);
701 yld = dev_get_drvdata(dev);
702 if (yld == NULL) {
703 up_write(&sysfs_rwsema);
704 return -ENODEV;
705 }
706
707 for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
708 if (lcdMap[i].type != '.')
709 continue;
710 if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
711 setChar(yld, i, chr);
712 break;
713 }
714 }
715
716 up_write(&sysfs_rwsema);
717 return count;
718}
719
720static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
721 const char *buf, size_t count)
722{
723 return set_icon(dev, buf, count, buf[0]);
724}
725
726static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
727 const char *buf, size_t count)
728{
729 return set_icon(dev, buf, count, ' ');
730}
731
732/* Upload a ringtone to the device.
733 */
734
735/* Stores raw ringtone data in the phone */
736static ssize_t store_ringtone(struct device *dev,
737 struct device_attribute *attr,
738 const char *buf, size_t count)
739{
740 struct yealink_dev *yld;
741
742 down_write(&sysfs_rwsema);
743 yld = dev_get_drvdata(dev);
744 if (yld == NULL) {
745 up_write(&sysfs_rwsema);
746 return -ENODEV;
747 }
748
749 /* TODO locking with async usb control interface??? */
750 yealink_set_ringtone(yld, (char *)buf, count);
751 up_write(&sysfs_rwsema);
752 return count;
753}
754
755#define _M444 S_IRUGO
756#define _M664 S_IRUGO|S_IWUSR|S_IWGRP
757#define _M220 S_IWUSR|S_IWGRP
758
759static DEVICE_ATTR(map_seg7 , _M664, show_map , store_map );
760static DEVICE_ATTR(line1 , _M664, show_line1 , store_line1 );
761static DEVICE_ATTR(line2 , _M664, show_line2 , store_line2 );
762static DEVICE_ATTR(line3 , _M664, show_line3 , store_line3 );
763static DEVICE_ATTR(get_icons , _M444, get_icons , NULL );
764static DEVICE_ATTR(show_icon , _M220, NULL , show_icon );
765static DEVICE_ATTR(hide_icon , _M220, NULL , hide_icon );
766static DEVICE_ATTR(ringtone , _M220, NULL , store_ringtone);
767
768static struct attribute *yld_attributes[] = {
769 &dev_attr_line1.attr,
770 &dev_attr_line2.attr,
771 &dev_attr_line3.attr,
772 &dev_attr_get_icons.attr,
773 &dev_attr_show_icon.attr,
774 &dev_attr_hide_icon.attr,
775 &dev_attr_map_seg7.attr,
776 &dev_attr_ringtone.attr,
777 NULL
778};
779
780static struct attribute_group yld_attr_group = {
781 .attrs = yld_attributes
782};
783
784/*******************************************************************************
785 * Linux interface and usb initialisation
786 ******************************************************************************/
787
788static const struct yld_device {
789 u16 idVendor;
790 u16 idProduct;
791 char *name;
792} yld_device[] = {
793 { 0x6993, 0xb001, "Yealink usb-p1k" },
794};
795
796static struct usb_device_id usb_table [] = {
797 { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) },
798 { }
799};
800
801static int usb_cleanup(struct yealink_dev *yld, int err)
802{
803 if (yld == NULL)
804 return err;
805
806 if (yld->urb_irq) {
807 usb_kill_urb(yld->urb_irq);
808 usb_free_urb(yld->urb_irq);
809 }
810 if (yld->urb_ctl)
811 usb_free_urb(yld->urb_ctl);
812 if (yld->idev.dev)
813 input_unregister_device(&yld->idev);
814 if (yld->ctl_req)
815 usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
816 yld->ctl_req, yld->ctl_req_dma);
817 if (yld->ctl_data)
818 usb_buffer_free(yld->udev, USB_PKT_LEN,
819 yld->ctl_data, yld->ctl_dma);
820 if (yld->irq_data)
821 usb_buffer_free(yld->udev, USB_PKT_LEN,
822 yld->irq_data, yld->irq_dma);
823 kfree(yld);
824 return err;
825}
826
827static void usb_disconnect(struct usb_interface *intf)
828{
829 struct yealink_dev *yld;
830
831 down_write(&sysfs_rwsema);
832 yld = usb_get_intfdata(intf);
833 sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
834 usb_set_intfdata(intf, NULL);
835 up_write(&sysfs_rwsema);
836
837 usb_cleanup(yld, 0);
838}
839
840static int usb_match(struct usb_device *udev)
841{
842 int i;
843 u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
844 u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
845
846 for (i = 0; i < ARRAY_SIZE(yld_device); i++) {
847 if ((idVendor == yld_device[i].idVendor) &&
848 (idProduct == yld_device[i].idProduct))
849 return i;
850 }
851 return -ENODEV;
852}
853
854static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
855{
856 struct usb_device *udev = interface_to_usbdev (intf);
857 struct usb_host_interface *interface;
858 struct usb_endpoint_descriptor *endpoint;
859 struct yealink_dev *yld;
860 char path[64];
861 int ret, pipe, i;
862
863 i = usb_match(udev);
864 if (i < 0)
865 return -ENODEV;
866
867 interface = intf->cur_altsetting;
868 endpoint = &interface->endpoint[0].desc;
869 if (!(endpoint->bEndpointAddress & 0x80))
870 return -EIO;
871 if ((endpoint->bmAttributes & 3) != 3)
872 return -EIO;
873
874 if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
875 return -ENOMEM;
876
877 memset(yld, 0, sizeof(*yld));
878 yld->udev = udev;
879
880 /* allocate usb buffers */
881 yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
882 SLAB_ATOMIC, &yld->irq_dma);
883 if (yld->irq_data == NULL)
884 return usb_cleanup(yld, -ENOMEM);
885
886 yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
887 SLAB_ATOMIC, &yld->ctl_dma);
888 if (!yld->ctl_data)
889 return usb_cleanup(yld, -ENOMEM);
890
891 yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
892 SLAB_ATOMIC, &yld->ctl_req_dma);
893 if (yld->ctl_req == NULL)
894 return usb_cleanup(yld, -ENOMEM);
895
896 /* allocate urb structures */
897 yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
898 if (yld->urb_irq == NULL)
899 return usb_cleanup(yld, -ENOMEM);
900
901 yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
902 if (yld->urb_ctl == NULL)
903 return usb_cleanup(yld, -ENOMEM);
904
905 /* get a handle to the interrupt data pipe */
906 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
907 ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
908 if (ret != USB_PKT_LEN)
909 err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
910
911 /* initialise irq urb */
912 usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
913 USB_PKT_LEN,
914 urb_irq_callback,
915 yld, endpoint->bInterval);
916 yld->urb_irq->transfer_dma = yld->irq_dma;
917 yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
918 yld->urb_irq->dev = udev;
919
920 /* initialise ctl urb */
921 yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
922 USB_DIR_OUT;
923 yld->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
924 yld->ctl_req->wValue = cpu_to_le16(0x200);
925 yld->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
926 yld->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
927
928 usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
929 (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
930 urb_ctl_callback, yld);
931 yld->urb_ctl->setup_dma = yld->ctl_req_dma;
932 yld->urb_ctl->transfer_dma = yld->ctl_dma;
933 yld->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
934 URB_NO_TRANSFER_DMA_MAP;
935 yld->urb_ctl->dev = udev;
936
937 /* find out the physical bus location */
938 if (usb_make_path(udev, path, sizeof(path)) > 0)
939 snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path);
940
941 /* register settings for the input device */
942 init_input_dev(&yld->idev);
943 yld->idev.private = yld;
944 yld->idev.id.bustype = BUS_USB;
945 yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
946 yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct);
947 yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
948 yld->idev.dev = &intf->dev;
949 yld->idev.name = yld_device[i].name;
950 yld->idev.phys = yld->phys;
951 /* yld->idev.event = input_ev; TODO */
952 yld->idev.open = input_open;
953 yld->idev.close = input_close;
954
955 /* register available key events */
956 yld->idev.evbit[0] = BIT(EV_KEY);
957 for (i = 0; i < 256; i++) {
958 int k = map_p1k_to_key(i);
959 if (k >= 0) {
960 set_bit(k & 0xff, yld->idev.keybit);
961 if (k >> 8)
962 set_bit(k >> 8, yld->idev.keybit);
963 }
964 }
965
966 printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
967
968 input_register_device(&yld->idev);
969
970 usb_set_intfdata(intf, yld);
971
972 /* clear visible elements */
973 for (i=0; i<ARRAY_SIZE(lcdMap); i++)
974 setChar(yld, i, ' ');
975
976 /* display driver version on LCD line 3 */
977 store_line3(&intf->dev, NULL,
978 DRIVER_VERSION, sizeof(DRIVER_VERSION));
979
980 /* Register sysfs hooks (don't care about failure) */
981 sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
982 return 0;
983}
984
985static struct usb_driver yealink_driver = {
986 .owner = THIS_MODULE,
987 .name = "yealink",
988 .probe = usb_probe,
989 .disconnect = usb_disconnect,
990 .id_table = usb_table,
991};
992
993static int __init yealink_dev_init(void)
994{
995 int ret = usb_register(&yealink_driver);
996 if (ret == 0)
997 info(DRIVER_DESC ":" DRIVER_VERSION);
998 return ret;
999}
1000
1001static void __exit yealink_dev_exit(void)
1002{
1003 usb_deregister(&yealink_driver);
1004}
1005
1006module_init(yealink_dev_init);
1007module_exit(yealink_dev_exit);
1008
1009MODULE_DEVICE_TABLE (usb, usb_table);
1010
1011MODULE_AUTHOR(DRIVER_AUTHOR);
1012MODULE_DESCRIPTION(DRIVER_DESC);
1013MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/yealink.h b/drivers/usb/input/yealink.h
new file mode 100644
index 000000000000..48af0be9cbdf
--- /dev/null
+++ b/drivers/usb/input/yealink.h
@@ -0,0 +1,220 @@
1/*
2 * drivers/usb/input/yealink.h
3 *
4 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
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 as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef INPUT_YEALINK_H
22#define INPUT_YEALINK_H
23
24/* Using the control channel on interface 3 various aspects of the phone
25 * can be controlled like LCD, LED, dialtone and the ringtone.
26 */
27
28struct yld_ctl_packet {
29 u8 cmd; /* command code, see below */
30 u8 size; /* 1-11, size of used data bytes. */
31 u16 offset; /* internal packet offset */
32 u8 data[11];
33 s8 sum; /* negative sum of 15 preceding bytes */
34} __attribute__ ((packed));
35
36#define USB_PKT_LEN sizeof(struct yld_ctl_packet)
37
38/* The following yld_ctl_packet's are available: */
39
40/* Init registers
41 *
42 * cmd 0x8e
43 * size 10
44 * offset 0
45 * data 0,0,0,0....
46 */
47#define CMD_INIT 0x8e
48
49/* Request key scan
50 *
51 * cmd 0x80
52 * size 1
53 * offset 0
54 * data[0] on return returns the key number, if it changes there's a new
55 * key pressed.
56 */
57#define CMD_KEYPRESS 0x80
58
59/* Request scancode
60 *
61 * cmd 0x81
62 * size 1
63 * offset key number [0-1f]
64 * data[0] on return returns the scancode
65 */
66#define CMD_SCANCODE 0x81
67
68/* Set LCD
69 *
70 * cmd 0x04
71 * size 1-11
72 * offset 0-23
73 * data segment bits
74 */
75#define CMD_LCD 0x04
76
77/* Set led
78 *
79 * cmd 0x05
80 * size 1
81 * offset 0
82 * data[0] 0 OFF / 1 ON
83 */
84#define CMD_LED 0x05
85
86/* Set ringtone volume
87 *
88 * cmd 0x11
89 * size 1
90 * offset 0
91 * data[0] 0-0xff volume
92 */
93#define CMD_RING_VOLUME 0x11
94
95/* Set ringtone notes
96 *
97 * cmd 0x02
98 * size 1-11
99 * offset 0->
100 * data binary representation LE16(-freq), LE16(duration) ....
101 */
102#define CMD_RING_NOTE 0x02
103
104/* Sound ringtone via the speaker on the back
105 *
106 * cmd 0x03
107 * size 1
108 * offset 0
109 * data[0] 0 OFF / 0x24 ON
110 */
111#define CMD_RINGTONE 0x03
112
113/* Sound dial tone via the ear speaker
114 *
115 * cmd 0x09
116 * size 1
117 * offset 0
118 * data[0] 0 OFF / 1 ON
119 */
120#define CMD_DIALTONE 0x09
121
122#endif /* INPUT_YEALINK_H */
123
124
125#if defined(_SEG) && defined(_PIC)
126/* This table maps the LCD segments onto individual bit positions in the
127 * yld_status struct.
128 */
129
130/* LCD, each segment must be driven seperately.
131 *
132 * Layout:
133 *
134 * |[] [][] [][] [][] in |[][]
135 * |[] M [][] D [][] : [][] out |[][]
136 * store
137 *
138 * NEW REP SU MO TU WE TH FR SA
139 *
140 * [] [] [] [] [] [] [] [] [] [] [] []
141 * [] [] [] [] [] [] [] [] [] [] [] []
142 */
143
144/* Line 1
145 * Format : 18.e8.M8.88...188
146 * Icon names : M D : IN OUT STORE
147 */
148#define LCD_LINE1_OFFSET 0
149#define LCD_LINE1_SIZE 17
150
151/* Note: first g then f => ! ! */
152/* _SEG( type a b c d e g f ) */
153 _SEG('1', 0,0 , 22,2 , 22,2 , 0,0 , 0,0 , 0,0 , 0,0 ),
154 _SEG('8', 20,1 , 20,2 , 20,4 , 20,8 , 21,4 , 21,2 , 21,1 ),
155 _PIC('.', 22,1 , "M" ),
156 _SEG('e', 18,1 , 18,2 , 18,4 , 18,1 , 19,2 , 18,1 , 19,1 ),
157 _SEG('8', 16,1 , 16,2 , 16,4 , 16,8 , 17,4 , 17,2 , 17,1 ),
158 _PIC('.', 15,8 , "D" ),
159 _SEG('M', 14,1 , 14,2 , 14,4 , 14,1 , 15,4 , 15,2 , 15,1 ),
160 _SEG('8', 12,1 , 12,2 , 12,4 , 12,8 , 13,4 , 13,2 , 13,1 ),
161 _PIC('.', 11,8 , ":" ),
162 _SEG('8', 10,1 , 10,2 , 10,4 , 10,8 , 11,4 , 11,2 , 11,1 ),
163 _SEG('8', 8,1 , 8,2 , 8,4 , 8,8 , 9,4 , 9,2 , 9,1 ),
164 _PIC('.', 7,1 , "IN" ),
165 _PIC('.', 7,2 , "OUT" ),
166 _PIC('.', 7,4 , "STORE" ),
167 _SEG('1', 0,0 , 5,1 , 5,1 , 0,0 , 0,0 , 0,0 , 0,0 ),
168 _SEG('8', 4,1 , 4,2 , 4,4 , 4,8 , 5,8 , 5,4 , 5,2 ),
169 _SEG('8', 2,1 , 2,2 , 2,4 , 2,8 , 3,4 , 3,2 , 3,1 ),
170
171/* Line 2
172 * Format : .........
173 * Pict. name : NEW REP SU MO TU WE TH FR SA
174 */
175#define LCD_LINE2_OFFSET LCD_LINE1_OFFSET + LCD_LINE1_SIZE
176#define LCD_LINE2_SIZE 9
177
178 _PIC('.', 23,2 , "NEW" ),
179 _PIC('.', 23,4 , "REP" ),
180 _PIC('.', 1,8 , "SU" ),
181 _PIC('.', 1,4 , "MO" ),
182 _PIC('.', 1,2 , "TU" ),
183 _PIC('.', 1,1 , "WE" ),
184 _PIC('.', 0,1 , "TH" ),
185 _PIC('.', 0,2 , "FR" ),
186 _PIC('.', 0,4 , "SA" ),
187
188/* Line 3
189 * Format : 888888888888
190 */
191#define LCD_LINE3_OFFSET LCD_LINE2_OFFSET + LCD_LINE2_SIZE
192#define LCD_LINE3_SIZE 12
193
194 _SEG('8', 22,16, 22,32, 22,64, 22,128, 23,128, 23,64, 23,32 ),
195 _SEG('8', 20,16, 20,32, 20,64, 20,128, 21,128, 21,64, 21,32 ),
196 _SEG('8', 18,16, 18,32, 18,64, 18,128, 19,128, 19,64, 19,32 ),
197 _SEG('8', 16,16, 16,32, 16,64, 16,128, 17,128, 17,64, 17,32 ),
198 _SEG('8', 14,16, 14,32, 14,64, 14,128, 15,128, 15,64, 15,32 ),
199 _SEG('8', 12,16, 12,32, 12,64, 12,128, 13,128, 13,64, 13,32 ),
200 _SEG('8', 10,16, 10,32, 10,64, 10,128, 11,128, 11,64, 11,32 ),
201 _SEG('8', 8,16, 8,32, 8,64, 8,128, 9,128, 9,64, 9,32 ),
202 _SEG('8', 6,16, 6,32, 6,64, 6,128, 7,128, 7,64, 7,32 ),
203 _SEG('8', 4,16, 4,32, 4,64, 4,128, 5,128, 5,64, 5,32 ),
204 _SEG('8', 2,16, 2,32, 2,64, 2,128, 3,128, 3,64, 3,32 ),
205 _SEG('8', 0,16, 0,32, 0,64, 0,128, 1,128, 1,64, 1,32 ),
206
207/* Line 4
208 *
209 * The LED, DIALTONE and RINGTONE are implemented as icons and use the same
210 * sysfs interface.
211 */
212#define LCD_LINE4_OFFSET LCD_LINE3_OFFSET + LCD_LINE3_SIZE
213
214 _PIC('.', offsetof(struct yld_status, led) , 0x01, "LED" ),
215 _PIC('.', offsetof(struct yld_status, dialtone) , 0x01, "DIALTONE" ),
216 _PIC('.', offsetof(struct yld_status, ringtone) , 0x24, "RINGTONE" ),
217
218#undef _SEG
219#undef _PIC
220#endif /* _SEG && _PIC */
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 6f7994f5a714..ae4681f9f0ea 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -426,7 +426,7 @@ static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb)
426 426
427/* cancel an urb which is submitted to the chain 427/* cancel an urb which is submitted to the chain
428 the result is 0 if the urb is cancelled, or -EINPROGRESS if 428 the result is 0 if the urb is cancelled, or -EINPROGRESS if
429 URB_ASYNC_UNLINK is set and the function is successfully started. 429 the function is successfully started.
430*/ 430*/
431static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) 431static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
432{ 432{
@@ -515,7 +515,6 @@ static void auerchain_unlink_all (pauerchain_t acp)
515 acep = acp->active; 515 acep = acp->active;
516 if (acep) { 516 if (acep) {
517 urbp = acep->urbp; 517 urbp = acep->urbp;
518 urbp->transfer_flags &= ~URB_ASYNC_UNLINK;
519 dbg ("unlink active urb"); 518 dbg ("unlink active urb");
520 usb_kill_urb (urbp); 519 usb_kill_urb (urbp);
521 } 520 }
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index ad17892aac9e..7e93ac96490f 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
464 actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size)); 464 actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
465 bytes_to_read = min(count, *actual_buffer); 465 bytes_to_read = min(count, *actual_buffer);
466 if (bytes_to_read < *actual_buffer) 466 if (bytes_to_read < *actual_buffer)
467 dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n", 467 dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n",
468 *actual_buffer-bytes_to_read); 468 *actual_buffer-bytes_to_read);
469 469
470 /* copy one interrupt_in_buffer from ring_buffer into userspace */ 470 /* copy one interrupt_in_buffer from ring_buffer into userspace */
@@ -528,8 +528,8 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
528 /* write the data into interrupt_out_buffer from userspace */ 528 /* write the data into interrupt_out_buffer from userspace */
529 bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); 529 bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
530 if (bytes_to_write < count) 530 if (bytes_to_write < count)
531 dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write); 531 dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
532 dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write); 532 dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write);
533 533
534 if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { 534 if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
535 retval = -EFAULT; 535 retval = -EFAULT;
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 2fd12264fd53..d63ce6c030f3 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -229,7 +229,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe,
229 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len, 229 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
230 sisusb_bulk_completeout, &sisusb->urbout_context[index]); 230 sisusb_bulk_completeout, &sisusb->urbout_context[index]);
231 231
232 urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK); 232 urb->transfer_flags |= tflags;
233 urb->actual_length = 0; 233 urb->actual_length = 0;
234 234
235 if ((urb->transfer_dma = transfer_dma)) 235 if ((urb->transfer_dma = transfer_dma))
@@ -295,7 +295,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data,
295 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len, 295 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
296 sisusb_bulk_completein, sisusb); 296 sisusb_bulk_completein, sisusb);
297 297
298 urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK); 298 urb->transfer_flags |= tflags;
299 urb->actual_length = 0; 299 urb->actual_length = 0;
300 300
301 if ((urb->transfer_dma = transfer_dma)) 301 if ((urb->transfer_dma = transfer_dma))
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index fd7fb98e4b20..54799eb0bc60 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -986,7 +986,6 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param)
986 986
987 u->context = &context; 987 u->context = &context;
988 u->complete = ctrl_complete; 988 u->complete = ctrl_complete;
989 u->transfer_flags |= URB_ASYNC_UNLINK;
990 } 989 }
991 990
992 /* queue the urbs */ 991 /* queue the urbs */
@@ -1052,7 +1051,6 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
1052 urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size); 1051 urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size);
1053 if (!urb) 1052 if (!urb)
1054 return -ENOMEM; 1053 return -ENOMEM;
1055 urb->transfer_flags |= URB_ASYNC_UNLINK;
1056 urb->context = &completion; 1054 urb->context = &completion;
1057 urb->complete = unlink1_callback; 1055 urb->complete = unlink1_callback;
1058 1056
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
index b0015b8a1d1f..3cf3ea3a88ed 100644
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -2,7 +2,7 @@
2# Makefile for USB Core files and filesystem 2# Makefile for USB Core files and filesystem
3# 3#
4 4
5usbmon-objs := mon_main.o mon_stat.o mon_text.o 5usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_dma.o
6 6
7# This does not use CONFIG_USB_MON because we want this to use a tristate. 7# This does not use CONFIG_USB_MON because we want this to use a tristate.
8obj-$(CONFIG_USB) += usbmon.o 8obj-$(CONFIG_USB) += usbmon.o
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c
new file mode 100644
index 000000000000..0a1367b760a0
--- /dev/null
+++ b/drivers/usb/mon/mon_dma.c
@@ -0,0 +1,55 @@
1/*
2 * The USB Monitor, inspired by Dave Harding's USBMon.
3 *
4 * mon_dma.c: Library which snoops on DMA areas.
5 *
6 * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
7 */
8#include <linux/kernel.h>
9#include <linux/list.h>
10#include <linux/highmem.h>
11#include <asm/page.h>
12
13#include <linux/usb.h> /* Only needed for declarations in usb_mon.h */
14#include "usb_mon.h"
15
16#ifdef __i386__ /* CONFIG_ARCH_I386 does not exit */
17#define MON_HAS_UNMAP 1
18
19#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT)
20
21char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
22{
23 struct page *pg;
24 unsigned long flags;
25 unsigned char *map;
26 unsigned char *ptr;
27
28 /*
29 * On i386, a DMA handle is the "physical" address of a page.
30 * In other words, the bus address is equal to physical address.
31 * There is no IOMMU.
32 */
33 pg = phys_to_page(dma_addr);
34
35 /*
36 * We are called from hardware IRQs in case of callbacks.
37 * But we can be called from softirq or process context in case
38 * of submissions. In such case, we need to protect KM_IRQ0.
39 */
40 local_irq_save(flags);
41 map = kmap_atomic(pg, KM_IRQ0);
42 ptr = map + (dma_addr & (PAGE_SIZE-1));
43 memcpy(dst, ptr, len);
44 kunmap_atomic(map, KM_IRQ0);
45 local_irq_restore(flags);
46 return 0;
47}
48#endif /* __i386__ */
49
50#ifndef MON_HAS_UNMAP
51char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
52{
53 return 'D';
54}
55#endif
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 26266b30028e..417464dea9f6 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -91,25 +91,11 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
91 int len, char ev_type) 91 int len, char ev_type)
92{ 92{
93 int pipe = urb->pipe; 93 int pipe = urb->pipe;
94 unsigned char *data;
95
96 /*
97 * The check to see if it's safe to poke at data has an enormous
98 * number of corner cases, but it seems that the following is
99 * more or less safe.
100 *
101 * We do not even try to look transfer_buffer, because it can
102 * contain non-NULL garbage in case the upper level promised to
103 * set DMA for the HCD.
104 */
105 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
106 return 'D';
107 94
108 if (len <= 0) 95 if (len <= 0)
109 return 'L'; 96 return 'L';
110 97 if (len >= DATA_MAX)
111 if ((data = urb->transfer_buffer) == NULL) 98 len = DATA_MAX;
112 return 'Z'; /* '0' would be not as pretty. */
113 99
114 /* 100 /*
115 * Bulk is easy to shortcut reliably. 101 * Bulk is easy to shortcut reliably.
@@ -126,8 +112,21 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
126 } 112 }
127 } 113 }
128 114
129 if (len >= DATA_MAX) 115 /*
130 len = DATA_MAX; 116 * The check to see if it's safe to poke at data has an enormous
117 * number of corner cases, but it seems that the following is
118 * more or less safe.
119 *
120 * We do not even try to look transfer_buffer, because it can
121 * contain non-NULL garbage in case the upper level promised to
122 * set DMA for the HCD.
123 */
124 if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
125 return mon_dmapeek(ep->data, urb->transfer_dma, len);
126
127 if (urb->transfer_buffer == NULL)
128 return 'Z'; /* '0' would be not as pretty. */
129
131 memcpy(ep->data, urb->transfer_buffer, len); 130 memcpy(ep->data, urb->transfer_buffer, len);
132 return 0; 131 return 0;
133} 132}
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index 9b06784d2c48..4be0f9346071 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -45,6 +45,10 @@ struct mon_reader {
45void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); 45void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r);
46void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); 46void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
47 47
48/*
49 */
50extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len);
51
48extern struct semaphore mon_lock; 52extern struct semaphore mon_lock;
49 53
50extern struct file_operations mon_fops_text; 54extern struct file_operations mon_fops_text;
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index b104430e2c6a..8c010bb44eb8 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -99,7 +99,7 @@ config USB_USBNET
99 with "minidrivers" built around a common network driver core 99 with "minidrivers" built around a common network driver core
100 that supports deep queues for efficient transfers. (This gives 100 that supports deep queues for efficient transfers. (This gives
101 better performance with small packets and at high speeds). 101 better performance with small packets and at high speeds).
102 102
103 The USB host runs "usbnet", and the other end of the link might be: 103 The USB host runs "usbnet", and the other end of the link might be:
104 104
105 - Another USB host, when using USB "network" or "data transfer" 105 - Another USB host, when using USB "network" or "data transfer"
@@ -125,38 +125,63 @@ config USB_USBNET
125 To compile this driver as a module, choose M here: the 125 To compile this driver as a module, choose M here: the
126 module will be called usbnet. 126 module will be called usbnet.
127 127
128comment "USB Host-to-Host Cables" 128config USB_NET_AX8817X
129 depends on USB_USBNET 129 tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
130 130 depends on USB_USBNET && NET_ETHERNET
131config USB_ALI_M5632 131 select CRC32
132 boolean "ALi M5632 based 'USB 2.0 Data Link' cables" 132 select MII
133 depends on USB_USBNET
134 default y 133 default y
135 help 134 help
136 Choose this option if you're using a host-to-host cable 135 This option adds support for ASIX AX88xxx based USB 2.0
137 based on this design, which supports USB 2.0 high speed. 136 10/100 Ethernet adapters.
138 137
139config USB_AN2720 138 This driver should work with at least the following devices:
140 boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)" 139 * Aten UC210T
141 depends on USB_USBNET 140 * ASIX AX88172
142 default y 141 * Billionton Systems, USB2AR
143 help 142 * Buffalo LUA-U2-KTX
144 Choose this option if you're using a host-to-host cable 143 * Corega FEther USB2-TX
145 based on this design. Note that AnchorChips is now a 144 * D-Link DUB-E100
146 Cypress brand. 145 * Hawking UF200
146 * Linksys USB200M
147 * Netgear FA120
148 * Sitecom LN-029
149 * Intellinet USB 2.0 Ethernet
150 * ST Lab USB 2.0 Ethernet
151 * TrendNet TU2-ET100
147 152
148config USB_BELKIN 153 This driver creates an interface named "ethX", where X depends on
149 boolean "eTEK based host-to-host cables (Advance, Belkin, ...)" 154 what other networking devices you have in use.
155
156
157config USB_NET_CDCETHER
158 tristate "CDC Ethernet support (smart devices such as cable modems)"
150 depends on USB_USBNET 159 depends on USB_USBNET
151 default y 160 default y
152 help 161 help
153 Choose this option if you're using a host-to-host cable 162 This option supports devices conforming to the Communication Device
154 based on this design: two NetChip 2890 chips and an Atmel 163 Class (CDC) Ethernet Control Model, a specification that's easy to
155 microcontroller, with LEDs that indicate traffic. 164 implement in device firmware. The CDC specifications are available
165 from <http://www.usb.org/>.
156 166
157config USB_GENESYS 167 CDC Ethernet is an implementation option for DOCSIS cable modems
158 boolean "GeneSys GL620USB-A based cables" 168 that support USB connectivity, used for non-Microsoft USB hosts.
159 default y 169 The Linux-USB CDC Ethernet Gadget driver is an open implementation.
170 This driver should work with at least the following devices:
171
172 * Ericsson PipeRider (all variants)
173 * Motorola (DM100 and SB4100)
174 * Broadcom Cable Modem (reference design)
175 * Toshiba PCX1100U
176 * ...
177
178 This driver creates an interface named "ethX", where X depends on
179 what other networking devices you have in use. However, if the
180 IEEE 802 "local assignment" bit is set in the address, a "usbX"
181 name is used instead.
182
183config USB_NET_GL620A
184 tristate "GeneSys GL620USB-A based cables"
160 depends on USB_USBNET 185 depends on USB_USBNET
161 help 186 help
162 Choose this option if you're using a host-to-host cable, 187 Choose this option if you're using a host-to-host cable,
@@ -164,38 +189,78 @@ config USB_GENESYS
164 189
165 Note that the half-duplex "GL620USB" is not supported. 190 Note that the half-duplex "GL620USB" is not supported.
166 191
167config USB_NET1080 192config USB_NET_NET1080
168 boolean "NetChip 1080 based cables (Laplink, ...)" 193 tristate "NetChip 1080 based cables (Laplink, ...)"
169 default y 194 default y
170 depends on USB_USBNET 195 depends on USB_USBNET
171 help 196 help
172 Choose this option if you're using a host-to-host cable based 197 Choose this option if you're using a host-to-host cable based
173 on this design: one NetChip 1080 chips and supporting logic, 198 on this design: one NetChip 1080 chip and supporting logic,
174 supporting LEDs that indicate traffic 199 optionally with LEDs that indicate traffic
175 200
176config USB_PL2301 201config USB_NET_PLUSB
177 boolean "Prolific PL-2301/2302 based cables" 202 tristate "Prolific PL-2301/2302 based cables"
178 default y 203 # if the handshake/init/reset problems, from original 'plusb',
179 # handshake/init/reset problems, from original 'plusb' driver 204 # are ever resolved ... then remove "experimental"
180 depends on USB_USBNET && EXPERIMENTAL 205 depends on USB_USBNET && EXPERIMENTAL
181 help 206 help
182 Choose this option if you're using a host-to-host cable 207 Choose this option if you're using a host-to-host cable
183 with one of these chips. 208 with one of these chips.
184 209
185config USB_KC2190 210config USB_NET_RNDIS_HOST
186 boolean "KT Technology KC2190 based cables (InstaNet)" 211 tristate "Host for RNDIS devices (EXPERIMENTAL)"
187 default y
188 depends on USB_USBNET && EXPERIMENTAL 212 depends on USB_USBNET && EXPERIMENTAL
213 select USB_NET_CDCETHER
189 help 214 help
190 Choose this option if you're using a host-to-host cable 215 This option enables hosting "Remote NDIS" USB networking links,
191 with one of these chips. 216 as encouraged by Microsoft (instead of CDC Ethernet!) for use in
217 various devices that may only support this protocol.
192 218
193comment "Intelligent USB Devices/Gadgets" 219 Avoid using this protocol unless you have no better options.
220 The protocol specification is incomplete, and is controlled by
221 (and for) Microsoft; it isn't an "Open" ecosystem or market.
222
223config USB_NET_CDC_SUBSET
224 tristate "Simple USB Network Links (CDC Ethernet subset)"
194 depends on USB_USBNET 225 depends on USB_USBNET
226 help
227 This driver module supports USB network devices that can work
228 without any device-specific information. Select it if you have
229 one of these drivers.
230
231 Note that while many USB host-to-host cables can work in this mode,
232 that may mean not being able to talk to Win32 systems or more
233 commonly not being able to handle certain events (like replugging
234 the host on the other end) very well. Also, these devices will
235 not generally have permanently assigned Ethernet addresses.
236
237config USB_ALI_M5632
238 boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
239 depends on USB_NET_CDC_SUBSET
240 help
241 Choose this option if you're using a host-to-host cable
242 based on this design, which supports USB 2.0 high speed.
243
244config USB_AN2720
245 boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
246 depends on USB_NET_CDC_SUBSET
247 help
248 Choose this option if you're using a host-to-host cable
249 based on this design. Note that AnchorChips is now a
250 Cypress brand.
251
252config USB_BELKIN
253 boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
254 depends on USB_NET_CDC_SUBSET
255 default y
256 help
257 Choose this option if you're using a host-to-host cable
258 based on this design: two NetChip 2890 chips and an Atmel
259 microcontroller, with LEDs that indicate traffic.
195 260
196config USB_ARMLINUX 261config USB_ARMLINUX
197 boolean "Embedded ARM Linux links (iPaq, ...)" 262 boolean "Embedded ARM Linux links (iPaq, ...)"
198 depends on USB_USBNET 263 depends on USB_NET_CDC_SUBSET
199 default y 264 default y
200 help 265 help
201 Choose this option to support the "usb-eth" networking driver 266 Choose this option to support the "usb-eth" networking driver
@@ -212,15 +277,15 @@ config USB_ARMLINUX
212 277
213config USB_EPSON2888 278config USB_EPSON2888
214 boolean "Epson 2888 based firmware (DEVELOPMENT)" 279 boolean "Epson 2888 based firmware (DEVELOPMENT)"
215 depends on USB_USBNET 280 depends on USB_NET_CDC_SUBSET
216 default y
217 help 281 help
218 Choose this option to support the usb networking links used 282 Choose this option to support the usb networking links used
219 by some sample firmware from Epson. 283 by some sample firmware from Epson.
220 284
221config USB_ZAURUS 285config USB_NET_ZAURUS
222 boolean "Sharp Zaurus (stock ROMs) and compatible" 286 tristate "Sharp Zaurus (stock ROMs) and compatible"
223 depends on USB_USBNET 287 depends on USB_USBNET
288 select USB_NET_CDCETHER
224 select CRC32 289 select CRC32
225 default y 290 default y
226 help 291 help
@@ -235,61 +300,6 @@ config USB_ZAURUS
235 really need this non-conformant variant of CDC Ethernet (or in 300 really need this non-conformant variant of CDC Ethernet (or in
236 some cases CDC MDLM) protocol, not "g_ether". 301 some cases CDC MDLM) protocol, not "g_ether".
237 302
238config USB_CDCETHER
239 boolean "CDC Ethernet support (smart devices such as cable modems)"
240 depends on USB_USBNET
241 default y
242 help
243 This option supports devices conforming to the Communication Device
244 Class (CDC) Ethernet Control Model, a specification that's easy to
245 implement in device firmware. The CDC specifications are available
246 from <http://www.usb.org/>.
247
248 CDC Ethernet is an implementation option for DOCSIS cable modems
249 that support USB connectivity, used for non-Microsoft USB hosts.
250 This driver should work with at least the following devices:
251
252 * Ericsson PipeRider (all variants)
253 * Motorola (DM100 and SB4100)
254 * Broadcom Cable Modem (reference design)
255 * Toshiba PCX1100U
256 * ...
257
258 This driver creates an interface named "ethX", where X depends on
259 what other networking devices you have in use. However, if the
260 IEEE 802 "local assignment" bit is set in the address, a "usbX"
261 name is used instead.
262
263comment "USB Network Adapters"
264 depends on USB_USBNET
265
266config USB_AX8817X
267 boolean "ASIX AX88xxx Based USB 2.0 Ethernet Devices"
268 depends on USB_USBNET && NET_ETHERNET
269 select CRC32
270 select MII
271 default y
272 help
273 This option adds support for ASIX AX88xxx based USB 2.0
274 10/100 Ethernet devices.
275
276 This driver should work with at least the following devices:
277 * Aten UC210T
278 * ASIX AX88172
279 * Billionton Systems, USB2AR
280 * Buffalo LUA-U2-KTX
281 * Corega FEther USB2-TX
282 * D-Link DUB-E100
283 * Hawking UF200
284 * Linksys USB200M
285 * Netgear FA120
286 * Sitecom LN-029
287 * Intellinet USB 2.0 Ethernet
288 * ST Lab USB 2.0 Ethernet
289 * TrendNet TU2-ET100
290
291 This driver creates an interface named "ethX", where X depends on
292 what other networking devices you have in use.
293 303
294config USB_ZD1201 304config USB_ZD1201
295 tristate "USB ZD1201 based Wireless device support" 305 tristate "USB ZD1201 based Wireless device support"
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index fe3fd4115e1e..222c0495f791 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -6,5 +6,13 @@ obj-$(CONFIG_USB_CATC) += catc.o
6obj-$(CONFIG_USB_KAWETH) += kaweth.o 6obj-$(CONFIG_USB_KAWETH) += kaweth.o
7obj-$(CONFIG_USB_PEGASUS) += pegasus.o 7obj-$(CONFIG_USB_PEGASUS) += pegasus.o
8obj-$(CONFIG_USB_RTL8150) += rtl8150.o 8obj-$(CONFIG_USB_RTL8150) += rtl8150.o
9obj-$(CONFIG_USB_NET_AX8817X) += asix.o
10obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
11obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
12obj-$(CONFIG_USB_NET_NET1080) += net1080.o
13obj-$(CONFIG_USB_NET_PLUSB) += plusb.o
14obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
15obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
16obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
9obj-$(CONFIG_USB_USBNET) += usbnet.o 17obj-$(CONFIG_USB_USBNET) += usbnet.o
10obj-$(CONFIG_USB_ZD1201) += zd1201.o 18obj-$(CONFIG_USB_ZD1201) += zd1201.o
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
new file mode 100644
index 000000000000..861f00a43750
--- /dev/null
+++ b/drivers/usb/net/asix.c
@@ -0,0 +1,948 @@
1/*
2 * ASIX AX8817X based USB 2.0 Ethernet Devices
3 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
4 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
5 * Copyright (c) 2002-2003 TiVo Inc.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22// #define DEBUG // error path messages, extra info
23// #define VERBOSE // more; success messages
24
25#include <linux/config.h>
26#ifdef CONFIG_USB_DEBUG
27# define DEBUG
28#endif
29#include <linux/module.h>
30#include <linux/kmod.h>
31#include <linux/sched.h>
32#include <linux/init.h>
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/ethtool.h>
36#include <linux/workqueue.h>
37#include <linux/mii.h>
38#include <linux/usb.h>
39#include <linux/crc32.h>
40
41#include "usbnet.h"
42
43
44/* ASIX AX8817X based USB 2.0 Ethernet Devices */
45
46#define AX_CMD_SET_SW_MII 0x06
47#define AX_CMD_READ_MII_REG 0x07
48#define AX_CMD_WRITE_MII_REG 0x08
49#define AX_CMD_SET_HW_MII 0x0a
50#define AX_CMD_READ_EEPROM 0x0b
51#define AX_CMD_WRITE_EEPROM 0x0c
52#define AX_CMD_WRITE_ENABLE 0x0d
53#define AX_CMD_WRITE_DISABLE 0x0e
54#define AX_CMD_WRITE_RX_CTL 0x10
55#define AX_CMD_READ_IPG012 0x11
56#define AX_CMD_WRITE_IPG0 0x12
57#define AX_CMD_WRITE_IPG1 0x13
58#define AX_CMD_WRITE_IPG2 0x14
59#define AX_CMD_WRITE_MULTI_FILTER 0x16
60#define AX_CMD_READ_NODE_ID 0x17
61#define AX_CMD_READ_PHY_ID 0x19
62#define AX_CMD_READ_MEDIUM_STATUS 0x1a
63#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
64#define AX_CMD_READ_MONITOR_MODE 0x1c
65#define AX_CMD_WRITE_MONITOR_MODE 0x1d
66#define AX_CMD_WRITE_GPIOS 0x1f
67#define AX_CMD_SW_RESET 0x20
68#define AX_CMD_SW_PHY_STATUS 0x21
69#define AX_CMD_SW_PHY_SELECT 0x22
70#define AX88772_CMD_READ_NODE_ID 0x13
71
72#define AX_MONITOR_MODE 0x01
73#define AX_MONITOR_LINK 0x02
74#define AX_MONITOR_MAGIC 0x04
75#define AX_MONITOR_HSFS 0x10
76
77/* AX88172 Medium Status Register values */
78#define AX_MEDIUM_FULL_DUPLEX 0x02
79#define AX_MEDIUM_TX_ABORT_ALLOW 0x04
80#define AX_MEDIUM_FLOW_CONTROL_EN 0x10
81
82#define AX_MCAST_FILTER_SIZE 8
83#define AX_MAX_MCAST 64
84
85#define AX_EEPROM_LEN 0x40
86
87#define AX_SWRESET_CLEAR 0x00
88#define AX_SWRESET_RR 0x01
89#define AX_SWRESET_RT 0x02
90#define AX_SWRESET_PRTE 0x04
91#define AX_SWRESET_PRL 0x08
92#define AX_SWRESET_BZ 0x10
93#define AX_SWRESET_IPRL 0x20
94#define AX_SWRESET_IPPD 0x40
95
96#define AX88772_IPG0_DEFAULT 0x15
97#define AX88772_IPG1_DEFAULT 0x0c
98#define AX88772_IPG2_DEFAULT 0x12
99
100#define AX88772_MEDIUM_FULL_DUPLEX 0x0002
101#define AX88772_MEDIUM_RESERVED 0x0004
102#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010
103#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020
104#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080
105#define AX88772_MEDIUM_RX_ENABLE 0x0100
106#define AX88772_MEDIUM_100MB 0x0200
107#define AX88772_MEDIUM_DEFAULT \
108 (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
109 AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
110 AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
111
112#define AX_EEPROM_MAGIC 0xdeadbeef
113
114/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
115struct ax8817x_data {
116 u8 multi_filter[AX_MCAST_FILTER_SIZE];
117};
118
119struct ax88172_int_data {
120 u16 res1;
121 u8 link;
122 u16 res2;
123 u8 status;
124 u16 res3;
125} __attribute__ ((packed));
126
127static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
128 u16 size, void *data)
129{
130 return usb_control_msg(
131 dev->udev,
132 usb_rcvctrlpipe(dev->udev, 0),
133 cmd,
134 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
135 value,
136 index,
137 data,
138 size,
139 USB_CTRL_GET_TIMEOUT);
140}
141
142static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
143 u16 size, void *data)
144{
145 return usb_control_msg(
146 dev->udev,
147 usb_sndctrlpipe(dev->udev, 0),
148 cmd,
149 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
150 value,
151 index,
152 data,
153 size,
154 USB_CTRL_SET_TIMEOUT);
155}
156
157static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
158{
159 struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
160
161 if (urb->status < 0)
162 printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
163 urb->status);
164
165 kfree(req);
166 usb_free_urb(urb);
167}
168
169static void ax8817x_status(struct usbnet *dev, struct urb *urb)
170{
171 struct ax88172_int_data *event;
172 int link;
173
174 if (urb->actual_length < 8)
175 return;
176
177 event = urb->transfer_buffer;
178 link = event->link & 0x01;
179 if (netif_carrier_ok(dev->net) != link) {
180 if (link) {
181 netif_carrier_on(dev->net);
182 usbnet_defer_kevent (dev, EVENT_LINK_RESET );
183 } else
184 netif_carrier_off(dev->net);
185 devdbg(dev, "ax8817x - Link Status is: %d", link);
186 }
187}
188
189static void
190ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
191 u16 size, void *data)
192{
193 struct usb_ctrlrequest *req;
194 int status;
195 struct urb *urb;
196
197 if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
198 devdbg(dev, "Error allocating URB in write_cmd_async!");
199 return;
200 }
201
202 if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
203 deverr(dev, "Failed to allocate memory for control request");
204 usb_free_urb(urb);
205 return;
206 }
207
208 req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
209 req->bRequest = cmd;
210 req->wValue = cpu_to_le16(value);
211 req->wIndex = cpu_to_le16(index);
212 req->wLength = cpu_to_le16(size);
213
214 usb_fill_control_urb(urb, dev->udev,
215 usb_sndctrlpipe(dev->udev, 0),
216 (void *)req, data, size,
217 ax8817x_async_cmd_callback, req);
218
219 if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
220 deverr(dev, "Error submitting the control message: status=%d",
221 status);
222 kfree(req);
223 usb_free_urb(urb);
224 }
225}
226
227static void ax8817x_set_multicast(struct net_device *net)
228{
229 struct usbnet *dev = netdev_priv(net);
230 struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
231 u8 rx_ctl = 0x8c;
232
233 if (net->flags & IFF_PROMISC) {
234 rx_ctl |= 0x01;
235 } else if (net->flags & IFF_ALLMULTI
236 || net->mc_count > AX_MAX_MCAST) {
237 rx_ctl |= 0x02;
238 } else if (net->mc_count == 0) {
239 /* just broadcast and directed */
240 } else {
241 /* We use the 20 byte dev->data
242 * for our 8 byte filter buffer
243 * to avoid allocating memory that
244 * is tricky to free later */
245 struct dev_mc_list *mc_list = net->mc_list;
246 u32 crc_bits;
247 int i;
248
249 memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
250
251 /* Build the multicast hash filter. */
252 for (i = 0; i < net->mc_count; i++) {
253 crc_bits =
254 ether_crc(ETH_ALEN,
255 mc_list->dmi_addr) >> 26;
256 data->multi_filter[crc_bits >> 3] |=
257 1 << (crc_bits & 7);
258 mc_list = mc_list->next;
259 }
260
261 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
262 AX_MCAST_FILTER_SIZE, data->multi_filter);
263
264 rx_ctl |= 0x10;
265 }
266
267 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
268}
269
270static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
271{
272 struct usbnet *dev = netdev_priv(netdev);
273 u16 res;
274 u8 buf[1];
275
276 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
277 ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
278 (__u16)loc, 2, (u16 *)&res);
279 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
280
281 return res & 0xffff;
282}
283
284/* same as above, but converts resulting value to cpu byte order */
285static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc)
286{
287 return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc));
288}
289
290static void
291ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
292{
293 struct usbnet *dev = netdev_priv(netdev);
294 u16 res = val;
295 u8 buf[1];
296
297 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
298 ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
299 (__u16)loc, 2, (u16 *)&res);
300 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
301}
302
303/* same as above, but converts new value to le16 byte order before writing */
304static void
305ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val)
306{
307 ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) );
308}
309
310static int ax88172_link_reset(struct usbnet *dev)
311{
312 u16 lpa;
313 u16 adv;
314 u16 res;
315 u8 mode;
316
317 mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
318 lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
319 adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
320 res = mii_nway_result(lpa|adv);
321 if (res & LPA_DUPLEX)
322 mode |= AX_MEDIUM_FULL_DUPLEX;
323 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
324
325 return 0;
326}
327
328static void
329ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
330{
331 struct usbnet *dev = netdev_priv(net);
332 u8 opt;
333
334 if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
335 wolinfo->supported = 0;
336 wolinfo->wolopts = 0;
337 return;
338 }
339 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
340 wolinfo->wolopts = 0;
341 if (opt & AX_MONITOR_MODE) {
342 if (opt & AX_MONITOR_LINK)
343 wolinfo->wolopts |= WAKE_PHY;
344 if (opt & AX_MONITOR_MAGIC)
345 wolinfo->wolopts |= WAKE_MAGIC;
346 }
347}
348
349static int
350ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
351{
352 struct usbnet *dev = netdev_priv(net);
353 u8 opt = 0;
354 u8 buf[1];
355
356 if (wolinfo->wolopts & WAKE_PHY)
357 opt |= AX_MONITOR_LINK;
358 if (wolinfo->wolopts & WAKE_MAGIC)
359 opt |= AX_MONITOR_MAGIC;
360 if (opt != 0)
361 opt |= AX_MONITOR_MODE;
362
363 if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
364 opt, 0, 0, &buf) < 0)
365 return -EINVAL;
366
367 return 0;
368}
369
370static int ax8817x_get_eeprom_len(struct net_device *net)
371{
372 return AX_EEPROM_LEN;
373}
374
375static int ax8817x_get_eeprom(struct net_device *net,
376 struct ethtool_eeprom *eeprom, u8 *data)
377{
378 struct usbnet *dev = netdev_priv(net);
379 u16 *ebuf = (u16 *)data;
380 int i;
381
382 /* Crude hack to ensure that we don't overwrite memory
383 * if an odd length is supplied
384 */
385 if (eeprom->len % 2)
386 return -EINVAL;
387
388 eeprom->magic = AX_EEPROM_MAGIC;
389
390 /* ax8817x returns 2 bytes from eeprom on read */
391 for (i=0; i < eeprom->len / 2; i++) {
392 if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
393 eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
394 return -EINVAL;
395 }
396 return 0;
397}
398
399static void ax8817x_get_drvinfo (struct net_device *net,
400 struct ethtool_drvinfo *info)
401{
402 /* Inherit standard device info */
403 usbnet_get_drvinfo(net, info);
404 info->eedump_len = 0x3e;
405}
406
407static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
408{
409 struct usbnet *dev = netdev_priv(net);
410
411 return mii_ethtool_gset(&dev->mii,cmd);
412}
413
414static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
415{
416 struct usbnet *dev = netdev_priv(net);
417
418 return mii_ethtool_sset(&dev->mii,cmd);
419}
420
421/* We need to override some ethtool_ops so we require our
422 own structure so we don't interfere with other usbnet
423 devices that may be connected at the same time. */
424static struct ethtool_ops ax8817x_ethtool_ops = {
425 .get_drvinfo = ax8817x_get_drvinfo,
426 .get_link = ethtool_op_get_link,
427 .get_msglevel = usbnet_get_msglevel,
428 .set_msglevel = usbnet_set_msglevel,
429 .get_wol = ax8817x_get_wol,
430 .set_wol = ax8817x_set_wol,
431 .get_eeprom_len = ax8817x_get_eeprom_len,
432 .get_eeprom = ax8817x_get_eeprom,
433 .get_settings = ax8817x_get_settings,
434 .set_settings = ax8817x_set_settings,
435};
436
437static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
438{
439 struct usbnet *dev = netdev_priv(net);
440
441 return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
442}
443
444static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
445{
446 int ret = 0;
447 void *buf;
448 int i;
449 unsigned long gpio_bits = dev->driver_info->data;
450
451 usbnet_get_endpoints(dev,intf);
452
453 buf = kmalloc(ETH_ALEN, GFP_KERNEL);
454 if(!buf) {
455 ret = -ENOMEM;
456 goto out1;
457 }
458
459 /* Toggle the GPIOs in a manufacturer/model specific way */
460 for (i = 2; i >= 0; i--) {
461 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
462 (gpio_bits >> (i * 8)) & 0xff, 0, 0,
463 buf)) < 0)
464 goto out2;
465 msleep(5);
466 }
467
468 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
469 0x80, 0, 0, buf)) < 0) {
470 dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
471 goto out2;
472 }
473
474 /* Get the MAC address */
475 memset(buf, 0, ETH_ALEN);
476 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID,
477 0, 0, 6, buf)) < 0) {
478 dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
479 goto out2;
480 }
481 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
482
483 /* Get the PHY id */
484 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
485 0, 0, 2, buf)) < 0) {
486 dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
487 goto out2;
488 } else if (ret < 2) {
489 /* this should always return 2 bytes */
490 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
491 ret);
492 ret = -EIO;
493 goto out2;
494 }
495
496 /* Initialize MII structure */
497 dev->mii.dev = dev->net;
498 dev->mii.mdio_read = ax8817x_mdio_read;
499 dev->mii.mdio_write = ax8817x_mdio_write;
500 dev->mii.phy_id_mask = 0x3f;
501 dev->mii.reg_num_mask = 0x1f;
502 dev->mii.phy_id = *((u8 *)buf + 1);
503 dev->net->do_ioctl = ax8817x_ioctl;
504
505 dev->net->set_multicast_list = ax8817x_set_multicast;
506 dev->net->ethtool_ops = &ax8817x_ethtool_ops;
507
508 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
509 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
510 ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
511 mii_nway_restart(&dev->mii);
512
513 return 0;
514out2:
515 kfree(buf);
516out1:
517 return ret;
518}
519
520static struct ethtool_ops ax88772_ethtool_ops = {
521 .get_drvinfo = ax8817x_get_drvinfo,
522 .get_link = ethtool_op_get_link,
523 .get_msglevel = usbnet_get_msglevel,
524 .set_msglevel = usbnet_set_msglevel,
525 .get_wol = ax8817x_get_wol,
526 .set_wol = ax8817x_set_wol,
527 .get_eeprom_len = ax8817x_get_eeprom_len,
528 .get_eeprom = ax8817x_get_eeprom,
529 .get_settings = ax8817x_get_settings,
530 .set_settings = ax8817x_set_settings,
531};
532
533static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
534{
535 int ret;
536 void *buf;
537
538 usbnet_get_endpoints(dev,intf);
539
540 buf = kmalloc(6, GFP_KERNEL);
541 if(!buf) {
542 dbg ("Cannot allocate memory for buffer");
543 ret = -ENOMEM;
544 goto out1;
545 }
546
547 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
548 0x00B0, 0, 0, buf)) < 0)
549 goto out2;
550
551 msleep(5);
552 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
553 0x0001, 0, 0, buf)) < 0) {
554 dbg("Select PHY #1 failed: %d", ret);
555 goto out2;
556 }
557
558 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD,
559 0, 0, buf)) < 0) {
560 dbg("Failed to power down internal PHY: %d", ret);
561 goto out2;
562 }
563
564 msleep(150);
565 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR,
566 0, 0, buf)) < 0) {
567 dbg("Failed to perform software reset: %d", ret);
568 goto out2;
569 }
570
571 msleep(150);
572 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
573 AX_SWRESET_IPRL | AX_SWRESET_PRL,
574 0, 0, buf)) < 0) {
575 dbg("Failed to set Internal/External PHY reset control: %d",
576 ret);
577 goto out2;
578 }
579
580 msleep(150);
581 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
582 0x0000, 0, 0, buf)) < 0) {
583 dbg("Failed to reset RX_CTL: %d", ret);
584 goto out2;
585 }
586
587 /* Get the MAC address */
588 memset(buf, 0, ETH_ALEN);
589 if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID,
590 0, 0, ETH_ALEN, buf)) < 0) {
591 dbg("Failed to read MAC address: %d", ret);
592 goto out2;
593 }
594 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
595
596 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII,
597 0, 0, 0, buf)) < 0) {
598 dbg("Enabling software MII failed: %d", ret);
599 goto out2;
600 }
601
602 if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG,
603 0x0010, 2, 2, buf)) < 0)
604 || (*((u16 *)buf) != 0x003b)) {
605 dbg("Read PHY register 2 must be 0x3b00: %d", ret);
606 goto out2;
607 }
608
609 /* Initialize MII structure */
610 dev->mii.dev = dev->net;
611 dev->mii.mdio_read = ax8817x_mdio_read;
612 dev->mii.mdio_write = ax8817x_mdio_write;
613 dev->mii.phy_id_mask = 0xff;
614 dev->mii.reg_num_mask = 0xff;
615 dev->net->do_ioctl = ax8817x_ioctl;
616
617 /* Get the PHY id */
618 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
619 0, 0, 2, buf)) < 0) {
620 dbg("Error reading PHY ID: %02x", ret);
621 goto out2;
622 } else if (ret < 2) {
623 /* this should always return 2 bytes */
624 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
625 ret);
626 ret = -EIO;
627 goto out2;
628 }
629 dev->mii.phy_id = *((u8 *)buf + 1);
630
631 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL,
632 0, 0, buf)) < 0) {
633 dbg("Set external PHY reset pin level: %d", ret);
634 goto out2;
635 }
636 msleep(150);
637 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
638 AX_SWRESET_IPRL | AX_SWRESET_PRL,
639 0, 0, buf)) < 0) {
640 dbg("Set Internal/External PHY reset control: %d", ret);
641 goto out2;
642 }
643 msleep(150);
644
645
646 dev->net->set_multicast_list = ax8817x_set_multicast;
647 dev->net->ethtool_ops = &ax88772_ethtool_ops;
648
649 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
650 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
651 ADVERTISE_ALL | ADVERTISE_CSMA);
652 mii_nway_restart(&dev->mii);
653
654 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
655 AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
656 dbg("Write medium mode register: %d", ret);
657 goto out2;
658 }
659
660 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,
661 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
662 AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
663 dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
664 goto out2;
665 }
666 if ((ret =
667 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
668 dbg("Failed to set hardware MII: %02x", ret);
669 goto out2;
670 }
671
672 /* Set RX_CTL to default values with 2k buffer, and enable cactus */
673 if ((ret =
674 ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
675 buf)) < 0) {
676 dbg("Reset RX_CTL failed: %d", ret);
677 goto out2;
678 }
679
680 kfree(buf);
681
682 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
683 if (dev->driver_info->flags & FLAG_FRAMING_AX) {
684 /* hard_mtu is still the default - the device does not support
685 jumbo eth frames */
686 dev->rx_urb_size = 2048;
687 }
688
689 return 0;
690
691out2:
692 kfree(buf);
693out1:
694 return ret;
695}
696
697static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
698{
699 u8 *head;
700 u32 header;
701 char *packet;
702 struct sk_buff *ax_skb;
703 u16 size;
704
705 head = (u8 *) skb->data;
706 memcpy(&header, head, sizeof(header));
707 le32_to_cpus(&header);
708 packet = head + sizeof(header);
709
710 skb_pull(skb, 4);
711
712 while (skb->len > 0) {
713 if ((short)(header & 0x0000ffff) !=
714 ~((short)((header & 0xffff0000) >> 16))) {
715 devdbg(dev,"header length data is error");
716 }
717 /* get the packet length */
718 size = (u16) (header & 0x0000ffff);
719
720 if ((skb->len) - ((size + 1) & 0xfffe) == 0)
721 return 2;
722 if (size > ETH_FRAME_LEN) {
723 devdbg(dev,"invalid rx length %d", size);
724 return 0;
725 }
726 ax_skb = skb_clone(skb, GFP_ATOMIC);
727 if (ax_skb) {
728 ax_skb->len = size;
729 ax_skb->data = packet;
730 ax_skb->tail = packet + size;
731 usbnet_skb_return(dev, ax_skb);
732 } else {
733 return 0;
734 }
735
736 skb_pull(skb, (size + 1) & 0xfffe);
737
738 if (skb->len == 0)
739 break;
740
741 head = (u8 *) skb->data;
742 memcpy(&header, head, sizeof(header));
743 le32_to_cpus(&header);
744 packet = head + sizeof(header);
745 skb_pull(skb, 4);
746 }
747
748 if (skb->len < 0) {
749 devdbg(dev,"invalid rx length %d", skb->len);
750 return 0;
751 }
752 return 1;
753}
754
755static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
756 unsigned flags)
757{
758 int padlen;
759 int headroom = skb_headroom(skb);
760 int tailroom = skb_tailroom(skb);
761 u32 packet_len;
762 u32 padbytes = 0xffff0000;
763
764 padlen = ((skb->len + 4) % 512) ? 0 : 4;
765
766 if ((!skb_cloned(skb))
767 && ((headroom + tailroom) >= (4 + padlen))) {
768 if ((headroom < 4) || (tailroom < padlen)) {
769 skb->data = memmove(skb->head + 4, skb->data, skb->len);
770 skb->tail = skb->data + skb->len;
771 }
772 } else {
773 struct sk_buff *skb2;
774 skb2 = skb_copy_expand(skb, 4, padlen, flags);
775 dev_kfree_skb_any(skb);
776 skb = skb2;
777 if (!skb)
778 return NULL;
779 }
780
781 skb_push(skb, 4);
782 packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
783 memcpy(skb->data, &packet_len, sizeof(packet_len));
784
785 if ((skb->len % 512) == 0) {
786 memcpy( skb->tail, &padbytes, sizeof(padbytes));
787 skb_put(skb, sizeof(padbytes));
788 }
789 return skb;
790}
791
792static int ax88772_link_reset(struct usbnet *dev)
793{
794 u16 lpa;
795 u16 adv;
796 u16 res;
797 u16 mode;
798
799 mode = AX88772_MEDIUM_DEFAULT;
800 lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
801 adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
802 res = mii_nway_result(lpa|adv);
803
804 if ((res & LPA_DUPLEX) == 0)
805 mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
806 if ((res & LPA_100) == 0)
807 mode &= ~AX88772_MEDIUM_100MB;
808 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
809
810 return 0;
811}
812
813static const struct driver_info ax8817x_info = {
814 .description = "ASIX AX8817x USB 2.0 Ethernet",
815 .bind = ax8817x_bind,
816 .status = ax8817x_status,
817 .link_reset = ax88172_link_reset,
818 .reset = ax88172_link_reset,
819 .flags = FLAG_ETHER,
820 .data = 0x00130103,
821};
822
823static const struct driver_info dlink_dub_e100_info = {
824 .description = "DLink DUB-E100 USB Ethernet",
825 .bind = ax8817x_bind,
826 .status = ax8817x_status,
827 .link_reset = ax88172_link_reset,
828 .reset = ax88172_link_reset,
829 .flags = FLAG_ETHER,
830 .data = 0x009f9d9f,
831};
832
833static const struct driver_info netgear_fa120_info = {
834 .description = "Netgear FA-120 USB Ethernet",
835 .bind = ax8817x_bind,
836 .status = ax8817x_status,
837 .link_reset = ax88172_link_reset,
838 .reset = ax88172_link_reset,
839 .flags = FLAG_ETHER,
840 .data = 0x00130103,
841};
842
843static const struct driver_info hawking_uf200_info = {
844 .description = "Hawking UF200 USB Ethernet",
845 .bind = ax8817x_bind,
846 .status = ax8817x_status,
847 .link_reset = ax88172_link_reset,
848 .reset = ax88172_link_reset,
849 .flags = FLAG_ETHER,
850 .data = 0x001f1d1f,
851};
852
853static const struct driver_info ax88772_info = {
854 .description = "ASIX AX88772 USB 2.0 Ethernet",
855 .bind = ax88772_bind,
856 .status = ax8817x_status,
857 .link_reset = ax88772_link_reset,
858 .reset = ax88772_link_reset,
859 .flags = FLAG_ETHER | FLAG_FRAMING_AX,
860 .rx_fixup = ax88772_rx_fixup,
861 .tx_fixup = ax88772_tx_fixup,
862 .data = 0x00130103,
863};
864
865static const struct usb_device_id products [] = {
866{
867 // Linksys USB200M
868 USB_DEVICE (0x077b, 0x2226),
869 .driver_info = (unsigned long) &ax8817x_info,
870}, {
871 // Netgear FA120
872 USB_DEVICE (0x0846, 0x1040),
873 .driver_info = (unsigned long) &netgear_fa120_info,
874}, {
875 // DLink DUB-E100
876 USB_DEVICE (0x2001, 0x1a00),
877 .driver_info = (unsigned long) &dlink_dub_e100_info,
878}, {
879 // Intellinet, ST Lab USB Ethernet
880 USB_DEVICE (0x0b95, 0x1720),
881 .driver_info = (unsigned long) &ax8817x_info,
882}, {
883 // Hawking UF200, TrendNet TU2-ET100
884 USB_DEVICE (0x07b8, 0x420a),
885 .driver_info = (unsigned long) &hawking_uf200_info,
886}, {
887 // Billionton Systems, USB2AR
888 USB_DEVICE (0x08dd, 0x90ff),
889 .driver_info = (unsigned long) &ax8817x_info,
890}, {
891 // ATEN UC210T
892 USB_DEVICE (0x0557, 0x2009),
893 .driver_info = (unsigned long) &ax8817x_info,
894}, {
895 // Buffalo LUA-U2-KTX
896 USB_DEVICE (0x0411, 0x003d),
897 .driver_info = (unsigned long) &ax8817x_info,
898}, {
899 // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
900 USB_DEVICE (0x6189, 0x182d),
901 .driver_info = (unsigned long) &ax8817x_info,
902}, {
903 // corega FEther USB2-TX
904 USB_DEVICE (0x07aa, 0x0017),
905 .driver_info = (unsigned long) &ax8817x_info,
906}, {
907 // Surecom EP-1427X-2
908 USB_DEVICE (0x1189, 0x0893),
909 .driver_info = (unsigned long) &ax8817x_info,
910}, {
911 // goodway corp usb gwusb2e
912 USB_DEVICE (0x1631, 0x6200),
913 .driver_info = (unsigned long) &ax8817x_info,
914}, {
915 // ASIX AX88772 10/100
916 USB_DEVICE (0x0b95, 0x7720),
917 .driver_info = (unsigned long) &ax88772_info,
918},
919 { }, // END
920};
921MODULE_DEVICE_TABLE(usb, products);
922
923static struct usb_driver asix_driver = {
924 .owner = THIS_MODULE,
925 .name = "asix",
926 .id_table = products,
927 .probe = usbnet_probe,
928 .suspend = usbnet_suspend,
929 .resume = usbnet_resume,
930 .disconnect = usbnet_disconnect,
931};
932
933static int __init asix_init(void)
934{
935 return usb_register(&asix_driver);
936}
937module_init(asix_init);
938
939static void __exit asix_exit(void)
940{
941 usb_deregister(&asix_driver);
942}
943module_exit(asix_exit);
944
945MODULE_AUTHOR("David Hollis");
946MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
947MODULE_LICENSE("GPL");
948
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index c8be912f24e1..37ef365a2472 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -383,7 +383,6 @@ static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
383 383
384 if (urb->status == -ECONNRESET) { 384 if (urb->status == -ECONNRESET) {
385 dbg("Tx Reset."); 385 dbg("Tx Reset.");
386 urb->transfer_flags &= ~URB_ASYNC_UNLINK;
387 urb->status = 0; 386 urb->status = 0;
388 catc->netdev->trans_start = jiffies; 387 catc->netdev->trans_start = jiffies;
389 catc->stats.tx_errors++; 388 catc->stats.tx_errors++;
@@ -445,7 +444,6 @@ static void catc_tx_timeout(struct net_device *netdev)
445 struct catc *catc = netdev_priv(netdev); 444 struct catc *catc = netdev_priv(netdev);
446 445
447 warn("Transmit timed out."); 446 warn("Transmit timed out.");
448 catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
449 usb_unlink_urb(catc->tx_urb); 447 usb_unlink_urb(catc->tx_urb);
450} 448}
451 449
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
new file mode 100644
index 000000000000..652b04bbf6af
--- /dev/null
+++ b/drivers/usb/net/cdc_ether.c
@@ -0,0 +1,509 @@
1/*
2 * CDC Ethernet based networking peripherals
3 * Copyright (C) 2003-2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// #define DEBUG // error path messages, extra info
21// #define VERBOSE // more; success messages
22
23#include <linux/config.h>
24#ifdef CONFIG_USB_DEBUG
25# define DEBUG
26#endif
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/init.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/ctype.h>
33#include <linux/ethtool.h>
34#include <linux/workqueue.h>
35#include <linux/mii.h>
36#include <linux/usb.h>
37#include <linux/usb_cdc.h>
38
39#include "usbnet.h"
40
41
42/*
43 * probes control interface, claims data interface, collects the bulk
44 * endpoints, activates data interface (if needed), maybe sets MTU.
45 * all pure cdc, except for certain firmware workarounds, and knowing
46 * that rndis uses one different rule.
47 */
48int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
49{
50 u8 *buf = intf->cur_altsetting->extra;
51 int len = intf->cur_altsetting->extralen;
52 struct usb_interface_descriptor *d;
53 struct cdc_state *info = (void *) &dev->data;
54 int status;
55 int rndis;
56 struct usb_driver *driver = driver_of(intf);
57
58 if (sizeof dev->data < sizeof *info)
59 return -EDOM;
60
61 /* expect strict spec conformance for the descriptors, but
62 * cope with firmware which stores them in the wrong place
63 */
64 if (len == 0 && dev->udev->actconfig->extralen) {
65 /* Motorola SB4100 (and others: Brad Hards says it's
66 * from a Broadcom design) put CDC descriptors here
67 */
68 buf = dev->udev->actconfig->extra;
69 len = dev->udev->actconfig->extralen;
70 if (len)
71 dev_dbg(&intf->dev,
72 "CDC descriptors on config\n");
73 }
74
75 /* this assumes that if there's a non-RNDIS vendor variant
76 * of cdc-acm, it'll fail RNDIS requests cleanly.
77 */
78 rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
79
80 memset(info, 0, sizeof *info);
81 info->control = intf;
82 while (len > 3) {
83 if (buf [1] != USB_DT_CS_INTERFACE)
84 goto next_desc;
85
86 /* use bDescriptorSubType to identify the CDC descriptors.
87 * We expect devices with CDC header and union descriptors.
88 * For CDC Ethernet we need the ethernet descriptor.
89 * For RNDIS, ignore two (pointless) CDC modem descriptors
90 * in favor of a complicated OID-based RPC scheme doing what
91 * CDC Ethernet achieves with a simple descriptor.
92 */
93 switch (buf [2]) {
94 case USB_CDC_HEADER_TYPE:
95 if (info->header) {
96 dev_dbg(&intf->dev, "extra CDC header\n");
97 goto bad_desc;
98 }
99 info->header = (void *) buf;
100 if (info->header->bLength != sizeof *info->header) {
101 dev_dbg(&intf->dev, "CDC header len %u\n",
102 info->header->bLength);
103 goto bad_desc;
104 }
105 break;
106 case USB_CDC_UNION_TYPE:
107 if (info->u) {
108 dev_dbg(&intf->dev, "extra CDC union\n");
109 goto bad_desc;
110 }
111 info->u = (void *) buf;
112 if (info->u->bLength != sizeof *info->u) {
113 dev_dbg(&intf->dev, "CDC union len %u\n",
114 info->u->bLength);
115 goto bad_desc;
116 }
117
118 /* we need a master/control interface (what we're
119 * probed with) and a slave/data interface; union
120 * descriptors sort this all out.
121 */
122 info->control = usb_ifnum_to_if(dev->udev,
123 info->u->bMasterInterface0);
124 info->data = usb_ifnum_to_if(dev->udev,
125 info->u->bSlaveInterface0);
126 if (!info->control || !info->data) {
127 dev_dbg(&intf->dev,
128 "master #%u/%p slave #%u/%p\n",
129 info->u->bMasterInterface0,
130 info->control,
131 info->u->bSlaveInterface0,
132 info->data);
133 goto bad_desc;
134 }
135 if (info->control != intf) {
136 dev_dbg(&intf->dev, "bogus CDC Union\n");
137 /* Ambit USB Cable Modem (and maybe others)
138 * interchanges master and slave interface.
139 */
140 if (info->data == intf) {
141 info->data = info->control;
142 info->control = intf;
143 } else
144 goto bad_desc;
145 }
146
147 /* a data interface altsetting does the real i/o */
148 d = &info->data->cur_altsetting->desc;
149 if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
150 dev_dbg(&intf->dev, "slave class %u\n",
151 d->bInterfaceClass);
152 goto bad_desc;
153 }
154 break;
155 case USB_CDC_ETHERNET_TYPE:
156 if (info->ether) {
157 dev_dbg(&intf->dev, "extra CDC ether\n");
158 goto bad_desc;
159 }
160 info->ether = (void *) buf;
161 if (info->ether->bLength != sizeof *info->ether) {
162 dev_dbg(&intf->dev, "CDC ether len %u\n",
163 info->ether->bLength);
164 goto bad_desc;
165 }
166 dev->hard_mtu = le16_to_cpu(
167 info->ether->wMaxSegmentSize);
168 /* because of Zaurus, we may be ignoring the host
169 * side link address we were given.
170 */
171 break;
172 }
173next_desc:
174 len -= buf [0]; /* bLength */
175 buf += buf [0];
176 }
177
178 if (!info->header || !info->u || (!rndis && !info->ether)) {
179 dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
180 info->header ? "" : "header ",
181 info->u ? "" : "union ",
182 info->ether ? "" : "ether ");
183 goto bad_desc;
184 }
185
186 /* claim data interface and set it up ... with side effects.
187 * network traffic can't flow until an altsetting is enabled.
188 */
189 status = usb_driver_claim_interface(driver, info->data, dev);
190 if (status < 0)
191 return status;
192 status = usbnet_get_endpoints(dev, info->data);
193 if (status < 0) {
194 /* ensure immediate exit from usbnet_disconnect */
195 usb_set_intfdata(info->data, NULL);
196 usb_driver_release_interface(driver, info->data);
197 return status;
198 }
199
200 /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
201 dev->status = NULL;
202 if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
203 struct usb_endpoint_descriptor *desc;
204
205 dev->status = &info->control->cur_altsetting->endpoint [0];
206 desc = &dev->status->desc;
207 if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
208 || !(desc->bEndpointAddress & USB_DIR_IN)
209 || (le16_to_cpu(desc->wMaxPacketSize)
210 < sizeof(struct usb_cdc_notification))
211 || !desc->bInterval) {
212 dev_dbg(&intf->dev, "bad notification endpoint\n");
213 dev->status = NULL;
214 }
215 }
216 if (rndis && !dev->status) {
217 dev_dbg(&intf->dev, "missing RNDIS status endpoint\n");
218 usb_set_intfdata(info->data, NULL);
219 usb_driver_release_interface(driver, info->data);
220 return -ENODEV;
221 }
222 return 0;
223
224bad_desc:
225 dev_info(&dev->udev->dev, "bad CDC descriptors\n");
226 return -ENODEV;
227}
228EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
229
230void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
231{
232 struct cdc_state *info = (void *) &dev->data;
233 struct usb_driver *driver = driver_of(intf);
234
235 /* disconnect master --> disconnect slave */
236 if (intf == info->control && info->data) {
237 /* ensure immediate exit from usbnet_disconnect */
238 usb_set_intfdata(info->data, NULL);
239 usb_driver_release_interface(driver, info->data);
240 info->data = NULL;
241 }
242
243 /* and vice versa (just in case) */
244 else if (intf == info->data && info->control) {
245 /* ensure immediate exit from usbnet_disconnect */
246 usb_set_intfdata(info->control, NULL);
247 usb_driver_release_interface(driver, info->control);
248 info->control = NULL;
249 }
250}
251EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
252
253
254/*-------------------------------------------------------------------------
255 *
256 * Communications Device Class, Ethernet Control model
257 *
258 * Takes two interfaces. The DATA interface is inactive till an altsetting
259 * is selected. Configuration data includes class descriptors. There's
260 * an optional status endpoint on the control interface.
261 *
262 * This should interop with whatever the 2.4 "CDCEther.c" driver
263 * (by Brad Hards) talked with, with more functionality.
264 *
265 *-------------------------------------------------------------------------*/
266
267static void dumpspeed(struct usbnet *dev, __le32 *speeds)
268{
269 if (netif_msg_timer(dev))
270 devinfo(dev, "link speeds: %u kbps up, %u kbps down",
271 __le32_to_cpu(speeds[0]) / 1000,
272 __le32_to_cpu(speeds[1]) / 1000);
273}
274
275static void cdc_status(struct usbnet *dev, struct urb *urb)
276{
277 struct usb_cdc_notification *event;
278
279 if (urb->actual_length < sizeof *event)
280 return;
281
282 /* SPEED_CHANGE can get split into two 8-byte packets */
283 if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
284 dumpspeed(dev, (__le32 *) urb->transfer_buffer);
285 return;
286 }
287
288 event = urb->transfer_buffer;
289 switch (event->bNotificationType) {
290 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
291 if (netif_msg_timer(dev))
292 devdbg(dev, "CDC: carrier %s",
293 event->wValue ? "on" : "off");
294 if (event->wValue)
295 netif_carrier_on(dev->net);
296 else
297 netif_carrier_off(dev->net);
298 break;
299 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
300 if (netif_msg_timer(dev))
301 devdbg(dev, "CDC: speed change (len %d)",
302 urb->actual_length);
303 if (urb->actual_length != (sizeof *event + 8))
304 set_bit(EVENT_STS_SPLIT, &dev->flags);
305 else
306 dumpspeed(dev, (__le32 *) &event[1]);
307 break;
308 /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
309 * but there are no standard formats for the response data.
310 */
311 default:
312 deverr(dev, "CDC: unexpected notification %02x!",
313 event->bNotificationType);
314 break;
315 }
316}
317
318static u8 nibble(unsigned char c)
319{
320 if (likely(isdigit(c)))
321 return c - '0';
322 c = toupper(c);
323 if (likely(isxdigit(c)))
324 return 10 + c - 'A';
325 return 0;
326}
327
328static inline int
329get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
330{
331 int tmp, i;
332 unsigned char buf [13];
333
334 tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
335 if (tmp != 12) {
336 dev_dbg(&dev->udev->dev,
337 "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
338 if (tmp >= 0)
339 tmp = -EINVAL;
340 return tmp;
341 }
342 for (i = tmp = 0; i < 6; i++, tmp += 2)
343 dev->net->dev_addr [i] =
344 (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
345 return 0;
346}
347
348static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
349{
350 int status;
351 struct cdc_state *info = (void *) &dev->data;
352
353 status = usbnet_generic_cdc_bind(dev, intf);
354 if (status < 0)
355 return status;
356
357 status = get_ethernet_addr(dev, info->ether);
358 if (status < 0) {
359 usb_set_intfdata(info->data, NULL);
360 usb_driver_release_interface(driver_of(intf), info->data);
361 return status;
362 }
363
364 /* FIXME cdc-ether has some multicast code too, though it complains
365 * in routine cases. info->ether describes the multicast support.
366 * Implement that here, manipulating the cdc filter as needed.
367 */
368 return 0;
369}
370
371static const struct driver_info cdc_info = {
372 .description = "CDC Ethernet Device",
373 .flags = FLAG_ETHER,
374 // .check_connect = cdc_check_connect,
375 .bind = cdc_bind,
376 .unbind = usbnet_cdc_unbind,
377 .status = cdc_status,
378};
379
380/*-------------------------------------------------------------------------*/
381
382
383static const struct usb_device_id products [] = {
384/*
385 * BLACKLIST !!
386 *
387 * First blacklist any products that are egregiously nonconformant
388 * with the CDC Ethernet specs. Minor braindamage we cope with; when
389 * they're not even trying, needing a separate driver is only the first
390 * of the differences to show up.
391 */
392
393#define ZAURUS_MASTER_INTERFACE \
394 .bInterfaceClass = USB_CLASS_COMM, \
395 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
396 .bInterfaceProtocol = USB_CDC_PROTO_NONE
397
398/* SA-1100 based Sharp Zaurus ("collie"), or compatible;
399 * wire-incompatible with true CDC Ethernet implementations.
400 * (And, it seems, needlessly so...)
401 */
402{
403 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
404 | USB_DEVICE_ID_MATCH_DEVICE,
405 .idVendor = 0x04DD,
406 .idProduct = 0x8004,
407 ZAURUS_MASTER_INTERFACE,
408 .driver_info = 0,
409},
410
411/* PXA-25x based Sharp Zaurii. Note that it seems some of these
412 * (later models especially) may have shipped only with firmware
413 * advertising false "CDC MDLM" compatibility ... but we're not
414 * clear which models did that, so for now let's assume the worst.
415 */
416{
417 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
418 | USB_DEVICE_ID_MATCH_DEVICE,
419 .idVendor = 0x04DD,
420 .idProduct = 0x8005, /* A-300 */
421 ZAURUS_MASTER_INTERFACE,
422 .driver_info = 0,
423}, {
424 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
425 | USB_DEVICE_ID_MATCH_DEVICE,
426 .idVendor = 0x04DD,
427 .idProduct = 0x8006, /* B-500/SL-5600 */
428 ZAURUS_MASTER_INTERFACE,
429 .driver_info = 0,
430}, {
431 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
432 | USB_DEVICE_ID_MATCH_DEVICE,
433 .idVendor = 0x04DD,
434 .idProduct = 0x8007, /* C-700 */
435 ZAURUS_MASTER_INTERFACE,
436 .driver_info = 0,
437}, {
438 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
439 | USB_DEVICE_ID_MATCH_DEVICE,
440 .idVendor = 0x04DD,
441 .idProduct = 0x9031, /* C-750 C-760 */
442 ZAURUS_MASTER_INTERFACE,
443 .driver_info = 0,
444}, {
445 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
446 | USB_DEVICE_ID_MATCH_DEVICE,
447 .idVendor = 0x04DD,
448 .idProduct = 0x9032, /* SL-6000 */
449 ZAURUS_MASTER_INTERFACE,
450 .driver_info = 0,
451}, {
452 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
453 | USB_DEVICE_ID_MATCH_DEVICE,
454 .idVendor = 0x04DD,
455 /* reported with some C860 units */
456 .idProduct = 0x9050, /* C-860 */
457 ZAURUS_MASTER_INTERFACE,
458 .driver_info = 0,
459},
460
461/*
462 * WHITELIST!!!
463 *
464 * CDC Ether uses two interfaces, not necessarily consecutive.
465 * We match the main interface, ignoring the optional device
466 * class so we could handle devices that aren't exclusively
467 * CDC ether.
468 *
469 * NOTE: this match must come AFTER entries blacklisting devices
470 * because of bugs/quirks in a given product (like Zaurus, above).
471 */
472{
473 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
474 USB_CDC_PROTO_NONE),
475 .driver_info = (unsigned long) &cdc_info,
476},
477 { }, // END
478};
479MODULE_DEVICE_TABLE(usb, products);
480
481static struct usb_driver cdc_driver = {
482 .owner = THIS_MODULE,
483 .name = "cdc_ether",
484 .id_table = products,
485 .probe = usbnet_probe,
486 .disconnect = usbnet_disconnect,
487 .suspend = usbnet_suspend,
488 .resume = usbnet_resume,
489};
490
491
492static int __init cdc_init(void)
493{
494 BUG_ON((sizeof(((struct usbnet *)0)->data)
495 < sizeof(struct cdc_state)));
496
497 return usb_register(&cdc_driver);
498}
499module_init(cdc_init);
500
501static void __exit cdc_exit(void)
502{
503 usb_deregister(&cdc_driver);
504}
505module_exit(cdc_exit);
506
507MODULE_AUTHOR("David Brownell");
508MODULE_DESCRIPTION("USB CDC Ethernet devices");
509MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
new file mode 100644
index 000000000000..f1730b685fd2
--- /dev/null
+++ b/drivers/usb/net/cdc_subset.c
@@ -0,0 +1,335 @@
1/*
2 * Simple "CDC Subset" USB Networking Links
3 * Copyright (C) 2000-2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/config.h>
21#ifdef CONFIG_USB_DEBUG
22# define DEBUG
23#endif
24#include <linux/module.h>
25#include <linux/kmod.h>
26#include <linux/sched.h>
27#include <linux/init.h>
28#include <linux/netdevice.h>
29#include <linux/etherdevice.h>
30#include <linux/ethtool.h>
31#include <linux/workqueue.h>
32#include <linux/mii.h>
33#include <linux/usb.h>
34
35#include "usbnet.h"
36
37
38/*
39 * This supports simple USB network links that don't require any special
40 * framing or hardware control operations. The protocol used here is a
41 * strict subset of CDC Ethernet, with three basic differences reflecting
42 * the goal that almost any hardware should run it:
43 *
44 * - Minimal runtime control: one interface, no altsettings, and
45 * no vendor or class specific control requests. If a device is
46 * configured, it is allowed to exchange packets with the host.
47 * Fancier models would mean not working on some hardware.
48 *
49 * - Minimal manufacturing control: no IEEE "Organizationally
50 * Unique ID" required, or an EEPROMs to store one. Each host uses
51 * one random "locally assigned" Ethernet address instead, which can
52 * of course be overridden using standard tools like "ifconfig".
53 * (With 2^46 such addresses, same-net collisions are quite rare.)
54 *
55 * - There is no additional framing data for USB. Packets are written
56 * exactly as in CDC Ethernet, starting with an Ethernet header and
57 * terminated by a short packet. However, the host will never send a
58 * zero length packet; some systems can't handle those robustly.
59 *
60 * Anything that can transmit and receive USB bulk packets can implement
61 * this protocol. That includes both smart peripherals and quite a lot
62 * of "host-to-host" USB cables (which embed two devices back-to-back).
63 *
64 * Note that although Linux may use many of those host-to-host links
65 * with this "cdc_subset" framing, that doesn't mean there may not be a
66 * better approach. Handling the "other end unplugs/replugs" scenario
67 * well tends to require chip-specific vendor requests. Also, Windows
68 * peers at the other end of host-to-host cables may expect their own
69 * framing to be used rather than this "cdc_subset" model.
70 */
71
72#if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
73/* PDA style devices are always connected if present */
74static int always_connected (struct usbnet *dev)
75{
76 return 0;
77}
78#endif
79
80#ifdef CONFIG_USB_ALI_M5632
81#define HAVE_HARDWARE
82
83/*-------------------------------------------------------------------------
84 *
85 * ALi M5632 driver ... does high speed
86 *
87 *-------------------------------------------------------------------------*/
88
89static const struct driver_info ali_m5632_info = {
90 .description = "ALi M5632",
91};
92
93
94#endif
95
96
97#ifdef CONFIG_USB_AN2720
98#define HAVE_HARDWARE
99
100/*-------------------------------------------------------------------------
101 *
102 * AnchorChips 2720 driver ... http://www.cypress.com
103 *
104 * This doesn't seem to have a way to detect whether the peer is
105 * connected, or need any reset handshaking. It's got pretty big
106 * internal buffers (handles most of a frame's worth of data).
107 * Chip data sheets don't describe any vendor control messages.
108 *
109 *-------------------------------------------------------------------------*/
110
111static const struct driver_info an2720_info = {
112 .description = "AnchorChips/Cypress 2720",
113 // no reset available!
114 // no check_connect available!
115
116 .in = 2, .out = 2, // direction distinguishes these
117};
118
119#endif /* CONFIG_USB_AN2720 */
120
121
122#ifdef CONFIG_USB_BELKIN
123#define HAVE_HARDWARE
124
125/*-------------------------------------------------------------------------
126 *
127 * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
128 *
129 * ... also two eTEK designs, including one sold as "Advance USBNET"
130 *
131 *-------------------------------------------------------------------------*/
132
133static const struct driver_info belkin_info = {
134 .description = "Belkin, eTEK, or compatible",
135};
136
137#endif /* CONFIG_USB_BELKIN */
138
139
140
141#ifdef CONFIG_USB_EPSON2888
142#define HAVE_HARDWARE
143
144/*-------------------------------------------------------------------------
145 *
146 * EPSON USB clients
147 *
148 * This is the same idea as Linux PDAs (below) except the firmware in the
149 * device might not be Tux-powered. Epson provides reference firmware that
150 * implements this interface. Product developers can reuse or modify that
151 * code, such as by using their own product and vendor codes.
152 *
153 * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
154 *
155 *-------------------------------------------------------------------------*/
156
157static const struct driver_info epson2888_info = {
158 .description = "Epson USB Device",
159 .check_connect = always_connected,
160
161 .in = 4, .out = 3,
162};
163
164#endif /* CONFIG_USB_EPSON2888 */
165
166
167#ifdef CONFIG_USB_KC2190
168#define HAVE_HARDWARE
169static const struct driver_info kc2190_info = {
170 .description = "KC Technology KC-190",
171};
172#endif /* CONFIG_USB_KC2190 */
173
174
175#ifdef CONFIG_USB_ARMLINUX
176#define HAVE_HARDWARE
177
178/*-------------------------------------------------------------------------
179 *
180 * Intel's SA-1100 chip integrates basic USB support, and is used
181 * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
182 * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
183 * network using minimal USB framing data.
184 *
185 * This describes the driver currently in standard ARM Linux kernels.
186 * The Zaurus uses a different driver (see later).
187 *
188 * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
189 * and different USB endpoint numbering than the SA1100 devices. The
190 * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
191 * so we rely on the endpoint descriptors.
192 *
193 *-------------------------------------------------------------------------*/
194
195static const struct driver_info linuxdev_info = {
196 .description = "Linux Device",
197 .check_connect = always_connected,
198};
199
200static const struct driver_info yopy_info = {
201 .description = "Yopy",
202 .check_connect = always_connected,
203};
204
205static const struct driver_info blob_info = {
206 .description = "Boot Loader OBject",
207 .check_connect = always_connected,
208};
209
210#endif /* CONFIG_USB_ARMLINUX */
211
212
213/*-------------------------------------------------------------------------*/
214
215#ifndef HAVE_HARDWARE
216#error You need to configure some hardware for this driver
217#endif
218
219/*
220 * chip vendor names won't normally be on the cables, and
221 * may not be on the device.
222 */
223
224static const struct usb_device_id products [] = {
225
226#ifdef CONFIG_USB_ALI_M5632
227{
228 USB_DEVICE (0x0402, 0x5632), // ALi defaults
229 .driver_info = (unsigned long) &ali_m5632_info,
230},
231#endif
232
233#ifdef CONFIG_USB_AN2720
234{
235 USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
236 .driver_info = (unsigned long) &an2720_info,
237}, {
238 USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
239 .driver_info = (unsigned long) &an2720_info,
240},
241#endif
242
243#ifdef CONFIG_USB_BELKIN
244{
245 USB_DEVICE (0x050d, 0x0004), // Belkin
246 .driver_info = (unsigned long) &belkin_info,
247}, {
248 USB_DEVICE (0x056c, 0x8100), // eTEK
249 .driver_info = (unsigned long) &belkin_info,
250}, {
251 USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
252 .driver_info = (unsigned long) &belkin_info,
253},
254#endif
255
256#ifdef CONFIG_USB_EPSON2888
257{
258 USB_DEVICE (0x0525, 0x2888), // EPSON USB client
259 .driver_info = (unsigned long) &epson2888_info,
260},
261#endif
262
263#ifdef CONFIG_USB_KC2190
264{
265 USB_DEVICE (0x050f, 0x0190), // KC-190
266 .driver_info = (unsigned long) &kc2190_info,
267},
268#endif
269
270#ifdef CONFIG_USB_ARMLINUX
271/*
272 * SA-1100 using standard ARM Linux kernels, or compatible.
273 * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
274 * The sa-1100 "usb-eth" driver handles the basic framing.
275 *
276 * PXA25x or PXA210 ... these use a "usb-eth" driver much like
277 * the sa1100 one, but hardware uses different endpoint numbers.
278 *
279 * Or the Linux "Ethernet" gadget on hardware that can't talk
280 * CDC Ethernet (e.g., no altsettings), in either of two modes:
281 * - acting just like the old "usb-eth" firmware, though
282 * the implementation is different
283 * - supporting RNDIS as the first/default configuration for
284 * MS-Windows interop; Linux needs to use the other config
285 */
286{
287 // 1183 = 0x049F, both used as hex values?
288 // Compaq "Itsy" vendor/product id
289 USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
290 .driver_info = (unsigned long) &linuxdev_info,
291}, {
292 USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
293 .driver_info = (unsigned long) &yopy_info,
294}, {
295 USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
296 .driver_info = (unsigned long) &blob_info,
297}, {
298 // Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
299 // e.g. Gumstix, current OpenZaurus, ...
300 USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
301 .driver_info = (unsigned long) &linuxdev_info,
302},
303#endif
304
305 { }, // END
306};
307MODULE_DEVICE_TABLE(usb, products);
308
309/*-------------------------------------------------------------------------*/
310
311static struct usb_driver cdc_subset_driver = {
312 .owner = THIS_MODULE,
313 .name = "cdc_subset",
314 .probe = usbnet_probe,
315 .suspend = usbnet_suspend,
316 .resume = usbnet_resume,
317 .disconnect = usbnet_disconnect,
318 .id_table = products,
319};
320
321static int __init cdc_subset_init(void)
322{
323 return usb_register(&cdc_subset_driver);
324}
325module_init(cdc_subset_init);
326
327static void __exit cdc_subset_exit(void)
328{
329 usb_deregister(&cdc_subset_driver);
330}
331module_exit(cdc_subset_exit);
332
333MODULE_AUTHOR("David Brownell");
334MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
335MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
new file mode 100644
index 000000000000..c8763ae33c73
--- /dev/null
+++ b/drivers/usb/net/gl620a.c
@@ -0,0 +1,407 @@
1/*
2 * GeneSys GL620USB-A based links
3 * Copyright (C) 2001 by Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
4 * Copyright (C) 2001 by Stanislav Brabec <utx@penguin.cz>
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// #define DEBUG // error path messages, extra info
22// #define VERBOSE // more; success messages
23
24#include <linux/config.h>
25#ifdef CONFIG_USB_DEBUG
26# define DEBUG
27#endif
28#include <linux/module.h>
29#include <linux/sched.h>
30#include <linux/init.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/ethtool.h>
34#include <linux/workqueue.h>
35#include <linux/mii.h>
36#include <linux/usb.h>
37
38#include "usbnet.h"
39
40
41/*
42 * GeneSys GL620USB-A (www.genesyslogic.com.tw)
43 *
44 * ... should partially interop with the Win32 driver for this hardware.
45 * The GeneSys docs imply there's some NDIS issue motivating this framing.
46 *
47 * Some info from GeneSys:
48 * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
49 * (Some cables, like the BAFO-100c, use the half duplex version.)
50 * - For the full duplex model, the low bit of the version code says
51 * which side is which ("left/right").
52 * - For the half duplex type, a control/interrupt handshake settles
53 * the transfer direction. (That's disabled here, partially coded.)
54 * A control URB would block until other side writes an interrupt.
55 *
56 * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
57 * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
58 */
59
60// control msg write command
61#define GENELINK_CONNECT_WRITE 0xF0
62// interrupt pipe index
63#define GENELINK_INTERRUPT_PIPE 0x03
64// interrupt read buffer size
65#define INTERRUPT_BUFSIZE 0x08
66// interrupt pipe interval value
67#define GENELINK_INTERRUPT_INTERVAL 0x10
68// max transmit packet number per transmit
69#define GL_MAX_TRANSMIT_PACKETS 32
70// max packet length
71#define GL_MAX_PACKET_LEN 1514
72// max receive buffer size
73#define GL_RCV_BUF_SIZE \
74 (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
75
76struct gl_packet {
77 u32 packet_length;
78 char packet_data [1];
79};
80
81struct gl_header {
82 u32 packet_count;
83 struct gl_packet packets;
84};
85
86#ifdef GENELINK_ACK
87
88// FIXME: this code is incomplete, not debugged; it doesn't
89// handle interrupts correctly; it should use the generic
90// status IRQ code (which didn't exist back in 2001).
91
92struct gl_priv {
93 struct urb *irq_urb;
94 char irq_buf [INTERRUPT_BUFSIZE];
95};
96
97static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
98{
99 int retval;
100
101 retval = usb_control_msg(dev->udev,
102 usb_sndctrlpipe(dev->udev, 0),
103 request,
104 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
105 value,
106 0, // index
107 0, // data buffer
108 0, // size
109 USB_CTRL_SET_TIMEOUT);
110 return retval;
111}
112
113static void gl_interrupt_complete(struct urb *urb, struct pt_regs *regs)
114{
115 int status = urb->status;
116
117 switch (status) {
118 case 0:
119 /* success */
120 break;
121 case -ECONNRESET:
122 case -ENOENT:
123 case -ESHUTDOWN:
124 /* this urb is terminated, clean up */
125 dbg("%s - urb shutting down with status: %d",
126 __FUNCTION__, status);
127 return;
128 default:
129 dbg("%s - nonzero urb status received: %d",
130 __FUNCTION__, urb->status);
131 }
132
133 status = usb_submit_urb(urb, GFP_ATOMIC);
134 if (status)
135 err("%s - usb_submit_urb failed with result %d",
136 __FUNCTION__, status);
137}
138
139static int gl_interrupt_read(struct usbnet *dev)
140{
141 struct gl_priv *priv = dev->priv_data;
142 int retval;
143
144 // issue usb interrupt read
145 if (priv && priv->irq_urb) {
146 // submit urb
147 if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0)
148 dbg("gl_interrupt_read: submit fail - %X...", retval);
149 else
150 dbg("gl_interrupt_read: submit success...");
151 }
152
153 return 0;
154}
155
156// check whether another side is connected
157static int genelink_check_connect(struct usbnet *dev)
158{
159 int retval;
160
161 dbg("genelink_check_connect...");
162
163 // detect whether another side is connected
164 if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
165 dbg("%s: genelink_check_connect write fail - %X",
166 dev->net->name, retval);
167 return retval;
168 }
169
170 // usb interrupt read to ack another side
171 if ((retval = gl_interrupt_read(dev)) != 0) {
172 dbg("%s: genelink_check_connect read fail - %X",
173 dev->net->name, retval);
174 return retval;
175 }
176
177 dbg("%s: genelink_check_connect read success", dev->net->name);
178 return 0;
179}
180
181// allocate and initialize the private data for genelink
182static int genelink_init(struct usbnet *dev)
183{
184 struct gl_priv *priv;
185
186 // allocate the private data structure
187 if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) {
188 dbg("%s: cannot allocate private data per device",
189 dev->net->name);
190 return -ENOMEM;
191 }
192
193 // allocate irq urb
194 if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) {
195 dbg("%s: cannot allocate private irq urb per device",
196 dev->net->name);
197 kfree(priv);
198 return -ENOMEM;
199 }
200
201 // fill irq urb
202 usb_fill_int_urb(priv->irq_urb, dev->udev,
203 usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE),
204 priv->irq_buf, INTERRUPT_BUFSIZE,
205 gl_interrupt_complete, 0,
206 GENELINK_INTERRUPT_INTERVAL);
207
208 // set private data pointer
209 dev->priv_data = priv;
210
211 return 0;
212}
213
214// release the private data
215static int genelink_free(struct usbnet *dev)
216{
217 struct gl_priv *priv = dev->priv_data;
218
219 if (!priv)
220 return 0;
221
222// FIXME: can't cancel here; it's synchronous, and
223// should have happened earlier in any case (interrupt
224// handling needs to be generic)
225
226 // cancel irq urb first
227 usb_kill_urb(priv->irq_urb);
228
229 // free irq urb
230 usb_free_urb(priv->irq_urb);
231
232 // free the private data structure
233 kfree(priv);
234
235 return 0;
236}
237
238#endif
239
240static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
241{
242 struct gl_header *header;
243 struct gl_packet *packet;
244 struct sk_buff *gl_skb;
245 u32 size;
246
247 header = (struct gl_header *) skb->data;
248
249 // get the packet count of the received skb
250 le32_to_cpus(&header->packet_count);
251 if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
252 || (header->packet_count < 0)) {
253 dbg("genelink: invalid received packet count %d",
254 header->packet_count);
255 return 0;
256 }
257
258 // set the current packet pointer to the first packet
259 packet = &header->packets;
260
261 // decrement the length for the packet count size 4 bytes
262 skb_pull(skb, 4);
263
264 while (header->packet_count > 1) {
265 // get the packet length
266 size = le32_to_cpu(packet->packet_length);
267
268 // this may be a broken packet
269 if (size > GL_MAX_PACKET_LEN) {
270 dbg("genelink: invalid rx length %d", size);
271 return 0;
272 }
273
274 // allocate the skb for the individual packet
275 gl_skb = alloc_skb(size, GFP_ATOMIC);
276 if (gl_skb) {
277
278 // copy the packet data to the new skb
279 memcpy(skb_put(gl_skb, size),
280 packet->packet_data, size);
281 usbnet_skb_return(dev, gl_skb);
282 }
283
284 // advance to the next packet
285 packet = (struct gl_packet *)
286 &packet->packet_data [size];
287 header->packet_count--;
288
289 // shift the data pointer to the next gl_packet
290 skb_pull(skb, size + 4);
291 }
292
293 // skip the packet length field 4 bytes
294 skb_pull(skb, 4);
295
296 if (skb->len > GL_MAX_PACKET_LEN) {
297 dbg("genelink: invalid rx length %d", skb->len);
298 return 0;
299 }
300 return 1;
301}
302
303static struct sk_buff *
304genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
305{
306 int padlen;
307 int length = skb->len;
308 int headroom = skb_headroom(skb);
309 int tailroom = skb_tailroom(skb);
310 u32 *packet_count;
311 u32 *packet_len;
312
313 // FIXME: magic numbers, bleech
314 padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
315
316 if ((!skb_cloned(skb))
317 && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
318 if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
319 skb->data = memmove(skb->head + (4 + 4*1),
320 skb->data, skb->len);
321 skb->tail = skb->data + skb->len;
322 }
323 } else {
324 struct sk_buff *skb2;
325 skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
326 dev_kfree_skb_any(skb);
327 skb = skb2;
328 if (!skb)
329 return NULL;
330 }
331
332 // attach the packet count to the header
333 packet_count = (u32 *) skb_push(skb, (4 + 4*1));
334 packet_len = packet_count + 1;
335
336 *packet_count = cpu_to_le32(1);
337 *packet_len = cpu_to_le32(length);
338
339 // add padding byte
340 if ((skb->len % dev->maxpacket) == 0)
341 skb_put(skb, 1);
342
343 return skb;
344}
345
346static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
347{
348 dev->hard_mtu = GL_RCV_BUF_SIZE;
349 dev->net->hard_header_len += 4;
350 dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
351 dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
352 return 0;
353}
354
355static const struct driver_info genelink_info = {
356 .description = "Genesys GeneLink",
357 .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT,
358 .bind = genelink_bind,
359 .rx_fixup = genelink_rx_fixup,
360 .tx_fixup = genelink_tx_fixup,
361
362 .in = 1, .out = 2,
363
364#ifdef GENELINK_ACK
365 .check_connect =genelink_check_connect,
366#endif
367};
368
369static const struct usb_device_id products [] = {
370
371{
372 USB_DEVICE(0x05e3, 0x0502), // GL620USB-A
373 .driver_info = (unsigned long) &genelink_info,
374},
375 /* NOT: USB_DEVICE(0x05e3, 0x0501), // GL620USB
376 * that's half duplex, not currently supported
377 */
378 { }, // END
379};
380MODULE_DEVICE_TABLE(usb, products);
381
382static struct usb_driver gl620a_driver = {
383 .owner = THIS_MODULE,
384 .name = "gl620a",
385 .id_table = products,
386 .probe = usbnet_probe,
387 .disconnect = usbnet_disconnect,
388 .suspend = usbnet_suspend,
389 .resume = usbnet_resume,
390};
391
392static int __init usbnet_init(void)
393{
394 return usb_register(&gl620a_driver);
395}
396module_init(usbnet_init);
397
398static void __exit usbnet_exit(void)
399{
400 usb_deregister(&gl620a_driver);
401}
402module_exit(usbnet_exit);
403
404MODULE_AUTHOR("Jiun-Jie Huang");
405MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables");
406MODULE_LICENSE("GPL");
407
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 7ffa99b9760f..e04b0ce3611a 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -787,7 +787,6 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
787 kaweth_usb_transmit_complete, 787 kaweth_usb_transmit_complete,
788 kaweth); 788 kaweth);
789 kaweth->end = 0; 789 kaweth->end = 0;
790 kaweth->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
791 790
792 if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) 791 if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
793 { 792 {
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
new file mode 100644
index 000000000000..a4309c4a491b
--- /dev/null
+++ b/drivers/usb/net/net1080.c
@@ -0,0 +1,622 @@
1/*
2 * Net1080 based USB host-to-host cables
3 * Copyright (C) 2000-2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// #define DEBUG // error path messages, extra info
21// #define VERBOSE // more; success messages
22
23#include <linux/config.h>
24#ifdef CONFIG_USB_DEBUG
25# define DEBUG
26#endif
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/init.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/ethtool.h>
33#include <linux/workqueue.h>
34#include <linux/mii.h>
35#include <linux/usb.h>
36
37#include <asm/unaligned.h>
38
39#include "usbnet.h"
40
41
42/*
43 * Netchip 1080 driver ... http://www.netchip.com
44 * (Sept 2004: End-of-life announcement has been sent.)
45 * Used in (some) LapLink cables
46 */
47
48#define frame_errors data[1]
49
50/*
51 * NetChip framing of ethernet packets, supporting additional error
52 * checks for links that may drop bulk packets from inside messages.
53 * Odd USB length == always short read for last usb packet.
54 * - nc_header
55 * - Ethernet header (14 bytes)
56 * - payload
57 * - (optional padding byte, if needed so length becomes odd)
58 * - nc_trailer
59 *
60 * This framing is to be avoided for non-NetChip devices.
61 */
62
63struct nc_header { // packed:
64 __le16 hdr_len; // sizeof nc_header (LE, all)
65 __le16 packet_len; // payload size (including ethhdr)
66 __le16 packet_id; // detects dropped packets
67#define MIN_HEADER 6
68
69 // all else is optional, and must start with:
70 // __le16 vendorId; // from usb-if
71 // __le16 productId;
72} __attribute__((__packed__));
73
74#define PAD_BYTE ((unsigned char)0xAC)
75
76struct nc_trailer {
77 __le16 packet_id;
78} __attribute__((__packed__));
79
80// packets may use FLAG_FRAMING_NC and optional pad
81#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
82 + sizeof (struct ethhdr) \
83 + (mtu) \
84 + 1 \
85 + sizeof (struct nc_trailer))
86
87#define MIN_FRAMED FRAMED_SIZE(0)
88
89/* packets _could_ be up to 64KB... */
90#define NC_MAX_PACKET 32767
91
92
93/*
94 * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
95 * before the hardware drops it. If that's done, the driver will need to
96 * frame network packets to guard against the dropped USB packets. The win32
97 * driver sets this for both sides of the link.
98 */
99#define NC_READ_TTL_MS ((u8)255) // ms
100
101/*
102 * We ignore most registers and EEPROM contents.
103 */
104#define REG_USBCTL ((u8)0x04)
105#define REG_TTL ((u8)0x10)
106#define REG_STATUS ((u8)0x11)
107
108/*
109 * Vendor specific requests to read/write data
110 */
111#define REQUEST_REGISTER ((u8)0x10)
112#define REQUEST_EEPROM ((u8)0x11)
113
114static int
115nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
116{
117 int status = usb_control_msg(dev->udev,
118 usb_rcvctrlpipe(dev->udev, 0),
119 req,
120 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
121 0, regnum,
122 retval_ptr, sizeof *retval_ptr,
123 USB_CTRL_GET_TIMEOUT);
124 if (status > 0)
125 status = 0;
126 if (!status)
127 le16_to_cpus(retval_ptr);
128 return status;
129}
130
131static inline int
132nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr)
133{
134 return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr);
135}
136
137// no retval ... can become async, usable in_interrupt()
138static void
139nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value)
140{
141 usb_control_msg(dev->udev,
142 usb_sndctrlpipe(dev->udev, 0),
143 req,
144 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
145 value, regnum,
146 NULL, 0, // data is in setup packet
147 USB_CTRL_SET_TIMEOUT);
148}
149
150static inline void
151nc_register_write(struct usbnet *dev, u8 regnum, u16 value)
152{
153 nc_vendor_write(dev, REQUEST_REGISTER, regnum, value);
154}
155
156
157#if 0
158static void nc_dump_registers(struct usbnet *dev)
159{
160 u8 reg;
161 u16 *vp = kmalloc(sizeof (u16));
162
163 if (!vp) {
164 dbg("no memory?");
165 return;
166 }
167
168 dbg("%s registers:", dev->net->name);
169 for (reg = 0; reg < 0x20; reg++) {
170 int retval;
171
172 // reading some registers is trouble
173 if (reg >= 0x08 && reg <= 0xf)
174 continue;
175 if (reg >= 0x12 && reg <= 0x1e)
176 continue;
177
178 retval = nc_register_read(dev, reg, vp);
179 if (retval < 0)
180 dbg("%s reg [0x%x] ==> error %d",
181 dev->net->name, reg, retval);
182 else
183 dbg("%s reg [0x%x] = 0x%x",
184 dev->net->name, reg, *vp);
185 }
186 kfree(vp);
187}
188#endif
189
190
191/*-------------------------------------------------------------------------*/
192
193/*
194 * Control register
195 */
196
197#define USBCTL_WRITABLE_MASK 0x1f0f
198// bits 15-13 reserved, r/o
199#define USBCTL_ENABLE_LANG (1 << 12)
200#define USBCTL_ENABLE_MFGR (1 << 11)
201#define USBCTL_ENABLE_PROD (1 << 10)
202#define USBCTL_ENABLE_SERIAL (1 << 9)
203#define USBCTL_ENABLE_DEFAULTS (1 << 8)
204// bits 7-4 reserved, r/o
205#define USBCTL_FLUSH_OTHER (1 << 3)
206#define USBCTL_FLUSH_THIS (1 << 2)
207#define USBCTL_DISCONN_OTHER (1 << 1)
208#define USBCTL_DISCONN_THIS (1 << 0)
209
210static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
211{
212 if (!netif_msg_link(dev))
213 return;
214 devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
215 " this%s%s;"
216 " other%s%s; r/o 0x%x",
217 dev->udev->bus->bus_name, dev->udev->devpath,
218 usbctl,
219 (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
220 (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
221 (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
222 (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
223 (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
224
225 (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
226 (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
227 (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
228 (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
229 usbctl & ~USBCTL_WRITABLE_MASK
230 );
231}
232
233/*-------------------------------------------------------------------------*/
234
235/*
236 * Status register
237 */
238
239#define STATUS_PORT_A (1 << 15)
240
241#define STATUS_CONN_OTHER (1 << 14)
242#define STATUS_SUSPEND_OTHER (1 << 13)
243#define STATUS_MAILBOX_OTHER (1 << 12)
244#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
245
246#define STATUS_CONN_THIS (1 << 6)
247#define STATUS_SUSPEND_THIS (1 << 5)
248#define STATUS_MAILBOX_THIS (1 << 4)
249#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
250
251#define STATUS_UNSPEC_MASK 0x0c8c
252#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
253
254
255static inline void nc_dump_status(struct usbnet *dev, u16 status)
256{
257 if (!netif_msg_link(dev))
258 return;
259 devdbg(dev, "net1080 %s-%s status 0x%x:"
260 " this (%c) PKT=%d%s%s%s;"
261 " other PKT=%d%s%s%s; unspec 0x%x",
262 dev->udev->bus->bus_name, dev->udev->devpath,
263 status,
264
265 // XXX the packet counts don't seem right
266 // (1 at reset, not 0); maybe UNSPEC too
267
268 (status & STATUS_PORT_A) ? 'A' : 'B',
269 STATUS_PACKETS_THIS(status),
270 (status & STATUS_CONN_THIS) ? " CON" : "",
271 (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
272 (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
273
274 STATUS_PACKETS_OTHER(status),
275 (status & STATUS_CONN_OTHER) ? " CON" : "",
276 (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
277 (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
278
279 status & STATUS_UNSPEC_MASK
280 );
281}
282
283/*-------------------------------------------------------------------------*/
284
285/*
286 * TTL register
287 */
288
289#define TTL_THIS(ttl) (0x00ff & ttl)
290#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
291#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
292
293static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl)
294{
295 if (netif_msg_link(dev))
296 devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
297 dev->udev->bus->bus_name, dev->udev->devpath,
298 ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
299}
300
301/*-------------------------------------------------------------------------*/
302
303static int net1080_reset(struct usbnet *dev)
304{
305 u16 usbctl, status, ttl;
306 u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
307 int retval;
308
309 if (!vp)
310 return -ENOMEM;
311
312 // nc_dump_registers(dev);
313
314 if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) {
315 dbg("can't read %s-%s status: %d",
316 dev->udev->bus->bus_name, dev->udev->devpath, retval);
317 goto done;
318 }
319 status = *vp;
320 nc_dump_status(dev, status);
321
322 if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) {
323 dbg("can't read USBCTL, %d", retval);
324 goto done;
325 }
326 usbctl = *vp;
327 nc_dump_usbctl(dev, usbctl);
328
329 nc_register_write(dev, REG_USBCTL,
330 USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
331
332 if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) {
333 dbg("can't read TTL, %d", retval);
334 goto done;
335 }
336 ttl = *vp;
337 // nc_dump_ttl(dev, ttl);
338
339 nc_register_write(dev, REG_TTL,
340 MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
341 dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
342
343 if (netif_msg_link(dev))
344 devinfo(dev, "port %c, peer %sconnected",
345 (status & STATUS_PORT_A) ? 'A' : 'B',
346 (status & STATUS_CONN_OTHER) ? "" : "dis"
347 );
348 retval = 0;
349
350done:
351 kfree(vp);
352 return retval;
353}
354
355static int net1080_check_connect(struct usbnet *dev)
356{
357 int retval;
358 u16 status;
359 u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
360
361 if (!vp)
362 return -ENOMEM;
363 retval = nc_register_read(dev, REG_STATUS, vp);
364 status = *vp;
365 kfree(vp);
366 if (retval != 0) {
367 dbg("%s net1080_check_conn read - %d", dev->net->name, retval);
368 return retval;
369 }
370 if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
371 return -ENOLINK;
372 return 0;
373}
374
375static void nc_flush_complete(struct urb *urb, struct pt_regs *regs)
376{
377 kfree(urb->context);
378 usb_free_urb(urb);
379}
380
381static void nc_ensure_sync(struct usbnet *dev)
382{
383 dev->frame_errors++;
384 if (dev->frame_errors > 5) {
385 struct urb *urb;
386 struct usb_ctrlrequest *req;
387 int status;
388
389 /* Send a flush */
390 urb = usb_alloc_urb(0, SLAB_ATOMIC);
391 if (!urb)
392 return;
393
394 req = kmalloc(sizeof *req, GFP_ATOMIC);
395 if (!req) {
396 usb_free_urb(urb);
397 return;
398 }
399
400 req->bRequestType = USB_DIR_OUT
401 | USB_TYPE_VENDOR
402 | USB_RECIP_DEVICE;
403 req->bRequest = REQUEST_REGISTER;
404 req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS
405 | USBCTL_FLUSH_OTHER);
406 req->wIndex = cpu_to_le16(REG_USBCTL);
407 req->wLength = cpu_to_le16(0);
408
409 /* queue an async control request, we don't need
410 * to do anything when it finishes except clean up.
411 */
412 usb_fill_control_urb(urb, dev->udev,
413 usb_sndctrlpipe(dev->udev, 0),
414 (unsigned char *) req,
415 NULL, 0,
416 nc_flush_complete, req);
417 status = usb_submit_urb(urb, GFP_ATOMIC);
418 if (status) {
419 kfree(req);
420 usb_free_urb(urb);
421 return;
422 }
423
424 if (netif_msg_rx_err(dev))
425 devdbg(dev, "flush net1080; too many framing errors");
426 dev->frame_errors = 0;
427 }
428}
429
430static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
431{
432 struct nc_header *header;
433 struct nc_trailer *trailer;
434 u16 hdr_len, packet_len;
435
436 if (!(skb->len & 0x01)) {
437#ifdef DEBUG
438 struct net_device *net = dev->net;
439 dbg("rx framesize %d range %d..%d mtu %d", skb->len,
440 net->hard_header_len, dev->hard_mtu, net->mtu);
441#endif
442 dev->stats.rx_frame_errors++;
443 nc_ensure_sync(dev);
444 return 0;
445 }
446
447 header = (struct nc_header *) skb->data;
448 hdr_len = le16_to_cpup(&header->hdr_len);
449 packet_len = le16_to_cpup(&header->packet_len);
450 if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
451 dev->stats.rx_frame_errors++;
452 dbg("packet too big, %d", packet_len);
453 nc_ensure_sync(dev);
454 return 0;
455 } else if (hdr_len < MIN_HEADER) {
456 dev->stats.rx_frame_errors++;
457 dbg("header too short, %d", hdr_len);
458 nc_ensure_sync(dev);
459 return 0;
460 } else if (hdr_len > MIN_HEADER) {
461 // out of band data for us?
462 dbg("header OOB, %d bytes", hdr_len - MIN_HEADER);
463 nc_ensure_sync(dev);
464 // switch (vendor/product ids) { ... }
465 }
466 skb_pull(skb, hdr_len);
467
468 trailer = (struct nc_trailer *)
469 (skb->data + skb->len - sizeof *trailer);
470 skb_trim(skb, skb->len - sizeof *trailer);
471
472 if ((packet_len & 0x01) == 0) {
473 if (skb->data [packet_len] != PAD_BYTE) {
474 dev->stats.rx_frame_errors++;
475 dbg("bad pad");
476 return 0;
477 }
478 skb_trim(skb, skb->len - 1);
479 }
480 if (skb->len != packet_len) {
481 dev->stats.rx_frame_errors++;
482 dbg("bad packet len %d (expected %d)",
483 skb->len, packet_len);
484 nc_ensure_sync(dev);
485 return 0;
486 }
487 if (header->packet_id != get_unaligned(&trailer->packet_id)) {
488 dev->stats.rx_fifo_errors++;
489 dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
490 le16_to_cpu(header->packet_id),
491 le16_to_cpu(trailer->packet_id));
492 return 0;
493 }
494#if 0
495 devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len,
496 header->packet_len, header->packet_id);
497#endif
498 dev->frame_errors = 0;
499 return 1;
500}
501
502static struct sk_buff *
503net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
504{
505 int padlen;
506 struct sk_buff *skb2;
507 struct nc_header *header = NULL;
508 struct nc_trailer *trailer = NULL;
509 int len = skb->len;
510
511 padlen = ((len + sizeof (struct nc_header)
512 + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
513 if (!skb_cloned(skb)) {
514 int headroom = skb_headroom(skb);
515 int tailroom = skb_tailroom(skb);
516
517 if ((padlen + sizeof (struct nc_trailer)) <= tailroom
518 && sizeof (struct nc_header) <= headroom)
519 /* There's enough head and tail room */
520 goto encapsulate;
521
522 if ((sizeof (struct nc_header) + padlen
523 + sizeof (struct nc_trailer)) <
524 (headroom + tailroom)) {
525 /* There's enough total room, so just readjust */
526 skb->data = memmove(skb->head
527 + sizeof (struct nc_header),
528 skb->data, skb->len);
529 skb->tail = skb->data + len;
530 goto encapsulate;
531 }
532 }
533
534 /* Create a new skb to use with the correct size */
535 skb2 = skb_copy_expand(skb,
536 sizeof (struct nc_header),
537 sizeof (struct nc_trailer) + padlen,
538 flags);
539 dev_kfree_skb_any(skb);
540 if (!skb2)
541 return skb2;
542 skb = skb2;
543
544encapsulate:
545 /* header first */
546 header = (struct nc_header *) skb_push(skb, sizeof *header);
547 header->hdr_len = cpu_to_le16(sizeof (*header));
548 header->packet_len = cpu_to_le16(len);
549 header->packet_id = cpu_to_le16((u16)dev->xid++);
550
551 /* maybe pad; then trailer */
552 if (!((skb->len + sizeof *trailer) & 0x01))
553 *skb_put(skb, 1) = PAD_BYTE;
554 trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
555 put_unaligned(header->packet_id, &trailer->packet_id);
556#if 0
557 devdbg(dev, "frame >tx h %d p %d id %d",
558 header->hdr_len, header->packet_len,
559 header->packet_id);
560#endif
561 return skb;
562}
563
564static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
565{
566 unsigned extra = sizeof (struct nc_header)
567 + 1
568 + sizeof (struct nc_trailer);
569
570 dev->net->hard_header_len += extra;
571 dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
572 dev->hard_mtu = NC_MAX_PACKET;
573 return usbnet_get_endpoints (dev, intf);
574}
575
576static const struct driver_info net1080_info = {
577 .description = "NetChip TurboCONNECT",
578 .flags = FLAG_FRAMING_NC,
579 .bind = net1080_bind,
580 .reset = net1080_reset,
581 .check_connect = net1080_check_connect,
582 .rx_fixup = net1080_rx_fixup,
583 .tx_fixup = net1080_tx_fixup,
584};
585
586static const struct usb_device_id products [] = {
587{
588 USB_DEVICE(0x0525, 0x1080), // NetChip ref design
589 .driver_info = (unsigned long) &net1080_info,
590}, {
591 USB_DEVICE(0x06D0, 0x0622), // Laplink Gold
592 .driver_info = (unsigned long) &net1080_info,
593},
594 { }, // END
595};
596MODULE_DEVICE_TABLE(usb, products);
597
598static struct usb_driver net1080_driver = {
599 .owner = THIS_MODULE,
600 .name = "net1080",
601 .id_table = products,
602 .probe = usbnet_probe,
603 .disconnect = usbnet_disconnect,
604 .suspend = usbnet_suspend,
605 .resume = usbnet_resume,
606};
607
608static int __init net1080_init(void)
609{
610 return usb_register(&net1080_driver);
611}
612module_init(net1080_init);
613
614static void __exit net1080_exit(void)
615{
616 usb_deregister(&net1080_driver);
617}
618module_exit(net1080_exit);
619
620MODULE_AUTHOR("David Brownell");
621MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links");
622MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index fcd6d3ccef44..7484d34780fc 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -825,7 +825,6 @@ static void pegasus_tx_timeout(struct net_device *net)
825 pegasus_t *pegasus = netdev_priv(net); 825 pegasus_t *pegasus = netdev_priv(net);
826 if (netif_msg_timer(pegasus)) 826 if (netif_msg_timer(pegasus))
827 printk(KERN_WARNING "%s: tx timeout\n", net->name); 827 printk(KERN_WARNING "%s: tx timeout\n", net->name);
828 pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
829 usb_unlink_urb(pegasus->tx_urb); 828 usb_unlink_urb(pegasus->tx_urb);
830 pegasus->stats.tx_errors++; 829 pegasus->stats.tx_errors++;
831} 830}
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
new file mode 100644
index 000000000000..74c2b3581c76
--- /dev/null
+++ b/drivers/usb/net/plusb.c
@@ -0,0 +1,156 @@
1/*
2 * PL-2301/2302 USB host-to-host link cables
3 * Copyright (C) 2000-2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// #define DEBUG // error path messages, extra info
21// #define VERBOSE // more; success messages
22
23#include <linux/config.h>
24#ifdef CONFIG_USB_DEBUG
25# define DEBUG
26#endif
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/init.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/ethtool.h>
33#include <linux/workqueue.h>
34#include <linux/mii.h>
35#include <linux/usb.h>
36
37#include "usbnet.h"
38
39
40/*
41 * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
42 *
43 * The protocol and handshaking used here should be bug-compatible
44 * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
45 *
46 * HEADS UP: this handshaking isn't all that robust. This driver
47 * gets confused easily if you unplug one end of the cable then
48 * try to connect it again; you'll need to restart both ends. The
49 * "naplink" software (used by some PlayStation/2 deveopers) does
50 * the handshaking much better! Also, sometimes this hardware
51 * seems to get wedged under load. Prolific docs are weak, and
52 * don't identify differences between PL2301 and PL2302, much less
53 * anything to explain the different PL2302 versions observed.
54 */
55
56/*
57 * Bits 0-4 can be used for software handshaking; they're set from
58 * one end, cleared from the other, "read" with the interrupt byte.
59 */
60#define PL_S_EN (1<<7) /* (feature only) suspend enable */
61/* reserved bit -- rx ready (6) ? */
62#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
63#define PL_RESET_OUT (1<<4) /* reset output pipe */
64#define PL_RESET_IN (1<<3) /* reset input pipe */
65#define PL_TX_C (1<<2) /* transmission complete */
66#define PL_TX_REQ (1<<1) /* transmission received */
67#define PL_PEER_E (1<<0) /* peer exists */
68
69static inline int
70pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
71{
72 return usb_control_msg(dev->udev,
73 usb_rcvctrlpipe(dev->udev, 0),
74 req,
75 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
76 val, index,
77 NULL, 0,
78 USB_CTRL_GET_TIMEOUT);
79}
80
81static inline int
82pl_clear_QuickLink_features(struct usbnet *dev, int val)
83{
84 return pl_vendor_req(dev, 1, (u8) val, 0);
85}
86
87static inline int
88pl_set_QuickLink_features(struct usbnet *dev, int val)
89{
90 return pl_vendor_req(dev, 3, (u8) val, 0);
91}
92
93static int pl_reset(struct usbnet *dev)
94{
95 /* some units seem to need this reset, others reject it utterly.
96 * FIXME be more like "naplink" or windows drivers.
97 */
98 (void) pl_set_QuickLink_features(dev,
99 PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
100 return 0;
101}
102
103static const struct driver_info prolific_info = {
104 .description = "Prolific PL-2301/PL-2302",
105 .flags = FLAG_NO_SETINT,
106 /* some PL-2302 versions seem to fail usb_set_interface() */
107 .reset = pl_reset,
108};
109
110
111/*-------------------------------------------------------------------------*/
112
113/*
114 * Proilific's name won't normally be on the cables, and
115 * may not be on the device.
116 */
117
118static const struct usb_device_id products [] = {
119
120{
121 USB_DEVICE(0x067b, 0x0000), // PL-2301
122 .driver_info = (unsigned long) &prolific_info,
123}, {
124 USB_DEVICE(0x067b, 0x0001), // PL-2302
125 .driver_info = (unsigned long) &prolific_info,
126},
127
128 { }, // END
129};
130MODULE_DEVICE_TABLE(usb, products);
131
132static struct usb_driver plusb_driver = {
133 .owner = THIS_MODULE,
134 .name = "plusb",
135 .id_table = products,
136 .probe = usbnet_probe,
137 .disconnect = usbnet_disconnect,
138 .suspend = usbnet_suspend,
139 .resume = usbnet_resume,
140};
141
142static int __init plusb_init(void)
143{
144 return usb_register(&plusb_driver);
145}
146module_init(plusb_init);
147
148static void __exit plusb_exit(void)
149{
150 usb_deregister(&plusb_driver);
151}
152module_exit(plusb_exit);
153
154MODULE_AUTHOR("David Brownell");
155MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver");
156MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
new file mode 100644
index 000000000000..2ed2e5fb7778
--- /dev/null
+++ b/drivers/usb/net/rndis_host.c
@@ -0,0 +1,615 @@
1/*
2 * Host Side support for RNDIS Networking Links
3 * Copyright (C) 2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// #define DEBUG // error path messages, extra info
21// #define VERBOSE // more; success messages
22
23#include <linux/config.h>
24#ifdef CONFIG_USB_DEBUG
25# define DEBUG
26#endif
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/init.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/ethtool.h>
33#include <linux/workqueue.h>
34#include <linux/mii.h>
35#include <linux/usb.h>
36#include <linux/usb_cdc.h>
37
38#include "usbnet.h"
39
40
41/*
42 * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of
43 * course ACM was intended for modems, not Ethernet links! USB's standard
44 * for Ethernet links is "CDC Ethernet", which is significantly simpler.
45 */
46
47/*
48 * CONTROL uses CDC "encapsulated commands" with funky notifications.
49 * - control-out: SEND_ENCAPSULATED
50 * - interrupt-in: RESPONSE_AVAILABLE
51 * - control-in: GET_ENCAPSULATED
52 *
53 * We'll try to ignore the RESPONSE_AVAILABLE notifications.
54 */
55struct rndis_msg_hdr {
56 __le32 msg_type; /* RNDIS_MSG_* */
57 __le32 msg_len;
58 // followed by data that varies between messages
59 __le32 request_id;
60 __le32 status;
61 // ... and more
62} __attribute__ ((packed));
63
64/* RNDIS defines this (absurdly huge) control timeout */
65#define RNDIS_CONTROL_TIMEOUT_MS (10 * 1000)
66
67
68#define ccpu2 __constant_cpu_to_le32
69
70#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
71
72/* codes for "msg_type" field of rndis messages;
73 * only the data channel uses packet messages (maybe batched);
74 * everything else goes on the control channel.
75 */
76#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
77#define RNDIS_MSG_INIT ccpu2(0x00000002)
78#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
79#define RNDIS_MSG_HALT ccpu2(0x00000003)
80#define RNDIS_MSG_QUERY ccpu2(0x00000004)
81#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
82#define RNDIS_MSG_SET ccpu2(0x00000005)
83#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
84#define RNDIS_MSG_RESET ccpu2(0x00000006)
85#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
86#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
87#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
88#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
89
90/* codes for "status" field of completion messages */
91#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
92#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
93#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
94#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
95#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
96#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
97
98
99struct rndis_data_hdr {
100 __le32 msg_type; /* RNDIS_MSG_PACKET */
101 __le32 msg_len; // rndis_data_hdr + data_len + pad
102 __le32 data_offset; // 36 -- right after header
103 __le32 data_len; // ... real packet size
104
105 __le32 oob_data_offset; // zero
106 __le32 oob_data_len; // zero
107 __le32 num_oob; // zero
108 __le32 packet_data_offset; // zero
109
110 __le32 packet_data_len; // zero
111 __le32 vc_handle; // zero
112 __le32 reserved; // zero
113} __attribute__ ((packed));
114
115struct rndis_init { /* OUT */
116 // header and:
117 __le32 msg_type; /* RNDIS_MSG_INIT */
118 __le32 msg_len; // 24
119 __le32 request_id;
120 __le32 major_version; // of rndis (1.0)
121 __le32 minor_version;
122 __le32 max_transfer_size;
123} __attribute__ ((packed));
124
125struct rndis_init_c { /* IN */
126 // header and:
127 __le32 msg_type; /* RNDIS_MSG_INIT_C */
128 __le32 msg_len;
129 __le32 request_id;
130 __le32 status;
131 __le32 major_version; // of rndis (1.0)
132 __le32 minor_version;
133 __le32 device_flags;
134 __le32 medium; // zero == 802.3
135 __le32 max_packets_per_message;
136 __le32 max_transfer_size;
137 __le32 packet_alignment; // max 7; (1<<n) bytes
138 __le32 af_list_offset; // zero
139 __le32 af_list_size; // zero
140} __attribute__ ((packed));
141
142struct rndis_halt { /* OUT (no reply) */
143 // header and:
144 __le32 msg_type; /* RNDIS_MSG_HALT */
145 __le32 msg_len;
146 __le32 request_id;
147} __attribute__ ((packed));
148
149struct rndis_query { /* OUT */
150 // header and:
151 __le32 msg_type; /* RNDIS_MSG_QUERY */
152 __le32 msg_len;
153 __le32 request_id;
154 __le32 oid;
155 __le32 len;
156 __le32 offset;
157/*?*/ __le32 handle; // zero
158} __attribute__ ((packed));
159
160struct rndis_query_c { /* IN */
161 // header and:
162 __le32 msg_type; /* RNDIS_MSG_QUERY_C */
163 __le32 msg_len;
164 __le32 request_id;
165 __le32 status;
166 __le32 len;
167 __le32 offset;
168} __attribute__ ((packed));
169
170struct rndis_set { /* OUT */
171 // header and:
172 __le32 msg_type; /* RNDIS_MSG_SET */
173 __le32 msg_len;
174 __le32 request_id;
175 __le32 oid;
176 __le32 len;
177 __le32 offset;
178/*?*/ __le32 handle; // zero
179} __attribute__ ((packed));
180
181struct rndis_set_c { /* IN */
182 // header and:
183 __le32 msg_type; /* RNDIS_MSG_SET_C */
184 __le32 msg_len;
185 __le32 request_id;
186 __le32 status;
187} __attribute__ ((packed));
188
189struct rndis_reset { /* IN */
190 // header and:
191 __le32 msg_type; /* RNDIS_MSG_RESET */
192 __le32 msg_len;
193 __le32 reserved;
194} __attribute__ ((packed));
195
196struct rndis_reset_c { /* OUT */
197 // header and:
198 __le32 msg_type; /* RNDIS_MSG_RESET_C */
199 __le32 msg_len;
200 __le32 status;
201 __le32 addressing_lost;
202} __attribute__ ((packed));
203
204struct rndis_indicate { /* IN (unrequested) */
205 // header and:
206 __le32 msg_type; /* RNDIS_MSG_INDICATE */
207 __le32 msg_len;
208 __le32 status;
209 __le32 length;
210 __le32 offset;
211/**/ __le32 diag_status;
212 __le32 error_offset;
213/**/ __le32 message;
214} __attribute__ ((packed));
215
216struct rndis_keepalive { /* OUT (optionally IN) */
217 // header and:
218 __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
219 __le32 msg_len;
220 __le32 request_id;
221} __attribute__ ((packed));
222
223struct rndis_keepalive_c { /* IN (optionally OUT) */
224 // header and:
225 __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
226 __le32 msg_len;
227 __le32 request_id;
228 __le32 status;
229} __attribute__ ((packed));
230
231/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
232 * there are gobs more that may optionally be supported. We'll avoid as much
233 * of that mess as possible.
234 */
235#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
236#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
237
238/*
239 * RNDIS notifications from device: command completion; "reverse"
240 * keepalives; etc
241 */
242static void rndis_status(struct usbnet *dev, struct urb *urb)
243{
244 devdbg(dev, "rndis status urb, len %d stat %d",
245 urb->actual_length, urb->status);
246 // FIXME for keepalives, respond immediately (asynchronously)
247 // if not an RNDIS status, do like cdc_status(dev,urb) does
248}
249
250/*
251 * RPC done RNDIS-style. Caller guarantees:
252 * - message is properly byteswapped
253 * - there's no other request pending
254 * - buf can hold up to 1KB response (required by RNDIS spec)
255 * On return, the first few entries are already byteswapped.
256 *
257 * Call context is likely probe(), before interface name is known,
258 * which is why we won't try to use it in the diagnostics.
259 */
260static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
261{
262 struct cdc_state *info = (void *) &dev->data;
263 int retval;
264 unsigned count;
265 __le32 rsp;
266 u32 xid = 0, msg_len, request_id;
267
268 /* REVISIT when this gets called from contexts other than probe() or
269 * disconnect(): either serialize, or dispatch responses on xid
270 */
271
272 /* Issue the request; don't bother byteswapping our xid */
273 if (likely(buf->msg_type != RNDIS_MSG_HALT
274 && buf->msg_type != RNDIS_MSG_RESET)) {
275 xid = dev->xid++;
276 if (!xid)
277 xid = dev->xid++;
278 buf->request_id = (__force __le32) xid;
279 }
280 retval = usb_control_msg(dev->udev,
281 usb_sndctrlpipe(dev->udev, 0),
282 USB_CDC_SEND_ENCAPSULATED_COMMAND,
283 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
284 0, info->u->bMasterInterface0,
285 buf, le32_to_cpu(buf->msg_len),
286 RNDIS_CONTROL_TIMEOUT_MS);
287 if (unlikely(retval < 0 || xid == 0))
288 return retval;
289
290 // FIXME Seems like some devices discard responses when
291 // we time out and cancel our "get response" requests...
292 // so, this is fragile. Probably need to poll for status.
293
294 /* ignore status endpoint, just poll the control channel;
295 * the request probably completed immediately
296 */
297 rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
298 for (count = 0; count < 10; count++) {
299 memset(buf, 0, 1024);
300 retval = usb_control_msg(dev->udev,
301 usb_rcvctrlpipe(dev->udev, 0),
302 USB_CDC_GET_ENCAPSULATED_RESPONSE,
303 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
304 0, info->u->bMasterInterface0,
305 buf, 1024,
306 RNDIS_CONTROL_TIMEOUT_MS);
307 if (likely(retval >= 8)) {
308 msg_len = le32_to_cpu(buf->msg_len);
309 request_id = (__force u32) buf->request_id;
310 if (likely(buf->msg_type == rsp)) {
311 if (likely(request_id == xid)) {
312 if (unlikely(rsp == RNDIS_MSG_RESET_C))
313 return 0;
314 if (likely(RNDIS_STATUS_SUCCESS
315 == buf->status))
316 return 0;
317 dev_dbg(&info->control->dev,
318 "rndis reply status %08x\n",
319 le32_to_cpu(buf->status));
320 return -EL3RST;
321 }
322 dev_dbg(&info->control->dev,
323 "rndis reply id %d expected %d\n",
324 request_id, xid);
325 /* then likely retry */
326 } else switch (buf->msg_type) {
327 case RNDIS_MSG_INDICATE: { /* fault */
328 // struct rndis_indicate *msg = (void *)buf;
329 dev_info(&info->control->dev,
330 "rndis fault indication\n");
331 }
332 break;
333 case RNDIS_MSG_KEEPALIVE: { /* ping */
334 struct rndis_keepalive_c *msg = (void *)buf;
335
336 msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
337 msg->msg_len = ccpu2(sizeof *msg);
338 msg->status = RNDIS_STATUS_SUCCESS;
339 retval = usb_control_msg(dev->udev,
340 usb_sndctrlpipe(dev->udev, 0),
341 USB_CDC_SEND_ENCAPSULATED_COMMAND,
342 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
343 0, info->u->bMasterInterface0,
344 msg, sizeof *msg,
345 RNDIS_CONTROL_TIMEOUT_MS);
346 if (unlikely(retval < 0))
347 dev_dbg(&info->control->dev,
348 "rndis keepalive err %d\n",
349 retval);
350 }
351 break;
352 default:
353 dev_dbg(&info->control->dev,
354 "unexpected rndis msg %08x len %d\n",
355 le32_to_cpu(buf->msg_type), msg_len);
356 }
357 } else {
358 /* device probably issued a protocol stall; ignore */
359 dev_dbg(&info->control->dev,
360 "rndis response error, code %d\n", retval);
361 }
362 msleep(2);
363 }
364 dev_dbg(&info->control->dev, "rndis response timeout\n");
365 return -ETIMEDOUT;
366}
367
368static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
369{
370 int retval;
371 struct net_device *net = dev->net;
372 union {
373 void *buf;
374 struct rndis_msg_hdr *header;
375 struct rndis_init *init;
376 struct rndis_init_c *init_c;
377 struct rndis_query *get;
378 struct rndis_query_c *get_c;
379 struct rndis_set *set;
380 struct rndis_set_c *set_c;
381 } u;
382 u32 tmp;
383
384 /* we can't rely on i/o from stack working, or stack allocation */
385 u.buf = kmalloc(1024, GFP_KERNEL);
386 if (!u.buf)
387 return -ENOMEM;
388 retval = usbnet_generic_cdc_bind(dev, intf);
389 if (retval < 0)
390 goto done;
391
392 net->hard_header_len += sizeof (struct rndis_data_hdr);
393
394 /* initialize; max transfer is 16KB at full speed */
395 u.init->msg_type = RNDIS_MSG_INIT;
396 u.init->msg_len = ccpu2(sizeof *u.init);
397 u.init->major_version = ccpu2(1);
398 u.init->minor_version = ccpu2(0);
399 u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len);
400
401 retval = rndis_command(dev, u.header);
402 if (unlikely(retval < 0)) {
403 /* it might not even be an RNDIS device!! */
404 dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
405fail:
406 usb_driver_release_interface(driver_of(intf),
407 ((struct cdc_state *)&(dev->data))->data);
408 goto done;
409 }
410 dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size);
411 /* REVISIT: peripheral "alignment" request is ignored ... */
412 dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu,
413 1 << le32_to_cpu(u.init_c->packet_alignment));
414
415 /* get designated host ethernet address */
416 memset(u.get, 0, sizeof *u.get);
417 u.get->msg_type = RNDIS_MSG_QUERY;
418 u.get->msg_len = ccpu2(sizeof *u.get);
419 u.get->oid = OID_802_3_PERMANENT_ADDRESS;
420
421 retval = rndis_command(dev, u.header);
422 if (unlikely(retval < 0)) {
423 dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
424 goto fail;
425 }
426 tmp = le32_to_cpu(u.get_c->offset);
427 if (unlikely((tmp + 8) > (1024 - ETH_ALEN)
428 || u.get_c->len != ccpu2(ETH_ALEN))) {
429 dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n",
430 tmp, le32_to_cpu(u.get_c->len));
431 retval = -EDOM;
432 goto fail;
433 }
434 memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN);
435
436 /* set a nonzero filter to enable data transfers */
437 memset(u.set, 0, sizeof *u.set);
438 u.set->msg_type = RNDIS_MSG_SET;
439 u.set->msg_len = ccpu2(4 + sizeof *u.set);
440 u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
441 u.set->len = ccpu2(4);
442 u.set->offset = ccpu2((sizeof *u.set) - 8);
443 *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
444
445 retval = rndis_command(dev, u.header);
446 if (unlikely(retval < 0)) {
447 dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
448 goto fail;
449 }
450
451 retval = 0;
452done:
453 kfree(u.buf);
454 return retval;
455}
456
457static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
458{
459 struct rndis_halt *halt;
460
461 /* try to clear any rndis state/activity (no i/o from stack!) */
462 halt = kcalloc(1, sizeof *halt, SLAB_KERNEL);
463 if (halt) {
464 halt->msg_type = RNDIS_MSG_HALT;
465 halt->msg_len = ccpu2(sizeof *halt);
466 (void) rndis_command(dev, (void *)halt);
467 kfree(halt);
468 }
469
470 return usbnet_cdc_unbind(dev, intf);
471}
472
473/*
474 * DATA -- host must not write zlps
475 */
476static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
477{
478 /* peripheral may have batched packets to us... */
479 while (likely(skb->len)) {
480 struct rndis_data_hdr *hdr = (void *)skb->data;
481 struct sk_buff *skb2;
482 u32 msg_len, data_offset, data_len;
483
484 msg_len = le32_to_cpu(hdr->msg_len);
485 data_offset = le32_to_cpu(hdr->data_offset);
486 data_len = le32_to_cpu(hdr->data_len);
487
488 /* don't choke if we see oob, per-packet data, etc */
489 if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
490 || skb->len < msg_len
491 || (data_offset + data_len + 8) > msg_len)) {
492 dev->stats.rx_frame_errors++;
493 devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
494 le32_to_cpu(hdr->msg_type),
495 msg_len, data_offset, data_len, skb->len);
496 return 0;
497 }
498 skb_pull(skb, 8 + data_offset);
499
500 /* at most one packet left? */
501 if (likely((data_len - skb->len) <= sizeof *hdr)) {
502 skb_trim(skb, data_len);
503 break;
504 }
505
506 /* try to return all the packets in the batch */
507 skb2 = skb_clone(skb, GFP_ATOMIC);
508 if (unlikely(!skb2))
509 break;
510 skb_pull(skb, msg_len - sizeof *hdr);
511 skb_trim(skb2, data_len);
512 usbnet_skb_return(dev, skb2);
513 }
514
515 /* caller will usbnet_skb_return the remaining packet */
516 return 1;
517}
518
519static struct sk_buff *
520rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
521{
522 struct rndis_data_hdr *hdr;
523 struct sk_buff *skb2;
524 unsigned len = skb->len;
525
526 if (likely(!skb_cloned(skb))) {
527 int room = skb_headroom(skb);
528
529 /* enough head room as-is? */
530 if (unlikely((sizeof *hdr) <= room))
531 goto fill;
532
533 /* enough room, but needs to be readjusted? */
534 room += skb_tailroom(skb);
535 if (likely((sizeof *hdr) <= room)) {
536 skb->data = memmove(skb->head + sizeof *hdr,
537 skb->data, len);
538 skb->tail = skb->data + len;
539 goto fill;
540 }
541 }
542
543 /* create a new skb, with the correct size (and tailpad) */
544 skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
545 dev_kfree_skb_any(skb);
546 if (unlikely(!skb2))
547 return skb2;
548 skb = skb2;
549
550 /* fill out the RNDIS header. we won't bother trying to batch
551 * packets; Linux minimizes wasted bandwidth through tx queues.
552 */
553fill:
554 hdr = (void *) __skb_push(skb, sizeof *hdr);
555 memset(hdr, 0, sizeof *hdr);
556 hdr->msg_type = RNDIS_MSG_PACKET;
557 hdr->msg_len = cpu_to_le32(skb->len);
558 hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
559 hdr->data_len = cpu_to_le32(len);
560
561 /* FIXME make the last packet always be short ... */
562 return skb;
563}
564
565
566static const struct driver_info rndis_info = {
567 .description = "RNDIS device",
568 .flags = FLAG_ETHER | FLAG_FRAMING_RN,
569 .bind = rndis_bind,
570 .unbind = rndis_unbind,
571 .status = rndis_status,
572 .rx_fixup = rndis_rx_fixup,
573 .tx_fixup = rndis_tx_fixup,
574};
575
576#undef ccpu2
577
578
579/*-------------------------------------------------------------------------*/
580
581static const struct usb_device_id products [] = {
582{
583 /* RNDIS is MSFT's un-official variant of CDC ACM */
584 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
585 .driver_info = (unsigned long) &rndis_info,
586},
587 { }, // END
588};
589MODULE_DEVICE_TABLE(usb, products);
590
591static struct usb_driver rndis_driver = {
592 .owner = THIS_MODULE,
593 .name = "rndis_host",
594 .id_table = products,
595 .probe = usbnet_probe,
596 .disconnect = usbnet_disconnect,
597 .suspend = usbnet_suspend,
598 .resume = usbnet_resume,
599};
600
601static int __init rndis_init(void)
602{
603 return usb_register(&rndis_driver);
604}
605module_init(rndis_init);
606
607static void __exit rndis_exit(void)
608{
609 usb_deregister(&rndis_driver);
610}
611module_exit(rndis_exit);
612
613MODULE_AUTHOR("David Brownell");
614MODULE_DESCRIPTION("USB Host side RNDIS driver");
615MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 59ab40ebb394..c3d4e3589e30 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -653,7 +653,6 @@ static void rtl8150_tx_timeout(struct net_device *netdev)
653{ 653{
654 rtl8150_t *dev = netdev_priv(netdev); 654 rtl8150_t *dev = netdev_priv(netdev);
655 warn("%s: Tx timeout.", netdev->name); 655 warn("%s: Tx timeout.", netdev->name);
656 dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
657 usb_unlink_urb(dev->tx_urb); 656 usb_unlink_urb(dev->tx_urb);
658 dev->stats.tx_errors++; 657 dev->stats.tx_errors++;
659} 658}
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index a2f67245f6da..6c460918d54f 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1,10 +1,7 @@
1/* 1/*
2 * USB Networking Links 2 * USB Network driver infrastructure
3 * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net> 3 * Copyright (C) 2000-2005 by David Brownell
4 * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
5 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> 4 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
6 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
7 * Copyright (c) 2002-2003 TiVo Inc.
8 * 5 *
9 * 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
10 * 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
@@ -23,95 +20,15 @@
23 20
24/* 21/*
25 * This is a generic "USB networking" framework that works with several 22 * This is a generic "USB networking" framework that works with several
26 * kinds of full and high speed networking devices: 23 * kinds of full and high speed networking devices: host-to-host cables,
27 * 24 * smart usb peripherals, and actual Ethernet adapters.
28 * + USB host-to-host "network cables", used for IP-over-USB links. 25 *
29 * These are often used for Laplink style connectivity products. 26 * These devices usually differ in terms of control protocols (if they
30 * - AnchorChip 2720 27 * even have one!) and sometimes they define new framing to wrap or batch
31 * - Belkin, eTEK (interops with Win32 drivers) 28 * Ethernet packets. Otherwise, they talk to USB pretty much the same,
32 * - GeneSys GL620USB-A 29 * so interface (un)binding, endpoint I/O queues, fault handling, and other
33 * - NetChip 1080 (interoperates with NetChip Win32 drivers) 30 * issues can usefully be addressed by this framework.
34 * - Prolific PL-2301/2302 (replaces "plusb" driver) 31 */
35 * - KC Technology KC2190
36 *
37 * + Smart USB devices can support such links directly, using Internet
38 * standard protocols instead of proprietary host-to-device links.
39 * - Linux PDAs like iPaq, Yopy, and Zaurus
40 * - The BLOB boot loader (for diskless booting)
41 * - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers
42 * - Devices using EPSON's sample USB firmware
43 * - CDC-Ethernet class devices, such as many cable modems
44 *
45 * + Adapters to networks such as Ethernet.
46 * - AX8817X based USB 2.0 products
47 *
48 * Links to these devices can be bridged using Linux Ethernet bridging.
49 * With minor exceptions, these all use similar USB framing for network
50 * traffic, but need different protocols for control traffic.
51 *
52 * USB devices can implement their side of this protocol at the cost
53 * of two bulk endpoints; it's not restricted to "cable" applications.
54 * See the SA1110, Zaurus, or EPSON device/client support in this driver;
55 * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or
56 * "g_ether" (in the Linux "gadget" framework) implement that behavior
57 * within devices.
58 *
59 *
60 * CHANGELOG:
61 *
62 * 13-sep-2000 experimental, new
63 * 10-oct-2000 usb_device_id table created.
64 * 28-oct-2000 misc fixes; mostly, discard more TTL-mangled rx packets.
65 * 01-nov-2000 usb_device_id table and probing api update by
66 * Adam J. Richter <adam@yggdrasil.com>.
67 * 18-dec-2000 (db) tx watchdog, "net1080" renaming to "usbnet", device_info
68 * and prolific support, isolate net1080-specific bits, cleanup.
69 * fix unlink_urbs oops in D3 PM resume code path.
70 *
71 * 02-feb-2001 (db) fix tx skb sharing, packet length, match_flags, ...
72 * 08-feb-2001 stubbed in "linuxdev", maybe the SA-1100 folk can use it;
73 * AnchorChips 2720 support (from spec) for testing;
74 * fix bit-ordering problem with ethernet multicast addr
75 * 19-feb-2001 Support for clearing halt conditions. SA1100 UDC support
76 * updates. Oleg Drokin (green@iXcelerator.com)
77 * 25-mar-2001 More SA-1100 updates, including workaround for ip problem
78 * expecting cleared skb->cb and framing change to match latest
79 * handhelds.org version (Oleg). Enable device IDs from the
80 * Win32 Belkin driver; other cleanups (db).
81 * 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
82 * cleanups for problems not yet seen in the field. (db)
83 * 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
84 * from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>;
85 * rx unlinks somehow weren't async; minor cleanup.
86 * 03-nov-2001 Merged GeneSys driver; original code from Jiun-Jie Huang
87 * <huangjj@genesyslogic.com.tw>, updated by Stanislav Brabec
88 * <utx@penguin.cz>. Made framing options (NetChip/GeneSys)
89 * tie mostly to (sub)driver info. Workaround some PL-2302
90 * chips that seem to reject SET_INTERFACE requests.
91 *
92 * 06-apr-2002 Added ethtool support, based on a patch from Brad Hards.
93 * Level of diagnostics is more configurable; they use device
94 * location (usb_device->devpath) instead of address (2.5).
95 * For tx_fixup, memflags can't be NOIO.
96 * 07-may-2002 Generalize/cleanup keventd support, handling rx stalls (mostly
97 * for USB 2.0 TTs) and memory shortages (potential) too. (db)
98 * Use "locally assigned" IEEE802 address space. (Brad Hards)
99 * 18-oct-2002 Support for Zaurus (Pavel Machek), related cleanup (db).
100 * 14-dec-2002 Remove Zaurus-private crc32 code (Pavel); 2.5 oops fix,
101 * cleanups and stubbed PXA-250 support (db), fix for framing
102 * issues on Z, net1080, and gl620a (Toby Milne)
103 *
104 * 31-mar-2003 Use endpoint descriptors: high speed support, simpler sa1100
105 * vs pxa25x, and CDC Ethernet. Throttle down log floods on
106 * disconnect; other cleanups. (db) Flush net1080 fifos
107 * after several sequential framing errors. (Johannes Erdfelt)
108 * 22-aug-2003 AX8817X support (Dave Hollis).
109 * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
110 * (Neil Bortnak)
111 * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell)
112 *
113 * 01-feb-2005 AX88772 support (Phil Chang & Dave Hollis)
114 *-------------------------------------------------------------------------*/
115 32
116// #define DEBUG // error path messages, extra info 33// #define DEBUG // error path messages, extra info
117// #define VERBOSE // more; success messages 34// #define VERBOSE // more; success messages
@@ -121,24 +38,18 @@
121# define DEBUG 38# define DEBUG
122#endif 39#endif
123#include <linux/module.h> 40#include <linux/module.h>
124#include <linux/kmod.h>
125#include <linux/sched.h> 41#include <linux/sched.h>
126#include <linux/init.h> 42#include <linux/init.h>
127#include <linux/netdevice.h> 43#include <linux/netdevice.h>
128#include <linux/etherdevice.h> 44#include <linux/etherdevice.h>
129#include <linux/random.h>
130#include <linux/ethtool.h> 45#include <linux/ethtool.h>
131#include <linux/workqueue.h> 46#include <linux/workqueue.h>
132#include <linux/mii.h> 47#include <linux/mii.h>
133#include <asm/uaccess.h>
134#include <asm/unaligned.h>
135#include <linux/usb.h> 48#include <linux/usb.h>
136#include <asm/io.h>
137#include <asm/scatterlist.h>
138#include <linux/mm.h>
139#include <linux/dma-mapping.h>
140 49
141#define DRIVER_VERSION "03-Nov-2004" 50#include "usbnet.h"
51
52#define DRIVER_VERSION "22-Aug-2005"
142 53
143 54
144/*-------------------------------------------------------------------------*/ 55/*-------------------------------------------------------------------------*/
@@ -149,15 +60,14 @@
149 * One maximum size Ethernet packet takes twenty four of them. 60 * One maximum size Ethernet packet takes twenty four of them.
150 * For high speed, each frame comfortably fits almost 36 max size 61 * For high speed, each frame comfortably fits almost 36 max size
151 * Ethernet packets (so queues should be bigger). 62 * Ethernet packets (so queues should be bigger).
63 *
64 * REVISIT qlens should be members of 'struct usbnet'; the goal is to
65 * let the USB host controller be busy for 5msec or more before an irq
66 * is required, under load. Jumbograms change the equation.
152 */ 67 */
153#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) 68#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
154#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) 69#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
155 70
156// packets are always ethernet inside
157// ... except they can be bigger (limit of 64K with NetChip framing)
158#define MIN_PACKET sizeof(struct ethhdr)
159#define MAX_PACKET 32768
160
161// reawaken network queue this soon after stopping; else watchdog barks 71// reawaken network queue this soon after stopping; else watchdog barks
162#define TX_TIMEOUT_JIFFIES (5*HZ) 72#define TX_TIMEOUT_JIFFIES (5*HZ)
163 73
@@ -165,9 +75,6 @@
165// us (it polls at HZ/4 usually) before we report too many false errors. 75// us (it polls at HZ/4 usually) before we report too many false errors.
166#define THROTTLE_JIFFIES (HZ/8) 76#define THROTTLE_JIFFIES (HZ/8)
167 77
168// for vendor-specific control operations
169#define CONTROL_TIMEOUT_MS 500
170
171// between wakeups 78// between wakeups
172#define UNLINK_TIMEOUT_MS 3 79#define UNLINK_TIMEOUT_MS 3
173 80
@@ -176,109 +83,6 @@
176// randomly generated ethernet address 83// randomly generated ethernet address
177static u8 node_id [ETH_ALEN]; 84static u8 node_id [ETH_ALEN];
178 85
179// state we keep for each device we handle
180struct usbnet {
181 // housekeeping
182 struct usb_device *udev;
183 struct driver_info *driver_info;
184 wait_queue_head_t *wait;
185
186 // i/o info: pipes etc
187 unsigned in, out;
188 struct usb_host_endpoint *status;
189 unsigned maxpacket;
190 struct timer_list delay;
191
192 // protocol/interface state
193 struct net_device *net;
194 struct net_device_stats stats;
195 int msg_enable;
196 unsigned long data [5];
197
198 struct mii_if_info mii;
199
200 // various kinds of pending driver work
201 struct sk_buff_head rxq;
202 struct sk_buff_head txq;
203 struct sk_buff_head done;
204 struct urb *interrupt;
205 struct tasklet_struct bh;
206
207 struct work_struct kevent;
208 unsigned long flags;
209# define EVENT_TX_HALT 0
210# define EVENT_RX_HALT 1
211# define EVENT_RX_MEMORY 2
212# define EVENT_STS_SPLIT 3
213# define EVENT_LINK_RESET 4
214};
215
216// device-specific info used by the driver
217struct driver_info {
218 char *description;
219
220 int flags;
221/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
222#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
223#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */
224#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */
225#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */
226
227#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
228#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
229
230#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
231
232 /* init device ... can sleep, or cause probe() failure */
233 int (*bind)(struct usbnet *, struct usb_interface *);
234
235 /* cleanup device ... can sleep, but can't fail */
236 void (*unbind)(struct usbnet *, struct usb_interface *);
237
238 /* reset device ... can sleep */
239 int (*reset)(struct usbnet *);
240
241 /* see if peer is connected ... can sleep */
242 int (*check_connect)(struct usbnet *);
243
244 /* for status polling */
245 void (*status)(struct usbnet *, struct urb *);
246
247 /* link reset handling, called from defer_kevent */
248 int (*link_reset)(struct usbnet *);
249
250 /* fixup rx packet (strip framing) */
251 int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
252
253 /* fixup tx packet (add framing) */
254 struct sk_buff *(*tx_fixup)(struct usbnet *dev,
255 struct sk_buff *skb, int flags);
256
257 // FIXME -- also an interrupt mechanism
258 // useful for at least PL2301/2302 and GL620USB-A
259 // and CDC use them to report 'is it connected' changes
260
261 /* for new devices, use the descriptor-reading code instead */
262 int in; /* rx endpoint */
263 int out; /* tx endpoint */
264
265 unsigned long data; /* Misc driver specific data */
266};
267
268// we record the state for each of our queued skbs
269enum skb_state {
270 illegal = 0,
271 tx_start, tx_done,
272 rx_start, rx_done, rx_cleanup
273};
274
275struct skb_data { // skb->cb is one of these
276 struct urb *urb;
277 struct usbnet *dev;
278 enum skb_state state;
279 size_t length;
280};
281
282static const char driver_name [] = "usbnet"; 86static const char driver_name [] = "usbnet";
283 87
284/* use ethtool to change the level for any given device */ 88/* use ethtool to change the level for any given device */
@@ -286,39 +90,10 @@ static int msg_level = -1;
286module_param (msg_level, int, 0); 90module_param (msg_level, int, 0);
287MODULE_PARM_DESC (msg_level, "Override default message level"); 91MODULE_PARM_DESC (msg_level, "Override default message level");
288 92
289
290#ifdef DEBUG
291#define devdbg(usbnet, fmt, arg...) \
292 printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
293#else
294#define devdbg(usbnet, fmt, arg...) do {} while(0)
295#endif
296
297#define deverr(usbnet, fmt, arg...) \
298 printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
299#define devwarn(usbnet, fmt, arg...) \
300 printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
301
302#define devinfo(usbnet, fmt, arg...) \
303 printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
304
305/*-------------------------------------------------------------------------*/ 93/*-------------------------------------------------------------------------*/
306 94
307static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
308static u32 usbnet_get_link (struct net_device *);
309static u32 usbnet_get_msglevel (struct net_device *);
310static void usbnet_set_msglevel (struct net_device *, u32);
311static void defer_kevent (struct usbnet *, int);
312
313/* mostly for PDA style devices, which are always connected if present */
314static int always_connected (struct usbnet *dev)
315{
316 return 0;
317}
318
319/* handles CDC Ethernet and many other network "bulk data" interfaces */ 95/* handles CDC Ethernet and many other network "bulk data" interfaces */
320static int 96int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
321get_endpoints (struct usbnet *dev, struct usb_interface *intf)
322{ 97{
323 int tmp; 98 int tmp;
324 struct usb_host_interface *alt = NULL; 99 struct usb_host_interface *alt = NULL;
@@ -382,6 +157,7 @@ get_endpoints (struct usbnet *dev, struct usb_interface *intf)
382 dev->status = status; 157 dev->status = status;
383 return 0; 158 return 0;
384} 159}
160EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
385 161
386static void intr_complete (struct urb *urb, struct pt_regs *regs); 162static void intr_complete (struct urb *urb, struct pt_regs *regs);
387 163
@@ -421,7 +197,11 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
421 return 0; 197 return 0;
422} 198}
423 199
424static void skb_return (struct usbnet *dev, struct sk_buff *skb) 200/* Passes this packet up the stack, updating its accounting.
201 * Some link protocols batch packets, so their rx_fixup paths
202 * can return clones as well as just modify the original skb.
203 */
204void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
425{ 205{
426 int status; 206 int status;
427 207
@@ -438,2425 +218,7 @@ static void skb_return (struct usbnet *dev, struct sk_buff *skb)
438 if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev)) 218 if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
439 devdbg (dev, "netif_rx status %d", status); 219 devdbg (dev, "netif_rx status %d", status);
440} 220}
441 221EXPORT_SYMBOL_GPL(usbnet_skb_return);
442
443#ifdef CONFIG_USB_ALI_M5632
444#define HAVE_HARDWARE
445
446/*-------------------------------------------------------------------------
447 *
448 * ALi M5632 driver ... does high speed
449 *
450 *-------------------------------------------------------------------------*/
451
452static const struct driver_info ali_m5632_info = {
453 .description = "ALi M5632",
454};
455
456
457#endif
458
459
460#ifdef CONFIG_USB_AN2720
461#define HAVE_HARDWARE
462
463/*-------------------------------------------------------------------------
464 *
465 * AnchorChips 2720 driver ... http://www.cypress.com
466 *
467 * This doesn't seem to have a way to detect whether the peer is
468 * connected, or need any reset handshaking. It's got pretty big
469 * internal buffers (handles most of a frame's worth of data).
470 * Chip data sheets don't describe any vendor control messages.
471 *
472 *-------------------------------------------------------------------------*/
473
474static const struct driver_info an2720_info = {
475 .description = "AnchorChips/Cypress 2720",
476 // no reset available!
477 // no check_connect available!
478
479 .in = 2, .out = 2, // direction distinguishes these
480};
481
482#endif /* CONFIG_USB_AN2720 */
483
484
485#ifdef CONFIG_USB_AX8817X
486/* ASIX AX8817X based USB 2.0 Ethernet Devices */
487
488#define HAVE_HARDWARE
489#define NEED_MII
490
491#include <linux/crc32.h>
492
493#define AX_CMD_SET_SW_MII 0x06
494#define AX_CMD_READ_MII_REG 0x07
495#define AX_CMD_WRITE_MII_REG 0x08
496#define AX_CMD_SET_HW_MII 0x0a
497#define AX_CMD_READ_EEPROM 0x0b
498#define AX_CMD_WRITE_EEPROM 0x0c
499#define AX_CMD_WRITE_ENABLE 0x0d
500#define AX_CMD_WRITE_DISABLE 0x0e
501#define AX_CMD_WRITE_RX_CTL 0x10
502#define AX_CMD_READ_IPG012 0x11
503#define AX_CMD_WRITE_IPG0 0x12
504#define AX_CMD_WRITE_IPG1 0x13
505#define AX_CMD_WRITE_IPG2 0x14
506#define AX_CMD_WRITE_MULTI_FILTER 0x16
507#define AX_CMD_READ_NODE_ID 0x17
508#define AX_CMD_READ_PHY_ID 0x19
509#define AX_CMD_READ_MEDIUM_STATUS 0x1a
510#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
511#define AX_CMD_READ_MONITOR_MODE 0x1c
512#define AX_CMD_WRITE_MONITOR_MODE 0x1d
513#define AX_CMD_WRITE_GPIOS 0x1f
514#define AX_CMD_SW_RESET 0x20
515#define AX_CMD_SW_PHY_STATUS 0x21
516#define AX_CMD_SW_PHY_SELECT 0x22
517#define AX88772_CMD_READ_NODE_ID 0x13
518
519#define AX_MONITOR_MODE 0x01
520#define AX_MONITOR_LINK 0x02
521#define AX_MONITOR_MAGIC 0x04
522#define AX_MONITOR_HSFS 0x10
523
524/* AX88172 Medium Status Register values */
525#define AX_MEDIUM_FULL_DUPLEX 0x02
526#define AX_MEDIUM_TX_ABORT_ALLOW 0x04
527#define AX_MEDIUM_FLOW_CONTROL_EN 0x10
528
529#define AX_MCAST_FILTER_SIZE 8
530#define AX_MAX_MCAST 64
531
532#define AX_EEPROM_LEN 0x40
533
534#define AX_SWRESET_CLEAR 0x00
535#define AX_SWRESET_RR 0x01
536#define AX_SWRESET_RT 0x02
537#define AX_SWRESET_PRTE 0x04
538#define AX_SWRESET_PRL 0x08
539#define AX_SWRESET_BZ 0x10
540#define AX_SWRESET_IPRL 0x20
541#define AX_SWRESET_IPPD 0x40
542
543#define AX88772_IPG0_DEFAULT 0x15
544#define AX88772_IPG1_DEFAULT 0x0c
545#define AX88772_IPG2_DEFAULT 0x12
546
547#define AX88772_MEDIUM_FULL_DUPLEX 0x0002
548#define AX88772_MEDIUM_RESERVED 0x0004
549#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010
550#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020
551#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080
552#define AX88772_MEDIUM_RX_ENABLE 0x0100
553#define AX88772_MEDIUM_100MB 0x0200
554#define AX88772_MEDIUM_DEFAULT \
555 (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
556 AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
557 AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
558
559#define AX_EEPROM_MAGIC 0xdeadbeef
560
561/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
562struct ax8817x_data {
563 u8 multi_filter[AX_MCAST_FILTER_SIZE];
564};
565
566struct ax88172_int_data {
567 u16 res1;
568 u8 link;
569 u16 res2;
570 u8 status;
571 u16 res3;
572} __attribute__ ((packed));
573
574static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
575 u16 size, void *data)
576{
577 return usb_control_msg(
578 dev->udev,
579 usb_rcvctrlpipe(dev->udev, 0),
580 cmd,
581 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
582 value,
583 index,
584 data,
585 size,
586 CONTROL_TIMEOUT_MS);
587}
588
589static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
590 u16 size, void *data)
591{
592 return usb_control_msg(
593 dev->udev,
594 usb_sndctrlpipe(dev->udev, 0),
595 cmd,
596 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
597 value,
598 index,
599 data,
600 size,
601 CONTROL_TIMEOUT_MS);
602}
603
604static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
605{
606 struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
607
608 if (urb->status < 0)
609 printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
610 urb->status);
611
612 kfree(req);
613 usb_free_urb(urb);
614}
615
616static void ax8817x_status(struct usbnet *dev, struct urb *urb)
617{
618 struct ax88172_int_data *event;
619 int link;
620
621 if (urb->actual_length < 8)
622 return;
623
624 event = urb->transfer_buffer;
625 link = event->link & 0x01;
626 if (netif_carrier_ok(dev->net) != link) {
627 if (link) {
628 netif_carrier_on(dev->net);
629 defer_kevent (dev, EVENT_LINK_RESET );
630 } else
631 netif_carrier_off(dev->net);
632 devdbg(dev, "ax8817x - Link Status is: %d", link);
633 }
634}
635
636static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
637 u16 size, void *data)
638{
639 struct usb_ctrlrequest *req;
640 int status;
641 struct urb *urb;
642
643 if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
644 devdbg(dev, "Error allocating URB in write_cmd_async!");
645 return;
646 }
647
648 if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
649 deverr(dev, "Failed to allocate memory for control request");
650 usb_free_urb(urb);
651 return;
652 }
653
654 req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
655 req->bRequest = cmd;
656 req->wValue = cpu_to_le16(value);
657 req->wIndex = cpu_to_le16(index);
658 req->wLength = cpu_to_le16(size);
659
660 usb_fill_control_urb(urb, dev->udev,
661 usb_sndctrlpipe(dev->udev, 0),
662 (void *)req, data, size,
663 ax8817x_async_cmd_callback, req);
664
665 if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
666 deverr(dev, "Error submitting the control message: status=%d", status);
667 kfree(req);
668 usb_free_urb(urb);
669 }
670}
671
672static void ax8817x_set_multicast(struct net_device *net)
673{
674 struct usbnet *dev = netdev_priv(net);
675 struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
676 u8 rx_ctl = 0x8c;
677
678 if (net->flags & IFF_PROMISC) {
679 rx_ctl |= 0x01;
680 } else if (net->flags & IFF_ALLMULTI
681 || net->mc_count > AX_MAX_MCAST) {
682 rx_ctl |= 0x02;
683 } else if (net->mc_count == 0) {
684 /* just broadcast and directed */
685 } else {
686 /* We use the 20 byte dev->data
687 * for our 8 byte filter buffer
688 * to avoid allocating memory that
689 * is tricky to free later */
690 struct dev_mc_list *mc_list = net->mc_list;
691 u32 crc_bits;
692 int i;
693
694 memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
695
696 /* Build the multicast hash filter. */
697 for (i = 0; i < net->mc_count; i++) {
698 crc_bits =
699 ether_crc(ETH_ALEN,
700 mc_list->dmi_addr) >> 26;
701 data->multi_filter[crc_bits >> 3] |=
702 1 << (crc_bits & 7);
703 mc_list = mc_list->next;
704 }
705
706 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
707 AX_MCAST_FILTER_SIZE, data->multi_filter);
708
709 rx_ctl |= 0x10;
710 }
711
712 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
713}
714
715static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
716{
717 struct usbnet *dev = netdev_priv(netdev);
718 u16 res;
719 u8 buf[1];
720
721 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
722 ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
723 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
724
725 return res & 0xffff;
726}
727
728static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
729{
730 struct usbnet *dev = netdev_priv(netdev);
731 u16 res = val;
732 u8 buf[1];
733
734 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
735 ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
736 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
737}
738
739static int ax88172_link_reset(struct usbnet *dev)
740{
741 u16 lpa;
742 u8 mode;
743
744 mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
745 lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
746 if (lpa & LPA_DUPLEX)
747 mode |= AX_MEDIUM_FULL_DUPLEX;
748 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
749
750 return 0;
751}
752
753static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
754{
755 struct usbnet *dev = netdev_priv(net);
756 u8 opt;
757
758 if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
759 wolinfo->supported = 0;
760 wolinfo->wolopts = 0;
761 return;
762 }
763 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
764 wolinfo->wolopts = 0;
765 if (opt & AX_MONITOR_MODE) {
766 if (opt & AX_MONITOR_LINK)
767 wolinfo->wolopts |= WAKE_PHY;
768 if (opt & AX_MONITOR_MAGIC)
769 wolinfo->wolopts |= WAKE_MAGIC;
770 }
771}
772
773static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
774{
775 struct usbnet *dev = netdev_priv(net);
776 u8 opt = 0;
777 u8 buf[1];
778
779 if (wolinfo->wolopts & WAKE_PHY)
780 opt |= AX_MONITOR_LINK;
781 if (wolinfo->wolopts & WAKE_MAGIC)
782 opt |= AX_MONITOR_MAGIC;
783 if (opt != 0)
784 opt |= AX_MONITOR_MODE;
785
786 if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
787 opt, 0, 0, &buf) < 0)
788 return -EINVAL;
789
790 return 0;
791}
792
793static int ax8817x_get_eeprom_len(struct net_device *net)
794{
795 return AX_EEPROM_LEN;
796}
797
798static int ax8817x_get_eeprom(struct net_device *net,
799 struct ethtool_eeprom *eeprom, u8 *data)
800{
801 struct usbnet *dev = netdev_priv(net);
802 u16 *ebuf = (u16 *)data;
803 int i;
804
805 /* Crude hack to ensure that we don't overwrite memory
806 * if an odd length is supplied
807 */
808 if (eeprom->len % 2)
809 return -EINVAL;
810
811 eeprom->magic = AX_EEPROM_MAGIC;
812
813 /* ax8817x returns 2 bytes from eeprom on read */
814 for (i=0; i < eeprom->len / 2; i++) {
815 if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
816 eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
817 return -EINVAL;
818 }
819 return 0;
820}
821
822static void ax8817x_get_drvinfo (struct net_device *net,
823 struct ethtool_drvinfo *info)
824{
825 /* Inherit standard device info */
826 usbnet_get_drvinfo(net, info);
827 info->eedump_len = 0x3e;
828}
829
830static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
831{
832 struct usbnet *dev = netdev_priv(net);
833
834 return mii_ethtool_gset(&dev->mii,cmd);
835}
836
837static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
838{
839 struct usbnet *dev = netdev_priv(net);
840
841 return mii_ethtool_sset(&dev->mii,cmd);
842}
843
844/* We need to override some ethtool_ops so we require our
845 own structure so we don't interfere with other usbnet
846 devices that may be connected at the same time. */
847static struct ethtool_ops ax8817x_ethtool_ops = {
848 .get_drvinfo = ax8817x_get_drvinfo,
849 .get_link = ethtool_op_get_link,
850 .get_msglevel = usbnet_get_msglevel,
851 .set_msglevel = usbnet_set_msglevel,
852 .get_wol = ax8817x_get_wol,
853 .set_wol = ax8817x_set_wol,
854 .get_eeprom_len = ax8817x_get_eeprom_len,
855 .get_eeprom = ax8817x_get_eeprom,
856 .get_settings = ax8817x_get_settings,
857 .set_settings = ax8817x_set_settings,
858};
859
860static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
861{
862 int ret = 0;
863 void *buf;
864 int i;
865 unsigned long gpio_bits = dev->driver_info->data;
866
867 get_endpoints(dev,intf);
868
869 buf = kmalloc(ETH_ALEN, GFP_KERNEL);
870 if(!buf) {
871 ret = -ENOMEM;
872 goto out1;
873 }
874
875 /* Toggle the GPIOs in a manufacturer/model specific way */
876 for (i = 2; i >= 0; i--) {
877 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
878 (gpio_bits >> (i * 8)) & 0xff, 0, 0,
879 buf)) < 0)
880 goto out2;
881 msleep(5);
882 }
883
884 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
885 dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
886 goto out2;
887 }
888
889 /* Get the MAC address */
890 memset(buf, 0, ETH_ALEN);
891 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) {
892 dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
893 goto out2;
894 }
895 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
896
897 /* Get the PHY id */
898 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
899 dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
900 goto out2;
901 } else if (ret < 2) {
902 /* this should always return 2 bytes */
903 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
904 ret = -EIO;
905 goto out2;
906 }
907
908 /* Initialize MII structure */
909 dev->mii.dev = dev->net;
910 dev->mii.mdio_read = ax8817x_mdio_read;
911 dev->mii.mdio_write = ax8817x_mdio_write;
912 dev->mii.phy_id_mask = 0x3f;
913 dev->mii.reg_num_mask = 0x1f;
914 dev->mii.phy_id = *((u8 *)buf + 1);
915
916 dev->net->set_multicast_list = ax8817x_set_multicast;
917 dev->net->ethtool_ops = &ax8817x_ethtool_ops;
918
919 ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
920 ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
921 ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
922 mii_nway_restart(&dev->mii);
923
924 return 0;
925out2:
926 kfree(buf);
927out1:
928 return ret;
929}
930
931static struct ethtool_ops ax88772_ethtool_ops = {
932 .get_drvinfo = ax8817x_get_drvinfo,
933 .get_link = ethtool_op_get_link,
934 .get_msglevel = usbnet_get_msglevel,
935 .set_msglevel = usbnet_set_msglevel,
936 .get_wol = ax8817x_get_wol,
937 .set_wol = ax8817x_set_wol,
938 .get_eeprom_len = ax8817x_get_eeprom_len,
939 .get_eeprom = ax8817x_get_eeprom,
940 .get_settings = ax8817x_get_settings,
941 .set_settings = ax8817x_set_settings,
942};
943
944static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
945{
946 int ret;
947 void *buf;
948
949 get_endpoints(dev,intf);
950
951 buf = kmalloc(6, GFP_KERNEL);
952 if(!buf) {
953 dbg ("Cannot allocate memory for buffer");
954 ret = -ENOMEM;
955 goto out1;
956 }
957
958 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
959 0x00B0, 0, 0, buf)) < 0)
960 goto out2;
961
962 msleep(5);
963 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) {
964 dbg("Select PHY #1 failed: %d", ret);
965 goto out2;
966 }
967
968 if ((ret =
969 ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, 0, 0, buf)) < 0) {
970 dbg("Failed to power down internal PHY: %d", ret);
971 goto out2;
972 }
973
974 msleep(150);
975 if ((ret =
976 ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, 0, 0, buf)) < 0) {
977 dbg("Failed to perform software reset: %d", ret);
978 goto out2;
979 }
980
981 msleep(150);
982 if ((ret =
983 ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
984 dbg("Failed to set Internal/External PHY reset control: %d", ret);
985 goto out2;
986 }
987
988 msleep(150);
989 if ((ret =
990 ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0000, 0, 0,
991 buf)) < 0) {
992 dbg("Failed to reset RX_CTL: %d", ret);
993 goto out2;
994 }
995
996 /* Get the MAC address */
997 memset(buf, 0, ETH_ALEN);
998 if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) {
999 dbg("Failed to read MAC address: %d", ret);
1000 goto out2;
1001 }
1002 memcpy(dev->net->dev_addr, buf, ETH_ALEN);
1003
1004 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, buf)) < 0) {
1005 dbg("Enabling software MII failed: %d", ret);
1006 goto out2;
1007 }
1008
1009 if (((ret =
1010 ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0)
1011 || (*((u16 *)buf) != 0x003b)) {
1012 dbg("Read PHY register 2 must be 0x3b00: %d", ret);
1013 goto out2;
1014 }
1015
1016 /* Initialize MII structure */
1017 dev->mii.dev = dev->net;
1018 dev->mii.mdio_read = ax8817x_mdio_read;
1019 dev->mii.mdio_write = ax8817x_mdio_write;
1020 dev->mii.phy_id_mask = 0xff;
1021 dev->mii.reg_num_mask = 0xff;
1022
1023 /* Get the PHY id */
1024 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
1025 dbg("Error reading PHY ID: %02x", ret);
1026 goto out2;
1027 } else if (ret < 2) {
1028 /* this should always return 2 bytes */
1029 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
1030 ret);
1031 ret = -EIO;
1032 goto out2;
1033 }
1034 dev->mii.phy_id = *((u8 *)buf + 1);
1035
1036 if ((ret =
1037 ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 0, 0, buf)) < 0) {
1038 dbg("Set external PHY reset pin level: %d", ret);
1039 goto out2;
1040 }
1041 msleep(150);
1042 if ((ret =
1043 ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
1044 dbg("Set Internal/External PHY reset control: %d", ret);
1045 goto out2;
1046 }
1047 msleep(150);
1048
1049
1050 dev->net->set_multicast_list = ax8817x_set_multicast;
1051 dev->net->ethtool_ops = &ax88772_ethtool_ops;
1052
1053 ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
1054 ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
1055 ADVERTISE_ALL | ADVERTISE_CSMA);
1056 mii_nway_restart(&dev->mii);
1057
1058 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
1059 dbg("Write medium mode register: %d", ret);
1060 goto out2;
1061 }
1062
1063 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
1064 dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
1065 goto out2;
1066 }
1067 if ((ret =
1068 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
1069 dbg("Failed to set hardware MII: %02x", ret);
1070 goto out2;
1071 }
1072
1073 /* Set RX_CTL to default values with 2k buffer, and enable cactus */
1074 if ((ret =
1075 ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
1076 buf)) < 0) {
1077 dbg("Reset RX_CTL failed: %d", ret);
1078 goto out2;
1079 }
1080
1081 kfree(buf);
1082
1083 return 0;
1084
1085out2:
1086 kfree(buf);
1087out1:
1088 return ret;
1089}
1090
1091static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
1092{
1093 u32 *header;
1094 char *packet;
1095 struct sk_buff *ax_skb;
1096 u16 size;
1097
1098 header = (u32 *) skb->data;
1099 le32_to_cpus(header);
1100 packet = (char *)(header + 1);
1101
1102 skb_pull(skb, 4);
1103
1104 while (skb->len > 0) {
1105 if ((short)(*header & 0x0000ffff) !=
1106 ~((short)((*header & 0xffff0000) >> 16))) {
1107 devdbg(dev,"header length data is error");
1108 }
1109 /* get the packet length */
1110 size = (u16) (*header & 0x0000ffff);
1111
1112 if ((skb->len) - ((size + 1) & 0xfffe) == 0)
1113 return 2;
1114 if (size > ETH_FRAME_LEN) {
1115 devdbg(dev,"invalid rx length %d", size);
1116 return 0;
1117 }
1118 ax_skb = skb_clone(skb, GFP_ATOMIC);
1119 if (ax_skb) {
1120 ax_skb->len = size;
1121 ax_skb->data = packet;
1122 ax_skb->tail = packet + size;
1123 skb_return(dev, ax_skb);
1124 } else {
1125 return 0;
1126 }
1127
1128 skb_pull(skb, (size + 1) & 0xfffe);
1129
1130 if (skb->len == 0)
1131 break;
1132
1133 header = (u32 *) skb->data;
1134 le32_to_cpus(header);
1135 packet = (char *)(header + 1);
1136 skb_pull(skb, 4);
1137 }
1138
1139 if (skb->len < 0) {
1140 devdbg(dev,"invalid rx length %d", skb->len);
1141 return 0;
1142 }
1143 return 1;
1144}
1145
1146static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
1147 int flags)
1148{
1149 int padlen;
1150 int headroom = skb_headroom(skb);
1151 int tailroom = skb_tailroom(skb);
1152 u32 *packet_len;
1153 u32 *padbytes_ptr;
1154
1155 padlen = ((skb->len + 4) % 512) ? 0 : 4;
1156
1157 if ((!skb_cloned(skb))
1158 && ((headroom + tailroom) >= (4 + padlen))) {
1159 if ((headroom < 4) || (tailroom < padlen)) {
1160 skb->data = memmove(skb->head + 4, skb->data, skb->len);
1161 skb->tail = skb->data + skb->len;
1162 }
1163 } else {
1164 struct sk_buff *skb2;
1165 skb2 = skb_copy_expand(skb, 4, padlen, flags);
1166 dev_kfree_skb_any(skb);
1167 skb = skb2;
1168 if (!skb)
1169 return NULL;
1170 }
1171
1172 packet_len = (u32 *) skb_push(skb, 4);
1173
1174 packet_len = (u32 *) skb->data;
1175 *packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
1176
1177 if ((skb->len % 512) == 0) {
1178 padbytes_ptr = (u32 *) skb->tail;
1179 *padbytes_ptr = 0xffff0000;
1180 skb_put(skb, padlen);
1181 }
1182 return skb;
1183}
1184
1185static int ax88772_link_reset(struct usbnet *dev)
1186{
1187 u16 lpa;
1188 u16 mode;
1189
1190 mode = AX88772_MEDIUM_DEFAULT;
1191 lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
1192
1193 if ((lpa & LPA_DUPLEX) == 0)
1194 mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
1195 if ((lpa & LPA_100) == 0)
1196 mode &= ~AX88772_MEDIUM_100MB;
1197 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
1198
1199 return 0;
1200}
1201
1202static const struct driver_info ax8817x_info = {
1203 .description = "ASIX AX8817x USB 2.0 Ethernet",
1204 .bind = ax8817x_bind,
1205 .status = ax8817x_status,
1206 .link_reset = ax88172_link_reset,
1207 .reset = ax88172_link_reset,
1208 .flags = FLAG_ETHER,
1209 .data = 0x00130103,
1210};
1211
1212static const struct driver_info dlink_dub_e100_info = {
1213 .description = "DLink DUB-E100 USB Ethernet",
1214 .bind = ax8817x_bind,
1215 .status = ax8817x_status,
1216 .link_reset = ax88172_link_reset,
1217 .reset = ax88172_link_reset,
1218 .flags = FLAG_ETHER,
1219 .data = 0x009f9d9f,
1220};
1221
1222static const struct driver_info netgear_fa120_info = {
1223 .description = "Netgear FA-120 USB Ethernet",
1224 .bind = ax8817x_bind,
1225 .status = ax8817x_status,
1226 .link_reset = ax88172_link_reset,
1227 .reset = ax88172_link_reset,
1228 .flags = FLAG_ETHER,
1229 .data = 0x00130103,
1230};
1231
1232static const struct driver_info hawking_uf200_info = {
1233 .description = "Hawking UF200 USB Ethernet",
1234 .bind = ax8817x_bind,
1235 .status = ax8817x_status,
1236 .link_reset = ax88172_link_reset,
1237 .reset = ax88172_link_reset,
1238 .flags = FLAG_ETHER,
1239 .data = 0x001f1d1f,
1240};
1241
1242static const struct driver_info ax88772_info = {
1243 .description = "ASIX AX88772 USB 2.0 Ethernet",
1244 .bind = ax88772_bind,
1245 .status = ax8817x_status,
1246 .link_reset = ax88772_link_reset,
1247 .reset = ax88772_link_reset,
1248 .flags = FLAG_ETHER | FLAG_FRAMING_AX,
1249 .rx_fixup = ax88772_rx_fixup,
1250 .tx_fixup = ax88772_tx_fixup,
1251 .data = 0x00130103,
1252};
1253
1254#endif /* CONFIG_USB_AX8817X */
1255
1256
1257
1258#ifdef CONFIG_USB_BELKIN
1259#define HAVE_HARDWARE
1260
1261/*-------------------------------------------------------------------------
1262 *
1263 * Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller
1264 *
1265 * ... also two eTEK designs, including one sold as "Advance USBNET"
1266 *
1267 *-------------------------------------------------------------------------*/
1268
1269static const struct driver_info belkin_info = {
1270 .description = "Belkin, eTEK, or compatible",
1271};
1272
1273#endif /* CONFIG_USB_BELKIN */
1274
1275
1276
1277/*-------------------------------------------------------------------------
1278 *
1279 * Communications Device Class declarations.
1280 * Used by CDC Ethernet, and some CDC variants
1281 *
1282 *-------------------------------------------------------------------------*/
1283
1284#ifdef CONFIG_USB_CDCETHER
1285#define NEED_GENERIC_CDC
1286#endif
1287
1288#ifdef CONFIG_USB_ZAURUS
1289/* Ethernet variant uses funky framing, broken ethernet addressing */
1290#define NEED_GENERIC_CDC
1291#endif
1292
1293#ifdef CONFIG_USB_RNDIS
1294/* ACM variant uses even funkier framing, complex control RPC scheme */
1295#define NEED_GENERIC_CDC
1296#endif
1297
1298
1299#ifdef NEED_GENERIC_CDC
1300
1301#include <linux/usb_cdc.h>
1302
1303struct cdc_state {
1304 struct usb_cdc_header_desc *header;
1305 struct usb_cdc_union_desc *u;
1306 struct usb_cdc_ether_desc *ether;
1307 struct usb_interface *control;
1308 struct usb_interface *data;
1309};
1310
1311static struct usb_driver usbnet_driver;
1312
1313/*
1314 * probes control interface, claims data interface, collects the bulk
1315 * endpoints, activates data interface (if needed), maybe sets MTU.
1316 * all pure cdc, except for certain firmware workarounds.
1317 */
1318static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
1319{
1320 u8 *buf = intf->cur_altsetting->extra;
1321 int len = intf->cur_altsetting->extralen;
1322 struct usb_interface_descriptor *d;
1323 struct cdc_state *info = (void *) &dev->data;
1324 int status;
1325 int rndis;
1326
1327 if (sizeof dev->data < sizeof *info)
1328 return -EDOM;
1329
1330 /* expect strict spec conformance for the descriptors, but
1331 * cope with firmware which stores them in the wrong place
1332 */
1333 if (len == 0 && dev->udev->actconfig->extralen) {
1334 /* Motorola SB4100 (and others: Brad Hards says it's
1335 * from a Broadcom design) put CDC descriptors here
1336 */
1337 buf = dev->udev->actconfig->extra;
1338 len = dev->udev->actconfig->extralen;
1339 if (len)
1340 dev_dbg (&intf->dev,
1341 "CDC descriptors on config\n");
1342 }
1343
1344 /* this assumes that if there's a non-RNDIS vendor variant
1345 * of cdc-acm, it'll fail RNDIS requests cleanly.
1346 */
1347 rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
1348
1349 memset (info, 0, sizeof *info);
1350 info->control = intf;
1351 while (len > 3) {
1352 if (buf [1] != USB_DT_CS_INTERFACE)
1353 goto next_desc;
1354
1355 /* use bDescriptorSubType to identify the CDC descriptors.
1356 * We expect devices with CDC header and union descriptors.
1357 * For CDC Ethernet we need the ethernet descriptor.
1358 * For RNDIS, ignore two (pointless) CDC modem descriptors
1359 * in favor of a complicated OID-based RPC scheme doing what
1360 * CDC Ethernet achieves with a simple descriptor.
1361 */
1362 switch (buf [2]) {
1363 case USB_CDC_HEADER_TYPE:
1364 if (info->header) {
1365 dev_dbg (&intf->dev, "extra CDC header\n");
1366 goto bad_desc;
1367 }
1368 info->header = (void *) buf;
1369 if (info->header->bLength != sizeof *info->header) {
1370 dev_dbg (&intf->dev, "CDC header len %u\n",
1371 info->header->bLength);
1372 goto bad_desc;
1373 }
1374 break;
1375 case USB_CDC_UNION_TYPE:
1376 if (info->u) {
1377 dev_dbg (&intf->dev, "extra CDC union\n");
1378 goto bad_desc;
1379 }
1380 info->u = (void *) buf;
1381 if (info->u->bLength != sizeof *info->u) {
1382 dev_dbg (&intf->dev, "CDC union len %u\n",
1383 info->u->bLength);
1384 goto bad_desc;
1385 }
1386
1387 /* we need a master/control interface (what we're
1388 * probed with) and a slave/data interface; union
1389 * descriptors sort this all out.
1390 */
1391 info->control = usb_ifnum_to_if(dev->udev,
1392 info->u->bMasterInterface0);
1393 info->data = usb_ifnum_to_if(dev->udev,
1394 info->u->bSlaveInterface0);
1395 if (!info->control || !info->data) {
1396 dev_dbg (&intf->dev,
1397 "master #%u/%p slave #%u/%p\n",
1398 info->u->bMasterInterface0,
1399 info->control,
1400 info->u->bSlaveInterface0,
1401 info->data);
1402 goto bad_desc;
1403 }
1404 if (info->control != intf) {
1405 dev_dbg (&intf->dev, "bogus CDC Union\n");
1406 /* Ambit USB Cable Modem (and maybe others)
1407 * interchanges master and slave interface.
1408 */
1409 if (info->data == intf) {
1410 info->data = info->control;
1411 info->control = intf;
1412 } else
1413 goto bad_desc;
1414 }
1415
1416 /* a data interface altsetting does the real i/o */
1417 d = &info->data->cur_altsetting->desc;
1418 if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
1419 dev_dbg (&intf->dev, "slave class %u\n",
1420 d->bInterfaceClass);
1421 goto bad_desc;
1422 }
1423 break;
1424 case USB_CDC_ETHERNET_TYPE:
1425 if (info->ether) {
1426 dev_dbg (&intf->dev, "extra CDC ether\n");
1427 goto bad_desc;
1428 }
1429 info->ether = (void *) buf;
1430 if (info->ether->bLength != sizeof *info->ether) {
1431 dev_dbg (&intf->dev, "CDC ether len %u\n",
1432 info->ether->bLength);
1433 goto bad_desc;
1434 }
1435 dev->net->mtu = le16_to_cpup (
1436 &info->ether->wMaxSegmentSize)
1437 - ETH_HLEN;
1438 /* because of Zaurus, we may be ignoring the host
1439 * side link address we were given.
1440 */
1441 break;
1442 }
1443next_desc:
1444 len -= buf [0]; /* bLength */
1445 buf += buf [0];
1446 }
1447
1448 if (!info->header || !info->u || (!rndis && !info->ether)) {
1449 dev_dbg (&intf->dev, "missing cdc %s%s%sdescriptor\n",
1450 info->header ? "" : "header ",
1451 info->u ? "" : "union ",
1452 info->ether ? "" : "ether ");
1453 goto bad_desc;
1454 }
1455
1456 /* claim data interface and set it up ... with side effects.
1457 * network traffic can't flow until an altsetting is enabled.
1458 */
1459 status = usb_driver_claim_interface (&usbnet_driver, info->data, dev);
1460 if (status < 0)
1461 return status;
1462 status = get_endpoints (dev, info->data);
1463 if (status < 0) {
1464 /* ensure immediate exit from usbnet_disconnect */
1465 usb_set_intfdata(info->data, NULL);
1466 usb_driver_release_interface (&usbnet_driver, info->data);
1467 return status;
1468 }
1469
1470 /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
1471 dev->status = NULL;
1472 if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
1473 struct usb_endpoint_descriptor *desc;
1474
1475 dev->status = &info->control->cur_altsetting->endpoint [0];
1476 desc = &dev->status->desc;
1477 if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
1478 || !(desc->bEndpointAddress & USB_DIR_IN)
1479 || (le16_to_cpu(desc->wMaxPacketSize)
1480 < sizeof (struct usb_cdc_notification))
1481 || !desc->bInterval) {
1482 dev_dbg (&intf->dev, "bad notification endpoint\n");
1483 dev->status = NULL;
1484 }
1485 }
1486 if (rndis && !dev->status) {
1487 dev_dbg (&intf->dev, "missing RNDIS status endpoint\n");
1488 usb_set_intfdata(info->data, NULL);
1489 usb_driver_release_interface (&usbnet_driver, info->data);
1490 return -ENODEV;
1491 }
1492 return 0;
1493
1494bad_desc:
1495 dev_info (&dev->udev->dev, "bad CDC descriptors\n");
1496 return -ENODEV;
1497}
1498
1499static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
1500{
1501 struct cdc_state *info = (void *) &dev->data;
1502
1503 /* disconnect master --> disconnect slave */
1504 if (intf == info->control && info->data) {
1505 /* ensure immediate exit from usbnet_disconnect */
1506 usb_set_intfdata(info->data, NULL);
1507 usb_driver_release_interface (&usbnet_driver, info->data);
1508 info->data = NULL;
1509 }
1510
1511 /* and vice versa (just in case) */
1512 else if (intf == info->data && info->control) {
1513 /* ensure immediate exit from usbnet_disconnect */
1514 usb_set_intfdata(info->control, NULL);
1515 usb_driver_release_interface (&usbnet_driver, info->control);
1516 info->control = NULL;
1517 }
1518}
1519
1520#endif /* NEED_GENERIC_CDC */
1521
1522
1523#ifdef CONFIG_USB_CDCETHER
1524#define HAVE_HARDWARE
1525
1526/*-------------------------------------------------------------------------
1527 *
1528 * Communications Device Class, Ethernet Control model
1529 *
1530 * Takes two interfaces. The DATA interface is inactive till an altsetting
1531 * is selected. Configuration data includes class descriptors.
1532 *
1533 * This should interop with whatever the 2.4 "CDCEther.c" driver
1534 * (by Brad Hards) talked with.
1535 *
1536 *-------------------------------------------------------------------------*/
1537
1538#include <linux/ctype.h>
1539
1540
1541static void dumpspeed (struct usbnet *dev, __le32 *speeds)
1542{
1543 if (netif_msg_timer (dev))
1544 devinfo (dev, "link speeds: %u kbps up, %u kbps down",
1545 __le32_to_cpu(speeds[0]) / 1000,
1546 __le32_to_cpu(speeds[1]) / 1000);
1547}
1548
1549static void cdc_status (struct usbnet *dev, struct urb *urb)
1550{
1551 struct usb_cdc_notification *event;
1552
1553 if (urb->actual_length < sizeof *event)
1554 return;
1555
1556 /* SPEED_CHANGE can get split into two 8-byte packets */
1557 if (test_and_clear_bit (EVENT_STS_SPLIT, &dev->flags)) {
1558 dumpspeed (dev, (__le32 *) urb->transfer_buffer);
1559 return;
1560 }
1561
1562 event = urb->transfer_buffer;
1563 switch (event->bNotificationType) {
1564 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
1565 if (netif_msg_timer (dev))
1566 devdbg (dev, "CDC: carrier %s",
1567 event->wValue ? "on" : "off");
1568 if (event->wValue)
1569 netif_carrier_on(dev->net);
1570 else
1571 netif_carrier_off(dev->net);
1572 break;
1573 case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
1574 if (netif_msg_timer (dev))
1575 devdbg (dev, "CDC: speed change (len %d)",
1576 urb->actual_length);
1577 if (urb->actual_length != (sizeof *event + 8))
1578 set_bit (EVENT_STS_SPLIT, &dev->flags);
1579 else
1580 dumpspeed (dev, (__le32 *) &event[1]);
1581 break;
1582 // case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: /* RNDIS; or unsolicited */
1583 default:
1584 deverr (dev, "CDC: unexpected notification %02x!",
1585 event->bNotificationType);
1586 break;
1587 }
1588}
1589
1590static u8 nibble (unsigned char c)
1591{
1592 if (likely (isdigit (c)))
1593 return c - '0';
1594 c = toupper (c);
1595 if (likely (isxdigit (c)))
1596 return 10 + c - 'A';
1597 return 0;
1598}
1599
1600static inline int
1601get_ethernet_addr (struct usbnet *dev, struct usb_cdc_ether_desc *e)
1602{
1603 int tmp, i;
1604 unsigned char buf [13];
1605
1606 tmp = usb_string (dev->udev, e->iMACAddress, buf, sizeof buf);
1607 if (tmp != 12) {
1608 dev_dbg (&dev->udev->dev,
1609 "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
1610 if (tmp >= 0)
1611 tmp = -EINVAL;
1612 return tmp;
1613 }
1614 for (i = tmp = 0; i < 6; i++, tmp += 2)
1615 dev->net->dev_addr [i] =
1616 (nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]);
1617 return 0;
1618}
1619
1620static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
1621{
1622 int status;
1623 struct cdc_state *info = (void *) &dev->data;
1624
1625 status = generic_cdc_bind (dev, intf);
1626 if (status < 0)
1627 return status;
1628
1629 status = get_ethernet_addr (dev, info->ether);
1630 if (status < 0) {
1631 usb_set_intfdata(info->data, NULL);
1632 usb_driver_release_interface (&usbnet_driver, info->data);
1633 return status;
1634 }
1635
1636 /* FIXME cdc-ether has some multicast code too, though it complains
1637 * in routine cases. info->ether describes the multicast support.
1638 */
1639 return 0;
1640}
1641
1642static const struct driver_info cdc_info = {
1643 .description = "CDC Ethernet Device",
1644 .flags = FLAG_ETHER,
1645 // .check_connect = cdc_check_connect,
1646 .bind = cdc_bind,
1647 .unbind = cdc_unbind,
1648 .status = cdc_status,
1649};
1650
1651#endif /* CONFIG_USB_CDCETHER */
1652
1653
1654
1655#ifdef CONFIG_USB_EPSON2888
1656#define HAVE_HARDWARE
1657
1658/*-------------------------------------------------------------------------
1659 *
1660 * EPSON USB clients
1661 *
1662 * This is the same idea as Linux PDAs (below) except the firmware in the
1663 * device might not be Tux-powered. Epson provides reference firmware that
1664 * implements this interface. Product developers can reuse or modify that
1665 * code, such as by using their own product and vendor codes.
1666 *
1667 * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
1668 *
1669 *-------------------------------------------------------------------------*/
1670
1671static const struct driver_info epson2888_info = {
1672 .description = "Epson USB Device",
1673 .check_connect = always_connected,
1674
1675 .in = 4, .out = 3,
1676};
1677
1678#endif /* CONFIG_USB_EPSON2888 */
1679
1680
1681#ifdef CONFIG_USB_GENESYS
1682#define HAVE_HARDWARE
1683
1684/*-------------------------------------------------------------------------
1685 *
1686 * GeneSys GL620USB-A (www.genesyslogic.com.tw)
1687 *
1688 * ... should partially interop with the Win32 driver for this hardware
1689 * The GeneSys docs imply there's some NDIS issue motivating this framing.
1690 *
1691 * Some info from GeneSys:
1692 * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
1693 * (Some cables, like the BAFO-100c, use the half duplex version.)
1694 * - For the full duplex model, the low bit of the version code says
1695 * which side is which ("left/right").
1696 * - For the half duplex type, a control/interrupt handshake settles
1697 * the transfer direction. (That's disabled here, partially coded.)
1698 * A control URB would block until other side writes an interrupt.
1699 *
1700 * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
1701 * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
1702 *
1703 *-------------------------------------------------------------------------*/
1704
1705// control msg write command
1706#define GENELINK_CONNECT_WRITE 0xF0
1707// interrupt pipe index
1708#define GENELINK_INTERRUPT_PIPE 0x03
1709// interrupt read buffer size
1710#define INTERRUPT_BUFSIZE 0x08
1711// interrupt pipe interval value
1712#define GENELINK_INTERRUPT_INTERVAL 0x10
1713// max transmit packet number per transmit
1714#define GL_MAX_TRANSMIT_PACKETS 32
1715// max packet length
1716#define GL_MAX_PACKET_LEN 1514
1717// max receive buffer size
1718#define GL_RCV_BUF_SIZE \
1719 (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
1720
1721struct gl_packet {
1722 u32 packet_length;
1723 char packet_data [1];
1724};
1725
1726struct gl_header {
1727 u32 packet_count;
1728 struct gl_packet packets;
1729};
1730
1731#ifdef GENELINK_ACK
1732
1733// FIXME: this code is incomplete, not debugged; it doesn't
1734// handle interrupts correctly. interrupts should be generic
1735// code like all other device I/O, anyway.
1736
1737struct gl_priv {
1738 struct urb *irq_urb;
1739 char irq_buf [INTERRUPT_BUFSIZE];
1740};
1741
1742static inline int gl_control_write (struct usbnet *dev, u8 request, u16 value)
1743{
1744 int retval;
1745
1746 retval = usb_control_msg (dev->udev,
1747 usb_sndctrlpipe (dev->udev, 0),
1748 request,
1749 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1750 value,
1751 0, // index
1752 0, // data buffer
1753 0, // size
1754 CONTROL_TIMEOUT_MS);
1755 return retval;
1756}
1757
1758static void gl_interrupt_complete (struct urb *urb, struct pt_regs *regs)
1759{
1760 int status = urb->status;
1761
1762 switch (status) {
1763 case 0:
1764 /* success */
1765 break;
1766 case -ECONNRESET:
1767 case -ENOENT:
1768 case -ESHUTDOWN:
1769 /* this urb is terminated, clean up */
1770 dbg("%s - urb shutting down with status: %d",
1771 __FUNCTION__, status);
1772 return;
1773 default:
1774 dbg("%s - nonzero urb status received: %d",
1775 __FUNCTION__, urb->status);
1776 }
1777
1778 status = usb_submit_urb (urb, GFP_ATOMIC);
1779 if (status)
1780 err ("%s - usb_submit_urb failed with result %d",
1781 __FUNCTION__, status);
1782}
1783
1784static int gl_interrupt_read (struct usbnet *dev)
1785{
1786 struct gl_priv *priv = dev->priv_data;
1787 int retval;
1788
1789 // issue usb interrupt read
1790 if (priv && priv->irq_urb) {
1791 // submit urb
1792 if ((retval = usb_submit_urb (priv->irq_urb, GFP_KERNEL)) != 0)
1793 dbg ("gl_interrupt_read: submit fail - %X...", retval);
1794 else
1795 dbg ("gl_interrupt_read: submit success...");
1796 }
1797
1798 return 0;
1799}
1800
1801// check whether another side is connected
1802static int genelink_check_connect (struct usbnet *dev)
1803{
1804 int retval;
1805
1806 dbg ("genelink_check_connect...");
1807
1808 // detect whether another side is connected
1809 if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
1810 dbg ("%s: genelink_check_connect write fail - %X",
1811 dev->net->name, retval);
1812 return retval;
1813 }
1814
1815 // usb interrupt read to ack another side
1816 if ((retval = gl_interrupt_read (dev)) != 0) {
1817 dbg ("%s: genelink_check_connect read fail - %X",
1818 dev->net->name, retval);
1819 return retval;
1820 }
1821
1822 dbg ("%s: genelink_check_connect read success", dev->net->name);
1823 return 0;
1824}
1825
1826// allocate and initialize the private data for genelink
1827static int genelink_init (struct usbnet *dev)
1828{
1829 struct gl_priv *priv;
1830
1831 // allocate the private data structure
1832 if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) {
1833 dbg ("%s: cannot allocate private data per device",
1834 dev->net->name);
1835 return -ENOMEM;
1836 }
1837
1838 // allocate irq urb
1839 if ((priv->irq_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
1840 dbg ("%s: cannot allocate private irq urb per device",
1841 dev->net->name);
1842 kfree (priv);
1843 return -ENOMEM;
1844 }
1845
1846 // fill irq urb
1847 usb_fill_int_urb (priv->irq_urb, dev->udev,
1848 usb_rcvintpipe (dev->udev, GENELINK_INTERRUPT_PIPE),
1849 priv->irq_buf, INTERRUPT_BUFSIZE,
1850 gl_interrupt_complete, 0,
1851 GENELINK_INTERRUPT_INTERVAL);
1852
1853 // set private data pointer
1854 dev->priv_data = priv;
1855
1856 return 0;
1857}
1858
1859// release the private data
1860static int genelink_free (struct usbnet *dev)
1861{
1862 struct gl_priv *priv = dev->priv_data;
1863
1864 if (!priv)
1865 return 0;
1866
1867// FIXME: can't cancel here; it's synchronous, and
1868// should have happened earlier in any case (interrupt
1869// handling needs to be generic)
1870
1871 // cancel irq urb first
1872 usb_kill_urb (priv->irq_urb);
1873
1874 // free irq urb
1875 usb_free_urb (priv->irq_urb);
1876
1877 // free the private data structure
1878 kfree (priv);
1879
1880 return 0;
1881}
1882
1883#endif
1884
1885static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
1886{
1887 struct gl_header *header;
1888 struct gl_packet *packet;
1889 struct sk_buff *gl_skb;
1890 u32 size;
1891
1892 header = (struct gl_header *) skb->data;
1893
1894 // get the packet count of the received skb
1895 le32_to_cpus (&header->packet_count);
1896 if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
1897 || (header->packet_count < 0)) {
1898 dbg ("genelink: invalid received packet count %d",
1899 header->packet_count);
1900 return 0;
1901 }
1902
1903 // set the current packet pointer to the first packet
1904 packet = &header->packets;
1905
1906 // decrement the length for the packet count size 4 bytes
1907 skb_pull (skb, 4);
1908
1909 while (header->packet_count > 1) {
1910 // get the packet length
1911 size = packet->packet_length;
1912
1913 // this may be a broken packet
1914 if (size > GL_MAX_PACKET_LEN) {
1915 dbg ("genelink: invalid rx length %d", size);
1916 return 0;
1917 }
1918
1919 // allocate the skb for the individual packet
1920 gl_skb = alloc_skb (size, GFP_ATOMIC);
1921 if (gl_skb) {
1922
1923 // copy the packet data to the new skb
1924 memcpy(skb_put(gl_skb, size), packet->packet_data, size);
1925 skb_return (dev, gl_skb);
1926 }
1927
1928 // advance to the next packet
1929 packet = (struct gl_packet *)
1930 &packet->packet_data [size];
1931 header->packet_count--;
1932
1933 // shift the data pointer to the next gl_packet
1934 skb_pull (skb, size + 4);
1935 }
1936
1937 // skip the packet length field 4 bytes
1938 skb_pull (skb, 4);
1939
1940 if (skb->len > GL_MAX_PACKET_LEN) {
1941 dbg ("genelink: invalid rx length %d", skb->len);
1942 return 0;
1943 }
1944 return 1;
1945}
1946
1947static struct sk_buff *
1948genelink_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
1949{
1950 int padlen;
1951 int length = skb->len;
1952 int headroom = skb_headroom (skb);
1953 int tailroom = skb_tailroom (skb);
1954 u32 *packet_count;
1955 u32 *packet_len;
1956
1957 // FIXME: magic numbers, bleech
1958 padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
1959
1960 if ((!skb_cloned (skb))
1961 && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
1962 if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
1963 skb->data = memmove (skb->head + (4 + 4*1),
1964 skb->data, skb->len);
1965 skb->tail = skb->data + skb->len;
1966 }
1967 } else {
1968 struct sk_buff *skb2;
1969 skb2 = skb_copy_expand (skb, (4 + 4*1) , padlen, flags);
1970 dev_kfree_skb_any (skb);
1971 skb = skb2;
1972 if (!skb)
1973 return NULL;
1974 }
1975
1976 // attach the packet count to the header
1977 packet_count = (u32 *) skb_push (skb, (4 + 4*1));
1978 packet_len = packet_count + 1;
1979
1980 // FIXME little endian?
1981 *packet_count = 1;
1982 *packet_len = length;
1983
1984 // add padding byte
1985 if ((skb->len % dev->maxpacket) == 0)
1986 skb_put (skb, 1);
1987
1988 return skb;
1989}
1990
1991static const struct driver_info genelink_info = {
1992 .description = "Genesys GeneLink",
1993 .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT,
1994 .rx_fixup = genelink_rx_fixup,
1995 .tx_fixup = genelink_tx_fixup,
1996
1997 .in = 1, .out = 2,
1998
1999#ifdef GENELINK_ACK
2000 .check_connect =genelink_check_connect,
2001#endif
2002};
2003
2004#endif /* CONFIG_USB_GENESYS */
2005
2006
2007
2008#ifdef CONFIG_USB_NET1080
2009#define HAVE_HARDWARE
2010
2011/*-------------------------------------------------------------------------
2012 *
2013 * Netchip 1080 driver ... http://www.netchip.com
2014 * Used in LapLink cables
2015 *
2016 *-------------------------------------------------------------------------*/
2017
2018#define dev_packet_id data[0]
2019#define frame_errors data[1]
2020
2021/*
2022 * NetChip framing of ethernet packets, supporting additional error
2023 * checks for links that may drop bulk packets from inside messages.
2024 * Odd USB length == always short read for last usb packet.
2025 * - nc_header
2026 * - Ethernet header (14 bytes)
2027 * - payload
2028 * - (optional padding byte, if needed so length becomes odd)
2029 * - nc_trailer
2030 *
2031 * This framing is to be avoided for non-NetChip devices.
2032 */
2033
2034struct nc_header { // packed:
2035 __le16 hdr_len; // sizeof nc_header (LE, all)
2036 __le16 packet_len; // payload size (including ethhdr)
2037 __le16 packet_id; // detects dropped packets
2038#define MIN_HEADER 6
2039
2040 // all else is optional, and must start with:
2041 // u16 vendorId; // from usb-if
2042 // u16 productId;
2043} __attribute__((__packed__));
2044
2045#define PAD_BYTE ((unsigned char)0xAC)
2046
2047struct nc_trailer {
2048 __le16 packet_id;
2049} __attribute__((__packed__));
2050
2051// packets may use FLAG_FRAMING_NC and optional pad
2052#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
2053 + sizeof (struct ethhdr) \
2054 + (mtu) \
2055 + 1 \
2056 + sizeof (struct nc_trailer))
2057
2058#define MIN_FRAMED FRAMED_SIZE(0)
2059
2060
2061/*
2062 * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
2063 * before the hardware drops it. If that's done, the driver will need to
2064 * frame network packets to guard against the dropped USB packets. The win32
2065 * driver sets this for both sides of the link.
2066 */
2067#define NC_READ_TTL_MS ((u8)255) // ms
2068
2069/*
2070 * We ignore most registers and EEPROM contents.
2071 */
2072#define REG_USBCTL ((u8)0x04)
2073#define REG_TTL ((u8)0x10)
2074#define REG_STATUS ((u8)0x11)
2075
2076/*
2077 * Vendor specific requests to read/write data
2078 */
2079#define REQUEST_REGISTER ((u8)0x10)
2080#define REQUEST_EEPROM ((u8)0x11)
2081
2082static int
2083nc_vendor_read (struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
2084{
2085 int status = usb_control_msg (dev->udev,
2086 usb_rcvctrlpipe (dev->udev, 0),
2087 req,
2088 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2089 0, regnum,
2090 retval_ptr, sizeof *retval_ptr,
2091 CONTROL_TIMEOUT_MS);
2092 if (status > 0)
2093 status = 0;
2094 if (!status)
2095 le16_to_cpus (retval_ptr);
2096 return status;
2097}
2098
2099static inline int
2100nc_register_read (struct usbnet *dev, u8 regnum, u16 *retval_ptr)
2101{
2102 return nc_vendor_read (dev, REQUEST_REGISTER, regnum, retval_ptr);
2103}
2104
2105// no retval ... can become async, usable in_interrupt()
2106static void
2107nc_vendor_write (struct usbnet *dev, u8 req, u8 regnum, u16 value)
2108{
2109 usb_control_msg (dev->udev,
2110 usb_sndctrlpipe (dev->udev, 0),
2111 req,
2112 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2113 value, regnum,
2114 NULL, 0, // data is in setup packet
2115 CONTROL_TIMEOUT_MS);
2116}
2117
2118static inline void
2119nc_register_write (struct usbnet *dev, u8 regnum, u16 value)
2120{
2121 nc_vendor_write (dev, REQUEST_REGISTER, regnum, value);
2122}
2123
2124
2125#if 0
2126static void nc_dump_registers (struct usbnet *dev)
2127{
2128 u8 reg;
2129 u16 *vp = kmalloc (sizeof (u16));
2130
2131 if (!vp) {
2132 dbg ("no memory?");
2133 return;
2134 }
2135
2136 dbg ("%s registers:", dev->net->name);
2137 for (reg = 0; reg < 0x20; reg++) {
2138 int retval;
2139
2140 // reading some registers is trouble
2141 if (reg >= 0x08 && reg <= 0xf)
2142 continue;
2143 if (reg >= 0x12 && reg <= 0x1e)
2144 continue;
2145
2146 retval = nc_register_read (dev, reg, vp);
2147 if (retval < 0)
2148 dbg ("%s reg [0x%x] ==> error %d",
2149 dev->net->name, reg, retval);
2150 else
2151 dbg ("%s reg [0x%x] = 0x%x",
2152 dev->net->name, reg, *vp);
2153 }
2154 kfree (vp);
2155}
2156#endif
2157
2158
2159/*-------------------------------------------------------------------------*/
2160
2161/*
2162 * Control register
2163 */
2164
2165#define USBCTL_WRITABLE_MASK 0x1f0f
2166// bits 15-13 reserved, r/o
2167#define USBCTL_ENABLE_LANG (1 << 12)
2168#define USBCTL_ENABLE_MFGR (1 << 11)
2169#define USBCTL_ENABLE_PROD (1 << 10)
2170#define USBCTL_ENABLE_SERIAL (1 << 9)
2171#define USBCTL_ENABLE_DEFAULTS (1 << 8)
2172// bits 7-4 reserved, r/o
2173#define USBCTL_FLUSH_OTHER (1 << 3)
2174#define USBCTL_FLUSH_THIS (1 << 2)
2175#define USBCTL_DISCONN_OTHER (1 << 1)
2176#define USBCTL_DISCONN_THIS (1 << 0)
2177
2178static inline void nc_dump_usbctl (struct usbnet *dev, u16 usbctl)
2179{
2180 if (!netif_msg_link (dev))
2181 return;
2182 devdbg (dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
2183 " this%s%s;"
2184 " other%s%s; r/o 0x%x",
2185 dev->udev->bus->bus_name, dev->udev->devpath,
2186 usbctl,
2187 (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
2188 (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
2189 (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
2190 (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
2191 (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
2192
2193 (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
2194 (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
2195 (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
2196 (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
2197 usbctl & ~USBCTL_WRITABLE_MASK
2198 );
2199}
2200
2201/*-------------------------------------------------------------------------*/
2202
2203/*
2204 * Status register
2205 */
2206
2207#define STATUS_PORT_A (1 << 15)
2208
2209#define STATUS_CONN_OTHER (1 << 14)
2210#define STATUS_SUSPEND_OTHER (1 << 13)
2211#define STATUS_MAILBOX_OTHER (1 << 12)
2212#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
2213
2214#define STATUS_CONN_THIS (1 << 6)
2215#define STATUS_SUSPEND_THIS (1 << 5)
2216#define STATUS_MAILBOX_THIS (1 << 4)
2217#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
2218
2219#define STATUS_UNSPEC_MASK 0x0c8c
2220#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
2221
2222
2223static inline void nc_dump_status (struct usbnet *dev, u16 status)
2224{
2225 if (!netif_msg_link (dev))
2226 return;
2227 devdbg (dev, "net1080 %s-%s status 0x%x:"
2228 " this (%c) PKT=%d%s%s%s;"
2229 " other PKT=%d%s%s%s; unspec 0x%x",
2230 dev->udev->bus->bus_name, dev->udev->devpath,
2231 status,
2232
2233 // XXX the packet counts don't seem right
2234 // (1 at reset, not 0); maybe UNSPEC too
2235
2236 (status & STATUS_PORT_A) ? 'A' : 'B',
2237 STATUS_PACKETS_THIS (status),
2238 (status & STATUS_CONN_THIS) ? " CON" : "",
2239 (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
2240 (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
2241
2242 STATUS_PACKETS_OTHER (status),
2243 (status & STATUS_CONN_OTHER) ? " CON" : "",
2244 (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
2245 (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
2246
2247 status & STATUS_UNSPEC_MASK
2248 );
2249}
2250
2251/*-------------------------------------------------------------------------*/
2252
2253/*
2254 * TTL register
2255 */
2256
2257#define TTL_THIS(ttl) (0x00ff & ttl)
2258#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
2259#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
2260
2261static inline void nc_dump_ttl (struct usbnet *dev, u16 ttl)
2262{
2263 if (netif_msg_link (dev))
2264 devdbg (dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
2265 dev->udev->bus->bus_name, dev->udev->devpath,
2266 ttl, TTL_THIS (ttl), TTL_OTHER (ttl));
2267}
2268
2269/*-------------------------------------------------------------------------*/
2270
2271static int net1080_reset (struct usbnet *dev)
2272{
2273 u16 usbctl, status, ttl;
2274 u16 *vp = kmalloc (sizeof (u16), GFP_KERNEL);
2275 int retval;
2276
2277 if (!vp)
2278 return -ENOMEM;
2279
2280 // nc_dump_registers (dev);
2281
2282 if ((retval = nc_register_read (dev, REG_STATUS, vp)) < 0) {
2283 dbg ("can't read %s-%s status: %d",
2284 dev->udev->bus->bus_name, dev->udev->devpath, retval);
2285 goto done;
2286 }
2287 status = *vp;
2288 nc_dump_status (dev, status);
2289
2290 if ((retval = nc_register_read (dev, REG_USBCTL, vp)) < 0) {
2291 dbg ("can't read USBCTL, %d", retval);
2292 goto done;
2293 }
2294 usbctl = *vp;
2295 nc_dump_usbctl (dev, usbctl);
2296
2297 nc_register_write (dev, REG_USBCTL,
2298 USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
2299
2300 if ((retval = nc_register_read (dev, REG_TTL, vp)) < 0) {
2301 dbg ("can't read TTL, %d", retval);
2302 goto done;
2303 }
2304 ttl = *vp;
2305 // nc_dump_ttl (dev, ttl);
2306
2307 nc_register_write (dev, REG_TTL,
2308 MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) );
2309 dbg ("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
2310
2311 if (netif_msg_link (dev))
2312 devinfo (dev, "port %c, peer %sconnected",
2313 (status & STATUS_PORT_A) ? 'A' : 'B',
2314 (status & STATUS_CONN_OTHER) ? "" : "dis"
2315 );
2316 retval = 0;
2317
2318done:
2319 kfree (vp);
2320 return retval;
2321}
2322
2323static int net1080_check_connect (struct usbnet *dev)
2324{
2325 int retval;
2326 u16 status;
2327 u16 *vp = kmalloc (sizeof (u16), GFP_KERNEL);
2328
2329 if (!vp)
2330 return -ENOMEM;
2331 retval = nc_register_read (dev, REG_STATUS, vp);
2332 status = *vp;
2333 kfree (vp);
2334 if (retval != 0) {
2335 dbg ("%s net1080_check_conn read - %d", dev->net->name, retval);
2336 return retval;
2337 }
2338 if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
2339 return -ENOLINK;
2340 return 0;
2341}
2342
2343static void nc_flush_complete (struct urb *urb, struct pt_regs *regs)
2344{
2345 kfree (urb->context);
2346 usb_free_urb(urb);
2347}
2348
2349static void nc_ensure_sync (struct usbnet *dev)
2350{
2351 dev->frame_errors++;
2352 if (dev->frame_errors > 5) {
2353 struct urb *urb;
2354 struct usb_ctrlrequest *req;
2355 int status;
2356
2357 /* Send a flush */
2358 urb = usb_alloc_urb (0, SLAB_ATOMIC);
2359 if (!urb)
2360 return;
2361
2362 req = kmalloc (sizeof *req, GFP_ATOMIC);
2363 if (!req) {
2364 usb_free_urb (urb);
2365 return;
2366 }
2367
2368 req->bRequestType = USB_DIR_OUT
2369 | USB_TYPE_VENDOR
2370 | USB_RECIP_DEVICE;
2371 req->bRequest = REQUEST_REGISTER;
2372 req->wValue = cpu_to_le16 (USBCTL_FLUSH_THIS
2373 | USBCTL_FLUSH_OTHER);
2374 req->wIndex = cpu_to_le16 (REG_USBCTL);
2375 req->wLength = cpu_to_le16 (0);
2376
2377 /* queue an async control request, we don't need
2378 * to do anything when it finishes except clean up.
2379 */
2380 usb_fill_control_urb (urb, dev->udev,
2381 usb_sndctrlpipe (dev->udev, 0),
2382 (unsigned char *) req,
2383 NULL, 0,
2384 nc_flush_complete, req);
2385 status = usb_submit_urb (urb, GFP_ATOMIC);
2386 if (status) {
2387 kfree (req);
2388 usb_free_urb (urb);
2389 return;
2390 }
2391
2392 if (netif_msg_rx_err (dev))
2393 devdbg (dev, "flush net1080; too many framing errors");
2394 dev->frame_errors = 0;
2395 }
2396}
2397
2398static int net1080_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
2399{
2400 struct nc_header *header;
2401 struct nc_trailer *trailer;
2402 u16 hdr_len, packet_len;
2403
2404 if (!(skb->len & 0x01)
2405 || MIN_FRAMED > skb->len
2406 || skb->len > FRAMED_SIZE (dev->net->mtu)) {
2407 dev->stats.rx_frame_errors++;
2408 dbg ("rx framesize %d range %d..%d mtu %d", skb->len,
2409 (int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net->mtu),
2410 dev->net->mtu);
2411 nc_ensure_sync (dev);
2412 return 0;
2413 }
2414
2415 header = (struct nc_header *) skb->data;
2416 hdr_len = le16_to_cpup (&header->hdr_len);
2417 packet_len = le16_to_cpup (&header->packet_len);
2418 if (FRAMED_SIZE (packet_len) > MAX_PACKET) {
2419 dev->stats.rx_frame_errors++;
2420 dbg ("packet too big, %d", packet_len);
2421 nc_ensure_sync (dev);
2422 return 0;
2423 } else if (hdr_len < MIN_HEADER) {
2424 dev->stats.rx_frame_errors++;
2425 dbg ("header too short, %d", hdr_len);
2426 nc_ensure_sync (dev);
2427 return 0;
2428 } else if (hdr_len > MIN_HEADER) {
2429 // out of band data for us?
2430 dbg ("header OOB, %d bytes", hdr_len - MIN_HEADER);
2431 nc_ensure_sync (dev);
2432 // switch (vendor/product ids) { ... }
2433 }
2434 skb_pull (skb, hdr_len);
2435
2436 trailer = (struct nc_trailer *)
2437 (skb->data + skb->len - sizeof *trailer);
2438 skb_trim (skb, skb->len - sizeof *trailer);
2439
2440 if ((packet_len & 0x01) == 0) {
2441 if (skb->data [packet_len] != PAD_BYTE) {
2442 dev->stats.rx_frame_errors++;
2443 dbg ("bad pad");
2444 return 0;
2445 }
2446 skb_trim (skb, skb->len - 1);
2447 }
2448 if (skb->len != packet_len) {
2449 dev->stats.rx_frame_errors++;
2450 dbg ("bad packet len %d (expected %d)",
2451 skb->len, packet_len);
2452 nc_ensure_sync (dev);
2453 return 0;
2454 }
2455 if (header->packet_id != get_unaligned (&trailer->packet_id)) {
2456 dev->stats.rx_fifo_errors++;
2457 dbg ("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
2458 le16_to_cpu (header->packet_id),
2459 le16_to_cpu (trailer->packet_id));
2460 return 0;
2461 }
2462#if 0
2463 devdbg (dev, "frame <rx h %d p %d id %d", header->hdr_len,
2464 header->packet_len, header->packet_id);
2465#endif
2466 dev->frame_errors = 0;
2467 return 1;
2468}
2469
2470static struct sk_buff *
2471net1080_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
2472{
2473 int padlen;
2474 struct sk_buff *skb2;
2475
2476 padlen = ((skb->len + sizeof (struct nc_header)
2477 + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
2478 if (!skb_cloned (skb)) {
2479 int headroom = skb_headroom (skb);
2480 int tailroom = skb_tailroom (skb);
2481
2482 if ((padlen + sizeof (struct nc_trailer)) <= tailroom
2483 && sizeof (struct nc_header) <= headroom)
2484 /* There's enough head and tail room */
2485 return skb;
2486
2487 if ((sizeof (struct nc_header) + padlen
2488 + sizeof (struct nc_trailer)) <
2489 (headroom + tailroom)) {
2490 /* There's enough total room, so just readjust */
2491 skb->data = memmove (skb->head
2492 + sizeof (struct nc_header),
2493 skb->data, skb->len);
2494 skb->tail = skb->data + skb->len;
2495 return skb;
2496 }
2497 }
2498
2499 /* Create a new skb to use with the correct size */
2500 skb2 = skb_copy_expand (skb,
2501 sizeof (struct nc_header),
2502 sizeof (struct nc_trailer) + padlen,
2503 flags);
2504 dev_kfree_skb_any (skb);
2505 return skb2;
2506}
2507
2508static const struct driver_info net1080_info = {
2509 .description = "NetChip TurboCONNECT",
2510 .flags = FLAG_FRAMING_NC,
2511 .reset = net1080_reset,
2512 .check_connect =net1080_check_connect,
2513 .rx_fixup = net1080_rx_fixup,
2514 .tx_fixup = net1080_tx_fixup,
2515};
2516
2517#endif /* CONFIG_USB_NET1080 */
2518
2519
2520
2521#ifdef CONFIG_USB_PL2301
2522#define HAVE_HARDWARE
2523
2524/*-------------------------------------------------------------------------
2525 *
2526 * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
2527 *
2528 * The protocol and handshaking used here should be bug-compatible
2529 * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
2530 *
2531 *-------------------------------------------------------------------------*/
2532
2533/*
2534 * Bits 0-4 can be used for software handshaking; they're set from
2535 * one end, cleared from the other, "read" with the interrupt byte.
2536 */
2537#define PL_S_EN (1<<7) /* (feature only) suspend enable */
2538/* reserved bit -- rx ready (6) ? */
2539#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
2540#define PL_RESET_OUT (1<<4) /* reset output pipe */
2541#define PL_RESET_IN (1<<3) /* reset input pipe */
2542#define PL_TX_C (1<<2) /* transmission complete */
2543#define PL_TX_REQ (1<<1) /* transmission received */
2544#define PL_PEER_E (1<<0) /* peer exists */
2545
2546static inline int
2547pl_vendor_req (struct usbnet *dev, u8 req, u8 val, u8 index)
2548{
2549 return usb_control_msg (dev->udev,
2550 usb_rcvctrlpipe (dev->udev, 0),
2551 req,
2552 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2553 val, index,
2554 NULL, 0,
2555 CONTROL_TIMEOUT_MS);
2556}
2557
2558static inline int
2559pl_clear_QuickLink_features (struct usbnet *dev, int val)
2560{
2561 return pl_vendor_req (dev, 1, (u8) val, 0);
2562}
2563
2564static inline int
2565pl_set_QuickLink_features (struct usbnet *dev, int val)
2566{
2567 return pl_vendor_req (dev, 3, (u8) val, 0);
2568}
2569
2570/*-------------------------------------------------------------------------*/
2571
2572static int pl_reset (struct usbnet *dev)
2573{
2574 /* some units seem to need this reset, others reject it utterly.
2575 * FIXME be more like "naplink" or windows drivers.
2576 */
2577 (void) pl_set_QuickLink_features (dev,
2578 PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
2579 return 0;
2580}
2581
2582static const struct driver_info prolific_info = {
2583 .description = "Prolific PL-2301/PL-2302",
2584 .flags = FLAG_NO_SETINT,
2585 /* some PL-2302 versions seem to fail usb_set_interface() */
2586 .reset = pl_reset,
2587};
2588
2589#endif /* CONFIG_USB_PL2301 */
2590
2591
2592#ifdef CONFIG_USB_KC2190
2593#define HAVE_HARDWARE
2594static const struct driver_info kc2190_info = {
2595 .description = "KC Technology KC-190",
2596};
2597#endif /* CONFIG_USB_KC2190 */
2598
2599
2600#ifdef CONFIG_USB_ARMLINUX
2601#define HAVE_HARDWARE
2602
2603/*-------------------------------------------------------------------------
2604 *
2605 * Intel's SA-1100 chip integrates basic USB support, and is used
2606 * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
2607 * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
2608 * network using minimal USB framing data.
2609 *
2610 * This describes the driver currently in standard ARM Linux kernels.
2611 * The Zaurus uses a different driver (see later).
2612 *
2613 * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
2614 * and different USB endpoint numbering than the SA1100 devices. The
2615 * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
2616 * so we rely on the endpoint descriptors.
2617 *
2618 *-------------------------------------------------------------------------*/
2619
2620static const struct driver_info linuxdev_info = {
2621 .description = "Linux Device",
2622 .check_connect = always_connected,
2623};
2624
2625static const struct driver_info yopy_info = {
2626 .description = "Yopy",
2627 .check_connect = always_connected,
2628};
2629
2630static const struct driver_info blob_info = {
2631 .description = "Boot Loader OBject",
2632 .check_connect = always_connected,
2633};
2634
2635#endif /* CONFIG_USB_ARMLINUX */
2636
2637
2638#ifdef CONFIG_USB_ZAURUS
2639#define HAVE_HARDWARE
2640
2641#include <linux/crc32.h>
2642
2643/*-------------------------------------------------------------------------
2644 *
2645 * Zaurus is also a SA-1110 based PDA, but one using a different driver
2646 * (and framing) for its USB slave/gadget controller than the case above.
2647 *
2648 * For the current version of that driver, the main way that framing is
2649 * nonstandard (also from perspective of the CDC ethernet model!) is a
2650 * crc32, added to help detect when some sa1100 usb-to-memory DMA errata
2651 * haven't been fully worked around. Also, all Zaurii use the same
2652 * default Ethernet address.
2653 *
2654 * PXA based models use the same framing, and also can't implement
2655 * set_interface properly.
2656 *
2657 * All known Zaurii lie about their standards conformance. Most lie by
2658 * saying they support CDC Ethernet. Some lie and say they support CDC
2659 * MDLM (as if for access to cell phone modems). Someone, please beat
2660 * on Sharp (and other such vendors) for a while with a cluestick.
2661 *
2662 *-------------------------------------------------------------------------*/
2663
2664static struct sk_buff *
2665zaurus_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
2666{
2667 int padlen;
2668 struct sk_buff *skb2;
2669
2670 padlen = 2;
2671 if (!skb_cloned (skb)) {
2672 int tailroom = skb_tailroom (skb);
2673 if ((padlen + 4) <= tailroom)
2674 goto done;
2675 }
2676 skb2 = skb_copy_expand (skb, 0, 4 + padlen, flags);
2677 dev_kfree_skb_any (skb);
2678 skb = skb2;
2679 if (skb) {
2680 u32 fcs;
2681done:
2682 fcs = crc32_le (~0, skb->data, skb->len);
2683 fcs = ~fcs;
2684
2685 *skb_put (skb, 1) = fcs & 0xff;
2686 *skb_put (skb, 1) = (fcs>> 8) & 0xff;
2687 *skb_put (skb, 1) = (fcs>>16) & 0xff;
2688 *skb_put (skb, 1) = (fcs>>24) & 0xff;
2689 }
2690 return skb;
2691}
2692
2693static const struct driver_info zaurus_sl5x00_info = {
2694 .description = "Sharp Zaurus SL-5x00",
2695 .flags = FLAG_FRAMING_Z,
2696 .check_connect = always_connected,
2697 .bind = generic_cdc_bind,
2698 .unbind = cdc_unbind,
2699 .tx_fixup = zaurus_tx_fixup,
2700};
2701#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
2702
2703static const struct driver_info zaurus_pxa_info = {
2704 .description = "Sharp Zaurus, PXA-2xx based",
2705 .flags = FLAG_FRAMING_Z,
2706 .check_connect = always_connected,
2707 .bind = generic_cdc_bind,
2708 .unbind = cdc_unbind,
2709 .tx_fixup = zaurus_tx_fixup,
2710};
2711#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
2712
2713static const struct driver_info olympus_mxl_info = {
2714 .description = "Olympus R1000",
2715 .flags = FLAG_FRAMING_Z,
2716 .check_connect = always_connected,
2717 .bind = generic_cdc_bind,
2718 .unbind = cdc_unbind,
2719 .tx_fixup = zaurus_tx_fixup,
2720};
2721#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
2722
2723
2724/* Some more recent products using Lineo/Belcarra code will wrongly claim
2725 * CDC MDLM conformance. They aren't conformant: data endpoints live
2726 * in the control interface, there's no data interface, and it's not used
2727 * to talk to a cell phone radio. But at least we can detect these two
2728 * pseudo-classes, rather than growing this product list with entries for
2729 * each new nonconformant product (sigh).
2730 */
2731static const u8 safe_guid[16] = {
2732 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
2733 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
2734};
2735static const u8 blan_guid[16] = {
2736 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
2737 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
2738};
2739
2740static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
2741{
2742 u8 *buf = intf->cur_altsetting->extra;
2743 int len = intf->cur_altsetting->extralen;
2744 struct usb_cdc_mdlm_desc *desc = NULL;
2745 struct usb_cdc_mdlm_detail_desc *detail = NULL;
2746
2747 while (len > 3) {
2748 if (buf [1] != USB_DT_CS_INTERFACE)
2749 goto next_desc;
2750
2751 /* use bDescriptorSubType, and just verify that we get a
2752 * "BLAN" (or "SAFE") descriptor.
2753 */
2754 switch (buf [2]) {
2755 case USB_CDC_MDLM_TYPE:
2756 if (desc) {
2757 dev_dbg (&intf->dev, "extra MDLM\n");
2758 goto bad_desc;
2759 }
2760 desc = (void *) buf;
2761 if (desc->bLength != sizeof *desc) {
2762 dev_dbg (&intf->dev, "MDLM len %u\n",
2763 desc->bLength);
2764 goto bad_desc;
2765 }
2766 /* expect bcdVersion 1.0, ignore */
2767 if (memcmp(&desc->bGUID, blan_guid, 16)
2768 && memcmp(&desc->bGUID, safe_guid, 16) ) {
2769 /* hey, this one might _really_ be MDLM! */
2770 dev_dbg (&intf->dev, "MDLM guid\n");
2771 goto bad_desc;
2772 }
2773 break;
2774 case USB_CDC_MDLM_DETAIL_TYPE:
2775 if (detail) {
2776 dev_dbg (&intf->dev, "extra MDLM detail\n");
2777 goto bad_desc;
2778 }
2779 detail = (void *) buf;
2780 switch (detail->bGuidDescriptorType) {
2781 case 0: /* "SAFE" */
2782 if (detail->bLength != (sizeof *detail + 2))
2783 goto bad_detail;
2784 break;
2785 case 1: /* "BLAN" */
2786 if (detail->bLength != (sizeof *detail + 3))
2787 goto bad_detail;
2788 break;
2789 default:
2790 goto bad_detail;
2791 }
2792
2793 /* assuming we either noticed BLAN already, or will
2794 * find it soon, there are some data bytes here:
2795 * - bmNetworkCapabilities (unused)
2796 * - bmDataCapabilities (bits, see below)
2797 * - bPad (ignored, for PADAFTER -- BLAN-only)
2798 * bits are:
2799 * - 0x01 -- Zaurus framing (add CRC)
2800 * - 0x02 -- PADBEFORE (CRC includes some padding)
2801 * - 0x04 -- PADAFTER (some padding after CRC)
2802 * - 0x08 -- "fermat" packet mangling (for hw bugs)
2803 * the PADBEFORE appears not to matter; we interop
2804 * with devices that use it and those that don't.
2805 */
2806 if ((detail->bDetailData[1] & ~02) != 0x01) {
2807 /* bmDataCapabilites == 0 would be fine too,
2808 * but framing is minidriver-coupled for now.
2809 */
2810bad_detail:
2811 dev_dbg (&intf->dev,
2812 "bad MDLM detail, %d %d %d\n",
2813 detail->bLength,
2814 detail->bDetailData[0],
2815 detail->bDetailData[2]);
2816 goto bad_desc;
2817 }
2818 break;
2819 }
2820next_desc:
2821 len -= buf [0]; /* bLength */
2822 buf += buf [0];
2823 }
2824
2825 if (!desc || !detail) {
2826 dev_dbg (&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
2827 desc ? "" : "func ",
2828 detail ? "" : "detail ");
2829 goto bad_desc;
2830 }
2831
2832 /* There's probably a CDC Ethernet descriptor there, but we can't
2833 * rely on the Ethernet address it provides since not all vendors
2834 * bother to make it unique. Likewise there's no point in tracking
2835 * of the CDC event notifications.
2836 */
2837 return get_endpoints (dev, intf);
2838
2839bad_desc:
2840 dev_info (&dev->udev->dev, "unsupported MDLM descriptors\n");
2841 return -ENODEV;
2842}
2843
2844static const struct driver_info bogus_mdlm_info = {
2845 .description = "pseudo-MDLM (BLAN) device",
2846 .flags = FLAG_FRAMING_Z,
2847 .check_connect = always_connected,
2848 .tx_fixup = zaurus_tx_fixup,
2849 .bind = blan_mdlm_bind,
2850};
2851
2852#else
2853
2854/* blacklist all those devices */
2855#define ZAURUS_STRONGARM_INFO 0
2856#define ZAURUS_PXA_INFO 0
2857#define OLYMPUS_MXL_INFO 0
2858
2859#endif
2860 222
2861 223
2862/*------------------------------------------------------------------------- 224/*-------------------------------------------------------------------------
@@ -2868,22 +230,12 @@ static const struct driver_info bogus_mdlm_info = {
2868static int usbnet_change_mtu (struct net_device *net, int new_mtu) 230static int usbnet_change_mtu (struct net_device *net, int new_mtu)
2869{ 231{
2870 struct usbnet *dev = netdev_priv(net); 232 struct usbnet *dev = netdev_priv(net);
233 int ll_mtu = new_mtu + net->hard_header_len;
2871 234
2872 if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET) 235 if (new_mtu <= 0 || ll_mtu > dev->hard_mtu)
2873 return -EINVAL; 236 return -EINVAL;
2874#ifdef CONFIG_USB_NET1080
2875 if (((dev->driver_info->flags) & FLAG_FRAMING_NC)) {
2876 if (FRAMED_SIZE (new_mtu) > MAX_PACKET)
2877 return -EINVAL;
2878 }
2879#endif
2880#ifdef CONFIG_USB_GENESYS
2881 if (((dev->driver_info->flags) & FLAG_FRAMING_GL)
2882 && new_mtu > GL_MAX_PACKET_LEN)
2883 return -EINVAL;
2884#endif
2885 // no second zero-length packet read wanted after mtu-sized packets 237 // no second zero-length packet read wanted after mtu-sized packets
2886 if (((new_mtu + sizeof (struct ethhdr)) % dev->maxpacket) == 0) 238 if ((ll_mtu % dev->maxpacket) == 0)
2887 return -EDOM; 239 return -EDOM;
2888 net->mtu = new_mtu; 240 net->mtu = new_mtu;
2889 return 0; 241 return 0;
@@ -2922,7 +274,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea
2922 * NOTE: annoying asymmetry: if it's active, schedule_work() fails, 274 * NOTE: annoying asymmetry: if it's active, schedule_work() fails,
2923 * but tasklet_schedule() doesn't. hope the failure is rare. 275 * but tasklet_schedule() doesn't. hope the failure is rare.
2924 */ 276 */
2925static void defer_kevent (struct usbnet *dev, int work) 277void usbnet_defer_kevent (struct usbnet *dev, int work)
2926{ 278{
2927 set_bit (work, &dev->flags); 279 set_bit (work, &dev->flags);
2928 if (!schedule_work (&dev->kevent)) 280 if (!schedule_work (&dev->kevent))
@@ -2930,50 +282,24 @@ static void defer_kevent (struct usbnet *dev, int work)
2930 else 282 else
2931 devdbg (dev, "kevent %d scheduled", work); 283 devdbg (dev, "kevent %d scheduled", work);
2932} 284}
285EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
2933 286
2934/*-------------------------------------------------------------------------*/ 287/*-------------------------------------------------------------------------*/
2935 288
2936static void rx_complete (struct urb *urb, struct pt_regs *regs); 289static void rx_complete (struct urb *urb, struct pt_regs *regs);
2937 290
2938static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) 291static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
2939{ 292{
2940 struct sk_buff *skb; 293 struct sk_buff *skb;
2941 struct skb_data *entry; 294 struct skb_data *entry;
2942 int retval = 0; 295 int retval = 0;
2943 unsigned long lockflags; 296 unsigned long lockflags;
2944 size_t size; 297 size_t size = dev->rx_urb_size;
2945
2946#ifdef CONFIG_USB_NET1080
2947 if (dev->driver_info->flags & FLAG_FRAMING_NC)
2948 size = FRAMED_SIZE (dev->net->mtu);
2949 else
2950#endif
2951#ifdef CONFIG_USB_GENESYS
2952 if (dev->driver_info->flags & FLAG_FRAMING_GL)
2953 size = GL_RCV_BUF_SIZE;
2954 else
2955#endif
2956#ifdef CONFIG_USB_ZAURUS
2957 if (dev->driver_info->flags & FLAG_FRAMING_Z)
2958 size = 6 + (sizeof (struct ethhdr) + dev->net->mtu);
2959 else
2960#endif
2961#ifdef CONFIG_USB_RNDIS
2962 if (dev->driver_info->flags & FLAG_FRAMING_RN)
2963 size = RNDIS_MAX_TRANSFER;
2964 else
2965#endif
2966#ifdef CONFIG_USB_AX8817X
2967 if (dev->driver_info->flags & FLAG_FRAMING_AX)
2968 size = 2048;
2969 else
2970#endif
2971 size = (sizeof (struct ethhdr) + dev->net->mtu);
2972 298
2973 if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { 299 if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
2974 if (netif_msg_rx_err (dev)) 300 if (netif_msg_rx_err (dev))
2975 devdbg (dev, "no rx skb"); 301 devdbg (dev, "no rx skb");
2976 defer_kevent (dev, EVENT_RX_MEMORY); 302 usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
2977 usb_free_urb (urb); 303 usb_free_urb (urb);
2978 return; 304 return;
2979 } 305 }
@@ -2987,7 +313,6 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
2987 313
2988 usb_fill_bulk_urb (urb, dev->udev, dev->in, 314 usb_fill_bulk_urb (urb, dev->udev, dev->in,
2989 skb->data, size, rx_complete, skb); 315 skb->data, size, rx_complete, skb);
2990 urb->transfer_flags |= URB_ASYNC_UNLINK;
2991 316
2992 spin_lock_irqsave (&dev->rxq.lock, lockflags); 317 spin_lock_irqsave (&dev->rxq.lock, lockflags);
2993 318
@@ -2996,10 +321,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
2996 && !test_bit (EVENT_RX_HALT, &dev->flags)) { 321 && !test_bit (EVENT_RX_HALT, &dev->flags)) {
2997 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 322 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
2998 case -EPIPE: 323 case -EPIPE:
2999 defer_kevent (dev, EVENT_RX_HALT); 324 usbnet_defer_kevent (dev, EVENT_RX_HALT);
3000 break; 325 break;
3001 case -ENOMEM: 326 case -ENOMEM:
3002 defer_kevent (dev, EVENT_RX_MEMORY); 327 usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
3003 break; 328 break;
3004 case -ENODEV: 329 case -ENODEV:
3005 if (netif_msg_ifdown (dev)) 330 if (netif_msg_ifdown (dev))
@@ -3037,7 +362,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
3037 // else network stack removes extra byte if we forced a short packet 362 // else network stack removes extra byte if we forced a short packet
3038 363
3039 if (skb->len) 364 if (skb->len)
3040 skb_return (dev, skb); 365 usbnet_skb_return (dev, skb);
3041 else { 366 else {
3042 if (netif_msg_rx_err (dev)) 367 if (netif_msg_rx_err (dev))
3043 devdbg (dev, "drop"); 368 devdbg (dev, "drop");
@@ -3063,7 +388,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
3063 switch (urb_status) { 388 switch (urb_status) {
3064 // success 389 // success
3065 case 0: 390 case 0:
3066 if (MIN_PACKET > skb->len || skb->len > MAX_PACKET) { 391 if (skb->len < dev->net->hard_header_len) {
3067 entry->state = rx_cleanup; 392 entry->state = rx_cleanup;
3068 dev->stats.rx_errors++; 393 dev->stats.rx_errors++;
3069 dev->stats.rx_length_errors++; 394 dev->stats.rx_length_errors++;
@@ -3078,7 +403,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
3078 // storm, recovering as needed. 403 // storm, recovering as needed.
3079 case -EPIPE: 404 case -EPIPE:
3080 dev->stats.rx_errors++; 405 dev->stats.rx_errors++;
3081 defer_kevent (dev, EVENT_RX_HALT); 406 usbnet_defer_kevent (dev, EVENT_RX_HALT);
3082 // FALLTHROUGH 407 // FALLTHROUGH
3083 408
3084 // software-driven interface shutdown 409 // software-driven interface shutdown
@@ -3320,55 +645,58 @@ done:
3320 645
3321/*-------------------------------------------------------------------------*/ 646/*-------------------------------------------------------------------------*/
3322 647
3323static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) 648/* ethtool methods; minidrivers may need to add some more, but
649 * they'll probably want to use this base set.
650 */
651
652void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
3324{ 653{
3325 struct usbnet *dev = netdev_priv(net); 654 struct usbnet *dev = netdev_priv(net);
3326 655
656 /* REVISIT don't always return "usbnet" */
3327 strncpy (info->driver, driver_name, sizeof info->driver); 657 strncpy (info->driver, driver_name, sizeof info->driver);
3328 strncpy (info->version, DRIVER_VERSION, sizeof info->version); 658 strncpy (info->version, DRIVER_VERSION, sizeof info->version);
3329 strncpy (info->fw_version, dev->driver_info->description, 659 strncpy (info->fw_version, dev->driver_info->description,
3330 sizeof info->fw_version); 660 sizeof info->fw_version);
3331 usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); 661 usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
3332} 662}
663EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
3333 664
3334static u32 usbnet_get_link (struct net_device *net) 665static u32 usbnet_get_link (struct net_device *net)
3335{ 666{
3336 struct usbnet *dev = netdev_priv(net); 667 struct usbnet *dev = netdev_priv(net);
3337 668
3338 /* If a check_connect is defined, return it's results */ 669 /* If a check_connect is defined, return its result */
3339 if (dev->driver_info->check_connect) 670 if (dev->driver_info->check_connect)
3340 return dev->driver_info->check_connect (dev) == 0; 671 return dev->driver_info->check_connect (dev) == 0;
3341 672
3342 /* Otherwise, we're up to avoid breaking scripts */ 673 /* Otherwise, say we're up (to avoid breaking scripts) */
3343 return 1; 674 return 1;
3344} 675}
3345 676
3346static u32 usbnet_get_msglevel (struct net_device *net) 677u32 usbnet_get_msglevel (struct net_device *net)
3347{ 678{
3348 struct usbnet *dev = netdev_priv(net); 679 struct usbnet *dev = netdev_priv(net);
3349 680
3350 return dev->msg_enable; 681 return dev->msg_enable;
3351} 682}
683EXPORT_SYMBOL_GPL(usbnet_get_msglevel);
3352 684
3353static void usbnet_set_msglevel (struct net_device *net, u32 level) 685void usbnet_set_msglevel (struct net_device *net, u32 level)
3354{ 686{
3355 struct usbnet *dev = netdev_priv(net); 687 struct usbnet *dev = netdev_priv(net);
3356 688
3357 dev->msg_enable = level; 689 dev->msg_enable = level;
3358} 690}
691EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
3359 692
3360static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd) 693/* drivers may override default ethtool_ops in their bind() routine */
3361{ 694static struct ethtool_ops usbnet_ethtool_ops = {
3362#ifdef NEED_MII 695 .get_drvinfo = usbnet_get_drvinfo,
3363 { 696 .get_link = usbnet_get_link,
3364 struct usbnet *dev = netdev_priv(net); 697 .get_msglevel = usbnet_get_msglevel,
3365 698 .set_msglevel = usbnet_set_msglevel,
3366 if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL) 699};
3367 return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
3368 }
3369#endif
3370 return -EOPNOTSUPP;
3371}
3372 700
3373/*-------------------------------------------------------------------------*/ 701/*-------------------------------------------------------------------------*/
3374 702
@@ -3387,19 +715,24 @@ kevent (void *data)
3387 if (test_bit (EVENT_TX_HALT, &dev->flags)) { 715 if (test_bit (EVENT_TX_HALT, &dev->flags)) {
3388 unlink_urbs (dev, &dev->txq); 716 unlink_urbs (dev, &dev->txq);
3389 status = usb_clear_halt (dev->udev, dev->out); 717 status = usb_clear_halt (dev->udev, dev->out);
3390 if (status < 0 && status != -EPIPE) { 718 if (status < 0
719 && status != -EPIPE
720 && status != -ESHUTDOWN) {
3391 if (netif_msg_tx_err (dev)) 721 if (netif_msg_tx_err (dev))
3392 deverr (dev, "can't clear tx halt, status %d", 722 deverr (dev, "can't clear tx halt, status %d",
3393 status); 723 status);
3394 } else { 724 } else {
3395 clear_bit (EVENT_TX_HALT, &dev->flags); 725 clear_bit (EVENT_TX_HALT, &dev->flags);
3396 netif_wake_queue (dev->net); 726 if (status != -ESHUTDOWN)
727 netif_wake_queue (dev->net);
3397 } 728 }
3398 } 729 }
3399 if (test_bit (EVENT_RX_HALT, &dev->flags)) { 730 if (test_bit (EVENT_RX_HALT, &dev->flags)) {
3400 unlink_urbs (dev, &dev->rxq); 731 unlink_urbs (dev, &dev->rxq);
3401 status = usb_clear_halt (dev->udev, dev->in); 732 status = usb_clear_halt (dev->udev, dev->in);
3402 if (status < 0 && status != -EPIPE) { 733 if (status < 0
734 && status != -EPIPE
735 && status != -ESHUTDOWN) {
3403 if (netif_msg_rx_err (dev)) 736 if (netif_msg_rx_err (dev))
3404 deverr (dev, "can't clear rx halt, status %d", 737 deverr (dev, "can't clear rx halt, status %d",
3405 status); 738 status);
@@ -3458,7 +791,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
3458 791
3459 switch (urb->status) { 792 switch (urb->status) {
3460 case -EPIPE: 793 case -EPIPE:
3461 defer_kevent (dev, EVENT_TX_HALT); 794 usbnet_defer_kevent (dev, EVENT_TX_HALT);
3462 break; 795 break;
3463 796
3464 /* software-driven interface shutdown */ 797 /* software-driven interface shutdown */
@@ -3515,10 +848,6 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
3515 struct skb_data *entry; 848 struct skb_data *entry;
3516 struct driver_info *info = dev->driver_info; 849 struct driver_info *info = dev->driver_info;
3517 unsigned long flags; 850 unsigned long flags;
3518#ifdef CONFIG_USB_NET1080
3519 struct nc_header *header = NULL;
3520 struct nc_trailer *trailer = NULL;
3521#endif /* CONFIG_USB_NET1080 */
3522 851
3523 // some devices want funky USB-level framing, for 852 // some devices want funky USB-level framing, for
3524 // win32 driver (usually) and/or hardware quirks 853 // win32 driver (usually) and/or hardware quirks
@@ -3544,24 +873,8 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
3544 entry->state = tx_start; 873 entry->state = tx_start;
3545 entry->length = length; 874 entry->length = length;
3546 875
3547 // FIXME: reorganize a bit, so that fixup() fills out NetChip
3548 // framing too. (Packet ID update needs the spinlock...)
3549 // [ BETTER: we already own net->xmit_lock, that's enough ]
3550
3551#ifdef CONFIG_USB_NET1080
3552 if (info->flags & FLAG_FRAMING_NC) {
3553 header = (struct nc_header *) skb_push (skb, sizeof *header);
3554 header->hdr_len = cpu_to_le16 (sizeof (*header));
3555 header->packet_len = cpu_to_le16 (length);
3556 if (!((skb->len + sizeof *trailer) & 0x01))
3557 *skb_put (skb, 1) = PAD_BYTE;
3558 trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
3559 }
3560#endif /* CONFIG_USB_NET1080 */
3561
3562 usb_fill_bulk_urb (urb, dev->udev, dev->out, 876 usb_fill_bulk_urb (urb, dev->udev, dev->out,
3563 skb->data, skb->len, tx_complete, skb); 877 skb->data, skb->len, tx_complete, skb);
3564 urb->transfer_flags |= URB_ASYNC_UNLINK;
3565 878
3566 /* don't assume the hardware handles USB_ZERO_PACKET 879 /* don't assume the hardware handles USB_ZERO_PACKET
3567 * NOTE: strictly conforming cdc-ether devices should expect 880 * NOTE: strictly conforming cdc-ether devices should expect
@@ -3574,22 +887,10 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
3574 887
3575 spin_lock_irqsave (&dev->txq.lock, flags); 888 spin_lock_irqsave (&dev->txq.lock, flags);
3576 889
3577#ifdef CONFIG_USB_NET1080
3578 if (info->flags & FLAG_FRAMING_NC) {
3579 header->packet_id = cpu_to_le16 ((u16)dev->dev_packet_id++);
3580 put_unaligned (header->packet_id, &trailer->packet_id);
3581#if 0
3582 devdbg (dev, "frame >tx h %d p %d id %d",
3583 header->hdr_len, header->packet_len,
3584 header->packet_id);
3585#endif
3586 }
3587#endif /* CONFIG_USB_NET1080 */
3588
3589 switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { 890 switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
3590 case -EPIPE: 891 case -EPIPE:
3591 netif_stop_queue (net); 892 netif_stop_queue (net);
3592 defer_kevent (dev, EVENT_TX_HALT); 893 usbnet_defer_kevent (dev, EVENT_TX_HALT);
3593 break; 894 break;
3594 default: 895 default:
3595 if (netif_msg_tx_err (dev)) 896 if (netif_msg_tx_err (dev))
@@ -3692,7 +993,7 @@ static void usbnet_bh (unsigned long param)
3692 993
3693// precondition: never called in_interrupt 994// precondition: never called in_interrupt
3694 995
3695static void usbnet_disconnect (struct usb_interface *intf) 996void usbnet_disconnect (struct usb_interface *intf)
3696{ 997{
3697 struct usbnet *dev; 998 struct usbnet *dev;
3698 struct usb_device *xdev; 999 struct usb_device *xdev;
@@ -3706,7 +1007,8 @@ static void usbnet_disconnect (struct usb_interface *intf)
3706 xdev = interface_to_usbdev (intf); 1007 xdev = interface_to_usbdev (intf);
3707 1008
3708 if (netif_msg_probe (dev)) 1009 if (netif_msg_probe (dev))
3709 devinfo (dev, "unregister usbnet usb-%s-%s, %s", 1010 devinfo (dev, "unregister '%s' usb-%s-%s, %s",
1011 intf->dev.driver->name,
3710 xdev->bus->bus_name, xdev->devpath, 1012 xdev->bus->bus_name, xdev->devpath,
3711 dev->driver_info->description); 1013 dev->driver_info->description);
3712 1014
@@ -3722,15 +1024,14 @@ static void usbnet_disconnect (struct usb_interface *intf)
3722 free_netdev(net); 1024 free_netdev(net);
3723 usb_put_dev (xdev); 1025 usb_put_dev (xdev);
3724} 1026}
1027EXPORT_SYMBOL_GPL(usbnet_disconnect);
3725 1028
3726 1029
3727/*-------------------------------------------------------------------------*/ 1030/*-------------------------------------------------------------------------*/
3728 1031
3729static struct ethtool_ops usbnet_ethtool_ops;
3730
3731// precondition: never called in_interrupt 1032// precondition: never called in_interrupt
3732 1033
3733static int 1034int
3734usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) 1035usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3735{ 1036{
3736 struct usbnet *dev; 1037 struct usbnet *dev;
@@ -3779,6 +1080,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3779 strcpy (net->name, "usb%d"); 1080 strcpy (net->name, "usb%d");
3780 memcpy (net->dev_addr, node_id, sizeof node_id); 1081 memcpy (net->dev_addr, node_id, sizeof node_id);
3781 1082
1083 /* rx and tx sides can use different message sizes;
1084 * bind() should set rx_urb_size in that case.
1085 */
1086 dev->hard_mtu = net->mtu + net->hard_header_len;
3782#if 0 1087#if 0
3783// dma_supported() is deeply broken on almost all architectures 1088// dma_supported() is deeply broken on almost all architectures
3784 // possible with some EHCI controllers 1089 // possible with some EHCI controllers
@@ -3793,7 +1098,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3793 net->stop = usbnet_stop; 1098 net->stop = usbnet_stop;
3794 net->watchdog_timeo = TX_TIMEOUT_JIFFIES; 1099 net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
3795 net->tx_timeout = usbnet_tx_timeout; 1100 net->tx_timeout = usbnet_tx_timeout;
3796 net->do_ioctl = usbnet_ioctl;
3797 net->ethtool_ops = &usbnet_ethtool_ops; 1101 net->ethtool_ops = &usbnet_ethtool_ops;
3798 1102
3799 // allow device-specific bind/init procedures 1103 // allow device-specific bind/init procedures
@@ -3806,8 +1110,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3806 if ((dev->driver_info->flags & FLAG_ETHER) != 0 1110 if ((dev->driver_info->flags & FLAG_ETHER) != 0
3807 && (net->dev_addr [0] & 0x02) == 0) 1111 && (net->dev_addr [0] & 0x02) == 0)
3808 strcpy (net->name, "eth%d"); 1112 strcpy (net->name, "eth%d");
3809 } else if (!info->in || info->out) 1113
3810 status = get_endpoints (dev, udev); 1114 /* maybe the remote can't receive an Ethernet MTU */
1115 if (net->mtu > (dev->hard_mtu - net->hard_header_len))
1116 net->mtu = dev->hard_mtu - net->hard_header_len;
1117 } else if (!info->in || !info->out)
1118 status = usbnet_get_endpoints (dev, udev);
3811 else { 1119 else {
3812 dev->in = usb_rcvbulkpipe (xdev, info->in); 1120 dev->in = usb_rcvbulkpipe (xdev, info->in);
3813 dev->out = usb_sndbulkpipe (xdev, info->out); 1121 dev->out = usb_sndbulkpipe (xdev, info->out);
@@ -3819,12 +1127,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3819 status = 0; 1127 status = 0;
3820 1128
3821 } 1129 }
3822
3823 if (status == 0 && dev->status) 1130 if (status == 0 && dev->status)
3824 status = init_status (dev, udev); 1131 status = init_status (dev, udev);
3825 if (status < 0) 1132 if (status < 0)
3826 goto out1; 1133 goto out1;
3827 1134
1135 if (!dev->rx_urb_size)
1136 dev->rx_urb_size = dev->hard_mtu;
3828 dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); 1137 dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
3829 1138
3830 SET_NETDEV_DEV(net, &udev->dev); 1139 SET_NETDEV_DEV(net, &udev->dev);
@@ -3832,8 +1141,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
3832 if (status) 1141 if (status)
3833 goto out3; 1142 goto out3;
3834 if (netif_msg_probe (dev)) 1143 if (netif_msg_probe (dev))
3835 devinfo (dev, "register usbnet at usb-%s-%s, %s, " 1144 devinfo (dev, "register '%s' at usb-%s-%s, %s, "
3836 "%02x:%02x:%02x:%02x:%02x:%02x", 1145 "%02x:%02x:%02x:%02x:%02x:%02x",
1146 udev->dev.driver->name,
3837 xdev->bus->bus_name, xdev->devpath, 1147 xdev->bus->bus_name, xdev->devpath,
3838 dev->driver_info->description, 1148 dev->driver_info->description,
3839 net->dev_addr [0], net->dev_addr [1], 1149 net->dev_addr [0], net->dev_addr [1],
@@ -3857,12 +1167,15 @@ out:
3857 usb_put_dev(xdev); 1167 usb_put_dev(xdev);
3858 return status; 1168 return status;
3859} 1169}
1170EXPORT_SYMBOL_GPL(usbnet_probe);
3860 1171
3861/*-------------------------------------------------------------------------*/ 1172/*-------------------------------------------------------------------------*/
3862 1173
3863#ifdef CONFIG_PM 1174/* FIXME these suspend/resume methods assume non-CDC style
1175 * devices, with only one interface.
1176 */
3864 1177
3865static int usbnet_suspend (struct usb_interface *intf, pm_message_t message) 1178int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
3866{ 1179{
3867 struct usbnet *dev = usb_get_intfdata(intf); 1180 struct usbnet *dev = usb_get_intfdata(intf);
3868 1181
@@ -3875,8 +1188,9 @@ static int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
3875 intf->dev.power.power_state = PMSG_SUSPEND; 1188 intf->dev.power.power_state = PMSG_SUSPEND;
3876 return 0; 1189 return 0;
3877} 1190}
1191EXPORT_SYMBOL_GPL(usbnet_suspend);
3878 1192
3879static int usbnet_resume (struct usb_interface *intf) 1193int usbnet_resume (struct usb_interface *intf)
3880{ 1194{
3881 struct usbnet *dev = usb_get_intfdata(intf); 1195 struct usbnet *dev = usb_get_intfdata(intf);
3882 1196
@@ -3885,357 +1199,27 @@ static int usbnet_resume (struct usb_interface *intf)
3885 tasklet_schedule (&dev->bh); 1199 tasklet_schedule (&dev->bh);
3886 return 0; 1200 return 0;
3887} 1201}
1202EXPORT_SYMBOL_GPL(usbnet_resume);
3888 1203
3889#else /* !CONFIG_PM */
3890
3891#define usbnet_suspend NULL
3892#define usbnet_resume NULL
3893
3894#endif /* CONFIG_PM */
3895
3896/*-------------------------------------------------------------------------*/
3897
3898#ifndef HAVE_HARDWARE
3899#error You need to configure some hardware for this driver
3900#endif
3901
3902/*
3903 * chip vendor names won't normally be on the cables, and
3904 * may not be on the device.
3905 */
3906
3907static const struct usb_device_id products [] = {
3908
3909#ifdef CONFIG_USB_ALI_M5632
3910{
3911 USB_DEVICE (0x0402, 0x5632), // ALi defaults
3912 .driver_info = (unsigned long) &ali_m5632_info,
3913},
3914#endif
3915
3916#ifdef CONFIG_USB_AN2720
3917{
3918 USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
3919 .driver_info = (unsigned long) &an2720_info,
3920}, {
3921 USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
3922 .driver_info = (unsigned long) &an2720_info,
3923},
3924#endif
3925
3926#ifdef CONFIG_USB_BELKIN
3927{
3928 USB_DEVICE (0x050d, 0x0004), // Belkin
3929 .driver_info = (unsigned long) &belkin_info,
3930}, {
3931 USB_DEVICE (0x056c, 0x8100), // eTEK
3932 .driver_info = (unsigned long) &belkin_info,
3933}, {
3934 USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
3935 .driver_info = (unsigned long) &belkin_info,
3936},
3937#endif
3938
3939#ifdef CONFIG_USB_AX8817X
3940{
3941 // Linksys USB200M
3942 USB_DEVICE (0x077b, 0x2226),
3943 .driver_info = (unsigned long) &ax8817x_info,
3944}, {
3945 // Netgear FA120
3946 USB_DEVICE (0x0846, 0x1040),
3947 .driver_info = (unsigned long) &netgear_fa120_info,
3948}, {
3949 // DLink DUB-E100
3950 USB_DEVICE (0x2001, 0x1a00),
3951 .driver_info = (unsigned long) &dlink_dub_e100_info,
3952}, {
3953 // Intellinet, ST Lab USB Ethernet
3954 USB_DEVICE (0x0b95, 0x1720),
3955 .driver_info = (unsigned long) &ax8817x_info,
3956}, {
3957 // Hawking UF200, TrendNet TU2-ET100
3958 USB_DEVICE (0x07b8, 0x420a),
3959 .driver_info = (unsigned long) &hawking_uf200_info,
3960}, {
3961 // Billionton Systems, USB2AR
3962 USB_DEVICE (0x08dd, 0x90ff),
3963 .driver_info = (unsigned long) &ax8817x_info,
3964}, {
3965 // ATEN UC210T
3966 USB_DEVICE (0x0557, 0x2009),
3967 .driver_info = (unsigned long) &ax8817x_info,
3968}, {
3969 // Buffalo LUA-U2-KTX
3970 USB_DEVICE (0x0411, 0x003d),
3971 .driver_info = (unsigned long) &ax8817x_info,
3972}, {
3973 // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
3974 USB_DEVICE (0x6189, 0x182d),
3975 .driver_info = (unsigned long) &ax8817x_info,
3976}, {
3977 // corega FEther USB2-TX
3978 USB_DEVICE (0x07aa, 0x0017),
3979 .driver_info = (unsigned long) &ax8817x_info,
3980}, {
3981 // Surecom EP-1427X-2
3982 USB_DEVICE (0x1189, 0x0893),
3983 .driver_info = (unsigned long) &ax8817x_info,
3984}, {
3985 // goodway corp usb gwusb2e
3986 USB_DEVICE (0x1631, 0x6200),
3987 .driver_info = (unsigned long) &ax8817x_info,
3988}, {
3989 // ASIX AX88772 10/100
3990 USB_DEVICE (0x0b95, 0x7720),
3991 .driver_info = (unsigned long) &ax88772_info,
3992},
3993#endif
3994
3995#ifdef CONFIG_USB_EPSON2888
3996{
3997 USB_DEVICE (0x0525, 0x2888), // EPSON USB client
3998 .driver_info = (unsigned long) &epson2888_info,
3999},
4000#endif
4001
4002#ifdef CONFIG_USB_GENESYS
4003{
4004 USB_DEVICE (0x05e3, 0x0502), // GL620USB-A
4005 .driver_info = (unsigned long) &genelink_info,
4006},
4007 /* NOT: USB_DEVICE (0x05e3, 0x0501), // GL620USB
4008 * that's half duplex, not currently supported
4009 */
4010#endif
4011
4012#ifdef CONFIG_USB_NET1080
4013{
4014 USB_DEVICE (0x0525, 0x1080), // NetChip ref design
4015 .driver_info = (unsigned long) &net1080_info,
4016}, {
4017 USB_DEVICE (0x06D0, 0x0622), // Laplink Gold
4018 .driver_info = (unsigned long) &net1080_info,
4019},
4020#endif
4021
4022#ifdef CONFIG_USB_PL2301
4023{
4024 USB_DEVICE (0x067b, 0x0000), // PL-2301
4025 .driver_info = (unsigned long) &prolific_info,
4026}, {
4027 USB_DEVICE (0x067b, 0x0001), // PL-2302
4028 .driver_info = (unsigned long) &prolific_info,
4029},
4030#endif
4031
4032#ifdef CONFIG_USB_KC2190
4033{
4034 USB_DEVICE (0x050f, 0x0190), // KC-190
4035 .driver_info = (unsigned long) &kc2190_info,
4036},
4037#endif
4038
4039#ifdef CONFIG_USB_RNDIS
4040{
4041 /* RNDIS is MSFT's un-official variant of CDC ACM */
4042 USB_INTERFACE_INFO (USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
4043 .driver_info = (unsigned long) &rndis_info,
4044},
4045#endif
4046
4047#ifdef CONFIG_USB_ARMLINUX
4048/*
4049 * SA-1100 using standard ARM Linux kernels, or compatible.
4050 * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
4051 * The sa-1100 "usb-eth" driver handles the basic framing.
4052 *
4053 * PXA25x or PXA210 ... these use a "usb-eth" driver much like
4054 * the sa1100 one, but hardware uses different endpoint numbers.
4055 *
4056 * Or the Linux "Ethernet" gadget on hardware that can't talk
4057 * CDC Ethernet (e.g., no altsettings), in either of two modes:
4058 * - acting just like the old "usb-eth" firmware, though
4059 * the implementation is different
4060 * - supporting RNDIS as the first/default configuration for
4061 * MS-Windows interop; Linux needs to use the other config
4062 */
4063{
4064 // 1183 = 0x049F, both used as hex values?
4065 // Compaq "Itsy" vendor/product id
4066 USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
4067 .driver_info = (unsigned long) &linuxdev_info,
4068}, {
4069 USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
4070 .driver_info = (unsigned long) &yopy_info,
4071}, {
4072 USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
4073 .driver_info = (unsigned long) &blob_info,
4074}, {
4075 // Linux Ethernet/RNDIS gadget on pxa210/25x/26x
4076 // e.g. Gumstix, current OpenZaurus, ...
4077 USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
4078 .driver_info = (unsigned long) &linuxdev_info,
4079},
4080#endif
4081
4082#if defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
4083/*
4084 * SA-1100 based Sharp Zaurus ("collie"), or compatible.
4085 * Same idea as above, but different framing.
4086 *
4087 * PXA-2xx based models are also lying-about-cdc.
4088 * Some models don't even tell the same lies ...
4089 *
4090 * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries,
4091 * unlike the older ones with 2.4 "embedix" kernels.
4092 *
4093 * NOTE: These entries do double-duty, serving as blacklist entries
4094 * whenever Zaurus support isn't enabled, but CDC Ethernet is.
4095 */
4096#define ZAURUS_MASTER_INTERFACE \
4097 .bInterfaceClass = USB_CLASS_COMM, \
4098 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
4099 .bInterfaceProtocol = USB_CDC_PROTO_NONE
4100{
4101 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4102 | USB_DEVICE_ID_MATCH_DEVICE,
4103 .idVendor = 0x04DD,
4104 .idProduct = 0x8004,
4105 ZAURUS_MASTER_INTERFACE,
4106 .driver_info = ZAURUS_STRONGARM_INFO,
4107}, {
4108 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4109 | USB_DEVICE_ID_MATCH_DEVICE,
4110 .idVendor = 0x04DD,
4111 .idProduct = 0x8005, /* A-300 */
4112 ZAURUS_MASTER_INTERFACE,
4113 .driver_info = ZAURUS_PXA_INFO,
4114}, {
4115 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4116 | USB_DEVICE_ID_MATCH_DEVICE,
4117 .idVendor = 0x04DD,
4118 .idProduct = 0x8006, /* B-500/SL-5600 */
4119 ZAURUS_MASTER_INTERFACE,
4120 .driver_info = ZAURUS_PXA_INFO,
4121}, {
4122 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4123 | USB_DEVICE_ID_MATCH_DEVICE,
4124 .idVendor = 0x04DD,
4125 .idProduct = 0x8007, /* C-700 */
4126 ZAURUS_MASTER_INTERFACE,
4127 .driver_info = ZAURUS_PXA_INFO,
4128}, {
4129 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4130 | USB_DEVICE_ID_MATCH_DEVICE,
4131 .idVendor = 0x04DD,
4132 .idProduct = 0x9031, /* C-750 C-760 */
4133 ZAURUS_MASTER_INTERFACE,
4134 .driver_info = ZAURUS_PXA_INFO,
4135}, {
4136 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4137 | USB_DEVICE_ID_MATCH_DEVICE,
4138 .idVendor = 0x04DD,
4139 .idProduct = 0x9032, /* SL-6000 */
4140 ZAURUS_MASTER_INTERFACE,
4141 .driver_info = ZAURUS_PXA_INFO,
4142}, {
4143 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4144 | USB_DEVICE_ID_MATCH_DEVICE,
4145 .idVendor = 0x04DD,
4146 /* reported with some C860 units */
4147 .idProduct = 0x9050, /* C-860 */
4148 ZAURUS_MASTER_INTERFACE,
4149 .driver_info = ZAURUS_PXA_INFO,
4150},
4151
4152#ifdef CONFIG_USB_ZAURUS
4153 /* At least some (reports vary) PXA units have very different lies
4154 * about their standards support: they claim to be cell phones with
4155 * direct access to their radios. (They don't conform to CDC MDLM.)
4156 */
4157{
4158 USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
4159 USB_CDC_PROTO_NONE),
4160 .driver_info = (unsigned long) &bogus_mdlm_info,
4161},
4162#endif
4163
4164/* Olympus has some models with a Zaurus-compatible option.
4165 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
4166 */
4167{
4168 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
4169 | USB_DEVICE_ID_MATCH_DEVICE,
4170 .idVendor = 0x07B4,
4171 .idProduct = 0x0F02, /* R-1000 */
4172 ZAURUS_MASTER_INTERFACE,
4173 .driver_info = OLYMPUS_MXL_INFO,
4174},
4175#endif
4176
4177#ifdef CONFIG_USB_CDCETHER
4178{
4179 /* CDC Ether uses two interfaces, not necessarily consecutive.
4180 * We match the main interface, ignoring the optional device
4181 * class so we could handle devices that aren't exclusively
4182 * CDC ether.
4183 *
4184 * NOTE: this match must come AFTER entries working around
4185 * bugs/quirks in a given product (like Zaurus, above).
4186 */
4187 USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
4188 USB_CDC_PROTO_NONE),
4189 .driver_info = (unsigned long) &cdc_info,
4190},
4191#endif
4192
4193 { }, // END
4194};
4195MODULE_DEVICE_TABLE (usb, products);
4196
4197static struct usb_driver usbnet_driver = {
4198 .owner = THIS_MODULE,
4199 .name = driver_name,
4200 .id_table = products,
4201 .probe = usbnet_probe,
4202 .disconnect = usbnet_disconnect,
4203 .suspend = usbnet_suspend,
4204 .resume = usbnet_resume,
4205};
4206
4207/* Default ethtool_ops assigned. Devices can override in their bind() routine */
4208static struct ethtool_ops usbnet_ethtool_ops = {
4209 .get_drvinfo = usbnet_get_drvinfo,
4210 .get_link = usbnet_get_link,
4211 .get_msglevel = usbnet_get_msglevel,
4212 .set_msglevel = usbnet_set_msglevel,
4213};
4214 1204
4215/*-------------------------------------------------------------------------*/ 1205/*-------------------------------------------------------------------------*/
4216 1206
4217static int __init usbnet_init (void) 1207static int __init usbnet_init(void)
4218{ 1208{
4219 // compiler should optimize these out 1209 /* compiler should optimize this out */
4220 BUG_ON (sizeof (((struct sk_buff *)0)->cb) 1210 BUG_ON (sizeof (((struct sk_buff *)0)->cb)
4221 < sizeof (struct skb_data)); 1211 < sizeof (struct skb_data));
4222#ifdef CONFIG_USB_CDCETHER
4223 BUG_ON ((sizeof (((struct usbnet *)0)->data)
4224 < sizeof (struct cdc_state)));
4225#endif
4226 1212
4227 random_ether_addr(node_id); 1213 random_ether_addr(node_id);
4228 1214 return 0;
4229 return usb_register(&usbnet_driver);
4230} 1215}
4231module_init (usbnet_init); 1216module_init(usbnet_init);
4232 1217
4233static void __exit usbnet_exit (void) 1218static void __exit usbnet_exit(void)
4234{ 1219{
4235 usb_deregister (&usbnet_driver);
4236} 1220}
4237module_exit (usbnet_exit); 1221module_exit(usbnet_exit);
4238 1222
4239MODULE_AUTHOR ("David Brownell <dbrownell@users.sourceforge.net>"); 1223MODULE_AUTHOR("David Brownell");
4240MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (numerous vendors)"); 1224MODULE_DESCRIPTION("USB network driver framework");
4241MODULE_LICENSE ("GPL"); 1225MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h
new file mode 100644
index 000000000000..7aa0abd1a9bd
--- /dev/null
+++ b/drivers/usb/net/usbnet.h
@@ -0,0 +1,193 @@
1/*
2 * USB Networking Link Interface
3 *
4 * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
5 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22
23#ifndef __USBNET_H
24#define __USBNET_H
25
26
27/* interface from usbnet core to each USB networking link we handle */
28struct usbnet {
29 /* housekeeping */
30 struct usb_device *udev;
31 struct driver_info *driver_info;
32 wait_queue_head_t *wait;
33
34 /* i/o info: pipes etc */
35 unsigned in, out;
36 struct usb_host_endpoint *status;
37 unsigned maxpacket;
38 struct timer_list delay;
39
40 /* protocol/interface state */
41 struct net_device *net;
42 struct net_device_stats stats;
43 int msg_enable;
44 unsigned long data [5];
45 u32 xid;
46 u32 hard_mtu; /* count any extra framing */
47 size_t rx_urb_size; /* size for rx urbs */
48 struct mii_if_info mii;
49
50 /* various kinds of pending driver work */
51 struct sk_buff_head rxq;
52 struct sk_buff_head txq;
53 struct sk_buff_head done;
54 struct urb *interrupt;
55 struct tasklet_struct bh;
56
57 struct work_struct kevent;
58 unsigned long flags;
59# define EVENT_TX_HALT 0
60# define EVENT_RX_HALT 1
61# define EVENT_RX_MEMORY 2
62# define EVENT_STS_SPLIT 3
63# define EVENT_LINK_RESET 4
64};
65
66static inline struct usb_driver *driver_of(struct usb_interface *intf)
67{
68 return to_usb_driver(intf->dev.driver);
69}
70
71/* interface from the device/framing level "minidriver" to core */
72struct driver_info {
73 char *description;
74
75 int flags;
76/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
77#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
78#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */
79#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */
80#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */
81
82#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
83#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
84
85#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
86
87 /* init device ... can sleep, or cause probe() failure */
88 int (*bind)(struct usbnet *, struct usb_interface *);
89
90 /* cleanup device ... can sleep, but can't fail */
91 void (*unbind)(struct usbnet *, struct usb_interface *);
92
93 /* reset device ... can sleep */
94 int (*reset)(struct usbnet *);
95
96 /* see if peer is connected ... can sleep */
97 int (*check_connect)(struct usbnet *);
98
99 /* for status polling */
100 void (*status)(struct usbnet *, struct urb *);
101
102 /* link reset handling, called from defer_kevent */
103 int (*link_reset)(struct usbnet *);
104
105 /* fixup rx packet (strip framing) */
106 int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
107
108 /* fixup tx packet (add framing) */
109 struct sk_buff *(*tx_fixup)(struct usbnet *dev,
110 struct sk_buff *skb, unsigned flags);
111
112 /* for new devices, use the descriptor-reading code instead */
113 int in; /* rx endpoint */
114 int out; /* tx endpoint */
115
116 unsigned long data; /* Misc driver specific data */
117};
118
119/* Minidrivers are just drivers using the "usbnet" core as a powerful
120 * network-specific subroutine library ... that happens to do pretty
121 * much everything except custom framing and chip-specific stuff.
122 */
123extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
124extern int usbnet_suspend (struct usb_interface *, pm_message_t );
125extern int usbnet_resume (struct usb_interface *);
126extern void usbnet_disconnect(struct usb_interface *);
127
128
129/* Drivers that reuse some of the standard USB CDC infrastructure
130 * (notably, using multiple interfaces according to the the CDC
131 * union descriptor) get some helper code.
132 */
133struct cdc_state {
134 struct usb_cdc_header_desc *header;
135 struct usb_cdc_union_desc *u;
136 struct usb_cdc_ether_desc *ether;
137 struct usb_interface *control;
138 struct usb_interface *data;
139};
140
141extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *);
142extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
143
144/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
145#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
146 |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
147 |USB_CDC_PACKET_TYPE_PROMISCUOUS \
148 |USB_CDC_PACKET_TYPE_DIRECTED)
149
150
151/* we record the state for each of our queued skbs */
152enum skb_state {
153 illegal = 0,
154 tx_start, tx_done,
155 rx_start, rx_done, rx_cleanup
156};
157
158struct skb_data { /* skb->cb is one of these */
159 struct urb *urb;
160 struct usbnet *dev;
161 enum skb_state state;
162 size_t length;
163};
164
165
166extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
167extern void usbnet_defer_kevent (struct usbnet *, int);
168extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
169
170extern u32 usbnet_get_msglevel (struct net_device *);
171extern void usbnet_set_msglevel (struct net_device *, u32);
172extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
173
174/* messaging support includes the interface name, so it must not be
175 * used before it has one ... notably, in minidriver bind() calls.
176 */
177#ifdef DEBUG
178#define devdbg(usbnet, fmt, arg...) \
179 printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
180#else
181#define devdbg(usbnet, fmt, arg...) do {} while(0)
182#endif
183
184#define deverr(usbnet, fmt, arg...) \
185 printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
186#define devwarn(usbnet, fmt, arg...) \
187 printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
188
189#define devinfo(usbnet, fmt, arg...) \
190 printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
191
192
193#endif /* __USBNET_H */
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
new file mode 100644
index 000000000000..ee3b892aeabc
--- /dev/null
+++ b/drivers/usb/net/zaurus.c
@@ -0,0 +1,386 @@
1/*
2 * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
3 * Copyright (C) 2002-2005 by David Brownell
4 *
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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// #define DEBUG // error path messages, extra info
21// #define VERBOSE // more; success messages
22
23#include <linux/config.h>
24#ifdef CONFIG_USB_DEBUG
25# define DEBUG
26#endif
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/init.h>
30#include <linux/netdevice.h>
31#include <linux/ethtool.h>
32#include <linux/workqueue.h>
33#include <linux/mii.h>
34#include <linux/crc32.h>
35#include <linux/usb.h>
36#include <linux/usb_cdc.h>
37
38#include "usbnet.h"
39
40
41/*
42 * All known Zaurii lie about their standards conformance. At least
43 * the earliest SA-1100 models lie by saying they support CDC Ethernet.
44 * Some later models (especially PXA-25x and PXA-27x based ones) lie
45 * and say they support CDC MDLM (for access to cell phone modems).
46 *
47 * There are non-Zaurus products that use these same protocols too.
48 *
49 * The annoying thing is that at the same time Sharp was developing
50 * that annoying standards-breaking software, the Linux community had
51 * a simple "CDC Subset" working reliably on the same SA-1100 hardware.
52 * That is, the same functionality but not violating standards.
53 *
54 * The CDC Ethernet nonconformance points are troublesome to hosts
55 * with a true CDC Ethernet implementation:
56 * - Framing appends a CRC, which the spec says drivers "must not" do;
57 * - Transfers data in altsetting zero, instead of altsetting 1;
58 * - All these peripherals use the same ethernet address.
59 *
60 * The CDC MDLM nonconformance is less immediately troublesome, since all
61 * MDLM implementations are quasi-proprietary anyway.
62 */
63
64static struct sk_buff *
65zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
66{
67 int padlen;
68 struct sk_buff *skb2;
69
70 padlen = 2;
71 if (!skb_cloned(skb)) {
72 int tailroom = skb_tailroom(skb);
73 if ((padlen + 4) <= tailroom)
74 goto done;
75 }
76 skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags);
77 dev_kfree_skb_any(skb);
78 skb = skb2;
79 if (skb) {
80 u32 fcs;
81done:
82 fcs = crc32_le(~0, skb->data, skb->len);
83 fcs = ~fcs;
84
85 *skb_put (skb, 1) = fcs & 0xff;
86 *skb_put (skb, 1) = (fcs>> 8) & 0xff;
87 *skb_put (skb, 1) = (fcs>>16) & 0xff;
88 *skb_put (skb, 1) = (fcs>>24) & 0xff;
89 }
90 return skb;
91}
92
93static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf)
94{
95 /* Belcarra's funky framing has other options; mostly
96 * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes.
97 */
98 dev->net->hard_header_len += 6;
99 dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
100 return usbnet_generic_cdc_bind(dev, intf);
101}
102
103/* PDA style devices are always connected if present */
104static int always_connected (struct usbnet *dev)
105{
106 return 0;
107}
108
109static const struct driver_info zaurus_sl5x00_info = {
110 .description = "Sharp Zaurus SL-5x00",
111 .flags = FLAG_FRAMING_Z,
112 .check_connect = always_connected,
113 .bind = zaurus_bind,
114 .unbind = usbnet_cdc_unbind,
115 .tx_fixup = zaurus_tx_fixup,
116};
117#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
118
119static const struct driver_info zaurus_pxa_info = {
120 .description = "Sharp Zaurus, PXA-2xx based",
121 .flags = FLAG_FRAMING_Z,
122 .check_connect = always_connected,
123 .bind = zaurus_bind,
124 .unbind = usbnet_cdc_unbind,
125 .tx_fixup = zaurus_tx_fixup,
126};
127#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
128
129static const struct driver_info olympus_mxl_info = {
130 .description = "Olympus R1000",
131 .flags = FLAG_FRAMING_Z,
132 .check_connect = always_connected,
133 .bind = zaurus_bind,
134 .unbind = usbnet_cdc_unbind,
135 .tx_fixup = zaurus_tx_fixup,
136};
137#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
138
139
140/* Some more recent products using Lineo/Belcarra code will wrongly claim
141 * CDC MDLM conformance. They aren't conformant: data endpoints live
142 * in the control interface, there's no data interface, and it's not used
143 * to talk to a cell phone radio. But at least we can detect these two
144 * pseudo-classes, rather than growing this product list with entries for
145 * each new nonconformant product (sigh).
146 */
147static const u8 safe_guid[16] = {
148 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
149 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
150};
151static const u8 blan_guid[16] = {
152 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
153 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
154};
155
156static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf)
157{
158 u8 *buf = intf->cur_altsetting->extra;
159 int len = intf->cur_altsetting->extralen;
160 struct usb_cdc_mdlm_desc *desc = NULL;
161 struct usb_cdc_mdlm_detail_desc *detail = NULL;
162
163 while (len > 3) {
164 if (buf [1] != USB_DT_CS_INTERFACE)
165 goto next_desc;
166
167 /* use bDescriptorSubType, and just verify that we get a
168 * "BLAN" (or "SAFE") descriptor.
169 */
170 switch (buf [2]) {
171 case USB_CDC_MDLM_TYPE:
172 if (desc) {
173 dev_dbg(&intf->dev, "extra MDLM\n");
174 goto bad_desc;
175 }
176 desc = (void *) buf;
177 if (desc->bLength != sizeof *desc) {
178 dev_dbg(&intf->dev, "MDLM len %u\n",
179 desc->bLength);
180 goto bad_desc;
181 }
182 /* expect bcdVersion 1.0, ignore */
183 if (memcmp(&desc->bGUID, blan_guid, 16)
184 && memcmp(&desc->bGUID, safe_guid, 16) ) {
185 /* hey, this one might _really_ be MDLM! */
186 dev_dbg(&intf->dev, "MDLM guid\n");
187 goto bad_desc;
188 }
189 break;
190 case USB_CDC_MDLM_DETAIL_TYPE:
191 if (detail) {
192 dev_dbg(&intf->dev, "extra MDLM detail\n");
193 goto bad_desc;
194 }
195 detail = (void *) buf;
196 switch (detail->bGuidDescriptorType) {
197 case 0: /* "SAFE" */
198 if (detail->bLength != (sizeof *detail + 2))
199 goto bad_detail;
200 break;
201 case 1: /* "BLAN" */
202 if (detail->bLength != (sizeof *detail + 3))
203 goto bad_detail;
204 break;
205 default:
206 goto bad_detail;
207 }
208
209 /* assuming we either noticed BLAN already, or will
210 * find it soon, there are some data bytes here:
211 * - bmNetworkCapabilities (unused)
212 * - bmDataCapabilities (bits, see below)
213 * - bPad (ignored, for PADAFTER -- BLAN-only)
214 * bits are:
215 * - 0x01 -- Zaurus framing (add CRC)
216 * - 0x02 -- PADBEFORE (CRC includes some padding)
217 * - 0x04 -- PADAFTER (some padding after CRC)
218 * - 0x08 -- "fermat" packet mangling (for hw bugs)
219 * the PADBEFORE appears not to matter; we interop
220 * with devices that use it and those that don't.
221 */
222 if ((detail->bDetailData[1] & ~0x02) != 0x01) {
223 /* bmDataCapabilites == 0 would be fine too,
224 * but framing is minidriver-coupled for now.
225 */
226bad_detail:
227 dev_dbg(&intf->dev,
228 "bad MDLM detail, %d %d %d\n",
229 detail->bLength,
230 detail->bDetailData[0],
231 detail->bDetailData[2]);
232 goto bad_desc;
233 }
234 break;
235 }
236next_desc:
237 len -= buf [0]; /* bLength */
238 buf += buf [0];
239 }
240
241 if (!desc || !detail) {
242 dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
243 desc ? "" : "func ",
244 detail ? "" : "detail ");
245 goto bad_desc;
246 }
247
248 /* There's probably a CDC Ethernet descriptor there, but we can't
249 * rely on the Ethernet address it provides since not all vendors
250 * bother to make it unique. Likewise there's no point in tracking
251 * of the CDC event notifications.
252 */
253 return usbnet_get_endpoints(dev, intf);
254
255bad_desc:
256 dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n");
257 return -ENODEV;
258}
259
260static const struct driver_info bogus_mdlm_info = {
261 .description = "pseudo-MDLM (BLAN) device",
262 .flags = FLAG_FRAMING_Z,
263 .check_connect = always_connected,
264 .tx_fixup = zaurus_tx_fixup,
265 .bind = blan_mdlm_bind,
266};
267
268static const struct usb_device_id products [] = {
269#define ZAURUS_MASTER_INTERFACE \
270 .bInterfaceClass = USB_CLASS_COMM, \
271 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
272 .bInterfaceProtocol = USB_CDC_PROTO_NONE
273
274/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
275{
276 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
277 | USB_DEVICE_ID_MATCH_DEVICE,
278 .idVendor = 0x04DD,
279 .idProduct = 0x8004,
280 ZAURUS_MASTER_INTERFACE,
281 .driver_info = ZAURUS_STRONGARM_INFO,
282},
283
284/* PXA-2xx based models are also lying-about-cdc. If you add any
285 * more devices that claim to be CDC Ethernet, make sure they get
286 * added to the blacklist in cdc_ether too.
287 *
288 * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries,
289 * unlike the older ones with 2.4 "embedix" kernels.
290 */
291{
292 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
293 | USB_DEVICE_ID_MATCH_DEVICE,
294 .idVendor = 0x04DD,
295 .idProduct = 0x8005, /* A-300 */
296 ZAURUS_MASTER_INTERFACE,
297 .driver_info = ZAURUS_PXA_INFO,
298}, {
299 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
300 | USB_DEVICE_ID_MATCH_DEVICE,
301 .idVendor = 0x04DD,
302 .idProduct = 0x8006, /* B-500/SL-5600 */
303 ZAURUS_MASTER_INTERFACE,
304 .driver_info = ZAURUS_PXA_INFO,
305}, {
306 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
307 | USB_DEVICE_ID_MATCH_DEVICE,
308 .idVendor = 0x04DD,
309 .idProduct = 0x8007, /* C-700 */
310 ZAURUS_MASTER_INTERFACE,
311 .driver_info = ZAURUS_PXA_INFO,
312}, {
313 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
314 | USB_DEVICE_ID_MATCH_DEVICE,
315 .idVendor = 0x04DD,
316 .idProduct = 0x9031, /* C-750 C-760 */
317 ZAURUS_MASTER_INTERFACE,
318 .driver_info = ZAURUS_PXA_INFO,
319}, {
320 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
321 | USB_DEVICE_ID_MATCH_DEVICE,
322 .idVendor = 0x04DD,
323 .idProduct = 0x9032, /* SL-6000 */
324 ZAURUS_MASTER_INTERFACE,
325 .driver_info = ZAURUS_PXA_INFO,
326}, {
327 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
328 | USB_DEVICE_ID_MATCH_DEVICE,
329 .idVendor = 0x04DD,
330 /* reported with some C860 units */
331 .idProduct = 0x9050, /* C-860 */
332 ZAURUS_MASTER_INTERFACE,
333 .driver_info = ZAURUS_PXA_INFO,
334},
335
336
337/* At least some of the newest PXA units have very different lies about
338 * their standards support: they claim to be cell phones offering
339 * direct access to their radios! (No, they don't conform to CDC MDLM.)
340 */
341{
342 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
343 USB_CDC_PROTO_NONE),
344 .driver_info = (unsigned long) &bogus_mdlm_info,
345},
346
347/* Olympus has some models with a Zaurus-compatible option.
348 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
349 */
350{
351 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
352 | USB_DEVICE_ID_MATCH_DEVICE,
353 .idVendor = 0x07B4,
354 .idProduct = 0x0F02, /* R-1000 */
355 ZAURUS_MASTER_INTERFACE,
356 .driver_info = OLYMPUS_MXL_INFO,
357},
358 { }, // END
359};
360MODULE_DEVICE_TABLE(usb, products);
361
362static struct usb_driver zaurus_driver = {
363 .owner = THIS_MODULE,
364 .name = "zaurus",
365 .id_table = products,
366 .probe = usbnet_probe,
367 .disconnect = usbnet_disconnect,
368 .suspend = usbnet_suspend,
369 .resume = usbnet_resume,
370};
371
372static int __init zaurus_init(void)
373{
374 return usb_register(&zaurus_driver);
375}
376module_init(zaurus_init);
377
378static void __exit zaurus_exit(void)
379{
380 usb_deregister(&zaurus_driver);
381}
382module_exit(zaurus_exit);
383
384MODULE_AUTHOR("Pavel Machek, David Brownell");
385MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products");
386MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index fc013978837e..c4e479ee926a 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -847,7 +847,6 @@ static void zd1201_tx_timeout(struct net_device *dev)
847 return; 847 return;
848 dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n", 848 dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
849 dev->name); 849 dev->name);
850 zd->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
851 usb_unlink_urb(zd->tx_urb); 850 usb_unlink_urb(zd->tx_urb);
852 zd->stats.tx_errors++; 851 zd->stats.tx_errors++;
853 /* Restart the timeout to quiet the watchdog: */ 852 /* Restart the timeout to quiet the watchdog: */
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 012e63e05806..05c44ae3ed32 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -453,8 +453,8 @@ static int generic_startup (struct usb_serial *serial)
453 priv->cbr_mask = B300; 453 priv->cbr_mask = B300;
454 usb_set_serial_port_data(serial->port[0], priv); 454 usb_set_serial_port_data(serial->port[0], priv);
455 455
456 return (0); 456 return 0;
457} 457}
458 458
459 459
460static int cypress_earthmate_startup (struct usb_serial *serial) 460static int cypress_earthmate_startup (struct usb_serial *serial)
@@ -464,14 +464,15 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
464 dbg("%s", __FUNCTION__); 464 dbg("%s", __FUNCTION__);
465 465
466 if (generic_startup(serial)) { 466 if (generic_startup(serial)) {
467 dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number); 467 dbg("%s - Failed setting up port %d", __FUNCTION__,
468 serial->port[0]->number);
468 return 1; 469 return 1;
469 } 470 }
470 471
471 priv = usb_get_serial_port_data(serial->port[0]); 472 priv = usb_get_serial_port_data(serial->port[0]);
472 priv->chiptype = CT_EARTHMATE; 473 priv->chiptype = CT_EARTHMATE;
473 474
474 return (0); 475 return 0;
475} /* cypress_earthmate_startup */ 476} /* cypress_earthmate_startup */
476 477
477 478
@@ -482,14 +483,15 @@ static int cypress_hidcom_startup (struct usb_serial *serial)
482 dbg("%s", __FUNCTION__); 483 dbg("%s", __FUNCTION__);
483 484
484 if (generic_startup(serial)) { 485 if (generic_startup(serial)) {
485 dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number); 486 dbg("%s - Failed setting up port %d", __FUNCTION__,
487 serial->port[0]->number);
486 return 1; 488 return 1;
487 } 489 }
488 490
489 priv = usb_get_serial_port_data(serial->port[0]); 491 priv = usb_get_serial_port_data(serial->port[0]);
490 priv->chiptype = CT_CYPHIDCOM; 492 priv->chiptype = CT_CYPHIDCOM;
491 493
492 return (0); 494 return 0;
493} /* cypress_hidcom_startup */ 495} /* cypress_hidcom_startup */
494 496
495 497
@@ -909,7 +911,8 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
909} /* cypress_ioctl */ 911} /* cypress_ioctl */
910 912
911 913
912static void cypress_set_termios (struct usb_serial_port *port, struct termios *old_termios) 914static void cypress_set_termios (struct usb_serial_port *port,
915 struct termios *old_termios)
913{ 916{
914 struct cypress_private *priv = usb_get_serial_port_data(port); 917 struct cypress_private *priv = usb_get_serial_port_data(port);
915 struct tty_struct *tty; 918 struct tty_struct *tty;
@@ -918,7 +921,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
918 unsigned long flags; 921 unsigned long flags;
919 __u8 oldlines; 922 __u8 oldlines;
920 int linechange = 0; 923 int linechange = 0;
921 924
922 dbg("%s - port %d", __FUNCTION__, port->number); 925 dbg("%s - port %d", __FUNCTION__, port->number);
923 926
924 tty = port->tty; 927 tty = port->tty;
@@ -931,10 +934,12 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
931 if (!priv->termios_initialized) { 934 if (!priv->termios_initialized) {
932 if (priv->chiptype == CT_EARTHMATE) { 935 if (priv->chiptype == CT_EARTHMATE) {
933 *(tty->termios) = tty_std_termios; 936 *(tty->termios) = tty_std_termios;
934 tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; 937 tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |
938 CLOCAL;
935 } else if (priv->chiptype == CT_CYPHIDCOM) { 939 } else if (priv->chiptype == CT_CYPHIDCOM) {
936 *(tty->termios) = tty_std_termios; 940 *(tty->termios) = tty_std_termios;
937 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 941 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
942 CLOCAL;
938 } 943 }
939 priv->termios_initialized = 1; 944 priv->termios_initialized = 1;
940 } 945 }
@@ -946,12 +951,15 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
946 /* check if there are new settings */ 951 /* check if there are new settings */
947 if (old_termios) { 952 if (old_termios) {
948 if ((cflag != old_termios->c_cflag) || 953 if ((cflag != old_termios->c_cflag) ||
949 (RELEVANT_IFLAG(iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { 954 (RELEVANT_IFLAG(iflag) !=
950 dbg("%s - attempting to set new termios settings", __FUNCTION__); 955 RELEVANT_IFLAG(old_termios->c_iflag))) {
951 /* should make a copy of this in case something goes wrong in the function, we can restore it */ 956 dbg("%s - attempting to set new termios settings",
957 __FUNCTION__);
958 /* should make a copy of this in case something goes
959 * wrong in the function, we can restore it */
952 spin_lock_irqsave(&priv->lock, flags); 960 spin_lock_irqsave(&priv->lock, flags);
953 priv->tmp_termios = *(tty->termios); 961 priv->tmp_termios = *(tty->termios);
954 spin_unlock_irqrestore(&priv->lock, flags); 962 spin_unlock_irqrestore(&priv->lock, flags);
955 } else { 963 } else {
956 dbg("%s - nothing to do, exiting", __FUNCTION__); 964 dbg("%s - nothing to do, exiting", __FUNCTION__);
957 return; 965 return;
@@ -962,21 +970,34 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
962 /* set number of data bits, parity, stop bits */ 970 /* set number of data bits, parity, stop bits */
963 /* when parity is disabled the parity type bit is ignored */ 971 /* when parity is disabled the parity type bit is ignored */
964 972
965 stop_bits = cflag & CSTOPB ? 1 : 0; /* 1 means 2 stop bits, 0 means 1 stop bit */ 973 /* 1 means 2 stop bits, 0 means 1 stop bit */
966 974 stop_bits = cflag & CSTOPB ? 1 : 0;
975
967 if (cflag & PARENB) { 976 if (cflag & PARENB) {
968 parity_enable = 1; 977 parity_enable = 1;
969 parity_type = cflag & PARODD ? 1 : 0; /* 1 means odd parity, 0 means even parity */ 978 /* 1 means odd parity, 0 means even parity */
979 parity_type = cflag & PARODD ? 1 : 0;
970 } else 980 } else
971 parity_enable = parity_type = 0; 981 parity_enable = parity_type = 0;
972 982
973 if (cflag & CSIZE) { 983 if (cflag & CSIZE) {
974 switch (cflag & CSIZE) { 984 switch (cflag & CSIZE) {
975 case CS5: data_bits = 0; break; 985 case CS5:
976 case CS6: data_bits = 1; break; 986 data_bits = 0;
977 case CS7: data_bits = 2; break; 987 break;
978 case CS8: data_bits = 3; break; 988 case CS6:
979 default: err("%s - CSIZE was set, but not CS5-CS8", __FUNCTION__); data_bits = 3; 989 data_bits = 1;
990 break;
991 case CS7:
992 data_bits = 2;
993 break;
994 case CS8:
995 data_bits = 3;
996 break;
997 default:
998 err("%s - CSIZE was set, but not CS5-CS8",
999 __FUNCTION__);
1000 data_bits = 3;
980 } 1001 }
981 } else 1002 } else
982 data_bits = 3; 1003 data_bits = 3;
@@ -991,63 +1012,85 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
991 } else { 1012 } else {
992 baud_mask = (cflag & CBAUD); 1013 baud_mask = (cflag & CBAUD);
993 switch(baud_mask) { 1014 switch(baud_mask) {
994 case B300: dbg("%s - setting baud 300bps", __FUNCTION__); break; 1015 case B300:
995 case B600: dbg("%s - setting baud 600bps", __FUNCTION__); break; 1016 dbg("%s - setting baud 300bps", __FUNCTION__);
996 case B1200: dbg("%s - setting baud 1200bps", __FUNCTION__); break; 1017 break;
997 case B2400: dbg("%s - setting baud 2400bps", __FUNCTION__); break; 1018 case B600:
998 case B4800: dbg("%s - setting baud 4800bps", __FUNCTION__); break; 1019 dbg("%s - setting baud 600bps", __FUNCTION__);
999 case B9600: dbg("%s - setting baud 9600bps", __FUNCTION__); break; 1020 break;
1000 case B19200: dbg("%s - setting baud 19200bps", __FUNCTION__); break; 1021 case B1200:
1001 case B38400: dbg("%s - setting baud 38400bps", __FUNCTION__); break; 1022 dbg("%s - setting baud 1200bps", __FUNCTION__);
1002 case B57600: dbg("%s - setting baud 57600bps", __FUNCTION__); break; 1023 break;
1003 case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break; 1024 case B2400:
1004 default: dbg("%s - unknown masked baud rate", __FUNCTION__); 1025 dbg("%s - setting baud 2400bps", __FUNCTION__);
1026 break;
1027 case B4800:
1028 dbg("%s - setting baud 4800bps", __FUNCTION__);
1029 break;
1030 case B9600:
1031 dbg("%s - setting baud 9600bps", __FUNCTION__);
1032 break;
1033 case B19200:
1034 dbg("%s - setting baud 19200bps", __FUNCTION__);
1035 break;
1036 case B38400:
1037 dbg("%s - setting baud 38400bps", __FUNCTION__);
1038 break;
1039 case B57600:
1040 dbg("%s - setting baud 57600bps", __FUNCTION__);
1041 break;
1042 case B115200:
1043 dbg("%s - setting baud 115200bps", __FUNCTION__);
1044 break;
1045 default:
1046 dbg("%s - unknown masked baud rate", __FUNCTION__);
1005 } 1047 }
1006 priv->line_control = (CONTROL_DTR | CONTROL_RTS); 1048 priv->line_control = (CONTROL_DTR | CONTROL_RTS);
1007 } 1049 }
1008 spin_unlock_irqrestore(&priv->lock, flags); 1050 spin_unlock_irqrestore(&priv->lock, flags);
1009
1010 dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)", __FUNCTION__,
1011 stop_bits, parity_enable, parity_type, data_bits);
1012 1051
1013 cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable, 1052 dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, "
1014 parity_type, 0, CYPRESS_SET_CONFIG); 1053 "%d data_bits (+5)", __FUNCTION__, stop_bits,
1054 parity_enable, parity_type, data_bits);
1055
1056 cypress_serial_control(port, baud_mask, data_bits, stop_bits,
1057 parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
1015 1058
1016 /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure 1059 /* we perform a CYPRESS_GET_CONFIG so that the current settings are
1017 * this should confirm that all is working if it returns what we just set */ 1060 * filled into the private structure this should confirm that all is
1061 * working if it returns what we just set */
1018 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 1062 cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
1019 1063
1020 /* Here we can define custom tty settings for devices 1064 /* Here we can define custom tty settings for devices; the main tty
1021 * 1065 * termios flag base comes from empeg.c */
1022 * the main tty termios flag base comes from empeg.c
1023 */
1024 1066
1025 spin_lock_irqsave(&priv->lock, flags); 1067 spin_lock_irqsave(&priv->lock, flags);
1026 if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) { 1068 if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
1027 1069 dbg("Using custom termios settings for a baud rate of "
1028 dbg("Using custom termios settings for a baud rate of 4800bps."); 1070 "4800bps.");
1029 /* define custom termios settings for NMEA protocol */ 1071 /* define custom termios settings for NMEA protocol */
1030 1072
1031 tty->termios->c_iflag /* input modes - */ 1073 tty->termios->c_iflag /* input modes - */
1032 &= ~(IGNBRK /* disable ignore break */ 1074 &= ~(IGNBRK /* disable ignore break */
1033 | BRKINT /* disable break causes interrupt */ 1075 | BRKINT /* disable break causes interrupt */
1034 | PARMRK /* disable mark parity errors */ 1076 | PARMRK /* disable mark parity errors */
1035 | ISTRIP /* disable clear high bit of input characters */ 1077 | ISTRIP /* disable clear high bit of input char */
1036 | INLCR /* disable translate NL to CR */ 1078 | INLCR /* disable translate NL to CR */
1037 | IGNCR /* disable ignore CR */ 1079 | IGNCR /* disable ignore CR */
1038 | ICRNL /* disable translate CR to NL */ 1080 | ICRNL /* disable translate CR to NL */
1039 | IXON); /* disable enable XON/XOFF flow control */ 1081 | IXON); /* disable enable XON/XOFF flow control */
1040 1082
1041 tty->termios->c_oflag /* output modes */ 1083 tty->termios->c_oflag /* output modes */
1042 &= ~OPOST; /* disable postprocess output characters */ 1084 &= ~OPOST; /* disable postprocess output char */
1043
1044 tty->termios->c_lflag /* line discipline modes */
1045 &= ~(ECHO /* disable echo input characters */
1046 | ECHONL /* disable echo new line */
1047 | ICANON /* disable erase, kill, werase, and rprnt special characters */
1048 | ISIG /* disable interrupt, quit, and suspend special characters */
1049 | IEXTEN); /* disable non-POSIX special characters */
1050 1085
1086 tty->termios->c_lflag /* line discipline modes */
1087 &= ~(ECHO /* disable echo input characters */
1088 | ECHONL /* disable echo new line */
1089 | ICANON /* disable erase, kill, werase, and rprnt
1090 special characters */
1091 | ISIG /* disable interrupt, quit, and suspend
1092 special characters */
1093 | IEXTEN); /* disable non-POSIX special characters */
1051 } /* CT_CYPHIDCOM: Application should handle this for device */ 1094 } /* CT_CYPHIDCOM: Application should handle this for device */
1052 1095
1053 linechange = (priv->line_control != oldlines); 1096 linechange = (priv->line_control != oldlines);
@@ -1060,7 +1103,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
1060 } 1103 }
1061} /* cypress_set_termios */ 1104} /* cypress_set_termios */
1062 1105
1063 1106
1064/* returns amount of data still left in soft buffer */ 1107/* returns amount of data still left in soft buffer */
1065static int cypress_chars_in_buffer(struct usb_serial_port *port) 1108static int cypress_chars_in_buffer(struct usb_serial_port *port)
1066{ 1109{
@@ -1088,7 +1131,7 @@ static void cypress_throttle (struct usb_serial_port *port)
1088 1131
1089 spin_lock_irqsave(&priv->lock, flags); 1132 spin_lock_irqsave(&priv->lock, flags);
1090 priv->rx_flags = THROTTLED; 1133 priv->rx_flags = THROTTLED;
1091 spin_unlock_irqrestore(&priv->lock, flags); 1134 spin_unlock_irqrestore(&priv->lock, flags);
1092} 1135}
1093 1136
1094 1137
@@ -1110,7 +1153,8 @@ static void cypress_unthrottle (struct usb_serial_port *port)
1110 1153
1111 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1154 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1112 if (result) 1155 if (result)
1113 dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); 1156 dev_err(&port->dev, "%s - failed submitting read urb, "
1157 "error %d\n", __FUNCTION__, result);
1114 } 1158 }
1115} 1159}
1116 1160
@@ -1122,7 +1166,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1122 struct tty_struct *tty; 1166 struct tty_struct *tty;
1123 unsigned char *data = urb->transfer_buffer; 1167 unsigned char *data = urb->transfer_buffer;
1124 unsigned long flags; 1168 unsigned long flags;
1125 char tty_flag = TTY_NORMAL; 1169 char tty_flag = TTY_NORMAL;
1126 int havedata = 0; 1170 int havedata = 0;
1127 int bytes = 0; 1171 int bytes = 0;
1128 int result; 1172 int result;
@@ -1131,7 +1175,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1131 dbg("%s - port %d", __FUNCTION__, port->number); 1175 dbg("%s - port %d", __FUNCTION__, port->number);
1132 1176
1133 if (urb->status) { 1177 if (urb->status) {
1134 dbg("%s - nonzero read status received: %d", __FUNCTION__, urb->status); 1178 dbg("%s - nonzero read status received: %d", __FUNCTION__,
1179 urb->status);
1135 return; 1180 return;
1136 } 1181 }
1137 1182
@@ -1155,51 +1200,55 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1155 case 32: 1200 case 32:
1156 /* This is for the CY7C64013... */ 1201 /* This is for the CY7C64013... */
1157 priv->current_status = data[0] & 0xF8; 1202 priv->current_status = data[0] & 0xF8;
1158 bytes = data[1]+2; 1203 bytes = data[1] + 2;
1159 i=2; 1204 i = 2;
1160 if (bytes > 2) 1205 if (bytes > 2)
1161 havedata = 1; 1206 havedata = 1;
1162 break; 1207 break;
1163 case 8: 1208 case 8:
1164 /* This is for the CY7C63743... */ 1209 /* This is for the CY7C63743... */
1165 priv->current_status = data[0] & 0xF8; 1210 priv->current_status = data[0] & 0xF8;
1166 bytes = (data[0] & 0x07)+1; 1211 bytes = (data[0] & 0x07) + 1;
1167 i=1; 1212 i = 1;
1168 if (bytes > 1) 1213 if (bytes > 1)
1169 havedata = 1; 1214 havedata = 1;
1170 break; 1215 break;
1171 default: 1216 default:
1172 dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length); 1217 dbg("%s - wrong packet size - received %d bytes",
1218 __FUNCTION__, urb->actual_length);
1173 spin_unlock_irqrestore(&priv->lock, flags); 1219 spin_unlock_irqrestore(&priv->lock, flags);
1174 goto continue_read; 1220 goto continue_read;
1175 } 1221 }
1176 spin_unlock_irqrestore(&priv->lock, flags); 1222 spin_unlock_irqrestore(&priv->lock, flags);
1177 1223
1178 usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data); 1224 usb_serial_debug_data (debug, &port->dev, __FUNCTION__,
1225 urb->actual_length, data);
1179 1226
1180 spin_lock_irqsave(&priv->lock, flags); 1227 spin_lock_irqsave(&priv->lock, flags);
1181 /* check to see if status has changed */ 1228 /* check to see if status has changed */
1182 if (priv != NULL) { 1229 if (priv != NULL) {
1183 if (priv->current_status != priv->prev_status) { 1230 if (priv->current_status != priv->prev_status) {
1184 priv->diff_status |= priv->current_status ^ priv->prev_status; 1231 priv->diff_status |= priv->current_status ^
1232 priv->prev_status;
1185 wake_up_interruptible(&priv->delta_msr_wait); 1233 wake_up_interruptible(&priv->delta_msr_wait);
1186 priv->prev_status = priv->current_status; 1234 priv->prev_status = priv->current_status;
1187 } 1235 }
1188 } 1236 }
1189 spin_unlock_irqrestore(&priv->lock, flags); 1237 spin_unlock_irqrestore(&priv->lock, flags);
1190 1238
1191 /* hangup, as defined in acm.c... this might be a bad place for it though */ 1239 /* hangup, as defined in acm.c... this might be a bad place for it
1192 if (tty && !(tty->termios->c_cflag & CLOCAL) && !(priv->current_status & UART_CD)) { 1240 * though */
1241 if (tty && !(tty->termios->c_cflag & CLOCAL) &&
1242 !(priv->current_status & UART_CD)) {
1193 dbg("%s - calling hangup", __FUNCTION__); 1243 dbg("%s - calling hangup", __FUNCTION__);
1194 tty_hangup(tty); 1244 tty_hangup(tty);
1195 goto continue_read; 1245 goto continue_read;
1196 } 1246 }
1197 1247
1198 /* There is one error bit... I'm assuming it is a parity error indicator 1248 /* There is one error bit... I'm assuming it is a parity error
1199 * as the generic firmware will set this bit to 1 if a parity error occurs. 1249 * indicator as the generic firmware will set this bit to 1 if a
1200 * I can not find reference to any other error events. 1250 * parity error occurs.
1201 * 1251 * I can not find reference to any other error events. */
1202 */
1203 spin_lock_irqsave(&priv->lock, flags); 1252 spin_lock_irqsave(&priv->lock, flags);
1204 if (priv->current_status & CYP_ERROR) { 1253 if (priv->current_status & CYP_ERROR) {
1205 spin_unlock_irqrestore(&priv->lock, flags); 1254 spin_unlock_irqrestore(&priv->lock, flags);
@@ -1211,7 +1260,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1211 /* process read if there is data other than line status */ 1260 /* process read if there is data other than line status */
1212 if (tty && (bytes > i)) { 1261 if (tty && (bytes > i)) {
1213 for (; i < bytes ; ++i) { 1262 for (; i < bytes ; ++i) {
1214 dbg("pushing byte number %d - %d - %c",i,data[i],data[i]); 1263 dbg("pushing byte number %d - %d - %c", i, data[i],
1264 data[i]);
1215 if(tty->flip.count >= TTY_FLIPBUF_SIZE) { 1265 if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
1216 tty_flip_buffer_push(tty); 1266 tty_flip_buffer_push(tty);
1217 } 1267 }
@@ -1221,25 +1271,28 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
1221 } 1271 }
1222 1272
1223 spin_lock_irqsave(&priv->lock, flags); 1273 spin_lock_irqsave(&priv->lock, flags);
1224 priv->bytes_in += bytes; /* control and status byte(s) are also counted */ 1274 /* control and status byte(s) are also counted */
1275 priv->bytes_in += bytes;
1225 spin_unlock_irqrestore(&priv->lock, flags); 1276 spin_unlock_irqrestore(&priv->lock, flags);
1226 1277
1227continue_read: 1278continue_read:
1228 1279
1229 /* Continue trying to always read... unless the port has closed. */ 1280 /* Continue trying to always read... unless the port has closed. */
1230 1281
1231 if (port->open_count > 0) { 1282 if (port->open_count > 0) {
1232 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, 1283 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
1233 usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress), 1284 usb_rcvintpipe(port->serial->dev,
1234 port->interrupt_in_urb->transfer_buffer, 1285 port->interrupt_in_endpointAddress),
1235 port->interrupt_in_urb->transfer_buffer_length, 1286 port->interrupt_in_urb->transfer_buffer,
1236 cypress_read_int_callback, port, 1287 port->interrupt_in_urb->transfer_buffer_length,
1237 interval); 1288 cypress_read_int_callback, port, interval);
1238 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1289 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1239 if (result) 1290 if (result)
1240 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 1291 dev_err(&urb->dev->dev, "%s - failed resubmitting "
1292 "read urb, error %d\n", __FUNCTION__,
1293 result);
1241 } 1294 }
1242 1295
1243 return; 1296 return;
1244} /* cypress_read_int_callback */ 1297} /* cypress_read_int_callback */
1245 1298
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d1964a0c4168..0a6e8b474b1f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -269,6 +269,8 @@
269#define DRIVER_DESC "USB FTDI Serial Converters Driver" 269#define DRIVER_DESC "USB FTDI Serial Converters Driver"
270 270
271static int debug; 271static int debug;
272static __u16 vendor = FTDI_VID;
273static __u16 product;
272 274
273/* struct ftdi_sio_quirk is used by devices requiring special attention. */ 275/* struct ftdi_sio_quirk is used by devices requiring special attention. */
274struct ftdi_sio_quirk { 276struct ftdi_sio_quirk {
@@ -407,6 +409,34 @@ static struct usb_device_id id_table_combined [] = {
407 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) }, 409 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
408 { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, 410 { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
409 { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, 411 { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
412 { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
413 { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
414 /*
415 * These will probably use user-space drivers. Uncomment them if
416 * you need them or use the user-specified vendor/product module
417 * parameters (see ftdi_sio.h for the numbers). Make a fuss if
418 * you think the driver should recognize any of them by default.
419 */
420 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
421 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
422 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
423 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
424 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
425 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
426 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
427 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
428 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
429 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
430 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
431 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */
432 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
433 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
434 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
435 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
436 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
437 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
438 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
439 /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
410 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, 440 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
411 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, 441 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
412 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, 442 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -418,6 +448,7 @@ static struct usb_device_id id_table_combined [] = {
418 { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, 448 { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
419 { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, 449 { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
420 { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, 450 { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
451 { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
421 { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, 452 { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
422 { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, 453 { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
423 { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, 454 { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
@@ -427,12 +458,21 @@ static struct usb_device_id id_table_combined [] = {
427 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) }, 458 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) },
428 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, 459 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
429 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, 460 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
461 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
462 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
463 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
464 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) },
465 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) },
466 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
467 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
468 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
430 { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, 469 { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
431 { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, 470 { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
432 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, 471 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
433 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, 472 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
434 { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, 473 { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
435 { } /* Terminating entry */ 474 { }, /* Optional parameter entry */
475 { } /* Terminating entry */
436}; 476};
437 477
438MODULE_DEVICE_TABLE (usb, id_table_combined); 478MODULE_DEVICE_TABLE (usb, id_table_combined);
@@ -2030,6 +2070,15 @@ static int __init ftdi_init (void)
2030 int retval; 2070 int retval;
2031 2071
2032 dbg("%s", __FUNCTION__); 2072 dbg("%s", __FUNCTION__);
2073 if (vendor > 0 && product > 0) {
2074 /* Add user specified VID/PID to reserved element of table. */
2075 int i;
2076 for (i = 0; id_table_combined[i].idVendor; i++)
2077 ;
2078 id_table_combined[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
2079 id_table_combined[i].idVendor = vendor;
2080 id_table_combined[i].idProduct = product;
2081 }
2033 retval = usb_serial_register(&ftdi_sio_device); 2082 retval = usb_serial_register(&ftdi_sio_device);
2034 if (retval) 2083 if (retval)
2035 goto failed_sio_register; 2084 goto failed_sio_register;
@@ -2066,4 +2115,9 @@ MODULE_LICENSE("GPL");
2066 2115
2067module_param(debug, bool, S_IRUGO | S_IWUSR); 2116module_param(debug, bool, S_IRUGO | S_IWUSR);
2068MODULE_PARM_DESC(debug, "Debug enabled or not"); 2117MODULE_PARM_DESC(debug, "Debug enabled or not");
2118module_param(vendor, ushort, 0);
2119MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
2120 __MODULE_STRING(FTDI_VID)")");
2121module_param(product, ushort, 0);
2122MODULE_PARM_DESC(vendor, "User specified product ID");
2069 2123
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 9f4342093e8b..2c35d74cc6d6 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -142,10 +142,43 @@
142/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ 142/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
143#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ 143#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
144 144
145/* ELV USB Module UO100 (PID sent by Stefan Frings) */ 145/*
146#define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ 146 * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
147/* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ 147 * All of these devices use FTDI's vendor ID (0x0403).
148#define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ 148 *
149 * The previously included PID for the UO 100 module was incorrect.
150 * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58).
151 *
152 * Armin Laeuger originally sent the PID for the UM 100 module.
153 */
154#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
155#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
156#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
157#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */
158/* Additional ELV PIDs that default to using the FTDI D2XX drivers on
159 * MS Windows, rather than the FTDI Virtual Com Port drivers.
160 * Maybe these will be easier to use with the libftdi/libusb user-space
161 * drivers, or possibly the Comedi drivers in some cases. */
162#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */
163#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */
164#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */
165#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */
166#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */
167#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */
168#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */
169#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */
170#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */
171#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */
172#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */
173#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */
174#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */
175#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
176#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */
177#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */
178#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */
179#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
180#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
181#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
149 182
150/* 183/*
151 * Definitions for ID TECH (www.idt-net.com) devices 184 * Definitions for ID TECH (www.idt-net.com) devices
@@ -222,6 +255,7 @@
222 */ 255 */
223#define FALCOM_VID 0x0F94 /* Vendor Id */ 256#define FALCOM_VID 0x0F94 /* Vendor Id */
224#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ 257#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */
258#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */
225 259
226/* 260/*
227 * SUUNTO product ids 261 * SUUNTO product ids
@@ -277,6 +311,18 @@
277#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ 311#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */
278 312
279/* 313/*
314 * Xsens Technologies BV products (http://www.xsens.com).
315 */
316#define XSENS_CONVERTER_0_PID 0xD388
317#define XSENS_CONVERTER_1_PID 0xD389
318#define XSENS_CONVERTER_2_PID 0xD38A
319#define XSENS_CONVERTER_3_PID 0xD38B
320#define XSENS_CONVERTER_4_PID 0xD38C
321#define XSENS_CONVERTER_5_PID 0xD38D
322#define XSENS_CONVERTER_6_PID 0xD38E
323#define XSENS_CONVERTER_7_PID 0xD38F
324
325/*
280 * Evolution Robotics products (http://www.evolution.com/). 326 * Evolution Robotics products (http://www.evolution.com/).
281 * Submitted by Shawn M. Lavelle. 327 * Submitted by Shawn M. Lavelle.
282 */ 328 */
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index fb0926292228..3b958e60f5e8 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -383,11 +383,8 @@ static int keyspan_write(struct usb_serial_port *port,
383 dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip); 383 dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip);
384 384
385 if (this_urb->status == -EINPROGRESS) { 385 if (this_urb->status == -EINPROGRESS) {
386 if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
387 break;
388 if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ)) 386 if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ))
389 break; 387 break;
390 this_urb->transfer_flags |= URB_ASYNC_UNLINK;
391 usb_unlink_urb(this_urb); 388 usb_unlink_urb(this_urb);
392 break; 389 break;
393 } 390 }
@@ -402,7 +399,6 @@ static int keyspan_write(struct usb_serial_port *port,
402 /* send the data out the bulk port */ 399 /* send the data out the bulk port */
403 this_urb->transfer_buffer_length = todo + dataOffset; 400 this_urb->transfer_buffer_length = todo + dataOffset;
404 401
405 this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
406 this_urb->dev = port->serial->dev; 402 this_urb->dev = port->serial->dev;
407 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { 403 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
408 dbg("usb_submit_urb(write bulk) failed (%d)", err); 404 dbg("usb_submit_urb(write bulk) failed (%d)", err);
@@ -1119,10 +1115,8 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
1119 1115
1120static inline void stop_urb(struct urb *urb) 1116static inline void stop_urb(struct urb *urb)
1121{ 1117{
1122 if (urb && urb->status == -EINPROGRESS) { 1118 if (urb && urb->status == -EINPROGRESS)
1123 urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1124 usb_kill_urb(urb); 1119 usb_kill_urb(urb);
1125 }
1126} 1120}
1127 1121
1128static void keyspan_close(struct usb_serial_port *port, struct file *filp) 1122static void keyspan_close(struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e9256408757f..92d0f925d053 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -45,29 +45,29 @@
45#include "usb-serial.h" 45#include "usb-serial.h"
46 46
47/* Function prototypes */ 47/* Function prototypes */
48static int option_open (struct usb_serial_port *port, struct file *filp); 48static int option_open(struct usb_serial_port *port, struct file *filp);
49static void option_close (struct usb_serial_port *port, struct file *filp); 49static void option_close(struct usb_serial_port *port, struct file *filp);
50static int option_startup (struct usb_serial *serial); 50static int option_startup(struct usb_serial *serial);
51static void option_shutdown (struct usb_serial *serial); 51static void option_shutdown(struct usb_serial *serial);
52static void option_rx_throttle (struct usb_serial_port *port); 52static void option_rx_throttle(struct usb_serial_port *port);
53static void option_rx_unthrottle (struct usb_serial_port *port); 53static void option_rx_unthrottle(struct usb_serial_port *port);
54static int option_write_room (struct usb_serial_port *port); 54static int option_write_room(struct usb_serial_port *port);
55 55
56static void option_instat_callback(struct urb *urb, struct pt_regs *regs); 56static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
57 57
58static int option_write (struct usb_serial_port *port, 58static int option_write(struct usb_serial_port *port,
59 const unsigned char *buf, int count); 59 const unsigned char *buf, int count);
60 60
61static int option_chars_in_buffer (struct usb_serial_port *port); 61static int option_chars_in_buffer(struct usb_serial_port *port);
62static int option_ioctl (struct usb_serial_port *port, struct file *file, 62static int option_ioctl(struct usb_serial_port *port, struct file *file,
63 unsigned int cmd, unsigned long arg); 63 unsigned int cmd, unsigned long arg);
64static void option_set_termios (struct usb_serial_port *port, 64static void option_set_termios(struct usb_serial_port *port,
65 struct termios *old); 65 struct termios *old);
66static void option_break_ctl (struct usb_serial_port *port, int break_state); 66static void option_break_ctl(struct usb_serial_port *port, int break_state);
67static int option_tiocmget (struct usb_serial_port *port, struct file *file); 67static int option_tiocmget(struct usb_serial_port *port, struct file *file);
68static int option_tiocmset (struct usb_serial_port *port, struct file *file, 68static int option_tiocmset(struct usb_serial_port *port, struct file *file,
69 unsigned int set, unsigned int clear); 69 unsigned int set, unsigned int clear);
70static int option_send_setup (struct usb_serial_port *port); 70static int option_send_setup(struct usb_serial_port *port);
71 71
72/* Vendor and product IDs */ 72/* Vendor and product IDs */
73#define OPTION_VENDOR_ID 0x0AF0 73#define OPTION_VENDOR_ID 0x0AF0
@@ -76,7 +76,6 @@ static int option_send_setup (struct usb_serial_port *port);
76#define OPTION_PRODUCT_FUSION 0x6000 76#define OPTION_PRODUCT_FUSION 0x6000
77#define OPTION_PRODUCT_FUSION2 0x6300 77#define OPTION_PRODUCT_FUSION2 0x6300
78 78
79
80static struct usb_device_id option_ids[] = { 79static struct usb_device_id option_ids[] = {
81 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, 80 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
82 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, 81 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
@@ -129,7 +128,6 @@ static int debug;
129#define debug 0 128#define debug 0
130#endif 129#endif
131 130
132
133/* per port private data */ 131/* per port private data */
134 132
135#define N_IN_URB 4 133#define N_IN_URB 4
@@ -156,10 +154,8 @@ struct option_port_private {
156 unsigned long tx_start_time[N_OUT_URB]; 154 unsigned long tx_start_time[N_OUT_URB];
157}; 155};
158 156
159
160/* Functions used by new usb-serial code. */ 157/* Functions used by new usb-serial code. */
161static int __init 158static int __init option_init(void)
162option_init (void)
163{ 159{
164 int retval; 160 int retval;
165 retval = usb_serial_register(&option_3port_device); 161 retval = usb_serial_register(&option_3port_device);
@@ -179,8 +175,7 @@ failed_3port_device_register:
179 return retval; 175 return retval;
180} 176}
181 177
182static void __exit 178static void __exit option_exit(void)
183option_exit (void)
184{ 179{
185 usb_deregister (&option_driver); 180 usb_deregister (&option_driver);
186 usb_serial_deregister (&option_3port_device); 181 usb_serial_deregister (&option_3port_device);
@@ -189,39 +184,31 @@ option_exit (void)
189module_init(option_init); 184module_init(option_init);
190module_exit(option_exit); 185module_exit(option_exit);
191 186
192static void 187static void option_rx_throttle(struct usb_serial_port *port)
193option_rx_throttle (struct usb_serial_port *port)
194{ 188{
195 dbg("%s", __FUNCTION__); 189 dbg("%s", __FUNCTION__);
196} 190}
197 191
198 192static void option_rx_unthrottle(struct usb_serial_port *port)
199static void
200option_rx_unthrottle (struct usb_serial_port *port)
201{ 193{
202 dbg("%s", __FUNCTION__); 194 dbg("%s", __FUNCTION__);
203} 195}
204 196
205 197static void option_break_ctl(struct usb_serial_port *port, int break_state)
206static void
207option_break_ctl (struct usb_serial_port *port, int break_state)
208{ 198{
209 /* Unfortunately, I don't know how to send a break */ 199 /* Unfortunately, I don't know how to send a break */
210 dbg("%s", __FUNCTION__); 200 dbg("%s", __FUNCTION__);
211} 201}
212 202
213 203static void option_set_termios(struct usb_serial_port *port,
214static void 204 struct termios *old_termios)
215option_set_termios (struct usb_serial_port *port,
216 struct termios *old_termios)
217{ 205{
218 dbg("%s", __FUNCTION__); 206 dbg("%s", __FUNCTION__);
219 207
220 option_send_setup(port); 208 option_send_setup(port);
221} 209}
222 210
223static int 211static int option_tiocmget(struct usb_serial_port *port, struct file *file)
224option_tiocmget (struct usb_serial_port *port, struct file *file)
225{ 212{
226 unsigned int value; 213 unsigned int value;
227 struct option_port_private *portdata; 214 struct option_port_private *portdata;
@@ -238,9 +225,8 @@ option_tiocmget (struct usb_serial_port *port, struct file *file)
238 return value; 225 return value;
239} 226}
240 227
241static int 228static int option_tiocmset(struct usb_serial_port *port, struct file *file,
242option_tiocmset (struct usb_serial_port *port, struct file *file, 229 unsigned int set, unsigned int clear)
243 unsigned int set, unsigned int clear)
244{ 230{
245 struct option_port_private *portdata; 231 struct option_port_private *portdata;
246 232
@@ -258,17 +244,15 @@ option_tiocmset (struct usb_serial_port *port, struct file *file,
258 return option_send_setup(port); 244 return option_send_setup(port);
259} 245}
260 246
261static int 247static int option_ioctl(struct usb_serial_port *port, struct file *file,
262option_ioctl (struct usb_serial_port *port, struct file *file, 248 unsigned int cmd, unsigned long arg)
263 unsigned int cmd, unsigned long arg)
264{ 249{
265 return -ENOIOCTLCMD; 250 return -ENOIOCTLCMD;
266} 251}
267 252
268/* Write */ 253/* Write */
269static int 254static int option_write(struct usb_serial_port *port,
270option_write (struct usb_serial_port *port, 255 const unsigned char *buf, int count)
271 const unsigned char *buf, int count)
272{ 256{
273 struct option_port_private *portdata; 257 struct option_port_private *portdata;
274 int i; 258 int i;
@@ -289,28 +273,29 @@ option_write (struct usb_serial_port *port,
289 273
290 this_urb = portdata->out_urbs[i]; 274 this_urb = portdata->out_urbs[i];
291 if (this_urb->status == -EINPROGRESS) { 275 if (this_urb->status == -EINPROGRESS) {
292 if (this_urb->transfer_flags & URB_ASYNC_UNLINK) 276 if (time_before(jiffies,
293 continue; 277 portdata->tx_start_time[i] + 10 * HZ))
294 if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
295 continue; 278 continue;
296 this_urb->transfer_flags |= URB_ASYNC_UNLINK;
297 usb_unlink_urb(this_urb); 279 usb_unlink_urb(this_urb);
298 continue; 280 continue;
299 } 281 }
300 if (this_urb->status != 0) 282 if (this_urb->status != 0)
301 dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status); 283 dbg("usb_write %p failed (err=%d)",
284 this_urb, this_urb->status);
302 285
303 dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i); 286 dbg("%s: endpoint %d buf %d", __FUNCTION__,
287 usb_pipeendpoint(this_urb->pipe), i);
304 288
305 /* send the data */ 289 /* send the data */
306 memcpy (this_urb->transfer_buffer, buf, todo); 290 memcpy (this_urb->transfer_buffer, buf, todo);
307 this_urb->transfer_buffer_length = todo; 291 this_urb->transfer_buffer_length = todo;
308 292
309 this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
310 this_urb->dev = port->serial->dev; 293 this_urb->dev = port->serial->dev;
311 err = usb_submit_urb(this_urb, GFP_ATOMIC); 294 err = usb_submit_urb(this_urb, GFP_ATOMIC);
312 if (err) { 295 if (err) {
313 dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status); 296 dbg("usb_submit_urb %p (write bulk) failed "
297 "(%d, has %d)", this_urb,
298 err, this_urb->status);
314 continue; 299 continue;
315 } 300 }
316 portdata->tx_start_time[i] = jiffies; 301 portdata->tx_start_time[i] = jiffies;
@@ -323,8 +308,7 @@ option_write (struct usb_serial_port *port,
323 return count; 308 return count;
324} 309}
325 310
326static void 311static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
327option_indat_callback (struct urb *urb, struct pt_regs *regs)
328{ 312{
329 int i, err; 313 int i, err;
330 int endpoint; 314 int endpoint;
@@ -357,14 +341,14 @@ option_indat_callback (struct urb *urb, struct pt_regs *regs)
357 if (port->open_count && urb->status != -ESHUTDOWN) { 341 if (port->open_count && urb->status != -ESHUTDOWN) {
358 err = usb_submit_urb(urb, GFP_ATOMIC); 342 err = usb_submit_urb(urb, GFP_ATOMIC);
359 if (err) 343 if (err)
360 printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err); 344 printk(KERN_ERR "%s: resubmit read urb failed. "
345 "(%d)", __FUNCTION__, err);
361 } 346 }
362 } 347 }
363 return; 348 return;
364} 349}
365 350
366static void 351static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
367option_outdat_callback (struct urb *urb, struct pt_regs *regs)
368{ 352{
369 struct usb_serial_port *port; 353 struct usb_serial_port *port;
370 354
@@ -376,8 +360,7 @@ option_outdat_callback (struct urb *urb, struct pt_regs *regs)
376 schedule_work(&port->work); 360 schedule_work(&port->work);
377} 361}
378 362
379static void 363static void option_instat_callback(struct urb *urb, struct pt_regs *regs)
380option_instat_callback (struct urb *urb, struct pt_regs *regs)
381{ 364{
382 int err; 365 int err;
383 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 366 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
@@ -395,10 +378,12 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
395 dbg("%s: NULL req_pkt\n", __FUNCTION__); 378 dbg("%s: NULL req_pkt\n", __FUNCTION__);
396 return; 379 return;
397 } 380 }
398 if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) { 381 if ((req_pkt->bRequestType == 0xA1) &&
382 (req_pkt->bRequest == 0x20)) {
399 int old_dcd_state; 383 int old_dcd_state;
400 unsigned char signals = *((unsigned char *) 384 unsigned char signals = *((unsigned char *)
401 urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); 385 urb->transfer_buffer +
386 sizeof(struct usb_ctrlrequest));
402 387
403 dbg("%s: signal x%x", __FUNCTION__, signals); 388 dbg("%s: signal x%x", __FUNCTION__, signals);
404 389
@@ -408,12 +393,13 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
408 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 393 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
409 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 394 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
410 395
411 if (port->tty && !C_CLOCAL(port->tty) 396 if (port->tty && !C_CLOCAL(port->tty) &&
412 && old_dcd_state && !portdata->dcd_state) { 397 old_dcd_state && !portdata->dcd_state)
413 tty_hangup(port->tty); 398 tty_hangup(port->tty);
414 } 399 } else {
415 } else 400 dbg("%s: type %x req %x", __FUNCTION__,
416 dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest); 401 req_pkt->bRequestType,req_pkt->bRequest);
402 }
417 } else 403 } else
418 dbg("%s: error %d", __FUNCTION__, urb->status); 404 dbg("%s: error %d", __FUNCTION__, urb->status);
419 405
@@ -422,13 +408,12 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
422 urb->dev = serial->dev; 408 urb->dev = serial->dev;
423 err = usb_submit_urb(urb, GFP_ATOMIC); 409 err = usb_submit_urb(urb, GFP_ATOMIC);
424 if (err) 410 if (err)
425 dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err); 411 dbg("%s: resubmit intr urb failed. (%d)",
412 __FUNCTION__, err);
426 } 413 }
427} 414}
428 415
429 416static int option_write_room(struct usb_serial_port *port)
430static int
431option_write_room (struct usb_serial_port *port)
432{ 417{
433 struct option_port_private *portdata; 418 struct option_port_private *portdata;
434 int i; 419 int i;
@@ -447,9 +432,7 @@ option_write_room (struct usb_serial_port *port)
447 return data_len; 432 return data_len;
448} 433}
449 434
450 435static int option_chars_in_buffer(struct usb_serial_port *port)
451static int
452option_chars_in_buffer (struct usb_serial_port *port)
453{ 436{
454 struct option_port_private *portdata; 437 struct option_port_private *portdata;
455 int i; 438 int i;
@@ -467,9 +450,7 @@ option_chars_in_buffer (struct usb_serial_port *port)
467 return data_len; 450 return data_len;
468} 451}
469 452
470 453static int option_open(struct usb_serial_port *port, struct file *filp)
471static int
472option_open (struct usb_serial_port *port, struct file *filp)
473{ 454{
474 struct option_port_private *portdata; 455 struct option_port_private *portdata;
475 struct usb_serial *serial = port->serial; 456 struct usb_serial *serial = port->serial;
@@ -490,17 +471,21 @@ option_open (struct usb_serial_port *port, struct file *filp)
490 if (! urb) 471 if (! urb)
491 continue; 472 continue;
492 if (urb->dev != serial->dev) { 473 if (urb->dev != serial->dev) {
493 dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev); 474 dbg("%s: dev %p != %p", __FUNCTION__,
475 urb->dev, serial->dev);
494 continue; 476 continue;
495 } 477 }
496 478
497 /* make sure endpoint data toggle is synchronized with the device */ 479 /*
498 480 * make sure endpoint data toggle is synchronized with the
481 * device
482 */
499 usb_clear_halt(urb->dev, urb->pipe); 483 usb_clear_halt(urb->dev, urb->pipe);
500 484
501 err = usb_submit_urb(urb, GFP_KERNEL); 485 err = usb_submit_urb(urb, GFP_KERNEL);
502 if (err) { 486 if (err) {
503 dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err, 487 dbg("%s: submit urb %d failed (%d) %d",
488 __FUNCTION__, i, err,
504 urb->transfer_buffer_length); 489 urb->transfer_buffer_length);
505 } 490 }
506 } 491 }
@@ -511,7 +496,8 @@ option_open (struct usb_serial_port *port, struct file *filp)
511 if (! urb) 496 if (! urb)
512 continue; 497 continue;
513 urb->dev = serial->dev; 498 urb->dev = serial->dev;
514 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ 499 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
500 usb_pipeout(urb->pipe), 0); */
515 } 501 }
516 502
517 port->tty->low_latency = 1; 503 port->tty->low_latency = 1;
@@ -521,17 +507,13 @@ option_open (struct usb_serial_port *port, struct file *filp)
521 return (0); 507 return (0);
522} 508}
523 509
524static inline void 510static inline void stop_urb(struct urb *urb)
525stop_urb (struct urb *urb)
526{ 511{
527 if (urb && urb->status == -EINPROGRESS) { 512 if (urb && urb->status == -EINPROGRESS)
528 urb->transfer_flags &= ~URB_ASYNC_UNLINK;
529 usb_kill_urb(urb); 513 usb_kill_urb(urb);
530 }
531} 514}
532 515
533static void 516static void option_close(struct usb_serial_port *port, struct file *filp)
534option_close (struct usb_serial_port *port, struct file *filp)
535{ 517{
536 int i; 518 int i;
537 struct usb_serial *serial = port->serial; 519 struct usb_serial *serial = port->serial;
@@ -555,12 +537,10 @@ option_close (struct usb_serial_port *port, struct file *filp)
555 port->tty = NULL; 537 port->tty = NULL;
556} 538}
557 539
558
559/* Helper functions used by option_setup_urbs */ 540/* Helper functions used by option_setup_urbs */
560static struct urb * 541static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
561option_setup_urb (struct usb_serial *serial, int endpoint, 542 int dir, void *ctx, char *buf, int len,
562 int dir, void *ctx, char *buf, int len, 543 void (*callback)(struct urb *, struct pt_regs *regs))
563 void (*callback)(struct urb *, struct pt_regs *regs))
564{ 544{
565 struct urb *urb; 545 struct urb *urb;
566 546
@@ -582,8 +562,7 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
582} 562}
583 563
584/* Setup urbs */ 564/* Setup urbs */
585static void 565static void option_setup_urbs(struct usb_serial *serial)
586option_setup_urbs (struct usb_serial *serial)
587{ 566{
588 int j; 567 int j;
589 struct usb_serial_port *port; 568 struct usb_serial_port *port;
@@ -609,9 +588,7 @@ option_setup_urbs (struct usb_serial *serial)
609 } 588 }
610} 589}
611 590
612 591static int option_send_setup(struct usb_serial_port *port)
613static int
614option_send_setup (struct usb_serial_port *port)
615{ 592{
616 struct usb_serial *serial = port->serial; 593 struct usb_serial *serial = port->serial;
617 struct option_port_private *portdata; 594 struct option_port_private *portdata;
@@ -627,16 +604,15 @@ option_send_setup (struct usb_serial_port *port)
627 if (portdata->rts_state) 604 if (portdata->rts_state)
628 val |= 0x02; 605 val |= 0x02;
629 606
630 return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 607 return usb_control_msg(serial->dev,
631 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); 608 usb_rcvctrlpipe(serial->dev, 0),
609 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
632 } 610 }
633 611
634 return 0; 612 return 0;
635} 613}
636 614
637 615static int option_startup(struct usb_serial *serial)
638static int
639option_startup (struct usb_serial *serial)
640{ 616{
641 int i, err; 617 int i, err;
642 struct usb_serial_port *port; 618 struct usb_serial_port *port;
@@ -647,9 +623,10 @@ option_startup (struct usb_serial *serial)
647 /* Now setup per port private data */ 623 /* Now setup per port private data */
648 for (i = 0; i < serial->num_ports; i++) { 624 for (i = 0; i < serial->num_ports; i++) {
649 port = serial->port[i]; 625 port = serial->port[i];
650 portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL); 626 portdata = kmalloc(sizeof(*portdata), GFP_KERNEL);
651 if (!portdata) { 627 if (!portdata) {
652 dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); 628 dbg("%s: kmalloc for option_port_private (%d) failed!.",
629 __FUNCTION__, i);
653 return (1); 630 return (1);
654 } 631 }
655 memset(portdata, 0, sizeof(struct option_port_private)); 632 memset(portdata, 0, sizeof(struct option_port_private));
@@ -660,7 +637,8 @@ option_startup (struct usb_serial *serial)
660 continue; 637 continue;
661 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 638 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
662 if (err) 639 if (err)
663 dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err); 640 dbg("%s: submit irq_in urb failed %d",
641 __FUNCTION__, err);
664 } 642 }
665 643
666 option_setup_urbs(serial); 644 option_setup_urbs(serial);
@@ -668,8 +646,7 @@ option_startup (struct usb_serial *serial)
668 return (0); 646 return (0);
669} 647}
670 648
671static void 649static void option_shutdown(struct usb_serial *serial)
672option_shutdown (struct usb_serial *serial)
673{ 650{
674 int i, j; 651 int i, j;
675 struct usb_serial_port *port; 652 struct usb_serial_port *port;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 7eab5d4cf3a8..461474176cfb 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -538,8 +538,10 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
538 538
539 dbg("%s - port %d", __FUNCTION__, port->number); 539 dbg("%s - port %d", __FUNCTION__, port->number);
540 540
541 usb_clear_halt(serial->dev, port->write_urb->pipe); 541 if (priv->type != HX) {
542 usb_clear_halt(serial->dev, port->read_urb->pipe); 542 usb_clear_halt(serial->dev, port->write_urb->pipe);
543 usb_clear_halt(serial->dev, port->read_urb->pipe);
544 }
543 545
544 buf = kmalloc(10, GFP_KERNEL); 546 buf = kmalloc(10, GFP_KERNEL);
545 if (buf==NULL) 547 if (buf==NULL)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0267b26dde18..e77fbdfc782d 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -531,7 +531,7 @@ bailout_kref_put:
531 531
532static void serial_close(struct tty_struct *tty, struct file * filp) 532static void serial_close(struct tty_struct *tty, struct file * filp)
533{ 533{
534 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 534 struct usb_serial_port *port = tty->driver_data;
535 535
536 if (!port) 536 if (!port)
537 return; 537 return;
@@ -561,7 +561,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
561 561
562static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) 562static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
563{ 563{
564 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 564 struct usb_serial_port *port = tty->driver_data;
565 int retval = -EINVAL; 565 int retval = -EINVAL;
566 566
567 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); 567 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
@@ -580,7 +580,7 @@ exit:
580 580
581static int serial_write_room (struct tty_struct *tty) 581static int serial_write_room (struct tty_struct *tty)
582{ 582{
583 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 583 struct usb_serial_port *port = tty->driver_data;
584 int retval = -EINVAL; 584 int retval = -EINVAL;
585 585
586 dbg("%s - port %d", __FUNCTION__, port->number); 586 dbg("%s - port %d", __FUNCTION__, port->number);
@@ -599,7 +599,7 @@ exit:
599 599
600static int serial_chars_in_buffer (struct tty_struct *tty) 600static int serial_chars_in_buffer (struct tty_struct *tty)
601{ 601{
602 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 602 struct usb_serial_port *port = tty->driver_data;
603 int retval = -EINVAL; 603 int retval = -EINVAL;
604 604
605 dbg("%s = port %d", __FUNCTION__, port->number); 605 dbg("%s = port %d", __FUNCTION__, port->number);
@@ -618,7 +618,7 @@ exit:
618 618
619static void serial_throttle (struct tty_struct * tty) 619static void serial_throttle (struct tty_struct * tty)
620{ 620{
621 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 621 struct usb_serial_port *port = tty->driver_data;
622 622
623 dbg("%s - port %d", __FUNCTION__, port->number); 623 dbg("%s - port %d", __FUNCTION__, port->number);
624 624
@@ -634,7 +634,7 @@ static void serial_throttle (struct tty_struct * tty)
634 634
635static void serial_unthrottle (struct tty_struct * tty) 635static void serial_unthrottle (struct tty_struct * tty)
636{ 636{
637 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 637 struct usb_serial_port *port = tty->driver_data;
638 638
639 dbg("%s - port %d", __FUNCTION__, port->number); 639 dbg("%s - port %d", __FUNCTION__, port->number);
640 640
@@ -650,7 +650,7 @@ static void serial_unthrottle (struct tty_struct * tty)
650 650
651static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) 651static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
652{ 652{
653 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 653 struct usb_serial_port *port = tty->driver_data;
654 int retval = -ENODEV; 654 int retval = -ENODEV;
655 655
656 dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); 656 dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
@@ -672,7 +672,7 @@ exit:
672 672
673static void serial_set_termios (struct tty_struct *tty, struct termios * old) 673static void serial_set_termios (struct tty_struct *tty, struct termios * old)
674{ 674{
675 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 675 struct usb_serial_port *port = tty->driver_data;
676 676
677 dbg("%s - port %d", __FUNCTION__, port->number); 677 dbg("%s - port %d", __FUNCTION__, port->number);
678 678
@@ -688,7 +688,7 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
688 688
689static void serial_break (struct tty_struct *tty, int break_state) 689static void serial_break (struct tty_struct *tty, int break_state)
690{ 690{
691 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 691 struct usb_serial_port *port = tty->driver_data;
692 692
693 dbg("%s - port %d", __FUNCTION__, port->number); 693 dbg("%s - port %d", __FUNCTION__, port->number);
694 694
@@ -749,7 +749,7 @@ done:
749 749
750static int serial_tiocmget (struct tty_struct *tty, struct file *file) 750static int serial_tiocmget (struct tty_struct *tty, struct file *file)
751{ 751{
752 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 752 struct usb_serial_port *port = tty->driver_data;
753 753
754 dbg("%s - port %d", __FUNCTION__, port->number); 754 dbg("%s - port %d", __FUNCTION__, port->number);
755 755
@@ -768,7 +768,7 @@ exit:
768static int serial_tiocmset (struct tty_struct *tty, struct file *file, 768static int serial_tiocmset (struct tty_struct *tty, struct file *file,
769 unsigned int set, unsigned int clear) 769 unsigned int set, unsigned int clear)
770{ 770{
771 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; 771 struct usb_serial_port *port = tty->driver_data;
772 772
773 dbg("%s - port %d", __FUNCTION__, port->number); 773 dbg("%s - port %d", __FUNCTION__, port->number);
774 774
@@ -786,7 +786,7 @@ exit:
786 786
787void usb_serial_port_softint(void *private) 787void usb_serial_port_softint(void *private)
788{ 788{
789 struct usb_serial_port *port = (struct usb_serial_port *)private; 789 struct usb_serial_port *port = private;
790 struct tty_struct *tty; 790 struct tty_struct *tty;
791 791
792 dbg("%s - port %d", __FUNCTION__, port->number); 792 dbg("%s - port %d", __FUNCTION__, port->number);
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index f1f1c0608c22..bb9819cc8826 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -111,3 +111,15 @@ config USB_STORAGE_JUMPSHOT
111 Say Y here to include additional code to support the Lexar Jumpshot 111 Say Y here to include additional code to support the Lexar Jumpshot
112 USB CompactFlash reader. 112 USB CompactFlash reader.
113 113
114
115config USB_STORAGE_ONETOUCH
116 bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
117 depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
118 help
119 Say Y here to include additional code to support the Maxtor OneTouch
120 USB hard drive's onetouch button.
121
122 This code registers the button on the front of Maxtor OneTouch USB
123 hard drive's as an input device. An action can be associated with
124 this input in any keybinding software. (e.g. gnome's keyboard short-
125 cuts)
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 56652ccc2881..44ab8f9978fe 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
18usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o 18usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
19usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o 19usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
20usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o 20usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
21usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
21 22
22usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ 23usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
23 initializers.o $(usb-storage-obj-y) 24 initializers.o $(usb-storage-obj-y)
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
new file mode 100644
index 000000000000..2c9402dc702b
--- /dev/null
+++ b/drivers/usb/storage/onetouch.c
@@ -0,0 +1,210 @@
1/*
2 * Support for the Maxtor OneTouch USB hard drive's button
3 *
4 * Current development and maintenance by:
5 * Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
6 *
7 * Initial work by:
8 * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
9 *
10 * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
11 *
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include <linux/config.h>
32#include <linux/kernel.h>
33#include <linux/input.h>
34#include <linux/init.h>
35#include <linux/slab.h>
36#include <linux/module.h>
37#include <linux/usb.h>
38#include <linux/usb_ch9.h>
39#include <linux/usb_input.h>
40#include "usb.h"
41#include "onetouch.h"
42#include "debug.h"
43
44void onetouch_release_input(void *onetouch_);
45
46struct usb_onetouch {
47 char name[128];
48 char phys[64];
49 struct input_dev dev; /* input device interface */
50 struct usb_device *udev; /* usb device */
51
52 struct urb *irq; /* urb for interrupt in report */
53 unsigned char *data; /* input data */
54 dma_addr_t data_dma;
55};
56
57static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
58{
59 struct usb_onetouch *onetouch = urb->context;
60 signed char *data = onetouch->data;
61 struct input_dev *dev = &onetouch->dev;
62 int status;
63
64 switch (urb->status) {
65 case 0: /* success */
66 break;
67 case -ECONNRESET: /* unlink */
68 case -ENOENT:
69 case -ESHUTDOWN:
70 return;
71 /* -EPIPE: should clear the halt */
72 default: /* error */
73 goto resubmit;
74 }
75
76 input_regs(dev, regs);
77
78 input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
79 data[0] & 0x02);
80
81 input_sync(dev);
82resubmit:
83 status = usb_submit_urb (urb, SLAB_ATOMIC);
84 if (status)
85 err ("can't resubmit intr, %s-%s/input0, status %d",
86 onetouch->udev->bus->bus_name,
87 onetouch->udev->devpath, status);
88}
89
90static int usb_onetouch_open(struct input_dev *dev)
91{
92 struct usb_onetouch *onetouch = dev->private;
93
94 onetouch->irq->dev = onetouch->udev;
95 if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
96 err("usb_submit_urb failed");
97 return -EIO;
98 }
99
100 return 0;
101}
102
103static void usb_onetouch_close(struct input_dev *dev)
104{
105 struct usb_onetouch *onetouch = dev->private;
106
107 usb_kill_urb(onetouch->irq);
108}
109
110int onetouch_connect_input(struct us_data *ss)
111{
112 struct usb_device *udev = ss->pusb_dev;
113 struct usb_host_interface *interface;
114 struct usb_endpoint_descriptor *endpoint;
115 struct usb_onetouch *onetouch;
116 int pipe, maxp;
117 char path[64];
118
119 interface = ss->pusb_intf->cur_altsetting;
120
121 if (interface->desc.bNumEndpoints != 3)
122 return -ENODEV;
123
124 endpoint = &interface->endpoint[2].desc;
125 if(!(endpoint->bEndpointAddress & USB_DIR_IN))
126 return -ENODEV;
127 if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
128 != USB_ENDPOINT_XFER_INT)
129 return -ENODEV;
130
131 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
132 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
133
134 if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
135 return -ENOMEM;
136
137 onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
138 SLAB_ATOMIC, &onetouch->data_dma);
139 if (!onetouch->data){
140 kfree(onetouch);
141 return -ENOMEM;
142 }
143
144 onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
145 if (!onetouch->irq){
146 kfree(onetouch);
147 usb_buffer_free(udev, ONETOUCH_PKT_LEN,
148 onetouch->data, onetouch->data_dma);
149 return -ENODEV;
150 }
151
152
153 onetouch->udev = udev;
154
155 set_bit(EV_KEY, onetouch->dev.evbit);
156 set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
157 clear_bit(0, onetouch->dev.keybit);
158
159 onetouch->dev.private = onetouch;
160 onetouch->dev.open = usb_onetouch_open;
161 onetouch->dev.close = usb_onetouch_close;
162
163 usb_make_path(udev, path, sizeof(path));
164 sprintf(onetouch->phys, "%s/input0", path);
165
166 onetouch->dev.name = onetouch->name;
167 onetouch->dev.phys = onetouch->phys;
168
169 usb_to_input_id(udev, &onetouch->dev.id);
170
171 onetouch->dev.dev = &udev->dev;
172
173 if (udev->manufacturer)
174 strcat(onetouch->name, udev->manufacturer);
175 if (udev->product)
176 sprintf(onetouch->name, "%s %s", onetouch->name,
177 udev->product);
178 if (!strlen(onetouch->name))
179 sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
180 onetouch->dev.id.vendor, onetouch->dev.id.product);
181
182 usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
183 (maxp > 8 ? 8 : maxp),
184 usb_onetouch_irq, onetouch, endpoint->bInterval);
185 onetouch->irq->transfer_dma = onetouch->data_dma;
186 onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
187
188 ss->extra_destructor = onetouch_release_input;
189 ss->extra = onetouch;
190
191 input_register_device(&onetouch->dev);
192 printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
193
194 return 0;
195}
196
197void onetouch_release_input(void *onetouch_)
198{
199 struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_;
200
201 if (onetouch) {
202 usb_kill_urb(onetouch->irq);
203 input_unregister_device(&onetouch->dev);
204 usb_free_urb(onetouch->irq);
205 usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
206 onetouch->data, onetouch->data_dma);
207 printk(KERN_INFO "usb-input: deregistering %s\n",
208 onetouch->dev.name);
209 }
210}
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
new file mode 100644
index 000000000000..41c7aa8f0446
--- /dev/null
+++ b/drivers/usb/storage/onetouch.h
@@ -0,0 +1,9 @@
1#ifndef _ONETOUCH_H_
2#define _ONETOUCH_H_
3
4#define ONETOUCH_PKT_LEN 0x02
5#define ONETOUCH_BUTTON KEY_PROG1
6
7int onetouch_connect_input(struct us_data *ss);
8
9#endif
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index af294bb68c35..d34dc9f417f0 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -156,6 +156,14 @@ static int slave_configure(struct scsi_device *sdev)
156 if (us->flags & US_FL_FIX_CAPACITY) 156 if (us->flags & US_FL_FIX_CAPACITY)
157 sdev->fix_capacity = 1; 157 sdev->fix_capacity = 1;
158 158
159 /* Some devices report a SCSI revision level above 2 but are
160 * unable to handle the REPORT LUNS command (for which
161 * support is mandatory at level 3). Since we already have
162 * a Get-Max-LUN request, we won't lose much by setting the
163 * revision level down to 2. The only devices that would be
164 * affected are those with sparse LUNs. */
165 sdev->scsi_level = SCSI_2;
166
159 /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable 167 /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
160 * Hardware Error) when any low-level error occurs, 168 * Hardware Error) when any low-level error occurs,
161 * recoverable or not. Setting this flag tells the SCSI 169 * recoverable or not. Setting this flag tells the SCSI
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index f3b60288696c..356342c6e7a2 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -839,34 +839,31 @@ static int usbat_identify_device(struct us_data *us,
839 rc = usbat_device_reset(us); 839 rc = usbat_device_reset(us);
840 if (rc != USB_STOR_TRANSPORT_GOOD) 840 if (rc != USB_STOR_TRANSPORT_GOOD)
841 return rc; 841 return rc;
842 msleep(25);
842 843
843 /* 844 /*
844 * By examining the device signature after a reset, we can identify 845 * In attempt to distinguish between HP CDRW's and Flash readers, we now
845 * whether the device supports the ATAPI packet interface. 846 * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash
846 * The flash-devices do not support this, whereas the HP CDRW's obviously 847 * readers), this command should fail with error. On ATAPI devices (i.e.
847 * do. 848 * CDROM drives), it should succeed.
848 *
849 * This method is not ideal, but works because no other devices have been
850 * produced based on the USBAT/USBAT02.
851 *
852 * Section 9.1 of the ATAPI-4 spec states (amongst other things) that
853 * after a device reset, a Cylinder low of 0x14 indicates that the device
854 * does support packet commands.
855 */ 849 */
856 rc = usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, &status); 850 rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1);
857 if (rc != USB_STOR_XFER_GOOD) 851 if (rc != USB_STOR_XFER_GOOD)
858 return USB_STOR_TRANSPORT_ERROR; 852 return USB_STOR_TRANSPORT_ERROR;
859 853
860 US_DEBUGP("usbat_identify_device: Cylinder low is %02X\n", status); 854 rc = usbat_get_status(us, &status);
855 if (rc != USB_STOR_XFER_GOOD)
856 return USB_STOR_TRANSPORT_ERROR;
861 857
862 if (status == 0x14) { 858 // Check for error bit
859 if (status & 0x01) {
860 // Device is a CompactFlash reader/writer
861 US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
862 info->devicetype = USBAT_DEV_FLASH;
863 } else {
863 // Device is HP 8200 864 // Device is HP 8200
864 US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); 865 US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");
865 info->devicetype = USBAT_DEV_HP8200; 866 info->devicetype = USBAT_DEV_HP8200;
866 } else {
867 // Device is a CompactFlash reader/writer
868 US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
869 info->devicetype = USBAT_DEV_FLASH;
870 } 867 }
871 868
872 return USB_STOR_TRANSPORT_GOOD; 869 return USB_STOR_TRANSPORT_GOOD;
@@ -1239,16 +1236,10 @@ static int usbat_select_and_test_registers(struct us_data *us)
1239{ 1236{
1240 int selector; 1237 int selector;
1241 unsigned char *status = us->iobuf; 1238 unsigned char *status = us->iobuf;
1242 unsigned char max_selector = 0xB0;
1243 if (usbat_get_device_type(us) == USBAT_DEV_FLASH)
1244 max_selector = 0xA0;
1245 1239
1246 // try device = master, then device = slave. 1240 // try device = master, then device = slave.
1247 1241 for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
1248 for (selector = 0xA0; selector <= max_selector; selector += 0x10) { 1242 if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
1249
1250 if (usbat_get_device_type(us) == USBAT_DEV_HP8200 &&
1251 usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
1252 USB_STOR_XFER_GOOD) 1243 USB_STOR_XFER_GOOD)
1253 return USB_STOR_TRANSPORT_ERROR; 1244 return USB_STOR_TRANSPORT_ERROR;
1254 1245
@@ -1334,60 +1325,30 @@ int init_usbat(struct us_data *us)
1334 1325
1335 US_DEBUGP("INIT 3\n"); 1326 US_DEBUGP("INIT 3\n");
1336 1327
1337 // At this point, we need to detect which device we are using
1338 if (usbat_set_transport(us, info))
1339 return USB_STOR_TRANSPORT_ERROR;
1340
1341 US_DEBUGP("INIT 4\n");
1342
1343 if (usbat_get_device_type(us) == USBAT_DEV_HP8200) {
1344 msleep(250);
1345
1346 // Write 0x80 to ISA port 0x3F
1347 rc = usbat_write(us, USBAT_ISA, 0x3F, 0x80);
1348 if (rc != USB_STOR_XFER_GOOD)
1349 return USB_STOR_TRANSPORT_ERROR;
1350
1351 US_DEBUGP("INIT 5\n");
1352
1353 // Read ISA port 0x27
1354 rc = usbat_read(us, USBAT_ISA, 0x27, status);
1355 if (rc != USB_STOR_XFER_GOOD)
1356 return USB_STOR_TRANSPORT_ERROR;
1357
1358 US_DEBUGP("INIT 6\n");
1359
1360 rc = usbat_read_user_io(us, status);
1361 if (rc != USB_STOR_XFER_GOOD)
1362 return USB_STOR_TRANSPORT_ERROR;
1363
1364 US_DEBUGP("INIT 7\n");
1365 }
1366
1367 rc = usbat_select_and_test_registers(us); 1328 rc = usbat_select_and_test_registers(us);
1368 if (rc != USB_STOR_TRANSPORT_GOOD) 1329 if (rc != USB_STOR_TRANSPORT_GOOD)
1369 return rc; 1330 return rc;
1370 1331
1371 US_DEBUGP("INIT 8\n"); 1332 US_DEBUGP("INIT 4\n");
1372 1333
1373 rc = usbat_read_user_io(us, status); 1334 rc = usbat_read_user_io(us, status);
1374 if (rc != USB_STOR_XFER_GOOD) 1335 if (rc != USB_STOR_XFER_GOOD)
1375 return USB_STOR_TRANSPORT_ERROR; 1336 return USB_STOR_TRANSPORT_ERROR;
1376 1337
1377 US_DEBUGP("INIT 9\n"); 1338 US_DEBUGP("INIT 5\n");
1378 1339
1379 // Enable peripheral control signals and card detect 1340 // Enable peripheral control signals and card detect
1380 rc = usbat_device_enable_cdt(us); 1341 rc = usbat_device_enable_cdt(us);
1381 if (rc != USB_STOR_TRANSPORT_GOOD) 1342 if (rc != USB_STOR_TRANSPORT_GOOD)
1382 return rc; 1343 return rc;
1383 1344
1384 US_DEBUGP("INIT 10\n"); 1345 US_DEBUGP("INIT 6\n");
1385 1346
1386 rc = usbat_read_user_io(us, status); 1347 rc = usbat_read_user_io(us, status);
1387 if (rc != USB_STOR_XFER_GOOD) 1348 if (rc != USB_STOR_XFER_GOOD)
1388 return USB_STOR_TRANSPORT_ERROR; 1349 return USB_STOR_TRANSPORT_ERROR;
1389 1350
1390 US_DEBUGP("INIT 11\n"); 1351 US_DEBUGP("INIT 7\n");
1391 1352
1392 msleep(1400); 1353 msleep(1400);
1393 1354
@@ -1395,13 +1356,19 @@ int init_usbat(struct us_data *us)
1395 if (rc != USB_STOR_XFER_GOOD) 1356 if (rc != USB_STOR_XFER_GOOD)
1396 return USB_STOR_TRANSPORT_ERROR; 1357 return USB_STOR_TRANSPORT_ERROR;
1397 1358
1398 US_DEBUGP("INIT 12\n"); 1359 US_DEBUGP("INIT 8\n");
1399 1360
1400 rc = usbat_select_and_test_registers(us); 1361 rc = usbat_select_and_test_registers(us);
1401 if (rc != USB_STOR_TRANSPORT_GOOD) 1362 if (rc != USB_STOR_TRANSPORT_GOOD)
1402 return rc; 1363 return rc;
1403 1364
1404 US_DEBUGP("INIT 13\n"); 1365 US_DEBUGP("INIT 9\n");
1366
1367 // At this point, we need to detect which device we are using
1368 if (usbat_set_transport(us, info))
1369 return USB_STOR_TRANSPORT_ERROR;
1370
1371 US_DEBUGP("INIT 10\n");
1405 1372
1406 if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { 1373 if (usbat_get_device_type(us) == USBAT_DEV_FLASH) {
1407 subcountH = 0x02; 1374 subcountH = 0x02;
@@ -1412,7 +1379,7 @@ int init_usbat(struct us_data *us)
1412 if (rc != USB_STOR_XFER_GOOD) 1379 if (rc != USB_STOR_XFER_GOOD)
1413 return USB_STOR_TRANSPORT_ERROR; 1380 return USB_STOR_TRANSPORT_ERROR;
1414 1381
1415 US_DEBUGP("INIT 14\n"); 1382 US_DEBUGP("INIT 11\n");
1416 1383
1417 return USB_STOR_TRANSPORT_GOOD; 1384 return USB_STOR_TRANSPORT_GOOD;
1418} 1385}
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e6b1c6cf07f2..c1ba5301ebfc 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -96,8 +96,8 @@
96 * or before the URB_ACTIVE bit was set. If so, it's essential to cancel 96 * or before the URB_ACTIVE bit was set. If so, it's essential to cancel
97 * the URB if it hasn't been cancelled already (i.e., if the URB_ACTIVE bit 97 * the URB if it hasn't been cancelled already (i.e., if the URB_ACTIVE bit
98 * is still set). Either way, the function must then wait for the URB to 98 * is still set). Either way, the function must then wait for the URB to
99 * finish. Note that because the URB_ASYNC_UNLINK flag is set, the URB can 99 * finish. Note that the URB can still be in progress even after a call to
100 * still be in progress even after a call to usb_unlink_urb() returns. 100 * usb_unlink_urb() returns.
101 * 101 *
102 * The idea is that (1) once the ABORTING or DISCONNECTING bit is set, 102 * The idea is that (1) once the ABORTING or DISCONNECTING bit is set,
103 * either the stop_transport() function or the submitting function 103 * either the stop_transport() function or the submitting function
@@ -158,8 +158,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
158 * hasn't been mapped for DMA. Yes, this is clunky, but it's 158 * hasn't been mapped for DMA. Yes, this is clunky, but it's
159 * easier than always having the caller tell us whether the 159 * easier than always having the caller tell us whether the
160 * transfer buffer has already been mapped. */ 160 * transfer buffer has already been mapped. */
161 us->current_urb->transfer_flags = 161 us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
162 URB_ASYNC_UNLINK | URB_NO_SETUP_DMA_MAP;
163 if (us->current_urb->transfer_buffer == us->iobuf) 162 if (us->current_urb->transfer_buffer == us->iobuf)
164 us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 163 us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
165 us->current_urb->transfer_dma = us->iobuf_dma; 164 us->current_urb->transfer_dma = us->iobuf_dma;
@@ -611,7 +610,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
611 unsigned char old_sc_data_direction; 610 unsigned char old_sc_data_direction;
612 unsigned char old_cmd_len; 611 unsigned char old_cmd_len;
613 unsigned char old_cmnd[MAX_COMMAND_SIZE]; 612 unsigned char old_cmnd[MAX_COMMAND_SIZE];
614 unsigned long old_serial_number;
615 int old_resid; 613 int old_resid;
616 614
617 US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); 615 US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
@@ -648,10 +646,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
648 old_sg = srb->use_sg; 646 old_sg = srb->use_sg;
649 srb->use_sg = 0; 647 srb->use_sg = 0;
650 648
651 /* change the serial number -- toggle the high bit*/
652 old_serial_number = srb->serial_number;
653 srb->serial_number ^= 0x80000000;
654
655 /* issue the auto-sense command */ 649 /* issue the auto-sense command */
656 old_resid = srb->resid; 650 old_resid = srb->resid;
657 srb->resid = 0; 651 srb->resid = 0;
@@ -662,7 +656,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
662 srb->request_buffer = old_request_buffer; 656 srb->request_buffer = old_request_buffer;
663 srb->request_bufflen = old_request_bufflen; 657 srb->request_bufflen = old_request_bufflen;
664 srb->use_sg = old_sg; 658 srb->use_sg = old_sg;
665 srb->serial_number = old_serial_number;
666 srb->sc_data_direction = old_sc_data_direction; 659 srb->sc_data_direction = old_sc_data_direction;
667 srb->cmd_len = old_cmd_len; 660 srb->cmd_len = old_cmd_len;
668 memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); 661 memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
@@ -985,7 +978,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
985 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 978 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
986 bcb->DataTransferLength = cpu_to_le32(transfer_length); 979 bcb->DataTransferLength = cpu_to_le32(transfer_length);
987 bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0; 980 bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
988 bcb->Tag = srb->serial_number; 981 bcb->Tag = ++us->tag;
989 bcb->Lun = srb->device->lun; 982 bcb->Lun = srb->device->lun;
990 if (us->flags & US_FL_SCM_MULT_TARG) 983 if (us->flags & US_FL_SCM_MULT_TARG)
991 bcb->Lun |= srb->device->id << 4; 984 bcb->Lun |= srb->device->id << 4;
@@ -1074,7 +1067,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
1074 US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", 1067 US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
1075 le32_to_cpu(bcs->Signature), bcs->Tag, 1068 le32_to_cpu(bcs->Signature), bcs->Tag,
1076 residue, bcs->Status); 1069 residue, bcs->Status);
1077 if (bcs->Tag != srb->serial_number || bcs->Status > US_BULK_STAT_PHASE) { 1070 if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) {
1078 US_DEBUGP("Bulk logical error\n"); 1071 US_DEBUGP("Bulk logical error\n");
1079 return USB_STOR_TRANSPORT_ERROR; 1072 return USB_STOR_TRANSPORT_ERROR;
1080 } 1073 }
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index bd0ab3039bdd..ad0cfd7a782f 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -79,6 +79,13 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
79 US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), 79 US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0),
80#endif 80#endif
81 81
82/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
83UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003,
84 "VIA Technologies Inc.",
85 "USB 2.0 Card Reader",
86 US_SC_DEVICE, US_PR_DEVICE, NULL,
87 US_FL_IGNORE_RESIDUE ),
88
82/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 89/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
83 * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message 90 * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
84 * always fails and confuses drive. 91 * always fails and confuses drive.
@@ -929,6 +936,18 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
929 US_FL_SINGLE_LUN ), 936 US_FL_SINGLE_LUN ),
930#endif 937#endif
931 938
939/* Submitted by: Nick Sillik <n.sillik@temple.edu>
940 * Needed for OneTouch extension to usb-storage
941 *
942 */
943#ifdef CONFIG_USB_STORAGE_ONETOUCH
944 UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
945 "Maxtor",
946 "OneTouch External Harddrive",
947 US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
948 0),
949#endif
950
932/* Submitted by Joris Struyve <joris@struyve.be> */ 951/* Submitted by Joris Struyve <joris@struyve.be> */
933UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, 952UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
934 "Medion", 953 "Medion",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 77e7fc258aa2..cb4c770baf32 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -90,7 +90,9 @@
90#ifdef CONFIG_USB_STORAGE_JUMPSHOT 90#ifdef CONFIG_USB_STORAGE_JUMPSHOT
91#include "jumpshot.h" 91#include "jumpshot.h"
92#endif 92#endif
93 93#ifdef CONFIG_USB_STORAGE_ONETOUCH
94#include "onetouch.h"
95#endif
94 96
95/* Some informational data */ 97/* Some informational data */
96MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); 98MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -786,6 +788,7 @@ static void usb_stor_release_resources(struct us_data *us)
786 * any more commands. 788 * any more commands.
787 */ 789 */
788 US_DEBUGP("-- sending exit command to thread\n"); 790 US_DEBUGP("-- sending exit command to thread\n");
791 set_bit(US_FLIDX_DISCONNECTING, &us->flags);
789 up(&us->sema); 792 up(&us->sema);
790 793
791 /* Call the destructor routine, if it exists */ 794 /* Call the destructor routine, if it exists */
@@ -816,6 +819,49 @@ static void dissociate_dev(struct us_data *us)
816 usb_set_intfdata(us->pusb_intf, NULL); 819 usb_set_intfdata(us->pusb_intf, NULL);
817} 820}
818 821
822/* First stage of disconnect processing: stop all commands and remove
823 * the host */
824static void quiesce_and_remove_host(struct us_data *us)
825{
826 /* Prevent new USB transfers, stop the current command, and
827 * interrupt a SCSI-scan or device-reset delay */
828 set_bit(US_FLIDX_DISCONNECTING, &us->flags);
829 usb_stor_stop_transport(us);
830 wake_up(&us->delay_wait);
831
832 /* It doesn't matter if the SCSI-scanning thread is still running.
833 * The thread will exit when it sees the DISCONNECTING flag. */
834
835 /* Wait for the current command to finish, then remove the host */
836 down(&us->dev_semaphore);
837 up(&us->dev_semaphore);
838
839 /* queuecommand won't accept any new commands and the control
840 * thread won't execute a previously-queued command. If there
841 * is such a command pending, complete it with an error. */
842 if (us->srb) {
843 us->srb->result = DID_NO_CONNECT << 16;
844 scsi_lock(us_to_host(us));
845 us->srb->scsi_done(us->srb);
846 us->srb = NULL;
847 scsi_unlock(us_to_host(us));
848 }
849
850 /* Now we own no commands so it's safe to remove the SCSI host */
851 scsi_remove_host(us_to_host(us));
852}
853
854/* Second stage of disconnect processing: deallocate all resources */
855static void release_everything(struct us_data *us)
856{
857 usb_stor_release_resources(us);
858 dissociate_dev(us);
859
860 /* Drop our reference to the host; the SCSI core will free it
861 * (and "us" along with it) when the refcount becomes 0. */
862 scsi_host_put(us_to_host(us));
863}
864
819/* Thread to carry out delayed SCSI-device scanning */ 865/* Thread to carry out delayed SCSI-device scanning */
820static int usb_stor_scan_thread(void * __us) 866static int usb_stor_scan_thread(void * __us)
821{ 867{
@@ -956,7 +1002,7 @@ static int storage_probe(struct usb_interface *intf,
956 if (result < 0) { 1002 if (result < 0) {
957 printk(KERN_WARNING USB_STORAGE 1003 printk(KERN_WARNING USB_STORAGE
958 "Unable to start the device-scanning thread\n"); 1004 "Unable to start the device-scanning thread\n");
959 scsi_remove_host(host); 1005 quiesce_and_remove_host(us);
960 goto BadDevice; 1006 goto BadDevice;
961 } 1007 }
962 atomic_inc(&total_threads); 1008 atomic_inc(&total_threads);
@@ -969,10 +1015,7 @@ static int storage_probe(struct usb_interface *intf,
969 /* We come here if there are any problems */ 1015 /* We come here if there are any problems */
970BadDevice: 1016BadDevice:
971 US_DEBUGP("storage_probe() failed\n"); 1017 US_DEBUGP("storage_probe() failed\n");
972 set_bit(US_FLIDX_DISCONNECTING, &us->flags); 1018 release_everything(us);
973 usb_stor_release_resources(us);
974 dissociate_dev(us);
975 scsi_host_put(host);
976 return result; 1019 return result;
977} 1020}
978 1021
@@ -982,28 +1025,8 @@ static void storage_disconnect(struct usb_interface *intf)
982 struct us_data *us = usb_get_intfdata(intf); 1025 struct us_data *us = usb_get_intfdata(intf);
983 1026
984 US_DEBUGP("storage_disconnect() called\n"); 1027 US_DEBUGP("storage_disconnect() called\n");
985 1028 quiesce_and_remove_host(us);
986 /* Prevent new USB transfers, stop the current command, and 1029 release_everything(us);
987 * interrupt a SCSI-scan or device-reset delay */
988 set_bit(US_FLIDX_DISCONNECTING, &us->flags);
989 usb_stor_stop_transport(us);
990 wake_up(&us->delay_wait);
991
992 /* It doesn't matter if the SCSI-scanning thread is still running.
993 * The thread will exit when it sees the DISCONNECTING flag. */
994
995 /* Wait for the current command to finish, then remove the host */
996 down(&us->dev_semaphore);
997 up(&us->dev_semaphore);
998 scsi_remove_host(us_to_host(us));
999
1000 /* Wait for everything to become idle and release all our resources */
1001 usb_stor_release_resources(us);
1002 dissociate_dev(us);
1003
1004 /* Drop our reference to the host; the SCSI core will free it
1005 * (and "us" along with it) when the refcount becomes 0. */
1006 scsi_host_put(us_to_host(us));
1007} 1030}
1008 1031
1009/*********************************************************************** 1032/***********************************************************************
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 625b7aa98074..a195adae57b6 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -158,6 +158,7 @@ struct us_data {
158 158
159 /* SCSI interfaces */ 159 /* SCSI interfaces */
160 struct scsi_cmnd *srb; /* current srb */ 160 struct scsi_cmnd *srb; /* current srb */
161 unsigned int tag; /* current dCBWTag */
161 162
162 /* thread information */ 163 /* thread information */
163 int pid; /* control thread */ 164 int pid; /* control thread */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index cde0ed097af6..615874e03ce8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -650,7 +650,6 @@ config FB_NVIDIA
650 select FB_CFB_FILLRECT 650 select FB_CFB_FILLRECT
651 select FB_CFB_COPYAREA 651 select FB_CFB_COPYAREA
652 select FB_CFB_IMAGEBLIT 652 select FB_CFB_IMAGEBLIT
653 select FB_SOFT_CURSOR
654 help 653 help
655 This driver supports graphics boards with the nVidia chips, TNT 654 This driver supports graphics boards with the nVidia chips, TNT
656 and newer. For very old chipsets, such as the RIVA128, then use 655 and newer. For very old chipsets, such as the RIVA128, then use
@@ -681,7 +680,6 @@ config FB_RIVA
681 select FB_CFB_FILLRECT 680 select FB_CFB_FILLRECT
682 select FB_CFB_COPYAREA 681 select FB_CFB_COPYAREA
683 select FB_CFB_IMAGEBLIT 682 select FB_CFB_IMAGEBLIT
684 select FB_SOFT_CURSOR
685 help 683 help
686 This driver supports graphics boards with the nVidia Riva/Geforce 684 This driver supports graphics boards with the nVidia Riva/Geforce
687 chips. 685 chips.
@@ -720,7 +718,6 @@ config FB_I810
720 select FB_CFB_FILLRECT 718 select FB_CFB_FILLRECT
721 select FB_CFB_COPYAREA 719 select FB_CFB_COPYAREA
722 select FB_CFB_IMAGEBLIT 720 select FB_CFB_IMAGEBLIT
723 select FB_SOFT_CURSOR
724 help 721 help
725 This driver supports the on-board graphics built in to the Intel 810 722 This driver supports the on-board graphics built in to the Intel 810
726 and 815 chipsets. Say Y if you have and plan to use such a board. 723 and 815 chipsets. Say Y if you have and plan to use such a board.
@@ -754,6 +751,12 @@ config FB_I810_GTF
754 751
755 If unsure, say N. 752 If unsure, say N.
756 753
754config FB_I810_I2C
755 bool "Enable DDC Support"
756 depends on FB_I810 && I2C && FB_I810_GTF
757 select I2C_ALGOBIT
758 help
759
757config FB_INTEL 760config FB_INTEL
758 tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" 761 tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
759 depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64 762 depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
@@ -763,7 +766,6 @@ config FB_INTEL
763 select FB_CFB_FILLRECT 766 select FB_CFB_FILLRECT
764 select FB_CFB_COPYAREA 767 select FB_CFB_COPYAREA
765 select FB_CFB_IMAGEBLIT 768 select FB_CFB_IMAGEBLIT
766 select FB_SOFT_CURSOR
767 help 769 help
768 This driver supports the on-board graphics built in to the Intel 770 This driver supports the on-board graphics built in to the Intel
769 830M/845G/852GM/855GM/865G chipsets. 771 830M/845G/852GM/855GM/865G chipsets.
@@ -960,8 +962,7 @@ config FB_RADEON
960 can be build either as modules or built-in. 962 can be build either as modules or built-in.
961 963
962 There is a product page at 964 There is a product page at
963 <http://www.ati.com/na/pages/products/pc/radeon32/index.html>. 965 http://apps.ati.com/ATIcompare/
964
965config FB_RADEON_I2C 966config FB_RADEON_I2C
966 bool "DDC/I2C for ATI Radeon support" 967 bool "DDC/I2C for ATI Radeon support"
967 depends on FB_RADEON 968 depends on FB_RADEON
@@ -1084,15 +1085,16 @@ config FB_SAVAGE_ACCEL
1084 choose N here. 1085 choose N here.
1085 1086
1086config FB_SIS 1087config FB_SIS
1087 tristate "SiS acceleration" 1088 tristate "SiS/XGI display support"
1088 depends on FB && PCI 1089 depends on FB && PCI
1089 select FB_CFB_FILLRECT 1090 select FB_CFB_FILLRECT
1090 select FB_CFB_COPYAREA 1091 select FB_CFB_COPYAREA
1091 select FB_CFB_IMAGEBLIT 1092 select FB_CFB_IMAGEBLIT
1092 select FB_SOFT_CURSOR 1093 select FB_SOFT_CURSOR
1093 help 1094 help
1094 This is the frame buffer device driver for the SiS 300, 315 and 1095 This is the frame buffer device driver for the SiS 300, 315, 330
1095 330 series VGA chipsets. Specs available at <http://www.sis.com> 1096 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
1097 Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
1096 1098
1097 To compile this driver as a module, choose M here; the module 1099 To compile this driver as a module, choose M here; the module
1098 will be called sisfb. 1100 will be called sisfb.
@@ -1104,11 +1106,12 @@ config FB_SIS_300
1104 Say Y here to support use of the SiS 300/305, 540, 630 and 730. 1106 Say Y here to support use of the SiS 300/305, 540, 630 and 730.
1105 1107
1106config FB_SIS_315 1108config FB_SIS_315
1107 bool "SiS 315/330 series support" 1109 bool "SiS 315/330/340 series and XGI support"
1108 depends on FB_SIS 1110 depends on FB_SIS
1109 help 1111 help
1110 Say Y here to support use of the SiS 315 and 330 series 1112 Say Y here to support use of the SiS 315, 330 and 340 series
1111 (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760). 1113 (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
1114 as XGI V3XT, V5, V8 and Z7.
1112 1115
1113config FB_NEOMAGIC 1116config FB_NEOMAGIC
1114 tristate "NeoMagic display support" 1117 tristate "NeoMagic display support"
@@ -1180,6 +1183,32 @@ config FB_VOODOO1
1180 Please read the <file:Documentation/fb/README-sstfb.txt> for supported 1183 Please read the <file:Documentation/fb/README-sstfb.txt> for supported
1181 options and other important info support. 1184 options and other important info support.
1182 1185
1186config FB_CYBLA
1187 tristate "Cyberblade/i1 support"
1188 depends on FB && PCI
1189 select FB_CFB_IMAGEBLIT
1190 select FB_SOFT_CURSOR
1191 select VIDEO_SELECT
1192 ---help---
1193 This driver is supposed to support the Trident Cyberblade/i1
1194 graphics core integrated in the VIA VT8601A North Bridge,
1195 also known as VIA Apollo PLE133.
1196
1197 Status:
1198 - Developed, tested and working on EPIA 5000 and EPIA 800.
1199 - Does work reliable on all systems with CRT/LCD connected to
1200 normal VGA ports.
1201 - Should work on systems that do use the internal LCD port, but
1202 this is absolutely not tested.
1203
1204 Character imageblit, copyarea and rectangle fill are hw accelerated,
1205 ypan scrolling is used by default.
1206
1207 Please do read <file:Documentation/fb/cyblafb/*>.
1208
1209 To compile this driver as a module, choose M here: the
1210 module will be called cyblafb.
1211
1183config FB_TRIDENT 1212config FB_TRIDENT
1184 tristate "Trident support" 1213 tristate "Trident support"
1185 depends on FB && PCI 1214 depends on FB && PCI
@@ -1193,8 +1222,12 @@ config FB_TRIDENT
1193 but also on some motherboards. For more information, read 1222 but also on some motherboards. For more information, read
1194 <file:Documentation/fb/tridentfb.txt> 1223 <file:Documentation/fb/tridentfb.txt>
1195 1224
1225 Cyberblade/i1 support will be removed soon, use the cyblafb driver
1226 instead.
1227
1196 Say Y if you have such a graphics board. 1228 Say Y if you have such a graphics board.
1197 1229
1230
1198 To compile this driver as a module, choose M here: the 1231 To compile this driver as a module, choose M here: the
1199 module will be called tridentfb. 1232 module will be called tridentfb.
1200 1233
@@ -1205,7 +1238,6 @@ config FB_TRIDENT_ACCEL
1205 This will compile the Trident frame buffer device with 1238 This will compile the Trident frame buffer device with
1206 acceleration functions. 1239 acceleration functions.
1207 1240
1208
1209config FB_PM3 1241config FB_PM3
1210 tristate "Permedia3 support" 1242 tristate "Permedia3 support"
1211 depends on FB && PCI && BROKEN 1243 depends on FB && PCI && BROKEN
@@ -1484,6 +1516,30 @@ config FB_S1D13XXX
1484 working with S1D13806). Product specs at 1516 working with S1D13806). Product specs at
1485 <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm> 1517 <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
1486 1518
1519config FB_S3C2410
1520 tristate "S3C2410 LCD framebuffer support"
1521 depends on FB && ARCH_S3C2410
1522 select FB_CFB_FILLRECT
1523 select FB_CFB_COPYAREA
1524 select FB_CFB_IMAGEBLIT
1525 select FB_SOFT_CURSOR
1526 ---help---
1527 Frame buffer driver for the built-in LCD controller in the Samsung
1528 S3C2410 processor.
1529
1530 This driver is also available as a module ( = code which can be
1531 inserted and removed from the running kernel whenever you want). The
1532 module will be called s3c2410fb. If you want to compile it as a module,
1533 say M here and read <file:Documentation/modules.txt>.
1534
1535 If unsure, say N.
1536config FB_S3C2410_DEBUG
1537 bool "S3C2410 lcd debug messages"
1538 depends on FB_S3C2410
1539 help
1540 Turn on debugging messages. Note that you can set/unset at run time
1541 through sysfs
1542
1487config FB_VIRTUAL 1543config FB_VIRTUAL
1488 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1544 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1489 depends on FB 1545 depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index b018df4e95c8..1fff29f48ca8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -9,7 +9,8 @@ obj-$(CONFIG_LOGO) += logo/
9obj-$(CONFIG_SYSFS) += backlight/ 9obj-$(CONFIG_SYSFS) += backlight/
10 10
11obj-$(CONFIG_FB) += fb.o 11obj-$(CONFIG_FB) += fb.o
12fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o 12fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
13 modedb.o fbcvt.o
13fb-objs := $(fb-y) 14fb-objs := $(fb-y)
14 15
15obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 16obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
@@ -50,7 +51,8 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o
50obj-$(CONFIG_FB_IMSTT) += imsttfb.o 51obj-$(CONFIG_FB_IMSTT) += imsttfb.o
51obj-$(CONFIG_FB_S3TRIO) += S3triofb.o 52obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
52obj-$(CONFIG_FB_FM2) += fm2fb.o 53obj-$(CONFIG_FB_FM2) += fm2fb.o
53obj-$(CONFIG_FB_TRIDENT) += tridentfb.o 54obj-$(CONFIG_FB_CYBLA) += cyblafb.o
55obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
54obj-$(CONFIG_FB_STI) += stifb.o 56obj-$(CONFIG_FB_STI) += stifb.o
55obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o 57obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
56obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o 58obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -92,6 +94,7 @@ obj-$(CONFIG_FB_MAXINE) += maxinefb.o
92obj-$(CONFIG_FB_TX3912) += tx3912fb.o 94obj-$(CONFIG_FB_TX3912) += tx3912fb.o
93obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 95obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
94obj-$(CONFIG_FB_IMX) += imxfb.o 96obj-$(CONFIG_FB_IMX) += imxfb.o
97obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
95 98
96# Platform or fallback drivers go here 99# Platform or fallback drivers go here
97obj-$(CONFIG_FB_VESA) += vesafb.o 100obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index b0eba3ac6420..e380ee8b0247 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -806,8 +806,8 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru
806 806
807 /* Very simple test to make sure it appeared */ 807 /* Very simple test to make sure it appeared */
808 if (BIOS_IN16(0) != 0xaa55) { 808 if (BIOS_IN16(0) != 0xaa55) {
809 printk(KERN_ERR "aty128fb: Invalid ROM signature %x should be 0xaa55\n", 809 printk(KERN_DEBUG "aty128fb: Invalid ROM signature %x should "
810 BIOS_IN16(0)); 810 " be 0xaa55\n", BIOS_IN16(0));
811 goto failed; 811 goto failed;
812 } 812 }
813 813
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3e10bd837d9e..037fe9d32fe3 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -911,20 +911,6 @@ static int aty_var_to_crtc(const struct fb_info *info,
911 vdisplay = par->lcd_height; 911 vdisplay = par->lcd_height;
912#endif 912#endif
913 913
914 if(vdisplay < 400) {
915 h_sync_pol = 1;
916 v_sync_pol = 0;
917 } else if(vdisplay < 480) {
918 h_sync_pol = 0;
919 v_sync_pol = 1;
920 } else if(vdisplay < 768) {
921 h_sync_pol = 0;
922 v_sync_pol = 0;
923 } else {
924 h_sync_pol = 1;
925 v_sync_pol = 1;
926 }
927
928 v_disp--; 914 v_disp--;
929 v_sync_strt--; 915 v_sync_strt--;
930 v_sync_end--; 916 v_sync_end--;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index e7e8b52014c3..046b47860266 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -329,8 +329,9 @@ static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev
329 329
330 /* Very simple test to make sure it appeared */ 330 /* Very simple test to make sure it appeared */
331 if (BIOS_IN16(0) != 0xaa55) { 331 if (BIOS_IN16(0) != 0xaa55) {
332 printk(KERN_ERR "radeonfb (%s): Invalid ROM signature %x should be" 332 printk(KERN_DEBUG "radeonfb (%s): Invalid ROM signature %x "
333 "0xaa55\n", pci_name(rinfo->pdev), BIOS_IN16(0)); 333 "should be 0xaa55\n",
334 pci_name(rinfo->pdev), BIOS_IN16(0));
334 goto failed; 335 goto failed;
335 } 336 }
336 /* Look for the PCI data to check the ROM type */ 337 /* Look for the PCI data to check the ROM type */
@@ -2312,19 +2313,27 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
2312 rinfo->mmio_base_phys = pci_resource_start (pdev, 2); 2313 rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
2313 2314
2314 /* request the mem regions */ 2315 /* request the mem regions */
2315 ret = pci_request_regions(pdev, "radeonfb"); 2316 ret = pci_request_region(pdev, 0, "radeonfb framebuffer");
2316 if (ret < 0) { 2317 if (ret < 0) {
2317 printk( KERN_ERR "radeonfb (%s): cannot reserve PCI regions." 2318 printk( KERN_ERR "radeonfb (%s): cannot request region 0.\n",
2318 " Someone already got them?\n", pci_name(rinfo->pdev)); 2319 pci_name(rinfo->pdev));
2319 goto err_release_fb; 2320 goto err_release_fb;
2320 } 2321 }
2321 2322
2323 ret = pci_request_region(pdev, 2, "radeonfb mmio");
2324 if (ret < 0) {
2325 printk( KERN_ERR "radeonfb (%s): cannot request region 2.\n",
2326 pci_name(rinfo->pdev));
2327 goto err_release_pci0;
2328 }
2329
2322 /* map the regions */ 2330 /* map the regions */
2323 rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE); 2331 rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
2324 if (!rinfo->mmio_base) { 2332 if (!rinfo->mmio_base) {
2325 printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n", pci_name(rinfo->pdev)); 2333 printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n",
2334 pci_name(rinfo->pdev));
2326 ret = -EIO; 2335 ret = -EIO;
2327 goto err_release_pci; 2336 goto err_release_pci2;
2328 } 2337 }
2329 2338
2330 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; 2339 rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
@@ -2499,10 +2508,12 @@ err_unmap_rom:
2499 if (rinfo->bios_seg) 2508 if (rinfo->bios_seg)
2500 radeon_unmap_ROM(rinfo, pdev); 2509 radeon_unmap_ROM(rinfo, pdev);
2501 iounmap(rinfo->mmio_base); 2510 iounmap(rinfo->mmio_base);
2502err_release_pci: 2511err_release_pci2:
2503 pci_release_regions(pdev); 2512 pci_release_region(pdev, 2);
2513err_release_pci0:
2514 pci_release_region(pdev, 0);
2504err_release_fb: 2515err_release_fb:
2505 framebuffer_release(info); 2516 framebuffer_release(info);
2506err_disable: 2517err_disable:
2507 pci_disable_device(pdev); 2518 pci_disable_device(pdev);
2508err_out: 2519err_out:
@@ -2548,7 +2559,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
2548 iounmap(rinfo->mmio_base); 2559 iounmap(rinfo->mmio_base);
2549 iounmap(rinfo->fb_base); 2560 iounmap(rinfo->fb_base);
2550 2561
2551 pci_release_regions(pdev); 2562 pci_release_region(pdev, 2);
2563 pci_release_region(pdev, 0);
2552 2564
2553 kfree(rinfo->mon1_EDID); 2565 kfree(rinfo->mon1_EDID);
2554 kfree(rinfo->mon2_EDID); 2566 kfree(rinfo->mon2_EDID);
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 3c731577fed6..9f70e512b88b 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -39,7 +39,7 @@ static inline int get_attribute(struct fb_info *info, u16 c)
39{ 39{
40 int attribute = 0; 40 int attribute = 0;
41 41
42 if (fb_get_color_depth(&info->var) == 1) { 42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c)) 43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE; 44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c)) 45 if (attr_reverse(c))
@@ -103,42 +103,104 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
103 info->fbops->fb_fillrect(info, &region); 103 info->fbops->fb_fillrect(info, &region);
104} 104}
105 105
106static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
107 const u16 *s, u32 attr, u32 cnt,
108 u32 d_pitch, u32 s_pitch, u32 cellsize,
109 struct fb_image *image, u8 *buf, u8 *dst)
110{
111 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
112 u32 idx = vc->vc_font.width >> 3;
113 u8 *src;
114
115 while (cnt--) {
116 src = vc->vc_font.data + (scr_readw(s++)&
117 charmask)*cellsize;
118
119 if (attr) {
120 update_attr(buf, src, attr, vc);
121 src = buf;
122 }
123
124 if (likely(idx == 1))
125 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
126 image->height);
127 else
128 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
129 image->height);
130
131 dst += s_pitch;
132 }
133
134 info->fbops->fb_imageblit(info, image);
135}
136
137static inline void bit_putcs_unaligned(struct vc_data *vc,
138 struct fb_info *info, const u16 *s,
139 u32 attr, u32 cnt, u32 d_pitch,
140 u32 s_pitch, u32 cellsize,
141 struct fb_image *image, u8 *buf,
142 u8 *dst)
143{
144 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
145 u32 shift_low = 0, mod = vc->vc_font.width % 8;
146 u32 shift_high = 8;
147 u32 idx = vc->vc_font.width >> 3;
148 u8 *src;
149
150 while (cnt--) {
151 src = vc->vc_font.data + (scr_readw(s++)&
152 charmask)*cellsize;
153
154 if (attr) {
155 update_attr(buf, src, attr, vc);
156 src = buf;
157 }
158
159 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
160 image->height, shift_high,
161 shift_low, mod);
162 shift_low += mod;
163 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
164 shift_low &= 7;
165 shift_high = 8 - shift_low;
166 }
167
168 info->fbops->fb_imageblit(info, image);
169
170}
171
106static void bit_putcs(struct vc_data *vc, struct fb_info *info, 172static void bit_putcs(struct vc_data *vc, struct fb_info *info,
107 const unsigned short *s, int count, int yy, int xx, 173 const unsigned short *s, int count, int yy, int xx,
108 int fg, int bg) 174 int fg, int bg)
109{ 175{
110 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
111 unsigned int width = (vc->vc_font.width + 7) >> 3;
112 unsigned int cellsize = vc->vc_font.height * width;
113 unsigned int maxcnt = info->pixmap.size/cellsize;
114 unsigned int scan_align = info->pixmap.scan_align - 1;
115 unsigned int buf_align = info->pixmap.buf_align - 1;
116 unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
117 unsigned int shift_high = 8, pitch, cnt, size, k;
118 unsigned int idx = vc->vc_font.width >> 3;
119 unsigned int attribute = get_attribute(info, scr_readw(s));
120 struct fb_image image; 176 struct fb_image image;
121 u8 *src, *dst, *buf = NULL; 177 u32 width = (vc->vc_font.width + 7)/8;
122 178 u32 cellsize = width * vc->vc_font.height;
123 if (attribute) { 179 u32 maxcnt = info->pixmap.size/cellsize;
124 buf = kmalloc(cellsize, GFP_KERNEL); 180 u32 scan_align = info->pixmap.scan_align - 1;
125 if (!buf) 181 u32 buf_align = info->pixmap.buf_align - 1;
126 return; 182 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
127 } 183 u32 attribute = get_attribute(info, scr_readw(s));
184 u8 *dst, *buf = NULL;
128 185
129 image.fg_color = fg; 186 image.fg_color = fg;
130 image.bg_color = bg; 187 image.bg_color = bg;
131
132 image.dx = xx * vc->vc_font.width; 188 image.dx = xx * vc->vc_font.width;
133 image.dy = yy * vc->vc_font.height; 189 image.dy = yy * vc->vc_font.height;
134 image.height = vc->vc_font.height; 190 image.height = vc->vc_font.height;
135 image.depth = 1; 191 image.depth = 1;
136 192
193 if (attribute) {
194 buf = kmalloc(cellsize, GFP_KERNEL);
195 if (!buf)
196 return;
197 }
198
137 while (count) { 199 while (count) {
138 if (count > maxcnt) 200 if (count > maxcnt)
139 cnt = k = maxcnt; 201 cnt = maxcnt;
140 else 202 else
141 cnt = k = count; 203 cnt = count;
142 204
143 image.width = vc->vc_font.width * cnt; 205 image.width = vc->vc_font.width * cnt;
144 pitch = ((image.width + 7) >> 3) + scan_align; 206 pitch = ((image.width + 7) >> 3) + scan_align;
@@ -147,41 +209,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
147 size &= ~buf_align; 209 size &= ~buf_align;
148 dst = fb_get_buffer_offset(info, &info->pixmap, size); 210 dst = fb_get_buffer_offset(info, &info->pixmap, size);
149 image.data = dst; 211 image.data = dst;
150 if (mod) { 212
151 while (k--) { 213 if (!mod)
152 src = vc->vc_font.data + (scr_readw(s++)& 214 bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
153 charmask)*cellsize; 215 width, cellsize, &image, buf, dst);
154 216 else
155 if (attribute) { 217 bit_putcs_unaligned(vc, info, s, attribute, cnt,
156 update_attr(buf, src, attribute, vc); 218 pitch, width, cellsize, &image,
157 src = buf; 219 buf, dst);
158 } 220
159
160 fb_pad_unaligned_buffer(dst, pitch, src, idx,
161 image.height, shift_high,
162 shift_low, mod);
163 shift_low += mod;
164 dst += (shift_low >= 8) ? width : width - 1;
165 shift_low &= 7;
166 shift_high = 8 - shift_low;
167 }
168 } else {
169 while (k--) {
170 src = vc->vc_font.data + (scr_readw(s++)&
171 charmask)*cellsize;
172
173 if (attribute) {
174 update_attr(buf, src, attribute, vc);
175 src = buf;
176 }
177
178 fb_pad_aligned_buffer(dst, pitch, src, idx, image.height);
179 dst += width;
180 }
181 }
182 info->fbops->fb_imageblit(info, &image);
183 image.dx += cnt * vc->vc_font.width; 221 image.dx += cnt * vc->vc_font.width;
184 count -= cnt; 222 count -= cnt;
223 s += cnt;
185 } 224 }
186 225
187 /* buf is always NULL except when in monochrome mode, so in this case 226 /* buf is always NULL except when in monochrome mode, so in this case
@@ -189,6 +228,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
189 NULL pointers just fine */ 228 NULL pointers just fine */
190 if (unlikely(buf)) 229 if (unlikely(buf))
191 kfree(buf); 230 kfree(buf);
231
192} 232}
193 233
194static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, 234static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 35c88bd7ba5e..2e93224d2d55 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -214,7 +214,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
214static inline int get_color(struct vc_data *vc, struct fb_info *info, 214static inline int get_color(struct vc_data *vc, struct fb_info *info,
215 u16 c, int is_fg) 215 u16 c, int is_fg)
216{ 216{
217 int depth = fb_get_color_depth(&info->var); 217 int depth = fb_get_color_depth(&info->var, &info->fix);
218 int color = 0; 218 int color = 0;
219 219
220 if (console_blanked) { 220 if (console_blanked) {
@@ -230,9 +230,13 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
230 switch (depth) { 230 switch (depth) {
231 case 1: 231 case 1:
232 { 232 {
233 int col = ~(0xfff << (max(info->var.green.length,
234 max(info->var.red.length,
235 info->var.blue.length)))) & 0xff;
236
233 /* 0 or 1 */ 237 /* 0 or 1 */
234 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0; 238 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
235 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1; 239 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
236 240
237 if (console_blanked) 241 if (console_blanked)
238 fg = bg; 242 fg = bg;
@@ -243,9 +247,25 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
243 case 2: 247 case 2:
244 /* 248 /*
245 * Scale down 16-colors to 4 colors. Default 4-color palette 249 * Scale down 16-colors to 4 colors. Default 4-color palette
246 * is grayscale. 250 * is grayscale. However, simply dividing the values by 4
251 * will not work, as colors 1, 2 and 3 will be scaled-down
252 * to zero rendering them invisible. So empirically convert
253 * colors to a sane 4-level grayscale.
247 */ 254 */
248 color /= 4; 255 switch (color) {
256 case 0:
257 color = 0; /* black */
258 break;
259 case 1 ... 6:
260 color = 2; /* white */
261 break;
262 case 7 ... 8:
263 color = 1; /* gray */
264 break;
265 default:
266 color = 3; /* intense white */
267 break;
268 }
249 break; 269 break;
250 case 3: 270 case 3:
251 /* 271 /*
@@ -311,6 +331,35 @@ static void cursor_timer_handler(unsigned long dev_addr)
311 mod_timer(&ops->cursor_timer, jiffies + HZ/5); 331 mod_timer(&ops->cursor_timer, jiffies + HZ/5);
312} 332}
313 333
334static void fbcon_add_cursor_timer(struct fb_info *info)
335{
336 struct fbcon_ops *ops = info->fbcon_par;
337
338 if ((!info->queue.func || info->queue.func == fb_flashcursor) &&
339 !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {
340 if (!info->queue.func)
341 INIT_WORK(&info->queue, fb_flashcursor, info);
342
343 init_timer(&ops->cursor_timer);
344 ops->cursor_timer.function = cursor_timer_handler;
345 ops->cursor_timer.expires = jiffies + HZ / 5;
346 ops->cursor_timer.data = (unsigned long ) info;
347 add_timer(&ops->cursor_timer);
348 ops->flags |= FBCON_FLAGS_CURSOR_TIMER;
349 }
350}
351
352static void fbcon_del_cursor_timer(struct fb_info *info)
353{
354 struct fbcon_ops *ops = info->fbcon_par;
355
356 if (info->queue.func == fb_flashcursor &&
357 ops->flags & FBCON_FLAGS_CURSOR_TIMER) {
358 del_timer_sync(&ops->cursor_timer);
359 ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER;
360 }
361}
362
314#ifndef MODULE 363#ifndef MODULE
315static int __init fb_console_setup(char *this_opt) 364static int __init fb_console_setup(char *this_opt)
316{ 365{
@@ -426,7 +475,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
426 * remove underline attribute from erase character 475 * remove underline attribute from erase character
427 * if black and white framebuffer. 476 * if black and white framebuffer.
428 */ 477 */
429 if (fb_get_color_depth(&info->var) == 1) 478 if (fb_get_color_depth(&info->var, &info->fix) == 1)
430 erase &= ~0x400; 479 erase &= ~0x400;
431 logo_height = fb_prepare_logo(info); 480 logo_height = fb_prepare_logo(info);
432 logo_lines = (logo_height + vc->vc_font.height - 1) / 481 logo_lines = (logo_height + vc->vc_font.height - 1) /
@@ -563,9 +612,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
563 } 612 }
564 613
565 if (!err) { 614 if (!err) {
566 if (oldinfo->queue.func == fb_flashcursor) 615 fbcon_del_cursor_timer(oldinfo);
567 del_timer_sync(&ops->cursor_timer);
568
569 kfree(ops->cursor_state.mask); 616 kfree(ops->cursor_state.mask);
570 kfree(ops->cursor_data); 617 kfree(ops->cursor_data);
571 kfree(oldinfo->fbcon_par); 618 kfree(oldinfo->fbcon_par);
@@ -576,22 +623,6 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
576 return err; 623 return err;
577} 624}
578 625
579static void con2fb_init_newinfo(struct fb_info *info)
580{
581 if (!info->queue.func || info->queue.func == fb_flashcursor) {
582 struct fbcon_ops *ops = info->fbcon_par;
583
584 if (!info->queue.func)
585 INIT_WORK(&info->queue, fb_flashcursor, info);
586
587 init_timer(&ops->cursor_timer);
588 ops->cursor_timer.function = cursor_timer_handler;
589 ops->cursor_timer.expires = jiffies + HZ / 5;
590 ops->cursor_timer.data = (unsigned long ) info;
591 add_timer(&ops->cursor_timer);
592 }
593}
594
595static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, 626static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
596 int unit, int show_logo) 627 int unit, int show_logo)
597{ 628{
@@ -675,7 +706,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
675 logo_shown != FBCON_LOGO_DONTSHOW); 706 logo_shown != FBCON_LOGO_DONTSHOW);
676 707
677 if (!found) 708 if (!found)
678 con2fb_init_newinfo(info); 709 fbcon_add_cursor_timer(info);
679 con2fb_map_boot[unit] = newidx; 710 con2fb_map_boot[unit] = newidx;
680 con2fb_init_display(vc, info, unit, show_logo); 711 con2fb_init_display(vc, info, unit, show_logo);
681 } 712 }
@@ -878,18 +909,7 @@ static const char *fbcon_startup(void)
878 } 909 }
879#endif /* CONFIG_MAC */ 910#endif /* CONFIG_MAC */
880 911
881 /* Initialize the work queue. If the driver provides its 912 fbcon_add_cursor_timer(info);
882 * own work queue this means it will use something besides
883 * default timer to flash the cursor. */
884 if (!info->queue.func) {
885 INIT_WORK(&info->queue, fb_flashcursor, info);
886
887 init_timer(&ops->cursor_timer);
888 ops->cursor_timer.function = cursor_timer_handler;
889 ops->cursor_timer.expires = jiffies + HZ / 5;
890 ops->cursor_timer.data = (unsigned long ) info;
891 add_timer(&ops->cursor_timer);
892 }
893 return display_desc; 913 return display_desc;
894} 914}
895 915
@@ -930,7 +950,7 @@ static void fbcon_init(struct vc_data *vc, int init)
930 } 950 }
931 if (p->userfont) 951 if (p->userfont)
932 charcnt = FNTCHARCNT(p->fontdata); 952 charcnt = FNTCHARCNT(p->fontdata);
933 vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1); 953 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
934 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 954 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
935 if (charcnt == 256) { 955 if (charcnt == 256) {
936 vc->vc_hi_font_mask = 0; 956 vc->vc_hi_font_mask = 0;
@@ -1178,7 +1198,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1178 if (p->userfont) 1198 if (p->userfont)
1179 charcnt = FNTCHARCNT(p->fontdata); 1199 charcnt = FNTCHARCNT(p->fontdata);
1180 1200
1181 vc->vc_can_do_color = (fb_get_color_depth(var) != 1); 1201 var->activate = FB_ACTIVATE_NOW;
1202 info->var.activate = var->activate;
1203 info->var.yoffset = info->var.xoffset = 0;
1204 fb_set_var(info, var);
1205
1206 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1182 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1207 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1183 if (charcnt == 256) { 1208 if (charcnt == 256) {
1184 vc->vc_hi_font_mask = 0; 1209 vc->vc_hi_font_mask = 0;
@@ -1898,7 +1923,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1898 1923
1899static int fbcon_switch(struct vc_data *vc) 1924static int fbcon_switch(struct vc_data *vc)
1900{ 1925{
1901 struct fb_info *info; 1926 struct fb_info *info, *old_info = NULL;
1902 struct display *p = &fb_display[vc->vc_num]; 1927 struct display *p = &fb_display[vc->vc_num];
1903 struct fb_var_screeninfo var; 1928 struct fb_var_screeninfo var;
1904 int i, prev_console; 1929 int i, prev_console;
@@ -1931,7 +1956,8 @@ static int fbcon_switch(struct vc_data *vc)
1931 } 1956 }
1932 1957
1933 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 1958 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon;
1934 1959 if (prev_console != -1)
1960 old_info = registered_fb[con2fb_map[prev_console]];
1935 /* 1961 /*
1936 * FIXME: If we have multiple fbdev's loaded, we need to 1962 * FIXME: If we have multiple fbdev's loaded, we need to
1937 * update all info->currcon. Perhaps, we can place this 1963 * update all info->currcon. Perhaps, we can place this
@@ -1959,15 +1985,17 @@ static int fbcon_switch(struct vc_data *vc)
1959 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 1985 info->var.yoffset = info->var.xoffset = p->yscroll = 0;
1960 fb_set_var(info, &var); 1986 fb_set_var(info, &var);
1961 1987
1962 if (prev_console != -1 && 1988 if (old_info != NULL && old_info != info) {
1963 registered_fb[con2fb_map[prev_console]] != info && 1989 if (info->fbops->fb_set_par)
1964 info->fbops->fb_set_par) 1990 info->fbops->fb_set_par(info);
1965 info->fbops->fb_set_par(info); 1991 fbcon_del_cursor_timer(old_info);
1992 fbcon_add_cursor_timer(info);
1993 }
1966 1994
1967 set_blitting_type(vc, info, p); 1995 set_blitting_type(vc, info, p);
1968 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 1996 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
1969 1997
1970 vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1); 1998 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1971 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1999 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1972 updatescrollmode(p, info, vc); 2000 updatescrollmode(p, info, vc);
1973 2001
@@ -2048,11 +2076,16 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2048 fbcon_generic_blank(vc, info, blank); 2076 fbcon_generic_blank(vc, info, blank);
2049 } 2077 }
2050 2078
2051 if (!blank) 2079 if (!blank)
2052 update_screen(vc); 2080 update_screen(vc);
2053 } 2081 }
2054 2082
2055 return 0; 2083 if (!blank)
2084 fbcon_add_cursor_timer(info);
2085 else
2086 fbcon_del_cursor_timer(info);
2087
2088 return 0;
2056} 2089}
2057 2090
2058static void fbcon_free_font(struct display *p) 2091static void fbcon_free_font(struct display *p)
@@ -2332,7 +2365,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
2332 if (!CON_IS_VISIBLE(vc)) 2365 if (!CON_IS_VISIBLE(vc))
2333 return 0; 2366 return 0;
2334 2367
2335 depth = fb_get_color_depth(&info->var); 2368 depth = fb_get_color_depth(&info->var, &info->fix);
2336 if (depth > 3) { 2369 if (depth > 3) {
2337 for (i = j = 0; i < 16; i++) { 2370 for (i = j = 0; i < 16; i++) {
2338 k = table[i]; 2371 k = table[i];
@@ -2593,6 +2626,51 @@ static void fbcon_modechanged(struct fb_info *info)
2593 } 2626 }
2594} 2627}
2595 2628
2629static void fbcon_set_all_vcs(struct fb_info *info)
2630{
2631 struct fbcon_ops *ops = info->fbcon_par;
2632 struct vc_data *vc;
2633 struct display *p;
2634 int i, rows, cols;
2635
2636 if (!ops || ops->currcon < 0)
2637 return;
2638
2639 for (i = 0; i < MAX_NR_CONSOLES; i++) {
2640 vc = vc_cons[i].d;
2641 if (!vc || vc->vc_mode != KD_TEXT ||
2642 registered_fb[con2fb_map[i]] != info)
2643 continue;
2644
2645 p = &fb_display[vc->vc_num];
2646
2647 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2648 var_to_display(p, &info->var, info);
2649 cols = info->var.xres / vc->vc_font.width;
2650 rows = info->var.yres / vc->vc_font.height;
2651 vc_resize(vc, cols, rows);
2652
2653 if (CON_IS_VISIBLE(vc)) {
2654 updatescrollmode(p, info, vc);
2655 scrollback_max = 0;
2656 scrollback_current = 0;
2657 update_var(vc->vc_num, info);
2658 fbcon_set_palette(vc, color_table);
2659 update_screen(vc);
2660 if (softback_buf) {
2661 int l = fbcon_softback_size / vc->vc_size_row;
2662 if (l > 5)
2663 softback_end = softback_buf + l * vc->vc_size_row;
2664 else {
2665 /* Smaller scrollback makes no sense, and 0
2666 would screw the operation totally */
2667 softback_top = 0;
2668 }
2669 }
2670 }
2671 }
2672}
2673
2596static int fbcon_mode_deleted(struct fb_info *info, 2674static int fbcon_mode_deleted(struct fb_info *info,
2597 struct fb_videomode *mode) 2675 struct fb_videomode *mode)
2598{ 2676{
@@ -2708,6 +2786,9 @@ static int fbcon_event_notify(struct notifier_block *self,
2708 case FB_EVENT_MODE_CHANGE: 2786 case FB_EVENT_MODE_CHANGE:
2709 fbcon_modechanged(info); 2787 fbcon_modechanged(info);
2710 break; 2788 break;
2789 case FB_EVENT_MODE_CHANGE_ALL:
2790 fbcon_set_all_vcs(info);
2791 break;
2711 case FB_EVENT_MODE_DELETE: 2792 case FB_EVENT_MODE_DELETE:
2712 mode = event->data; 2793 mode = event->data;
2713 ret = fbcon_mode_deleted(info, mode); 2794 ret = fbcon_mode_deleted(info, mode);
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 5d377860bce2..08befafe11d1 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -18,7 +18,8 @@
18 18
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21#define FBCON_FLAGS_INIT 1 21#define FBCON_FLAGS_INIT 1
22#define FBCON_FLAGS_CURSOR_TIMER 2
22 23
23 /* 24 /*
24 * This is the interface between the low-level console driver and the 25 * This is the interface between the low-level console driver and the
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d27fa91e5886..0705cd741411 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -497,6 +497,57 @@ static void vgacon_cursor(struct vc_data *c, int mode)
497 } 497 }
498} 498}
499 499
500static int vgacon_doresize(struct vc_data *c,
501 unsigned int width, unsigned int height)
502{
503 unsigned long flags;
504 unsigned int scanlines = height * c->vc_font.height;
505 u8 scanlines_lo, r7, vsync_end, mode;
506
507 spin_lock_irqsave(&vga_lock, flags);
508
509 outb_p(VGA_CRTC_MODE, vga_video_port_reg);
510 mode = inb_p(vga_video_port_val);
511
512 if (mode & 0x04)
513 scanlines >>= 1;
514
515 scanlines -= 1;
516 scanlines_lo = scanlines & 0xff;
517
518 outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
519 r7 = inb_p(vga_video_port_val) & ~0x42;
520
521 if (scanlines & 0x100)
522 r7 |= 0x02;
523 if (scanlines & 0x200)
524 r7 |= 0x40;
525
526 /* deprotect registers */
527 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
528 vsync_end = inb_p(vga_video_port_val);
529 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
530 outb_p(vsync_end & ~0x80, vga_video_port_val);
531
532 outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
533 outb_p(width - 1, vga_video_port_val);
534 outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
535 outb_p(width >> 1, vga_video_port_val);
536
537 outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
538 outb_p(scanlines_lo, vga_video_port_val);
539 outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
540 outb_p(r7,vga_video_port_val);
541
542 /* reprotect registers */
543 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
544 outb_p(vsync_end, vga_video_port_val);
545
546 spin_unlock_irqrestore(&vga_lock, flags);
547
548 return 0;
549}
550
500static int vgacon_switch(struct vc_data *c) 551static int vgacon_switch(struct vc_data *c)
501{ 552{
502 /* 553 /*
@@ -510,9 +561,13 @@ static int vgacon_switch(struct vc_data *c)
510 /* We can only copy out the size of the video buffer here, 561 /* We can only copy out the size of the video buffer here,
511 * otherwise we get into VGA BIOS */ 562 * otherwise we get into VGA BIOS */
512 563
513 if (!vga_is_gfx) 564 if (!vga_is_gfx) {
514 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, 565 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
515 c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); 566 c->vc_screenbuf_size > vga_vram_size ?
567 vga_vram_size : c->vc_screenbuf_size);
568 vgacon_doresize(c, c->vc_cols, c->vc_rows);
569 }
570
516 return 0; /* Redrawing not needed */ 571 return 0; /* Redrawing not needed */
517} 572}
518 573
@@ -962,6 +1017,17 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
962 1017
963#endif 1018#endif
964 1019
1020static int vgacon_resize(struct vc_data *c, unsigned int width,
1021 unsigned int height)
1022{
1023 if (width % 2 || width > ORIG_VIDEO_COLS || height > ORIG_VIDEO_LINES)
1024 return -EINVAL;
1025
1026 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
1027 vgacon_doresize(c, width, height);
1028 return 0;
1029}
1030
965static int vgacon_scrolldelta(struct vc_data *c, int lines) 1031static int vgacon_scrolldelta(struct vc_data *c, int lines)
966{ 1032{
967 if (!lines) /* Turn scrollback off */ 1033 if (!lines) /* Turn scrollback off */
@@ -1103,6 +1169,7 @@ const struct consw vga_con = {
1103 .con_blank = vgacon_blank, 1169 .con_blank = vgacon_blank,
1104 .con_font_set = vgacon_font_set, 1170 .con_font_set = vgacon_font_set,
1105 .con_font_get = vgacon_font_get, 1171 .con_font_get = vgacon_font_get,
1172 .con_resize = vgacon_resize,
1106 .con_set_palette = vgacon_set_palette, 1173 .con_set_palette = vgacon_set_palette,
1107 .con_scrolldelta = vgacon_scrolldelta, 1174 .con_scrolldelta = vgacon_scrolldelta,
1108 .con_set_origin = vgacon_set_origin, 1175 .con_set_origin = vgacon_set_origin,
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
new file mode 100644
index 000000000000..ae2762cb5608
--- /dev/null
+++ b/drivers/video/cyblafb.c
@@ -0,0 +1,1456 @@
1/*
2 * Frame buffer driver for Trident Cyberblade/i1 graphics core
3 *
4 * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de>
5 *
6 * CREDITS:
7 * tridentfb.c by Jani Monoses
8 * see files above for further credits
9 *
10 * TODO:
11 *
12 */
13
14#define CYBLAFB_DEBUG 0
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/string.h>
19#include <linux/fb.h>
20#include <linux/init.h>
21#include <linux/pci.h>
22#include <asm/types.h>
23#include <video/cyblafb.h>
24
25#define VERSION "0.54"
26
27struct cyblafb_par {
28 u32 pseudo_pal[16];
29 struct fb_ops ops;
30};
31
32static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
33 .id = "CyBla",
34 .type = FB_TYPE_PACKED_PIXELS,
35 .ypanstep = 1,
36 .visual = FB_VISUAL_PSEUDOCOLOR,
37 .accel = FB_ACCEL_NONE,
38};
39
40static char *mode __devinitdata = NULL;
41static int bpp __devinitdata = 8;
42static int ref __devinitdata = 75;
43static int fp __devinitdata;
44static int crt __devinitdata;
45static int memsize __devinitdata;
46static int vesafb __devinitdata;
47
48static int nativex;
49static int center;
50static int stretch;
51static int pciwb = 1;
52static int pcirb = 1;
53static int pciwr = 1;
54static int pcirr = 1;
55static int verbosity;
56static int displaytype;
57
58static void __iomem * io_virt; // iospace virtual memory address
59
60module_param(mode,charp,0);
61module_param(bpp,int,0);
62module_param(ref,int,0);
63module_param(fp,int,0);
64module_param(crt,int,0);
65module_param(nativex,int,0);
66module_param(center,int,0);
67module_param(stretch,int,0);
68module_param(pciwb,int,0);
69module_param(pcirb,int,0);
70module_param(pciwr,int,0);
71module_param(pcirr,int,0);
72module_param(memsize,int,0);
73module_param(verbosity,int,0);
74module_param(vesafb,int,0);
75
76//=========================================
77//
78// Port access macros for memory mapped io
79//
80//=========================================
81
82#define out8(r,v) writeb(v,io_virt+r)
83#define out32(r,v) writel(v,io_virt+r)
84#define in8(r) readb(io_virt+r)
85#define in32(r) readl(io_virt+r)
86
87//======================================
88//
89// Hardware access inline functions
90//
91//======================================
92
93static inline unsigned char read3X4(int reg)
94{
95 out8(0x3D4,reg);
96 return in8(0x3D5);
97}
98
99static inline unsigned char read3C4(int reg)
100{
101 out8(0x3C4,reg);
102 return in8(0x3C5);
103}
104
105static inline unsigned char read3CE(int reg)
106{
107 out8(0x3CE,reg);
108 return in8(0x3CF);
109}
110
111static inline void write3X4(int reg,unsigned char val)
112{
113 out8(0x3D4,reg);
114 out8(0x3D5,val);
115}
116
117static inline void write3C4(int reg,unsigned char val)
118{
119 out8(0x3C4,reg);
120 out8(0x3C5,val);
121}
122
123static inline void write3CE(int reg,unsigned char val)
124{
125 out8(0x3CE,reg);
126 out8(0x3CF,val);
127}
128
129static inline void write3C0(int reg,unsigned char val)
130{
131 in8(0x3DA); // read to reset index
132 out8(0x3C0,reg);
133 out8(0x3C0,val);
134}
135
136//=================================================
137//
138// Enable memory mapped io and unprotect registers
139//
140//=================================================
141
142static inline void enable_mmio(void)
143{
144 int tmp;
145
146 outb(0x0B,0x3C4);
147 inb(0x3C5); // Set NEW mode
148 outb(SR0E,0x3C4); // write enable a lot of extended ports
149 outb(0x80,0x3C5);
150
151 outb(SR11,0x3C4); // write enable those extended ports that
152 outb(0x87,0x3C5); // are not affected by SR0E_New
153
154 outb(CR1E,0x3d4); // clear write protect bit for port 0x3c2
155 tmp=inb(0x3d5) & 0xBF;
156 outb(CR1E,0x3d4);
157 outb(tmp,0x3d5);
158
159 outb(CR39,0x3D4);
160 outb(inb(0x3D5)|0x01,0x3D5); // Enable mmio, everything else untouched
161}
162
163//=================================================
164//
165// Set pixel clock VCLK1
166// - multipliers set elswhere
167// - freq in units of 0.01 MHz
168//
169//=================================================
170
171static void set_vclk(struct cyblafb_par *par, int freq)
172{
173 u32 m,n,k;
174 int f,fi,d,di;
175 u8 lo=0,hi=0;
176
177 d = 2000;
178 k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
179 for(m = 0;m<64;m++)
180 for(n = 0;n<250;n++) { // max 249 is a hardware limit for cybla/i1 !
181 fi = (int)(((5864727*(n+8))/((m+2)*(1<<k)))>>12);
182 if ((di = abs(fi - freq)) < d) {
183 d = di;
184 f = fi;
185 lo = (u8) n;
186 hi = (u8) ((k<<6) | m);
187 }
188 }
189 write3C4(SR19,hi);
190 write3C4(SR18,lo);
191 if(verbosity > 1)
192 output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
193 freq/100,freq%100,(hi&0xc0)>>6,hi&0x3f,lo);
194}
195
196//================================================
197//
198// Cyberblade specific Graphics Engine (GE) setup
199//
200//================================================
201
202static void cyblafb_setup_GE(int pitch,int bpp)
203{
204 int base = (pitch>>3)<<20;
205
206 switch (bpp) {
207 case 8: base |= (0<<29); break;
208 case 15: base |= (5<<29); break;
209 case 16: base |= (1<<29); break;
210 case 24:
211 case 32: base |= (2<<29); break;
212 }
213
214 write3X4(CR36,0x90); // reset GE
215 write3X4(CR36,0x80); // enable GE
216
217 out32(GE24,1<<7); // reset all GE pointers
218 out32(GE24,0);
219
220 write3X4(CR2D,0x00); // GE Timinigs, no delays
221
222 out32(GEB8,base); // Destination Stride / Buffer Base 0, p 133
223 out32(GEBC,base); // Destination Stride / Buffer Base 1, p 133
224 out32(GEC0,base); // Destination Stride / Buffer Base 2, p 133
225 out32(GEC4,base); // Destination Stride / Buffer Base 3, p 133
226 out32(GEC8,base); // Source Stride / Buffer Base 0, p 133
227 out32(GECC,base); // Source Stride / Buffer Base 1, p 133
228 out32(GED0,base); // Source Stride / Buffer Base 2, p 133
229 out32(GED4,base); // Source Stride / Buffer Base 3, p 133
230 out32(GE6C,0); // Pattern and Style, p 129, ok
231}
232
233//=====================================================================
234//
235// Although this is a .fb_sync function that could be enabled in
236// cyblafb_ops, we do not include it there. We sync immediately before
237// new GE operations to improve performance.
238//
239//=====================================================================
240
241static int cyblafb_sync(struct fb_info *info)
242{
243 int status, i=100000;
244 while( ((status=in32(GE20)) & 0xFA800000) && i != 0)
245 i--;
246
247 if (i == 0) {
248 // The timeout might be caused by disabled mmio.
249 // Cause:
250 // - bit CR39 & 1 == 0 upon return, X trident driver bug
251 // - kdm bug (KD_GRAPHICS not set on first switch)
252 // - kernel design flaw (it believes in the correctness
253 // of kdm/X
254 // So we make sure that mmio is enabled first ...
255 enable_mmio();
256// show_trace(NULL,&status);
257 i=1000000;
258 while( ((status=in32(GE20)) & 0xFA800000) && i != 0)
259 i--;
260 if (i == 0) {
261 output("GE Timeout, status: %x\n",status);
262 if(status & 0x80000000)
263 output("Bresenham Engine : Busy\n");
264 if(status & 0x40000000)
265 output("Setup Engine : Busy\n");
266 if(status & 0x20000000)
267 output("SP / DPE : Busy\n");
268 if(status & 0x10000000)
269 output("Memory Interface : Busy\n");
270 if(status & 0x08000000)
271 output("Com Lst Proc : Busy\n");
272 if(status & 0x04000000)
273 output("Block Write : Busy\n");
274 if(status & 0x02000000)
275 output("Command Buffer : Full\n");
276 if(status & 0x01000000)
277 output("RESERVED : Busy\n");
278 if(status & 0x00800000)
279 output("PCI Write Buffer : Busy\n");
280 cyblafb_setup_GE(info->var.xres,
281 info->var.bits_per_pixel);
282 }
283 }
284
285 return 0;
286}
287
288//==============================
289//
290// Cyberblade specific fillrect
291//
292//==============================
293
294static void cyblafb_fillrect(struct fb_info * info,
295 const struct fb_fillrect *fr)
296{
297 int bpp = info->var.bits_per_pixel;
298 int col;
299
300 switch (bpp) {
301 default:
302 case 8: col = fr->color;
303 col |= col <<8;
304 col |= col <<16;
305 break;
306 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
307 col |= col <<16;
308 break;
309 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
310 break;
311 }
312
313 cyblafb_sync(info);
314
315 out32(GE60,col);
316 out32(GE48,fr->rop ? 0x66:ROP_S);
317 out32(GE44,0x20000000|1<<19|1<<4|2<<2);
318 out32(GE08,point(fr->dx,fr->dy));
319 out32(GE0C,point(fr->dx+fr->width-1,fr->dy+fr->height-1));
320
321}
322
323//==============================
324//
325// Cyberblade specific copyarea
326//
327//==============================
328
329static void cyblafb_copyarea(struct fb_info *info,
330 const struct fb_copyarea *ca)
331{
332 __u32 s1,s2,d1,d2;
333 int direction;
334
335 s1 = point(ca->sx,ca->sy);
336 s2 = point(ca->sx+ca->width-1,ca->sy+ca->height-1);
337 d1 = point(ca->dx,ca->dy);
338 d2 = point(ca->dx+ca->width-1,ca->dy+ca->height-1);
339 if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
340 direction = 0;
341 else
342 direction = 2;
343
344 cyblafb_sync(info);
345
346 out32(GE44,0xa0000000|1<<19|1<<2|direction);
347 out32(GE00,direction?s2:s1);
348 out32(GE04,direction?s1:s2);
349 out32(GE08,direction?d2:d1);
350 out32(GE0C,direction?d1:d2);
351
352}
353
354//=======================================================================
355//
356// Cyberblade specific imageblit
357//
358// Accelerated for the most usual case, blitting 1-bit deep character
359// character images. Everything else is passed to the generic imageblit.
360//
361//=======================================================================
362
363static void cyblafb_imageblit(struct fb_info *info,
364 const struct fb_image *image)
365{
366
367 u32 fgcol, bgcol;
368
369 int i;
370 int bpp = info->var.bits_per_pixel;
371 int index = 0;
372 int index_end=image->height * image->width / 8;
373 int width_dds=image->width / 32;
374 int width_dbs=image->width % 32;
375
376 if (image->depth != 1 || bpp < 8 || bpp > 32 || bpp % 8 != 0 ||
377 image->width % 8 != 0 || image->width == 0 || image->height == 0) {
378 cfb_imageblit(info,image);
379 return;
380 }
381
382 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
383 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
384 fgcol = ((u32*)(info->pseudo_palette))[image->fg_color];
385 bgcol = ((u32*)(info->pseudo_palette))[image->bg_color];
386 } else {
387 fgcol = image->fg_color;
388 bgcol = image->bg_color;
389 }
390
391 switch (bpp) {
392 case 8:
393 fgcol |= fgcol <<8; fgcol |= fgcol <<16;
394 bgcol |= bgcol <<8; bgcol |= bgcol <<16;
395 break;
396 case 16:
397 fgcol |= fgcol <<16;
398 bgcol |= bgcol <<16;
399 break;
400 default:
401 break;
402 }
403
404 cyblafb_sync(info);
405
406 out32(GE60,fgcol);
407 out32(GE64,bgcol);
408 out32(GE44,0xa0000000 | 1<<20 | 1<<19);
409 out32(GE08,point(image->dx,image->dy));
410 out32(GE0C,point(image->dx+image->width-1,image->dy+image->height-1));
411
412 while(index < index_end) {
413 for(i=0;i<width_dds;i++) {
414 out32(GE9C,*((u32*) ((u32)image->data + index)));
415 index+=4;
416 }
417 switch(width_dbs) {
418 case 0: break;
419 case 8: out32(GE9C,*((u8*)((u32)image->data+index)));
420 index+=1;
421 break;
422 case 16: out32(GE9C,*((u16*)((u32)image->data+index)));
423 index+=2;
424 break;
425 case 24: out32(GE9C,(u32)(*((u16*)((u32)image->data+index))) |
426 (u32)(*((u8*)((u32)image->data+index+2)))<<16);
427 index+=3;
428 break;
429 }
430 }
431}
432
433//==========================================================
434//
435// Check if video mode is acceptable. We change var->??? if
436// video mode is slightly off or return error otherwise.
437// info->??? must not be changed!
438//
439//==========================================================
440
441static int cyblafb_check_var(struct fb_var_screeninfo *var,
442 struct fb_info *info)
443{
444 int bpp = var->bits_per_pixel;
445 int s,t,maxvyres;
446
447 //
448 // we try to support 8, 16, 24 and 32 bpp modes,
449 // default to 8
450 //
451 // there is a 24 bpp mode, but for now we change requests to 32 bpp
452 // (This is what tridentfb does ... will be changed in the future)
453 //
454 //
455 if ( bpp % 8 != 0 || bpp < 8 || bpp >32)
456 bpp = 8;
457 if (bpp == 24 )
458 bpp = var->bits_per_pixel = 32;
459
460 //
461 // interlaced modes are broken, fail if one is requested
462 //
463 if (var->vmode & FB_VMODE_INTERLACED)
464 return -EINVAL;
465
466 //
467 // fail if requested resolution is higher than physical
468 // flatpanel resolution
469 //
470 if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex)
471 return -EINVAL;
472
473 //
474 // xres != xres_virtual is broken, fail if such an
475 // unusual mode is requested
476 //
477 if (var->xres != var->xres_virtual)
478 return -EINVAL;
479
480 //
481 // we do not allow vclk to exceed 230 MHz
482 //
483 if ((bpp==32 ? 200000000 : 100000000) / var->pixclock > 23000)
484 return -EINVAL;
485
486 //
487 // calc max yres_virtual that would fit in memory
488 // and max yres_virtual that could be used for scrolling
489 // and use minimum of the results as maxvyres
490 //
491 // adjust vyres_virtual to maxvyres if necessary
492 // fail if requested yres is bigger than maxvyres
493 //
494 s = (0x1fffff / (var->xres * bpp/8)) + var->yres;
495 t = info->fix.smem_len / (var->xres * bpp/8);
496 maxvyres = t < s ? t : s;
497 if (maxvyres < var->yres_virtual)
498 var->yres_virtual=maxvyres;
499 if (maxvyres < var->yres)
500 return -EINVAL;
501
502 switch (bpp) {
503 case 8:
504 var->red.offset = 0;
505 var->green.offset = 0;
506 var->blue.offset = 0;
507 var->red.length = 6;
508 var->green.length = 6;
509 var->blue.length = 6;
510 break;
511 case 16:
512 var->red.offset = 11;
513 var->green.offset = 5;
514 var->blue.offset = 0;
515 var->red.length = 5;
516 var->green.length = 6;
517 var->blue.length = 5;
518 break;
519 case 32:
520 var->red.offset = 16;
521 var->green.offset = 8;
522 var->blue.offset = 0;
523 var->red.length = 8;
524 var->green.length = 8;
525 var->blue.length = 8;
526 break;
527 default:
528 return -EINVAL;
529 }
530
531 return 0;
532
533}
534
535//=====================================================================
536//
537// Pan the display
538//
539// The datasheets defines crt start address to be 20 bits wide and
540// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is
541// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use
542// it, so it is also safe to be used here. BTW: datasheet CR0E on page
543// 90 really is CR1E, the real CRE is documented on page 72.
544//
545//=====================================================================
546
547static int cyblafb_pan_display(struct fb_var_screeninfo *var,
548 struct fb_info *info)
549{
550 unsigned int offset;
551
552 offset=(var->xoffset+(var->yoffset*var->xres))*var->bits_per_pixel/32;
553 info->var.xoffset = var->xoffset;
554 info->var.yoffset = var->yoffset;
555
556 write3X4(CR0D,offset & 0xFF);
557 write3X4(CR0C,(offset & 0xFF00) >> 8);
558 write3X4(CR1E,(read3X4(CR1E) & 0xDF) | ((offset & 0x10000) >> 11));
559 write3X4(CR27,(read3X4(CR27) & 0xF8) | ((offset & 0xE0000) >> 17));
560 write3X4(CR2B,(read3X4(CR2B) & 0xDF) | ((offset & 0x100000) >> 15));
561
562 return 0;
563}
564
565//============================================
566//
567// This will really help in case of a bug ...
568// dump most gaphics core registers.
569//
570//============================================
571
572static void regdump(struct cyblafb_par *par)
573{
574 int i;
575
576 if (verbosity < 2)
577 return;
578
579 printk("\n");
580 for(i=0; i<=0xff; i++) {
581 outb(i,0x3d4);
582 printk("CR%02x=%02x ",i,inb(0x3d5));
583 if (i%16==15)
584 printk("\n");
585 }
586
587 outb(0x30,0x3ce);
588 outb(inb(0x3cf) | 0x40,0x3cf);
589 for(i=0; i<=0x1f; i++) {
590 if (i==0 || (i>2 && i<8) || i==0x10 || i==0x11 || i==0x16) {
591 outb(i,0x3d4);
592 printk("CR%02x=%02x ",i,inb(0x3d5));
593 } else
594 printk("------- ");
595 if (i%16==15)
596 printk("\n");
597 }
598 outb(0x30,0x3ce);
599 outb(inb(0x3cf) & 0xbf,0x3cf);
600
601 printk("\n");
602 for(i=0; i<=0x7f; i++) {
603 outb(i,0x3ce);
604 printk("GR%02x=%02x ",i,inb(0x3cf));
605 if (i%16==15)
606 printk("\n");
607 }
608
609 printk("\n");
610 for(i=0; i<=0xff; i++) {
611 outb(i,0x3c4);
612 printk("SR%02x=%02x ",i,inb(0x3c5));
613 if (i%16==15)
614 printk("\n");
615 }
616
617 printk("\n");
618 for(i=0; i <= 0x1F; i++) {
619 inb(0x3da); // next access is index!
620 outb(i,0x3c0);
621 printk("AR%02x=%02x ",i,inb(0x3c1));
622 if (i%16==15)
623 printk("\n");
624 }
625 printk("\n");
626
627 inb(0x3DA); // reset internal flag to 3c0 index
628 outb(0x20,0x3C0); // enable attr
629
630 return;
631}
632
633//======================================
634//
635// Set hardware to requested video mode
636//
637//======================================
638
639static int cyblafb_set_par(struct fb_info *info)
640{
641 struct cyblafb_par *par = info->par;
642 u32
643 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,preendfetch,
644 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend;
645 struct fb_var_screeninfo *var = &info->var;
646 int bpp = var->bits_per_pixel;
647 int i;
648
649 if (verbosity > 0)
650 output("Switching to new mode: "
651 "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
652 var->xres,var->yres,var->xres_virtual,
653 var->yres_virtual,var->bits_per_pixel,var->pixclock,
654 var->left_margin,var->right_margin,var->upper_margin,
655 var->lower_margin,var->hsync_len,var->vsync_len);
656
657 htotal = (var->xres + var->left_margin + var->right_margin +
658 var->hsync_len) / 8 - 5;
659 hdispend = var->xres/8 - 1;
660 hsyncstart = (var->xres + var->right_margin)/8;
661 hsyncend = var->hsync_len/8;
662 hblankstart = hdispend + 1;
663 hblankend = htotal + 3; // should be htotal + 5, bios does it this way
664 preendfetch = ((var->xres >> 3) + 1) * ((bpp+1) >> 3);
665
666 vtotal = var->yres + var->upper_margin + var->lower_margin +
667 var->vsync_len - 2;
668 vdispend = var->yres - 1;
669 vsyncstart = var->yres + var->lower_margin;
670 vblankstart = var->yres;
671 vblankend = vtotal; // should be vtotal + 2, but bios does it this way
672 vsyncend = var->vsync_len;
673
674 enable_mmio(); // necessary! ... check X ...
675
676 write3X4(CR11,read3X4(CR11) & 0x7F); // unlock cr00 .. cr07
677
678 write3CE(GR30,8);
679
680 if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
681
682 // stretch or center ?
683
684 out8(0x3C2,0xEB);
685
686 write3CE(GR30,read3CE(GR30) | 0x81); // shadow mode on
687
688 if (center) {
689 write3CE(GR52,(read3CE(GR52) & 0x7C) | 0x80);
690 write3CE(GR53,(read3CE(GR53) & 0x7C) | 0x80);
691 }
692 else if (stretch) {
693 write3CE(GR5D,0);
694 write3CE(GR52,(read3CE(GR52) & 0x7C) | 1);
695 write3CE(GR53,(read3CE(GR53) & 0x7C) | 1);
696 }
697
698 } else {
699 out8(0x3C2,0x2B);
700 write3CE(GR30,8);
701 }
702
703 //
704 // Setup CRxx regs
705 //
706
707 write3X4(CR00,htotal & 0xFF);
708 write3X4(CR01,hdispend & 0xFF);
709 write3X4(CR02,hblankstart & 0xFF);
710 write3X4(CR03,hblankend & 0x1F);
711 write3X4(CR04,hsyncstart & 0xFF);
712 write3X4(CR05,(hsyncend & 0x1F) | ((hblankend & 0x20)<<2));
713 write3X4(CR06,vtotal & 0xFF);
714 write3X4(CR07,(vtotal & 0x100) >> 8 |
715 (vdispend & 0x100) >> 7 |
716 (vsyncstart & 0x100) >> 6 |
717 (vblankstart & 0x100) >> 5 |
718 0x10 |
719 (vtotal & 0x200) >> 4 |
720 (vdispend & 0x200) >> 3 |
721 (vsyncstart & 0x200) >> 2);
722 write3X4(CR08,0);
723 write3X4(CR09,(vblankstart & 0x200) >> 4 | 0x40 | // FIX !!!
724 ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
725 write3X4(CR0A,0); // Init to some reasonable default
726 write3X4(CR0B,0); // Init to some reasonable default
727 write3X4(CR0C,0); // Offset 0
728 write3X4(CR0D,0); // Offset 0
729 write3X4(CR0E,0); // Init to some reasonable default
730 write3X4(CR0F,0); // Init to some reasonable default
731 write3X4(CR10,vsyncstart & 0xFF);
732 write3X4(CR11,(vsyncend & 0x0F));
733 write3X4(CR12,vdispend & 0xFF);
734 write3X4(CR13,((info->var.xres * bpp)/(4*16)) & 0xFF);
735 write3X4(CR14,0x40); // double word mode
736 write3X4(CR15,vblankstart & 0xFF);
737 write3X4(CR16,vblankend & 0xFF);
738 write3X4(CR17,0xC3);
739 write3X4(CR18,0xFF);
740 // CR19: needed for interlaced modes ... ignore it for now
741 write3X4(CR1A,0x07); // Arbitration Control Counter 1
742 write3X4(CR1B,0x07); // Arbitration Control Counter 2
743 write3X4(CR1C,0x07); // Arbitration Control Counter 3
744 write3X4(CR1D,0x00); // Don't know, doesn't hurt ;-)
745 write3X4(CR1E,(info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
746 // CR1F: do not set, contains BIOS info about memsize
747 write3X4(CR20,0x20); // enabe wr buf, disable 16bit planar mode
748 write3X4(CR21,0x20); // enable linear memory access
749 // CR22: RO cpu latch readback
750 // CR23: ???
751 // CR24: RO AR flag state
752 // CR25: RAMDAC rw timing, pclk buffer tristate control ????
753 // CR26: ???
754 write3X4(CR27,(vdispend & 0x400) >> 6 |
755 (vsyncstart & 0x400) >> 5 |
756 (vblankstart & 0x400) >> 4 |
757 (vtotal & 0x400) >> 3 |
758 0x8);
759 // CR28: ???
760 write3X4(CR29,(read3X4(CR29) & 0xCF) |
761 ((((info->var.xres * bpp) / (4*16)) & 0x300) >>4));
762 write3X4(CR2A,read3X4(CR2A) | 0x40);
763 write3X4(CR2B,(htotal & 0x100) >> 8 |
764 (hdispend & 0x100) >> 7 |
765 // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ???
766 (hsyncstart & 0x100) >> 5 |
767 (hblankstart & 0x100) >> 4);
768 // CR2C: ???
769 // CR2D: initialized in cyblafb_setup_GE()
770 write3X4(CR2F,0x92); // conservative, better signal quality
771 // CR30: reserved
772 // CR31: reserved
773 // CR32: reserved
774 // CR33: reserved
775 // CR34: disabled in CR36
776 // CR35: disabled in CR36
777 // CR36: initialized in cyblafb_setup_GE
778 // CR37: i2c, ignore for now
779 write3X4(CR38,(bpp == 8) ? 0x00 : //
780 (bpp == 16) ? 0x05 : // highcolor
781 (bpp == 24) ? 0x29 : // packed 24bit truecolor
782 (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
783 write3X4(CR39,0x01 | // MMIO enable
784 (pcirb ? 0x02 : 0) | // pci read burst enable
785 (pciwb ? 0x04 : 0)); // pci write burst enable
786 write3X4(CR55,0x1F | // pci clocks * 2 for STOP# during 1st data phase
787 (pcirr ? 0x40 : 0) | // pci read retry enable
788 (pciwr ? 0x80 : 0)); // pci write retry enable
789 write3X4(CR56,preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01)|2 : 0);
790 write3X4(CR57,preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
791 write3X4(CR58,0x82); // Bios does this .... don't know more
792 //
793 // Setup SRxx regs
794 //
795 write3C4(SR00,3);
796 write3C4(SR01,1); //set char clock 8 dots wide
797 write3C4(SR02,0x0F); //enable 4 maps needed in chain4 mode
798 write3C4(SR03,0); //no character map select
799 write3C4(SR04,0x0E); //memory mode: ext mem, even, chain4
800
801 out8(0x3C4,0x0b);
802 in8(0x3C5); // Set NEW mode
803 write3C4(SR0D,0x00); // test ... check
804
805 set_vclk(par,(bpp==32 ? 200000000 : 100000000)/
806 info->var.pixclock); //SR18,SR19
807
808 //
809 // Setup GRxx regs
810 //
811 write3CE(GR00,0x00); // test ... check
812 write3CE(GR01,0x00); // test ... check
813 write3CE(GR02,0x00); // test ... check
814 write3CE(GR03,0x00); // test ... check
815 write3CE(GR04,0x00); // test ... check
816 write3CE(GR05,0x40); // no CGA compat,allow 256 col
817 write3CE(GR06,0x05); // graphics mode
818 write3CE(GR07,0x0F); // planes?
819 write3CE(GR08,0xFF); // test ... check
820 write3CE(GR0F,(bpp==32)?0x1A:0x12); // div vclk by 2 if 32bpp, chain4
821 write3CE(GR20,0xC0); // test ... check
822 write3CE(GR2F,0xA0); // PCLK = VCLK, no skew,
823
824 //
825 // Setup ARxx regs
826 //
827 for(i = 0;i < 0x10;i++) // set AR00 .. AR0f
828 write3C0(i,i);
829 write3C0(AR10,0x41); // graphics mode and support 256 color modes
830 write3C0(AR12,0x0F); // planes
831 write3C0(AR13,0); // horizontal pel panning
832 in8(0x3DA); // reset internal flag to 3c0 index
833 out8(0x3C0,0x20); // enable attr
834
835 //
836 // Setup hidden RAMDAC command register
837 //
838 in8(0x3C8); // these reads are
839 in8(0x3C6); // necessary to
840 in8(0x3C6); // unmask the RAMDAC
841 in8(0x3C6); // command reg, otherwise
842 in8(0x3C6); // we would write the pixelmask reg!
843 out8(0x3C6,(bpp == 8) ? 0x00 : // 256 colors
844 (bpp == 15) ? 0x10 : //
845 (bpp == 16) ? 0x30 : // hicolor
846 (bpp == 24) ? 0xD0 : // truecolor
847 (bpp == 32) ? 0xD0 : 0); // truecolor
848 in8(0x3C8);
849
850 //
851 // GR31 is not mentioned in the datasheet
852 //
853 if (displaytype == DISPLAY_FP)
854 write3CE(GR31,(read3CE(GR31) & 0x8F) |
855 ((info->var.yres > 1024) ? 0x50 :
856 (info->var.yres > 768) ? 0x30 :
857 (info->var.yres > 600) ? 0x20 :
858 (info->var.yres > 480) ? 0x10 : 0));
859
860 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
861 : FB_VISUAL_TRUECOLOR;
862 info->fix.line_length = info->var.xres * (bpp >> 3);
863 info->cmap.len = (bpp == 8) ? 256: 16;
864
865 //
866 // init acceleration engine
867 //
868 cyblafb_setup_GE(info->var.xres,info->var.bits_per_pixel);
869
870 regdump(par);
871
872 return 0;
873}
874
875//========================
876//
877// Set one color register
878//
879//========================
880
881static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
882 unsigned blue, unsigned transp,
883 struct fb_info *info)
884{
885 int bpp = info->var.bits_per_pixel;
886
887 if (regno >= info->cmap.len)
888 return 1;
889
890 if (bpp == 8) {
891 out8(0x3C6,0xFF);
892 out8(0x3C8,regno);
893 out8(0x3C9,red>>10);
894 out8(0x3C9,green>>10);
895 out8(0x3C9,blue>>10);
896
897 } else if (bpp == 16) // RGB 565
898 ((u32*)info->pseudo_palette)[regno] =
899 (red & 0xF800) |
900 ((green & 0xFC00) >> 5) |
901 ((blue & 0xF800) >> 11);
902 else if (bpp == 32) // ARGB 8888
903 ((u32*)info->pseudo_palette)[regno] =
904 ((transp & 0xFF00) <<16) |
905 ((red & 0xFF00) << 8) |
906 ((green & 0xFF00)) |
907 ((blue & 0xFF00)>>8);
908
909 return 0;
910}
911
912//==========================================================
913//
914// Try blanking the screen. For flat panels it does nothing
915//
916//==========================================================
917
918static int cyblafb_blank(int blank_mode, struct fb_info *info)
919{
920 unsigned char PMCont,DPMSCont;
921
922 if (displaytype == DISPLAY_FP)
923 return 0;
924
925 out8(0x83C8,0x04); // DPMS Control
926 PMCont = in8(0x83C6) & 0xFC;
927
928 DPMSCont = read3CE(GR23) & 0xFC;
929
930 switch (blank_mode)
931 {
932 case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On
933 case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
934 PMCont |= 0x03;
935 DPMSCont |= 0x00;
936 break;
937 case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On
938 PMCont |= 0x02;
939 DPMSCont |= 0x01;
940 break;
941 case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off
942 PMCont |= 0x02;
943 DPMSCont |= 0x02;
944 break;
945 case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off
946 PMCont |= 0x00;
947 DPMSCont |= 0x03;
948 break;
949 }
950
951 write3CE(GR23,DPMSCont);
952 out8(0x83C8,4);
953 out8(0x83C6,PMCont);
954 //
955 // let fbcon do a softblank for us
956 //
957 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
958}
959
960static struct fb_ops cyblafb_ops __devinitdata = {
961 .owner = THIS_MODULE,
962 .fb_setcolreg = cyblafb_setcolreg,
963 .fb_pan_display = cyblafb_pan_display,
964 .fb_blank = cyblafb_blank,
965 .fb_check_var = cyblafb_check_var,
966 .fb_set_par = cyblafb_set_par,
967 .fb_fillrect = cyblafb_fillrect,
968 .fb_copyarea= cyblafb_copyarea,
969 .fb_imageblit = cyblafb_imageblit,
970 .fb_cursor = soft_cursor,
971};
972
973//==========================================================================
974//
975// getstartupmode() decides about the inital video mode
976//
977// There is no reason to use modedb, a lot of video modes there would
978// need altered timings to display correctly. So I decided that it is much
979// better to provide a limited optimized set of modes plus the option of
980// using the mode in effect at startup time (might be selected using the
981// vga=??? paramter). After that the user might use fbset to select any
982// mode he likes, check_var will not try to alter geometry parameters as
983// it would be necessary otherwise.
984//
985//==========================================================================
986
987static int __devinit getstartupmode(struct fb_info *info)
988{
989 u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,
990 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend,
991 cr00,cr01,cr02,cr03,cr04,cr05,cr2b,
992 cr06,cr07,cr09,cr10,cr11,cr12,cr15,cr16,cr27,
993 cr38,
994 sr0d,sr18,sr19,
995 gr0f,
996 fi,pxclkdiv,vclkdiv,tmp,i;
997
998 struct modus {
999 int xres; int yres; int vyres; int bpp; int pxclk;
1000 int left_margin; int right_margin; int upper_margin;
1001 int lower_margin; int hsync_len; int vsync_len;
1002 } modedb[5] = {
1003 { 0, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0},
1004 { 640, 480, 3756, 0, 0, -40, 24, 17, 0, 216, 3},
1005 { 800, 600, 3221, 0, 0, 96, 24, 14, 0, 136, 11},
1006 {1024, 768, 2815, 0, 0, 144, 24, 29, 0, 120, 3},
1007 {1280, 1024, 2662, 0, 0, 232, 16, 39, 0, 160, 3}
1008 };
1009
1010 outb(0x00,0x3d4); cr00=inb(0x3d5); outb(0x01,0x3d4); cr01=inb(0x3d5);
1011 outb(0x02,0x3d4); cr02=inb(0x3d5); outb(0x03,0x3d4); cr03=inb(0x3d5);
1012 outb(0x04,0x3d4); cr04=inb(0x3d5); outb(0x05,0x3d4); cr05=inb(0x3d5);
1013 outb(0x06,0x3d4); cr06=inb(0x3d5); outb(0x07,0x3d4); cr07=inb(0x3d5);
1014 outb(0x09,0x3d4); cr09=inb(0x3d5); outb(0x10,0x3d4); cr10=inb(0x3d5);
1015 outb(0x11,0x3d4); cr11=inb(0x3d5); outb(0x12,0x3d4); cr12=inb(0x3d5);
1016 outb(0x15,0x3d4); cr15=inb(0x3d5); outb(0x16,0x3d4); cr16=inb(0x3d5);
1017 outb(0x27,0x3d4); cr27=inb(0x3d5); outb(0x2b,0x3d4); cr2b=inb(0x3d5);
1018 outb(0x38,0x3d4); cr38=inb(0x3d5); outb(0x0b,0x3c4); inb(0x3c5);
1019 outb(0x0d,0x3c4); sr0d=inb(0x3c5); outb(0x18,0x3c4); sr18=inb(0x3c5);
1020 outb(0x19,0x3c4); sr19=inb(0x3c5); outb(0x0f,0x3ce); gr0f=inb(0x3cf);
1021
1022 htotal = cr00 | (cr2b & 0x01) << 8;
1023 hdispend = cr01 | (cr2b & 0x02) << 7;
1024 hblankstart = cr02 | (cr2b & 0x10) << 4;
1025 hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
1026 hsyncstart = cr04 | (cr2b & 0x08) << 5;
1027 hsyncend = cr05 & 0x1f;
1028
1029 modedb[0].xres = hblankstart * 8;
1030 modedb[0].hsync_len = hsyncend * 8;
1031 modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
1032 modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
1033 modedb[0].right_margin - modedb[0].hsync_len;
1034
1035 vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
1036 | (cr27 & 0x80) << 3;
1037 vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
1038 | (cr27 & 0x10) << 6;
1039 vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
1040 | (cr27 & 0x20) << 5;
1041 vsyncend = cr11 & 0x0f;
1042 vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
1043 | (cr27 & 0x40) << 4;
1044 vblankend = cr16;
1045
1046 modedb[0].yres = vdispend + 1;
1047 modedb[0].vsync_len = vsyncend;
1048 modedb[0].lower_margin = vsyncstart - modedb[0].yres;
1049 modedb[0].upper_margin = vtotal - modedb[0].yres -
1050 modedb[0].lower_margin - modedb[0].vsync_len + 2;
1051
1052 tmp = cr38 & 0x3c;
1053 modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
1054 tmp == 8 ? 32 : 8;
1055
1056 fi = ((5864727*(sr18+8))/(((sr19&0x3f)+2)*(1<<((sr19&0xc0)>>6))))>>12;
1057 pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
1058 tmp = sr0d & 0x06;
1059 vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
1060 modedb[0].pxclk = ((100000000 * pxclkdiv * vclkdiv) >> 1) / fi;
1061
1062 if (verbosity > 0)
1063 output("detected startup mode: "
1064 "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
1065 modedb[0].xres,modedb[0].yres,modedb[0].xres,
1066 modedb[0].bpp,modedb[0].pxclk,modedb[0].left_margin,
1067 modedb[0].right_margin,modedb[0].upper_margin,
1068 modedb[0].lower_margin,modedb[0].hsync_len,
1069 modedb[0].vsync_len);
1070
1071 //
1072 // We use this goto target in case of a failed check_var. No, I really
1073 // do not want to do it in another way!
1074 //
1075
1076 tryagain:
1077
1078 i = (mode == NULL) ? 0 :
1079 !strncmp(mode,"640x480",7) ? 1 :
1080 !strncmp(mode,"800x600",7) ? 2 :
1081 !strncmp(mode,"1024x768",8) ? 3 :
1082 !strncmp(mode,"1280x1024",9) ? 4 : 0;
1083
1084 ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
1085
1086 if(i==0) {
1087 info->var.pixclock = modedb[i].pxclk;
1088 info->var.bits_per_pixel = modedb[i].bpp;
1089 } else {
1090 info->var.pixclock = (100000000 /
1091 ((modedb[i].left_margin + modedb[i].xres +
1092 modedb[i].right_margin + modedb[i].hsync_len
1093 ) * (
1094 modedb[i].upper_margin + modedb[i].yres +
1095 modedb[i].lower_margin + modedb[i].vsync_len
1096 ) *
1097 ref / 10000
1098 ));
1099 info->var.bits_per_pixel = bpp;
1100 }
1101
1102 info->var.left_margin = modedb[i].left_margin;
1103 info->var.right_margin = modedb[i].right_margin;
1104 info->var.xres = modedb[i].xres;
1105 info->var.xres_virtual = modedb[i].xres;
1106 info->var.xoffset = 0;
1107 info->var.hsync_len = modedb[i].hsync_len;
1108 info->var.upper_margin = modedb[i].upper_margin;
1109 info->var.yres = modedb[i].yres;
1110 info->var.yres_virtual = modedb[i].vyres;
1111 info->var.yoffset = 0;
1112 info->var.lower_margin = modedb[i].lower_margin;
1113 info->var.vsync_len = modedb[i].vsync_len;
1114 info->var.sync = 0;
1115 info->var.vmode = FB_VMODE_NONINTERLACED;
1116
1117 if(cyblafb_check_var(&info->var,info)) {
1118 // 640x480-8@75 should really never fail. One case would
1119 // be fp == 1 and nativex < 640 ... give up then
1120 if(i==1 && bpp == 8 && ref == 75){
1121 output("Can't find a valid mode :-(\n");
1122 return -EINVAL;
1123 }
1124 // Our detected mode is unlikely to fail. If it does,
1125 // try 640x480-8@75 ...
1126 if(i==0) {
1127 mode="640x480";
1128 bpp=8;
1129 ref=75;
1130 output("Detected mode failed check_var! "
1131 "Trying 640x480-8@75\n");
1132 goto tryagain;
1133 }
1134 // A specified video mode failed for some reason.
1135 // Try the startup mode first
1136 output("Specified mode '%s' failed check! "
1137 "Falling back to startup mode.\n",mode);
1138 mode=NULL;
1139 goto tryagain;
1140 }
1141
1142 return 0;
1143
1144}
1145
1146//========================================================
1147//
1148// Detect activated memory size. Undefined values require
1149// memsize parameter.
1150//
1151//========================================================
1152
1153static unsigned int __devinit get_memsize(void)
1154{
1155 unsigned char tmp;
1156 unsigned int k;
1157
1158 if (memsize)
1159 k = memsize * Kb;
1160 else {
1161 tmp = read3X4(CR1F) & 0x0F;
1162 switch (tmp) {
1163 case 0x03: k = 1 * Mb; break;
1164 case 0x07: k = 2 * Mb; break;
1165 case 0x0F: k = 4 * Mb; break;
1166 case 0x04: k = 8 * Mb; break;
1167 default:
1168 k = 1 * Mb;
1169 output("Unknown memory size code %x in CR1F."
1170 " We default to 1 Mb for now, please"
1171 " do provide a memsize parameter!\n",
1172 tmp);
1173 }
1174 }
1175
1176 if (verbosity > 0)
1177 output("framebuffer size = %d Kb\n",k/Kb);
1178 return k;
1179}
1180
1181//=========================================================
1182//
1183// Detect if a flat panel monitor connected to the special
1184// interface is active. Override is possible by fp and crt
1185// parameters.
1186//
1187//=========================================================
1188
1189static unsigned int __devinit get_displaytype(void)
1190{
1191 if (fp)
1192 return DISPLAY_FP;
1193 if (crt)
1194 return DISPLAY_CRT;
1195 return (read3CE(GR33) & 0x10)?DISPLAY_FP:DISPLAY_CRT;
1196}
1197
1198//=====================================
1199//
1200// Get native resolution of flat panel
1201//
1202//=====================================
1203
1204static int __devinit get_nativex(void)
1205{
1206 int x,y,tmp;
1207
1208 if (nativex)
1209 return nativex;
1210
1211 tmp = (read3CE(GR52) >> 4) & 3;
1212
1213 switch (tmp) {
1214 case 0: x = 1280; y = 1024; break;
1215 case 2: x = 1024; y = 768; break;
1216 case 3: x = 800; y = 600; break;
1217 case 4: x = 1400; y = 1050; break;
1218 case 1:
1219 default: x = 640; y = 480; break;
1220 }
1221
1222 if (verbosity > 0)
1223 output("%dx%d flat panel found\n",x,y);
1224 return x;
1225}
1226
1227static int __devinit cybla_pci_probe(struct pci_dev * dev,
1228 const struct pci_device_id * id)
1229{
1230 struct fb_info *info;
1231 struct cyblafb_par *par;
1232
1233 info = framebuffer_alloc(sizeof(struct cyblafb_par),&dev->dev);
1234
1235 if (!info)
1236 goto errout_alloc;
1237
1238 par = info->par;
1239 par->ops = cyblafb_ops;
1240
1241 info->fix = cyblafb_fix;
1242 info->fbops = &par->ops;
1243 info->fix = cyblafb_fix;
1244
1245 if (pci_enable_device(dev)) {
1246 output("could not enable device!\n");
1247 goto errout_enable;
1248 }
1249
1250 // might already be requested by vga console or vesafb,
1251 // so we do care about success
1252 request_region(0x3c0,32,"cyblafb");
1253
1254 //
1255 // Graphics Engine Registers
1256 //
1257 request_region(GEBase,0x100,"cyblafb");
1258
1259 regdump(par);
1260
1261 enable_mmio();
1262
1263 // setup MMIO region
1264 info->fix.mmio_start = pci_resource_start(dev,1);
1265 info->fix.mmio_len = 0x20000;
1266
1267 if (!request_mem_region(info->fix.mmio_start,
1268 info->fix.mmio_len,"cyblafb")) {
1269 output("request_mem_region failed for mmio region!\n");
1270 goto errout_mmio_reqmem;
1271 }
1272
1273 io_virt = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
1274
1275 if (!io_virt) {
1276 output("ioremap failed for mmio region\n");
1277 goto errout_mmio_remap;
1278 }
1279
1280 // setup framebuffer memory ... might already be requested
1281 // by vesafb. Not to fail in case of an unsuccessful request
1282 // is useful for the development cycle
1283 info->fix.smem_start = pci_resource_start(dev,0);
1284 info->fix.smem_len = get_memsize();
1285
1286 if (!request_mem_region(info->fix.smem_start,
1287 info->fix.smem_len,"cyblafb")) {
1288 output("request_mem_region failed for smem region!\n");
1289 if (!vesafb)
1290 goto errout_smem_req;
1291 }
1292
1293 info->screen_base = ioremap_nocache(info->fix.smem_start,
1294 info->fix.smem_len);
1295
1296 if (!info->screen_base) {
1297 output("ioremap failed for smem region\n");
1298 goto errout_smem_remap;
1299 }
1300
1301 displaytype = get_displaytype();
1302
1303 if(displaytype == DISPLAY_FP)
1304 nativex = get_nativex();
1305
1306 //
1307 // FBINFO_HWACCEL_YWRAP .... does not work (could be made to work?)
1308 // FBINFO_PARTIAL_PAN_OK .... is not ok
1309 // FBINFO_READS_FAST .... is necessary for optimal scrolling
1310 //
1311 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN
1312 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT
1313 | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_READS_FAST;
1314
1315 info->pseudo_palette = par->pseudo_pal;
1316
1317 if(getstartupmode(info))
1318 goto errout_findmode;
1319
1320 fb_alloc_cmap(&info->cmap,256,0);
1321
1322 if (register_framebuffer(info)) {
1323 output("Could not register CyBla framebuffer\n");
1324 goto errout_register;
1325 }
1326
1327 pci_set_drvdata(dev,info);
1328
1329 //
1330 // normal exit and error paths
1331 //
1332
1333 return 0;
1334
1335 errout_register:
1336 errout_findmode:
1337 iounmap(info->screen_base);
1338 errout_smem_remap:
1339 release_mem_region(info->fix.smem_start,
1340 info->fix.smem_len);
1341 errout_smem_req:
1342 iounmap(io_virt);
1343 errout_mmio_remap:
1344 release_mem_region(info->fix.mmio_start,
1345 info->fix.mmio_len);
1346 errout_mmio_reqmem:
1347// release_region(0x3c0,32);
1348 errout_enable:
1349 framebuffer_release(info);
1350 errout_alloc:
1351 output("CyblaFB version %s aborting init.\n",VERSION);
1352 return -ENODEV;
1353}
1354
1355static void __devexit cybla_pci_remove(struct pci_dev *dev)
1356{
1357 struct fb_info *info = pci_get_drvdata(dev);
1358
1359 unregister_framebuffer(info);
1360 iounmap(io_virt);
1361 iounmap(info->screen_base);
1362 release_mem_region(info->fix.smem_start,info->fix.smem_len);
1363 release_mem_region(info->fix.mmio_start,info->fix.mmio_len);
1364 fb_dealloc_cmap(&info->cmap);
1365 framebuffer_release(info);
1366 output("CyblaFB version %s normal exit.\n",VERSION);
1367}
1368
1369//
1370// List of boards that we are trying to support
1371//
1372static struct pci_device_id cybla_devices[] = {
1373 {PCI_VENDOR_ID_TRIDENT,CYBERBLADEi1,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
1374 {0,}
1375};
1376
1377MODULE_DEVICE_TABLE(pci,cybla_devices);
1378
1379static struct pci_driver cyblafb_pci_driver = {
1380 .name = "cyblafb",
1381 .id_table = cybla_devices,
1382 .probe = cybla_pci_probe,
1383 .remove = __devexit_p(cybla_pci_remove)
1384};
1385
1386//=============================================================
1387//
1388// kernel command line example:
1389//
1390// video=cyblafb:1280x1024,bpp=16,ref=50 ...
1391//
1392// modprobe command line example:
1393//
1394// modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
1395//
1396//=============================================================
1397
1398static int __devinit cyblafb_init(void)
1399{
1400#ifndef MODULE
1401 char *options = NULL;
1402 char *opt;
1403
1404 if (fb_get_options("cyblafb",&options))
1405 return -ENODEV;
1406
1407 if (options && *options)
1408 while((opt = strsep(&options,",")) != NULL ) {
1409 if (!*opt) continue;
1410 else if (!strncmp(opt,"bpp=",4))
1411 bpp = simple_strtoul(opt+4,NULL,0);
1412 else if (!strncmp(opt,"ref=",4))
1413 ref = simple_strtoul(opt+4,NULL,0);
1414 else if (!strncmp(opt,"fp",2))
1415 displaytype = DISPLAY_FP;
1416 else if (!strncmp(opt,"crt",3))
1417 displaytype = DISPLAY_CRT;
1418 else if (!strncmp(opt,"nativex=",8))
1419 nativex = simple_strtoul(opt+8,NULL,0);
1420 else if (!strncmp(opt,"center",6))
1421 center = 1;
1422 else if (!strncmp(opt,"stretch",7))
1423 stretch = 1;
1424 else if (!strncmp(opt,"pciwb=",6))
1425 pciwb = simple_strtoul(opt+6,NULL,0);
1426 else if (!strncmp(opt,"pcirb=",6))
1427 pcirb = simple_strtoul(opt+6,NULL,0);
1428 else if (!strncmp(opt,"pciwr=",6))
1429 pciwr = simple_strtoul(opt+6,NULL,0);
1430 else if (!strncmp(opt,"pcirr=",6))
1431 pcirr = simple_strtoul(opt+6,NULL,0);
1432 else if (!strncmp(opt,"memsize=",8))
1433 memsize = simple_strtoul(opt+8,NULL,0);
1434 else if (!strncmp(opt,"verbosity=",10))
1435 verbosity = simple_strtoul(opt+10,NULL,0);
1436 else if (!strncmp(opt,"vesafb",6))
1437 vesafb = 1;
1438 else
1439 mode = opt;
1440 }
1441#endif
1442 output("CyblaFB version %s initializing\n",VERSION);
1443 return pci_module_init(&cyblafb_pci_driver);
1444}
1445
1446static void __exit cyblafb_exit(void)
1447{
1448 pci_unregister_driver(&cyblafb_pci_driver);
1449}
1450
1451module_init(cyblafb_init);
1452module_exit(cyblafb_exit);
1453
1454MODULE_AUTHOR("Knut Petersen <knut_petersen@t-online.de>");
1455MODULE_DESCRIPTION("Framebuffer driver for Cyberblade/i1 graphics core");
1456MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
new file mode 100644
index 000000000000..cfa61b512de0
--- /dev/null
+++ b/drivers/video/fbcvt.c
@@ -0,0 +1,380 @@
1/*
2 * linux/drivers/video/fbcvt.c - VESA(TM) Coordinated Video Timings
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
5 *
6 * Based from the VESA(TM) Coordinated Video Timing Generator by
7 * Graham Loveridge April 9, 2003 available at
8 * http://www.vesa.org/public/CVT/CVTd6r1.xls
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive
12 * for more details.
13 *
14 */
15#include <linux/fb.h>
16
17#define FB_CVT_CELLSIZE 8
18#define FB_CVT_GTF_C 40
19#define FB_CVT_GTF_J 20
20#define FB_CVT_GTF_K 128
21#define FB_CVT_GTF_M 600
22#define FB_CVT_MIN_VSYNC_BP 550
23#define FB_CVT_MIN_VPORCH 3
24#define FB_CVT_MIN_BPORCH 6
25
26#define FB_CVT_RB_MIN_VBLANK 460
27#define FB_CVT_RB_HBLANK 160
28#define FB_CVT_RB_V_FPORCH 3
29
30#define FB_CVT_FLAG_REDUCED_BLANK 1
31#define FB_CVT_FLAG_MARGINS 2
32#define FB_CVT_FLAG_INTERLACED 4
33
34struct fb_cvt_data {
35 u32 xres;
36 u32 yres;
37 u32 refresh;
38 u32 f_refresh;
39 u32 pixclock;
40 u32 hperiod;
41 u32 hblank;
42 u32 hfreq;
43 u32 htotal;
44 u32 vtotal;
45 u32 vsync;
46 u32 hsync;
47 u32 h_front_porch;
48 u32 h_back_porch;
49 u32 v_front_porch;
50 u32 v_back_porch;
51 u32 h_margin;
52 u32 v_margin;
53 u32 interlace;
54 u32 aspect_ratio;
55 u32 active_pixels;
56 u32 flags;
57 u32 status;
58};
59
60static int fb_cvt_vbi_tab[] = {
61 4, /* 4:3 */
62 5, /* 16:9 */
63 6, /* 16:10 */
64 7, /* 5:4 */
65 7, /* 15:9 */
66 8, /* reserved */
67 9, /* reserved */
68 10 /* custom */
69};
70
71/* returns hperiod * 1000 */
72static u32 fb_cvt_hperiod(struct fb_cvt_data *cvt)
73{
74 u32 num = 1000000000/cvt->f_refresh;
75 u32 den;
76
77 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
78 num -= FB_CVT_RB_MIN_VBLANK * 1000;
79 den = 2 * (cvt->yres/cvt->interlace + 2 * cvt->v_margin);
80 } else {
81 num -= FB_CVT_MIN_VSYNC_BP * 1000;
82 den = 2 * (cvt->yres/cvt->interlace + cvt->v_margin * 2
83 + FB_CVT_MIN_VPORCH + cvt->interlace/2);
84 }
85
86 return 2 * (num/den);
87}
88
89/* returns ideal duty cycle * 1000 */
90static u32 fb_cvt_ideal_duty_cycle(struct fb_cvt_data *cvt)
91{
92 u32 c_prime = (FB_CVT_GTF_C - FB_CVT_GTF_J) *
93 (FB_CVT_GTF_K) + 256 * FB_CVT_GTF_J;
94 u32 m_prime = (FB_CVT_GTF_K * FB_CVT_GTF_M);
95 u32 h_period_est = cvt->hperiod;
96
97 return (1000 * c_prime - ((m_prime * h_period_est)/1000))/256;
98}
99
100static u32 fb_cvt_hblank(struct fb_cvt_data *cvt)
101{
102 u32 hblank = 0;
103
104 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
105 hblank = FB_CVT_RB_HBLANK;
106 else {
107 u32 ideal_duty_cycle = fb_cvt_ideal_duty_cycle(cvt);
108 u32 active_pixels = cvt->active_pixels;
109
110 if (ideal_duty_cycle < 20000)
111 hblank = (active_pixels * 20000)/
112 (100000 - 20000);
113 else {
114 hblank = (active_pixels * ideal_duty_cycle)/
115 (100000 - ideal_duty_cycle);
116 }
117 }
118
119 hblank &= ~((2 * FB_CVT_CELLSIZE) - 1);
120
121 return hblank;
122}
123
124static u32 fb_cvt_hsync(struct fb_cvt_data *cvt)
125{
126 u32 hsync;
127
128 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
129 hsync = 32;
130 else
131 hsync = (FB_CVT_CELLSIZE * cvt->htotal)/100;
132
133 hsync &= ~(FB_CVT_CELLSIZE - 1);
134 return hsync;
135}
136
137static u32 fb_cvt_vbi_lines(struct fb_cvt_data *cvt)
138{
139 u32 vbi_lines, min_vbi_lines, act_vbi_lines;
140
141 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
142 vbi_lines = (1000 * FB_CVT_RB_MIN_VBLANK)/cvt->hperiod + 1;
143 min_vbi_lines = FB_CVT_RB_V_FPORCH + cvt->vsync +
144 FB_CVT_MIN_BPORCH;
145
146 } else {
147 vbi_lines = (FB_CVT_MIN_VSYNC_BP * 1000)/cvt->hperiod + 1 +
148 FB_CVT_MIN_VPORCH;
149 min_vbi_lines = cvt->vsync + FB_CVT_MIN_BPORCH +
150 FB_CVT_MIN_VPORCH;
151 }
152
153 if (vbi_lines < min_vbi_lines)
154 act_vbi_lines = min_vbi_lines;
155 else
156 act_vbi_lines = vbi_lines;
157
158 return act_vbi_lines;
159}
160
161static u32 fb_cvt_vtotal(struct fb_cvt_data *cvt)
162{
163 u32 vtotal = cvt->yres/cvt->interlace;
164
165 vtotal += 2 * cvt->v_margin + cvt->interlace/2 + fb_cvt_vbi_lines(cvt);
166 vtotal |= cvt->interlace/2;
167
168 return vtotal;
169}
170
171static u32 fb_cvt_pixclock(struct fb_cvt_data *cvt)
172{
173 u32 pixclock;
174
175 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
176 pixclock = (cvt->f_refresh * cvt->vtotal * cvt->htotal)/1000;
177 else
178 pixclock = (cvt->htotal * 1000000)/cvt->hperiod;
179
180 pixclock /= 250;
181 pixclock *= 250;
182 pixclock *= 1000;
183
184 return pixclock;
185}
186
187static u32 fb_cvt_aspect_ratio(struct fb_cvt_data *cvt)
188{
189 u32 xres = cvt->xres;
190 u32 yres = cvt->yres;
191 u32 aspect = -1;
192
193 if (xres == (yres * 4)/3 && !((yres * 4) % 3))
194 aspect = 0;
195 else if (xres == (yres * 16)/9 && !((yres * 16) % 9))
196 aspect = 1;
197 else if (xres == (yres * 16)/10 && !((yres * 16) % 10))
198 aspect = 2;
199 else if (xres == (yres * 5)/4 && !((yres * 5) % 4))
200 aspect = 3;
201 else if (xres == (yres * 15)/9 && !((yres * 15) % 9))
202 aspect = 4;
203 else {
204 printk(KERN_INFO "fbcvt: Aspect ratio not CVT "
205 "standard\n");
206 aspect = 7;
207 cvt->status = 1;
208 }
209
210 return aspect;
211}
212
213static void fb_cvt_print_name(struct fb_cvt_data *cvt)
214{
215 u32 pixcount, pixcount_mod;
216 int cnt = 255, offset = 0, read = 0;
217 u8 *buf = kmalloc(256, GFP_KERNEL);
218
219 if (!buf)
220 return;
221
222 memset(buf, 0, 256);
223 pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000;
224 pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000;
225 pixcount_mod /= 1000;
226
227 read = snprintf(buf+offset, cnt, "fbcvt: %dx%d@%d: CVT Name - ",
228 cvt->xres, cvt->yres, cvt->refresh);
229 offset += read;
230 cnt -= read;
231
232 if (cvt->status)
233 snprintf(buf+offset, cnt, "Not a CVT standard - %d.%03d Mega "
234 "Pixel Image\n", pixcount, pixcount_mod);
235 else {
236 if (pixcount) {
237 read = snprintf(buf+offset, cnt, "%d", pixcount);
238 cnt -= read;
239 offset += read;
240 }
241
242 read = snprintf(buf+offset, cnt, ".%03dM", pixcount_mod);
243 cnt -= read;
244 offset += read;
245
246 if (cvt->aspect_ratio == 0)
247 read = snprintf(buf+offset, cnt, "3");
248 else if (cvt->aspect_ratio == 3)
249 read = snprintf(buf+offset, cnt, "4");
250 else if (cvt->aspect_ratio == 1 || cvt->aspect_ratio == 4)
251 read = snprintf(buf+offset, cnt, "9");
252 else if (cvt->aspect_ratio == 2)
253 read = snprintf(buf+offset, cnt, "A");
254 else
255 read = 0;
256 cnt -= read;
257 offset += read;
258
259 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
260 read = snprintf(buf+offset, cnt, "-R");
261 cnt -= read;
262 offset += read;
263 }
264 }
265
266 printk(KERN_INFO "%s\n", buf);
267 kfree(buf);
268}
269
270static void fb_cvt_convert_to_mode(struct fb_cvt_data *cvt,
271 struct fb_videomode *mode)
272{
273 mode->refresh = cvt->f_refresh;
274 mode->pixclock = KHZ2PICOS(cvt->pixclock/1000);
275 mode->left_margin = cvt->h_front_porch;
276 mode->right_margin = cvt->h_back_porch;
277 mode->hsync_len = cvt->hsync;
278 mode->upper_margin = cvt->v_front_porch;
279 mode->lower_margin = cvt->v_back_porch;
280 mode->vsync_len = cvt->vsync;
281
282 mode->sync &= ~(FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
283
284 if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
285 mode->sync |= FB_SYNC_HOR_HIGH_ACT;
286 else
287 mode->sync |= FB_SYNC_VERT_HIGH_ACT;
288}
289
290/*
291 * fb_find_mode_cvt - calculate mode using VESA(TM) CVT
292 * @mode: pointer to fb_videomode; xres, yres, refresh and vmode must be
293 * pre-filled with the desired values
294 * @margins: add margin to calculation (1.8% of xres and yres)
295 * @rb: compute with reduced blanking (for flatpanels)
296 *
297 * RETURNS:
298 * 0 for success
299 * @mode is filled with computed values. If interlaced, the refresh field
300 * will be filled with the field rate (2x the frame rate)
301 *
302 * DESCRIPTION:
303 * Computes video timings using VESA(TM) Coordinated Video Timings
304 */
305int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
306{
307 struct fb_cvt_data cvt;
308
309 memset(&cvt, 0, sizeof(cvt));
310
311 if (margins)
312 cvt.flags |= FB_CVT_FLAG_MARGINS;
313
314 if (rb)
315 cvt.flags |= FB_CVT_FLAG_REDUCED_BLANK;
316
317 if (mode->vmode & FB_VMODE_INTERLACED)
318 cvt.flags |= FB_CVT_FLAG_INTERLACED;
319
320 cvt.xres = mode->xres;
321 cvt.yres = mode->yres;
322 cvt.refresh = mode->refresh;
323 cvt.f_refresh = cvt.refresh;
324 cvt.interlace = 1;
325
326 if (!cvt.xres || !cvt.yres || !cvt.refresh) {
327 printk(KERN_INFO "fbcvt: Invalid input parameters\n");
328 return 1;
329 }
330
331 if (!(cvt.refresh == 50 || cvt.refresh == 60 || cvt.refresh == 70 ||
332 cvt.refresh == 85)) {
333 printk(KERN_INFO "fbcvt: Refresh rate not CVT "
334 "standard\n");
335 cvt.status = 1;
336 }
337
338 cvt.xres &= ~(FB_CVT_CELLSIZE - 1);
339
340 if (cvt.flags & FB_CVT_FLAG_INTERLACED) {
341 cvt.interlace = 2;
342 cvt.f_refresh *= 2;
343 }
344
345 if (cvt.flags & FB_CVT_FLAG_REDUCED_BLANK) {
346 if (cvt.refresh != 60) {
347 printk(KERN_INFO "fbcvt: 60Hz refresh rate "
348 "advised for reduced blanking\n");
349 cvt.status = 1;
350 }
351 }
352
353 if (cvt.flags & FB_CVT_FLAG_MARGINS) {
354 cvt.h_margin = (cvt.xres * 18)/1000;
355 cvt.h_margin &= ~(FB_CVT_CELLSIZE - 1);
356 cvt.v_margin = ((cvt.yres/cvt.interlace)* 18)/1000;
357 }
358
359 cvt.aspect_ratio = fb_cvt_aspect_ratio(&cvt);
360 cvt.active_pixels = cvt.xres + 2 * cvt.h_margin;
361 cvt.hperiod = fb_cvt_hperiod(&cvt);
362 cvt.vsync = fb_cvt_vbi_tab[cvt.aspect_ratio];
363 cvt.vtotal = fb_cvt_vtotal(&cvt);
364 cvt.hblank = fb_cvt_hblank(&cvt);
365 cvt.htotal = cvt.active_pixels + cvt.hblank;
366 cvt.hsync = fb_cvt_hsync(&cvt);
367 cvt.pixclock = fb_cvt_pixclock(&cvt);
368 cvt.hfreq = cvt.pixclock/cvt.htotal;
369 cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin;
370 cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch +
371 2 * cvt.h_margin;
372 cvt.v_back_porch = 3 + cvt.v_margin;
373 cvt.v_front_porch = cvt.vtotal - cvt.yres/cvt.interlace -
374 cvt.v_back_porch - cvt.vsync;
375 fb_cvt_print_name(&cvt);
376 fb_cvt_convert_to_mode(&cvt, mode);
377
378 return 0;
379}
380EXPORT_SYMBOL(fb_find_mode_cvt);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 4ff853fbe0be..70be7009f8af 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -62,16 +62,26 @@ int num_registered_fb;
62 * Helpers 62 * Helpers
63 */ 63 */
64 64
65int fb_get_color_depth(struct fb_var_screeninfo *var) 65int fb_get_color_depth(struct fb_var_screeninfo *var,
66 struct fb_fix_screeninfo *fix)
66{ 67{
67 if (var->green.length == var->blue.length && 68 int depth = 0;
68 var->green.length == var->red.length && 69
69 !var->green.offset && !var->blue.offset && 70 if (fix->visual == FB_VISUAL_MONO01 ||
70 !var->red.offset) 71 fix->visual == FB_VISUAL_MONO10)
71 return var->green.length; 72 depth = 1;
72 else 73 else {
73 return (var->green.length + var->red.length + 74 if (var->green.length == var->blue.length &&
74 var->blue.length); 75 var->green.length == var->red.length &&
76 var->green.offset == var->blue.offset &&
77 var->green.offset == var->red.offset)
78 depth = var->green.length;
79 else
80 depth = var->green.length + var->red.length +
81 var->blue.length;
82 }
83
84 return depth;
75} 85}
76EXPORT_SYMBOL(fb_get_color_depth); 86EXPORT_SYMBOL(fb_get_color_depth);
77 87
@@ -80,15 +90,7 @@ EXPORT_SYMBOL(fb_get_color_depth);
80 */ 90 */
81void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) 91void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
82{ 92{
83 int i, j; 93 __fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, height);
84
85 for (i = height; i--; ) {
86 /* s_pitch is a few bytes at the most, memcpy is suboptimal */
87 for (j = 0; j < s_pitch; j++)
88 dst[j] = src[j];
89 src += s_pitch;
90 dst += d_pitch;
91 }
92} 94}
93EXPORT_SYMBOL(fb_pad_aligned_buffer); 95EXPORT_SYMBOL(fb_pad_aligned_buffer);
94 96
@@ -249,13 +251,18 @@ static void fb_set_logo(struct fb_info *info,
249 const struct linux_logo *logo, u8 *dst, 251 const struct linux_logo *logo, u8 *dst,
250 int depth) 252 int depth)
251{ 253{
252 int i, j, k, fg = 1; 254 int i, j, k;
253 const u8 *src = logo->data; 255 const u8 *src = logo->data;
254 u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; 256 u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
257 u8 fg = 1, d;
255 258
256 if (fb_get_color_depth(&info->var) == 3) 259 if (fb_get_color_depth(&info->var, &info->fix) == 3)
257 fg = 7; 260 fg = 7;
258 261
262 if (info->fix.visual == FB_VISUAL_MONO01 ||
263 info->fix.visual == FB_VISUAL_MONO10)
264 fg = ~((u8) (0xfff << info->var.green.length));
265
259 switch (depth) { 266 switch (depth) {
260 case 4: 267 case 4:
261 for (i = 0; i < logo->height; i++) 268 for (i = 0; i < logo->height; i++)
@@ -318,7 +325,7 @@ static struct logo_data {
318 325
319int fb_prepare_logo(struct fb_info *info) 326int fb_prepare_logo(struct fb_info *info)
320{ 327{
321 int depth = fb_get_color_depth(&info->var); 328 int depth = fb_get_color_depth(&info->var, &info->fix);
322 329
323 memset(&fb_logo, 0, sizeof(struct logo_data)); 330 memset(&fb_logo, 0, sizeof(struct logo_data));
324 331
@@ -684,11 +691,13 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
684 691
685 if (!err && (flags & FBINFO_MISC_USEREVENT)) { 692 if (!err && (flags & FBINFO_MISC_USEREVENT)) {
686 struct fb_event event; 693 struct fb_event event;
694 int evnt = (var->activate & FB_ACTIVATE_ALL) ?
695 FB_EVENT_MODE_CHANGE_ALL :
696 FB_EVENT_MODE_CHANGE;
687 697
688 info->flags &= ~FBINFO_MISC_USEREVENT; 698 info->flags &= ~FBINFO_MISC_USEREVENT;
689 event.info = info; 699 event.info = info;
690 notifier_call_chain(&fb_notifier_list, 700 notifier_call_chain(&fb_notifier_list, evnt,
691 FB_EVENT_MODE_CHANGE,
692 &event); 701 &event);
693 } 702 }
694 } 703 }
@@ -1012,6 +1021,7 @@ register_framebuffer(struct fb_info *fb_info)
1012{ 1021{
1013 int i; 1022 int i;
1014 struct fb_event event; 1023 struct fb_event event;
1024 struct fb_videomode mode;
1015 1025
1016 if (num_registered_fb == FB_MAX) 1026 if (num_registered_fb == FB_MAX)
1017 return -ENXIO; 1027 return -ENXIO;
@@ -1042,16 +1052,11 @@ register_framebuffer(struct fb_info *fb_info)
1042 } 1052 }
1043 fb_info->pixmap.offset = 0; 1053 fb_info->pixmap.offset = 0;
1044 1054
1045 if (!fb_info->modelist.prev || 1055 if (!fb_info->modelist.prev || !fb_info->modelist.next)
1046 !fb_info->modelist.next ||
1047 list_empty(&fb_info->modelist)) {
1048 struct fb_videomode mode;
1049
1050 INIT_LIST_HEAD(&fb_info->modelist); 1056 INIT_LIST_HEAD(&fb_info->modelist);
1051 fb_var_to_videomode(&mode, &fb_info->var);
1052 fb_add_videomode(&mode, &fb_info->modelist);
1053 }
1054 1057
1058 fb_var_to_videomode(&mode, &fb_info->var);
1059 fb_add_videomode(&mode, &fb_info->modelist);
1055 registered_fb[i] = fb_info; 1060 registered_fb[i] = fb_info;
1056 1061
1057 devfs_mk_cdev(MKDEV(FB_MAJOR, i), 1062 devfs_mk_cdev(MKDEV(FB_MAJOR, i),
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index c2718bb94949..713226cdf3c6 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -29,6 +29,7 @@
29#include <linux/tty.h> 29#include <linux/tty.h>
30#include <linux/fb.h> 30#include <linux/fb.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <video/edid.h>
32#ifdef CONFIG_PPC_OF 33#ifdef CONFIG_PPC_OF
33#include <linux/pci.h> 34#include <linux/pci.h>
34#include <asm/prom.h> 35#include <asm/prom.h>
@@ -313,11 +314,13 @@ static int edid_is_monitor_block(unsigned char *block)
313 return 0; 314 return 0;
314} 315}
315 316
316static void calc_mode_timings(int xres, int yres, int refresh, struct fb_videomode *mode) 317static void calc_mode_timings(int xres, int yres, int refresh,
318 struct fb_videomode *mode)
317{ 319{
318 struct fb_var_screeninfo var; 320 struct fb_var_screeninfo var;
319 struct fb_info info; 321 struct fb_info info;
320 322
323 memset(&var, 0, sizeof(struct fb_var_screeninfo));
321 var.xres = xres; 324 var.xres = xres;
322 var.yres = yres; 325 var.yres = yres;
323 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 326 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON,
@@ -1251,9 +1254,41 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1251 -EINVAL : 0; 1254 -EINVAL : 0;
1252} 1255}
1253 1256
1257#if defined(__i386__)
1258#include <linux/pci.h>
1259
1260/*
1261 * We need to ensure that the EDID block is only returned for
1262 * the primary graphics adapter.
1263 */
1264
1265const unsigned char *fb_firmware_edid(struct device *device)
1266{
1267 struct pci_dev *dev = NULL;
1268 struct resource *res = NULL;
1269 unsigned char *edid = NULL;
1270
1271 if (device)
1272 dev = to_pci_dev(device);
1273
1274 if (dev)
1275 res = &dev->resource[PCI_ROM_RESOURCE];
1276
1277 if (res && res->flags & IORESOURCE_ROM_SHADOW)
1278 edid = edid_info.dummy;
1279
1280 return edid;
1281}
1282#else
1283const unsigned char *fb_firmware_edid(struct device *device)
1284{
1285 return NULL;
1286}
1287#endif /* _i386_ */
1288
1254EXPORT_SYMBOL(fb_parse_edid); 1289EXPORT_SYMBOL(fb_parse_edid);
1255EXPORT_SYMBOL(fb_edid_to_monspecs); 1290EXPORT_SYMBOL(fb_edid_to_monspecs);
1256 1291EXPORT_SYMBOL(fb_firmware_edid);
1257EXPORT_SYMBOL(fb_get_mode); 1292EXPORT_SYMBOL(fb_get_mode);
1258EXPORT_SYMBOL(fb_validate_mode); 1293EXPORT_SYMBOL(fb_validate_mode);
1259EXPORT_SYMBOL(fb_destroy_modedb); 1294EXPORT_SYMBOL(fb_destroy_modedb);
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index b075fd02de31..5a9b89c3831b 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -3,15 +3,13 @@
3# 3#
4config FB_GEODE 4config FB_GEODE
5 bool "AMD Geode family framebuffer support (EXPERIMENTAL)" 5 bool "AMD Geode family framebuffer support (EXPERIMENTAL)"
6 default n 6 depends on FB && PCI && EXPERIMENTAL && X86
7 depends on FB && EXPERIMENTAL && X86
8 ---help--- 7 ---help---
9 Say 'Y' here to allow you to select framebuffer drivers for 8 Say 'Y' here to allow you to select framebuffer drivers for
10 the AMD Geode family of processors. 9 the AMD Geode family of processors.
11 10
12config FB_GEODE_GX1 11config FB_GEODE_GX1
13 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)" 12 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
14 default n
15 depends on FB_GEODE && EXPERIMENTAL 13 depends on FB_GEODE && EXPERIMENTAL
16 select FB_CFB_FILLRECT 14 select FB_CFB_FILLRECT
17 select FB_CFB_COPYAREA 15 select FB_CFB_COPYAREA
@@ -21,9 +19,7 @@ config FB_GEODE_GX1
21 Framebuffer driver for the display controller integrated into the 19 Framebuffer driver for the display controller integrated into the
22 AMD Geode GX1 processor. 20 AMD Geode GX1 processor.
23 21
24 This driver is also available as a module ( = code which can be 22 To compile this driver as a module, choose M here: the module will be
25 inserted and removed from the running kernel whenever you want). The 23 called gx1fb.
26 module will be called gx1fb. If you want to compile it as a module,
27 say M here and read <file:Documentation/modules.txt>.
28 24
29 If unsure, say N. 25 If unsure, say N.
diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/geode/display_gx1.c
index f4983879fcc4..926d53eeb549 100644
--- a/drivers/video/geode/display_gx1.c
+++ b/drivers/video/geode/display_gx1.c
@@ -22,7 +22,7 @@
22#include "geodefb.h" 22#include "geodefb.h"
23#include "display_gx1.h" 23#include "display_gx1.h"
24 24
25static spinlock_t gx1_conf_reg_lock = SPIN_LOCK_UNLOCKED; 25static DEFINE_SPINLOCK(gx1_conf_reg_lock);
26 26
27static u8 gx1_read_conf_reg(u8 reg) 27static u8 gx1_read_conf_reg(u8 reg)
28{ 28{
diff --git a/drivers/video/geode/geodefb.h b/drivers/video/geode/geodefb.h
index b7bac0a526b3..ae04820e0c57 100644
--- a/drivers/video/geode/geodefb.h
+++ b/drivers/video/geode/geodefb.h
@@ -29,7 +29,6 @@ struct geodefb_par {
29 int enable_crt; 29 int enable_crt;
30 int panel_x; /* dimensions of an attached flat panel, non-zero => enable panel */ 30 int panel_x; /* dimensions of an attached flat panel, non-zero => enable panel */
31 int panel_y; 31 int panel_y;
32 struct pci_dev *vid_dev;
33 void __iomem *dc_regs; 32 void __iomem *dc_regs;
34 void __iomem *vid_regs; 33 void __iomem *vid_regs;
35 struct geode_dc_ops *dc_ops; 34 struct geode_dc_ops *dc_ops;
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 83830d24bcda..74a5fca86b8a 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -30,6 +30,62 @@ static char mode_option[32] = "640x480-16@60";
30static int crt_option = 1; 30static int crt_option = 1;
31static char panel_option[32] = ""; 31static char panel_option[32] = "";
32 32
33/* Modes relevant to the GX1 (taken from modedb.c) */
34static const struct fb_videomode __initdata gx1_modedb[] = {
35 /* 640x480-60 VESA */
36 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
37 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
38 /* 640x480-75 VESA */
39 { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
40 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
41 /* 640x480-85 VESA */
42 { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
43 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
44 /* 800x600-60 VESA */
45 { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
46 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
47 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
48 /* 800x600-75 VESA */
49 { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
50 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
51 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
52 /* 800x600-85 VESA */
53 { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
54 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
55 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
56 /* 1024x768-60 VESA */
57 { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
58 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
59 /* 1024x768-75 VESA */
60 { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
61 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
62 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
63 /* 1024x768-85 VESA */
64 { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
65 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
66 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
67 /* 1280x960-60 VESA */
68 { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
69 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
70 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
71 /* 1280x960-85 VESA */
72 { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
73 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
74 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
75 /* 1280x1024-60 VESA */
76 { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
77 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
78 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
79 /* 1280x1024-75 VESA */
80 { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
81 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
82 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
83 /* 1280x1024-85 VESA */
84 { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
85 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
86 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
87};
88
33static int gx1_line_delta(int xres, int bpp) 89static int gx1_line_delta(int xres, int bpp)
34{ 90{
35 int line_delta = xres * (bpp >> 3); 91 int line_delta = xres * (bpp >> 3);
@@ -47,8 +103,6 @@ static int gx1fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
47{ 103{
48 struct geodefb_par *par = info->par; 104 struct geodefb_par *par = info->par;
49 105
50 printk(KERN_DEBUG "%s()\n", __FUNCTION__);
51
52 /* Maximum resolution is 1280x1024. */ 106 /* Maximum resolution is 1280x1024. */
53 if (var->xres > 1280 || var->yres > 1024) 107 if (var->xres > 1280 || var->yres > 1024)
54 return -EINVAL; 108 return -EINVAL;
@@ -146,40 +200,48 @@ static int gx1fb_blank(int blank_mode, struct fb_info *info)
146 return par->vid_ops->blank_display(info, blank_mode); 200 return par->vid_ops->blank_display(info, blank_mode);
147} 201}
148 202
149static int __init gx1fb_map_video_memory(struct fb_info *info) 203static int __init gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
150{ 204{
151 struct geodefb_par *par = info->par; 205 struct geodefb_par *par = info->par;
152 unsigned gx_base; 206 unsigned gx_base;
153 int fb_len; 207 int fb_len;
208 int ret;
154 209
155 gx_base = gx1_gx_base(); 210 gx_base = gx1_gx_base();
156 if (!gx_base) 211 if (!gx_base)
157 return -ENODEV; 212 return -ENODEV;
158 213
159 par->vid_dev = pci_get_device(PCI_VENDOR_ID_CYRIX, 214 ret = pci_enable_device(dev);
160 PCI_DEVICE_ID_CYRIX_5530_VIDEO, NULL); 215 if (ret < 0)
161 if (!par->vid_dev) 216 return ret;
162 return -ENODEV;
163 217
164 par->vid_regs = ioremap(pci_resource_start(par->vid_dev, 1), 218 ret = pci_request_region(dev, 1, "gx1fb (video)");
165 pci_resource_len(par->vid_dev, 1)); 219 if (ret < 0)
220 return ret;
221 par->vid_regs = ioremap(pci_resource_start(dev, 1),
222 pci_resource_len(dev, 1));
166 if (!par->vid_regs) 223 if (!par->vid_regs)
167 return -ENOMEM; 224 return -ENOMEM;
168 225
226 if (!request_mem_region(gx_base + 0x8300, 0x100, "gx1fb (display controller)"))
227 return -EBUSY;
169 par->dc_regs = ioremap(gx_base + 0x8300, 0x100); 228 par->dc_regs = ioremap(gx_base + 0x8300, 0x100);
170 if (!par->dc_regs) 229 if (!par->dc_regs)
171 return -ENOMEM; 230 return -ENOMEM;
172 231
173 info->fix.smem_start = gx_base + 0x800000; 232 ret = pci_request_region(dev, 0, "gx1fb (frame buffer)");
233 if (ret < 0 )
234 return -EBUSY;
174 if ((fb_len = gx1_frame_buffer_size()) < 0) 235 if ((fb_len = gx1_frame_buffer_size()) < 0)
175 return -ENOMEM; 236 return -ENOMEM;
237 info->fix.smem_start = pci_resource_start(dev, 0);
176 info->fix.smem_len = fb_len; 238 info->fix.smem_len = fb_len;
177 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 239 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
178 if (!info->screen_base) 240 if (!info->screen_base)
179 return -ENOMEM; 241 return -ENOMEM;
180 242
181 printk(KERN_INFO "%s: %d Kibyte of video memory at 0x%lx\n", 243 dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
182 info->fix.id, info->fix.smem_len / 1024, info->fix.smem_start); 244 info->fix.smem_len / 1024, info->fix.smem_start);
183 245
184 return 0; 246 return 0;
185} 247}
@@ -216,13 +278,13 @@ static struct fb_ops gx1fb_ops = {
216 .fb_cursor = soft_cursor, 278 .fb_cursor = soft_cursor,
217}; 279};
218 280
219static struct fb_info * __init gx1fb_init_fbinfo(void) 281static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
220{ 282{
221 struct fb_info *info;
222 struct geodefb_par *par; 283 struct geodefb_par *par;
284 struct fb_info *info;
223 285
224 /* Alloc enough space for the pseudo palette. */ 286 /* Alloc enough space for the pseudo palette. */
225 info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, NULL); 287 info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, dev);
226 if (!info) 288 if (!info)
227 return NULL; 289 return NULL;
228 290
@@ -255,47 +317,37 @@ static struct fb_info * __init gx1fb_init_fbinfo(void)
255 /* CRT and panel options */ 317 /* CRT and panel options */
256 par->enable_crt = crt_option; 318 par->enable_crt = crt_option;
257 if (parse_panel_option(info) < 0) 319 if (parse_panel_option(info) < 0)
258 printk(KERN_WARNING "%s: invalid 'panel' option -- disabling flat panel\n", 320 printk(KERN_WARNING "gx1fb: invalid 'panel' option -- disabling flat panel\n");
259 info->fix.id);
260 if (!par->panel_x) 321 if (!par->panel_x)
261 par->enable_crt = 1; /* fall back to CRT if no panel is specified */ 322 par->enable_crt = 1; /* fall back to CRT if no panel is specified */
262 323
263 return info; 324 return info;
264} 325}
265 326
266 327static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
267static struct fb_info *gx1fb_info;
268
269static int __init gx1fb_init(void)
270{ 328{
329 struct geodefb_par *par;
271 struct fb_info *info; 330 struct fb_info *info;
272 struct geodefb_par *par;
273 int ret; 331 int ret;
274 332
275#ifndef MODULE 333 info = gx1fb_init_fbinfo(&pdev->dev);
276 if (fb_get_options("gx1fb", NULL))
277 return -ENODEV;
278#endif
279
280 info = gx1fb_init_fbinfo();
281 if (!info) 334 if (!info)
282 return -ENOMEM; 335 return -ENOMEM;
283 gx1fb_info = info;
284
285 par = info->par; 336 par = info->par;
286 337
287 /* GX1 display controller and CS5530 video device */ 338 /* GX1 display controller and CS5530 video device */
288 par->dc_ops = &gx1_dc_ops; 339 par->dc_ops = &gx1_dc_ops;
289 par->vid_ops = &cs5530_vid_ops; 340 par->vid_ops = &cs5530_vid_ops;
290 341
291 if ((ret = gx1fb_map_video_memory(info)) < 0) { 342 if ((ret = gx1fb_map_video_memory(info, pdev)) < 0) {
292 printk(KERN_ERR "%s: gx1fb_map_video_memory() failed\n", info->fix.id); 343 dev_err(&pdev->dev, "failed to map frame buffer or controller registers\n");
293 goto err; 344 goto err;
294 } 345 }
295 346
296 ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16); 347 ret = fb_find_mode(&info->var, info, mode_option,
348 gx1_modedb, ARRAY_SIZE(gx1_modedb), NULL, 16);
297 if (ret == 0 || ret == 4) { 349 if (ret == 0 || ret == 4) {
298 printk(KERN_ERR "%s: could not find valid video mode\n", info->fix.id); 350 dev_err(&pdev->dev, "could not find valid video mode\n");
299 ret = -EINVAL; 351 ret = -EINVAL;
300 goto err; 352 goto err;
301 } 353 }
@@ -310,39 +362,83 @@ static int __init gx1fb_init(void)
310 ret = -EINVAL; 362 ret = -EINVAL;
311 goto err; 363 goto err;
312 } 364 }
365 pci_set_drvdata(pdev, info);
313 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); 366 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
314 return 0; 367 return 0;
315 368
316 err: 369 err:
317 if (info->screen_base) 370 if (info->screen_base) {
318 iounmap(info->screen_base); 371 iounmap(info->screen_base);
319 if (par->vid_regs) 372 pci_release_region(pdev, 0);
373 }
374 if (par->vid_regs) {
320 iounmap(par->vid_regs); 375 iounmap(par->vid_regs);
321 if (par->dc_regs) 376 pci_release_region(pdev, 1);
377 }
378 if (par->dc_regs) {
322 iounmap(par->dc_regs); 379 iounmap(par->dc_regs);
323 if (par->vid_dev) 380 release_mem_region(gx1_gx_base() + 0x8300, 0x100);
324 pci_dev_put(par->vid_dev); 381 }
382
383 pci_disable_device(pdev);
384
325 if (info) 385 if (info)
326 framebuffer_release(info); 386 framebuffer_release(info);
327 return ret; 387 return ret;
328} 388}
329 389
330static void __exit gx1fb_cleanup(void) 390static void gx1fb_remove(struct pci_dev *pdev)
331{ 391{
332 struct fb_info *info = gx1fb_info; 392 struct fb_info *info = pci_get_drvdata(pdev);
333 struct geodefb_par *par = gx1fb_info->par; 393 struct geodefb_par *par = info->par;
334 394
335 unregister_framebuffer(info); 395 unregister_framebuffer(info);
336 396
337 iounmap((void __iomem *)info->screen_base); 397 iounmap((void __iomem *)info->screen_base);
398 pci_release_region(pdev, 0);
399
338 iounmap(par->vid_regs); 400 iounmap(par->vid_regs);
401 pci_release_region(pdev, 1);
402
339 iounmap(par->dc_regs); 403 iounmap(par->dc_regs);
404 release_mem_region(gx1_gx_base() + 0x8300, 0x100);
340 405
341 pci_dev_put(par->vid_dev); 406 pci_disable_device(pdev);
407 pci_set_drvdata(pdev, NULL);
342 408
343 framebuffer_release(info); 409 framebuffer_release(info);
344} 410}
345 411
412static struct pci_device_id gx1fb_id_table[] = {
413 { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_VIDEO,
414 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
415 0xff0000, 0 },
416 { 0, }
417};
418
419MODULE_DEVICE_TABLE(pci, gx1fb_id_table);
420
421static struct pci_driver gx1fb_driver = {
422 .name = "gx1fb",
423 .id_table = gx1fb_id_table,
424 .probe = gx1fb_probe,
425 .remove = gx1fb_remove,
426};
427
428static int __init gx1fb_init(void)
429{
430#ifndef MODULE
431 if (fb_get_options("gx1fb", NULL))
432 return -ENODEV;
433#endif
434 return pci_register_driver(&gx1fb_driver);
435}
436
437static void __exit gx1fb_cleanup(void)
438{
439 pci_unregister_driver(&gx1fb_driver);
440}
441
346module_init(gx1fb_init); 442module_init(gx1fb_init);
347module_exit(gx1fb_cleanup); 443module_exit(gx1fb_cleanup);
348 444
diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/geode/video_cs5530.c
index d3764acf8443..649c3943d431 100644
--- a/drivers/video/geode/video_cs5530.c
+++ b/drivers/video/geode/video_cs5530.c
@@ -69,8 +69,6 @@ static const struct cs5530_pll_entry cs5530_pll_table[] = {
69 { 4310, 0x2FB1B802, }, /* 232.0000 */ 69 { 4310, 0x2FB1B802, }, /* 232.0000 */
70}; 70};
71 71
72#define NUM_CS5530_FREQUENCIES sizeof(cs5530_pll_table)/sizeof(struct cs5530_pll_entry)
73
74static void cs5530_set_dclk_frequency(struct fb_info *info) 72static void cs5530_set_dclk_frequency(struct fb_info *info)
75{ 73{
76 struct geodefb_par *par = info->par; 74 struct geodefb_par *par = info->par;
@@ -82,7 +80,7 @@ static void cs5530_set_dclk_frequency(struct fb_info *info)
82 value = cs5530_pll_table[0].pll_value; 80 value = cs5530_pll_table[0].pll_value;
83 min = cs5530_pll_table[0].pixclock - info->var.pixclock; 81 min = cs5530_pll_table[0].pixclock - info->var.pixclock;
84 if (min < 0) min = -min; 82 if (min < 0) min = -min;
85 for (i = 1; i < NUM_CS5530_FREQUENCIES; i++) { 83 for (i = 1; i < ARRAY_SIZE(cs5530_pll_table); i++) {
86 diff = cs5530_pll_table[i].pixclock - info->var.pixclock; 84 diff = cs5530_pll_table[i].pixclock - info->var.pixclock;
87 if (diff < 0L) diff = -diff; 85 if (diff < 0L) diff = -diff;
88 if (diff < min) { 86 if (diff < min) {
diff --git a/drivers/video/i810/Makefile b/drivers/video/i810/Makefile
index 794ae76c7c4b..96e08c8ded97 100644
--- a/drivers/video/i810/Makefile
+++ b/drivers/video/i810/Makefile
@@ -4,7 +4,6 @@
4 4
5obj-$(CONFIG_FB_I810) += i810fb.o 5obj-$(CONFIG_FB_I810) += i810fb.o
6 6
7
8i810fb-objs := i810_main.o i810_accel.o 7i810fb-objs := i810_main.o i810_accel.o
9 8
10ifdef CONFIG_FB_I810_GTF 9ifdef CONFIG_FB_I810_GTF
@@ -12,3 +11,7 @@ i810fb-objs += i810_gtf.o
12else 11else
13i810fb-objs += i810_dvt.o 12i810fb-objs += i810_dvt.o
14endif 13endif
14
15ifdef CONFIG_FB_I810_I2C
16i810fb-objs += i810-i2c.o
17endif
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
new file mode 100644
index 000000000000..fda53aac1fc1
--- /dev/null
+++ b/drivers/video/i810/i810-i2c.c
@@ -0,0 +1,257 @@
1 /*-*- linux-c -*-
2 * linux/drivers/video/i810-i2c.c -- Intel 810/815 I2C support
3 *
4 * Copyright (C) 2004 Antonino Daplas<adaplas@pol.net>
5 * All Rights Reserved
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 */
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/delay.h>
16#include <linux/pci.h>
17#include <linux/fb.h>
18#include "i810.h"
19#include "i810_regs.h"
20#include "../edid.h"
21
22#define I810_DDC 0x50
23/* bit locations in the registers */
24#define SCL_DIR_MASK 0x0001
25#define SCL_DIR 0x0002
26#define SCL_VAL_MASK 0x0004
27#define SCL_VAL_OUT 0x0008
28#define SCL_VAL_IN 0x0010
29#define SDA_DIR_MASK 0x0100
30#define SDA_DIR 0x0200
31#define SDA_VAL_MASK 0x0400
32#define SDA_VAL_OUT 0x0800
33#define SDA_VAL_IN 0x1000
34
35#define DEBUG /* define this for verbose EDID parsing output */
36
37#ifdef DEBUG
38#define DPRINTK(fmt, args...) printk(fmt,## args)
39#else
40#define DPRINTK(fmt, args...)
41#endif
42
43static void i810i2c_setscl(void *data, int state)
44{
45 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
46 struct i810fb_par *par = chan->par;
47 u8 *mmio = par->mmio_start_virtual;
48
49 i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
50 SCL_DIR_MASK | SCL_VAL_MASK);
51 i810_readl(mmio, GPIOB); /* flush posted write */
52}
53
54static void i810i2c_setsda(void *data, int state)
55{
56 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
57 struct i810fb_par *par = chan->par;
58 u8 *mmio = par->mmio_start_virtual;
59
60 i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
61 SDA_DIR_MASK | SDA_VAL_MASK);
62 i810_readl(mmio, GPIOB); /* flush posted write */
63}
64
65static int i810i2c_getscl(void *data)
66{
67 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
68 struct i810fb_par *par = chan->par;
69 u8 *mmio = par->mmio_start_virtual;
70
71 i810_writel(mmio, GPIOB, SCL_DIR_MASK);
72 i810_writel(mmio, GPIOB, 0);
73 return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN));
74}
75
76static int i810i2c_getsda(void *data)
77{
78 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
79 struct i810fb_par *par = chan->par;
80 u8 *mmio = par->mmio_start_virtual;
81
82 i810_writel(mmio, GPIOB, SDA_DIR_MASK);
83 i810_writel(mmio, GPIOB, 0);
84 return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN));
85}
86
87static void i810ddc_setscl(void *data, int state)
88{
89 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
90 struct i810fb_par *par = chan->par;
91 u8 *mmio = par->mmio_start_virtual;
92
93 i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
94 SCL_DIR_MASK | SCL_VAL_MASK);
95 i810_readl(mmio, GPIOA); /* flush posted write */
96}
97
98static void i810ddc_setsda(void *data, int state)
99{
100 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
101 struct i810fb_par *par = chan->par;
102 u8 *mmio = par->mmio_start_virtual;
103
104 i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
105 SDA_DIR_MASK | SDA_VAL_MASK);
106 i810_readl(mmio, GPIOA); /* flush posted write */
107}
108
109static int i810ddc_getscl(void *data)
110{
111 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
112 struct i810fb_par *par = chan->par;
113 u8 *mmio = par->mmio_start_virtual;
114
115 i810_writel(mmio, GPIOA, SCL_DIR_MASK);
116 i810_writel(mmio, GPIOA, 0);
117 return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
118}
119
120static int i810ddc_getsda(void *data)
121{
122 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
123 struct i810fb_par *par = chan->par;
124 u8 *mmio = par->mmio_start_virtual;
125
126 i810_writel(mmio, GPIOA, SDA_DIR_MASK);
127 i810_writel(mmio, GPIOA, 0);
128 return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
129}
130
131#define I2C_ALGO_DDC_I810 0x0e0000
132#define I2C_ALGO_I2C_I810 0x0f0000
133static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
134 int conn)
135{
136 int rc;
137
138 strcpy(chan->adapter.name, name);
139 chan->adapter.owner = THIS_MODULE;
140 chan->adapter.algo_data = &chan->algo;
141 chan->adapter.dev.parent = &chan->par->dev->dev;
142 switch (conn) {
143 case 1:
144 chan->adapter.id = I2C_ALGO_DDC_I810;
145 chan->algo.setsda = i810ddc_setsda;
146 chan->algo.setscl = i810ddc_setscl;
147 chan->algo.getsda = i810ddc_getsda;
148 chan->algo.getscl = i810ddc_getscl;
149 break;
150 case 2:
151 chan->adapter.id = I2C_ALGO_I2C_I810;
152 chan->algo.setsda = i810i2c_setsda;
153 chan->algo.setscl = i810i2c_setscl;
154 chan->algo.getsda = i810i2c_getsda;
155 chan->algo.getscl = i810i2c_getscl;
156 break;
157 }
158 chan->algo.udelay = 10;
159 chan->algo.mdelay = 10;
160 chan->algo.timeout = (HZ/2);
161 chan->algo.data = chan;
162
163 i2c_set_adapdata(&chan->adapter, chan);
164
165 /* Raise SCL and SDA */
166 chan->algo.setsda(chan, 1);
167 chan->algo.setscl(chan, 1);
168 udelay(20);
169
170 rc = i2c_bit_add_bus(&chan->adapter);
171 if (rc == 0)
172 dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
173 else
174 dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
175 "%s.\n", name);
176 return rc;
177}
178
179void i810_create_i2c_busses(struct i810fb_par *par)
180{
181 par->chan[0].par = par;
182 par->chan[1].par = par;
183 i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1);
184 i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2);
185}
186
187void i810_delete_i2c_busses(struct i810fb_par *par)
188{
189 if (par->chan[0].par)
190 i2c_bit_del_bus(&par->chan[0].adapter);
191 par->chan[0].par = NULL;
192 if (par->chan[1].par)
193 i2c_bit_del_bus(&par->chan[1].adapter);
194 par->chan[1].par = NULL;
195}
196
197static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
198{
199 u8 start = 0x0;
200 struct i2c_msg msgs[] = {
201 {
202 .addr = I810_DDC,
203 .len = 1,
204 .buf = &start,
205 }, {
206 .addr = I810_DDC,
207 .flags = I2C_M_RD,
208 .len = EDID_LENGTH,
209 },
210 };
211 u8 *buf;
212
213 buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
214 if (!buf) {
215 DPRINTK("i810-i2c: Failed to allocate memory\n");
216 return NULL;
217 }
218 msgs[1].buf = buf;
219
220 if (i2c_transfer(&chan->adapter, msgs, 2) == 2) {
221 DPRINTK("i810-i2c: I2C Transfer successful\n");
222 return buf;
223 }
224 DPRINTK("i810-i2c: Unable to read EDID block.\n");
225 kfree(buf);
226 return NULL;
227}
228
229int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
230{
231 struct i810fb_par *par = info->par;
232 u8 *edid = NULL;
233 int i;
234
235 DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
236 if (conn < 3) {
237 for (i = 0; i < 3; i++) {
238 /* Do the real work */
239 edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
240 if (edid)
241 break;
242 }
243 } else {
244 DPRINTK("i810-i2c: Getting EDID from BIOS\n");
245 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
246 if (edid)
247 memcpy(edid, fb_firmware_edid(info->device),
248 EDID_LENGTH);
249 }
250
251 if (out_edid)
252 *out_edid = edid;
253
254 return (edid) ? 0 : 1;
255}
256
257
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index fe3b75794756..d48949ceaacc 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -16,6 +16,9 @@
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/agp_backend.h> 17#include <linux/agp_backend.h>
18#include <linux/fb.h> 18#include <linux/fb.h>
19#include <linux/i2c.h>
20#include <linux/i2c-id.h>
21#include <linux/i2c-algo-bit.h>
19#include <video/vga.h> 22#include <video/vga.h>
20 23
21/* Fence */ 24/* Fence */
@@ -201,7 +204,6 @@
201#define HAS_ACCELERATION 2 204#define HAS_ACCELERATION 2
202#define ALWAYS_SYNC 4 205#define ALWAYS_SYNC 4
203#define LOCKUP 8 206#define LOCKUP 8
204#define USE_HWCUR 16
205 207
206struct gtt_data { 208struct gtt_data {
207 struct agp_memory *i810_fb_memory; 209 struct agp_memory *i810_fb_memory;
@@ -241,6 +243,14 @@ struct state_registers {
241 u8 cr39, cr41, cr70, sr01, msr; 243 u8 cr39, cr41, cr70, sr01, msr;
242}; 244};
243 245
246struct i810fb_par;
247
248struct i810fb_i2c_chan {
249 struct i810fb_par *par;
250 struct i2c_adapter adapter;
251 struct i2c_algo_bit_data algo;
252};
253
244struct i810fb_par { 254struct i810fb_par {
245 struct mode_registers regs; 255 struct mode_registers regs;
246 struct state_registers hw_state; 256 struct state_registers hw_state;
@@ -252,10 +262,12 @@ struct i810fb_par {
252 struct heap_data iring; 262 struct heap_data iring;
253 struct heap_data cursor_heap; 263 struct heap_data cursor_heap;
254 struct vgastate state; 264 struct vgastate state;
265 struct i810fb_i2c_chan chan[2];
255 atomic_t use_count; 266 atomic_t use_count;
256 u32 pseudo_palette[17]; 267 u32 pseudo_palette[17];
257 unsigned long mmio_start_phys; 268 unsigned long mmio_start_phys;
258 u8 __iomem *mmio_start_virtual; 269 u8 __iomem *mmio_start_virtual;
270 u8 *edid;
259 u32 pitch; 271 u32 pitch;
260 u32 pixconf; 272 u32 pixconf;
261 u32 watermark; 273 u32 watermark;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 6db183462b92..7018ffffcbc4 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -92,20 +92,21 @@ static struct pci_driver i810fb_driver = {
92 .resume = i810fb_resume, 92 .resume = i810fb_resume,
93}; 93};
94 94
95static int vram __initdata = 4; 95static char *mode_option __devinitdata = NULL;
96static int bpp __initdata = 8; 96static int vram __devinitdata = 4;
97static int mtrr __initdata = 0; 97static int bpp __devinitdata = 8;
98static int accel __initdata = 0; 98static int mtrr __devinitdata = 0;
99static int hsync1 __initdata = 0; 99static int accel __devinitdata = 0;
100static int hsync2 __initdata = 0; 100static int hsync1 __devinitdata = 0;
101static int vsync1 __initdata = 0; 101static int hsync2 __devinitdata = 0;
102static int vsync2 __initdata = 0; 102static int vsync1 __devinitdata = 0;
103static int xres __initdata = 640; 103static int vsync2 __devinitdata = 0;
104static int yres __initdata = 480; 104static int xres __devinitdata = 640;
105static int vyres __initdata = 0; 105static int yres __devinitdata = 480;
106static int sync __initdata = 0; 106static int vyres __devinitdata = 0;
107static int ext_vga __initdata = 0; 107static int sync __devinitdata = 0;
108static int dcolor __initdata = 0; 108static int ext_vga __devinitdata = 0;
109static int dcolor __devinitdata = 0;
109 110
110/*------------------------------------------------------------*/ 111/*------------------------------------------------------------*/
111 112
@@ -310,6 +311,8 @@ static void i810_hires(u8 __iomem *mmio)
310 val = i810_readb(CR_DATA_CGA, mmio); 311 val = i810_readb(CR_DATA_CGA, mmio);
311 i810_writeb(CR_INDEX_CGA, mmio, CR80); 312 i810_writeb(CR_INDEX_CGA, mmio, CR80);
312 i810_writeb(CR_DATA_CGA, mmio, val | 1); 313 i810_writeb(CR_DATA_CGA, mmio, val | 1);
314 /* Stop LCD displays from flickering */
315 i810_writel(MEM_MODE, mmio, i810_readl(MEM_MODE, mmio) | 4);
313} 316}
314 317
315/** 318/**
@@ -947,31 +950,24 @@ static int i810_check_params(struct fb_var_screeninfo *var,
947 struct fb_info *info) 950 struct fb_info *info)
948{ 951{
949 struct i810fb_par *par = (struct i810fb_par *) info->par; 952 struct i810fb_par *par = (struct i810fb_par *) info->par;
950 int line_length, vidmem; 953 int line_length, vidmem, mode_valid = 0;
951 u32 xres, yres, vxres, vyres; 954 u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
952
953 xres = var->xres;
954 yres = var->yres;
955 vxres = var->xres_virtual;
956 vyres = var->yres_virtual;
957
958 /* 955 /*
959 * Memory limit 956 * Memory limit
960 */ 957 */
961 line_length = get_line_length(par, vxres, 958 line_length = get_line_length(par, vxres, var->bits_per_pixel);
962 var->bits_per_pixel);
963
964 vidmem = line_length*vyres; 959 vidmem = line_length*vyres;
960
965 if (vidmem > par->fb.size) { 961 if (vidmem > par->fb.size) {
966 vyres = par->fb.size/line_length; 962 vyres = par->fb.size/line_length;
967 if (vyres < yres) { 963 if (vyres < var->yres) {
968 vyres = yres; 964 vyres = yres;
969 vxres = par->fb.size/vyres; 965 vxres = par->fb.size/vyres;
970 vxres /= var->bits_per_pixel >> 3; 966 vxres /= var->bits_per_pixel >> 3;
971 line_length = get_line_length(par, vxres, 967 line_length = get_line_length(par, vxres,
972 var->bits_per_pixel); 968 var->bits_per_pixel);
973 vidmem = line_length * yres; 969 vidmem = line_length * yres;
974 if (vxres < xres) { 970 if (vxres < var->xres) {
975 printk("i810fb: required video memory, " 971 printk("i810fb: required video memory, "
976 "%d bytes, for %dx%d-%d (virtual) " 972 "%d bytes, for %dx%d-%d (virtual) "
977 "is out of range\n", 973 "is out of range\n",
@@ -981,6 +977,10 @@ static int i810_check_params(struct fb_var_screeninfo *var,
981 } 977 }
982 } 978 }
983 } 979 }
980
981 var->xres_virtual = vxres;
982 var->yres_virtual = vyres;
983
984 /* 984 /*
985 * Monitor limit 985 * Monitor limit
986 */ 986 */
@@ -996,25 +996,39 @@ static int i810_check_params(struct fb_var_screeninfo *var,
996 info->monspecs.dclkmax = 204000000; 996 info->monspecs.dclkmax = 204000000;
997 break; 997 break;
998 } 998 }
999
999 info->monspecs.dclkmin = 15000000; 1000 info->monspecs.dclkmin = 15000000;
1000 1001
1001 if (fb_validate_mode(var, info)) { 1002 if (!fb_validate_mode(var, info))
1003 mode_valid = 1;
1004
1005#ifdef CONFIG_FB_I810_I2C
1006 if (!mode_valid && info->monspecs.gtf &&
1007 !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1008 mode_valid = 1;
1009
1010 if (!mode_valid && info->monspecs.modedb_len) {
1011 struct fb_videomode *mode;
1012
1013 mode = fb_find_best_mode(var, &info->modelist);
1014 if (mode) {
1015 fb_videomode_to_var(var, mode);
1016 mode_valid = 1;
1017 }
1018 }
1019#endif
1020 if (!mode_valid && info->monspecs.modedb_len == 0) {
1002 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) { 1021 if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
1003 int default_sync = (info->monspecs.hfmin-HFMIN) 1022 int default_sync = (info->monspecs.hfmin-HFMIN)
1004 |(info->monspecs.hfmax-HFMAX) 1023 |(info->monspecs.hfmax-HFMAX)
1005 |(info->monspecs.vfmin-VFMIN) 1024 |(info->monspecs.vfmin-VFMIN)
1006 |(info->monspecs.vfmax-VFMAX); 1025 |(info->monspecs.vfmax-VFMAX);
1007 printk("i810fb: invalid video mode%s\n", 1026 printk("i810fb: invalid video mode%s\n",
1008 default_sync ? "" : 1027 default_sync ? "" : ". Specifying "
1009 ". Specifying vsyncN/hsyncN parameters may help"); 1028 "vsyncN/hsyncN parameters may help");
1010 return -EINVAL;
1011 } 1029 }
1012 } 1030 }
1013 1031
1014 var->xres = xres;
1015 var->yres = yres;
1016 var->xres_virtual = vxres;
1017 var->yres_virtual = vyres;
1018 return 0; 1032 return 0;
1019} 1033}
1020 1034
@@ -1375,7 +1389,6 @@ static int i810fb_set_par(struct fb_info *info)
1375 decode_var(&info->var, par); 1389 decode_var(&info->var, par);
1376 i810_load_regs(par); 1390 i810_load_regs(par);
1377 i810_init_cursor(par); 1391 i810_init_cursor(par);
1378
1379 encode_fix(&info->fix, info); 1392 encode_fix(&info->fix, info);
1380 1393
1381 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) { 1394 if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {
@@ -1418,9 +1431,8 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1418 struct i810fb_par *par = (struct i810fb_par *)info->par; 1431 struct i810fb_par *par = (struct i810fb_par *)info->par;
1419 u8 __iomem *mmio = par->mmio_start_virtual; 1432 u8 __iomem *mmio = par->mmio_start_virtual;
1420 1433
1421 if (!(par->dev_flags & USE_HWCUR) || !info->var.accel_flags || 1434 if (!par->dev_flags & LOCKUP)
1422 par->dev_flags & LOCKUP) 1435 return -ENXIO;
1423 return soft_cursor(info, cursor);
1424 1436
1425 if (cursor->image.width > 64 || cursor->image.height > 64) 1437 if (cursor->image.width > 64 || cursor->image.height > 64)
1426 return -ENXIO; 1438 return -ENXIO;
@@ -1814,8 +1826,72 @@ i810_allocate_pci_resource(struct i810fb_par *par,
1814 return 0; 1826 return 0;
1815} 1827}
1816 1828
1829static void __devinit i810fb_find_init_mode(struct fb_info *info)
1830{
1831 struct fb_videomode mode;
1832 struct fb_var_screeninfo var;
1833 struct fb_monspecs *specs = NULL;
1834 int found = 0;
1835#ifdef CONFIG_FB_I810_I2C
1836 int i;
1837 int err;
1838 struct i810fb_par *par = info->par;
1839#endif
1840
1841 INIT_LIST_HEAD(&info->modelist);
1842 memset(&mode, 0, sizeof(struct fb_videomode));
1843 var = info->var;
1844#ifdef CONFIG_FB_I810_I2C
1845 i810_create_i2c_busses(par);
1846
1847 for (i = 0; i < 3; i++) {
1848 err = i810_probe_i2c_connector(info, &par->edid, i+1);
1849 if (!err)
1850 break;
1851 }
1852
1853 if (!err)
1854 printk("i810fb_init_pci: DDC probe successful\n");
1855
1856 fb_edid_to_monspecs(par->edid, &info->monspecs);
1857
1858 if (info->monspecs.modedb == NULL)
1859 printk("i810fb_init_pci: Unable to get Mode Database\n");
1860
1861 specs = &info->monspecs;
1862 fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1863 &info->modelist);
1864 if (specs->modedb != NULL) {
1865 if (specs->misc & FB_MISC_1ST_DETAIL) {
1866 for (i = 0; i < specs->modedb_len; i++) {
1867 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1868 mode = specs->modedb[i];
1869 found = 1;
1870 break;
1871 }
1872 }
1873 }
1874
1875 if (!found) {
1876 mode = specs->modedb[0];
1877 found = 1;
1878 }
1879
1880 fb_videomode_to_var(&var, &mode);
1881 }
1882#endif
1883 if (mode_option)
1884 fb_find_mode(&var, info, mode_option, specs->modedb,
1885 specs->modedb_len, (found) ? &mode : NULL,
1886 info->var.bits_per_pixel);
1887
1888 info->var = var;
1889 fb_destroy_modedb(specs->modedb);
1890 specs->modedb = NULL;
1891}
1892
1817#ifndef MODULE 1893#ifndef MODULE
1818static int __init i810fb_setup(char *options) 1894static int __devinit i810fb_setup(char *options)
1819{ 1895{
1820 char *this_opt, *suffix = NULL; 1896 char *this_opt, *suffix = NULL;
1821 1897
@@ -1857,6 +1933,8 @@ static int __init i810fb_setup(char *options)
1857 vsync2 = simple_strtoul(this_opt+7, NULL, 0); 1933 vsync2 = simple_strtoul(this_opt+7, NULL, 0);
1858 else if (!strncmp(this_opt, "dcolor", 6)) 1934 else if (!strncmp(this_opt, "dcolor", 6))
1859 dcolor = 1; 1935 dcolor = 1;
1936 else
1937 mode_option = this_opt;
1860 } 1938 }
1861 return 0; 1939 return 0;
1862} 1940}
@@ -1867,6 +1945,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1867{ 1945{
1868 struct fb_info *info; 1946 struct fb_info *info;
1869 struct i810fb_par *par = NULL; 1947 struct i810fb_par *par = NULL;
1948 struct fb_videomode mode;
1870 int i, err = -1, vfreq, hfreq, pixclock; 1949 int i, err = -1, vfreq, hfreq, pixclock;
1871 1950
1872 i = 0; 1951 i = 0;
@@ -1875,7 +1954,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1875 if (!info) 1954 if (!info)
1876 return -ENOMEM; 1955 return -ENOMEM;
1877 1956
1878 par = (struct i810fb_par *) info->par; 1957 par = info->par;
1879 par->dev = dev; 1958 par->dev = dev;
1880 1959
1881 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) { 1960 if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
@@ -1906,15 +1985,20 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
1906 info->fbops = &par->i810fb_ops; 1985 info->fbops = &par->i810fb_ops;
1907 info->pseudo_palette = par->pseudo_palette; 1986 info->pseudo_palette = par->pseudo_palette;
1908 fb_alloc_cmap(&info->cmap, 256, 0); 1987 fb_alloc_cmap(&info->cmap, 256, 0);
1988 i810fb_find_init_mode(info);
1909 1989
1910 if ((err = info->fbops->fb_check_var(&info->var, info))) { 1990 if ((err = info->fbops->fb_check_var(&info->var, info))) {
1911 i810fb_release_resource(info, par); 1991 i810fb_release_resource(info, par);
1912 return err; 1992 return err;
1913 } 1993 }
1994
1995 fb_var_to_videomode(&mode, &info->var);
1996 fb_add_videomode(&mode, &info->modelist);
1914 encode_fix(&info->fix, info); 1997 encode_fix(&info->fix, info);
1915 1998
1916 i810fb_init_ringbuffer(info); 1999 i810fb_init_ringbuffer(info);
1917 err = register_framebuffer(info); 2000 err = register_framebuffer(info);
2001
1918 if (err < 0) { 2002 if (err < 0) {
1919 i810fb_release_resource(info, par); 2003 i810fb_release_resource(info, par);
1920 printk("i810fb_init: cannot register framebuffer device\n"); 2004 printk("i810fb_init: cannot register framebuffer device\n");
@@ -1953,6 +2037,8 @@ static void i810fb_release_resource(struct fb_info *info,
1953 struct gtt_data *gtt = &par->i810_gtt; 2037 struct gtt_data *gtt = &par->i810_gtt;
1954 unset_mtrr(par); 2038 unset_mtrr(par);
1955 2039
2040 i810_delete_i2c_busses(par);
2041
1956 if (par->i810_gtt.i810_cursor_memory) 2042 if (par->i810_gtt.i810_cursor_memory)
1957 agp_free_memory(gtt->i810_cursor_memory); 2043 agp_free_memory(gtt->i810_cursor_memory);
1958 if (par->i810_gtt.i810_fb_memory) 2044 if (par->i810_gtt.i810_fb_memory)
@@ -1962,7 +2048,8 @@ static void i810fb_release_resource(struct fb_info *info,
1962 iounmap(par->mmio_start_virtual); 2048 iounmap(par->mmio_start_virtual);
1963 if (par->aperture.virtual) 2049 if (par->aperture.virtual)
1964 iounmap(par->aperture.virtual); 2050 iounmap(par->aperture.virtual);
1965 2051 if (par->edid)
2052 kfree(par->edid);
1966 if (par->res_flags & FRAMEBUFFER_REQ) 2053 if (par->res_flags & FRAMEBUFFER_REQ)
1967 release_mem_region(par->aperture.physical, 2054 release_mem_region(par->aperture.physical,
1968 par->aperture.size); 2055 par->aperture.size);
@@ -1988,7 +2075,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
1988} 2075}
1989 2076
1990#ifndef MODULE 2077#ifndef MODULE
1991static int __init i810fb_init(void) 2078static int __devinit i810fb_init(void)
1992{ 2079{
1993 char *option = NULL; 2080 char *option = NULL;
1994 2081
@@ -2006,7 +2093,7 @@ static int __init i810fb_init(void)
2006 2093
2007#ifdef MODULE 2094#ifdef MODULE
2008 2095
2009static int __init i810fb_init(void) 2096static int __devinit i810fb_init(void)
2010{ 2097{
2011 hsync1 *= 1000; 2098 hsync1 *= 1000;
2012 hsync2 *= 1000; 2099 hsync2 *= 1000;
@@ -2054,6 +2141,8 @@ MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
2054module_param(dcolor, bool, 0); 2141module_param(dcolor, bool, 0);
2055MODULE_PARM_DESC(dcolor, "use DirectColor visuals" 2142MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
2056 " (default = 0 = TrueColor)"); 2143 " (default = 0 = TrueColor)");
2144module_param(mode_option, charp, 0);
2145MODULE_PARM_DESC(mode_option, "Specify initial video mode");
2057 2146
2058MODULE_AUTHOR("Tony A. Daplas"); 2147MODULE_AUTHOR("Tony A. Daplas");
2059MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and" 2148MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"
diff --git a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h
index 43b4297b4d48..06072a6466f2 100644
--- a/drivers/video/i810/i810_main.h
+++ b/drivers/video/i810/i810_main.h
@@ -83,6 +83,22 @@ extern int i810fb_sync (struct fb_info *p);
83extern void i810fb_init_ringbuffer(struct fb_info *info); 83extern void i810fb_init_ringbuffer(struct fb_info *info);
84extern void i810fb_load_front (u32 offset, struct fb_info *info); 84extern void i810fb_load_front (u32 offset, struct fb_info *info);
85 85
86#ifdef CONFIG_FB_I810_I2C
87/* I2C */
88extern int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid,
89 int conn);
90extern void i810_create_i2c_busses(struct i810fb_par *par);
91extern void i810_delete_i2c_busses(struct i810fb_par *par);
92#else
93static inline int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid,
94 int conn)
95{
96 return 1;
97}
98static inline void i810_create_i2c_busses(struct i810fb_par *par) { }
99static inline void i810_delete_i2c_busses(struct i810fb_par *par) { }
100#endif
101
86/* Conditionals */ 102/* Conditionals */
87#ifdef CONFIG_X86 103#ifdef CONFIG_X86
88inline void flush_cache(void) 104inline void flush_cache(void)
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6680ec9ba69e..011e11626558 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -234,7 +234,6 @@ struct intelfb_info {
234 234
235 /* palette */ 235 /* palette */
236 u32 pseudo_palette[17]; 236 u32 pseudo_palette[17];
237 struct { u8 red, green, blue, pad; } palette[256];
238 237
239 /* chip info */ 238 /* chip info */
240 int pci_chipset; 239 int pci_chipset;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index a112a1786855..bf62e6ed0382 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -117,14 +117,10 @@
117#include <linux/slab.h> 117#include <linux/slab.h>
118#include <linux/delay.h> 118#include <linux/delay.h>
119#include <linux/fb.h> 119#include <linux/fb.h>
120#include <linux/console.h>
121#include <linux/selection.h>
122#include <linux/ioport.h> 120#include <linux/ioport.h>
123#include <linux/init.h> 121#include <linux/init.h>
124#include <linux/pci.h> 122#include <linux/pci.h>
125#include <linux/vmalloc.h> 123#include <linux/vmalloc.h>
126#include <linux/kd.h>
127#include <linux/vt_kern.h>
128#include <linux/pagemap.h> 124#include <linux/pagemap.h>
129#include <linux/version.h> 125#include <linux/version.h>
130 126
@@ -242,7 +238,7 @@ static int voffset = 48;
242static char *mode = NULL; 238static char *mode = NULL;
243 239
244module_param(accel, bool, S_IRUGO); 240module_param(accel, bool, S_IRUGO);
245MODULE_PARM_DESC(accel, "Enable console acceleration"); 241MODULE_PARM_DESC(accel, "Enable hardware acceleration");
246module_param(vram, int, S_IRUGO); 242module_param(vram, int, S_IRUGO);
247MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"); 243MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB");
248module_param(voffset, int, S_IRUGO); 244module_param(voffset, int, S_IRUGO);
@@ -498,7 +494,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
498{ 494{
499 struct fb_info *info; 495 struct fb_info *info;
500 struct intelfb_info *dinfo; 496 struct intelfb_info *dinfo;
501 int i, j, err, dvo; 497 int i, err, dvo;
502 int aperture_size, stolen_size; 498 int aperture_size, stolen_size;
503 struct agp_kern_info gtt_info; 499 struct agp_kern_info gtt_info;
504 int agp_memtype; 500 int agp_memtype;
@@ -845,13 +841,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
845 if (bailearly == 5) 841 if (bailearly == 5)
846 bailout(dinfo); 842 bailout(dinfo);
847 843
848 for (i = 0; i < 16; i++) {
849 j = color_table[i];
850 dinfo->palette[i].red = default_red[j];
851 dinfo->palette[i].green = default_grn[j];
852 dinfo->palette[i].blue = default_blu[j];
853 }
854
855 if (bailearly == 6) 844 if (bailearly == 6)
856 bailout(dinfo); 845 bailout(dinfo);
857 846
@@ -1363,10 +1352,6 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1363 green >>= 8; 1352 green >>= 8;
1364 blue >>= 8; 1353 blue >>= 8;
1365 1354
1366 dinfo->palette[regno].red = red;
1367 dinfo->palette[regno].green = green;
1368 dinfo->palette[regno].blue = blue;
1369
1370 intelfbhw_setcolreg(dinfo, regno, red, green, blue, 1355 intelfbhw_setcolreg(dinfo, regno, red, green, blue,
1371 transp); 1356 transp);
1372 } 1357 }
@@ -1499,7 +1484,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1499#endif 1484#endif
1500 1485
1501 if (!dinfo->hwcursor) 1486 if (!dinfo->hwcursor)
1502 return soft_cursor(info, cursor); 1487 return -ENXIO;
1503 1488
1504 intelfbhw_cursor_hide(dinfo); 1489 intelfbhw_cursor_hide(dinfo);
1505 1490
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index f5bed581dc45..5bafc3c54db7 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -29,14 +29,10 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/fb.h> 31#include <linux/fb.h>
32#include <linux/console.h>
33#include <linux/selection.h>
34#include <linux/ioport.h> 32#include <linux/ioport.h>
35#include <linux/init.h> 33#include <linux/init.h>
36#include <linux/pci.h> 34#include <linux/pci.h>
37#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
38#include <linux/kd.h>
39#include <linux/vt_kern.h>
40#include <linux/pagemap.h> 36#include <linux/pagemap.h>
41#include <linux/version.h> 37#include <linux/version.h>
42 38
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index a18dd024fc86..d9d3e9f6c08e 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -68,6 +68,9 @@
68 * "David C. Hansen" <haveblue@us.ibm.com> 68 * "David C. Hansen" <haveblue@us.ibm.com>
69 * Fixes 69 * Fixes
70 * 70 *
71 * "Ian Romanick" <idr@us.ibm.com>
72 * Find PInS data in BIOS on PowerPC systems.
73 *
71 * (following author is not in any relation with this code, but his code 74 * (following author is not in any relation with this code, but his code
72 * is included in this driver) 75 * is included in this driver)
73 * 76 *
@@ -496,10 +499,35 @@ static void parse_bios(unsigned char __iomem* vbios, struct matrox_bios* bd) {
496 get_bios_version(vbios, bd); 499 get_bios_version(vbios, bd);
497 get_bios_output(vbios, bd); 500 get_bios_output(vbios, bd);
498 get_bios_tvout(vbios, bd); 501 get_bios_tvout(vbios, bd);
502#if defined(__powerpc__)
503 /* On PowerPC cards, the PInS offset isn't stored at the end of the
504 * BIOS image. Instead, you must search the entire BIOS image for
505 * the magic PInS signature.
506 *
507 * This actually applies to all OpenFirmware base cards. Since these
508 * cards could be put in a MIPS or SPARC system, should the condition
509 * be something different?
510 */
511 for ( pins_offset = 0 ; pins_offset <= 0xFF80 ; pins_offset++ ) {
512 unsigned char header[3];
513
514 header[0] = readb(vbios + pins_offset);
515 header[1] = readb(vbios + pins_offset + 1);
516 header[2] = readb(vbios + pins_offset + 2);
517 if ( (header[0] == 0x2E) && (header[1] == 0x41)
518 && ((header[2] == 0x40) || (header[2] == 0x80)) ) {
519 printk(KERN_INFO "PInS data found at offset %u\n",
520 pins_offset);
521 get_pins(vbios + pins_offset, bd);
522 break;
523 }
524 }
525#else
499 pins_offset = readb(vbios + 0x7FFC) | (readb(vbios + 0x7FFD) << 8); 526 pins_offset = readb(vbios + 0x7FFC) | (readb(vbios + 0x7FFD) << 8);
500 if (pins_offset <= 0xFF80) { 527 if (pins_offset <= 0xFF80) {
501 get_pins(vbios + pins_offset, bd); 528 get_pins(vbios + pins_offset, bd);
502 } 529 }
530#endif
503} 531}
504 532
505#define get_u16(x) (le16_to_cpu(get_unaligned((__u16*)(x)))) 533#define get_u16(x) (le16_to_cpu(get_unaligned((__u16*)(x))))
@@ -755,6 +783,8 @@ void matroxfb_read_pins(WPMINFO2) {
755 } 783 }
756#endif 784#endif
757 matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios)); 785 matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios));
786 printk(KERN_INFO "PInS memtype = %u\n",
787 (ACCESS_FBINFO(values).reg.opt & 0x1C00) >> 10);
758} 788}
759 789
760EXPORT_SYMBOL(matroxfb_DAC_in); 790EXPORT_SYMBOL(matroxfb_DAC_in);
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3edc9f49344b..47516c44a390 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -456,12 +456,22 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
456 * 456 *
457 * Valid mode specifiers for @mode_option: 457 * Valid mode specifiers for @mode_option:
458 * 458 *
459 * <xres>x<yres>[-<bpp>][@<refresh>] or 459 * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
460 * <name>[-<bpp>][@<refresh>] 460 * <name>[-<bpp>][@<refresh>]
461 * 461 *
462 * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and 462 * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
463 * <name> a string. 463 * <name> a string.
464 * 464 *
465 * If 'M' is present after yres (and before refresh/bpp if present),
466 * the function will compute the timings using VESA(tm) Coordinated
467 * Video Timings (CVT). If 'R' is present after 'M', will compute with
468 * reduced blanking (for flatpanels). If 'i' is present, compute
469 * interlaced mode. If 'm' is present, add margins equal to 1.8%
470 * of xres rounded down to 8 pixels, and 1.8% of yres. The char
471 * 'i' and 'm' must be after 'M' and 'R'. Example:
472 *
473 * 1024x768MR-8@60m - Reduced blank with margins at 60Hz.
474 *
465 * NOTE: The passed struct @var is _not_ cleared! This allows you 475 * NOTE: The passed struct @var is _not_ cleared! This allows you
466 * to supply values for e.g. the grayscale and accel_flags fields. 476 * to supply values for e.g. the grayscale and accel_flags fields.
467 * 477 *
@@ -495,7 +505,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
495 unsigned int namelen = strlen(name); 505 unsigned int namelen = strlen(name);
496 int res_specified = 0, bpp_specified = 0, refresh_specified = 0; 506 int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
497 unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0; 507 unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
498 int yres_specified = 0; 508 int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
499 u32 best, diff; 509 u32 best, diff;
500 510
501 for (i = namelen-1; i >= 0; i--) { 511 for (i = namelen-1; i >= 0; i--) {
@@ -506,6 +516,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
506 !yres_specified) { 516 !yres_specified) {
507 refresh = my_atoi(&name[i+1]); 517 refresh = my_atoi(&name[i+1]);
508 refresh_specified = 1; 518 refresh_specified = 1;
519 if (cvt || rb)
520 cvt = 0;
509 } else 521 } else
510 goto done; 522 goto done;
511 break; 523 break;
@@ -514,6 +526,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
514 if (!bpp_specified && !yres_specified) { 526 if (!bpp_specified && !yres_specified) {
515 bpp = my_atoi(&name[i+1]); 527 bpp = my_atoi(&name[i+1]);
516 bpp_specified = 1; 528 bpp_specified = 1;
529 if (cvt || rb)
530 cvt = 0;
517 } else 531 } else
518 goto done; 532 goto done;
519 break; 533 break;
@@ -526,6 +540,22 @@ int fb_find_mode(struct fb_var_screeninfo *var,
526 break; 540 break;
527 case '0'...'9': 541 case '0'...'9':
528 break; 542 break;
543 case 'M':
544 if (!yres_specified)
545 cvt = 1;
546 break;
547 case 'R':
548 if (!cvt)
549 rb = 1;
550 break;
551 case 'm':
552 if (!cvt)
553 margins = 1;
554 break;
555 case 'i':
556 if (!cvt)
557 interlace = 1;
558 break;
529 default: 559 default:
530 goto done; 560 goto done;
531 } 561 }
@@ -535,6 +565,34 @@ int fb_find_mode(struct fb_var_screeninfo *var,
535 res_specified = 1; 565 res_specified = 1;
536 } 566 }
537done: 567done:
568 if (cvt) {
569 struct fb_videomode cvt_mode;
570 int ret;
571
572 DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
573 (refresh) ? refresh : 60, (rb) ? " reduced blanking" :
574 "", (margins) ? " with margins" : "", (interlace) ?
575 " interlaced" : "");
576
577 cvt_mode.xres = xres;
578 cvt_mode.yres = yres;
579 cvt_mode.refresh = (refresh) ? refresh : 60;
580
581 if (interlace)
582 cvt_mode.vmode |= FB_VMODE_INTERLACED;
583 else
584 cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
585
586 ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
587
588 if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
589 DPRINTK("modedb CVT: CVT mode ok\n");
590 return 1;
591 }
592
593 DPRINTK("CVT mode invalid, getting mode from database\n");
594 }
595
538 DPRINTK("Trying specified video mode%s %ix%i\n", 596 DPRINTK("Trying specified video mode%s %ix%i\n",
539 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); 597 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
540 598
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 1a91bffdda26..ace484fa61ce 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -194,8 +194,9 @@ static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
194 return NULL; 194 return NULL;
195} 195}
196 196
197int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid) 197int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
198{ 198{
199 struct nvidia_par *par = info->par;
199 u8 *edid = NULL; 200 u8 *edid = NULL;
200 int i; 201 int i;
201 202
@@ -205,10 +206,17 @@ int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
205 if (edid) 206 if (edid)
206 break; 207 break;
207 } 208 }
209
210 if (!edid && conn == 1) {
211 /* try to get from firmware */
212 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
213 if (edid)
214 memcpy(edid, fb_firmware_edid(info->device),
215 EDID_LENGTH);
216 }
217
208 if (out_edid) 218 if (out_edid)
209 *out_edid = edid; 219 *out_edid = edid;
210 if (!edid)
211 return 1;
212 220
213 return 0; 221 return (edid) ? 0 : 1;
214} 222}
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index 9da320986f4c..afee284fc73c 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -95,6 +95,7 @@
95 95
96#define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2) 96#define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2)
97 97
98#ifdef __LITTLE_ENDIAN
98#define reverse_order(l) \ 99#define reverse_order(l) \
99do { \ 100do { \
100 u8 *a = (u8 *)(l); \ 101 u8 *a = (u8 *)(l); \
@@ -103,5 +104,8 @@ do { \
103 *a = byte_rev[*a], a++; \ 104 *a = byte_rev[*a], a++; \
104 *a = byte_rev[*a]; \ 105 *a = byte_rev[*a]; \
105} while(0) 106} while(0)
107#else
108#define reverse_order(l)
109#endif /* __LITTLE_ENDIAN */
106 110
107#endif /* __NV_LOCAL_H__ */ 111#endif /* __NV_LOCAL_H__ */
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 42847ce1b8dd..cac44fc7f587 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -34,7 +34,7 @@ void NVLockUnlock(struct nvidia_par *par, int);
34#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF) 34#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
35void nvidia_create_i2c_busses(struct nvidia_par *par); 35void nvidia_create_i2c_busses(struct nvidia_par *par);
36void nvidia_delete_i2c_busses(struct nvidia_par *par); 36void nvidia_delete_i2c_busses(struct nvidia_par *par);
37int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, 37int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
38 u8 ** out_edid); 38 u8 ** out_edid);
39#else 39#else
40#define nvidia_create_i2c_busses(...) 40#define nvidia_create_i2c_busses(...)
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 0bbdca2e0f91..11c84178f420 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -401,7 +401,7 @@ void NVCommonSetup(struct fb_info *info)
401 nvidia_create_i2c_busses(par); 401 nvidia_create_i2c_busses(par);
402 if (!par->twoHeads) { 402 if (!par->twoHeads) {
403 par->CRTCnumber = 0; 403 par->CRTCnumber = 0;
404 nvidia_probe_i2c_connector(par, 1, &edidA); 404 nvidia_probe_i2c_connector(info, 1, &edidA);
405 if (edidA && !fb_parse_edid(edidA, &var)) { 405 if (edidA && !fb_parse_edid(edidA, &var)) {
406 printk("nvidiafb: EDID found from BUS1\n"); 406 printk("nvidiafb: EDID found from BUS1\n");
407 monA = &monitorA; 407 monA = &monitorA;
@@ -488,14 +488,14 @@ void NVCommonSetup(struct fb_info *info)
488 oldhead = NV_RD32(par->PCRTC0, 0x00000860); 488 oldhead = NV_RD32(par->PCRTC0, 0x00000860);
489 NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010); 489 NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
490 490
491 nvidia_probe_i2c_connector(par, 1, &edidA); 491 nvidia_probe_i2c_connector(info, 1, &edidA);
492 if (edidA && !fb_parse_edid(edidA, &var)) { 492 if (edidA && !fb_parse_edid(edidA, &var)) {
493 printk("nvidiafb: EDID found from BUS1\n"); 493 printk("nvidiafb: EDID found from BUS1\n");
494 monA = &monitorA; 494 monA = &monitorA;
495 fb_edid_to_monspecs(edidA, monA); 495 fb_edid_to_monspecs(edidA, monA);
496 } 496 }
497 497
498 nvidia_probe_i2c_connector(par, 2, &edidB); 498 nvidia_probe_i2c_connector(info, 2, &edidB);
499 if (edidB && !fb_parse_edid(edidB, &var)) { 499 if (edidB && !fb_parse_edid(edidB, &var)) {
500 printk("nvidiafb: EDID found from BUS2\n"); 500 printk("nvidiafb: EDID found from BUS2\n");
501 monB = &monitorB; 501 monB = &monitorB;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 52b16850a54e..3620de0f252e 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -658,7 +658,7 @@ static int nvidia_calc_regs(struct fb_info *info)
658{ 658{
659 struct nvidia_par *par = info->par; 659 struct nvidia_par *par = info->par;
660 struct _riva_hw_state *state = &par->ModeReg; 660 struct _riva_hw_state *state = &par->ModeReg;
661 int i, depth = fb_get_color_depth(&info->var); 661 int i, depth = fb_get_color_depth(&info->var, &info->fix);
662 int h_display = info->var.xres / 8 - 1; 662 int h_display = info->var.xres / 8 - 1;
663 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1; 663 int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
664 int h_end = (info->var.xres + info->var.right_margin + 664 int h_end = (info->var.xres + info->var.right_margin +
@@ -893,7 +893,7 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
893 int i, set = cursor->set; 893 int i, set = cursor->set;
894 u16 fg, bg; 894 u16 fg, bg;
895 895
896 if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS) 896 if (!hwcur || cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
897 return -ENXIO; 897 return -ENXIO;
898 898
899 NVShowHideCursor(par, 0); 899 NVShowHideCursor(par, 0);
@@ -978,6 +978,9 @@ static int nvidiafb_set_par(struct fb_info *info)
978 !par->twoHeads) 978 !par->twoHeads)
979 par->FPDither = 0; 979 par->FPDither = 0;
980 980
981 info->fix.visual = (info->var.bits_per_pixel == 8) ?
982 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
983
981 nvidia_init_vga(info); 984 nvidia_init_vga(info);
982 nvidia_calc_regs(info); 985 nvidia_calc_regs(info);
983 nvidia_write_regs(par); 986 nvidia_write_regs(par);
@@ -992,9 +995,6 @@ static int nvidiafb_set_par(struct fb_info *info)
992 NVWriteCrtc(par, 0x11, 0x00); 995 NVWriteCrtc(par, 0x11, 0x00);
993 info->fix.line_length = (info->var.xres_virtual * 996 info->fix.line_length = (info->var.xres_virtual *
994 info->var.bits_per_pixel) >> 3; 997 info->var.bits_per_pixel) >> 3;
995 info->fix.visual = (info->var.bits_per_pixel == 8) ?
996 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
997
998 if (info->var.accel_flags) { 998 if (info->var.accel_flags) {
999 info->fbops->fb_imageblit = nvidiafb_imageblit; 999 info->fbops->fb_imageblit = nvidiafb_imageblit;
1000 info->fbops->fb_fillrect = nvidiafb_fillrect; 1000 info->fbops->fb_fillrect = nvidiafb_fillrect;
@@ -1328,7 +1328,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1328 char buf[16]; 1328 char buf[16];
1329 1329
1330 memset(buf, 0, 16); 1330 memset(buf, 0, 16);
1331 snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight); 1331 snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
1332 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, 1332 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1333 specs->modedb_len, &modedb, 8); 1333 specs->modedb_len, &modedb, 8);
1334 } 1334 }
@@ -1356,8 +1356,6 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1356 info->pixmap.size = 8 * 1024; 1356 info->pixmap.size = 8 * 1024;
1357 info->pixmap.flags = FB_PIXMAP_SYSTEM; 1357 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1358 1358
1359 if (!hwcur)
1360 info->fbops->fb_cursor = soft_cursor;
1361 info->var.accel_flags = (!noaccel); 1359 info->var.accel_flags = (!noaccel);
1362 1360
1363 switch (par->Architecture) { 1361 switch (par->Architecture) {
@@ -1473,10 +1471,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1473 par->Chipset = (pd->vendor << 16) | pd->device; 1471 par->Chipset = (pd->vendor << 16) | pd->device;
1474 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); 1472 printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
1475 1473
1476#ifdef CONFIG_PCI_NAMES
1477 printk(KERN_INFO PFX "%s\n", pd->pretty_name);
1478#endif
1479
1480 if (par->Architecture == 0) { 1474 if (par->Architecture == 0) {
1481 printk(KERN_ERR PFX "unknown NV_ARCH\n"); 1475 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1482 goto err_out_free_base0; 1476 goto err_out_free_base0;
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 42a6591e863f..611922c0b22f 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -363,7 +363,7 @@ static void __init offb_init_nodriver(struct device_node *dp)
363 address = (u_long) dp->addrs[i].address; 363 address = (u_long) dp->addrs[i].address;
364 364
365#ifdef CONFIG_PPC64 365#ifdef CONFIG_PPC64
366 address += dp->phb->pci_mem_offset; 366 address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset;
367#endif 367#endif
368 368
369 /* kludge for valkyrie */ 369 /* kludge for valkyrie */
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 30112816420c..34d4dcc0320a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -468,6 +468,36 @@ static inline unsigned int get_pcd(unsigned int pixclock)
468} 468}
469 469
470/* 470/*
471 * Some touchscreens need hsync information from the video driver to
472 * function correctly. We export it here.
473 */
474static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
475{
476 unsigned long long htime;
477
478 if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
479 fbi->hsync_time=0;
480 return;
481 }
482
483 htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000;
484 do_div(htime, pcd * fbi->fb.var.hsync_len);
485 fbi->hsync_time = htime;
486}
487
488unsigned long pxafb_get_hsync_time(struct device *dev)
489{
490 struct pxafb_info *fbi = dev_get_drvdata(dev);
491
492 /* If display is blanked/suspended, hsync isn't active */
493 if (!fbi || (fbi->state != C_ENABLE))
494 return 0;
495
496 return fbi->hsync_time;
497}
498EXPORT_SYMBOL(pxafb_get_hsync_time);
499
500/*
471 * pxafb_activate_var(): 501 * pxafb_activate_var():
472 * Configures LCD Controller based on entries in var parameter. Settings are 502 * Configures LCD Controller based on entries in var parameter. Settings are
473 * only written to the controller if changes were made. 503 * only written to the controller if changes were made.
@@ -631,6 +661,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
631 fbi->reg_lccr1 = new_regs.lccr1; 661 fbi->reg_lccr1 = new_regs.lccr1;
632 fbi->reg_lccr2 = new_regs.lccr2; 662 fbi->reg_lccr2 = new_regs.lccr2;
633 fbi->reg_lccr3 = new_regs.lccr3; 663 fbi->reg_lccr3 = new_regs.lccr3;
664 set_hsync_time(fbi, pcd);
634 local_irq_restore(flags); 665 local_irq_restore(flags);
635 666
636 /* 667 /*
@@ -907,6 +938,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
907 938
908 case CPUFREQ_POSTCHANGE: 939 case CPUFREQ_POSTCHANGE:
909 pcd = get_pcd(fbi->fb.var.pixclock); 940 pcd = get_pcd(fbi->fb.var.pixclock);
941 set_hsync_time(fbi, pcd);
910 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); 942 fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
911 set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); 943 set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
912 break; 944 break;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index de15fec5f82f..22c00be786a8 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -83,6 +83,8 @@ struct pxafb_info {
83 u_int reg_lccr2; 83 u_int reg_lccr2;
84 u_int reg_lccr3; 84 u_int reg_lccr3;
85 85
86 unsigned long hsync_time;
87
86 volatile u_char state; 88 volatile u_char state;
87 volatile u_char task_state; 89 volatile u_char task_state;
88 struct semaphore ctrlr_sem; 90 struct semaphore ctrlr_sem;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index ae297e222681..3e9f96e9237d 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1936,10 +1936,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
1936 default_par->Chipset = (pd->vendor << 16) | pd->device; 1936 default_par->Chipset = (pd->vendor << 16) | pd->device;
1937 printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset); 1937 printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1938 1938
1939#ifdef CONFIG_PCI_NAMES
1940 printk(KERN_INFO PFX "%s\n", pd->pretty_name);
1941#endif
1942
1943 if(default_par->riva.Architecture == 0) { 1939 if(default_par->riva.Architecture == 0) {
1944 printk(KERN_ERR PFX "unknown NV_ARCH\n"); 1940 printk(KERN_ERR PFX "unknown NV_ARCH\n");
1945 ret=-ENODEV; 1941 ret=-ENODEV;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
new file mode 100644
index 000000000000..00c0223a352e
--- /dev/null
+++ b/drivers/video/s3c2410fb.c
@@ -0,0 +1,915 @@
1/*
2 * linux/drivers/video/s3c2410fb.c
3 * Copyright (c) Arnaud Patard, Ben Dooks
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file COPYING in the main directory of this archive for
7 * more details.
8 *
9 * S3C2410 LCD Controller Frame Buffer Driver
10 * based on skeletonfb.c, sa1100fb.c and others
11 *
12 * ChangeLog
13 * 2005-04-07: Arnaud Patard <arnaud.patard@rtp-net.org>
14 * - u32 state -> pm_message_t state
15 * - S3C2410_{VA,SZ}_LCD -> S3C24XX
16 *
17 * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org>
18 * - Removed the ioctl
19 * - use readl/writel instead of __raw_writel/__raw_readl
20 *
21 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - Added the possibility to set on or off the
23 * debugging mesaages
24 * - Replaced 0 and 1 by on or off when reading the
25 * /sys files
26 *
27 * 2005-03-23: Ben Dooks <ben-linux@fluff.org>
28 * - added non 16bpp modes
29 * - updated platform information for range of x/y/bpp
30 * - add code to ensure palette is written correctly
31 * - add pixel clock divisor control
32 *
33 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
34 * - Removed the use of currcon as it no more exist
35 * - Added LCD power sysfs interface
36 *
37 * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
38 * - minor cleanups
39 * - add suspend/resume support
40 * - s3c2410fb_setcolreg() not valid in >8bpp modes
41 * - removed last CONFIG_FB_S3C2410_FIXED
42 * - ensure lcd controller stopped before cleanup
43 * - added sysfs interface for backlight power
44 * - added mask for gpio configuration
45 * - ensured IRQs disabled during GPIO configuration
46 * - disable TPAL before enabling video
47 *
48 * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org>
49 * - Suppress command line options
50 *
51 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
52 * - code cleanup
53 *
54 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
55 * - Renamed from h1940fb.c to s3c2410fb.c
56 * - Add support for different devices
57 * - Backlight support
58 *
59 * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
60 * - added clock (de-)allocation code
61 * - added fixem fbmem option
62 *
63 * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org>
64 * - code cleanup
65 * - added a forgotten return in h1940fb_init
66 *
67 * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
68 * - code cleanup and extended debugging
69 *
70 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
71 * - First version
72 */
73
74#include <linux/module.h>
75#include <linux/kernel.h>
76#include <linux/errno.h>
77#include <linux/string.h>
78#include <linux/mm.h>
79#include <linux/tty.h>
80#include <linux/slab.h>
81#include <linux/delay.h>
82#include <linux/fb.h>
83#include <linux/init.h>
84#include <linux/dma-mapping.h>
85#include <linux/string.h>
86#include <linux/interrupt.h>
87#include <linux/workqueue.h>
88#include <linux/wait.h>
89
90#include <asm/io.h>
91#include <asm/uaccess.h>
92#include <asm/div64.h>
93
94#include <asm/mach/map.h>
95#include <asm/arch/regs-lcd.h>
96#include <asm/arch/regs-gpio.h>
97#include <asm/arch/fb.h>
98#include <asm/hardware/clock.h>
99
100#ifdef CONFIG_PM
101#include <linux/pm.h>
102#endif
103
104#include "s3c2410fb.h"
105
106
107static struct s3c2410fb_mach_info *mach_info;
108
109/* Debugging stuff */
110#ifdef CONFIG_FB_S3C2410_DEBUG
111static int debug = 1;
112#else
113static int debug = 0;
114#endif
115
116#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
117
118/* useful functions */
119
120/* s3c2410fb_set_lcdaddr
121 *
122 * initialise lcd controller address pointers
123*/
124
125static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
126{
127 struct fb_var_screeninfo *var = &fbi->fb->var;
128 unsigned long saddr1, saddr2, saddr3;
129
130 saddr1 = fbi->fb->fix.smem_start >> 1;
131 saddr2 = fbi->fb->fix.smem_start;
132 saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
133 saddr2>>= 1;
134
135 saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres);
136
137 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
138 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
139 dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
140
141 writel(saddr1, S3C2410_LCDSADDR1);
142 writel(saddr2, S3C2410_LCDSADDR2);
143 writel(saddr3, S3C2410_LCDSADDR3);
144}
145
146/* s3c2410fb_calc_pixclk()
147 *
148 * calculate divisor for clk->pixclk
149*/
150
151static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
152 unsigned long pixclk)
153{
154 unsigned long clk = clk_get_rate(fbi->clk);
155 unsigned long long div;
156
157 /* pixclk is in picoseoncds, our clock is in Hz
158 *
159 * Hz -> picoseconds is / 10^-12
160 */
161
162 div = (unsigned long long)clk * pixclk;
163 do_div(div,1000000UL);
164 do_div(div,1000000UL);
165
166 dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div);
167 return div;
168}
169
170/*
171 * s3c2410fb_check_var():
172 * Get the video params out of 'var'. If a value doesn't fit, round it up,
173 * if it's too big, return -EINVAL.
174 *
175 */
176static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
177 struct fb_info *info)
178{
179 struct s3c2410fb_info *fbi = info->par;
180
181 dprintk("check_var(var=%p, info=%p)\n", var, info);
182
183 /* validate x/y resolution */
184
185 if (var->yres > fbi->mach_info->yres.max)
186 var->yres = fbi->mach_info->yres.max;
187 else if (var->yres < fbi->mach_info->yres.min)
188 var->yres = fbi->mach_info->yres.min;
189
190 if (var->xres > fbi->mach_info->xres.max)
191 var->yres = fbi->mach_info->xres.max;
192 else if (var->xres < fbi->mach_info->xres.min)
193 var->xres = fbi->mach_info->xres.min;
194
195 /* validate bpp */
196
197 if (var->bits_per_pixel > fbi->mach_info->bpp.max)
198 var->bits_per_pixel = fbi->mach_info->bpp.max;
199 else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
200 var->bits_per_pixel = fbi->mach_info->bpp.min;
201
202 /* set r/g/b positions */
203
204 if (var->bits_per_pixel == 16) {
205 var->red.offset = 11;
206 var->green.offset = 5;
207 var->blue.offset = 0;
208 var->red.length = 5;
209 var->green.length = 6;
210 var->blue.length = 5;
211 var->transp.length = 0;
212 } else {
213 var->red.length = var->bits_per_pixel;
214 var->red.offset = 0;
215 var->green.length = var->bits_per_pixel;
216 var->green.offset = 0;
217 var->blue.length = var->bits_per_pixel;
218 var->blue.offset = 0;
219 var->transp.length = 0;
220 }
221
222 return 0;
223}
224
225/* s3c2410fb_activate_var
226 *
227 * activate (set) the controller from the given framebuffer
228 * information
229*/
230
231static int s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
232 struct fb_var_screeninfo *var)
233{
234 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
235
236 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
237 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
238 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
239
240 switch (var->bits_per_pixel) {
241 case 1:
242 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
243 break;
244 case 2:
245 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
246 break;
247 case 4:
248 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
249 break;
250 case 8:
251 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
252 break;
253 case 16:
254 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
255 break;
256 }
257
258 /* check to see if we need to update sync/borders */
259
260 if (!fbi->mach_info->fixed_syncs) {
261 dprintk("setting vert: up=%d, low=%d, sync=%d\n",
262 var->upper_margin, var->lower_margin,
263 var->vsync_len);
264
265 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
266 var->left_margin, var->right_margin,
267 var->hsync_len);
268
269 fbi->regs.lcdcon2 =
270 S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
271 S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
272 S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
273
274 fbi->regs.lcdcon3 =
275 S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
276 S3C2410_LCDCON3_HFPD(var->left_margin - 1);
277
278 fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff);
279 fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
280 }
281
282 /* update X/Y info */
283
284 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
285 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
286
287 fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
288 fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(var->xres - 1);
289
290 if (var->pixclock > 0) {
291 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
292
293 clkdiv = (clkdiv / 2) -1;
294 if (clkdiv < 0)
295 clkdiv = 0;
296
297 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
298 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
299 }
300
301 /* write new registers */
302
303 dprintk("new register set:\n");
304 dprintk("lcdcon[1] = 0x%08lx\n", fbi->regs.lcdcon1);
305 dprintk("lcdcon[2] = 0x%08lx\n", fbi->regs.lcdcon2);
306 dprintk("lcdcon[3] = 0x%08lx\n", fbi->regs.lcdcon3);
307 dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
308 dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);
309
310 writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
311 writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
312 writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
313 writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
314 writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);
315
316 /* set lcd address pointers */
317 s3c2410fb_set_lcdaddr(fbi);
318
319 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
320}
321
322
323/*
324 * s3c2410fb_set_par - Optional function. Alters the hardware state.
325 * @info: frame buffer structure that represents a single frame buffer
326 *
327 */
328static int s3c2410fb_set_par(struct fb_info *info)
329{
330 struct s3c2410fb_info *fbi = info->par;
331 struct fb_var_screeninfo *var = &info->var;
332
333 if (var->bits_per_pixel == 16)
334 fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
335 else
336 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
337
338 fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8;
339
340 /* activate this new configuration */
341
342 s3c2410fb_activate_var(fbi, var);
343 return 0;
344}
345
346static void schedule_palette_update(struct s3c2410fb_info *fbi,
347 unsigned int regno, unsigned int val)
348{
349 unsigned long flags;
350 unsigned long irqen;
351
352 local_irq_save(flags);
353
354 fbi->palette_buffer[regno] = val;
355
356 if (!fbi->palette_ready) {
357 fbi->palette_ready = 1;
358
359 /* enable IRQ */
360 irqen = readl(S3C2410_LCDINTMSK);
361 irqen &= ~S3C2410_LCDINT_FRSYNC;
362 writel(irqen, S3C2410_LCDINTMSK);
363 }
364
365 local_irq_restore(flags);
366}
367
368/* from pxafb.c */
369static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
370{
371 chan &= 0xffff;
372 chan >>= 16 - bf->length;
373 return chan << bf->offset;
374}
375
376static int s3c2410fb_setcolreg(unsigned regno,
377 unsigned red, unsigned green, unsigned blue,
378 unsigned transp, struct fb_info *info)
379{
380 struct s3c2410fb_info *fbi = info->par;
381 unsigned int val;
382
383 /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */
384
385 switch (fbi->fb->fix.visual) {
386 case FB_VISUAL_TRUECOLOR:
387 /* true-colour, use pseuo-palette */
388
389 if (regno < 16) {
390 u32 *pal = fbi->fb->pseudo_palette;
391
392 val = chan_to_field(red, &fbi->fb->var.red);
393 val |= chan_to_field(green, &fbi->fb->var.green);
394 val |= chan_to_field(blue, &fbi->fb->var.blue);
395
396 pal[regno] = val;
397 }
398 break;
399
400 case FB_VISUAL_PSEUDOCOLOR:
401 if (regno < 256) {
402 /* currently assume RGB 5-6-5 mode */
403
404 val = ((red >> 0) & 0xf800);
405 val |= ((green >> 5) & 0x07e0);
406 val |= ((blue >> 11) & 0x001f);
407
408 writel(val, S3C2410_TFTPAL(regno));
409 schedule_palette_update(fbi, regno, val);
410 }
411
412 break;
413
414 default:
415 return 1; /* unknown type */
416 }
417
418 return 0;
419}
420
421
422/**
423 * s3c2410fb_blank
424 * @blank_mode: the blank mode we want.
425 * @info: frame buffer structure that represents a single frame buffer
426 *
427 * Blank the screen if blank_mode != 0, else unblank. Return 0 if
428 * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
429 * video mode which doesn't support it. Implements VESA suspend
430 * and powerdown modes on hardware that supports disabling hsync/vsync:
431 * blank_mode == 2: suspend vsync
432 * blank_mode == 3: suspend hsync
433 * blank_mode == 4: powerdown
434 *
435 * Returns negative errno on error, or zero on success.
436 *
437 */
438static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
439{
440 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
441
442 if (mach_info == NULL)
443 return -EINVAL;
444
445 if (blank_mode == FB_BLANK_UNBLANK)
446 writel(0x0, S3C2410_TPAL);
447 else {
448 dprintk("setting TPAL to output 0x000000\n");
449 writel(S3C2410_TPAL_EN, S3C2410_TPAL);
450 }
451
452 return 0;
453}
454
455static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf)
456{
457 return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
458}
459static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr,
460 const char *buf, size_t len)
461{
462 if (mach_info == NULL)
463 return -EINVAL;
464
465 if (len < 1)
466 return -EINVAL;
467
468 if (strnicmp(buf, "on", 2) == 0 ||
469 strnicmp(buf, "1", 1) == 0) {
470 debug = 1;
471 printk(KERN_DEBUG "s3c2410fb: Debug On");
472 } else if (strnicmp(buf, "off", 3) == 0 ||
473 strnicmp(buf, "0", 1) == 0) {
474 debug = 0;
475 printk(KERN_DEBUG "s3c2410fb: Debug Off");
476 } else {
477 return -EINVAL;
478 }
479
480 return len;
481}
482
483
484static DEVICE_ATTR(debug, 0666,
485 s3c2410fb_debug_show,
486 s3c2410fb_debug_store);
487
488static struct fb_ops s3c2410fb_ops = {
489 .owner = THIS_MODULE,
490 .fb_check_var = s3c2410fb_check_var,
491 .fb_set_par = s3c2410fb_set_par,
492 .fb_blank = s3c2410fb_blank,
493 .fb_setcolreg = s3c2410fb_setcolreg,
494 .fb_fillrect = cfb_fillrect,
495 .fb_copyarea = cfb_copyarea,
496 .fb_imageblit = cfb_imageblit,
497 .fb_cursor = soft_cursor,
498};
499
500
501/*
502 * s3c2410fb_map_video_memory():
503 * Allocates the DRAM memory for the frame buffer. This buffer is
504 * remapped into a non-cached, non-buffered, memory region to
505 * allow palette and pixel writes to occur without flushing the
506 * cache. Once this area is remapped, all virtual memory
507 * access to the video memory should occur at the new region.
508 */
509static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi)
510{
511 dprintk("map_video_memory(fbi=%p)\n", fbi);
512
513 fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);
514 fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
515 &fbi->map_dma, GFP_KERNEL);
516
517 fbi->map_size = fbi->fb->fix.smem_len;
518
519 if (fbi->map_cpu) {
520 /* prevent initial garbage on screen */
521 dprintk("map_video_memory: clear %p:%08x\n",
522 fbi->map_cpu, fbi->map_size);
523 memset(fbi->map_cpu, 0xf0, fbi->map_size);
524
525 fbi->screen_dma = fbi->map_dma;
526 fbi->fb->screen_base = fbi->map_cpu;
527 fbi->fb->fix.smem_start = fbi->screen_dma;
528
529 dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n",
530 fbi->map_dma, fbi->map_cpu, fbi->fb->fix.smem_len);
531 }
532
533 return fbi->map_cpu ? 0 : -ENOMEM;
534}
535
536static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi)
537{
538 dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma);
539}
540
541static inline void modify_gpio(void __iomem *reg,
542 unsigned long set, unsigned long mask)
543{
544 unsigned long tmp;
545
546 tmp = readl(reg) & ~mask;
547 writel(tmp | set, reg);
548}
549
550
551/*
552 * s3c2410fb_init_registers - Initialise all LCD-related registers
553 */
554
555int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
556{
557 unsigned long flags;
558
559 /* Initialise LCD with values from haret */
560
561 local_irq_save(flags);
562
563 /* modify the gpio(s) with interrupts set (bjd) */
564
565 modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask);
566 modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask);
567 modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask);
568 modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask);
569
570 local_irq_restore(flags);
571
572 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
573 writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
574 writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
575 writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
576 writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);
577
578 s3c2410fb_set_lcdaddr(fbi);
579
580 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
581 writel(mach_info->lpcsel, S3C2410_LPCSEL);
582
583 dprintk("replacing TPAL %08x\n", readl(S3C2410_TPAL));
584
585 /* ensure temporary palette disabled */
586 writel(0x00, S3C2410_TPAL);
587
588 /* Enable video by setting the ENVID bit to 1 */
589 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
590 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
591 return 0;
592}
593
594static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
595{
596 unsigned int i;
597 unsigned long ent;
598
599 fbi->palette_ready = 0;
600
601 for (i = 0; i < 256; i++) {
602 if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR)
603 continue;
604
605 writel(ent, S3C2410_TFTPAL(i));
606
607 /* it seems the only way to know exactly
608 * if the palette wrote ok, is to check
609 * to see if the value verifies ok
610 */
611
612 if (readw(S3C2410_TFTPAL(i)) == ent)
613 fbi->palette_buffer[i] = PALETTE_BUFF_CLEAR;
614 else
615 fbi->palette_ready = 1; /* retry */
616 }
617}
618
619static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r)
620{
621 struct s3c2410fb_info *fbi = dev_id;
622 unsigned long lcdirq = readl(S3C2410_LCDINTPND);
623
624 if (lcdirq & S3C2410_LCDINT_FRSYNC) {
625 if (fbi->palette_ready)
626 s3c2410fb_write_palette(fbi);
627
628 writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDINTPND);
629 writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDSRCPND);
630 }
631
632 return IRQ_HANDLED;
633}
634
635static char driver_name[]="s3c2410fb";
636
637int __init s3c2410fb_probe(struct device *dev)
638{
639 struct s3c2410fb_info *info;
640 struct fb_info *fbinfo;
641 struct platform_device *pdev = to_platform_device(dev);
642 struct s3c2410fb_hw *mregs;
643 int ret;
644 int irq;
645 int i;
646
647 mach_info = dev->platform_data;
648 if (mach_info == NULL) {
649 dev_err(dev,"no platform data for lcd, cannot attach\n");
650 return -EINVAL;
651 }
652
653 mregs = &mach_info->regs;
654
655 irq = platform_get_irq(pdev, 0);
656 if (irq < 0) {
657 dev_err(dev, "no irq for device\n");
658 return -ENOENT;
659 }
660
661 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), dev);
662 if (!fbinfo) {
663 return -ENOMEM;
664 }
665
666
667 info = fbinfo->par;
668 info->fb = fbinfo;
669 dev_set_drvdata(dev, fbinfo);
670
671 s3c2410fb_init_registers(info);
672
673 dprintk("devinit\n");
674
675 strcpy(fbinfo->fix.id, driver_name);
676
677 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
678
679 info->mach_info = dev->platform_data;
680
681 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
682 fbinfo->fix.type_aux = 0;
683 fbinfo->fix.xpanstep = 0;
684 fbinfo->fix.ypanstep = 0;
685 fbinfo->fix.ywrapstep = 0;
686 fbinfo->fix.accel = FB_ACCEL_NONE;
687
688 fbinfo->var.nonstd = 0;
689 fbinfo->var.activate = FB_ACTIVATE_NOW;
690 fbinfo->var.height = mach_info->height;
691 fbinfo->var.width = mach_info->width;
692 fbinfo->var.accel_flags = 0;
693 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
694
695 fbinfo->fbops = &s3c2410fb_ops;
696 fbinfo->flags = FBINFO_FLAG_DEFAULT;
697 fbinfo->pseudo_palette = &info->pseudo_pal;
698
699 fbinfo->var.xres = mach_info->xres.defval;
700 fbinfo->var.xres_virtual = mach_info->xres.defval;
701 fbinfo->var.yres = mach_info->yres.defval;
702 fbinfo->var.yres_virtual = mach_info->yres.defval;
703 fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
704
705 fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) +1;
706 fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) +1;
707 fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
708
709 fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
710 fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
711 fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
712
713 fbinfo->var.red.offset = 11;
714 fbinfo->var.green.offset = 5;
715 fbinfo->var.blue.offset = 0;
716 fbinfo->var.transp.offset = 0;
717 fbinfo->var.red.length = 5;
718 fbinfo->var.green.length = 6;
719 fbinfo->var.blue.length = 5;
720 fbinfo->var.transp.length = 0;
721 fbinfo->fix.smem_len = mach_info->xres.max *
722 mach_info->yres.max *
723 mach_info->bpp.max / 8;
724
725 for (i = 0; i < 256; i++)
726 info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
727
728 if (!request_mem_region((unsigned long)S3C24XX_VA_LCD, SZ_1M, "s3c2410-lcd")) {
729 ret = -EBUSY;
730 goto dealloc_fb;
731 }
732
733
734 dprintk("got LCD region\n");
735
736 ret = request_irq(irq, s3c2410fb_irq, SA_INTERRUPT, pdev->name, info);
737 if (ret) {
738 dev_err(dev, "cannot get irq %d - err %d\n", irq, ret);
739 ret = -EBUSY;
740 goto release_mem;
741 }
742
743 info->clk = clk_get(NULL, "lcd");
744 if (!info->clk || IS_ERR(info->clk)) {
745 printk(KERN_ERR "failed to get lcd clock source\n");
746 ret = -ENOENT;
747 goto release_irq;
748 }
749
750 clk_use(info->clk);
751 clk_enable(info->clk);
752 dprintk("got and enabled clock\n");
753
754 msleep(1);
755
756 /* Initialize video memory */
757 ret = s3c2410fb_map_video_memory(info);
758 if (ret) {
759 printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret);
760 ret = -ENOMEM;
761 goto release_clock;
762 }
763 dprintk("got video memory\n");
764
765 ret = s3c2410fb_init_registers(info);
766
767 ret = s3c2410fb_check_var(&fbinfo->var, fbinfo);
768
769 ret = register_framebuffer(fbinfo);
770 if (ret < 0) {
771 printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
772 goto free_video_memory;
773 }
774
775 /* create device files */
776 device_create_file(dev, &dev_attr_debug);
777
778 printk(KERN_INFO "fb%d: %s frame buffer device\n",
779 fbinfo->node, fbinfo->fix.id);
780
781 return 0;
782
783free_video_memory:
784 s3c2410fb_unmap_video_memory(info);
785release_clock:
786 clk_disable(info->clk);
787 clk_unuse(info->clk);
788 clk_put(info->clk);
789release_irq:
790 free_irq(irq,info);
791release_mem:
792 release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD);
793dealloc_fb:
794 framebuffer_release(fbinfo);
795 return ret;
796}
797
798/* s3c2410fb_stop_lcd
799 *
800 * shutdown the lcd controller
801*/
802
803static void s3c2410fb_stop_lcd(void)
804{
805 unsigned long flags;
806 unsigned long tmp;
807
808 local_irq_save(flags);
809
810 tmp = readl(S3C2410_LCDCON1);
811 writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
812
813 local_irq_restore(flags);
814}
815
816/*
817 * Cleanup
818 */
819static int s3c2410fb_remove(struct device *dev)
820{
821 struct platform_device *pdev = to_platform_device(dev);
822 struct fb_info *fbinfo = dev_get_drvdata(dev);
823 struct s3c2410fb_info *info = fbinfo->par;
824 int irq;
825
826 s3c2410fb_stop_lcd();
827 msleep(1);
828
829 s3c2410fb_unmap_video_memory(info);
830
831 if (info->clk) {
832 clk_disable(info->clk);
833 clk_unuse(info->clk);
834 clk_put(info->clk);
835 info->clk = NULL;
836 }
837
838 irq = platform_get_irq(pdev, 0);
839 free_irq(irq,info);
840 release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD);
841 unregister_framebuffer(fbinfo);
842
843 return 0;
844}
845
846#ifdef CONFIG_PM
847
848/* suspend and resume support for the lcd controller */
849
850static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level)
851{
852 struct fb_info *fbinfo = dev_get_drvdata(dev);
853 struct s3c2410fb_info *info = fbinfo->par;
854
855 if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
856 s3c2410fb_stop_lcd();
857
858 /* sleep before disabling the clock, we need to ensure
859 * the LCD DMA engine is not going to get back on the bus
860 * before the clock goes off again (bjd) */
861
862 msleep(1);
863 clk_disable(info->clk);
864 }
865
866 return 0;
867}
868
869static int s3c2410fb_resume(struct device *dev, u32 level)
870{
871 struct fb_info *fbinfo = dev_get_drvdata(dev);
872 struct s3c2410fb_info *info = fbinfo->par;
873
874 if (level == RESUME_ENABLE) {
875 clk_enable(info->clk);
876 msleep(1);
877
878 s3c2410fb_init_registers(info);
879
880 }
881
882 return 0;
883}
884
885#else
886#define s3c2410fb_suspend NULL
887#define s3c2410fb_resume NULL
888#endif
889
890static struct device_driver s3c2410fb_driver = {
891 .name = "s3c2410-lcd",
892 .bus = &platform_bus_type,
893 .probe = s3c2410fb_probe,
894 .suspend = s3c2410fb_suspend,
895 .resume = s3c2410fb_resume,
896 .remove = s3c2410fb_remove
897};
898
899int __devinit s3c2410fb_init(void)
900{
901 return driver_register(&s3c2410fb_driver);
902}
903
904static void __exit s3c2410fb_cleanup(void)
905{
906 driver_unregister(&s3c2410fb_driver);
907}
908
909
910module_init(s3c2410fb_init);
911module_exit(s3c2410fb_cleanup);
912
913MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>");
914MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
915MODULE_LICENSE("GPL");
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
new file mode 100644
index 000000000000..be40968f899e
--- /dev/null
+++ b/drivers/video/s3c2410fb.h
@@ -0,0 +1,56 @@
1/*
2 * linux/drivers/s3c2410fb.h
3 * Copyright (c) Arnaud Patard
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file COPYING in the main directory of this archive for
7 * more details.
8 *
9 * S3C2410 LCD Controller Frame Buffer Driver
10 * based on skeletonfb.c, sa1100fb.h
11 *
12 * ChangeLog
13 *
14 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
15 * - Moved dprintk to s3c2410fb.c
16 *
17 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
18 * - Renamed from h1940fb.h to s3c2410fb.h
19 * - Chenged h1940 to s3c2410
20 *
21 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - First version
23 */
24
25#ifndef __S3C2410FB_H
26#define __S3C2410FB_H
27
28struct s3c2410fb_info {
29 struct fb_info *fb;
30 struct device *dev;
31 struct clk *clk;
32
33 struct s3c2410fb_mach_info *mach_info;
34
35 /* raw memory addresses */
36 dma_addr_t map_dma; /* physical */
37 u_char * map_cpu; /* virtual */
38 u_int map_size;
39
40 struct s3c2410fb_hw regs;
41
42 /* addresses of pieces placed in raw buffer */
43 u_char * screen_cpu; /* virtual address of buffer */
44 dma_addr_t screen_dma; /* physical address of buffer */
45 unsigned int palette_ready;
46
47 /* keep these registers in case we need to re-write palette */
48 u32 palette_buffer[256];
49 u32 pseudo_pal[16];
50};
51
52#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */
53
54int s3c2410fb_init(void);
55
56#endif
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 847698b5cfe7..959404ad68f4 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -259,8 +259,9 @@ static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
259 return buf; 259 return buf;
260} 260}
261 261
262int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid) 262int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
263{ 263{
264 struct savagefb_par *par = info->par;
264 u8 *edid = NULL; 265 u8 *edid = NULL;
265 int i; 266 int i;
266 267
@@ -270,12 +271,19 @@ int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
270 if (edid) 271 if (edid)
271 break; 272 break;
272 } 273 }
274
275 if (!edid) {
276 /* try to get from firmware */
277 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
278 if (edid)
279 memcpy(edid, fb_firmware_edid(info->device),
280 EDID_LENGTH);
281 }
282
273 if (out_edid) 283 if (out_edid)
274 *out_edid = edid; 284 *out_edid = edid;
275 if (!edid)
276 return 1;
277 285
278 return 0; 286 return (edid) ? 0 : 1;
279} 287}
280 288
281MODULE_LICENSE("GPL"); 289MODULE_LICENSE("GPL");
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index 8594b1e42d71..d6f94742c9f2 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -60,6 +60,7 @@
60 60
61#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) 61#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
62 62
63#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) || (chip == S3_PROSAVAGEDDR))
63 64
64/* Chip tags. These are used to group the adapters into 65/* Chip tags. These are used to group the adapters into
65 * related families. 66 * related families.
@@ -73,6 +74,8 @@ typedef enum {
73 S3_PROSAVAGE, 74 S3_PROSAVAGE,
74 S3_SUPERSAVAGE, 75 S3_SUPERSAVAGE,
75 S3_SAVAGE2000, 76 S3_SAVAGE2000,
77 S3_PROSAVAGEDDR,
78 S3_TWISTER,
76 S3_LAST 79 S3_LAST
77} savage_chipset; 80} savage_chipset;
78 81
@@ -128,6 +131,10 @@ typedef enum {
128#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16)) 131#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16))
129#define BCI_CMD_SEND_COLOR 0x00008000 132#define BCI_CMD_SEND_COLOR 0x00008000
130 133
134#define DISP_CRT 1
135#define DISP_LCD 2
136#define DISP_DFP 3
137
131struct xtimings { 138struct xtimings {
132 unsigned int Clock; 139 unsigned int Clock;
133 unsigned int HDisplay; 140 unsigned int HDisplay;
@@ -166,6 +173,10 @@ struct savagefb_par {
166 struct savagefb_i2c_chan chan; 173 struct savagefb_i2c_chan chan;
167 unsigned char *edid; 174 unsigned char *edid;
168 u32 pseudo_palette[16]; 175 u32 pseudo_palette[16];
176 int pm_state;
177 int display_type;
178 int dvi;
179 int crtonly;
169 int dacSpeedBpp; 180 int dacSpeedBpp;
170 int maxClock; 181 int maxClock;
171 int minClock; 182 int minClock;
@@ -338,7 +349,7 @@ do { \
338 } \ 349 } \
339} 350}
340 351
341extern int savagefb_probe_i2c_connector(struct savagefb_par *par, 352extern int savagefb_probe_i2c_connector(struct fb_info *info,
342 u8 **out_edid); 353 u8 **out_edid);
343extern void savagefb_create_i2c_busses(struct fb_info *info); 354extern void savagefb_create_i2c_busses(struct fb_info *info);
344extern void savagefb_delete_i2c_busses(struct fb_info *info); 355extern void savagefb_delete_i2c_busses(struct fb_info *info);
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 117ad42f120d..b5ca3ef8271f 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1400,6 +1400,58 @@ static int savagefb_pan_display (struct fb_var_screeninfo *var,
1400 return 0; 1400 return 0;
1401} 1401}
1402 1402
1403static int savagefb_blank(int blank, struct fb_info *info)
1404{
1405 struct savagefb_par *par = info->par;
1406 u8 sr8 = 0, srd = 0;
1407
1408 if (par->display_type == DISP_CRT) {
1409 vga_out8(0x3c4, 0x08);
1410 sr8 = vga_in8(0x3c5);
1411 sr8 |= 0x06;
1412 vga_out8(0x3c5, sr8);
1413 vga_out8(0x3c4, 0x0d);
1414 srd = vga_in8(0x3c5);
1415 srd &= 0x03;
1416
1417 switch (blank) {
1418 case FB_BLANK_UNBLANK:
1419 case FB_BLANK_NORMAL:
1420 break;
1421 case FB_BLANK_VSYNC_SUSPEND:
1422 srd |= 0x10;
1423 break;
1424 case FB_BLANK_HSYNC_SUSPEND:
1425 srd |= 0x40;
1426 break;
1427 case FB_BLANK_POWERDOWN:
1428 srd |= 0x50;
1429 break;
1430 }
1431
1432 vga_out8(0x3c4, 0x0d);
1433 vga_out8(0x3c5, srd);
1434 }
1435
1436 if (par->display_type == DISP_LCD ||
1437 par->display_type == DISP_DFP) {
1438 switch(blank) {
1439 case FB_BLANK_UNBLANK:
1440 case FB_BLANK_NORMAL:
1441 vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
1442 vga_out8(0x3c5, vga_in8(0x3c5) | 0x10);
1443 break;
1444 case FB_BLANK_VSYNC_SUSPEND:
1445 case FB_BLANK_HSYNC_SUSPEND:
1446 case FB_BLANK_POWERDOWN:
1447 vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
1448 vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10);
1449 break;
1450 }
1451 }
1452
1453 return (blank == FB_BLANK_NORMAL) ? 1 : 0;
1454}
1403 1455
1404static struct fb_ops savagefb_ops = { 1456static struct fb_ops savagefb_ops = {
1405 .owner = THIS_MODULE, 1457 .owner = THIS_MODULE,
@@ -1407,6 +1459,7 @@ static struct fb_ops savagefb_ops = {
1407 .fb_set_par = savagefb_set_par, 1459 .fb_set_par = savagefb_set_par,
1408 .fb_setcolreg = savagefb_setcolreg, 1460 .fb_setcolreg = savagefb_setcolreg,
1409 .fb_pan_display = savagefb_pan_display, 1461 .fb_pan_display = savagefb_pan_display,
1462 .fb_blank = savagefb_blank,
1410#if defined(CONFIG_FB_SAVAGE_ACCEL) 1463#if defined(CONFIG_FB_SAVAGE_ACCEL)
1411 .fb_fillrect = savagefb_fillrect, 1464 .fb_fillrect = savagefb_fillrect,
1412 .fb_copyarea = savagefb_copyarea, 1465 .fb_copyarea = savagefb_copyarea,
@@ -1583,8 +1636,7 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1583 static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 }; 1636 static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
1584 static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 }; 1637 static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
1585 static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 2, 2 }; 1638 static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 2, 2 };
1586 1639 int videoRam, videoRambytes, dvi;
1587 int videoRam, videoRambytes;
1588 1640
1589 DBG("savage_init_hw"); 1641 DBG("savage_init_hw");
1590 1642
@@ -1705,6 +1757,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1705 printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", 1757 printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n",
1706 par->MCLK); 1758 par->MCLK);
1707 1759
1760 /* check for DVI/flat panel */
1761 dvi = 0;
1762
1763 if (par->chip == S3_SAVAGE4) {
1764 unsigned char sr30 = 0x00;
1765
1766 vga_out8(0x3c4, 0x30);
1767 /* clear bit 1 */
1768 vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02);
1769 sr30 = vga_in8(0x3c5);
1770 if (sr30 & 0x02 /*0x04 */) {
1771 dvi = 1;
1772 printk("savagefb: Digital Flat Panel Detected\n");
1773 }
1774 }
1775
1776 if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
1777 (S3_MOBILE_TWISTER_SERIES(par->chip) && !par->crtonly))
1778 par->display_type = DISP_LCD;
1779 else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi))
1780 par->display_type = DISP_DFP;
1781 else
1782 par->display_type = DISP_CRT;
1783
1708 /* Check LCD panel parrmation */ 1784 /* Check LCD panel parrmation */
1709 1785
1710 if (par->chip == S3_SAVAGE_MX) { 1786 if (par->chip == S3_SAVAGE_MX) {
@@ -1759,7 +1835,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1759 par->SavagePanelWidth = panelX; 1835 par->SavagePanelWidth = panelX;
1760 par->SavagePanelHeight = panelY; 1836 par->SavagePanelHeight = panelY;
1761 1837
1762 } 1838 } else
1839 par->display_type = DISP_CRT;
1763 } 1840 }
1764 1841
1765 savage_get_default_par (par); 1842 savage_get_default_par (par);
@@ -1845,15 +1922,15 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1845 snprintf (info->fix.id, 16, "ProSavageKM"); 1922 snprintf (info->fix.id, 16, "ProSavageKM");
1846 break; 1923 break;
1847 case FB_ACCEL_S3TWISTER_P: 1924 case FB_ACCEL_S3TWISTER_P:
1848 par->chip = S3_PROSAVAGE; 1925 par->chip = S3_TWISTER;
1849 snprintf (info->fix.id, 16, "TwisterP"); 1926 snprintf (info->fix.id, 16, "TwisterP");
1850 break; 1927 break;
1851 case FB_ACCEL_S3TWISTER_K: 1928 case FB_ACCEL_S3TWISTER_K:
1852 par->chip = S3_PROSAVAGE; 1929 par->chip = S3_TWISTER;
1853 snprintf (info->fix.id, 16, "TwisterK"); 1930 snprintf (info->fix.id, 16, "TwisterK");
1854 break; 1931 break;
1855 case FB_ACCEL_PROSAVAGE_DDR: 1932 case FB_ACCEL_PROSAVAGE_DDR:
1856 par->chip = S3_PROSAVAGE; 1933 par->chip = S3_PROSAVAGEDDR;
1857 snprintf (info->fix.id, 16, "ProSavageDDR"); 1934 snprintf (info->fix.id, 16, "ProSavageDDR");
1858 break; 1935 break;
1859 case FB_ACCEL_PROSAVAGE_DDRK: 1936 case FB_ACCEL_PROSAVAGE_DDRK:
@@ -1899,12 +1976,11 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1899 info->pixmap.buf_align = 4; 1976 info->pixmap.buf_align = 4;
1900 info->pixmap.access_align = 32; 1977 info->pixmap.access_align = 32;
1901 1978
1902 fb_alloc_cmap (&info->cmap, NR_PALETTE, 0); 1979 err = fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
1980 if (!err)
1903 info->flags |= FBINFO_HWACCEL_COPYAREA | 1981 info->flags |= FBINFO_HWACCEL_COPYAREA |
1904 FBINFO_HWACCEL_FILLRECT | 1982 FBINFO_HWACCEL_FILLRECT |
1905 FBINFO_HWACCEL_IMAGEBLIT; 1983 FBINFO_HWACCEL_IMAGEBLIT;
1906
1907 err = 0;
1908 } 1984 }
1909#endif 1985#endif
1910 return err; 1986 return err;
@@ -1932,14 +2008,14 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
1932 if (err) 2008 if (err)
1933 goto failed_enable; 2009 goto failed_enable;
1934 2010
1935 if (pci_request_regions(dev, "savagefb")) { 2011 if ((err = pci_request_regions(dev, "savagefb"))) {
1936 printk(KERN_ERR "cannot request PCI regions\n"); 2012 printk(KERN_ERR "cannot request PCI regions\n");
1937 goto failed_enable; 2013 goto failed_enable;
1938 } 2014 }
1939 2015
1940 err = -ENOMEM; 2016 err = -ENOMEM;
1941 2017
1942 if (savage_init_fb_info(info, dev, id)) 2018 if ((err = savage_init_fb_info(info, dev, id)))
1943 goto failed_init; 2019 goto failed_init;
1944 2020
1945 err = savage_map_mmio(info); 2021 err = savage_map_mmio(info);
@@ -1947,6 +2023,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
1947 goto failed_mmio; 2023 goto failed_mmio;
1948 2024
1949 video_len = savage_init_hw(par); 2025 video_len = savage_init_hw(par);
2026 /* FIXME: cant be negative */
1950 if (video_len < 0) { 2027 if (video_len < 0) {
1951 err = video_len; 2028 err = video_len;
1952 goto failed_mmio; 2029 goto failed_mmio;
@@ -1959,7 +2036,8 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
1959 INIT_LIST_HEAD(&info->modelist); 2036 INIT_LIST_HEAD(&info->modelist);
1960#if defined(CONFIG_FB_SAVAGE_I2C) 2037#if defined(CONFIG_FB_SAVAGE_I2C)
1961 savagefb_create_i2c_busses(info); 2038 savagefb_create_i2c_busses(info);
1962 savagefb_probe_i2c_connector(par, &par->edid); 2039 savagefb_probe_i2c_connector(info, &par->edid);
2040 kfree(par->edid);
1963 fb_edid_to_monspecs(par->edid, &info->monspecs); 2041 fb_edid_to_monspecs(par->edid, &info->monspecs);
1964 fb_videomode_to_modelist(info->monspecs.modedb, 2042 fb_videomode_to_modelist(info->monspecs.modedb,
1965 info->monspecs.modedb_len, 2043 info->monspecs.modedb_len,
@@ -2111,13 +2189,30 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
2111 2189
2112 DBG("savagefb_suspend"); 2190 DBG("savagefb_suspend");
2113 2191
2192
2193 par->pm_state = state.event;
2194
2195 /*
2196 * For PM_EVENT_FREEZE, do not power down so the console
2197 * can remain active.
2198 */
2199 if (state.event == PM_EVENT_FREEZE) {
2200 dev->dev.power.power_state = state;
2201 return 0;
2202 }
2203
2114 acquire_console_sem(); 2204 acquire_console_sem();
2115 fb_set_suspend(info, pci_choose_state(dev, state)); 2205 fb_set_suspend(info, 1);
2116 savage_disable_mmio(par);
2117 release_console_sem();
2118 2206
2207 if (info->fbops->fb_sync)
2208 info->fbops->fb_sync(info);
2209
2210 savagefb_blank(FB_BLANK_POWERDOWN, info);
2211 savage_disable_mmio(par);
2212 pci_save_state(dev);
2119 pci_disable_device(dev); 2213 pci_disable_device(dev);
2120 pci_set_power_state(dev, pci_choose_state(dev, state)); 2214 pci_set_power_state(dev, pci_choose_state(dev, state));
2215 release_console_sem();
2121 2216
2122 return 0; 2217 return 0;
2123} 2218}
@@ -2127,22 +2222,34 @@ static int savagefb_resume (struct pci_dev* dev)
2127 struct fb_info *info = 2222 struct fb_info *info =
2128 (struct fb_info *)pci_get_drvdata(dev); 2223 (struct fb_info *)pci_get_drvdata(dev);
2129 struct savagefb_par *par = (struct savagefb_par *)info->par; 2224 struct savagefb_par *par = (struct savagefb_par *)info->par;
2225 int cur_state = par->pm_state;
2130 2226
2131 DBG("savage_resume"); 2227 DBG("savage_resume");
2132 2228
2133 pci_set_power_state(dev, 0); 2229 par->pm_state = PM_EVENT_ON;
2134 pci_restore_state(dev);
2135 if(pci_enable_device(dev))
2136 DBG("err");
2137 2230
2138 SavagePrintRegs(); 2231 /*
2232 * The adapter was not powered down coming back from a
2233 * PM_EVENT_FREEZE.
2234 */
2235 if (cur_state == PM_EVENT_FREEZE) {
2236 pci_set_power_state(dev, PCI_D0);
2237 return 0;
2238 }
2139 2239
2140 acquire_console_sem(); 2240 acquire_console_sem();
2141 2241
2242 pci_set_power_state(dev, PCI_D0);
2243 pci_restore_state(dev);
2244
2245 if(pci_enable_device(dev))
2246 DBG("err");
2247
2248 pci_set_master(dev);
2142 savage_enable_mmio(par); 2249 savage_enable_mmio(par);
2143 savage_init_hw(par); 2250 savage_init_hw(par);
2144 savagefb_set_par (info); 2251 savagefb_set_par (info);
2145 2252 savagefb_blank(FB_BLANK_UNBLANK, info);
2146 fb_set_suspend (info, 0); 2253 fb_set_suspend (info, 0);
2147 release_console_sem(); 2254 release_console_sem();
2148 2255
@@ -2276,3 +2383,6 @@ static int __init savagefb_init(void)
2276 2383
2277module_init(savagefb_init); 2384module_init(savagefb_init);
2278module_exit(savage_done); 2385module_exit(savage_done);
2386
2387module_param(mode_option, charp, 0);
2388MODULE_PARM_DESC(mode_option, "Specify initial video mode");
diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
index b6d5c71b2563..e4b4a2626da4 100644
--- a/drivers/video/sis/300vtbl.h
+++ b/drivers/video/sis/300vtbl.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * Register settings for SiS 300 series 4 * Register settings for SiS 300 series
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,31 +50,7 @@
50 * 50 *
51 */ 51 */
52 52
53static const SiS_StStruct SiS300_SModeIDTable[] = 53static const struct SiS_Ext SiS300_EModeIDTable[] =
54{
55 {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
56 {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
57 {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00, 0},
58 {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00, 0},
59 {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00, 0},
60 {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
61 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00, 0},
62 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00, 0},
63 {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00, 0},
64 {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00, 0},
65 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00, 0},
66 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00, 0},
67 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00, 0},
68 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00, 0},
69 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00, 0},
70 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00, 0},
71 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00, 0},
72 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
73 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00, 0},
74 {0xff, 0, 0, 0, 0, 0, 0, 0, 0}
75};
76
77static const SiS_ExtStruct SiS300_EModeIDTable[] =
78{ 54{
79 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */ 55 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */
80 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1}, 56 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
@@ -110,7 +86,7 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
110 {0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */ 86 {0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */
111 {0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */ 87 {0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */
112 {0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */ 88 {0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */
113 {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */ 89 {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
114 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1}, 90 {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
115 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */ 91 {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */
116 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, 92 {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
@@ -119,8 +95,8 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
119 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1}, 95 {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
120 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1}, 96 {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
121 {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1}, 97 {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
122 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 - not in BIOS! */ 98 {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 */
123 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 - not in BIOS! */ 99 {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 */
124 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */ 100 {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */
125 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */ 101 {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */
126 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */ 102 {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */
@@ -166,77 +142,77 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
166 {0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00} 142 {0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
167}; 143};
168 144
169static const SiS_Ext2Struct SiS300_RefIndex[] = 145static const struct SiS_Ext2 SiS300_RefIndex[] =
170{ 146{
171 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */ 147 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 00 */
172 {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */ 148 {0x0467,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 01 */
173 {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */ 149 {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 02 - CRT1CRTC was 0x4f */
174 {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0}, /* 03 */ 150 {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 03 */
175 {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0}, /* 04 */ 151 {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 04 */
176 {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0}, /* 05 */ 152 {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 05 */
177 {0x0047,0x11,0x4e,0x00,0x05,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */ 153 {0x0047,0x11,0x0e,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 06 - CRT1CRTC was 0x51 */
178 {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0}, /* 07 */ 154 {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 07 */
179 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */ 155 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 08 */
180 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */ 156 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 09 */
181 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */ 157 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0a */
182 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */ 158 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0b */
183 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 0c */ 159 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0c */
184 {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0}, /* 0d */ 160 {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0d */
185 {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0}, /* 0e */ 161 {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0e */
186 {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0}, /* 0f */ 162 {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0f */
187 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */ 163 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0, 0x4a, 0x49}, /* 10 */
188 {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0}, /* 11 */ 164 {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0, 0x00, 0x00}, /* 11 */
189 {0x006f,0x32,0x03,0x06,0x14,0x32, 720, 576, 0}, /* 12 */ 165 {0x006f,0x32,0x4a,0x06,0x14,0x32, 720, 576, 0, 0x00, 0x00}, /* 12 */ /* 4a was 03 */
190 {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0}, /* 13 */ 166 {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 13 */
191 {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */ 167 {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 14 */
192 {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */ 168 {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 15 - CRT1CRTC was 0x97 */
193 {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */ 169 {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 16 */
194 {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */ 170 {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 17 - CRT1CRTC was 0x59 */
195 {0x0047,0x1a,0x52,0x00,0x06,0x37,1024, 768, 0}, /* 18 */ 171 {0x0047,0x1a,0x12,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 18 */
196 {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */ 172 {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 19 - CRT1CRTC was 0x5b */
197 {0x0387,0x1c,0x4d,0x00,0x07,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */ 173 {0x0387,0x1c,0x0d,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1a - CRT1CRTC was 0x5c */
198 {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0}, /* 1b */ 174 {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1b */
199 {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0}, /* 1c */ 175 {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1c */
200 {0x0007,0x1f,0x98,0x00,0x07,0x3a,1280,1024, 0}, /* 1d */ 176 {0x0007,0x1f,0x18,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1d */
201 {0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */ 177 {0x0007,0x20,0x19,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1e - CRT1CRTC was 0x60 */
202 {0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */ 178 {0x0007,0x21,0x1a,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1f */
203 {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */ 179 {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 20 */
204 {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */ 180 {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 21 - CRT1CRTC was 0x63 */
205 {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */ 181 {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 22 */
206 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */ 182 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0, 0x4b, 0x4b}, /* 23 */
207 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */ 183 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0, 0x00, 0x00}, /* 24 */
208 {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */ 184 {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0, 0x00, 0x00}, /* 25 */
209 {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */ /* was c077 */ 185 {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0, 0x00, 0x00}, /* 26 */ /* was c077 */
210 {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */ 186 {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0, 0x00, 0x00}, /* 27 */
211 {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */ 187 {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0, 0x00, 0x00}, /* 28 */
212 {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */ 188 {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 29 - 1280x960-60 */
213 {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */ 189 {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 2a - 1280x960-85 */
214 {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */ 190 {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0, 0x00, 0x00}, /* 2b */
215 {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */ /* VCLK 0x09 */ 191 {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0, 0x00, 0x00}, /* 2c */ /* VCLK 0x09 */
216 {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0}, /* 2d */ 192 {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2d */
217 {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0}, /* 2e */ 193 {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2e */
218 {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0}, /* 2f */ 194 {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2f */
219 {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0}, /* 30 */ 195 {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 30 */
220 {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0}, /* 31 */ 196 {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 31 */
221 {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0}, /* 32 */ 197 {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 32 */
222 {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0}, /* 33 */ 198 {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 33 */
223 {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0}, /* 34 */ 199 {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 34 */
224 {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0}, /* 35 */ 200 {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 35 */
225 {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0}, /* 36 1152x864-60Hz */ 201 {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 36 1152x864-60Hz */
226 {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0}, /* 37 1152x864-75Hz */ 202 {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 37 1152x864-75Hz */
227 {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0}, /* 38 1152x864-85Hz */ 203 {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 38 1152x864-85Hz */
228 {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0}, /* 39 848x480-38Hzi */ 204 {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 39 848x480-38Hzi */
229 {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0}, /* 3a 848x480-60Hz */ 205 {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 3a 848x480-60Hz */
230 {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3b 856x480-38Hzi */ 206 {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3b 856x480-38Hzi */
231 {0xc047,0x42,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3c 856x480-60Hz */ 207 {0xc067,0x42,0x28,0x0c,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3c 856x480-60Hz */
232 {0x0067,0x43,0x3e,0x0c,0x1b,0x48,1360, 768, 0}, /* 3d 1360x768-60Hz */ 208 {0x0067,0x43,0x3e,0x0d,0x1b,0x48,1360, 768, 0, 0x00, 0x00}, /* 3d 1360x768-60Hz */
233 {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0}, /* 3e 1280x768-60Hz */ 209 {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0, 0x00, 0x00}, /* 3e 1280x768-60Hz */
234 {0x006f,0x47,0x03,0x06,0x15,0x5f, 768, 576, 0}, /* 3f 768x576 */ 210 {0x006f,0x47,0x4c,0x06,0x15,0x5f, 768, 576, 0, 0x00, 0x00}, /* 3f 768x576 */
235 {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0}, /* 40 1360x1024-59Hz (BARCO1366 only) */ 211 {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0, 0x00, 0x00}, /* 40 1360x1024-59Hz (BARCO1366 only) */
236 {0xffff, 0, 0, 0, 0, 0, 0, 0, 0} 212 {0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00}
237}; 213};
238 214
239static const SiS_VBModeStruct SiS300_VBModeIDTable[] = 215static const struct SiS_VBMode SiS300_VBModeIDTable[] =
240{ 216{
241 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 217 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
242 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 218 {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
@@ -303,53 +279,26 @@ static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
303 {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00} 279 {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
304}; 280};
305 281
306static const SiS_CRT1TableStruct SiS300_CRT1Table[] = 282static const struct SiS_CRT1Table SiS300_CRT1Table[] =
307{ 283{
308#if 1
309 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */ 284 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
310 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */ 285 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
311 0x00}}, 286 0x00}},
312#endif
313#if 0
314 {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f, /* 0x00 - corrected 320x200-72 - does not work */
315 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
316 0x00}},
317#endif
318 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */ 287 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */
319 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */ 288 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
320 0x00}}, 289 0x00}},
321#if 0
322 {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e, /* 0x01 - corrected 320x240-60 - does not work */
323 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
324 0x00}},
325#endif
326 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */ 290 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */
327 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, 291 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
328 0x01}}, 292 0x01}},
329#if 0
330 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 - corrected 400x300-60 */
331 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
332 0x01}},
333#endif
334 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, 293 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
335 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, 294 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
336 0x01}}, 295 0x01}},
337 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, 296 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
338 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, 297 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
339 0x00}}, 298 0x00}},
340#if 0
341 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 0x05 */
342 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
343 0x00}},
344#endif
345 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */ 299 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
346 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, 300 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
347 0x00}}, 301 0x00}},
348#if 0
349 {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, /* 0x06 */
350 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
351 0x00}},
352#endif
353 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */ 302 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
354 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, 303 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
355 0x00}}, 304 0x00}},
@@ -359,19 +308,9 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
359 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, 308 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
360 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, 309 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
361 0x00}}, 310 0x00}},
362#if 0
363 {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e, /* 0x09 */
364 0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
365 0x00}},
366#endif
367 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */ 311 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */
368 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05, 312 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
369 0x00}}, 313 0x00}},
370#if 0
371 {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e, /* 0x0a */
372 0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
373 0x00}},
374#endif
375 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */ 314 {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */
376 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05, 315 0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
377 0x00}}, 316 0x00}},
@@ -459,11 +398,6 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
459 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, 398 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
460 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, 399 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
461 0x00}}, 400 0x00}},
462#if 0
463 {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 0x27: 1280x960-70 - invalid! */
464 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
465 0x01}},
466#endif
467 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */ 401 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */
468 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, 402 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
469 0x01}}, 403 0x01}},
@@ -497,9 +431,9 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
497 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, 431 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
498 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, 432 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
499 0x00}}, 433 0x00}},
500 {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 0x32 */ 434 {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 0x32: 720x576, corrected to 60Hz */
501 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, 435 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
502 0x01}}, 436 0x41}},
503 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */ 437 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
504 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, 438 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
505 0x01}}, 439 0x01}},
@@ -560,18 +494,24 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
560 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */ 494 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */
561 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07, 495 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
562 0x01}}, /* 0x46 */ 496 0x01}}, /* 0x46 */
563 {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */ 497 {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
564 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, 498 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
565 0x01}}, /* 0x47 */ 499 0x41}}, /* 0x47 */
566 {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */ 500 {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */
567 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03, 501 0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
568 0x00}}, /* 0x48 */ 502 0x00}}, /* 0x48 */
569 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */ 503 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
570 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07, 504 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
571 0x41}} /* 0x49 */ 505 0x41}}, /* 0x49 */
506 {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
507 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
508 0x40}}, /* 0x4a */
509 {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
510 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
511 0x00}} /* 0x4b */
572}; 512};
573 513
574static const SiS_MCLKDataStruct SiS300_MCLKData_630[] = 514static const struct SiS_MCLKData SiS300_MCLKData_630[] =
575{ 515{
576 { 0x5a,0x64,0x80, 66}, 516 { 0x5a,0x64,0x80, 66},
577 { 0xb3,0x45,0x80, 83}, 517 { 0xb3,0x45,0x80, 83},
@@ -583,7 +523,7 @@ static const SiS_MCLKDataStruct SiS300_MCLKData_630[] =
583 { 0x37,0x61,0x80,100} 523 { 0x37,0x61,0x80,100}
584}; 524};
585 525
586static const SiS_MCLKDataStruct SiS300_MCLKData_300[] = 526static const struct SiS_MCLKData SiS300_MCLKData_300[] =
587{ 527{
588 { 0x68,0x43,0x80,125}, 528 { 0x68,0x43,0x80,125},
589 { 0x68,0x43,0x80,125}, 529 { 0x68,0x43,0x80,125},
@@ -595,7 +535,7 @@ static const SiS_MCLKDataStruct SiS300_MCLKData_300[] =
595 { 0x37,0x61,0x80,100} 535 { 0x37,0x61,0x80,100}
596}; 536};
597 537
598static SiS_VCLKDataStruct SiS300_VCLKData[] = 538static struct SiS_VCLKData SiS300_VCLKData[] =
599{ 539{
600 { 0x1b,0xe1, 25}, /* 0x00 */ 540 { 0x1b,0xe1, 25}, /* 0x00 */
601 { 0x4e,0xe4, 28}, /* 0x01 */ 541 { 0x4e,0xe4, 28}, /* 0x01 */
@@ -669,53 +609,26 @@ static SiS_VCLKDataStruct SiS300_VCLKData[] =
669 { 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */ 609 { 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */
670 { 0x70,0x29, 81}, /* 0x46 */ /* unused */ 610 { 0x70,0x29, 81}, /* 0x46 */ /* unused */
671 { 0, 0, 0}, /* 0x47 custom (will be filled out) */ 611 { 0, 0, 0}, /* 0x47 custom (will be filled out) */
672 { 0xce,0x25,189} /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */ 612 { 0xce,0x25,189}, /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */
613 { 0x15,0xe1, 20}, /* 0x49 */ /* 640x400@60 (fake, not actually used) */
614 { 0x5f,0xc6, 33}, /* 0x4a */ /* 720x576@60 */
615 { 0x37,0x5a, 10}, /* 0x4b */ /* 320x200@60 (fake, not actually used) */
616 { 0x2b,0xc2, 35} /* 0x4c */ /* 768@576@60 */
673}; 617};
674 618
675#ifdef LINUX_KERNEL 619static const unsigned char SiS300_SR15[4 * 8] =
676static UCHAR SiS300_SR07 = 0x10;
677#endif
678
679static const DRAM4Type SiS300_SR15[8] =
680{ 620{
681 {0x01,0x09,0xa3,0x00}, 621 0x01,0x09,0xa3,0x00,
682 {0x43,0x43,0x43,0x00}, 622 0x43,0x43,0x43,0x00,
683 {0x1e,0x1e,0x1e,0x00}, 623 0x1e,0x1e,0x1e,0x00,
684 {0x2a,0x2a,0x2a,0x00}, 624 0x2a,0x2a,0x2a,0x00,
685 {0x06,0x06,0x06,0x00}, 625 0x06,0x06,0x06,0x00,
686 {0x00,0x00,0x00,0x00}, 626 0x00,0x00,0x00,0x00,
687 {0x00,0x00,0x00,0x00}, 627 0x00,0x00,0x00,0x00,
688 {0x00,0x00,0x00,0x00} 628 0x00,0x00,0x00,0x00
689}; 629};
690 630
691#ifdef LINUX_KERNEL 631static const struct SiS_PanelDelayTbl SiS300_PanelDelayTbl[] =
692static UCHAR SiS300_SR1F = 0x00;
693static UCHAR SiS300_SR21 = 0x16;
694static UCHAR SiS300_SR22 = 0xb2;
695static UCHAR SiS300_SR23 = 0xf6;
696static UCHAR SiS300_SR24 = 0x0d;
697static UCHAR SiS300_SR25[] = {0x0,0x0};
698static UCHAR SiS300_SR31 = 0x00;
699static UCHAR SiS300_SR32 = 0x11;
700static UCHAR SiS300_SR33 = 0x00;
701static UCHAR SiS300_CRT2Data_1_2 = 0x40;
702static UCHAR SiS300_CRT2Data_4_D = 0x00;
703static UCHAR SiS300_CRT2Data_4_E = 0x00;
704static UCHAR SiS300_CRT2Data_4_10 = 0x80;
705
706static const USHORT SiS300_RGBSenseData = 0xd1;
707static const USHORT SiS300_VideoSenseData = 0xb3;
708static const USHORT SiS300_YCSenseData = 0xb9;
709static const USHORT SiS300_RGBSenseData2 = 0x0190;
710static const USHORT SiS300_VideoSenseData2 = 0x0174;
711static const USHORT SiS300_YCSenseData2 = 0x016b;
712
713static const DRAM4Type SiS300_CR40[5];
714
715static UCHAR SiS300_CR49[2];
716#endif
717
718static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
719{ 632{
720 {{0x05,0xaa}}, 633 {{0x05,0xaa}},
721 {{0x05,0x14}}, 634 {{0x05,0x14}},
@@ -735,33 +648,11 @@ static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
735 {{0x05,0x60}} 648 {{0x05,0x60}}
736}; 649};
737 650
738#if 0
739static const SiS_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
740{
741 {{0x05,0xaa}},
742 {{0x05,0x14}},
743 {{0x05,0x36}},
744 {{0x05,0x14}},
745 {{0x05,0x14}},
746 {{0x05,0x14}},
747 {{0x05,0x90}},
748 {{0x05,0x90}},
749 {{0x05,0x14}},
750 {{0x05,0x14}},
751 {{0x05,0x14}},
752 {{0x05,0x14}}, /* 2.07a (JVC): 14,96 */
753 {{0x05,0x28}}, /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
754 {{0x05,0x14}},
755 {{0x05,0x14}}, /* Some BIOSes: 05, 40 */
756 {{0x05,0x60}}
757};
758#endif
759
760/**************************************************************/ 651/**************************************************************/
761/* SIS VIDEO BRIDGE ----------------------------------------- */ 652/* SIS VIDEO BRIDGE ----------------------------------------- */
762/**************************************************************/ 653/**************************************************************/
763 654
764static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] = 655static const struct SiS_LCDData SiS300_St2LCD1024x768Data[] =
765{ 656{
766 { 62, 25, 800, 546,1344, 806}, 657 { 62, 25, 800, 546,1344, 806},
767 { 32, 15, 930, 546,1344, 806}, 658 { 32, 15, 930, 546,1344, 806},
@@ -772,7 +663,7 @@ static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] =
772 { 1, 1,1344, 806,1344, 806} 663 { 1, 1,1344, 806,1344, 806}
773}; 664};
774 665
775static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] = 666static const struct SiS_LCDData SiS300_ExtLCD1024x768Data[] =
776{ 667{
777 { 12, 5, 896, 512,1344, 806}, 668 { 12, 5, 896, 512,1344, 806},
778 { 12, 5, 896, 510,1344, 806}, 669 { 12, 5, 896, 510,1344, 806},
@@ -789,7 +680,7 @@ static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
789 { 1, 1,1344, 806,1344, 806} 680 { 1, 1,1344, 806,1344, 806}
790}; 681};
791 682
792static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] = 683static const struct SiS_LCDData SiS300_St2LCD1280x1024Data[] =
793{ 684{
794 { 22, 5, 800, 510,1650,1088}, 685 { 22, 5, 800, 510,1650,1088},
795 { 22, 5, 800, 510,1650,1088}, 686 { 22, 5, 800, 510,1650,1088},
@@ -801,7 +692,7 @@ static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
801 { 1, 1,1688,1066,1688,1066} 692 { 1, 1,1688,1066,1688,1066}
802}; 693};
803 694
804static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] = 695static const struct SiS_LCDData SiS300_ExtLCD1280x1024Data[] =
805{ 696{
806 { 211, 60,1024, 501,1688,1066}, 697 { 211, 60,1024, 501,1688,1066},
807 { 211, 60,1024, 508,1688,1066}, 698 { 211, 60,1024, 508,1688,1066},
@@ -813,53 +704,116 @@ static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
813 { 1, 1,1688,1066,1688,1066} 704 { 1, 1,1688,1066,1688,1066}
814}; 705};
815 706
816static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] = 707static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_1[] =
817{ /* VESA Timing */ 708{ /* VESA Timing */
818 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, 709 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
819 {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, 710 {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
820 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}}, 711 {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
821 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 712 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
822 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}, 713 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
823 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}, 714 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
824 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}} 715 {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
825}; 716};
826 717
827static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] = 718static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_2[] =
828{ /* Non-VESA */ 719{ /* Non-VESA */
829 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 720 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
830 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 721 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
831 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 722 {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
832 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 723 {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
833 {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 724 {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
834 {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 725 {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
835 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}} 726 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
836};
837
838static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
839{
840 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
841};
842
843static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
844{
845 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
846};
847
848static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
849{
850 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
851}; 727};
852 728
853static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] = 729static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_3[] =
854{ 730{
855 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} 731 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
856}; 732};
857 733
858/**************************************************************/ 734/**************************************************************/
859/* LVDS/Chrontel -------------------------------------------- */ 735/* LVDS/Chrontel -------------------------------------------- */
860/**************************************************************/ 736/**************************************************************/
861 737
862static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] = 738/* Custom data for Barco iQ R series */
739static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_1[]=
740{
741 { 832, 438,1331, 806},
742 { 832, 388,1331, 806},
743 { 832, 438,1331, 806},
744 { 832, 388,1331, 806},
745 { 832, 518,1331, 806},
746 {1050, 638,1344, 806},
747 {1344, 806,1344, 806},
748 {1688,1066,1688,1066},
749 {1688,1066,1688,1066} /* 1360x1024 */
750};
751
752/* Custom data for Barco iQ R series */
753static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_2[]=
754{
755 {1344, 806,1344, 806},
756 {1344, 806,1344, 806},
757 {1344, 806,1344, 806},
758 {1344, 806,1344, 806},
759 {1344, 806,1344, 806},
760 {1344, 806,1344, 806},
761 {1344, 806,1344, 806},
762 {1688,1066,1688,1066},
763 {1688,1066,1688,1066} /* 1360x1024 */
764};
765
766/* Custom data for Barco iQ G series */
767static const struct SiS_LVDSData SiS300_LVDSBARCO1024Data_1[]=
768{
769 { 832, 438,1331, 806},
770 { 832, 409,1331, 806},
771 { 832, 438,1331, 806},
772 { 832, 409,1331, 806},
773 { 832, 518,1331, 806}, /* 640x480 */
774 {1050, 638,1344, 806}, /* 800x600 */
775 {1344, 806,1344, 806}, /* 1024x768 */
776};
777
778/* Custom data for 848x480 and 856x480 parallel LVDS panels */
779static const struct SiS_LVDSData SiS300_LVDS848x480Data_1[]=
780{
781 { 0, 0, 0, 0},
782 { 0, 0, 0, 0},
783 { 0, 0, 0, 0},
784 { 0, 0, 0, 0},
785 {1088, 525,1088, 525}, /* 640x480 TODO */
786 {1088, 525,1088, 525}, /* 800x600 TODO */
787 {1088, 525,1088, 525}, /* 1024x768 TODO */
788 { 0, 0, 0, 0},
789 { 0, 0, 0, 0},
790 { 0, 0, 0, 0},
791 { 0, 0, 0, 0},
792 {1088, 525,1088, 525}, /* 848x480 */
793 {1088, 525,1088, 525}, /* 856x480 */
794 {1088, 525,1088, 525} /* 1360x768 TODO */
795};
796
797/* Custom data for 848x480 parallel panel */
798static const struct SiS_LVDSData SiS300_LVDS848x480Data_2[]=
799{
800 { 0, 0, 0, 0},
801 { 0, 0, 0, 0},
802 { 0, 0, 0, 0},
803 { 0, 0, 0, 0},
804 {1088, 525,1088, 525}, /* 640x480 */
805 {1088, 525,1088, 525}, /* 800x600 */
806 {1088, 525,1088, 525}, /* 1024x768 */
807 { 0, 0, 0, 0},
808 { 0, 0, 0, 0},
809 { 0, 0, 0, 0},
810 { 0, 0, 0, 0},
811 {1088, 525,1088, 525}, /* 848x480 */
812 {1088, 525,1088, 525}, /* 856x480 */
813 {1088, 525,1088, 525} /* 1360x768 TODO */
814};
815
816static const struct SiS_LVDSData SiS300_CHTVUPALData[] =
863{ 817{
864 {1008, 625,1008, 625}, 818 {1008, 625,1008, 625},
865 {1008, 625,1008, 625}, 819 {1008, 625,1008, 625},
@@ -869,7 +823,7 @@ static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] =
869 { 936, 836, 936, 836} 823 { 936, 836, 936, 836}
870}; 824};
871 825
872static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] = 826static const struct SiS_LVDSData SiS300_CHTVOPALData[] =
873{ 827{
874 {1008, 625,1008, 625}, 828 {1008, 625,1008, 625},
875 {1008, 625,1008, 625}, 829 {1008, 625,1008, 625},
@@ -879,7 +833,7 @@ static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] =
879 { 960, 750, 960, 750} 833 { 960, 750, 960, 750}
880}; 834};
881 835
882static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] = 836static const struct SiS_LVDSData SiS300_CHTVSOPALData[] =
883{ 837{
884 {1008, 625,1008, 625}, 838 {1008, 625,1008, 625},
885 {1008, 625,1008, 625}, 839 {1008, 625,1008, 625},
@@ -889,486 +843,8 @@ static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] =
889 { 944, 625, 944, 625} 843 { 944, 625, 944, 625}
890}; 844};
891 845
892 846/* Custom des data for Barco iQ R200/300/400 (BIOS 2.00.07) */
893static const SiS_LVDSDesStruct SiS300_PanelType00_1[] = 847static const struct SiS_LVDSDes SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
894{
895 { 1059, 626 }, /* 2.08 */
896 { 1059, 624 },
897 { 1059, 626 },
898 { 1059, 624 },
899 { 1059, 624 },
900 { 0, 627 },
901 { 0, 627 },
902 { 0, 0 },
903 { 0, 0 }
904#if 0
905 {0, 626},
906 {0, 624},
907 {0, 626},
908 {0, 624},
909 {0, 624},
910 {0, 627},
911 {0, 627},
912 {0, 0},
913 {0, 0}
914#endif
915};
916
917static const SiS_LVDSDesStruct SiS300_PanelType01_1[] =
918{
919 { 0, 0 }, /* 2.08 */
920 { 0, 0 },
921 { 0, 0 },
922 { 0, 0 },
923 { 0, 0 },
924 { 0, 0 },
925 { 0, 0 },
926 { 0, 0 },
927 { 0, 0 }
928#if 0
929 {1343, 798},
930 {1343, 794},
931 {1343, 798},
932 {1343, 794},
933 {1343, 0},
934 {1343, 0},
935 { 0, 805},
936 { 0, 794},
937 { 0, 0}
938#endif
939};
940
941static const SiS_LVDSDesStruct SiS300_PanelType02_1[] =
942{
943 { 1059, 626 }, /* 2.08 */
944 { 1059, 624 },
945 { 1059, 626 },
946 { 1059, 624 },
947 { 1059, 624 },
948 { 0, 627 },
949 { 0, 627 },
950 { 0, 0 },
951 { 0, 0 }
952#if 0
953 {0, 626},
954 {0, 624},
955 {0, 626},
956 {0, 624},
957 {0, 624},
958 {0, 627},
959 {0, 627},
960 {0, 0},
961 {0, 0}
962#endif
963};
964
965static const SiS_LVDSDesStruct SiS300_PanelType03_1[] =
966{
967 { 8, 436},
968 { 8, 440},
969 { 8, 436},
970 { 8, 440},
971 { 8, 512},
972 {1343, 798},
973 {1343, 794},
974 {1343, 798},
975 {1343, 794}
976};
977
978static const SiS_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
979{
980 {1343, 798},
981 {1343, 794},
982 {1343, 798},
983 {1343, 794},
984 {1343, 0},
985 {1343, 0},
986 { 0, 805},
987 { 0, 794},
988 { 0, 0}
989};
990
991static const SiS_LVDSDesStruct SiS300_PanelType05_1[] =
992{
993 {1343, 798},
994 {1343, 794},
995 {1343, 798},
996 {1343, 794},
997 {1343, 0},
998 {1343, 0},
999 { 0, 805},
1000 { 0, 794},
1001 { 0, 0}
1002};
1003
1004static const SiS_LVDSDesStruct SiS300_PanelType06_1[] = /* Clevo Trumpion 1024x768 */
1005{
1006 {1343, 798},
1007 {1343, 794},
1008 {1343, 798},
1009 {1343, 794},
1010 {1343, 0},
1011 {1343, 0},
1012 { 0, 805},
1013 { 0, 794},
1014 { 0, 0}
1015};
1016
1017static const SiS_LVDSDesStruct SiS300_PanelType07_1[] =
1018{
1019 {1343, 798},
1020 {1343, 794},
1021 {1343, 798},
1022 {1343, 794},
1023 {1343, 0},
1024 {1343, 0},
1025 { 0, 805},
1026 { 0, 794},
1027 { 0, 0}
1028};
1029
1030static const SiS_LVDSDesStruct SiS300_PanelType08_1[] =
1031{
1032 {1059, 626},
1033 {1059, 624},
1034 {1059, 626},
1035 {1059, 624},
1036 {1059, 624},
1037 { 0, 627},
1038 { 0, 627},
1039 { 0, 0},
1040 { 0, 0}
1041};
1042
1043static const SiS_LVDSDesStruct SiS300_PanelType09_1[] =
1044{
1045 {1343, 798},
1046 {1343, 794},
1047 {1343, 798},
1048 {1343, 794},
1049 {1343, 0},
1050 {1343, 0},
1051 { 0, 805},
1052 { 0, 794},
1053 { 0, 0}
1054};
1055
1056static const SiS_LVDSDesStruct SiS300_PanelType0a_1[] =
1057{
1058 {1059, 626},
1059 {1059, 624},
1060 {1059, 626},
1061 {1059, 624},
1062 {1059, 624},
1063 { 0, 627},
1064 { 0, 627},
1065 { 0, 0},
1066 { 0, 0}
1067};
1068
1069static const SiS_LVDSDesStruct SiS300_PanelType0b_1[] =
1070{
1071 {1343, 0},
1072 {1343, 0},
1073 {1343, 0},
1074 {1343, 0},
1075 {1343, 0},
1076 {1343, 0},
1077 { 0, 799},
1078 { 0, 0},
1079 { 0, 0}
1080};
1081
1082static const SiS_LVDSDesStruct SiS300_PanelType0c_1[] =
1083{
1084 {1343, 798},
1085 {1343, 794},
1086 {1343, 798},
1087 {1343, 794},
1088 {1343, 0},
1089 {1343, 0},
1090 { 0, 805},
1091 { 0, 794},
1092 { 0, 0}
1093};
1094
1095static const SiS_LVDSDesStruct SiS300_PanelType0d_1[] =
1096{
1097 {1343, 798},
1098 {1343, 794},
1099 {1343, 798},
1100 {1343, 794},
1101 {1343, 0},
1102 {1343, 0},
1103 { 0, 805},
1104 { 0, 794},
1105 { 0, 0}
1106};
1107
1108static const SiS_LVDSDesStruct SiS300_PanelType0e_1[] =
1109{
1110 {1343, 798},
1111 {1343, 794},
1112 {1343, 798},
1113 {1343, 794},
1114 {1343, 0}, /* 640x480 */
1115 {1343, 0}, /* 800x600 */
1116 { 0, 805}, /* 1024x768 */
1117 { 0, 794}, /* 1280x1024 */
1118 { 0, 0} /* 1280x960 - not applicable */
1119};
1120
1121static const SiS_LVDSDesStruct SiS300_PanelType0f_1[] =
1122{
1123 {1343, 798},
1124 {1343, 794},
1125 {1343, 798},
1126 {1343, 794},
1127 {1343, 0},
1128 {1343, 0},
1129 { 0, 805},
1130 { 0, 794},
1131 { 0, 0}
1132};
1133
1134static const SiS_LVDSDesStruct SiS300_PanelType00_2[] =
1135{
1136 {976, 527},
1137 {976, 502},
1138 {976, 527},
1139 {976, 502},
1140 {976, 567},
1141 { 0, 627},
1142 { 0, 627},
1143 { 0, 0},
1144 { 0, 0}
1145};
1146
1147static const SiS_LVDSDesStruct SiS300_PanelType01_2[] =
1148{
1149 {1152, 622},
1150 {1152, 597},
1151 {1152, 622},
1152 {1152, 597},
1153 {1152, 662},
1154 {1232, 722},
1155 { 0, 805},
1156 { 0, 794},
1157 { 0, 0}
1158};
1159
1160static const SiS_LVDSDesStruct SiS300_PanelType02_2[] =
1161{
1162 {976, 527},
1163 {976, 502},
1164 {976, 527},
1165 {976, 502},
1166 {976, 567},
1167 { 0, 627},
1168 { 0, 627},
1169 { 0, 0},
1170 { 0, 0}
1171};
1172
1173static const SiS_LVDSDesStruct SiS300_PanelType03_2[] =
1174{
1175 {1152, 622},
1176 {1152, 597},
1177 {1152, 622},
1178 {1152, 597},
1179 {1152, 662},
1180 {1232, 722},
1181 { 0, 805},
1182 {1152, 622},
1183 {1152, 597}
1184};
1185
1186static const SiS_LVDSDesStruct SiS300_PanelType04_2[] =
1187{
1188 {1152, 622},
1189 {1152, 597},
1190 {1152, 622},
1191 {1152, 597},
1192 {1152, 662},
1193 {1232, 722},
1194 { 0, 805},
1195 { 0, 794},
1196 { 0, 0}
1197};
1198
1199static const SiS_LVDSDesStruct SiS300_PanelType05_2[] =
1200{
1201 {1152, 622},
1202 {1152, 597},
1203 {1152, 622},
1204 {1152, 597},
1205 {1152, 662},
1206 {1232, 722},
1207 { 0, 805},
1208 { 0, 794},
1209 { 0, 0}
1210};
1211
1212static const SiS_LVDSDesStruct SiS300_PanelType06_2[] =
1213{
1214 {1152, 622},
1215 {1152, 597},
1216 {1152, 622},
1217 {1152, 597},
1218 {1152, 662},
1219 {1232, 722},
1220 { 0, 805},
1221 { 0, 794},
1222 { 0, 0}
1223};
1224
1225static const SiS_LVDSDesStruct SiS300_PanelType07_2[] =
1226{
1227 {1152, 622},
1228 {1152, 597},
1229 {1152, 622},
1230 {1152, 597},
1231 {1152, 662},
1232 {1232, 722},
1233 { 0, 805},
1234 { 0, 794},
1235 { 0, 0}
1236};
1237
1238static const SiS_LVDSDesStruct SiS300_PanelType08_2[] =
1239{
1240 {976, 527},
1241 {976, 502},
1242 {976, 527},
1243 {976, 502},
1244 {976, 567},
1245 { 0, 627},
1246 { 0, 627},
1247 { 0, 0},
1248 { 0, 0}
1249};
1250
1251static const SiS_LVDSDesStruct SiS300_PanelType09_2[] =
1252{
1253 {1152, 622},
1254 {1152, 597},
1255 {1152, 622},
1256 {1152, 597},
1257 {1152, 662},
1258 {1232, 722},
1259 { 0, 805},
1260 { 0, 794},
1261 { 0, 0}
1262};
1263
1264static const SiS_LVDSDesStruct SiS300_PanelType0a_2[] =
1265{
1266 {976, 527},
1267 {976, 502},
1268 {976, 527},
1269 {976, 502},
1270 {976, 567},
1271 { 0, 627},
1272 { 0, 627},
1273 { 0, 0},
1274 { 0, 0}
1275};
1276
1277static const SiS_LVDSDesStruct SiS300_PanelType0b_2[] =
1278{
1279 { 1152, 700},
1280 { 1152, 675},
1281 { 1152, 700},
1282 { 1152, 675},
1283 { 1152, 740},
1284 { 1232, 799},
1285 { 0, 799},
1286 { 0, 0},
1287 { 0, 0}
1288};
1289
1290static const SiS_LVDSDesStruct SiS300_PanelType0c_2[] =
1291{
1292 {1152, 622},
1293 {1152, 597},
1294 {1152, 622},
1295 {1152, 597},
1296 {1152, 662},
1297 {1232, 722},
1298 { 0, 805},
1299 { 0, 794},
1300 { 0, 0}
1301};
1302
1303static const SiS_LVDSDesStruct SiS300_PanelType0d_2[] =
1304{
1305 {1152, 622},
1306 {1152, 597},
1307 {1152, 622},
1308 {1152, 597},
1309 {1152, 662},
1310 {1232, 722},
1311 { 0, 805},
1312 { 0, 794},
1313 { 0, 0}
1314};
1315
1316static const SiS_LVDSDesStruct SiS300_PanelType0e_2[] =
1317{
1318 {1152, 622},
1319 {1152, 597},
1320 {1152, 622},
1321 {1152, 597},
1322 {1152, 662},
1323 {1232, 722},
1324 { 0, 805},
1325 { 0, 794},
1326 { 0, 0}
1327};
1328
1329static const SiS_LVDSDesStruct SiS300_PanelType0f_2[] =
1330{
1331 {1152, 622},
1332 {1152, 597},
1333 {1152, 622},
1334 {1152, 597},
1335 {1152, 662},
1336 {1232, 722},
1337 { 0, 805},
1338 { 0, 794},
1339 { 0, 0}
1340};
1341
1342static const SiS_LVDSDesStruct SiS300_PanelTypeNS_1[]=
1343{
1344 { 0, 0},
1345 { 0, 0},
1346 { 0, 0},
1347 { 0, 0},
1348 { 0, 0},
1349 { 0, 0},
1350 { 0, 805},
1351 { 0, 0},
1352 { 0, 0},
1353 { 0, 0}
1354};
1355
1356static const SiS_LVDSDesStruct SiS300_PanelTypeNS_2[] =
1357{
1358 { 0 , 0},
1359 { 0 , 0},
1360 { 0 , 0},
1361 { 0 , 0},
1362 { 0 , 0},
1363 { 0 , 0},
1364 { 0 , 0},
1365 { 0 , 0},
1366 { 0 , 0},
1367 { 0 , 0}
1368};
1369
1370/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
1371static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
1372{ 848{
1373 {1330, 798}, /* 320x200 */ 849 {1330, 798}, /* 320x200 */
1374 {1330, 794}, 850 {1330, 794},
@@ -1381,7 +857,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x102
1381 { 0, 0} /* 1360x1024 */ 857 { 0, 0} /* 1360x1024 */
1382}; 858};
1383 859
1384static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] = 860static const struct SiS_LVDSDes SiS300_PanelType04_2a[] =
1385{ 861{
1386 {1152, 622}, 862 {1152, 622},
1387 {1152, 597}, 863 {1152, 597},
@@ -1394,8 +870,8 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] =
1394 { 0, 0} 870 { 0, 0}
1395}; 871};
1396 872
1397/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */ 873/* Custom des data for Barco iQ G200/300/400 (BIOS 2.00.07) */
1398static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */ 874static const struct SiS_LVDSDes SiS300_PanelType04_1b[] = /* 1024x768 */
1399{ 875{
1400 {1330, 798}, /* 320x200 */ 876 {1330, 798}, /* 320x200 */
1401 {1330, 794}, 877 {1330, 794},
@@ -1406,7 +882,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
1406 { 0, 805} /* 1024x768 / 512x384 */ 882 { 0, 805} /* 1024x768 / 512x384 */
1407}; 883};
1408 884
1409static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] = 885static const struct SiS_LVDSDes SiS300_PanelType04_2b[] =
1410{ 886{
1411 {1152, 622}, 887 {1152, 622},
1412 {1152, 597}, 888 {1152, 597},
@@ -1419,376 +895,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] =
1419 895
1420/* CRT1 CRTC for slave modes */ 896/* CRT1 CRTC for slave modes */
1421 897
1422static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] = 898static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UNTSC[] =
1423{
1424 {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
1425 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1426 0x00 }},
1427 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1428 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1429 0x00 }},
1430 {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
1431 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1432 0x00 }},
1433 {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
1434 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1435 0x00 }},
1436 {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
1437 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1438 0x00 }},
1439 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1440 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1441 0x01 }}
1442};
1443
1444static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
1445{
1446 {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
1447 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
1448 0x00 }},
1449 {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
1450 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
1451 0x00 }},
1452 {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
1453 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
1454 0x00 }},
1455 {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
1456 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
1457 0x00 }},
1458 {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
1459 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
1460 0x00 }},
1461 {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
1462 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
1463 0x01 }}
1464};
1465
1466static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
1467{
1468 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1469 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1470 0x00}},
1471 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1472 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1473 0x00}},
1474 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1475 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1476 0x00}},
1477 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1478 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1479 0x00}},
1480 {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
1481 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1482 0x00}},
1483 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1484 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1485 0x01}},
1486 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1487 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1488 0x01}}
1489};
1490
1491static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
1492{
1493 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1494 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1495 0x00 }},
1496 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1497 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
1498 0x00}},
1499 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1500 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1501 0x00}},
1502 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1503 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
1504 0x00}},
1505 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1506 0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
1507 0x00}},
1508 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1509 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
1510 0x01}},
1511 {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
1512 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1513 0x01 }}
1514
1515#if 0
1516 {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
1517 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1518 0x00 }},
1519 {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
1520 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
1521 0x00}},
1522 {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
1523 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1524 0x00}},
1525 {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
1526 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
1527 0x00}},
1528 {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
1529 0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
1530 0x00}},
1531 {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
1532 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
1533 0x01}},
1534 {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
1535 0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
1536 0x01 }}
1537#endif
1538};
1539
1540static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
1541{
1542 {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
1543 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1544 0x00 }},
1545 {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
1546 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1547 0x00 }},
1548 {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
1549 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1550 0x00 }},
1551 {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
1552 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1553 0x00 }},
1554 {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
1555 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1556 0x00 }},
1557 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1558 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1559 0x01 }},
1560 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1561 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1562 0x01 }}
1563};
1564
1565static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
1566{
1567 {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
1568 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
1569 0x00 }},
1570 {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
1571 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
1572 0x00 }},
1573 {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
1574 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
1575 0x00 }},
1576 {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
1577 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
1578 0x00 }},
1579 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1580 0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
1581 0x00 }},
1582 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1583 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1584 0x01 }},
1585 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1586 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1587 0x01 }}
1588};
1589
1590static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] =
1591{
1592 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1593 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
1594 0x00 }},
1595 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1596 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
1597 0x00 }},
1598 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1599 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
1600 0x00 }},
1601 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1602 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
1603 0x00 }},
1604 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
1605 0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
1606 0x00 }},
1607 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1608 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1609 0x01 }}
1610};
1611
1612static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
1613{
1614 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1615 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
1616 0x00 }},
1617 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1618 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
1619 0x00 }},
1620 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
1621 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
1622 0x00 }},
1623 {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
1624 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
1625 0x00 }},
1626 {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
1627 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
1628 0x00 }},
1629 {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
1630 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
1631 0x01 }}
1632};
1633
1634static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
1635{
1636 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1637 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1638 0x00 }},
1639 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1640 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1641 0x00 }},
1642 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1643 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1644 0x00 }},
1645 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1646 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1647 0x00 }},
1648 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1649 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1650 0x00 }},
1651 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1652 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1653 0x01 }},
1654 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1655 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1656 0x01 }}
1657};
1658
1659static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
1660{
1661 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1662 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1663 0x00 }},
1664 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1665 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1666 0x00 }},
1667 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1668 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1669 0x00 }},
1670 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1671 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1672 0x00 }},
1673 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1674 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1675 0x00 }},
1676 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1677 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1678 0x01 }},
1679 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1680 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1681 0x01 }}
1682};
1683
1684static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
1685{
1686 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1687 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1688 0x00 }},
1689 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1690 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1691 0x00 }},
1692 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1693 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1694 0x00 }},
1695 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1696 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1697 0x00 }},
1698 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1699 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1700 0x00 }},
1701 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1702 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1703 0x01 }},
1704 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1705 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1706 0x01 }}
1707};
1708
1709static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
1710{
1711 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1712 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1713 0x00 }},
1714 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1715 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1716 0x00 }},
1717 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1718 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1719 0x00 }},
1720 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1721 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1722 0x00 }},
1723 {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
1724 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1725 0x00 }},
1726 {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
1727 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1728 0x01 }},
1729 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1730 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1731 0x01}}
1732};
1733
1734static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1[] =
1735{
1736 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1737 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1738 0x00}},
1739 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1740 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1741 0x00}},
1742 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1743 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1744 0x00}},
1745 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
1746 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
1747 0x00}},
1748 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1749 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
1750 0x00}},
1751 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1752 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1753 0x01}},
1754 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1755 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1756 0x01}},
1757 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1758 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1759 0x01}},
1760 {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
1761 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
1762 0x01}}
1763};
1764
1765static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1_H[] =
1766{
1767 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1768 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1769 0x00}},
1770 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1771 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1772 0x00}},
1773 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1774 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1775 0x00}},
1776 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
1777 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
1778 0x00}},
1779 {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
1780 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1781 0x00}},
1782 {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
1783 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
1784 0x01}},
1785 {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
1786 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1787 0x01}}
1788};
1789
1790
1791static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
1792{ 899{
1793 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, 900 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
1794 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, 901 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -1810,7 +917,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
1810 0x01 }} 917 0x01 }}
1811}; 918};
1812 919
1813static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] = 920static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1ONTSC[] =
1814{ 921{
1815 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e, 922 {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
1816 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, 923 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -1832,7 +939,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
1832 0x01 }} 939 0x01 }}
1833}; 940};
1834 941
1835static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] = 942static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UPAL[] =
1836{ 943{
1837 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 944 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1838 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, 945 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1854,7 +961,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
1854 0x01 }} 961 0x01 }}
1855}; 962};
1856 963
1857static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] = 964static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1OPAL[] =
1858{ 965{
1859 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 966 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1860 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, 967 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1876,7 +983,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
1876 0x01 }} 983 0x01 }}
1877}; 984};
1878 985
1879static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] = 986static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1SOPAL[] =
1880{ 987{
1881 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 988 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
1882 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, 989 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1898,7 +1005,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
1898 0x01 }} 1005 0x01 }}
1899}; 1006};
1900 1007
1901static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] = 1008static const struct SiS_CHTVRegData SiS300_CHTVReg_UNTSC[] =
1902{ 1009{
1903 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, 1010 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1904 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, 1011 {{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1908,7 +1015,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
1908 {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */ 1015 {{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
1909}; 1016};
1910 1017
1911static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] = 1018static const struct SiS_CHTVRegData SiS300_CHTVReg_ONTSC[] =
1912{ 1019{
1913 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, 1020 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
1914 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}}, 1021 {{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1918,7 +1025,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
1918 {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */ 1025 {{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
1919}; 1026};
1920 1027
1921static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] = 1028static const struct SiS_CHTVRegData SiS300_CHTVReg_UPAL[] =
1922{ 1029{
1923 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, 1030 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1924 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, 1031 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1929,7 +1036,7 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
1929 1036
1930}; 1037};
1931 1038
1932static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = 1039static const struct SiS_CHTVRegData SiS300_CHTVReg_OPAL[] =
1933{ 1040{
1934 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */ 1041 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1935 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, 1042 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
@@ -1940,26 +1047,26 @@ static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
1940 1047
1941}; 1048};
1942 1049
1943static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] = 1050static const struct SiS_CHTVRegData SiS300_CHTVReg_SOPAL[] =
1944{ 1051{
1945 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */ 1052 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
1946 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, 1053 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1947 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, 1054 {{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
1948 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}}, 1055 {{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
1949 {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */ 1056 {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 13: 640x480 PAL 5/4 */
1950 {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */ 1057 {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 19: 800x600 PAL 1/1 */
1951}; 1058};
1952 1059
1953static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e}; 1060static const unsigned char SiS300_CHTVVCLKUNTSC[] = { 0x29,0x29,0x29,0x29,0x2a,0x2e };
1954 1061
1955static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b}; 1062static const unsigned char SiS300_CHTVVCLKONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
1956 1063
1957static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b}; 1064static const unsigned char SiS300_CHTVVCLKSONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
1958 1065
1959static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31}; 1066static const unsigned char SiS300_CHTVVCLKUPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x2f,0x31 };
1960 1067
1961static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32}; 1068static const unsigned char SiS300_CHTVVCLKOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x30,0x32 };
1962 1069
1963static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29}; 1070static const unsigned char SiS300_CHTVVCLKSOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x36,0x29 };
1964 1071
1965 1072
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
index 2c71d048f7c4..54fcbbf4ef63 100644
--- a/drivers/video/sis/310vtbl.h
+++ b/drivers/video/sis/310vtbl.h
@@ -1,9 +1,9 @@
1/* $XFree86$ */ 1/* $XFree86$ */
2/* $XdotOrg$ */ 2/* $XdotOrg$ */
3/* 3/*
4 * Register settings for SiS 315/330 series 4 * Register settings for SiS 315/330/340 series
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,37 +50,13 @@
50 * 50 *
51 */ 51 */
52 52
53static const SiS_StStruct SiS310_SModeIDTable[]= 53static const struct SiS_Ext SiS310_EModeIDTable[] =
54{
55 {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
56 {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
57 {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01, 0x40},
58 {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02, 0x40},
59 {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02, 0x40},
60 {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03, 0x40},
61 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04, 0x40},
62 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05, 0x40},
63 {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03, 0x40},
64 {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03, 0x40},
65 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04, 0x40},
66 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05, 0x40},
67 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05, 0x40},
68 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05, 0x40},
69 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05, 0x40},
70 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05, 0x40},
71 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04, 0x40},
72 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05, 0x40},
73 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05, 0x40},
74 {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
75};
76
77static const SiS_ExtStruct SiS310_EModeIDTable[]=
78{ 54{
79 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */ 55 {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
80 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */ 56 {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
81 {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */ 57 {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
82 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */ 58 {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
83 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */ 59 {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
84 {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */ 60 {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
85 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */ 61 {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
86 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */ 62 {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
@@ -103,10 +79,10 @@ static const SiS_ExtStruct SiS310_EModeIDTable[]=
103 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */ 79 {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
104 {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */ 80 {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */
105 {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */ 81 {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */
106 {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */ 82 {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
107 {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */ 83 {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
108 {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */ 84 {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
109 {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */ 85 {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
110 {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */ 86 {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */
111 {0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */ 87 {0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */
112 {0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */ 88 {0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
@@ -139,406 +115,335 @@ static const SiS_ExtStruct SiS310_EModeIDTable[]=
139 {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */ 115 {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
140 {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */ 116 {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
141 {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */ 117 {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
142 {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */ 118 {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x8 */
143 {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */ 119 {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x16 */
144 {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/ 120 {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x32*/
145 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */ 121 {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1}, /* 1152x864 */
146 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, 122 {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
147 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, 123 {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
148 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1}, /* 848x480 */ 124 {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 848x480 */
149 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1}, 125 {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
150 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1}, 126 {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
151 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 856x480 */ 127 {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 856x480 */
152 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1}, 128 {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
153 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1}, 129 {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
154 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 1360x768 */ 130 {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1}, /* 1360x768 */
155 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, 131 {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
156 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, 132 {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
157 {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */ 133 {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
158 {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */ 134 {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
159 {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */ 135 {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
160 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1}, /* 768x576 */ 136 {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1}, /* 768x576 */
161 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1}, 137 {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
162 {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1}, 138 {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
163 {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, /* 1280x800 */ 139 {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7}, /* 1280x800 */
164 {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, 140 {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
165 {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, 141 {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
166 {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, /* 1680x1050 */ 142 {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9}, /* 1680x1050 */
167 {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, 143 {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
168 {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, 144 {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
169 {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, /* 1920x1080(i) */ 145 {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1}, /* 1920x1080(i) */
170 {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, 146 {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
171 {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, 147 {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
172 {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1}, /* 960x540 */ 148 {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1}, /* 960x540 */
173 {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1}, 149 {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
174 {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1}, 150 {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
175 {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1}, /* 960x600 */ 151 {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1}, /* 960x600 */
176 {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1}, 152 {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
177 {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1}, 153 {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
154 {0x1a,0x0e3b,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8}, /* 1280x854 */
155 {0x1b,0x0e7d,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
156 {0x1c,0x0eff,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
178 {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1} 157 {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
179}; 158};
180 159
181static const SiS_Ext2Struct SiS310_RefIndex[]= 160static const struct SiS_Ext2 SiS310_RefIndex[] =
182{ 161{
183 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */ 162 {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x0 */
184 {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */ 163 {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1 */
185 {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */ 164 {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2 */
186 {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */ 165 {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3 */
187 {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */ 166 {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4 */
188 {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */ 167 {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x5 */
189 {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */ 168 {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x6 */
190 {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */ 169 {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x7 */
191 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */ 170 {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x8 */
192 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */ 171 {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x9 */
193 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */ 172 {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xa */
194 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */ 173 {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xb */
195 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */ 174 {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xc */
196 {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */ 175 {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xd */
197 {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */ 176 {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xe */
198 {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */ 177 {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xf */
199 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */ 178 {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00}, /* 0x10 */
200 {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */ 179 {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x11 */
201 {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */ 180 {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x12 (6f was 03) */
202 {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */ 181 {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x13 */
203 {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */ 182 {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x14 */
204 {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */ 183 {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x15 */
205 {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */ 184 {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x16 */
206 {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */ 185 {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x17 */
207 {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */ 186 {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x18 */
208 {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */ 187 {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x19 */
209 {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */ 188 {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1a */
210 {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */ 189 {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1b */
211 {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */ 190 {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1c */
212 {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */ 191 {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1d */
213 {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */ 192 {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1e */
214 {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */ 193 {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1f */
215 {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */ 194 {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x20 */
216 {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */ 195 {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x21 */
217 {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */ 196 {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x22 */
218 {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */ 197 {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x23 */
219 {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */ 198 {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x24 */
220 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */ 199 {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30, 0x56, 0x4e, 0x00, 0x00, 0x00, 0x00}, /* 0x25 */
221 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */ 200 {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x26 */
222 {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */ 201 {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x27 */
223 {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */ 202 {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x28 */
224 {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */ 203 {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x29 */
225 {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */ 204 {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2a */
226 {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */ 205 {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2b */
227 {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */ 206 {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2c */
228 {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */ 207 {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2d */
229 {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */ 208 {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2e */
230 {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */ 209 {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2f */
231 {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */ 210 {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x30 */
232 {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */ 211 {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x31 */
233 {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */ 212 {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x32 */
234 {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */ 213 {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x33 */
235 {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */ 214 {0x2077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x32, 0x40, 0x5e, 0x73}, /* 0x34 */
236 {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */ 215 {0x2047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x33, 0x07, 0xff, 0xff}, /* 0x35 */
237 {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */ 216 {0x2047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x34, 0x0a, 0xff, 0xff}, /* 0x36 */
238 {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */ 217 {0x2077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x35, 0x0b, 0x5f, 0x74}, /* 0x37 */
239 {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */ 218 {0x2047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x36, 0x11, 0xff, 0xff}, /* 0x38 */
240 {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */ 219 {0x2047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x37, 0x16, 0xff, 0xff}, /* 0x39 */
241 {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */ 220 {0x3137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x38, 0x19, 0x60, 0x75}, /* 0x3a */
242 {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */ 221 {0x3107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x39, 0x1e, 0xff, 0xff}, /* 0x3b */
243 {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */ 222 {0x3307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x3a, 0x20, 0xff, 0xff}, /* 0x3c */
244 {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */ 223 {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3d */
245 {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */ 224 {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3e */
246 {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */ /* FSTN 320x240 */ 225 {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3f */ /* FSTN 320x240 */
247 {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */ /* 0x5b was 0x12 */ 226 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x58, 0x19, 0x42, 0x5b}, /* 0x40 */ /* 0x5b was 0x12 */
248 {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */ 227 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x59, 0x1e, 0xff, 0xff}, /* 0x41 */
249 {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */ 228 {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x5a, 0x20, 0xff, 0xff}, /* 0x42 */
250 {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-60Hz */ 229 {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x43 */
251 {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-75Hz */ 230 {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x44 1400x1050-75Hz */
252 {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x45 1152x864-85Hz */ 231 {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x45 1152x864-60Hz */
253 {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-38Hzi */ 232 {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x46 1152x864-75Hz */
254 {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x47 848x480-60Hz */ 233 {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x47 1152x864-85Hz */
255 {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-38Hzi */ 234 {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x48 848x480-38Hzi */
256 {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x49 856x480-60Hz */ 235 {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x49 848x480-60Hz */
257 {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x4a 1360x768-60Hz */ 236 {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4a 856x480-38Hzi */
258 {0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4b 768x576-56Hz */ 237 {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4b 856x480-60Hz */
259 {0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4c 1280x800-60Hz */ 238 {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4c 1360x768-60Hz */
260 {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4d 1680x1050-60Hz */ 239 {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4d 768x576-56Hz */
261 {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4e 1920x1080 60Hzi */ 240 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5b, 0x19, 0x4f, 0x5c}, /* 0x4e 1280x800-60Hz */
262 {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4f 960x540 60Hz */ 241 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5c, 0x1e, 0xff, 0xff}, /* 0x4f 1280x800-75Hz */
263 {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30}, /* 0x50 960x600 60Hz */ 242 {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5d, 0x20, 0xff, 0xff}, /* 0x50 1280x800-85Hz */
264 {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0} 243 {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x51 1680x1050-60Hz */
265}; 244 {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x52 1920x1080 60Hzi */
266 245 {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x53 960x540 60Hz */
267#ifdef LINUX_XF86 246 {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x54 960x600 60Hz */
268static const struct { 247 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x62, 0x19, 0x61, 0x76}, /* 0x55 1280x854-60Hz */
269 UCHAR Ext_ModeID; /* ModeID in new ROM */ 248 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x63, 0x1e, 0xff, 0xff}, /* 0x56 1280x854-75Hz */
270 UCHAR Ext_MyModeID; /* corresponding ModeID in my tables (0 = identical) */ 249 {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x64, 0x20, 0xff, 0xff}, /* 0x57 1280x854-85Hz */
271 USHORT Ext_VESAID; /* corresponding VESA ID in new ROM */ 250 {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
272} SiS_EModeIDTable661[] = { 251};
273 { 0x6a, 0x00, 0x0102 }, 252
274 { 0x1d, 0x20, 0x0000 }, 253static const struct SiS_CRT1Table SiS310_CRT1Table[] =
275 { 0x1e, 0x21, 0x0000 },
276 { 0x1f, 0x22, 0x0000 },
277 { 0x20, 0x29, 0x0000 },
278 { 0x21, 0x2a, 0x0000 },
279 { 0x22, 0x2b, 0x0000 },
280 { 0x23, 0x00, 0x011c },
281 { 0x24, 0x00, 0x011d },
282 { 0x25, 0x00, 0x011e },
283 { 0x26, 0x00, 0x011f },
284 { 0x27, 0x00, 0x0120 },
285 { 0x28, 0x00, 0x0121 },
286 { 0x2a, 0x14, 0x013d },
287 { 0x2b, 0x15, 0x013e },
288 { 0x2c, 0x16, 0x013f },
289 { 0x2e, 0x00, 0x0101 },
290 { 0x2f, 0x00, 0x0100 },
291 { 0x30, 0x00, 0x0103 },
292 { 0x37, 0x00, 0x0104 },
293 { 0x38, 0x00, 0x0105 },
294 { 0x3a, 0x00, 0x0107 },
295 { 0x3c, 0x00, 0x0125 },
296 { 0x3d, 0x00, 0x0126 },
297 { 0x40, 0x00, 0x010d },
298 { 0x41, 0x00, 0x010e },
299 { 0x43, 0x00, 0x0110 },
300 { 0x44, 0x00, 0x0111 },
301 { 0x46, 0x00, 0x0113 },
302 { 0x47, 0x00, 0x0114 },
303 { 0x49, 0x00, 0x0116 },
304 { 0x4a, 0x00, 0x0117 },
305 { 0x4c, 0x00, 0x0119 },
306 { 0x4d, 0x00, 0x011a },
307 { 0x50, 0x00, 0x0127 },
308 { 0x51, 0x00, 0x0128 },
309 { 0x52, 0x00, 0x0129 },
310 { 0x56, 0x00, 0x012a },
311 { 0x57, 0x00, 0x012b },
312 { 0x58, 0x00, 0x012c },
313 { 0x59, 0x00, 0x012d },
314 { 0x5a, 0x17, 0x012e },
315 { 0x5b, 0x18, 0x012f },
316 { 0x5c, 0x19, 0x0130 },
317 { 0x5d, 0x00, 0x0131 },
318 { 0x62, 0x00, 0x0112 },
319 { 0x63, 0x00, 0x0115 },
320 { 0x64, 0x00, 0x0118 },
321 { 0x65, 0x00, 0x011b },
322 { 0x66, 0x00, 0x0132 },
323 { 0x75, 0x00, 0x013a },
324 { 0x78, 0x00, 0x013b },
325 { 0x79, 0x00, 0x013c },
326 { 0x7b, 0x7c, 0x0136 },
327 { 0x7c, 0x7d, 0x0137 },
328 { 0x7d, 0x7e, 0x0138 },
329 { 0xff, 0xff, 0xffff }
330};
331#endif
332
333static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
334{ 254{
335 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, 255 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
336 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, 256 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
337 0x00}}, /* 0x0 */ 257 0x00}}, /* 0x0 */
338 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, 258 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
339 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, 259 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
340 0x00}}, /* 0x1 */ 260 0x00}}, /* 0x1 */
341 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, 261 {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
342 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, 262 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
343 0x01}}, /* 0x2 */ 263 0x01}}, /* 0x2 */
344 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, 264 {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
345 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, 265 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
346 0x01}}, /* 0x3 */ 266 0x01}}, /* 0x3 */
347 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, 267 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
348 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, 268 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
349 0x00}}, /* 0x4 */ 269 0x00}}, /* 0x4 */
350#if 0 270 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* corrected 640x480-60 */
351 {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
352 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
353 0x00}}, /* 0x5 */
354#endif
355 {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
356 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, 271 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
357 0x00}}, 272 0x00}}, /* 0x5 */
358#if 0 273 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* corrected 640x480-72 */
359 {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
360 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
361 0x00}}, /* 0x6 */
362#endif
363 {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
364 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, 274 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
365 0x00}}, 275 0x00}}, /* 0x6 */
366 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f, 276 {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
367 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01, 277 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
368 0x00}}, /* 0x7 */ 278 0x00}}, /* 0x7 */
369 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, 279 {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
370 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, 280 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
371 0x00}}, /* 0x8 */ 281 0x00}}, /* 0x8 */
372 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f, 282 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
373 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */ 283 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
374 0x61}}, /* 0x9 */ 284 0x61}}, /* 0x9 */
375 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e, 285 {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
376 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05, 286 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
377 0x61}}, /* 0xa */ 287 0x61}}, /* 0xa */
378 {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e, 288 {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
379 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */ 289 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
380 0x61}}, /* 0xb */ 290 0x61}}, /* 0xb */
381 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f, 291 {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
382 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */ 292 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
383 0x00}}, /* 0xc */ 293 0x00}}, /* 0xc */
384 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0, 294 {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
385 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05, 295 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
386 0x01}}, /* 0xd */ 296 0x01}}, /* 0xd */
387 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0, 297 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
388 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06, 298 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
389 0x01}}, /* 0xe */ 299 0x01}}, /* 0xe */
390 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0, 300 {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
391 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06, 301 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
392 0x01}}, /* 0xf */ 302 0x01}}, /* 0xf */
393 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0, 303 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
394 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06, 304 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
395 0x01}}, /* 0x10 */ 305 0x01}}, /* 0x10 */
396 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0, 306 {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
397 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06, 307 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
398 0x01}}, /* 0x11 */ 308 0x01}}, /* 0x11 */
399 {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0, 309 {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
400 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06, 310 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
401 0x61}}, /* 0x12 */ 311 0x61}}, /* 0x12 */
402 {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0, 312 {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
403 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06, 313 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
404 0x61}}, /* 0x13 */ 314 0x61}}, /* 0x13 */
405 {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0, 315 {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
406 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06, 316 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
407 0x61}}, /* 0x14 */ 317 0x61}}, /* 0x14 */
408 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f, 318 {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
409 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02, 319 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
410 0x00}}, /* 0x15 */ 320 0x00}}, /* 0x15 */
411 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, 321 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
412 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, 322 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
413 0x01}}, /* 0x16 */ 323 0x01}}, /* 0x16 */
414 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5, 324 {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
415 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, 325 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
416 0x01}}, /* 0x17 */ 326 0x01}}, /* 0x17 */
417 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5, 327 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
418 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02, 328 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
419 0x01}}, /* 0x18 */ 329 0x01}}, /* 0x18 */
420 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5, 330 {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
421 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02, 331 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
422 0x01}}, /* 0x19 */ 332 0x01}}, /* 0x19 */
423 {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5, 333 {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
424 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02, 334 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
425 0x62}}, /* 0x1a */ 335 0x62}}, /* 0x1a */
426 {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5, 336 {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
427 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02, 337 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
428 0x62}}, /* 0x1b */ 338 0x62}}, /* 0x1b */
429 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba, 339 {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
430 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03, 340 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
431 0x00}}, /* 0x1c */ 341 0x00}}, /* 0x1c */
432 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a, 342 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
433 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, 343 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
434 0x01}}, /* 0x1d */ 344 0x01}}, /* 0x1d */
435 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, 345 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
436 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, 346 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
437 0x01}}, /* 0x1e */ 347 0x01}}, /* 0x1e */
438 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a, 348 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
439 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07, 349 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
440 0x01}}, /* 0x1f */ 350 0x01}}, /* 0x1f */
441 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 351 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
442 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 352 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
443 0x00}}, /* 0x20 */ 353 0x00}}, /* 0x20 */
444 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 354 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
445 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 355 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
446 0x00}}, /* 0x21 @ 4084 */ 356 0x00}}, /* 0x21 */
447 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 357 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
448 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 358 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
449 0x00}}, /* 0x22 */ 359 0x00}}, /* 0x22 */
450 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 360 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
451 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 361 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
452 0x00}}, /* 0x23 */ 362 0x00}}, /* 0x23 */
453 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 363 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
454 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 364 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
455 0x00}}, /* 0x24 */ 365 0x00}}, /* 0x24 */
456 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 366 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
457 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 367 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
458 0x00}}, /* 0x25 */ 368 0x00}}, /* 0x25 */
459 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, 369 {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
460 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, 370 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
461 0x00}}, /* 0x26 */ 371 0x00}}, /* 0x26 */
462 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, 372 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
463 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, 373 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
464 0x00}}, /* 0x27 */ 374 0x00}}, /* 0x27 */
465 {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f, 375 {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
466 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05, 376 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
467 0x63}}, /* 0x28 */ 377 0x63}}, /* 0x28 */
468 {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f, 378 {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
469 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05, 379 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
470 0x63}}, /* 0x29 */ 380 0x63}}, /* 0x29 */
471 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, 381 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
472 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, 382 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
473 0x00}}, /* 0x2a */ 383 0x00}}, /* 0x2a */
474 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, 384 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
475 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, 385 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
476 0x00}}, /* 0x2b */ 386 0x00}}, /* 0x2b */
477 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, 387 {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
478 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, 388 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
479 0x00}}, /* 0x2c */ 389 0x00}}, /* 0x2c */
480 {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba, 390 {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
481 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05, 391 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
482 0x44}}, /* 0x2d */ 392 0x44}}, /* 0x2d */
483 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba, 393 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
484 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05, 394 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
485 0x44}}, /* 0x2e */ 395 0x44}}, /* 0x2e */
486 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba, 396 {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
487 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05, 397 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
488 0x44}}, /* 0x2f */ 398 0x44}}, /* 0x2f */
489 {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba, 399 {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
490 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05, 400 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
491 0x44}}, /* 0x30 */ 401 0x44}}, /* 0x30 */
492 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, 402 {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
493 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, 403 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
494 0x00}}, /* 0x31 */ 404 0x00}}, /* 0x31 */
495 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, 405 {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
496 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, 406 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
497 0x01}}, /* 0x32 */ 407 0x01}}, /* 0x32 */
498 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, 408 {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
499 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, 409 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
500 0x01}}, /* 0x33 */ 410 0x01}}, /* 0x33 */
501 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, 411 {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
502 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, 412 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
503 0x01}}, /* 0x34 */ 413 0x01}}, /* 0x34 */
504 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, 414 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
505 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, 415 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
506 0x01}}, /* 0x35 */ 416 0x01}}, /* 0x35 */
507 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, 417 {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
508 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, 418 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
509 0x01}}, /* 0x36 */ 419 0x01}}, /* 0x36 */
510 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */ 420 {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
511 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, 421 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
512 0x01}}, /* 0x37 */ 422 0x01}}, /* 0x37 */
513 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, 423 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
514 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, 424 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
515 0x01}}, /* 0x38 */ 425 0x01}}, /* 0x38 */
516 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, 426 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
517 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, 427 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
518 0x01}}, /* 0x39 */ 428 0x01}}, /* 0x39 */
519 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, 429 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
520 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, 430 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
521 0x01}}, /* 0x3a */ 431 0x01}}, /* 0x3a */
522#if 0
523 {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 1280x960 - invalid */
524 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
525 0x01}}, /* 0x3b */
526#endif
527 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */ 432 {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
528 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, 433 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
529 0x01}}, /* 0x3b */ 434 0x01}}, /* 0x3b */
530 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, 435 {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
531 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, 436 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
532 0x00}}, /* 0x3c */ 437 0x00}}, /* 0x3c */
533 {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, 438 {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 720x576, corrected to 60Hz */
534 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, 439 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
535 0x01}}, /* 0x3d */ 440 0x41}}, /* 0x3d */
536 {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15, 441 {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
537 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02, 442 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
538 0x00}}, /* 0x3e */ 443 0x00}}, /* 0x3e */
539 {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e, 444 {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
540 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02, 445 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
541 0x00}}, /* 0x3f */ 446 0x00}}, /* 0x3f */
542 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, 447 {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
543 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, 448 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
544 0x01}}, /* 0x40 */ 449 0x01}}, /* 0x40 */
@@ -578,11 +483,11 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
578 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */ 483 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
579 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, 484 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
580 0x01}}, /* 0x4c */ 485 0x01}}, /* 0x4c */
581 {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */ 486 {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
582 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05, 487 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
583 0x01}}, /* 0x4d */ 488 0x41}}, /* 0x4d */
584 {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */ 489 {{0x5f,0x27,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* FSTN 320x240 (working) */
585 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, 490 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
586 0x00}}, /* 0x4e */ 491 0x00}}, /* 0x4e */
587 {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */ 492 {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
588 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07, 493 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
@@ -601,10 +506,58 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
601 0x01}}, /* 0x53 */ 506 0x01}}, /* 0x53 */
602 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */ 507 {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
603 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07, 508 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
604 0x41}} /* 0x54 */ 509 0x41}}, /* 0x54 */
605}; 510 {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
606 511 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
607static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] = 512 0x40}}, /* 0x55 */
513 {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
514 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
515 0x00}}, /* 0x56 */
516 {{0xd7,0xc7,0xc7,0x9b,0xd1,0x15,0xd1,0x10, /* 1600x1200 for LCDA */
517 0xb2,0x86,0xaf,0xb0,0xd2,0x2f,0x00,0x03,
518 0x00}}, /* 0x57 */
519 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 60 Hz */
520 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
521 0x01}}, /* 0x58 */
522 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 75 Hz */
523 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
524 0x01}}, /* 0x59 */
525 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xdc, /* 1280x768 (1280x1024) 85 Hz */
526 0x95,0x89,0xff,0x94,0x2f,0x21,0x00,0x07,
527 0x01}}, /* 0x5a */
528 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x800 (1280x1024) 60 Hz */
529 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
530 0x01}}, /* 0x5b */
531 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x800 (1280x1024) 75 Hz */
532 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
533 0x01}}, /* 0x5c */
534 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x800 (1280x1024) 85 Hz */
535 0xa5,0x89,0x1f,0xa4,0x2f,0x01,0x00,0x07,
536 0x01}}, /* 0x5d */
537 {{0x7f,0x63,0x63,0x83,0x6d,0x1d,0x0b,0x3e, /* 800x480 (wide) 60 Hz */
538 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x06,
539 0x00}}, /* 0x5e */
540 {{0xa0,0x7f,0x7f,0x84,0x85,0x97,0x52,0xf0, /* 1024x576 (wide) 60 Hz */
541 0x41,0x85,0x3f,0x40,0x53,0x00,0x00,0x02,
542 0x01}}, /* 0x5f */
543 {{0xc9,0x9f,0x9f,0x8d,0xb0,0x15,0xec,0xf0, /* 1280x720 (wide) 60 Hz */
544 0xd4,0x89,0xcf,0xd3,0xed,0x20,0x00,0x07,
545 0x01}}, /* 0x60 */
546 {{0xcb,0x9f,0x9f,0x8f,0xa5,0x13,0x5b,0xff, /* 1280x854-60 wide */
547 0x56,0x89,0x55,0x55,0x5c,0x30,0x00,0x07,
548 0x01}}, /* 0x61 */
549 {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x854 (1280x1024) 60 Hz */
550 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
551 0x41}}, /* 0x62 */
552 {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x854 (1280x1024) 75 Hz */
553 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
554 0x41}}, /* 0x63 */
555 {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x854 (1280x1024) 85 Hz */
556 0xc0,0x84,0x55,0xbf,0x2f,0x01,0x00,0x07,
557 0x41}} /* 0x64 */
558};
559
560static const struct SiS_MCLKData SiS310_MCLKData_0_315[] =
608{ 561{
609 { 0x3b,0x22,0x01,143}, 562 { 0x3b,0x22,0x01,143},
610 { 0x5c,0x23,0x01,166}, 563 { 0x5c,0x23,0x01,166},
@@ -616,7 +569,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
616 { 0x5c,0x23,0x01,166} 569 { 0x5c,0x23,0x01,166}
617}; 570};
618 571
619static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] = 572static const struct SiS_MCLKData SiS310_MCLKData_0_650[] =
620{ 573{
621 { 0x5a,0x64,0x82, 66}, 574 { 0x5a,0x64,0x82, 66},
622 { 0xb3,0x45,0x82, 83}, 575 { 0xb3,0x45,0x82, 83},
@@ -628,7 +581,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
628 { 0x37,0x22,0x82,133} 581 { 0x37,0x22,0x82,133}
629}; 582};
630 583
631static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] = 584static const struct SiS_MCLKData SiS310_MCLKData_0_330[] =
632{ 585{
633 { 0x5c,0x23,0x01,166}, 586 { 0x5c,0x23,0x01,166},
634 { 0x5c,0x23,0x01,166}, 587 { 0x5c,0x23,0x01,166},
@@ -640,7 +593,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
640 { 0x79,0x06,0x01,250} 593 { 0x79,0x06,0x01,250}
641}; 594};
642 595
643static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] = 596static const struct SiS_MCLKData SiS310_MCLKData_0_660[] =
644{ 597{
645 { 0x5c,0x23,0x82,166}, 598 { 0x5c,0x23,0x82,166},
646 { 0x5c,0x23,0x82,166}, 599 { 0x5c,0x23,0x82,166},
@@ -652,7 +605,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
652 { 0x37,0x21,0x82,200} 605 { 0x37,0x21,0x82,200}
653}; 606};
654 607
655static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] = 608static const struct SiS_MCLKData SiS310_MCLKData_0_760[] =
656{ 609{
657 { 0x37,0x22,0x82,133}, 610 { 0x37,0x22,0x82,133},
658 { 0x5c,0x23,0x82,166}, 611 { 0x5c,0x23,0x82,166},
@@ -664,7 +617,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
664 { 0x37,0x21,0x82,200} 617 { 0x37,0x21,0x82,200}
665}; 618};
666 619
667static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] = 620static const struct SiS_MCLKData SiS310_MCLKData_0_761[] =
668{ 621{
669 { 0x37,0x22,0x82,133}, /* Preliminary */ 622 { 0x37,0x22,0x82,133}, /* Preliminary */
670 { 0x5c,0x23,0x82,166}, 623 { 0x5c,0x23,0x82,166},
@@ -676,7 +629,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
676 { 0x37,0x21,0x82,200} 629 { 0x37,0x21,0x82,200}
677}; 630};
678 631
679static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] = 632static const struct SiS_MCLKData SiS310_MCLKData_0_340[] =
680{ 633{
681 { 0x79,0x06,0x01,250}, 634 { 0x79,0x06,0x01,250},
682 { 0x7c,0x08,0x01,200}, 635 { 0x7c,0x08,0x01,200},
@@ -688,9 +641,9 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
688 { 0x29,0x01,0x81,300} 641 { 0x29,0x01,0x81,300}
689}; 642};
690 643
691static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */ 644static const struct SiS_MCLKData SiS310_MCLKData_1[] = /* ECLK */
692{ 645{
693 { 0x29,0x21,0x82,150}, 646 { 0x29,0x21,0x82,150},
694 { 0x5c,0x23,0x82,166}, 647 { 0x5c,0x23,0x82,166},
695 { 0x65,0x23,0x82,183}, 648 { 0x65,0x23,0x82,183},
696 { 0x37,0x21,0x82,200}, 649 { 0x37,0x21,0x82,200},
@@ -700,7 +653,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
700 { 0x37,0x22,0x82,133} 653 { 0x37,0x22,0x82,133}
701}; 654};
702 655
703static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] = 656static const struct SiS_MCLKData SiS310_MCLKData_1_340[] =
704{ 657{
705 { 0x7c,0x08,0x01,200}, 658 { 0x7c,0x08,0x01,200},
706 { 0x7c,0x08,0x01,200}, 659 { 0x7c,0x08,0x01,200},
@@ -712,7 +665,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
712 { 0x29,0x01,0x81,300} 665 { 0x29,0x01,0x81,300}
713}; 666};
714 667
715static SiS_VCLKDataStruct SiS310_VCLKData[]= 668static struct SiS_VCLKData SiS310_VCLKData[] =
716{ 669{
717 { 0x1b,0xe1, 25}, /* 0x00 */ 670 { 0x1b,0xe1, 25}, /* 0x00 */
718 { 0x4e,0xe4, 28}, /* 0x01 */ 671 { 0x4e,0xe4, 28}, /* 0x01 */
@@ -805,7 +758,7 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
805 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */ 758 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
806 { 0x52,0x07,149}, /* 0x59 1280x960-85 */ 759 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
807 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */ 760 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
808 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */ 761 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
809 { 0x45,0x25, 83}, /* 0x5c 1280x800 */ 762 { 0x45,0x25, 83}, /* 0x5c 1280x800 */
810 { 0x70,0x0a,147}, /* 0x5d 1680x1050 */ 763 { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
811 { 0x70,0x24,162}, /* 0x5e 1600x1200 */ 764 { 0x70,0x24,162}, /* 0x5e 1600x1200 */
@@ -823,10 +776,19 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
823 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */ 776 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
824 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */ 777 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
825 { 0x45,0x25, 83}, /* 0x6c 1280x800 */ 778 { 0x45,0x25, 83}, /* 0x6c 1280x800 */
826 { 0x70,0x28, 90} /* 0x6d 1152x864@60 */ 779 { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
780 { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
781 { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
782 { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
783 { 0x2b,0xc2, 35}, /* 0x71 768x576@60 */
784 { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
785 { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
786 { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
787 { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
788 { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (wide) */
827}; 789};
828 790
829static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]= 791static struct SiS_VBVCLKData SiS310_VBVCLKData[] =
830{ 792{
831 { 0x1b,0xe1, 25}, /* 0x00 */ 793 { 0x1b,0xe1, 25}, /* 0x00 */
832 { 0x4e,0xe4, 28}, /* 0x01 */ 794 { 0x4e,0xe4, 28}, /* 0x01 */
@@ -858,12 +820,6 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
858 { 0x5e,0x43,113}, /* 0x1b */ 820 { 0x5e,0x43,113}, /* 0x1b */
859 { 0xbc,0x44,116}, /* 0x1c */ 821 { 0xbc,0x44,116}, /* 0x1c */
860 { 0xe0,0x46,132}, /* 0x1d */ 822 { 0xe0,0x46,132}, /* 0x1d */
861#if 0
862 { 0xd4,0x28,135}, /* 0x1e */
863 { 0xea,0x2a,139}, /* 0x1f */
864 { 0x41,0x22,157}, /* 0x20 */
865 { 0x70,0x24,162}, /* 0x21 */
866#endif
867 { 0xe2,0x46,135}, /* 0x1e */ /* 1280x1024-75, better clock for VGA2 */ 823 { 0xe2,0x46,135}, /* 0x1e */ /* 1280x1024-75, better clock for VGA2 */
868 { 0xe5,0x46,139}, /* 0x1f */ /* 1024x768-120, better clock for VGA2 */ 824 { 0xe5,0x46,139}, /* 0x1f */ /* 1024x768-120, better clock for VGA2 */
869 { 0x15,0x01,157}, /* 0x20 */ /* 1280x1024-85, better clock for VGA2 */ 825 { 0x15,0x01,157}, /* 0x20 */ /* 1280x1024-85, better clock for VGA2 */
@@ -912,7 +868,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
912 { 0x34,0x61, 95}, /* 0x4b UNUSED */ 868 { 0x34,0x61, 95}, /* 0x4b UNUSED */
913 { 0x78,0x27,108}, /* 0x4c UNUSED */ 869 { 0x78,0x27,108}, /* 0x4c UNUSED */
914 { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */ 870 { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
915 { 0x41,0x4e, 21}, /* 0x4e UNUSED */ 871 { 0x41,0x4e, 21}, /* 0x4e */
916 { 0xa1,0x4a, 29}, /* 0x4f UNUSED */ 872 { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
917 { 0x19,0x42, 42}, /* 0x50 UNUSED */ 873 { 0x19,0x42, 42}, /* 0x50 UNUSED */
918 { 0x54,0x46, 58}, /* 0x51 UNUSED */ 874 { 0x54,0x46, 58}, /* 0x51 UNUSED */
@@ -925,7 +881,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
925 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */ 881 { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
926 { 0x52,0x07,149}, /* 0x59 1280x960-85 */ 882 { 0x52,0x07,149}, /* 0x59 1280x960-85 */
927 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */ 883 { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
928 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */ 884 { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
929 { 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */ 885 { 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
930 { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */ 886 { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
931 { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */ 887 { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
@@ -943,57 +899,33 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
943 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */ 899 { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
944 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */ 900 { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
945 { 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */ 901 { 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
946 { 0x70,0x28, 90} /* 0x6d 1152x864@60 */ 902 { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
903 { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
904 { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
905 { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
906 { 0x2b,0xc2, 35}, /* 0x71 768@576@60 */
907 { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
908 { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
909 { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
910 { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
911 { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (SiS LVDS) LCD */
947}; 912};
948 913
949static const DRAM4Type SiS310_SR15[8] = { 914static const unsigned char SiS310_SR15[4 * 8] =
950 {0x00,0x04,0x60,0x60}, 915{
951 {0x0f,0x0f,0x0f,0x0f}, 916 0x00,0x04,0x60,0x60,
952 {0xba,0xba,0xba,0xba}, 917 0x0f,0x0f,0x0f,0x0f,
953 {0xa9,0xa9,0xac,0xac}, 918 0xba,0xba,0xba,0xba,
954 {0xa0,0xa0,0xa0,0xa8}, 919 0xa9,0xa9,0xac,0xac,
955 {0x00,0x00,0x02,0x02}, 920 0xa0,0xa0,0xa0,0xa8,
956 {0x30,0x30,0x40,0x40}, 921 0x00,0x00,0x02,0x02,
957 {0x00,0xa5,0xfb,0xf6} 922 0x30,0x30,0x40,0x40,
958}; 923 0x00,0xa5,0xfb,0xf6
959
960#ifdef LINUX_KERNEL
961
962static UCHAR SiS310_SR07 = 0x18;
963
964static const DRAM4Type SiS310_CR40[5] = {
965 {0x77,0x77,0x33,0x33},
966 {0x77,0x77,0x33,0x33},
967 {0x00,0x00,0x00,0x00},
968 {0x5b,0x5b,0x03,0x03},
969 {0x00,0x00,0xf0,0xf8}
970}; 924};
971 925
972static UCHAR SiS310_CR49[] = {0xaa,0x88}; 926static const struct SiS_PanelDelayTbl SiS310_PanelDelayTbl[] =
973static UCHAR SiS310_SR1F = 0x00;
974static UCHAR SiS310_SR21 = 0xa5;
975static UCHAR SiS310_SR22 = 0xfb;
976static UCHAR SiS310_SR23 = 0xf6;
977static UCHAR SiS310_SR24 = 0x0d;
978static UCHAR SiS310_SR25[] = {0x33,0x3};
979static UCHAR SiS310_SR31 = 0x00;
980static UCHAR SiS310_SR32 = 0x11;
981static UCHAR SiS310_SR33 = 0x00;
982static UCHAR SiS310_CRT2Data_1_2 = 0x00;
983static UCHAR SiS310_CRT2Data_4_D = 0x00;
984static UCHAR SiS310_CRT2Data_4_E = 0x00;
985static UCHAR SiS310_CRT2Data_4_10 = 0x80;
986static const USHORT SiS310_RGBSenseData = 0xd1;
987static const USHORT SiS310_VideoSenseData = 0xb9;
988static const USHORT SiS310_YCSenseData = 0xb3;
989static const USHORT SiS310_RGBSenseData2 = 0x0190;
990static const USHORT SiS310_VideoSenseData2 = 0x0174;
991static const USHORT SiS310_YCSenseData2 = 0x016b;
992#endif
993
994static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
995{ 927{
996 {{0x10,0x40}}, 928 {{0x10,0x40}},
997 {{0x10,0x40}}, 929 {{0x10,0x40}},
998 {{0x10,0x40}}, 930 {{0x10,0x40}},
999 {{0x10,0x40}}, 931 {{0x10,0x40}},
@@ -1011,7 +943,7 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
1011 {{0x10,0x40}} 943 {{0x10,0x40}}
1012}; 944};
1013 945
1014static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]= 946static const struct SiS_PanelDelayTbl SiS310_PanelDelayTblLVDS[] =
1015{ 947{
1016 {{0x28,0xc8}}, 948 {{0x28,0xc8}},
1017 {{0x28,0xc8}}, 949 {{0x28,0xc8}},
@@ -1035,18 +967,18 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
1035/* SIS VIDEO BRIDGE ----------------------------------------- */ 967/* SIS VIDEO BRIDGE ----------------------------------------- */
1036/**************************************************************/ 968/**************************************************************/
1037 969
1038static const SiS_LCDDataStruct SiS310_St2LCD1024x768Data[] = 970static const struct SiS_LCDData SiS310_St2LCD1024x768Data[] =
1039{ 971{
1040 { 62, 25, 800, 546,1344, 806}, 972 { 62, 25, 800, 546,1344, 806},
1041 { 32, 15, 930, 546,1344, 806}, 973 { 32, 15, 930, 546,1344, 806},
1042 { 62, 25, 800, 546,1344, 806}, 974 { 62, 25, 800, 546,1344, 806},
1043 { 104, 45, 945, 496,1344, 806}, 975 { 104, 45, 945, 496,1344, 806},
1044 { 62, 25, 800, 546,1344, 806}, 976 { 62, 25, 800, 546,1344, 806},
1045 { 31, 18,1008, 624,1344, 806}, 977 { 31, 18,1008, 624,1344, 806},
1046 { 1, 1,1344, 806,1344, 806} 978 { 1, 1,1344, 806,1344, 806}
1047}; 979};
1048 980
1049static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] = 981static const struct SiS_LCDData SiS310_ExtLCD1024x768Data[] =
1050{ 982{
1051 { 42, 25,1536, 419,1344, 806}, 983 { 42, 25,1536, 419,1344, 806},
1052 { 48, 25,1536, 369,1344, 806}, 984 { 48, 25,1536, 369,1344, 806},
@@ -1057,7 +989,7 @@ static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
1057 { 1, 1,1344, 806,1344, 806} 989 { 1, 1,1344, 806,1344, 806}
1058}; 990};
1059 991
1060static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] = 992static const struct SiS_LCDData SiS310_St2LCD1280x1024Data[] =
1061{ 993{
1062 { 22, 5, 800, 510,1650,1088}, 994 { 22, 5, 800, 510,1650,1088},
1063 { 22, 5, 800, 510,1650,1088}, 995 { 22, 5, 800, 510,1650,1088},
@@ -1069,7 +1001,7 @@ static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
1069 { 1, 1,1688,1066,1688,1066} 1001 { 1, 1,1688,1066,1688,1066}
1070}; 1002};
1071 1003
1072static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] = 1004static const struct SiS_LCDData SiS310_ExtLCD1280x1024Data[] =
1073{ 1005{
1074 { 211, 60,1024, 501,1688,1066}, 1006 { 211, 60,1024, 501,1688,1066},
1075 { 211, 60,1024, 508,1688,1066}, 1007 { 211, 60,1024, 508,1688,1066},
@@ -1081,45 +1013,22 @@ static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
1081 { 1, 1,1688,1066,1688,1066} 1013 { 1, 1,1688,1066,1688,1066}
1082}; 1014};
1083 1015
1084static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] = 1016static const struct SiS_Part2PortTbl SiS310_CRT2Part2_1024x768_1[] =
1085{ 1017{
1086 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 1018 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1087 {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 1019 {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1088 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 1020 {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1089 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 1021 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
1090 {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 1022 {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1091 {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 1023 {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
1092 {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}} 1024 {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
1093}; 1025};
1094 1026
1095/* *** LCDA *** */
1096
1097#if 0
1098static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
1099{ /* Clevo, 651+301C */
1100 {1200, 450, 2048,1250},
1101 {1200, 400, 2048,1250},
1102 {1280, 450, 2048,1250},
1103 {1280, 400, 2048,1250},
1104 {1200, 530, 2048,1250},
1105 {1360, 650, 2048,1250},
1106 {1584, 818, 2048,1250},
1107 {1688,1066, 2048,1250},
1108 {1688,1066, 2048,1250},
1109#if 0
1110 {2048,1250, 2048,1250} /* this should be correct */
1111#endif
1112#if 1
1113 {2160,1250, 2048,1250} /* ? */
1114#endif
1115};
1116#endif
1117
1118/**************************************************************/ 1027/**************************************************************/
1119/* LVDS, CHRONTEL ------------------------------------------- */ 1028/* LVDS, CHRONTEL ------------------------------------------- */
1120/**************************************************************/ 1029/**************************************************************/
1121 1030
1122static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]= 1031static const struct SiS_LVDSData SiS310_CHTVUPALData[] =
1123{ 1032{
1124 {1008, 625,1008, 625}, 1033 {1008, 625,1008, 625},
1125 {1008, 625,1008, 625}, 1034 {1008, 625,1008, 625},
@@ -1130,7 +1039,7 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]=
1130 {1400,1000,1400,1000} 1039 {1400,1000,1400,1000}
1131}; 1040};
1132 1041
1133static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]= 1042static const struct SiS_LVDSData SiS310_CHTVOPALData[] =
1134{ 1043{
1135 {1008, 625,1008, 625}, 1044 {1008, 625,1008, 625},
1136 {1008, 625,1008, 625}, 1045 {1008, 625,1008, 625},
@@ -1138,10 +1047,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]=
1138 {1008, 625,1008, 625}, 1047 {1008, 625,1008, 625},
1139 { 840, 625, 840, 625}, 1048 { 840, 625, 840, 625},
1140 { 944, 625, 944, 625}, 1049 { 944, 625, 944, 625},
1141 {1400, 875,1400, 875} 1050 {1400, 875,1400, 875}
1142}; 1051};
1143 1052
1144static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]= 1053static const struct SiS_LVDSData SiS310_CHTVUPALMData[] =
1145{ 1054{
1146 { 840, 600, 840, 600}, 1055 { 840, 600, 840, 600},
1147 { 840, 600, 840, 600}, 1056 { 840, 600, 840, 600},
@@ -1149,10 +1058,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]=
1149 { 840, 600, 840, 600}, 1058 { 840, 600, 840, 600},
1150 { 784, 600, 784, 600}, 1059 { 784, 600, 784, 600},
1151 {1064, 750,1064, 750}, 1060 {1064, 750,1064, 750},
1152 {1160, 945,1160, 945} 1061 {1160, 945,1160, 945}
1153}; 1062};
1154 1063
1155static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]= 1064static const struct SiS_LVDSData SiS310_CHTVOPALMData[] =
1156{ 1065{
1157 { 840, 525, 840, 525}, 1066 { 840, 525, 840, 525},
1158 { 840, 525, 840, 525}, 1067 { 840, 525, 840, 525},
@@ -1160,10 +1069,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]=
1160 { 840, 525, 840, 525}, 1069 { 840, 525, 840, 525},
1161 { 784, 525, 784, 525}, 1070 { 784, 525, 784, 525},
1162 {1040, 700,1040, 700}, 1071 {1040, 700,1040, 700},
1163 {1160, 840,1160, 840} 1072 {1160, 840,1160, 840}
1164}; 1073};
1165 1074
1166static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]= 1075static const struct SiS_LVDSData SiS310_CHTVUPALNData[] =
1167{ 1076{
1168 {1008, 625,1008, 625}, 1077 {1008, 625,1008, 625},
1169 {1008, 625,1008, 625}, 1078 {1008, 625,1008, 625},
@@ -1174,7 +1083,7 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]=
1174 {1400,1000,1400,1000} 1083 {1400,1000,1400,1000}
1175}; 1084};
1176 1085
1177static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]= 1086static const struct SiS_LVDSData SiS310_CHTVOPALNData[] =
1178{ 1087{
1179 {1008, 625,1008, 625}, 1088 {1008, 625,1008, 625},
1180 {1008, 625,1008, 625}, 1089 {1008, 625,1008, 625},
@@ -1182,10 +1091,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]=
1182 {1008, 625,1008, 625}, 1091 {1008, 625,1008, 625},
1183 { 840, 625, 840, 625}, 1092 { 840, 625, 840, 625},
1184 { 944, 625, 944, 625}, 1093 { 944, 625, 944, 625},
1185 {1400, 875,1400, 875} 1094 {1400, 875,1400, 875}
1186}; 1095};
1187 1096
1188static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan - no effect on 7019) */ 1097static const struct SiS_LVDSData SiS310_CHTVSOPALData[] = /* (super overscan - no effect on 7019) */
1189{ 1098{
1190 {1008, 625,1008, 625}, 1099 {1008, 625,1008, 625},
1191 {1008, 625,1008, 625}, 1100 {1008, 625,1008, 625},
@@ -1196,1333 +1105,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan -
1196 {1400, 875,1400, 875} 1105 {1400, 875,1400, 875}
1197}; 1106};
1198 1107
1199
1200static const SiS_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
1201{
1202 { 0, 0},
1203 { 0, 0},
1204 { 0, 0},
1205 { 0, 0},
1206 { 0, 0},
1207 { 0, 0},
1208 { 0, 0},
1209 { 0, 0},
1210 { 0, 0}
1211};
1212
1213static const SiS_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
1214{
1215 { 0, 0},
1216 { 0, 0},
1217 { 0, 0},
1218 { 0, 0},
1219 { 0, 0},
1220 { 0, 0},
1221 { 0, 805},
1222 { 0, 0},
1223 { 0, 0}
1224};
1225
1226static const SiS_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
1227{
1228 { 0, 0},
1229 { 0, 0},
1230 { 0, 0},
1231 { 0, 0},
1232 { 0, 0},
1233 { 0, 0},
1234 { 0, 0},
1235 { 0, 1065},
1236 { 0, 0},
1237 { 0, 0}
1238};
1239
1240
1241static const SiS_LVDSDesStruct SiS310_PanelType03_1[]=
1242{
1243 { 0, 0},
1244 { 0, 0},
1245 { 0, 0},
1246 { 0, 0},
1247 { 0, 0},
1248 { 0, 0},
1249 { 0, 0},
1250 { 0, 0},
1251 { 0, 0}
1252};
1253
1254static const SiS_LVDSDesStruct SiS310_PanelType04_1[]=
1255{
1256 {1343, 798},
1257 {1343, 794},
1258 {1343, 798},
1259 {1343, 794},
1260 {1343, 0},
1261 {1343, 0},
1262 { 0, 805},
1263 { 0, 794},
1264 { 0, 0}
1265};
1266
1267static const SiS_LVDSDesStruct SiS310_PanelType05_1[]=
1268{
1269 {1343, 798},
1270 {1343, 794},
1271 {1343, 798},
1272 {1343, 794},
1273 {1343, 0},
1274 {1343, 0},
1275 { 0, 805},
1276 { 0, 794},
1277 { 0, 0}
1278};
1279
1280static const SiS_LVDSDesStruct SiS310_PanelType06_1[]=
1281{
1282 {1343, 798},
1283 {1343, 794},
1284 {1343, 798},
1285 {1343, 794},
1286 {1343, 0},
1287 {1343, 0},
1288 { 0, 805},
1289 { 0, 794},
1290 { 0, 0}
1291};
1292
1293static const SiS_LVDSDesStruct SiS310_PanelType07_1[]=
1294{
1295 {1343, 798},
1296 {1343, 794},
1297 {1343, 798},
1298 {1343, 794},
1299 {1343, 0},
1300 {1343, 0},
1301 { 0, 805},
1302 { 0, 794},
1303 { 0, 0}
1304};
1305
1306static const SiS_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */
1307{
1308 { 0, 0},
1309 { 0, 0},
1310 { 0, 0},
1311 { 0, 0},
1312 { 0, 0},
1313 { 0, 0},
1314 { 0, 0},
1315 { 0, 0},
1316 { 0, 0},
1317 { 0, 0},
1318 { 0, 0}
1319};
1320
1321static const SiS_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */
1322{
1323 { 0, 0},
1324 { 0, 0},
1325 { 0, 0},
1326 { 0, 0},
1327 { 0, 0},
1328 { 0, 0},
1329 { 0, 0},
1330 { 0, 0},
1331 { 0, 0},
1332 { 0, 0},
1333 { 0, 0}
1334};
1335
1336static const SiS_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */
1337{
1338 { 0, 0},
1339 { 0, 0},
1340 { 0, 0},
1341 { 0, 0},
1342 { 0, 0},
1343 { 0, 0},
1344 { 0, 0},
1345 { 0, 0},
1346 { 0, 0},
1347 { 0, 0},
1348 { 0, 0}
1349};
1350
1351static const SiS_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
1352{
1353 { 0, 524},
1354 { 0, 524},
1355 { 0, 524},
1356 { 0, 524},
1357 { 0, 524},
1358 { 0, 524},
1359 { 8, 524},
1360 { 0, 524}
1361};
1362
1363static const SiS_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
1364{
1365 { 0, 524},
1366 { 0, 524},
1367 { 0, 524},
1368 { 0, 524},
1369 { 0, 524},
1370 { 0, 524},
1371 { 8, 524},
1372 { 0, 524}
1373};
1374
1375static const SiS_LVDSDesStruct SiS310_PanelType0d_1[]=
1376{
1377 {1343, 798},
1378 {1343, 794},
1379 {1343, 798},
1380 {1343, 794},
1381 {1343, 0},
1382 {1343, 0},
1383 { 0, 805},
1384 { 0, 794},
1385 { 0, 0}
1386};
1387
1388static const SiS_LVDSDesStruct SiS310_PanelType0e_1[]=
1389{
1390 {1343, 798},
1391 {1343, 794},
1392 {1343, 798},
1393 {1343, 794},
1394 {1343, 0},
1395 {1343, 0},
1396 { 0, 805},
1397 { 0, 794},
1398 { 0, 0}
1399};
1400
1401static const SiS_LVDSDesStruct SiS310_PanelType0f_1[]=
1402{
1403 {1343, 798},
1404 {1343, 794},
1405 {1343, 798},
1406 {1343, 794},
1407 {1343, 0},
1408 {1343, 0},
1409 { 0, 805},
1410 { 0, 794},
1411 { 0, 0}
1412};
1413
1414static const SiS_LVDSDesStruct SiS310_PanelType00_2[]=
1415{
1416 {980, 528},
1417 {980, 503},
1418 {980, 528},
1419 {980, 503},
1420 {980, 568},
1421 { 0, 628},
1422 { 0, 0},
1423 { 0, 0},
1424 { 0, 0}
1425};
1426
1427static const SiS_LVDSDesStruct SiS310_PanelType01_2[]=
1428{
1429 {1152, 622},
1430 {1152, 597},
1431 {1152, 622},
1432 {1152, 597},
1433 {1152, 662},
1434 {1232, 722},
1435 { 0, 806},
1436 { 0, 0},
1437 { 0, 0}
1438};
1439
1440static const SiS_LVDSDesStruct SiS310_PanelType02_2[]=
1441{
1442 {1368, 754},
1443 {1368, 729},
1444 {1368, 754},
1445 {1368, 729},
1446 {1368, 794},
1447 {1448, 854},
1448 {1560, 938},
1449 { 0,1066},
1450 { 0, 0},
1451 { 0, 0},
1452 { 0, 0}
1453};
1454
1455static const SiS_LVDSDesStruct SiS310_PanelType03_2[]=
1456{
1457 { 0, 0},
1458 { 0, 0},
1459 { 0, 0},
1460 { 0, 0},
1461 { 0, 0},
1462 { 0, 0},
1463 { 0, 0}
1464};
1465
1466static const SiS_LVDSDesStruct SiS310_PanelType04_2[]=
1467{
1468 { 0, 0},
1469 { 0, 0},
1470 { 0, 0},
1471 { 0, 0},
1472 { 0, 0},
1473 { 0, 0},
1474 { 0, 0},
1475 { 0, 0},
1476 { 0, 0}
1477};
1478
1479static const SiS_LVDSDesStruct SiS310_PanelType05_2[]=
1480{
1481 {1152, 622},
1482 {1152, 597},
1483 {1152, 622},
1484 {1152, 597},
1485 {1152, 662},
1486 {1232, 722},
1487 { 0, 805},
1488 { 0, 794},
1489 { 0, 0}
1490};
1491
1492static const SiS_LVDSDesStruct SiS310_PanelType06_2[]=
1493{
1494 {1152, 622},
1495 {1152, 597},
1496 {1152, 622},
1497 {1152, 597},
1498 {1152, 662},
1499 {1232, 722},
1500 { 0, 805},
1501 { 0, 794},
1502 { 0, 0}
1503};
1504
1505static const SiS_LVDSDesStruct SiS310_PanelType07_2[]=
1506{
1507 {1152, 622},
1508 {1152, 597},
1509 {1152, 622},
1510 {1152, 597},
1511 {1152, 662},
1512 {1232, 722},
1513 { 0, 805},
1514 { 0, 794},
1515 { 0, 0}
1516};
1517
1518static const SiS_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */
1519{
1520 {1308, 741},
1521 {1308, 716},
1522 {1308, 741},
1523 {1308, 716},
1524 {1308, 781},
1525 {1388, 841},
1526 {1500, 925},
1527 {1628,1053},
1528 { 0,1065},
1529 { 0, 0},
1530 { 0, 0}
1531};
1532
1533static const SiS_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */
1534{
1535 {1083, 622},
1536 {1083, 597},
1537 {1083, 622},
1538 {1083, 597},
1539 {1083, 662},
1540 {1163, 722},
1541 {1286, 805},
1542 { 0, 794},
1543 { 0, 0}
1544};
1545
1546static const SiS_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */
1547{
1548 {1568, 920},
1549 {1568, 895},
1550 {1568, 920},
1551 {1568, 895},
1552 {1568, 960},
1553 {1648,1020},
1554 {1760,1104},
1555 {1888,1232},
1556 {1948,1245},
1557 { 0, 0}
1558#if 0
1559 {1568, 850},
1560 {1568, 825},
1561 {1568, 850},
1562 {1568, 825},
1563 {1568, 890},
1564 {1648, 950},
1565 {1760,1034},
1566 {1888,1162},
1567 {1948,1175},
1568 { 0, 0}
1569#endif
1570};
1571
1572static const SiS_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
1573{
1574 {1152, 622},
1575 {1152, 597},
1576 {1152, 622},
1577 {1152, 597},
1578 {1152, 662},
1579 {1232, 722},
1580 { 0, 805},
1581 { 0, 794},
1582 { 0, 0}
1583};
1584
1585static const SiS_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
1586{
1587 {1152, 622},
1588 {1152, 597},
1589 {1152, 622},
1590 {1152, 597},
1591 {1152, 662},
1592 {1232, 722},
1593 { 0, 805},
1594 { 0, 794},
1595 { 0, 0}
1596};
1597
1598static const SiS_LVDSDesStruct SiS310_PanelType0d_2[]=
1599{
1600 {1152, 622},
1601 {1152, 597},
1602 {1152, 622},
1603 {1152, 597},
1604 {1152, 662},
1605 {1232, 722},
1606 { 0, 805},
1607 { 0, 794},
1608 { 0, 0}
1609};
1610
1611static const SiS_LVDSDesStruct SiS310_PanelType0e_2[]=
1612{
1613 {1152, 622},
1614 {1152, 597},
1615 {1152, 622},
1616 {1152, 597},
1617 {1152, 662},
1618 {1232, 722},
1619 { 0, 805},
1620 { 0, 794},
1621 { 0, 0}
1622};
1623
1624static const SiS_LVDSDesStruct SiS310_PanelType0f_2[] =
1625{
1626 {1152, 622},
1627 {1152, 597},
1628 {1152, 622},
1629 {1152, 597},
1630 {1152, 662},
1631 {1232, 722},
1632 { 0, 805},
1633 { 0, 794},
1634 { 0, 0}
1635};
1636
1637static const SiS_LVDSDesStruct SiS310_PanelTypeNS_1[]=
1638{
1639 { 8, 0},
1640 { 8, 0},
1641 { 8, 0},
1642 { 8, 0},
1643 { 8, 0},
1644 { 0, 0},
1645 { 0, 0},
1646 { 0, 0},
1647 { 0, 806},
1648 { 0, 0}
1649};
1650
1651static const SiS_LVDSDesStruct SiS310_PanelTypeNS_2[] =
1652{
1653 { 0 , 0},
1654 { 0 , 0},
1655 { 0 , 0},
1656 { 0 , 0},
1657 { 0 , 0},
1658 { 0 , 0},
1659 { 0 , 0},
1660 { 0 , 0},
1661 { 0 , 0},
1662 { 0 , 0}
1663};
1664
1665/* CRT1 CRTC for SlaveModes and LCDA */
1666
1667static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
1668{
1669 {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
1670 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1671 0x00 }},
1672 {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
1673 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1674 0x00 }},
1675 {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
1676 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1677 0x00 }},
1678 {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
1679 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1680 0x00 }},
1681 {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
1682 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1683 0x00 }},
1684 {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
1685 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1686 0x01 }}
1687};
1688
1689static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
1690{
1691 {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
1692 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
1693 0x00 }},
1694 {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
1695 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1696 0x00 }},
1697 {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
1698 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1699 0x00 }},
1700 {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
1701 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
1702 0x00 }},
1703 {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
1704 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
1705 0x00 }},
1706 {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
1707 0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
1708 0x01 }}
1709};
1710
1711static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]=
1712{
1713 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1714 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
1715 0x00 }},
1716 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1717 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
1718 0x00 }},
1719 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1720 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
1721 0x00 }},
1722 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
1723 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
1724 0x00 }},
1725 {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
1726 0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
1727 0x00 }},
1728 {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
1729 0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
1730 0x01 }}
1731};
1732
1733static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
1734{
1735 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1736 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
1737 0x00 }},
1738 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1739 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
1740 0x00 }},
1741 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1742 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
1743 0x00 }},
1744 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
1745 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
1746 0x00 }},
1747 {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
1748 0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
1749 0x00 }},
1750 {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
1751 0x63,0x88,0x57,0x73,0x00,0x00,0x01,
1752 0x01 }}
1753};
1754
1755static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
1756{
1757 {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
1758 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1759 0x00}},
1760 {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
1761 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
1762 0x00}},
1763 {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
1764 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1765 0x00}},
1766 {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
1767 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
1768 0x00}},
1769 {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
1770 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
1771 0x00}},
1772 {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
1773 0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
1774 0x01}},
1775 {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
1776 0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
1777 0x01}}
1778};
1779
1780static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
1781{
1782 {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
1783 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1784 0x00 }},
1785 {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
1786 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
1787 0x00}},
1788 {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
1789 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
1790 0x00}},
1791 {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
1792 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
1793 0x00}},
1794 {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
1795 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
1796 0x00}},
1797 {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
1798 0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
1799 0x01}},
1800 {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
1801 0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
1802 0x01 }}
1803};
1804
1805static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
1806{
1807 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1808 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
1809 0x00 }},
1810 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1811 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
1812 0x00 }},
1813 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1814 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
1815 0x00 }},
1816 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1817 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
1818 0x01 }},
1819 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1820 0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
1821 0x00 }},
1822 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1823 0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
1824 0x01 }},
1825 {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
1826 0x02,0x89,0xff,0x25,0x10,0x00,0x02,
1827 0x01 }}
1828};
1829
1830static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
1831{
1832 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1833 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
1834 0x00 }},
1835 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1836 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
1837 0x00 }},
1838 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1839 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
1840 0x00 }},
1841 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1842 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
1843 0x00 }},
1844 {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
1845 0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
1846 0x00 }},
1847 {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
1848 0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
1849 0x01 }},
1850 {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
1851 0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
1852 0x01 }}
1853};
1854
1855static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
1856{
1857 {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
1858 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
1859 0x00}},
1860 {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
1861 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
1862 0x00}},
1863 {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
1864 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
1865 0x00}},
1866 {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
1867 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
1868 0x00}},
1869 {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e,
1870 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
1871 0x00}},
1872 {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0,
1873 0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
1874 0x01}},
1875 {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5,
1876 0x00,0x84,0xff,0x29,0x10,0x00,0x02,
1877 0x01}},
1878 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1879 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1880 0x01}}
1881};
1882
1883static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
1884{
1885 {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
1886 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
1887 0x00}},
1888 {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
1889 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
1890 0x00}},
1891 {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
1892 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
1893 0x00}},
1894 {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
1895 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
1896 0x01}},
1897 {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e,
1898 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
1899 0x00}},
1900 {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0,
1901 0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
1902 0x01}},
1903 {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5,
1904 0x00,0x84,0xff,0x29,0x10,0x00,0x01,
1905 0x01}}
1906};
1907
1908static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
1909{
1910 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1911 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
1912 0x01}},
1913 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1914 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
1915 0x01}},
1916 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1917 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
1918 0x01}},
1919 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1920 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
1921 0x01}},
1922 {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
1923 0xf0,0x84,0x85,0x84,0x11,0x00,0x02,
1924 0x01}},
1925 {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
1926 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
1927 0x01}},
1928 {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
1929 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
1930 0x01}},
1931 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
1932 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
1933 0x01}}
1934};
1935
1936static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
1937{
1938 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1939 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
1940 0x01}},
1941 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1942 0xaf,0x83,0x44,0x43,0x21,0x00,0x06,
1943 0x01}},
1944 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1945 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
1946 0x01}},
1947 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1948 0xfa,0x83,0x44,0x43,0x31,0x00,0x06,
1949 0x01}},
1950 {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
1951 0xf0,0x84,0x85,0x84,0x11,0x00,0x06,
1952 0x01}},
1953 {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
1954 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
1955 0x01}},
1956 {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4,
1957 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
1958 0x01}}
1959};
1960
1961static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
1962{
1963 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1964 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
1965 0x00}},
1966 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1967 0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05,
1968 0x00}},
1969 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1970 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
1971 0x00}},
1972 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1973 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1974 0x00}},
1975 {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
1976 0xdf,0x82,0xdf,0xef,0x10,0x00,0x05,
1977 0x00}},
1978 {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
1979 0x57,0x8e,0x57,0x67,0x20,0x00,0x06,
1980 0x01}},
1981 {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1,
1982 0xff,0x86,0xff,0x0f,0x10,0x00,0x02,
1983 0x01,}},
1984 {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde,
1985 0xff,0x86,0xff,0x0f,0x01,0x00,0x07,
1986 0x01}},
1987 {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
1988 0x19,0x80,0x19,0x29,0x0f,0x00,0x03,
1989 0x00}}
1990#if 0
1991 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1992 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
1993 0x00}},
1994 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
1995 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1996 0x00}},
1997 {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
1998 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
1999 0x00}},
2000 {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
2001 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2002 0x00}},
2003 {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
2004 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
2005 0x00}},
2006 {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
2007 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06,
2008 0x01}},
2009 {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
2010 0x02,0x86,0xff,0x0f,0x10,0x00,0x02,
2011 0x01}},
2012 {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
2013 0x02,0x86,0xff,0x0f,0x09,0x00,0x07,
2014 0x01}},
2015 {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
2016 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
2017 0x00}}
2018#endif
2019};
2020
2021static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] =
2022{
2023 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
2024 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
2025 0x00}},
2026 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2027 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2028 0x00}},
2029 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
2030 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
2031 0x00}},
2032 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2033 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2034 0x00}},
2035 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
2036 0xdf,0x86,0xdf,0xef,0x10,0x00,0x05,
2037 0x00}},
2038 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
2039 0x57,0x8e,0x57,0x67,0x20,0x00,0x01,
2040 0x01}},
2041 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1,
2042 0xff,0x86,0xff,0x0f,0x10,0x00,0x01,
2043 0x01}},
2044 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
2045 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
2046 0x01}},
2047 {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
2048 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
2049 0x00}}
2050#if 0
2051 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
2052 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
2053 0x00}},
2054 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2055 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2056 0x00}},
2057 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
2058 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
2059 0x00}},
2060 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
2061 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
2062 0x00}},
2063 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
2064 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
2065 0x00}},
2066 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
2067 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
2068 0x01}},
2069 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
2070 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
2071 0x01}},
2072 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
2073 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
2074 0x01}},
2075 {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
2076 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
2077 0x00}}
2078#endif
2079};
2080
2081static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] =
2082{
2083 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2084 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
2085 0x01}},
2086 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2087 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
2088 0x01}},
2089 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2090 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
2091 0x01}},
2092 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2093 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
2094 0x01}},
2095 {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
2096 0xff,0x83,0x85,0x84,0x11,0x00,0x02,
2097 0x01}},
2098 {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4,
2099 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
2100 0x01}},
2101 {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4,
2102 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
2103 0x01}},
2104 {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a,
2105 0x13,0x87,0xff,0x29,0x29,0x00,0x07,
2106 0x01}},
2107 {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
2108 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
2109 0x00}}
2110#if 0
2111 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2112 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
2113 0x00}},
2114 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2115 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
2116 0x01}},
2117 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2118 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
2119 0x00}},
2120 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
2121 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
2122 0x00}},
2123 {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
2124 0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
2125 0x00}},
2126 {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4,
2127 0x3f,0x83,0x57,0x29,0x01,0x00,0x07,
2128 0x01}},
2129 {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4,
2130 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
2131 0x01}},
2132 {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a,
2133 0x13,0x87,0xff,0x29,0x29,0x00,0x03,
2134 0x01}},
2135 {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
2136 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
2137 0x00}}
2138#endif
2139};
2140
2141static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] =
2142{
2143 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2144 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
2145 0x01}},
2146 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2147 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
2148 0x01}},
2149 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2150 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
2151 0x01}},
2152 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2153 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
2154 0x01}},
2155 {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
2156 0xff,0x83,0x85,0x84,0x11,0x00,0x06,
2157 0x01}},
2158 {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4,
2159 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
2160 0x01}},
2161 {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4,
2162 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
2163 0x01}},
2164 {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a,
2165 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
2166 0x01}},
2167 {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
2168 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
2169 0x00}}
2170#if 0
2171 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2172 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
2173 0x00}},
2174 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2175 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
2176 0x00}},
2177 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2178 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
2179 0x00}},
2180 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
2181 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
2182 0x00}},
2183 {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e,
2184 0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
2185 0x00}},
2186 {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4,
2187 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
2188 0x01}},
2189 {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4,
2190 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
2191 0x01}},
2192 {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a,
2193 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
2194 0x01}},
2195 {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
2196 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
2197 0x00}}
2198#endif
2199};
2200
2201static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
2202{
2203 {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
2204 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
2205 0x00}},
2206 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2207 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2208 0x00}},
2209 {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
2210 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
2211 0x00}},
2212 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2213 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2214 0x00}},
2215 {{0x83,0x4F,0x87,0x5B,0x13,0x56,0xBA,
2216 0x03,0x86,0xDF,0x57,0x00,0x00,0x06,
2217 0x00}},
2218 {{0x97,0x63,0x9B,0x6F,0x07,0xCE,0xF0,
2219 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x02,
2220 0x01}},
2221 {{0xB3,0x7F,0x97,0x8B,0x83,0x76,0xF5,
2222 0x23,0x86,0xFF,0x77,0x10,0x00,0x06,
2223 0x01}},
2224 {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
2225 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
2226 0x01}},
2227 {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
2228 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
2229 0x00}},
2230 {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
2231 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
2232 0x00}}
2233#if 0
2234 {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
2235 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
2236 0x00}},
2237 {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
2238 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
2239 0x00}},
2240 {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
2241 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
2242 0x00}},
2243 {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
2244 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
2245 0x00}},
2246 {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e,
2247 0xe0,0x84,0xdf,0x11,0x00,0x00,0x06,
2248 0x00}},
2249 {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0,
2250 0x58,0x8c,0x57,0x89,0x20,0x00,0x06,
2251 0x01}},
2252 {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5,
2253 0x00,0x84,0xff,0x31,0x10,0x00,0x02,
2254 0x01}},
2255 {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a,
2256 0x00,0x84,0xff,0x31,0x09,0x00,0x07,
2257 0x01}},
2258 {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10,
2259 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03,
2260 0x00}},
2261 {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
2262 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
2263 0x00}}
2264#endif
2265};
2266
2267static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
2268{
2269 {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
2270 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
2271 0x00}},
2272 {{0x5B,0x27,0x9F,0x29,0x01,0x8E,0x1F,
2273 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2274 0x00}},
2275 {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
2276 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
2277 0x00}},
2278 {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
2279 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
2280 0x00}},
2281 {{0x5B,0x27,0x9F,0x33,0x0B,0x56,0xBA,
2282 0x03,0x86,0xDF,0x57,0x00,0x00,0x01,
2283 0x00}},
2284 {{0x65,0x31,0x89,0x3D,0x95,0xCE,0xF0,
2285 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x01,
2286 0x01}},
2287 {{0x73,0x3F,0x97,0x4B,0x83,0x76,0xF5,
2288 0x23,0x86,0xFF,0x77,0x10,0x00,0x05,
2289 0x01}},
2290 {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
2291 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
2292 0x01}},
2293 {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
2294 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
2295 0x00}},
2296 {{0x97,0x63,0x9B,0x6F,0x07,0xE0,0x10,
2297 0xB0,0x84,0xAF,0xE1,0x2F,0x00,0x06,
2298 0x00}}
2299#if 0
2300 {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
2301 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
2302 0x00}},
2303 {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
2304 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
2305 0x00}},
2306 {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
2307 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
2308 0x00}},
2309 {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
2310 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
2311 0x00}},
2312 {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e,
2313 0xe0,0x84,0xdf,0x11,0x00,0x00,0x01,
2314 0x00}},
2315 {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0,
2316 0x58,0x8c,0x57,0x89,0x20,0x00,0x01,
2317 0x01}},
2318 {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5,
2319 0x00,0x84,0xff,0x31,0x10,0x00,0x01,
2320 0x01}},
2321 {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a,
2322 0x00,0x84,0xff,0x31,0x09,0x00,0x06,
2323 0x01}},
2324 {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10,
2325 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06,
2326 0x00}},
2327 {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
2328 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
2329 0x00}}
2330#endif
2331};
2332
2333static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
2334{
2335 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2336 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
2337 0x01}},
2338 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2339 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
2340 0x01}},
2341 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2342 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
2343 0x01}},
2344 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
2345 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
2346 0x01}},
2347 {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x9F,
2348 0x6B,0x8E,0x03,0x02,0x01,0x00,0x07,
2349 0x01}},
2350 {{0xFB,0x63,0x9F,0xA1,0x99,0x26,0xD5,
2351 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x07,
2352 0x01}},
2353 {{0xFB,0x7F,0x9F,0xAF,0x87,0x26,0xDD,
2354 0xFB,0x8E,0x13,0x12,0x31,0x00,0x03,
2355 0x01}},
2356 {{0xFB,0x9F,0x9F,0xBF,0x97,0x26,0x5B,
2357 0x7B,0x8E,0xFF,0x27,0x39,0x00,0x03,
2358 0x01}},
2359 {{0xFB,0xAE,0x9F,0xC6,0x9E,0x26,0x11,
2360 0x88,0x8B,0x19,0x27,0x1F,0x00,0x03,
2361 0x00}},
2362 {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
2363 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
2364 0x00}}
2365#if 0
2366 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2367 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
2368 0x01}},
2369 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2370 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
2371 0x01}},
2372 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2373 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
2374 0x01}},
2375 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2376 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
2377 0x01}},
2378 {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
2379 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07,
2380 0x01}},
2381 {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4,
2382 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07,
2383 0x01}},
2384 {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4,
2385 0xef,0x83,0xff,0xe1,0x21,0x00,0x03,
2386 0x01}},
2387 {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a,
2388 0x6f,0x83,0xff,0xe1,0x29,0x00,0x03,
2389 0x01}},
2390 {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10,
2391 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03,
2392 0x00}},
2393 {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
2394 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
2395 0x00}}
2396#endif
2397};
2398
2399static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] =
2400{
2401 {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
2402 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
2403 0x01}},
2404 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2405 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
2406 0x01}},
2407 {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
2408 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
2409 0x01}},
2410 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2411 0x07,0x8B,0xA0,0x9F,0x01,0x00,0x02,
2412 0x01}},
2413 {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
2414 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
2415 0x01}},
2416 {{0xC9,0x31,0x8D,0x6F,0x07,0x26,0xD5,
2417 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x03,
2418 0x01}},
2419 {{0xBB,0x3F,0x9F,0x6F,0x87,0x26,0xDD,
2420 0xFB,0x8E,0x13,0x12,0x31,0x00,0x02,
2421 0x01}},
2422 {{0xAB,0x4F,0x8F,0x68,0x80,0xE0,0x5A,
2423 0x6F,0x83,0xFF,0xE1,0x29,0x00,0x02,
2424 0x01}},
2425 {{0xA3,0x56,0x87,0x67,0x9F,0xE0,0x10,
2426 0x7C,0x80,0x19,0xE1,0x0F,0x00,0x06,
2427 0x00}},
2428 {{0x97,0x63,0x9B,0x68,0x00,0xE0,0x10,
2429 0xC7,0x8B,0xAF,0xE1,0x0F,0x00,0x02,
2430 0x00}}
2431#if 0
2432 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2433 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
2434 0x01}},
2435 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2436 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
2437 0x01}},
2438 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2439 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
2440 0x01}},
2441 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2442 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
2443 0x01}},
2444 {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
2445 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02,
2446 0x01}},
2447 {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4,
2448 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03,
2449 0x01}},
2450 {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4,
2451 0xef,0x83,0xff,0xe1,0x21,0x00,0x02,
2452 0x01}},
2453 {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a,
2454 0x6f,0x83,0xff,0xe1,0x29,0x00,0x02,
2455 0x01}},
2456 {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10,
2457 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06,
2458 0x00}},
2459 {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
2460 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
2461 0x00}}
2462#endif
2463};
2464
2465static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] =
2466{
2467 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2468 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2469 0x00}},
2470 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2471 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2472 0x00}},
2473 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2474 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2475 0x00}},
2476 {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
2477 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
2478 0x00}},
2479 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
2480 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
2481 0x00}},
2482 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
2483 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
2484 0x01}},
2485 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
2486 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
2487 0x01}},
2488 {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
2489 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
2490 0x01}},
2491 {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
2492 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
2493 0x01}}
2494};
2495
2496static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] =
2497{
2498 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2499 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2500 0x00}},
2501 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2502 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2503 0x00}},
2504 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2505 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2506 0x00}},
2507 {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
2508 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
2509 0x00}},
2510 {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
2511 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
2512 0x00}},
2513 {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
2514 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
2515 0x01}},
2516 {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
2517 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
2518 0x01}}
2519};
2520
2521
2522/* CRT1 CRTC for Chrontel TV slave modes */ 1108/* CRT1 CRTC for Chrontel TV slave modes */
2523 1109
2524static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] = 1110static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UNTSC[] =
2525{ 1111{
2526 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e, 1112 {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
2527 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01, 1113 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
2528 0x00 }}, 1114 0x00 }},
@@ -2546,7 +1132,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
2546 0x01}} 1132 0x01}}
2547}; 1133};
2548 1134
2549static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] = 1135static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1ONTSC[] =
2550{ 1136{
2551 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e, 1137 {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
2552 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01, 1138 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -2571,8 +1157,8 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
2571 0x01 }} 1157 0x01 }}
2572}; 1158};
2573 1159
2574static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] = 1160static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UPAL[] =
2575{ 1161{
2576 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 1162 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2577 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05, 1163 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
2578 0x00 }}, 1164 0x00 }},
@@ -2596,7 +1182,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
2596 0x01}} 1182 0x01}}
2597}; 1183};
2598 1184
2599static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] = 1185static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1OPAL[] =
2600{ 1186{
2601 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e, 1187 {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
2602 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05, 1188 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2621,8 +1207,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
2621 0x01 }} 1207 0x01 }}
2622}; 1208};
2623 1209
2624 1210static const struct SiS_CHTVRegData SiS310_CHTVReg_UNTSC[] =
2625static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
2626{ 1211{
2627 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1212 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2628 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1213 {{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2642,7 +1227,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
2642 for PAL-M and PAL-N all above is corrected. 1227 for PAL-M and PAL-N all above is corrected.
2643 */ 1228 */
2644 1229
2645static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = 1230static const struct SiS_CHTVRegData SiS310_CHTVReg_ONTSC[] =
2646{ 1231{
2647 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1232 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2648 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1233 {{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2653,7 +1238,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
2653 {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}} 1238 {{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
2654}; 1239};
2655 1240
2656static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = 1241static const struct SiS_CHTVRegData SiS310_CHTVReg_UPAL[] =
2657{ 1242{
2658 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1243 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2659 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1244 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2664,7 +1249,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
2664 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}} 1249 {{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
2665}; 1250};
2666 1251
2667static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = 1252static const struct SiS_CHTVRegData SiS310_CHTVReg_OPAL[] =
2668{ 1253{
2669 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1254 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2670 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1255 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2675,7 +1260,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
2675 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}} 1260 {{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
2676}; 1261};
2677 1262
2678static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] = 1263static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALM[] =
2679{ 1264{
2680 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1265 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2681 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1266 {{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2691,7 +1276,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
2691#endif 1276#endif
2692}; 1277};
2693 1278
2694static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] = 1279static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALM[] =
2695{ 1280{
2696 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1281 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
2697 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}}, 1282 {{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -2707,7 +1292,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
2707#endif 1292#endif
2708}; 1293};
2709 1294
2710static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] = 1295static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALN[] =
2711{ 1296{
2712 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}, 1297 {{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2713 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}, 1298 {{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
@@ -2723,7 +1308,7 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
2723#endif 1308#endif
2724}; 1309};
2725 1310
2726static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] = 1311static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALN[] =
2727{ 1312{
2728 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}, 1313 {{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
2729 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}}, 1314 {{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
@@ -2739,16 +1324,16 @@ static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
2739#endif 1324#endif
2740}; 1325};
2741 1326
2742static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53}; 1327static const unsigned char SiS310_CHTVVCLKUNTSC[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
2743static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51}; 1328static const unsigned char SiS310_CHTVVCLKONTSC[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
2744 1329
2745static const UCHAR SiS310_CHTVVCLKUPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54}; 1330static const unsigned char SiS310_CHTVVCLKUPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
2746static const UCHAR SiS310_CHTVVCLKOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; 1331static const unsigned char SiS310_CHTVVCLKOPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
2747 1332
2748static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53}; 1333static const unsigned char SiS310_CHTVVCLKUPALM[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
2749static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51}; 1334static const unsigned char SiS310_CHTVVCLKOPALM[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
2750 1335
2751static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54}; 1336static const unsigned char SiS310_CHTVVCLKUPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
2752static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52}; 1337static const unsigned char SiS310_CHTVVCLKOPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
2753 1338
2754 1339
diff --git a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
index aaed8c2b4a64..f7c0046e5b1d 100644
--- a/drivers/video/sis/Makefile
+++ b/drivers/video/sis/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_FB_SIS) += sisfb.o 5obj-$(CONFIG_FB_SIS) += sisfb.o
6 6
7sisfb-objs := sis_main.o sis_accel.o init.o init301.o 7sisfb-objs := sis_main.o sis_accel.o init.o init301.o initextlfb.o
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index ecfd72178dbb..2ab3868efde3 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -2,11 +2,12 @@
2/* $XdotOrg$ */ 2/* $XdotOrg$ */
3/* 3/*
4 * Mode initializing code (CRT1 section) for 4 * Mode initializing code (CRT1 section) for
5 * for SiS 300/305/540/630/730 and 5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760 6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7 * (Universal module for Linux kernel framebuffer and XFree86 4.x) 7 * XGI Volari V3XT/V5/V8, Z7
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
8 * 9 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
10 * 11 *
11 * If distributed as part of the Linux kernel, the following license terms 12 * If distributed as part of the Linux kernel, the following license terms
12 * apply: 13 * apply:
@@ -53,17 +54,12 @@
53 * 54 *
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission. 56 * Used by permission.
56 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if they are marked TW or not.
64 *
65 */ 57 */
66 58
59#ifdef HAVE_CONFIG_H
60#include "config.h"
61#endif
62
67#include "init.h" 63#include "init.h"
68 64
69#ifdef SIS300 65#ifdef SIS300
@@ -84,24 +80,13 @@
84 80
85#if defined(SIS300) || defined(SIS315H) 81#if defined(SIS300) || defined(SIS315H)
86static void 82static void
87InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 83InitCommonPointer(struct SiS_Private *SiS_Pr)
88{ 84{
85 SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable;
89 SiS_Pr->SiS_StResInfo = SiS_StResInfo; 86 SiS_Pr->SiS_StResInfo = SiS_StResInfo;
90 SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo; 87 SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
91 SiS_Pr->SiS_StandTable = SiS_StandTable; 88 SiS_Pr->SiS_StandTable = SiS_StandTable;
92 89
93 SiS_Pr->SiS_NTSCPhase = SiS_NTSCPhase;
94 SiS_Pr->SiS_PALPhase = SiS_PALPhase;
95 SiS_Pr->SiS_NTSCPhase2 = SiS_NTSCPhase2;
96 SiS_Pr->SiS_PALPhase2 = SiS_PALPhase2;
97 SiS_Pr->SiS_PALMPhase = SiS_PALMPhase;
98 SiS_Pr->SiS_PALNPhase = SiS_PALNPhase;
99 SiS_Pr->SiS_PALMPhase2 = SiS_PALMPhase2;
100 SiS_Pr->SiS_PALNPhase2 = SiS_PALNPhase2;
101 SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
102 SiS_Pr->SiS_SpecialPhaseM = SiS_SpecialPhaseM;
103 SiS_Pr->SiS_SpecialPhaseJ = SiS_SpecialPhaseJ;
104
105 SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming; 90 SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
106 SiS_Pr->SiS_PALTiming = SiS_PALTiming; 91 SiS_Pr->SiS_PALTiming = SiS_PALTiming;
107 SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing; 92 SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
@@ -137,6 +122,7 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
137 SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data; 122 SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
138 SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data; 123 SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
139 SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data; 124 SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data;
125 SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data;
140 SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data; 126 SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
141 SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data; 127 SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
142 SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data; 128 SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
@@ -145,67 +131,30 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
145 SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data; 131 SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
146 SiS_Pr->SiS_NoScaleData = SiS_NoScaleData; 132 SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
147 133
148 SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1; 134 SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1;
135 SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2;
136 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
149 SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1; 137 SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
150 SiS_Pr->SiS_LVDS800x600Data_2 = SiS_LVDS800x600Data_2;
151 SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
152 SiS_Pr->SiS_LVDS1024x768Data_2 = SiS_LVDS1024x768Data_2;
153 SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
154 SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
155 SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
156 SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
157 SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
158 SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
159 SiS_Pr->SiS_LVDS1280x768Data_1 = SiS_LVDS1280x768Data_1;
160 SiS_Pr->SiS_LVDS1280x768Data_2 = SiS_LVDS1280x768Data_2;
161 SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1; 138 SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
162 SiS_Pr->SiS_LVDS1024x600Data_2 = SiS_LVDS1024x600Data_2; 139 SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
163 SiS_Pr->SiS_LVDS1152x768Data_1 = SiS_LVDS1152x768Data_1;
164 SiS_Pr->SiS_LVDS1152x768Data_2 = SiS_LVDS1152x768Data_2;
165 SiS_Pr->SiS_LVDSXXXxXXXData_1 = SiS_LVDSXXXxXXXData_1;
166 SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x960Data_1;
167 SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x960Data_2;
168 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
169 SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x1024Data_1;
170 SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x1024Data_2;
171 SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
172 SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2;
173
174 SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1;
175 SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2;
176 SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
177 SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
178 SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
179 SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
180 140
181 SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1; 141 SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1;
142 SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2;
143 SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H;
144 SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3;
145 SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H;
146 SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
147 SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
148#if 0
182 SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1; 149 SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
183 SiS_Pr->SiS_LVDSCRT11152x768_1 = SiS_LVDSCRT11152x768_1;
184 SiS_Pr->SiS_LVDSCRT11280x768_1_H = SiS_LVDSCRT11280x768_1_H;
185 SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H; 150 SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
186 SiS_Pr->SiS_LVDSCRT11152x768_1_H = SiS_LVDSCRT11152x768_1_H;
187 SiS_Pr->SiS_LVDSCRT11280x768_2 = SiS_LVDSCRT11280x768_2;
188 SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2; 151 SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
189 SiS_Pr->SiS_LVDSCRT11152x768_2 = SiS_LVDSCRT11152x768_2;
190 SiS_Pr->SiS_LVDSCRT11280x768_2_H = SiS_LVDSCRT11280x768_2_H;
191 SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H; 152 SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
192 SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H; 153#endif
193 SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1;
194 SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
195 SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
196 SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2;
197 SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H;
198 SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3;
199 SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H;
200 154
201 SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData; 155 SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
202 SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData; 156 SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
203 157
204 SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
205 SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
206 SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
207 SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
208
209 SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */ 158 SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
210 SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */ 159 SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
211} 160}
@@ -213,50 +162,24 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
213 162
214#ifdef SIS300 163#ifdef SIS300
215static void 164static void
216InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 165InitTo300Pointer(struct SiS_Private *SiS_Pr)
217{ 166{
218 InitCommonPointer(SiS_Pr, HwInfo); 167 InitCommonPointer(SiS_Pr);
219 168
220 SiS_Pr->SiS_SModeIDTable = SiS300_SModeIDTable;
221 SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable; 169 SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
222 SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable; 170 SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
223 SiS_Pr->SiS_RefIndex = SiS300_RefIndex; 171 SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
224 SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table; 172 SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
225 if(HwInfo->jChipType == SIS_300) { 173 if(SiS_Pr->ChipType == SIS_300) {
226 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */ 174 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
227 } else { 175 } else {
228 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */ 176 SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
229 } 177 }
230 SiS_Pr->SiS_VCLKData = SiS300_VCLKData; 178 SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
231 SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData; 179 SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData;
232 180
233 SiS_Pr->SiS_SR15 = SiS300_SR15; 181 SiS_Pr->SiS_SR15 = SiS300_SR15;
234 182
235#ifdef LINUX_KERNEL
236 SiS_Pr->pSiS_SR07 = &SiS300_SR07;
237 SiS_Pr->SiS_CR40 = SiS300_CR40;
238 SiS_Pr->SiS_CR49 = SiS300_CR49;
239 SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
240 SiS_Pr->pSiS_SR21 = &SiS300_SR21;
241 SiS_Pr->pSiS_SR22 = &SiS300_SR22;
242 SiS_Pr->pSiS_SR23 = &SiS300_SR23;
243 SiS_Pr->pSiS_SR24 = &SiS300_SR24;
244 SiS_Pr->SiS_SR25 = SiS300_SR25;
245 SiS_Pr->pSiS_SR31 = &SiS300_SR31;
246 SiS_Pr->pSiS_SR32 = &SiS300_SR32;
247 SiS_Pr->pSiS_SR33 = &SiS300_SR33;
248 SiS_Pr->pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
249 SiS_Pr->pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
250 SiS_Pr->pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
251 SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
252 SiS_Pr->pSiS_RGBSenseData = &SiS300_RGBSenseData;
253 SiS_Pr->pSiS_VideoSenseData = &SiS300_VideoSenseData;
254 SiS_Pr->pSiS_YCSenseData = &SiS300_YCSenseData;
255 SiS_Pr->pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
256 SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
257 SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2;
258#endif
259
260 SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl; 183 SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
261 SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl; 184 SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
262 185
@@ -266,11 +189,8 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
266 SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data; 189 SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
267 190
268 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1; 191 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
269 SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
270 SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2; 192 SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
271 SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
272 SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3; 193 SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
273 SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
274 194
275 SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData; 195 SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
276 SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData; 196 SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
@@ -280,64 +200,16 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
280 SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */ 200 SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */
281 SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData; 201 SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
282 202
283 SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1; 203 SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1;
284 SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1; 204 SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2;
285 SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1; 205 SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
286 SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1; 206 SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
287 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1; 207 SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
288 SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1; 208
289 SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1; 209 SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
290 SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1; 210 SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
291 SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1; 211 SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
292 SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1; 212 SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
293 SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
294 SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
295 SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
296 SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
297 SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
298 SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
299 SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
300 SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
301 SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
302 SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
303 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
304 SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
305 SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
306 SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
307 SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
308 SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
309 SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
310 SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
311 SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
312 SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
313 SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
314 SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
315 SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
316 SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
317
318 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
319 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
320 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
321 }
322 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
323 SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
324 SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
325 }
326
327 SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS300_LVDSCRT1800x600_1;
328 SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS300_LVDSCRT1800x600_1_H;
329 SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS300_LVDSCRT1800x600_2;
330 SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS300_LVDSCRT1800x600_2_H;
331 SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS300_LVDSCRT11024x768_1;
332 SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS300_LVDSCRT11024x768_1_H;
333 SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS300_LVDSCRT11024x768_2;
334 SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS300_LVDSCRT11024x768_2_H;
335 SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS300_LVDSCRT11280x1024_1;
336 SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
337 SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS300_LVDSCRT11280x1024_2;
338 SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
339 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS300_LVDSCRT1XXXxXXX_1;
340 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS300_LVDSCRT1XXXxXXX_1_H;
341 213
342 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC; 214 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
343 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC; 215 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
@@ -367,64 +239,38 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
367 239
368#ifdef SIS315H 240#ifdef SIS315H
369static void 241static void
370InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 242InitTo310Pointer(struct SiS_Private *SiS_Pr)
371{ 243{
372 InitCommonPointer(SiS_Pr, HwInfo); 244 InitCommonPointer(SiS_Pr);
373 245
374 SiS_Pr->SiS_SModeIDTable = SiS310_SModeIDTable;
375 SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable; 246 SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
376 SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex; 247 SiS_Pr->SiS_RefIndex = SiS310_RefIndex;
377 SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table; 248 SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
378 if(HwInfo->jChipType >= SIS_340) { 249 if(SiS_Pr->ChipType >= SIS_340) {
379 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 */ 250 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 + XGI */
380 } else if(HwInfo->jChipType >= SIS_761) { 251 } else if(SiS_Pr->ChipType >= SIS_761) {
381 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */ 252 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */
382 } else if(HwInfo->jChipType >= SIS_760) { 253 } else if(SiS_Pr->ChipType >= SIS_760) {
383 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */ 254 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */
384 } else if(HwInfo->jChipType >= SIS_661) { 255 } else if(SiS_Pr->ChipType >= SIS_661) {
385 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */ 256 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */
386 } else if(HwInfo->jChipType == SIS_330) { 257 } else if(SiS_Pr->ChipType == SIS_330) {
387 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */ 258 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */
388 } else if(HwInfo->jChipType > SIS_315PRO) { 259 } else if(SiS_Pr->ChipType > SIS_315PRO) {
389 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */ 260 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */
390 } else { 261 } else {
391 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */ 262 SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */
392 } 263 }
393 if(HwInfo->jChipType >= SIS_340) { 264 if(SiS_Pr->ChipType >= SIS_340) {
394 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340; 265 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
395 } else { 266 } else {
396 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1; 267 SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
397 } 268 }
398 SiS_Pr->SiS_VCLKData = SiS310_VCLKData; 269 SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
399 SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData; 270 SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
400 271
401 SiS_Pr->SiS_SR15 = SiS310_SR15; 272 SiS_Pr->SiS_SR15 = SiS310_SR15;
402 273
403#ifdef LINUX_KERNEL
404 SiS_Pr->pSiS_SR07 = &SiS310_SR07;
405 SiS_Pr->SiS_CR40 = SiS310_CR40;
406 SiS_Pr->SiS_CR49 = SiS310_CR49;
407 SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
408 SiS_Pr->pSiS_SR21 = &SiS310_SR21;
409 SiS_Pr->pSiS_SR22 = &SiS310_SR22;
410 SiS_Pr->pSiS_SR23 = &SiS310_SR23;
411 SiS_Pr->pSiS_SR24 = &SiS310_SR24;
412 SiS_Pr->SiS_SR25 = SiS310_SR25;
413 SiS_Pr->pSiS_SR31 = &SiS310_SR31;
414 SiS_Pr->pSiS_SR32 = &SiS310_SR32;
415 SiS_Pr->pSiS_SR33 = &SiS310_SR33;
416 SiS_Pr->pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
417 SiS_Pr->pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
418 SiS_Pr->pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
419 SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
420 SiS_Pr->pSiS_RGBSenseData = &SiS310_RGBSenseData;
421 SiS_Pr->pSiS_VideoSenseData = &SiS310_VideoSenseData;
422 SiS_Pr->pSiS_YCSenseData = &SiS310_YCSenseData;
423 SiS_Pr->pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
424 SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
425 SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2;
426#endif
427
428 SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl; 274 SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
429 SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS; 275 SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
430 276
@@ -435,41 +281,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
435 281
436 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1; 282 SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
437 283
438 SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
439 SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
440 SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
441 SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
442 SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
443 SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
444 SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
445 SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
446 SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
447 SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
448 SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
449 SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
450 SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
451 SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
452 SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
453 SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
454 SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
455 SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
456 SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
457 SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
458 SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
459 SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
460 SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
461 SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
462 SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
463 SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
464 SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
465 SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
466 SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
467 SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
468 SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
469 SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
470 SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
471 SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
472
473 SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData; 284 SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
474 SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData; 285 SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
475 SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData; 286 SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
@@ -478,33 +289,11 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
478 SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData; 289 SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
479 SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData; 290 SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
480 291
481 SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS310_LVDSCRT1800x600_1; 292 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
482 SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS310_LVDSCRT11024x768_1; 293 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
483 SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS310_LVDSCRT11280x1024_1; 294 SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
484 SiS_Pr->SiS_LVDSCRT11400x1050_1 = SiS310_LVDSCRT11400x1050_1; 295 SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
485 SiS_Pr->SiS_LVDSCRT11600x1200_1 = SiS310_LVDSCRT11600x1200_1; 296 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
486 SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS310_LVDSCRT1800x600_1_H;
487 SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS310_LVDSCRT11024x768_1_H;
488 SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
489 SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
490 SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
491 SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS310_LVDSCRT1800x600_2;
492 SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS310_LVDSCRT11024x768_2;
493 SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS310_LVDSCRT11280x1024_2;
494 SiS_Pr->SiS_LVDSCRT11400x1050_2 = SiS310_LVDSCRT11400x1050_2;
495 SiS_Pr->SiS_LVDSCRT11600x1200_2 = SiS310_LVDSCRT11600x1200_2;
496 SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS310_LVDSCRT1800x600_2_H;
497 SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS310_LVDSCRT11024x768_2_H;
498 SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
499 SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
500 SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
501 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS310_LVDSCRT1XXXxXXX_1;
502 SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS310_LVDSCRT1XXXxXXX_1_H;
503 SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
504 SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
505 SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
506 SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
507 SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
508 297
509 SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC; 298 SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
510 SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC; 299 SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
@@ -528,208 +317,203 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
528} 317}
529#endif 318#endif
530 319
531static void 320BOOLEAN
532SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 321SiSInitPtr(struct SiS_Private *SiS_Pr)
533{ 322{
534 switch(HwInfo->jChipType) { 323 if(SiS_Pr->ChipType < SIS_315H) {
535#ifdef SIS315H
536 case SIS_315H:
537 case SIS_315:
538 case SIS_315PRO:
539 case SIS_550:
540 case SIS_650:
541 case SIS_740:
542 case SIS_330:
543 case SIS_661:
544 case SIS_741:
545 case SIS_660:
546 case SIS_760:
547 case SIS_761:
548 case SIS_340:
549 InitTo310Pointer(SiS_Pr, HwInfo);
550 break;
551#endif
552#ifdef SIS300 324#ifdef SIS300
553 case SIS_300: 325 InitTo300Pointer(SiS_Pr);
554 case SIS_540: 326#else
555 case SIS_630: 327 return FALSE;
556 case SIS_730: 328#endif
557 InitTo300Pointer(SiS_Pr, HwInfo); 329 } else {
558 break; 330#ifdef SIS315H
331 InitTo310Pointer(SiS_Pr);
332#else
333 return FALSE;
559#endif 334#endif
560 default:
561 break;
562 } 335 }
336 return TRUE;
563} 337}
564 338
565/*********************************************/ 339/*********************************************/
566/* HELPER: Get ModeID */ 340/* HELPER: Get ModeID */
567/*********************************************/ 341/*********************************************/
568 342
569#ifdef LINUX_XF86 343#ifndef SIS_XORG_XF86
570USHORT 344static
571SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, 345#endif
572 int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight) 346unsigned short
347SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
348 int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
573{ 349{
574 USHORT ModeIndex = 0; 350 unsigned short ModeIndex = 0;
575 351
576 switch(HDisplay) 352 switch(HDisplay)
577 { 353 {
578 case 320: 354 case 320:
579 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 355 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
580 else if(VDisplay == 240) { 356 else if(VDisplay == 240) {
581 if(FSTN) ModeIndex = ModeIndex_320x240_FSTN[Depth]; 357 if((VBFlags & CRT2_LCD) && (FSTN))
582 else ModeIndex = ModeIndex_320x240[Depth]; 358 ModeIndex = ModeIndex_320x240_FSTN[Depth];
583 } 359 else
584 break; 360 ModeIndex = ModeIndex_320x240[Depth];
585 case 400: 361 }
586 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) { 362 break;
587 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 363 case 400:
588 } 364 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
589 break; 365 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
590 case 512: 366 }
591 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) { 367 break;
592 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 368 case 512:
593 } 369 if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
594 break; 370 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
595 case 640: 371 }
596 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 372 break;
597 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 373 case 640:
598 break; 374 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
599 case 720: 375 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
600 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 376 break;
601 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 377 case 720:
602 break; 378 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
603 case 768: 379 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
604 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 380 break;
605 break; 381 case 768:
606 case 800: 382 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
607 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 383 break;
608 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 384 case 800:
609 break; 385 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
610 case 848: 386 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
611 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 387 break;
612 break; 388 case 848:
613 case 856: 389 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
614 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 390 break;
615 break; 391 case 856:
616 case 960: 392 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
617 if(VGAEngine == SIS_315_VGA) { 393 break;
618 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 394 case 960:
619 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 395 if(VGAEngine == SIS_315_VGA) {
620 } 396 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
621 break; 397 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
622 case 1024: 398 }
623 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 399 break;
624 else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 400 case 1024:
625 else if(VGAEngine == SIS_300_VGA) { 401 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
626 if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth]; 402 else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
627 } 403 else if(VGAEngine == SIS_300_VGA) {
628 break; 404 if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
629 case 1152: 405 }
630 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 406 break;
631 if(VGAEngine == SIS_300_VGA) { 407 case 1152:
632 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth]; 408 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
633 } 409 if(VGAEngine == SIS_300_VGA) {
634 break; 410 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
635 case 1280: 411 }
636 switch(VDisplay) { 412 break;
637 case 720: 413 case 1280:
638 ModeIndex = ModeIndex_1280x720[Depth]; 414 switch(VDisplay) {
639 break; 415 case 720:
640 case 768: 416 ModeIndex = ModeIndex_1280x720[Depth];
641 if(VGAEngine == SIS_300_VGA) { 417 break;
642 ModeIndex = ModeIndex_300_1280x768[Depth]; 418 case 768:
643 } else { 419 if(VGAEngine == SIS_300_VGA) {
644 ModeIndex = ModeIndex_310_1280x768[Depth]; 420 ModeIndex = ModeIndex_300_1280x768[Depth];
645 } 421 } else {
646 break; 422 ModeIndex = ModeIndex_310_1280x768[Depth];
647 case 800: 423 }
648 if(VGAEngine == SIS_315_VGA) { 424 break;
649 ModeIndex = ModeIndex_1280x800[Depth]; 425 case 800:
650 } 426 if(VGAEngine == SIS_315_VGA) {
651 break; 427 ModeIndex = ModeIndex_1280x800[Depth];
652 case 960: 428 }
653 ModeIndex = ModeIndex_1280x960[Depth]; 429 break;
654 break; 430 case 854:
655 case 1024: 431 if(VGAEngine == SIS_315_VGA) {
656 ModeIndex = ModeIndex_1280x1024[Depth]; 432 ModeIndex = ModeIndex_1280x854[Depth];
657 break; 433 }
658 } 434 break;
659 break; 435 case 960:
660 case 1360: 436 ModeIndex = ModeIndex_1280x960[Depth];
661 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 437 break;
662 if(VGAEngine == SIS_300_VGA) { 438 case 1024:
663 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 439 ModeIndex = ModeIndex_1280x1024[Depth];
664 } 440 break;
665 break; 441 }
666 case 1400: 442 break;
667 if(VGAEngine == SIS_315_VGA) { 443 case 1360:
668 if(VDisplay == 1050) { 444 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
669 ModeIndex = ModeIndex_1400x1050[Depth]; 445 if(VGAEngine == SIS_300_VGA) {
670 } 446 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
671 } 447 }
672 break; 448 break;
673 case 1600: 449 case 1400:
674 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 450 if(VGAEngine == SIS_315_VGA) {
675 break; 451 if(VDisplay == 1050) {
676 case 1680: 452 ModeIndex = ModeIndex_1400x1050[Depth];
677 if(VGAEngine == SIS_315_VGA) { 453 }
678 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 454 }
679 } 455 break;
680 break; 456 case 1600:
681 case 1920: 457 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
682 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth]; 458 break;
683 else if(VGAEngine == SIS_315_VGA) { 459 case 1680:
684 if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth]; 460 if(VGAEngine == SIS_315_VGA) {
685 } 461 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
686 break; 462 }
687 case 2048: 463 break;
688 if(VDisplay == 1536) { 464 case 1920:
689 if(VGAEngine == SIS_300_VGA) { 465 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
690 ModeIndex = ModeIndex_300_2048x1536[Depth]; 466 else if(VGAEngine == SIS_315_VGA) {
691 } else { 467 if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
692 ModeIndex = ModeIndex_310_2048x1536[Depth]; 468 }
693 } 469 break;
694 } 470 case 2048:
695 break; 471 if(VDisplay == 1536) {
472 if(VGAEngine == SIS_300_VGA) {
473 ModeIndex = ModeIndex_300_2048x1536[Depth];
474 } else {
475 ModeIndex = ModeIndex_310_2048x1536[Depth];
476 }
477 }
478 break;
696 } 479 }
697 480
698 return(ModeIndex); 481 return ModeIndex;
699} 482}
700#endif
701 483
702USHORT 484unsigned short
703SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, 485SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
704 int Depth, BOOLEAN FSTN, USHORT CustomT, int LCDwidth, int LCDheight) 486 int Depth, BOOLEAN FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
487 unsigned int VBFlags2)
705{ 488{
706 USHORT ModeIndex = 0; 489 unsigned short ModeIndex = 0;
707 490
708 if(VBFlags & (VB_LVDS | VB_30xBDH)) { 491 if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
709 492
710 switch(HDisplay) 493 switch(HDisplay)
711 { 494 {
712 case 320: 495 case 320:
713 if(CustomT != CUT_PANEL848) { 496 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
714 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 497 if(VDisplay == 200) {
715 else if(VDisplay == 240) { 498 if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
499 } else if(VDisplay == 240) {
716 if(!FSTN) ModeIndex = ModeIndex_320x240[Depth]; 500 if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
717 else if(VGAEngine == SIS_315_VGA) { 501 else if(VGAEngine == SIS_315_VGA) {
718 ModeIndex = ModeIndex_320x240_FSTN[Depth]; 502 ModeIndex = ModeIndex_320x240_FSTN[Depth];
719 } 503 }
720 } 504 }
721 } 505 }
722 break; 506 break;
723 case 400: 507 case 400:
724 if(CustomT != CUT_PANEL848) { 508 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
725 if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) { 509 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
726 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 510 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
727 } 511 }
728 } 512 }
729 break; 513 break;
730 case 512: 514 case 512:
731 if(CustomT != CUT_PANEL848) { 515 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
732 if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) { 516 if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
733 if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) { 517 if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
734 if(VDisplay == 384) { 518 if(VDisplay == 384) {
735 ModeIndex = ModeIndex_512x384[Depth]; 519 ModeIndex = ModeIndex_512x384[Depth];
@@ -739,9 +523,10 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
739 } 523 }
740 break; 524 break;
741 case 640: 525 case 640:
742 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 526 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
743 else if(VDisplay == 400) { 527 else if(VDisplay == 400) {
744 if(CustomT != CUT_PANEL848) ModeIndex = ModeIndex_640x400[Depth]; 528 if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
529 ModeIndex = ModeIndex_640x400[Depth];
745 } 530 }
746 break; 531 break;
747 case 800: 532 case 800:
@@ -752,6 +537,11 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
752 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 537 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
753 } 538 }
754 break; 539 break;
540 case 856:
541 if(CustomT == CUT_PANEL856) {
542 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
543 }
544 break;
755 case 1024: 545 case 1024:
756 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 546 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
757 else if(VGAEngine == SIS_300_VGA) { 547 else if(VGAEngine == SIS_300_VGA) {
@@ -762,7 +552,7 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
762 break; 552 break;
763 case 1152: 553 case 1152:
764 if(VGAEngine == SIS_300_VGA) { 554 if(VGAEngine == SIS_300_VGA) {
765 if((VDisplay == 768) && (LCDheight == 768)) { 555 if((VDisplay == 768) && (LCDheight == 768)) {
766 ModeIndex = ModeIndex_1152x768[Depth]; 556 ModeIndex = ModeIndex_1152x768[Depth];
767 } 557 }
768 } 558 }
@@ -770,49 +560,49 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
770 case 1280: 560 case 1280:
771 if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth]; 561 if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
772 else if(VGAEngine == SIS_315_VGA) { 562 else if(VGAEngine == SIS_315_VGA) {
773 if((VDisplay == 768) && (LCDheight == 768)) { 563 if((VDisplay == 768) && (LCDheight == 768)) {
774 ModeIndex = ModeIndex_310_1280x768[Depth]; 564 ModeIndex = ModeIndex_310_1280x768[Depth];
775 } 565 }
776 } 566 }
777 break; 567 break;
778 case 1360: 568 case 1360:
779 if(VGAEngine == SIS_300_VGA) { 569 if(VGAEngine == SIS_300_VGA) {
780 if(CustomT == CUT_BARCO1366) { 570 if(CustomT == CUT_BARCO1366) {
781 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 571 if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
782 } 572 }
783 } 573 }
784 if(CustomT == CUT_PANEL848) { 574 if(CustomT == CUT_PANEL848) {
785 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 575 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
786 } 576 }
787 break; 577 break;
788 case 1400: 578 case 1400:
789 if(VGAEngine == SIS_315_VGA) { 579 if(VGAEngine == SIS_315_VGA) {
790 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 580 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
791 } 581 }
792 break; 582 break;
793 case 1600: 583 case 1600:
794 if(VGAEngine == SIS_315_VGA) { 584 if(VGAEngine == SIS_315_VGA) {
795 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 585 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
796 } 586 }
797 break; 587 break;
798 } 588 }
799 589
800 } else if(VBFlags & VB_SISBRIDGE) { 590 } else if(VBFlags2 & VB2_SISBRIDGE) {
801 591
802 switch(HDisplay) 592 switch(HDisplay)
803 { 593 {
804 case 320: 594 case 320:
805 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 595 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
806 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 596 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
807 break; 597 break;
808 case 400: 598 case 400:
809 if(LCDwidth >= 800 && LCDheight >= 600) { 599 if(LCDwidth >= 800 && LCDheight >= 600) {
810 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 600 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
811 } 601 }
812 break; 602 break;
813 case 512: 603 case 512:
814 if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) { 604 if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
815 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 605 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
816 } 606 }
817 break; 607 break;
818 case 640: 608 case 640:
@@ -821,96 +611,115 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
821 break; 611 break;
822 case 720: 612 case 720:
823 if(VGAEngine == SIS_315_VGA) { 613 if(VGAEngine == SIS_315_VGA) {
824 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 614 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
825 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 615 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
826 } 616 }
827 break; 617 break;
828 case 768: 618 case 768:
829 if(VGAEngine == SIS_315_VGA) { 619 if(VGAEngine == SIS_315_VGA) {
830 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 620 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
831 } 621 }
832 break; 622 break;
833 case 800: 623 case 800:
834 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 624 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
835 if(VGAEngine == SIS_315_VGA) { 625 if(VGAEngine == SIS_315_VGA) {
836 if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 626 if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
837 } 627 }
838 break; 628 break;
839 case 848: 629 case 848:
840 if(VGAEngine == SIS_315_VGA) { 630 if(VGAEngine == SIS_315_VGA) {
841 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 631 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
842 } 632 }
843 break; 633 break;
844 case 856: 634 case 856:
845 if(VGAEngine == SIS_315_VGA) { 635 if(VGAEngine == SIS_315_VGA) {
846 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 636 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
847 } 637 }
848 break; 638 break;
849 case 960: 639 case 960:
850 if(VGAEngine == SIS_315_VGA) { 640 if(VGAEngine == SIS_315_VGA) {
851 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 641 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
852 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 642 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
853 } 643 }
854 break; 644 break;
855 case 1024: 645 case 1024:
856 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 646 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
857 if(VGAEngine == SIS_315_VGA) { 647 if(VGAEngine == SIS_315_VGA) {
858 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 648 if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
859 } 649 }
860 break; 650 break;
861 case 1152: 651 case 1152:
862 if(VGAEngine == SIS_315_VGA) { 652 if(VGAEngine == SIS_315_VGA) {
863 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 653 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
864 } 654 }
865 break; 655 break;
866 case 1280: 656 case 1280:
867 switch(VDisplay) { 657 switch(VDisplay) {
868 case 720: 658 case 720:
869 ModeIndex = ModeIndex_1280x720[Depth]; 659 ModeIndex = ModeIndex_1280x720[Depth];
870 case 768: 660 case 768:
871 if(VGAEngine == SIS_300_VGA) { 661 if(VGAEngine == SIS_300_VGA) {
872 ModeIndex = ModeIndex_300_1280x768[Depth]; 662 ModeIndex = ModeIndex_300_1280x768[Depth];
873 } else { 663 } else {
874 ModeIndex = ModeIndex_310_1280x768[Depth]; 664 ModeIndex = ModeIndex_310_1280x768[Depth];
875 } 665 }
876 break; 666 break;
877 case 800: 667 case 800:
878 if(VGAEngine == SIS_315_VGA) { 668 if(VGAEngine == SIS_315_VGA) {
879 ModeIndex = ModeIndex_1280x800[Depth]; 669 ModeIndex = ModeIndex_1280x800[Depth];
880 } 670 }
881 break; 671 break;
672 case 854:
673 if(VGAEngine == SIS_315_VGA) {
674 ModeIndex = ModeIndex_1280x854[Depth];
675 }
676 break;
882 case 960: 677 case 960:
883 ModeIndex = ModeIndex_1280x960[Depth]; 678 ModeIndex = ModeIndex_1280x960[Depth];
884 break; 679 break;
885 case 1024: 680 case 1024:
886 ModeIndex = ModeIndex_1280x1024[Depth]; 681 ModeIndex = ModeIndex_1280x1024[Depth];
887 break; 682 break;
888 } 683 }
889 break; 684 break;
890 case 1360: 685 case 1360:
891 if(VGAEngine == SIS_315_VGA) { 686 if(VGAEngine == SIS_315_VGA) { /* OVER1280 only? */
892 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 687 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
893 } 688 }
894 break; 689 break;
895 case 1400: 690 case 1400:
896 if(VGAEngine == SIS_315_VGA) { 691 if(VGAEngine == SIS_315_VGA) {
897 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { 692 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
898 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 693 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
899 } 694 }
900 } 695 }
901 break; 696 break;
902 case 1600: 697 case 1600:
903 if(VGAEngine == SIS_315_VGA) { 698 if(VGAEngine == SIS_315_VGA) {
904 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { 699 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
905 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 700 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
906 } 701 }
907 } 702 }
908 break; 703 break;
909#ifndef VB_FORBID_CRT2LCD_OVER_1600 704#ifndef VB_FORBID_CRT2LCD_OVER_1600
910 case 1680: 705 case 1680:
911 if(VGAEngine == SIS_315_VGA) { 706 if(VGAEngine == SIS_315_VGA) {
912 if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { 707 if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
913 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 708 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
709 }
710 }
711 break;
712 case 1920:
713 if(VGAEngine == SIS_315_VGA) {
714 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
715 if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
716 }
717 }
718 break;
719 case 2048:
720 if(VGAEngine == SIS_315_VGA) {
721 if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
722 if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
914 } 723 }
915 } 724 }
916 break; 725 break;
@@ -921,16 +730,17 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
921 return ModeIndex; 730 return ModeIndex;
922} 731}
923 732
924USHORT 733unsigned short
925SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth) 734SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
735 unsigned int VBFlags2)
926{ 736{
927 USHORT ModeIndex = 0; 737 unsigned short ModeIndex = 0;
928 738
929 if(VBFlags & VB_CHRONTEL) { 739 if(VBFlags2 & VB2_CHRONTEL) {
930 740
931 switch(HDisplay) 741 switch(HDisplay)
932 { 742 {
933 case 512: 743 case 512:
934 if(VGAEngine == SIS_315_VGA) { 744 if(VGAEngine == SIS_315_VGA) {
935 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 745 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
936 } 746 }
@@ -944,27 +754,27 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
944 break; 754 break;
945 case 1024: 755 case 1024:
946 if(VGAEngine == SIS_315_VGA) { 756 if(VGAEngine == SIS_315_VGA) {
947 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 757 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
948 } 758 }
949 break; 759 break;
950 } 760 }
951 761
952 } else if(VBFlags & VB_SISTVBRIDGE) { 762 } else if(VBFlags2 & VB2_SISTVBRIDGE) {
953 763
954 switch(HDisplay) 764 switch(HDisplay)
955 { 765 {
956 case 320: 766 case 320:
957 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 767 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
958 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 768 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
959 break; 769 break;
960 case 400: 770 case 400:
961 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 771 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
962 break; 772 break;
963 case 512: 773 case 512:
964 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) || 774 if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
965 (VBFlags & TV_HIVISION) || 775 (VBFlags & TV_HIVISION) ||
966 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) { 776 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
967 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 777 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
968 } 778 }
969 break; 779 break;
970 case 640: 780 case 640:
@@ -973,34 +783,34 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
973 break; 783 break;
974 case 720: 784 case 720:
975 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 785 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
976 if(VDisplay == 480) { 786 if(VDisplay == 480) {
977 ModeIndex = ModeIndex_720x480[Depth]; 787 ModeIndex = ModeIndex_720x480[Depth];
978 } else if(VDisplay == 576) { 788 } else if(VDisplay == 576) {
979 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) || 789 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
980 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) 790 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
981 ModeIndex = ModeIndex_720x576[Depth]; 791 ModeIndex = ModeIndex_720x576[Depth];
982 } 792 }
983 } 793 }
984 break; 794 break;
985 case 768: 795 case 768:
986 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 796 if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
987 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) || 797 if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
988 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) { 798 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
989 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 799 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
990 } 800 }
991 } 801 }
992 break; 802 break;
993 case 800: 803 case 800:
994 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 804 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
995 else if(VDisplay == 480) { 805 else if(VDisplay == 480) {
996 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 806 if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
997 ModeIndex = ModeIndex_800x480[Depth]; 807 ModeIndex = ModeIndex_800x480[Depth];
998 } 808 }
999 } 809 }
1000 break; 810 break;
1001 case 960: 811 case 960:
1002 if(VGAEngine == SIS_315_VGA) { 812 if(VGAEngine == SIS_315_VGA) {
1003 if(VDisplay == 600) { 813 if(VDisplay == 600) {
1004 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 814 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
1005 ModeIndex = ModeIndex_960x600[Depth]; 815 ModeIndex = ModeIndex_960x600[Depth];
1006 } 816 }
@@ -1009,25 +819,28 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
1009 break; 819 break;
1010 case 1024: 820 case 1024:
1011 if(VDisplay == 768) { 821 if(VDisplay == 768) {
1012 if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) { 822 if(VBFlags2 & VB2_30xBLV) {
1013 ModeIndex = ModeIndex_1024x768[Depth]; 823 ModeIndex = ModeIndex_1024x768[Depth];
1014 } 824 }
1015 } else if(VDisplay == 576) { 825 } else if(VDisplay == 576) {
1016 if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 826 if( (VBFlags & TV_HIVISION) ||
827 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
828 ((VBFlags2 & VB2_30xBLV) &&
829 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
1017 ModeIndex = ModeIndex_1024x576[Depth]; 830 ModeIndex = ModeIndex_1024x576[Depth];
1018 } 831 }
1019 } 832 }
1020 break; 833 break;
1021 case 1280: 834 case 1280:
1022 if(VDisplay == 720) { 835 if(VDisplay == 720) {
1023 if((VBFlags & TV_HIVISION) || 836 if((VBFlags & TV_HIVISION) ||
1024 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) { 837 ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
1025 ModeIndex = ModeIndex_1280x720[Depth]; 838 ModeIndex = ModeIndex_1280x720[Depth];
1026 } 839 }
1027 } else if(VDisplay == 1024) { 840 } else if(VDisplay == 1024) {
1028 if((VBFlags & TV_HIVISION) || 841 if((VBFlags & TV_HIVISION) ||
1029 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 842 ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
1030 ModeIndex = ModeIndex_1280x1024[Depth]; 843 ModeIndex = ModeIndex_1280x1024[Depth];
1031 } 844 }
1032 } 845 }
1033 break; 846 break;
@@ -1036,99 +849,31 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
1036 return ModeIndex; 849 return ModeIndex;
1037} 850}
1038 851
1039USHORT 852unsigned short
1040SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth) 853SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
854 unsigned int VBFlags2)
1041{ 855{
1042 USHORT ModeIndex = 0; 856 if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
1043 857
1044 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0; 858 if(HDisplay >= 1920) return 0;
1045 859
1046 switch(HDisplay) 860 switch(HDisplay)
1047 { 861 {
1048 case 320:
1049 if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
1050 else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
1051 break;
1052 case 400:
1053 if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
1054 break;
1055 case 512:
1056 if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
1057 break;
1058 case 640:
1059 if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
1060 else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
1061 break;
1062 case 720:
1063 if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
1064 else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
1065 break;
1066 case 768:
1067 if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
1068 break;
1069 case 800:
1070 if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
1071 else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
1072 break;
1073 case 848:
1074 if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
1075 break;
1076 case 856:
1077 if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
1078 break;
1079 case 960:
1080 if(VGAEngine == SIS_315_VGA) {
1081 if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
1082 else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
1083 }
1084 break;
1085 case 1024:
1086 if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
1087 else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
1088 break;
1089 case 1152:
1090 if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
1091 else if(VGAEngine == SIS_300_VGA) {
1092 if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
1093 }
1094 break;
1095 case 1280:
1096 if(VDisplay == 768) {
1097 if(VGAEngine == SIS_300_VGA) {
1098 ModeIndex = ModeIndex_300_1280x768[Depth];
1099 } else {
1100 ModeIndex = ModeIndex_310_1280x768[Depth];
1101 }
1102 } else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
1103 else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
1104 else if(VDisplay == 800) ModeIndex = ModeIndex_1280x800[Depth];
1105 else if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
1106 break;
1107 case 1360:
1108 if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
1109 break;
1110 case 1400:
1111 if(VGAEngine == SIS_315_VGA) {
1112 if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
1113 }
1114 break;
1115 case 1600: 862 case 1600:
1116 if(VGAEngine == SIS_315_VGA) { 863 if(VDisplay == 1200) {
1117 if(VBFlags & (VB_301B|VB_301C|VB_302B)) { 864 if(VGAEngine != SIS_315_VGA) return 0;
1118 if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 865 if(!(VBFlags2 & VB2_30xB)) return 0;
1119 }
1120 } 866 }
1121 break; 867 break;
1122 case 1680: 868 case 1680:
1123 if(VGAEngine == SIS_315_VGA) { 869 if(VDisplay == 1050) {
1124 if(VBFlags & (VB_301B|VB_301C|VB_302B)) { 870 if(VGAEngine != SIS_315_VGA) return 0;
1125 if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 871 if(!(VBFlags2 & VB2_30xB)) return 0;
1126 }
1127 } 872 }
1128 break; 873 break;
1129 } 874 }
1130 875
1131 return ModeIndex; 876 return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, FALSE, 0, 0);
1132} 877}
1133 878
1134 879
@@ -1137,83 +882,83 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
1137/*********************************************/ 882/*********************************************/
1138 883
1139void 884void
1140SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data) 885SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
1141{ 886{
1142 OutPortByte(port,index); 887 OutPortByte(port, index);
1143 OutPortByte(port + 1,data); 888 OutPortByte(port + 1, data);
1144} 889}
1145 890
1146void 891void
1147SiS_SetRegByte(SISIOADDRESS port, USHORT data) 892SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
1148{ 893{
1149 OutPortByte(port,data); 894 OutPortByte(port, data);
1150} 895}
1151 896
1152void 897void
1153SiS_SetRegShort(SISIOADDRESS port, USHORT data) 898SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
1154{ 899{
1155 OutPortWord(port,data); 900 OutPortWord(port, data);
1156} 901}
1157 902
1158void 903void
1159SiS_SetRegLong(SISIOADDRESS port, ULONG data) 904SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
1160{ 905{
1161 OutPortLong(port,data); 906 OutPortLong(port, data);
1162} 907}
1163 908
1164UCHAR 909unsigned char
1165SiS_GetReg(SISIOADDRESS port, USHORT index) 910SiS_GetReg(SISIOADDRESS port, unsigned short index)
1166{ 911{
1167 OutPortByte(port,index); 912 OutPortByte(port, index);
1168 return(InPortByte(port + 1)); 913 return(InPortByte(port + 1));
1169} 914}
1170 915
1171UCHAR 916unsigned char
1172SiS_GetRegByte(SISIOADDRESS port) 917SiS_GetRegByte(SISIOADDRESS port)
1173{ 918{
1174 return(InPortByte(port)); 919 return(InPortByte(port));
1175} 920}
1176 921
1177USHORT 922unsigned short
1178SiS_GetRegShort(SISIOADDRESS port) 923SiS_GetRegShort(SISIOADDRESS port)
1179{ 924{
1180 return(InPortWord(port)); 925 return(InPortWord(port));
1181} 926}
1182 927
1183ULONG 928unsigned int
1184SiS_GetRegLong(SISIOADDRESS port) 929SiS_GetRegLong(SISIOADDRESS port)
1185{ 930{
1186 return(InPortLong(port)); 931 return(InPortLong(port));
1187} 932}
1188 933
1189void 934void
1190SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR) 935SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR)
1191{ 936{
1192 USHORT temp; 937 unsigned short temp;
1193 938
1194 temp = SiS_GetReg(Port,Index); 939 temp = SiS_GetReg(Port, Index);
1195 temp = (temp & (DataAND)) | DataOR; 940 temp = (temp & (DataAND)) | DataOR;
1196 SiS_SetReg(Port,Index,temp); 941 SiS_SetReg(Port, Index, temp);
1197} 942}
1198 943
1199void 944void
1200SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND) 945SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND)
1201{ 946{
1202 USHORT temp; 947 unsigned short temp;
1203 948
1204 temp = SiS_GetReg(Port,Index); 949 temp = SiS_GetReg(Port, Index);
1205 temp &= DataAND; 950 temp &= DataAND;
1206 SiS_SetReg(Port,Index,temp); 951 SiS_SetReg(Port, Index, temp);
1207} 952}
1208 953
1209void 954void
1210SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR) 955SiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR)
1211{ 956{
1212 USHORT temp; 957 unsigned short temp;
1213 958
1214 temp = SiS_GetReg(Port,Index); 959 temp = SiS_GetReg(Port, Index);
1215 temp |= DataOR; 960 temp |= DataOR;
1216 SiS_SetReg(Port,Index,temp); 961 SiS_SetReg(Port, Index, temp);
1217} 962}
1218 963
1219/*********************************************/ 964/*********************************************/
@@ -1221,13 +966,13 @@ SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
1221/*********************************************/ 966/*********************************************/
1222 967
1223void 968void
1224SiS_DisplayOn(SiS_Private *SiS_Pr) 969SiS_DisplayOn(struct SiS_Private *SiS_Pr)
1225{ 970{
1226 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF); 971 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
1227} 972}
1228 973
1229void 974void
1230SiS_DisplayOff(SiS_Private *SiS_Pr) 975SiS_DisplayOff(struct SiS_Private *SiS_Pr)
1231{ 976{
1232 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); 977 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
1233} 978}
@@ -1238,7 +983,7 @@ SiS_DisplayOff(SiS_Private *SiS_Pr)
1238/*********************************************/ 983/*********************************************/
1239 984
1240void 985void
1241SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr) 986SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
1242{ 987{
1243 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; 988 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
1244 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; 989 SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
@@ -1251,16 +996,17 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
1251 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; 996 SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
1252 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; 997 SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
1253 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; 998 SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
999 SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
1254 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; 1000 SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
1255 SiS_Pr->SiS_P3da = BaseAddr + 0x2a; 1001 SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
1256 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */ 1002 SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
1257 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */ 1003 SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
1258 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */ 1004 SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
1259 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */ 1005 SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
1260 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */ 1006 SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
1261 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */ 1007 SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;
1262 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE; 1008 SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
1263 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK; 1009 SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
1264} 1010}
1265 1011
1266/*********************************************/ 1012/*********************************************/
@@ -1268,7 +1014,7 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
1268/*********************************************/ 1014/*********************************************/
1269 1015
1270static void 1016static void
1271SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1017SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
1272{ 1018{
1273 unsigned char cr5f, temp1, temp2; 1019 unsigned char cr5f, temp1, temp2;
1274 1020
@@ -1276,9 +1022,9 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1276 /* (SR11 is used for DDC and in enable/disablebridge) */ 1022 /* (SR11 is used for DDC and in enable/disablebridge) */
1277 SiS_Pr->SiS_SensibleSR11 = FALSE; 1023 SiS_Pr->SiS_SensibleSR11 = FALSE;
1278 SiS_Pr->SiS_MyCR63 = 0x63; 1024 SiS_Pr->SiS_MyCR63 = 0x63;
1279 if(HwInfo->jChipType >= SIS_330) { 1025 if(SiS_Pr->ChipType >= SIS_330) {
1280 SiS_Pr->SiS_MyCR63 = 0x53; 1026 SiS_Pr->SiS_MyCR63 = 0x53;
1281 if(HwInfo->jChipType >= SIS_661) { 1027 if(SiS_Pr->ChipType >= SIS_661) {
1282 SiS_Pr->SiS_SensibleSR11 = TRUE; 1028 SiS_Pr->SiS_SensibleSR11 = TRUE;
1283 } 1029 }
1284 } 1030 }
@@ -1286,43 +1032,52 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1286 /* You should use the macros, not these flags directly */ 1032 /* You should use the macros, not these flags directly */
1287 1033
1288 SiS_Pr->SiS_SysFlags = 0; 1034 SiS_Pr->SiS_SysFlags = 0;
1289 if(HwInfo->jChipType == SIS_650) { 1035 if(SiS_Pr->ChipType == SIS_650) {
1290 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 1036 cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07); 1037 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1292 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 1038 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1293 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8); 1039 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1294 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 1040 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1295 if((!temp1) || (temp2)) { 1041 if((!temp1) || (temp2)) {
1296 switch(cr5f) { 1042 switch(cr5f) {
1297 case 0x80: 1043 case 0x80:
1298 case 0x90: 1044 case 0x90:
1299 case 0xc0: 1045 case 0xc0:
1300 SiS_Pr->SiS_SysFlags |= SF_IsM650; break; 1046 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1047 break;
1301 case 0xa0: 1048 case 0xa0:
1302 case 0xb0: 1049 case 0xb0:
1303 case 0xe0: 1050 case 0xe0:
1304 SiS_Pr->SiS_SysFlags |= SF_Is651; break; 1051 SiS_Pr->SiS_SysFlags |= SF_Is651;
1052 break;
1305 } 1053 }
1306 } else { 1054 } else {
1307 switch(cr5f) { 1055 switch(cr5f) {
1308 case 0x90: 1056 case 0x90:
1309 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 1057 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1310 switch(temp1) { 1058 switch(temp1) {
1311 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break; 1059 case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1312 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break; 1060 case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1313 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break; 1061 default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1314 } 1062 }
1315 break; 1063 break;
1316 case 0xb0: 1064 case 0xb0:
1317 SiS_Pr->SiS_SysFlags |= SF_Is652; break; 1065 SiS_Pr->SiS_SysFlags |= SF_Is652;
1066 break;
1318 default: 1067 default:
1319 SiS_Pr->SiS_SysFlags |= SF_IsM650; break; 1068 SiS_Pr->SiS_SysFlags |= SF_IsM650;
1069 break;
1320 } 1070 }
1321 } 1071 }
1322 } 1072 }
1323 if(HwInfo->jChipType == SIS_760) { 1073
1324 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78); 1074 if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
1325 if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB; 1075 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
1076 SiS_Pr->SiS_SysFlags |= SF_760LFB;
1077 }
1078 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
1079 SiS_Pr->SiS_SysFlags |= SF_760UMA;
1080 }
1326 } 1081 }
1327} 1082}
1328 1083
@@ -1331,18 +1086,20 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1331/*********************************************/ 1086/*********************************************/
1332 1087
1333static void 1088static void
1334SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1089SiSInitPCIetc(struct SiS_Private *SiS_Pr)
1335{ 1090{
1336 switch(HwInfo->jChipType) { 1091 switch(SiS_Pr->ChipType) {
1092#ifdef SIS300
1337 case SIS_300: 1093 case SIS_300:
1338 case SIS_540: 1094 case SIS_540:
1339 case SIS_630: 1095 case SIS_630:
1340 case SIS_730: 1096 case SIS_730:
1341 /* Set - PCI LINEAR ADDRESSING ENABLE (0x80) 1097 /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1342 * - RELOCATED VGA IO (0x20) 1098 * - RELOCATED VGA IO ENABLED (0x20)
1343 * - MMIO ENABLE (0x1) 1099 * - MMIO ENABLED (0x01)
1100 * Leave other bits untouched.
1344 */ 1101 */
1345 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1); 1102 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1346 /* - Enable 2D (0x40) 1103 /* - Enable 2D (0x40)
1347 * - Enable 3D (0x02) 1104 * - Enable 3D (0x02)
1348 * - Enable 3D Vertex command fetch (0x10) ? 1105 * - Enable 3D Vertex command fetch (0x10) ?
@@ -1350,6 +1107,8 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1350 */ 1107 */
1351 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A); 1108 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1352 break; 1109 break;
1110#endif
1111#ifdef SIS315H
1353 case SIS_315H: 1112 case SIS_315H:
1354 case SIS_315: 1113 case SIS_315:
1355 case SIS_315PRO: 1114 case SIS_315PRO:
@@ -1362,21 +1121,30 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1362 case SIS_760: 1121 case SIS_760:
1363 case SIS_761: 1122 case SIS_761:
1364 case SIS_340: 1123 case SIS_340:
1365 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1); 1124 case XGI_40:
1366 /* - Enable 2D (0x40) 1125 /* See above */
1367 * - Enable 3D (0x02) 1126 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1127 /* - Enable 3D G/L transformation engine (0x80)
1128 * - Enable 2D (0x40)
1368 * - Enable 3D vertex command fetch (0x10) 1129 * - Enable 3D vertex command fetch (0x10)
1369 * - Enable 3D command parser (0x08) 1130 * - Enable 3D command parser (0x08)
1370 * - Enable 3D G/L transformation engine (0x80) 1131 * - Enable 3D (0x02)
1371 */ 1132 */
1372 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA); 1133 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1373 break; 1134 break;
1135 case XGI_20:
1374 case SIS_550: 1136 case SIS_550:
1375 SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1); 1137 /* See above */
1138 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1376 /* No 3D engine ! */ 1139 /* No 3D engine ! */
1377 /* - Enable 2D (0x40) 1140 /* - Enable 2D (0x40)
1141 * - disable 3D
1378 */ 1142 */
1379 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x40); 1143 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
1144 break;
1145#endif
1146 default:
1147 break;
1380 } 1148 }
1381} 1149}
1382 1150
@@ -1384,38 +1152,40 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1384/* HELPER: SetLVDSetc */ 1152/* HELPER: SetLVDSetc */
1385/*********************************************/ 1153/*********************************************/
1386 1154
1387static void 1155#ifdef SIS_LINUX_KERNEL
1388SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1156static
1157#endif
1158void
1159SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
1389{ 1160{
1390 USHORT temp; 1161 unsigned short temp;
1391 1162
1392 SiS_Pr->SiS_IF_DEF_LVDS = 0; 1163 SiS_Pr->SiS_IF_DEF_LVDS = 0;
1393 SiS_Pr->SiS_IF_DEF_TRUMPION = 0; 1164 SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1394 SiS_Pr->SiS_IF_DEF_CH70xx = 0; 1165 SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1395 SiS_Pr->SiS_IF_DEF_DSTN = 0;
1396 SiS_Pr->SiS_IF_DEF_FSTN = 0;
1397 SiS_Pr->SiS_IF_DEF_CONEX = 0; 1166 SiS_Pr->SiS_IF_DEF_CONEX = 0;
1398 1167
1399 SiS_Pr->SiS_ChrontelInit = 0; 1168 SiS_Pr->SiS_ChrontelInit = 0;
1400 1169
1170 if(SiS_Pr->ChipType == XGI_20) return;
1171
1401 /* Check for SiS30x first */ 1172 /* Check for SiS30x first */
1402 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 1173 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1403 if((temp == 1) || (temp == 2)) return; 1174 if((temp == 1) || (temp == 2)) return;
1404 1175
1405 switch(HwInfo->jChipType) { 1176 switch(SiS_Pr->ChipType) {
1406#ifdef SIS300 1177#ifdef SIS300
1407 case SIS_540: 1178 case SIS_540:
1408 case SIS_630: 1179 case SIS_630:
1409 case SIS_730: 1180 case SIS_730:
1410 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 1181 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1411 temp = (temp & 0x0E) >> 1; 1182 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1412 if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 1183 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1413 if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1; 1184 if((temp == 4) || (temp == 5)) {
1414 if((temp == 4) || (temp == 5)) {
1415 /* Save power status (and error check) - UNUSED */ 1185 /* Save power status (and error check) - UNUSED */
1416 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e); 1186 SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1417 SiS_Pr->SiS_IF_DEF_CH70xx = 1; 1187 SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1418 } 1188 }
1419 break; 1189 break;
1420#endif 1190#endif
1421#ifdef SIS315H 1191#ifdef SIS315H
@@ -1423,26 +1193,26 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1423 case SIS_650: 1193 case SIS_650:
1424 case SIS_740: 1194 case SIS_740:
1425 case SIS_330: 1195 case SIS_330:
1426 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 1196 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1427 temp = (temp & 0x0E) >> 1; 1197 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1428 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 1198 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1429 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 1199 break;
1430 break;
1431 case SIS_661: 1200 case SIS_661:
1432 case SIS_741: 1201 case SIS_741:
1433 case SIS_660: 1202 case SIS_660:
1434 case SIS_760: 1203 case SIS_760:
1435 case SIS_761: 1204 case SIS_761:
1436 case SIS_340: 1205 case SIS_340:
1437 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1206 case XGI_20:
1438 temp = (temp & 0xe0) >> 5; 1207 case XGI_40:
1439 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 1208 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
1440 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 1209 if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
1441 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */ 1210 if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1442 break; 1211 if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
1212 break;
1443#endif 1213#endif
1444 default: 1214 default:
1445 break; 1215 break;
1446 } 1216 }
1447} 1217}
1448 1218
@@ -1451,35 +1221,55 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1451/*********************************************/ 1221/*********************************************/
1452 1222
1453void 1223void
1454SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable) 1224SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
1455{ 1225{
1456 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0; 1226 SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1457} 1227}
1458 1228
1459void 1229void
1460SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable) 1230SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
1461{ 1231{
1462 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0; 1232 SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1463} 1233}
1464 1234
1465/*********************************************/ 1235/*********************************************/
1236/* HELPER: Get modeflag */
1237/*********************************************/
1238
1239unsigned short
1240SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1241 unsigned short ModeIdIndex)
1242{
1243 if(SiS_Pr->UseCustomMode) {
1244 return SiS_Pr->CModeFlag;
1245 } else if(ModeNo <= 0x13) {
1246 return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1247 } else {
1248 return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1249 }
1250}
1251
1252/*********************************************/
1466/* HELPER: Determine ROM usage */ 1253/* HELPER: Determine ROM usage */
1467/*********************************************/ 1254/*********************************************/
1468 1255
1469BOOLEAN 1256BOOLEAN
1470SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1257SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
1471{ 1258{
1472 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 1259 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1473 USHORT romversoffs, romvmaj = 1, romvmin = 0; 1260 unsigned short romversoffs, romvmaj = 1, romvmin = 0;
1474 1261
1475 if(HwInfo->jChipType >= SIS_761) { 1262 if(SiS_Pr->ChipType >= XGI_20) {
1476 /* I very much assume 761 and 340 will use new layout */ 1263 /* XGI ROMs don't qualify */
1264 return FALSE;
1265 } else if(SiS_Pr->ChipType >= SIS_761) {
1266 /* I very much assume 761, 340 and newer will use new layout */
1477 return TRUE; 1267 return TRUE;
1478 } else if(HwInfo->jChipType >= SIS_661) { 1268 } else if(SiS_Pr->ChipType >= SIS_661) {
1479 if((ROMAddr[0x1a] == 'N') && 1269 if((ROMAddr[0x1a] == 'N') &&
1480 (ROMAddr[0x1b] == 'e') && 1270 (ROMAddr[0x1b] == 'e') &&
1481 (ROMAddr[0x1c] == 'w') && 1271 (ROMAddr[0x1c] == 'w') &&
1482 (ROMAddr[0x1d] == 'V')) { 1272 (ROMAddr[0x1d] == 'V')) {
1483 return TRUE; 1273 return TRUE;
1484 } 1274 }
1485 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8); 1275 romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
@@ -1494,9 +1284,9 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1494 } 1284 }
1495 } else if(IS_SIS650740) { 1285 } else if(IS_SIS650740) {
1496 if((ROMAddr[0x1a] == 'N') && 1286 if((ROMAddr[0x1a] == 'N') &&
1497 (ROMAddr[0x1b] == 'e') && 1287 (ROMAddr[0x1b] == 'e') &&
1498 (ROMAddr[0x1c] == 'w') && 1288 (ROMAddr[0x1c] == 'w') &&
1499 (ROMAddr[0x1d] == 'V')) { 1289 (ROMAddr[0x1d] == 'V')) {
1500 return TRUE; 1290 return TRUE;
1501 } 1291 }
1502 } 1292 }
@@ -1504,45 +1294,50 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1504} 1294}
1505 1295
1506static void 1296static void
1507SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1297SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
1508{ 1298{
1509 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 1299 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1510 USHORT romptr = 0; 1300 unsigned short romptr = 0;
1511 1301
1512 SiS_Pr->SiS_UseROM = FALSE; 1302 SiS_Pr->SiS_UseROM = FALSE;
1513 SiS_Pr->SiS_ROMNew = FALSE; 1303 SiS_Pr->SiS_ROMNew = FALSE;
1304 SiS_Pr->SiS_PWDOffset = 0;
1514 1305
1515 if((ROMAddr) && (HwInfo->UseROM)) { 1306 if(SiS_Pr->ChipType >= XGI_20) return;
1516 if(HwInfo->jChipType == SIS_300) { 1307
1517 /* 300: We check if the code starts below 0x220 by 1308 if((ROMAddr) && (SiS_Pr->UseROM)) {
1309 if(SiS_Pr->ChipType == SIS_300) {
1310 /* 300: We check if the code starts below 0x220 by
1518 * checking the jmp instruction at the beginning 1311 * checking the jmp instruction at the beginning
1519 * of the BIOS image. 1312 * of the BIOS image.
1520 */ 1313 */
1521 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a) 1314 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1522 SiS_Pr->SiS_UseROM = TRUE; 1315 SiS_Pr->SiS_UseROM = TRUE;
1523 } else if(HwInfo->jChipType < SIS_315H) { 1316 } else if(SiS_Pr->ChipType < SIS_315H) {
1524 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps 1317 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
1525 * the others do as well 1318 * the others do as well
1526 */ 1319 */
1527 SiS_Pr->SiS_UseROM = TRUE; 1320 SiS_Pr->SiS_UseROM = TRUE;
1528 } else { 1321 } else {
1529 /* 315/330 series stick to the standard(s) */ 1322 /* 315/330 series stick to the standard(s) */
1530 SiS_Pr->SiS_UseROM = TRUE; 1323 SiS_Pr->SiS_UseROM = TRUE;
1531 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) { 1324 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
1532 SiS_Pr->SiS_EMIOffset = 14; 1325 SiS_Pr->SiS_EMIOffset = 14;
1326 SiS_Pr->SiS_PWDOffset = 17;
1533 SiS_Pr->SiS661LCD2TableSize = 36; 1327 SiS_Pr->SiS661LCD2TableSize = 36;
1534 /* Find out about LCD data table entry size */ 1328 /* Find out about LCD data table entry size */
1535 if((romptr = SISGETROMW(0x0102))) { 1329 if((romptr = SISGETROMW(0x0102))) {
1536 if(ROMAddr[romptr + (32 * 16)] == 0xff) 1330 if(ROMAddr[romptr + (32 * 16)] == 0xff)
1537 SiS_Pr->SiS661LCD2TableSize = 32; 1331 SiS_Pr->SiS661LCD2TableSize = 32;
1538 else if(ROMAddr[romptr + (34 * 16)] == 0xff) 1332 else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1539 SiS_Pr->SiS661LCD2TableSize = 34; 1333 SiS_Pr->SiS661LCD2TableSize = 34;
1540 else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94 */ 1334 else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */
1541 SiS_Pr->SiS661LCD2TableSize = 36; 1335 SiS_Pr->SiS661LCD2TableSize = 36;
1542 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */ 1336 else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */
1543 (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00+ */ 1337 (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */
1544 SiS_Pr->SiS661LCD2TableSize = 38; 1338 SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */
1545 SiS_Pr->SiS_EMIOffset = 16; 1339 SiS_Pr->SiS_EMIOffset = 16;
1340 SiS_Pr->SiS_PWDOffset = 19;
1546 } 1341 }
1547 } 1342 }
1548 } 1343 }
@@ -1555,9 +1350,9 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1555/*********************************************/ 1350/*********************************************/
1556 1351
1557static void 1352static void
1558SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value) 1353SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
1559{ 1354{
1560 USHORT temp; 1355 unsigned short temp;
1561 1356
1562 value &= 0x00ff; 1357 value &= 0x00ff;
1563 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0; 1358 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
@@ -1569,9 +1364,9 @@ SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
1569} 1364}
1570 1365
1571static void 1366static void
1572SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value) 1367SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
1573{ 1368{
1574 USHORT temp; 1369 unsigned short temp;
1575 1370
1576 value &= 0x00ff; 1371 value &= 0x00ff;
1577 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f; 1372 temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
@@ -1583,22 +1378,22 @@ SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
1583} 1378}
1584 1379
1585static void 1380static void
1586SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value) 1381SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
1587{ 1382{
1588 SiS_SetSegRegLower(SiS_Pr, value); 1383 SiS_SetSegRegLower(SiS_Pr, value);
1589 SiS_SetSegRegUpper(SiS_Pr, value); 1384 SiS_SetSegRegUpper(SiS_Pr, value);
1590} 1385}
1591 1386
1592static void 1387static void
1593SiS_ResetSegmentReg(SiS_Private *SiS_Pr) 1388SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
1594{ 1389{
1595 SiS_SetSegmentReg(SiS_Pr, 0); 1390 SiS_SetSegmentReg(SiS_Pr, 0);
1596} 1391}
1597 1392
1598static void 1393static void
1599SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value) 1394SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
1600{ 1395{
1601 USHORT temp = value >> 8; 1396 unsigned short temp = value >> 8;
1602 1397
1603 temp &= 0x07; 1398 temp &= 0x07;
1604 temp |= (temp << 4); 1399 temp |= (temp << 4);
@@ -1607,15 +1402,15 @@ SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
1607} 1402}
1608 1403
1609static void 1404static void
1610SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr) 1405SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
1611{ 1406{
1612 SiS_SetSegmentRegOver(SiS_Pr, 0); 1407 SiS_SetSegmentRegOver(SiS_Pr, 0);
1613} 1408}
1614 1409
1615static void 1410static void
1616SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo) 1411SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
1617{ 1412{
1618 if((IS_SIS65x) || (HwInfo->jChipType >= SIS_661)) { 1413 if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
1619 SiS_ResetSegmentReg(SiS_Pr); 1414 SiS_ResetSegmentReg(SiS_Pr);
1620 SiS_ResetSegmentRegOver(SiS_Pr); 1415 SiS_ResetSegmentRegOver(SiS_Pr);
1621 } 1416 }
@@ -1625,89 +1420,86 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
1625/* HELPER: GetVBType */ 1420/* HELPER: GetVBType */
1626/*********************************************/ 1421/*********************************************/
1627 1422
1628static void 1423#ifdef SIS_LINUX_KERNEL
1629SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1424static
1425#endif
1426void
1427SiS_GetVBType(struct SiS_Private *SiS_Pr)
1630{ 1428{
1631 USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27; 1429 unsigned short flag = 0, rev = 0, nolcd = 0;
1632 1430 unsigned short p4_0f, p4_25, p4_27;
1633 SiS_Pr->SiS_VBType = 0; 1431
1634 1432 SiS_Pr->SiS_VBType = 0;
1635 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX)) 1433
1636 return; 1434 if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1637 1435 return;
1638 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 1436
1639 1437 if(SiS_Pr->ChipType == XGI_20)
1640 if(flag > 3) return; 1438 return;
1641 1439
1642 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); 1440 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1643 1441
1644 if(flag >= 2) { 1442 if(flag > 3)
1645 SiS_Pr->SiS_VBType = VB_SIS302B; 1443 return;
1646 } else if(flag == 1) { 1444
1647 if(rev >= 0xC0) { 1445 rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1648 SiS_Pr->SiS_VBType = VB_SIS301C; 1446
1649 } else if(rev >= 0xB0) { 1447 if(flag >= 2) {
1650 SiS_Pr->SiS_VBType = VB_SIS301B; 1448 SiS_Pr->SiS_VBType = VB_SIS302B;
1651 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */ 1449 } else if(flag == 1) {
1652 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23); 1450 if(rev >= 0xC0) {
1653 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD; 1451 SiS_Pr->SiS_VBType = VB_SIS301C;
1654 } else { 1452 } else if(rev >= 0xB0) {
1655 SiS_Pr->SiS_VBType = VB_SIS301; 1453 SiS_Pr->SiS_VBType = VB_SIS301B;
1656 } 1454 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
1657 } 1455 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1658 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) { 1456 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1659 if(rev >= 0xE0) { 1457 } else {
1660 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39); 1458 SiS_Pr->SiS_VBType = VB_SIS301;
1661 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV; 1459 }
1662 else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */ 1460 }
1663 } else if(rev >= 0xD0) { 1461 if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1664 SiS_Pr->SiS_VBType = VB_SIS301LV; 1462 if(rev >= 0xE0) {
1665 } 1463 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1666 } 1464 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1667 if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) { 1465 else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
1668 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f); 1466 } else if(rev >= 0xD0) {
1669 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25); 1467 SiS_Pr->SiS_VBType = VB_SIS301LV;
1670 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27); 1468 }
1671 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f); 1469 }
1672 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08); 1470 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
1673 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd); 1471 p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1674 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) { 1472 p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1675 SiS_Pr->SiS_VBType |= VB_UMC; 1473 p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1676 } 1474 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27); 1475 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25); 1476 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f); 1477 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1680 } 1478 SiS_Pr->SiS_VBType |= VB_UMC;
1479 }
1480 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1481 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1482 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1483 }
1681} 1484}
1682 1485
1683/*********************************************/ 1486/*********************************************/
1684/* HELPER: Check RAM size */ 1487/* HELPER: Check RAM size */
1685/*********************************************/ 1488/*********************************************/
1686 1489
1687#ifdef LINUX_KERNEL 1490#ifdef SIS_LINUX_KERNEL
1688static BOOLEAN 1491static BOOLEAN
1689SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 1492SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1690 USHORT ModeNo, USHORT ModeIdIndex) 1493 unsigned short ModeIdIndex)
1691{ 1494{
1692 USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024); 1495 unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
1693 USHORT memorysize,modeflag; 1496 unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1694 1497 unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
1695 if(SiS_Pr->UseCustomMode) { 1498
1696 modeflag = SiS_Pr->CModeFlag; 1499 if(!AdapterMemSize) return TRUE;
1697 } else { 1500
1698 if(ModeNo <= 0x13) { 1501 if(AdapterMemSize < memorysize) return FALSE;
1699 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 1502 return TRUE;
1700 } else {
1701 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1702 }
1703 }
1704
1705 memorysize = modeflag & MemoryInfoFlag;
1706 memorysize >>= MemorySizeShift; /* Get required memory size */
1707 memorysize++;
1708
1709 if(AdapterMemSize < memorysize) return FALSE;
1710 return TRUE;
1711} 1503}
1712#endif 1504#endif
1713 1505
@@ -1716,63 +1508,65 @@ SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
1716/*********************************************/ 1508/*********************************************/
1717 1509
1718#ifdef SIS315H 1510#ifdef SIS315H
1719static UCHAR 1511static unsigned char
1720SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1512SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1721{ 1513{
1722 UCHAR data, temp; 1514 unsigned char data;
1723 1515
1724 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) { 1516 if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1725 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03; 1517 data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1726 } else { 1518 } else {
1727 if(HwInfo->jChipType >= SIS_340) { 1519 if(SiS_Pr->ChipType >= XGI_20) {
1728 /* TODO */ 1520 /* Do I need this? SR17 seems to be zero anyway... */
1729 data = 0; 1521 data = 0;
1730 } if(HwInfo->jChipType >= SIS_661) { 1522 } else if(SiS_Pr->ChipType >= SIS_340) {
1731 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07; 1523 /* TODO */
1732 if(SiS_Pr->SiS_ROMNew) { 1524 data = 0;
1733 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); 1525 } if(SiS_Pr->ChipType >= SIS_661) {
1734 } 1526 if(SiS_Pr->SiS_ROMNew) {
1735 } else if(IS_SIS550650740) { 1527 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1736 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07; 1528 } else {
1737 } else { /* 315, 330 */ 1529 data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1738 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03; 1530 }
1739 if(HwInfo->jChipType == SIS_330) { 1531 } else if(IS_SIS550650740) {
1740 if(data > 1) { 1532 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1741 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30; 1533 } else { /* 315, 330 */
1742 switch(temp) { 1534 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1743 case 0x00: data = 1; break; 1535 if(SiS_Pr->ChipType == SIS_330) {
1744 case 0x10: data = 3; break; 1536 if(data > 1) {
1745 case 0x20: data = 3; break; 1537 switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
1746 case 0x30: data = 2; break; 1538 case 0x00: data = 1; break;
1747 } 1539 case 0x10: data = 3; break;
1748 } else { 1540 case 0x20: data = 3; break;
1749 data = 0; 1541 case 0x30: data = 2; break;
1750 } 1542 }
1751 } 1543 } else {
1752 } 1544 data = 0;
1545 }
1546 }
1547 }
1753 } 1548 }
1754 1549
1755 return data; 1550 return data;
1756} 1551}
1757 1552
1758static USHORT 1553static unsigned short
1759SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1554SiS_GetMCLK(struct SiS_Private *SiS_Pr)
1760{ 1555{
1761 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 1556 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1762 USHORT index; 1557 unsigned short index;
1763 1558
1764 index = SiS_Get310DRAMType(SiS_Pr, HwInfo); 1559 index = SiS_Get310DRAMType(SiS_Pr);
1765 if(HwInfo->jChipType >= SIS_661) { 1560 if(SiS_Pr->ChipType >= SIS_661) {
1766 if(SiS_Pr->SiS_ROMNew) { 1561 if(SiS_Pr->SiS_ROMNew) {
1767 return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3)))); 1562 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
1768 } 1563 }
1769 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 1564 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1770 } else if(index >= 4) { 1565 } else if(index >= 4) {
1771 index -= 4; 1566 return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
1772 return(SiS_Pr->SiS_MCLKData_1[index].CLOCK); 1567 } else {
1773 } else { 1568 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1774 return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 1569 }
1775 }
1776} 1570}
1777#endif 1571#endif
1778 1572
@@ -1780,30 +1574,30 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1780/* HELPER: ClearBuffer */ 1574/* HELPER: ClearBuffer */
1781/*********************************************/ 1575/*********************************************/
1782 1576
1783#ifdef LINUX_KERNEL 1577#ifdef SIS_LINUX_KERNEL
1784static void 1578static void
1785SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo) 1579SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1786{ 1580{
1787 UCHAR SISIOMEMTYPE *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress; 1581 unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
1788 ULONG AdapterMemorySize = HwInfo->ulVideoMemorySize; 1582 unsigned int memsize = SiS_Pr->VideoMemorySize;
1789 USHORT SISIOMEMTYPE *pBuffer; 1583 unsigned short SISIOMEMTYPE *pBuffer;
1790 int i; 1584 int i;
1791 1585
1792 if(SiS_Pr->SiS_ModeType >= ModeEGA) { 1586 if(!memaddr || !memsize) return;
1793 if(ModeNo > 0x13) { 1587
1794 SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0); 1588 if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1795 } else { 1589 if(ModeNo > 0x13) {
1796 pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress; 1590 SiS_SetMemory(memaddr, memsize, 0);
1797 for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]); 1591 } else {
1798 } 1592 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1799 } else { 1593 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
1800 if(SiS_Pr->SiS_ModeType < ModeCGA) { 1594 }
1801 pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress; 1595 } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
1802 for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]); 1596 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1803 } else { 1597 for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
1804 SiS_SetMemory(VideoMemoryAddress, 0x8000, 0); 1598 } else {
1805 } 1599 SiS_SetMemory(memaddr, 0x8000, 0);
1806 } 1600 }
1807} 1601}
1808#endif 1602#endif
1809 1603
@@ -1812,35 +1606,36 @@ SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
1812/*********************************************/ 1606/*********************************************/
1813 1607
1814BOOLEAN 1608BOOLEAN
1815SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex) 1609SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1610 unsigned short *ModeIdIndex)
1816{ 1611{
1817 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO; 1612 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
1818 1613
1819 if(*ModeNo <= 0x13) { 1614 if((*ModeNo) <= 0x13) {
1820 1615
1821 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01; 1616 if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1822 1617
1823 for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { 1618 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1824 if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break; 1619 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
1825 if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) return FALSE; 1620 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE;
1826 } 1621 }
1827 1622
1828 if(*ModeNo == 0x07) { 1623 if((*ModeNo) == 0x07) {
1829 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 1624 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1830 /* else 350 lines */ 1625 /* else 350 lines */
1831 } 1626 }
1832 if(*ModeNo <= 0x03) { 1627 if((*ModeNo) <= 0x03) {
1833 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; 1628 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1834 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 1629 if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
1835 /* else 350 lines */ 1630 /* else 350 lines */
1836 } 1631 }
1837 /* else 200 lines */ 1632 /* else 200 lines */
1838 1633
1839 } else { 1634 } else {
1840 1635
1841 for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { 1636 for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1842 if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break; 1637 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
1843 if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE; 1638 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE;
1844 } 1639 }
1845 1640
1846 } 1641 }
@@ -1851,10 +1646,10 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
1851/* HELPER: GetModePtr */ 1646/* HELPER: GetModePtr */
1852/*********************************************/ 1647/*********************************************/
1853 1648
1854UCHAR 1649unsigned short
1855SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex) 1650SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1856{ 1651{
1857 UCHAR index; 1652 unsigned short index;
1858 1653
1859 if(ModeNo <= 0x13) { 1654 if(ModeNo <= 0x13) {
1860 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex; 1655 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
@@ -1866,79 +1661,125 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
1866} 1661}
1867 1662
1868/*********************************************/ 1663/*********************************************/
1664/* HELPERS: Get some indices */
1665/*********************************************/
1666
1667unsigned short
1668SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1669{
1670 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1671 if(UseWide == 1) {
1672 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
1673 } else {
1674 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
1675 }
1676 } else {
1677 return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
1678 }
1679}
1680
1681unsigned short
1682SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
1683{
1684 if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
1685 if(UseWide == 1) {
1686 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
1687 } else {
1688 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
1689 }
1690 } else {
1691 return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
1692 }
1693}
1694
1695/*********************************************/
1869/* HELPER: LowModeTests */ 1696/* HELPER: LowModeTests */
1870/*********************************************/ 1697/*********************************************/
1871 1698
1872static BOOLEAN 1699static BOOLEAN
1873SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo) 1700SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1874{ 1701{
1875 USHORT temp,temp1,temp2; 1702 unsigned short temp, temp1, temp2;
1876 1703
1877 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) 1704 if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
1878 return(TRUE); 1705 return TRUE;
1879 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11); 1706 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
1880 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); 1707 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
1881 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 1708 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1882 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55); 1709 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
1883 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 1710 temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
1884 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1); 1711 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
1885 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp); 1712 SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
1886 if((HwInfo->jChipType >= SIS_315H) || 1713 if((SiS_Pr->ChipType >= SIS_315H) ||
1887 (HwInfo->jChipType == SIS_300)) { 1714 (SiS_Pr->ChipType == SIS_300)) {
1888 if(temp2 == 0x55) return(FALSE); 1715 if(temp2 == 0x55) return FALSE;
1889 else return(TRUE); 1716 else return TRUE;
1890 } else { 1717 } else {
1891 if(temp2 != 0x55) return(TRUE); 1718 if(temp2 != 0x55) return TRUE;
1892 else { 1719 else {
1893 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 1720 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
1894 return(FALSE); 1721 return FALSE;
1895 } 1722 }
1896 } 1723 }
1897} 1724}
1898 1725
1899static void 1726static void
1900SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo) 1727SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1901{ 1728{
1902 if(SiS_DoLowModeTest(SiS_Pr, ModeNo, HwInfo)) { 1729 if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
1903 SiS_Pr->SiS_SetFlag |= LowModeTests; 1730 SiS_Pr->SiS_SetFlag |= LowModeTests;
1904 } 1731 }
1905} 1732}
1906 1733
1907/*********************************************/ 1734/*********************************************/
1908/* HELPER: ENABLE CRT1 */ 1735/* HELPER: OPEN/CLOSE CRT1 CRTC */
1909/*********************************************/ 1736/*********************************************/
1910 1737
1911static void 1738static void
1912SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1739SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
1740{
1741 if(IS_SIS650) {
1742 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1743 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
1744 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1745 } else if(IS_SIS661741660760) {
1746 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
1747 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
1748 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
1749 if(!SiS_Pr->SiS_ROMNew) {
1750 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1751 }
1752 }
1753}
1754
1755static void
1756SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
1913{ 1757{
1914 if(IS_SIS650) { 1758#if 0 /* This locks some CRTC registers. We don't want that. */
1915 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 1759 unsigned short temp1 = 0, temp2 = 0;
1916 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 1760
1917 if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); 1761 if(IS_SIS661741660760) {
1918 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 1762 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1919 } 1763 temp1 = 0xa0; temp2 = 0x08;
1920 } else if(IS_SIS661741660760) { 1764 }
1921 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7); 1765 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
1922 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 1766 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
1923 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 1767 }
1924 if(!SiS_Pr->SiS_ROMNew) { 1768#endif
1925 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
1926 }
1927 }
1928} 1769}
1929 1770
1930static void 1771static void
1931SiS_HandleCRT1(SiS_Private *SiS_Pr) 1772SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
1932{ 1773{
1933 /* Enable CRT1 gating */ 1774 /* Enable CRT1 gating */
1934 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf); 1775 SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
1935#if 0 1776#if 0
1936 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) { 1777 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
1937 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) || 1778 if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
1938 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) { 1779 (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
1939 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40); 1780 SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
1940 } 1781 }
1941 } 1782 }
1942#endif 1783#endif
1943} 1784}
1944 1785
@@ -1946,57 +1787,54 @@ SiS_HandleCRT1(SiS_Private *SiS_Pr)
1946/* HELPER: GetColorDepth */ 1787/* HELPER: GetColorDepth */
1947/*********************************************/ 1788/*********************************************/
1948 1789
1949USHORT 1790unsigned short
1950SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex) 1791SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1792 unsigned short ModeIdIndex)
1951{ 1793{
1952 USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; 1794 static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
1953 SHORT index; 1795 unsigned short modeflag;
1954 USHORT modeflag; 1796 short index;
1955 1797
1956 /* Do NOT check UseCustomMode, will skrew up FIFO */ 1798 /* Do NOT check UseCustomMode, will skrew up FIFO */
1957 if(ModeNo == 0xfe) { 1799 if(ModeNo == 0xfe) {
1958 modeflag = SiS_Pr->CModeFlag; 1800 modeflag = SiS_Pr->CModeFlag;
1959 } else { 1801 } else if(ModeNo <= 0x13) {
1960 if(ModeNo <= 0x13) 1802 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1961 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 1803 } else {
1962 else 1804 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1963 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 1805 }
1964 } 1806
1965 1807 index = (modeflag & ModeTypeMask) - ModeEGA;
1966 index = (modeflag & ModeTypeMask) - ModeEGA; 1808 if(index < 0) index = 0;
1967 if(index < 0) index = 0; 1809 return ColorDepth[index];
1968 return(ColorDepth[index]);
1969} 1810}
1970 1811
1971/*********************************************/ 1812/*********************************************/
1972/* HELPER: GetOffset */ 1813/* HELPER: GetOffset */
1973/*********************************************/ 1814/*********************************************/
1974 1815
1975USHORT 1816unsigned short
1976SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 1817SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1977 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo) 1818 unsigned short ModeIdIndex, unsigned short RRTI)
1978{ 1819{
1979 USHORT xres, temp, colordepth, infoflag; 1820 unsigned short xres, temp, colordepth, infoflag;
1980 1821
1981 if(SiS_Pr->UseCustomMode) { 1822 if(SiS_Pr->UseCustomMode) {
1982 infoflag = SiS_Pr->CInfoFlag; 1823 infoflag = SiS_Pr->CInfoFlag;
1983 xres = SiS_Pr->CHDisplay; 1824 xres = SiS_Pr->CHDisplay;
1984 } else { 1825 } else {
1985 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 1826 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
1986 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes; 1827 xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
1987 } 1828 }
1988 1829
1989 colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex); 1830 colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
1990 1831
1991 temp = xres / 16; 1832 temp = xres / 16;
1992 if(infoflag & InterlaceMode) temp <<= 1; 1833 if(infoflag & InterlaceMode) temp <<= 1;
1993 temp *= colordepth; 1834 temp *= colordepth;
1994 if(xres % 16) { 1835 if(xres % 16) temp += (colordepth >> 1);
1995 colordepth >>= 1; 1836
1996 temp += colordepth; 1837 return temp;
1997 }
1998
1999 return(temp);
2000} 1838}
2001 1839
2002/*********************************************/ 1840/*********************************************/
@@ -2004,55 +1842,29 @@ SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2004/*********************************************/ 1842/*********************************************/
2005 1843
2006static void 1844static void
2007SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo) 1845SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
2008{ 1846{
2009 UCHAR SRdata; 1847 unsigned char SRdata;
2010 USHORT i; 1848 int i;
2011 1849
2012 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); /* Set SR0 */ 1850 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
2013 1851
2014 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0]; 1852 /* or "display off" */
1853 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
2015 1854
2016 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 1855 /* determine whether to force x8 dotclock */
2017 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 1856 if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
2018 SRdata |= 0x01;
2019 }
2020 if(HwInfo->jChipType >= SIS_661) {
2021 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2022 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2023 SRdata |= 0x01; /* 8 dot clock */
2024 }
2025 }
2026 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2027 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2028 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2029 SRdata |= 0x01; /* 8 dot clock */
2030 }
2031 }
2032 }
2033 }
2034 1857
2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1858 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2036 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1859 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01;
2037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 1860 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
2038 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2039 SRdata |= 0x01; /* 8 dot clock */
2040 }
2041 }
2042 }
2043 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2044 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2045 SRdata |= 0x01; /* 8 dot clock */
2046 }
2047 }
2048 }
2049 1861
2050 SRdata |= 0x20; /* screen off */ 1862 }
2051 1863
2052 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata); 1864 SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
2053 1865
2054 for(i = 2; i <= 4; i++) { 1866 for(i = 2; i <= 4; i++) {
2055 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; 1867 SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
2056 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata); 1868 SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
2057 } 1869 }
2058} 1870}
@@ -2062,17 +1874,17 @@ SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
2062/*********************************************/ 1874/*********************************************/
2063 1875
2064static void 1876static void
2065SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo) 1877SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
2066{ 1878{
2067 UCHAR Miscdata; 1879 unsigned char Miscdata;
2068 1880
2069 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; 1881 Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
2070 1882
2071 if(HwInfo->jChipType < SIS_661) { 1883 if(SiS_Pr->ChipType < SIS_661) {
2072 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 1884 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2073 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 1885 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2074 Miscdata |= 0x0C; 1886 Miscdata |= 0x0C;
2075 } 1887 }
2076 } 1888 }
2077 } 1889 }
2078 1890
@@ -2084,33 +1896,34 @@ SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo
2084/*********************************************/ 1896/*********************************************/
2085 1897
2086static void 1898static void
2087SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 1899SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
2088 USHORT StandTableIndex)
2089{ 1900{
2090 UCHAR CRTCdata; 1901 unsigned char CRTCdata;
2091 USHORT i; 1902 unsigned short i;
2092 1903
2093 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* Unlock CRTC */ 1904 /* Unlock CRTC */
2094 1905 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
2095 for(i = 0; i <= 0x18; i++) { 1906
2096 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 1907 for(i = 0; i <= 0x18; i++) {
2097 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */ 1908 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
2098 } 1909 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
2099 if(HwInfo->jChipType >= SIS_661) { 1910 }
2100 SiS_SetupCR5x(SiS_Pr, HwInfo); 1911
2101 for(i = 0x13; i <= 0x14; i++) { 1912 if(SiS_Pr->ChipType >= SIS_661) {
2102 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 1913 SiS_OpenCRTC(SiS_Pr);
2103 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); 1914 for(i = 0x13; i <= 0x14; i++) {
2104 } 1915 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
2105 } else if( ( (HwInfo->jChipType == SIS_630) || 1916 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
2106 (HwInfo->jChipType == SIS_730) ) && 1917 }
2107 (HwInfo->jChipRevision >= 0x30) ) { /* for 630S0 */ 1918 } else if( ( (SiS_Pr->ChipType == SIS_630) ||
2108 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 1919 (SiS_Pr->ChipType == SIS_730) ) &&
2109 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 1920 (SiS_Pr->ChipRevision >= 0x30) ) {
2110 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE); 1921 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2111 } 1922 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
2112 } 1923 SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
2113 } 1924 }
1925 }
1926 }
2114} 1927}
2115 1928
2116/*********************************************/ 1929/*********************************************/
@@ -2118,64 +1931,58 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
2118/*********************************************/ 1931/*********************************************/
2119 1932
2120static void 1933static void
2121SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, 1934SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
2122 PSIS_HW_INFO HwInfo)
2123{ 1935{
2124 UCHAR ARdata; 1936 unsigned char ARdata;
2125 USHORT i; 1937 unsigned short i;
2126 1938
2127 for(i = 0; i <= 0x13; i++) { 1939 for(i = 0; i <= 0x13; i++) {
2128 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; 1940 ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
2129#if 0 1941
2130 if((i <= 0x0f) || (i == 0x11)) {
2131 if(ds:489 & 0x08) {
2132 continue;
2133 }
2134 }
2135#endif
2136 if(i == 0x13) { 1942 if(i == 0x13) {
2137 /* Pixel shift. If screen on LCD or TV is shifted left or right, 1943 /* Pixel shift. If screen on LCD or TV is shifted left or right,
2138 * this might be the cause. 1944 * this might be the cause.
2139 */ 1945 */
2140 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 1946 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2141 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0; 1947 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
2142 } 1948 }
2143 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1949 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2144 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1950 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2145 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 1951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2146 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; 1952 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
2147 } 1953 }
2148 } 1954 }
2149 } 1955 }
2150 if(HwInfo->jChipType >= SIS_661) { 1956 if(SiS_Pr->ChipType >= SIS_661) {
2151 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { 1957 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
2152 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; 1958 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
2153 } 1959 }
2154 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 1960 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2155 if(HwInfo->jChipType >= SIS_315H) { 1961 if(SiS_Pr->ChipType >= SIS_315H) {
2156 if(IS_SIS550650740660) { 1962 if(IS_SIS550650740660) {
2157 /* 315, 330 don't do this */ 1963 /* 315, 330 don't do this */
2158 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 1964 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
2159 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; 1965 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
2160 } else { 1966 } else {
2161 ARdata = 0; 1967 ARdata = 0;
2162 } 1968 }
2163 } 1969 }
2164 } else { 1970 } else {
2165 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0; 1971 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
2166 } 1972 }
2167 } 1973 }
2168 } 1974 }
2169 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 1975 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
2170 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */ 1976 SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */
2171 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */ 1977 SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */
2172 } 1978 }
2173 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 1979
2174 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */ 1980 SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
2175 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */ 1981 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */
1982 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */
2176 1983
2177 SiS_GetRegByte(SiS_Pr->SiS_P3da); 1984 SiS_GetRegByte(SiS_Pr->SiS_P3da);
2178 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */ 1985 SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
2179 SiS_GetRegByte(SiS_Pr->SiS_P3da); 1986 SiS_GetRegByte(SiS_Pr->SiS_P3da);
2180} 1987}
2181 1988
@@ -2184,10 +1991,10 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
2184/*********************************************/ 1991/*********************************************/
2185 1992
2186static void 1993static void
2187SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex) 1994SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
2188{ 1995{
2189 UCHAR GRdata; 1996 unsigned char GRdata;
2190 USHORT i; 1997 unsigned short i;
2191 1998
2192 for(i = 0; i <= 0x08; i++) { 1999 for(i = 0; i <= 0x08; i++) {
2193 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; 2000 GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
@@ -2205,22 +2012,22 @@ SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
2205/*********************************************/ 2012/*********************************************/
2206 2013
2207static void 2014static void
2208SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo) 2015SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
2209{ 2016{
2210 USHORT i; 2017 unsigned short i;
2211 2018
2212 for(i = 0x0A; i <= 0x0E; i++) { 2019 for(i = 0x0A; i <= 0x0E; i++) {
2213 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00); 2020 SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
2214 } 2021 }
2215 2022
2216 if(HwInfo->jChipType >= SIS_315H) { 2023 if(SiS_Pr->ChipType >= SIS_315H) {
2217 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE); 2024 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
2218 if(ModeNo <= 0x13) { 2025 if(ModeNo <= 0x13) {
2219 if(ModeNo == 0x06 || ModeNo >= 0x0e) { 2026 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
2220 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20); 2027 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
2221 } 2028 }
2222 } 2029 }
2223 } 2030 }
2224} 2031}
2225 2032
2226/*********************************************/ 2033/*********************************************/
@@ -2228,32 +2035,24 @@ SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
2228/*********************************************/ 2035/*********************************************/
2229 2036
2230static void 2037static void
2231SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 2038SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
2232{ 2039{
2233 if(HwInfo->jChipType >= SIS_315H) { 2040 if(SiS_Pr->ChipType >= SIS_315H) {
2234 if(HwInfo->jChipType < SIS_661) { 2041 if(SiS_Pr->ChipType < SIS_661) {
2235 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return; 2042 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
2236 } 2043 }
2237 } else { 2044 } else {
2238 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && 2045 if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
2239 (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { 2046 (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
2240 return; 2047 return;
2241 } 2048 }
2242 } 2049 }
2243 2050
2244 if(HwInfo->jChipType >= SIS_315H) { 2051 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
2245 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
2246 } else {
2247 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
2248 }
2249 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B); 2052 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
2250 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C); 2053 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
2251 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 2054 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2252 if(HwInfo->jChipType >= SIS_315H) { 2055 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2253 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
2254 } else {
2255 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
2256 }
2257 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B); 2056 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
2258 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C); 2057 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
2259 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 2058 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
@@ -2264,19 +2063,19 @@ SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
2264/*********************************************/ 2063/*********************************************/
2265 2064
2266static void 2065static void
2267SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex) 2066SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
2268{ 2067{
2269 USHORT sync; 2068 unsigned short sync;
2270 2069
2271 if(SiS_Pr->UseCustomMode) { 2070 if(SiS_Pr->UseCustomMode) {
2272 sync = SiS_Pr->CInfoFlag >> 8; 2071 sync = SiS_Pr->CInfoFlag >> 8;
2273 } else { 2072 } else {
2274 sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; 2073 sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
2275 } 2074 }
2276 2075
2277 sync &= 0xC0; 2076 sync &= 0xC0;
2278 sync |= 0x2f; 2077 sync |= 0x2f;
2279 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync); 2078 SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
2280} 2079}
2281 2080
2282/*********************************************/ 2081/*********************************************/
@@ -2284,72 +2083,67 @@ SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
2284/*********************************************/ 2083/*********************************************/
2285 2084
2286static void 2085static void
2287SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2086SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2288 USHORT RefreshRateTableIndex, 2087 unsigned short ModeIdIndex, unsigned short RRTI)
2289 PSIS_HW_INFO HwInfo)
2290{ 2088{
2291 UCHAR index; 2089 unsigned short temp, i, j, modeflag;
2292 USHORT temp,i,j,modeflag; 2090 unsigned char *crt1data = NULL;
2293 2091
2294 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* unlock cr0-7 */ 2092 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2295 2093
2296 if(SiS_Pr->UseCustomMode) { 2094 if(SiS_Pr->UseCustomMode) {
2297 2095
2298 modeflag = SiS_Pr->CModeFlag; 2096 crt1data = &SiS_Pr->CCRT1CRTC[0];
2299 2097
2300 for(i=0,j=0;i<=7;i++,j++) { 2098 } else {
2301 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 2099
2302 } 2100 temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
2303 for(j=0x10;i<=10;i++,j++) { 2101
2304 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 2102 /* Alternate for 1600x1200 LCDA */
2305 } 2103 if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
2306 for(j=0x15;i<=12;i++,j++) { 2104
2307 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 2105 crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
2308 } 2106
2309 for(j=0x0A;i<=15;i++,j++) { 2107 }
2310 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]); 2108
2311 } 2109 /* unlock cr0-7 */
2312 2110 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
2313 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0; 2111
2314 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp); 2112 for(i = 0, j = 0; i <= 7; i++, j++) {
2315 2113 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2316 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 2114 }
2317 if(modeflag & DoubleScanMode) temp |= 0x80; 2115 for(j = 0x10; i <= 10; i++, j++) {
2318 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp); 2116 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2319 2117 }
2320 } else { 2118 for(j = 0x15; i <= 12; i++, j++) {
2321 2119 SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
2322 if(ModeNo <= 0x13) { 2120 }
2323 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 2121 for(j = 0x0A; i <= 15; i++, j++) {
2324 } else { 2122 SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
2325 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2123 }
2326 } 2124
2327 2125 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
2328 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 2126
2329 2127 temp = (crt1data[16] & 0x01) << 5;
2330 for(i=0,j=0;i<=7;i++,j++) { 2128 if(modeflag & DoubleScanMode) temp |= 0x80;
2331 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]); 2129 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
2332 } 2130
2333 for(j=0x10;i<=10;i++,j++) { 2131 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2334 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]); 2132 SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2335 } 2133 }
2336 for(j=0x15;i<=12;i++,j++) { 2134
2337 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]); 2135#ifdef SIS315H
2338 } 2136 if(SiS_Pr->ChipType == XGI_20) {
2339 for(j=0x0A;i<=15;i++,j++) { 2137 SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
2340 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]); 2138 if(!(temp = crt1data[5] & 0x1f)) {
2341 } 2139 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
2342 2140 }
2343 temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; 2141 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
2344 SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp); 2142 temp = (crt1data[16] >> 5) + 3;
2345 2143 if(temp > 7) temp -= 7;
2346 temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; 2144 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
2347 if(modeflag & DoubleScanMode) temp |= 0x80; 2145 }
2348 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp); 2146#endif
2349
2350 }
2351
2352 if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
2353} 2147}
2354 2148
2355/*********************************************/ 2149/*********************************************/
@@ -2359,33 +2153,32 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2359/*********************************************/ 2153/*********************************************/
2360 2154
2361static void 2155static void
2362SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2156SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2363 USHORT RefreshRateTableIndex, 2157 unsigned short ModeIdIndex, unsigned short RRTI)
2364 PSIS_HW_INFO HwInfo)
2365{ 2158{
2366 USHORT temp, DisplayUnit, infoflag; 2159 unsigned short temp, DisplayUnit, infoflag;
2367 2160
2368 if(SiS_Pr->UseCustomMode) { 2161 if(SiS_Pr->UseCustomMode) {
2369 infoflag = SiS_Pr->CInfoFlag; 2162 infoflag = SiS_Pr->CInfoFlag;
2370 } else { 2163 } else {
2371 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 2164 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2372 } 2165 }
2373 2166
2374 DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex, 2167 DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2375 RefreshRateTableIndex,HwInfo);
2376 2168
2377 temp = (DisplayUnit >> 8) & 0x0f; 2169 temp = (DisplayUnit >> 8) & 0x0f;
2378 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp); 2170 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
2379 2171
2380 temp = DisplayUnit & 0xFF; 2172 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
2381 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
2382 2173
2383 if(infoflag & InterlaceMode) DisplayUnit >>= 1; 2174 if(infoflag & InterlaceMode) DisplayUnit >>= 1;
2384 2175
2385 DisplayUnit <<= 5; 2176 DisplayUnit <<= 5;
2386 temp = (DisplayUnit & 0xff00) >> 8; 2177 temp = (DisplayUnit >> 8) + 1;
2387 if(DisplayUnit & 0xff) temp++; 2178 if(DisplayUnit & 0xff) temp++;
2388 temp++; 2179 if(SiS_Pr->ChipType == XGI_20) {
2180 if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
2181 }
2389 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp); 2182 SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
2390} 2183}
2391 2184
@@ -2394,39 +2187,49 @@ SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2394/*********************************************/ 2187/*********************************************/
2395 2188
2396static void 2189static void
2397SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2190SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2398 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex) 2191 unsigned short ModeIdIndex, unsigned short RRTI)
2399{ 2192{
2400 USHORT index=0, clka, clkb; 2193 unsigned short index = 0, clka, clkb;
2401 2194
2402 if(SiS_Pr->UseCustomMode) { 2195 if(SiS_Pr->UseCustomMode) {
2403 clka = SiS_Pr->CSR2B; 2196 clka = SiS_Pr->CSR2B;
2404 clkb = SiS_Pr->CSR2C; 2197 clkb = SiS_Pr->CSR2C;
2405 } else { 2198 } else {
2406 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 2199 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
2407 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2200 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
2408 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A; 2201 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2409 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B; 2202 /* Alternate for 1600x1200 LCDA */
2410 } else { 2203 if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
2411 clka = SiS_Pr->SiS_VCLKData[index].SR2B; 2204 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
2412 clkb = SiS_Pr->SiS_VCLKData[index].SR2C; 2205 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
2413 } 2206 } else {
2414 } 2207 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
2415 2208 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
2416 if(HwInfo->jChipType >= SIS_315H) { 2209 }
2417 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); 2210 }
2418 } else { 2211
2419 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00); 2212 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
2420 } 2213
2421 2214 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
2422 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,clka); 2215 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2423 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,clkb); 2216
2424 2217 if(SiS_Pr->ChipType >= SIS_315H) {
2425 if(HwInfo->jChipType >= SIS_315H) { 2218#ifdef SIS315H
2426 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01); 2219 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
2427 } else { 2220 if(SiS_Pr->ChipType == XGI_20) {
2428 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 2221 unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2429 } 2222 if(mf & HalfDCLK) {
2223 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
2224 clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
2225 clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
2226 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
2227 }
2228 }
2229#endif
2230 } else {
2231 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
2232 }
2430} 2233}
2431 2234
2432/*********************************************/ 2235/*********************************************/
@@ -2434,415 +2237,358 @@ SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2434/*********************************************/ 2237/*********************************************/
2435 2238
2436#ifdef SIS300 2239#ifdef SIS300
2437static USHORT 2240void
2438SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key) 2241SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
2242 unsigned short *idx2)
2243{
2244 unsigned short temp1, temp2;
2245 static const unsigned char ThTiming[8] = {
2246 1, 2, 2, 3, 0, 1, 1, 2
2247 };
2248
2249 temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
2250 (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
2251 (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
2252 (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
2253 (*idx1) <<= 1;
2254}
2255
2256static unsigned short
2257SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
2258{
2259 static const unsigned char ThLowA[8 * 3] = {
2260 61, 3,52, 5,68, 7,100,11,
2261 43, 3,42, 5,54, 7, 78,11,
2262 34, 3,37, 5,47, 7, 67,11
2263 };
2264
2265 return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
2266}
2267
2268unsigned short
2269SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
2270{
2271 static const unsigned char ThLowB[8 * 3] = {
2272 81, 4,72, 6,88, 8,120,12,
2273 55, 4,54, 6,66, 8, 90,12,
2274 42, 4,45, 6,55, 8, 75,12
2275 };
2276
2277 return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
2278}
2279
2280static unsigned short
2281SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
2282 unsigned short colordepth, unsigned short key)
2439{ 2283{
2440 const UCHAR ThLowA[] = { 61, 3,52, 5,68, 7,100,11, 2284 unsigned short idx1, idx2;
2441 43, 3,42, 5,54, 7, 78,11, 2285 unsigned int longtemp = VCLK * colordepth;
2442 34, 3,37, 5,47, 7, 67,11 }; 2286
2443 2287 SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
2444 const UCHAR ThLowB[] = { 81, 4,72, 6,88, 8,120,12, 2288
2445 55, 4,54, 6,66, 8, 90,12, 2289 if(key == 0) {
2446 42, 4,45, 6,55, 8, 75,12 }; 2290 longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
2447 2291 } else {
2448 const UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 }; 2292 longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
2449 2293 }
2450 USHORT tempah, tempal, tempcl, tempbx, temp; 2294 idx1 = longtemp % (MCLK * 16);
2451 ULONG longtemp; 2295 longtemp /= (MCLK * 16);
2452 2296 if(idx1) longtemp++;
2453 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18); 2297 return (unsigned short)longtemp;
2454 tempah &= 0x62;
2455 tempah >>= 1;
2456 tempal = tempah;
2457 tempah >>= 3;
2458 tempal |= tempah;
2459 tempal &= 0x07;
2460 tempcl = ThTiming[tempal];
2461 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
2462 tempbx >>= 6;
2463 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
2464 tempah >>= 4;
2465 tempah &= 0x0c;
2466 tempbx |= tempah;
2467 tempbx <<= 1;
2468 if(key == 0) {
2469 tempal = ThLowA[tempbx + 1];
2470 tempal *= tempcl;
2471 tempal += ThLowA[tempbx];
2472 } else {
2473 tempal = ThLowB[tempbx + 1];
2474 tempal *= tempcl;
2475 tempal += ThLowB[tempbx];
2476 }
2477 longtemp = tempal * VCLK * colordepth;
2478 temp = longtemp % (MCLK * 16);
2479 longtemp /= (MCLK * 16);
2480 if(temp) longtemp++;
2481 return((USHORT)longtemp);
2482} 2298}
2483 2299
2484static USHORT 2300static unsigned short
2485SiS_CalcDelay(SiS_Private *SiS_Pr, USHORT VCLK, USHORT colordepth, USHORT MCLK) 2301SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
2302 unsigned short colordepth, unsigned short MCLK)
2486{ 2303{
2487 USHORT tempax, tempbx; 2304 unsigned short temp1, temp2;
2488 2305
2489 tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0); 2306 temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
2490 tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1); 2307 temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
2491 if(tempax < 4) tempax = 4; 2308 if(temp1 < 4) temp1 = 4;
2492 tempax -= 4; 2309 temp1 -= 4;
2493 if(tempbx < tempax) tempbx = tempax; 2310 if(temp2 < temp1) temp2 = temp1;
2494 return(tempbx); 2311 return temp2;
2495} 2312}
2496 2313
2497static void 2314static void
2498SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo, 2315SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2499 USHORT RefreshRateTableIndex) 2316 unsigned short RefreshRateTableIndex)
2317{
2318 unsigned short ThresholdLow = 0;
2319 unsigned short temp, index, VCLK, MCLK, colorth;
2320 static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
2321
2322 if(ModeNo > 0x13) {
2323
2324 /* Get VCLK */
2325 if(SiS_Pr->UseCustomMode) {
2326 VCLK = SiS_Pr->CSRClock;
2327 } else {
2328 index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2329 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2330 }
2331
2332 /* Get half colordepth */
2333 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2334
2335 /* Get MCLK */
2336 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
2337 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
2338
2339 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
2340 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
2341
2342 do {
2343 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
2344 if(ThresholdLow < 0x13) break;
2345 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2346 ThresholdLow = 0x13;
2347 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
2348 if(!temp) break;
2349 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
2350 } while(0);
2351
2352 } else ThresholdLow = 2;
2353
2354 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2355 temp = (ThresholdLow << 4) | 0x0f;
2356 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2357
2358 temp = (ThresholdLow & 0x10) << 1;
2359 if(ModeNo > 0x13) temp |= 0x40;
2360 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2361
2362 /* What is this? */
2363 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2364
2365 /* Write CRT/CPU threshold high */
2366 temp = ThresholdLow + 3;
2367 if(temp > 0x0f) temp = 0x0f;
2368 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2369}
2370
2371unsigned short
2372SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
2500{ 2373{
2501 USHORT ThresholdLow = 0; 2374 static const unsigned char LatencyFactor[] = {
2502 USHORT index, VCLK, MCLK, colorth=0; 2375 97, 88, 86, 79, 77, 0, /* 64 bit BQ=2 */
2503 USHORT tempah, temp; 2376 0, 87, 85, 78, 76, 54, /* 64 bit BQ=1 */
2504 2377 97, 88, 86, 79, 77, 0, /* 128 bit BQ=2 */
2505 if(ModeNo > 0x13) { 2378 0, 79, 77, 70, 68, 48, /* 128 bit BQ=1 */
2506 2379 80, 72, 69, 63, 61, 0, /* 64 bit BQ=2 */
2507 if(SiS_Pr->UseCustomMode) { 2380 0, 70, 68, 61, 59, 37, /* 64 bit BQ=1 */
2508 VCLK = SiS_Pr->CSRClock; 2381 86, 77, 75, 68, 66, 0, /* 128 bit BQ=2 */
2509 } else { 2382 0, 68, 66, 59, 57, 37 /* 128 bit BQ=1 */
2510 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 2383 };
2511 index &= 0x3F; 2384 static const unsigned char LatencyFactor730[] = {
2512 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ 2385 69, 63, 61,
2513 } 2386 86, 79, 77,
2514 2387 103, 96, 94,
2515 switch (SiS_Pr->SiS_ModeType - ModeEGA) { /* Get half colordepth */ 2388 120,113,111,
2516 case 0 : colorth = 1; break; 2389 137,130,128
2517 case 1 : colorth = 1; break; 2390 };
2518 case 2 : colorth = 2; break; 2391
2519 case 3 : colorth = 2; break; 2392 if(SiS_Pr->ChipType == SIS_730) {
2520 case 4 : colorth = 3; break; 2393 return (unsigned short)LatencyFactor730[index];
2521 case 5 : colorth = 4; break; 2394 } else {
2522 } 2395 return (unsigned short)LatencyFactor[index];
2523 2396 }
2524 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
2525 index &= 0x07;
2526 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
2527
2528 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
2529 tempah &= 0xc3;
2530 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
2531
2532 do {
2533 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK);
2534 ThresholdLow++;
2535 if(ThresholdLow < 0x13) break;
2536 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
2537 ThresholdLow = 0x13;
2538 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
2539 tempah >>= 6;
2540 if(!(tempah)) break;
2541 tempah--;
2542 tempah <<= 6;
2543 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
2544 } while(0);
2545
2546 } else ThresholdLow = 2;
2547
2548 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2549 temp = (ThresholdLow << 4) | 0x0f;
2550 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
2551
2552 temp = (ThresholdLow & 0x10) << 1;
2553 if(ModeNo > 0x13) temp |= 0x40;
2554 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
2555
2556 /* What is this? */
2557 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2558
2559 /* Write CRT/CPU threshold high */
2560 temp = ThresholdLow + 3;
2561 if(temp > 0x0f) temp = 0x0f;
2562 SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
2563} 2397}
2564 2398
2565static USHORT 2399static unsigned short
2566SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR key, PSIS_HW_INFO HwInfo) 2400SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
2567{ 2401{
2568 USHORT data,index; 2402 unsigned short index;
2569 const UCHAR LatencyFactor[] = { 2403
2570 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */ 2404 if(SiS_Pr->ChipType == SIS_730) {
2571 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */ 2405 index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
2572 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */ 2406 } else {
2573 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */ 2407 index = (key & 0xe0) >> 5;
2574 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */ 2408 if(key & 0x10) index += 6;
2575 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */ 2409 if(!(key & 0x01)) index += 24;
2576 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */ 2410 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
2577 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */ 2411 }
2578 }; 2412 return SiS_GetLatencyFactor630(SiS_Pr, index);
2579 const UCHAR LatencyFactor730[] = {
2580 69, 63, 61,
2581 86, 79, 77,
2582 103, 96, 94,
2583 120,113,111,
2584 137,130,128, /* --- Table ends with this entry, data below */
2585 137,130,128, /* to avoid using illegal values */
2586 137,130,128,
2587 137,130,128,
2588 137,130,128,
2589 137,130,128,
2590 137,130,128,
2591 137,130,128,
2592 137,130,128,
2593 137,130,128,
2594 137,130,128,
2595 137,130,128,
2596 };
2597
2598 if(HwInfo->jChipType == SIS_730) {
2599 index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
2600 data = LatencyFactor730[index];
2601 } else {
2602 index = (key & 0xE0) >> 5;
2603 if(key & 0x10) index +=6;
2604 if(!(key & 0x01)) index += 24;
2605 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
2606 if(data & 0x0080) index += 12;
2607 data = LatencyFactor[index];
2608 }
2609 return(data);
2610} 2413}
2611 2414
2612static void 2415static void
2613SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo, 2416SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2614 PSIS_HW_INFO HwInfo, 2417 unsigned short RefreshRateTableIndex)
2615 USHORT RefreshRateTableIndex)
2616{ 2418{
2617 USHORT i,index,data,VCLK,MCLK,colorth=0; 2419 unsigned short ThresholdLow = 0;
2618 ULONG B,eax,bl,data2; 2420 unsigned short i, data, VCLK, MCLK16, colorth = 0;
2619 USHORT ThresholdLow=0; 2421 unsigned int templ, datal;
2620 UCHAR FQBQData[]= { 2422 const unsigned char *queuedata = NULL;
2621 0x01,0x21,0x41,0x61,0x81, 2423 static const unsigned char FQBQData[21] = {
2622 0x31,0x51,0x71,0x91,0xb1, 2424 0x01,0x21,0x41,0x61,0x81,
2623 0x00,0x20,0x40,0x60,0x80, 2425 0x31,0x51,0x71,0x91,0xb1,
2624 0x30,0x50,0x70,0x90,0xb0, 2426 0x00,0x20,0x40,0x60,0x80,
2625 0xFF 2427 0x30,0x50,0x70,0x90,0xb0,
2626 }; 2428 0xff
2627 UCHAR FQBQData730[]= { 2429 };
2628 0x34,0x74,0xb4, 2430 static const unsigned char FQBQData730[16] = {
2629 0x23,0x63,0xa3, 2431 0x34,0x74,0xb4,
2630 0x12,0x52,0x92, 2432 0x23,0x63,0xa3,
2631 0x01,0x41,0x81, 2433 0x12,0x52,0x92,
2632 0x00,0x40,0x80, 2434 0x01,0x41,0x81,
2633 0xff 2435 0x00,0x40,0x80,
2634 }; 2436 0xff
2635 2437 };
2636 i=0; 2438 static const unsigned short colortharray[6] = {
2637 if(ModeNo > 0x13) { 2439 1, 1, 2, 2, 3, 4
2638 if(SiS_Pr->UseCustomMode) { 2440 };
2639 VCLK = SiS_Pr->CSRClock;
2640 } else {
2641 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2642 index &= 0x3F;
2643 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
2644 }
2645
2646 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
2647 index &= 0x07;
2648 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
2649
2650 data2 = SiS_Pr->SiS_ModeType - ModeEGA; /* Get half colordepth */
2651 switch (data2) {
2652 case 0 : colorth = 1; break;
2653 case 1 : colorth = 1; break;
2654 case 2 : colorth = 2; break;
2655 case 3 : colorth = 2; break;
2656 case 4 : colorth = 3; break;
2657 case 5 : colorth = 4; break;
2658 }
2659
2660 if(HwInfo->jChipType == SIS_730) {
2661
2662 do {
2663 B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
2664 bl = B / (MCLK * 16);
2665
2666 if(B == bl * 16 * MCLK) {
2667 bl = bl + 1;
2668 } else {
2669 bl = bl + 2;
2670 }
2671
2672 if(bl > 0x13) {
2673 if(FQBQData730[i+1] == 0xFF) {
2674 ThresholdLow = 0x13;
2675 break;
2676 }
2677 i++;
2678 } else {
2679 ThresholdLow = bl;
2680 break;
2681 }
2682 } while(FQBQData730[i] != 0xFF);
2683 2441
2684 } else { 2442 i = 0;
2685 2443
2686 do { 2444 if(ModeNo > 0x13) {
2687 B = SiS_CalcDelay2(SiS_Pr, FQBQData[i], HwInfo) * VCLK * colorth;
2688 bl = B / (MCLK * 16);
2689 2445
2690 if(B == bl * 16 * MCLK) { 2446 /* Get VCLK */
2691 bl = bl + 1; 2447 if(SiS_Pr->UseCustomMode) {
2692 } else { 2448 VCLK = SiS_Pr->CSRClock;
2693 bl = bl + 2; 2449 } else {
2694 } 2450 data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
2451 VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
2452 }
2695 2453
2696 if(bl > 0x13) { 2454 /* Get MCLK * 16 */
2697 if(FQBQData[i+1] == 0xFF) { 2455 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
2698 ThresholdLow = 0x13; 2456 MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
2699 break; 2457
2700 } 2458 /* Get half colordepth */
2701 i++; 2459 colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
2702 } else { 2460
2703 ThresholdLow = bl; 2461 if(SiS_Pr->ChipType == SIS_730) {
2704 break; 2462 queuedata = &FQBQData730[0];
2705 } 2463 } else {
2706 } while(FQBQData[i] != 0xFF); 2464 queuedata = &FQBQData[0];
2707 } 2465 }
2708 } 2466
2709 else { 2467 do {
2710 if(HwInfo->jChipType == SIS_730) { 2468 templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
2711 } else { 2469
2712 i = 9; 2470 datal = templ % MCLK16;
2713 } 2471 templ = (templ / MCLK16) + 1;
2714 ThresholdLow = 0x02; 2472 if(datal) templ++;
2715 } 2473
2474 if(templ > 0x13) {
2475 if(queuedata[i + 1] == 0xFF) {
2476 ThresholdLow = 0x13;
2477 break;
2478 }
2479 i++;
2480 } else {
2481 ThresholdLow = templ;
2482 break;
2483 }
2484 } while(queuedata[i] != 0xFF);
2485
2486 } else {
2487
2488 if(SiS_Pr->ChipType != SIS_730) i = 9;
2489 ThresholdLow = 0x02;
2490
2491 }
2492
2493 /* Write CRT/CPU threshold low, CRT/Engine threshold high */
2494 data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
2495 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
2496
2497 data = (ThresholdLow & 0x10) << 1;
2498 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
2499
2500 /* What is this? */
2501 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2502
2503 /* Write CRT/CPU threshold high (gap = 3) */
2504 data = ThresholdLow + 3;
2505 if(data > 0x0f) data = 0x0f;
2506 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
2716 2507
2717 /* Write foreground and background queue */ 2508 /* Write foreground and background queue */
2718 if(HwInfo->jChipType == SIS_730) { 2509#ifdef SIS_LINUX_KERNEL
2719 2510 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
2720 data2 = FQBQData730[i];
2721 data2 = (data2 & 0xC0) >> 5;
2722 data2 <<= 8;
2723
2724#ifdef LINUX_KERNEL
2725 SiS_SetRegLong(0xcf8,0x80000050);
2726 eax = SiS_GetRegLong(0xcfc);
2727 eax &= 0xfffff9ff;
2728 eax |= data2;
2729 SiS_SetRegLong(0xcfc,eax);
2730#else 2511#else
2731 /* We use pci functions X offers. We use pcitag 0, because 2512 templ = pciReadLong(0x00000000, 0x50);
2732 * we want to read/write to the host bridge (which is always
2733 * 00:00.0 on 630, 730 and 540), not the VGA device.
2734 */
2735 eax = pciReadLong(0x00000000, 0x50);
2736 eax &= 0xfffff9ff;
2737 eax |= data2;
2738 pciWriteLong(0x00000000, 0x50, eax);
2739#endif 2513#endif
2740 2514
2741 /* Write GUI grant timer (PCI config 0xA3) */ 2515 if(SiS_Pr->ChipType == SIS_730) {
2742 data2 = FQBQData730[i] << 8;
2743 data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
2744 data2 <<= 20;
2745
2746#ifdef LINUX_KERNEL
2747 SiS_SetRegLong(0xcf8,0x800000A0);
2748 eax = SiS_GetRegLong(0xcfc);
2749 eax &= 0x00ffffff;
2750 eax |= data2;
2751 SiS_SetRegLong(0xcfc,eax);
2752#else
2753 eax = pciReadLong(0x00000000, 0xA0);
2754 eax &= 0x00ffffff;
2755 eax |= data2;
2756 pciWriteLong(0x00000000, 0xA0, eax);
2757#endif
2758 2516
2759 } else { 2517 templ &= 0xfffff9ff;
2518 templ |= ((queuedata[i] & 0xc0) << 3);
2760 2519
2761 data2 = FQBQData[i]; 2520 } else {
2762 data2 = (data2 & 0xf0) >> 4;
2763 data2 <<= 24;
2764 2521
2765#ifdef LINUX_KERNEL 2522 templ &= 0xf0ffffff;
2766 SiS_SetRegLong(0xcf8,0x80000050); 2523 if( (ModeNo <= 0x13) &&
2767 eax = SiS_GetRegLong(0xcfc); 2524 (SiS_Pr->ChipType == SIS_630) &&
2768 eax &= 0xf0ffffff; 2525 (SiS_Pr->ChipRevision >= 0x30) ) {
2769 eax |= data2; 2526 templ |= 0x0b000000;
2770 SiS_SetRegLong(0xcfc,eax); 2527 } else {
2771#else 2528 templ |= ((queuedata[i] & 0xf0) << 20);
2772 eax = pciReadLong(0x00000000, 0x50); 2529 }
2773 eax &= 0xf0ffffff; 2530
2774 eax |= data2; 2531 }
2775 pciWriteLong(0x00000000, 0x50, eax);
2776#endif
2777 2532
2778 /* Write GUI grant timer (PCI config 0xA3) */ 2533#ifdef SIS_LINUX_KERNEL
2779 data2 = FQBQData[i]; 2534 sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
2780 data2 &= 0x0f; 2535 templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
2781 data2 <<= 24;
2782
2783#ifdef LINUX_KERNEL
2784 SiS_SetRegLong(0xcf8,0x800000A0);
2785 eax = SiS_GetRegLong(0xcfc);
2786 eax &= 0xf0ffffff;
2787 eax |= data2;
2788 SiS_SetRegLong(0xcfc,eax);
2789#else 2536#else
2790 eax = pciReadLong(0x00000000, 0xA0); 2537 pciWriteLong(0x00000000, 0x50, templ);
2791 eax &= 0xf0ffffff; 2538 templ = pciReadLong(0x00000000, 0xA0);
2792 eax |= data2;
2793 pciWriteLong(0x00000000, 0xA0, eax);
2794#endif 2539#endif
2795 2540
2796 } 2541 /* GUI grant timer (PCI config 0xA3) */
2542 if(SiS_Pr->ChipType == SIS_730) {
2543
2544 templ &= 0x00ffffff;
2545 datal = queuedata[i] << 8;
2546 templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
2797 2547
2798 /* Write CRT/CPU threshold low, CRT/Engine threshold high */ 2548 } else {
2799 data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
2800 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
2801 2549
2802 data = (ThresholdLow & 0x10) << 1; 2550 templ &= 0xf0ffffff;
2803 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data); 2551 templ |= ((queuedata[i] & 0x0f) << 24);
2804 2552
2805 /* What is this? */ 2553 }
2806 SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
2807 2554
2808 /* Write CRT/CPU threshold high (gap = 3) */ 2555#ifdef SIS_LINUX_KERNEL
2809 data = ThresholdLow + 3; 2556 sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
2810 if(data > 0x0f) data = 0x0f; 2557#else
2811 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); 2558 pciWriteLong(0x00000000, 0xA0, templ);
2812}
2813#endif 2559#endif
2560}
2561#endif /* SIS300 */
2814 2562
2815#ifdef SIS315H 2563#ifdef SIS315H
2816static void 2564static void
2817SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2565SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2818 PSIS_HW_INFO HwInfo)
2819{ 2566{
2820 USHORT modeflag; 2567 unsigned short modeflag;
2821 2568
2822 /* disable auto-threshold */ 2569 /* disable auto-threshold */
2823 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); 2570 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
2824 2571
2825 if(SiS_Pr->UseCustomMode) { 2572 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2826 modeflag = SiS_Pr->CModeFlag; 2573
2827 } else { 2574 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
2828 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2575 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
2829 } 2576 if(ModeNo > 0x13) {
2830 2577 if(SiS_Pr->ChipType >= XGI_20) {
2831 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE); 2578 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2832 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); 2579 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2833 if(ModeNo > 0x13) { 2580 } else if(SiS_Pr->ChipType >= SIS_661) {
2834 if(HwInfo->jChipType >= SIS_661) { 2581 if(!(modeflag & HalfDCLK)) {
2835 if(!(modeflag & HalfDCLK)) { 2582 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2836 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 2583 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2837 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 2584 }
2838 } 2585 } else {
2839 } else { 2586 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
2840 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { 2587 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
2841 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 2588 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
2842 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 2589 }
2843 } 2590 }
2844 } 2591 }
2845 }
2846} 2592}
2847#endif 2593#endif
2848 2594
@@ -2851,385 +2597,370 @@ SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2851/*********************************************/ 2597/*********************************************/
2852 2598
2853static void 2599static void
2854SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 2600SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2855 USHORT ModeNo, USHORT RefreshRateTableIndex, 2601 unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
2856 USHORT ModeIdIndex)
2857{ 2602{
2858 USHORT data=0, VCLK=0, index=0; 2603 unsigned short data = 0, VCLK = 0, index = 0;
2859 2604
2860 if(ModeNo > 0x13) { 2605 if(ModeNo > 0x13) {
2861 if(SiS_Pr->UseCustomMode) { 2606 if(SiS_Pr->UseCustomMode) {
2862 VCLK = SiS_Pr->CSRClock; 2607 VCLK = SiS_Pr->CSRClock;
2863 } else { 2608 } else {
2864 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex, 2609 index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
2865 RefreshRateTableIndex,HwInfo); 2610 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
2866 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 2611 }
2867 } 2612 }
2868 }
2869
2870 if(HwInfo->jChipType < SIS_315H) {
2871
2872 if(VCLK > 150) data |= 0x80;
2873 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
2874
2875 data = 0x00;
2876 if(VCLK >= 150) data |= 0x08;
2877 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
2878 2613
2879 } else { 2614 if(SiS_Pr->ChipType < SIS_315H) {
2615#ifdef SIS300
2616 if(VCLK > 150) data |= 0x80;
2617 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
2880 2618
2881 if(VCLK >= 166) data |= 0x0c; 2619 data = 0x00;
2882 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); 2620 if(VCLK >= 150) data |= 0x08;
2621 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
2622#endif
2623 } else if(SiS_Pr->ChipType < XGI_20) {
2624#ifdef SIS315H
2625 if(VCLK >= 166) data |= 0x0c;
2626 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2883 2627
2884 if(VCLK >= 166) { 2628 if(VCLK >= 166) {
2885 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7); 2629 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
2886 } 2630 }
2887 } 2631#endif
2632 } else {
2633#ifdef SIS315H
2634 if(VCLK >= 200) data |= 0x0c;
2635 if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
2636 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
2637 if(SiS_Pr->ChipType != XGI_20) {
2638 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
2639 if(VCLK < 200) data |= 0x10;
2640 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
2641 }
2642#endif
2643 }
2888 2644
2889 /* DAC speed */ 2645 /* DAC speed */
2890 if(HwInfo->jChipType >= SIS_661) { 2646 if(SiS_Pr->ChipType >= SIS_661) {
2891 2647
2892 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10); 2648 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
2893 2649
2894 } else { 2650 } else {
2895 2651
2896 data = 0x03; 2652 data = 0x03;
2897 if((VCLK >= 135) && (VCLK < 160)) data = 0x02; 2653 if(VCLK >= 260) data = 0x00;
2898 else if((VCLK >= 160) && (VCLK < 260)) data = 0x01; 2654 else if(VCLK >= 160) data = 0x01;
2899 else if(VCLK >= 260) data = 0x00; 2655 else if(VCLK >= 135) data = 0x02;
2900 2656
2901 if(HwInfo->jChipType == SIS_540) { 2657 if(SiS_Pr->ChipType == SIS_540) {
2902 if((VCLK == 203) || (VCLK < 234)) data = 0x02; 2658 if((VCLK == 203) || (VCLK < 234)) data = 0x02;
2903 } 2659 }
2904 2660
2905 if(HwInfo->jChipType < SIS_315H) { 2661 if(SiS_Pr->ChipType < SIS_315H) {
2906 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data); 2662 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
2907 } else { 2663 } else {
2908 if(HwInfo->jChipType > SIS_315PRO) { 2664 if(SiS_Pr->ChipType > SIS_315PRO) {
2909 if(ModeNo > 0x13) data &= 0xfc; 2665 if(ModeNo > 0x13) data &= 0xfc;
2910 } 2666 }
2911 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data); 2667 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
2912 } 2668 }
2913 2669
2914 } 2670 }
2915} 2671}
2916 2672
2917static void 2673static void
2918SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 2674SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2919 USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex) 2675 unsigned short ModeIdIndex, unsigned short RRTI)
2920{ 2676{
2921 USHORT data,infoflag=0,modeflag; 2677 unsigned short data, infoflag = 0, modeflag, resindex;
2922 USHORT resindex,xres;
2923#ifdef SIS315H 2678#ifdef SIS315H
2924 USHORT data2,data3; 2679 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2925 ULONG longdata; 2680 unsigned short data2, data3;
2926 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
2927#endif 2681#endif
2928 2682
2929 if(SiS_Pr->UseCustomMode) { 2683 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2930 modeflag = SiS_Pr->CModeFlag; 2684
2931 infoflag = SiS_Pr->CInfoFlag; 2685 if(SiS_Pr->UseCustomMode) {
2932 xres = SiS_Pr->CHDisplay; 2686 infoflag = SiS_Pr->CInfoFlag;
2933 } else { 2687 } else {
2934 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex); 2688 resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
2935 if(ModeNo > 0x13) { 2689 if(ModeNo > 0x13) {
2936 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2690 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
2937 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 2691 }
2938 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; 2692 }
2939 } else { 2693
2940 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 2694 /* Disable DPMS */
2941 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; 2695 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
2942 } 2696
2943 } 2697 data = 0;
2944 2698 if(ModeNo > 0x13) {
2945 /* Disable DPMS */ 2699 if(SiS_Pr->SiS_ModeType > ModeEGA) {
2946 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 2700 data |= 0x02;
2947 2701 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
2948 data = 0; 2702 }
2949 if(ModeNo > 0x13) { 2703 if(infoflag & InterlaceMode) data |= 0x20;
2950 if(SiS_Pr->SiS_ModeType > ModeEGA) { 2704 }
2951 data |= 0x02; 2705 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
2952 data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); 2706
2953 } 2707 if(SiS_Pr->ChipType != SIS_300) {
2954 if(infoflag & InterlaceMode) data |= 0x20; 2708 data = 0;
2955 } 2709 if(infoflag & InterlaceMode) {
2956 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data); 2710 /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
2957 2711 int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
2958 if(HwInfo->jChipType != SIS_300) { 2712 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
2959 data = 0; 2713 int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
2960 if(infoflag & InterlaceMode) { 2714 ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
2961 if(xres <= 800) data = 0x0020; 2715 data = hrs - (hto >> 1) + 3;
2962 else if(xres <= 1024) data = 0x0035; 2716 }
2963 else data = 0x0048; 2717 SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
2964 } 2718 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
2965 SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF)); 2719 }
2966 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8)); 2720
2967 } 2721 if(modeflag & HalfDCLK) {
2968 2722 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
2969 if(modeflag & HalfDCLK) { 2723 }
2970 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08); 2724
2971 } 2725 data = 0;
2972 2726 if(modeflag & LineCompareOff) data = 0x08;
2973 data = 0; 2727 if(SiS_Pr->ChipType == SIS_300) {
2974 if(modeflag & LineCompareOff) data = 0x08; 2728 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
2975 if(HwInfo->jChipType == SIS_300) { 2729 } else {
2976 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data); 2730 if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
2977 } else { 2731 if(SiS_Pr->SiS_ModeType == ModeEGA) {
2978 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data); 2732 if(ModeNo > 0x13) {
2979 if(SiS_Pr->SiS_ModeType == ModeEGA) { 2733 data |= 0x40;
2980 if(ModeNo > 0x13) { 2734 }
2981 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40); 2735 }
2982 } 2736 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
2983 } 2737 }
2984 }
2985
2986 if(HwInfo->jChipType >= SIS_661) {
2987 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
2988 }
2989 2738
2990#ifdef SIS315H 2739#ifdef SIS315H
2991 if(HwInfo->jChipType == SIS_315PRO) { 2740 if(SiS_Pr->ChipType >= SIS_315H) {
2992 2741 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
2993 data = SiS_Get310DRAMType(SiS_Pr, HwInfo); 2742 }
2994 data = SiS_Pr->SiS_SR15[2][data];
2995 if(SiS_Pr->SiS_ModeType == ModeText) {
2996 data &= 0xc7;
2997 } else {
2998 data2 = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
2999 RefreshRateTableIndex,HwInfo);
3000 data2 >>= 1;
3001 if(infoflag & InterlaceMode) data2 >>= 1;
3002 data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
3003 if(!data3) data3++;
3004 data2 /= data3;
3005 if(data2 >= 0x50) {
3006 data &= 0x0f;
3007 data |= 0x50;
3008 }
3009 }
3010 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
3011
3012 } else if( (HwInfo->jChipType == SIS_330) ||
3013 ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
3014
3015 data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
3016 if(HwInfo->jChipType == SIS_330) {
3017 data = SiS_Pr->SiS_SR15[2][data];
3018 } else {
3019 if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
3020 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
3021 else data = 0xba;
3022 }
3023 if(SiS_Pr->SiS_ModeType <= ModeEGA) {
3024 data &= 0xc7;
3025 } else {
3026 if(SiS_Pr->UseCustomMode) {
3027 data2 = SiS_Pr->CSRClock;
3028 } else {
3029 data2 = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
3030 RefreshRateTableIndex,HwInfo);
3031 data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
3032 }
3033 2743
3034 data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1; 2744 if(SiS_Pr->ChipType == SIS_315PRO) {
3035 if(data3) data2 *= data3; 2745
3036 2746 data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
3037 longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024; 2747 if(SiS_Pr->SiS_ModeType == ModeText) {
3038 2748 data &= 0xc7;
3039 data2 = longdata / data2; 2749 } else {
3040 2750 data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
3041 if(HwInfo->jChipType == SIS_330) { 2751 if(infoflag & InterlaceMode) data2 >>= 1;
3042 if(SiS_Pr->SiS_ModeType != Mode16Bpp) { 2752 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
3043 if (data2 >= 0x19c) data = 0xba; 2753 if(data3) data2 /= data3;
3044 else if(data2 >= 0x140) data = 0x7a; 2754 if(data2 >= 0x50) {
3045 else if(data2 >= 0x101) data = 0x3a; 2755 data &= 0x0f;
3046 else if(data2 >= 0xf5) data = 0x32; 2756 data |= 0x50;
3047 else if(data2 >= 0xe2) data = 0x2a; 2757 }
3048 else if(data2 >= 0xc4) data = 0x22; 2758 }
3049 else if(data2 >= 0xac) data = 0x1a; 2759 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
3050 else if(data2 >= 0x9e) data = 0x12; 2760
3051 else if(data2 >= 0x8e) data = 0x0a; 2761 } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
3052 else data = 0x02; 2762
3053 } else { 2763 data = SiS_Get310DRAMType(SiS_Pr);
3054 if(data2 >= 0x127) data = 0xba; 2764 if(SiS_Pr->ChipType == SIS_330) {
3055 else data = 0x7a; 2765 data = SiS_Pr->SiS_SR15[(2 * 4) + data];
3056 } 2766 } else {
3057 } else { /* 760+LFB */ 2767 if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
3058 if (data2 >= 0x190) data = 0xba; 2768 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
3059 else if(data2 >= 0xff) data = 0x7a; 2769 else data = 0xba;
3060 else if(data2 >= 0xd3) data = 0x3a; 2770 }
3061 else if(data2 >= 0xa9) data = 0x1a; 2771 if(SiS_Pr->SiS_ModeType <= ModeEGA) {
3062 else if(data2 >= 0x93) data = 0x0a; 2772 data &= 0xc7;
3063 else data = 0x02; 2773 } else {
3064 } 2774 if(SiS_Pr->UseCustomMode) {
3065 } 2775 data2 = SiS_Pr->CSRClock;
3066 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data); 2776 } else {
3067 } else if(HwInfo->jChipType == SIS_340) { 2777 data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
3068 /* TODO */ 2778 data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
3069 } 2779 }
2780
2781 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
2782 if(data3) data2 *= data3;
2783
2784 data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
2785
2786 if(SiS_Pr->ChipType == SIS_330) {
2787 if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
2788 if (data2 >= 0x19c) data = 0xba;
2789 else if(data2 >= 0x140) data = 0x7a;
2790 else if(data2 >= 0x101) data = 0x3a;
2791 else if(data2 >= 0xf5) data = 0x32;
2792 else if(data2 >= 0xe2) data = 0x2a;
2793 else if(data2 >= 0xc4) data = 0x22;
2794 else if(data2 >= 0xac) data = 0x1a;
2795 else if(data2 >= 0x9e) data = 0x12;
2796 else if(data2 >= 0x8e) data = 0x0a;
2797 else data = 0x02;
2798 } else {
2799 if(data2 >= 0x127) data = 0xba;
2800 else data = 0x7a;
2801 }
2802 } else { /* 76x+LFB */
2803 if (data2 >= 0x190) data = 0xba;
2804 else if(data2 >= 0xff) data = 0x7a;
2805 else if(data2 >= 0xd3) data = 0x3a;
2806 else if(data2 >= 0xa9) data = 0x1a;
2807 else if(data2 >= 0x93) data = 0x0a;
2808 else data = 0x02;
2809 }
2810 }
2811 SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
2812
2813 }
2814 /* XGI: Nothing. */
2815 /* TODO: Check SiS340 */
3070#endif 2816#endif
3071 2817
3072 data = 0x60; 2818 data = 0x60;
3073 if(SiS_Pr->SiS_ModeType != ModeText) { 2819 if(SiS_Pr->SiS_ModeType != ModeText) {
3074 data ^= 0x60; 2820 data ^= 0x60;
3075 if(SiS_Pr->SiS_ModeType != ModeEGA) { 2821 if(SiS_Pr->SiS_ModeType != ModeEGA) {
3076 data ^= 0xA0; 2822 data ^= 0xA0;
3077 } 2823 }
3078 } 2824 }
3079 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data); 2825 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
3080 2826
3081 SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex); 2827 SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
3082 2828
3083#ifdef SIS315H 2829#ifdef SIS315H
3084 if(HwInfo->jChipType >= SIS_315H) { 2830 if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
3085 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 2831 (SiS_Pr->ChipType == XGI_40)) {
3086 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c); 2832 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3087 } else { 2833 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
3088 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c); 2834 } else {
3089 } 2835 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
3090 } 2836 }
2837 } else if(SiS_Pr->ChipType == XGI_20) {
2838 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
2839 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
2840 } else {
2841 SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
2842 }
2843 SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
2844 }
3091#endif 2845#endif
3092} 2846}
3093 2847
3094/*********************************************/ 2848#ifdef SIS315H
3095/* LOAD DAC */
3096/*********************************************/
3097
3098#if 0
3099static void 2849static void
3100SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port) 2850SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
3101{ 2851{
2852#if 0
2853 /* TODO: Find out about IOAddress2 */
2854 SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
2855 SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
2856 SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
3102 int i; 2857 int i;
3103 2858
3104 OutPortByte(port, 0); 2859 if((SiS_Pr->ChipRevision != 0) ||
3105 port++; 2860 (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
3106 for (i=0; i < (256 * 3); i++) { 2861 return;
3107 OutPortByte(port, 0); 2862
2863 for(i = 0; i <= 4; i++) { /* SR00 - SR04 */
2864 SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
3108 } 2865 }
2866 for(i = 0; i <= 8; i++) { /* GR00 - GR08 */
2867 SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
2868 }
2869 SiS_SetReg(P2_3c4,0x05,0x86);
2870 SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06)); /* SR06 */
2871 SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21)); /* SR21 */
2872 SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc)); /* MISC */
2873 SiS_SetReg(P2_3c4,0x05,0x00);
2874#endif
3109} 2875}
3110#endif 2876#endif
3111 2877
2878/*********************************************/
2879/* LOAD DAC */
2880/*********************************************/
2881
3112static void 2882static void
3113SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag, 2883SiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
3114 USHORT dl, USHORT ah, USHORT al, USHORT dh) 2884 unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
3115{ 2885{
3116 USHORT temp,bh,bl; 2886 unsigned short d1, d2, d3;
3117 2887
3118 bh = ah; 2888 switch(dl) {
3119 bl = al; 2889 case 0: d1 = dh; d2 = ah; d3 = al; break;
3120 if(dl != 0) { 2890 case 1: d1 = ah; d2 = al; d3 = dh; break;
3121 temp = bh; 2891 default: d1 = al; d2 = dh; d3 = ah;
3122 bh = dh; 2892 }
3123 dh = temp; 2893 SiS_SetRegByte(DACData, (d1 << shiftflag));
3124 if(dl == 1) { 2894 SiS_SetRegByte(DACData, (d2 << shiftflag));
3125 temp = bl; 2895 SiS_SetRegByte(DACData, (d3 << shiftflag));
3126 bl = dh;
3127 dh = temp;
3128 } else {
3129 temp = bl;
3130 bl = bh;
3131 bh = temp;
3132 }
3133 }
3134 if(shiftflag) {
3135 dh <<= 2;
3136 bh <<= 2;
3137 bl <<= 2;
3138 }
3139 SiS_SetRegByte(DACData,(USHORT)dh);
3140 SiS_SetRegByte(DACData,(USHORT)bh);
3141 SiS_SetRegByte(DACData,(USHORT)bl);
3142} 2896}
3143 2897
3144void 2898void
3145SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 2899SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3146 USHORT ModeNo, USHORT ModeIdIndex)
3147{ 2900{
3148 USHORT data,data2; 2901 unsigned short data, data2, time, i, j, k, m, n, o;
3149 USHORT time,i,j,k,m,n,o; 2902 unsigned short si, di, bx, sf;
3150 USHORT si,di,bx,dl,al,ah,dh;
3151 USHORT shiftflag;
3152 SISIOADDRESS DACAddr, DACData; 2903 SISIOADDRESS DACAddr, DACData;
3153 const USHORT *table = NULL; 2904 const unsigned char *table = NULL;
3154 2905
3155 if(ModeNo <= 0x13) { 2906 data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
3156 data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3157 } else {
3158 if(SiS_Pr->UseCustomMode) {
3159 data = SiS_Pr->CModeFlag;
3160 } else {
3161 data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3162 }
3163 }
3164 2907
3165 data &= DACInfoFlag; 2908 j = time = 64;
3166 time = 64; 2909 if(data == 0x00) table = SiS_MDA_DAC;
3167 if(data == 0x00) table = SiS_MDA_DAC; 2910 else if(data == 0x08) table = SiS_CGA_DAC;
3168 if(data == 0x08) table = SiS_CGA_DAC; 2911 else if(data == 0x10) table = SiS_EGA_DAC;
3169 if(data == 0x10) table = SiS_EGA_DAC; 2912 else if(data == 0x18) {
3170 if(data == 0x18) { 2913 j = 16;
3171 time = 256; 2914 time = 256;
3172 table = SiS_VGA_DAC; 2915 table = SiS_VGA_DAC;
3173 } 2916 }
3174 if(time == 256) j = 16;
3175 else j = time;
3176 2917
3177 if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */ 2918 if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
3178 (SiS_Pr->SiS_VBType & VB_NoLCD) ) || 2919 (SiS_Pr->SiS_VBType & VB_NoLCD) ) ||
3179 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ 2920 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */
3180 (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ 2921 (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
2922 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3181 DACAddr = SiS_Pr->SiS_P3c8; 2923 DACAddr = SiS_Pr->SiS_P3c8;
3182 DACData = SiS_Pr->SiS_P3c9; 2924 DACData = SiS_Pr->SiS_P3c9;
3183 shiftflag = 0; 2925 sf = 0;
3184 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3185 } else { 2926 } else {
3186 shiftflag = 1;
3187 DACAddr = SiS_Pr->SiS_Part5Port; 2927 DACAddr = SiS_Pr->SiS_Part5Port;
3188 DACData = SiS_Pr->SiS_Part5Port + 1; 2928 DACData = SiS_Pr->SiS_Part5Port + 1;
2929 sf = 2;
3189 } 2930 }
3190 2931
3191 SiS_SetRegByte(DACAddr,0x00); 2932 SiS_SetRegByte(DACAddr,0x00);
3192 2933
3193 for(i=0; i<j; i++) { 2934 for(i = 0; i < j; i++) {
3194 data = table[i]; 2935 data = table[i];
3195 for(k=0; k<3; k++) { 2936 for(k = 0; k < 3; k++) {
3196 data2 = 0; 2937 data2 = 0;
3197 if(data & 0x01) data2 = 0x2A; 2938 if(data & 0x01) data2 += 0x2A;
3198 if(data & 0x02) data2 += 0x15; 2939 if(data & 0x02) data2 += 0x15;
3199 if(shiftflag) data2 <<= 2; 2940 SiS_SetRegByte(DACData, (data2 << sf));
3200 SiS_SetRegByte(DACData, data2);
3201 data >>= 2; 2941 data >>= 2;
3202 } 2942 }
3203 } 2943 }
3204 2944
3205 if(time == 256) { 2945 if(time == 256) {
3206 for(i = 16; i < 32; i++) { 2946 for(i = 16; i < 32; i++) {
3207 data = table[i]; 2947 data = table[i] << sf;
3208 if(shiftflag) data <<= 2;
3209 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data); 2948 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
3210 } 2949 }
3211 si = 32; 2950 si = 32;
3212 for(m = 0; m < 9; m++) { 2951 for(m = 0; m < 9; m++) {
3213 di = si; 2952 di = si;
3214 bx = si + 4; 2953 bx = si + 4;
3215 dl = 0; 2954 for(n = 0; n < 3; n++) {
3216 for(n = 0; n < 3; n++) { 2955 for(o = 0; o < 5; o++) {
3217 for(o = 0; o < 5; o++) { 2956 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
3218 dh = table[si];
3219 ah = table[di];
3220 al = table[bx];
3221 si++; 2957 si++;
3222 SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
3223 } 2958 }
3224 si -= 2; 2959 si -= 2;
3225 for(o = 0; o < 3; o++) { 2960 for(o = 0; o < 3; o++) {
3226 dh = table[bx]; 2961 SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
3227 ah = table[di];
3228 al = table[si];
3229 si--; 2962 si--;
3230 SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
3231 } 2963 }
3232 dl++;
3233 } /* for n < 3 */ 2964 } /* for n < 3 */
3234 si += 5; 2965 si += 5;
3235 } /* for m < 9 */ 2966 } /* for m < 9 */
@@ -3241,89 +2972,114 @@ SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
3241/*********************************************/ 2972/*********************************************/
3242 2973
3243static void 2974static void
3244SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 2975SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
3245 USHORT ModeNo, USHORT ModeIdIndex)
3246{ 2976{
3247 USHORT StandTableIndex,RefreshRateTableIndex; 2977 unsigned short StandTableIndex, RefreshRateTableIndex;
3248 2978
3249 SiS_Pr->SiS_CRT1Mode = ModeNo; 2979 SiS_Pr->SiS_CRT1Mode = ModeNo;
3250 StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex); 2980
3251 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 2981 StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
3252 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) { 2982
3253 SiS_DisableBridge(SiS_Pr, HwInfo); 2983 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
3254 } 2984 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
3255 } 2985 SiS_DisableBridge(SiS_Pr);
3256 2986 }
3257 SiS_ResetSegmentRegisters(SiS_Pr, HwInfo); 2987 }
3258 2988
3259 SiS_SetSeqRegs(SiS_Pr, StandTableIndex, HwInfo); 2989 SiS_ResetSegmentRegisters(SiS_Pr);
3260 SiS_SetMiscRegs(SiS_Pr, StandTableIndex, HwInfo); 2990
3261 SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex); 2991 SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
3262 SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo); 2992 SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
3263 SiS_SetGRCRegs(SiS_Pr, StandTableIndex); 2993 SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
3264 SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo); 2994 SiS_SetATTRegs(SiS_Pr, StandTableIndex);
3265 SiS_ResetCRT1VCLK(SiS_Pr, HwInfo); 2995 SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
3266 2996 SiS_ClearExt1Regs(SiS_Pr, ModeNo);
3267 SiS_Pr->SiS_SelectCRT2Rate = 0; 2997 SiS_ResetCRT1VCLK(SiS_Pr);
3268 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 2998
3269 2999 SiS_Pr->SiS_SelectCRT2Rate = 0;
3270#ifdef LINUX_XF86 3000 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
3271 xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n", 3001
3002#ifdef SIS_XORG_XF86
3003 xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
3272 SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo); 3004 SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
3273#endif 3005#endif
3274 3006
3275 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { 3007 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
3276 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3008 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3277 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 3009 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3278 } 3010 }
3279 } 3011 }
3280 3012
3281 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3282 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 3014 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
3283 } 3015 }
3284 3016
3285 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3017 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
3286 3018
3287 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3019 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3288 SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2; 3020 SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
3289 } 3021 }
3290 3022
3291 if(RefreshRateTableIndex != 0xFFFF) { 3023 if(RefreshRateTableIndex != 0xFFFF) {
3292 SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex); 3024 SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
3293 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3025 SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3294 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3026 SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3295 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 3027 SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3296 } 3028 }
3297 3029
3030 switch(SiS_Pr->ChipType) {
3298#ifdef SIS300 3031#ifdef SIS300
3299 if(HwInfo->jChipType == SIS_300) { 3032 case SIS_300:
3300 SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo,HwInfo,RefreshRateTableIndex); 3033 SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
3301 } else if((HwInfo->jChipType == SIS_630) || 3034 break;
3302 (HwInfo->jChipType == SIS_730) || 3035 case SIS_540:
3303 (HwInfo->jChipType == SIS_540)) { 3036 case SIS_630:
3304 SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, HwInfo, RefreshRateTableIndex); 3037 case SIS_730:
3305 } 3038 SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
3039 break;
3306#endif 3040#endif
3041 default:
3307#ifdef SIS315H 3042#ifdef SIS315H
3308 if(HwInfo->jChipType >= SIS_315H) { 3043 if(SiS_Pr->ChipType == XGI_20) {
3309 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3044 unsigned char sr2b = 0, sr2c = 0;
3310 } 3045 switch(ModeNo) {
3046 case 0x00:
3047 case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
3048 case 0x04:
3049 case 0x05:
3050 case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
3051 }
3052 if(sr2b) {
3053 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
3054 SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
3055 SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
3056 }
3057 }
3058 SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
3311#endif 3059#endif
3060 break;
3061 }
3062
3063 SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3312 3064
3313 SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3065#ifdef SIS315H
3066 if(SiS_Pr->ChipType == XGI_40) {
3067 SiS_SetupDualChip(SiS_Pr);
3068 }
3069#endif
3314 3070
3315 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 3071 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
3316 3072
3317#ifdef LINUX_KERNEL 3073#ifdef SIS_LINUX_KERNEL
3318 if(SiS_Pr->SiS_flag_clearbuffer) { 3074 if(SiS_Pr->SiS_flag_clearbuffer) {
3319 SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo); 3075 SiS_ClearBuffer(SiS_Pr, ModeNo);
3320 } 3076 }
3321#endif 3077#endif
3322 3078
3323 if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { 3079 if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
3324 SiS_WaitRetrace1(SiS_Pr); 3080 SiS_WaitRetrace1(SiS_Pr);
3325 SiS_DisplayOn(SiS_Pr); 3081 SiS_DisplayOn(SiS_Pr);
3326 } 3082 }
3327} 3083}
3328 3084
3329/*********************************************/ 3085/*********************************************/
@@ -3331,33 +3087,62 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
3331/*********************************************/ 3087/*********************************************/
3332 3088
3333static void 3089static void
3334SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 3090SiS_InitVB(struct SiS_Private *SiS_Pr)
3091{
3092 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3093
3094 SiS_Pr->Init_P4_0E = 0;
3095 if(SiS_Pr->SiS_ROMNew) {
3096 SiS_Pr->Init_P4_0E = ROMAddr[0x82];
3097 } else if(SiS_Pr->ChipType >= XGI_40) {
3098 if(SiS_Pr->SiS_XGIROM) {
3099 SiS_Pr->Init_P4_0E = ROMAddr[0x80];
3100 }
3101 }
3102}
3103
3104static void
3105SiS_ResetVB(struct SiS_Private *SiS_Pr)
3335{ 3106{
3336 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 3107#ifdef SIS315H
3337 USHORT temp; 3108 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3109 unsigned short temp;
3338 3110
3339 /* VB programming clock */ 3111 /* VB programming clock */
3340 if(SiS_Pr->SiS_UseROM) { 3112 if(SiS_Pr->SiS_UseROM) {
3341 if(HwInfo->jChipType < SIS_330) { 3113 if(SiS_Pr->ChipType < SIS_330) {
3342 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40; 3114 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
3343 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 3115 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 3116 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3345 } else if(HwInfo->jChipType >= SIS_661) { 3117 } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
3346 temp = ROMAddr[0x7e] | 0x40; 3118 temp = ROMAddr[0x7e] | 0x40;
3347 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 3119 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
3348 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 3120 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3349 } 3121 }
3122 } else if(SiS_Pr->ChipType >= XGI_40) {
3123 temp = 0x40;
3124 if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
3125 /* Can we do this on any chipset? */
3126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
3350 } 3127 }
3128#endif
3351} 3129}
3352 3130
3353/*********************************************/ 3131/*********************************************/
3354/* HELPER: SET VIDEO REGISTERS */ 3132/* HELPER: SET VIDEO/CAPTURE REGISTERS */
3355/*********************************************/ 3133/*********************************************/
3356 3134
3357static void 3135static void
3358SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 3136SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
3359{ 3137{
3360 if((IS_SIS651) || (IS_SISM650)) { 3138 /* SiS65x and XGI set up some sort of "lock mode" for text
3139 * which locks CRT2 in some way to CRT1 timing. Disable
3140 * this here.
3141 */
3142#ifdef SIS315H
3143 if((IS_SIS651) || (IS_SISM650) ||
3144 SiS_Pr->ChipType == SIS_340 ||
3145 SiS_Pr->ChipType == XGI_40) {
3361 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */ 3146 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */
3362 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00); 3147 SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
3363 SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */ 3148 SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */
@@ -3365,49 +3150,99 @@ SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3365 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef); 3150 SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
3366 } 3151 }
3367 /* !!! This does not support modes < 0x13 !!! */ 3152 /* !!! This does not support modes < 0x13 !!! */
3153#endif
3368} 3154}
3369 3155
3370/*********************************************/ 3156/*********************************************/
3371/* XFree86: SET SCREEN PITCH */ 3157/* HELPER: SET AGP TIMING FOR SiS760 */
3372/*********************************************/ 3158/*********************************************/
3373 3159
3374#ifdef LINUX_XF86
3375static void 3160static void
3376SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 3161SiS_Handle760(struct SiS_Private *SiS_Pr)
3162{
3163#ifdef SIS315H
3164 unsigned int somebase;
3165 unsigned char temp1, temp2, temp3;
3166
3167 if( (SiS_Pr->ChipType != SIS_760) ||
3168 ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
3169 (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) ||
3170 (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
3171 return;
3172
3173#ifdef SIS_LINUX_KERNEL
3174 somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
3175#else
3176 somebase = pciReadWord(0x00001000, 0x74);
3177#endif
3178 somebase &= 0xffff;
3179
3180 if(somebase == 0) return;
3181
3182 temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
3183
3184 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
3185 temp1 = 0x21;
3186 temp2 = 0x03;
3187 temp3 |= 0x08;
3188 } else {
3189 temp1 = 0x25;
3190 temp2 = 0x0b;
3191 }
3192
3193#ifdef SIS_LINUX_KERNEL
3194 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
3195 sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
3196#else
3197 pciWriteByte(0x00000000, 0x7e, temp1);
3198 pciWriteByte(0x00000000, 0x8d, temp2);
3199#endif
3200
3201 SiS_SetRegByte((somebase + 0x85), temp3);
3202#endif
3203}
3204
3205/*********************************************/
3206/* X.org/XFree86: SET SCREEN PITCH */
3207/*********************************************/
3208
3209#ifdef SIS_XORG_XF86
3210static void
3211SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3377{ 3212{
3378 SISPtr pSiS = SISPTR(pScrn); 3213 SISPtr pSiS = SISPTR(pScrn);
3379 UShort HDisplay = pSiS->scrnPitch >> 3; 3214 unsigned short HDisplay = pSiS->scrnPitch >> 3;
3380 3215
3381 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF)); 3216 SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
3382 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay>>8)); 3217 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
3383} 3218}
3384 3219
3385static void 3220static void
3386SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 3221SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3387{ 3222{
3388 SISPtr pSiS = SISPTR(pScrn); 3223 SISPtr pSiS = SISPTR(pScrn);
3389 UShort HDisplay = pSiS->scrnPitch2 >> 3; 3224 unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
3390 3225
3391 /* Unlock CRT2 */ 3226 /* Unlock CRT2 */
3392 if(pSiS->VGAEngine == SIS_315_VGA) 3227 if(pSiS->VGAEngine == SIS_315_VGA)
3393 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01); 3228 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
3394 else 3229 else
3395 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01); 3230 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
3396 3231
3397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF)); 3232 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
3398 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8)); 3233 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
3399} 3234}
3400 3235
3401static void 3236static void
3402SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 3237SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3403{ 3238{
3404 SISPtr pSiS = SISPTR(pScrn); 3239 SISPtr pSiS = SISPTR(pScrn);
3405 BOOLEAN isslavemode = FALSE; 3240 BOOLEAN isslavemode = FALSE;
3406 3241
3407 if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && 3242 if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
3408 ( ((pSiS->VGAEngine == SIS_300_VGA) && 3243 ( ((pSiS->VGAEngine == SIS_300_VGA) &&
3409 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || 3244 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
3410 ((pSiS->VGAEngine == SIS_315_VGA) && 3245 ((pSiS->VGAEngine == SIS_315_VGA) &&
3411 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) { 3246 (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
3412 isslavemode = TRUE; 3247 isslavemode = TRUE;
3413 } 3248 }
@@ -3427,59 +3262,59 @@ SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
3427/* SiSSetMode() */ 3262/* SiSSetMode() */
3428/*********************************************/ 3263/*********************************************/
3429 3264
3430#ifdef LINUX_XF86 3265#ifdef SIS_XORG_XF86
3431/* We need pScrn for setting the pitch correctly */ 3266/* We need pScrn for setting the pitch correctly */
3432BOOLEAN 3267BOOLEAN
3433SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch) 3268SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, BOOLEAN dosetpitch)
3434#else 3269#else
3435BOOLEAN 3270BOOLEAN
3436SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo) 3271SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
3437#endif 3272#endif
3438{ 3273{
3439 USHORT ModeIdIndex; 3274 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3440 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress; 3275 unsigned short RealModeNo, ModeIdIndex;
3441 unsigned char backupreg=0; 3276 unsigned char backupreg = 0;
3442#ifdef LINUX_KERNEL 3277#ifdef SIS_LINUX_KERNEL
3443 USHORT KeepLockReg; 3278 unsigned short KeepLockReg;
3444 ULONG temp;
3445 3279
3446 SiS_Pr->UseCustomMode = FALSE; 3280 SiS_Pr->UseCustomMode = FALSE;
3447 SiS_Pr->CRT1UsesCustomMode = FALSE; 3281 SiS_Pr->CRT1UsesCustomMode = FALSE;
3448#endif 3282#endif
3449 3283
3284 SiS_Pr->SiS_flag_clearbuffer = 0;
3285
3450 if(SiS_Pr->UseCustomMode) { 3286 if(SiS_Pr->UseCustomMode) {
3451 ModeNo = 0xfe; 3287 ModeNo = 0xfe;
3288 } else {
3289#ifdef SIS_LINUX_KERNEL
3290 if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
3291#endif
3292 ModeNo &= 0x7f;
3452 } 3293 }
3453 3294
3454 SiSInitPtr(SiS_Pr, HwInfo); 3295 /* Don't use FSTN mode for CRT1 */
3296 RealModeNo = ModeNo;
3297 if(ModeNo == 0x5b) ModeNo = 0x56;
3298
3299 SiSInitPtr(SiS_Pr);
3455 SiSRegInit(SiS_Pr, BaseAddr); 3300 SiSRegInit(SiS_Pr, BaseAddr);
3456 SiS_GetSysFlags(SiS_Pr, HwInfo); 3301 SiS_GetSysFlags(SiS_Pr);
3457 3302
3458#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__)) 3303 SiS_Pr->SiS_VGAINFO = 0x11;
3304#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
3459 if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 3305 if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3460 else
3461#endif
3462 SiS_Pr->SiS_VGAINFO = 0x11;
3463
3464 SiSInitPCIetc(SiS_Pr, HwInfo);
3465 SiSSetLVDSetc(SiS_Pr, HwInfo);
3466 SiSDetermineROMUsage(SiS_Pr, HwInfo);
3467
3468 SiS_Pr->SiS_flag_clearbuffer = 0;
3469
3470 if(!SiS_Pr->UseCustomMode) {
3471#ifdef LINUX_KERNEL
3472 if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
3473#endif 3306#endif
3474 ModeNo &= 0x7f;
3475 }
3476 3307
3477#ifdef LINUX_KERNEL 3308#ifdef SIS_LINUX_KERNEL
3478 KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); 3309 KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
3479#endif 3310#endif
3480 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 3311 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3481 3312
3482 SiS_UnLockCRT2(SiS_Pr, HwInfo); 3313 SiSInitPCIetc(SiS_Pr);
3314 SiSSetLVDSetc(SiS_Pr);
3315 SiSDetermineROMUsage(SiS_Pr);
3316
3317 SiS_UnLockCRT2(SiS_Pr);
3483 3318
3484 if(!SiS_Pr->UseCustomMode) { 3319 if(!SiS_Pr->UseCustomMode) {
3485 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 3320 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3487,13 +3322,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3487 ModeIdIndex = 0; 3322 ModeIdIndex = 0;
3488 } 3323 }
3489 3324
3490 SiS_GetVBType(SiS_Pr, HwInfo); 3325 SiS_GetVBType(SiS_Pr);
3491 3326
3492 /* Init/restore some VB registers */ 3327 /* Init/restore some VB registers */
3493 3328 SiS_InitVB(SiS_Pr);
3494 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3329 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3495 if(HwInfo->jChipType >= SIS_315H) { 3330 if(SiS_Pr->ChipType >= SIS_315H) {
3496 SiS_ResetVB(SiS_Pr, HwInfo); 3331 SiS_ResetVB(SiS_Pr);
3497 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); 3332 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3498 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); 3333 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3499 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 3334 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -3503,21 +3338,20 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3503 } 3338 }
3504 3339
3505 /* Get VB information (connectors, connected devices) */ 3340 /* Get VB information (connectors, connected devices) */
3506 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1); 3341 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
3507 SiS_SetYPbPr(SiS_Pr, HwInfo); 3342 SiS_SetYPbPr(SiS_Pr);
3508 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3343 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3509 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3344 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3510 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo); 3345 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3511 3346
3512#ifdef LINUX_KERNEL 3347#ifdef SIS_LINUX_KERNEL
3513 /* 3. Check memory size (Kernel framebuffer driver only) */ 3348 /* Check memory size (kernel framebuffer driver only) */
3514 temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 3349 if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
3515 if(!temp) return(0); 3350 return FALSE;
3351 }
3516#endif 3352#endif
3517 3353
3518 if(HwInfo->jChipType >= SIS_315H) { 3354 SiS_OpenCRTC(SiS_Pr);
3519 SiS_SetupCR5x(SiS_Pr, HwInfo);
3520 }
3521 3355
3522 if(SiS_Pr->UseCustomMode) { 3356 if(SiS_Pr->UseCustomMode) {
3523 SiS_Pr->CRT1UsesCustomMode = TRUE; 3357 SiS_Pr->CRT1UsesCustomMode = TRUE;
@@ -3530,38 +3364,41 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3530 /* Set mode on CRT1 */ 3364 /* Set mode on CRT1 */
3531 if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) || 3365 if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
3532 (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) { 3366 (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
3533 SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 3367 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
3534 } 3368 }
3535 3369
3536 /* Set mode on CRT2 */ 3370 /* Set mode on CRT2 */
3537 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) { 3371 if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
3538 if( (SiS_Pr->SiS_VBType & VB_SISVB) || 3372 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3539 (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 3373 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3540 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || 3374 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3541 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { 3375 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3542 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo); 3376 SiS_SetCRT2Group(SiS_Pr, RealModeNo);
3543 } 3377 }
3544 } 3378 }
3545 3379
3546 SiS_HandleCRT1(SiS_Pr); 3380 SiS_HandleCRT1(SiS_Pr);
3547 3381
3548 SiS_StrangeStuff(SiS_Pr, HwInfo); 3382 SiS_StrangeStuff(SiS_Pr);
3549 3383
3550 SiS_DisplayOn(SiS_Pr); 3384 SiS_DisplayOn(SiS_Pr);
3551 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 3385 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3552 3386
3553 if(HwInfo->jChipType >= SIS_315H) { 3387#ifdef SIS315H
3388 if(SiS_Pr->ChipType >= SIS_315H) {
3554 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 3389 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3555 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) { 3390 if(!(SiS_IsDualEdge(SiS_Pr))) {
3556 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3391 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3557 } 3392 }
3558 } 3393 }
3559 } 3394 }
3395#endif
3560 3396
3561 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3397 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3562 if(HwInfo->jChipType >= SIS_315H) { 3398 if(SiS_Pr->ChipType >= SIS_315H) {
3563 if(!SiS_Pr->SiS_ROMNew) { 3399#ifdef SIS315H
3564 if(SiS_IsVAMode(SiS_Pr,HwInfo)) { 3400 if(!SiS_Pr->SiS_ROMNew) {
3401 if(SiS_IsVAMode(SiS_Pr)) {
3565 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 3402 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3566 } else { 3403 } else {
3567 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); 3404 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3574,23 +3411,24 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3574 if((ModeNo == 0x03) || (ModeNo == 0x10)) { 3411 if((ModeNo == 0x03) || (ModeNo == 0x10)) {
3575 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); 3412 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
3576 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); 3413 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
3577 } 3414 }
3578 } 3415 }
3579 3416
3580 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { 3417 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3581 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 3418 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3582 } 3419 }
3583 } else if((HwInfo->jChipType == SIS_630) || 3420#endif
3584 (HwInfo->jChipType == SIS_730)) { 3421 } else if((SiS_Pr->ChipType == SIS_630) ||
3585 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 3422 (SiS_Pr->ChipType == SIS_730)) {
3423 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3586 } 3424 }
3587 } 3425 }
3588 3426
3589#ifdef LINUX_XF86 3427#ifdef SIS_XORG_XF86
3590 if(pScrn) { 3428 if(pScrn) {
3591 /* SetPitch: Adapt to virtual size & position */ 3429 /* SetPitch: Adapt to virtual size & position */
3592 if((ModeNo > 0x13) && (dosetpitch)) { 3430 if((ModeNo > 0x13) && (dosetpitch)) {
3593 SiS_SetPitch(SiS_Pr, pScrn); 3431 SiS_SetPitch(SiS_Pr, pScrn);
3594 } 3432 }
3595 3433
3596 /* Backup/Set ModeNo in BIOS scratch area */ 3434 /* Backup/Set ModeNo in BIOS scratch area */
@@ -3598,33 +3436,37 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
3598 } 3436 }
3599#endif 3437#endif
3600 3438
3601#ifdef LINUX_KERNEL /* We never lock registers in XF86 */ 3439 SiS_CloseCRTC(SiS_Pr);
3602 if(KeepLockReg == 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 3440
3603 else SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); 3441 SiS_Handle760(SiS_Pr);
3442
3443#ifdef SIS_LINUX_KERNEL
3444 /* We never lock registers in XF86 */
3445 if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
3604#endif 3446#endif
3605 3447
3606 return TRUE; 3448 return TRUE;
3607} 3449}
3608 3450
3609/*********************************************/ 3451/*********************************************/
3610/* XFree86: SiSBIOSSetMode() */ 3452/* X.org/XFree86: SiSBIOSSetMode() */
3611/* for non-Dual-Head mode */ 3453/* for non-Dual-Head mode */
3612/*********************************************/ 3454/*********************************************/
3613 3455
3614#ifdef LINUX_XF86 3456#ifdef SIS_XORG_XF86
3615BOOLEAN 3457BOOLEAN
3616SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, 3458SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3617 DisplayModePtr mode, BOOLEAN IsCustom) 3459 DisplayModePtr mode, BOOLEAN IsCustom)
3618{ 3460{
3619 SISPtr pSiS = SISPTR(pScrn); 3461 SISPtr pSiS = SISPTR(pScrn);
3620 UShort ModeNo = 0; 3462 unsigned short ModeNo = 0;
3621 3463
3622 SiS_Pr->UseCustomMode = FALSE; 3464 SiS_Pr->UseCustomMode = FALSE;
3623 3465
3624 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { 3466 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3625 3467
3626 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 3468 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
3627 SiS_Pr->CHDisplay, 3469 SiS_Pr->CHDisplay,
3628 (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : 3470 (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
3629 (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : 3471 (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
3630 SiS_Pr->CVDisplay))); 3472 SiS_Pr->CVDisplay)));
@@ -3632,32 +3474,33 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3632 } else { 3474 } else {
3633 3475
3634 /* Don't need vbflags here; checks done earlier */ 3476 /* Don't need vbflags here; checks done earlier */
3635 ModeNo = SiS_GetModeNumber(pScrn, mode, 0); 3477 ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
3636 if(!ModeNo) return FALSE; 3478 if(!ModeNo) return FALSE;
3637 3479
3638 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); 3480 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
3639 3481
3640 } 3482 }
3641 3483
3642 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE)); 3484 return(SiSSetMode(SiS_Pr, pScrn, ModeNo, TRUE));
3643} 3485}
3644 3486
3645/*********************************************/ 3487/*********************************************/
3646/* XFree86: SiSBIOSSetModeCRT2() */ 3488/* X.org/XFree86: SiSBIOSSetModeCRT2() */
3647/* for Dual-Head modes */ 3489/* for Dual-Head modes */
3648/*********************************************/ 3490/*********************************************/
3491
3649BOOLEAN 3492BOOLEAN
3650SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, 3493SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3651 DisplayModePtr mode, BOOLEAN IsCustom) 3494 DisplayModePtr mode, BOOLEAN IsCustom)
3652{ 3495{
3653 USHORT ModeIdIndex; 3496 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3654 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress; 3497 SISPtr pSiS = SISPTR(pScrn);
3655 UShort ModeNo = 0;
3656 unsigned char backupreg=0;
3657 SISPtr pSiS = SISPTR(pScrn);
3658#ifdef SISDUALHEAD 3498#ifdef SISDUALHEAD
3659 SISEntPtr pSiSEnt = pSiS->entityPrivate; 3499 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3660#endif 3500#endif
3501 unsigned short ModeIdIndex;
3502 unsigned short ModeNo = 0;
3503 unsigned char backupreg = 0;
3661 3504
3662 SiS_Pr->UseCustomMode = FALSE; 3505 SiS_Pr->UseCustomMode = FALSE;
3663 3506
@@ -3672,22 +3515,25 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3672 3515
3673 } else { 3516 } else {
3674 3517
3675 ModeNo = SiS_GetModeNumber(pScrn, mode, 0); 3518 ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
3676 if(!ModeNo) return FALSE; 3519 if(!ModeNo) return FALSE;
3677 3520
3678 } 3521 }
3679 3522
3680 SiSRegInit(SiS_Pr, BaseAddr); 3523 SiSRegInit(SiS_Pr, BaseAddr);
3681 SiSInitPtr(SiS_Pr, HwInfo); 3524 SiSInitPtr(SiS_Pr);
3682 SiS_GetSysFlags(SiS_Pr, HwInfo); 3525 SiS_GetSysFlags(SiS_Pr);
3683#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__)) 3526#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
3684 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 3527 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3685#else 3528#else
3686 SiS_Pr->SiS_VGAINFO = 0x11; 3529 SiS_Pr->SiS_VGAINFO = 0x11;
3687#endif 3530#endif
3688 SiSInitPCIetc(SiS_Pr, HwInfo); 3531
3689 SiSSetLVDSetc(SiS_Pr, HwInfo); 3532 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3690 SiSDetermineROMUsage(SiS_Pr, HwInfo); 3533
3534 SiSInitPCIetc(SiS_Pr);
3535 SiSSetLVDSetc(SiS_Pr);
3536 SiSDetermineROMUsage(SiS_Pr);
3691 3537
3692 /* Save mode info so we can set it from within SetMode for CRT1 */ 3538 /* Save mode info so we can set it from within SetMode for CRT1 */
3693#ifdef SISDUALHEAD 3539#ifdef SISDUALHEAD
@@ -3700,23 +3546,20 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3700 pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 3546 pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3701 pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 3547 pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3702#if 0 3548#if 0
3703 /* We can't set CRT2 mode before CRT1 mode is set */ 3549 /* We can't set CRT2 mode before CRT1 mode is set - says who...? */
3704 if(pSiSEnt->CRT1ModeNo == -1) { 3550 if(pSiSEnt->CRT1ModeNo == -1) {
3705 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 3551 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3706 "Setting CRT2 mode delayed until after setting CRT1 mode\n"); 3552 "Setting CRT2 mode delayed until after setting CRT1 mode\n");
3707 return TRUE; 3553 return TRUE;
3708 } 3554 }
3709#endif 3555#endif
3710 pSiSEnt->CRT2ModeSet = TRUE; 3556 pSiSEnt->CRT2ModeSet = TRUE;
3711 } 3557 }
3712#endif 3558#endif
3713 3559
3714 /* We don't clear the buffer in X */
3715 SiS_Pr->SiS_flag_clearbuffer=0;
3716
3717 if(SiS_Pr->UseCustomMode) { 3560 if(SiS_Pr->UseCustomMode) {
3718 3561
3719 USHORT temptemp = SiS_Pr->CVDisplay; 3562 unsigned short temptemp = SiS_Pr->CVDisplay;
3720 3563
3721 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; 3564 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3722 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; 3565 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
@@ -3728,13 +3571,11 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3728 } else { 3571 } else {
3729 3572
3730 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 3573 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3731 "Setting standard mode 0x%x on CRT2\n", ModeNo); 3574 "Setting standard mode 0x%x on CRT2\n", ModeNo);
3732 3575
3733 } 3576 }
3734 3577
3735 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 3578 SiS_UnLockCRT2(SiS_Pr);
3736
3737 SiS_UnLockCRT2(SiS_Pr, HwInfo);
3738 3579
3739 if(!SiS_Pr->UseCustomMode) { 3580 if(!SiS_Pr->UseCustomMode) {
3740 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 3581 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3742,56 +3583,59 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3742 ModeIdIndex = 0; 3583 ModeIdIndex = 0;
3743 } 3584 }
3744 3585
3745 SiS_GetVBType(SiS_Pr, HwInfo); 3586 SiS_GetVBType(SiS_Pr);
3746 3587
3747 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3588 SiS_InitVB(SiS_Pr);
3748 if(HwInfo->jChipType >= SIS_315H) { 3589 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3749 SiS_ResetVB(SiS_Pr, HwInfo); 3590 if(SiS_Pr->ChipType >= SIS_315H) {
3591 SiS_ResetVB(SiS_Pr);
3750 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); 3592 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
3751 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); 3593 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
3752 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 3594 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3753 } else { 3595 } else {
3754 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 3596 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
3755 } 3597 }
3756 } 3598 }
3757 3599
3758 /* Get VB information (connectors, connected devices) */ 3600 /* Get VB information (connectors, connected devices) */
3759 if(!SiS_Pr->UseCustomMode) { 3601 if(!SiS_Pr->UseCustomMode) {
3760 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 1); 3602 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
3761 } else { 3603 } else {
3762 /* If this is a custom mode, we don't check the modeflag for CRT2Mode */ 3604 /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
3763 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0); 3605 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
3764 } 3606 }
3765 SiS_SetYPbPr(SiS_Pr, HwInfo); 3607 SiS_SetYPbPr(SiS_Pr);
3766 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3608 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3767 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3609 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3768 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo); 3610 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3611
3612 SiS_ResetSegmentRegisters(SiS_Pr);
3769 3613
3770 /* Set mode on CRT2 */ 3614 /* Set mode on CRT2 */
3771 if( (SiS_Pr->SiS_VBType & VB_SISVB) || 3615 if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
3772 (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 3616 (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
3773 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || 3617 (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
3774 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { 3618 (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
3775 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo); 3619 SiS_SetCRT2Group(SiS_Pr, ModeNo);
3776 } 3620 }
3777 3621
3778 SiS_StrangeStuff(SiS_Pr, HwInfo); 3622 SiS_StrangeStuff(SiS_Pr);
3779 3623
3780 SiS_DisplayOn(SiS_Pr); 3624 SiS_DisplayOn(SiS_Pr);
3781 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 3625 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3782 3626
3783 if(HwInfo->jChipType >= SIS_315H) { 3627 if(SiS_Pr->ChipType >= SIS_315H) {
3784 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 3628 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
3785 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) { 3629 if(!(SiS_IsDualEdge(SiS_Pr))) {
3786 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3630 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
3787 } 3631 }
3788 } 3632 }
3789 } 3633 }
3790 3634
3791 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3635 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3792 if(HwInfo->jChipType >= SIS_315H) { 3636 if(SiS_Pr->ChipType >= SIS_315H) {
3793 if(!SiS_Pr->SiS_ROMNew) { 3637 if(!SiS_Pr->SiS_ROMNew) {
3794 if(SiS_IsVAMode(SiS_Pr,HwInfo)) { 3638 if(SiS_IsVAMode(SiS_Pr)) {
3795 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 3639 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
3796 } else { 3640 } else {
3797 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); 3641 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3803,8 +3647,8 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3803 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { 3647 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
3804 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 3648 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
3805 } 3649 }
3806 } else if((HwInfo->jChipType == SIS_630) || 3650 } else if((SiS_Pr->ChipType == SIS_630) ||
3807 (HwInfo->jChipType == SIS_730)) { 3651 (SiS_Pr->ChipType == SIS_730)) {
3808 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 3652 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3809 } 3653 }
3810 } 3654 }
@@ -3812,25 +3656,27 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3812 /* SetPitch: Adapt to virtual size & position */ 3656 /* SetPitch: Adapt to virtual size & position */
3813 SiS_SetPitchCRT2(SiS_Pr, pScrn); 3657 SiS_SetPitchCRT2(SiS_Pr, pScrn);
3814 3658
3659 SiS_Handle760(SiS_Pr);
3660
3815 return TRUE; 3661 return TRUE;
3816} 3662}
3817 3663
3818/*********************************************/ 3664/*********************************************/
3819/* XFree86: SiSBIOSSetModeCRT1() */ 3665/* X.org/XFree86: SiSBIOSSetModeCRT1() */
3820/* for Dual-Head modes */ 3666/* for Dual-Head modes */
3821/*********************************************/ 3667/*********************************************/
3822 3668
3823BOOLEAN 3669BOOLEAN
3824SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, 3670SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
3825 DisplayModePtr mode, BOOLEAN IsCustom) 3671 DisplayModePtr mode, BOOLEAN IsCustom)
3826{ 3672{
3673 SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
3827 SISPtr pSiS = SISPTR(pScrn); 3674 SISPtr pSiS = SISPTR(pScrn);
3828 SISIOADDRESS BaseAddr = HwInfo->ulIOAddress; 3675 unsigned short ModeIdIndex, ModeNo = 0;
3829 USHORT ModeIdIndex, ModeNo=0; 3676 unsigned char backupreg = 0;
3830 UCHAR backupreg=0;
3831#ifdef SISDUALHEAD 3677#ifdef SISDUALHEAD
3832 SISEntPtr pSiSEnt = pSiS->entityPrivate; 3678 SISEntPtr pSiSEnt = pSiS->entityPrivate;
3833 UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0; 3679 unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
3834 BOOLEAN backupcustom; 3680 BOOLEAN backupcustom;
3835#endif 3681#endif
3836 3682
@@ -3838,43 +3684,41 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3838 3684
3839 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { 3685 if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
3840 3686
3841 USHORT temptemp = SiS_Pr->CVDisplay; 3687 unsigned short temptemp = SiS_Pr->CVDisplay;
3842 3688
3843 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; 3689 if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
3844 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; 3690 else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
3845 3691
3846 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 3692 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3847 "Setting custom mode %dx%d on CRT1\n", 3693 "Setting custom mode %dx%d on CRT1\n",
3848 SiS_Pr->CHDisplay, temptemp); 3694 SiS_Pr->CHDisplay, temptemp);
3849 ModeNo = 0xfe; 3695 ModeNo = 0xfe;
3850 3696
3851 } else { 3697 } else {
3852 3698
3853 ModeNo = SiS_GetModeNumber(pScrn, mode, 0); 3699 ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
3854 if(!ModeNo) return FALSE; 3700 if(!ModeNo) return FALSE;
3855 3701
3856 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 3702 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3857 "Setting standard mode 0x%x on CRT1\n", ModeNo); 3703 "Setting standard mode 0x%x on CRT1\n", ModeNo);
3858 } 3704 }
3859 3705
3860 SiSInitPtr(SiS_Pr, HwInfo); 3706 SiSInitPtr(SiS_Pr);
3861 SiSRegInit(SiS_Pr, BaseAddr); 3707 SiSRegInit(SiS_Pr, BaseAddr);
3862 SiS_GetSysFlags(SiS_Pr, HwInfo); 3708 SiS_GetSysFlags(SiS_Pr);
3863#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__)) 3709#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
3864 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 3710 SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
3865#else 3711#else
3866 SiS_Pr->SiS_VGAINFO = 0x11; 3712 SiS_Pr->SiS_VGAINFO = 0x11;
3867#endif 3713#endif
3868 SiSInitPCIetc(SiS_Pr, HwInfo);
3869 SiSSetLVDSetc(SiS_Pr, HwInfo);
3870 SiSDetermineROMUsage(SiS_Pr, HwInfo);
3871
3872 /* We don't clear the buffer in X */
3873 SiS_Pr->SiS_flag_clearbuffer = 0;
3874 3714
3875 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 3715 SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
3876 3716
3877 SiS_UnLockCRT2(SiS_Pr, HwInfo); 3717 SiSInitPCIetc(SiS_Pr);
3718 SiSSetLVDSetc(SiS_Pr);
3719 SiSDetermineROMUsage(SiS_Pr);
3720
3721 SiS_UnLockCRT2(SiS_Pr);
3878 3722
3879 if(!SiS_Pr->UseCustomMode) { 3723 if(!SiS_Pr->UseCustomMode) {
3880 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 3724 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3883,10 +3727,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3883 } 3727 }
3884 3728
3885 /* Determine VBType */ 3729 /* Determine VBType */
3886 SiS_GetVBType(SiS_Pr, HwInfo); 3730 SiS_GetVBType(SiS_Pr);
3887 3731
3888 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3732 SiS_InitVB(SiS_Pr);
3889 if(HwInfo->jChipType >= SIS_315H) { 3733 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3734 if(SiS_Pr->ChipType >= SIS_315H) {
3890 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 3735 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
3891 } else { 3736 } else {
3892 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 3737 backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
@@ -3895,25 +3740,29 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3895 3740
3896 /* Get VB information (connectors, connected devices) */ 3741 /* Get VB information (connectors, connected devices) */
3897 /* (We don't care if the current mode is a CRT2 mode) */ 3742 /* (We don't care if the current mode is a CRT2 mode) */
3898 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0); 3743 SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
3899 SiS_SetYPbPr(SiS_Pr, HwInfo); 3744 SiS_SetYPbPr(SiS_Pr);
3900 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3745 SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
3901 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3746 SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3902 SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo); 3747 SiS_SetLowModeTest(SiS_Pr, ModeNo);
3903 3748
3904 if(HwInfo->jChipType >= SIS_315H) { 3749 SiS_OpenCRTC(SiS_Pr);
3905 SiS_SetupCR5x(SiS_Pr, HwInfo);
3906 }
3907 3750
3908 /* Set mode on CRT1 */ 3751 /* Set mode on CRT1 */
3909 SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 3752 SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
3910 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3753 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3911 SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo); 3754 SiS_SetCRT2Group(SiS_Pr, ModeNo);
3912 } 3755 }
3913 3756
3914 /* SetPitch: Adapt to virtual size & position */ 3757 /* SetPitch: Adapt to virtual size & position */
3915 SiS_SetPitchCRT1(SiS_Pr, pScrn); 3758 SiS_SetPitchCRT1(SiS_Pr, pScrn);
3916 3759
3760 SiS_HandleCRT1(SiS_Pr);
3761
3762 SiS_StrangeStuff(SiS_Pr);
3763
3764 SiS_CloseCRTC(SiS_Pr);
3765
3917#ifdef SISDUALHEAD 3766#ifdef SISDUALHEAD
3918 if(pSiS->DualHeadMode) { 3767 if(pSiS->DualHeadMode) {
3919 pSiSEnt->CRT1ModeNo = ModeNo; 3768 pSiSEnt->CRT1ModeNo = ModeNo;
@@ -3933,7 +3782,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3933#ifdef SISDUALHEAD 3782#ifdef SISDUALHEAD
3934 if(pSiS->DualHeadMode) { 3783 if(pSiS->DualHeadMode) {
3935 if(pSiSEnt->CRT2ModeNo != -1) { 3784 if(pSiSEnt->CRT2ModeNo != -1) {
3936 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 3785 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
3937 "(Re-)Setting mode for CRT2\n"); 3786 "(Re-)Setting mode for CRT2\n");
3938 backupcustom = SiS_Pr->UseCustomMode; 3787 backupcustom = SiS_Pr->UseCustomMode;
3939 backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 3788 backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
@@ -3952,9 +3801,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3952 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35); 3801 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
3953 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38); 3802 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
3954 } 3803 }
3955 SiSBIOSSetModeCRT2(SiS_Pr, HwInfo, pSiSEnt->pScrn_1, 3804
3805 SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
3956 pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom); 3806 pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
3957 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30); 3807
3808 SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
3958 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31); 3809 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
3959 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35); 3810 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
3960 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38); 3811 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
@@ -3970,22 +3821,20 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3970 * possibly overwritten 3821 * possibly overwritten
3971 */ 3822 */
3972 3823
3973 SiS_HandleCRT1(SiS_Pr);
3974
3975 SiS_StrangeStuff(SiS_Pr, HwInfo);
3976
3977 SiS_DisplayOn(SiS_Pr); 3824 SiS_DisplayOn(SiS_Pr);
3978 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 3825 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
3979 3826
3980 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 3827 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
3981 if(HwInfo->jChipType >= SIS_315H) { 3828 if(SiS_Pr->ChipType >= SIS_315H) {
3982 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); 3829 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
3983 } else if((HwInfo->jChipType == SIS_630) || 3830 } else if((SiS_Pr->ChipType == SIS_630) ||
3984 (HwInfo->jChipType == SIS_730)) { 3831 (SiS_Pr->ChipType == SIS_730)) {
3985 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 3832 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
3986 } 3833 }
3987 } 3834 }
3988 3835
3836 SiS_Handle760(SiS_Pr);
3837
3989 /* Backup/Set ModeNo in BIOS scratch area */ 3838 /* Backup/Set ModeNo in BIOS scratch area */
3990 SiS_GetSetModeID(pScrn,ModeNo); 3839 SiS_GetSetModeID(pScrn,ModeNo);
3991 3840
@@ -3993,84 +3842,6 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
3993} 3842}
3994#endif /* Linux_XF86 */ 3843#endif /* Linux_XF86 */
3995 3844
3996
3997#ifdef LINUX_XF86
3998BOOLEAN
3999SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4000{
4001 const USHORT PanelTypeTable300[16] = {
4002 0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
4003 0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
4004 };
4005 const USHORT PanelTypeTable31030x[16] = {
4006 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
4007 0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4008 };
4009 const USHORT PanelTypeTable310LVDS[16] = {
4010 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
4011 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
4012 };
4013 USHORT tempax,tempbx,temp;
4014
4015 if(HwInfo->jChipType < SIS_315H) {
4016
4017 tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
4018 tempbx = tempax & 0x0F;
4019 if(!(tempax & 0x10)){
4020 if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
4021 tempbx = 0;
4022 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x38);
4023 if(temp & 0x40) tempbx |= 0x08;
4024 if(temp & 0x20) tempbx |= 0x02;
4025 if(temp & 0x01) tempbx |= 0x01;
4026 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x39);
4027 if(temp & 0x80) tempbx |= 0x04;
4028 } else {
4029 return 0;
4030 }
4031 }
4032 tempbx = PanelTypeTable300[tempbx];
4033 tempbx |= LCDSync;
4034 temp = tempbx & 0x00FF;
4035 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
4036 temp = (tempbx & 0xFF00) >> 8;
4037 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
4038
4039 } else {
4040
4041 if(HwInfo->jChipType >= SIS_661) return 0;
4042
4043 tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1a);
4044 tempax &= 0x1e;
4045 tempax >>= 1;
4046 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
4047 if(tempax == 0) {
4048 /* TODO: Include HUGE detection routine
4049 (Probably not worth bothering)
4050 */
4051 return 0;
4052 }
4053 temp = tempax & 0xff;
4054 tempax--;
4055 tempbx = PanelTypeTable310LVDS[tempax];
4056 } else {
4057 tempbx = PanelTypeTable31030x[tempax];
4058 temp = tempbx & 0xff;
4059 }
4060 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
4061 tempbx = (tempbx & 0xff00) >> 8;
4062 temp = tempbx & 0xc1;
4063 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
4064 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4065 temp = tempbx & 0x04;
4066 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
4067 }
4068
4069 }
4070 return 1;
4071}
4072#endif
4073
4074#ifndef GETBITSTR 3845#ifndef GETBITSTR
4075#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) 3846#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
4076#define GENMASK(mask) BITMASK(1?mask,0?mask) 3847#define GENMASK(mask) BITMASK(1?mask,0?mask)
@@ -4078,26 +3849,28 @@ SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4078#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) 3849#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
4079#endif 3850#endif
4080 3851
4081static void 3852void
4082SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth) 3853SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
4083{ 3854{
3855 int x = 1; /* Fix sync */
3856
4084 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */ 3857 SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
4085 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */ 3858 SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
4086 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */ 3859 SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
4087 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */ 3860 SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
4088 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */ 3861 SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
4089 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */ 3862 SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
4090 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F); 3863 (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
4091 3864
4092 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */ 3865 SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
4093 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */ 3866 SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
4094 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7) 3867 | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
4095 | ((SiS_Pr->CVSyncStart & 0x100) >> 6) 3868 | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
4096 | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5) 3869 | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
4097 | 0x10 3870 | 0x10
4098 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4) 3871 | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
4099 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3) 3872 | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
4100 | ((SiS_Pr->CVSyncStart & 0x200) >> 2); 3873 | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
4101 3874
4102 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */ 3875 SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
4103 3876
@@ -4106,55 +3879,44 @@ SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
4106 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40; 3879 else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
4107 } 3880 }
4108 3881
4109#if 0 3882 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF; /* CR10 */
4110 if (mode->VScan >= 32) 3883 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80; /* CR11 */
4111 regp->CRTC[9] |= 0x1F;
4112 else if (mode->VScan > 1)
4113 regp->CRTC[9] |= mode->VScan - 1;
4114#endif
4115
4116 SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart ) & 0xFF; /* CR10 */
4117 SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* CR11 */
4118 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */ 3884 SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
4119 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */ 3885 SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
4120 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */ 3886 SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
4121 3887
4122 SiS_Pr->CCRT1CRTC[13] = /* SRA */ 3888 SiS_Pr->CCRT1CRTC[13] = /* SRA */
4123 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) | 3889 GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
4124 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) | 3890 GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
4125 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) | 3891 GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
4126 GETBITSTR((SiS_Pr->CVSyncStart ), 10:10, 3:3) | 3892 GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
4127 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) | 3893 GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
4128 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ; 3894 GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
4129 3895
4130 SiS_Pr->CCRT1CRTC[14] = /* SRB */ 3896 SiS_Pr->CCRT1CRTC[14] = /* SRB */
4131 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) | 3897 GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
4132 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) | 3898 GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
4133 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) | 3899 GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
4134 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ; 3900 GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
4135 3901
4136 3902
4137 SiS_Pr->CCRT1CRTC[15] = /* SRC */ 3903 SiS_Pr->CCRT1CRTC[15] = /* SRC */
4138 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) | 3904 GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
4139 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; 3905 GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
4140} 3906}
4141 3907
4142void 3908void
4143SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex) 3909SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3910 unsigned short ModeIdIndex)
4144{ 3911{
4145 USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE; 3912 unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
4146 int i,j; 3913 unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
3914 int i, j;
4147 3915
4148 /* 1:1 data: use data set by setcrt1crtc() */ 3916 /* 1:1 data: use data set by setcrt1crtc() */
4149 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 3917 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
4150 3918
4151 if(ModeNo <= 0x13) { 3919 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
4152 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
4153 } else if(SiS_Pr->UseCustomMode) {
4154 modeflag = SiS_Pr->CModeFlag;
4155 } else {
4156 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4157 }
4158 3920
4159 if(modeflag & HalfDCLK) VGAHDE >>= 1; 3921 if(modeflag & HalfDCLK) VGAHDE >>= 1;
4160 3922
@@ -4164,32 +3926,91 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
4164 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE; 3926 SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
4165 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE; 3927 SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
4166 3928
4167 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes; 3929 if(SiS_Pr->ChipType < SIS_315H) {
4168 tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */ 3930#ifdef SIS300
4169 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3931 tempbx = SiS_Pr->SiS_VGAHT;
4170 tempax = SiS_Pr->PanelXRes; 3932 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3933 tempbx = SiS_Pr->PanelHT;
3934 }
3935 if(modeflag & HalfDCLK) tempbx >>= 1;
3936 remaining = tempbx % 8;
3937#endif
3938 } else {
3939#ifdef SIS315H
3940 /* OK for LCDA, LVDS */
3941 tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
3942 tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
3943 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3944 tempax = SiS_Pr->PanelXRes;
3945 }
3946 tempbx += tempax;
3947 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
3948#endif
4171 } 3949 }
4172 tempbx += tempax;
4173 if(modeflag & HalfDCLK) tempbx -= VGAHDE;
4174 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx; 3950 SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
4175 3951
4176 tempax = VGAHDE; 3952 if(SiS_Pr->ChipType < SIS_315H) {
4177 tempbx = SiS_Pr->CHTotal; 3953#ifdef SIS300
4178 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3954 if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
4179 tempbx = SiS_Pr->PanelXRes; 3955 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
4180 if(modeflag & HalfDCLK) tempbx >>= 1; 3956 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
4181 tempax += ((tempbx - tempax) >> 1); 3957 if(modeflag & HalfDCLK) {
3958 SiS_Pr->CHSyncStart >>= 1;
3959 SiS_Pr->CHSyncEnd >>= 1;
3960 }
3961 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3962 tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
3963 tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
3964 if(modeflag & HalfDCLK) {
3965 tempax >>= 1;
3966 tempbx >>= 1;
3967 }
3968 SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
3969 tempax = SiS_Pr->PanelHRE + 7;
3970 if(modeflag & HalfDCLK) tempax >>= 1;
3971 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
3972 } else {
3973 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
3974 if(modeflag & HalfDCLK) {
3975 SiS_Pr->CHSyncStart >>= 1;
3976 tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
3977 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
3978 } else {
3979 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
3980 SiS_Pr->CHSyncStart += 8;
3981 }
3982 }
3983#endif
3984 } else {
3985#ifdef SIS315H
3986 tempax = VGAHDE;
3987 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3988 tempbx = SiS_Pr->PanelXRes;
3989 if(modeflag & HalfDCLK) tempbx >>= 1;
3990 tempax += ((tempbx - tempax) >> 1);
3991 }
3992 tempax += SiS_Pr->PanelHRS;
3993 SiS_Pr->CHSyncStart = tempax;
3994 tempax += SiS_Pr->PanelHRE;
3995 SiS_Pr->CHSyncEnd = tempax;
3996#endif
4182 } 3997 }
4183 3998
4184 tempax += SiS_Pr->PanelHRS;
4185 SiS_Pr->CHSyncStart = tempax;
4186 tempax += SiS_Pr->PanelHRE;
4187 SiS_Pr->CHSyncEnd = tempax;
4188
4189 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes; 3999 tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
4190 tempax = SiS_Pr->SiS_VGAVDE; 4000 tempax = SiS_Pr->SiS_VGAVDE;
4191 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 4001 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
4192 tempax = SiS_Pr->PanelYRes; 4002 tempax = SiS_Pr->PanelYRes;
4003 } else if(SiS_Pr->ChipType < SIS_315H) {
4004#ifdef SIS300
4005 /* Stupid hack for 640x400/320x200 */
4006 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
4007 if((tempax + tempbx) == 438) tempbx += 16;
4008 } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
4009 (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
4010 tempax = 0;
4011 tempbx = SiS_Pr->SiS_VGAVT;
4012 }
4013#endif
4193 } 4014 }
4194 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax; 4015 SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
4195 4016
@@ -4201,22 +4022,28 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
4201 SiS_Pr->CVSyncStart = tempax; 4022 SiS_Pr->CVSyncStart = tempax;
4202 tempax += SiS_Pr->PanelVRE; 4023 tempax += SiS_Pr->PanelVRE;
4203 SiS_Pr->CVSyncEnd = tempax; 4024 SiS_Pr->CVSyncEnd = tempax;
4025 if(SiS_Pr->ChipType < SIS_315H) {
4026 SiS_Pr->CVSyncStart--;
4027 SiS_Pr->CVSyncEnd--;
4028 }
4204 4029
4205 SiS_CalcCRRegisters(SiS_Pr, 8); 4030 SiS_CalcCRRegisters(SiS_Pr, 8);
4031 SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
4032 SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
4206 SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 4033 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
4207 4034
4208 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 4035 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
4209 4036
4210 for(i=0,j=0;i<=7;i++,j++) { 4037 for(i = 0, j = 0; i <= 7; i++, j++) {
4211 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 4038 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4212 } 4039 }
4213 for(j=0x10;i<=10;i++,j++) { 4040 for(j = 0x10; i <= 10; i++, j++) {
4214 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 4041 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4215 } 4042 }
4216 for(j=0x15;i<=12;i++,j++) { 4043 for(j = 0x15; i <= 12; i++, j++) {
4217 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 4044 SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
4218 } 4045 }
4219 for(j=0x0A;i<=15;i++,j++) { 4046 for(j = 0x0A; i <= 15; i++, j++) {
4220 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]); 4047 SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
4221 } 4048 }
4222 4049
@@ -4227,1092 +4054,192 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
4227 if(modeflag & DoubleScanMode) tempax |= 0x80; 4054 if(modeflag & DoubleScanMode) tempax |= 0x80;
4228 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); 4055 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
4229 4056
4057#ifdef SIS_XORG_XF86
4230#ifdef TWDEBUG 4058#ifdef TWDEBUG
4231 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", 4059 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
4232 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, 4060 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
4233 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, 4061 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
4234 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); 4062 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
4235
4236 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 4063 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4237 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], 4064 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
4238 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], 4065 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
4239 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], 4066 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
4240 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); 4067 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
4241 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 4068 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4242 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], 4069 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
4243 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], 4070 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
4244 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], 4071 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
4245 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); 4072 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
4246 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); 4073 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
4247#endif 4074#endif
4075#endif
4248} 4076}
4249 4077
4250#ifdef LINUX_XF86
4251
4252void 4078void
4253SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c) 4079SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
4254{ 4080 int xres, int yres,
4255 int out_n, out_dn, out_div, out_sbit, out_scale; 4081#ifdef SIS_XORG_XF86
4256 unsigned int vclk[5]; 4082 DisplayModePtr current
4257
4258#define Midx 0
4259#define Nidx 1
4260#define VLDidx 2
4261#define Pidx 3
4262#define PSNidx 4
4263
4264 if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
4265 (*p2b) = (out_div == 2) ? 0x80 : 0x00;
4266 (*p2b) |= ((out_n - 1) & 0x7f);
4267 (*p2c) = (out_dn - 1) & 0x1f;
4268 (*p2c) |= (((out_scale - 1) & 3) << 5);
4269 (*p2c) |= ((out_sbit & 0x01) << 7);
4270#ifdef TWDEBUG
4271 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
4272 clock, out_n, out_dn, out_div, out_sbit, out_scale);
4273#endif 4083#endif
4274 } else { 4084#ifdef SIS_LINUX_KERNEL
4275 SiSCalcClock(pScrn, clock, 2, vclk); 4085 struct fb_var_screeninfo *var, BOOLEAN writeres
4276 (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
4277 (*p2b) |= (vclk[Midx] - 1) & 0x7f;
4278 (*p2c) = (vclk[Nidx] - 1) & 0x1f;
4279 if(vclk[Pidx] <= 4) {
4280 /* postscale 1,2,3,4 */
4281 (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
4282 } else {
4283 /* postscale 6,8 */
4284 (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
4285 (*p2c) |= 0x80;
4286 }
4287#ifdef TWDEBUG
4288 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
4289 clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
4290#endif 4086#endif
4291 } 4087)
4292}
4293
4294#endif
4295
4296/* ================ XFREE86/X.ORG ================= */
4297
4298/* Helper functions */
4299
4300#ifdef LINUX_XF86
4301
4302USHORT
4303SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
4304{ 4088{
4305 SISPtr pSiS = SISPTR(pScrn); 4089 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
4306 int depth = pSiS->CurrentLayout.bitsPerPixel; 4090 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
4307 4091 unsigned char sr_data, cr_data, cr_data2;
4308 pSiS->SiS_Pr->CModeFlag = 0; 4092 int A, B, C, D, E, F, temp;
4309
4310 pSiS->SiS_Pr->CDClock = mode->Clock;
4311
4312 pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
4313 pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
4314 pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
4315 pSiS->SiS_Pr->CHTotal = mode->HTotal;
4316
4317 pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
4318 pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
4319 pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
4320 pSiS->SiS_Pr->CVTotal = mode->VTotal;
4321
4322 pSiS->SiS_Pr->CFlags = mode->Flags;
4323
4324 if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
4325 pSiS->SiS_Pr->CVDisplay >>= 1;
4326 pSiS->SiS_Pr->CVSyncStart >>= 1;
4327 pSiS->SiS_Pr->CVSyncEnd >>= 1;
4328 pSiS->SiS_Pr->CVTotal >>= 1;
4329 }
4330 if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
4331 /* pSiS->SiS_Pr->CDClock <<= 1; */
4332 pSiS->SiS_Pr->CVDisplay <<= 1;
4333 pSiS->SiS_Pr->CVSyncStart <<= 1;
4334 pSiS->SiS_Pr->CVSyncEnd <<= 1;
4335 pSiS->SiS_Pr->CVTotal <<= 1;
4336 }
4337
4338 pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
4339 pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
4340 pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
4341 pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
4342 4093
4343 SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C); 4094 sr_data = crdata[14];
4344 4095
4345 pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1; 4096 /* Horizontal total */
4097 HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
4098 A = HT + 5;
4346 4099
4347 SiS_CalcCRRegisters(pSiS->SiS_Pr, depth); 4100 /* Horizontal display enable end */
4101 HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
4102 E = HDE + 1;
4348 4103
4349 switch(depth) { 4104 /* Horizontal retrace (=sync) start */
4350 case 8: pSiS->SiS_Pr->CModeFlag |= 0x223b; break; 4105 HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
4351 case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break; 4106 F = HRS - E - 3;
4352 case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
4353 default: return 0;
4354 }
4355 4107
4356 if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) 4108 /* Horizontal blank start */
4357 pSiS->SiS_Pr->CModeFlag |= DoubleScanMode; 4109 HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
4358 4110
4359 if((pSiS->SiS_Pr->CVDisplay >= 1024) || 4111 sr_data = crdata[15];
4360 (pSiS->SiS_Pr->CVTotal >= 1024) || 4112 cr_data = crdata[5];
4361 (pSiS->SiS_Pr->CHDisplay >= 1024))
4362 pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
4363 4113
4364 if(pSiS->SiS_Pr->CFlags & V_CLKDIV2) 4114 /* Horizontal blank end */
4365 pSiS->SiS_Pr->CModeFlag |= HalfDCLK; 4115 HBE = (crdata[3] & 0x1f) |
4116 ((unsigned short)(cr_data & 0x80) >> 2) |
4117 ((unsigned short)(sr_data & 0x03) << 6);
4366 4118
4367 pSiS->SiS_Pr->CInfoFlag = 0x0007; 4119 /* Horizontal retrace (=sync) end */
4120 HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
4368 4121
4369 if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 4122 temp = HBE - ((E - 1) & 255);
4370 pSiS->SiS_Pr->CInfoFlag |= 0x4000; 4123 B = (temp > 0) ? temp : (temp + 256);
4371 4124
4372 if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 4125 temp = HRE - ((E + F + 3) & 63);
4373 pSiS->SiS_Pr->CInfoFlag |= 0x8000; 4126 C = (temp > 0) ? temp : (temp + 64);
4374 4127
4375 if(pSiS->SiS_Pr->CFlags & V_INTERLACE) 4128 D = B - F - C;
4376 pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
4377 4129
4378 pSiS->SiS_Pr->UseCustomMode = TRUE; 4130#ifdef SIS_XORG_XF86
4131 current->HDisplay = (E * 8);
4132 current->HSyncStart = (E * 8) + (F * 8);
4133 current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
4134 current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
4379#ifdef TWDEBUG 4135#ifdef TWDEBUG
4380 xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n", 4136 xf86DrvMsg(0, X_INFO,
4381 pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay); 4137 "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
4382 xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n", 4138 A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
4383 pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
4384 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4385 pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
4386 pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
4387 pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
4388 pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
4389 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
4390 pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
4391 pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
4392 pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
4393 pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
4394 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
4395 xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
4396 pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
4397#endif
4398 return 1;
4399}
4400
4401int
4402SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy)
4403{
4404 int i, j;
4405 BOOLEAN done = FALSE;
4406
4407 i = 0;
4408 while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) {
4409 if(SiS_PlasmaTable[i].vendor == panelvendor) {
4410 for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
4411 if(SiS_PlasmaTable[i].product[j] == panelproduct) {
4412 if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) {
4413 (*maxx) = (int)SiS_PlasmaTable[i].maxx;
4414 (*maxy) = (int)SiS_PlasmaTable[i].maxy;
4415 (*prefx) = (int)SiS_PlasmaTable[i].prefx;
4416 (*prefy) = (int)SiS_PlasmaTable[i].prefy;
4417 done = TRUE;
4418 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
4419 "Identified %s, correcting max X res %d, max Y res %d\n",
4420 SiS_PlasmaTable[i].plasmaname,
4421 SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy);
4422 break;
4423 }
4424 }
4425 }
4426 }
4427 i++;
4428 }
4429 return (done) ? 1 : 0;
4430}
4431
4432/* Build a list of supported modes:
4433 * Built-in modes for which we have all data are M_T_DEFAULT,
4434 * modes derived from DDC or database data are M_T_BUILTIN
4435 */
4436DisplayModePtr
4437SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
4438{
4439 SISPtr pSiS = SISPTR(pScrn);
4440 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
4441 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
4442 unsigned char sr_data, cr_data, cr_data2, cr_data3;
4443 unsigned char sr2b, sr2c;
4444 float num, denum, postscalar, divider;
4445 int A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
4446 DisplayModePtr new = NULL, current = NULL, first = NULL;
4447 BOOLEAN done = FALSE;
4448#if 0
4449 DisplayModePtr backup = NULL;
4450#endif
4451
4452 pSiS->backupmodelist = NULL;
4453 pSiS->AddedPlasmaModes = FALSE;
4454
4455 /* Initialize our pointers */
4456 if(pSiS->VGAEngine == SIS_300_VGA) {
4457#ifdef SIS300
4458 InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4459#else 4139#else
4460 return NULL; 4140 (void)VBS; (void)HBS; (void)A;
4461#endif 4141#endif
4462 } else if(pSiS->VGAEngine == SIS_315_VGA) {
4463#ifdef SIS315H
4464 InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4465#else
4466 return NULL;
4467#endif
4468 } else return NULL;
4469
4470 i = 0;
4471 while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
4472
4473 index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
4474
4475 /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
4476 if((!pSiS->FSTN) &&
4477 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a)) {
4478 i++;
4479 continue;
4480 }
4481 if((pSiS->FSTN) &&
4482 (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
4483 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
4484 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
4485 i++;
4486 continue;
4487 }
4488
4489 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4490 memset(new, 0, sizeof(DisplayModeRec));
4491 if(!(new->name = xalloc(10))) {
4492 xfree(new);
4493 return first;
4494 }
4495 if(!first) first = new;
4496 if(current) {
4497 current->next = new;
4498 new->prev = current;
4499 }
4500
4501 current = new;
4502
4503 sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
4504 pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
4505
4506 current->status = MODE_OK;
4507
4508 current->type = M_T_DEFAULT;
4509
4510 vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
4511 if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
4512
4513 sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
4514 sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
4515
4516 divider = (sr2b & 0x80) ? 2.0 : 1.0;
4517 postscalar = (sr2c & 0x80) ?
4518 ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
4519 num = (sr2b & 0x7f) + 1.0;
4520 denum = (sr2c & 0x1f) + 1.0;
4521
4522#ifdef TWDEBUG
4523 xf86DrvMsg(0, X_INFO, "------------\n");
4524 xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
4525 sr2b, sr2c, divider, postscalar, num, denum);
4526#endif 4142#endif
4527 4143#ifdef SIS_LINUX_KERNEL
4528 current->Clock = (int)(14318 * (divider / postscalar) * (num / denum)); 4144 if(writeres) var->xres = xres = E * 8;
4529 4145 var->left_margin = D * 8;
4530 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14]; 4146 var->right_margin = F * 8;
4531 /* inSISIDXREG(SISSR, 0x0b, sr_data); */ 4147 var->hsync_len = C * 8;
4532
4533 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0];
4534 /* inSISIDXREG(SISCR, 0x00, cr_data); */
4535
4536 /* Horizontal total */
4537 HT = (cr_data & 0xff) |
4538 ((unsigned short) (sr_data & 0x03) << 8);
4539 A = HT + 5;
4540
4541 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1];
4542 /* inSISIDXREG(SISCR, 0x01, cr_data); */
4543
4544 /* Horizontal display enable end */
4545 HDE = (cr_data & 0xff) |
4546 ((unsigned short) (sr_data & 0x0C) << 6);
4547 E = HDE + 1; /* 0x80 0x64 */
4548
4549 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
4550 /* inSISIDXREG(SISCR, 0x04, cr_data); */
4551
4552 /* Horizontal retrace (=sync) start */
4553 HRS = (cr_data & 0xff) |
4554 ((unsigned short) (sr_data & 0xC0) << 2);
4555 F = HRS - E - 3; /* 0x06 0x06 */
4556
4557 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
4558 /* inSISIDXREG(SISCR, 0x02, cr_data); */
4559
4560 /* Horizontal blank start */
4561 HBS = (cr_data & 0xff) |
4562 ((unsigned short) (sr_data & 0x30) << 4);
4563
4564 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15];
4565 /* inSISIDXREG(SISSR, 0x0c, sr_data); */
4566
4567 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3];
4568 /* inSISIDXREG(SISCR, 0x03, cr_data); */
4569
4570 cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5];
4571 /* inSISIDXREG(SISCR, 0x05, cr_data2); */
4572
4573 /* Horizontal blank end */
4574 HBE = (cr_data & 0x1f) |
4575 ((unsigned short) (cr_data2 & 0x80) >> 2) |
4576 ((unsigned short) (sr_data & 0x03) << 6);
4577
4578 /* Horizontal retrace (=sync) end */
4579 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
4580
4581 temp = HBE - ((E - 1) & 255);
4582 B = (temp > 0) ? temp : (temp + 256);
4583
4584 temp = HRE - ((E + F + 3) & 63);
4585 C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
4586
4587 D = B - F - C;
4588
4589 if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
4590 ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
4591 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
4592
4593 /* Terrible hack, but correct CRTC data for
4594 * these modes only produces a black screen...
4595 * (HRE is 0, leading into a too large C and
4596 * a negative D. The CRT controller does not
4597 * seem to like correcting HRE to 50
4598 */
4599 current->HDisplay = 320;
4600 current->HSyncStart = 328;
4601 current->HSyncEnd = 376;
4602 current->HTotal = 400;
4603
4604 } else {
4605
4606 current->HDisplay = (E * 8);
4607 current->HSyncStart = (E * 8) + (F * 8);
4608 current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
4609 current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
4610
4611 }
4612
4613#ifdef TWDEBUG
4614 xf86DrvMsg(0, X_INFO,
4615 "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
4616 A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
4617#endif 4148#endif
4618 4149
4619 sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13]; 4150 /* Vertical */
4620 /* inSISIDXREG(SISSR, 0x0A, sr_data); */ 4151 sr_data = crdata[13];
4621 4152 cr_data = crdata[7];
4622 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6]; 4153
4623 /* inSISIDXREG(SISCR, 0x06, cr_data); */ 4154 /* Vertical total */
4624 4155 VT = crdata[6] |
4625 cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7]; 4156 ((unsigned short)(cr_data & 0x01) << 8) |
4626 /* inSISIDXREG(SISCR, 0x07, cr_data2); */ 4157 ((unsigned short)(cr_data & 0x20) << 4) |
4627 4158 ((unsigned short)(sr_data & 0x01) << 10);
4628 /* Vertical total */ 4159 A = VT + 2;
4629 VT = (cr_data & 0xFF) | 4160
4630 ((unsigned short) (cr_data2 & 0x01) << 8) | 4161 /* Vertical display enable end */
4631 ((unsigned short)(cr_data2 & 0x20) << 4) | 4162 VDE = crdata[10] |
4632 ((unsigned short) (sr_data & 0x01) << 10); 4163 ((unsigned short)(cr_data & 0x02) << 7) |
4633 A = VT + 2; 4164 ((unsigned short)(cr_data & 0x40) << 3) |
4634 4165 ((unsigned short)(sr_data & 0x02) << 9);
4635 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10]; 4166 E = VDE + 1;
4636 /* inSISIDXREG(SISCR, 0x12, cr_data); */ 4167
4637 4168 /* Vertical retrace (=sync) start */
4638 /* Vertical display enable end */ 4169 VRS = crdata[8] |
4639 VDE = (cr_data & 0xff) | 4170 ((unsigned short)(cr_data & 0x04) << 6) |
4640 ((unsigned short) (cr_data2 & 0x02) << 7) | 4171 ((unsigned short)(cr_data & 0x80) << 2) |
4641 ((unsigned short) (cr_data2 & 0x40) << 3) | 4172 ((unsigned short)(sr_data & 0x08) << 7);
4642 ((unsigned short) (sr_data & 0x02) << 9); 4173 F = VRS + 1 - E;
4643 E = VDE + 1; 4174
4644 4175 cr_data2 = (crdata[16] & 0x01) << 5;
4645 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8]; 4176
4646 /* inSISIDXREG(SISCR, 0x10, cr_data); */ 4177 /* Vertical blank start */
4647 4178 VBS = crdata[11] |
4648 /* Vertical retrace (=sync) start */ 4179 ((unsigned short)(cr_data & 0x08) << 5) |
4649 VRS = (cr_data & 0xff) | 4180 ((unsigned short)(cr_data2 & 0x20) << 4) |
4650 ((unsigned short) (cr_data2 & 0x04) << 6) | 4181 ((unsigned short)(sr_data & 0x04) << 8);
4651 ((unsigned short) (cr_data2 & 0x80) << 2) | 4182
4652 ((unsigned short) (sr_data & 0x08) << 7); 4183 /* Vertical blank end */
4653 F = VRS + 1 - E; 4184 VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
4654 4185 temp = VBE - ((E - 1) & 511);
4655 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11]; 4186 B = (temp > 0) ? temp : (temp + 512);
4656 /* inSISIDXREG(SISCR, 0x15, cr_data); */ 4187
4657 4188 /* Vertical retrace (=sync) end */
4658 cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5; 4189 VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
4659 /* inSISIDXREG(SISCR, 0x09, cr_data3); */ 4190 temp = VRE - ((E + F - 1) & 31);
4660 4191 C = (temp > 0) ? temp : (temp + 32);
4661 /* Vertical blank start */ 4192
4662 VBS = (cr_data & 0xff) | 4193 D = B - F - C;
4663 ((unsigned short) (cr_data2 & 0x08) << 5) | 4194
4664 ((unsigned short) (cr_data3 & 0x20) << 4) | 4195#ifdef SIS_XORG_XF86
4665 ((unsigned short) (sr_data & 0x04) << 8); 4196 current->VDisplay = VDE + 1;
4666 4197 current->VSyncStart = VRS + 1;
4667 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12]; 4198 current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
4668 /* inSISIDXREG(SISCR, 0x16, cr_data); */ 4199 if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
4669 4200 current->VTotal = E + D + C + F;
4670 /* Vertical blank end */
4671 VBE = (cr_data & 0xff) |
4672 ((unsigned short) (sr_data & 0x10) << 4);
4673 temp = VBE - ((E - 1) & 511);
4674 B = (temp > 0) ? temp : (temp + 512);
4675
4676 cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9];
4677 /* inSISIDXREG(SISCR, 0x11, cr_data); */
4678
4679 /* Vertical retrace (=sync) end */
4680 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
4681 temp = VRE - ((E + F - 1) & 31);
4682 C = (temp > 0) ? temp : (temp + 32);
4683
4684 D = B - F - C;
4685
4686 current->VDisplay = VDE + 1;
4687 current->VSyncStart = VRS + 1;
4688 current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
4689 if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
4690 current->VTotal = E + D + C + F;
4691
4692#if 0 4201#if 0
4693 current->VDisplay = E; 4202 current->VDisplay = E;
4694 current->VSyncStart = E + D; 4203 current->VSyncStart = E + D;
4695 current->VSyncEnd = E + D + C; 4204 current->VSyncEnd = E + D + C;
4696 current->VTotal = E + D + C + F; 4205 current->VTotal = E + D + C + F;
4697#endif 4206#endif
4698
4699#ifdef TWDEBUG 4207#ifdef TWDEBUG
4700 xf86DrvMsg(0, X_INFO, 4208 xf86DrvMsg(0, X_INFO,
4701 "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n", 4209 "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
4702 A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE); 4210 A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
4703#endif 4211#endif
4704
4705 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
4706 current->Flags |= V_NHSYNC;
4707 else
4708 current->Flags |= V_PHSYNC;
4709
4710 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
4711 current->Flags |= V_NVSYNC;
4712 else
4713 current->Flags |= V_PVSYNC;
4714
4715 if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
4716 current->Flags |= V_INTERLACE;
4717
4718 j = 0;
4719 while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
4720 if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
4721 pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) {
4722 if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
4723 current->Flags |= V_DBLSCAN;
4724 }
4725 break;
4726 }
4727 j++;
4728 }
4729
4730 if(current->Flags & V_INTERLACE) {
4731 current->VDisplay <<= 1;
4732 current->VSyncStart <<= 1;
4733 current->VSyncEnd <<= 1;
4734 current->VTotal <<= 1;
4735 current->VTotal |= 1;
4736 }
4737 if(current->Flags & V_DBLSCAN) {
4738 current->Clock >>= 1;
4739 current->VDisplay >>= 1;
4740 current->VSyncStart >>= 1;
4741 current->VSyncEnd >>= 1;
4742 current->VTotal >>= 1;
4743 }
4744
4745#ifdef TWDEBUG
4746 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4747 "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
4748 current->name, (float)current->Clock / 1000,
4749 current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
4750 current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
4751#else
4752 (void)VBS; (void)HBS; (void)A;
4753#endif 4212#endif
4754 4213#ifdef SIS_LINUX_KERNEL
4755 i++; 4214 if(writeres) var->yres = yres = E;
4756 } 4215 var->upper_margin = D;
4757 4216 var->lower_margin = F;
4758 /* Add non-standard LCD modes for panel's detailed timings */ 4217 var->vsync_len = C;
4759
4760 if(!includelcdmodes) return first;
4761
4762 if(pSiS->SiS_Pr->CP_Vendor) {
4763 xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
4764 pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
4765 }
4766
4767 i = 0;
4768 while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
4769
4770 if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
4771
4772 for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
4773
4774 if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
4775
4776 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
4777 "Identified %s panel, adding specific modes\n",
4778 SiS_PlasmaTable[i].plasmaname);
4779
4780 for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
4781
4782 if(isfordvi) {
4783 if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
4784 } else {
4785 if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
4786 }
4787
4788 l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
4789
4790 if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) {
4791 if(isfordvi) {
4792 if(SiS_PlasmaMode[l].VDisplay > 1024) continue;
4793 }
4794 }
4795
4796 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4797
4798 memset(new, 0, sizeof(DisplayModeRec));
4799 if(!(new->name = xalloc(12))) {
4800 xfree(new);
4801 return first;
4802 }
4803 if(!first) first = new;
4804 if(current) {
4805 current->next = new;
4806 new->prev = current;
4807 }
4808
4809 current = new;
4810
4811 pSiS->AddedPlasmaModes = TRUE;
4812
4813 strcpy(current->name, SiS_PlasmaMode[l].name);
4814 /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
4815 SiS_PlasmaMode[l].VDisplay); */
4816
4817 current->status = MODE_OK;
4818
4819 current->type = M_T_BUILTIN;
4820
4821 current->Clock = SiS_PlasmaMode[l].clock;
4822 current->SynthClock = current->Clock;
4823
4824 current->HDisplay = SiS_PlasmaMode[l].HDisplay;
4825 current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
4826 current->HSyncEnd = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
4827 current->HTotal = SiS_PlasmaMode[l].HTotal;
4828
4829 current->VDisplay = SiS_PlasmaMode[l].VDisplay;
4830 current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
4831 current->VSyncEnd = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
4832 current->VTotal = SiS_PlasmaMode[l].VTotal;
4833
4834 current->CrtcHDisplay = current->HDisplay;
4835 current->CrtcHBlankStart = current->HSyncStart;
4836 current->CrtcHSyncStart = current->HSyncStart;
4837 current->CrtcHSyncEnd = current->HSyncEnd;
4838 current->CrtcHBlankEnd = current->HSyncEnd;
4839 current->CrtcHTotal = current->HTotal;
4840
4841 current->CrtcVDisplay = current->VDisplay;
4842 current->CrtcVBlankStart = current->VSyncStart;
4843 current->CrtcVSyncStart = current->VSyncStart;
4844 current->CrtcVSyncEnd = current->VSyncEnd;
4845 current->CrtcVBlankEnd = current->VSyncEnd;
4846 current->CrtcVTotal = current->VTotal;
4847
4848 if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
4849 current->Flags |= V_PHSYNC;
4850 else
4851 current->Flags |= V_NHSYNC;
4852
4853 if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
4854 current->Flags |= V_PVSYNC;
4855 else
4856 current->Flags |= V_NVSYNC;
4857
4858 if(current->HDisplay > pSiS->LCDwidth)
4859 pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
4860 if(current->VDisplay > pSiS->LCDheight)
4861 pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
4862
4863 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
4864 "\tAdding \"%s\" to list of built-in modes\n", current->name);
4865
4866 }
4867 done = TRUE;
4868 break;
4869 }
4870 }
4871 }
4872
4873 i++;
4874
4875 }
4876
4877 if(pSiS->SiS_Pr->CP_HaveCustomData) {
4878
4879 for(i=0; i<7; i++) {
4880
4881 if(pSiS->SiS_Pr->CP_DataValid[i]) {
4882
4883 if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
4884
4885 memset(new, 0, sizeof(DisplayModeRec));
4886 if(!(new->name = xalloc(10))) {
4887 xfree(new);
4888 return first;
4889 }
4890 if(!first) first = new;
4891 if(current) {
4892 current->next = new;
4893 new->prev = current;
4894 }
4895
4896 current = new;
4897
4898 sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
4899 pSiS->SiS_Pr->CP_VDisplay[i]);
4900
4901 current->status = MODE_OK;
4902
4903 current->type = M_T_BUILTIN;
4904
4905 current->Clock = pSiS->SiS_Pr->CP_Clock[i];
4906 current->SynthClock = current->Clock;
4907
4908 current->HDisplay = pSiS->SiS_Pr->CP_HDisplay[i];
4909 current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
4910 current->HSyncEnd = pSiS->SiS_Pr->CP_HSyncEnd[i];
4911 current->HTotal = pSiS->SiS_Pr->CP_HTotal[i];
4912
4913 current->VDisplay = pSiS->SiS_Pr->CP_VDisplay[i];
4914 current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
4915 current->VSyncEnd = pSiS->SiS_Pr->CP_VSyncEnd[i];
4916 current->VTotal = pSiS->SiS_Pr->CP_VTotal[i];
4917
4918 current->CrtcHDisplay = current->HDisplay;
4919 current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
4920 current->CrtcHSyncStart = current->HSyncStart;
4921 current->CrtcHSyncEnd = current->HSyncEnd;
4922 current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
4923 current->CrtcHTotal = current->HTotal;
4924
4925 current->CrtcVDisplay = current->VDisplay;
4926 current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
4927 current->CrtcVSyncStart = current->VSyncStart;
4928 current->CrtcVSyncEnd = current->VSyncEnd;
4929 current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
4930 current->CrtcVTotal = current->VTotal;
4931
4932 if(pSiS->SiS_Pr->CP_SyncValid[i]) {
4933 if(pSiS->SiS_Pr->CP_HSync_P[i])
4934 current->Flags |= V_PHSYNC;
4935 else
4936 current->Flags |= V_NHSYNC;
4937
4938 if(pSiS->SiS_Pr->CP_VSync_P[i])
4939 current->Flags |= V_PVSYNC;
4940 else
4941 current->Flags |= V_NVSYNC;
4942 } else {
4943 /* No sync data? Use positive sync... */
4944 current->Flags |= V_PHSYNC;
4945 current->Flags |= V_PVSYNC;
4946 }
4947 }
4948 }
4949 }
4950
4951 return first;
4952
4953}
4954
4955/* Translate a mode number into the VESA pendant */
4956int
4957SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
4958{
4959 SISPtr pSiS = SISPTR(pScrn);
4960 int i = 0;
4961
4962 /* Initialize our pointers */
4963 if(pSiS->VGAEngine == SIS_300_VGA) {
4964#ifdef SIS300
4965 InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4966#else
4967 return -1;
4968#endif
4969 } else if(pSiS->VGAEngine == SIS_315_VGA) {
4970#ifdef SIS315H
4971 InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
4972#else
4973 return -1;
4974#endif 4218#endif
4975 } else return -1;
4976
4977 if(modenumber <= 0x13) return modenumber;
4978 4219
4979#ifdef SIS315H 4220 if((xres == 320) && ((yres == 200) || (yres == 240))) {
4980 if(pSiS->ROM661New) { 4221 /* Terrible hack, but correct CRTC data for
4981 while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) { 4222 * these modes only produces a black screen...
4982 if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) { 4223 * (HRE is 0, leading into a too large C and
4983 return (int)SiS_EModeIDTable661[i].Ext_VESAID; 4224 * a negative D. The CRT controller does not
4984 } 4225 * seem to like correcting HRE to 50)
4985 i++; 4226 */
4986 } 4227#ifdef SIS_XORG_XF86
4987 } else { 4228 current->HDisplay = 320;
4229 current->HSyncStart = 328;
4230 current->HSyncEnd = 376;
4231 current->HTotal = 400;
4988#endif 4232#endif
4989 while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) { 4233#ifdef SIS_LINUX_KERNEL
4990 if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) { 4234 var->left_margin = (400 - 376);
4991 return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID; 4235 var->right_margin = (328 - 320);
4992 } 4236 var->hsync_len = (376 - 328);
4993 i++;
4994 }
4995#ifdef SIS315H
4996 }
4997#endif 4237#endif
4998 return -1;
4999}
5000 4238
5001/* Translate a new BIOS mode number into the driver's pendant */
5002int
5003SiSTranslateToOldMode(int modenumber)
5004{
5005#ifdef SIS315H
5006 int i = 0;
5007
5008 while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
5009 if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
5010 if(SiS_EModeIDTable661[i].Ext_MyModeID)
5011 return (int)SiS_EModeIDTable661[i].Ext_MyModeID;
5012 else
5013 return modenumber;
5014 }
5015 i++;
5016 } 4239 }
5017#endif
5018 return modenumber;
5019}
5020
5021#endif /* Xfree86 */
5022
5023#ifdef LINUX_KERNEL
5024int
5025sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5026 unsigned char modeno, unsigned char rateindex)
5027{
5028 USHORT ModeNo = modeno;
5029 USHORT ModeIdIndex = 0, ClockIndex = 0;
5030 USHORT RefreshRateTableIndex = 0;
5031 int Clock;
5032
5033 if(HwInfo->jChipType < SIS_315H) {
5034#ifdef SIS300
5035 InitTo300Pointer(SiS_Pr, HwInfo);
5036#else
5037 return 65 * 1000;
5038#endif
5039 } else {
5040#ifdef SIS315H
5041 InitTo310Pointer(SiS_Pr, HwInfo);
5042#else
5043 return 65 * 1000;
5044#endif
5045 }
5046
5047 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
5048 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
5049 return 65 * 1000;
5050 }
5051
5052 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5053 RefreshRateTableIndex += (rateindex - 1);
5054 ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
5055 if(HwInfo->jChipType < SIS_315H) {
5056 ClockIndex &= 0x3F;
5057 }
5058 Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
5059
5060 return(Clock);
5061}
5062
5063BOOLEAN
5064sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5065 unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
5066{
5067 USHORT ModeNo = modeno;
5068 USHORT ModeIdIndex = 0, CRT1Index = 0;
5069 USHORT RefreshRateTableIndex = 0;
5070 unsigned char sr_data, cr_data, cr_data2;
5071
5072 if(HwInfo->jChipType < SIS_315H) {
5073#ifdef SIS300
5074 InitTo300Pointer(SiS_Pr, HwInfo);
5075#else
5076 return FALSE;
5077#endif
5078 } else {
5079#ifdef SIS315H
5080 InitTo310Pointer(SiS_Pr, HwInfo);
5081#else
5082 return FALSE;
5083#endif
5084 }
5085
5086 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
5087
5088 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5089 RefreshRateTableIndex += (rateindex - 1);
5090 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
5091
5092 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
5093 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
5094 *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
5095 4240
5096 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
5097 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
5098 cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
5099 *vtotal = ((cr_data & 0xFF) |
5100 ((unsigned short)(cr_data2 & 0x01) << 8) |
5101 ((unsigned short)(cr_data2 & 0x20) << 4) |
5102 ((unsigned short)(sr_data & 0x01) << 10)) + 2;
5103
5104 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
5105 *vtotal *= 2;
5106
5107 return TRUE;
5108} 4241}
5109 4242
5110int
5111sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
5112 unsigned char modeno, unsigned char rateindex,
5113 struct fb_var_screeninfo *var)
5114{
5115 USHORT ModeNo = modeno;
5116 USHORT ModeIdIndex = 0, index = 0;
5117 USHORT RefreshRateTableIndex = 0;
5118 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
5119 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
5120 unsigned char sr_data, cr_data, cr_data2, cr_data3;
5121 int A, B, C, D, E, F, temp, j;
5122
5123 if(HwInfo->jChipType < SIS_315H) {
5124#ifdef SIS300
5125 InitTo300Pointer(SiS_Pr, HwInfo);
5126#else
5127 return 0;
5128#endif
5129 } else {
5130#ifdef SIS315H
5131 InitTo310Pointer(SiS_Pr, HwInfo);
5132#else
5133 return 0;
5134#endif
5135 }
5136
5137 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
5138
5139 RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
5140 RefreshRateTableIndex += (rateindex - 1);
5141 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
5142
5143 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14];
5144
5145 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0];
5146
5147 /* Horizontal total */
5148 HT = (cr_data & 0xff) |
5149 ((unsigned short) (sr_data & 0x03) << 8);
5150 A = HT + 5;
5151
5152 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1];
5153
5154 /* Horizontal display enable end */
5155 HDE = (cr_data & 0xff) |
5156 ((unsigned short) (sr_data & 0x0C) << 6);
5157 E = HDE + 1;
5158
5159 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4];
5160
5161 /* Horizontal retrace (=sync) start */
5162 HRS = (cr_data & 0xff) |
5163 ((unsigned short) (sr_data & 0xC0) << 2);
5164 F = HRS - E - 3;
5165
5166 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2];
5167
5168 /* Horizontal blank start */
5169 HBS = (cr_data & 0xff) |
5170 ((unsigned short) (sr_data & 0x30) << 4);
5171
5172 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15];
5173
5174 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3];
5175
5176 cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5];
5177
5178 /* Horizontal blank end */
5179 HBE = (cr_data & 0x1f) |
5180 ((unsigned short) (cr_data2 & 0x80) >> 2) |
5181 ((unsigned short) (sr_data & 0x03) << 6);
5182
5183 /* Horizontal retrace (=sync) end */
5184 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
5185 4243
5186 temp = HBE - ((E - 1) & 255);
5187 B = (temp > 0) ? temp : (temp + 256);
5188 4244
5189 temp = HRE - ((E + F + 3) & 63);
5190 C = (temp > 0) ? temp : (temp + 64);
5191
5192 D = B - F - C;
5193
5194 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
5195 ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
5196 (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
5197
5198 /* Terrible hack, but the correct CRTC data for
5199 * these modes only produces a black screen...
5200 */
5201 var->left_margin = (400 - 376);
5202 var->right_margin = (328 - 320);
5203 var->hsync_len = (376 - 328);
5204
5205 } else {
5206
5207 var->left_margin = D * 8;
5208 var->right_margin = F * 8;
5209 var->hsync_len = C * 8;
5210
5211 }
5212
5213 sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
5214
5215 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
5216
5217 cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
5218
5219 /* Vertical total */
5220 VT = (cr_data & 0xFF) |
5221 ((unsigned short) (cr_data2 & 0x01) << 8) |
5222 ((unsigned short)(cr_data2 & 0x20) << 4) |
5223 ((unsigned short) (sr_data & 0x01) << 10);
5224 A = VT + 2;
5225
5226 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10];
5227
5228 /* Vertical display enable end */
5229 VDE = (cr_data & 0xff) |
5230 ((unsigned short) (cr_data2 & 0x02) << 7) |
5231 ((unsigned short) (cr_data2 & 0x40) << 3) |
5232 ((unsigned short) (sr_data & 0x02) << 9);
5233 E = VDE + 1;
5234
5235 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8];
5236
5237 /* Vertical retrace (=sync) start */
5238 VRS = (cr_data & 0xff) |
5239 ((unsigned short) (cr_data2 & 0x04) << 6) |
5240 ((unsigned short) (cr_data2 & 0x80) << 2) |
5241 ((unsigned short) (sr_data & 0x08) << 7);
5242 F = VRS + 1 - E;
5243
5244 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[11];
5245
5246 cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
5247
5248 /* Vertical blank start */
5249 VBS = (cr_data & 0xff) |
5250 ((unsigned short) (cr_data2 & 0x08) << 5) |
5251 ((unsigned short) (cr_data3 & 0x20) << 4) |
5252 ((unsigned short) (sr_data & 0x04) << 8);
5253
5254 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[12];
5255
5256 /* Vertical blank end */
5257 VBE = (cr_data & 0xff) |
5258 ((unsigned short) (sr_data & 0x10) << 4);
5259 temp = VBE - ((E - 1) & 511);
5260 B = (temp > 0) ? temp : (temp + 512);
5261
5262 cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9];
5263
5264 /* Vertical retrace (=sync) end */
5265 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
5266 temp = VRE - ((E + F - 1) & 31);
5267 C = (temp > 0) ? temp : (temp + 32);
5268
5269 D = B - F - C;
5270
5271 var->upper_margin = D;
5272 var->lower_margin = F;
5273 var->vsync_len = C;
5274
5275 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
5276 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
5277 else
5278 var->sync |= FB_SYNC_VERT_HIGH_ACT;
5279
5280 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
5281 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
5282 else
5283 var->sync |= FB_SYNC_HOR_HIGH_ACT;
5284
5285 var->vmode = FB_VMODE_NONINTERLACED;
5286 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
5287 var->vmode = FB_VMODE_INTERLACED;
5288 else {
5289 j = 0;
5290 while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
5291 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
5292 SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
5293 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
5294 var->vmode = FB_VMODE_DOUBLE;
5295 }
5296 break;
5297 }
5298 j++;
5299 }
5300 }
5301
5302 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
5303#if 0 /* Do this? */
5304 var->upper_margin <<= 1;
5305 var->lower_margin <<= 1;
5306 var->vsync_len <<= 1;
5307#endif
5308 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
5309 var->upper_margin >>= 1;
5310 var->lower_margin >>= 1;
5311 var->vsync_len >>= 1;
5312 }
5313
5314 return 1;
5315}
5316
5317#endif
5318 4245
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 7e36b7ac1470..634c0a9d219b 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * Data and prototypes for init.c 4 * Data and prototypes for init.c
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,18 +50,24 @@
50 * 50 *
51 */ 51 */
52 52
53#ifndef _INIT_ 53#ifndef _INIT_H_
54#define _INIT_ 54#define _INIT_H_
55 55
56#include "osdef.h" 56#include "osdef.h"
57#include "initdef.h" 57#include "initdef.h"
58 58
59#ifdef LINUX_XF86 59#ifdef SIS_XORG_XF86
60#include "sis.h" 60#include "sis.h"
61#define SIS_NEED_inSISREG
62#define SIS_NEED_inSISREGW
63#define SIS_NEED_inSISREGL
64#define SIS_NEED_outSISREG
65#define SIS_NEED_outSISREGW
66#define SIS_NEED_outSISREGL
61#include "sis_regs.h" 67#include "sis_regs.h"
62#endif 68#endif
63 69
64#ifdef LINUX_KERNEL 70#ifdef SIS_LINUX_KERNEL
65#include "vgatypes.h" 71#include "vgatypes.h"
66#include "vstruct.h" 72#include "vstruct.h"
67#ifdef SIS_CP 73#ifdef SIS_CP
@@ -73,6 +79,10 @@
73#include <asm/io.h> 79#include <asm/io.h>
74#include <linux/fb.h> 80#include <linux/fb.h>
75#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 81#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
82#include <video/fbcon.h>
83#endif
84#include "sis.h"
85#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
76#include <linux/sisfb.h> 86#include <linux/sisfb.h>
77#else 87#else
78#include <video/sisfb.h> 88#include <video/sisfb.h>
@@ -80,44 +90,45 @@
80#endif 90#endif
81 91
82/* Mode numbers */ 92/* Mode numbers */
83static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; 93static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
84static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53}; 94static const unsigned short ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
85static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */ 95static const unsigned short ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
86static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54}; 96static const unsigned short ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
87static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; 97static const unsigned short ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
88static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; 98static const unsigned short ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
89static const USHORT ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; 99static const unsigned short ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
90static const USHORT ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; 100static const unsigned short ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
91static const USHORT ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; 101static const unsigned short ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
92static const USHORT ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61}; 102static const unsigned short ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
93static const USHORT ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; 103static const unsigned short ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
94static const USHORT ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; 104static const unsigned short ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
95static const USHORT ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; 105static const unsigned short ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
96static const USHORT ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; 106static const unsigned short ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
97static const USHORT ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */ 107static const unsigned short ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
98static const USHORT ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */ 108static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */
99static const USHORT ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; 109static const unsigned short ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
100static const USHORT ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; 110static const unsigned short ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
101static const USHORT ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */ 111static const unsigned short ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
102static const USHORT ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; 112static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
103static const USHORT ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e}; 113static const unsigned short ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
104static const USHORT ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */ 114static const unsigned short ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
105static const USHORT ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; 115static const unsigned short ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
106static const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b}; 116static const unsigned short ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
107static const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25}; 117static const unsigned short ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
108static const USHORT ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; 118static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
109static const USHORT ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16}; 119static const unsigned short ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
110static const USHORT ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e}; 120static const unsigned short ModeIndex_1280x854[] = {0x1a, 0x1b, 0x00, 0x1c};
111static const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */ 121static const unsigned short ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
112static const USHORT ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */ 122static const unsigned short ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
113static const USHORT ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */ 123static const unsigned short ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
114static const USHORT ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66}; 124static const unsigned short ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
115static const USHORT ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */ 125static const unsigned short ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
116static const USHORT ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b}; 126static const unsigned short ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
117static const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00}; 127static const unsigned short ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
118static const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e}; 128static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
119 129static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
120static const USHORT SiS_DRAMType[17][5]={ 130
131static const unsigned short SiS_DRAMType[17][5]={
121 {0x0C,0x0A,0x02,0x40,0x39}, 132 {0x0C,0x0A,0x02,0x40,0x39},
122 {0x0D,0x0A,0x01,0x40,0x48}, 133 {0x0D,0x0A,0x01,0x40,0x48},
123 {0x0C,0x09,0x02,0x20,0x35}, 134 {0x0C,0x09,0x02,0x20,0x35},
@@ -137,7 +148,7 @@ static const USHORT SiS_DRAMType[17][5]={
137 {0x09,0x08,0x01,0x01,0x00} 148 {0x09,0x08,0x01,0x01,0x00}
138}; 149};
139 150
140static const USHORT SiS_SDRDRAM_TYPE[13][5] = 151static const unsigned short SiS_SDRDRAM_TYPE[13][5] =
141{ 152{
142 { 2,12, 9,64,0x35}, 153 { 2,12, 9,64,0x35},
143 { 1,13, 9,64,0x44}, 154 { 1,13, 9,64,0x44},
@@ -154,7 +165,7 @@ static const USHORT SiS_SDRDRAM_TYPE[13][5] =
154 { 1, 9, 8, 2,0x00} 165 { 1, 9, 8, 2,0x00}
155}; 166};
156 167
157static const USHORT SiS_DDRDRAM_TYPE[4][5] = 168static const unsigned short SiS_DDRDRAM_TYPE[4][5] =
158{ 169{
159 { 2,12, 9,64,0x35}, 170 { 2,12, 9,64,0x35},
160 { 2,12, 8,32,0x31}, 171 { 2,12, 8,32,0x31},
@@ -162,7 +173,7 @@ static const USHORT SiS_DDRDRAM_TYPE[4][5] =
162 { 2, 9, 8, 4,0x01} 173 { 2, 9, 8, 4,0x01}
163}; 174};
164 175
165static const USHORT SiS_MDA_DAC[] = 176static const unsigned char SiS_MDA_DAC[] =
166{ 177{
167 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 178 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, 179 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -174,7 +185,7 @@ static const USHORT SiS_MDA_DAC[] =
174 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F 185 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
175}; 186};
176 187
177static const USHORT SiS_CGA_DAC[] = 188static const unsigned char SiS_CGA_DAC[] =
178{ 189{
179 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, 190 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
180 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, 191 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -186,7 +197,7 @@ static const USHORT SiS_CGA_DAC[] =
186 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F 197 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
187}; 198};
188 199
189static const USHORT SiS_EGA_DAC[] = 200static const unsigned char SiS_EGA_DAC[] =
190{ 201{
191 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15, 202 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
192 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35, 203 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -198,7 +209,7 @@ static const USHORT SiS_EGA_DAC[] =
198 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F 209 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
199}; 210};
200 211
201static const USHORT SiS_VGA_DAC[] = 212static const unsigned char SiS_VGA_DAC[] =
202{ 213{
203 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, 214 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
204 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, 215 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -212,7 +223,31 @@ static const USHORT SiS_VGA_DAC[] =
212 0x0B,0x0C,0x0D,0x0F,0x10 223 0x0B,0x0C,0x0D,0x0F,0x10
213}; 224};
214 225
215static const SiS_StResInfoStruct SiS_StResInfo[]= 226static const struct SiS_St SiS_SModeIDTable[] =
227{
228 {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00,0x40},
229 {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00,0x40},
230 {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01,0x40},
231 {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02,0x40},
232 {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02,0x40},
233 {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40},
234 {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04,0x40},
235 {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05,0x40},
236 {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03,0x40},
237 {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03,0x40},
238 {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04,0x40},
239 {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05,0x40},
240 {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05,0x40},
241 {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05,0x40},
242 {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05,0x40},
243 {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05,0x40},
244 {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04,0x40},
245 {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05,0x40},
246 {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05,0x40},
247 {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
248};
249
250static const struct SiS_StResInfo_S SiS_StResInfo[]=
216{ 251{
217 { 640,400}, 252 { 640,400},
218 { 640,350}, 253 { 640,350},
@@ -221,7 +256,7 @@ static const SiS_StResInfoStruct SiS_StResInfo[]=
221 { 640,480} 256 { 640,480}
222}; 257};
223 258
224static const SiS_ModeResInfoStruct SiS_ModeResInfo[] = 259static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
225{ 260{
226 { 320, 200, 8, 8}, /* 0x00 */ 261 { 320, 200, 8, 8}, /* 0x00 */
227 { 320, 240, 8, 8}, /* 0x01 */ 262 { 320, 240, 8, 8}, /* 0x01 */
@@ -256,11 +291,12 @@ static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
256 { 1280, 800, 8,16}, /* 0x1e */ 291 { 1280, 800, 8,16}, /* 0x1e */
257 { 1920,1080, 8,16}, /* 0x1f */ 292 { 1920,1080, 8,16}, /* 0x1f */
258 { 960, 540, 8,16}, /* 0x20 */ 293 { 960, 540, 8,16}, /* 0x20 */
259 { 960, 600, 8,16} /* 0x21 */ 294 { 960, 600, 8,16}, /* 0x21 */
295 { 1280, 854, 8,16} /* 0x22 */
260}; 296};
261 297
262#if defined(SIS300) || defined(SIS315H) 298#if defined(SIS300) || defined(SIS315H)
263static const SiS_StandTableStruct SiS_StandTable[]= 299static const struct SiS_StandTable_S SiS_StandTable[]=
264{ 300{
265/* 0x00: MD_0_200 */ 301/* 0x00: MD_0_200 */
266 { 302 {
@@ -704,11 +740,11 @@ static const SiS_StandTableStruct SiS_StandTable[]=
704/* SIS VIDEO BRIDGE ----------------------------------------- */ 740/* SIS VIDEO BRIDGE ----------------------------------------- */
705/**************************************************************/ 741/**************************************************************/
706 742
707static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */ 743static const unsigned char SiS_SoftSetting = 0x30; /* RAM setting */
708 744
709static const UCHAR SiS_OutputSelect = 0x40; 745static const unsigned char SiS_OutputSelect = 0x40;
710 746
711static const UCHAR SiS_NTSCTiming[] = { 747static const unsigned char SiS_NTSCTiming[] = {
712 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, 748 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
713 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, 749 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
714 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, 750 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -719,7 +755,7 @@ static const UCHAR SiS_NTSCTiming[] = {
719 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 755 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
720}; 756};
721 757
722static const UCHAR SiS_PALTiming[] = { 758static const unsigned char SiS_PALTiming[] = {
723 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70, 759 0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
724 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d, 760 0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
725 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b, 761 0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -730,8 +766,8 @@ static const UCHAR SiS_PALTiming[] = {
730 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00 766 0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
731}; 767};
732 768
733static const UCHAR SiS_HiTVExtTiming[] = { 769static const unsigned char SiS_HiTVExtTiming[] = {
734 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, 770 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
735 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, 771 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
736 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, 772 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
737 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, 773 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -741,8 +777,8 @@ static const UCHAR SiS_HiTVExtTiming[] = {
741 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00 777 0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
742}; 778};
743 779
744static const UCHAR SiS_HiTVSt1Timing[] = { 780static const unsigned char SiS_HiTVSt1Timing[] = {
745 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, 781 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
746 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, 782 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
747 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, 783 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
748 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03, 784 0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
@@ -752,8 +788,8 @@ static const UCHAR SiS_HiTVSt1Timing[] = {
752 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00 788 0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
753}; 789};
754 790
755static const UCHAR SiS_HiTVSt2Timing[] = { 791static const unsigned char SiS_HiTVSt2Timing[] = {
756 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64, 792 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
757 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, 793 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
758 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, 794 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
759 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13, 795 0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -764,8 +800,8 @@ static const UCHAR SiS_HiTVSt2Timing[] = {
764}; 800};
765 801
766#if 0 802#if 0
767static const UCHAR SiS_HiTVTextTiming[] = { 803static const unsigned char SiS_HiTVTextTiming[] = {
768 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65, 804 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
769 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d, 805 0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
770 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f, 806 0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
771 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03, 807 0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
@@ -776,8 +812,8 @@ static const UCHAR SiS_HiTVTextTiming[] = {
776}; 812};
777#endif 813#endif
778 814
779static const UCHAR SiS_HiTVGroup3Data[] = { 815static const unsigned char SiS_HiTVGroup3Data[] = {
780 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f, 816 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
781 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6, 817 0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
782 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, 818 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
783 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44, 819 0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
@@ -787,8 +823,8 @@ static const UCHAR SiS_HiTVGroup3Data[] = {
787 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01 823 0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
788}; 824};
789 825
790static const UCHAR SiS_HiTVGroup3Simu[] = { 826static const unsigned char SiS_HiTVGroup3Simu[] = {
791 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95, 827 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
792 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6, 828 0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
793 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, 829 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
794 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11, 830 0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
@@ -799,8 +835,8 @@ static const UCHAR SiS_HiTVGroup3Simu[] = {
799}; 835};
800 836
801#if 0 837#if 0
802static const UCHAR SiS_HiTVGroup3Text[] = { 838static const unsigned char SiS_HiTVGroup3Text[] = {
803 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7, 839 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
804 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6, 840 0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
805 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20, 841 0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
806 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22, 842 0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
@@ -811,136 +847,141 @@ static const UCHAR SiS_HiTVGroup3Text[] = {
811}; 847};
812#endif 848#endif
813 849
814static const UCHAR SiS_NTSCPhase[] = {0x21,0xed,0xba,0x08}; 850static const struct SiS_TVData SiS_StPALData[] =
815static const UCHAR SiS_PALPhase[] = {0x2a,0x05,0xe3,0x00};
816static const UCHAR SiS_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};
817static const UCHAR SiS_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
818static const UCHAR SiS_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
819static const UCHAR SiS_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
820static const UCHAR SiS_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4};
821static const UCHAR SiS_PALNPhase2[] = {0x21,0xF6,0x94,0x46};
822static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
823static const UCHAR SiS_SpecialPhaseM[]= {0x1e,0x83,0x0a,0xe0};
824static const UCHAR SiS_SpecialPhaseJ[]= {0x25,0xd4,0xfd,0x5e};
825
826static const SiS_TVDataStruct SiS_StPALData[] =
827{ 851{
828 { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22}, 852 { 1, 1, 864, 525,1270, 400, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
829 { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22}, 853 { 1, 1, 864, 525,1270, 350, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
830 { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, 854 { 1, 1, 864, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
831 { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, 855 { 1, 1, 864, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
832 { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22}, 856 { 1, 1, 864, 525,1270, 480, 50, 0, 760, 0,0xf4,0xff,0x1c,0x22},
833 { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22} 857 { 1, 1, 864, 525,1270, 600, 50, 0, 0,0x300,0xf4,0xff,0x1c,0x22}
834}; 858};
835 859
836static const SiS_TVDataStruct SiS_ExtPALData[] = 860static const struct SiS_TVData SiS_ExtPALData[] =
837{ 861{
838 { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */ 862 { 27, 10, 848, 448,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
839 { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, 863 { 108, 35, 848, 398,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22},
840 { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18}, 864 { 12, 5, 954, 448,1270, 530, 50, 0, 50, 0,0xf1,0x04,0x1f,0x18},
841 { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a}, 865 { 9, 4, 960, 463,1644, 438, 50, 0, 50, 0,0xf4,0x0b,0x1c,0x0a},
842 { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */ 866 { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
843/*{ 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */ 867 { 36, 25,1060, 648,1270, 530, 438, 0, 438, 0,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 */
844 { 36, 25,1060, 648,1270, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 - better */ 868 { 3, 2,1080, 619,1270, 540, 438, 0, 438, 0,0xf3,0x00,0x1d,0x20}, /* 720x576 */
845 { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */ 869 { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
846 { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 */ 870 { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
847 { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */ 871 { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a} /* 720x480 */
848 { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a} /* 720x480 test */
849}; 872};
850 873
851static const SiS_TVDataStruct SiS_StNTSCData[] = 874static const struct SiS_TVData SiS_StNTSCData[] =
852{ 875{
853 { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18}, 876 { 1, 1, 858, 525,1270, 400, 50, 0, 760, 0,0xf1,0x04,0x1f,0x18},
854 { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18}, 877 { 1, 1, 858, 525,1270, 350, 50, 0, 640, 0,0xf1,0x04,0x1f,0x18},
855 { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18}, 878 { 1, 1, 858, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
856 { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a}, 879 { 1, 1, 858, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
857 { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18} 880 { 1, 1, 858, 525,1270, 480, 0, 0, 760, 0,0xf1,0x04,0x1f,0x18}
858}; 881};
859 882
860static const SiS_TVDataStruct SiS_ExtNTSCData[] = 883static const struct SiS_TVData SiS_ExtNTSCData[] =
861{ 884{
862 { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */ 885 { 143, 65, 858, 443,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
863 { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, 886 { 88, 35, 858, 393,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18},
864 { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18}, 887 { 143, 70, 924, 443,1270, 440, 92, 0, 92, 0,0xf1,0x04,0x1f,0x18},
865 { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a}, 888 { 143, 70, 924, 393,1270, 440, 92, 0, 92, 0,0xf4,0x0b,0x1c,0x0a},
866 { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */ 889 { 143, 76, 836, 523,1270, 440, 224, 0, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
867 { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */ 890 { 143, 120,1056, 643,1270, 440, 0, 1, 0, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
868/*{ 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08},*/ /* 720x480 (old, from 650) */ 891 { 143, 76, 836, 523,1270, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
869 { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */ 892 { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */
870/*{ 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} */ /* 1024x768 (525i) */ 893#if 0 /* flimmert und ist unten abgeschnitten (NTSCHT, NTSC clock) */
871 { 1, 1,1100, 811,1412, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */ 894 { 65, 64,1056, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
872 { 65, 64,1056, 791,1270, 480, 455, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */ 895#endif
896#if 0
897 { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
898#endif
899#if 0
900 { 1, 1,1120, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
901#endif
902#if 0
903 { 1, 1, 938, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
904#endif
905#if 0 /* zoom hin, unten abgeschnitten (NTSC2HT, NTSC1024 clock) */
906 { 1, 1,1072, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
907#endif
908#if 1 /* zu weit links (squeezed) (NTSC2HT, NTSC1024 clock) */
909 { 1, 1,1100, 846,1270, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
910#endif
911#if 0 /* zu weit links, rechts abgeschnitten (NTSC2HT, NTSC1024 clock) */
912 { 1, 1,1100, 846,1412, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
913#endif
873}; 914};
874 915
875static const SiS_TVDataStruct SiS_StHiTVData[] = /* Slave + TVSimu */ 916static const struct SiS_TVData SiS_StHiTVData[] = /* Slave + TVSimu */
876{ 917{
877 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00}, 918 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
878 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, 919 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
879 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00}, 920 { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
880 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, 921 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
881 { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, 922 { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
882 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150,128, 0, 0x00,0x00,0x00,0x00} 923 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150, 1, 0, 0, 0, 0, 0, 0}
883}; 924};
884 925
885static const SiS_TVDataStruct SiS_St2HiTVData[] = /* Slave */ 926static const struct SiS_TVData SiS_St2HiTVData[] = /* Slave */
886{ 927{
887 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, 928 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
888 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, 929 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
889 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, 930 { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
890 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00}, 931 { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
891 { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00}, 932 { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d, 1, 0, 0, 0, 0, 0, 0},
892 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00} 933 { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c, 1, 0, 0, 0, 0, 0, 0}
893}; 934};
894 935
895static const SiS_TVDataStruct SiS_ExtHiTVData[] = 936static const struct SiS_TVData SiS_ExtHiTVData[] =
896{ 937{ /* all ok */
897 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, 938 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
898 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, 939 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
899 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, 940 { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
900 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00}, 941 { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
901 { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */ 942 { 5, 1, 0x348,0x233,0x670,0x3c0,0x166, 1, 0, 0, 0, 0, 0, 0}, /* 640x480 */
902 { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */ 943 { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x600 */
903 { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */ 944 { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 */
904 { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x1024 */ 945 { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x1024 */
905 { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x480 */ 946 { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x480 */
906 { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x576 */ 947 { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x576 */
907 { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x720 */ 948 { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x720 */
908 { 137, 32, 0x3d4,0x233,0x663,0x3bf,0x143, 0, 0, 0x00,0x00,0x00,0x00} /* 960x600 */ 949 { 8, 3, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 960x600 */
909}; 950};
910 951
911static const SiS_TVDataStruct SiS_St525pData[] = 952static const struct SiS_TVData SiS_St525pData[] =
912{ 953{
913 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00}, 954 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
914 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00}, 955 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
915 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00}, 956 { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
916 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00}, 957 { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
917 { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00} 958 { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
918}; 959};
919 960
920static const SiS_TVDataStruct SiS_St750pData[] = 961static const struct SiS_TVData SiS_St750pData[] =
921{ 962{
922 { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00}, 963 { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
923 { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00}, 964 { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
924 { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00}, 965 { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
925 { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00}, 966 { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
926 { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00} 967 { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
927}; 968};
928 969
929static const SiS_TVDataStruct SiS_Ext750pData[] = 970static const struct SiS_TVData SiS_Ext750pData[] =
930{ 971{ /* all ok */
931 { 143, 65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00}, 972 { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0}, /* 320x200/640x400 */
932 { 88, 35, 0x35a,0x189,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00}, 973 { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
933 { 18, 5, 0x339,0x1ae,0x500,0x2d0,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00}, 974 { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
934 { 143, 70, 0x39c,0x189,0x4f6,0x1b8,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00}, 975 { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
935 { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */ 976 { 2, 1, 1100, 590, 1130, 640, 50, 0, 0, 0, 0, 0, 0, 0}, /* 640x480 */
936 { 5, 4, 0x5d8,0x29e,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */ 977 { 3, 2, 1210, 690, 1130, 660, 50, 0, 0, 0, 0, 0, 0, 0}, /* 800x600 OK */
937 { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 720x480 test WORKS */ 978 { 2, 1, 1100, 562, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720x480 OK */
938 { 68, 64, 0x55f,0x346,0x500,0x2a8,0x27e, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */ 979 { 1, 1, 1375, 878, 1130, 640, 638, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 OK */
939 { 5, 2, 0x3a7,0x226,0x500,0x2a8, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x576 */ 980 { 5, 3, 1100, 675, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720/768x576 OK */
940 { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 WORKS */ 981 { 25, 24, 1496, 755, 1120, 680, 50, 0, 0, 0, 0, 0, 0, 0} /* 1280x720 OK */
941}; 982};
942 983
943static const SiS_LCDDataStruct SiS_LCD1280x720Data[] = /* 2.03.00 */ 984static const struct SiS_LCDData SiS_LCD1280x720Data[] = /* 2.03.00 */
944{ 985{
945 { 44, 15, 864, 430, 1408, 806 }, /* 640x400 */ 986 { 44, 15, 864, 430, 1408, 806 }, /* 640x400 */
946 { 128, 35, 792, 385, 1408, 806 }, 987 { 128, 35, 792, 385, 1408, 806 },
@@ -962,7 +1003,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x720Data[] = /* 2.03.00 */
962 * (Note: 1280x768_3 is now special for SiS301/NetVista 1003 * (Note: 1280x768_3 is now special for SiS301/NetVista
963 */ 1004 */
964 1005
965static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] = /* 2.03.00 */ 1006static const struct SiS_LCDData SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
966{ 1007{
967 { 64, 21, 858, 434, 1408, 806 }, /* 640x400 */ 1008 { 64, 21, 858, 434, 1408, 806 }, /* 640x400 */
968 { 32, 9, 858, 372, 1408, 806 }, 1009 { 32, 9, 858, 372, 1408, 806 },
@@ -977,7 +1018,7 @@ static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
977 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 - from Ext */ 1018 { 16, 15, 1600, 750, 1600, 806 } /* 1280x720 - from Ext */
978}; 1019};
979 1020
980static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */ 1021static const struct SiS_LCDData SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
981{ 1022{
982 { 16, 5, 960, 410, 1600, 806 }, /* 640x400 */ 1023 { 16, 5, 960, 410, 1600, 806 }, /* 640x400 */
983 { 64, 21, 1152, 364, 1600, 806 }, 1024 { 64, 21, 1152, 364, 1600, 806 },
@@ -993,7 +1034,7 @@ static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
993}; 1034};
994 1035
995#if 0 /* Not used; _3 now reserved for NetVista (SiS301) */ 1036#if 0 /* Not used; _3 now reserved for NetVista (SiS301) */
996static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] = 1037static const struct SiS_LCDData SiS_LCD1280x768_3Data[] =
997{ 1038{
998 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */ 1039 { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
999 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */ 1040 { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
@@ -1009,7 +1050,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] =
1009}; 1050};
1010#endif 1051#endif
1011 1052
1012static const SiS_LCDDataStruct SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */ 1053static const struct SiS_LCDData SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
1013{ 1054{
1014 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */ 1055 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
1015 { 128, 49, 1232, 361, 1408, 816 }, 1056 { 128, 49, 1232, 361, 1408, 816 },
@@ -1024,7 +1065,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
1024 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */ 1065 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
1025}; 1066};
1026 1067
1027static const SiS_LCDDataStruct SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */ 1068static const struct SiS_LCDData SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
1028{ 1069{
1029 { 97, 42, 1344, 409, 1552, 812 }, /* 640x400 */ 1070 { 97, 42, 1344, 409, 1552, 812 }, /* 640x400 */
1030 { 97, 35, 1280, 358, 1552, 812 }, 1071 { 97, 35, 1280, 358, 1552, 812 },
@@ -1039,7 +1080,42 @@ static const SiS_LCDDataStruct SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
1039 { 97, 90, 1600, 730, 1552, 812 } /* 1280x720 */ 1080 { 97, 90, 1600, 730, 1552, 812 } /* 1280x720 */
1040}; 1081};
1041 1082
1042static const SiS_LCDDataStruct SiS_LCD1280x960Data[] = 1083#if 0
1084static const struct SiS_LCDData SiS_LCD1280x800_3Data[] = /* 2.02.05a (LVDS); m250 */
1085{
1086 { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
1087 { 128, 49, 1232, 361, 1408, 816 },
1088 { 128, 51, 1122, 412, 1408, 816 },
1089 { 128, 49, 1232, 361, 1408, 816 },
1090 { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
1091 { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
1092 { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
1093 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1094 { 1, 1, 1408, 816, 1408, 816 }, /* 1280x800 */
1095 { 0, 0, 0, 0, 0, 0 }, /* 1280x768 - patch index */
1096 { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
1097};
1098#endif
1099
1100static const struct SiS_LCDData SiS_LCD1280x854Data[] = /* 2.21.00CS (LVDS) */
1101{
1102 { 56, 15, 936, 410, 1664, 861 }, /* 640x400 */
1103 { 64, 25, 1586, 355, 1664, 861 },
1104 { 56, 15, 936, 410, 1664, 861 },
1105 { 64, 25, 1586, 355, 1664, 861 },
1106 { 91, 45, 1464, 485, 1664, 861 }, /* 640x480 */
1107 { 182, 75, 976, 605, 1664, 861 }, /* 800x600 */
1108 { 91, 66, 1342, 774, 1664, 861 }, /* 1024x768 */
1109 { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
1110 { 26, 25, 1708, 807, 1664, 861 }, /* 1280x800 */
1111 { 13, 12, 1708, 774, 1664, 861 }, /* 1280x768 - patch index */
1112 { 52, 45, 1708, 725, 1664, 861 }, /* 1280x720 */
1113 { 0, 0, 0, 0, 0, 0 },
1114 { 0, 0, 0, 0, 0, 0 },
1115 { 1, 1, 1664, 861, 1664, 861 } /* 1280x854 */
1116};
1117
1118static const struct SiS_LCDData SiS_LCD1280x960Data[] =
1043{ 1119{
1044 { 9, 2, 800, 500, 1800, 1000 }, 1120 { 9, 2, 800, 500, 1800, 1000 },
1045 { 9, 2, 800, 500, 1800, 1000 }, 1121 { 9, 2, 800, 500, 1800, 1000 },
@@ -1049,10 +1125,15 @@ static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
1049 { 30, 11, 1056, 625, 1800, 1000 }, 1125 { 30, 11, 1056, 625, 1800, 1000 },
1050 { 5, 3, 1350, 800, 1800, 1000 }, 1126 { 5, 3, 1350, 800, 1800, 1000 },
1051 { 1, 1, 1576, 1050, 1576, 1050 }, 1127 { 1, 1, 1576, 1050, 1576, 1050 },
1052 { 1, 1, 1800, 1000, 1800, 1000 } 1128 { 1, 1, 1800, 1000, 1800, 1000 },
1129 { 0, 0, 0, 0, 0, 0 },
1130 { 0, 0, 0, 0, 0, 0 },
1131 { 0, 0, 0, 0, 0, 0 },
1132 { 0, 0, 0, 0, 0, 0 },
1133 { 0, 0, 0, 0, 0, 0 }
1053}; 1134};
1054 1135
1055static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] = 1136static const struct SiS_LCDData SiS_StLCD1400x1050Data[] =
1056{ 1137{
1057 { 211, 100, 2100, 408, 1688, 1066 }, 1138 { 211, 100, 2100, 408, 1688, 1066 },
1058 { 211, 64, 1536, 358, 1688, 1066 }, 1139 { 211, 64, 1536, 358, 1688, 1066 },
@@ -1062,10 +1143,15 @@ static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
1062 { 211, 72, 1008, 609, 1688, 1066 }, 1143 { 211, 72, 1008, 609, 1688, 1066 },
1063 { 211, 128, 1400, 776, 1688, 1066 }, 1144 { 211, 128, 1400, 776, 1688, 1066 },
1064 { 211, 205, 1680, 1041, 1688, 1066 }, 1145 { 211, 205, 1680, 1041, 1688, 1066 },
1065 { 1, 1, 1688, 1066, 1688, 1066 } 1146 { 1, 1, 1688, 1066, 1688, 1066 },
1147 { 0, 0, 0, 0, 0, 0 },
1148 { 0, 0, 0, 0, 0, 0 },
1149 { 0, 0, 0, 0, 0, 0 },
1150 { 0, 0, 0, 0, 0, 0 },
1151 { 0, 0, 0, 0, 0, 0 }
1066}; 1152};
1067 1153
1068static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] = 1154static const struct SiS_LCDData SiS_ExtLCD1400x1050Data[] =
1069{ 1155{
1070/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */ 1156/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */
1071 { 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */ 1157 { 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */
@@ -1080,10 +1166,13 @@ static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
1080 { 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */ 1166 { 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
1081 { 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */ 1167 { 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
1082 { 0, 0, 0, 0, 0, 0 }, /* kludge */ 1168 { 0, 0, 0, 0, 0, 0 }, /* kludge */
1083 { 211, 120, 1400, 730, 1688, 1066 } /* 1280x720 */ 1169 { 211, 120, 1400, 730, 1688, 1066 }, /* 1280x720 */
1170 { 0, 0, 0, 0, 0, 0 },
1171 { 0, 0, 0, 0, 0, 0 },
1172 { 0, 0, 0, 0, 0, 0 }
1084}; 1173};
1085 1174
1086static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] = 1175static const struct SiS_LCDData SiS_LCD1680x1050Data[] =
1087{ 1176{
1088 { 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */ 1177 { 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */
1089 { 10, 3, 1710, 362, 1900, 1066 }, 1178 { 10, 3, 1710, 362, 1900, 1066 },
@@ -1097,10 +1186,11 @@ static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] =
1097 { 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch index */ 1186 { 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch index */
1098 { 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */ 1187 { 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */
1099 { 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */ 1188 { 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
1100 { 1, 1, 1900, 1066, 1900, 1066 } /* 12 1680x1050 */ 1189 { 1, 1, 1900, 1066, 1900, 1066 }, /* 12 1680x1050 */
1190 { 0, 0, 0, 0, 0, 0 }
1101}; 1191};
1102 1192
1103static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] = 1193static const struct SiS_LCDData SiS_StLCD1600x1200Data[] =
1104{ 1194{
1105 {27, 4, 800, 500, 2160, 1250 }, 1195 {27, 4, 800, 500, 2160, 1250 },
1106 {27, 4, 800, 500, 2160, 1250 }, 1196 {27, 4, 800, 500, 2160, 1250 },
@@ -1111,10 +1201,14 @@ static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
1111 { 5, 2,1350, 800, 2160, 1250 }, 1201 { 5, 2,1350, 800, 2160, 1250 },
1112 {135,88,1600,1100, 2160, 1250 }, 1202 {135,88,1600,1100, 2160, 1250 },
1113 {72, 49,1680,1092, 2160, 1250 }, 1203 {72, 49,1680,1092, 2160, 1250 },
1114 { 1, 1,2160,1250, 2160, 1250 } 1204 { 1, 1,2160,1250, 2160, 1250 },
1205 { 0, 0, 0, 0, 0, 0 },
1206 { 0, 0, 0, 0, 0, 0 },
1207 { 0, 0, 0, 0, 0, 0 },
1208 { 0, 0, 0, 0, 0, 0 }
1115}; 1209};
1116 1210
1117static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] = 1211static const struct SiS_LCDData SiS_ExtLCD1600x1200Data[] =
1118{ 1212{
1119 {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */ 1213 {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
1120/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */ 1214/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */
@@ -1127,10 +1221,14 @@ static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
1127 { 5, 2,1350, 800, 2160, 1250 }, 1221 { 5, 2,1350, 800, 2160, 1250 },
1128 {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */ 1222 {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
1129 {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */ 1223 {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
1130 { 1, 1,2160,1250, 2160, 1250 } 1224 { 1, 1,2160,1250, 2160, 1250 },
1225 { 0, 0, 0, 0, 0, 0 },
1226 { 0, 0, 0, 0, 0, 0 },
1227 { 0, 0, 0, 0, 0, 0 },
1228 { 0, 0, 0, 0, 0, 0 }
1131}; 1229};
1132 1230
1133static const SiS_LCDDataStruct SiS_NoScaleData[] = 1231static const struct SiS_LCDData SiS_NoScaleData[] =
1134{ 1232{
1135 { 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */ 1233 { 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */
1136 { 1, 1, 800, 449, 800, 449 }, 1234 { 1, 1, 800, 449, 800, 449 },
@@ -1162,14 +1260,18 @@ static const SiS_LCDDataStruct SiS_NoScaleData[] =
1162 { 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */ 1260 { 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */
1163 { 1, 1,1104, 563,1104, 563 }, /* 0x1c: 960x540 */ 1261 { 1, 1,1104, 563,1104, 563 }, /* 0x1c: 960x540 */
1164 { 1, 1,1120, 618,1120, 618 }, /* 0x1d: 960x600 */ 1262 { 1, 1,1120, 618,1120, 618 }, /* 0x1d: 960x600 */
1165 { 1, 1,1408, 816,1408, 816 } /* 0x1f: 1280x800 (TMDS special) */ 1263 { 1, 1,1408, 816,1408, 816 }, /* 0x1f: 1280x800 (TMDS special) */
1264 { 1, 1,1760,1235,1760,1235 }, /* 0x20: 1600x1200 for LCDA */
1265 { 1, 1,2048,1320,2048,1320 }, /* 0x21: 1600x1200 for non-SiS LVDS */
1266 { 1, 1,1664, 861,1664, 861 } /* 0x22: 1280x854 */
1166}; 1267};
1167 1268
1168/**************************************************************/ 1269/**************************************************************/
1169/* LVDS ----------------------------------------------------- */ 1270/* LVDS ----------------------------------------------------- */
1170/**************************************************************/ 1271/**************************************************************/
1171 1272
1172static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]= 1273/* FSTN/DSTN 320x240, 2 variants */
1274static const struct SiS_LVDSData SiS_LVDS320x240Data_1[]=
1173{ 1275{
1174 { 848, 433, 400, 525}, 1276 { 848, 433, 400, 525},
1175 { 848, 389, 400, 525}, 1277 { 848, 389, 400, 525},
@@ -1177,157 +1279,40 @@ static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]=
1177 { 848, 389, 400, 525}, 1279 { 848, 389, 400, 525},
1178 { 848, 518, 400, 525}, 1280 { 848, 518, 400, 525},
1179 {1056, 628, 400, 525}, 1281 {1056, 628, 400, 525},
1180 { 400, 525, 400, 525}, 1282 { 400, 525, 400, 525} /* xSTN */
1181 { 800, 449,1000, 644},
1182 { 800, 525,1000, 635}
1183}; 1283};
1184 1284
1185static const SiS_LVDSDataStruct SiS_LVDS640x480Data_1[]= 1285static const struct SiS_LVDSData SiS_LVDS320x240Data_2[]=
1186{ 1286{
1187 { 800, 445, 800, 525}, /* 800, 449, 800, 449 */ 1287 { 800, 445, 800, 525},
1188 { 800, 395, 800, 525}, 1288 { 800, 395, 800, 525},
1189 { 800, 445, 800, 525}, 1289 { 800, 445, 800, 525},
1190 { 800, 395, 800, 525}, 1290 { 800, 395, 800, 525},
1191 { 800, 525, 800, 525}, 1291 { 800, 525, 800, 525},
1192 { 800, 525, 800, 525}, /* pseudo */ 1292 {1056, 628,1056, 628},
1193 { 800, 525, 800, 525} /* pseudo */ 1293 { 480, 525, 480, 525} /* xSTN */
1194}; 1294};
1195 1295
1196/* FSTN 320x240 */ 1296static const struct SiS_LVDSData SiS_LVDS640x480Data_1[]=
1197static const SiS_LVDSDataStruct SiS_LVDS640x480Data_2[]=
1198{ 1297{
1199 { 800, 445, 800, 525}, 1298 { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
1200 { 800, 395, 800, 525}, 1299 { 800, 395, 800, 525},
1201 { 800, 445, 800, 525}, 1300 { 800, 445, 800, 525},
1202 { 800, 395, 800, 525}, 1301 { 800, 395, 800, 525},
1203 { 800, 525, 800, 525}, 1302 { 800, 525, 800, 525}
1204 { 800, 525, 800, 525}, /* pseudo */
1205 { 800, 525, 800, 525} /* pseudo */
1206}; 1303};
1207 1304
1208static const SiS_LVDSDataStruct SiS_LVDS800x600Data_1[]= 1305static const struct SiS_LVDSData SiS_LVDS800x600Data_1[]=
1209{ 1306{
1210 { 848, 433,1060, 629}, 1307 { 848, 433,1060, 629},
1211 { 848, 389,1060, 629}, 1308 { 848, 389,1060, 629},
1212 { 848, 433,1060, 629}, 1309 { 848, 433,1060, 629},
1213 { 848, 389,1060, 629}, 1310 { 848, 389,1060, 629},
1214 { 848, 518,1060, 629}, 1311 { 848, 518,1060, 629},
1215 {1056, 628,1056, 628},
1216 {1056, 628,1056, 628} 1312 {1056, 628,1056, 628}
1217}; 1313};
1218 1314
1219static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]= 1315static const struct SiS_LVDSData SiS_LVDS1024x600Data_1[] =
1220{
1221 {1056, 628,1056, 628}
1222};
1223
1224static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]=
1225{
1226 { 840, 438,1344, 806},
1227 { 840, 409,1344, 806},
1228 { 840, 438,1344, 806},
1229 { 840, 409,1344, 806},
1230 { 840, 518,1344, 806}, /* 640x480 */
1231 {1050, 638,1344, 806}, /* 800x600 */
1232 {1344, 806,1344, 806}, /* 1024x768 */
1233};
1234
1235static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]=
1236{
1237 {1344, 806,1344, 806}
1238};
1239
1240static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]=
1241{
1242 {1048, 442,1688,1066},
1243 {1048, 392,1688,1066},
1244 {1048, 442,1688,1066},
1245 {1048, 392,1688,1066},
1246 {1048, 522,1688,1066},
1247 {1208, 642,1688,1066},
1248 {1432, 810,1688,1066},
1249 {1688,1066,1688,1066}
1250};
1251
1252static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_2[]=
1253{
1254 {1688,1066,1688,1066}
1255};
1256
1257static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_1[]=
1258{
1259 { 928, 416, 1688,1066},
1260 { 928, 366, 1688,1066},
1261 { 928, 416, 1688,1066},
1262 { 928, 366, 1688,1066},
1263 { 928, 496, 1688,1066},
1264 {1088, 616, 1688,1066},
1265 {1312, 784, 1688,1066},
1266 {1568,1040, 1688,1066},
1267 {1688,1066, 1688,1066}
1268};
1269
1270static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_2[]=
1271{
1272 {1688,1066, 1688,1066}
1273};
1274
1275static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_1[]=
1276{
1277 {1088, 520, 2048,1320},
1278 {1088, 470, 2048,1320},
1279 {1088, 520, 2048,1320},
1280 {1088, 470, 2048,1320},
1281 {1088, 600, 2048,1320},
1282 {1248, 720, 2048,1320},
1283 {1472, 888, 2048,1320},
1284 {1728,1144, 2048,1320},
1285 {1848,1170, 2048,1320},
1286 {2048,1320, 2048,1320}
1287};
1288
1289static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_2[]=
1290{
1291 {2048,1320, 2048,1320}
1292};
1293
1294static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_1[]=
1295{
1296 { 840, 438,1344, 806},
1297 { 840, 409,1344, 806},
1298 { 840, 438,1344, 806},
1299 { 840, 409,1344, 806},
1300 { 840, 518,1344, 806},
1301 {1050, 638,1344, 806},
1302 {1344, 806,1344, 806},
1303 { 800, 449,1280, 801},
1304 { 800, 525,1280, 813}
1305};
1306
1307static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_2[]=
1308{
1309 {1344, 806,1344, 806}
1310};
1311
1312static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_1[]=
1313{
1314 { 768, 438, 1408, 806},
1315 { 768, 388, 1408, 806},
1316 { 768, 438, 1408, 806},
1317 { 768, 388, 1408, 806},
1318 { 768, 518, 1408, 806},
1319 { 928, 638, 1408, 806},
1320 {1152, 806, 1408, 806},
1321 {1408, 806, 1408, 806},
1322 {1408, 806, 1408, 806}
1323};
1324
1325static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_2[]=
1326{
1327 {1408, 806, 1408, 806}
1328};
1329
1330static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
1331{ 1316{
1332 { 840, 604,1344, 800}, 1317 { 840, 604,1344, 800},
1333 { 840, 560,1344, 800}, 1318 { 840, 560,1344, 800},
@@ -1338,124 +1323,18 @@ static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
1338 {1344, 800,1344, 800} 1323 {1344, 800,1344, 800}
1339}; 1324};
1340 1325
1341static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] = 1326static const struct SiS_LVDSData SiS_LVDS1024x768Data_1[]=
1342{
1343 {1344, 800,1344, 800}
1344};
1345
1346static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] =
1347{ 1327{
1348 { 840, 438,1344, 806}, 1328 { 840, 438,1344, 806},
1349 { 840, 409,1344, 806}, 1329 { 840, 409,1344, 806},
1350 { 840, 438,1344, 806}, 1330 { 840, 438,1344, 806},
1351 { 840, 409,1344, 806}, 1331 { 840, 409,1344, 806},
1352 { 840, 518,1344, 806}, 1332 { 840, 518,1344, 806}, /* 640x480 */
1353 {1050, 638,1344, 806},
1354 {1344, 806,1344, 806}
1355};
1356
1357static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] =
1358{
1359 {1344, 806,1344, 806}
1360};
1361
1362/* Pass 1:1 data */
1363static const SiS_LVDSDataStruct SiS_LVDSXXXxXXXData_1[]=
1364{
1365 { 800, 449, 800, 449},
1366 { 800, 449, 800, 449},
1367 { 900, 449, 900, 449},
1368 { 900, 449, 900, 449},
1369 { 800, 525, 800, 525}, /* 640x480 */
1370 {1056, 628, 1056, 628}, /* 800x600 */
1371 {1344, 806, 1344, 806}, /* 1024x768 */
1372 {1688,1066, 1688,1066}, /* 1280x1024 */ /* INSERTED */
1373 {1688, 806, 1688, 806}, /* 1280x768 */
1374};
1375
1376/* Custom data for Barco iQ R series */
1377static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_1[]=
1378{
1379 { 832, 438,1331, 806},
1380 { 832, 388,1331, 806},
1381 { 832, 438,1331, 806},
1382 { 832, 388,1331, 806},
1383 { 832, 518,1331, 806},
1384 {1050, 638,1344, 806},
1385 {1344, 806,1344, 806},
1386 {1688,1066,1688,1066},
1387 {1688,1066,1688,1066} /* 1360x1024 */
1388};
1389
1390/* Custom data for Barco iQ R series */
1391static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_2[]=
1392{
1393 {1344, 806,1344, 806},
1394 {1344, 806,1344, 806},
1395 {1344, 806,1344, 806},
1396 {1344, 806,1344, 806},
1397 {1344, 806,1344, 806},
1398 {1344, 806,1344, 806},
1399 {1344, 806,1344, 806},
1400 {1688,1066,1688,1066},
1401 {1688,1066,1688,1066} /* 1360x1024 */
1402};
1403
1404/* Custom data for Barco iQ G series */
1405static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_1[]=
1406{
1407 { 832, 438,1331, 806},
1408 { 832, 409,1331, 806},
1409 { 832, 438,1331, 806},
1410 { 832, 409,1331, 806},
1411 { 832, 518,1331, 806}, /* 640x480 */
1412 {1050, 638,1344, 806}, /* 800x600 */ 1333 {1050, 638,1344, 806}, /* 800x600 */
1413 {1344, 806,1344, 806}, /* 1024x768 */ 1334 {1344, 806,1344, 806}, /* 1024x768 */
1414}; 1335};
1415 1336
1416/* Custom data for Barco iQ G series */ 1337static const struct SiS_LVDSData SiS_CHTVUNTSCData[]=
1417static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_2[]=
1418{
1419 {1344, 806,1344, 806}
1420};
1421
1422/* Custom data for 848x480 parallel panel */
1423static const SiS_LVDSDataStruct SiS_LVDS848x480Data_1[]=
1424{
1425 { 0, 0, 0, 0},
1426 { 0, 0, 0, 0},
1427 { 0, 0, 0, 0},
1428 { 0, 0, 0, 0},
1429 {1088, 525,1088, 525}, /* 640x480 TODO */
1430 {1088, 525,1088, 525}, /* 800x600 TODO */
1431 {1088, 525,1088, 525}, /* 1024x768 TODO */
1432 { 0, 0, 0, 0},
1433 { 0, 0, 0, 0},
1434 { 0, 0, 0, 0},
1435 { 0, 0, 0, 0},
1436 {1088, 525,1088, 525}, /* 848x480 */
1437 {1088, 525,1088, 525} /* 1360x768 TODO */
1438};
1439
1440/* Custom data for 848x480 parallel panel */
1441static const SiS_LVDSDataStruct SiS_LVDS848x480Data_2[]=
1442{
1443 { 0, 0, 0, 0},
1444 { 0, 0, 0, 0},
1445 { 0, 0, 0, 0},
1446 { 0, 0, 0, 0},
1447 {1088, 525,1088, 525}, /* 640x480 */
1448 {1088, 525,1088, 525}, /* 800x600 */
1449 {1088, 525,1088, 525}, /* 1024x768 */
1450 { 0, 0, 0, 0},
1451 { 0, 0, 0, 0},
1452 { 0, 0, 0, 0},
1453 { 0, 0, 0, 0},
1454 {1088, 525,1088, 525}, /* 848x480 */
1455 {1088, 525,1088, 525} /* 1360x768 TODO */
1456};
1457
1458static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
1459{ 1338{
1460 { 840, 600, 840, 600}, 1339 { 840, 600, 840, 600},
1461 { 840, 600, 840, 600}, 1340 { 840, 600, 840, 600},
@@ -1466,7 +1345,7 @@ static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
1466 {1160, 945,1160, 945} 1345 {1160, 945,1160, 945}
1467}; 1346};
1468 1347
1469static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]= 1348static const struct SiS_LVDSData SiS_CHTVONTSCData[]=
1470{ 1349{
1471 { 840, 525, 840, 525}, 1350 { 840, 525, 840, 525},
1472 { 840, 525, 840, 525}, 1351 { 840, 525, 840, 525},
@@ -1477,55 +1356,9 @@ static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]=
1477 {1160, 840,1160, 840} 1356 {1160, 840,1160, 840}
1478}; 1357};
1479 1358
1480/* Chrontel TV Skew */
1481
1482static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]=
1483{
1484 { 0, 0},
1485 { 0, 0},
1486 { 0, 0},
1487 { 0, 0},
1488 { 0, 0},
1489 { 0, 0},
1490 { 0, 0}
1491};
1492
1493static const SiS_LVDSDesStruct SiS_CHTVONTSCDesData[]=
1494{
1495 { 0, 0},
1496 { 0, 0},
1497 { 0, 0},
1498 { 0, 0},
1499 { 0, 0},
1500 { 0, 0},
1501 { 0, 0}
1502};
1503
1504static const SiS_LVDSDesStruct SiS_CHTVUPALDesData[]=
1505{
1506 {256, 0},
1507 {256, 0},
1508 {256, 0},
1509 {256, 0},
1510 { 0, 0},
1511 { 0, 0},
1512 { 0, 0}
1513};
1514
1515static const SiS_LVDSDesStruct SiS_CHTVOPALDesData[]=
1516{
1517 {256, 0},
1518 {256, 0},
1519 {256, 0},
1520 {256, 0},
1521 { 0, 0},
1522 { 0, 0},
1523 { 0, 0}
1524};
1525
1526/* CRT1 CRTC data for slave modes */ 1359/* CRT1 CRTC data for slave modes */
1527 1360
1528static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] = 1361static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_1[] =
1529{ 1362{
1530 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, 1363 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1531 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, 1364 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1550,48 +1383,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] =
1550 0x00 }} 1383 0x00 }}
1551}; 1384};
1552 1385
1553static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1[] = 1386static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2[] =
1554{
1555 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1556 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1557 0x00}},
1558 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1559 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1560 0x00}},
1561 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1562 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1563 0x00}},
1564 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1565 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1566 0x00}},
1567 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1568 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1569 0x00}},
1570 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1571 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1572 0x01}}
1573};
1574
1575static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1_H[] =
1576{
1577 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1578 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1579 0x00}},
1580 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1581 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1582 0x00}},
1583 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1584 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1585 0x00}},
1586 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1587 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1588 0x00}},
1589 {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
1590 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1591 0x00}}
1592};
1593
1594static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
1595{ 1387{
1596 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, 1388 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1597 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05, 1389 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
@@ -1611,12 +1403,17 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
1611 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0, 1403 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1612 0x58,0x8c,0x57,0x73,0x20,0x00,0x06, 1404 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1613 0x01}}, 1405 0x01}},
1406#if 0
1614 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e, 1407 {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
1615 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00, 1408 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
1616 0x00}} 1409 0x00}}
1410#endif
1411 {{0x5f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
1412 0xe9,0x8b,0xe8,0x0c,0x00,0x00,0x05,
1413 0x00}},
1617}; 1414};
1618 1415
1619static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] = 1416static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2_H[] =
1620{ 1417{
1621 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, 1418 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1622 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, 1419 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1641,7 +1438,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] =
1641 0x00}} 1438 0x00}}
1642}; 1439};
1643 1440
1644static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] = 1441static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3[] =
1645{ 1442{
1646 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e, 1443 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1647 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05, 1444 0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
@@ -1666,7 +1463,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] =
1666 0x00}} 1463 0x00}}
1667}; 1464};
1668 1465
1669static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] = 1466static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3_H[] =
1670{ 1467{
1671 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f, 1468 {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
1672 0x90,0x85,0x8f,0xab,0x30,0x00,0x05, 1469 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1691,778 +1488,175 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] =
1691 0x00}} 1488 0x00}}
1692}; 1489};
1693 1490
1694static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1[] = 1491static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1[] =
1695{
1696 {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
1697 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
1698 0x00}},
1699 {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
1700 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
1701 0x00}},
1702 {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
1703 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
1704 0x00}},
1705 {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
1706 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
1707 0x00}},
1708 {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
1709 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
1710 0x00}},
1711 {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
1712 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
1713 0x01}},
1714 {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
1715 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
1716 0x01}}
1717};
1718
1719static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1_H[] =
1720{
1721 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1722 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1723 0x00}},
1724 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1725 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1726 0x00}},
1727 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1728 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1729 0x00}},
1730 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1731 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1732 0x00}},
1733 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1734 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
1735 0x00}},
1736 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1737 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1738 0x01}},
1739 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1740 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1741 0x01}}
1742};
1743
1744static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2[] =
1745{
1746 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1747 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1748 0x00}},
1749 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1750 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1751 0x00}},
1752 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1753 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1754 0x00}},
1755 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1756 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1757 0x00}},
1758 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1759 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1760 0x00}},
1761 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1762 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1763 0x01}},
1764 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1765 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1766 0x01}}
1767};
1768
1769static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2_H[] =
1770{
1771 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1772 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1773 0x00}},
1774 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1775 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1776 0x00}},
1777 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1778 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1779 0x00}},
1780 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1781 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1782 0x00}},
1783 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1784 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1785 0x00}},
1786 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1787 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1788 0x01}},
1789 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1790 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1791 0x01}}
1792};
1793
1794static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1[] =
1795{
1796 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1797 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1798 0x00}},
1799 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1800 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1801 0x00}},
1802 {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
1803 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
1804 0x00}},
1805 {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
1806 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
1807 0x00}},
1808 {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
1809 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
1810 0x00}},
1811 {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
1812 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
1813 0x01}},
1814 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1815 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1816 0x01}}
1817};
1818
1819static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1_H[] =
1820{
1821 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1822 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1823 0x00}},
1824 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1825 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1826 0x00}},
1827 {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
1828 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
1829 0x00}},
1830 {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
1831 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
1832 0x00}},
1833 {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
1834 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
1835 0x00}},
1836 {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
1837 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
1838 0x01}},
1839 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1840 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1841 0x01}}
1842};
1843
1844static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2[] =
1845{
1846 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1847 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1848 0x00}},
1849 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1850 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1851 0x00}},
1852 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1853 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
1854 0x00}},
1855 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1856 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
1857 0x00}},
1858 {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
1859 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
1860 0x00}},
1861 {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
1862 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
1863 0x01}},
1864 {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
1865 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
1866 0x01}}
1867};
1868
1869static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2_H[] =
1870{
1871 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1872 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1873 0x00}},
1874 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1875 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1876 0x00}},
1877 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1878 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
1879 0x00}},
1880 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1881 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
1882 0x00}},
1883 {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
1884 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
1885 0x00}},
1886 {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
1887 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
1888 0x01}},
1889 {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
1890 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
1891 0x01}}
1892};
1893
1894static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1[] =
1895{
1896 {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
1897 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
1898 0x00}},
1899 {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
1900 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
1901 0x00}},
1902 {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
1903 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
1904 0x00}},
1905 {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
1906 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
1907 0x00}},
1908 {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
1909 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
1910 0x00}},
1911 {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
1912 0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
1913 0x01}},
1914 {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
1915 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
1916 0x01}},
1917 {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
1918 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
1919 0x01}},
1920 {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
1921 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
1922 0x01}}
1923};
1924
1925static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1_H[] =
1926{ 1492{
1927 {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f, 1493 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1928 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05, 1494 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1929 0x00}},
1930 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
1931 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1932 0x00}},
1933 {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
1934 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
1935 0x00}},
1936 {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
1937 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
1938 0x00}},
1939 {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
1940 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
1941 0x00}}, 1495 0x00}},
1942 {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0, 1496 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1943 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01, 1497 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1944 0x01}},
1945 {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
1946 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
1947 0x01}},
1948 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
1949 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
1950 0x01}},
1951 {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
1952 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
1953 0x01}}
1954};
1955
1956static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2[] =
1957{
1958 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
1959 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
1960 0x00}}, 1498 0x00}},
1961 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, 1499 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1962 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02, 1500 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1963 0x00}}, 1501 0x00}},
1964 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, 1502 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1965 0x54,0x86,0xdb,0xda,0x00,0x00,0x02, 1503 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1966 0x00}}, 1504 0x00}},
1967 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb, 1505 {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
1968 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02, 1506 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
1969 0x00}}, 1507 0x00}},
1970 {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3, 1508 {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
1971 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02, 1509 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
1972 0x01}},
1973 {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
1974 0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
1975 0x01}},
1976 {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
1977 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
1978 0x01}},
1979 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
1980 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
1981 0x01}},
1982 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
1983 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
1984 0x01}} 1510 0x01}}
1985}; 1511};
1986 1512
1987static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2_H[] = 1513static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
1988{ 1514{
1989 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, 1515 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1990 0x54,0x86,0xdb,0xda,0x00,0x00,0x01, 1516 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1991 0x00}}, 1517 0x00}},
1992 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, 1518 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1993 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01, 1519 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
1994 0x00}}, 1520 0x00}},
1995 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, 1521 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1996 0x54,0x86,0xdb,0xda,0x00,0x00,0x01, 1522 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
1997 0x00}}, 1523 0x00}},
1998 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb, 1524 {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
1999 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01, 1525 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
2000 0x00}}, 1526 0x00}},
2001 {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3, 1527 {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
2002 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01, 1528 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
2003 0x01}}, 1529 0x00}}
2004 {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
2005 0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
2006 0x01}},
2007 {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
2008 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
2009 0x01}},
2010 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
2011 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
2012 0x01}},
2013 {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
2014 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
2015 0x01}}
2016};
2017
2018/**************************************************************/
2019/* COMMON --------------------------------------------------- */
2020/**************************************************************/
2021
2022#ifdef LINUX_XF86
2023
2024#define SIS_PL_HSYNCP 0x01
2025#define SIS_PL_HSYNCN 0x02
2026#define SIS_PL_VSYNCP 0x04
2027#define SIS_PL_VSYNCN 0x08
2028#define SIS_PL_DVI 0x80
2029
2030typedef struct _SiS_PlasmaModes
2031{
2032 const char *name;
2033 ULONG clock;
2034 USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
2035 USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
2036 UCHAR SyncFlags;
2037} SiS_PlasmaModes;
2038
2039typedef struct _SiS_PlasmaTables
2040{
2041 USHORT vendor;
2042 UCHAR productnum;
2043 USHORT product[5];
2044 const char *DDCnames[5];
2045 const char *plasmaname;
2046 USHORT maxx,maxy;
2047 USHORT prefx, prefy;
2048 UCHAR modenum;
2049 UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */
2050} SiS_PlasmaTables;
2051
2052static const SiS_PlasmaModes SiS_PlasmaMode[] = {
2053 { "640x400", /* 00: IBM 400@70 */
2054 25175,
2055 640, 800, 17, 64,
2056 400, 449, 13, 2,
2057 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2058 { "640x480", /* 01: VESA 480@72 */
2059 31500,
2060 640, 832, 24, 40,
2061 480, 520, 9, 3,
2062 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2063 { "800x600", /* 02: VESA 600@72 */
2064 50000,
2065 800, 1040, 56, 120,
2066 600, 666, 37, 6,
2067 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2068 { "864x480", /* 03: Cereb wide 1 */
2069 42526,
2070 864, 1134, 22, 86,
2071 480, 500, 1, 3,
2072 SIS_PL_HSYNCP | SIS_PL_VSYNCN },
2073 { "848x480", /* 04: VESA wide (NEC1) */
2074 33750,
2075 848, 1088, 16, 112,
2076 480, 517, 6, 8,
2077 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2078 { "1024x576", /* 05: VESA wide (NEC2) */
2079 47250,
2080 1024, 1320, 16, 144,
2081 576, 596, 2, 4,
2082 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2083 { "1280x720", /* 06: VESA wide (NEC3) */
2084 76500,
2085 1280, 1696, 48, 176,
2086 720, 750, 4, 8,
2087 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2088 { "1360x765", /* 07: VESA wide (NEC4) */
2089 85500,
2090 1360, 1792, 64, 176,
2091 765, 795, 4, 8,
2092 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2093 { "1024x600", /* 08: CEREB wide 2 */
2094 51200,
2095 1024, 1352, 51, 164,
2096 600, 628, 1, 4,
2097 SIS_PL_HSYNCN | SIS_PL_VSYNCP },
2098 { "1024x768", /* 09: VESA 768@75 */
2099 78750,
2100 1024, 1312, 16, 96,
2101 768, 800, 1, 3,
2102 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2103 { "1152x864", /* 10: VESA 1152x864@75 */
2104 108000,
2105 1152, 1600, 64, 128,
2106 864, 900, 1, 3,
2107 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2108 { "1280x1024", /* 11: VESA 1024@60 */
2109 108000,
2110 1280, 1688, 48, 112,
2111 1024, 1066, 1, 3,
2112 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2113 { "1280x768", /* 12: W_XGA */
2114 81000,
2115 1280, 1688, 48, 112,
2116 768, 802, 3, 6,
2117 SIS_PL_HSYNCP | SIS_PL_VSYNCN },
2118 { "1280x768", /* 13: I/O Data W_XGA@56Hz */
2119 76064,
2120 1280, 1688, 48, 112,
2121 768, 802, 2, 3,
2122 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2123 { "1376x768", /* 14: I/O Wide XGA */
2124 87340,
2125 1376, 1808, 32, 128,
2126 768, 806, 3, 6,
2127 SIS_PL_HSYNCN | SIS_PL_VSYNCP },
2128 { "1280x960", /* 15: VESA 960@60 */
2129 108000,
2130 1280, 1800, 96, 112,
2131 960, 1000, 1, 3,
2132 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2133 { "1400x1050", /* 16: VESA 1050@60Hz */
2134 108000,
2135 1400, 1688, 48, 112,
2136 1050, 1066, 1, 3,
2137 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2138 { "1360x768", /* 17: VESA wide (NEC4/2) */
2139 85500,
2140 1360, 1792, 64, 112,
2141 765, 795, 3, 6,
2142 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2143 { "800x600", /* 18: VESA 600@56 */
2144 36000,
2145 800, 1024, 24, 2,
2146 600, 625, 1, 2,
2147 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2148 { "1072x600", /* 19: Panasonic 1072x600 (sync?) */
2149 54100,
2150 1072, 1424, 48, 176,
2151 600, 628, 16, 1,
2152 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2153 { "848x480", /* 20: Panasonic 848x480 (sync?) */
2154 33070, /* is 852x480, but we can't use 852 */
2155 848, 1068, 20, 40, /* differs from DDC data, better centered */
2156 480, 516, 3, 5, /* won't work assumingly, because data is % 8 */
2157 SIS_PL_HSYNCN | SIS_PL_VSYNCN },
2158 { "1280x720", /* 21: WIDE720(60) (aka "750p") (Panasonic) */
2159 74300,
2160 1280, 1650,110, 40,
2161 720, 750, 5, 5,
2162 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2163 { "1280x768", /* 22: 1280x768@56.5 (Panasonic) */
2164 76200, /* (According to manual not supported for HDMI; but works) */
2165 1280, 1680, 16, 24,
2166 768, 802, 2, 5,
2167 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2168 { "1280x720@50", /* 23: WIDE720(50) (aka "750p") (Panasonic) */
2169 74300, /* Panasonic states 45.0kHz. Not possible. This one works (with some overscan) */
2170 1280, 1980,400, 80,
2171 720, 750, 1, 2,
2172 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2173 { "720x480", /* 24: 720x480 (aka "525p" and "480p") (Panasonic) */
2174 27000,
2175 720, 856, 40, 32,
2176 480, 525, 1, 3,
2177 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2178 { "720x576", /* 25: 720x576 (aka "625p"and "576p") (Panasonic) */
2179 27500,
2180 720, 864, 16, 64,
2181 576, 625, 5, 6,
2182 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2183 { "1280x720@50", /* 26: WIDE720(50) (aka "750p") (Generic) */
2184 74300,
2185 1280, 1980,400, 80,
2186 720, 750, 5, 5,
2187 SIS_PL_HSYNCP | SIS_PL_VSYNCP },
2188}; 1530};
2189 1531
2190/* 1532BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
219127.00 720 755 791 858 480 480 484 525 1533#ifdef SIS_XORG_XF86
219227.50 720 732 795 864 576 581 587 625 1534unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
2193*/ 1535 int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
2194
2195static const SiS_PlasmaTables SiS_PlasmaTable[] = {
2196#if 0 /* Product IDs missing */
2197 { 0x38a3, 4,
2198 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2199 { "", "", "", "", "" },
2200 "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
2201 0, 0,
2202 0, 0,
2203 11, /* All DVI, except 0, 7, 13 */
2204 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2205 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2206 },
2207#endif 1536#endif
2208#if 0 /* Product IDs missing */ 1537unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
2209 { 0x38a3, 3, 1538 int VDisplay, int Depth, BOOLEAN FSTN,
2210 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 1539 unsigned short CustomT, int LCDwith, int LCDheight,
2211 { "", "", "", "", "" }, 1540 unsigned int VBFlags2);
2212 "NEC PlasmaSync 42PD1/50PD1/50PD2", 1541unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
2213 0, 0, 1542 int VDisplay, int Depth, unsigned int VBFlags2);
2214 0, 0, 1543unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
2215 5, /* DVI entirely unknown */ 1544 int VDisplay, int Depth, unsigned int VBFlags2);
2216 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 , 1545
2217 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } 1546void SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data);
2218 }, 1547void SiS_SetRegByte(SISIOADDRESS port, unsigned short data);
2219 { 0x38a3, 1, 1548void SiS_SetRegShort(SISIOADDRESS port, unsigned short data);
2220 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 1549void SiS_SetRegLong(SISIOADDRESS port, unsigned int data);
2221 { "", "", "", "", "" }, 1550unsigned char SiS_GetReg(SISIOADDRESS port, unsigned short index);
2222 "NEC PlasmaSync 42PD3", 1551unsigned char SiS_GetRegByte(SISIOADDRESS port);
2223 0, 0, 1552unsigned short SiS_GetRegShort(SISIOADDRESS port);
2224 0, 0, 1553unsigned int SiS_GetRegLong(SISIOADDRESS port);
2225 10, /* DVI entirely unknown */ 1554void SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND,
2226 { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0, 1555 unsigned short DataOR);
2227 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } 1556void SiS_SetRegAND(SISIOADDRESS Port,unsigned short Index, unsigned short DataAND);
2228 }, 1557void SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR);
2229 { 0x38a3, 2, 1558
2230 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, 1559void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
2231 { "", "", "", "", "" }, 1560void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
2232 "NEC PlasmaSync 42VM3/61XM1", 1561void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
2233 0, 0, 1562#ifndef SIS_LINUX_KERNEL
2234 0, 0, 1563void SiSSetLVDSetc(struct SiS_Private *SiS_Pr);
2235 11, /* DVI entirely unknown */
2236 { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
2237 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2238 },
2239 { 0x38a3, 2,
2240 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2241 { "", "", "", "", "" },
2242 "NEC PlasmaSync 42MP1/42MP2",
2243 0, 0,
2244 0, 0,
2245 6, /* DVI entirely unknown */
2246 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
2247 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2248 },
2249 { 0x38a3, 1,
2250 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2251 { "", "", "", "", "" },
2252 "NEC PlasmaSync 50MP1",
2253 0, 0,
2254 0, 0,
2255 10, /* DVI entirely unknown */
2256 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2257 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2258 },
2259#endif 1564#endif
2260 { 0x38a3, 4, 1565void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
2261 { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 }, 1566void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
2262 { "PX-42VM", "", "", "", "" }, 1567unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2263 "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1", 1568 unsigned short ModeIdIndex);
2264 0, 0, 1569BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
2265 0, 0, 1570#ifndef SIS_LINUX_KERNEL
2266 11, /* All DVI except 0, 7, 13, 17 */ 1571void SiS_GetVBType(struct SiS_Private *SiS_Pr);
2267 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
2268 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2269 },
2270#if 0 /* Product IDs missing */
2271 { 0x38a3, 1,
2272 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2273 { "", "", "", "", "" },
2274 "NEC PlasmaSync 3300W",
2275 0, 0,
2276 0, 0,
2277 3,
2278 { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2279 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2280 },
2281 { 0x38a3, 1,
2282 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2283 { "", "", "", "", "" },
2284 "NEC PlasmaSync 4200W",
2285 4, /* DVI entirely unknown */
2286 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0 , 0 , 0 , 0 , 0 , 0 ,
2287 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2288 },
2289 { 0x38a3, 1,
2290 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2291 { "", "", "", "", "" },
2292 "NEC PlasmaSync 4210W",
2293 0, 0,
2294 0, 0,
2295 6, /* DVI entirely unknown */
2296 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
2297 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2298 },
2299 { 0x38a3, 1,
2300 { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
2301 { "", "", "", "", "" },
2302 "NEC PlasmaSync 5000W",
2303 0, 0,
2304 0, 0,
2305 7, /* DVI entirely unknown */
2306 { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0 , 0 , 0 ,
2307 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2308 },
2309#endif
2310 { 0x412f, 2,
2311 { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
2312 { "", "", "", "", "" },
2313 "Pioneer 503CMX/PDA-5002",
2314 0, 0,
2315 0, 0,
2316 6, /* DVI unknown */
2317 { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 ,
2318 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2319 },
2320 { 0x34a9, 1,
2321 { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
2322 { "", "", "", "", "" },
2323 "Panasonic TH-42",
2324 0, 0,
2325 0, 0,
2326 5, /* No DVI output */
2327 { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 ,
2328 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2329 },
2330 { 0x34a9, 1,
2331 { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
2332 { "TH-42PW*4", "", "", "", "" },
2333 "Panasonic TH-42PW5",
2334 0, 0,
2335 0, 0,
2336 1, /* No special modes otherwise; no DVI. */
2337 {20|0x40,19|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2338 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2339 },
2340 { 0x4c2e, 1,
2341 { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 },
2342 { "PLV-Z2", "", "", "", "" },
2343 "Sanyo PLV-Z2 (non HDCP-mode)", /* HDCP mode would be id 9b06, but not needed */
2344 1280, 768, /* as it then advertises correct size */
2345 1280, 720,
2346 1, /* 1280x720, no special modes otherwise */
2347 {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2348 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2349 },
2350 { 0x34a9, 1,
2351 { 0xd034, 0x0000, 0x0000, 0x0000, 0x0000 },
2352 { "AE500U (DVI-D)", "", "", "", "" },
2353 "Panasonic AE500U",
2354 1280, 768,
2355 1280, 720,
2356 1, /* 1280x720, no special modes otherwise */
2357 {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
2358 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2359 },
2360 { 0x34a9, 1,
2361 { 0xd043, 0x0000, 0x0000, 0x0000, 0x0000 },
2362 { "AE700U (HDMI)", "", "", "", "" },
2363 "Panasonic AE700U",
2364 1360, 768,
2365 1280, 720,
2366 6, /* 1280x720/60, 1280x720/50, 1280x768@56(digital/analog), 720x480, 720x576 */
2367 {21|0xc0,23|0xc0,22|0x80,13|0x40,24|0x80,25|0x80, 0 , 0 , 0 , 0 ,
2368 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
2369 },
2370 { 0x0000 }
2371};
2372#endif 1572#endif
2373 1573
2374#ifdef LINUX_XF86 1574BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
2375USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, 1575 unsigned short *ModeIdIndex);
2376 int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight); 1576unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1577 unsigned short ModeIdIndex);
1578unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
1579unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
1580unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1581 unsigned short ModeIdIndex);
1582unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
1583 unsigned short ModeIdIndex, unsigned short RRTI);
1584#ifdef SIS300
1585void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
1586 unsigned short *idx2);
1587unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
1588unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
2377#endif 1589#endif
2378USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN, 1590void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
2379 USHORT CustomT, int LCDwith, int LCDheight); 1591#ifdef SIS_XORG_XF86
2380USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth); 1592BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
2381USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth); 1593 BOOLEAN dosetpitch);
2382 1594BOOLEAN SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
2383void SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data); 1595 DisplayModePtr mode, BOOLEAN IsCustom);
2384void SiS_SetRegByte(SISIOADDRESS port, USHORT data); 1596BOOLEAN SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
2385void SiS_SetRegShort(SISIOADDRESS port, USHORT data); 1597 DisplayModePtr mode, BOOLEAN IsCustom);
2386void SiS_SetRegLong(SISIOADDRESS port, ULONG data); 1598BOOLEAN SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
2387UCHAR SiS_GetReg(SISIOADDRESS port, USHORT index); 1599 DisplayModePtr mode, BOOLEAN IsCustom);
2388UCHAR SiS_GetRegByte(SISIOADDRESS port); 1600#endif
2389USHORT SiS_GetRegShort(SISIOADDRESS port); 1601#ifdef SIS_LINUX_KERNEL
2390ULONG SiS_GetRegLong(SISIOADDRESS port); 1602BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
2391void SiS_SetRegANDOR(SISIOADDRESS Port, USHORT Index, USHORT DataAND, USHORT DataOR); 1603#endif
2392void SiS_SetRegAND(SISIOADDRESS Port,USHORT Index, USHORT DataAND); 1604void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
2393void SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR); 1605void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2394void SiS_DisplayOn(SiS_Private *SiS_Pr); 1606 unsigned short ModeIdIndex);
2395void SiS_DisplayOff(SiS_Private *SiS_Pr); 1607#ifdef SIS_XORG_XF86
2396void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); 1608void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
2397BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 1609 int yres, DisplayModePtr current);
2398void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); 1610#endif
2399void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); 1611#ifdef SIS_LINUX_KERNEL
2400BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex); 1612void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
2401UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex); 1613 int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
2402USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2403USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo, USHORT ModeIdIndex,
2404 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
2405void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
2406void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2407
2408#ifdef LINUX_XF86
2409BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
2410BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2411 DisplayModePtr mode, BOOLEAN IsCustom);
2412BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2413 DisplayModePtr mode, BOOLEAN IsCustom);
2414BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
2415 DisplayModePtr mode, BOOLEAN IsCustom);
2416int SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
2417int SiSTranslateToOldMode(int modenumber);
2418BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
2419USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
2420DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
2421int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy);
2422void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
2423#else
2424BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
2425#endif 1614#endif
2426 1615
2427#ifdef LINUX_KERNEL 1616/* From init301.c: */
2428int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 1617extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2429 UCHAR modeno, UCHAR rateindex); 1618 unsigned short ModeIdIndex, int chkcrt2mode);
2430int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 1619extern void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2431 UCHAR modeno, UCHAR rateindex, 1620 unsigned short ModeIdIndex);
2432 struct fb_var_screeninfo *var); 1621extern void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
2433BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 1622extern void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
2434 UCHAR modeno, int *htotal, int *vtotal, UCHAR rateindex); 1623 unsigned short ModeIdIndex);
1624extern void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
1625extern void SiS_DisableBridge(struct SiS_Private *);
1626extern BOOLEAN SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
1627extern unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1628 unsigned short ModeIdIndex);
1629extern void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
1630extern unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1631 unsigned short ModeIdIndex);
1632extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
1633extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1634 unsigned short ModeIdIndex, unsigned short RRTI);
1635extern BOOLEAN SiS_IsVAMode(struct SiS_Private *);
1636extern BOOLEAN SiS_IsDualEdge(struct SiS_Private *);
1637
1638#ifdef SIS_XORG_XF86
1639/* From other modules: */
1640extern unsigned short SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
1641 unsigned int VBFlags);
1642extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset,
1643 unsigned char value);
1644extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
1645extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
1646 unsigned int VBFlags);
2435#endif 1647#endif
2436 1648
2437/* init301.c: */ 1649#ifdef SIS_LINUX_KERNEL
2438extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 1650#ifdef SIS300
2439 PSIS_HW_INFO HwInfo, int chkcrt2mode); 1651extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
2440extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 1652extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
2441 PSIS_HW_INFO HwInfo); 1653 unsigned int val);
2442extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 1654#endif
2443extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); 1655#ifdef SIS315H
2444extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 1656extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
2445extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO); 1657 unsigned char val);
2446extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT); 1658extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
2447extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 1659#endif
2448 PSIS_HW_INFO HwInfo);
2449extern void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
2450extern USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
2451extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
2452extern USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2453 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
2454extern BOOLEAN SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
2455extern BOOLEAN SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
2456
2457#ifdef LINUX_XF86
2458/* From other sis driver modules: */
2459extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
2460 int *out_sbit, int *out_scale);
2461extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
2462
2463extern UCHAR SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, UCHAR value);
2464extern UCHAR SiS_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
2465extern USHORT SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ULONG VBFlags);
2466#endif 1660#endif
2467 1661
2468#endif 1662#endif
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 274dacd54bb8..2d88f908170a 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -2,11 +2,12 @@
2/* $XdotOrg$ */ 2/* $XdotOrg$ */
3/* 3/*
4 * Mode initializing code (CRT2 section) 4 * Mode initializing code (CRT2 section)
5 * for SiS 300/305/540/630/730 and 5 * for SiS 300/305/540/630/730,
6 * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760 6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
7 * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x) 7 * XGI V3XT/V5/V8, Z7
8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
8 * 9 *
9 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
10 * 11 *
11 * If distributed as part of the Linux kernel, the following license terms 12 * If distributed as part of the Linux kernel, the following license terms
12 * apply: 13 * apply:
@@ -38,7 +39,7 @@
38 * * 3) The name of the author may not be used to endorse or promote products 39 * * 3) The name of the author may not be used to endorse or promote products
39 * * derived from this software without specific prior written permission. 40 * * derived from this software without specific prior written permission.
40 * * 41 * *
41 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
@@ -54,20 +55,20 @@
54 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
55 * Used by permission. 56 * Used by permission.
56 * 57 *
57 * TW says: This code looks awful, I know. But please don't do anything about
58 * this otherwise debugging will be hell.
59 * The code is extremely fragile as regards the different chipsets, different
60 * video bridges and combinations thereof. If anything is changed, extreme
61 * care has to be taken that that change doesn't break it for other chipsets,
62 * bridges or combinations thereof.
63 * All comments in this file are by me, regardless if marked TW or not.
64 *
65 */ 58 */
66 59
60#ifdef HAVE_CONFIG_H
61#include "config.h"
62#endif
63
67#if 1 64#if 1
68#define SET_EMI /* 302LV/ELV: Set EMI values */ 65#define SET_EMI /* 302LV/ELV: Set EMI values */
69#endif 66#endif
70 67
68#if 1
69#define SET_PWD /* 301/302LV: Set PWD */
70#endif
71
71#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */ 72#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
72#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */ 73#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
73#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */ 74#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
@@ -85,26 +86,35 @@
85#define SiS_I2CDELAY 1000 86#define SiS_I2CDELAY 1000
86#define SiS_I2CDELAYSHORT 150 87#define SiS_I2CDELAYSHORT 150
87 88
88static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr); 89static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
89static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx); 90#ifdef SIS_LINUX_KERNEL
91static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
92#endif
90 93
91/*********************************************/ 94/*********************************************/
92/* HELPER: Lock/Unlock CRT2 */ 95/* HELPER: Lock/Unlock CRT2 */
93/*********************************************/ 96/*********************************************/
94 97
95void 98void
96SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 99SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
97{ 100{
98 if(HwInfo->jChipType >= SIS_315H) 101 if(SiS_Pr->ChipType == XGI_20)
102 return;
103 else if(SiS_Pr->ChipType >= SIS_315H)
99 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01); 104 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
100 else 105 else
101 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); 106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
102} 107}
103 108
104static void 109#ifdef SIS_LINUX_KERNEL
105SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 110static
111#endif
112void
113SiS_LockCRT2(struct SiS_Private *SiS_Pr)
106{ 114{
107 if(HwInfo->jChipType >= SIS_315H) 115 if(SiS_Pr->ChipType == XGI_20)
116 return;
117 else if(SiS_Pr->ChipType >= SIS_315H)
108 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE); 118 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
109 else 119 else
110 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE); 120 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
@@ -115,9 +125,9 @@ SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
115/*********************************************/ 125/*********************************************/
116 126
117static void 127static void
118SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR) 128SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
119{ 129{
120 if(HwInfo->jChipType >= SIS_661) { 130 if(SiS_Pr->ChipType >= SIS_661) {
121 DataAND &= 0x0f; 131 DataAND &= 0x0f;
122 DataOR &= 0x0f; 132 DataOR &= 0x0f;
123 } 133 }
@@ -129,12 +139,12 @@ SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, US
129/*********************************************/ 139/*********************************************/
130 140
131#ifdef SIS315H 141#ifdef SIS315H
132static UCHAR * 142static unsigned char *
133GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 143GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
134{ 144{
135 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 145 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
136 UCHAR *myptr = NULL; 146 unsigned char *myptr = NULL;
137 USHORT romindex = 0, reg = 0, idx = 0; 147 unsigned short romindex = 0, reg = 0, idx = 0;
138 148
139 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 149 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
140 * due to the variaty of panels the BIOS doesn't know about. 150 * due to the variaty of panels the BIOS doesn't know about.
@@ -144,15 +154,15 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
144 */ 154 */
145 155
146 if((SiS_Pr->SiS_ROMNew) && 156 if((SiS_Pr->SiS_ROMNew) &&
147 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) { 157 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
148 158
149 if(HwInfo->jChipType < SIS_661) reg = 0x3c; 159 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
150 else reg = 0x7d; 160 else reg = 0x7d;
151 161
152 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26; 162 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
153 163
154 if(idx < (8*26)) { 164 if(idx < (8*26)) {
155 myptr = (UCHAR *)&SiS_LCDStruct661[idx]; 165 myptr = (unsigned char *)&SiS_LCDStruct661[idx];
156 } 166 }
157 romindex = SISGETROMW(0x100); 167 romindex = SISGETROMW(0x100);
158 if(romindex) { 168 if(romindex) {
@@ -163,11 +173,11 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
163 return myptr; 173 return myptr;
164} 174}
165 175
166static USHORT 176static unsigned short
167GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 177GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
168{ 178{
169 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 179 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
170 USHORT romptr = 0; 180 unsigned short romptr = 0;
171 181
172 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 182 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
173 * due to the variaty of panels the BIOS doesn't know about. 183 * due to the variaty of panels the BIOS doesn't know about.
@@ -177,12 +187,12 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
177 */ 187 */
178 188
179 if((SiS_Pr->SiS_ROMNew) && 189 if((SiS_Pr->SiS_ROMNew) &&
180 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) { 190 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
181 romptr = SISGETROMW(0x102); 191 romptr = SISGETROMW(0x102);
182 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize); 192 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
183 } 193 }
184 194
185 return(romptr); 195 return romptr;
186} 196}
187#endif 197#endif
188 198
@@ -191,186 +201,187 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
191/*********************************************/ 201/*********************************************/
192 202
193static BOOLEAN 203static BOOLEAN
194SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 204SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
195 USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo) 205 unsigned short RRTI, unsigned short *i)
196{ 206{
197 USHORT checkmask=0,modeid,infoflag; 207 unsigned short checkmask=0, modeid, infoflag;
198 208
199 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID; 209 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
200 210
201 if(SiS_Pr->SiS_VBType & VB_SISVB) { 211 if(SiS_Pr->SiS_VBType & VB_SISVB) {
202 212
203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 213 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
204 214
205 checkmask |= SupportRAMDAC2; 215 checkmask |= SupportRAMDAC2;
206 if(HwInfo->jChipType >= SIS_315H) { 216 if(SiS_Pr->ChipType >= SIS_315H) {
207 checkmask |= SupportRAMDAC2_135; 217 checkmask |= SupportRAMDAC2_135;
208 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 218 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
209 checkmask |= SupportRAMDAC2_162; 219 checkmask |= SupportRAMDAC2_162;
210 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 220 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
211 checkmask |= SupportRAMDAC2_202; 221 checkmask |= SupportRAMDAC2_202;
212 } 222 }
213 } 223 }
214 } 224 }
215 225
216 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 226 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
217 227
218 checkmask |= SupportLCD; 228 checkmask |= SupportLCD;
219 if(HwInfo->jChipType >= SIS_315H) { 229 if(SiS_Pr->ChipType >= SIS_315H) {
220 if(SiS_Pr->SiS_VBType & VB_SISVB) { 230 if(SiS_Pr->SiS_VBType & VB_SISVB) {
221 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 231 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
222 if(modeid == 0x2e) checkmask |= Support64048060Hz; 232 if(modeid == 0x2e) checkmask |= Support64048060Hz;
223 } 233 }
224 } 234 }
225 } 235 }
226 236
227 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 237 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
228 238
229 checkmask |= SupportHiVision; 239 checkmask |= SupportHiVision;
230 240
231 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) { 241 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
232 242
233 checkmask |= SupportTV; 243 checkmask |= SupportTV;
234 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 244 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
235 checkmask |= SupportTV1024; 245 checkmask |= SupportTV1024;
236 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
237 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 247 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
238 checkmask |= SupportYPbPr750p; 248 checkmask |= SupportYPbPr750p;
239 } 249 }
240 } 250 }
241 } 251 }
242 252
243 } 253 }
244 254
245 } else { /* LVDS */ 255 } else { /* LVDS */
246 256
247 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 257 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 258 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
249 checkmask |= SupportCHTV; 259 checkmask |= SupportCHTV;
250 } 260 }
251 } 261 }
252 262
253 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 263 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
254 checkmask |= SupportLCD; 264 checkmask |= SupportLCD;
255 } 265 }
256 266
257 } 267 }
258 268
259 /* Look backwards in table for matching CRT2 mode */ 269 /* Look backwards in table for matching CRT2 mode */
260 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) { 270 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
261 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
262 if(infoflag & checkmask) return TRUE; 272 if(infoflag & checkmask) return TRUE;
263 if((*i) == 0) break; 273 if((*i) == 0) break;
264 } 274 }
265 275
266 /* Look through the whole mode-section of the table from the beginning 276 /* Look through the whole mode-section of the table from the beginning
267 * for a matching CRT2 mode if no mode was found yet. 277 * for a matching CRT2 mode if no mode was found yet.
268 */ 278 */
269 for((*i) = 0; ; (*i)++) { 279 for((*i) = 0; ; (*i)++) {
270 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break; 280 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
271 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 281 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
272 if(infoflag & checkmask) return TRUE; 282 if(infoflag & checkmask) return TRUE;
273 } 283 }
274 return FALSE; 284 return FALSE;
275} 285}
276 286
277/*********************************************/ 287/*********************************************/
278/* Get rate index */ 288/* Get rate index */
279/*********************************************/ 289/*********************************************/
280 290
281USHORT 291unsigned short
282SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 292SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
283 PSIS_HW_INFO HwInfo) 293{
284{ 294 unsigned short RRTI,i,backup_i;
285 SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01, 295 unsigned short modeflag,index,temp,backupindex;
286 0x01, 0x01, 0x01, 0x01, 296 static const unsigned short LCDRefreshIndex[] = {
287 0x01, 0x01, 0x01, 0x01, 297 0x00, 0x00, 0x01, 0x01,
288 0x01, 0x01, 0x01, 0x01, 298 0x01, 0x01, 0x01, 0x01,
289 0x00, 0x00, 0x00, 0x00 }; 299 0x01, 0x01, 0x01, 0x01,
290 USHORT RRTI,i,backup_i; 300 0x01, 0x01, 0x01, 0x01,
291 USHORT modeflag,index,temp,backupindex; 301 0x00, 0x00, 0x00, 0x00
302 };
292 303
293 /* Do NOT check for UseCustomMode here, will skrew up FIFO */ 304 /* Do NOT check for UseCustomMode here, will skrew up FIFO */
294 if(ModeNo == 0xfe) return 0; 305 if(ModeNo == 0xfe) return 0;
295 306
296 if(ModeNo <= 0x13) { 307 if(ModeNo <= 0x13) {
297 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 308 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
298 } else { 309 } else {
299 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 310 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
300 } 311 }
301 312
302 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 313 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
303 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 314 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
304 if(modeflag & HalfDCLK) return 0; 315 if(modeflag & HalfDCLK) return 0;
305 } 316 }
306 } 317 }
307 318
308 if(ModeNo < 0x14) return 0xFFFF; 319 if(ModeNo < 0x14) return 0xFFFF;
309 320
310 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F; 321 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
311 backupindex = index; 322 backupindex = index;
312 323
313 if(index > 0) index--; 324 if(index > 0) index--;
314 325
315 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 326 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
316 if(SiS_Pr->SiS_VBType & VB_SISVB) { 327 if(SiS_Pr->SiS_VBType & VB_SISVB) {
317 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 328 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
318 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0; 329 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
319 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0; 330 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
320 } 331 }
321 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 332 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
322 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) { 333 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
323 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)]; 334 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
324 if(index > temp) index = temp; 335 if(index > temp) index = temp;
325 } 336 }
326 } 337 }
327 } else { 338 } else {
328 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0; 339 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
329 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 340 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
330 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0; 341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
331 } 342 }
332 } 343 }
333 } 344 }
334 345
335 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; 346 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
336 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID; 347 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
337 348
338 if(HwInfo->jChipType >= SIS_315H) { 349 if(SiS_Pr->ChipType >= SIS_315H) {
339 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) { 350 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
340 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) || 351 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
341 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) { 352 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
342 if(backupindex <= 1) RRTI++; 353 if(backupindex <= 1) RRTI++;
343 } 354 }
344 } 355 }
345 } 356 }
346 357
347 i = 0; 358 i = 0;
348 do { 359 do {
349 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break; 360 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
350 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag; 361 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
351 temp &= ModeTypeMask; 362 temp &= ModeTypeMask;
352 if(temp < SiS_Pr->SiS_ModeType) break; 363 if(temp < SiS_Pr->SiS_ModeType) break;
353 i++; 364 i++;
354 index--; 365 index--;
355 } while(index != 0xFFFF); 366 } while(index != 0xFFFF);
356 367
357 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 368 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
358 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 369 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
359 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag; 370 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
360 if(temp & InterlaceMode) i++; 371 if(temp & InterlaceMode) i++;
361 } 372 }
362 } 373 }
363 374
364 i--; 375 i--;
365 376
366 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) { 377 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
367 backup_i = i; 378 backup_i = i;
368 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) { 379 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
369 i = backup_i; 380 i = backup_i;
370 } 381 }
371 } 382 }
372 383
373 return(RRTI + i); 384 return (RRTI + i);
374} 385}
375 386
376/*********************************************/ 387/*********************************************/
@@ -378,15 +389,15 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
378/*********************************************/ 389/*********************************************/
379 390
380static void 391static void
381SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo) 392SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
382{ 393{
383 USHORT temp1,temp2; 394 unsigned short temp1, temp2;
384 395
385 /* Store CRT1 ModeNo in CR34 */ 396 /* Store CRT1 ModeNo in CR34 */
386 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo); 397 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
387 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8; 398 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
388 temp2 = ~(SetInSlaveMode >> 8); 399 temp2 = ~(SetInSlaveMode >> 8);
389 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1); 400 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
390} 401}
391 402
392/*********************************************/ 403/*********************************************/
@@ -395,35 +406,35 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
395 406
396#ifdef SIS300 407#ifdef SIS300
397static BOOLEAN 408static BOOLEAN
398SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 409SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
399{ 410{
400 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 411 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
401 USHORT temp,temp1; 412 unsigned short temp,temp1;
402 413
403 if(SiS_Pr->SiS_UseROM) { 414 if(SiS_Pr->SiS_UseROM) {
404 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 415 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
405 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 416 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
406 temp1 = SISGETROMW(0x23b); 417 temp1 = SISGETROMW(0x23b);
407 if(temp1 & temp) return TRUE; 418 if(temp1 & temp) return TRUE;
408 } 419 }
409 } 420 }
410 return FALSE; 421 return FALSE;
411} 422}
412 423
413static BOOLEAN 424static BOOLEAN
414SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 425SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
415{ 426{
416 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 427 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
417 USHORT temp,temp1; 428 unsigned short temp,temp1;
418 429
419 if(SiS_Pr->SiS_UseROM) { 430 if(SiS_Pr->SiS_UseROM) {
420 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 431 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
421 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 432 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
422 temp1 = SISGETROMW(0x23d); 433 temp1 = SISGETROMW(0x23d);
423 if(temp1 & temp) return TRUE; 434 if(temp1 & temp) return TRUE;
424 } 435 }
425 } 436 }
426 return FALSE; 437 return FALSE;
427} 438}
428#endif 439#endif
429 440
@@ -432,85 +443,76 @@ SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
432/*********************************************/ 443/*********************************************/
433 444
434void 445void
435SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime) 446SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
436{ 447{
437 USHORT i, j; 448 unsigned int i, j;
438 449
439 for(i=0; i<delaytime; i++) { 450 for(i = 0; i < delaytime; i++) {
440 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); 451 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
441 } 452 }
442} 453}
443 454
444#if defined(SIS300) || defined(SIS315H) 455#if defined(SIS300) || defined(SIS315H)
445static void 456static void
446SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay) 457SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
447{ 458{
448 USHORT temp,flag; 459 SiS_DDC2Delay(SiS_Pr, delay * 36);
449
450 flag = SiS_GetRegByte(0x61) & 0x10;
451
452 while(delay) {
453 temp = SiS_GetRegByte(0x61) & 0x10;
454 if(temp == flag) continue;
455 flag = temp;
456 delay--;
457 }
458} 460}
459#endif 461#endif
460 462
461#ifdef SIS315H 463#ifdef SIS315H
462static void 464static void
463SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay) 465SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
464{ 466{
465 while(delay--) { 467 while(delay--) {
466 SiS_GenericDelay(SiS_Pr,0x19df); 468 SiS_GenericDelay(SiS_Pr, 6623);
467 } 469 }
468} 470}
469#endif 471#endif
470 472
471#if defined(SIS300) || defined(SIS315H) 473#if defined(SIS300) || defined(SIS315H)
472static void 474static void
473SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay) 475SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
474{ 476{
475 while(delay--) { 477 while(delay--) {
476 SiS_GenericDelay(SiS_Pr,0x42); 478 SiS_GenericDelay(SiS_Pr, 66);
477 } 479 }
478} 480}
479#endif 481#endif
480 482
481static void 483static void
482SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime) 484SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
483{ 485{
484#if defined(SIS300) || defined(SIS315H) 486#if defined(SIS300) || defined(SIS315H)
485 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 487 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
486 USHORT PanelID, DelayIndex, Delay=0; 488 unsigned short PanelID, DelayIndex, Delay=0;
487#endif 489#endif
488 490
489 if(HwInfo->jChipType < SIS_315H) { 491 if(SiS_Pr->ChipType < SIS_315H) {
490 492
491#ifdef SIS300 493#ifdef SIS300
492 494
493 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 495 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
494 if(SiS_Pr->SiS_VBType & VB_SISVB) { 496 if(SiS_Pr->SiS_VBType & VB_SISVB) {
495 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7; 497 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
496 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12; 498 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
497 } 499 }
498 DelayIndex = PanelID >> 4; 500 DelayIndex = PanelID >> 4;
499 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 501 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
500 Delay = 3; 502 Delay = 3;
501 } else { 503 } else {
502 if(DelayTime >= 2) DelayTime -= 2; 504 if(DelayTime >= 2) DelayTime -= 2;
503 if(!(DelayTime & 0x01)) { 505 if(!(DelayTime & 0x01)) {
504 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 506 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
505 } else { 507 } else {
506 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 508 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
507 } 509 }
508 if(SiS_Pr->SiS_UseROM) { 510 if(SiS_Pr->SiS_UseROM) {
509 if(ROMAddr[0x220] & 0x40) { 511 if(ROMAddr[0x220] & 0x40) {
510 if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225]; 512 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
511 else Delay = (USHORT)ROMAddr[0x226]; 513 else Delay = (unsigned short)ROMAddr[0x226];
512 } 514 }
513 } 515 }
514 } 516 }
515 SiS_ShortDelay(SiS_Pr, Delay); 517 SiS_ShortDelay(SiS_Pr, Delay);
516 518
@@ -520,23 +522,23 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
520 522
521#ifdef SIS315H 523#ifdef SIS315H
522 524
523 if((HwInfo->jChipType >= SIS_661) || 525 if((SiS_Pr->ChipType >= SIS_661) ||
524 (HwInfo->jChipType <= SIS_315PRO) || 526 (SiS_Pr->ChipType <= SIS_315PRO) ||
525 (HwInfo->jChipType == SIS_330) || 527 (SiS_Pr->ChipType == SIS_330) ||
526 (SiS_Pr->SiS_ROMNew)) { 528 (SiS_Pr->SiS_ROMNew)) {
527 529
528 if(!(DelayTime & 0x01)) { 530 if(!(DelayTime & 0x01)) {
529 SiS_DDC2Delay(SiS_Pr, 0x1000); 531 SiS_DDC2Delay(SiS_Pr, 0x1000);
530 } else { 532 } else {
531 SiS_DDC2Delay(SiS_Pr, 0x4000); 533 SiS_DDC2Delay(SiS_Pr, 0x4000);
532 } 534 }
533 535
534 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* || 536 } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
535 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 537 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
536 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */ 538 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
537 539
538 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 540 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
539 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 541 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
540 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) { 542 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
541 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12; 543 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
542 } 544 }
@@ -546,35 +548,35 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
546 DelayIndex = PanelID >> 4; 548 DelayIndex = PanelID >> 4;
547 } 549 }
548 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 550 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
549 Delay = 3; 551 Delay = 3;
550 } else { 552 } else {
551 if(DelayTime >= 2) DelayTime -= 2; 553 if(DelayTime >= 2) DelayTime -= 2;
552 if(!(DelayTime & 0x01)) { 554 if(!(DelayTime & 0x01)) {
553 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0]; 555 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
554 } else { 556 } else {
555 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1]; 557 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
556 } 558 }
557 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 559 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
558 if(ROMAddr[0x13c] & 0x40) { 560 if(ROMAddr[0x13c] & 0x40) {
559 if(!(DelayTime & 0x01)) { 561 if(!(DelayTime & 0x01)) {
560 Delay = (USHORT)ROMAddr[0x17e]; 562 Delay = (unsigned short)ROMAddr[0x17e];
561 } else { 563 } else {
562 Delay = (USHORT)ROMAddr[0x17f]; 564 Delay = (unsigned short)ROMAddr[0x17f];
563 } 565 }
564 } 566 }
565 } 567 }
566 } 568 }
567 SiS_ShortDelay(SiS_Pr, Delay); 569 SiS_ShortDelay(SiS_Pr, Delay);
568 } 570 }
569 571
570 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */ 572 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
571 573
572 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 574 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
573 if(!(DelayTime & 0x01)) { 575 if(!(DelayTime & 0x01)) {
574 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 576 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
575 } else { 577 } else {
576 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 578 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
577 } 579 }
578 Delay <<= 8; 580 Delay <<= 8;
579 SiS_DDC2Delay(SiS_Pr, Delay); 581 SiS_DDC2Delay(SiS_Pr, Delay);
580 582
@@ -587,12 +589,11 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
587 589
588#ifdef SIS315H 590#ifdef SIS315H
589static void 591static void
590SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 592SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
591 USHORT DelayTime, USHORT DelayLoop)
592{ 593{
593 int i; 594 int i;
594 for(i=0; i<DelayLoop; i++) { 595 for(i = 0; i < DelayLoop; i++) {
595 SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime); 596 SiS_PanelDelay(SiS_Pr, DelayTime);
596 } 597 }
597} 598}
598#endif 599#endif
@@ -602,86 +603,86 @@ SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
602/*********************************************/ 603/*********************************************/
603 604
604void 605void
605SiS_WaitRetrace1(SiS_Private *SiS_Pr) 606SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
606{ 607{
607 USHORT watchdog; 608 unsigned short watchdog;
608 609
609 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; 610 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
610 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return; 611 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
611 612
612 watchdog = 65535; 613 watchdog = 65535;
613 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); 614 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
614 watchdog = 65535; 615 watchdog = 65535;
615 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); 616 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
616} 617}
617 618
618#if defined(SIS300) || defined(SIS315H) 619#if defined(SIS300) || defined(SIS315H)
619static void 620static void
620SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg) 621SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
621{ 622{
622 USHORT watchdog; 623 unsigned short watchdog;
623 624
624 watchdog = 65535; 625 watchdog = 65535;
625 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog); 626 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
626 watchdog = 65535; 627 watchdog = 65535;
627 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog); 628 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
628} 629}
629#endif 630#endif
630 631
631static void 632static void
632SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 633SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
633{ 634{
634 if(HwInfo->jChipType < SIS_315H) { 635 if(SiS_Pr->ChipType < SIS_315H) {
635#ifdef SIS300 636#ifdef SIS300
636 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 637 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
637 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; 638 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
638 } 639 }
639 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) { 640 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
640 SiS_WaitRetrace1(SiS_Pr); 641 SiS_WaitRetrace1(SiS_Pr);
641 } else { 642 } else {
642 SiS_WaitRetrace2(SiS_Pr, 0x25); 643 SiS_WaitRetrace2(SiS_Pr, 0x25);
643 } 644 }
644#endif 645#endif
645 } else { 646 } else {
646#ifdef SIS315H 647#ifdef SIS315H
647 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { 648 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
648 SiS_WaitRetrace1(SiS_Pr); 649 SiS_WaitRetrace1(SiS_Pr);
649 } else { 650 } else {
650 SiS_WaitRetrace2(SiS_Pr, 0x30); 651 SiS_WaitRetrace2(SiS_Pr, 0x30);
651 } 652 }
652#endif 653#endif
653 } 654 }
654} 655}
655 656
656static void 657static void
657SiS_VBWait(SiS_Private *SiS_Pr) 658SiS_VBWait(struct SiS_Private *SiS_Pr)
658{ 659{
659 USHORT tempal,temp,i,j; 660 unsigned short tempal,temp,i,j;
660 661
661 temp = 0; 662 temp = 0;
662 for(i=0; i<3; i++) { 663 for(i = 0; i < 3; i++) {
663 for(j=0; j<100; j++) { 664 for(j = 0; j < 100; j++) {
664 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da); 665 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
665 if(temp & 0x01) { 666 if(temp & 0x01) {
666 if((tempal & 0x08)) continue; 667 if((tempal & 0x08)) continue;
667 else break; 668 else break;
668 } else { 669 } else {
669 if(!(tempal & 0x08)) continue; 670 if(!(tempal & 0x08)) continue;
670 else break; 671 else break;
671 } 672 }
672 } 673 }
673 temp ^= 0x01; 674 temp ^= 0x01;
674 } 675 }
675} 676}
676 677
677static void 678static void
678SiS_VBLongWait(SiS_Private *SiS_Pr) 679SiS_VBLongWait(struct SiS_Private *SiS_Pr)
679{ 680{
680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 681 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
681 SiS_VBWait(SiS_Pr); 682 SiS_VBWait(SiS_Pr);
682 } else { 683 } else {
683 SiS_WaitRetrace1(SiS_Pr); 684 SiS_WaitRetrace1(SiS_Pr);
684 } 685 }
685} 686}
686 687
687/*********************************************/ 688/*********************************************/
@@ -690,237 +691,225 @@ SiS_VBLongWait(SiS_Private *SiS_Pr)
690 691
691#ifdef SIS300 692#ifdef SIS300
692static BOOLEAN 693static BOOLEAN
693SiS_Is301B(SiS_Private *SiS_Pr) 694SiS_Is301B(struct SiS_Private *SiS_Pr)
694{ 695{
695 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE; 696 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
696 return FALSE; 697 return FALSE;
697} 698}
698#endif 699#endif
699 700
700static BOOLEAN 701static BOOLEAN
701SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 702SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
702{ 703{
703 USHORT flag; 704 if(SiS_Pr->ChipType == SIS_730) {
704 705 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
705 if(HwInfo->jChipType == SIS_730) { 706 }
706 flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13); 707 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
707 if(flag & 0x20) return TRUE; 708 return FALSE;
708 }
709 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
710 if(flag & 0x20) return TRUE;
711 return FALSE;
712} 709}
713 710
714BOOLEAN 711BOOLEAN
715SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 712SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
716{ 713{
717#ifdef SIS315H 714#ifdef SIS315H
718 USHORT flag; 715 if(SiS_Pr->ChipType >= SIS_315H) {
719 716 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
720 if(HwInfo->jChipType >= SIS_315H) { 717 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
721 if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { 718 }
722 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 719 }
723 if(flag & EnableDualEdge) return TRUE;
724 }
725 }
726#endif 720#endif
727 return FALSE; 721 return FALSE;
728} 722}
729 723
730BOOLEAN 724BOOLEAN
731SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 725SiS_IsVAMode(struct SiS_Private *SiS_Pr)
732{ 726{
733#ifdef SIS315H 727#ifdef SIS315H
734 USHORT flag; 728 unsigned short flag;
735 729
736 if(HwInfo->jChipType >= SIS_315H) { 730 if(SiS_Pr->ChipType >= SIS_315H) {
737 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 731 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
738 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE; 732 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
739 } 733 }
740#endif 734#endif
741 return FALSE; 735 return FALSE;
742} 736}
743 737
744#ifdef SIS315H 738#ifdef SIS315H
745static BOOLEAN 739static BOOLEAN
746SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 740SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
747{ 741{
748 if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE; 742 if(SiS_IsVAMode(SiS_Pr)) return TRUE;
749 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE; 743 if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
750 return FALSE; 744 return FALSE;
751} 745}
752#endif 746#endif
753 747
754static BOOLEAN 748static BOOLEAN
755SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 749SiS_IsDualLink(struct SiS_Private *SiS_Pr)
756{ 750{
757#ifdef SIS315H 751#ifdef SIS315H
758 if(HwInfo->jChipType >= SIS_315H) { 752 if(SiS_Pr->ChipType >= SIS_315H) {
759 if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) || 753 if((SiS_CRT2IsLCD(SiS_Pr)) ||
760 (SiS_IsVAMode(SiS_Pr, HwInfo))) { 754 (SiS_IsVAMode(SiS_Pr))) {
761 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE; 755 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
762 } 756 }
763 } 757 }
764#endif 758#endif
765 return FALSE; 759 return FALSE;
766} 760}
767 761
768#ifdef SIS315H 762#ifdef SIS315H
769static BOOLEAN 763static BOOLEAN
770SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 764SiS_TVEnabled(struct SiS_Private *SiS_Pr)
771{ 765{
772 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE; 766 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
773 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) { 767 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
774 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE; 768 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
775 } 769 }
776 return FALSE; 770 return FALSE;
777} 771}
778#endif 772#endif
779 773
780#ifdef SIS315H 774#ifdef SIS315H
781static BOOLEAN 775static BOOLEAN
782SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 776SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
783{ 777{
784 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE; 778 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
785 return FALSE; 779 return FALSE;
786} 780}
787#endif 781#endif
788 782
789#ifdef SIS315H 783#ifdef SIS315H
790static BOOLEAN 784static BOOLEAN
791SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 785SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
792{ 786{
793 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) { 787 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
794 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE; 788 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
795 } 789 }
796 return FALSE; 790 return FALSE;
797} 791}
798#endif 792#endif
799 793
800#ifdef SIS315H 794#ifdef SIS315H
801static BOOLEAN 795static BOOLEAN
802SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 796SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
803{ 797{
804 USHORT flag; 798 unsigned short flag;
805 799
806 if(HwInfo->jChipType == SIS_650) { 800 if(SiS_Pr->ChipType == SIS_650) {
807 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f); 801 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
808 flag &= 0xF0; 802 /* Check for revision != A0 only */
809 /* Check for revision != A0 only */ 803 if((flag == 0xe0) || (flag == 0xc0) ||
810 if((flag == 0xe0) || (flag == 0xc0) || 804 (flag == 0xb0) || (flag == 0x90)) return FALSE;
811 (flag == 0xb0) || (flag == 0x90)) return FALSE; 805 } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
812 } else if(HwInfo->jChipType >= SIS_661) return FALSE; 806 return TRUE;
813 return TRUE;
814} 807}
815#endif 808#endif
816 809
817#ifdef SIS315H 810#ifdef SIS315H
818static BOOLEAN 811static BOOLEAN
819SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 812SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
820{ 813{
821 USHORT flag; 814 if(SiS_Pr->ChipType >= SIS_315H) {
822 815 /* YPrPb = 0x08 */
823 if(HwInfo->jChipType >= SIS_315H) { 816 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
824 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 817 }
825 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */ 818 return FALSE;
826 }
827 return FALSE;
828} 819}
829#endif 820#endif
830 821
831#ifdef SIS315H 822#ifdef SIS315H
832static BOOLEAN 823static BOOLEAN
833SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 824SiS_IsChScart(struct SiS_Private *SiS_Pr)
834{ 825{
835 USHORT flag; 826 if(SiS_Pr->ChipType >= SIS_315H) {
836 827 /* Scart = 0x04 */
837 if(HwInfo->jChipType >= SIS_315H) { 828 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
838 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 829 }
839 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */ 830 return FALSE;
840 }
841 return FALSE;
842} 831}
843#endif 832#endif
844 833
845#ifdef SIS315H 834#ifdef SIS315H
846static BOOLEAN 835static BOOLEAN
847SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 836SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
848{ 837{
849 USHORT flag; 838 unsigned short flag;
850 839
851 if(HwInfo->jChipType >= SIS_315H) { 840 if(SiS_Pr->ChipType >= SIS_315H) {
852 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 841 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
853 if(flag & SetCRT2ToTV) return TRUE; 842 if(flag & SetCRT2ToTV) return TRUE;
854 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 843 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
855 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */ 844 if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
856 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */ 845 if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
857 } else { 846 } else {
858 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 847 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
859 if(flag & SetCRT2ToTV) return TRUE; 848 if(flag & SetCRT2ToTV) return TRUE;
860 } 849 }
861 return FALSE; 850 return FALSE;
862} 851}
863#endif 852#endif
864 853
865#ifdef SIS315H 854#ifdef SIS315H
866static BOOLEAN 855static BOOLEAN
867SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 856SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
868{ 857{
869 USHORT flag; 858 unsigned short flag;
870 859
871 if(HwInfo->jChipType >= SIS_315H) { 860 if(SiS_Pr->ChipType >= SIS_315H) {
872 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 861 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
873 if(flag & SetCRT2ToLCD) return TRUE; 862 if(flag & SetCRT2ToLCD) return TRUE;
874 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 863 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
875 if(flag & SetToLCDA) return TRUE; 864 if(flag & SetToLCDA) return TRUE;
876 } else { 865 } else {
877 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 866 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
878 if(flag & SetCRT2ToLCD) return TRUE; 867 if(flag & SetCRT2ToLCD) return TRUE;
879 } 868 }
880 return FALSE; 869 return FALSE;
881} 870}
882#endif 871#endif
883 872
884static BOOLEAN 873static BOOLEAN
885SiS_BridgeIsOn(SiS_Private *SiS_Pr) 874SiS_HaveBridge(struct SiS_Private *SiS_Pr)
886{ 875{
887 USHORT flag; 876 unsigned short flag;
888 877
889 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 878 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
890 return TRUE; 879 return TRUE;
891 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 880 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
892 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 881 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
893 if((flag == 1) || (flag == 2)) return TRUE; 882 if((flag == 1) || (flag == 2)) return TRUE;
894 } 883 }
895 return FALSE; 884 return FALSE;
896} 885}
897 886
898static BOOLEAN 887static BOOLEAN
899SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 888SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
900{ 889{
901 USHORT flag; 890 unsigned short flag;
902 891
903 if(SiS_BridgeIsOn(SiS_Pr)) { 892 if(SiS_HaveBridge(SiS_Pr)) {
904 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 893 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
905 if(HwInfo->jChipType < SIS_315H) { 894 if(SiS_Pr->ChipType < SIS_315H) {
906 flag &= 0xa0; 895 flag &= 0xa0;
907 if((flag == 0x80) || (flag == 0x20)) return TRUE; 896 if((flag == 0x80) || (flag == 0x20)) return TRUE;
908 } else { 897 } else {
909 flag &= 0x50; 898 flag &= 0x50;
910 if((flag == 0x40) || (flag == 0x10)) return TRUE; 899 if((flag == 0x40) || (flag == 0x10)) return TRUE;
911 } 900 }
912 } 901 }
913 return FALSE; 902 return FALSE;
914} 903}
915 904
916static BOOLEAN 905static BOOLEAN
917SiS_BridgeInSlavemode(SiS_Private *SiS_Pr) 906SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
918{ 907{
919 USHORT flag1; 908 unsigned short flag1;
920 909
921 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 910 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
922 if(flag1 & (SetInSlaveMode >> 8)) return TRUE; 911 if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
923 return FALSE; 912 return FALSE;
924} 913}
925 914
926/*********************************************/ 915/*********************************************/
@@ -928,119 +917,97 @@ SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
928/*********************************************/ 917/*********************************************/
929 918
930/* Setup general purpose IO for Chrontel communication */ 919/* Setup general purpose IO for Chrontel communication */
920#ifdef SIS300
931void 921void
932SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo) 922SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
933{ 923{
934 unsigned long acpibase; 924 unsigned int acpibase;
935 unsigned short temp; 925 unsigned short temp;
936 926
937 if(!(SiS_Pr->SiS_ChSW)) return; 927 if(!(SiS_Pr->SiS_ChSW)) return;
938 928
939#ifdef LINUX_KERNEL 929#ifdef SIS_LINUX_KERNEL
940 SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */ 930 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
941 acpibase = SiS_GetRegLong(0xcfc);
942#else 931#else
943 acpibase = pciReadLong(0x00000800, 0x74); 932 acpibase = pciReadLong(0x00000800, 0x74);
944#endif 933#endif
945 acpibase &= 0xFFFF; 934 acpibase &= 0xFFFF;
946 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ 935 if(!acpibase) return;
936 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
947 temp &= 0xFEFF; 937 temp &= 0xFEFF;
948 SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp); 938 SiS_SetRegShort((acpibase + 0x3c), temp);
949 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); 939 temp = SiS_GetRegShort((acpibase + 0x3c));
950 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */ 940 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
951 temp &= 0xFEFF; 941 temp &= 0xFEFF;
952 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100; 942 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
953 SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp); 943 SiS_SetRegShort((acpibase + 0x3a), temp);
954 temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); 944 temp = SiS_GetRegShort((acpibase + 0x3a));
955} 945}
946#endif
956 947
957void 948void
958SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 949SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
959 PSIS_HW_INFO HwInfo, int checkcrt2mode) 950 unsigned short ModeIdIndex, int checkcrt2mode)
960{ 951{
961 USHORT tempax,tempbx,temp; 952 unsigned short tempax, tempbx, temp;
962 USHORT modeflag, resinfo=0; 953 unsigned short modeflag, resinfo = 0;
963 954
964 if(ModeNo <= 0x13) { 955 SiS_Pr->SiS_SetFlag = 0;
965 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
966 } else if(SiS_Pr->UseCustomMode) {
967 modeflag = SiS_Pr->CModeFlag;
968 } else {
969 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
970 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
971 }
972 956
973 SiS_Pr->SiS_SetFlag = 0; 957 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
974 958
975 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask; 959 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
976 960
977 tempbx = 0; 961 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
978 if(SiS_BridgeIsOn(SiS_Pr)) { 962 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
979 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 963 }
980#if 0 964
981 if(HwInfo->jChipType < SIS_661) { 965 tempbx = 0;
982 /* NO - YPbPr not set yet ! */ 966
983 if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) { 967 if(SiS_HaveBridge(SiS_Pr)) {
984 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */ 968
985 temp |= SetCRT2ToHiVision; /* 0x80 */ 969 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
986 } 970 tempbx |= temp;
987 if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) { 971 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
988 temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */ 972 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
989 temp |= SetCRT2ToSVIDEO; /* 0x08 */ 973 tempbx |= tempax;
990 }
991 }
992#endif
993 tempbx |= temp;
994 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
995 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
996 tempbx |= tempax;
997 974
998#ifdef SIS315H 975#ifdef SIS315H
999 if(HwInfo->jChipType >= SIS_315H) { 976 if(SiS_Pr->ChipType >= SIS_315H) {
1000 if(SiS_Pr->SiS_VBType & VB_SISLCDA) { 977 if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
1001 if(ModeNo == 0x03) { 978 if(ModeNo == 0x03) {
1002 /* Mode 0x03 is never in driver mode */ 979 /* Mode 0x03 is never in driver mode */
1003 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); 980 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
1004 } 981 }
1005 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) { 982 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
1006 /* Reset LCDA setting if not driver mode */ 983 /* Reset LCDA setting if not driver mode */
1007 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 984 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
1008 } 985 }
1009 if(IS_SIS650) { 986 if(IS_SIS650) {
1010 if(SiS_Pr->SiS_UseLCDA) { 987 if(SiS_Pr->SiS_UseLCDA) {
1011 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { 988 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
1012 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { 989 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
1013 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); 990 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
1014 } 991 }
1015 } 992 }
1016 } 993 }
1017 } 994 }
1018 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 995 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1019 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) { 996 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
1020 tempbx |= SetCRT2ToLCDA; 997 tempbx |= SetCRT2ToLCDA;
1021 } 998 }
1022 } 999 }
1023 1000
1024 if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) { 1001 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
1025 tempbx &= ~(SetCRT2ToRAMDAC);
1026 }
1027
1028 if(HwInfo->jChipType >= SIS_661) {
1029 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision); 1002 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
1030 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1003 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
1031 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1004 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1032 if(temp & 0x04) { 1005 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1033 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; 1006 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1034 if(temp == 0x60) tempbx |= SetCRT2ToHiVision; 1007 tempbx |= SetCRT2ToYPbPr525750;
1035 else tempbx |= SetCRT2ToYPbPr525750;
1036 }
1037 } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
1038 if(temp & 0x04) {
1039 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
1040 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
1041 } 1008 }
1042 } 1009 }
1043 } 1010 }
1044 1011
1045 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1012 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1046 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1013 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -1048,7 +1015,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1048 tempbx |= SetCRT2ToLCDA; 1015 tempbx |= SetCRT2ToLCDA;
1049 } 1016 }
1050 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1017 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1051 if(temp & EnableCHYPbPr) { 1018 if(temp & EnableCHYPbPr) {
1052 tempbx |= SetCRT2ToCHYPbPr; 1019 tempbx |= SetCRT2ToCHYPbPr;
1053 } 1020 }
1054 } 1021 }
@@ -1057,44 +1024,49 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1057 1024
1058#endif /* SIS315H */ 1025#endif /* SIS315H */
1059 1026
1060 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1027 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
1028 tempbx &= ~(SetCRT2ToRAMDAC);
1029 }
1030
1031 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1061 temp = SetCRT2ToSVIDEO | 1032 temp = SetCRT2ToSVIDEO |
1062 SetCRT2ToAVIDEO | 1033 SetCRT2ToAVIDEO |
1063 SetCRT2ToSCART | 1034 SetCRT2ToSCART |
1064 SetCRT2ToLCDA | 1035 SetCRT2ToLCDA |
1065 SetCRT2ToLCD | 1036 SetCRT2ToLCD |
1066 SetCRT2ToRAMDAC | 1037 SetCRT2ToRAMDAC |
1067 SetCRT2ToHiVision | 1038 SetCRT2ToHiVision |
1068 SetCRT2ToYPbPr525750; 1039 SetCRT2ToYPbPr525750;
1069 } else { 1040 } else {
1070 if(HwInfo->jChipType >= SIS_315H) { 1041 if(SiS_Pr->ChipType >= SIS_315H) {
1071 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1042 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1072 temp = SetCRT2ToAVIDEO | 1043 temp = SetCRT2ToAVIDEO |
1073 SetCRT2ToSVIDEO | 1044 SetCRT2ToSVIDEO |
1074 SetCRT2ToSCART | 1045 SetCRT2ToSCART |
1075 SetCRT2ToLCDA | 1046 SetCRT2ToLCDA |
1076 SetCRT2ToLCD | 1047 SetCRT2ToLCD |
1077 SetCRT2ToCHYPbPr; 1048 SetCRT2ToCHYPbPr;
1078 } else { 1049 } else {
1079 temp = SetCRT2ToLCDA | 1050 temp = SetCRT2ToLCDA |
1080 SetCRT2ToLCD; 1051 SetCRT2ToLCD;
1081 } 1052 }
1082 } else { 1053 } else {
1083 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1054 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1084 temp = SetCRT2ToTV | SetCRT2ToLCD; 1055 temp = SetCRT2ToTV | SetCRT2ToLCD;
1085 } else { 1056 } else {
1086 temp = SetCRT2ToLCD; 1057 temp = SetCRT2ToLCD;
1087 } 1058 }
1088 } 1059 }
1089 } 1060 }
1061
1062 if(!(tempbx & temp)) {
1063 tempax = DisableCRT2Display;
1064 tempbx = 0;
1065 }
1090 1066
1091 if(!(tempbx & temp)) { 1067 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1092 tempax = DisableCRT2Display;
1093 tempbx = 0;
1094 }
1095 1068
1096 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1069 unsigned short clearmask = ( DriverMode |
1097 USHORT clearmask = ( DriverMode |
1098 DisableCRT2Display | 1070 DisableCRT2Display |
1099 LoadDACFlag | 1071 LoadDACFlag |
1100 SetNotSimuMode | 1072 SetNotSimuMode |
@@ -1102,106 +1074,104 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1102 SetPALTV | 1074 SetPALTV |
1103 SwitchCRT2 | 1075 SwitchCRT2 |
1104 SetSimuScanMode ); 1076 SetSimuScanMode );
1105 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA); 1077
1078 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
1106 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC); 1079 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
1107 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD); 1080 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
1108 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART); 1081 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
1109 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision); 1082 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
1110 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750); 1083 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
1111 } else { 1084
1112 if(HwInfo->jChipType >= SIS_315H) { 1085 } else {
1086
1087 if(SiS_Pr->ChipType >= SIS_315H) {
1113 if(tempbx & SetCRT2ToLCDA) { 1088 if(tempbx & SetCRT2ToLCDA) {
1114 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode); 1089 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
1115 } 1090 }
1116 } 1091 }
1117 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1092 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1118 if(tempbx & SetCRT2ToTV) { 1093 if(tempbx & SetCRT2ToTV) {
1119 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode); 1094 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
1120 } 1095 }
1121 }
1122 if(tempbx & SetCRT2ToLCD) {
1123 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1124 } 1096 }
1125 if(HwInfo->jChipType >= SIS_315H) { 1097 if(tempbx & SetCRT2ToLCD) {
1098 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
1099 }
1100 if(SiS_Pr->ChipType >= SIS_315H) {
1126 if(tempbx & SetCRT2ToLCDA) { 1101 if(tempbx & SetCRT2ToLCDA) {
1127 tempbx |= SetCRT2ToLCD; 1102 tempbx |= SetCRT2ToLCD;
1128 } 1103 }
1129 } 1104 }
1105
1130 } 1106 }
1131 1107
1132 if(tempax & DisableCRT2Display) { 1108 if(tempax & DisableCRT2Display) {
1133 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { 1109 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
1134 tempbx = SetSimuScanMode | DisableCRT2Display; 1110 tempbx = SetSimuScanMode | DisableCRT2Display;
1135 } 1111 }
1136 } 1112 }
1137 1113
1138 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode; 1114 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
1139 1115
1140 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */ 1116 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
1141 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 1117 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
1142 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 1118 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
1143 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) { 1119 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
1144 modeflag &= (~CRT2Mode); 1120 modeflag &= (~CRT2Mode);
1145 } 1121 }
1146 } 1122 }
1147 1123
1148 if(!(tempbx & SetSimuScanMode)) { 1124 if(!(tempbx & SetSimuScanMode)) {
1149 if(tempbx & SwitchCRT2) { 1125 if(tempbx & SwitchCRT2) {
1150 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1126 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1151 if( (HwInfo->jChipType >= SIS_315H) && 1127 if(resinfo != SIS_RI_1600x1200) {
1152 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) { 1128 tempbx |= SetSimuScanMode;
1153 if(resinfo != SIS_RI_1600x1200) { 1129 }
1154 tempbx |= SetSimuScanMode;
1155 }
1156 } else {
1157 tempbx |= SetSimuScanMode;
1158 }
1159 } 1130 }
1160 } else { 1131 } else {
1161 if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) { 1132 if(SiS_BridgeIsEnabled(SiS_Pr)) {
1162 if(!(tempbx & DriverMode)) { 1133 if(!(tempbx & DriverMode)) {
1163 if(SiS_BridgeInSlavemode(SiS_Pr)) { 1134 if(SiS_BridgeInSlavemode(SiS_Pr)) {
1164 tempbx |= SetSimuScanMode; 1135 tempbx |= SetSimuScanMode;
1165 } 1136 }
1166 } 1137 }
1167 } 1138 }
1168 } 1139 }
1169 } 1140 }
1170
1171 if(!(tempbx & DisableCRT2Display)) {
1172 if(tempbx & DriverMode) {
1173 if(tempbx & SetSimuScanMode) {
1174 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1175 if( (HwInfo->jChipType >= SIS_315H) &&
1176 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
1177 if(resinfo != SIS_RI_1600x1200) {
1178 tempbx |= SetInSlaveMode;
1179 }
1180 } else {
1181 tempbx |= SetInSlaveMode;
1182 }
1183 }
1184 }
1185 } else {
1186 tempbx |= SetInSlaveMode;
1187 }
1188 }
1189 1141
1190 } 1142 if(!(tempbx & DisableCRT2Display)) {
1143 if(tempbx & DriverMode) {
1144 if(tempbx & SetSimuScanMode) {
1145 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
1146 if(resinfo != SIS_RI_1600x1200) {
1147 tempbx |= SetInSlaveMode;
1148 }
1149 }
1150 }
1151 } else {
1152 tempbx |= SetInSlaveMode;
1153 }
1154 }
1191 1155
1192 SiS_Pr->SiS_VBInfo = tempbx; 1156 }
1193 1157
1194 if(HwInfo->jChipType == SIS_630) { 1158 SiS_Pr->SiS_VBInfo = tempbx;
1195 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1196 }
1197 1159
1198#ifdef TWDEBUG 1160#ifdef SIS300
1199#ifdef LINUX_KERNEL 1161 if(SiS_Pr->ChipType == SIS_630) {
1200 printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n", 1162 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
1163 }
1164#endif
1165
1166#ifdef SIS_LINUX_KERNEL
1167#if 0
1168 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
1201 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1169 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1202#endif 1170#endif
1203#ifdef LINUX_XF86 1171#endif
1204 xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", 1172#ifdef SIS_XORG_XF86
1173#ifdef TWDEBUG
1174 xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
1205 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1175 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
1206#endif 1176#endif
1207#endif 1177#endif
@@ -1212,41 +1182,41 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1212/*********************************************/ 1182/*********************************************/
1213 1183
1214void 1184void
1215SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1185SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
1216{ 1186{
1217 1187
1218 UCHAR temp; 1188 unsigned char temp;
1219 1189
1220 /* Note: This variable is only used on 30xLV systems. 1190 /* Note: This variable is only used on 30xLV systems.
1221 * CR38 has a different meaning on LVDS/CH7019 systems. 1191 * CR38 has a different meaning on LVDS/CH7019 systems.
1222 * On 661 and later, these bits moved to CR35. 1192 * On 661 and later, these bits moved to CR35.
1223 * 1193 *
1224 * On 301, 301B, only HiVision 1080i is supported. 1194 * On 301, 301B, only HiVision 1080i is supported.
1225 * On 30xLV, 301C, only YPbPr 1080i is supported. 1195 * On 30xLV, 301C, only YPbPr 1080i is supported.
1226 */ 1196 */
1227 1197
1228 SiS_Pr->SiS_YPbPr = 0; 1198 SiS_Pr->SiS_YPbPr = 0;
1229 if(HwInfo->jChipType >= SIS_661) return; 1199 if(SiS_Pr->ChipType >= SIS_661) return;
1230 1200
1231 if(SiS_Pr->SiS_VBType) { 1201 if(SiS_Pr->SiS_VBType) {
1232 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1202 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1233 SiS_Pr->SiS_YPbPr = YPbPrHiVision; 1203 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
1234 } 1204 }
1235 } 1205 }
1236 1206
1237 if(HwInfo->jChipType >= SIS_315H) { 1207 if(SiS_Pr->ChipType >= SIS_315H) {
1238 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) { 1208 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
1239 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1209 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1240 if(temp & 0x08) { 1210 if(temp & 0x08) {
1241 switch((temp >> 4)) { 1211 switch((temp >> 4)) {
1242 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break; 1212 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
1243 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break; 1213 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
1244 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break; 1214 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
1245 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break; 1215 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
1246 } 1216 }
1247 } 1217 }
1248 } 1218 }
1249 } 1219 }
1250 1220
1251} 1221}
1252 1222
@@ -1255,199 +1225,204 @@ SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1255/*********************************************/ 1225/*********************************************/
1256 1226
1257void 1227void
1258SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo) 1228SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1259{ 1229{
1260 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 1230 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1261 USHORT temp, temp1, resinfo = 0, romindex = 0; 1231 unsigned short temp, temp1, resinfo = 0, romindex = 0;
1262 UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect; 1232 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
1263 1233
1264 SiS_Pr->SiS_TVMode = 0; 1234 SiS_Pr->SiS_TVMode = 0;
1265 1235
1266 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 1236 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
1267 if(SiS_Pr->UseCustomMode) return; 1237 if(SiS_Pr->UseCustomMode) return;
1268 1238
1269 if(ModeNo > 0x13) { 1239 if(ModeNo > 0x13) {
1270 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1240 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1271 } 1241 }
1272 1242
1273 if(HwInfo->jChipType < SIS_661) { 1243 if(SiS_Pr->ChipType < SIS_661) {
1274 1244
1275 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL; 1245 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
1276 1246
1277 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1247 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1278 temp = 0; 1248 temp = 0;
1279 if((HwInfo->jChipType == SIS_630) || 1249 if((SiS_Pr->ChipType == SIS_630) ||
1280 (HwInfo->jChipType == SIS_730)) { 1250 (SiS_Pr->ChipType == SIS_730)) {
1281 temp = 0x35; 1251 temp = 0x35;
1282 romindex = 0xfe; 1252 romindex = 0xfe;
1283 } else if(HwInfo->jChipType >= SIS_315H) { 1253 } else if(SiS_Pr->ChipType >= SIS_315H) {
1284 temp = 0x38; 1254 temp = 0x38;
1285 romindex = 0xf3; 1255 if(SiS_Pr->ChipType < XGI_20) {
1286 if(HwInfo->jChipType >= SIS_330) romindex = 0x11b; 1256 romindex = 0xf3;
1287 } 1257 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
1288 if(temp) { 1258 }
1289 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 1259 }
1290 OutputSelect = ROMAddr[romindex]; 1260 if(temp) {
1291 if(!(OutputSelect & EnablePALMN)) { 1261 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
1292 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F); 1262 OutputSelect = ROMAddr[romindex];
1293 } 1263 if(!(OutputSelect & EnablePALMN)) {
1294 } 1264 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
1295 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp); 1265 }
1296 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1266 }
1297 if(temp1 & EnablePALM) { /* 0x40 */ 1267 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
1298 SiS_Pr->SiS_TVMode |= TVSetPALM; 1268 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1299 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1269 if(temp1 & EnablePALM) { /* 0x40 */
1300 } else if(temp1 & EnablePALN) { /* 0x80 */ 1270 SiS_Pr->SiS_TVMode |= TVSetPALM;
1301 SiS_Pr->SiS_TVMode |= TVSetPALN; 1271 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1302 } 1272 } else if(temp1 & EnablePALN) { /* 0x80 */
1303 } else { 1273 SiS_Pr->SiS_TVMode |= TVSetPALN;
1304 if(temp1 & EnableNTSCJ) { /* 0x40 */ 1274 }
1305 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1275 } else {
1306 } 1276 if(temp1 & EnableNTSCJ) { /* 0x40 */
1307 } 1277 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1308 } 1278 }
1309 /* Translate HiVision/YPbPr to our new flags */ 1279 }
1310 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1280 }
1311 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1281 /* Translate HiVision/YPbPr to our new flags */
1312 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1282 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1313 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision; 1283 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1314 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1284 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1315 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) { 1285 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
1316 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision; 1286 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1317 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750; 1287 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
1318 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 1288 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
1319 SiS_Pr->SiS_TVMode |= TVSetPAL; 1289 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
1320 } 1290 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
1321 } 1291 SiS_Pr->SiS_TVMode |= TVSetPAL;
1322 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1292 }
1323 if(SiS_Pr->SiS_CHOverScan) { 1293 }
1324 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 1294 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
1325 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1295 if(SiS_Pr->SiS_CHOverScan) {
1326 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) { 1296 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
1327 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1297 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1328 } 1298 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
1329 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1299 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1330 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79); 1300 }
1331 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) { 1301 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1332 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1302 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
1333 } 1303 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
1334 } 1304 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1335 if(SiS_Pr->SiS_CHSOverScan) { 1305 }
1336 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1306 }
1337 } 1307 if(SiS_Pr->SiS_CHSOverScan) {
1338 } 1308 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1339 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1309 }
1340 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1310 }
1341 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1311 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1342 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM; 1312 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
1343 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN; 1313 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
1344 } else { 1314 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
1345 if(temp & EnableNTSCJ) { 1315 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
1346 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1316 } else {
1347 } 1317 if(temp & EnableNTSCJ) {
1348 } 1318 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1349 } 1319 }
1350 } 1320 }
1321 }
1322 }
1351 1323
1352 } else { /* 661 and later */ 1324 } else { /* 661 and later */
1353 1325
1354 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1326 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1355 if(temp1 & 0x01) { 1327 if(temp1 & 0x01) {
1356 SiS_Pr->SiS_TVMode |= TVSetPAL; 1328 SiS_Pr->SiS_TVMode |= TVSetPAL;
1357 if(temp1 & 0x08) { 1329 if(temp1 & 0x08) {
1358 SiS_Pr->SiS_TVMode |= TVSetPALN; 1330 SiS_Pr->SiS_TVMode |= TVSetPALN;
1359 } else if(temp1 & 0x04) { 1331 } else if(temp1 & 0x04) {
1360 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1332 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1361 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1333 SiS_Pr->SiS_TVMode &= ~TVSetPAL;
1362 } 1334 }
1363 SiS_Pr->SiS_TVMode |= TVSetPALM; 1335 SiS_Pr->SiS_TVMode |= TVSetPALM;
1364 } 1336 }
1365 } else { 1337 } else {
1366 if(temp1 & 0x02) { 1338 if(temp1 & 0x02) {
1367 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1339 SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
1368 } 1340 }
1369 } 1341 }
1370 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1342 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
1371 if(SiS_Pr->SiS_CHOverScan) { 1343 if(SiS_Pr->SiS_CHOverScan) {
1372 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) { 1344 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
1373 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1345 SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
1374 } 1346 }
1375 } 1347 }
1376 } 1348 }
1377 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1349 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1350 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1379 temp1 &= 0xe0; 1351 temp1 &= 0xe0;
1380 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1352 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
1381 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1353 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
1382 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1354 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
1383 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1355 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1384 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL); 1356 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
1385 } 1357 }
1386 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) { 1358 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
1387 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) { 1359 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
1388 SiS_Pr->SiS_TVMode |= TVAspect169; 1360 SiS_Pr->SiS_TVMode |= TVAspect169;
1389 } else { 1361 } else {
1390 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39); 1362 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
1391 if(temp1 & 0x02) { 1363 if(temp1 & 0x02) {
1392 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) { 1364 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
1393 SiS_Pr->SiS_TVMode |= TVAspect169; 1365 SiS_Pr->SiS_TVMode |= TVAspect169;
1394 } else { 1366 } else {
1395 SiS_Pr->SiS_TVMode |= TVAspect43LB; 1367 SiS_Pr->SiS_TVMode |= TVAspect43LB;
1396 } 1368 }
1397 } else { 1369 } else {
1398 SiS_Pr->SiS_TVMode |= TVAspect43; 1370 SiS_Pr->SiS_TVMode |= TVAspect43;
1399 } 1371 }
1400 } 1372 }
1401 } 1373 }
1402 } 1374 }
1403 } 1375 }
1404 1376
1405 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL; 1377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
1406 1378
1407 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1379 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1408 1380
1409 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1381 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
1410 SiS_Pr->SiS_TVMode |= TVSetPAL; 1382 SiS_Pr->SiS_TVMode |= TVSetPAL;
1411 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ); 1383 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
1412 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1384 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
1413 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) { 1385 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
1414 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN); 1386 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
1415 } 1387 }
1416 } 1388 }
1417 1389
1418 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 1390 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
1419 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 1391 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
1420 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 1392 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
1421 } 1393 }
1422 } 1394 }
1423 1395
1424 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 1396 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
1425 /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */ 1397 if(resinfo == SIS_RI_1024x768) {
1426 if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) { 1398 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
1427 if(resinfo == SIS_RI_1024x768) { 1399 SiS_Pr->SiS_TVMode |= TVSet525p1024;
1428 SiS_Pr->SiS_TVMode |= TVSetNTSC1024; 1400 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
1429 } 1401 SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
1430 } 1402 }
1431 } 1403 }
1404 }
1432 1405
1433 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO; 1406 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
1434 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && 1407 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
1435 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 1408 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
1436 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1409 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1437 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 1410 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
1438 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1411 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1439 } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { 1412 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
1440 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 1413 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
1441 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1414 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
1442 } 1415 }
1443 } 1416 }
1444 1417
1445 } 1418 }
1446 1419
1447 SiS_Pr->SiS_VBInfo &= ~SetPALTV; 1420 SiS_Pr->SiS_VBInfo &= ~SetPALTV;
1448 1421
1422#ifdef SIS_XORG_XF86
1449#ifdef TWDEBUG 1423#ifdef TWDEBUG
1450 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo); 1424 xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
1425#endif
1451#endif 1426#endif
1452} 1427}
1453 1428
@@ -1455,41 +1430,46 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
1455/* GET LCD INFO */ 1430/* GET LCD INFO */
1456/*********************************************/ 1431/*********************************************/
1457 1432
1458static USHORT 1433static unsigned short
1459SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr) 1434SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
1460{ 1435{
1461 USHORT temp = SiS_Pr->SiS_LCDResInfo; 1436 unsigned short temp = SiS_Pr->SiS_LCDResInfo;
1462 /* Translate my LCDResInfo to BIOS value */ 1437 /* Translate my LCDResInfo to BIOS value */
1463 if(temp == Panel_1280x768_2) temp = Panel_1280x768; 1438 switch(temp) {
1464 if(temp == Panel_1280x800_2) temp = Panel_1280x800; 1439 case Panel_1280x768_2: temp = Panel_1280x768; break;
1440 case Panel_1280x800_2: temp = Panel_1280x800; break;
1441 case Panel_1280x854: temp = Panel661_1280x854; break;
1442 }
1465 return temp; 1443 return temp;
1466} 1444}
1467 1445
1468static void 1446static void
1469SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 1447SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
1470{ 1448{
1471#ifdef SIS315H 1449#ifdef SIS315H
1472 UCHAR *ROMAddr; 1450 unsigned char *ROMAddr;
1473 USHORT temp; 1451 unsigned short temp;
1474 1452
1453#ifdef SIS_XORG_XF86
1475#ifdef TWDEBUG 1454#ifdef TWDEBUG
1476 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", 1455 xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1477 SiS_Pr->PanelHT, SiS_Pr->PanelVT, 1456 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1478 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, 1457 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1479 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, 1458 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1480 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, 1459 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1481 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, 1460 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1482 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); 1461 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1483#endif 1462#endif
1463#endif
1484 1464
1485 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) { 1465 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
1486 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { 1466 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
1487 SiS_Pr->SiS_NeedRomModeData = TRUE; 1467 SiS_Pr->SiS_NeedRomModeData = TRUE;
1488 SiS_Pr->PanelHT = temp; 1468 SiS_Pr->PanelHT = temp;
1489 } 1469 }
1490 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) { 1470 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
1491 SiS_Pr->SiS_NeedRomModeData = TRUE; 1471 SiS_Pr->SiS_NeedRomModeData = TRUE;
1492 SiS_Pr->PanelVT = temp; 1472 SiS_Pr->PanelVT = temp;
1493 } 1473 }
1494 SiS_Pr->PanelHRS = SISGETROMW(10); 1474 SiS_Pr->PanelHRS = SISGETROMW(10);
1495 SiS_Pr->PanelHRE = SISGETROMW(12); 1475 SiS_Pr->PanelHRE = SISGETROMW(12);
@@ -1497,56 +1477,58 @@ SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
1497 SiS_Pr->PanelVRE = SISGETROMW(16); 1477 SiS_Pr->PanelVRE = SISGETROMW(16);
1498 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1478 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1499 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK = 1479 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
1500 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]); 1480 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
1501 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B = 1481 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
1502 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19]; 1482 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
1503 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = 1483 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
1504 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; 1484 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
1505 1485
1486#ifdef SIS_XORG_XF86
1506#ifdef TWDEBUG 1487#ifdef TWDEBUG
1507 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", 1488 xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
1508 SiS_Pr->PanelHT, SiS_Pr->PanelVT, 1489 SiS_Pr->PanelHT, SiS_Pr->PanelVT,
1509 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, 1490 SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
1510 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, 1491 SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
1511 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, 1492 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
1512 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, 1493 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
1513 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); 1494 SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
1514#endif 1495#endif
1496#endif
1515 1497
1516 } 1498 }
1517#endif 1499#endif
1518} 1500}
1519 1501
1520static void 1502static void
1521SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes) 1503SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
1522{ 1504 const unsigned char *nonscalingmodes)
1523 int i = 0; 1505{
1524 while(nonscalingmodes[i] != 0xff) { 1506 int i = 0;
1525 if(nonscalingmodes[i++] == resinfo) { 1507 while(nonscalingmodes[i] != 0xff) {
1526 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || 1508 if(nonscalingmodes[i++] == resinfo) {
1527 (SiS_Pr->UsePanelScaler == -1)) { 1509 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
1528 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1510 (SiS_Pr->UsePanelScaler == -1)) {
1529 } 1511 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1530 break; 1512 }
1531 } 1513 break;
1532 } 1514 }
1515 }
1533} 1516}
1534 1517
1535void 1518void
1536SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 1519SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1537 PSIS_HW_INFO HwInfo)
1538{ 1520{
1521 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1522 BOOLEAN panelcanscale = FALSE;
1539#ifdef SIS300 1523#ifdef SIS300
1540 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 1524 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
1541 const unsigned char SiS300SeriesLCDRes[] = 1525 static const unsigned char SiS300SeriesLCDRes[] =
1542 { 0, 1, 2, 3, 7, 4, 5, 8, 1526 { 0, 1, 2, 3, 7, 4, 5, 8,
1543 0, 0, 10, 0, 0, 0, 0, 15 }; 1527 0, 0, 10, 0, 0, 0, 0, 15 };
1544#endif 1528#endif
1545#ifdef SIS315H 1529#ifdef SIS315H
1546 UCHAR *myptr = NULL; 1530 unsigned char *myptr = NULL;
1547#endif 1531#endif
1548 USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
1549 BOOLEAN panelcanscale = FALSE;
1550 1532
1551 SiS_Pr->SiS_LCDResInfo = 0; 1533 SiS_Pr->SiS_LCDResInfo = 0;
1552 SiS_Pr->SiS_LCDTypeInfo = 0; 1534 SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -1557,14 +1539,14 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1557 SiS_Pr->PanelVRE = 999; /* VSync end */ 1539 SiS_Pr->PanelVRE = 999; /* VSync end */
1558 SiS_Pr->SiS_NeedRomModeData = FALSE; 1540 SiS_Pr->SiS_NeedRomModeData = FALSE;
1559 1541
1542 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
1543 SiS_Pr->Alternate1600x1200 = FALSE;
1544
1560 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return; 1545 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
1561 1546
1562 if(ModeNo <= 0x13) { 1547 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1563 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 1548
1564 } else if(SiS_Pr->UseCustomMode) { 1549 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
1565 modeflag = SiS_Pr->CModeFlag;
1566 } else {
1567 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1568 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1550 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1569 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal; 1551 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
1570 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal; 1552 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
@@ -1575,16 +1557,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1575 /* For broken BIOSes: Assume 1024x768 */ 1557 /* For broken BIOSes: Assume 1024x768 */
1576 if(temp == 0) temp = 0x02; 1558 if(temp == 0) temp = 0x02;
1577 1559
1578 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 1560 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
1579 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2; 1561 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
1580 } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) { 1562 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
1581 SiS_Pr->SiS_LCDTypeInfo = temp >> 4; 1563 SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
1582 } else { 1564 } else {
1583 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; 1565 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
1584 } 1566 }
1585 temp &= 0x0f; 1567 temp &= 0x0f;
1586#ifdef SIS300 1568#ifdef SIS300
1587 if(HwInfo->jChipType < SIS_315H) { 1569 if(SiS_Pr->ChipType < SIS_315H) {
1588 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ 1570 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
1589 if(SiS_Pr->SiS_VBType & VB_SIS301) { 1571 if(SiS_Pr->SiS_VBType & VB_SIS301) {
1590 if(temp < 0x0f) temp &= 0x07; 1572 if(temp < 0x0f) temp &= 0x07;
@@ -1595,17 +1577,22 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1595#endif 1577#endif
1596 1578
1597 /* Translate to our internal types */ 1579 /* Translate to our internal types */
1598 if(HwInfo->jChipType == SIS_550) { 1580#ifdef SIS315H
1599 if(temp == Panel310_640x480_2) temp = Panel_640x480_2; 1581 if(SiS_Pr->ChipType == SIS_550) {
1600 if(temp == Panel310_640x480_3) temp = Panel_640x480_3; 1582 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
1583 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
1584 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
1585 } else if(SiS_Pr->ChipType >= SIS_661) {
1586 if(temp == Panel661_1280x854) temp = Panel_1280x854;
1601 } 1587 }
1588#endif
1602 1589
1603 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */ 1590 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
1604 if(temp == Panel310_1280x768) { 1591 if(temp == Panel310_1280x768) {
1605 temp = Panel_1280x768_2; 1592 temp = Panel_1280x768_2;
1606 } 1593 }
1607 if(SiS_Pr->SiS_ROMNew) { 1594 if(SiS_Pr->SiS_ROMNew) {
1608 if(temp == Panel661_1280x800) { 1595 if(temp == Panel661_1280x800) {
1609 temp = Panel_1280x800_2; 1596 temp = Panel_1280x800_2;
1610 } 1597 }
1611 } 1598 }
@@ -1613,13 +1600,17 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1613 1600
1614 SiS_Pr->SiS_LCDResInfo = temp; 1601 SiS_Pr->SiS_LCDResInfo = temp;
1615 1602
1603#ifdef SIS300
1616 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1604 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1617 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 1605 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
1618 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; 1606 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
1619 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 1607 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
1620 SiS_Pr->SiS_LCDResInfo = Panel_848x480; 1608 SiS_Pr->SiS_LCDResInfo = Panel_848x480;
1609 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
1610 SiS_Pr->SiS_LCDResInfo = Panel_856x480;
1621 } 1611 }
1622 } 1612 }
1613#endif
1623 1614
1624 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1615 if(SiS_Pr->SiS_VBType & VB_SISVB) {
1625 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301) 1616 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
@@ -1633,10 +1624,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1633 SiS_Pr->SiS_LCDInfo = temp & ~0x000e; 1624 SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
1634 /* Need temp below! */ 1625 /* Need temp below! */
1635 1626
1636 /* These can't scale no matter what */ 1627 /* These must/can't scale no matter what */
1637 switch(SiS_Pr->SiS_LCDResInfo) { 1628 switch(SiS_Pr->SiS_LCDResInfo) {
1629 case Panel_320x240_1:
1630 case Panel_320x240_2:
1631 case Panel_320x240_3:
1638 case Panel_1280x960: 1632 case Panel_1280x960:
1639 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1633 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
1634 break;
1635 case Panel_640x480:
1636 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1640 } 1637 }
1641 1638
1642 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE; 1639 panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
@@ -1646,41 +1643,41 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1646 1643
1647 /* Dual link, Pass 1:1 BIOS default, etc. */ 1644 /* Dual link, Pass 1:1 BIOS default, etc. */
1648#ifdef SIS315H 1645#ifdef SIS315H
1649 if(HwInfo->jChipType >= SIS_661) { 1646 if(SiS_Pr->ChipType >= SIS_661) {
1650 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1647 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1651 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1648 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1652 } 1649 }
1653 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 1650 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1654 if(SiS_Pr->SiS_ROMNew) { 1651 if(SiS_Pr->SiS_ROMNew) {
1655 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1652 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1656 } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) { 1653 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
1657 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1654 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1658 } 1655 }
1659 } 1656 }
1660 } else if(HwInfo->jChipType >= SIS_315H) { 1657 } else if(SiS_Pr->ChipType >= SIS_315H) {
1661 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1658 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
1662 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1659 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1663 } 1660 }
1664 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) { 1661 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
1665 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit); 1662 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
1666 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1663 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
1667 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit; 1664 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
1668 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 1665 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1669 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1666 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1670 } 1667 }
1671 } else if(!(SiS_Pr->SiS_ROMNew)) { 1668 } else if(!(SiS_Pr->SiS_ROMNew)) {
1672 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 1669 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
1673 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) && 1670 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
1674 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) { 1671 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
1675 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1672 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1676 } 1673 }
1677 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 1674 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
1678 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 1675 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
1679 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 1676 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
1680 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) { 1677 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
1681 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1678 SiS_Pr->SiS_LCDInfo |= LCDDualLink;
1682 } 1679 }
1683 } 1680 }
1684 } 1681 }
1685 } 1682 }
1686#endif 1683#endif
@@ -1691,12 +1688,12 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1691 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1688 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1692 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1689 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
1693 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 1690 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
1694 /* Always center screen on SiS LVDS (if scaling is disabled) */ 1691 /* Always center screen on SiS LVDS (if scaling is disabled) */
1695 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1692 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1696 } else { 1693 } else {
1697 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */ 1694 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
1698 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1695 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
1699 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1696 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
1700 } 1697 }
1701 } 1698 }
1702 1699
@@ -1704,19 +1701,15 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1704 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1701 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1705 1702
1706 switch(SiS_Pr->SiS_LCDResInfo) { 1703 switch(SiS_Pr->SiS_LCDResInfo) {
1707 case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480; 1704 case Panel_320x240_1:
1708 SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525; 1705 case Panel_320x240_2:
1709 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1706 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1710 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1707 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1711 break;
1712 case Panel_640x480_2:
1713 case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1714 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
1715 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1708 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1716 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1709 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1717 break; 1710 break;
1718 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1711 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
1719 SiS_Pr->PanelVRE = 3; 1712 SiS_Pr->PanelVRE = 3;
1720 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1713 SiS_Pr->PanelVCLKIdx300 = VCLK28;
1721 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1714 SiS_Pr->PanelVCLKIdx315 = VCLK28;
1722 break; 1715 break;
@@ -1728,52 +1721,52 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1728 SiS_Pr->PanelVCLKIdx315 = VCLK40; 1721 SiS_Pr->PanelVCLKIdx315 = VCLK40;
1729 break; 1722 break;
1730 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; 1723 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
1731 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800; 1724 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
1732 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1725 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1733 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6; 1726 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
1734 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1727 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1735 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1728 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1736 break; 1729 break;
1737 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 1730 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1738 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1731 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1739 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1732 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1740 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1733 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1741 if(HwInfo->jChipType < SIS_315H) { 1734 if(SiS_Pr->ChipType < SIS_315H) {
1742 SiS_Pr->PanelHRS = 23; 1735 SiS_Pr->PanelHRS = 23;
1743 SiS_Pr->PanelVRE = 5; 1736 SiS_Pr->PanelVRE = 5;
1744 } 1737 }
1745 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1738 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1746 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1739 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1747 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1740 SiS_GetLCDInfoBIOS(SiS_Pr);
1748 break; 1741 break;
1749 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; 1742 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
1750 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1743 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1751 SiS_Pr->PanelHRS = 24; 1744 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
1752 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1745 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1753 if(HwInfo->jChipType < SIS_315H) { 1746 if(SiS_Pr->ChipType < SIS_315H) {
1754 SiS_Pr->PanelHRS = 23; 1747 SiS_Pr->PanelHRS = 23;
1755 SiS_Pr->PanelVRE = 5; 1748 SiS_Pr->PanelVRE = 5;
1756 } 1749 }
1757 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1750 SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
1758 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 1751 SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
1759 break; 1752 break;
1760 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; 1753 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
1761 break; 1754 break;
1762 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720; 1755 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
1763 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750; 1756 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
1764 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40; 1757 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
1765 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5; 1758 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
1766 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720; 1759 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
1767 /* Data above for TMDS (projector); get from BIOS for LVDS */ 1760 /* Data above for TMDS (projector); get from BIOS for LVDS */
1768 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1761 SiS_GetLCDInfoBIOS(SiS_Pr);
1769 break; 1762 break;
1770 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 1763 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1771 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1764 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
1772 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806; 1765 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
1773 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */ 1766 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
1774 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */ 1767 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
1775 } else { 1768 } else {
1776 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802; 1769 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
1777 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112; 1770 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
1778 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1771 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1779 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; 1772 SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
@@ -1781,77 +1774,100 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1781 } 1774 }
1782 break; 1775 break;
1783 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 1776 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
1784 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806; 1777 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
1785 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1778 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1786 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1779 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1787 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2; 1780 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
1788 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1781 SiS_GetLCDInfoBIOS(SiS_Pr);
1789 break; 1782 break;
1790 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 1783 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1791 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816; 1784 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
1792 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24; 1785 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
1793 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 1786 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1794 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315; 1787 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
1795 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1788 SiS_GetLCDInfoBIOS(SiS_Pr);
1796 break; 1789 break;
1797 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 1790 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
1798 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812; 1791 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
1799 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1792 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1800 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 1793 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
1801 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2; 1794 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
1802 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1795 SiS_GetLCDInfoBIOS(SiS_Pr);
1796 break;
1797 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
1798 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
1799 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
1800 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1801 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
1802 SiS_GetLCDInfoBIOS(SiS_Pr);
1803 break; 1803 break;
1804 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; 1804 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
1805 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000; 1805 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
1806 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 1806 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1807 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315; 1807 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
1808 if(resinfo == SIS_RI_1280x1024) { 1808 if(resinfo == SIS_RI_1280x1024) {
1809 SiS_Pr->PanelVCLKIdx300 = VCLK100_300; 1809 SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
1810 SiS_Pr->PanelVCLKIdx315 = VCLK100_315; 1810 SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
1811 } 1811 }
1812 break; 1812 break;
1813 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; 1813 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
1814 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1814 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1815 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 1815 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1816 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1816 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1817 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 1817 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
1818 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1818 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1819 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1819 SiS_GetLCDInfoBIOS(SiS_Pr);
1820 break; 1820 break;
1821 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; 1821 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
1822 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1822 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1823 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */ 1823 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
1824 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1824 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1825 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1825 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
1826 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1826 SiS_GetLCDInfoBIOS(SiS_Pr);
1827 break; 1827 break;
1828 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; 1828 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
1829 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250; 1829 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
1830 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192; 1830 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
1831 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 1831 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
1832 SiS_Pr->PanelVCLKIdx315 = VCLK162_315; 1832 SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
1833 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1833 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
1834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
1835 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
1836 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
1837 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
1838 SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
1839 SiS_Pr->Alternate1600x1200 = TRUE;
1840 }
1841 } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
1842 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
1843 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
1844 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
1845 }
1846 SiS_GetLCDInfoBIOS(SiS_Pr);
1834 break; 1847 break;
1835 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050; 1848 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
1836 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066; 1849 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
1837 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76; 1850 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
1838 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 1851 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
1839 SiS_Pr->PanelVCLKIdx315 = VCLK121_315; 1852 SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
1840 SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo); 1853 SiS_GetLCDInfoBIOS(SiS_Pr);
1841 break; 1854 break;
1842 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; 1855 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
1843 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 1856 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
1844 break; 1857 break;
1845 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; 1858 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
1846 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 1859 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1847 break; 1860 break;
1861 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
1862 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
1863 break;
1848 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX; 1864 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
1849 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY; 1865 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
1850 SiS_Pr->PanelHT = SiS_Pr->CHTotal; 1866 SiS_Pr->PanelHT = SiS_Pr->CHTotal;
1851 SiS_Pr->PanelVT = SiS_Pr->CVTotal; 1867 SiS_Pr->PanelVT = SiS_Pr->CVTotal;
1852 if(SiS_Pr->CP_PreferredIndex != -1) { 1868 if(SiS_Pr->CP_PreferredIndex != -1) {
1853 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex]; 1869 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
1854 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex]; 1870 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
1855 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex]; 1871 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
1856 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex]; 1872 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
1857 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex]; 1873 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
@@ -1863,22 +1879,22 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1863 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes; 1879 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
1864 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS; 1880 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
1865 if(SiS_Pr->CP_PrefClock) { 1881 if(SiS_Pr->CP_PrefClock) {
1866 int idx; 1882 int idx;
1867 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1883 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
1868 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300; 1884 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
1869 if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300; 1885 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
1870 else idx = VCLK_CUSTOM_315; 1886 else idx = VCLK_CUSTOM_315;
1871 SiS_Pr->SiS_VCLKData[idx].CLOCK = 1887 SiS_Pr->SiS_VCLKData[idx].CLOCK =
1872 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock; 1888 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
1873 SiS_Pr->SiS_VCLKData[idx].SR2B = 1889 SiS_Pr->SiS_VCLKData[idx].SR2B =
1874 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B; 1890 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
1875 SiS_Pr->SiS_VCLKData[idx].SR2C = 1891 SiS_Pr->SiS_VCLKData[idx].SR2C =
1876 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C; 1892 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
1877 } 1893 }
1878 } 1894 }
1879 break; 1895 break;
1880 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 1896 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
1881 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 1897 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
1882 break; 1898 break;
1883 } 1899 }
1884 1900
@@ -1887,14 +1903,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1887 (SiS_Pr->SiS_IF_DEF_DSTN) || 1903 (SiS_Pr->SiS_IF_DEF_DSTN) ||
1888 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 1904 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1889 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 1905 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1890 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) { 1906 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1907 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1891 SiS_Pr->PanelHRS = 999; 1908 SiS_Pr->PanelHRS = 999;
1892 SiS_Pr->PanelHRE = 999; 1909 SiS_Pr->PanelHRE = 999;
1893 } 1910 }
1894 1911
1895 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 1912 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
1896 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 1913 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
1897 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) { 1914 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
1915 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
1898 SiS_Pr->PanelVRS = 999; 1916 SiS_Pr->PanelVRS = 999;
1899 SiS_Pr->PanelVRE = 999; 1917 SiS_Pr->PanelVRE = 999;
1900 } 1918 }
@@ -1912,18 +1930,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1912 case Panel_Custom: 1930 case Panel_Custom:
1913 case Panel_1152x864: 1931 case Panel_1152x864:
1914 case Panel_1280x768: /* TMDS only */ 1932 case Panel_1280x768: /* TMDS only */
1915 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1933 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1916 break; 1934 break;
1917 1935
1918 case Panel_800x600: { 1936 case Panel_800x600: {
1919 static const UCHAR nonscalingmodes[] = { 1937 static const unsigned char nonscalingmodes[] = {
1920 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff 1938 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
1921 }; 1939 };
1922 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 1940 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1923 break; 1941 break;
1924 } 1942 }
1925 case Panel_1024x768: { 1943 case Panel_1024x768: {
1926 static const UCHAR nonscalingmodes[] = { 1944 static const unsigned char nonscalingmodes[] = {
1927 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1945 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1928 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1946 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1929 0xff 1947 0xff
@@ -1932,7 +1950,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1932 break; 1950 break;
1933 } 1951 }
1934 case Panel_1280x720: { 1952 case Panel_1280x720: {
1935 static const UCHAR nonscalingmodes[] = { 1953 static const unsigned char nonscalingmodes[] = {
1936 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1954 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1937 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1955 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1938 0xff 1956 0xff
@@ -1944,7 +1962,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1944 break; 1962 break;
1945 } 1963 }
1946 case Panel_1280x768_2: { /* LVDS only */ 1964 case Panel_1280x768_2: { /* LVDS only */
1947 static const UCHAR nonscalingmodes[] = { 1965 static const unsigned char nonscalingmodes[] = {
1948 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1966 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1949 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1967 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1950 SIS_RI_1152x768,0xff 1968 SIS_RI_1152x768,0xff
@@ -1952,23 +1970,23 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1952 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 1970 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1953 switch(resinfo) { 1971 switch(resinfo) {
1954 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 1972 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
1955 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1973 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1956 } 1974 }
1957 break; 1975 break;
1958 } 1976 }
1959 break; 1977 break;
1960 } 1978 }
1961 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */ 1979 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
1962 static const UCHAR nonscalingmodes[] = { 1980 static const unsigned char nonscalingmodes[] = {
1963 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1981 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1964 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1982 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1965 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff 1983 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
1966 }; 1984 };
1967 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 1985 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1968 break; 1986 break;
1969 } 1987 }
1970 case Panel_1280x800_2: { /* SiS LVDS */ 1988 case Panel_1280x800_2: { /* SiS LVDS */
1971 static const UCHAR nonscalingmodes[] = { 1989 static const unsigned char nonscalingmodes[] = {
1972 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 1990 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1973 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 1991 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1974 SIS_RI_1152x768,0xff 1992 SIS_RI_1152x768,0xff
@@ -1977,66 +1995,83 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
1977 switch(resinfo) { 1995 switch(resinfo) {
1978 case SIS_RI_1280x720: 1996 case SIS_RI_1280x720:
1979 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) { 1997 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
1980 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1998 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
1981 } 1999 }
1982 break; 2000 break;
1983 } 2001 }
1984 break; 2002 break;
2003 }
2004 case Panel_1280x854: { /* SiS LVDS */
2005 static const unsigned char nonscalingmodes[] = {
2006 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2007 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2008 SIS_RI_1152x768,0xff
2009 };
2010 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2011 switch(resinfo) {
2012 case SIS_RI_1280x720:
2013 case SIS_RI_1280x768:
2014 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
2015 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2016 }
2017 break;
2018 }
2019 break;
1985 } 2020 }
1986 case Panel_1280x960: { 2021 case Panel_1280x960: {
1987 static const UCHAR nonscalingmodes[] = { 2022 static const unsigned char nonscalingmodes[] = {
1988 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2023 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1989 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2024 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
1990 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2025 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
1991 0xff 2026 SIS_RI_1280x854,0xff
1992 }; 2027 };
1993 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2028 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
1994 break; 2029 break;
1995 } 2030 }
1996 case Panel_1280x1024: { 2031 case Panel_1280x1024: {
1997 static const UCHAR nonscalingmodes[] = { 2032 static const unsigned char nonscalingmodes[] = {
1998 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2033 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
1999 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2034 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2000 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2035 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2001 SIS_RI_1280x960,0xff 2036 SIS_RI_1280x854,SIS_RI_1280x960,0xff
2002 }; 2037 };
2003 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2038 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2004 break; 2039 break;
2005 } 2040 }
2006 case Panel_1400x1050: { 2041 case Panel_1400x1050: {
2007 static const UCHAR nonscalingmodes[] = { 2042 static const unsigned char nonscalingmodes[] = {
2008 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2043 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2009 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2044 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2010 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960, 2045 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
2011 0xff 2046 SIS_RI_1280x960,0xff
2012 }; 2047 };
2013 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2048 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2014 switch(resinfo) { 2049 switch(resinfo) {
2015 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2050 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
2016 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2051 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2017 } 2052 }
2018 break; 2053 break;
2019 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2054 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
2020 break; 2055 break;
2021 } 2056 }
2022 break; 2057 break;
2023 } 2058 }
2024 case Panel_1600x1200: { 2059 case Panel_1600x1200: {
2025 static const UCHAR nonscalingmodes[] = { 2060 static const unsigned char nonscalingmodes[] = {
2026 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2061 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2027 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2062 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2028 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2063 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
2029 SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff 2064 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
2030 }; 2065 };
2031 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2066 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2032 break; 2067 break;
2033 } 2068 }
2034 case Panel_1680x1050: { 2069 case Panel_1680x1050: {
2035 static const UCHAR nonscalingmodes[] = { 2070 static const unsigned char nonscalingmodes[] = {
2036 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2071 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
2037 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2072 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
2038 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024, 2073 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
2039 0xff 2074 SIS_RI_1360x1024,0xff
2040 }; 2075 };
2041 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2076 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
2042 break; 2077 break;
@@ -2044,25 +2079,25 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2044 } 2079 }
2045 } 2080 }
2046 2081
2082#ifdef SIS300
2047 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2083 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2048 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 2084 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2049 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ 2085 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
2050 } 2086 }
2051 } 2087 }
2052 2088
2053#ifdef SIS300 2089 if(SiS_Pr->ChipType < SIS_315H) {
2054 if(HwInfo->jChipType < SIS_315H) {
2055 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2090 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2056 if(SiS_Pr->SiS_UseROM) { 2091 if(SiS_Pr->SiS_UseROM) {
2057 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 2092 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
2058 if(!(ROMAddr[0x235] & 0x02)) { 2093 if(!(ROMAddr[0x235] & 0x02)) {
2059 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2094 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2060 } 2095 }
2061 } 2096 }
2062 } 2097 }
2063 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 2098 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2064 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) { 2099 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
2065 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2100 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
2066 } 2101 }
2067 } 2102 }
2068 } 2103 }
@@ -2080,7 +2115,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2080 2115
2081 switch(SiS_Pr->SiS_LCDResInfo) { 2116 switch(SiS_Pr->SiS_LCDResInfo) {
2082 case Panel_640x480: 2117 case Panel_640x480:
2083 SiS_Pr->SiS_LCDInfo |= LCDPass11; 2118 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2084 break; 2119 break;
2085 case Panel_1280x800: 2120 case Panel_1280x800:
2086 /* Don't pass 1:1 by default (TMDS special) */ 2121 /* Don't pass 1:1 by default (TMDS special) */
@@ -2097,7 +2132,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2097 break; 2132 break;
2098 } 2133 }
2099 2134
2100 if(SiS_Pr->UseCustomMode) { 2135 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
2101 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2136 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
2102 } 2137 }
2103 2138
@@ -2107,19 +2142,19 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2107 } 2142 }
2108 2143
2109 /* LVDS DDA */ 2144 /* LVDS DDA */
2110 if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) { 2145 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
2111 2146
2112 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 2147 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
2113 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { 2148 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
2114 if(ModeNo == 0x12) { 2149 if(ModeNo == 0x12) {
2115 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 2150 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2116 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2151 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2117 } 2152 }
2118 } else if(ModeNo > 0x13) { 2153 } else if(ModeNo > 0x13) {
2119 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 2154 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
2120 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2155 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2121 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) { 2156 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
2122 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2157 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2123 } 2158 }
2124 } 2159 }
2125 } 2160 }
@@ -2128,18 +2163,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2128 } 2163 }
2129 2164
2130 if(modeflag & HalfDCLK) { 2165 if(modeflag & HalfDCLK) {
2131 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) { 2166 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
2132 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2167 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2133 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2168 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2134 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2169 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2135 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) { 2170 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
2136 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2171 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2137 } else if(ModeNo > 0x13) { 2172 } else if(ModeNo > 0x13) {
2138 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 2173 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
2139 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2174 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2140 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) { 2175 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
2141 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2176 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
2142 } 2177 }
2143 } 2178 }
2144 } 2179 }
2145 2180
@@ -2148,21 +2183,21 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2148 /* VESA timing */ 2183 /* VESA timing */
2149 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2184 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2150 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) { 2185 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
2151 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2186 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2152 } 2187 }
2153 } else { 2188 } else {
2154 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2189 SiS_Pr->SiS_SetFlag |= LCDVESATiming;
2155 } 2190 }
2156 2191
2157#ifdef LINUX_KERNEL 2192#ifdef SIS_LINUX_KERNEL
2158#ifdef TWDEBUG 2193#if 0
2159 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", 2194 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
2160 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); 2195 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
2161#endif 2196#endif
2162#endif 2197#endif
2163#ifdef LINUX_XF86 2198#ifdef SIS_XORG_XF86
2164 xf86DrvMsgVerb(0, X_PROBED, 4, 2199 xf86DrvMsgVerb(0, X_PROBED, 4,
2165 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n", 2200 "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
2166 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag); 2201 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
2167#endif 2202#endif
2168} 2203}
@@ -2171,45 +2206,46 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2171/* GET VCLK */ 2206/* GET VCLK */
2172/*********************************************/ 2207/*********************************************/
2173 2208
2174USHORT 2209unsigned short
2175SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2210SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2176 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 2211 unsigned short RefreshRateTableIndex)
2177{ 2212{
2178 USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0; 2213 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
2179 USHORT modeflag,resinfo,tempbx; 2214 unsigned short modeflag, resinfo, tempbx;
2180 const UCHAR *CHTVVCLKPtr = NULL; 2215 const unsigned char *CHTVVCLKPtr = NULL;
2181 2216
2182 if(ModeNo <= 0x13) { 2217 if(ModeNo <= 0x13) {
2183 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 2218 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2184 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 2219 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
2185 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2220 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2186 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03; 2221 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
2222 VCLKIndexGENCRT = VCLKIndexGEN;
2187 } else { 2223 } else {
2188 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 2224 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2189 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2225 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2190 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 2226 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2191 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 2227 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
2192 if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f; 2228 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
2229 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
2193 } 2230 }
2194 2231
2195 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */ 2232 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
2196 2233
2197 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2234 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2198 2235
2199 CRT2Index >>= 6; 2236 CRT2Index >>= 6;
2200 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */ 2237 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
2201 2238
2202 if(HwInfo->jChipType < SIS_315H) { 2239 if(SiS_Pr->ChipType < SIS_315H) {
2203 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2240 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2204 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2241 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2205 VCLKIndex = VCLKIndexGEN; 2242 VCLKIndex = VCLKIndexGEN;
2206 } 2243 }
2207 } else { 2244 } else {
2208 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2245 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2209 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2246 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
2210 switch(resinfo) { 2247 switch(resinfo) {
2211 /* Only those whose IndexGEN doesn't match VBVCLK array */ 2248 /* Correct those whose IndexGEN doesn't match VBVCLK array */
2212 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2213 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break; 2249 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
2214 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break; 2250 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
2215 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break; 2251 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
@@ -2218,18 +2254,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2218 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break; 2254 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
2219 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break; 2255 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
2220 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break; 2256 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
2257 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
2221 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break; 2258 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
2222 default: VCLKIndex = VCLKIndexGEN; 2259 default: VCLKIndex = VCLKIndexGEN;
2223 } 2260 }
2224 2261
2225 if(ModeNo <= 0x13) { 2262 if(ModeNo <= 0x13) {
2226 if(HwInfo->jChipType <= SIS_315PRO) { 2263 if(SiS_Pr->ChipType <= SIS_315PRO) {
2227 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42; 2264 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
2228 } else { 2265 } else {
2229 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00; 2266 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
2230 } 2267 }
2231 } 2268 }
2232 if(HwInfo->jChipType <= SIS_315PRO) { 2269 if(SiS_Pr->ChipType <= SIS_315PRO) {
2233 if(VCLKIndex == 0) VCLKIndex = 0x41; 2270 if(VCLKIndex == 0) VCLKIndex = 0x41;
2234 if(VCLKIndex == 1) VCLKIndex = 0x43; 2271 if(VCLKIndex == 1) VCLKIndex = 0x43;
2235 if(VCLKIndex == 4) VCLKIndex = 0x44; 2272 if(VCLKIndex == 4) VCLKIndex = 0x44;
@@ -2237,49 +2274,46 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2237 } 2274 }
2238 } 2275 }
2239 2276
2240 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */ 2277 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
2241 2278
2242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
2243 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2; 2280 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
2244 else VCLKIndex = HiTVVCLK; 2281 else VCLKIndex = HiTVVCLK;
2245 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 2282 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
2246 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK; 2283 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
2247 else VCLKIndex = HiTVTextVCLK; 2284 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
2248 } 2285 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
2249 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK; 2286 else VCLKIndex = TVVCLK;
2250 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2; 2287
2251 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2; 2288 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
2252 else VCLKIndex = TVVCLK; 2289 else VCLKIndex += TVCLKBASE_315;
2253 2290
2254 if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300; 2291 } else { /* VGA2 */
2255 else VCLKIndex += TVCLKBASE_315; 2292
2256 2293 VCLKIndex = VCLKIndexGENCRT;
2257 } else { /* VGA2 */ 2294 if(SiS_Pr->ChipType < SIS_315H) {
2258 2295 if(ModeNo > 0x13) {
2259 VCLKIndex = VCLKIndexGEN; 2296 if( (SiS_Pr->ChipType == SIS_630) &&
2260 if(HwInfo->jChipType < SIS_315H) { 2297 (SiS_Pr->ChipRevision >= 0x30)) {
2261 if(ModeNo > 0x13) {
2262 if( (HwInfo->jChipType == SIS_630) &&
2263 (HwInfo->jChipRevision >= 0x30)) {
2264 if(VCLKIndex == 0x14) VCLKIndex = 0x34; 2298 if(VCLKIndex == 0x14) VCLKIndex = 0x34;
2265 } 2299 }
2266 /* Better VGA2 clock for 1280x1024@75 */ 2300 /* Better VGA2 clock for 1280x1024@75 */
2267 if(VCLKIndex == 0x17) VCLKIndex = 0x45; 2301 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
2268 } 2302 }
2269 } 2303 }
2270 } 2304 }
2271 2305
2272 } else { /* If not programming CRT2 */ 2306 } else { /* If not programming CRT2 */
2273 2307
2274 VCLKIndex = VCLKIndexGEN; 2308 VCLKIndex = VCLKIndexGENCRT;
2275 if(HwInfo->jChipType < SIS_315H) { 2309 if(SiS_Pr->ChipType < SIS_315H) {
2276 if(ModeNo > 0x13) { 2310 if(ModeNo > 0x13) {
2277 if( (HwInfo->jChipType != SIS_630) && 2311 if( (SiS_Pr->ChipType != SIS_630) &&
2278 (HwInfo->jChipType != SIS_300) ) { 2312 (SiS_Pr->ChipType != SIS_300) ) {
2279 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2313 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2280 } 2314 }
2281 } 2315 }
2282 } 2316 }
2283 } 2317 }
2284 2318
2285 } else { /* LVDS */ 2319 } else { /* LVDS */
@@ -2288,12 +2322,12 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2288 2322
2289 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2323 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
2290 2324
2291 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { 2325 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
2292 2326
2293 VCLKIndex &= 0x1f; 2327 VCLKIndex &= 0x1f;
2294 tempbx = 0; 2328 tempbx = 0;
2295 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2329 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2296 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 2330 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2297 tempbx += 2; 2331 tempbx += 2;
2298 if(SiS_Pr->SiS_ModeType > ModeVGA) { 2332 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2299 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8; 2333 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
@@ -2306,66 +2340,68 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2306 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2340 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
2307 } 2341 }
2308 } 2342 }
2309 switch(tempbx) { 2343 switch(tempbx) {
2310 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break; 2344 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
2311 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break; 2345 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
2312 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break; 2346 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
2313 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2347 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2314 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break; 2348 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
2315 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break; 2349 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
2316 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break; 2350 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
2317 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break; 2351 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
2318 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break; 2352 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
2319 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2353 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
2320 } 2354 }
2321 VCLKIndex = CHTVVCLKPtr[VCLKIndex]; 2355 VCLKIndex = CHTVVCLKPtr[VCLKIndex];
2322 2356
2323 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2357 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2324 2358
2325 if(HwInfo->jChipType < SIS_315H) { 2359 if(SiS_Pr->ChipType < SIS_315H) {
2326 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2360 VCLKIndex = SiS_Pr->PanelVCLKIdx300;
2327 } else { 2361 } else {
2328 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2362 VCLKIndex = SiS_Pr->PanelVCLKIdx315;
2329 } 2363 }
2330 2364
2365#ifdef SIS300
2331 /* Special Timing: Barco iQ Pro R series */ 2366 /* Special Timing: Barco iQ Pro R series */
2332 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; 2367 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
2333 2368
2334 /* Special Timing: 848x480 parallel lvds */ 2369 /* Special Timing: 848x480 and 856x480 parallel lvds panels */
2335 if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 2370 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
2336 if(HwInfo->jChipType < SIS_315H) { 2371 if(SiS_Pr->ChipType < SIS_315H) {
2337 VCLKIndex = VCLK34_300; 2372 VCLKIndex = VCLK34_300;
2338 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2373 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2339 } else { 2374 } else {
2340 VCLKIndex = VCLK34_315; 2375 VCLKIndex = VCLK34_315;
2341 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2376 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
2342 } 2377 }
2343 } 2378 }
2379#endif
2344 2380
2345 } else { 2381 } else {
2346 2382
2347 VCLKIndex = VCLKIndexGEN; 2383 VCLKIndex = VCLKIndexGENCRT;
2348 if(HwInfo->jChipType < SIS_315H) { 2384 if(SiS_Pr->ChipType < SIS_315H) {
2349 if(ModeNo > 0x13) { 2385 if(ModeNo > 0x13) {
2350 if( (HwInfo->jChipType == SIS_630) && 2386 if( (SiS_Pr->ChipType == SIS_630) &&
2351 (HwInfo->jChipRevision >= 0x30) ) { 2387 (SiS_Pr->ChipRevision >= 0x30) ) {
2352 if(VCLKIndex == 0x14) VCLKIndex = 0x2e; 2388 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
2353 } 2389 }
2354 } 2390 }
2355 } 2391 }
2356 } 2392 }
2357 2393
2358 } else { /* if not programming CRT2 */ 2394 } else { /* if not programming CRT2 */
2359 2395
2360 VCLKIndex = VCLKIndexGEN; 2396 VCLKIndex = VCLKIndexGENCRT;
2361 if(HwInfo->jChipType < SIS_315H) { 2397 if(SiS_Pr->ChipType < SIS_315H) {
2362 if(ModeNo > 0x13) { 2398 if(ModeNo > 0x13) {
2363 if( (HwInfo->jChipType != SIS_630) && 2399 if( (SiS_Pr->ChipType != SIS_630) &&
2364 (HwInfo->jChipType != SIS_300) ) { 2400 (SiS_Pr->ChipType != SIS_300) ) {
2365 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2401 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
2366 } 2402 }
2367#if 0 2403#if 0
2368 if(HwInfo->jChipType == SIS_730) { 2404 if(SiS_Pr->ChipType == SIS_730) {
2369 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */ 2405 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
2370 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */ 2406 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
2371 } 2407 }
@@ -2377,11 +2413,13 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2377 2413
2378 } 2414 }
2379 2415
2416#ifdef SIS_XORG_XF86
2380#ifdef TWDEBUG 2417#ifdef TWDEBUG
2381 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex); 2418 xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
2382#endif 2419#endif
2420#endif
2383 2421
2384 return(VCLKIndex); 2422 return VCLKIndex;
2385} 2423}
2386 2424
2387/*********************************************/ 2425/*********************************************/
@@ -2389,26 +2427,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2389/*********************************************/ 2427/*********************************************/
2390 2428
2391static void 2429static void
2392SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 2430SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2393 PSIS_HW_INFO HwInfo)
2394{ 2431{
2395 USHORT i,j,modeflag; 2432 unsigned short i, j, modeflag, tempah=0;
2396 USHORT tempcl,tempah=0; 2433 short tempcl;
2397#if defined(SIS300) || defined(SIS315H) 2434#if defined(SIS300) || defined(SIS315H)
2398 USHORT tempbl; 2435 unsigned short tempbl;
2399#endif 2436#endif
2400#ifdef SIS315H 2437#ifdef SIS315H
2401 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 2438 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
2402 USHORT tempah2, tempbl2; 2439 unsigned short tempah2, tempbl2;
2403#endif 2440#endif
2404 2441
2405 if(ModeNo <= 0x13) { 2442 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
2406 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2407 } else if(SiS_Pr->UseCustomMode) {
2408 modeflag = SiS_Pr->CModeFlag;
2409 } else {
2410 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2411 }
2412 2443
2413 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2444 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
2414 2445
@@ -2418,18 +2449,18 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2418 } else { 2449 } else {
2419 2450
2420 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0); 2451 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
2421 if(HwInfo->jChipType >= SIS_315H) { 2452 if(SiS_Pr->ChipType >= SIS_315H) {
2422 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F); 2453 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
2423 } 2454 }
2424 2455
2425 tempcl = SiS_Pr->SiS_ModeType; 2456 tempcl = SiS_Pr->SiS_ModeType;
2426 2457
2427 if(HwInfo->jChipType < SIS_315H) { 2458 if(SiS_Pr->ChipType < SIS_315H) {
2428 2459
2429#ifdef SIS300 /* ---- 300 series ---- */ 2460#ifdef SIS300 /* ---- 300 series ---- */
2430 2461
2431 /* For 301BDH: (with LCD via LVDS) */ 2462 /* For 301BDH: (with LCD via LVDS) */
2432 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 2463 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
2433 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32); 2464 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
2434 tempbl &= 0xef; 2465 tempbl &= 0xef;
2435 tempbl |= 0x02; 2466 tempbl |= 0x02;
@@ -2438,16 +2469,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2438 tempbl &= 0xfd; 2469 tempbl &= 0xfd;
2439 } 2470 }
2440 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl); 2471 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
2441 } 2472 }
2442 2473
2443 if(ModeNo > 0x13) { 2474 if(ModeNo > 0x13) {
2444 tempcl -= ModeVGA; 2475 tempcl -= ModeVGA;
2445 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */ 2476 if(tempcl >= 0) {
2446 tempah = ((0x10 >> tempcl) | 0x80); 2477 tempah = ((0x10 >> tempcl) | 0x80);
2447 } 2478 }
2448 } else tempah = 0x80; 2479 } else tempah = 0x80;
2449 2480
2450 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; 2481 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
2451 2482
2452#endif /* SIS300 */ 2483#endif /* SIS300 */
2453 2484
@@ -2455,22 +2486,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2455 2486
2456#ifdef SIS315H /* ------- 315/330 series ------ */ 2487#ifdef SIS315H /* ------- 315/330 series ------ */
2457 2488
2458 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 2489 if(ModeNo > 0x13) {
2459 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 2490 tempcl -= ModeVGA;
2460 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08); 2491 if(tempcl >= 0) {
2461 } 2492 tempah = (0x08 >> tempcl);
2462 } 2493 if (tempah == 0) tempah = 1;
2463 2494 tempah |= 0x40;
2464 if(ModeNo > 0x13) { 2495 }
2465 tempcl -= ModeVGA; 2496 } else tempah = 0x40;
2466 if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
2467 tempah = (0x08 >> tempcl);
2468 if (tempah == 0) tempah = 1;
2469 tempah |= 0x40;
2470 }
2471 } else tempah = 0x40;
2472 2497
2473 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; 2498 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
2474 2499
2475#endif /* SIS315H */ 2500#endif /* SIS315H */
2476 2501
@@ -2478,84 +2503,89 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2478 2503
2479 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2504 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2480 2505
2481 if(HwInfo->jChipType < SIS_315H) { 2506 if(SiS_Pr->ChipType < SIS_315H) {
2482 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2507 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2483 } else { 2508 } else {
2484 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2509#ifdef SIS315H
2485 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2510 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2486 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 2511 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2487 if(IS_SIS740) { 2512 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2513 if(IS_SIS740) {
2488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2514 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
2489 } else { 2515 } else {
2490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2516 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
2491 } 2517 }
2492 } 2518 }
2519#endif
2493 } 2520 }
2494 2521
2495 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2522 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2496 2523
2497 tempah = 0x01; 2524 tempah = 0x01;
2498 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 2525 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
2499 tempah |= 0x02; 2526 tempah |= 0x02;
2500 } 2527 }
2501 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2528 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
2502 tempah ^= 0x05; 2529 tempah ^= 0x05;
2503 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 2530 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
2504 tempah ^= 0x01; 2531 tempah ^= 0x01;
2505 } 2532 }
2506 } 2533 }
2507 2534
2508 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2535 if(SiS_Pr->ChipType < SIS_315H) {
2509 2536
2510 if(HwInfo->jChipType < SIS_315H) { 2537 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2511 2538
2512 tempah = (tempah << 5) & 0xFF; 2539 tempah = (tempah << 5) & 0xFF;
2513 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2540 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2514 tempah = (tempah >> 5) & 0xFF; 2541 tempah = (tempah >> 5) & 0xFF;
2515 2542
2516 } else { 2543 } else {
2517 2544
2518 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah); 2545 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
2546 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
2547 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
2548 tempah &= ~0x08;
2519 2549
2520 } 2550 }
2521 2551
2522 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 2552 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
2523 tempah |= 0x10; 2553 tempah |= 0x10;
2524 } 2554 }
2525 2555
2526 tempah |= 0x80; 2556 tempah |= 0x80;
2527 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2557 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2528 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80; 2558 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
2529 } 2559 }
2530 2560
2531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2561 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2532 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) { 2562 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
2533 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2563 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
2534 tempah |= 0x20; 2564 tempah |= 0x20;
2535 } 2565 }
2536 } 2566 }
2537 } 2567 }
2538 2568
2539 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah); 2569 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
2540 2570
2541 tempah = 0x80; 2571 tempah = 0x80;
2542 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2572 if(SiS_Pr->SiS_VBType & VB_SIS301) {
2543 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0; 2573 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
2544 } 2574 }
2545 2575
2546 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40; 2576 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
2547 2577
2548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2578 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
2549 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) { 2579 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
2550 tempah |= 0x40; 2580 tempah |= 0x40;
2551 } 2581 }
2552 } 2582 }
2553 2583
2554 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah); 2584 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
2555 2585
2556 } else { /* LVDS */ 2586 } else { /* LVDS */
2557 2587
2558 if(HwInfo->jChipType >= SIS_315H) { 2588 if(SiS_Pr->ChipType >= SIS_315H) {
2559 2589
2560#ifdef SIS315H 2590#ifdef SIS315H
2561 /* LVDS can only be slave in 8bpp modes */ 2591 /* LVDS can only be slave in 8bpp modes */
@@ -2566,36 +2596,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2566 } 2596 }
2567 } 2597 }
2568 2598
2569 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 2599 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
2570 tempah |= 0x02;
2571 }
2572 2600
2573 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2601 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
2574 tempah ^= 0x01;
2575 }
2576 2602
2577 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 2603 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
2578 tempah = 1;
2579 }
2580 2604
2581 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah); 2605 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
2582#endif 2606#endif
2583 2607
2584 } else { 2608 } else {
2585 2609
2586#ifdef SIS300 2610#ifdef SIS300
2587 tempah = 0; 2611 tempah = 0;
2588 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { 2612 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
2589 tempah |= 0x02; 2613 tempah |= 0x02;
2590 } 2614 }
2591 tempah <<= 5; 2615 tempah <<= 5;
2592 2616
2593 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2617 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
2594 2618
2595 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
2596#endif 2620#endif
2597 2621
2598 } 2622 }
2599 2623
2600 } 2624 }
2601 2625
@@ -2603,10 +2627,10 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2603 2627
2604 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2628 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2605 2629
2606 if(HwInfo->jChipType >= SIS_315H) { 2630 if(SiS_Pr->ChipType >= SIS_315H) {
2607 2631
2608#ifdef SIS315H 2632#ifdef SIS315H
2609 unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); 2633 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
2610 2634
2611 /* The following is nearly unpreditable and varies from machine 2635 /* The following is nearly unpreditable and varies from machine
2612 * to machine. Especially the 301DH seems to be a real trouble 2636 * to machine. Especially the 301DH seems to be a real trouble
@@ -2619,25 +2643,28 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2619 2643
2620 /* 740 variants match for 30xB, 301B-DH, 30xLV */ 2644 /* 740 variants match for 30xB, 301B-DH, 30xLV */
2621 2645
2622 if(!(IS_SIS740)) { 2646 if(!(IS_SIS740)) {
2623 tempah = 0x04; /* For all bridges */ 2647 tempah = 0x04; /* For all bridges */
2624 tempbl = 0xfb; 2648 tempbl = 0xfb;
2625 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2649 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2626 tempah = 0x00; 2650 tempah = 0x00;
2627 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) { 2651 if(SiS_IsDualEdge(SiS_Pr)) {
2628 tempbl = 0xff; 2652 tempbl = 0xff;
2629 } 2653 }
2630 } 2654 }
2631 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2655 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2632 } 2656 }
2633 2657
2634 /* The following two are responsible for eventually wrong colors 2658 /* The following two are responsible for eventually wrong colors
2635 * in TV output. The DH (VB_NoLCD) conditions are unknown; the 2659 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
2636 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version 2660 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
2637 * in a 650 box (Jake). What is the criteria? 2661 * in a 650 box (Jake). What is the criteria?
2662 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
2663 * treatment like the 651+301B-DH(b0) case. Seems more to be the
2664 * chipset than the bridge revision.
2638 */ 2665 */
2639 2666
2640 if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 2667 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
2641 tempah = 0x30; 2668 tempah = 0x30;
2642 tempbl = 0xc0; 2669 tempbl = 0xc0;
2643 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2670 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
@@ -2649,20 +2676,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2649 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl); 2676 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
2650 } else if(SiS_Pr->SiS_VBType & VB_SIS301) { 2677 } else if(SiS_Pr->SiS_VBType & VB_SIS301) {
2651 /* Fixes "TV-blue-bug" on 315+301 */ 2678 /* Fixes "TV-blue-bug" on 315+301 */
2652 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */ 2679 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
2653 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2680 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2654 } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 2681 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
2655 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */ 2682 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
2656 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2657 } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
2658 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
2659 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0); 2683 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
2684 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
2685 tempah = 0x30; tempah2 = 0xc0;
2686 tempbl = 0xcf; tempbl2 = 0x3f;
2687 if(SiS_Pr->SiS_TVBlue == 0) {
2688 tempah = tempah2 = 0x00;
2689 } else if(SiS_Pr->SiS_TVBlue == -1) {
2690 /* Set on 651/M650, clear on 315/650 */
2691 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
2692 tempah = tempah2 = 0x00;
2693 }
2694 }
2695 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
2696 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
2660 } else { 2697 } else {
2661 tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */ 2698 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
2662 tempbl = 0xcf; tempbl2 = 0x3f; 2699 tempbl = 0xcf; tempbl2 = 0x3f;
2663 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2700 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2664 tempah = tempah2 = 0x00; 2701 tempah = tempah2 = 0x00;
2665 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) { 2702 if(SiS_IsDualEdge(SiS_Pr)) {
2666 tempbl = tempbl2 = 0xff; 2703 tempbl = tempbl2 = 0xff;
2667 } 2704 }
2668 } 2705 }
@@ -2676,23 +2713,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2676 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah); 2713 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
2677 } else { 2714 } else {
2678 tempah = 0x00; 2715 tempah = 0x00;
2679 tempbl = 0x7f; 2716 tempbl = 0x7f;
2680 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2717 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2681 tempbl = 0xff; 2718 tempbl = 0xff;
2682 if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80; 2719 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
2683 } 2720 }
2684 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); 2721 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
2685 } 2722 }
2686 2723
2687#endif /* SIS315H */ 2724#endif /* SIS315H */
2688 2725
2689 } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 2726 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2690 2727
2691#ifdef SIS300 2728#ifdef SIS300
2692 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2729 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
2693 2730
2694 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2731 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
2695 ((SiS_Pr->SiS_VBType & VB_NoLCD) && 2732 ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
2696 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) { 2733 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
2697 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F); 2734 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
2698 } else { 2735 } else {
@@ -2702,9 +2739,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2702 2739
2703 } 2740 }
2704 2741
2705 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 2742 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
2706 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80); 2743 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
2707 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 2744 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
2708 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0); 2745 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
2709 } 2746 }
2710 } 2747 }
@@ -2712,16 +2749,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2712 } else { /* LVDS */ 2749 } else { /* LVDS */
2713 2750
2714#ifdef SIS315H 2751#ifdef SIS315H
2715 if(HwInfo->jChipType >= SIS_315H) { 2752 if(SiS_Pr->ChipType >= SIS_315H) {
2716 2753
2717 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 2754 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
2718 2755
2719 tempah = 0x04; 2756 tempah = 0x04;
2720 tempbl = 0xfb; 2757 tempbl = 0xfb;
2721 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2758 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2722 tempah = 0x00; 2759 tempah = 0x00;
2723 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff; 2760 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
2724 } 2761 }
2725 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2762 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
2726 2763
2727 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 2764 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
@@ -2730,7 +2767,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2730 2767
2731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 2768 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
2732 2769
2733 } else if(HwInfo->jChipType == SIS_550) { 2770 } else if(SiS_Pr->ChipType == SIS_550) {
2734 2771
2735 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 2772 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
2736 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 2773 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
@@ -2748,212 +2785,120 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2748/* GET RESOLUTION DATA */ 2785/* GET RESOLUTION DATA */
2749/*********************************************/ 2786/*********************************************/
2750 2787
2751USHORT 2788unsigned short
2752SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex) 2789SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2753{ 2790{
2754 if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo); 2791 if(ModeNo <= 0x13)
2755 else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO); 2792 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
2793 else
2794 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
2756} 2795}
2757 2796
2758static void 2797static void
2759SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 2798SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
2760 PSIS_HW_INFO HwInfo)
2761{ 2799{
2762 USHORT xres,yres,modeflag=0,resindex; 2800 unsigned short xres, yres, modeflag=0, resindex;
2763 2801
2764 if(SiS_Pr->UseCustomMode) { 2802 if(SiS_Pr->UseCustomMode) {
2765 xres = SiS_Pr->CHDisplay; 2803 xres = SiS_Pr->CHDisplay;
2766 if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2; 2804 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
2767 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 2805 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2768 yres = SiS_Pr->CVDisplay; 2806 /* DoubleScanMode-check done in CheckCalcCustomMode()! */
2769 if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2; 2807 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
2770 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; 2808 return;
2771 return; 2809 }
2772 }
2773
2774 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2775 2810
2776 if(ModeNo <= 0x13) { 2811 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
2777 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2778 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2779 } else {
2780 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2781 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2782 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2783 }
2784 2812
2785 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) { 2813 if(ModeNo <= 0x13) {
2814 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
2815 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
2816 } else {
2817 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
2818 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
2819 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2820 }
2786 2821
2787 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) { 2822 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
2788 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2789 if(yres == 350) yres = 400;
2790 }
2791 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2792 if(ModeNo == 0x12) yres = 400;
2793 }
2794 }
2795 2823
2796 if(modeflag & HalfDCLK) xres *= 2; 2824 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
2797 if(modeflag & DoubleScanMode) yres *= 2; 2825 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
2826 if(yres == 350) yres = 400;
2827 }
2828 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
2829 if(ModeNo == 0x12) yres = 400;
2830 }
2831 }
2798 2832
2799 } 2833 if(modeflag & HalfDCLK) xres <<= 1;
2834 if(modeflag & DoubleScanMode) yres <<= 1;
2800 2835
2801 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 2836 }
2802 2837
2803#if 0 2838 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
2804 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
2805 if(xres == 720) xres = 640;
2806 }
2807#endif
2808 2839
2809 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2840 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
2810 switch(SiS_Pr->SiS_LCDResInfo) { 2841 switch(SiS_Pr->SiS_LCDResInfo) {
2811 case Panel_1024x768: 2842 case Panel_1024x768:
2812 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 2843 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2813 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2844 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2814 if(yres == 350) yres = 357; 2845 if(yres == 350) yres = 357;
2815 if(yres == 400) yres = 420; 2846 if(yres == 400) yres = 420;
2816 if(yres == 480) yres = 525; 2847 if(yres == 480) yres = 525;
2817 } 2848 }
2818 } 2849 }
2819 break; 2850 break;
2820 case Panel_1280x1024: 2851 case Panel_1280x1024:
2821 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2852 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2822 /* BIOS bug - does this regardless of scaling */ 2853 /* BIOS bug - does this regardless of scaling */
2823 if(yres == 400) yres = 405; 2854 if(yres == 400) yres = 405;
2855 }
2856 if(yres == 350) yres = 360;
2857 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2858 if(yres == 360) yres = 375;
2824 } 2859 }
2825 if(yres == 350) yres = 360;
2826 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
2827 if(yres == 360) yres = 375;
2828 }
2829 break; 2860 break;
2830 case Panel_1600x1200: 2861 case Panel_1600x1200:
2831 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 2862 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
2832 if(yres == 1024) yres = 1056; 2863 if(yres == 1024) yres = 1056;
2833 } 2864 }
2834 break; 2865 break;
2835 } 2866 }
2836 } 2867 }
2837 2868
2838 } else { 2869 } else {
2839 2870
2840 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2871 if(SiS_Pr->SiS_VBType & VB_SISVB) {
2841 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) { 2872 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
2842 if(xres == 720) xres = 640; 2873 if(xres == 720) xres = 640;
2843 } 2874 }
2844 } else if(xres == 720) xres = 640; 2875 } else if(xres == 720) xres = 640;
2845 2876
2846 if(SiS_Pr->SiS_SetFlag & SetDOSMode) { 2877 if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
2847 yres = 400; 2878 yres = 400;
2848 if(HwInfo->jChipType >= SIS_315H) { 2879 if(SiS_Pr->ChipType >= SIS_315H) {
2849 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; 2880 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
2850 } else { 2881 } else {
2851 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; 2882 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
2852 } 2883 }
2853 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480; 2884 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
2854 } 2885 }
2855 2886
2856 } 2887 }
2857 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 2888 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
2858 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; 2889 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
2859} 2890}
2860 2891
2861/*********************************************/ 2892/*********************************************/
2862/* GET CRT2 TIMING DATA */ 2893/* GET CRT2 TIMING DATA */
2863/*********************************************/ 2894/*********************************************/
2864 2895
2865static BOOLEAN
2866SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
2867 USHORT RefreshRateTableIndex, USHORT *ResIndex,
2868 USHORT *DisplayType)
2869 {
2870 USHORT modeflag=0;
2871
2872 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
2873 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
2874 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2875 }
2876 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
2877 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
2878 } else
2879 return FALSE;
2880
2881 if(ModeNo <= 0x13) {
2882 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
2883 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
2884 } else {
2885 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2886 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
2887 }
2888
2889 (*ResIndex) &= 0x3F;
2890
2891 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
2892 (*DisplayType) = 18;
2893 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2894 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
2895 (*DisplayType) += 2;
2896 if(SiS_Pr->SiS_ModeType > ModeVGA) {
2897 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
2898 }
2899 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
2900 (*DisplayType) = 18; /* PALM uses NTSC data */
2901 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2902 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
2903 (*DisplayType) = 20; /* PALN uses PAL data */
2904 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
2905 }
2906 }
2907 } else {
2908 switch(SiS_Pr->SiS_LCDResInfo) {
2909 case Panel_640x480: (*DisplayType) = 50; break;
2910 case Panel_640x480_2: (*DisplayType) = 52; break;
2911 case Panel_640x480_3: (*DisplayType) = 54; break;
2912 case Panel_800x600: (*DisplayType) = 0; break;
2913 case Panel_1024x600: (*DisplayType) = 23; break;
2914 case Panel_1024x768: (*DisplayType) = 4; break;
2915 case Panel_1152x768: (*DisplayType) = 27; break;
2916 case Panel_1280x768: (*DisplayType) = 40; break;
2917 case Panel_1280x1024: (*DisplayType) = 8; break;
2918 case Panel_1400x1050: (*DisplayType) = 14; break;
2919 case Panel_1600x1200: (*DisplayType) = 36; break;
2920 default: return FALSE;
2921 }
2922
2923 if(modeflag & HalfDCLK) (*DisplayType)++;
2924
2925 switch(SiS_Pr->SiS_LCDResInfo) {
2926 case Panel_640x480:
2927 case Panel_640x480_2:
2928 case Panel_640x480_3:
2929 break;
2930 default:
2931 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
2932 }
2933
2934 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
2935 (*DisplayType) = 12;
2936 if(modeflag & HalfDCLK) (*DisplayType)++;
2937 }
2938 }
2939
2940#if 0
2941 if(SiS_Pr->SiS_IF_DEF_FSTN) {
2942 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
2943 (*DisplayType) = 22;
2944 }
2945 }
2946#endif
2947
2948 return TRUE;
2949}
2950
2951static void 2896static void
2952SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 2897SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
2953 USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex, 2898 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
2954 PSIS_HW_INFO HwInfo) 2899 unsigned short *ResIndex)
2955{ 2900{
2956 USHORT tempbx=0,tempal=0,resinfo=0; 2901 unsigned short tempbx=0, tempal=0, resinfo=0;
2957 2902
2958 if(ModeNo <= 0x13) { 2903 if(ModeNo <= 0x13) {
2959 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2904 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -2966,18 +2911,20 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2966 2911
2967 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ 2912 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
2968 2913
2969 tempbx = SiS_Pr->SiS_LCDResInfo; 2914 tempbx = SiS_Pr->SiS_LCDResInfo;
2970 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32; 2915 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
2971 2916
2917 /* patch index */
2972 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) { 2918 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
2973 if (resinfo == SIS_RI_1280x800) tempal = 9; 2919 if (resinfo == SIS_RI_1280x800) tempal = 9;
2974 else if(resinfo == SIS_RI_1400x1050) tempal = 11; 2920 else if(resinfo == SIS_RI_1400x1050) tempal = 11;
2975 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) || 2921 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
2976 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) { 2922 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
2923 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
2977 if (resinfo == SIS_RI_1280x768) tempal = 9; 2924 if (resinfo == SIS_RI_1280x768) tempal = 9;
2978 } 2925 }
2979 2926
2980 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2927 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
2981 /* Pass 1:1 only (center-screen handled outside) */ 2928 /* Pass 1:1 only (center-screen handled outside) */
2982 /* This is never called for the panel's native resolution */ 2929 /* This is never called for the panel's native resolution */
2983 /* since Pass1:1 will not be set in this case */ 2930 /* since Pass1:1 will not be set in this case */
@@ -2991,8 +2938,8 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
2991 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 2938 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
2992 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 2939 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
2993 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2940 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
2994 tempbx = 200; 2941 tempbx = 200;
2995 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 2942 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
2996 } 2943 }
2997 } 2944 }
2998 } 2945 }
@@ -3000,23 +2947,23 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3000 2947
3001 } else { /* TV */ 2948 } else { /* TV */
3002 2949
3003 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2950 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3004 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */ 2951 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
3005 tempbx = 2; 2952 tempbx = 2;
3006 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2953 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3007 tempbx = 13; 2954 tempbx = 13;
3008 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14; 2955 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
3009 } 2956 }
3010 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 2957 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3011 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7; 2958 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
3012 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6; 2959 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
3013 else tempbx = 5; 2960 else tempbx = 5;
3014 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 2961 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3015 } else { 2962 } else {
3016 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3; 2963 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
3017 else tempbx = 4; 2964 else tempbx = 4;
3018 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 2965 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
3019 } 2966 }
3020 2967
3021 } 2968 }
3022 2969
@@ -3024,26 +2971,34 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3024 2971
3025 if(ModeNo > 0x13) { 2972 if(ModeNo > 0x13) {
3026 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) { 2973 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
3027 if(tempal == 6) tempal = 7; 2974 switch(resinfo) {
3028 if((resinfo == SIS_RI_720x480) || 2975 case SIS_RI_720x480:
3029 (resinfo == SIS_RI_720x576) ||
3030 (resinfo == SIS_RI_768x576)) {
3031 tempal = 6; 2976 tempal = 6;
3032 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) { 2977 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
3033 if(resinfo == SIS_RI_720x480) tempal = 9; 2978 break;
2979 case SIS_RI_720x576:
2980 case SIS_RI_768x576:
2981 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
2982 tempal = 6;
2983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2984 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
3034 } 2985 }
3035 } 2986 break;
3036 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 2987 case SIS_RI_800x480:
3037 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 2988 tempal = 4;
3038 if(resinfo == SIS_RI_1024x768) tempal = 8; 2989 break;
2990 case SIS_RI_512x384:
2991 case SIS_RI_1024x768:
2992 tempal = 7;
2993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
2994 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
3039 } 2995 }
3040 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 2996 break;
3041 if((resinfo == SIS_RI_720x576) || 2997 case SIS_RI_1280x720:
3042 (resinfo == SIS_RI_768x576)) { 2998 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3043 tempal = 8; 2999 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
3044 }
3045 if(resinfo == SIS_RI_1280x720) tempal = 9;
3046 } 3000 }
3001 break;
3047 } 3002 }
3048 } 3003 }
3049 } 3004 }
@@ -3056,65 +3011,60 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3056 tempbx = 0; 3011 tempbx = 0;
3057 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3012 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3058 3013
3059 tempbx = 10; 3014 tempbx = 90;
3060 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 3015 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
3061 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 3016 tempbx = 92;
3062 tempbx += 2;
3063 if(SiS_Pr->SiS_ModeType > ModeVGA) { 3017 if(SiS_Pr->SiS_ModeType > ModeVGA) {
3064 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; 3018 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
3065 } 3019 }
3066 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 3020 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
3067 tempbx = 90; 3021 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
3068 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 3022 }
3069 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 3023 if(tempbx != 99) {
3070 tempbx = 92; 3024 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
3071 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 3025 }
3072 }
3073 }
3074 3026
3075 } else { 3027 } else {
3076 3028
3077 switch(SiS_Pr->SiS_LCDResInfo) { 3029 switch(SiS_Pr->SiS_LCDResInfo) {
3078 case Panel_640x480: tempbx = 6; break; 3030 case Panel_640x480: tempbx = 12; break;
3079 case Panel_640x480_2: 3031 case Panel_320x240_1: tempbx = 10; break;
3080 case Panel_640x480_3: tempbx = 30; break; 3032 case Panel_320x240_2:
3081 case Panel_800x600: tempbx = 0; break; 3033 case Panel_320x240_3: tempbx = 14; break;
3082 case Panel_1024x600: tempbx = 15; break; 3034 case Panel_800x600: tempbx = 16; break;
3083 case Panel_1024x768: tempbx = 2; break; 3035 case Panel_1024x600: tempbx = 18; break;
3084 case Panel_1152x768: tempbx = 17; break; 3036 case Panel_1152x768:
3085 case Panel_1280x768: tempbx = 18; break; 3037 case Panel_1024x768: tempbx = 20; break;
3086 case Panel_1280x1024: tempbx = 4; break; 3038 case Panel_1280x768: tempbx = 22; break;
3087 case Panel_1400x1050: tempbx = 8; break; 3039 case Panel_1280x1024: tempbx = 24; break;
3088 case Panel_1600x1200: tempbx = 21; break; 3040 case Panel_1400x1050: tempbx = 26; break;
3041 case Panel_1600x1200: tempbx = 28; break;
3042#ifdef SIS300
3089 case Panel_Barco1366: tempbx = 80; break; 3043 case Panel_Barco1366: tempbx = 80; break;
3044#endif
3090 } 3045 }
3091 3046
3092 switch(SiS_Pr->SiS_LCDResInfo) { 3047 switch(SiS_Pr->SiS_LCDResInfo) {
3048 case Panel_320x240_1:
3049 case Panel_320x240_2:
3050 case Panel_320x240_3:
3093 case Panel_640x480: 3051 case Panel_640x480:
3094 case Panel_640x480_2:
3095 case Panel_640x480_3:
3096 break; 3052 break;
3097 default: 3053 default:
3098 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3054 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3099 } 3055 }
3100 3056
3101 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7; 3057 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
3102 3058
3059#ifdef SIS300
3103 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3060 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3104 tempbx = 82; 3061 tempbx = 82;
3105 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3062 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3106 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 3063 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
3107 tempbx = 84; 3064 tempbx = 84;
3108 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3065 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
3109 } 3066 }
3110 3067#endif
3111 if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
3112 (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
3113 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
3114 (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3115 tempal = 0;
3116 }
3117 }
3118 3068
3119 } 3069 }
3120 3070
@@ -3124,12 +3074,11 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3124} 3074}
3125 3075
3126static void 3076static void
3127SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 3077SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3128 USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo) 3078 unsigned short RefreshRateTableIndex)
3129{ 3079{
3130 USHORT tempax=0,tempbx=0; 3080 unsigned short tempax=0, tempbx=0, index, dotclock;
3131 USHORT temp1=0,modeflag=0,tempcx=0; 3081 unsigned short temp1=0, modeflag=0, tempcx=0;
3132 USHORT index;
3133 3082
3134 SiS_Pr->SiS_RVBHCMAX = 1; 3083 SiS_Pr->SiS_RVBHCMAX = 1;
3135 SiS_Pr->SiS_RVBHCFACT = 1; 3084 SiS_Pr->SiS_RVBHCFACT = 1;
@@ -3143,10 +3092,12 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3143 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6]; 3092 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
3144 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7]; 3093 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
3145 3094
3095 dotclock = (modeflag & Charx8Dot) ? 8 : 9;
3096
3146 } else { 3097 } else {
3147 3098
3148 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3099 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3149 index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 3100 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
3150 3101
3151 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0]; 3102 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
3152 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8); 3103 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
@@ -3158,22 +3109,16 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3158 tempbx |= tempcx; 3109 tempbx |= tempcx;
3159 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7]; 3110 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
3160 3111
3112 dotclock = 8;
3113
3161 } 3114 }
3162 3115
3163 if(temp1 & 0x01) tempbx |= 0x0100; 3116 if(temp1 & 0x01) tempbx |= 0x0100;
3164 if(temp1 & 0x20) tempbx |= 0x0200; 3117 if(temp1 & 0x20) tempbx |= 0x0200;
3165 3118
3166 tempax += 5; 3119 tempax += 5;
3167 3120 tempax *= dotclock;
3168 /* Charx8Dot is no more used (and assumed), so we set it */ 3121 if(modeflag & HalfDCLK) tempax <<= 1;
3169 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
3170 modeflag |= Charx8Dot;
3171 }
3172
3173 if(modeflag & Charx8Dot) tempax *= 8;
3174 else tempax *= 9;
3175
3176 if(modeflag & HalfDCLK) tempax <<= 1;
3177 3122
3178 tempbx++; 3123 tempbx++;
3179 3124
@@ -3182,13 +3127,56 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3182} 3127}
3183 3128
3184static void 3129static void
3185SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 3130SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
3186 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 3131 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
3132{
3133 unsigned short ResIndex;
3134
3135 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3136 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3137 if(SiS_Pr->UseCustomMode) {
3138 ResIndex = SiS_Pr->CHTotal;
3139 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
3140 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
3141 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3142 } else {
3143 if(ModeNo < 0x13) {
3144 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3145 } else {
3146 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3147 }
3148 if(ResIndex == 0x09) {
3149 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
3150 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
3151 }
3152 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3153 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3154 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3155 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3156 }
3157 } else {
3158 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3159 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3160 }
3161 } else {
3162 /* This handles custom modes and custom panels */
3163 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3164 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3165 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3166 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3167 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3168 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3169 }
3170}
3171
3172static void
3173SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3174 unsigned short RefreshRateTableIndex)
3187{ 3175{
3188 USHORT CRT2Index, ResIndex; 3176 unsigned short CRT2Index, ResIndex, backup;
3189 const SiS_LVDSDataStruct *LVDSData = NULL; 3177 const struct SiS_LVDSData *LVDSData = NULL;
3190 3178
3191 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 3179 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
3192 3180
3193 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3181 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3194 SiS_Pr->SiS_RVBHCMAX = 1; 3182 SiS_Pr->SiS_RVBHCMAX = 1;
@@ -3199,133 +3187,94 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3199 SiS_Pr->SiS_RY2COE = 0; 3187 SiS_Pr->SiS_RY2COE = 0;
3200 SiS_Pr->SiS_RY3COE = 0; 3188 SiS_Pr->SiS_RY3COE = 0;
3201 SiS_Pr->SiS_RY4COE = 0; 3189 SiS_Pr->SiS_RY4COE = 0;
3190 SiS_Pr->SiS_RVBHRS2 = 0;
3202 } 3191 }
3203 3192
3204 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3193 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3205 3194
3206#ifdef SIS315H 3195#ifdef SIS315H
3207 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3196 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3208 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 3197 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
3209 if(SiS_Pr->UseCustomMode) {
3210 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3211 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3212 } else {
3213 if(ModeNo < 0x13) {
3214 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3215 } else {
3216 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
3217 }
3218 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
3219 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
3220 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
3221 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
3222 }
3223 } else {
3224 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3225 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3226 }
3227 } else {
3228 /* This handles custom modes and custom panels */
3229 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3230 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3231 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3232 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3233 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
3234 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
3235 }
3236
3237 SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
3238
3239#endif 3198#endif
3240 3199
3241 } else { 3200 } else {
3242 3201
3243 /* 301BDH needs LVDS Data */ 3202 /* 301BDH needs LVDS Data */
3203 backup = SiS_Pr->SiS_IF_DEF_LVDS;
3244 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3204 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3245 SiS_Pr->SiS_IF_DEF_LVDS = 1; 3205 SiS_Pr->SiS_IF_DEF_LVDS = 1;
3246 } 3206 }
3247 3207
3248 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 3208 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
3249 &CRT2Index, &ResIndex, HwInfo); 3209 &CRT2Index, &ResIndex);
3250 3210
3251 /* 301BDH needs LVDS Data */ 3211 SiS_Pr->SiS_IF_DEF_LVDS = backup;
3252 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3253 SiS_Pr->SiS_IF_DEF_LVDS = 0;
3254 }
3255 3212
3256 switch (CRT2Index) { 3213 switch(CRT2Index) {
3257 case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; 3214 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
3258 case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break; 3215 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
3259 case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; 3216 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
3260 case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break; 3217 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
3261 case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break; 3218 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3262 case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break; 3219 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
3263 case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break; 3220#ifdef SIS300
3264 case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
3265 case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
3266 case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
3267 case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3268 case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3269 case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3270 case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3271 case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
3272 case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
3273 case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
3274 case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
3275 case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
3276 case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
3277 case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
3278 case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
3279 case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
3280 case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
3281 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; 3221 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
3282 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; 3222 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
3283 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; 3223 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
3284 case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
3285 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break; 3224 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
3286 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break; 3225 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
3287 case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break; 3226#endif
3288 case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break; 3227 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
3289 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break; 3228 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
3290 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break; 3229 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
3291 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */ 3230 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
3292 default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; 3231 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
3232 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
3233 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
3234 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
3235 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
3293 } 3236 }
3294 3237
3295 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT; 3238 if(LVDSData) {
3296 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT; 3239 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
3297 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT; 3240 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
3298 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT; 3241 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
3299 3242 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
3300 if(!(SiS_Pr->SiS_VBType & VB_SISVB)) { 3243 } else {
3301 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 3244 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3302 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) { 3245 }
3303 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3246
3304 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3247 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
3305 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3248 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3306 if(ResIndex < 0x08) { 3249 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3307 SiS_Pr->SiS_HDE = 1280; 3250 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
3308 SiS_Pr->SiS_VDE = 1024; 3251 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
3309 } 3252 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
3310 } 3253 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
3311 } 3254#ifdef SIS300
3255 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3256 if(ResIndex < 0x08) {
3257 SiS_Pr->SiS_HDE = 1280;
3258 SiS_Pr->SiS_VDE = 1024;
3259 }
3260 }
3261#endif
3312 } 3262 }
3313 } 3263 }
3314 } 3264 }
3315} 3265}
3316 3266
3317static void 3267static void
3318SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 3268SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3319 USHORT RefreshRateTableIndex, 3269 unsigned short RefreshRateTableIndex)
3320 PSIS_HW_INFO HwInfo) 3270{
3321{ 3271 unsigned char *ROMAddr = NULL;
3322 UCHAR *ROMAddr = NULL; 3272 unsigned short tempax, tempbx, modeflag, romptr=0;
3323 USHORT tempax,tempbx,modeflag,romptr=0; 3273 unsigned short resinfo, CRT2Index, ResIndex;
3324 USHORT resinfo,CRT2Index,ResIndex; 3274 const struct SiS_LCDData *LCDPtr = NULL;
3325 const SiS_LCDDataStruct *LCDPtr = NULL; 3275 const struct SiS_TVData *TVPtr = NULL;
3326 const SiS_TVDataStruct *TVPtr = NULL;
3327#ifdef SIS315H 3276#ifdef SIS315H
3328 SHORT resinfo661; 3277 short resinfo661;
3329#endif 3278#endif
3330 3279
3331 if(ModeNo <= 0x13) { 3280 if(ModeNo <= 0x13) {
@@ -3340,67 +3289,69 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3340#ifdef SIS315H 3289#ifdef SIS315H
3341 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; 3290 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
3342 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3291 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
3343 (SiS_Pr->SiS_SetFlag & LCDVESATiming) && 3292 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
3344 (resinfo661 >= 0) && 3293 (resinfo661 >= 0) &&
3345 (SiS_Pr->SiS_NeedRomModeData) ) { 3294 (SiS_Pr->SiS_NeedRomModeData) ) {
3346 if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) { 3295 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
3347 if((romptr = (SISGETROMW(21)))) { 3296 if((romptr = (SISGETROMW(21)))) {
3348 romptr += (resinfo661 * 10); 3297 romptr += (resinfo661 * 10);
3349 ROMAddr = HwInfo->pjVirtualRomBase; 3298 ROMAddr = SiS_Pr->VirtualRomBase;
3350 } 3299 }
3351 } 3300 }
3352 } 3301 }
3353#endif 3302#endif
3354 } 3303 }
3355 3304
3356 SiS_Pr->SiS_NewFlickerMode = 0; 3305 SiS_Pr->SiS_NewFlickerMode = 0;
3357 SiS_Pr->SiS_RVBHRS = 50; 3306 SiS_Pr->SiS_RVBHRS = 50;
3358 SiS_Pr->SiS_RY1COE = 0; 3307 SiS_Pr->SiS_RY1COE = 0;
3359 SiS_Pr->SiS_RY2COE = 0; 3308 SiS_Pr->SiS_RY2COE = 0;
3360 SiS_Pr->SiS_RY3COE = 0; 3309 SiS_Pr->SiS_RY3COE = 0;
3361 SiS_Pr->SiS_RY4COE = 0; 3310 SiS_Pr->SiS_RY4COE = 0;
3311 SiS_Pr->SiS_RVBHRS2 = 0;
3362 3312
3363 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo); 3313 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
3364 3314
3365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){ 3315 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
3366 3316
3367 if(SiS_Pr->UseCustomMode) { 3317 if(SiS_Pr->UseCustomMode) {
3368 3318
3369 SiS_Pr->SiS_RVBHCMAX = 1; 3319 SiS_Pr->SiS_RVBHCMAX = 1;
3370 SiS_Pr->SiS_RVBHCFACT = 1; 3320 SiS_Pr->SiS_RVBHCFACT = 1;
3371 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3372 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3373 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3374 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3375 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3321 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3376 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3322 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3323
3324 tempax = SiS_Pr->CHTotal;
3325 if(modeflag & HalfDCLK) tempax <<= 1;
3326 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3327 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3377 3328
3378 } else { 3329 } else {
3379 3330
3380 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3331 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3381 3332
3382 } 3333 }
3383 3334
3384 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 3335 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
3385 3336
3386 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3337 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3387 &CRT2Index,&ResIndex,HwInfo); 3338 &CRT2Index,&ResIndex);
3388 3339
3389 switch(CRT2Index) { 3340 switch(CRT2Index) {
3390 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break; 3341 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
3391 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break; 3342 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
3392 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break; 3343 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
3393 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break; 3344 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
3394 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break; 3345 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
3395 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break; 3346 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
3396 case 8: TVPtr = SiS_Pr->SiS_StPALData; break; 3347 case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
3397 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break; 3348 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
3398 case 10: TVPtr = SiS_Pr->SiS_St525iData; break; 3349 case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
3399 case 11: TVPtr = SiS_Pr->SiS_St525pData; break; 3350 case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
3400 case 12: TVPtr = SiS_Pr->SiS_St750pData; break; 3351 case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
3401 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break; 3352 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
3402 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break; 3353 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
3403 default: TVPtr = SiS_Pr->SiS_StPALData; break; 3354 default: TVPtr = SiS_Pr->SiS_StPALData; break;
3404 } 3355 }
3405 3356
3406 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX; 3357 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3409,73 +3360,77 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3409 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT; 3360 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
3410 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE; 3361 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
3411 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE; 3362 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
3412 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS; 3363 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
3413 SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
3414 if(modeflag & HalfDCLK) { 3364 if(modeflag & HalfDCLK) {
3415 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS; 3365 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
3366 if(SiS_Pr->SiS_RVBHRS2) {
3367 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3368 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
3369 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
3370 else SiS_Pr->SiS_RVBHRS2 += tempax;
3371 }
3372 } else {
3373 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
3416 } 3374 }
3375 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
3417 3376
3418 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3377 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
3419 3378
3420 if((resinfo == SIS_RI_1024x768) || 3379 if((resinfo == SIS_RI_960x600) ||
3421 (resinfo == SIS_RI_1280x1024) || 3380 (resinfo == SIS_RI_1024x768) ||
3422 (resinfo == SIS_RI_1280x720)) { 3381 (resinfo == SIS_RI_1280x1024) ||
3382 (resinfo == SIS_RI_1280x720)) {
3423 SiS_Pr->SiS_NewFlickerMode = 0x40; 3383 SiS_Pr->SiS_NewFlickerMode = 0x40;
3424 } 3384 }
3425 3385
3426 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 3386 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
3427 3387
3428 SiS_Pr->SiS_HT = ExtHiTVHT; 3388 SiS_Pr->SiS_HT = ExtHiTVHT;
3429 SiS_Pr->SiS_VT = ExtHiTVVT; 3389 SiS_Pr->SiS_VT = ExtHiTVVT;
3430 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3390 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
3431 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 3391 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
3432 SiS_Pr->SiS_HT = StHiTVHT; 3392 SiS_Pr->SiS_HT = StHiTVHT;
3433 SiS_Pr->SiS_VT = StHiTVVT; 3393 SiS_Pr->SiS_VT = StHiTVVT;
3434#if 0 3394 }
3435 if(!(modeflag & Charx8Dot)) { 3395 }
3436 SiS_Pr->SiS_HT = StHiTextTVHT;
3437 SiS_Pr->SiS_VT = StHiTextTVVT;
3438 }
3439#endif
3440 }
3441 }
3442 3396
3443 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3397 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
3444 3398
3445 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 3399 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
3446 SiS_Pr->SiS_HT = 1650; 3400 SiS_Pr->SiS_HT = 1650;
3447 SiS_Pr->SiS_VT = 750; 3401 SiS_Pr->SiS_VT = 750;
3448 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 3402 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
3449 SiS_Pr->SiS_HT = NTSCHT; 3403 SiS_Pr->SiS_HT = NTSCHT;
3404 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
3450 SiS_Pr->SiS_VT = NTSCVT; 3405 SiS_Pr->SiS_VT = NTSCVT;
3451 } else { 3406 } else {
3452 SiS_Pr->SiS_HT = NTSCHT; 3407 SiS_Pr->SiS_HT = NTSCHT;
3453 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3408 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3454 SiS_Pr->SiS_VT = NTSCVT; 3409 SiS_Pr->SiS_VT = NTSCVT;
3455 } 3410 }
3456 3411
3457 } else { 3412 } else {
3458 3413
3459 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE; 3414 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
3460 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE; 3415 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
3461 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE; 3416 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
3462 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE; 3417 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
3463 3418
3464 if(modeflag & HalfDCLK) { 3419 if(modeflag & HalfDCLK) {
3465 SiS_Pr->SiS_RY1COE = 0x00; 3420 SiS_Pr->SiS_RY1COE = 0x00;
3466 SiS_Pr->SiS_RY2COE = 0xf4; 3421 SiS_Pr->SiS_RY2COE = 0xf4;
3467 SiS_Pr->SiS_RY3COE = 0x10; 3422 SiS_Pr->SiS_RY3COE = 0x10;
3468 SiS_Pr->SiS_RY4COE = 0x38; 3423 SiS_Pr->SiS_RY4COE = 0x38;
3469 } 3424 }
3470 3425
3471 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 3426 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
3472 SiS_Pr->SiS_HT = NTSCHT; 3427 SiS_Pr->SiS_HT = NTSCHT;
3473 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3428 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
3474 SiS_Pr->SiS_VT = NTSCVT; 3429 SiS_Pr->SiS_VT = NTSCVT;
3475 } else { 3430 } else {
3476 SiS_Pr->SiS_HT = PALHT; 3431 SiS_Pr->SiS_HT = PALHT;
3477 SiS_Pr->SiS_VT = PALVT; 3432 SiS_Pr->SiS_VT = PALVT;
3478 } 3433 }
3479 3434
3480 } 3435 }
3481 3436
@@ -3486,42 +3441,53 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3486 3441
3487 if(SiS_Pr->UseCustomMode) { 3442 if(SiS_Pr->UseCustomMode) {
3488 3443
3489 SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
3490 SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
3491 SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
3492 SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3493 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3444 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
3494 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3445 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
3446
3447 tempax = SiS_Pr->CHTotal;
3448 if(modeflag & HalfDCLK) tempax <<= 1;
3449 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
3450 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
3495 3451
3496 } else { 3452 } else {
3497 3453
3498 BOOLEAN gotit = FALSE; 3454 BOOLEAN gotit = FALSE;
3499 3455
3500 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 3456 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
3501 3457
3502 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3458 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3503 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3459 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3504 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3460 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3505 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3461 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3506 gotit = TRUE; 3462 gotit = TRUE;
3507 3463
3508 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { 3464 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
3509 3465
3510#ifdef SIS315H 3466#ifdef SIS315H
3511 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; 3467 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
3512 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; 3468 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
3513 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); 3469 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
3514 SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4); 3470 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
3515 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8); 3471 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
3516 SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4); 3472 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
3473 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
3474 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
3475 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
3476 tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
3477 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
3478 else SiS_Pr->SiS_RVBHRS2 += tempax;
3479 }
3517 if(SiS_Pr->SiS_VGAHT) gotit = TRUE; 3480 if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
3518 else { 3481 else {
3519 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 3482 SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
3520 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 3483 SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
3484 SiS_Pr->SiS_RVBHCMAX = 1;
3485 SiS_Pr->SiS_RVBHCFACT = 1;
3521 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3486 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
3522 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3487 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
3523 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3488 SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
3524 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3489 SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
3490 SiS_Pr->SiS_RVBHRS2 = 0;
3525 gotit = TRUE; 3491 gotit = TRUE;
3526 } 3492 }
3527#endif 3493#endif
@@ -3530,28 +3496,30 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3530 3496
3531 if(!gotit) { 3497 if(!gotit) {
3532 3498
3533 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3499 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
3534 &CRT2Index,&ResIndex,HwInfo); 3500 &CRT2Index,&ResIndex);
3535 3501
3536 switch(CRT2Index) { 3502 switch(CRT2Index) {
3537 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3503 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3538 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; 3504 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
3539 case Panel_1280x720 : 3505 case Panel_1280x720 :
3540 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break; 3506 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
3541 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break; 3507 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
3542 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break; 3508 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
3543 case Panel_1280x800 : 3509 case Panel_1280x800 :
3544 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break; 3510 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
3545 case Panel_1280x800_2 : 3511 case Panel_1280x800_2 :
3546 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break; 3512 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
3513 case Panel_1280x854 :
3514 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
3547 case Panel_1280x960 : 3515 case Panel_1280x960 :
3548 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; 3516 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
3549 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; 3517 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
3550 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3518 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3551 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; 3519 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
3552 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; 3520 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
3553 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; 3521 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
3554 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; 3522 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
3555 case Panel_1680x1050 : 3523 case Panel_1680x1050 :
3556 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; 3524 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
3557 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; 3525 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
@@ -3559,271 +3527,340 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
3559 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; 3527 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
3560 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3528 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
3561#endif 3529#endif
3562 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3530 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
3563 } 3531 }
3564 3532
3533#ifdef SIS_XORG_XF86
3565#ifdef TWDEBUG 3534#ifdef TWDEBUG
3566 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex); 3535 xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
3536#endif
3567#endif 3537#endif
3568 3538
3569 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; 3539 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
3570 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; 3540 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
3571 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; 3541 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
3572 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT; 3542 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
3573 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT; 3543 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
3574 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT; 3544 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
3575 3545
3576 } 3546 }
3577 3547
3578 tempax = SiS_Pr->PanelXRes; 3548 tempax = SiS_Pr->PanelXRes;
3579 tempbx = SiS_Pr->PanelYRes; 3549 tempbx = SiS_Pr->PanelYRes;
3580 3550
3581 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3551 switch(SiS_Pr->SiS_LCDResInfo) {
3582 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3552 case Panel_1024x768:
3583 if(HwInfo->jChipType < SIS_315H) { 3553 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
3584 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3554 if(SiS_Pr->ChipType < SIS_315H) {
3585 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3555 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3586 } 3556 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3587 } else { 3557 }
3588 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527; 3558 } else {
3589 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620; 3559 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
3590 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775; 3560 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
3591 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775; 3561 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
3592 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3562 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
3593 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3563 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
3594 } 3564 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
3595 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) { 3565 }
3596 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700; 3566 break;
3597 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800; 3567 case Panel_1280x960:
3598 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960; 3568 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
3599 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 3569 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
3600 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768; 3570 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
3601 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800; 3571 break;
3602 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864; 3572 case Panel_1280x1024:
3603 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) { 3573 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
3574 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
3575 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
3576 break;
3577 case Panel_1600x1200:
3604 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3578 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
3605 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875; 3579 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
3606 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000; 3580 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
3607 } 3581 }
3608 } 3582 break;
3583 }
3609 3584
3610 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3585 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3611 tempax = SiS_Pr->SiS_VGAHDE; 3586 tempax = SiS_Pr->SiS_VGAHDE;
3612 tempbx = SiS_Pr->SiS_VGAVDE; 3587 tempbx = SiS_Pr->SiS_VGAVDE;
3613 } 3588 }
3614 3589
3615 SiS_Pr->SiS_HDE = tempax; 3590 SiS_Pr->SiS_HDE = tempax;
3616 SiS_Pr->SiS_VDE = tempbx; 3591 SiS_Pr->SiS_VDE = tempbx;
3617 } 3592 }
3618 } 3593 }
3619} 3594}
3620 3595
3621static void 3596static void
3622SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 3597SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3623 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 3598 unsigned short RefreshRateTableIndex)
3624{ 3599{
3625 3600
3626 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3601 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3627 3602
3628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3603 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
3629 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3604 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3630 } else { 3605 } else {
3631 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3606 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
3632 /* Need LVDS Data for LCD on 301B-DH */ 3607 /* Need LVDS Data for LCD on 301B-DH */
3633 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3608 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3634 } else { 3609 } else {
3635 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3610 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3636 } 3611 }
3637 } 3612 }
3638 3613
3639 } else { 3614 } else {
3640 3615
3641 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 3616 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
3642 3617
3643 } 3618 }
3644} 3619}
3645 3620
3646/*********************************************/ 3621/*********************************************/
3647/* GET LVDS DES (SKEW) DATA */ 3622/* GET LVDS DES (SKEW) DATA */
3648/*********************************************/ 3623/*********************************************/
3649 3624
3650static void 3625static const struct SiS_LVDSDes *
3651SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 3626SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
3652 USHORT RefreshRateTableIndex, USHORT *PanelIndex,
3653 USHORT *ResIndex, PSIS_HW_INFO HwInfo)
3654{ 3627{
3655 USHORT modeflag; 3628 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3656 3629
3657 if(ModeNo <= 0x13) { 3630#ifdef SIS300
3658 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3631 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3659 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3632
3660 } else { 3633 if(SiS_Pr->ChipType < SIS_315H) {
3661 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3634 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
3662 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3635 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
3663 } 3636 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
3637 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3638 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
3639 }
3640 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
3641 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
3642 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3643 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
3644 }
3645 }
3646 }
3647 }
3648 }
3649#endif
3650 return PanelDesPtr;
3651}
3664 3652
3665 (*ResIndex) &= 0x1F; 3653static void
3666 (*PanelIndex) = 0; 3654SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
3655 unsigned short RefreshRateTableIndex)
3656{
3657 unsigned short modeflag, ResIndex;
3658 const struct SiS_LVDSDes *PanelDesPtr = NULL;
3667 3659
3668 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 3660 SiS_Pr->SiS_LCDHDES = 0;
3669 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 3661 SiS_Pr->SiS_LCDVDES = 0;
3670 (*PanelIndex) = 50;
3671 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
3672 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
3673 /* Nothing special needed for SOverscan */
3674 /* PALM uses NTSC data, PALN uses PAL data */
3675 }
3676 }
3677 3662
3663 /* Some special cases */
3678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3664 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
3679 *PanelIndex = SiS_Pr->SiS_LCDTypeInfo; 3665
3680 if(HwInfo->jChipType >= SIS_661) { 3666 /* Trumpion */
3681 /* As long as we don's use the BIOS tables, we 3667 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
3682 * need to convert the TypeInfo as for 315 series 3668 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3683 */ 3669 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3684 (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1; 3670 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3685 } 3671 }
3686 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3687 (*PanelIndex) += 16;
3688 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
3689 (*PanelIndex) = 32;
3690 if(modeflag & HalfDCLK) (*PanelIndex)++;
3691 } 3672 }
3673 return;
3692 } 3674 }
3693 }
3694 3675
3695 if(SiS_Pr->SiS_SetFlag & SetDOSMode) { 3676 /* 640x480 on LVDS */
3696 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) { 3677 if(SiS_Pr->ChipType < SIS_315H) {
3697 (*ResIndex) = 7; 3678 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
3698 if(HwInfo->jChipType < SIS_315H) { 3679 SiS_Pr->SiS_LCDHDES = 8;
3699 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++; 3680 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3700 } 3681 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3682 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3683 return;
3684 }
3701 } 3685 }
3702 }
3703}
3704
3705static void
3706SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3707 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
3708{
3709 USHORT modeflag;
3710 USHORT PanelIndex,ResIndex;
3711 const SiS_LVDSDesStruct *PanelDesPtr = NULL;
3712 3686
3713 SiS_Pr->SiS_LCDHDES = 0; 3687 } /* LCD */
3714 SiS_Pr->SiS_LCDVDES = 0;
3715 3688
3716 if( (SiS_Pr->UseCustomMode) || 3689 if( (SiS_Pr->UseCustomMode) ||
3717 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) || 3690 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
3718 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 3691 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
3719 ((SiS_Pr->SiS_VBType & VB_SISVB) && 3692 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
3720 (SiS_Pr->SiS_LCDInfo & DontExpandLCD) && 3693 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
3721 (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
3722 return; 3694 return;
3723 } 3695 }
3724 3696
3725 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3697 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
3698 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
3699
3700 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3726 3701
3727#ifdef SIS315H 3702#ifdef SIS315H
3728 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3703 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3729 /* non-pass 1:1 only, see above */ 3704 /* non-pass 1:1 only, see above */
3730 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 3705 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3731 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 3706 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3732 } 3707 }
3733 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 3708 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3734 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 3709 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3735 } 3710 }
3736 } 3711 }
3737 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3712 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3738 switch(SiS_Pr->SiS_CustomT) { 3713 switch(SiS_Pr->SiS_CustomT) {
3739 case CUT_UNIWILL1024: 3714 case CUT_UNIWILL1024:
3740 case CUT_UNIWILL10242: 3715 case CUT_UNIWILL10242:
3741 case CUT_CLEVO1400: 3716 case CUT_CLEVO1400:
3742 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3717 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
3743 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3718 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3744 } 3719 }
3745 break; 3720 break;
3746 } 3721 }
3747 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 3722 switch(SiS_Pr->SiS_LCDResInfo) {
3723 case Panel_1280x1024:
3748 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { 3724 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
3749 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3725 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3750 } 3726 }
3727 break;
3728 case Panel_1280x800: /* Verified for Averatec 6240 */
3729 case Panel_1280x800_2: /* Verified for Asus A4L */
3730 case Panel_1280x854: /* Not verified yet FIXME */
3731 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3732 break;
3751 } 3733 }
3752 } 3734 }
3753#endif 3735#endif
3754 3736
3755 } else { 3737 } else {
3756 3738
3757 SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 3739 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
3758 &PanelIndex, &ResIndex, HwInfo); 3740
3759 3741 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
3760 switch(PanelIndex) { 3742 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
3761 case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */ 3743 }
3762 case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break; 3744
3763 case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break; 3745 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
3764 case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break; 3746
3765 case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break; 3747 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
3766 case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break; 3748 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
3767 case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break; 3749
3768 case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break; 3750 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
3769 case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break; 3751
3770 case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break; 3752 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
3771 case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break; 3753 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
3772 case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break; 3754 }
3773 case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break; 3755 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
3774 case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break; 3756 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
3775 case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break; 3757 } else {
3776 case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break; 3758 if(SiS_Pr->ChipType < SIS_315H) {
3777 case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */ 3759 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3778 case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break; 3760 } else {
3779 case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break; 3761 switch(SiS_Pr->SiS_LCDResInfo) {
3780 case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break; 3762 case Panel_800x600:
3781 case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break; 3763 case Panel_1024x768:
3782 case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break; 3764 case Panel_1280x1024:
3783 case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break; 3765 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3784 case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break; 3766 break;
3785 case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break; 3767 case Panel_1400x1050:
3786 case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break; 3768 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3787 case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break; 3769 break;
3788 case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break; 3770 }
3789 case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break; 3771 }
3790 case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break; 3772 }
3791 case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break; 3773
3792 case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break; 3774 } else {
3793 case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */ 3775
3794 case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break; 3776 if(SiS_Pr->ChipType < SIS_315H) {
3795 case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */ 3777#ifdef SIS300
3796 case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break; 3778 switch(SiS_Pr->SiS_LCDResInfo) {
3797 case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break; 3779 case Panel_800x600:
3798 case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break; 3780 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3799 default: return; 3781 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3800 } 3782 } else {
3801 3783 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
3802 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES; 3784 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
3803 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES; 3785 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
3786 else SiS_Pr->SiS_LCDVDES -= 4;
3787 }
3788 break;
3789 case Panel_1024x768:
3790 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3791 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3792 } else {
3793 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3794 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
3795 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
3796 }
3797 break;
3798 case Panel_1024x600:
3799 default:
3800 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
3801 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
3802 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3803 } else {
3804 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
3805 }
3806 break;
3807 }
3808
3809 switch(SiS_Pr->SiS_LCDTypeInfo) {
3810 case 1:
3811 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
3812 break;
3813 case 3: /* 640x480 only? */
3814 SiS_Pr->SiS_LCDHDES = 8;
3815 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
3816 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
3817 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
3818 break;
3819 }
3820#endif
3821 } else {
3822#ifdef SIS315H
3823 switch(SiS_Pr->SiS_LCDResInfo) {
3824 case Panel_1024x768:
3825 case Panel_1280x1024:
3826 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
3827 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
3828 }
3829 break;
3830 case Panel_320x240_1:
3831 case Panel_320x240_2:
3832 case Panel_320x240_3:
3833 SiS_Pr->SiS_LCDVDES = 524;
3834 break;
3835 }
3836#endif
3837 }
3838 }
3804 3839
3805 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3840 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
3806 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3841 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
3807 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3842 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
3808 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632; 3843 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
3809 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) { 3844 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
3810 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 3845 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
3811 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) { 3846 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
3812 if(HwInfo->jChipType < SIS_315H) { 3847 if(SiS_Pr->ChipType < SIS_315H) {
3813 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; 3848 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
3814 } else { 3849 } else {
3815 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; 3850#ifdef SIS315H
3816 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; 3851 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
3852 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
3817 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; 3853 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
3818 if(!(modeflag & HalfDCLK)) { 3854 if(!(modeflag & HalfDCLK)) {
3819 SiS_Pr->SiS_LCDHDES = 320; 3855 SiS_Pr->SiS_LCDHDES = 320;
3820 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632; 3856 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
3821 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542; 3857 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
3822 } 3858 }
3823 } 3859#endif
3824 } 3860 }
3825 } 3861 }
3826 } 3862 }
3863 }
3827 } 3864 }
3828 } 3865 }
3829} 3866}
@@ -3832,54 +3869,90 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
3832/* DISABLE VIDEO BRIDGE */ 3869/* DISABLE VIDEO BRIDGE */
3833/*********************************************/ 3870/*********************************************/
3834 3871
3872#ifdef SIS315H
3873static int
3874SiS_HandlePWD(struct SiS_Private *SiS_Pr)
3875{
3876 int ret = 0;
3877#ifdef SET_PWD
3878 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
3879 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
3880 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
3881 unsigned short temp;
3882
3883 if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
3884 (romptr) &&
3885 (SiS_Pr->SiS_PWDOffset) ) {
3886 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
3887 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
3888 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
3889 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
3890 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
3891 temp = 0x00;
3892 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
3893 temp = 0x80;
3894 ret = 1;
3895 }
3896 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
3897#ifdef SIS_XORG_XF86
3898#ifdef TWDEBUG
3899 xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
3900#endif
3901#endif
3902 }
3903#endif
3904 return ret;
3905}
3906#endif
3907
3835/* NEVER use any variables (VBInfo), this will be called 3908/* NEVER use any variables (VBInfo), this will be called
3836 * from outside the context of modeswitch! 3909 * from outside the context of modeswitch!
3837 * MUST call getVBType before calling this 3910 * MUST call getVBType before calling this
3838 */ 3911 */
3839void 3912void
3840SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 3913SiS_DisableBridge(struct SiS_Private *SiS_Pr)
3841{ 3914{
3842#ifdef SIS315H 3915#ifdef SIS315H
3843 USHORT tempah,pushax=0,modenum; 3916 unsigned short tempah, pushax=0, modenum;
3844#endif 3917#endif
3845 USHORT temp=0; 3918 unsigned short temp=0;
3846 3919
3847 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3920 if(SiS_Pr->SiS_VBType & VB_SISVB) {
3848 3921
3849 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */ 3922 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
3850 3923
3851 if(HwInfo->jChipType < SIS_315H) { 3924 if(SiS_Pr->ChipType < SIS_315H) {
3852 3925
3853#ifdef SIS300 /* 300 series */ 3926#ifdef SIS300 /* 300 series */
3854 3927
3855 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 3928 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
3856 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 3929 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3857 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 3930 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
3858 } else { 3931 } else {
3859 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08); 3932 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
3860 } 3933 }
3861 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 3934 SiS_PanelDelay(SiS_Pr, 3);
3862 } 3935 }
3863 if(SiS_Is301B(SiS_Pr)) { 3936 if(SiS_Is301B(SiS_Pr)) {
3864 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); 3937 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
3865 SiS_ShortDelay(SiS_Pr,1); 3938 SiS_ShortDelay(SiS_Pr,1);
3866 } 3939 }
3867 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); 3940 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
3868 SiS_DisplayOff(SiS_Pr); 3941 SiS_DisplayOff(SiS_Pr);
3869 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 3942 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3870 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 3943 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3871 SiS_UnLockCRT2(SiS_Pr,HwInfo); 3944 SiS_UnLockCRT2(SiS_Pr);
3872 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 3945 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
3873 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 3946 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
3874 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 3947 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
3875 } 3948 }
3876 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) || 3949 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
3877 (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) { 3950 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
3878 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 3951 SiS_PanelDelay(SiS_Pr, 2);
3879 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 3952 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3880 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 3953 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3881 } else { 3954 } else {
3882 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04); 3955 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
3883 } 3956 }
3884 } 3957 }
3885 3958
@@ -3889,130 +3962,127 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
3889 3962
3890#ifdef SIS315H /* 315 series */ 3963#ifdef SIS315H /* 315 series */
3891 3964
3965 int didpwd = 0;
3892 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 3966 BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
3893 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE; 3967 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
3894 3968
3895 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f; 3969 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
3896 3970
3897 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 3971 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3898 3972
3899#ifdef SET_EMI 3973#ifdef SET_EMI
3900 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 3974 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
3901 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 3975 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
3902 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 3976 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
3903 } 3977 }
3904 } 3978 }
3905#endif 3979#endif
3906 if( (modenum <= 0x13) || 3980
3907 (SiS_IsVAMode(SiS_Pr,HwInfo)) || 3981 didpwd = SiS_HandlePWD(SiS_Pr);
3908 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) { 3982
3909 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 3983 if( (modenum <= 0x13) ||
3910 if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3); 3984 (SiS_IsVAMode(SiS_Pr)) ||
3985 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3986 if(!didpwd) {
3987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
3988 if(custom1) SiS_PanelDelay(SiS_Pr, 3);
3989 } else {
3990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
3991 }
3911 } 3992 }
3912 3993
3913 if(!custom1) { 3994 if(!custom1) {
3914 SiS_DDC2Delay(SiS_Pr,0xff00); 3995 SiS_DDC2Delay(SiS_Pr,0xff00);
3915 SiS_DDC2Delay(SiS_Pr,0xe000); 3996 SiS_DDC2Delay(SiS_Pr,0xe000);
3916 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 3997 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
3917 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 3998 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
3918 if(IS_SIS740) { 3999 if(IS_SIS740) {
3919 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4000 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
3920 } 4001 }
3921 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 4002 SiS_PanelDelay(SiS_Pr, 3);
3922 } 4003 }
3923 4004
3924 } 4005 }
3925 4006
3926 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) { 4007 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
3927 if(HwInfo->jChipType < SIS_340) { 4008 /* if(SiS_Pr->ChipType < SIS_340) {*/
3928 tempah = 0xef; 4009 tempah = 0xef;
3929 if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7; 4010 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
3930 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4011 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
3931 } 4012 /*}*/
3932 } 4013 }
3933 4014
3934 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4015 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3935 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10); 4016 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
3936 } 4017 }
3937 4018
3938 tempah = 0x3f; 4019 tempah = 0x3f;
3939 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) { 4020 if(SiS_IsDualEdge(SiS_Pr)) {
3940 tempah = 0x7f; 4021 tempah = 0x7f;
3941 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf; 4022 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
3942 } 4023 }
3943 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4024 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
3944 4025
3945 if((SiS_IsVAMode(SiS_Pr,HwInfo)) || 4026 if((SiS_IsVAMode(SiS_Pr)) ||
3946 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) { 4027 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3947 4028
3948 SiS_DisplayOff(SiS_Pr); 4029 SiS_DisplayOff(SiS_Pr);
3949 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4030 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3950 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4031 SiS_PanelDelay(SiS_Pr, 2);
3951 } 4032 }
3952 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4033 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3953 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); 4034 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
3954 4035
3955 } 4036 }
3956 4037
3957 if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) || 4038 if((!(SiS_IsVAMode(SiS_Pr))) ||
3958 ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) { 4039 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
3959 4040
3960 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) { 4041 if(!(SiS_IsDualEdge(SiS_Pr))) {
3961 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); 4042 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
3962 SiS_DisplayOff(SiS_Pr); 4043 SiS_DisplayOff(SiS_Pr);
3963 } 4044 }
3964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4045 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
3965 4046
3966 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4047 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3967 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4048 SiS_PanelDelay(SiS_Pr, 2);
3968 } 4049 }
3969 4050
3970 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4051 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
3971 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4052 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
3972 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4053 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
3973 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4054 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
3974 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
3975 4056
3976 } 4057 }
3977 4058
3978 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) { 4059 if(SiS_IsNotM650orLater(SiS_Pr)) {
3979 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4060 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
3980 } 4061 }
3981 4062
3982 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4063 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
3983
3984 if(!custom1) {
3985
3986 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
3987 if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
3988 if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
3989 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3990 }
3991 }
3992 }
3993 4064
3994 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4065 if( (!(SiS_IsVAMode(SiS_Pr))) &&
4066 (!(SiS_CRT2IsLCD(SiS_Pr))) &&
4067 (!(SiS_IsDualEdge(SiS_Pr))) ) {
3995 4068
3996 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4069 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
3997 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) { 4070 if(!didpwd) {
3998 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20); 4071 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
3999 } 4072 }
4000 } 4073 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
4001 4074 }
4002 } else {
4003 4075
4004 if((SiS_IsVAMode(SiS_Pr,HwInfo)) || 4076 if(!custom1) {
4005 (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) { 4077 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
4006 if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) || 4078 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4007 (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) { 4079 if(SiS_IsVAorLCD(SiS_Pr)) {
4008 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4080 SiS_PanelDelayLoop(SiS_Pr, 3, 20);
4009 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
4010 SiS_PanelDelay(SiS_Pr, HwInfo, 4);
4011 } 4081 }
4012 } 4082 }
4013
4014 } 4083 }
4015 } 4084
4085 }
4016 4086
4017#endif /* SIS315H */ 4087#endif /* SIS315H */
4018 4088
@@ -4020,36 +4090,36 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4020 4090
4021 } else { /* ============ For 301 ================ */ 4091 } else { /* ============ For 301 ================ */
4022 4092
4023 if(HwInfo->jChipType < SIS_315H) { 4093 if(SiS_Pr->ChipType < SIS_315H) {
4024#ifdef SIS300 4094#ifdef SIS300
4025 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4095 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4026 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08); 4096 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4027 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 4097 SiS_PanelDelay(SiS_Pr, 3);
4028 } 4098 }
4029#endif 4099#endif
4030 } 4100 }
4031 4101
4032 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */ 4102 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
4033 SiS_DisplayOff(SiS_Pr); 4103 SiS_DisplayOff(SiS_Pr);
4034 4104
4035 if(HwInfo->jChipType >= SIS_315H) { 4105 if(SiS_Pr->ChipType >= SIS_315H) {
4036 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4106 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4037 } 4107 }
4038 4108
4039 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */ 4109 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
4040 4110
4041 if(HwInfo->jChipType >= SIS_315H) { 4111 if(SiS_Pr->ChipType >= SIS_315H) {
4042 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4112 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
4043 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4113 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
4044 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4114 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4045 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4115 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
4046 } else { 4116 } else {
4047#ifdef SIS300 4117#ifdef SIS300
4048 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ 4118 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
4049 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) || 4119 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4050 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) { 4120 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4051 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4121 SiS_PanelDelay(SiS_Pr, 2);
4052 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04); 4122 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4053 } 4123 }
4054#endif 4124#endif
4055 } 4125 }
@@ -4058,34 +4128,34 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4058 4128
4059 } else { /* ============ For LVDS =============*/ 4129 } else { /* ============ For LVDS =============*/
4060 4130
4061 if(HwInfo->jChipType < SIS_315H) { 4131 if(SiS_Pr->ChipType < SIS_315H) {
4062 4132
4063#ifdef SIS300 /* 300 series */ 4133#ifdef SIS300 /* 300 series */
4064 4134
4065 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4135 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4066 SiS_SetCH700x(SiS_Pr,0x090E); 4136 SiS_SetCH700x(SiS_Pr,0x0E,0x09);
4067 } 4137 }
4068 4138
4069 if(HwInfo->jChipType == SIS_730) { 4139 if(SiS_Pr->ChipType == SIS_730) {
4070 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4140 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4071 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 4141 SiS_WaitVBRetrace(SiS_Pr);
4072 } 4142 }
4073 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4143 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4074 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08); 4144 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4075 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 4145 SiS_PanelDelay(SiS_Pr, 3);
4076 } 4146 }
4077 } else { 4147 } else {
4078 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4148 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
4079 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4149 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4080 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4150 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4081 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 4151 SiS_WaitVBRetrace(SiS_Pr);
4082 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) { 4152 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
4083 SiS_DisplayOff(SiS_Pr); 4153 SiS_DisplayOff(SiS_Pr);
4084 } 4154 }
4085 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08); 4155 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4086 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 4156 SiS_PanelDelay(SiS_Pr, 3);
4087 } 4157 }
4088 } 4158 }
4089 } 4159 }
4090 } 4160 }
4091 4161
@@ -4094,14 +4164,14 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4094 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4164 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4095 4165
4096 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4166 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4097 SiS_UnLockCRT2(SiS_Pr,HwInfo); 4167 SiS_UnLockCRT2(SiS_Pr);
4098 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4168 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
4099 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4169 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
4100 4170
4101 if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) || 4171 if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
4102 (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) { 4172 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
4103 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4173 SiS_PanelDelay(SiS_Pr, 2);
4104 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04); 4174 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4105 } 4175 }
4106 4176
4107#endif /* SIS300 */ 4177#endif /* SIS300 */
@@ -4110,113 +4180,113 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4110 4180
4111#ifdef SIS315H /* 315 series */ 4181#ifdef SIS315H /* 315 series */
4112 4182
4113 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) { 4183 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4114 if(HwInfo->jChipType < SIS_340) { 4184 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
4115 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18); 4185 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
4116 } 4186 /* } */
4117 } 4187 }
4118 4188
4119 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4189 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4120 4190
4121 if(HwInfo->jChipType == SIS_740) { 4191 if(SiS_Pr->ChipType == SIS_740) {
4122 temp = SiS_GetCH701x(SiS_Pr,0x61); 4192 temp = SiS_GetCH701x(SiS_Pr,0x61);
4123 if(temp < 1) { 4193 if(temp < 1) {
4124 SiS_SetCH701x(SiS_Pr,0xac76); 4194 SiS_SetCH701x(SiS_Pr,0x76,0xac);
4125 SiS_SetCH701x(SiS_Pr,0x0066); 4195 SiS_SetCH701x(SiS_Pr,0x66,0x00);
4126 } 4196 }
4127 4197
4128 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4198 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4129 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) { 4199 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4130 SiS_SetCH701x(SiS_Pr,0x3e49); 4200 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
4131 } 4201 }
4132 } 4202 }
4133 4203
4134 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4204 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4135 (SiS_IsVAMode(SiS_Pr,HwInfo)) ) { 4205 (SiS_IsVAMode(SiS_Pr)) ) {
4136 SiS_Chrontel701xBLOff(SiS_Pr); 4206 SiS_Chrontel701xBLOff(SiS_Pr);
4137 SiS_Chrontel701xOff(SiS_Pr,HwInfo); 4207 SiS_Chrontel701xOff(SiS_Pr);
4138 } 4208 }
4139 4209
4140 if(HwInfo->jChipType != SIS_740) { 4210 if(SiS_Pr->ChipType != SIS_740) {
4141 if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4211 if( (!(SiS_IsDualEdge(SiS_Pr))) ||
4142 (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) { 4212 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
4143 SiS_SetCH701x(SiS_Pr,0x0149); 4213 SiS_SetCH701x(SiS_Pr,0x49,0x01);
4144 } 4214 }
4145 } 4215 }
4146 4216
4147 } 4217 }
4148 4218
4149 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4219 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4150 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08); 4220 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
4151 SiS_PanelDelay(SiS_Pr, HwInfo, 3); 4221 SiS_PanelDelay(SiS_Pr, 3);
4152 } 4222 }
4153 4223
4154 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4224 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4155 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4225 (!(SiS_IsDualEdge(SiS_Pr))) ||
4156 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) { 4226 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
4157 SiS_DisplayOff(SiS_Pr); 4227 SiS_DisplayOff(SiS_Pr);
4158 } 4228 }
4159 4229
4160 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4230 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4161 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4231 (!(SiS_IsDualEdge(SiS_Pr))) ||
4162 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) { 4232 (!(SiS_IsVAMode(SiS_Pr))) ) {
4163 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4233 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
4164 } 4234 }
4165 4235
4166 if(HwInfo->jChipType == SIS_740) { 4236 if(SiS_Pr->ChipType == SIS_740) {
4167 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4237 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4168 } 4238 }
4169 4239
4170 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4240 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
4171 4241
4172 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4242 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4173 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4243 (!(SiS_IsDualEdge(SiS_Pr))) ||
4174 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) { 4244 (!(SiS_IsVAMode(SiS_Pr))) ) {
4175 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4245 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
4176 } 4246 }
4177 4247
4178 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4248 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4179 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4249 if(SiS_CRT2IsLCD(SiS_Pr)) {
4180 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4250 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4181 if(HwInfo->jChipType == SIS_550) { 4251 if(SiS_Pr->ChipType == SIS_550) {
4182 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf); 4252 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
4183 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef); 4253 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
4184 } 4254 }
4185 } 4255 }
4186 } else { 4256 } else {
4187 if(HwInfo->jChipType == SIS_740) { 4257 if(SiS_Pr->ChipType == SIS_740) {
4188 if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) { 4258 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4189 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4259 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4190 } 4260 }
4191 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) { 4261 } else if(SiS_IsVAMode(SiS_Pr)) {
4192 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4262 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
4193 } 4263 }
4194 } 4264 }
4195 4265
4196 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4266 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
4197 if(SiS_IsDualEdge(SiS_Pr,HwInfo)) { 4267 if(SiS_IsDualEdge(SiS_Pr)) {
4198 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */ 4268 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
4199 } else { 4269 } else {
4200 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 4270 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
4201 } 4271 }
4202 } 4272 }
4203 4273
4204 SiS_UnLockCRT2(SiS_Pr,HwInfo); 4274 SiS_UnLockCRT2(SiS_Pr);
4205 4275
4206 if(HwInfo->jChipType == SIS_550) { 4276 if(SiS_Pr->ChipType == SIS_550) {
4207 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/ 4277 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
4208 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */ 4278 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
4209 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4279 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
4210 (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) || 4280 (!(SiS_IsDualEdge(SiS_Pr))) ||
4211 (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) { 4281 (!(SiS_IsVAMode(SiS_Pr))) ) {
4212 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4282 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4213 } 4283 }
4214 4284
4215 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4285 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4216 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4286 if(SiS_CRT2IsLCD(SiS_Pr)) {
4217 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4287 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4218 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4288 SiS_PanelDelay(SiS_Pr, 2);
4219 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04); 4289 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
4220 } 4290 }
4221 } 4291 }
4222 } 4292 }
@@ -4237,78 +4307,81 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4237 * from outside the context of a mode switch! 4307 * from outside the context of a mode switch!
4238 * MUST call getVBType before calling this 4308 * MUST call getVBType before calling this
4239 */ 4309 */
4240static void 4310#ifdef SIS_LINUX_KERNEL
4241SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 4311static
4312#endif
4313void
4314SiS_EnableBridge(struct SiS_Private *SiS_Pr)
4242{ 4315{
4243 USHORT temp=0,tempah; 4316 unsigned short temp=0, tempah;
4244#ifdef SIS315H 4317#ifdef SIS315H
4245 USHORT temp1,pushax=0; 4318 unsigned short temp1, pushax=0;
4246 BOOLEAN delaylong = FALSE; 4319 BOOLEAN delaylong = FALSE;
4247#endif 4320#endif
4248 4321
4249 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4322 if(SiS_Pr->SiS_VBType & VB_SISVB) {
4250 4323
4251 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */ 4324 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
4252 4325
4253 if(HwInfo->jChipType < SIS_315H) { 4326 if(SiS_Pr->ChipType < SIS_315H) {
4254 4327
4255#ifdef SIS300 /* 300 series */ 4328#ifdef SIS300 /* 300 series */
4256 4329
4257 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4330 if(SiS_CRT2IsLCD(SiS_Pr)) {
4258 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4331 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4259 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4332 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4260 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { 4333 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4261 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00); 4334 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4262 } 4335 }
4263 if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) { 4336 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
4264 if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) { 4337 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4265 SiS_PanelDelay(SiS_Pr, HwInfo, 0); 4338 SiS_PanelDelay(SiS_Pr, 0);
4266 } 4339 }
4267 } 4340 }
4268 } 4341 }
4269 4342
4270 if((SiS_Pr->SiS_VBType & VB_NoLCD) && 4343 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
4271 (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) { 4344 (SiS_CRT2IsLCD(SiS_Pr))) {
4272 4345
4273 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */ 4346 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
4274 SiS_DisplayOn(SiS_Pr); 4347 SiS_DisplayOn(SiS_Pr);
4275 SiS_UnLockCRT2(SiS_Pr,HwInfo); 4348 SiS_UnLockCRT2(SiS_Pr);
4276 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4349 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4277 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4350 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4278 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4351 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4279 } else { 4352 } else {
4280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4353 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4281 } 4354 }
4282 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4355 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4283 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4356 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4284 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4357 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4285 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4358 SiS_PanelDelay(SiS_Pr, 1);
4286 } 4359 }
4287 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 4360 SiS_WaitVBRetrace(SiS_Pr);
4288 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00); 4361 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4289 } 4362 }
4290 } 4363 }
4291 4364
4292 } else { 4365 } else {
4293 4366
4294 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4367 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4295 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4368 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4296 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4369 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4297 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4370 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4298 } 4371 }
4299 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4372 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4300 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4373 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4301 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4374 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
4302 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); 4375 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
4303 SiS_DisplayOn(SiS_Pr); 4376 SiS_DisplayOn(SiS_Pr);
4304 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4377 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4305 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4378 if(SiS_CRT2IsLCD(SiS_Pr)) {
4306 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4379 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4307 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4380 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4308 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4381 SiS_PanelDelay(SiS_Pr, 1);
4309 } 4382 }
4310 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4383 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4311 } 4384 }
4312 } 4385 }
4313 } 4386 }
4314 4387
@@ -4322,31 +4395,32 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4322#ifdef SIS315H /* 315 series */ 4395#ifdef SIS315H /* 315 series */
4323 4396
4324#ifdef SET_EMI 4397#ifdef SET_EMI
4325 UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0; 4398 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
4326 /* USHORT emidelay=0; */ 4399 int didpwd = 0;
4400 /* unsigned short emidelay=0; */
4327#endif 4401#endif
4328 4402
4329 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4403 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4330 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); 4404 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
4331#ifdef SET_EMI 4405#ifdef SET_EMI
4332 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4406 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4333 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4407 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4334 } 4408 }
4335#endif 4409#endif
4336 } 4410 }
4337 4411
4338 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) { 4412 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4339 if(HwInfo->jChipType < SIS_340) { 4413 /*if(SiS_Pr->ChipType < SIS_340) { */
4340 tempah = 0x10; 4414 tempah = 0x10;
4341 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) { 4415 if(SiS_LCDAEnabled(SiS_Pr)) {
4342 if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18; 4416 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
4343 else tempah = 0x08; 4417 else tempah = 0x08;
4344 } 4418 }
4345 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4419 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
4346 } 4420 /*}*/
4347 } 4421 }
4348 4422
4349 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4423 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4350 4424
4351 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4425 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
4352 SiS_DisplayOff(SiS_Pr); 4426 SiS_DisplayOff(SiS_Pr);
@@ -4355,42 +4429,51 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4355 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4429 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
4356 } 4430 }
4357 4431
4358 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) { 4432 didpwd = SiS_HandlePWD(SiS_Pr);
4359 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 4433
4360 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2); 4434 if(SiS_IsVAorLCD(SiS_Pr)) {
4361 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4435 if(!didpwd) {
4362 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2); 4436 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
4363 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4437 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4364 SiS_GenericDelay(SiS_Pr, 0x4500); 4438 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
4439 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4440 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4441 SiS_GenericDelay(SiS_Pr, 17664);
4442 }
4443 }
4444 } else {
4445 SiS_PanelDelayLoop(SiS_Pr, 3, 2);
4446 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4447 SiS_GenericDelay(SiS_Pr, 17664);
4365 } 4448 }
4366 } 4449 }
4367 } 4450 }
4368 4451
4369 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) { 4452 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
4370 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10); 4453 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4371 delaylong = TRUE; 4454 delaylong = TRUE;
4372 } 4455 }
4373 4456
4374 } 4457 }
4375 4458
4376 if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) { 4459 if(!(SiS_IsVAMode(SiS_Pr))) {
4377 4460
4378 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; 4461 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
4379 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4462 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4380 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4463 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4381 if(!(tempah & SetCRT2ToRAMDAC)) { 4464 if(!(tempah & SetCRT2ToRAMDAC)) {
4382 if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20; 4465 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
4383 } 4466 }
4384 } 4467 }
4385 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4468 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4386 4469
4387 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4470 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4388 4471
4389 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4472 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4390 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4473 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4391 4474
4392 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4475 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4393 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4476 SiS_PanelDelay(SiS_Pr, 2);
4394 } 4477 }
4395 4478
4396 } else { 4479 } else {
@@ -4402,38 +4485,48 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4402 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); 4485 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
4403 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4486 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4404 4487
4488 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
4489 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4490 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4491 /* Enable "LVDS PLL power on" (even on 301C) */
4492 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
4493 /* Enable "LVDS Driver Power on" (even on 301C) */
4494 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
4495 }
4496 }
4497
4405 tempah = 0xc0; 4498 tempah = 0xc0;
4406 if(SiS_IsDualEdge(SiS_Pr, HwInfo)) { 4499 if(SiS_IsDualEdge(SiS_Pr)) {
4407 tempah = 0x80; 4500 tempah = 0x80;
4408 if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40; 4501 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
4409 } 4502 }
4410 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4503 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
4411 4504
4412 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 4505 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
4413 4506
4414 SiS_PanelDelay(SiS_Pr, HwInfo, 2); 4507 SiS_PanelDelay(SiS_Pr, 2);
4415 4508
4416 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); 4509 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
4417 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4510 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
4418 4511
4419 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4512 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
4420#ifdef SET_EMI 4513#ifdef SET_EMI
4421 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4514 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4422 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4515 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
4423 SiS_GenericDelay(SiS_Pr, 0x500); 4516 SiS_GenericDelay(SiS_Pr, 2048);
4424 } 4517 }
4425#endif 4518#endif
4426 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c); 4519 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
4427 4520
4428 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4521 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4429#ifdef SET_EMI 4522#ifdef SET_EMI
4430 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 4523 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
4431 4524
4432 if(SiS_Pr->SiS_ROMNew) { 4525 if(SiS_Pr->SiS_ROMNew) {
4433 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 4526 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4434 USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo); 4527 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
4435 if(romptr) { 4528 if(romptr) {
4436 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4529 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4437 SiS_Pr->EMI_30 = 0; 4530 SiS_Pr->EMI_30 = 0;
4438 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0]; 4531 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
4439 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1]; 4532 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
@@ -4511,21 +4604,21 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4511 if(!SiS_Pr->OverruleEMI) { 4604 if(!SiS_Pr->OverruleEMI) {
4512#ifdef COMPAL_HACK 4605#ifdef COMPAL_HACK
4513 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4606 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
4514 if((cr36 & 0x0f) == 0x09) { 4607 if((cr36 & 0x0f) == 0x09) {
4515 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00; 4608 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
4516 } 4609 }
4517 } 4610 }
4518#endif 4611#endif
4519#ifdef COMPAQ_HACK 4612#ifdef COMPAQ_HACK
4520 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4613 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
4521 if((cr36 & 0x0f) == 0x03) { 4614 if((cr36 & 0x0f) == 0x03) {
4522 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4615 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
4523 } 4616 }
4524 } 4617 }
4525#endif 4618#endif
4526#ifdef ASUS_HACK 4619#ifdef ASUS_HACK
4527 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4620 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4528 if((cr36 & 0x0f) == 0x02) { 4621 if((cr36 & 0x0f) == 0x02) {
4529 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */ 4622 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
4530 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */ 4623 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
4531 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */ 4624 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
@@ -4533,11 +4626,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4533 } 4626 }
4534 } 4627 }
4535#endif 4628#endif
4536 } 4629 }
4537 4630
4538 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) { 4631 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
4539 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4632 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
4540 SiS_GenericDelay(SiS_Pr, 0x500); 4633 SiS_GenericDelay(SiS_Pr, 2048);
4541 } 4634 }
4542 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31); 4635 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
4543 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32); 4636 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
@@ -4547,36 +4640,44 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4547 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 4640 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
4548 4641
4549#ifdef SET_EMI 4642#ifdef SET_EMI
4550 if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) || 4643 if( (SiS_LCDAEnabled(SiS_Pr)) ||
4551 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) { 4644 (SiS_CRT2IsLCD(SiS_Pr)) ) {
4552 if(r30 & 0x40) { 4645 if(r30 & 0x40) {
4553 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5); 4646 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
4647 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4554 if(delaylong) { 4648 if(delaylong) {
4555 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5); 4649 SiS_PanelDelayLoop(SiS_Pr, 3, 5);
4556 delaylong = FALSE; 4650 delaylong = FALSE;
4557 } 4651 }
4558 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 4652 SiS_WaitVBRetrace(SiS_Pr);
4653 SiS_WaitVBRetrace(SiS_Pr);
4559 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4654 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
4560 SiS_GenericDelay(SiS_Pr, 0x500); 4655 SiS_GenericDelay(SiS_Pr, 1280);
4561 } 4656 }
4562 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */ 4657 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
4563 } 4658 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
4659 }
4564 } 4660 }
4565#endif 4661#endif
4566 } 4662 }
4567 } 4663 }
4568 4664
4569 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4665 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4570 if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) { 4666 if(SiS_IsVAorLCD(SiS_Pr)) {
4571 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10); 4667 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4572 if(delaylong) { 4668 if(delaylong) {
4573 SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10); 4669 SiS_PanelDelayLoop(SiS_Pr, 3, 10);
4574 } 4670 }
4575 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 4671 SiS_WaitVBRetrace(SiS_Pr);
4576 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 4672 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
4577 SiS_GenericDelay(SiS_Pr, 0x500); 4673 SiS_GenericDelay(SiS_Pr, 2048);
4674 SiS_WaitVBRetrace(SiS_Pr);
4675 }
4676 if(!didpwd) {
4677 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4678 } else {
4679 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
4578 } 4680 }
4579 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
4580 } 4681 }
4581 } 4682 }
4582 4683
@@ -4586,7 +4687,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4586 4687
4587 } 4688 }
4588 4689
4589 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4690 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4590 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4691 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4591 } 4692 }
4592 4693
@@ -4596,26 +4697,26 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4596 4697
4597 } else { /* ============ For 301 ================ */ 4698 } else { /* ============ For 301 ================ */
4598 4699
4599 if(HwInfo->jChipType < SIS_315H) { 4700 if(SiS_Pr->ChipType < SIS_315H) {
4600 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4701 if(SiS_CRT2IsLCD(SiS_Pr)) {
4601 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00); 4702 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4602 SiS_PanelDelay(SiS_Pr, HwInfo, 0); 4703 SiS_PanelDelay(SiS_Pr, 0);
4603 } 4704 }
4604 } 4705 }
4605 4706
4606 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4707 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
4607 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4708 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4608 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4709 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
4609 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4710 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
4610 } 4711 }
4611 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4712 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
4612 4713
4613 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4714 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
4614 4715
4615 if(HwInfo->jChipType >= SIS_315H) { 4716 if(SiS_Pr->ChipType >= SIS_315H) {
4616 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4717 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4617 if(!(temp & 0x80)) { 4718 if(!(temp & 0x80)) {
4618 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */ 4719 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
4619 } 4720 }
4620 } 4721 }
4621 4722
@@ -4623,15 +4724,15 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4623 4724
4624 SiS_VBLongWait(SiS_Pr); 4725 SiS_VBLongWait(SiS_Pr);
4625 SiS_DisplayOn(SiS_Pr); 4726 SiS_DisplayOn(SiS_Pr);
4626 if(HwInfo->jChipType >= SIS_315H) { 4727 if(SiS_Pr->ChipType >= SIS_315H) {
4627 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4728 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4628 } 4729 }
4629 SiS_VBLongWait(SiS_Pr); 4730 SiS_VBLongWait(SiS_Pr);
4630 4731
4631 if(HwInfo->jChipType < SIS_315H) { 4732 if(SiS_Pr->ChipType < SIS_315H) {
4632 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4733 if(SiS_CRT2IsLCD(SiS_Pr)) {
4633 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4734 SiS_PanelDelay(SiS_Pr, 1);
4634 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00); 4735 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4635 } 4736 }
4636 } 4737 }
4637 4738
@@ -4639,49 +4740,49 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4639 4740
4640 } else { /* =================== For LVDS ================== */ 4741 } else { /* =================== For LVDS ================== */
4641 4742
4642 if(HwInfo->jChipType < SIS_315H) { 4743 if(SiS_Pr->ChipType < SIS_315H) {
4643 4744
4644#ifdef SIS300 /* 300 series */ 4745#ifdef SIS300 /* 300 series */
4645 4746
4646 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4747 if(SiS_CRT2IsLCD(SiS_Pr)) {
4647 if(HwInfo->jChipType == SIS_730) { 4748 if(SiS_Pr->ChipType == SIS_730) {
4648 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4749 SiS_PanelDelay(SiS_Pr, 1);
4649 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4750 SiS_PanelDelay(SiS_Pr, 1);
4650 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4751 SiS_PanelDelay(SiS_Pr, 1);
4651 } 4752 }
4652 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00); 4753 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4653 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) { 4754 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
4654 SiS_PanelDelay(SiS_Pr, HwInfo, 0); 4755 SiS_PanelDelay(SiS_Pr, 0);
4655 } 4756 }
4656 } 4757 }
4657 4758
4658 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4759 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4659 SiS_DisplayOn(SiS_Pr); 4760 SiS_DisplayOn(SiS_Pr);
4660 SiS_UnLockCRT2(SiS_Pr,HwInfo); 4761 SiS_UnLockCRT2(SiS_Pr);
4661 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4762 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
4662 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4763 if(SiS_BridgeInSlavemode(SiS_Pr)) {
4663 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4764 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
4664 } else { 4765 } else {
4665 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4766 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
4666 } 4767 }
4667 4768
4668 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4769 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
4669 if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) { 4770 if(!(SiS_CRT2IsLCD(SiS_Pr))) {
4670 SiS_WaitVBRetrace(SiS_Pr, HwInfo); 4771 SiS_WaitVBRetrace(SiS_Pr);
4671 SiS_SetCH700x(SiS_Pr,0x0B0E); 4772 SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
4672 } 4773 }
4673 } 4774 }
4674 4775
4675 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4776 if(SiS_CRT2IsLCD(SiS_Pr)) {
4676 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4777 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
4677 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4778 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
4678 if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) { 4779 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
4679 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4780 SiS_PanelDelay(SiS_Pr, 1);
4680 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4781 SiS_PanelDelay(SiS_Pr, 1);
4681 } 4782 }
4682 SiS_WaitVBRetrace(SiS_Pr, HwInfo); 4783 SiS_WaitVBRetrace(SiS_Pr);
4683 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00); 4784 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4684 } 4785 }
4685 } 4786 }
4686 } 4787 }
4687 4788
@@ -4691,94 +4792,94 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4691 4792
4692#ifdef SIS315H /* 315 series */ 4793#ifdef SIS315H /* 315 series */
4693 4794
4694 if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) { 4795 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
4695 if(HwInfo->jChipType < SIS_340) { 4796 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
4696 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18); 4797 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
4697 } 4798 /*}*/
4698 } 4799 }
4699 4800
4700 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4801 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4701 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4802 if(SiS_CRT2IsLCD(SiS_Pr)) {
4702 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00); 4803 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
4703 SiS_PanelDelay(SiS_Pr, HwInfo, 0); 4804 SiS_PanelDelay(SiS_Pr, 0);
4704 } 4805 }
4705 } 4806 }
4706 4807
4707 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4808 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
4708 SiS_UnLockCRT2(SiS_Pr,HwInfo); 4809 SiS_UnLockCRT2(SiS_Pr);
4709 4810
4710 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4811 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
4711 4812
4712 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4813 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4713 temp = SiS_GetCH701x(SiS_Pr,0x66); 4814 temp = SiS_GetCH701x(SiS_Pr,0x66);
4714 temp &= 0x20; 4815 temp &= 0x20;
4715 SiS_Chrontel701xBLOff(SiS_Pr); 4816 SiS_Chrontel701xBLOff(SiS_Pr);
4716 } 4817 }
4717 4818
4718 if(HwInfo->jChipType != SIS_550) { 4819 if(SiS_Pr->ChipType != SIS_550) {
4719 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4820 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
4720 } 4821 }
4721 4822
4722 if(HwInfo->jChipType == SIS_740) { 4823 if(SiS_Pr->ChipType == SIS_740) {
4723 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4824 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4724 if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) { 4825 if(SiS_IsLCDOrLCDA(SiS_Pr)) {
4725 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4826 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4726 } 4827 }
4727 } 4828 }
4728 } 4829 }
4729 4830
4730 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4831 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
4731 if(!(temp1 & 0x80)) { 4832 if(!(temp1 & 0x80)) {
4732 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); 4833 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
4733 } 4834 }
4734 4835
4735 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4836 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4736 if(temp) { 4837 if(temp) {
4737 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo); 4838 SiS_Chrontel701xBLOn(SiS_Pr);
4738 } 4839 }
4739 } 4840 }
4740 4841
4741 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4842 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4742 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4843 if(SiS_CRT2IsLCD(SiS_Pr)) {
4743 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4844 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4744 if(HwInfo->jChipType == SIS_550) { 4845 if(SiS_Pr->ChipType == SIS_550) {
4745 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40); 4846 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
4746 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10); 4847 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
4747 } 4848 }
4748 } 4849 }
4749 } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) { 4850 } else if(SiS_IsVAMode(SiS_Pr)) {
4750 if(HwInfo->jChipType != SIS_740) { 4851 if(SiS_Pr->ChipType != SIS_740) {
4751 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 4852 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
4752 } 4853 }
4753 } 4854 }
4754 4855
4755 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4856 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4756 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4857 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
4757 } 4858 }
4758 4859
4759 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4860 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4760 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) { 4861 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
4761 SiS_Chrontel701xOn(SiS_Pr,HwInfo); 4862 SiS_Chrontel701xOn(SiS_Pr);
4762 } 4863 }
4763 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) || 4864 if( (SiS_IsVAMode(SiS_Pr)) ||
4764 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) { 4865 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4765 SiS_ChrontelDoSomething1(SiS_Pr,HwInfo); 4866 SiS_ChrontelDoSomething1(SiS_Pr);
4766 } 4867 }
4767 } 4868 }
4768 4869
4769 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 4870 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
4770 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4871 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4771 if( (SiS_IsVAMode(SiS_Pr,HwInfo)) || 4872 if( (SiS_IsVAMode(SiS_Pr)) ||
4772 (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) { 4873 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
4773 SiS_Chrontel701xBLOn(SiS_Pr, HwInfo); 4874 SiS_Chrontel701xBLOn(SiS_Pr);
4774 SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo); 4875 SiS_ChrontelInitTVVSync(SiS_Pr);
4775 } 4876 }
4776 } 4877 }
4777 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4878 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
4778 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) { 4879 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
4779 if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) { 4880 if(SiS_CRT2IsLCD(SiS_Pr)) {
4780 SiS_PanelDelay(SiS_Pr, HwInfo, 1); 4881 SiS_PanelDelay(SiS_Pr, 1);
4781 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00); 4882 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
4782 } 4883 }
4783 } 4884 }
4784 } 4885 }
@@ -4797,243 +4898,204 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
4797 4898
4798/* Set CRT2 OFFSET / PITCH */ 4899/* Set CRT2 OFFSET / PITCH */
4799static void 4900static void
4800SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 4901SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
4801 USHORT RRTI, PSIS_HW_INFO HwInfo) 4902 unsigned short RRTI)
4802{ 4903{
4803 USHORT offset; 4904 unsigned short offset;
4804 UCHAR temp; 4905 unsigned char temp;
4805 4906
4806 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return; 4907 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
4807 4908
4808 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo); 4909 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
4809 4910
4810 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) || 4911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
4811 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) { 4912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
4812 offset >>= 1;
4813 }
4814 4913
4815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF)); 4914 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
4816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8)); 4915 if(offset & 0x07) temp++;
4817 temp = (UCHAR)(((offset >> 3) & 0xFF) + 1); 4916 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4818 if(offset % 8) temp++;
4819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
4820} 4917}
4821 4918
4822/* Set CRT2 sync and PanelLink mode */ 4919/* Set CRT2 sync and PanelLink mode */
4823static void 4920static void
4824SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex, 4921SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
4825 PSIS_HW_INFO HwInfo)
4826{ 4922{
4827 USHORT tempah=0,tempbl,infoflag; 4923 unsigned short tempah=0, tempbl, infoflag;
4828 4924
4829 tempbl = 0xC0; 4925 tempbl = 0xC0;
4830 4926
4831 if(SiS_Pr->UseCustomMode) { 4927 if(SiS_Pr->UseCustomMode) {
4832 infoflag = SiS_Pr->CInfoFlag; 4928 infoflag = SiS_Pr->CInfoFlag;
4833 } else { 4929 } else {
4834 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 4930 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
4835 } 4931 }
4836 4932
4837 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */ 4933 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
4838 4934
4839 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 4935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4840 tempah = 0; 4936 tempah = 0;
4841 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) { 4937 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
4842 tempah = SiS_Pr->SiS_LCDInfo; 4938 tempah = SiS_Pr->SiS_LCDInfo;
4843 } else tempah = infoflag >> 8; 4939 } else tempah = infoflag >> 8;
4844 tempah &= 0xC0; 4940 tempah &= 0xC0;
4845 tempah |= 0x20; 4941 tempah |= 0x20;
4846 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 4942 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4847 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 4943 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4848 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 4944 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
4849 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 4945 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
4850 tempah |= 0xf0; 4946 tempah |= 0xf0;
4851 } 4947 }
4852 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 4948 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4853 (SiS_Pr->SiS_IF_DEF_DSTN) || 4949 (SiS_Pr->SiS_IF_DEF_DSTN) ||
4854 (SiS_Pr->SiS_IF_DEF_TRUMPION) || 4950 (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
4855 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) { 4951 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
4856 tempah |= 0x30; 4952 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
4857 } 4953 tempah |= 0x30;
4858 } 4954 }
4859 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 4955 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
4860 if(HwInfo->jChipType >= SIS_315H) { 4956 (SiS_Pr->SiS_IF_DEF_DSTN) ) {
4861 tempah >>= 3; 4957 tempah &= ~0xc0;
4862 tempah &= 0x18; 4958 }
4863 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah); 4959 }
4864 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */ 4960 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
4865 } else { 4961 if(SiS_Pr->ChipType >= SIS_315H) {
4866 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0); 4962 tempah >>= 3;
4867 } 4963 tempah &= 0x18;
4868 } else { 4964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
4869 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 4965 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
4870 } 4966 } else {
4967 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
4968 }
4969 } else {
4970 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4971 }
4871 4972
4872 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 4973 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
4873 4974
4874 if(HwInfo->jChipType < SIS_315H) { 4975 if(SiS_Pr->ChipType < SIS_315H) {
4875 4976
4876#ifdef SIS300 /* ---- 300 series --- */ 4977#ifdef SIS300 /* ---- 300 series --- */
4877 4978
4878 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */ 4979 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
4879 4980
4880 tempah = infoflag >> 8; 4981 tempah = infoflag >> 8;
4881 tempbl = 0; 4982 tempbl = 0;
4882 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 4983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4883 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 4984 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4884 tempah = SiS_Pr->SiS_LCDInfo; 4985 tempah = SiS_Pr->SiS_LCDInfo;
4885 tempbl = (tempah >> 6) & 0x03; 4986 tempbl = (tempah >> 6) & 0x03;
4886 } 4987 }
4887 } 4988 }
4888 tempah &= 0xC0; 4989 tempah &= 0xC0;
4889 tempah |= 0x20; 4990 tempah |= 0x20;
4890 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 4991 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4891 tempah |= 0xc0; 4992 tempah |= 0xc0;
4892 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 4993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4893 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 4994 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
4894 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 4995 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4895 } 4996 }
4896 4997
4897 } else { /* 630 - 301 */ 4998 } else { /* 630 - 301 */
4898 4999
4899 tempah = infoflag >> 8; 5000 tempah = ((infoflag >> 8) & 0xc0) | 0x20;
4900 tempah &= 0xC0; 5001 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4901 tempah |= 0x20; 5002 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4902 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4903 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4904 5003
4905 } 5004 }
4906 5005
4907#endif /* SIS300 */ 5006#endif /* SIS300 */
4908 5007
4909 } else { 5008 } else {
4910 5009
4911#ifdef SIS315H /* ------- 315 series ------ */ 5010#ifdef SIS315H /* ------- 315 series ------ */
4912 5011
4913 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */ 5012 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
4914 5013
4915 tempbl = 0; 5014 tempbl = 0;
4916 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && 5015 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
4917 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5016 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
4918 tempah = infoflag >> 8; 5017 tempah = infoflag >> 8;
4919 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5018 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4920 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6); 5019 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
4921 } 5020 }
4922 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) && 5021 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
4923 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) { 5022 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
4924 tempah = infoflag >> 8; 5023 tempah = infoflag >> 8;
4925 tempbl = 0x03; 5024 tempbl = 0x03;
4926 } else { 5025 } else {
4927 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 5026 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
4928 tempbl = (tempah >> 6) & 0x03; 5027 tempbl = (tempah >> 6) & 0x03;
4929 tempbl |= 0x08; 5028 tempbl |= 0x08;
4930 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04; 5029 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
4931 } 5030 }
4932 tempah &= 0xC0; 5031 tempah &= 0xC0;
4933 tempah |= 0x20; 5032 tempah |= 0x20;
4934 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5033 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0; 5034 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
4936 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5035 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4937 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 5036 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4938 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5037 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4939 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5038 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4940 } 5039 }
4941 } 5040 }
4942 5041
4943 } else { /* 315 - TMDS */ 5042 } else { /* 315 - TMDS */
4944 5043
4945 tempah = tempbl = infoflag >> 8; 5044 tempah = tempbl = infoflag >> 8;
4946 if(!SiS_Pr->UseCustomMode) { 5045 if(!SiS_Pr->UseCustomMode) {
4947 tempbl = 0; 5046 tempbl = 0;
4948 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5047 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4949 if(ModeNo <= 0x13) { 5048 if(ModeNo <= 0x13) {
4950 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5049 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
4951 } 5050 }
4952 } 5051 }
4953 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5052 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
4954 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5053 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
4955 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5054 if(SiS_Pr->SiS_LCDInfo & LCDSync) {
4956 tempah = SiS_Pr->SiS_LCDInfo; 5055 tempah = SiS_Pr->SiS_LCDInfo;
4957 tempbl = (tempah >> 6) & 0x03; 5056 tempbl = (tempah >> 6) & 0x03;
4958 } 5057 }
4959 } 5058 }
4960 } 5059 }
4961 } 5060 }
4962 tempah &= 0xC0; 5061 tempah &= 0xC0;
4963 tempah |= 0x20; 5062 tempah |= 0x20;
4964 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5063 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
4965 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 5064 if(SiS_Pr->SiS_VBType & VB_NoLCD) {
4966 /* Imitate BIOS bug */ 5065 /* Imitate BIOS bug */
4967 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0; 5066 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
4968 } 5067 }
4969 if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5068 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
4970 tempah >>= 3; 5069 tempah >>= 3;
4971 tempah &= 0x18; 5070 tempah &= 0x18;
4972 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah); 5071 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
4973 } else { 5072 } else {
4974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5073 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
4975 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 5074 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
4976 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5075 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
4977 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5076 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
4978 } 5077 }
4979 } 5078 }
4980 } 5079 }
4981 5080
4982 } 5081 }
4983#endif /* SIS315H */ 5082#endif /* SIS315H */
4984 } 5083 }
4985 } 5084 }
4986} 5085}
4987 5086
4988/* Set CRT2 FIFO on 300/630/730 */ 5087/* Set CRT2 FIFO on 300/540/630/730 */
4989#ifdef SIS300 5088#ifdef SIS300
4990static void 5089static void
4991SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo, 5090SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
4992 PSIS_HW_INFO HwInfo) 5091{
4993{ 5092 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
4994 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 5093 unsigned short temp, index, modeidindex, refreshratetableindex;
4995 USHORT temp,index; 5094 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
4996 USHORT modeidindex,refreshratetableindex; 5095 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
4997 USHORT VCLK=0,MCLK,colorth=0,data2=0; 5096 unsigned int data, pci50, pciA0;
4998 USHORT tempal, tempah, tempbx, tempcl, tempax; 5097 static const unsigned char colortharray[] = {
4999 USHORT CRT1ModeNo,CRT2ModeNo; 5098 1, 1, 2, 2, 3, 4
5000 USHORT SelectRate_backup;
5001 ULONG data,eax;
5002 const UCHAR LatencyFactor[] = {
5003 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
5004 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
5005 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
5006 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
5007 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
5008 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
5009 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
5010 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
5011 };
5012 const UCHAR LatencyFactor730[] = {
5013 69, 63, 61,
5014 86, 79, 77,
5015 103, 96, 94,
5016 120,113,111,
5017 137,130,128, /* <-- last entry, data below */
5018 137,130,128, /* to avoid using illegal values */
5019 137,130,128,
5020 137,130,128,
5021 137,130,128,
5022 137,130,128,
5023 137,130,128,
5024 137,130,128,
5025 137,130,128,
5026 137,130,128,
5027 137,130,128,
5028 137,130,128,
5029 };
5030 const UCHAR ThLowB[] = {
5031 81, 4, 72, 6, 88, 8,120,12,
5032 55, 4, 54, 6, 66, 8, 90,12,
5033 42, 4, 45, 6, 55, 8, 75,12
5034 };
5035 const UCHAR ThTiming[] = {
5036 1, 2, 2, 3, 0, 1, 1, 2
5037 }; 5099 };
5038 5100
5039 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; 5101 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
@@ -5044,232 +5106,159 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
5044 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex); 5106 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
5045 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 5107 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
5046 SiS_Pr->SiS_SelectCRT2Rate = 0; 5108 SiS_Pr->SiS_SelectCRT2Rate = 0;
5047 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo); 5109 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
5048 5110
5049 if(CRT1ModeNo >= 0x13) { 5111 if(CRT1ModeNo >= 0x13) {
5050 index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK; 5112 /* Get VCLK */
5051 index &= 0x3F; 5113 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
5052 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */ 5114 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5053 5115
5054 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */ 5116 /* Get colordepth */
5055 colorth >>= 1; 5117 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
5056 if(!colorth) colorth++; 5118 if(!colorth) colorth++;
5057 } 5119 }
5058 5120
5059 } else { 5121 } else {
5060 5122
5061 CRT1ModeNo = 0xfe; 5123 CRT1ModeNo = 0xfe;
5062 VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */ 5124
5063 data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2; 5125 /* Get VCLK */
5064 switch(data2) { /* Get color depth */ 5126 VCLK = SiS_Pr->CSRClock_CRT1;
5065 case 0 : colorth = 1; break; 5127
5066 case 1 : colorth = 1; break; 5128 /* Get color depth */
5067 case 2 : colorth = 2; break; 5129 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
5068 case 3 : colorth = 2; break;
5069 case 4 : colorth = 3; break;
5070 case 5 : colorth = 4; break;
5071 default: colorth = 2;
5072 }
5073 5130
5074 } 5131 }
5075 5132
5076 if(CRT1ModeNo >= 0x13) { 5133 if(CRT1ModeNo >= 0x13) {
5077 if(HwInfo->jChipType == SIS_300) { 5134 /* Get MCLK */
5078 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A); 5135 if(SiS_Pr->ChipType == SIS_300) {
5079 } else { 5136 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
5080 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A); 5137 } else {
5081 } 5138 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
5082 index &= 0x07; 5139 }
5083 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */ 5140 index &= 0x07;
5141 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
5084 5142
5085 data2 = (colorth * VCLK) / MCLK; 5143 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
5144 if(!temp) temp++;
5145 temp <<= 2;
5086 5146
5087 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14); 5147 data2 = temp - ((colorth * VCLK) / MCLK);
5088 temp = ((temp & 0x00FF) >> 6) << 1;
5089 if(temp == 0) temp = 1;
5090 temp <<= 2;
5091 temp &= 0xff;
5092 5148
5093 data2 = temp - data2; 5149 temp = (28 * 16) % data2;
5150 data2 = (28 * 16) / data2;
5151 if(temp) data2++;
5094 5152
5095 if((28 * 16) % data2) { 5153 if(SiS_Pr->ChipType == SIS_300) {
5096 data2 = (28 * 16) / data2;
5097 data2++;
5098 } else {
5099 data2 = (28 * 16) / data2;
5100 }
5101 5154
5102 if(HwInfo->jChipType == SIS_300) { 5155 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
5103 5156 data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
5104 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18); 5157
5105 tempah &= 0x62; 5158 } else {
5106 tempah >>= 1; 5159
5107 tempal = tempah; 5160#ifdef SIS_LINUX_KERNEL
5108 tempah >>= 3; 5161 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
5109 tempal |= tempah; 5162 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
5110 tempal &= 0x07;
5111 tempcl = ThTiming[tempal];
5112 tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
5113 tempbx >>= 6;
5114 tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5115 tempah >>= 4;
5116 tempah &= 0x0c;
5117 tempbx |= tempah;
5118 tempbx <<= 1;
5119 tempal = ThLowB[tempbx + 1];
5120 tempal *= tempcl;
5121 tempal += ThLowB[tempbx];
5122 data = tempal;
5123
5124 } else if(HwInfo->jChipType == SIS_730) {
5125
5126#ifdef LINUX_KERNEL
5127 SiS_SetRegLong(0xcf8,0x80000050);
5128 eax = SiS_GetRegLong(0xcfc);
5129#else 5163#else
5130 eax = pciReadLong(0x00000000, 0x50); 5164 pci50 = pciReadLong(0x00000000, 0x50);
5165 pciA0 = pciReadLong(0x00000000, 0xA0);
5131#endif 5166#endif
5132 tempal = (USHORT)(eax >> 8);
5133 tempal &= 0x06;
5134 tempal <<= 5;
5135 5167
5136#ifdef LINUX_KERNEL 5168 if(SiS_Pr->ChipType == SIS_730) {
5137 SiS_SetRegLong(0xcf8,0x800000A0);
5138 eax = SiS_GetRegLong(0xcfc);
5139#else
5140 eax = pciReadLong(0x00000000, 0xA0);
5141#endif
5142 temp = (USHORT)(eax >> 28);
5143 temp &= 0x0F;
5144 tempal |= temp;
5145
5146 tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5147 tempbx = 0; /* -- do it like the BIOS anyway... */
5148 tempax = tempbx;
5149 tempbx &= 0xc0;
5150 tempbx >>= 6;
5151 tempax &= 0x0f;
5152 tempax *= 3;
5153 tempbx += tempax;
5154
5155 data = LatencyFactor730[tempbx];
5156 data += 15;
5157 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5158 if(!(temp & 0x80)) data += 5;
5159 5169
5160 } else { 5170 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
5171 index += (unsigned short)(((pci50 >> 9)) & 0x03);
5161 5172
5162 index = 0; 5173 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
5163 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14); 5174 index = 0; /* -- do it like the BIOS anyway... */
5164 if(temp & 0x0080) index += 12;
5165 5175
5166#ifdef LINUX_KERNEL 5176 } else {
5167 SiS_SetRegLong(0xcf8,0x800000A0);
5168 eax = SiS_GetRegLong(0xcfc);
5169#else
5170 /* We use pci functions X offers. We use tag 0, because
5171 * we want to read/write to the host bridge (which is always
5172 * 00:00.0 on 630, 730 and 540), not the VGA device.
5173 */
5174 eax = pciReadLong(0x00000000, 0xA0);
5175#endif
5176 temp = (USHORT)(eax >> 24);
5177 if(!(temp&0x01)) index += 24;
5178
5179#ifdef LINUX_KERNEL
5180 SiS_SetRegLong(0xcf8,0x80000050);
5181 eax = SiS_GetRegLong(0xcfc);
5182#else
5183 eax = pciReadLong(0x00000000, 0x50);
5184#endif
5185 temp=(USHORT)(eax >> 24);
5186 if(temp & 0x01) index += 6;
5187 5177
5188 temp = (temp & 0x0F) >> 1; 5178 pci50 >>= 24;
5189 index += temp; 5179 pciA0 >>= 24;
5190 5180
5191 data = LatencyFactor[index]; 5181 index = (pci50 >> 1) & 0x07;
5192 data += 15;
5193 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
5194 if(!(temp & 0x80)) data += 5;
5195 }
5196 5182
5197 data += data2; /* CRT1 Request Period */ 5183 if(pci50 & 0x01) index += 6;
5184 if(!(pciA0 & 0x01)) index += 24;
5198 5185
5199 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5186 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
5200 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5201 5187
5202 if(!SiS_Pr->UseCustomMode) { 5188 }
5203 5189
5204 CRT2ModeNo = ModeNo; 5190 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
5205 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex); 5191 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
5206 5192
5207 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo); 5193 }
5208 5194
5209 index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex, 5195 data += data2; /* CRT1 Request Period */
5210 refreshratetableindex,HwInfo);
5211 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
5212 5196
5213 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5197 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5214 if(SiS_Pr->SiS_UseROM) { 5198 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5215 if(ROMAddr[0x220] & 0x01) {
5216 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5217 }
5218 }
5219 }
5220 5199
5221 } else { 5200 if(!SiS_Pr->UseCustomMode) {
5222 5201
5223 CRT2ModeNo = 0xfe; 5202 CRT2ModeNo = ModeNo;
5224 VCLK = SiS_Pr->CSRClock; /* Get VCLK */ 5203 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
5225 5204
5226 } 5205 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
5227 5206
5228 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */ 5207 /* Get VCLK */
5229 colorth >>= 1; 5208 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
5230 if(!colorth) colorth++; 5209 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
5231 5210
5232 data = data * VCLK * colorth; 5211 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
5233 if(data % (MCLK << 4)) { 5212 if(SiS_Pr->SiS_UseROM) {
5234 data = data / (MCLK << 4); 5213 if(ROMAddr[0x220] & 0x01) {
5235 data++; 5214 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
5236 } else { 5215 }
5237 data = data / (MCLK << 4); 5216 }
5238 } 5217 }
5239 5218
5240 if(data <= 6) data = 6; 5219 } else {
5241 if(data > 0x14) data = 0x14;
5242 5220
5243 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01); 5221 /* Get VCLK */
5244 if(HwInfo->jChipType == SIS_300) { 5222 CRT2ModeNo = 0xfe;
5245 if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13; 5223 VCLK = SiS_Pr->CSRClock;
5246 else temp = (temp & (~0x1F)) | 0x16;
5247 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
5248 temp = (temp & (~0x1F)) | 0x13;
5249 }
5250 } else {
5251 if( ( (HwInfo->jChipType == SIS_630) ||
5252 (HwInfo->jChipType == SIS_730) ) &&
5253 (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
5254 {
5255 temp = (temp & (~0x1F)) | 0x1b;
5256 } else {
5257 temp = (temp & (~0x1F)) | 0x16;
5258 }
5259 }
5260 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5261 5224
5262 if( (HwInfo->jChipType == SIS_630) && 5225 }
5263 (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */ 5226
5264 { 5227 /* Get colordepth */
5265 if(data > 0x13) data = 0x13; 5228 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
5266 } 5229 if(!colorth) colorth++;
5267 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data); 5230
5231 data = data * VCLK * colorth;
5232 temp = data % (MCLK << 4);
5233 data = data / (MCLK << 4);
5234 if(temp) data++;
5235
5236 if(data < 6) data = 6;
5237 else if(data > 0x14) data = 0x14;
5238
5239 if(SiS_Pr->ChipType == SIS_300) {
5240 temp = 0x16;
5241 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
5242 temp = 0x13;
5243 } else {
5244 temp = 0x16;
5245 if(( (SiS_Pr->ChipType == SIS_630) ||
5246 (SiS_Pr->ChipType == SIS_730) ) &&
5247 (SiS_Pr->ChipRevision >= 0x30))
5248 temp = 0x1b;
5249 }
5250 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
5251
5252 if((SiS_Pr->ChipType == SIS_630) &&
5253 (SiS_Pr->ChipRevision >= 0x30)) {
5254 if(data > 0x13) data = 0x13;
5255 }
5256 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
5268 5257
5269 } else { /* If mode <= 0x13, we just restore everything */ 5258 } else { /* If mode <= 0x13, we just restore everything */
5270 5259
5271 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5260 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
5272 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5261 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
5273 5262
5274 } 5263 }
5275} 5264}
@@ -5278,10 +5267,10 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
5278/* Set CRT2 FIFO on 315/330 series */ 5267/* Set CRT2 FIFO on 315/330 series */
5279#ifdef SIS315H 5268#ifdef SIS315H
5280static void 5269static void
5281SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 5270SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
5282{ 5271{
5283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B); 5272 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
5284 if( (HwInfo->jChipType == SIS_760) && 5273 if( (SiS_Pr->ChipType == SIS_760) &&
5285 (SiS_Pr->SiS_SysFlags & SF_760LFB) && 5274 (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
5286 (SiS_Pr->SiS_ModeType == Mode32Bpp) && 5275 (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
5287 (SiS_Pr->SiS_VGAHDE >= 1280) && 5276 (SiS_Pr->SiS_VGAHDE >= 1280) &&
@@ -5299,337 +5288,162 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
5299} 5288}
5300#endif 5289#endif
5301 5290
5302static USHORT 5291static unsigned short
5303SiS_GetVGAHT2(SiS_Private *SiS_Pr) 5292SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
5304{ 5293{
5305 ULONG tempax,tempbx; 5294 unsigned int tempax,tempbx;
5306 5295
5307 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX; 5296 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
5308 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT; 5297 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
5309 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx; 5298 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
5310 return((USHORT)tempax); 5299 return (unsigned short)tempax;
5311} 5300}
5312 5301
5313/* Set Part 1 / SiS bridge slave mode */ 5302/* Set Part 1 / SiS bridge slave mode */
5314static void 5303static void
5315SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex, 5304SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
5316 PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex) 5305 unsigned short RefreshRateTableIndex)
5317{ 5306{
5318 USHORT push1,push2; 5307 unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
5319 USHORT tempax,tempbx,tempcx,temp; 5308 static const unsigned short CRTranslation[] = {
5320 USHORT resinfo,modeflag,xres=0; 5309 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
5321 unsigned char p1_7, p1_8; 5310 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
5311 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
5312 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
5313 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
5314 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
5315 };
5322 5316
5323 if(ModeNo <= 0x13) { 5317 if(ModeNo <= 0x13) {
5324 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5318 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
5325 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
5326 } else if(SiS_Pr->UseCustomMode) { 5319 } else if(SiS_Pr->UseCustomMode) {
5327 modeflag = SiS_Pr->CModeFlag; 5320 modeflag = SiS_Pr->CModeFlag;
5328 resinfo = 0;
5329 xres = SiS_Pr->CHDisplay; 5321 xres = SiS_Pr->CHDisplay;
5330 } else { 5322 } else {
5331 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5323 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5332 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5333 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes; 5324 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
5334 } 5325 }
5335 5326
5336 /* The following is only done if bridge is in slave mode: */ 5327 /* The following is only done if bridge is in slave mode: */
5337 5328
5338 if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) { 5329 if(SiS_Pr->ChipType >= SIS_315H) {
5339 if(xres >= 1600) { 5330 if(xres >= 1600) { /* BIOS: == 1600 */
5340 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04); 5331 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
5341 } 5332 }
5342 } 5333 }
5343 5334
5344 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */ 5335 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
5345
5346 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
5347 5336
5348 if(modeflag & Charx8Dot) tempcx = 0x08; 5337 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
5349 else tempcx = 0x09; 5338 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
5350
5351 tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
5352 if(modeflag & HalfDCLK) tempax >>= 1;
5353 tempax = ((tempax / tempcx) - 1) & 0xff;
5354 tempbx = tempax;
5355
5356 temp = tempax;
5357 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
5358 5339
5340 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
5359 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5341 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5360 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { 5342 SiS_Pr->CHBlankStart += 16;
5361 temp += 2;
5362 }
5363 }
5364 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5365 if(resinfo == SIS_RI_800x600) temp -= 2;
5366 }
5367 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
5368
5369 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
5370
5371 tempax = 0xFFFF;
5372 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
5373 if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
5374 if(modeflag & HalfDCLK) tempax >>= 1;
5375 tempax = (tempax / tempcx) - 5;
5376 tempcx = tempax;
5377
5378 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
5379 temp = tempcx - 1;
5380 if(!(modeflag & HalfDCLK)) {
5381 temp -= 6;
5382 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5383 temp -= 2;
5384 if(ModeNo > 0x13) temp -= 10;
5385 }
5386 }
5387 } else {
5388 tempcx = (tempcx + tempbx) >> 1;
5389 temp = (tempcx & 0x00FF) + 2;
5390 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5391 temp--;
5392 if(!(modeflag & HalfDCLK)) {
5393 if((modeflag & Charx8Dot)) {
5394 temp += 4;
5395 if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
5396 if(HwInfo->jChipType >= SIS_315H) {
5397 if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
5398 }
5399 }
5400 }
5401 } else {
5402 if(!(modeflag & HalfDCLK)) {
5403 temp -= 4;
5404 if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
5405 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
5406 if(SiS_Pr->SiS_VGAHDE >= 800) {
5407 temp -= 7;
5408 if(HwInfo->jChipType < SIS_315H) {
5409 if(SiS_Pr->SiS_ModeType == ModeEGA) {
5410 if(SiS_Pr->SiS_VGAVDE == 1024) {
5411 temp += 15;
5412 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
5413 temp += 7;
5414 }
5415 }
5416 }
5417 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5418 if(SiS_Pr->SiS_VGAHDE >= 1280) {
5419 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
5420 }
5421 }
5422 }
5423 }
5424 }
5425 }
5426 } 5343 }
5427 5344
5428 p1_7 = temp; 5345 SiS_Pr->CHBlankEnd = 32;
5429 p1_8 = 0x00; 5346 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5430 5347 if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
5431 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
5432 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5433 if(ModeNo <= 0x01) {
5434 p1_7 = 0x2a;
5435 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
5436 else p1_8 = 0x41;
5437 } else if(SiS_Pr->SiS_ModeType == ModeText) {
5438 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
5439 else p1_7 = 0x55;
5440 p1_8 = 0x00;
5441 } else if(ModeNo <= 0x13) {
5442 if(modeflag & HalfDCLK) {
5443 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5444 p1_7 = 0x30;
5445 p1_8 = 0x03;
5446 } else {
5447 p1_7 = 0x2f;
5448 p1_8 = 0x02;
5449 }
5450 } else {
5451 p1_7 = 0x5b;
5452 p1_8 = 0x03;
5453 }
5454 } else if( ((HwInfo->jChipType >= SIS_315H) &&
5455 ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
5456 ((HwInfo->jChipType < SIS_315H) &&
5457 (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
5458 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
5459 p1_7 = 0x30,
5460 p1_8 = 0x03;
5461 } else {
5462 p1_7 = 0x2f;
5463 p1_8 = 0x03;
5464 }
5465 }
5466 }
5467 } 5348 }
5468 5349
5469 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 5350 temp = SiS_Pr->SiS_VGAHT - 96;
5470 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) { 5351 if(!(modeflag & HalfDCLK)) temp -= 32;
5471 p1_7 = 0x63; 5352 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
5472 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55; 5353 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
5473 } 5354 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
5474 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 5355 temp -= 3;
5475 if(!(modeflag & HalfDCLK)) { 5356 temp <<= 3;
5476 p1_7 = 0xb2; 5357 } else {
5477 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 5358 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
5478 p1_7 = 0xab;
5479 }
5480 }
5481 } else {
5482 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
5483 if(modeflag & HalfDCLK) p1_7 = 0x30;
5484 }
5485 }
5486 } 5359 }
5360 SiS_Pr->CHSyncStart = temp;
5487 5361
5488 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */ 5362 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
5489 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
5490 5363
5491 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */ 5364 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
5492 5365
5493 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0); 5366 VGAVDE = SiS_Pr->SiS_VGAVDE;
5367 if (VGAVDE == 357) VGAVDE = 350;
5368 else if(VGAVDE == 360) VGAVDE = 350;
5369 else if(VGAVDE == 375) VGAVDE = 350;
5370 else if(VGAVDE == 405) VGAVDE = 400;
5371 else if(VGAVDE == 420) VGAVDE = 400;
5372 else if(VGAVDE == 525) VGAVDE = 480;
5373 else if(VGAVDE == 1056) VGAVDE = 1024;
5374 SiS_Pr->CVDisplay = VGAVDE;
5494 5375
5495 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */ 5376 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
5496 5377
5497 tempcx = 0x121; 5378 SiS_Pr->CVBlankEnd = 1;
5498 tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */ 5379 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
5499 if (tempbx == 357) tempbx = 350;
5500 else if(tempbx == 360) tempbx = 350;
5501 else if(tempbx == 375) tempbx = 350;
5502 else if(tempbx == 405) tempbx = 400;
5503 else if(tempbx == 420) tempbx = 400;
5504 else if(tempbx == 525) tempbx = 480;
5505 push2 = tempbx;
5506 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
5507 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5508 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
5509 if (tempbx == 350) tempbx += 5;
5510 else if(tempbx == 480) tempbx += 5;
5511 }
5512 }
5513 }
5514 tempbx -= 2;
5515 temp = tempbx & 0x00FF;
5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
5517
5518 tempbx = push2;
5519 tempbx--;
5520 temp = tempbx & 0x00FF;
5521#if 0
5522 /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
5523 if(xxx()) {
5524 if(temp == 0xdf) temp = 0xda;
5525 }
5526#endif
5527 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
5528
5529 temp = 0;
5530 if(modeflag & DoubleScanMode) temp |= 0x80;
5531 if(HwInfo->jChipType >= SIS_661) {
5532 if(tempbx & 0x0200) temp |= 0x20;
5533 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
5534 if(tempbx & 0x0100) tempcx |= 0x000a;
5535 if(tempbx & 0x0400) tempcx |= 0x1200;
5536 } else {
5537 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
5538 if(tempbx & 0x0100) tempcx |= 0x0002;
5539 if(tempbx & 0x0400) tempcx |= 0x0600;
5540 }
5541 5380
5542 if(tempbx & 0x0200) tempcx |= 0x0040; 5381 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
5382 SiS_Pr->CVSyncStart = VGAVDE + temp;
5543 5383
5544 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */ 5384 temp >>= 3;
5385 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
5545 5386
5546 tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2; 5387 SiS_CalcCRRegisters(SiS_Pr, 0);
5388 SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
5547 5389
5548 if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) { 5390 for(i = 0; i <= 7; i++) {
5549 if(resinfo != SIS_RI_1280x1024) { 5391 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
5550 tempbx += (tempax << 1);
5551 }
5552 } else if(HwInfo->jChipType >= SIS_315H) {
5553 if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
5554 tempbx += (tempax << 1);
5555 }
5556 } 5392 }
5557 5393 for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
5558 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 5394 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5559 tempbx -= 10;
5560 } else {
5561 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
5562 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5563 tempbx += 40;
5564 if(HwInfo->jChipType >= SIS_315H) {
5565 if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
5566 }
5567 }
5568 }
5569 }
5570 tempax >>= 2;
5571 tempax++;
5572 tempax += tempbx;
5573 push1 = tempax;
5574 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
5575 if(tempbx <= 513) {
5576 if(tempax >= 513) tempbx = 513;
5577 }
5578 } 5395 }
5579 temp = tempbx & 0x00FF; 5396 for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
5580 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */ 5397 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5581
5582 tempbx--;
5583 temp = tempbx & 0x00FF;
5584 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
5585
5586 if(tempbx & 0x0100) tempcx |= 0x0008;
5587
5588 if(tempbx & 0x0200) {
5589 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
5590 } 5398 }
5591 tempbx++; 5399 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
5592 5400 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
5593 if(tempbx & 0x0100) tempcx |= 0x0004;
5594 if(tempbx & 0x0200) tempcx |= 0x0080;
5595 if(tempbx & 0x0400) {
5596 if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
5597 else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
5598 else tempcx |= 0x0C00;
5599 } 5401 }
5600 5402
5601 tempbx = push1; 5403 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
5602 temp = tempbx & 0x000F; 5404 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
5603 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
5604
5605 if(tempbx & 0x0010) tempcx |= 0x2000;
5606
5607 temp = tempcx & 0x00FF;
5608 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
5609
5610 temp = (tempcx & 0xFF00) >> 8;
5611 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
5612 5405
5613 tempax = modeflag; 5406 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
5614 temp = (tempax & 0xFF00) >> 8; 5407 if(modeflag & DoubleScanMode) temp |= 0x80;
5615 temp = (temp >> 1) & 0x09; 5408 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
5616 if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
5617 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
5618 5409
5619 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */ 5410 temp = 0;
5411 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
5412 if(modeflag & HalfDCLK) temp |= 0x08;
5413 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
5620 5414
5621 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */ 5415 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
5416 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
5622 5417
5623 temp = 0x00; 5418 temp = 0;
5624 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5419 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5625 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { 5420 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
5626 temp = 0x80;
5627 }
5628 } 5421 }
5629 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */ 5422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
5630 5423
5631 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5424 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
5632 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); 5425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
5426
5427#ifdef SIS_XORG_XF86
5428#ifdef TWDEBUG
5429 xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
5430 SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
5431 SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
5432 SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
5433
5434 xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5435 SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
5436 SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
5437 SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
5438 SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
5439 xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
5440 SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
5441 SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
5442 SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
5443 SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
5444 xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
5445#endif
5446#endif
5633} 5447}
5634 5448
5635/* Setup panel link 5449/* Setup panel link
@@ -5637,18 +5451,18 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
5637 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA 5451 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
5638 */ 5452 */
5639static void 5453static void
5640SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 5454SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
5641 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex) 5455 unsigned short RefreshRateTableIndex)
5642{ 5456{
5643 USHORT modeflag,resinfo; 5457 unsigned short modeflag, resinfo = 0;
5644 USHORT push2,tempax,tempbx,tempcx,temp; 5458 unsigned short push2, tempax, tempbx, tempcx, temp;
5645 ULONG tempeax=0,tempebx,tempecx,tempvcfact=0; 5459 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
5646 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE; 5460 BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
5647#ifdef SIS300 5461#ifdef SIS300
5648 USHORT crt2crtc; 5462 unsigned short crt2crtc = 0;
5649#endif 5463#endif
5650#ifdef SIS315H 5464#ifdef SIS315H
5651 USHORT pushcx; 5465 unsigned short pushcx;
5652#endif 5466#endif
5653 5467
5654 if(ModeNo <= 0x13) { 5468 if(ModeNo <= 0x13) {
@@ -5659,15 +5473,11 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5659#endif 5473#endif
5660 } else if(SiS_Pr->UseCustomMode) { 5474 } else if(SiS_Pr->UseCustomMode) {
5661 modeflag = SiS_Pr->CModeFlag; 5475 modeflag = SiS_Pr->CModeFlag;
5662 resinfo = 0;
5663#ifdef SIS300
5664 crt2crtc = 0;
5665#endif
5666 } else { 5476 } else {
5667 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5477 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
5668 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 5478 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
5669#ifdef SIS300 5479#ifdef SIS300
5670 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 5480 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
5671#endif 5481#endif
5672 } 5482 }
5673 5483
@@ -5681,14 +5491,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5681 issis = TRUE; 5491 issis = TRUE;
5682 } 5492 }
5683 5493
5684 if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) { 5494 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
5685 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { 5495 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
5686 chkdclkfirst = TRUE; 5496 chkdclkfirst = TRUE;
5687 } 5497 }
5688 } 5498 }
5689 5499
5690#ifdef SIS315H 5500#ifdef SIS315H
5691 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 5501 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
5692 if(IS_SIS330) { 5502 if(IS_SIS330) {
5693 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5503 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
5694 } else if(IS_SIS740) { 5504 } else if(IS_SIS740) {
@@ -5704,7 +5514,7 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5704 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); 5514 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
5705 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5515 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
5706 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); 5516 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
5707 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 5517 if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
5708 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) || 5518 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
5709 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5519 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
5710 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20); 5520 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
@@ -5720,10 +5530,10 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5720 tempax = SiS_Pr->SiS_LCDHDES; 5530 tempax = SiS_Pr->SiS_LCDHDES;
5721 if(islvds) { 5531 if(islvds) {
5722 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5532 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5723 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { 5533 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
5724 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) && 5534 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
5725 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 5535 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
5726 tempax -= 8; 5536 tempax -= 8;
5727 } 5537 }
5728 } 5538 }
5729 } 5539 }
@@ -5736,13 +5546,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5736 5546
5737 tempbx = SiS_Pr->SiS_HDE; 5547 tempbx = SiS_Pr->SiS_HDE;
5738 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5548 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5739 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
5740 (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
5741 tempbx >>= 1;
5742 }
5743 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5549 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5744 tempbx = SiS_Pr->PanelXRes; 5550 tempbx = SiS_Pr->PanelXRes;
5745 } 5551 }
5552 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
5553 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
5554 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
5555 tempbx >>= 1;
5556 }
5746 } 5557 }
5747 5558
5748 tempax += tempbx; 5559 tempax += tempbx;
@@ -5767,25 +5578,25 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5767 temp = (tempcx >> 3) & 0x00FF; 5578 temp = (tempcx >> 3) & 0x00FF;
5768 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5579 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5769 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5580 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5770 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5581 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5771 switch(ModeNo) { 5582 switch(ModeNo) {
5772 case 0x04: 5583 case 0x04:
5773 case 0x05: 5584 case 0x05:
5774 case 0x0d: temp = 0x56; break; 5585 case 0x0d: temp = 0x56; break;
5775 case 0x10: temp = 0x60; break; 5586 case 0x10: temp = 0x60; break;
5776 case 0x13: temp = 0x5f; break; 5587 case 0x13: temp = 0x5f; break;
5777 case 0x40: 5588 case 0x40:
5778 case 0x41: 5589 case 0x41:
5779 case 0x4f: 5590 case 0x4f:
5780 case 0x43: 5591 case 0x43:
5781 case 0x44: 5592 case 0x44:
5782 case 0x62: 5593 case 0x62:
5783 case 0x56: 5594 case 0x56:
5784 case 0x53: 5595 case 0x53:
5785 case 0x5d: 5596 case 0x5d:
5786 case 0x5e: temp = 0x54; break; 5597 case 0x5e: temp = 0x54; break;
5787 } 5598 }
5788 } 5599 }
5789 } 5600 }
5790 } 5601 }
5791 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */ 5602 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
@@ -5793,12 +5604,12 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5793 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5604 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5794 temp += 2; 5605 temp += 2;
5795 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5606 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5796 temp += 8; 5607 temp += 8;
5797 if(SiS_Pr->PanelHRE != 999) { 5608 if(SiS_Pr->PanelHRE != 999) {
5798 temp = tempcx + SiS_Pr->PanelHRE; 5609 temp = tempcx + SiS_Pr->PanelHRE;
5799 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT; 5610 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
5800 temp >>= 3; 5611 temp >>= 3;
5801 } 5612 }
5802 } 5613 }
5803 } else { 5614 } else {
5804 temp += 10; 5615 temp += 10;
@@ -5806,9 +5617,6 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5806 5617
5807 temp &= 0x1F; 5618 temp &= 0x1F;
5808 temp |= ((tempcx & 0x07) << 5); 5619 temp |= ((tempcx & 0x07) << 5);
5809#if 0
5810 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
5811#endif
5812 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */ 5620 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
5813 5621
5814 /* Vertical */ 5622 /* Vertical */
@@ -5826,9 +5634,9 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5826 push2 = tempbx; 5634 push2 = tempbx;
5827 5635
5828 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; 5636 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
5829 if(HwInfo->jChipType < SIS_315H) { 5637 if(SiS_Pr->ChipType < SIS_315H) {
5830 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5638 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5831 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5639 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
5832 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes; 5640 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
5833 } 5641 }
5834 } 5642 }
@@ -5844,19 +5652,19 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5844 if(issis) tempbx++; 5652 if(issis) tempbx++;
5845 } else { 5653 } else {
5846 tempbx += tempcx; 5654 tempbx += tempcx;
5847 if(HwInfo->jChipType < SIS_315H) tempbx++; 5655 if(SiS_Pr->ChipType < SIS_315H) tempbx++;
5848 else if(issis) tempbx++; 5656 else if(issis) tempbx++;
5849 } 5657 }
5850 5658
5851 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */ 5659 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
5852 5660
5853 temp = tempbx & 0x00FF; 5661 temp = tempbx & 0x00FF;
5854 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5662 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
5855 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5663 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
5856 if(ModeNo == 0x10) temp = 0xa9; 5664 if(ModeNo == 0x10) temp = 0xa9;
5857 } 5665 }
5858 } 5666 }
5859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); 5667 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
5860 5668
5861 tempcx >>= 3; 5669 tempcx >>= 3;
5862 tempcx++; 5670 tempcx++;
@@ -5879,13 +5687,13 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5879 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5687 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
5880 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; 5688 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
5881 tempbx = 0x87; 5689 tempbx = 0x87;
5882 if((HwInfo->jChipType >= SIS_315H) || 5690 if((SiS_Pr->ChipType >= SIS_315H) ||
5883 (HwInfo->jChipRevision >= 0x30)) { 5691 (SiS_Pr->ChipRevision >= 0x30)) {
5884 tempbx = 0x07; 5692 tempbx = 0x07;
5885 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 5693 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
5886 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80; 5694 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
5887 } 5695 }
5888 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */ 5696 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
5889 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5697 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
5890 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5698 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
5891 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80; 5699 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
@@ -5896,59 +5704,58 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5896 } 5704 }
5897 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp); 5705 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
5898 5706
5899 tempbx = push2; /* BPLVDEE */ 5707 tempbx = push2; /* BPLVDEE */
5900 5708
5901 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */ 5709 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
5902 5710
5903 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5711 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
5904 switch(SiS_Pr->SiS_LCDResInfo) { 5712 switch(SiS_Pr->SiS_LCDResInfo) {
5905 case Panel_640x480: 5713 case Panel_640x480:
5906 tempbx = SiS_Pr->SiS_VGAVDE - 1; 5714 tempbx = SiS_Pr->SiS_VGAVDE - 1;
5907 tempcx = SiS_Pr->SiS_VGAVDE; 5715 tempcx = SiS_Pr->SiS_VGAVDE;
5908 break; 5716 break;
5909 case Panel_800x600: 5717 case Panel_800x600:
5910 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5718 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5911 if(resinfo == SIS_RI_800x600) tempcx++; 5719 if(resinfo == SIS_RI_800x600) tempcx++;
5912 } 5720 }
5913 break; 5721 break;
5914 case Panel_1024x600: 5722 case Panel_1024x600:
5915 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5723 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5916 if(resinfo == SIS_RI_1024x600) tempcx++; 5724 if(resinfo == SIS_RI_1024x600) tempcx++;
5917 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 5725 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
5918 if(resinfo == SIS_RI_800x600) tempcx++; 5726 if(resinfo == SIS_RI_800x600) tempcx++;
5919 } 5727 }
5920 } 5728 }
5921 break; 5729 break;
5922 case Panel_1024x768: 5730 case Panel_1024x768:
5923 if(HwInfo->jChipType < SIS_315H) { 5731 if(SiS_Pr->ChipType < SIS_315H) {
5924 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5732 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
5925 if(resinfo == SIS_RI_1024x768) tempcx++; 5733 if(resinfo == SIS_RI_1024x768) tempcx++;
5926 } 5734 }
5927 } 5735 }
5928 break; 5736 break;
5929 } 5737 }
5930 } 5738 }
5931 5739
5932 temp = ((tempbx >> 8) & 0x07) << 3; 5740 temp = ((tempbx >> 8) & 0x07) << 3;
5933 temp = temp | ((tempcx >> 8) & 0x07); 5741 temp |= ((tempcx >> 8) & 0x07);
5934 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); 5742 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
5935 /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
5936 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx); 5743 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
5937 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx); 5744 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
5938 5745
5939 /* Vertical scaling */ 5746 /* Vertical scaling */
5940 5747
5941 if(HwInfo->jChipType < SIS_315H) { 5748 if(SiS_Pr->ChipType < SIS_315H) {
5942 5749
5943#ifdef SIS300 /* 300 series */ 5750#ifdef SIS300 /* 300 series */
5944 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5751 tempeax = SiS_Pr->SiS_VGAVDE << 6;
5945 temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE); 5752 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
5946 tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE; 5753 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
5947 if(temp) tempeax++; 5754 if(temp) tempeax++;
5948 5755
5949 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F; 5756 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
5950 5757
5951 temp = (USHORT)(tempeax & 0x00FF); 5758 temp = (unsigned short)(tempeax & 0x00FF);
5952 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ 5759 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
5953 tempvcfact = temp; 5760 tempvcfact = temp;
5954#endif /* SIS300 */ 5761#endif /* SIS300 */
@@ -5963,20 +5770,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5963 if(temp) tempeax++; 5770 if(temp) tempeax++;
5964 tempvcfact = tempeax; 5771 tempvcfact = tempeax;
5965 5772
5966 temp = (USHORT)(tempeax & 0x00FF); 5773 temp = (unsigned short)(tempeax & 0x00FF);
5967 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp); 5774 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
5968 temp = (USHORT)((tempeax & 0x00FF00) >> 8); 5775 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5969 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp); 5776 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
5970 temp = (USHORT)((tempeax & 0x00030000) >> 16); 5777 temp = (unsigned short)((tempeax & 0x00030000) >> 16);
5971 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; 5778 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp); 5779 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
5973 5780
5974 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) { 5781 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
5975 temp = (USHORT)(tempeax & 0x00FF); 5782 temp = (unsigned short)(tempeax & 0x00FF);
5976 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp); 5783 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
5977 temp = (USHORT)((tempeax & 0x00FF00) >> 8); 5784 temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
5978 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp); 5785 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
5979 temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6); 5786 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
5980 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp); 5787 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
5981 temp = 0; 5788 temp = 0;
5982 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08; 5789 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
@@ -5997,29 +5804,29 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
5997 tempecx = 0xFFFF; 5804 tempecx = 0xFFFF;
5998 } else { 5805 } else {
5999 tempecx = tempebx / SiS_Pr->SiS_HDE; 5806 tempecx = tempebx / SiS_Pr->SiS_HDE;
6000 if(HwInfo->jChipType >= SIS_315H) { 5807 if(SiS_Pr->ChipType >= SIS_315H) {
6001 if(tempebx % SiS_Pr->SiS_HDE) tempecx++; 5808 if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
6002 } 5809 }
6003 } 5810 }
6004 5811
6005 if(HwInfo->jChipType >= SIS_315H) { 5812 if(SiS_Pr->ChipType >= SIS_315H) {
6006 tempeax = (tempebx / tempecx) - 1; 5813 tempeax = (tempebx / tempecx) - 1;
6007 } else { 5814 } else {
6008 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1; 5815 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
6009 } 5816 }
6010 tempecx = (tempecx << 16) | (tempeax & 0xFFFF); 5817 tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
6011 temp = (USHORT)(tempecx & 0x00FF); 5818 temp = (unsigned short)(tempecx & 0x00FF);
6012 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); 5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
6013 5820
6014 if(HwInfo->jChipType >= SIS_315H) { 5821 if(SiS_Pr->ChipType >= SIS_315H) {
6015 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact; 5822 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
6016 tempbx = (USHORT)(tempeax & 0xFFFF); 5823 tempbx = (unsigned short)(tempeax & 0xFFFF);
6017 } else { 5824 } else {
6018 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5825 tempeax = SiS_Pr->SiS_VGAVDE << 6;
6019 tempbx = tempvcfact & 0x3f; 5826 tempbx = tempvcfact & 0x3f;
6020 if(tempbx == 0) tempbx = 64; 5827 if(tempbx == 0) tempbx = 64;
6021 tempeax /= tempbx; 5828 tempeax /= tempbx;
6022 tempbx = (USHORT)(tempeax & 0xFFFF); 5829 tempbx = (unsigned short)(tempeax & 0xFFFF);
6023 } 5830 }
6024 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--; 5831 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
6025 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { 5832 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
@@ -6032,24 +5839,24 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6032 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); 5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
6033 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx); 5840 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
6034 5841
6035 tempecx >>= 16; /* BPLHCFACT */ 5842 tempecx >>= 16; /* BPLHCFACT */
6036 if(!chkdclkfirst) { 5843 if(!chkdclkfirst) {
6037 if(modeflag & HalfDCLK) tempecx >>= 1; 5844 if(modeflag & HalfDCLK) tempecx >>= 1;
6038 } 5845 }
6039 temp = (USHORT)((tempecx & 0xFF00) >> 8); 5846 temp = (unsigned short)((tempecx & 0xFF00) >> 8);
6040 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); 5847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
6041 temp = (USHORT)(tempecx & 0x00FF); 5848 temp = (unsigned short)(tempecx & 0x00FF);
6042 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); 5849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
6043 5850
6044#ifdef SIS315H 5851#ifdef SIS315H
6045 if(HwInfo->jChipType >= SIS_315H) { 5852 if(SiS_Pr->ChipType >= SIS_315H) {
6046 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5853 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6047 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) { 5854 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
6048 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20); 5855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
6049 } 5856 }
6050 } else { 5857 } else {
6051 if(islvds) { 5858 if(islvds) {
6052 if(HwInfo->jChipType == SIS_740) { 5859 if(SiS_Pr->ChipType == SIS_740) {
6053 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 5860 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
6054 } else { 5861 } else {
6055 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23); 5862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
@@ -6061,17 +5868,26 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6061 5868
6062#ifdef SIS300 5869#ifdef SIS300
6063 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5870 if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
6064 int i; 5871 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6065 UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 }; 5872 unsigned char *trumpdata;
6066 UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 }; 5873 int i, j = crt2crtc;
6067 UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 }; 5874 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
5875 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
5876 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
5877
5878 if(SiS_Pr->SiS_UseROM) {
5879 trumpdata = &ROMAddr[0x8001 + (j * 80)];
5880 } else {
5881 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
5882 trumpdata = &SiS300_TrumpionData[j][0];
5883 }
6068 5884
6069 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf); 5885 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
6070 for(i=0; i<5; i++) { 5886 for(i=0; i<5; i++) {
6071 SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]); 5887 SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
6072 } 5888 }
6073 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5889 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
6074 if(ModeNo == 0x13) { 5890 if(ModeNo == 0x13) {
6075 for(i=0; i<4; i++) { 5891 for(i=0; i<4; i++) {
6076 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]); 5892 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
6077 } 5893 }
@@ -6095,67 +5911,66 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6095 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A); 5911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
6096 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B); 5912 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
6097 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03); 5913 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
6098 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */ 5914 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
6099 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 || 5915 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6100 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1; 5916 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5917 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6101 tempax += 64; 5918 tempax += 64;
6102 temp = tempax & 0x00FF; 5919 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
6103 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp); 5920 temp = (tempax >> 8) << 3;
6104 temp = ((tempax & 0xFF00) >> 8) << 3;
6105 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp); 5921 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
6106 tempax += 32; /* Blpe=lBlps+32 */ 5922 tempax += 32; /* Blpe = lBlps+32 */
6107 temp = tempax & 0x00FF; 5923 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
6108 if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0; 5924 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
6109 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp); 5925 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
6110 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
6111 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
6112 5926
6113 tempax = SiS_Pr->SiS_VDE; 5927 tempax = SiS_Pr->SiS_VDE;
6114 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 || 5928 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6115 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1; 5929 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
5930 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6116 tempax >>= 1; 5931 tempax >>= 1;
6117 temp = tempax & 0x00FF; 5932 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
6118 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp); 5933 temp = (tempax >> 8) << 3;
6119 temp = ((tempax & 0xFF00) >> 8) << 3;
6120 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp); 5934 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
6121 5935
6122 tempeax = SiS_Pr->SiS_HDE; 5936 tempeax = SiS_Pr->SiS_HDE;
6123 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 || 5937 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6124 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1; 5938 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6125 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */ 5939 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
6126 tempebx = 128; 5940 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
6127 temp = (USHORT)(tempeax % tempebx); 5941 temp = tempeax & 0x7f;
6128 tempeax = tempeax / tempebx; 5942 tempeax >>= 7;
6129 if(temp) tempeax++; 5943 if(temp) tempeax++;
6130 temp = (USHORT)(tempeax & 0x003F); 5944 temp = tempeax & 0x3f;
6131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp); 5945 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
6132 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */ 5946 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
6133 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00); 5947 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
6134 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10); 5948 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
6135 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00); 5949 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
6136 5950
6137 tempax = SiS_Pr->SiS_HDE; 5951 tempax = SiS_Pr->SiS_HDE;
6138 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 || 5952 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6139 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1; 5953 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6140 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */ 5954 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
5955 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
6141 pushcx = tempax; 5956 pushcx = tempax;
6142 temp = tempax & 0x00FF; 5957 temp = tempax & 0x00FF;
6143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); 5958 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
6144 temp = ((tempax & 0xFF00) >> 8) << 3; 5959 temp = ((tempax & 0xFF00) >> 8) << 3;
6145 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp); 5960 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
6146 5961
6147 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ 5962 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
6148 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 || 5963 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
6149 SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1; 5964 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
6150 tempeax = (tempax * pushcx); 5965 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
6151 tempebx = 0x00100000 + tempeax; 5966 tempeax = tempax * pushcx;
6152 temp = (USHORT)tempebx & 0x000000FF; 5967 temp = tempeax & 0xFF;
6153 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp); 5968 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
6154 temp = (USHORT)((tempebx & 0x0000FF00) >> 8); 5969 temp = (tempeax & 0xFF00) >> 8;
6155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp); 5970 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
6156 temp = (USHORT)((tempebx & 0x00FF0000) >> 16); 5971 temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
6157 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); 5972 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
6158 temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7); 5973 temp = ((tempeax & 0x01000000) >> 24) << 7;
6159 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp); 5974 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
6160 5975
6161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); 5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
@@ -6192,20 +6007,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6192 6007
6193/* Set Part 1 */ 6008/* Set Part 1 */
6194static void 6009static void
6195SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 6010SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6196 PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex) 6011 unsigned short RefreshRateTableIndex)
6197{ 6012{
6198#if defined(SIS300) || defined(SIS315H) 6013#if defined(SIS300) || defined(SIS315H)
6199 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 6014 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
6200#endif 6015#endif
6201 USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; 6016 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
6202 USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0; 6017 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
6203#ifdef SIS315H 6018#ifdef SIS315H
6204 USHORT tempbl=0; 6019 unsigned short tempbl=0;
6205#endif 6020#endif
6206 6021
6207 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
6208 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 6023 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6209 return; 6024 return;
6210 } 6025 }
6211 6026
@@ -6214,47 +6029,47 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6214 } else if(SiS_Pr->UseCustomMode) { 6029 } else if(SiS_Pr->UseCustomMode) {
6215 modeflag = SiS_Pr->CModeFlag; 6030 modeflag = SiS_Pr->CModeFlag;
6216 } else { 6031 } else {
6217 CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; 6032 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
6218 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 6033 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
6219 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6034 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
6220 } 6035 }
6221 6036
6222 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 6037 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6223 6038
6224 if( ! ((HwInfo->jChipType >= SIS_315H) && 6039 if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
6225 (SiS_Pr->SiS_IF_DEF_LVDS == 1) && 6040 (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
6226 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { 6041 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
6227 6042
6228 if(HwInfo->jChipType < SIS_315H ) { 6043 if(SiS_Pr->ChipType < SIS_315H ) {
6229#ifdef SIS300 6044#ifdef SIS300
6230 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo); 6045 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
6231#endif 6046#endif
6232 } else { 6047 } else {
6233#ifdef SIS315H 6048#ifdef SIS315H
6234 SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo); 6049 SiS_SetCRT2FIFO_310(SiS_Pr);
6235#endif 6050#endif
6236 } 6051 }
6237 6052
6238 /* 1. Horizontal setup */ 6053 /* 1. Horizontal setup */
6239 6054
6240 if(HwInfo->jChipType < SIS_315H ) { 6055 if(SiS_Pr->ChipType < SIS_315H ) {
6241 6056
6242#ifdef SIS300 /* ------------- 300 series --------------*/ 6057#ifdef SIS300 /* ------------- 300 series --------------*/
6243 6058
6244 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ 6059 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
6245 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ 6060 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
6246 6061
6247 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; 6062 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
6248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6063 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
6249 6064
6250 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ 6065 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
6251 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ 6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
6252 6067
6253 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */ 6068 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
6254 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; 6069 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
6255 tempbx = pushbx + tempcx; 6070 tempbx = pushbx + tempcx;
6256 tempcx <<= 1; 6071 tempcx <<= 1;
6257 tempcx += tempbx; 6072 tempcx += tempbx;
6258 6073
6259 bridgeadd = 12; 6074 bridgeadd = 12;
6260 6075
@@ -6301,7 +6116,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6301 bridgeadd = 16; 6116 bridgeadd = 16;
6302 6117
6303 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6118 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6304 if(HwInfo->jChipType >= SIS_661) { 6119 if(SiS_Pr->ChipType >= SIS_661) {
6305 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 6120 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
6306 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 6121 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
6307 if(resinfo == SIS_RI_1280x1024) { 6122 if(resinfo == SIS_RI_1280x1024) {
@@ -6319,7 +6134,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6319 6134
6320 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6135 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6321 6136
6322 if(SiS_Pr->UseCustomMode) { 6137 if(SiS_Pr->UseCustomMode) {
6323 tempbx = SiS_Pr->CHSyncStart + bridgeadd; 6138 tempbx = SiS_Pr->CHSyncStart + bridgeadd;
6324 tempcx = SiS_Pr->CHSyncEnd + bridgeadd; 6139 tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
6325 tempax = SiS_Pr->SiS_VGAHT; 6140 tempax = SiS_Pr->SiS_VGAHT;
@@ -6341,22 +6156,22 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6341 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; 6156 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
6342 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; 6157 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
6343 } 6158 }
6344 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */ 6159 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
6345 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */ 6160 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
6346 tempcx &= 0x00FF; 6161 tempcx &= 0x00FF;
6347 tempcx |= (tempbx & 0xFF00); 6162 tempcx |= (tempbx & 0xFF00);
6348 tempbx += bridgeadd; 6163 tempbx += bridgeadd;
6349 tempcx += bridgeadd; 6164 tempcx += bridgeadd;
6350 tempax = SiS_Pr->SiS_VGAHT; 6165 tempax = SiS_Pr->SiS_VGAHT;
6351 if(modeflag & HalfDCLK) tempax >>= 1; 6166 if(modeflag & HalfDCLK) tempax >>= 1;
6352 tempax--; 6167 tempax--;
6353 if(tempcx > tempax) tempcx = tempax; 6168 if(tempcx > tempax) tempcx = tempax;
6354 } 6169 }
6355 6170
6356 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6171 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
6357 tempbx = 1040; 6172 tempbx = 1040;
6358 tempcx = 1044; /* HWCursor bug! */ 6173 tempcx = 1044; /* HWCursor bug! */
6359 } 6174 }
6360 6175
6361 } 6176 }
6362 6177
@@ -6372,18 +6187,18 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6372 tempcx = SiS_Pr->SiS_VGAVT - 1; 6187 tempcx = SiS_Pr->SiS_VGAVT - 1;
6373 temp = tempcx & 0x00FF; 6188 temp = tempcx & 0x00FF;
6374 6189
6375 if(HwInfo->jChipType < SIS_661) { 6190 if(SiS_Pr->ChipType < SIS_661) {
6376 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6191 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6377 if(HwInfo->jChipType < SIS_315H) { 6192 if(SiS_Pr->ChipType < SIS_315H) {
6378 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6193 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6379 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 6194 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
6380 temp--; 6195 temp--;
6381 } 6196 }
6382 } 6197 }
6383 } else { 6198 } else {
6384 temp--; 6199 temp--;
6385 } 6200 }
6386 } else if(HwInfo->jChipType >= SIS_315H) { 6201 } else if(SiS_Pr->ChipType >= SIS_315H) {
6387 temp--; 6202 temp--;
6388 } 6203 }
6389 } 6204 }
@@ -6395,9 +6210,9 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6395 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07); 6210 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
6396 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */ 6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
6397 6212
6398 if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) { 6213 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
6399 tempbx++; 6214 tempbx++;
6400 tempax = tempbx; 6215 tempax = tempbx;
6401 tempcx++; 6216 tempcx++;
6402 tempcx -= tempax; 6217 tempcx -= tempax;
6403 tempcx >>= 2; 6218 tempcx >>= 2;
@@ -6407,8 +6222,8 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6407 tempcx += tempbx; 6222 tempcx += tempbx;
6408 tempcx++; 6223 tempcx++;
6409 } else { 6224 } else {
6410 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ 6225 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
6411 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ 6226 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
6412 } 6227 }
6413 6228
6414 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6229 if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -6416,7 +6231,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6416 tempbx = SiS_Pr->CVSyncStart; 6231 tempbx = SiS_Pr->CVSyncStart;
6417 tempcx = SiS_Pr->CVSyncEnd; 6232 tempcx = SiS_Pr->CVSyncEnd;
6418 } 6233 }
6419 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6234 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
6420 unsigned char cr8, cr7, cr13; 6235 unsigned char cr8, cr7, cr13;
6421 if(SiS_Pr->UseCustomMode) { 6236 if(SiS_Pr->UseCustomMode) {
6422 cr8 = SiS_Pr->CCRT1CRTC[8]; 6237 cr8 = SiS_Pr->CCRT1CRTC[8];
@@ -6429,11 +6244,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6429 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; 6244 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
6430 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9]; 6245 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
6431 } 6246 }
6432 tempbx = cr8; 6247 tempbx = cr8;
6433 if(cr7 & 0x04) tempbx |= 0x0100; 6248 if(cr7 & 0x04) tempbx |= 0x0100;
6434 if(cr7 & 0x80) tempbx |= 0x0200; 6249 if(cr7 & 0x80) tempbx |= 0x0200;
6435 if(cr13 & 0x08) tempbx |= 0x0400; 6250 if(cr13 & 0x08) tempbx |= 0x0400;
6436 } 6251 }
6437 } 6252 }
6438 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */ 6253 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
6439 6254
@@ -6442,13 +6257,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6442 6257
6443 /* 3. Panel delay compensation */ 6258 /* 3. Panel delay compensation */
6444 6259
6445 if(HwInfo->jChipType < SIS_315H) { 6260 if(SiS_Pr->ChipType < SIS_315H) {
6446 6261
6447#ifdef SIS300 /* ---------- 300 series -------------- */ 6262#ifdef SIS300 /* ---------- 300 series -------------- */
6448 6263
6449 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6264 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6450 temp = 0x20; 6265 temp = 0x20;
6451 if(HwInfo->jChipType == SIS_300) { 6266 if(SiS_Pr->ChipType == SIS_300) {
6452 temp = 0x10; 6267 temp = 0x10;
6453 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c; 6268 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
6454 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6269 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
@@ -6460,24 +6275,23 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6460 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c; 6275 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
6461 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08; 6276 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
6462 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6277 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6463 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; 6278 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
6464 else temp = 0x20; 6279 else temp = 0x20;
6465 } 6280 }
6466 if(SiS_Pr->SiS_UseROM) { 6281 if(SiS_Pr->SiS_UseROM) {
6467 if(ROMAddr[0x220] & 0x80) { 6282 if(ROMAddr[0x220] & 0x80) {
6468 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) 6283 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
6469 temp = ROMAddr[0x221]; 6284 temp = ROMAddr[0x221];
6470 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) 6285 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
6471 temp = ROMAddr[0x222]; 6286 temp = ROMAddr[0x222];
6472 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) 6287 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
6473 temp = ROMAddr[0x223]; 6288 temp = ROMAddr[0x223];
6474 else 6289 else
6475 temp = ROMAddr[0x224]; 6290 temp = ROMAddr[0x224];
6476 temp &= 0x3c;
6477 } 6291 }
6478 } 6292 }
6479 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6293 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6480 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c; 6294 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6481 } 6295 }
6482 6296
6483 } else { 6297 } else {
@@ -6487,15 +6301,17 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6487 } 6301 }
6488 if(SiS_Pr->SiS_UseROM) { 6302 if(SiS_Pr->SiS_UseROM) {
6489 if(ROMAddr[0x220] & 0x80) { 6303 if(ROMAddr[0x220] & 0x80) {
6490 temp = ROMAddr[0x220] & 0x3c; 6304 temp = ROMAddr[0x220];
6491 } 6305 }
6492 } 6306 }
6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6307 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6494 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c; 6308 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
6495 } 6309 }
6496 } 6310 }
6497 6311
6498 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ 6312 temp &= 0x3c;
6313
6314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
6499 6315
6500#endif /* SIS300 */ 6316#endif /* SIS300 */
6501 6317
@@ -6503,16 +6319,16 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6503 6319
6504#ifdef SIS315H /* --------------- 315/330 series ---------------*/ 6320#ifdef SIS315H /* --------------- 315/330 series ---------------*/
6505 6321
6506 if(HwInfo->jChipType < SIS_661) { 6322 if(SiS_Pr->ChipType < SIS_661) {
6507 6323
6508 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6324 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
6509 6325
6510 if(HwInfo->jChipType == SIS_740) temp = 0x03; 6326 if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
6511 else temp = 0x00; 6327 else temp = 0x00;
6512 6328
6513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a; 6329 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
6514 tempbl = 0xF0; 6330 tempbl = 0xF0;
6515 if(HwInfo->jChipType == SIS_650) { 6331 if(SiS_Pr->ChipType == SIS_650) {
6516 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6332 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6517 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F; 6333 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
6518 } 6334 }
@@ -6531,10 +6347,10 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6531 6347
6532 } /* < 661 */ 6348 } /* < 661 */
6533 6349
6534 tempax = 0; 6350 tempax = 0;
6535 if(modeflag & DoubleScanMode) tempax |= 0x80; 6351 if(modeflag & DoubleScanMode) tempax |= 0x80;
6536 if(modeflag & HalfDCLK) tempax |= 0x40; 6352 if(modeflag & HalfDCLK) tempax |= 0x40;
6537 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); 6353 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
6538 6354
6539#endif /* SIS315H */ 6355#endif /* SIS315H */
6540 6356
@@ -6544,21 +6360,21 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6544 6360
6545 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6361 if(SiS_Pr->SiS_VBType & VB_SISVB) {
6546 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 6362 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
6547 /* For 301BDH with LCD, we set up the Panel Link */ 6363 /* For 301BDH with LCD, we set up the Panel Link */
6548 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 6364 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6549 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6365 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6550 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 6366 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6551 } 6367 }
6552 } else { 6368 } else {
6553 if(HwInfo->jChipType < SIS_315H) { 6369 if(SiS_Pr->ChipType < SIS_315H) {
6554 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 6370 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
6555 } else { 6371 } else {
6556 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6372 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
6557 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 6373 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
6558 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex); 6374 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6559 } 6375 }
6560 } else { 6376 } else {
6561 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex); 6377 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
6562 } 6378 }
6563 } 6379 }
6564 } 6380 }
@@ -6569,11 +6385,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6569/*********************************************/ 6385/*********************************************/
6570 6386
6571#ifdef SIS315H 6387#ifdef SIS315H
6572static UCHAR * 6388static unsigned char *
6573SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo) 6389SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
6574{ 6390{
6575 const UCHAR *tableptr = NULL; 6391 const unsigned char *tableptr = NULL;
6576 USHORT a, b, p = 0; 6392 unsigned short a, b, p = 0;
6577 6393
6578 a = SiS_Pr->SiS_VGAHDE; 6394 a = SiS_Pr->SiS_VGAHDE;
6579 b = SiS_Pr->SiS_HDE; 6395 b = SiS_Pr->SiS_HDE;
@@ -6606,25 +6422,25 @@ SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
6606 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42; 6422 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
6607 } 6423 }
6608 p += 2; 6424 p += 2;
6609 return((UCHAR *)&tableptr[p]); 6425 return ((unsigned char *)&tableptr[p]);
6610} 6426}
6611 6427
6612static void 6428static void
6613SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 6429SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6614 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 6430 unsigned short RefreshRateTableIndex)
6615{ 6431{
6616 UCHAR *tableptr; 6432 unsigned char *tableptr;
6433 unsigned char temp;
6617 int i, j; 6434 int i, j;
6618 UCHAR temp;
6619 6435
6620 if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return; 6436 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
6621 6437
6622 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo); 6438 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
6623 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) { 6439 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
6624 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6440 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6625 } 6441 }
6626 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6442 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
6627 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo); 6443 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
6628 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) { 6444 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
6629 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6445 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
6630 } 6446 }
@@ -6635,12 +6451,12 @@ SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
6635} 6451}
6636 6452
6637static BOOLEAN 6453static BOOLEAN
6638SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex, 6454SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
6639 USHORT RefreshRateTableIndex,USHORT *CRT2Index, 6455 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
6640 USHORT *ResIndex,PSIS_HW_INFO HwInfo) 6456 unsigned short *ResIndex)
6641{ 6457{
6642 6458
6643 if(HwInfo->jChipType < SIS_315H) return FALSE; 6459 if(SiS_Pr->ChipType < SIS_315H) return FALSE;
6644 6460
6645 if(ModeNo <= 0x13) 6461 if(ModeNo <= 0x13)
6646 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6462 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -6661,82 +6477,79 @@ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
6661 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206; 6477 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
6662 } 6478 }
6663 } 6479 }
6664 return(((*CRT2Index) != 0)); 6480 return (((*CRT2Index) != 0));
6665} 6481}
6666#endif 6482#endif
6667 6483
6668#ifdef SIS300 6484#ifdef SIS300
6669static void 6485static void
6670SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc) 6486SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
6671{ 6487{
6672 USHORT tempcx; 6488 unsigned short tempcx;
6673 const UCHAR atable[] = { 6489 static const unsigned char atable[] = {
6674 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02, 6490 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
6675 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02 6491 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
6676 }; 6492 };
6677 6493
6678 if(!SiS_Pr->UseCustomMode) { 6494 if(!SiS_Pr->UseCustomMode) {
6679 if( ( ( (HwInfo->jChipType == SIS_630) || 6495 if( ( ( (SiS_Pr->ChipType == SIS_630) ||
6680 (HwInfo->jChipType == SIS_730) ) && 6496 (SiS_Pr->ChipType == SIS_730) ) &&
6681 (HwInfo->jChipRevision > 2) ) && 6497 (SiS_Pr->ChipRevision > 2) ) &&
6682 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) && 6498 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
6683 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) && 6499 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
6684 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { 6500 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
6685 if(ModeNo == 0x13) { 6501 if(ModeNo == 0x13) {
6686 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9); 6502 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
6687 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC); 6503 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
6688 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6); 6504 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
6689 } else { 6505 } else if((crt2crtc & 0x3F) == 4) {
6690 if((crt2crtc & 0x3F) == 4) { 6506 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
6691 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B); 6507 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
6692 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13); 6508 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
6693 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5); 6509 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
6694 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08); 6510 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
6695 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2); 6511 }
6696 }
6697 }
6698 } 6512 }
6699 6513
6700 if(HwInfo->jChipType < SIS_315H) { 6514 if(SiS_Pr->ChipType < SIS_315H) {
6701 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) { 6515 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
6702 crt2crtc &= 0x1f; 6516 crt2crtc &= 0x1f;
6703 tempcx = 0; 6517 tempcx = 0;
6704 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6518 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6705 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6519 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6706 tempcx += 7; 6520 tempcx += 7;
6707 } 6521 }
6708 } 6522 }
6709 tempcx += crt2crtc; 6523 tempcx += crt2crtc;
6710 if(crt2crtc >= 4) { 6524 if(crt2crtc >= 4) {
6711 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff); 6525 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
6712 } 6526 }
6713 6527
6714 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6528 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
6715 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6529 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
6716 if(crt2crtc == 4) { 6530 if(crt2crtc == 4) {
6717 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28); 6531 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
6718 } 6532 }
6719 } 6533 }
6720 } 6534 }
6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18); 6535 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]); 6536 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
6723 } 6537 }
6724 } 6538 }
6725 } 6539 }
6726} 6540}
6727 6541
6728/* For ECS A907. Highly preliminary. */ 6542/* For ECS A907. Highly preliminary. */
6729static void 6543static void
6730SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 6544SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
6731 USHORT ModeIdIndex, USHORT RefreshRateTableIndex, 6545 unsigned short ModeNo)
6732 USHORT ModeNo)
6733{ 6546{
6734 USHORT crt2crtc, resindex; 6547 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6735 int i,j; 6548 unsigned short crt2crtc, resindex;
6736 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL; 6549 int i, j;
6737 6550
6738 if(HwInfo->jChipType != SIS_300) return; 6551 if(SiS_Pr->ChipType != SIS_300) return;
6739 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return; 6552 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6740 if(SiS_Pr->UseCustomMode) return; 6553 if(SiS_Pr->UseCustomMode) return;
6741 6554
6742 if(ModeNo <= 0x13) { 6555 if(ModeNo <= 0x13) {
@@ -6758,13 +6571,13 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6758 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 6571 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
6759 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 6572 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
6760 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 6573 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
6761 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6574 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6762 } 6575 }
6763 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 6576 for(j = 0x1c; j <= 0x1d; i++, j++ ) {
6764 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6577 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6765 } 6578 }
6766 for(j = 0x1f; j <= 0x21; i++, j++ ) { 6579 for(j = 0x1f; j <= 0x21; i++, j++ ) {
6767 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6580 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
6768 } 6581 }
6769 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 6582 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
6770 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 6583 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
@@ -6772,15 +6585,15 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
6772#endif 6585#endif
6773 6586
6774static void 6587static void
6775SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo) 6588SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6776{ 6589{
6777 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return; 6590 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
6778 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return; 6591 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
6779 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return; 6592 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
6780 6593
6781 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 6594 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
6782 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6595 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6783 const UCHAR specialtv[] = { 6596 const unsigned char specialtv[] = {
6784 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53, 6597 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
6785 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a, 6598 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
6786 0x58,0xe4,0x73,0xda,0x13 6599 0x58,0xe4,0x73,0xda,0x13
@@ -6813,16 +6626,16 @@ SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
6813} 6626}
6814 6627
6815static void 6628static void
6816SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo) 6629SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
6817{ 6630{
6818 USHORT temp; 6631 unsigned short temp;
6819 6632
6820 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6633 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
6821 if(SiS_Pr->SiS_VGAVDE == 525) { 6634 if(SiS_Pr->SiS_VGAVDE == 525) {
6822 temp = 0xc3; 6635 temp = 0xc3;
6823 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6636 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6824 temp++; 6637 temp++;
6825 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2; 6638 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
6826 } 6639 }
6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6640 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3); 6641 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
@@ -6830,7 +6643,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6830 temp = 0x4d; 6643 temp = 0x4d;
6831 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6644 if(SiS_Pr->SiS_ModeType <= ModeVGA) {
6832 temp++; 6645 temp++;
6833 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++; 6646 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
6834 } 6647 }
6835 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6648 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
6836 } 6649 }
@@ -6838,7 +6651,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6838 6651
6839 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6652 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
6840 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 6653 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
6841 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 6654 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
6842 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03); 6655 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
6843 /* Not always for LV, see SetGrp2 */ 6656 /* Not always for LV, see SetGrp2 */
6844 } 6657 }
@@ -6872,17 +6685,17 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
6872} 6685}
6873 6686
6874static void 6687static void
6875SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex, 6688SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
6876 PSIS_HW_INFO HwInfo) 6689 unsigned short RefreshRateTableIndex)
6877{ 6690{
6878 USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp; 6691 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
6879 USHORT push2, modeflag, crt2crtc, bridgeoffset; 6692 unsigned short push2, modeflag, crt2crtc, bridgeoffset;
6880 ULONG longtemp; 6693 unsigned int longtemp, PhaseIndex;
6881 const UCHAR *PhasePoint; 6694 BOOLEAN newtvphase;
6882 const UCHAR *TimingPoint; 6695 const unsigned char *TimingPoint;
6883#ifdef SIS315H 6696#ifdef SIS315H
6884 USHORT resindex, CRT2Index; 6697 unsigned short resindex, CRT2Index;
6885 const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL; 6698 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
6886 6699
6887 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 6700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
6888#endif 6701#endif
@@ -6908,9 +6721,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
6908 6721
6909 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp); 6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
6910 6723
6911 PhasePoint = SiS_Pr->SiS_PALPhase; 6724 PhaseIndex = 0x01; /* SiS_PALPhase */
6912 TimingPoint = SiS_Pr->SiS_PALTiming; 6725 TimingPoint = SiS_Pr->SiS_PALTiming;
6913 6726
6727 newtvphase = FALSE;
6728 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
6729 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6730 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6731 newtvphase = TRUE;
6732 }
6733
6914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
6915 6735
6916 TimingPoint = SiS_Pr->SiS_HiTVExtTiming; 6736 TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
@@ -6918,82 +6738,54 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
6918 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing; 6738 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
6919 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6739 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
6920 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing; 6740 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
6921#if 0
6922 if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
6923#endif
6924 } 6741 }
6925 } 6742 }
6926 6743
6927 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6744 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
6928 6745
6929 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0]; 6746 i = 0;
6930 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0]; 6747 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
6931 else TimingPoint = &SiS_YPbPrTable[0][0]; 6748 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
6749
6750 TimingPoint = &SiS_YPbPrTable[i][0];
6932 6751
6933 PhasePoint = SiS_Pr->SiS_NTSCPhase; 6752 PhaseIndex = 0x00; /* SiS_NTSCPhase */
6934 6753
6935 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6754 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
6936 6755
6937 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && 6756 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
6938 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6939 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6940 PhasePoint = SiS_Pr->SiS_PALPhase2;
6941 }
6942 6757
6943 } else { 6758 } else {
6944 6759
6945 TimingPoint = SiS_Pr->SiS_NTSCTiming; 6760 TimingPoint = SiS_Pr->SiS_NTSCTiming;
6946 PhasePoint = SiS_Pr->SiS_NTSCPhase; 6761 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
6947 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 6762 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
6948 PhasePoint = SiS_Pr->SiS_PALPhase;
6949 }
6950
6951 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6952 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6953 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6954 PhasePoint = SiS_Pr->SiS_NTSCPhase2;
6955 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6956 PhasePoint = SiS_Pr->SiS_PALPhase2;
6957 }
6958 }
6959
6960 }
6961 6763
6962 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6963 PhasePoint = SiS_Pr->SiS_PALMPhase;
6964 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
6965 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6966 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6967 PhasePoint = SiS_Pr->SiS_PALMPhase2;
6968 }
6969 } 6764 }
6970 6765
6971 if(SiS_Pr->SiS_TVMode & TVSetPALN) { 6766 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
6972 PhasePoint = SiS_Pr->SiS_PALNPhase; 6767 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
6973 if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && 6768 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
6974 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
6975 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
6976 PhasePoint = SiS_Pr->SiS_PALNPhase2;
6977 }
6978 } 6769 }
6979 6770
6980 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6771 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
6981 PhasePoint = SiS_Pr->SiS_SpecialPhase;
6982 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6772 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
6983 PhasePoint = SiS_Pr->SiS_SpecialPhaseM; 6773 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
6984 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 6774 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
6985 PhasePoint = SiS_Pr->SiS_SpecialPhaseJ; 6775 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
6776 } else {
6777 PhaseIndex = 0x10; /* SiS_SpecialPhase */
6986 } 6778 }
6987 } 6779 }
6988 6780
6989 for(i=0x31, j=0; i<=0x34; i++, j++) { 6781 for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
6990 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]); 6782 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
6991 } 6783 }
6992 6784
6993 for(i=0x01, j=0; i<=0x2D; i++, j++) { 6785 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
6994 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 6786 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6995 } 6787 }
6996 for(i=0x39; i<=0x45; i++, j++) { 6788 for(i = 0x39; i <= 0x45; i++, j++) {
6997 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 6789 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
6998 } 6790 }
6999 6791
@@ -7010,28 +6802,32 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7010 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE); 6802 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
7011 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE); 6803 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
7012 6804
7013 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950; 6805 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
7014 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520; 6806 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
7015 else tempax = 440; /* NTSC, YPbPr 525, 750 */ 6807 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
6808 else tempax = 440; /* NTSC, YPbPr 525 */
7016 6809
7017 if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) || 6810 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
7018 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && 6811 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
7019 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) { 6812 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
7020 6813
7021 tempax -= SiS_Pr->SiS_VDE; 6814 tempax -= SiS_Pr->SiS_VDE;
7022 tempax >>= 2; 6815 tempax >>= 1;
6816 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
6817 tempax >>= 1;
6818 }
7023 tempax &= 0x00ff; 6819 tempax &= 0x00ff;
7024 6820
7025 temp = tempax + (USHORT)TimingPoint[0]; 6821 temp = tempax + (unsigned short)TimingPoint[0];
7026 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7027 6823
7028 temp = tempax + (USHORT)TimingPoint[1]; 6824 temp = tempax + (unsigned short)TimingPoint[1];
7029 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
7030 6826
7031 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) { 6827 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
7032 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6828 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
7033 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */ 6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
7034 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */ 6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
7035 } else { 6831 } else {
7036 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17); 6832 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
7037 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d); 6833 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
@@ -7041,14 +6837,14 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7041 } 6837 }
7042 6838
7043 tempcx = SiS_Pr->SiS_HT; 6839 tempcx = SiS_Pr->SiS_HT;
7044 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1; 6840 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7045 tempcx--; 6841 tempcx--;
7046 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--; 6842 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
7047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx); 6843 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
7048 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f)); 6844 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
7049 6845
7050 tempcx = SiS_Pr->SiS_HT >> 1; 6846 tempcx = SiS_Pr->SiS_HT >> 1;
7051 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1; 6847 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7052 tempcx += 7; 6848 tempcx += 7;
7053 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 6849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
7054 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0)); 6850 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
@@ -7075,7 +6871,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7075 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0)); 6871 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
7076 6872
7077 tempcx = SiS_Pr->SiS_HT >> 1; 6873 tempcx = SiS_Pr->SiS_HT >> 1;
7078 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1; 6874 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
7079 j += 2; 6875 j += 2;
7080 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8)); 6876 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0)); 6877 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
@@ -7094,7 +6890,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7094 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 6890 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7095 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) { 6891 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
7096 tempbx >>= 1; 6892 tempbx >>= 1;
7097 if(HwInfo->jChipType >= SIS_315H) { 6893 if(SiS_Pr->ChipType >= SIS_315H) {
7098 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6894 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
7099 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++; 6895 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
7100 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6896 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
@@ -7123,23 +6919,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7123 } 6919 }
7124 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp); 6920 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
7125 6921
7126 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) { 6922 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7127 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5)); 6923 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
7128 } 6924 }
7129 6925
7130#if 0 6926 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7131 /* TEST qqqq */
7132 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
7133 for(i=0x01, j=0; i<=0x2D; i++, j++) {
7134 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7135 }
7136 for(i=0x39; i<=0x45; i++, j++) {
7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
7138 }
7139 }
7140#endif
7141
7142 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
7143 tempbx = SiS_Pr->SiS_VDE; 6927 tempbx = SiS_Pr->SiS_VDE;
7144 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 6928 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
7145 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) { 6929 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
@@ -7150,7 +6934,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7150 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp); 6934 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx); 6935 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
7152 6936
7153 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) { 6937 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
7154 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4)); 6938 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
7155 } 6939 }
7156 } 6940 }
@@ -7165,14 +6949,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7165 6949
7166 tempch = tempcl = 0x01; 6950 tempch = tempcl = 0x01;
7167 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7168 if(SiS_Pr->SiS_VGAHDE >= 1024) { 6952 if(SiS_Pr->SiS_VGAHDE >= 960) {
7169 if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) { 6953 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
7170 tempch = 0x19;
7171 tempcl = 0x20; 6954 tempcl = 0x20;
7172 if(SiS_Pr->SiS_VGAHDE >= 1280) { 6955 if(SiS_Pr->SiS_VGAHDE >= 1280) {
7173 tempch = 0x14; 6956 tempch = 20;
7174 tempbx &= ~0x20; 6957 tempbx &= ~0x20;
7175 } 6958 } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
6959 tempch = 25;
6960 } else {
6961 tempch = 25; /* OK */
6962 }
7176 } 6963 }
7177 } 6964 }
7178 } 6965 }
@@ -7180,7 +6967,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7180 if(!(tempbx & 0x20)) { 6967 if(!(tempbx & 0x20)) {
7181 if(modeflag & HalfDCLK) tempcl <<= 1; 6968 if(modeflag & HalfDCLK) tempcl <<= 1;
7182 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13; 6969 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
7183 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3; 6970 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
7184 tempax = longtemp / SiS_Pr->SiS_HDE; 6971 tempax = longtemp / SiS_Pr->SiS_HDE;
7185 if(longtemp % SiS_Pr->SiS_HDE) tempax++; 6972 if(longtemp % SiS_Pr->SiS_HDE) tempax++;
7186 tempbx |= ((tempax >> 8) & 0x1F); 6973 tempbx |= ((tempax >> 8) & 0x1F);
@@ -7190,7 +6977,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7190 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax); 6977 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
7191 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx); 6978 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
7192 6979
7193 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 6980 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7194 6981
7195 tempcx &= 0x07; 6982 tempcx &= 0x07;
7196 if(tempbx & 0x20) tempcx = 0; 6983 if(tempbx & 0x20) tempcx = 0;
@@ -7219,7 +7006,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7219 7006
7220 SiS_SetTVSpecial(SiS_Pr, ModeNo); 7007 SiS_SetTVSpecial(SiS_Pr, ModeNo);
7221 7008
7222 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 7009 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7223 temp = 0; 7010 temp = 0;
7224 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 7011 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
7225 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp); 7012 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
@@ -7246,7 +7033,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7246 /* From here: Part2 LCD setup */ 7033 /* From here: Part2 LCD setup */
7247 7034
7248 tempbx = SiS_Pr->SiS_HDE; 7035 tempbx = SiS_Pr->SiS_HDE;
7249 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1; 7036 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7250 tempbx--; /* RHACTE = HDE - 1 */ 7037 tempbx--; /* RHACTE = HDE - 1 */
7251 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx); 7038 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
7252 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0)); 7039 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
@@ -7256,10 +7043,8 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7256 if(SiS_Pr->SiS_ModeType == ModeEGA) { 7043 if(SiS_Pr->SiS_ModeType == ModeEGA) {
7257 if(SiS_Pr->SiS_VGAHDE >= 1024) { 7044 if(SiS_Pr->SiS_VGAHDE >= 1024) {
7258 temp = 0x02; 7045 temp = 0x02;
7259 if(HwInfo->jChipType >= SIS_315H) { 7046 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
7260 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7047 temp = 0x01;
7261 temp = 0x01;
7262 }
7263 } 7048 }
7264 } 7049 }
7265 } 7050 }
@@ -7289,11 +7074,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7289 7074
7290#ifdef SIS315H 7075#ifdef SIS315H
7291 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7076 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7292 &CRT2Index, &resindex, HwInfo)) { 7077 &CRT2Index, &resindex)) {
7293 switch(CRT2Index) { 7078 switch(CRT2Index) {
7079 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7080 default:
7294 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; 7081 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
7295 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
7296 default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
7297 } 7082 }
7298 7083
7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
@@ -7312,7 +7097,6 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7312 7097
7313 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7098 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7314 7099
7315
7316 } else { 7100 } else {
7317#endif 7101#endif
7318 7102
@@ -7349,9 +7133,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7349 7133
7350 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ 7134 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
7351 7135
7136#ifdef SIS_XORG_XF86
7352#ifdef TWDEBUG 7137#ifdef TWDEBUG
7353 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx); 7138 xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
7354#endif 7139#endif
7140#endif
7355 7141
7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ 7142 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
7357 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ 7143 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
@@ -7401,9 +7187,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7401 tempbx = SiS_Pr->CVSyncStart; 7187 tempbx = SiS_Pr->CVSyncStart;
7402 } 7188 }
7403 7189
7190#ifdef SIS_XORG_XF86
7404#ifdef TWDEBUG 7191#ifdef TWDEBUG
7405 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx); 7192 xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
7406#endif 7193#endif
7194#endif
7407 7195
7408 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ 7196 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
7409 7197
@@ -7416,26 +7204,30 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7416 temp |= (SiS_Pr->CVSyncEnd & 0x0f); 7204 temp |= (SiS_Pr->CVSyncEnd & 0x0f);
7417 } 7205 }
7418 7206
7207#ifdef SIS_XORG_XF86
7419#ifdef TWDEBUG 7208#ifdef TWDEBUG
7420 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f)); 7209 xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
7421#endif 7210#endif
7211#endif
7422 7212
7423 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7213 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
7424 7214
7425#ifdef SIS300 7215#ifdef SIS300
7426 SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc); 7216 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
7427#endif 7217#endif
7428 7218
7429 bridgeoffset = 7; 7219 bridgeoffset = 7;
7430 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2; 7220 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
7431 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++; 7221 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
7432 if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++; 7222 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
7223 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
7224 /* Higher bridgeoffset shifts to the LEFT */
7433 7225
7434 temp = 0; 7226 temp = 0;
7435 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7227 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
7436 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7228 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
7437 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7229 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7438 if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1; 7230 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
7439 } 7231 }
7440 } 7232 }
7441 temp += bridgeoffset; 7233 temp += bridgeoffset;
@@ -7450,15 +7242,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7450 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7242 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
7451 } 7243 }
7452 } 7244 }
7453 if(SiS_IsDualLink(SiS_Pr, HwInfo)) { 7245 if(SiS_IsDualLink(SiS_Pr)) {
7454 tempcx >>= 1; 7246 tempcx >>= 1;
7455 tempbx >>= 1; 7247 tempbx >>= 1;
7456 tempax >>= 1; 7248 tempax >>= 1;
7457 } 7249 }
7458 7250
7251#ifdef SIS_XORG_XF86
7459#ifdef TWDEBUG 7252#ifdef TWDEBUG
7460 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx); 7253 xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
7461#endif 7254#endif
7255#endif
7462 7256
7463 tempbx += bridgeoffset; 7257 tempbx += bridgeoffset;
7464 7258
@@ -7480,13 +7274,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7480 7274
7481 if(SiS_Pr->UseCustomMode) { 7275 if(SiS_Pr->UseCustomMode) {
7482 tempbx = SiS_Pr->CHSyncStart; 7276 tempbx = SiS_Pr->CHSyncStart;
7483 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1; 7277 if(modeflag & HalfDCLK) tempbx <<= 1;
7278 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7484 tempbx += bridgeoffset; 7279 tempbx += bridgeoffset;
7485 } 7280 }
7486 7281
7282#ifdef SIS_XORG_XF86
7487#ifdef TWDEBUG 7283#ifdef TWDEBUG
7488 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx); 7284 xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
7489#endif 7285#endif
7286#endif
7490 7287
7491 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ 7288 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
7492 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); 7289 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
@@ -7501,20 +7298,23 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7501 7298
7502 if(SiS_Pr->UseCustomMode) { 7299 if(SiS_Pr->UseCustomMode) {
7503 tempbx = SiS_Pr->CHSyncEnd; 7300 tempbx = SiS_Pr->CHSyncEnd;
7504 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1; 7301 if(modeflag & HalfDCLK) tempbx <<= 1;
7302 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7505 tempbx += bridgeoffset; 7303 tempbx += bridgeoffset;
7506 } 7304 }
7507 7305
7306#ifdef SIS_XORG_XF86
7508#ifdef TWDEBUG 7307#ifdef TWDEBUG
7509 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx); 7308 xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
7510#endif 7309#endif
7310#endif
7511 7311
7512 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ 7312 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
7513 7313
7514 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7314 SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
7515 7315
7516#ifdef SIS300 7316#ifdef SIS300
7517 SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo); 7317 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
7518#endif 7318#endif
7519#ifdef SIS315H 7319#ifdef SIS315H
7520 } /* CRT2-LCD from table */ 7320 } /* CRT2-LCD from table */
@@ -7526,11 +7326,10 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
7526/*********************************************/ 7326/*********************************************/
7527 7327
7528static void 7328static void
7529SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7329SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7530 PSIS_HW_INFO HwInfo)
7531{ 7330{
7532 USHORT i; 7331 unsigned short i;
7533 const UCHAR *tempdi; 7332 const unsigned char *tempdi;
7534 7333
7535 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7334 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
7536 7335
@@ -7570,7 +7369,7 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7570 for(i=0; i<=0x3E; i++) { 7369 for(i=0; i<=0x3E; i++) {
7571 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]); 7370 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
7572 } 7371 }
7573 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) { 7372 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
7574 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 7373 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
7575 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f); 7374 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
7576 } 7375 }
@@ -7587,35 +7386,43 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7587/*********************************************/ 7386/*********************************************/
7588 7387
7589#ifdef SIS315H 7388#ifdef SIS315H
7389#if 0
7590static void 7390static void
7591SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift) 7391SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
7592{ 7392{
7593 USHORT temp, temp1, temp2; 7393 unsigned short temp, temp1, temp2;
7594 7394
7595 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f); 7395 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
7596 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20); 7396 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
7597 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7397 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7598 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp); 7398 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
7599 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0)); 7399 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
7600 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f; 7400 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
7601 temp = (USHORT)((int)(temp) + shift); 7401 temp = (unsigned short)((int)(temp) + shift);
7602 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f)); 7402 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
7603 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7403 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
7604 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42); 7404 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
7605 temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7405 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
7606 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp); 7406 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
7607 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0)); 7407 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
7608} 7408}
7409#endif
7609 7410
7610static void 7411static void
7611SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 7412SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7612 USHORT ModeNo, USHORT ModeIdIndex)
7613{ 7413{
7614 USHORT temp, temp1, resinfo = 0; 7414 unsigned short temp, temp1, resinfo = 0;
7415 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
7615 7416
7616 if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return; 7417 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
7617 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return; 7418 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
7618 7419
7420 if(SiS_Pr->ChipType >= XGI_20) return;
7421
7422 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
7423 if(!(ROMAddr[0x61] & 0x04)) return;
7424 }
7425
7619 if(ModeNo > 0x13) { 7426 if(ModeNo > 0x13) {
7620 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 7427 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7621 } 7428 }
@@ -7625,7 +7432,7 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7625 if(!(temp & 0x01)) { 7432 if(!(temp & 0x01)) {
7626 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf); 7433 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
7627 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc); 7434 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
7628 if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) { 7435 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
7629 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8); 7436 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
7630 } 7437 }
7631 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb); 7438 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
@@ -7633,24 +7440,29 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7633 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002; 7440 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
7634 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400; 7441 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
7635 else temp = 0x0402; 7442 else temp = 0x0402;
7636 if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 7443 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
7637 temp1 = 0; 7444 temp1 = 0;
7638 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4; 7445 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
7639 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1); 7446 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
7640 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01; 7447 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
7641 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff)); 7448 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
7449 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7450 if(ModeNo > 0x13) {
7451 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
7452 }
7642 } else { 7453 } else {
7643 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03; 7454 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
7644 if(temp1 == 0x01) temp |= 0x01; 7455 if(temp1 == 0x01) temp |= 0x01;
7645 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */ 7456 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
7646 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff)); 7457 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
7647 } 7458 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
7648 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7459 if(ModeNo > 0x13) {
7649 if(ModeNo > 0x13) { 7460 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
7650 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd); 7461 }
7651 } 7462 }
7652 7463
7653 if(HwInfo->jChipType >= SIS_661) { /* ? */ 7464#if 0
7465 if(SiS_Pr->ChipType >= SIS_661) { /* ? */
7654 if(SiS_Pr->SiS_TVMode & TVAspect43) { 7466 if(SiS_Pr->SiS_TVMode & TVAspect43) {
7655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 7467 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
7656 if(resinfo == SIS_RI_1024x768) { 7468 if(resinfo == SIS_RI_1024x768) {
@@ -7663,29 +7475,30 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
7663 } 7475 }
7664 } 7476 }
7665 } 7477 }
7478#endif
7479
7666 } 7480 }
7481
7667} 7482}
7668#endif 7483#endif
7669 7484
7670static void 7485static void
7671SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7486SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7672 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 7487 unsigned short RefreshRateTableIndex)
7673{ 7488{
7674 USHORT vclkindex; 7489 unsigned short vclkindex, temp, reg1, reg2;
7675 USHORT temp, reg1, reg2;
7676 7490
7677 if(SiS_Pr->UseCustomMode) { 7491 if(SiS_Pr->UseCustomMode) {
7678 reg1 = SiS_Pr->CSR2B; 7492 reg1 = SiS_Pr->CSR2B;
7679 reg2 = SiS_Pr->CSR2C; 7493 reg2 = SiS_Pr->CSR2C;
7680 } else { 7494 } else {
7681 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7495 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7682 HwInfo);
7683 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A; 7496 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
7684 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B; 7497 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
7685 } 7498 }
7686 7499
7687 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 7500 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7688 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 7501 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57); 7502 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
7690 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46); 7503 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
7691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6); 7504 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
@@ -7705,11 +7518,35 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7705} 7518}
7706 7519
7707static void 7520static void
7708SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7521SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
7709 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 7522{
7523 if(SiS_Pr->ChipType >= SIS_315H) {
7524 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
7525 if((SiS_CRT2IsLCD(SiS_Pr)) ||
7526 (SiS_IsVAMode(SiS_Pr))) {
7527 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
7528 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7529 } else {
7530 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7531 }
7532 }
7533 }
7534 }
7535 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
7536 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7537#ifdef SET_EMI
7538 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7539#endif
7540 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7541 }
7542}
7543
7544static void
7545SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7546 unsigned short RefreshRateTableIndex)
7710{ 7547{
7711 USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo; 7548 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
7712 ULONG tempebx,tempeax,templong; 7549 unsigned int tempebx, tempeax, templong;
7713 7550
7714 if(ModeNo <= 0x13) { 7551 if(ModeNo <= 0x13) {
7715 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7552 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
@@ -7722,38 +7559,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7722 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 7559 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
7723 } 7560 }
7724 7561
7725 if(HwInfo->jChipType >= SIS_315H) { 7562 if(SiS_Pr->ChipType >= SIS_315H) {
7726 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 7563 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7727 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7728 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7565 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7729 } 7566 }
7730 } 7567 }
7731 } 7568 }
7732 7569
7733 if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) { 7570 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
7734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7571 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f); 7572 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
7736 } 7573 }
7737 } 7574 }
7738 7575
7739 if(HwInfo->jChipType >= SIS_315H) { 7576 if(SiS_Pr->ChipType >= SIS_315H) {
7740 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7577 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
7741 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 7578 SiS_SetDualLinkEtc(SiS_Pr);
7742 if(SiS_IsDualLink(SiS_Pr, HwInfo)) { 7579 return;
7743 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7744 } else {
7745 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7746 }
7747
7748 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7749 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7750#ifdef SET_EMI
7751 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7752#endif
7753 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7754 }
7755 }
7756 return;
7757 } 7580 }
7758 } 7581 }
7759 7582
@@ -7777,16 +7600,16 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7777 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp); 7600 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
7778 7601
7779 tempbx = SiS_Pr->SiS_VGAHDE; 7602 tempbx = SiS_Pr->SiS_VGAHDE;
7780 if(modeflag & HalfDCLK) tempbx >>= 1; 7603 if(modeflag & HalfDCLK) tempbx >>= 1;
7781 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1; 7604 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7782 7605
7783 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7606 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7784 temp = 0; 7607 temp = 0;
7785 if(tempbx > 800) temp = 0x60; 7608 if(tempbx > 800) temp = 0x60;
7786 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7609 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
7787 temp = 0; 7610 temp = 0;
7788 if(tempbx == 1024) temp = 0xA0; 7611 if(tempbx > 1024) temp = 0xC0;
7789 else if(tempbx > 1024) temp = 0xC0; 7612 else if(tempbx >= 960) temp = 0xA0;
7790 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 7613 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
7791 temp = 0; 7614 temp = 0;
7792 if(tempbx >= 1280) temp = 0x40; 7615 if(tempbx >= 1280) temp = 0x40;
@@ -7796,8 +7619,13 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7796 if(tempbx >= 1024) temp = 0xA0; 7619 if(tempbx >= 1024) temp = 0xA0;
7797 } 7620 }
7798 7621
7622 temp |= SiS_Pr->Init_P4_0E;
7623
7799 if(SiS_Pr->SiS_VBType & VB_SIS301) { 7624 if(SiS_Pr->SiS_VBType & VB_SIS301) {
7800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A; 7625 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
7626 temp &= 0xf0;
7627 temp |= 0x0A;
7628 }
7801 } 7629 }
7802 7630
7803 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp); 7631 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
@@ -7824,15 +7652,15 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7824 tempeax /= tempebx; 7652 tempeax /= tempebx;
7825 if(templong) tempeax++; 7653 if(templong) tempeax++;
7826 7654
7827 temp = (USHORT)(tempeax & 0x000000FF); 7655 temp = (unsigned short)(tempeax & 0x000000FF);
7828 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp); 7656 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
7829 temp = (USHORT)((tempeax & 0x0000FF00) >> 8); 7657 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
7830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp); 7658 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
7831 temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */ 7659 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
7832 temp |= (tempcx & 0x4F); 7660 temp |= (tempcx & 0x4F);
7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp); 7661 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
7834 7662
7835 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 7663 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
7836 7664
7837 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28); 7665 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
7838 7666
@@ -7840,23 +7668,26 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7840 tempbx = 0; 7668 tempbx = 0;
7841 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08; 7669 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
7842 tempax = SiS_Pr->SiS_VGAHDE; 7670 tempax = SiS_Pr->SiS_VGAHDE;
7843 if(modeflag & HalfDCLK) tempax >>= 1; 7671 if(modeflag & HalfDCLK) tempax >>= 1;
7844 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1; 7672 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
7845 if(tempax > 800) { 7673 if(tempax > 800) {
7846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7674 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7847 tempax -= 800; 7675 tempax -= 800;
7848 } else { /* 651+301C: Only if TVNoHiviNoYPbPr */ 7676 } else {
7849 tempbx = 0x08; 7677 tempbx = 0x08;
7850 if(tempax == 1024) tempax *= 25; 7678 if(tempax == 960) tempax *= 25; /* Correct */
7851 else tempax *= 20; 7679 else if(tempax == 1024) tempax *= 25;
7680 else tempax *= 20;
7852 temp = tempax % 32; 7681 temp = tempax % 32;
7853 tempax /= 32; 7682 tempax /= 32;
7854 if(temp) tempax++; 7683 if(temp) tempax++;
7855 tempax++; 7684 tempax++;
7856 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) || 7685 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
7857 (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) { 7686 if(resinfo == SIS_RI_1024x768 ||
7858 if(resinfo == SIS_RI_1024x768) { 7687 resinfo == SIS_RI_1024x576 ||
7859 /* Otherwise white line at right edge */ 7688 resinfo == SIS_RI_1280x1024 ||
7689 resinfo == SIS_RI_1280x720) {
7690 /* Otherwise white line or garbage at right edge */
7860 tempax = (tempax & 0xff00) | 0x20; 7691 tempax = (tempax & 0xff00) | 0x20;
7861 } 7692 }
7862 } 7693 }
@@ -7868,7 +7699,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7868 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp); 7699 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
7869 7700
7870 temp = 0x0036; tempbx = 0xD0; 7701 temp = 0x0036; tempbx = 0xD0;
7871 if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 7702 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
7872 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */ 7703 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
7873 } 7704 }
7874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7705 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7884,36 +7715,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7884 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp); 7715 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
7885 7716
7886 tempbx = SiS_Pr->SiS_HT >> 1; 7717 tempbx = SiS_Pr->SiS_HT >> 1;
7887 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1; 7718 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
7888 tempbx -= 2; 7719 tempbx -= 2;
7889 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx); 7720 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
7890 temp = (tempbx >> 5) & 0x38; 7721 temp = (tempbx >> 5) & 0x38;
7891 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp); 7722 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
7892 7723
7893 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 7724 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
7894 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7725 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
7895 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7726 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
7896 /* LCD-too-dark-error-source, see FinalizeLCD() */ 7727 /* LCD-too-dark-error-source, see FinalizeLCD() */
7897 } 7728 }
7898 if(HwInfo->jChipType >= SIS_315H) {
7899 if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
7900 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
7901 } else {
7902 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
7903 }
7904 }
7905 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
7906 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
7907#ifdef SET_EMI
7908 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
7909#endif
7910 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
7911 }
7912 } 7729 }
7913 7730
7731 SiS_SetDualLinkEtc(SiS_Pr);
7732
7914 } /* 301B */ 7733 } /* 301B */
7915 7734
7916 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 7735 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
7917} 7736}
7918 7737
7919/*********************************************/ 7738/*********************************************/
@@ -7921,8 +7740,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7921/*********************************************/ 7740/*********************************************/
7922 7741
7923static void 7742static void
7924SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7743SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
7925 PSIS_HW_INFO HwInfo)
7926{ 7744{
7927 7745
7928 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
@@ -7930,7 +7748,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7930 if(SiS_Pr->SiS_ModeType == ModeVGA) { 7748 if(SiS_Pr->SiS_ModeType == ModeVGA) {
7931 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) { 7749 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
7932 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 7750 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
7933 SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 7751 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
7934 } 7752 }
7935 } 7753 }
7936} 7754}
@@ -7939,116 +7757,156 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
7939/* MODIFY CRT1 GROUP FOR SLAVE MODE */ 7757/* MODIFY CRT1 GROUP FOR SLAVE MODE */
7940/*********************************************/ 7758/*********************************************/
7941 7759
7942static void 7760static BOOLEAN
7943SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7761SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7944 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 7762 unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
7945{ 7763 unsigned short *DisplayType)
7946 USHORT tempah,i,modeflag,j; 7764 {
7947 USHORT ResIndex,DisplayType; 7765 unsigned short modeflag = 0;
7948 const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL; 7766 BOOLEAN checkhd = TRUE;
7949 7767
7950 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7768 /* Pass 1:1 not supported here */
7951 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7769
7770 if(ModeNo <= 0x13) {
7771 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7772 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
7773 } else {
7774 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7775 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
7776 }
7777
7778 (*ResIndex) &= 0x3F;
7779
7780 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
7781
7782 (*DisplayType) = 80;
7783 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
7784 (*DisplayType) = 82;
7785 if(SiS_Pr->SiS_ModeType > ModeVGA) {
7786 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
7787 }
7788 }
7789 if((*DisplayType) != 84) {
7790 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
7791 }
7792
7793 } else {
7794
7795 (*DisplayType = 0);
7796 switch(SiS_Pr->SiS_LCDResInfo) {
7797 case Panel_320x240_1: (*DisplayType) = 50;
7798 checkhd = FALSE;
7799 break;
7800 case Panel_320x240_2: (*DisplayType) = 14;
7801 break;
7802 case Panel_320x240_3: (*DisplayType) = 18;
7803 break;
7804 case Panel_640x480: (*DisplayType) = 10;
7805 break;
7806 case Panel_1024x600: (*DisplayType) = 26;
7807 break;
7808 default: return TRUE;
7809 }
7810
7811 if(checkhd) {
7812 if(modeflag & HalfDCLK) (*DisplayType)++;
7813 }
7814
7815 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
7816 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
7817 }
7818
7819 }
7820
7821 return TRUE;
7822}
7823
7824static void
7825SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
7826 unsigned short RefreshRateTableIndex)
7827{
7828 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
7829 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
7830 static const unsigned short CRIdx[] = {
7831 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
7832 0x07, 0x10, 0x11, 0x15, 0x16
7833 };
7952 7834
7953 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 7835 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
7954 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 7836 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
7955 (SiS_Pr->SiS_CustomT == CUT_PANEL848)) 7837 (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
7838 (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
7956 return; 7839 return;
7957 7840
7841 if(SiS_Pr->SiS_IF_DEF_LVDS) {
7842 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
7843 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7844 }
7845 } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
7846 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
7847 } else return;
7848
7849 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
7850
7851 if(SiS_Pr->ChipType < SIS_315H) {
7852 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
7853 }
7854
7958 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7855 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
7959 &ResIndex, &DisplayType))) { 7856 &ResIndex, &DisplayType))) {
7960 return; 7857 return;
7961 } 7858 }
7962 7859
7963 if(HwInfo->jChipType < SIS_315H) { 7860 switch(DisplayType) {
7964 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return; 7861 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
7862 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
7863 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
7864 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
7865 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
7866 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
7867 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
7868#if 0 /* Works better with calculated numbers */
7869 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
7870 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
7871 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
7872 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
7873#endif
7874 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
7875 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
7876 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
7877 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
7878 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
7965 } 7879 }
7966 7880
7967 switch(DisplayType) { 7881 if(LVDSCRT1Ptr) {
7968 case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break; 7882
7969 case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break; 7883 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
7970 case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break; 7884
7971 case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break; 7885 for(i = 0; i <= 10; i++) {
7972 case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break; 7886 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
7973 case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break; 7887 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
7974 case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break; 7888 }
7975 case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break; 7889
7976 case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break; 7890 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
7977 case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break; 7891 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
7978 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break; 7892 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
7979 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break; 7893 }
7980 case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break; 7894
7981 case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break; 7895 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
7982 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break; 7896 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
7983 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break; 7897
7984 case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break; 7898 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
7985 case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break; 7899 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
7986 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; 7900
7987 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; 7901 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
7988 case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; 7902 if(modeflag & DoubleScanMode) tempah |= 0x80;
7989 case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; 7903 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
7990 case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */ 7904
7991 case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; 7905 } else {
7992 case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; 7906
7993 case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; 7907 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
7994 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; 7908
7995 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break; 7909 }
7996 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
7997 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
7998 case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
7999 case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
8000 case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
8001 case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
8002 case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
8003 case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
8004 case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
8005 case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
8006 case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
8007 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
8008 case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
8009 case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
8010 case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
8011 case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
8012 case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
8013 case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
8014 default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
8015 }
8016
8017 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
8018
8019 tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
8020 SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
8021
8022 for(i=0x02,j=1;i<=0x05;i++,j++){
8023 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8024 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8025 }
8026 for(i=0x06,j=5;i<=0x07;i++,j++){
8027 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8028 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8029 }
8030 for(i=0x10,j=7;i<=0x11;i++,j++){
8031 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8032 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8033 }
8034 for(i=0x15,j=9;i<=0x16;i++,j++){
8035 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8036 SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
8037 }
8038 for(i=0x0A,j=11;i<=0x0C;i++,j++){
8039 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
8040 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
8041 }
8042
8043 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8044 tempah &= 0xE0;
8045 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
8046
8047 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
8048 tempah &= 0x01;
8049 tempah <<= 5;
8050 if(modeflag & DoubleScanMode) tempah |= 0x080;
8051 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
8052} 7910}
8053 7911
8054/*********************************************/ 7912/*********************************************/
@@ -8056,24 +7914,24 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8056/*********************************************/ 7914/*********************************************/
8057 7915
8058static void 7916static void
8059SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7917SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8060 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo) 7918 unsigned short RefreshRateTableIndex)
8061{ 7919{
8062 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 7920 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8063 USHORT clkbase, vclkindex=0; 7921 unsigned short clkbase, vclkindex = 0;
8064 UCHAR sr2b, sr2c; 7922 unsigned char sr2b, sr2c;
8065 7923
8066 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 7924 if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
8067 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 7925 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
8068 if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) { 7926 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
8069 RefreshRateTableIndex--; 7927 RefreshRateTableIndex--;
8070 } 7928 }
8071 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 7929 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8072 RefreshRateTableIndex, HwInfo); 7930 RefreshRateTableIndex);
8073 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 7931 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8074 } else { 7932 } else {
8075 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 7933 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
8076 RefreshRateTableIndex, HwInfo); 7934 RefreshRateTableIndex);
8077 } 7935 }
8078 7936
8079 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B; 7937 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
@@ -8082,7 +7940,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8082 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 7940 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8083 if(SiS_Pr->SiS_UseROM) { 7941 if(SiS_Pr->SiS_UseROM) {
8084 if(ROMAddr[0x220] & 0x01) { 7942 if(ROMAddr[0x220] & 0x01) {
8085 sr2b = ROMAddr[0x227]; 7943 sr2b = ROMAddr[0x227];
8086 sr2c = ROMAddr[0x228]; 7944 sr2c = ROMAddr[0x228];
8087 } 7945 }
8088 } 7946 }
@@ -8091,7 +7949,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8091 clkbase = 0x02B; 7949 clkbase = 0x02B;
8092 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 7950 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
8093 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 7951 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
8094 clkbase += 3; 7952 clkbase += 3;
8095 } 7953 }
8096 } 7954 }
8097 7955
@@ -8111,368 +7969,331 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
8111/*********************************************/ 7969/*********************************************/
8112 7970
8113static void 7971static void
8114SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 7972SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
8115 USHORT RefreshRateTableIndex) 7973 unsigned short RefreshRateTableIndex)
8116{ 7974{
8117#if defined(SIS300) || defined(SIS315H) 7975 unsigned short TVType, resindex;
8118 USHORT temp, tempbx; 7976 const struct SiS_CHTVRegData *CHTVRegData = NULL;
8119#endif
8120 USHORT tempcl;
8121 USHORT TVType, resindex;
8122 const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
8123 7977
8124 if(ModeNo <= 0x13) 7978 if(ModeNo <= 0x13)
8125 tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 7979 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
8126 else 7980 else
8127 tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 7981 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
8128 7982
8129 TVType = 0; 7983 resindex &= 0x3F;
8130 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 7984
8131 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7985 TVType = 0;
8132 TVType += 2; 7986 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8133 if(SiS_Pr->SiS_ModeType > ModeVGA) { 7987 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8134 if(SiS_Pr->SiS_CHSOverScan) TVType = 8; 7988 TVType += 2;
8135 } 7989 if(SiS_Pr->SiS_ModeType > ModeVGA) {
8136 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7990 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
8137 TVType = 4; 7991 }
8138 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 7992 if(SiS_Pr->SiS_TVMode & TVSetPALM) {
8139 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 7993 TVType = 4;
8140 TVType = 6; 7994 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8141 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 7995 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
8142 } 7996 TVType = 6;
8143 } 7997 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
8144 switch(TVType) { 7998 }
8145 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break; 7999 }
8146 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break; 8000
8147 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break; 8001 switch(TVType) {
8148 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8002 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
8149 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break; 8003 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
8150 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break; 8004 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
8151 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break; 8005 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8152 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break; 8006 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
8153 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break; 8007 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
8154 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8008 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
8155 } 8009 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
8156 resindex = tempcl & 0x3F; 8010 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
8011 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
8012 }
8157 8013
8158 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8014
8015 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
8159 8016
8160#ifdef SIS300 8017#ifdef SIS300
8161 8018
8162 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ 8019 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
8163 8020
8164 /* We don't support modes >800x600 */ 8021 /* We don't support modes >800x600 */
8165 if (resindex > 5) return; 8022 if (resindex > 5) return;
8166 8023
8167 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8024 if(SiS_Pr->SiS_TVMode & TVSetPAL) {
8168 SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/ 8025 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
8169 SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/ 8026 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
8170 } else { 8027 } else {
8171 SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/ 8028 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
8172 SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/ 8029 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
8173 } 8030 }
8174 8031
8175 temp = CHTVRegData[resindex].Reg[0]; 8032 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
8176 tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */ 8033 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
8177 SiS_SetCH700x(SiS_Pr,tempbx); 8034 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
8178 temp = CHTVRegData[resindex].Reg[1]; 8035 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
8179 tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */ 8036 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
8180 SiS_SetCH700x(SiS_Pr,tempbx); 8037
8181 temp = CHTVRegData[resindex].Reg[2]; 8038 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8182 tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
8183 SiS_SetCH700x(SiS_Pr,tempbx);
8184 temp = CHTVRegData[resindex].Reg[3];
8185 tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
8186 SiS_SetCH700x(SiS_Pr,tempbx);
8187 temp = CHTVRegData[resindex].Reg[4];
8188 tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
8189 SiS_SetCH700x(SiS_Pr,tempbx);
8190
8191 /* Set minimum flicker filter for Luma channel (SR1-0=00),
8192 minimum text enhancement (S3-2=10), 8039 minimum text enhancement (S3-2=10),
8193 maximum flicker filter for Chroma channel (S5-4=10) 8040 maximum flicker filter for Chroma channel (S5-4=10)
8194 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!) 8041 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
8195 */ 8042 */
8196 SiS_SetCH700x(SiS_Pr,0x2801); 8043 SiS_SetCH700x(SiS_Pr,0x01,0x28);
8197 8044
8198 /* Set video bandwidth 8045 /* Set video bandwidth
8199 High bandwith Luma composite video filter(S0=1) 8046 High bandwith Luma composite video filter(S0=1)
8200 low bandwith Luma S-video filter (S2-1=00) 8047 low bandwith Luma S-video filter (S2-1=00)
8201 disable peak filter in S-video channel (S3=0) 8048 disable peak filter in S-video channel (S3=0)
8202 high bandwidth Chroma Filter (S5-4=11) 8049 high bandwidth Chroma Filter (S5-4=11)
8203 =00110001=0x31 8050 =00110001=0x31
8204 */ 8051 */
8205 SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */ 8052 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
8206 8053
8207 /* Register 0x3D does not exist in non-macrovision register map 8054 /* Register 0x3D does not exist in non-macrovision register map
8208 (Maybe this is a macrovision register?) 8055 (Maybe this is a macrovision register?)
8209 */ 8056 */
8210#ifndef SIS_CP 8057#ifndef SIS_CP
8211 SiS_SetCH70xx(SiS_Pr,0x003D); 8058 SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
8212#endif 8059#endif
8213 8060
8214 /* Register 0x10 only contains 1 writable bit (S0) for sensing, 8061 /* Register 0x10 only contains 1 writable bit (S0) for sensing,
8215 all other bits a read-only. Macrovision? 8062 all other bits a read-only. Macrovision?
8216 */ 8063 */
8217 SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F); 8064 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
8218 8065
8219 /* Register 0x11 only contains 3 writable bits (S0-S2) for 8066 /* Register 0x11 only contains 3 writable bits (S0-S2) for
8220 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) ) 8067 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
8221 */ 8068 */
8222 SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8); 8069 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
8223 8070
8224 /* Clear DSEN 8071 /* Clear DSEN
8225 */ 8072 */
8226 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF); 8073 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
8227 8074
8228 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */ 8075 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
8229 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) { 8076 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
8230 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */ 8077 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
8231 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ 8078 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8232 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */ 8079 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
8233 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */ 8080 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
8234 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */ 8081 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
8235 SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0); 8082 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
8236 SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0); 8083 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
8237 SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0); 8084 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
8238 SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0); 8085 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
8239 SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0); 8086 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
8240 SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0); 8087 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
8241 SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0); 8088 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
8242 SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */ 8089 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
8243 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */ 8090 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
8244 } 8091 }
8245 } else { 8092 } else {
8246 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */ 8093 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
8247 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ 8094 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8248 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); 8095 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8249 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */ 8096 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
8250#if 0 8097#if 0
8251 SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */ 8098 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
8252 SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */ 8099 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
8253 SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */ 8100 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
8254 SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0); 8101 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
8255 SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0); 8102 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
8256 SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0); 8103 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
8257 SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0); 8104 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
8258 SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0); 8105 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
8259 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */ 8106 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
8260 SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */ 8107 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
8261#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */ 8108#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
8262 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ 8109 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8263 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); 8110 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
8111 }
8264 } 8112 }
8265 } 8113 } else { /* ---- PAL ---- */
8266 } else { /* ---- PAL ---- */ 8114 /* We don't play around with FSCI in PAL mode */
8267 /* We don't play around with FSCI in PAL mode */
8268 if(resindex == 0x04) { 8115 if(resindex == 0x04) {
8269 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ 8116 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8270 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */ 8117 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8271 } else { 8118 } else {
8272 SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */ 8119 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
8273 SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */ 8120 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
8274 } 8121 }
8275 } 8122 }
8276 8123
8277#endif /* 300 */ 8124#endif /* 300 */
8278 8125
8279 } else { 8126 } else {
8280 8127
8281 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ 8128 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
8282 8129
8283#ifdef SIS315H 8130#ifdef SIS315H
8284 8131
8285 /* We don't support modes >1024x768 */ 8132 unsigned short temp;
8286 if (resindex > 6) return; 8133
8287 8134 /* We don't support modes >1024x768 */
8288 temp = CHTVRegData[resindex].Reg[0]; 8135 if (resindex > 6) return;
8289 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 8136
8290 temp |= 0x10; 8137 temp = CHTVRegData[resindex].Reg[0];
8291 } 8138 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
8292 tempbx=((temp & 0x00FF) << 8) | 0x00; 8139 SiS_SetCH701x(SiS_Pr,0x00,temp);
8293 SiS_SetCH701x(SiS_Pr,tempbx); 8140
8294 8141 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
8295 temp = CHTVRegData[resindex].Reg[1]; 8142 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
8296 tempbx=((temp & 0x00FF) << 8) | 0x01; 8143 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
8297 SiS_SetCH701x(SiS_Pr,tempbx); 8144 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
8298 8145 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
8299 temp = CHTVRegData[resindex].Reg[2]; 8146 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
8300 tempbx=((temp & 0x00FF) << 8) | 0x02; 8147
8301 SiS_SetCH701x(SiS_Pr,tempbx); 8148 temp = CHTVRegData[resindex].Reg[7];
8302 8149 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
8303 temp = CHTVRegData[resindex].Reg[3]; 8150 SiS_SetCH701x(SiS_Pr,0x07,temp);
8304 tempbx=((temp & 0x00FF) << 8) | 0x04; 8151
8305 SiS_SetCH701x(SiS_Pr,tempbx); 8152 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
8306 8153 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
8307 temp = CHTVRegData[resindex].Reg[4]; 8154 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
8308 tempbx=((temp & 0x00FF) << 8) | 0x03; 8155 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
8309 SiS_SetCH701x(SiS_Pr,tempbx); 8156 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
8310 8157 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
8311 temp = CHTVRegData[resindex].Reg[5]; 8158 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
8312 tempbx=((temp & 0x00FF) << 8) | 0x05; 8159 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
8313 SiS_SetCH701x(SiS_Pr,tempbx); 8160
8314 8161 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8315 temp = CHTVRegData[resindex].Reg[6]; 8162 /* D1 should be set for PAL, PAL-N and NTSC-J,
8316 tempbx=((temp & 0x00FF) << 8) | 0x06; 8163 but I won't do that for PAL unless somebody
8317 SiS_SetCH701x(SiS_Pr,tempbx); 8164 tells me to do so. Since the BIOS uses
8318 8165 non-default CIV values and blacklevels,
8319 temp = CHTVRegData[resindex].Reg[7]; 8166 this might be compensated anyway.
8320 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 8167 */
8321 temp = 0x66; 8168 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8322 } 8169 SiS_SetCH701x(SiS_Pr,0x21,temp);
8323 tempbx=((temp & 0x00FF) << 8) | 0x07;
8324 SiS_SetCH701x(SiS_Pr,tempbx);
8325
8326 temp = CHTVRegData[resindex].Reg[8];
8327 tempbx=((temp & 0x00FF) << 8) | 0x08;
8328 SiS_SetCH701x(SiS_Pr,tempbx);
8329
8330 temp = CHTVRegData[resindex].Reg[9];
8331 tempbx=((temp & 0x00FF) << 8) | 0x15;
8332 SiS_SetCH701x(SiS_Pr,tempbx);
8333
8334 temp = CHTVRegData[resindex].Reg[10];
8335 tempbx=((temp & 0x00FF) << 8) | 0x1f;
8336 SiS_SetCH701x(SiS_Pr,tempbx);
8337
8338 temp = CHTVRegData[resindex].Reg[11];
8339 tempbx=((temp & 0x00FF) << 8) | 0x0c;
8340 SiS_SetCH701x(SiS_Pr,tempbx);
8341
8342 temp = CHTVRegData[resindex].Reg[12];
8343 tempbx=((temp & 0x00FF) << 8) | 0x0d;
8344 SiS_SetCH701x(SiS_Pr,tempbx);
8345
8346 temp = CHTVRegData[resindex].Reg[13];
8347 tempbx=((temp & 0x00FF) << 8) | 0x0e;
8348 SiS_SetCH701x(SiS_Pr,tempbx);
8349
8350 temp = CHTVRegData[resindex].Reg[14];
8351 tempbx=((temp & 0x00FF) << 8) | 0x0f;
8352 SiS_SetCH701x(SiS_Pr,tempbx);
8353
8354 temp = CHTVRegData[resindex].Reg[15];
8355 tempbx=((temp & 0x00FF) << 8) | 0x10;
8356 SiS_SetCH701x(SiS_Pr,tempbx);
8357
8358 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
8359 /* D1 should be set for PAL, PAL-N and NTSC-J,
8360 but I won't do that for PAL unless somebody
8361 tells me to do so. Since the BIOS uses
8362 non-default CIV values and blacklevels,
8363 this might be compensated anyway.
8364 */
8365 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
8366 SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
8367 8170
8368#endif /* 315 */ 8171#endif /* 315 */
8369 8172
8370 } 8173 }
8371 8174
8372#ifdef SIS_CP 8175#ifdef SIS_CP
8373 SIS_CP_INIT301_CP3 8176 SIS_CP_INIT301_CP3
8374#endif 8177#endif
8375 8178
8376} 8179}
8377 8180
8181#ifdef SIS315H /* ----------- 315 series only ---------- */
8182
8378void 8183void
8379SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8184SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
8380{ 8185{
8381 USHORT temp; 8186 unsigned short temp;
8382 8187
8383 /* Enable Chrontel 7019 LCD panel backlight */ 8188 /* Enable Chrontel 7019 LCD panel backlight */
8384 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8189 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8385 if(HwInfo->jChipType == SIS_740) { 8190 if(SiS_Pr->ChipType == SIS_740) {
8386 SiS_SetCH701x(SiS_Pr,0x6566); 8191 SiS_SetCH701x(SiS_Pr,0x66,0x65);
8387 } else { 8192 } else {
8388 temp = SiS_GetCH701x(SiS_Pr,0x66); 8193 temp = SiS_GetCH701x(SiS_Pr,0x66);
8389 temp |= 0x20; 8194 temp |= 0x20;
8390 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); 8195 SiS_SetCH701x(SiS_Pr,0x66,temp);
8391 } 8196 }
8392 } 8197 }
8393} 8198}
8394 8199
8395void 8200void
8396SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr) 8201SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
8397{ 8202{
8398 USHORT temp; 8203 unsigned short temp;
8399 8204
8400 /* Disable Chrontel 7019 LCD panel backlight */ 8205 /* Disable Chrontel 7019 LCD panel backlight */
8401 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8206 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8402 temp = SiS_GetCH701x(SiS_Pr,0x66); 8207 temp = SiS_GetCH701x(SiS_Pr,0x66);
8403 temp &= 0xDF; 8208 temp &= 0xDF;
8404 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); 8209 SiS_SetCH701x(SiS_Pr,0x66,temp);
8405 } 8210 }
8406} 8211}
8407 8212
8408#ifdef SIS315H /* ----------- 315 series only ---------- */
8409
8410static void 8213static void
8411SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8214SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
8412{ 8215{
8413 UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b }; 8216 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
8414 UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 }; 8217 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
8415 UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 }; 8218 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
8416 UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8219 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8417 UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8220 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
8418 UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8221 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8419 UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8222 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
8420 UCHAR *tableptr = NULL; 8223 const unsigned char *tableptr = NULL;
8421 int i; 8224 int i;
8422 8225
8423 /* Set up Power up/down timing */ 8226 /* Set up Power up/down timing */
8424 8227
8425 if(HwInfo->jChipType == SIS_740) { 8228 if(SiS_Pr->ChipType == SIS_740) {
8426 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8229 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8427 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740; 8230 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
8428 else tableptr = table1024_740; 8231 else tableptr = table1024_740;
8429 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8232 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8430 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8233 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8431 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8234 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8432 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740; 8235 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
8433 else tableptr = table1400_740; 8236 else tableptr = table1400_740;
8434 } else return; 8237 } else return;
8435 } else { 8238 } else {
8436 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8239 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
8437 tableptr = table1024_650; 8240 tableptr = table1024_650;
8438 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8241 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
8439 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8242 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
8440 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8243 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
8441 tableptr = table1400_650; 8244 tableptr = table1400_650;
8442 } else return; 8245 } else return;
8443 } 8246 }
8444 8247
8445 for(i=0; i<5; i++) { 8248 for(i=0; i<5; i++) {
8446 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]); 8249 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8447 } 8250 }
8448} 8251}
8449 8252
8450static void 8253static void
8451SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8254SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
8452{ 8255{
8453 UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71, 8256 const unsigned char *tableptr = NULL;
8454 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 }; 8257 unsigned short tempbh;
8455 UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8456 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
8457 UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8458 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8459 UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8460 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
8461 UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8462 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
8463 UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8464 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
8465 UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8466 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
8467 UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8468 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
8469 UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8470 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
8471 UCHAR *tableptr = NULL;
8472 USHORT tempbh;
8473 int i; 8258 int i;
8259 static const unsigned char regtable[] = {
8260 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
8261 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
8262 };
8263 static const unsigned char table1024_740[] = {
8264 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8265 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
8266 };
8267 static const unsigned char table1280_740[] = {
8268 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8269 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8270 };
8271 static const unsigned char table1400_740[] = {
8272 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8273 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
8274 };
8275 static const unsigned char table1600_740[] = {
8276 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8277 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
8278 };
8279 static const unsigned char table1024_650[] = {
8280 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
8281 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
8282 };
8283 static const unsigned char table1280_650[] = {
8284 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
8285 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
8286 };
8287 static const unsigned char table1400_650[] = {
8288 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
8289 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
8290 };
8291 static const unsigned char table1600_650[] = {
8292 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
8293 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
8294 };
8474 8295
8475 if(HwInfo->jChipType == SIS_740) { 8296 if(SiS_Pr->ChipType == SIS_740) {
8476 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740; 8297 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740; 8298 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740; 8299 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
@@ -8499,138 +8320,139 @@ SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8499 } 8320 }
8500 } 8321 }
8501 8322
8502 if(HwInfo->jChipType == SIS_740) tempbh = 0x0d; 8323 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
8503 else tempbh = 0x0c; 8324 else tempbh = 0x0c;
8504 8325
8505 for(i = 0; i < tempbh; i++) { 8326 for(i = 0; i < tempbh; i++) {
8506 SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]); 8327 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
8507 } 8328 }
8508 SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo); 8329 SiS_ChrontelPowerSequencing(SiS_Pr);
8509 tempbh = SiS_GetCH701x(SiS_Pr,0x1e); 8330 tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
8510 tempbh |= 0xc0; 8331 tempbh |= 0xc0;
8511 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e); 8332 SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
8512 8333
8513 if(HwInfo->jChipType == SIS_740) { 8334 if(SiS_Pr->ChipType == SIS_740) {
8514 tempbh = SiS_GetCH701x(SiS_Pr,0x1c); 8335 tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
8515 tempbh &= 0xfb; 8336 tempbh &= 0xfb;
8516 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c); 8337 SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
8517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8338 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8518 tempbh = SiS_GetCH701x(SiS_Pr,0x64); 8339 tempbh = SiS_GetCH701x(SiS_Pr,0x64);
8519 tempbh |= 0x40; 8340 tempbh |= 0x40;
8520 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64); 8341 SiS_SetCH701x(SiS_Pr,0x64,tempbh);
8521 tempbh = SiS_GetCH701x(SiS_Pr,0x03); 8342 tempbh = SiS_GetCH701x(SiS_Pr,0x03);
8522 tempbh &= 0x3f; 8343 tempbh &= 0x3f;
8523 SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03); 8344 SiS_SetCH701x(SiS_Pr,0x03,tempbh);
8524 } 8345 }
8525} 8346}
8526 8347
8527static void 8348static void
8528SiS_ChrontelResetVSync(SiS_Private *SiS_Pr) 8349SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
8529{ 8350{
8530 unsigned char temp, temp1; 8351 unsigned char temp, temp1;
8531 8352
8532 temp1 = SiS_GetCH701x(SiS_Pr,0x49); 8353 temp1 = SiS_GetCH701x(SiS_Pr,0x49);
8533 SiS_SetCH701x(SiS_Pr,0x3e49); 8354 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8534 temp = SiS_GetCH701x(SiS_Pr,0x47); 8355 temp = SiS_GetCH701x(SiS_Pr,0x47);
8535 temp &= 0x7f; /* Use external VSYNC */ 8356 temp &= 0x7f; /* Use external VSYNC */
8536 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); 8357 SiS_SetCH701x(SiS_Pr,0x47,temp);
8537 SiS_LongDelay(SiS_Pr,3); 8358 SiS_LongDelay(SiS_Pr, 3);
8538 temp = SiS_GetCH701x(SiS_Pr,0x47); 8359 temp = SiS_GetCH701x(SiS_Pr,0x47);
8539 temp |= 0x80; /* Use internal VSYNC */ 8360 temp |= 0x80; /* Use internal VSYNC */
8540 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); 8361 SiS_SetCH701x(SiS_Pr,0x47,temp);
8541 SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49); 8362 SiS_SetCH701x(SiS_Pr,0x49,temp1);
8542} 8363}
8543 8364
8544static void 8365static void
8545SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8366SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
8546{ 8367{
8547 USHORT temp; 8368 unsigned short temp;
8548 8369
8549 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8370 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8550 if(HwInfo->jChipType == SIS_740) { 8371 if(SiS_Pr->ChipType == SIS_740) {
8551 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8372 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8552 temp |= 0x04; /* Invert XCLK phase */ 8373 temp |= 0x04; /* Invert XCLK phase */
8553 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c); 8374 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8554 } 8375 }
8555 if(SiS_IsYPbPr(SiS_Pr, HwInfo)) { 8376 if(SiS_IsYPbPr(SiS_Pr)) {
8556 temp = SiS_GetCH701x(SiS_Pr,0x01); 8377 temp = SiS_GetCH701x(SiS_Pr,0x01);
8557 temp &= 0x3f; 8378 temp &= 0x3f;
8558 temp |= 0x80; /* Enable YPrPb (HDTV) */ 8379 temp |= 0x80; /* Enable YPrPb (HDTV) */
8559 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01); 8380 SiS_SetCH701x(SiS_Pr,0x01,temp);
8560 } 8381 }
8561 if(SiS_IsChScart(SiS_Pr, HwInfo)) { 8382 if(SiS_IsChScart(SiS_Pr)) {
8562 temp = SiS_GetCH701x(SiS_Pr,0x01); 8383 temp = SiS_GetCH701x(SiS_Pr,0x01);
8563 temp &= 0x3f; 8384 temp &= 0x3f;
8564 temp |= 0xc0; /* Enable SCART + CVBS */ 8385 temp |= 0xc0; /* Enable SCART + CVBS */
8565 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01); 8386 SiS_SetCH701x(SiS_Pr,0x01,temp);
8566 } 8387 }
8567 if(HwInfo->jChipType == SIS_740) { 8388 if(SiS_Pr->ChipType == SIS_740) {
8568 SiS_ChrontelResetVSync(SiS_Pr); 8389 SiS_ChrontelResetVSync(SiS_Pr);
8569 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */ 8390 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8570 } else { 8391 } else {
8571 SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */ 8392 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
8572 temp = SiS_GetCH701x(SiS_Pr,0x49); 8393 temp = SiS_GetCH701x(SiS_Pr,0x49);
8573 if(SiS_IsYPbPr(SiS_Pr,HwInfo)) { 8394 if(SiS_IsYPbPr(SiS_Pr)) {
8574 temp = SiS_GetCH701x(SiS_Pr,0x73); 8395 temp = SiS_GetCH701x(SiS_Pr,0x73);
8575 temp |= 0x60; 8396 temp |= 0x60;
8576 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73); 8397 SiS_SetCH701x(SiS_Pr,0x73,temp);
8577 } 8398 }
8578 temp = SiS_GetCH701x(SiS_Pr,0x47); 8399 temp = SiS_GetCH701x(SiS_Pr,0x47);
8579 temp &= 0x7f; 8400 temp &= 0x7f;
8580 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); 8401 SiS_SetCH701x(SiS_Pr,0x47,temp);
8581 SiS_LongDelay(SiS_Pr,2); 8402 SiS_LongDelay(SiS_Pr, 2);
8582 temp = SiS_GetCH701x(SiS_Pr,0x47); 8403 temp = SiS_GetCH701x(SiS_Pr,0x47);
8583 temp |= 0x80; 8404 temp |= 0x80;
8584 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); 8405 SiS_SetCH701x(SiS_Pr,0x47,temp);
8585 } 8406 }
8586 } 8407 }
8587} 8408}
8588 8409
8589static void 8410static void
8590SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8411SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
8591{ 8412{
8592 USHORT temp; 8413 unsigned short temp;
8593 8414
8594 /* Complete power down of LVDS */ 8415 /* Complete power down of LVDS */
8595 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8416 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8596 if(HwInfo->jChipType == SIS_740) { 8417 if(SiS_Pr->ChipType == SIS_740) {
8597 SiS_LongDelay(SiS_Pr,1); 8418 SiS_LongDelay(SiS_Pr, 1);
8598 SiS_GenericDelay(SiS_Pr,0x16ff); 8419 SiS_GenericDelay(SiS_Pr, 5887);
8599 SiS_SetCH701x(SiS_Pr,0xac76); 8420 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8600 SiS_SetCH701x(SiS_Pr,0x0066); 8421 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8601 } else { 8422 } else {
8602 SiS_LongDelay(SiS_Pr,2); 8423 SiS_LongDelay(SiS_Pr, 2);
8603 temp = SiS_GetCH701x(SiS_Pr,0x76); 8424 temp = SiS_GetCH701x(SiS_Pr,0x76);
8604 temp &= 0xfc; 8425 temp &= 0xfc;
8605 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); 8426 SiS_SetCH701x(SiS_Pr,0x76,temp);
8606 SiS_SetCH701x(SiS_Pr,0x0066); 8427 SiS_SetCH701x(SiS_Pr,0x66,0x00);
8607 } 8428 }
8608 } 8429 }
8609} 8430}
8610 8431
8611static void 8432static void
8612SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8433SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
8613{ 8434{
8614 USHORT temp; 8435 unsigned short temp;
8615 8436
8616 if(HwInfo->jChipType == SIS_740) { 8437 if(SiS_Pr->ChipType == SIS_740) {
8617 8438
8618 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */ 8439 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
8619 temp &= 0x01; 8440 temp &= 0x01;
8620 if(!temp) { 8441 if(!temp) {
8621 8442
8622 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) { 8443 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8623 temp = SiS_GetCH701x(SiS_Pr,0x49); 8444 temp = SiS_GetCH701x(SiS_Pr,0x49);
8624 SiS_SetCH701x(SiS_Pr,0x3e49); 8445 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
8625 } 8446 }
8447
8626 /* Reset Chrontel 7019 datapath */ 8448 /* Reset Chrontel 7019 datapath */
8627 SiS_SetCH701x(SiS_Pr,0x1048); 8449 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8628 SiS_LongDelay(SiS_Pr,1); 8450 SiS_LongDelay(SiS_Pr, 1);
8629 SiS_SetCH701x(SiS_Pr,0x1848); 8451 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8630 8452
8631 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) { 8453 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8632 SiS_ChrontelResetVSync(SiS_Pr); 8454 SiS_ChrontelResetVSync(SiS_Pr);
8633 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49); 8455 SiS_SetCH701x(SiS_Pr,0x49,temp);
8634 } 8456 }
8635 8457
8636 } else { 8458 } else {
@@ -8638,72 +8460,72 @@ SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8638 /* Clear/set/clear GPIO */ 8460 /* Clear/set/clear GPIO */
8639 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8461 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8640 temp &= 0xef; 8462 temp &= 0xef;
8641 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); 8463 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8642 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8464 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8643 temp |= 0x10; 8465 temp |= 0x10;
8644 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); 8466 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8645 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8467 temp = SiS_GetCH701x(SiS_Pr,0x5c);
8646 temp &= 0xef; 8468 temp &= 0xef;
8647 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c); 8469 SiS_SetCH701x(SiS_Pr,0x5c,temp);
8648 temp = SiS_GetCH701x(SiS_Pr,0x61); 8470 temp = SiS_GetCH701x(SiS_Pr,0x61);
8649 if(!temp) { 8471 if(!temp) {
8650 SiS_SetCH701xForLCD(SiS_Pr, HwInfo); 8472 SiS_SetCH701xForLCD(SiS_Pr);
8651 } 8473 }
8652 } 8474 }
8653 8475
8654 } else { /* 650 */ 8476 } else { /* 650 */
8655 /* Reset Chrontel 7019 datapath */ 8477 /* Reset Chrontel 7019 datapath */
8656 SiS_SetCH701x(SiS_Pr,0x1048); 8478 SiS_SetCH701x(SiS_Pr,0x48,0x10);
8657 SiS_LongDelay(SiS_Pr,1); 8479 SiS_LongDelay(SiS_Pr, 1);
8658 SiS_SetCH701x(SiS_Pr,0x1848); 8480 SiS_SetCH701x(SiS_Pr,0x48,0x18);
8659 } 8481 }
8660} 8482}
8661 8483
8662static void 8484static void
8663SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8485SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
8664{ 8486{
8665 USHORT temp; 8487 unsigned short temp;
8666 8488
8667 if(HwInfo->jChipType == SIS_740) { 8489 if(SiS_Pr->ChipType == SIS_740) {
8668 8490
8669 if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) { 8491 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8670 SiS_ChrontelResetVSync(SiS_Pr); 8492 SiS_ChrontelResetVSync(SiS_Pr);
8671 } 8493 }
8672 8494
8673 } else { 8495 } else {
8674 8496
8675 SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */ 8497 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
8676 temp = SiS_GetCH701x(SiS_Pr,0x49); 8498 temp = SiS_GetCH701x(SiS_Pr,0x49);
8677 temp &= 1; 8499 temp &= 1;
8678 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */ 8500 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
8679 temp = SiS_GetCH701x(SiS_Pr,0x47); 8501 temp = SiS_GetCH701x(SiS_Pr,0x47);
8680 temp &= 0x70; 8502 temp &= 0x70;
8681 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */ 8503 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
8682 SiS_LongDelay(SiS_Pr,3); 8504 SiS_LongDelay(SiS_Pr, 3);
8683 temp = SiS_GetCH701x(SiS_Pr,0x47); 8505 temp = SiS_GetCH701x(SiS_Pr,0x47);
8684 temp |= 0x80; 8506 temp |= 0x80;
8685 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */ 8507 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
8686 } 8508 }
8687 8509
8688 } 8510 }
8689} 8511}
8690 8512
8691static void 8513static void
8692SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo) 8514SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8693{ 8515{
8694 USHORT temp,temp1; 8516 unsigned short temp,temp1;
8695 8517
8696 if(HwInfo->jChipType == SIS_740) { 8518 if(SiS_Pr->ChipType == SIS_740) {
8697 8519
8698 temp = SiS_GetCH701x(SiS_Pr,0x61); 8520 temp = SiS_GetCH701x(SiS_Pr,0x61);
8699 if(temp < 1) { 8521 if(temp < 1) {
8700 temp++; 8522 temp++;
8701 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61); 8523 SiS_SetCH701x(SiS_Pr,0x61,temp);
8702 } 8524 }
8703 SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */ 8525 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
8704 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */ 8526 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
8705 SiS_LongDelay(SiS_Pr,1); 8527 SiS_LongDelay(SiS_Pr, 1);
8706 SiS_GenericDelay(SiS_Pr,0x16ff); 8528 SiS_GenericDelay(SiS_Pr, 5887);
8707 8529
8708 } else { /* 650 */ 8530 } else { /* 650 */
8709 8531
@@ -8711,38 +8533,38 @@ SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo
8711 temp = SiS_GetCH701x(SiS_Pr,0x61); 8533 temp = SiS_GetCH701x(SiS_Pr,0x61);
8712 if(temp < 2) { 8534 if(temp < 2) {
8713 temp++; 8535 temp++;
8714 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61); 8536 SiS_SetCH701x(SiS_Pr,0x61,temp);
8715 temp1 = 1; 8537 temp1 = 1;
8716 } 8538 }
8717 SiS_SetCH701x(SiS_Pr,0xac76); 8539 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8718 temp = SiS_GetCH701x(SiS_Pr,0x66); 8540 temp = SiS_GetCH701x(SiS_Pr,0x66);
8719 temp |= 0x5f; 8541 temp |= 0x5f;
8720 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); 8542 SiS_SetCH701x(SiS_Pr,0x66,temp);
8721 if(ModeNo > 0x13) { 8543 if(ModeNo > 0x13) {
8722 if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) { 8544 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
8723 SiS_GenericDelay(SiS_Pr,0x3ff); 8545 SiS_GenericDelay(SiS_Pr, 1023);
8724 } else { 8546 } else {
8725 SiS_GenericDelay(SiS_Pr,0x2ff); 8547 SiS_GenericDelay(SiS_Pr, 767);
8726 } 8548 }
8727 } else { 8549 } else {
8728 if(!temp1) 8550 if(!temp1)
8729 SiS_GenericDelay(SiS_Pr,0x2ff); 8551 SiS_GenericDelay(SiS_Pr, 767);
8730 } 8552 }
8731 temp = SiS_GetCH701x(SiS_Pr,0x76); 8553 temp = SiS_GetCH701x(SiS_Pr,0x76);
8732 temp |= 0x03; 8554 temp |= 0x03;
8733 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); 8555 SiS_SetCH701x(SiS_Pr,0x76,temp);
8734 temp = SiS_GetCH701x(SiS_Pr,0x66); 8556 temp = SiS_GetCH701x(SiS_Pr,0x66);
8735 temp &= 0x7f; 8557 temp &= 0x7f;
8736 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66); 8558 SiS_SetCH701x(SiS_Pr,0x66,temp);
8737 SiS_LongDelay(SiS_Pr,1); 8559 SiS_LongDelay(SiS_Pr, 1);
8738 8560
8739 } 8561 }
8740} 8562}
8741 8563
8742static void 8564static void
8743SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8565SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
8744{ 8566{
8745 USHORT temp,tempcl,tempch; 8567 unsigned short temp,tempcl,tempch;
8746 8568
8747 SiS_LongDelay(SiS_Pr, 1); 8569 SiS_LongDelay(SiS_Pr, 1);
8748 tempcl = 3; 8570 tempcl = 3;
@@ -8753,87 +8575,87 @@ SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8753 temp &= 0x04; /* PLL stable? -> bail out */ 8575 temp &= 0x04; /* PLL stable? -> bail out */
8754 if(temp == 0x04) break; 8576 if(temp == 0x04) break;
8755 8577
8756 if(HwInfo->jChipType == SIS_740) { 8578 if(SiS_Pr->ChipType == SIS_740) {
8757 /* Power down LVDS output, PLL normal operation */ 8579 /* Power down LVDS output, PLL normal operation */
8758 SiS_SetCH701x(SiS_Pr,0xac76); 8580 SiS_SetCH701x(SiS_Pr,0x76,0xac);
8759 } 8581 }
8760 8582
8761 SiS_SetCH701xForLCD(SiS_Pr,HwInfo); 8583 SiS_SetCH701xForLCD(SiS_Pr);
8762 8584
8763 if(tempcl == 0) { 8585 if(tempcl == 0) {
8764 if(tempch == 3) break; 8586 if(tempch == 3) break;
8765 SiS_ChrontelResetDB(SiS_Pr,HwInfo); 8587 SiS_ChrontelResetDB(SiS_Pr);
8766 tempcl = 3; 8588 tempcl = 3;
8767 tempch++; 8589 tempch++;
8768 } 8590 }
8769 tempcl--; 8591 tempcl--;
8770 temp = SiS_GetCH701x(SiS_Pr,0x76); 8592 temp = SiS_GetCH701x(SiS_Pr,0x76);
8771 temp &= 0xfb; /* Reset PLL */ 8593 temp &= 0xfb; /* Reset PLL */
8772 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); 8594 SiS_SetCH701x(SiS_Pr,0x76,temp);
8773 SiS_LongDelay(SiS_Pr,2); 8595 SiS_LongDelay(SiS_Pr, 2);
8774 temp = SiS_GetCH701x(SiS_Pr,0x76); 8596 temp = SiS_GetCH701x(SiS_Pr,0x76);
8775 temp |= 0x04; /* PLL normal operation */ 8597 temp |= 0x04; /* PLL normal operation */
8776 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76); 8598 SiS_SetCH701x(SiS_Pr,0x76,temp);
8777 if(HwInfo->jChipType == SIS_740) { 8599 if(SiS_Pr->ChipType == SIS_740) {
8778 SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */ 8600 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
8779 } else { 8601 } else {
8780 SiS_SetCH701x(SiS_Pr,0x6078); 8602 SiS_SetCH701x(SiS_Pr,0x78,0x60);
8781 } 8603 }
8782 SiS_LongDelay(SiS_Pr,2); 8604 SiS_LongDelay(SiS_Pr, 2);
8783 } while(0); 8605 } while(0);
8784 8606
8785 SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */ 8607 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
8786} 8608}
8787 8609
8788static void 8610static void
8789SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8611SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
8790{ 8612{
8791 USHORT temp; 8613 unsigned short temp;
8792 8614
8793 temp = SiS_GetCH701x(SiS_Pr,0x03); 8615 temp = SiS_GetCH701x(SiS_Pr,0x03);
8794 temp |= 0x80; /* Set datapath 1 to TV */ 8616 temp |= 0x80; /* Set datapath 1 to TV */
8795 temp &= 0xbf; /* Set datapath 2 to LVDS */ 8617 temp &= 0xbf; /* Set datapath 2 to LVDS */
8796 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03); 8618 SiS_SetCH701x(SiS_Pr,0x03,temp);
8797 8619
8798 if(HwInfo->jChipType == SIS_740) { 8620 if(SiS_Pr->ChipType == SIS_740) {
8799 8621
8800 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8622 temp = SiS_GetCH701x(SiS_Pr,0x1c);
8801 temp &= 0xfb; /* Normal XCLK phase */ 8623 temp &= 0xfb; /* Normal XCLK phase */
8802 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c); 8624 SiS_SetCH701x(SiS_Pr,0x1c,temp);
8803 8625
8804 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8626 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
8805 8627
8806 temp = SiS_GetCH701x(SiS_Pr,0x64); 8628 temp = SiS_GetCH701x(SiS_Pr,0x64);
8807 temp |= 0x40; /* ? Bit not defined */ 8629 temp |= 0x40; /* ? Bit not defined */
8808 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64); 8630 SiS_SetCH701x(SiS_Pr,0x64,temp);
8809 8631
8810 temp = SiS_GetCH701x(SiS_Pr,0x03); 8632 temp = SiS_GetCH701x(SiS_Pr,0x03);
8811 temp &= 0x3f; /* D1 input to both LVDS and TV */ 8633 temp &= 0x3f; /* D1 input to both LVDS and TV */
8812 SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03); 8634 SiS_SetCH701x(SiS_Pr,0x03,temp);
8813 8635
8814 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) { 8636 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
8815 SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */ 8637 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
8816 SiS_LongDelay(SiS_Pr, 1); 8638 SiS_LongDelay(SiS_Pr, 1);
8817 SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */ 8639 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
8818 SiS_ChrontelResetDB(SiS_Pr, HwInfo); 8640 SiS_ChrontelResetDB(SiS_Pr);
8819 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo); 8641 SiS_ChrontelDoSomething2(SiS_Pr);
8820 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo); 8642 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8821 } else { 8643 } else {
8822 temp = SiS_GetCH701x(SiS_Pr,0x66); 8644 temp = SiS_GetCH701x(SiS_Pr,0x66);
8823 if(temp != 0x45) { 8645 if(temp != 0x45) {
8824 SiS_ChrontelResetDB(SiS_Pr, HwInfo); 8646 SiS_ChrontelResetDB(SiS_Pr);
8825 SiS_ChrontelDoSomething2(SiS_Pr, HwInfo); 8647 SiS_ChrontelDoSomething2(SiS_Pr);
8826 SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo); 8648 SiS_ChrontelDoSomething3(SiS_Pr, 0);
8827 } 8649 }
8828 } 8650 }
8829 8651
8830 } else { /* 650 */ 8652 } else { /* 650 */
8831 8653
8832 SiS_ChrontelResetDB(SiS_Pr,HwInfo); 8654 SiS_ChrontelResetDB(SiS_Pr);
8833 SiS_ChrontelDoSomething2(SiS_Pr,HwInfo); 8655 SiS_ChrontelDoSomething2(SiS_Pr);
8834 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34); 8656 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
8835 SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo); 8657 SiS_ChrontelDoSomething3(SiS_Pr,temp);
8836 SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */ 8658 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
8837 8659
8838 } 8660 }
8839 8661
@@ -8845,15 +8667,12 @@ SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
8845/*********************************************/ 8667/*********************************************/
8846 8668
8847BOOLEAN 8669BOOLEAN
8848SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo) 8670SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
8849{ 8671{
8850#ifdef SIS300 8672#ifdef SIS300
8851 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 8673 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
8852#endif
8853 USHORT ModeIdIndex, RefreshRateTableIndex;
8854#if 0
8855 USHORT temp;
8856#endif 8674#endif
8675 unsigned short ModeIdIndex, RefreshRateTableIndex;
8857 8676
8858 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8677 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
8859 8678
@@ -8866,37 +8685,37 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8866 /* Used for shifting CR33 */ 8685 /* Used for shifting CR33 */
8867 SiS_Pr->SiS_SelectCRT2Rate = 4; 8686 SiS_Pr->SiS_SelectCRT2Rate = 4;
8868 8687
8869 SiS_UnLockCRT2(SiS_Pr, HwInfo); 8688 SiS_UnLockCRT2(SiS_Pr);
8870 8689
8871 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 8690 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
8872 8691
8873 SiS_SaveCRT2Info(SiS_Pr,ModeNo); 8692 SiS_SaveCRT2Info(SiS_Pr,ModeNo);
8874 8693
8875 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8694 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8876 SiS_DisableBridge(SiS_Pr,HwInfo); 8695 SiS_DisableBridge(SiS_Pr);
8877 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) { 8696 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
8878 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80); 8697 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
8879 } 8698 }
8880 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 8699 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
8881 } 8700 }
8882 8701
8883 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 8702 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
8884 SiS_LockCRT2(SiS_Pr, HwInfo); 8703 SiS_LockCRT2(SiS_Pr);
8885 SiS_DisplayOn(SiS_Pr); 8704 SiS_DisplayOn(SiS_Pr);
8886 return TRUE; 8705 return TRUE;
8887 } 8706 }
8888 8707
8889 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 8708 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8890 8709
8891 /* Set up Panel Link for LVDS and LCDA */ 8710 /* Set up Panel Link for LVDS and LCDA */
8892 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 8711 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
8893 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 8712 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
8894 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) || 8713 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
8895 ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) { 8714 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
8896 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 8715 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8897 } 8716 }
8898 8717
8899#ifdef LINUX_XF86 8718#ifdef SIS_XORG_XF86
8900#ifdef TWDEBUG 8719#ifdef TWDEBUG
8901 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES); 8720 xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
8902 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE); 8721 xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
@@ -8907,86 +8726,79 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8907#endif 8726#endif
8908 8727
8909 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8728 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8910 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex); 8729 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8911 } 8730 }
8912 8731
8913 if(SiS_Pr->SiS_VBType & VB_SISVB) { 8732 if(SiS_Pr->SiS_VBType & VB_SISVB) {
8914 8733
8915 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8734 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8916 8735
8917 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 8736 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8918#ifdef SIS315H 8737#ifdef SIS315H
8919 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 8738 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8920#endif 8739#endif
8921 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 8740 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
8922 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo); 8741 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8923#ifdef SIS315H 8742#ifdef SIS315H
8924 SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex); 8743 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
8925#endif 8744#endif
8926 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 8745 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
8927 8746
8928 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo); 8747 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8929 8748
8930 /* For 301BDH (Panel link initialization): */ 8749 /* For 301BDH (Panel link initialization): */
8931 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 8750 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
8932 if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) { 8751
8933 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) { 8752 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
8934 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 8753 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
8935 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex, 8754 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8936 RefreshRateTableIndex,HwInfo); 8755 }
8937 } 8756 }
8938 } 8757 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8939 } 8758 }
8940 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex, 8759 }
8941 RefreshRateTableIndex,HwInfo);
8942 }
8943 }
8944 8760
8945 } else { 8761 } else {
8946 8762
8947 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo); 8763 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
8948 8764
8949 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 8765 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8950 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
8951 }
8952 8766
8953 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo); 8767 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8954 8768
8955 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8769 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8956 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 8770 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
8957 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 8771 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
8958 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8772 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
8959#ifdef SIS315H 8773#ifdef SIS315H
8960 SiS_SetCH701xForLCD(SiS_Pr,HwInfo); 8774 SiS_SetCH701xForLCD(SiS_Pr);
8961#endif 8775#endif
8962 } 8776 }
8963 } 8777 }
8964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8778 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
8965 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8779 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
8966 } 8780 }
8967 } 8781 }
8968 } 8782 }
8969 8783
8970 } 8784 }
8971 8785
8972#ifdef SIS300 8786#ifdef SIS300
8973 if(HwInfo->jChipType < SIS_315H) { 8787 if(SiS_Pr->ChipType < SIS_315H) {
8974 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8788 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
8975 if(SiS_Pr->SiS_UseOEM) { 8789 if(SiS_Pr->SiS_UseOEM) {
8976 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) { 8790 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
8977 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 8791 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
8978 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex, 8792 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8979 RefreshRateTableIndex);
8980 } 8793 }
8981 } else { 8794 } else {
8982 SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex, 8795 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
8983 RefreshRateTableIndex);
8984 } 8796 }
8985 } 8797 }
8986 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 8798 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
8987 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8799 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
8988 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8800 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
8989 SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex); 8801 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
8990 } 8802 }
8991 SiS_DisplayOn(SiS_Pr); 8803 SiS_DisplayOn(SiS_Pr);
8992 } 8804 }
@@ -8995,21 +8807,21 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
8995#endif 8807#endif
8996 8808
8997#ifdef SIS315H 8809#ifdef SIS315H
8998 if(HwInfo->jChipType >= SIS_315H) { 8810 if(SiS_Pr->ChipType >= SIS_315H) {
8999 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8811 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9000 if(HwInfo->jChipType < SIS_661) { 8812 if(SiS_Pr->ChipType < SIS_661) {
9001 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo); 8813 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
9002 SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8814 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9003 } else { 8815 } else {
9004 SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8816 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
9005 } 8817 }
9006 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40); 8818 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
9007 } 8819 }
9008 } 8820 }
9009#endif 8821#endif
9010 8822
9011 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8823 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9012 SiS_EnableBridge(SiS_Pr, HwInfo); 8824 SiS_EnableBridge(SiS_Pr);
9013 } 8825 }
9014 8826
9015 SiS_DisplayOn(SiS_Pr); 8827 SiS_DisplayOn(SiS_Pr);
@@ -9017,15 +8829,15 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
9017 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8829 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
9018 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8830 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
9019 /* Disable LCD panel when using TV */ 8831 /* Disable LCD panel when using TV */
9020 SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C); 8832 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
9021 } else { 8833 } else {
9022 /* Disable TV when using LCD */ 8834 /* Disable TV when using LCD */
9023 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8); 8835 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
9024 } 8836 }
9025 } 8837 }
9026 8838
9027 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8839 if(SiS_Pr->SiS_SetFlag & LowModeTests) {
9028 SiS_LockCRT2(SiS_Pr,HwInfo); 8840 SiS_LockCRT2(SiS_Pr);
9029 } 8841 }
9030 8842
9031 return TRUE; 8843 return TRUE;
@@ -9037,13 +8849,13 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
9037/*********************************************/ 8849/*********************************************/
9038 8850
9039void 8851void
9040SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8852SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
9041{ 8853{
9042 /* Switch on LCD backlight on SiS30xLV */ 8854 /* Switch on LCD backlight on SiS30xLV */
9043 SiS_DDC2Delay(SiS_Pr,0xff00); 8855 SiS_DDC2Delay(SiS_Pr,0xff00);
9044 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 8856 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
9045 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 8857 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
9046 SiS_WaitVBRetrace(SiS_Pr,HwInfo); 8858 SiS_WaitVBRetrace(SiS_Pr);
9047 } 8859 }
9048 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) { 8860 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
9049 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 8861 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
@@ -9051,12 +8863,11 @@ SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9051} 8863}
9052 8864
9053void 8865void
9054SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 8866SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
9055{ 8867{
9056 /* Switch off LCD backlight on SiS30xLV */ 8868 /* Switch off LCD backlight on SiS30xLV */
9057 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 8869 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
9058 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 8870 SiS_DDC2Delay(SiS_Pr,0xff00);
9059 SiS_DDC2Delay(SiS_Pr,0xe000);
9060} 8871}
9061 8872
9062/*********************************************/ 8873/*********************************************/
@@ -9064,7 +8875,7 @@ SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
9064/*********************************************/ 8875/*********************************************/
9065 8876
9066static void 8877static void
9067SiS_SetupDDCN(SiS_Private *SiS_Pr) 8878SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
9068{ 8879{
9069 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data; 8880 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
9070 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk; 8881 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
@@ -9075,12 +8886,12 @@ SiS_SetupDDCN(SiS_Private *SiS_Pr)
9075} 8886}
9076 8887
9077#ifdef SIS300 8888#ifdef SIS300
9078static UCHAR * 8889static unsigned char *
9079SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr) 8890SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9080{ 8891{
9081 int i, j, num; 8892 int i, j, num;
9082 USHORT tempah,temp; 8893 unsigned short tempah,temp;
9083 UCHAR *mydataptr; 8894 unsigned char *mydataptr;
9084 8895
9085 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 8896 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9086 mydataptr = dataptr; 8897 mydataptr = dataptr;
@@ -9088,7 +8899,7 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9088 if(!num) return mydataptr; 8899 if(!num) return mydataptr;
9089 if(i) { 8900 if(i) {
9090 SiS_SetStop(SiS_Pr); 8901 SiS_SetStop(SiS_Pr);
9091 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2); 8902 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
9092 } 8903 }
9093 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 8904 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9094 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 8905 tempah = SiS_Pr->SiS_DDC_DeviceAddr;
@@ -9110,12 +8921,12 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
9110} 8921}
9111 8922
9112static BOOLEAN 8923static BOOLEAN
9113SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr) 8924SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
9114{ 8925{
9115 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */ 8926 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9116 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 8927 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9117 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 8928 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9118 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 8929 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9119 SiS_SetupDDCN(SiS_Pr); 8930 SiS_SetupDDCN(SiS_Pr);
9120 8931
9121 SiS_SetSwitchDDC2(SiS_Pr); 8932 SiS_SetSwitchDDC2(SiS_Pr);
@@ -9124,9 +8935,11 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9124 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); 8935 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
9125 if(!dataptr) return FALSE; 8936 if(!dataptr) return FALSE;
9126 } 8937 }
8938#ifdef SIS_XORG_XF86
9127#ifdef TWDEBUG 8939#ifdef TWDEBUG
9128 xf86DrvMsg(0, X_INFO, "Trumpion block success\n"); 8940 xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
9129#endif 8941#endif
8942#endif
9130 return TRUE; 8943 return TRUE;
9131} 8944}
9132#endif 8945#endif
@@ -9139,155 +8952,121 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
9139 */ 8952 */
9140 8953
9141static BOOLEAN 8954static BOOLEAN
9142SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor) 8955SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
9143{ 8956{
9144 USHORT tempah,temp,i; 8957 unsigned short temp, i;
9145 8958
9146 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 8959 for(i=0; i<20; i++) { /* Do 20 attempts to write */
9147 if(i) { 8960 if(i) {
9148 SiS_SetStop(SiS_Pr); 8961 SiS_SetStop(SiS_Pr);
9149 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 8962 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9150 } 8963 }
9151 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 8964 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9152 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 8965 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9153 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ 8966 if(temp) continue; /* (ERROR: no ack) */
9154 if(temp) continue; /* (ERROR: no ack) */ 8967 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
9155 tempah = tempbx & 0x00FF; /* Write RAB */ 8968 if(temp) continue; /* (ERROR: no ack) */
9156 tempah |= myor; /* (700x: set bit 7, see datasheet) */ 8969 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
9157 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); 8970 if(temp) continue; /* (ERROR: no ack) */
9158 if(temp) continue; /* (ERROR: no ack) */ 8971 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9159 tempah = (tempbx & 0xFF00) >> 8;
9160 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
9161 if(temp) continue; /* (ERROR: no ack) */
9162 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
9163 SiS_Pr->SiS_ChrontelInit = 1; 8972 SiS_Pr->SiS_ChrontelInit = 1;
9164 return TRUE; 8973 return TRUE;
9165 } 8974 }
9166 return FALSE; 8975 return FALSE;
9167} 8976}
9168 8977
9169#if 0
9170#ifdef SIS300
9171/* Write Trumpion register */
9172static void
9173SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9174{
9175 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
9176 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9177 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9178 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9179 SiS_SetupDDCN(SiS_Pr);
9180 SiS_SetChReg(SiS_Pr, tempbx, 0);
9181}
9182#endif
9183#endif
9184
9185/* Write to Chrontel 700x */ 8978/* Write to Chrontel 700x */
9186/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9187void 8979void
9188SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx) 8980SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9189{ 8981{
9190 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 8982 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9191 8983
8984 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
8985
9192 if(!(SiS_Pr->SiS_ChrontelInit)) { 8986 if(!(SiS_Pr->SiS_ChrontelInit)) {
9193 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 8987 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9194 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 8988 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9195 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 8989 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9196 SiS_SetupDDCN(SiS_Pr); 8990 SiS_SetupDDCN(SiS_Pr);
9197 } 8991 }
9198 8992
9199 if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) && 8993 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
9200 (!(SiS_Pr->SiS_ChrontelInit)) ) { 8994 (!(SiS_Pr->SiS_ChrontelInit)) ) {
9201 SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */ 8995 SiS_Pr->SiS_DDC_Index = 0x0a;
9202 SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */ 8996 SiS_Pr->SiS_DDC_Data = 0x80;
9203 SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */ 8997 SiS_Pr->SiS_DDC_Clk = 0x40;
9204 SiS_SetupDDCN(SiS_Pr); 8998 SiS_SetupDDCN(SiS_Pr);
9205 8999
9206 SiS_SetChReg(SiS_Pr, tempbx, 0x80); 9000 SiS_SetChReg(SiS_Pr, reg, val, 0x80);
9207 } 9001 }
9208} 9002}
9209 9003
9210/* Write to Chrontel 701x */ 9004/* Write to Chrontel 701x */
9211/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ 9005/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
9212void 9006void
9213SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) 9007SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9214{ 9008{
9215 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9009 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9216 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9010 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9217 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9011 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9218 SiS_SetupDDCN(SiS_Pr); 9012 SiS_SetupDDCN(SiS_Pr);
9219 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9013 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
9220 SiS_SetChReg(SiS_Pr, tempbx, 0); 9014 SiS_SetChReg(SiS_Pr, reg, val, 0);
9221} 9015}
9222 9016
9223static void 9017#ifdef SIS_LINUX_KERNEL
9224SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) 9018static
9019#endif
9020void
9021SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
9225{ 9022{
9226 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9023 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9227 SiS_SetCH700x(SiS_Pr,tempbx); 9024 SiS_SetCH700x(SiS_Pr, reg, val);
9228 else 9025 else
9229 SiS_SetCH701x(SiS_Pr,tempbx); 9026 SiS_SetCH701x(SiS_Pr, reg, val);
9230} 9027}
9231 9028
9232static USHORT 9029static unsigned short
9233SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor) 9030SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
9234{ 9031{
9235 USHORT tempah,temp,i; 9032 unsigned short tempah, temp, i;
9236 9033
9237 for(i=0; i<20; i++) { /* Do 20 attempts to read */ 9034 for(i=0; i<20; i++) { /* Do 20 attempts to read */
9238 if(i) { 9035 if(i) {
9239 SiS_SetStop(SiS_Pr); 9036 SiS_SetStop(SiS_Pr);
9240 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9037 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
9241 } 9038 }
9242 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9039 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
9243 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 9040 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
9244 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ 9041 if(temp) continue; /* (ERROR: no ack) */
9245 if(temp) continue; /* (ERROR: no ack) */ 9042 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
9246 tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */ 9043 if(temp) continue; /* (ERROR: no ack) */
9247 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); 9044 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
9248 if(temp) continue; /* (ERROR: no ack) */ 9045 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
9249 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ 9046 if(temp) continue; /* (ERROR: no ack) */
9250 tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */ 9047 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
9251 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */ 9048 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9252 if(temp) continue; /* (ERROR: no ack) */
9253 tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
9254 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
9255 SiS_Pr->SiS_ChrontelInit = 1; 9049 SiS_Pr->SiS_ChrontelInit = 1;
9256 return(tempah); 9050 return tempah;
9257 } 9051 }
9258 return 0xFFFF; 9052 return 0xFFFF;
9259} 9053}
9260 9054
9261#if 0
9262#ifdef SIS300
9263/* Read from Trumpion */
9264static USHORT
9265SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
9266{
9267 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
9268 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9269 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9270 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9271 SiS_SetupDDCN(SiS_Pr);
9272 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9273 return(SiS_GetChReg(SiS_Pr,0));
9274}
9275#endif
9276#endif
9277
9278/* Read from Chrontel 700x */ 9055/* Read from Chrontel 700x */
9279/* Parameter is [Register no (S7-S0)] */ 9056/* Parameter is [Register no (S7-S0)] */
9280USHORT 9057unsigned short
9281SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx) 9058SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9282{ 9059{
9283 USHORT result; 9060 unsigned short result;
9284 9061
9285 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9062 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9286 9063
9064 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
9065
9287 if(!(SiS_Pr->SiS_ChrontelInit)) { 9066 if(!(SiS_Pr->SiS_ChrontelInit)) {
9288 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9067 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9289 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9068 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
9290 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9069 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
9291 SiS_SetupDDCN(SiS_Pr); 9070 SiS_SetupDDCN(SiS_Pr);
9292 } 9071 }
9293 9072
@@ -9303,52 +9082,69 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
9303 9082
9304 result = SiS_GetChReg(SiS_Pr,0x80); 9083 result = SiS_GetChReg(SiS_Pr,0x80);
9305 } 9084 }
9306 return(result); 9085 return result;
9307} 9086}
9308 9087
9309/* Read from Chrontel 701x */ 9088/* Read from Chrontel 701x */
9310/* Parameter is [Register no (S7-S0)] */ 9089/* Parameter is [Register no (S7-S0)] */
9311USHORT 9090unsigned short
9312SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) 9091SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9313{ 9092{
9314 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9093 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
9315 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9094 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
9316 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9095 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
9317 SiS_SetupDDCN(SiS_Pr); 9096 SiS_SetupDDCN(SiS_Pr);
9318 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9097 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
9319 9098
9320 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9099 SiS_Pr->SiS_DDC_ReadAddr = tempbx;
9321 9100
9322 return(SiS_GetChReg(SiS_Pr,0)); 9101 return SiS_GetChReg(SiS_Pr,0);
9323} 9102}
9324 9103
9325/* Read from Chrontel 70xx */ 9104/* Read from Chrontel 70xx */
9326/* Parameter is [Register no (S7-S0)] */ 9105/* Parameter is [Register no (S7-S0)] */
9327static USHORT 9106#ifdef SIS_LINUX_KERNEL
9328SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) 9107static
9108#endif
9109unsigned short
9110SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
9329{ 9111{
9330 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9112 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
9331 return(SiS_GetCH700x(SiS_Pr, tempbx)); 9113 return SiS_GetCH700x(SiS_Pr, tempbx);
9332 else 9114 else
9333 return(SiS_GetCH701x(SiS_Pr, tempbx)); 9115 return SiS_GetCH701x(SiS_Pr, tempbx);
9116}
9117
9118void
9119SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
9120 unsigned char myor, unsigned short myand)
9121{
9122 unsigned short tempbl;
9123
9124 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
9125 SiS_SetCH70xx(SiS_Pr, reg, tempbl);
9334} 9126}
9335 9127
9336/* Our own DDC functions */ 9128/* Our own DDC functions */
9337static USHORT 9129#ifndef SIS_XORG_XF86
9338SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, 9130static
9339 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32) 9131#endif
9132unsigned short
9133SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9134 unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
9135 unsigned int VBFlags2)
9340{ 9136{
9341 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 }; 9137 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
9342 unsigned char flag, cr32; 9138 unsigned char flag, cr32;
9343 USHORT temp = 0, myadaptnum = adaptnum; 9139 unsigned short temp = 0, myadaptnum = adaptnum;
9344 9140
9345 if(adaptnum != 0) { 9141 if(adaptnum != 0) {
9346 if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF; 9142 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
9347 if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF; 9143 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
9348 } 9144 }
9349 9145
9350 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */ 9146 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
9351 9147
9352 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */ 9148 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
9353 9149
9354 SiS_Pr->SiS_DDC_SecAddr = 0; 9150 SiS_Pr->SiS_DDC_SecAddr = 0;
@@ -9360,7 +9156,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9360 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32); 9156 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
9361 9157
9362#if 0 9158#if 0
9363 if(VBFlags & VB_SISBRIDGE) { 9159 if(VBFlags2 & VB2_SISBRIDGE) {
9364 if(myadaptnum == 0) { 9160 if(myadaptnum == 0) {
9365 if(!(cr32 & 0x20)) { 9161 if(!(cr32 & 0x20)) {
9366 myadaptnum = 2; 9162 myadaptnum = 2;
@@ -9376,20 +9172,20 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9376#endif 9172#endif
9377 9173
9378 if(VGAEngine == SIS_300_VGA) { /* 300 series */ 9174 if(VGAEngine == SIS_300_VGA) { /* 300 series */
9379 9175
9380 if(myadaptnum != 0) { 9176 if(myadaptnum != 0) {
9381 flag = 0; 9177 flag = 0;
9382 if(VBFlags & VB_SISBRIDGE) { 9178 if(VBFlags2 & VB2_SISBRIDGE) {
9383 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9179 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9384 SiS_Pr->SiS_DDC_Index = 0x0f; 9180 SiS_Pr->SiS_DDC_Index = 0x0f;
9385 } 9181 }
9386 } 9182 }
9387 9183
9388 if(!(VBFlags & VB_301)) { 9184 if(!(VBFlags2 & VB2_301)) {
9389 if((cr32 & 0x80) && (checkcr32)) { 9185 if((cr32 & 0x80) && (checkcr32)) {
9390 if(myadaptnum >= 1) { 9186 if(myadaptnum >= 1) {
9391 if(!(cr32 & 0x08)) { 9187 if(!(cr32 & 0x08)) {
9392 myadaptnum = 1; 9188 myadaptnum = 1;
9393 if(!(cr32 & 0x10)) return 0xFFFF; 9189 if(!(cr32 & 0x10)) return 0xFFFF;
9394 } 9190 }
9395 } 9191 }
@@ -9401,17 +9197,17 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9401 9197
9402 } else { /* 315/330 series */ 9198 } else { /* 315/330 series */
9403 9199
9404 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */ 9200 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
9405 9201
9406 if(VBFlags & VB_SISBRIDGE) { 9202 if(VBFlags2 & VB2_SISBRIDGE) {
9407 if(myadaptnum == 2) { 9203 if(myadaptnum == 2) {
9408 myadaptnum = 1; 9204 myadaptnum = 1;
9409 } 9205 }
9410 } 9206 }
9411 9207
9412 if(myadaptnum == 1) { 9208 if(myadaptnum == 1) {
9413 flag = 0; 9209 flag = 0;
9414 if(VBFlags & VB_SISBRIDGE) { 9210 if(VBFlags2 & VB2_SISBRIDGE) {
9415 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9211 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
9416 SiS_Pr->SiS_DDC_Index = 0x0f; 9212 SiS_Pr->SiS_DDC_Index = 0x0f;
9417 } 9213 }
@@ -9429,93 +9225,96 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9429 temp = myadaptnum; 9225 temp = myadaptnum;
9430 if(myadaptnum == 1) { 9226 if(myadaptnum == 1) {
9431 temp = 0; 9227 temp = 0;
9432 if(VBFlags & VB_LVDS) flag = 0xff; 9228 if(VBFlags2 & VB2_LVDS) flag = 0xff;
9433 } 9229 }
9434 9230
9435 if(flag) temp = 0; 9231 if(flag) temp = 0;
9436 } 9232 }
9437 9233
9438 SiS_Pr->SiS_DDC_Data = 0x02 << temp; 9234 SiS_Pr->SiS_DDC_Data = 0x02 << temp;
9439 SiS_Pr->SiS_DDC_Clk = 0x01 << temp; 9235 SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
9440 9236
9441 SiS_SetupDDCN(SiS_Pr); 9237 SiS_SetupDDCN(SiS_Pr);
9442 9238
9239#ifdef SIS_XORG_XF86
9443#ifdef TWDEBUG 9240#ifdef TWDEBUG
9444 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n", 9241 xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
9445 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp); 9242 SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
9446#endif 9243#endif
9447 9244#endif
9448 return 0; 9245 return 0;
9449} 9246}
9450 9247
9451static USHORT 9248static unsigned short
9452SiS_WriteDABDDC(SiS_Private *SiS_Pr) 9249SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
9453{ 9250{
9454 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9251 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9455 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) { 9252 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
9456 return 0xFFFF; 9253 return 0xFFFF;
9457 } 9254 }
9458 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) { 9255 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
9459 return 0xFFFF; 9256 return 0xFFFF;
9460 } 9257 }
9461 return(0); 9258 return 0;
9462} 9259}
9463 9260
9464static USHORT 9261static unsigned short
9465SiS_PrepareReadDDC(SiS_Private *SiS_Pr) 9262SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
9466{ 9263{
9467 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9264 if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
9468 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) { 9265 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
9469 return 0xFFFF; 9266 return 0xFFFF;
9470 } 9267 }
9471 return(0); 9268 return 0;
9472} 9269}
9473 9270
9474static USHORT 9271static unsigned short
9475SiS_PrepareDDC(SiS_Private *SiS_Pr) 9272SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
9476{ 9273{
9477 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr); 9274 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
9478 if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr)); 9275 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
9479 return(0); 9276 return 0;
9480} 9277}
9481 9278
9482static void 9279static void
9483SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno) 9280SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
9484{ 9281{
9485 SiS_SetSCLKLow(SiS_Pr); 9282 SiS_SetSCLKLow(SiS_Pr);
9486 if(yesno) { 9283 if(yesno) {
9487 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9284 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9488 SiS_Pr->SiS_DDC_Index, 9285 SiS_Pr->SiS_DDC_Index,
9489 SiS_Pr->SiS_DDC_NData, 9286 SiS_Pr->SiS_DDC_NData,
9490 SiS_Pr->SiS_DDC_Data); 9287 SiS_Pr->SiS_DDC_Data);
9491 } else { 9288 } else {
9492 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9289 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
9493 SiS_Pr->SiS_DDC_Index, 9290 SiS_Pr->SiS_DDC_Index,
9494 SiS_Pr->SiS_DDC_NData, 9291 SiS_Pr->SiS_DDC_NData,
9495 0); 9292 0);
9496 } 9293 }
9497 SiS_SetSCLKHigh(SiS_Pr); 9294 SiS_SetSCLKHigh(SiS_Pr);
9498} 9295}
9499 9296
9500static USHORT 9297static unsigned short
9501SiS_DoProbeDDC(SiS_Private *SiS_Pr) 9298SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
9502{ 9299{
9503 unsigned char mask, value; 9300 unsigned char mask, value;
9504 USHORT temp, ret=0; 9301 unsigned short temp, ret=0;
9505 BOOLEAN failed = FALSE; 9302 BOOLEAN failed = FALSE;
9506 9303
9507 SiS_SetSwitchDDC2(SiS_Pr); 9304 SiS_SetSwitchDDC2(SiS_Pr);
9508 if(SiS_PrepareDDC(SiS_Pr)) { 9305 if(SiS_PrepareDDC(SiS_Pr)) {
9509 SiS_SetStop(SiS_Pr); 9306 SiS_SetStop(SiS_Pr);
9307#ifdef SIS_XORG_XF86
9510#ifdef TWDEBUG 9308#ifdef TWDEBUG
9511 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n"); 9309 xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
9512#endif 9310#endif
9513 return(0xFFFF); 9311#endif
9312 return 0xFFFF;
9514 } 9313 }
9515 mask = 0xf0; 9314 mask = 0xf0;
9516 value = 0x20; 9315 value = 0x20;
9517 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9316 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9518 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); 9317 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9519 SiS_SendACK(SiS_Pr, 0); 9318 SiS_SendACK(SiS_Pr, 0);
9520 if(temp == 0) { 9319 if(temp == 0) {
9521 mask = 0xff; 9320 mask = 0xff;
@@ -9523,34 +9322,41 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
9523 } else { 9322 } else {
9524 failed = TRUE; 9323 failed = TRUE;
9525 ret = 0xFFFF; 9324 ret = 0xFFFF;
9325#ifdef SIS_XORG_XF86
9526#ifdef TWDEBUG 9326#ifdef TWDEBUG
9527 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n"); 9327 xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
9528#endif 9328#endif
9329#endif
9529 } 9330 }
9530 } 9331 }
9531 if(failed == FALSE) { 9332 if(failed == FALSE) {
9532 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); 9333 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9533 SiS_SendACK(SiS_Pr, 1); 9334 SiS_SendACK(SiS_Pr, 1);
9534 temp &= mask; 9335 temp &= mask;
9535 if(temp == value) ret = 0; 9336 if(temp == value) ret = 0;
9536 else { 9337 else {
9537 ret = 0xFFFF; 9338 ret = 0xFFFF;
9339#ifdef SIS_XORG_XF86
9538#ifdef TWDEBUG 9340#ifdef TWDEBUG
9539 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n"); 9341 xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
9540#endif 9342#endif
9343#endif
9541 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9344 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
9542 if(temp == 0x30) ret = 0; 9345 if(temp == 0x30) ret = 0;
9543 } 9346 }
9544 } 9347 }
9545 } 9348 }
9546 SiS_SetStop(SiS_Pr); 9349 SiS_SetStop(SiS_Pr);
9547 return(ret); 9350 return ret;
9548} 9351}
9549 9352
9550static USHORT 9353#ifndef SIS_XORG_XF86
9551SiS_ProbeDDC(SiS_Private *SiS_Pr) 9354static
9355#endif
9356unsigned short
9357SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
9552{ 9358{
9553 USHORT flag; 9359 unsigned short flag;
9554 9360
9555 flag = 0x180; 9361 flag = 0x180;
9556 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; 9362 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
@@ -9560,16 +9366,19 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
9560 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; 9366 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
9561 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10; 9367 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
9562 if(!(flag & 0x1a)) flag = 0; 9368 if(!(flag & 0x1a)) flag = 0;
9563 return(flag); 9369 return flag;
9564} 9370}
9565 9371
9566static USHORT 9372#ifndef SIS_XORG_XF86
9567SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer) 9373static
9374#endif
9375unsigned short
9376SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
9568{ 9377{
9569 USHORT flag, length, i; 9378 unsigned short flag, length, i;
9570 unsigned char chksum,gotcha; 9379 unsigned char chksum,gotcha;
9571 9380
9572 if(DDCdatatype > 4) return 0xFFFF; 9381 if(DDCdatatype > 4) return 0xFFFF;
9573 9382
9574 flag = 0; 9383 flag = 0;
9575 SiS_SetSwitchDDC2(SiS_Pr); 9384 SiS_SetSwitchDDC2(SiS_Pr);
@@ -9579,21 +9388,21 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9579 chksum = 0; 9388 chksum = 0;
9580 gotcha = 0; 9389 gotcha = 0;
9581 for(i=0; i<length; i++) { 9390 for(i=0; i<length; i++) {
9582 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); 9391 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9583 chksum += buffer[i]; 9392 chksum += buffer[i];
9584 gotcha |= buffer[i]; 9393 gotcha |= buffer[i];
9585 SiS_SendACK(SiS_Pr, 0); 9394 SiS_SendACK(SiS_Pr, 0);
9586 } 9395 }
9587 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0); 9396 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
9588 chksum += buffer[i]; 9397 chksum += buffer[i];
9589 SiS_SendACK(SiS_Pr, 1); 9398 SiS_SendACK(SiS_Pr, 1);
9590 if(gotcha) flag = (USHORT)chksum; 9399 if(gotcha) flag = (unsigned short)chksum;
9591 else flag = 0xFFFF; 9400 else flag = 0xFFFF;
9592 } else { 9401 } else {
9593 flag = 0xFFFF; 9402 flag = 0xFFFF;
9594 } 9403 }
9595 SiS_SetStop(SiS_Pr); 9404 SiS_SetStop(SiS_Pr);
9596 return(flag); 9405 return flag;
9597} 9406}
9598 9407
9599/* Our private DDC functions 9408/* Our private DDC functions
@@ -9617,17 +9426,25 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
9617 if DDCdatatype = 0: Returns supported DDC modes 9426 if DDCdatatype = 0: Returns supported DDC modes
9618 9427
9619 */ 9428 */
9620USHORT 9429unsigned short
9621SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine, 9430SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
9622 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer) 9431 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
9432 unsigned int VBFlags2)
9623{ 9433{
9624 unsigned char sr1f,cr17=1; 9434 unsigned char sr1f, cr17=1;
9625 USHORT result; 9435 unsigned short result;
9626 9436
9627 if(adaptnum > 2) return 0xFFFF; 9437 if(adaptnum > 2)
9628 if(DDCdatatype > 4) return 0xFFFF; 9438 return 0xFFFF;
9629 if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF; 9439
9630 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF; 9440 if(DDCdatatype > 4)
9441 return 0xFFFF;
9442
9443 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
9444 return 0xFFFF;
9445
9446 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
9447 return 0xFFFF;
9631 9448
9632 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f); 9449 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
9633 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04); 9450 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
@@ -9656,10 +9473,12 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9656 (buffer[4] == 0xff) && (buffer[5] == 0xff) && 9473 (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
9657 (buffer[6] == 0xff) && (buffer[7] == 0x00) && 9474 (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
9658 (buffer[0x12] == 1)) { 9475 (buffer[0x12] == 1)) {
9659 if(adaptnum == 1) { 9476 if(!SiS_Pr->DDCPortMixup) {
9660 if(!(buffer[0x14] & 0x80)) result = 0xFFFE; 9477 if(adaptnum == 1) {
9661 } else { 9478 if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
9662 if(buffer[0x14] & 0x80) result = 0xFFFE; 9479 } else {
9480 if(buffer[0x14] & 0x80) result = 0xFFFE;
9481 }
9663 } 9482 }
9664 } 9483 }
9665 } 9484 }
@@ -9671,832 +9490,10 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
9671 return result; 9490 return result;
9672} 9491}
9673 9492
9674#ifdef LINUX_XF86
9675
9676static BOOLEAN
9677checkedid1(unsigned char *buffer)
9678{
9679 /* Check header */
9680 if((buffer[0] != 0x00) ||
9681 (buffer[1] != 0xff) ||
9682 (buffer[2] != 0xff) ||
9683 (buffer[3] != 0xff) ||
9684 (buffer[4] != 0xff) ||
9685 (buffer[5] != 0xff) ||
9686 (buffer[6] != 0xff) ||
9687 (buffer[7] != 0x00))
9688 return FALSE;
9689
9690 /* Check EDID version and revision */
9691 if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
9692
9693 /* Check week of manufacture for sanity */
9694 if(buffer[0x10] > 53) return FALSE;
9695
9696 /* Check year of manufacture for sanity */
9697 if(buffer[0x11] > 40) return FALSE;
9698
9699 return TRUE;
9700}
9701
9702static BOOLEAN
9703checkedid2(unsigned char *buffer)
9704{
9705 USHORT year = buffer[6] | (buffer[7] << 8);
9706
9707 /* Check EDID version */
9708 if((buffer[0] & 0xf0) != 0x20) return FALSE;
9709
9710 /* Check week of manufacture for sanity */
9711 if(buffer[5] > 53) return FALSE;
9712
9713 /* Check year of manufacture for sanity */
9714 if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
9715
9716 return TRUE;
9717}
9718
9719/* Sense the LCD parameters (CR36, CR37) via DDC */
9720/* SiS30x(B) only */
9721USHORT
9722SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
9723{
9724 USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
9725 USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
9726 int maxx=0, maxy=0, prefx=0, prefy=0;
9727 unsigned char cr37=0, seekcode;
9728 BOOLEAN checkexpand = FALSE;
9729 BOOLEAN havesync = FALSE;
9730 BOOLEAN indb = FALSE;
9731 int retry, i;
9732 unsigned char buffer[256];
9733
9734 for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
9735 SiS_Pr->CP_HaveCustomData = FALSE;
9736 SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
9737 SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
9738 SiS_Pr->CP_PreferredIndex = -1;
9739 SiS_Pr->CP_PrefClock = 0;
9740 SiS_Pr->PanelSelfDetected = FALSE;
9741
9742 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
9743 if(pSiS->VBFlags & VB_30xBDH) return 0;
9744
9745 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
9746
9747 SiS_Pr->SiS_DDC_SecAddr = 0x00;
9748
9749 /* Probe supported DA's */
9750 flag = SiS_ProbeDDC(SiS_Pr);
9751#ifdef TWDEBUG
9752 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
9753 "CRT2 DDC capabilities 0x%x\n", flag);
9754#endif
9755 if(flag & 0x10) {
9756 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
9757 DDCdatatype = 4;
9758 } else if(flag & 0x08) {
9759 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
9760 DDCdatatype = 3;
9761 } else if(flag & 0x02) {
9762 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
9763 DDCdatatype = 1;
9764 } else return 0; /* no DDC support (or no device attached) */
9765
9766 /* Read the entire EDID */
9767 retry = 2;
9768 do {
9769 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
9770 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9771 "CRT2: DDC read failed (attempt %d), %s\n",
9772 (3-retry), (retry == 1) ? "giving up" : "retrying");
9773 retry--;
9774 if(retry == 0) return 0xFFFF;
9775 } else break;
9776 } while(1);
9777
9778#ifdef TWDEBUG
9779 for(i=0; i<256; i+=16) {
9780 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9781 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
9782 buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
9783 buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
9784 buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
9785 buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
9786 }
9787#endif
9788
9789 /* Analyze EDID and retrieve LCD panel information */
9790 paneltype = 0;
9791 switch(DDCdatatype) {
9792 case 1: /* Analyze EDID V1 */
9793 /* Catch a few clear cases: */
9794 if(!(checkedid1(buffer))) {
9795 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9796 "LCD sense: EDID corrupt\n");
9797 return 0;
9798 }
9799
9800 if(!(buffer[0x14] & 0x80)) {
9801 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9802 "LCD sense: Attached display expects analog input (0x%02x)\n",
9803 buffer[0x14]);
9804 return 0;
9805 }
9806
9807 if((buffer[0x18] & 0x18) != 0x08) {
9808 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
9809 "LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
9810 ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
9811 ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
9812 "undefined"),
9813 buffer[0x18]);
9814 }
9815
9816 /* Now analyze the first Detailed Timing Block and see
9817 * if the preferred timing mode is stored there. If so,
9818 * check if this is a standard panel for which we already
9819 * know the timing.
9820 */
9821
9822 paneltype = Panel_Custom;
9823 checkexpand = FALSE;
9824
9825 panelvendor = buffer[9] | (buffer[8] << 8);
9826 panelproduct = buffer[10] | (buffer[11] << 8);
9827
9828 /* Overrule bogus preferred modes from database */
9829 if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
9830 if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
9831 if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
9832 }
9833
9834 if(buffer[0x18] & 0x02) {
9835
9836 USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
9837 USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
9838 USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
9839
9840 if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
9841 if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
9842
9843 switch(xres) {
9844#if 0 /* Treat as custom */
9845 case 800:
9846 if(yres == 600) {
9847 paneltype = Panel_800x600;
9848 checkexpand = TRUE;
9849 }
9850 break;
9851#endif
9852 case 1024:
9853 if(yres == 768) {
9854 paneltype = Panel_1024x768;
9855 checkexpand = TRUE;
9856 }
9857 break;
9858 case 1280:
9859 if(yres == 1024) {
9860 paneltype = Panel_1280x1024;
9861 checkexpand = TRUE;
9862 } else if(yres == 960) {
9863 if(pSiS->VGAEngine == SIS_300_VGA) {
9864 paneltype = Panel300_1280x960;
9865 } else {
9866 paneltype = Panel310_1280x960;
9867 }
9868 } else if(yres == 768) {
9869 if( (pclk == 8100) &&
9870 (phb == (1688 - 1280)) &&
9871 (pvb == (802 - 768)) ) {
9872 paneltype = Panel_1280x768;
9873 checkexpand = FALSE;
9874 cr37 |= 0x10;
9875 }
9876 } else if(yres == 800) {
9877 if( (pclk == 6900) &&
9878 (phb == (1408 - 1280)) &&
9879 (pvb == (816 - 800)) ) {
9880 paneltype = Panel_1280x800;
9881 }
9882 }
9883 break;
9884 case 1400:
9885 if(pSiS->VGAEngine == SIS_315_VGA) {
9886 if(yres == 1050) {
9887 paneltype = Panel310_1400x1050;
9888 checkexpand = TRUE;
9889 }
9890 }
9891 break;
9892 case 1600:
9893 if(pSiS->VGAEngine == SIS_315_VGA) {
9894 if(pSiS->VBFlags & VB_301C) {
9895 if(yres == 1200) {
9896 paneltype = Panel310_1600x1200;
9897 checkexpand = TRUE;
9898 }
9899 }
9900 }
9901 break;
9902 }
9903
9904 /* Save sync: This is used if "Pass 1:1" is off; in this case
9905 * we always use the panel's native mode = this "preferred mode"
9906 * we just have been analysing. Hence, we also need its sync.
9907 */
9908 if((buffer[0x47] & 0x18) == 0x18) {
9909 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
9910 havesync = TRUE;
9911 } else {
9912 /* What now? There is no digital separate output timing... */
9913 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
9914 "LCD sense: Unable to retrieve Sync polarity information\n");
9915 cr37 |= 0xc0; /* Default */
9916 }
9917
9918 }
9919
9920 /* Check against our database; eg. Sanyo Z2 projector reports
9921 * 1024x768 as preferred mode, although it supports 1280x720
9922 * natively in non-HDCP mode. Treat such wrongly reporting
9923 * panels as custom and fixup actual maximum resolutions.
9924 */
9925 if(paneltype != Panel_Custom) {
9926 if(indb) {
9927 paneltype = Panel_Custom;
9928 SiS_Pr->CP_MaxX = maxx;
9929 SiS_Pr->CP_MaxY = maxy;
9930 /* Leave preferred unchanged (MUST contain a valid mode!) */
9931 }
9932 }
9933
9934 /* If we still don't know what panel this is, we take it
9935 * as a custom panel and derive the timing data from the
9936 * detailed timing blocks
9937 */
9938 if(paneltype == Panel_Custom) {
9939
9940 int i, temp, base = 0x36;
9941 unsigned long estpack;
9942 const unsigned short estx[] = {
9943 720, 720, 640, 640, 640, 640, 800, 800,
9944 800, 800, 832,1024,1024,1024,1024,1280,
9945 1152
9946 };
9947 const unsigned short esty[] = {
9948 400, 400, 480, 480, 480, 480, 600, 600,
9949 600, 600, 624, 768, 768, 768, 768,1024,
9950 870
9951 };
9952 const int estclk[] = {
9953 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
9954 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
9955 0
9956 };
9957
9958 paneltype = 0;
9959 SiS_Pr->CP_Supports64048075 = TRUE;
9960
9961 /* Find the maximum resolution */
9962
9963 /* 1. From Established timings */
9964 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
9965 for(i=16; i>=0; i--) {
9966 if(estpack & (1 << i)) {
9967 if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
9968 if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
9969 if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
9970 }
9971 }
9972
9973 /* By default we drive the LCD at 75Hz in 640x480 mode; if
9974 * the panel does not provide this mode, use 60hz
9975 */
9976 if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
9977
9978 /* 2. From Standard Timings */
9979 for(i=0x26; i < 0x36; i+=2) {
9980 if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
9981 temp = (buffer[i] + 31) * 8;
9982 if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
9983 switch((buffer[i+1] & 0xc0) >> 6) {
9984 case 0x03: temp = temp * 9 / 16; break;
9985 case 0x02: temp = temp * 4 / 5; break;
9986 case 0x01: temp = temp * 3 / 4; break;
9987 }
9988 if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
9989 }
9990 }
9991
9992 /* Now extract the Detailed Timings and convert them into modes */
9993
9994 for(i = 0; i < 4; i++, base += 18) {
9995
9996 /* Is this a detailed timing block or a monitor descriptor? */
9997 if(buffer[base] || buffer[base+1] || buffer[base+2]) {
9998
9999 xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
10000 yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
10001
10002 SiS_Pr->CP_HDisplay[i] = xres;
10003 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
10004 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
10005 SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
10006 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10007 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10008
10009 SiS_Pr->CP_VDisplay[i] = yres;
10010 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
10011 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
10012 SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
10013 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10014 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10015
10016 SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
10017
10018 SiS_Pr->CP_DataValid[i] = TRUE;
10019
10020 /* Sort out invalid timings, interlace and too high clocks */
10021 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10022 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10023 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10024 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10025 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10026 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10027 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10028 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10029 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10030 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10031 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10032 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10033 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10034 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10035 ((!(pSiS->VBFlags & VB_301C)) &&
10036 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
10037 (SiS_Pr->CP_HDisplay[i] > 1600)))) ||
10038 (buffer[base+17] & 0x80)) {
10039
10040 SiS_Pr->CP_DataValid[i] = FALSE;
10041
10042 } else {
10043
10044 SiS_Pr->CP_HaveCustomData = TRUE;
10045
10046 if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
10047 if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
10048 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10049
10050 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10051 SiS_Pr->CP_PreferredIndex = i;
10052 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10053 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10054 }
10055
10056 /* Extract the sync polarisation information. This only works
10057 * if the Flags indicate a digital separate output.
10058 */
10059 if((buffer[base+17] & 0x18) == 0x18) {
10060 SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
10061 SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
10062 SiS_Pr->CP_SyncValid[i] = TRUE;
10063 if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
10064 cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
10065 havesync = TRUE;
10066 }
10067 } else {
10068 SiS_Pr->CP_SyncValid[i] = FALSE;
10069 }
10070
10071 }
10072
10073 } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
10074
10075 /* Maximum pixclock from Monitor Range Limits */
10076 if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
10077 int maxclk = buffer[base+9] * 10;
10078 /* More than 170 is not supported anyway */
10079 if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
10080 }
10081
10082 }
10083
10084 }
10085
10086 if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
10087 paneltype = Panel_Custom;
10088 checkexpand = FALSE;
10089 cr37 |= 0x10;
10090 SiS_Pr->CP_Vendor = panelvendor;
10091 SiS_Pr->CP_Product = panelproduct;
10092 }
10093
10094 }
10095
10096 if(paneltype && checkexpand) {
10097 /* If any of the Established low-res modes is supported, the
10098 * panel can scale automatically. For 800x600 panels, we only
10099 * check the even lower ones.
10100 */
10101 if(paneltype == Panel_800x600) {
10102 if(buffer[0x23] & 0xfc) cr37 |= 0x10;
10103 } else {
10104 if(buffer[0x23]) cr37 |= 0x10;
10105 }
10106 }
10107
10108 break;
10109
10110 case 3: /* Analyze EDID V2 */
10111 case 4:
10112 index = 0;
10113
10114 if(!(checkedid2(buffer))) {
10115 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10116 "LCD sense: EDID corrupt\n");
10117 return 0;
10118 }
10119
10120 if((buffer[0x41] & 0x0f) == 0x03) {
10121 index = 0x42 + 3;
10122 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10123 "LCD sense: Display supports TMDS input on primary interface\n");
10124 } else if((buffer[0x41] & 0xf0) == 0x30) {
10125 index = 0x46 + 3;
10126 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10127 "LCD sense: Display supports TMDS input on secondary interface\n");
10128 } else {
10129 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10130 "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
10131 buffer[0x41]);
10132 return 0;
10133 }
10134
10135 SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
10136 SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
10137
10138 paneltype = Panel_Custom;
10139 SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
10140 SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
10141
10142 switch(xres) {
10143#if 0
10144 case 800:
10145 if(yres == 600) {
10146 paneltype = Panel_800x600;
10147 checkexpand = TRUE;
10148 }
10149 break;
10150#endif
10151 case 1024:
10152 if(yres == 768) {
10153 paneltype = Panel_1024x768;
10154 checkexpand = TRUE;
10155 }
10156 break;
10157 case 1280:
10158 if(yres == 960) {
10159 if(pSiS->VGAEngine == SIS_315_VGA) {
10160 paneltype = Panel310_1280x960;
10161 } else {
10162 paneltype = Panel300_1280x960;
10163 }
10164 } else if(yres == 1024) {
10165 paneltype = Panel_1280x1024;
10166 checkexpand = TRUE;
10167 }
10168 /* 1280x768 treated as custom here */
10169 break;
10170 case 1400:
10171 if(pSiS->VGAEngine == SIS_315_VGA) {
10172 if(yres == 1050) {
10173 paneltype = Panel310_1400x1050;
10174 checkexpand = TRUE;
10175 }
10176 }
10177 break;
10178 case 1600:
10179 if(pSiS->VGAEngine == SIS_315_VGA) {
10180 if(pSiS->VBFlags & VB_301C) {
10181 if(yres == 1200) {
10182 paneltype = Panel310_1600x1200;
10183 checkexpand = TRUE;
10184 }
10185 }
10186 }
10187 break;
10188 }
10189
10190 /* Determine if RGB18 or RGB24 */
10191 if(index) {
10192 if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
10193 cr37 |= 0x01;
10194 }
10195 }
10196
10197 if(checkexpand) {
10198 /* TODO - for now, we let the panel scale */
10199 cr37 |= 0x10;
10200 }
10201
10202 /* Now seek 4-Byte Timing codes and extract sync pol info */
10203 index = 0x80;
10204 if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
10205 lumsize = buffer[0x80] & 0x1f;
10206 if(buffer[0x80] & 0x80) lumsize *= 3;
10207 lumsize++; /* luminance header byte */
10208 index += lumsize;
10209 }
10210#if 0 /* "pixel rate" = pixel clock? */
10211 if(buffer[0x7e] & 0x1c) {
10212 for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
10213 if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
10214 int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
10215 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10216 }
10217 }
10218 }
10219#endif
10220 index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
10221 if(buffer[0x7e] & 0x03) {
10222 for(i=0; i<(buffer[0x7e] & 0x03); i++) {
10223 if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
10224 int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
10225 if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
10226 }
10227 }
10228 }
10229 index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
10230 numcodes = (buffer[0x7f] & 0xf8) >> 3;
10231 if(numcodes) {
10232 myindex = index;
10233 seekcode = (xres - 256) / 16;
10234 for(i=0; i<numcodes; i++) {
10235 if(buffer[myindex] == seekcode) break;
10236 myindex += 4;
10237 }
10238 if(buffer[myindex] == seekcode) {
10239 cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
10240 havesync = TRUE;
10241 } else {
10242 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10243 "LCD sense: Unable to retrieve Sync polarity information\n");
10244 }
10245 } else {
10246 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
10247 "LCD sense: Unable to retrieve Sync polarity information\n");
10248 }
10249
10250 /* Check against our database; Eg. Sanyo projector reports
10251 * 1024x768 in non-HDPC mode, although it supports 1280x720.
10252 * Treat such wrongly reporting panels as custom.
10253 */
10254 if(paneltype != Panel_Custom) {
10255 int maxx, maxy, prefx, prefy;
10256 if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
10257 paneltype = Panel_Custom;
10258 SiS_Pr->CP_MaxX = maxx;
10259 SiS_Pr->CP_MaxY = maxy;
10260 cr37 |= 0x10;
10261 /* Leave preferred unchanged (MUST be a valid mode!) */
10262 }
10263 }
10264
10265 /* Now seek the detailed timing descriptions for custom panels */
10266 if(paneltype == Panel_Custom) {
10267
10268 SiS_Pr->CP_Supports64048075 = TRUE;
10269
10270 index += (numcodes * 4);
10271 numcodes = buffer[0x7f] & 0x07;
10272 for(i=0; i<numcodes; i++, index += 18) {
10273 xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
10274 yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
10275
10276 SiS_Pr->CP_HDisplay[i] = xres;
10277 SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
10278 SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
10279 SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
10280 SiS_Pr->CP_HBlankStart[i] = xres + 1;
10281 SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
10282
10283 SiS_Pr->CP_VDisplay[i] = yres;
10284 SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
10285 SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
10286 SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
10287 SiS_Pr->CP_VBlankStart[i] = yres + 1;
10288 SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
10289
10290 SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
10291
10292 SiS_Pr->CP_DataValid[i] = TRUE;
10293
10294 if((SiS_Pr->CP_HDisplay[i] & 7) ||
10295 (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
10296 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10297 (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
10298 (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
10299 (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
10300 (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
10301 (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
10302 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
10303 (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
10304 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
10305 (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
10306 (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
10307 (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
10308 ((!(pSiS->VBFlags & VB_301C)) &&
10309 ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
10310 (buffer[index + 17] & 0x80)) {
10311
10312 SiS_Pr->CP_DataValid[i] = FALSE;
10313
10314 } else {
10315
10316 SiS_Pr->CP_HaveCustomData = TRUE;
10317
10318 if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
10319
10320 if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
10321 SiS_Pr->CP_PreferredIndex = i;
10322 SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
10323 SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
10324 if(!havesync) {
10325 cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
10326 havesync = TRUE;
10327 }
10328 }
10329
10330 SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
10331 SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
10332 SiS_Pr->CP_SyncValid[i] = TRUE;
10333
10334 }
10335 }
10336
10337 cr37 |= 0x10;
10338
10339 }
10340
10341 break;
10342
10343 }
10344
10345 /* 1280x960 panels are always RGB24, unable to scale and use
10346 * high active sync polarity
10347 */
10348 if(pSiS->VGAEngine == SIS_315_VGA) {
10349 if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
10350 } else {
10351 if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
10352 }
10353
10354 for(i = 0; i < 7; i++) {
10355 if(SiS_Pr->CP_DataValid[i]) {
10356 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10357 "Non-standard LCD/DVI-D timing data no. %d:\n", i);
10358 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10359 " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
10360 SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
10361 SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
10362 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10363 " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
10364 SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
10365 SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
10366 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10367 " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
10368 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
10369 " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
10370 SiS_Pr->CP_HDisplay[i],
10371 SiS_Pr->CP_VDisplay[i]);
10372 }
10373 }
10374
10375 if(paneltype) {
10376 if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
10377 if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
10378 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
10379 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
10380 cr37 &= 0xf1;
10381 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
10382 SiS_Pr->PanelSelfDetected = TRUE;
10383#ifdef TWDEBUG
10384 xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
10385 "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
10386#endif
10387 } else {
10388 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
10389 SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
10390 }
10391 return 0;
10392}
10393
10394USHORT
10395SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
10396{
10397 USHORT DDCdatatype,flag;
10398 BOOLEAN foundcrt = FALSE;
10399 int retry;
10400 unsigned char buffer[256];
10401
10402 if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
10403
10404 if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
10405
10406 SiS_Pr->SiS_DDC_SecAddr = 0x00;
10407
10408 /* Probe supported DA's */
10409 flag = SiS_ProbeDDC(SiS_Pr);
10410 if(flag & 0x10) {
10411 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
10412 DDCdatatype = 4;
10413 } else if(flag & 0x08) {
10414 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
10415 DDCdatatype = 3;
10416 } else if(flag & 0x02) {
10417 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
10418 DDCdatatype = 1;
10419 } else {
10420 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10421 "VGA2 sense: Do DDC answer\n");
10422 return 0; /* no DDC support (or no device attached) */
10423 }
10424
10425 /* Read the entire EDID */
10426 retry = 2;
10427 do {
10428 if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
10429 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
10430 "VGA2 sense: DDC read failed (attempt %d), %s\n",
10431 (3-retry), (retry == 1) ? "giving up" : "retrying");
10432 retry--;
10433 if(retry == 0) return 0xFFFF;
10434 } else break;
10435 } while(1);
10436
10437 /* Analyze EDID. We don't have many chances to
10438 * distinguish a flat panel from a CRT...
10439 */
10440 switch(DDCdatatype) {
10441 case 1:
10442 if(!(checkedid1(buffer))) {
10443 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10444 "VGA2 sense: EDID corrupt\n");
10445 return 0;
10446 }
10447 if(buffer[0x14] & 0x80) { /* Display uses digital input */
10448 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10449 "VGA2 sense: Attached display expects digital input\n");
10450 return 0;
10451 }
10452 SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
10453 SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
10454 foundcrt = TRUE;
10455 break;
10456 case 3:
10457 case 4:
10458 if(!(checkedid2(buffer))) {
10459 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10460 "VGA2 sense: EDID corrupt\n");
10461 return 0;
10462 }
10463 if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
10464 ((buffer[0x41] & 0x0f) != 0x02) &&
10465 ((buffer[0x41] & 0xf0) != 0x10) &&
10466 ((buffer[0x41] & 0xf0) != 0x20) ) {
10467 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
10468 "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
10469 buffer[0x41]);
10470 return 0;
10471 }
10472 SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
10473 SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
10474 foundcrt = TRUE;
10475 break;
10476 }
10477
10478 if(foundcrt) {
10479 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
10480 }
10481 return(0);
10482}
10483
10484#endif
10485
10486void
10487SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
10488{
10489 USHORT tempbl;
10490
10491 tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
10492 tempbl = (((tempbl & tempbh) << 8) | tempax);
10493 SiS_SetCH70xx(SiS_Pr,tempbl);
10494}
10495
10496/* Generic I2C functions for Chrontel & DDC --------- */ 9493/* Generic I2C functions for Chrontel & DDC --------- */
10497 9494
10498static void 9495static void
10499SiS_SetSwitchDDC2(SiS_Private *SiS_Pr) 9496SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
10500{ 9497{
10501 SiS_SetSCLKHigh(SiS_Pr); 9498 SiS_SetSCLKHigh(SiS_Pr);
10502 SiS_WaitRetrace1(SiS_Pr); 9499 SiS_WaitRetrace1(SiS_Pr);
@@ -10505,125 +9502,127 @@ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
10505 SiS_WaitRetrace1(SiS_Pr); 9502 SiS_WaitRetrace1(SiS_Pr);
10506} 9503}
10507 9504
10508USHORT 9505unsigned short
10509SiS_ReadDDC1Bit(SiS_Private *SiS_Pr) 9506SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
10510{ 9507{
10511 SiS_WaitRetrace1(SiS_Pr); 9508 SiS_WaitRetrace1(SiS_Pr);
10512 return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1); 9509 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
10513} 9510}
10514 9511
10515/* Set I2C start condition */ 9512/* Set I2C start condition */
10516/* This is done by a SD high-to-low transition while SC is high */ 9513/* This is done by a SD high-to-low transition while SC is high */
10517static USHORT 9514static unsigned short
10518SiS_SetStart(SiS_Private *SiS_Pr) 9515SiS_SetStart(struct SiS_Private *SiS_Pr)
10519{ 9516{
10520 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9517 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10521 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9518 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10522 SiS_Pr->SiS_DDC_Index, 9519 SiS_Pr->SiS_DDC_Index,
10523 SiS_Pr->SiS_DDC_NData, 9520 SiS_Pr->SiS_DDC_NData,
10524 SiS_Pr->SiS_DDC_Data); /* SD->high */ 9521 SiS_Pr->SiS_DDC_Data); /* SD->high */
10525 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9522 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10526 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9523 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10527 SiS_Pr->SiS_DDC_Index, 9524 SiS_Pr->SiS_DDC_Index,
10528 SiS_Pr->SiS_DDC_NData, 9525 SiS_Pr->SiS_DDC_NData,
10529 0x00); /* SD->low = start condition */ 9526 0x00); /* SD->low = start condition */
10530 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9527 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10531 return 0; 9528 return 0;
10532} 9529}
10533 9530
10534/* Set I2C stop condition */ 9531/* Set I2C stop condition */
10535/* This is done by a SD low-to-high transition while SC is high */ 9532/* This is done by a SD low-to-high transition while SC is high */
10536static USHORT 9533static unsigned short
10537SiS_SetStop(SiS_Private *SiS_Pr) 9534SiS_SetStop(struct SiS_Private *SiS_Pr)
10538{ 9535{
10539 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9536 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
10540 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9537 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10541 SiS_Pr->SiS_DDC_Index, 9538 SiS_Pr->SiS_DDC_Index,
10542 SiS_Pr->SiS_DDC_NData, 9539 SiS_Pr->SiS_DDC_NData,
10543 0x00); /* SD->low */ 9540 0x00); /* SD->low */
10544 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9541 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
10545 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9542 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10546 SiS_Pr->SiS_DDC_Index, 9543 SiS_Pr->SiS_DDC_Index,
10547 SiS_Pr->SiS_DDC_NData, 9544 SiS_Pr->SiS_DDC_NData,
10548 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */ 9545 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
10549 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */ 9546 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
10550 return 0; 9547 return 0;
10551} 9548}
10552 9549
10553/* Write 8 bits of data */ 9550/* Write 8 bits of data */
10554static USHORT 9551static unsigned short
10555SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax) 9552SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
10556{ 9553{
10557 USHORT i,flag,temp; 9554 unsigned short i,flag,temp;
10558 9555
10559 flag = 0x80; 9556 flag = 0x80;
10560 for(i=0; i<8; i++) { 9557 for(i = 0; i < 8; i++) {
10561 SiS_SetSCLKLow(SiS_Pr); /* SC->low */ 9558 SiS_SetSCLKLow(SiS_Pr); /* SC->low */
10562 if(tempax & flag) { 9559 if(tempax & flag) {
10563 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9560 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10564 SiS_Pr->SiS_DDC_Index, 9561 SiS_Pr->SiS_DDC_Index,
10565 SiS_Pr->SiS_DDC_NData, 9562 SiS_Pr->SiS_DDC_NData,
10566 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */ 9563 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
10567 } else { 9564 } else {
10568 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9565 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10569 SiS_Pr->SiS_DDC_Index, 9566 SiS_Pr->SiS_DDC_Index,
10570 SiS_Pr->SiS_DDC_NData, 9567 SiS_Pr->SiS_DDC_NData,
10571 0x00); /* Write bit (0) to SD */ 9568 0x00); /* Write bit (0) to SD */
10572 } 9569 }
10573 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */ 9570 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
10574 flag >>= 1; 9571 flag >>= 1;
10575 } 9572 }
10576 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */ 9573 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
10577 return(temp); 9574 return temp;
10578} 9575}
10579 9576
10580static USHORT 9577static unsigned short
10581SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax) 9578SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
10582{ 9579{
10583 USHORT i,temp,getdata; 9580 unsigned short i, temp, getdata;
10584 9581
10585 getdata=0; 9582 getdata = 0;
10586 for(i=0; i<8; i++) { 9583 for(i = 0; i < 8; i++) {
10587 getdata <<= 1; 9584 getdata <<= 1;
10588 SiS_SetSCLKLow(SiS_Pr); 9585 SiS_SetSCLKLow(SiS_Pr);
10589 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9586 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10590 SiS_Pr->SiS_DDC_Index, 9587 SiS_Pr->SiS_DDC_Index,
10591 SiS_Pr->SiS_DDC_NData, 9588 SiS_Pr->SiS_DDC_NData,
10592 SiS_Pr->SiS_DDC_Data); 9589 SiS_Pr->SiS_DDC_Data);
10593 SiS_SetSCLKHigh(SiS_Pr); 9590 SiS_SetSCLKHigh(SiS_Pr);
10594 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9591 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10595 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01; 9592 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
10596 } 9593 }
10597 return(getdata); 9594 return getdata;
10598} 9595}
10599 9596
10600static USHORT 9597static unsigned short
10601SiS_SetSCLKLow(SiS_Private *SiS_Pr) 9598SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
10602{ 9599{
10603 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9600 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10604 SiS_Pr->SiS_DDC_Index, 9601 SiS_Pr->SiS_DDC_Index,
10605 SiS_Pr->SiS_DDC_NClk, 9602 SiS_Pr->SiS_DDC_NClk,
10606 0x00); /* SetSCLKLow() */ 9603 0x00); /* SetSCLKLow() */
10607 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9604 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
10608 return 0; 9605 return 0;
10609} 9606}
10610 9607
10611static USHORT 9608static unsigned short
10612SiS_SetSCLKHigh(SiS_Private *SiS_Pr) 9609SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
10613{ 9610{
10614 USHORT temp, watchdog=1000; 9611 unsigned short temp, watchdog=1000;
10615 9612
10616 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9613 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10617 SiS_Pr->SiS_DDC_Index, 9614 SiS_Pr->SiS_DDC_Index,
10618 SiS_Pr->SiS_DDC_NClk, 9615 SiS_Pr->SiS_DDC_NClk,
10619 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */ 9616 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
10620 do { 9617 do {
10621 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9618 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
10622 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); 9619 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
10623 if (!watchdog) { 9620 if (!watchdog) {
9621#ifdef SIS_XORG_XF86
10624#ifdef TWDEBUG 9622#ifdef TWDEBUG
10625 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n"); 9623 xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
10626#endif 9624#endif
9625#endif
10627 return 0xFFFF; 9626 return 0xFFFF;
10628 } 9627 }
10629 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9628 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
@@ -10632,21 +9631,21 @@ SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
10632 9631
10633/* Check I2C acknowledge */ 9632/* Check I2C acknowledge */
10634/* Returns 0 if ack ok, non-0 if ack not ok */ 9633/* Returns 0 if ack ok, non-0 if ack not ok */
10635static USHORT 9634static unsigned short
10636SiS_CheckACK(SiS_Private *SiS_Pr) 9635SiS_CheckACK(struct SiS_Private *SiS_Pr)
10637{ 9636{
10638 USHORT tempah; 9637 unsigned short tempah;
10639 9638
10640 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */ 9639 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
10641 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9640 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
10642 SiS_Pr->SiS_DDC_Index, 9641 SiS_Pr->SiS_DDC_Index,
10643 SiS_Pr->SiS_DDC_NData, 9642 SiS_Pr->SiS_DDC_NData,
10644 SiS_Pr->SiS_DDC_Data); /* (SD->high) */ 9643 SiS_Pr->SiS_DDC_Data); /* (SD->high) */
10645 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */ 9644 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
10646 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */ 9645 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
10647 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */ 9646 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
10648 if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */ 9647 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
10649 else return(0); 9648 return 0;
10650} 9649}
10651 9650
10652/* End of I2C functions ----------------------- */ 9651/* End of I2C functions ----------------------- */
@@ -10656,67 +9655,67 @@ SiS_CheckACK(SiS_Private *SiS_Pr)
10656 9655
10657#ifdef SIS315H 9656#ifdef SIS315H
10658 9657
10659static USHORT 9658static unsigned short
10660GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 9659GetRAMDACromptr(struct SiS_Private *SiS_Pr)
10661{ 9660{
10662 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 9661 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10663 USHORT romptr; 9662 unsigned short romptr;
10664 9663
10665 if(HwInfo->jChipType < SIS_330) { 9664 if(SiS_Pr->ChipType < SIS_330) {
10666 romptr = SISGETROMW(0x128); 9665 romptr = SISGETROMW(0x128);
10667 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) 9666 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
10668 romptr = SISGETROMW(0x12a); 9667 romptr = SISGETROMW(0x12a);
10669 } else { 9668 } else {
10670 romptr = SISGETROMW(0x1a8); 9669 romptr = SISGETROMW(0x1a8);
10671 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) 9670 if(SiS_Pr->SiS_VBType & VB_SIS30xB)
10672 romptr = SISGETROMW(0x1aa); 9671 romptr = SISGETROMW(0x1aa);
10673 } 9672 }
10674 return(romptr); 9673 return romptr;
10675} 9674}
10676 9675
10677static USHORT 9676static unsigned short
10678GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 9677GetLCDromptr(struct SiS_Private *SiS_Pr)
10679{ 9678{
10680 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 9679 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10681 USHORT romptr; 9680 unsigned short romptr;
10682 9681
10683 if(HwInfo->jChipType < SIS_330) { 9682 if(SiS_Pr->ChipType < SIS_330) {
10684 romptr = SISGETROMW(0x120); 9683 romptr = SISGETROMW(0x120);
10685 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) 9684 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
10686 romptr = SISGETROMW(0x122); 9685 romptr = SISGETROMW(0x122);
10687 } else { 9686 } else {
10688 romptr = SISGETROMW(0x1a0); 9687 romptr = SISGETROMW(0x1a0);
10689 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) 9688 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
10690 romptr = SISGETROMW(0x1a2); 9689 romptr = SISGETROMW(0x1a2);
10691 } 9690 }
10692 return(romptr); 9691 return romptr;
10693} 9692}
10694 9693
10695static USHORT 9694static unsigned short
10696GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 9695GetTVromptr(struct SiS_Private *SiS_Pr)
10697{ 9696{
10698 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 9697 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10699 USHORT romptr; 9698 unsigned short romptr;
10700 9699
10701 if(HwInfo->jChipType < SIS_330) { 9700 if(SiS_Pr->ChipType < SIS_330) {
10702 romptr = SISGETROMW(0x114); 9701 romptr = SISGETROMW(0x114);
10703 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) 9702 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
10704 romptr = SISGETROMW(0x11a); 9703 romptr = SISGETROMW(0x11a);
10705 } else { 9704 } else {
10706 romptr = SISGETROMW(0x194); 9705 romptr = SISGETROMW(0x194);
10707 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) 9706 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
10708 romptr = SISGETROMW(0x19a); 9707 romptr = SISGETROMW(0x19a);
10709 } 9708 }
10710 return(romptr); 9709 return romptr;
10711} 9710}
10712 9711
10713static USHORT 9712static unsigned short
10714GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 9713GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
10715{ 9714{
10716 USHORT index; 9715 unsigned short index;
10717 9716
10718 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 9717 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10719 if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) { 9718 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
10720 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) { 9719 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
10721 index >>= 4; 9720 index >>= 4;
10722 index *= 3; 9721 index *= 3;
@@ -10729,7 +9728,12 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10729 9728
10730 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F; 9729 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
10731 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5; 9730 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
10732 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6; 9731 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
9732 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
9733 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
9734 } else {
9735 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
9736 }
10733 index--; 9737 index--;
10734 index *= 3; 9738 index *= 3;
10735 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9739 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -10737,10 +9741,10 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
10737 return index; 9741 return index;
10738} 9742}
10739 9743
10740static USHORT 9744static unsigned short
10741GetLCDPtrIndex(SiS_Private *SiS_Pr) 9745GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
10742{ 9746{
10743 USHORT index; 9747 unsigned short index;
10744 9748
10745 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3; 9749 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
10746 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9750 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -10748,10 +9752,10 @@ GetLCDPtrIndex(SiS_Private *SiS_Pr)
10748 return index; 9752 return index;
10749} 9753}
10750 9754
10751static USHORT 9755static unsigned short
10752GetTVPtrIndex(SiS_Private *SiS_Pr) 9756GetTVPtrIndex(struct SiS_Private *SiS_Pr)
10753{ 9757{
10754 USHORT index; 9758 unsigned short index;
10755 9759
10756 index = 0; 9760 index = 0;
10757 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9761 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
@@ -10769,10 +9773,10 @@ GetTVPtrIndex(SiS_Private *SiS_Pr)
10769 return index; 9773 return index;
10770} 9774}
10771 9775
10772static ULONG 9776static unsigned int
10773GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme) 9777GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
10774{ 9778{
10775 USHORT index = 0, temp = 0; 9779 unsigned short index = 0, temp = 0;
10776 9780
10777 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9781 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
10778 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2; 9782 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
@@ -10784,7 +9788,7 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10784 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7; 9788 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
10785 } 9789 }
10786 9790
10787 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 9791 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
10788 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 9792 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
10789 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9793 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
10790 index += addme; 9794 index += addme;
@@ -10792,25 +9796,25 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
10792 } 9796 }
10793 temp += 0x0100; 9797 temp += 0x0100;
10794 } 9798 }
10795 return(ULONG)(index | (temp << 16)); 9799 return (unsigned int)(index | (temp << 16));
10796} 9800}
10797 9801
10798static ULONG 9802static unsigned int
10799GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr) 9803GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
10800{ 9804{
10801 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8)); 9805 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
10802} 9806}
10803 9807
10804#if 0 9808#if 0
10805static ULONG 9809static unsigned int
10806GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr) 9810GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
10807{ 9811{
10808 return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6)); 9812 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
10809} 9813}
10810#endif 9814#endif
10811 9815
10812static int 9816static int
10813GetOEMTVPtr661(SiS_Private *SiS_Pr) 9817GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
10814{ 9818{
10815 int index = 0; 9819 int index = 0;
10816 9820
@@ -10833,10 +9837,10 @@ GetOEMTVPtr661(SiS_Private *SiS_Pr)
10833} 9837}
10834 9838
10835static void 9839static void
10836SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo) 9840SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
10837{ 9841{
10838 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 9842 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
10839 USHORT delay=0,index,myindex,temp,romptr=0; 9843 unsigned short delay=0,index,myindex,temp,romptr=0;
10840 BOOLEAN dochiptest = TRUE; 9844 BOOLEAN dochiptest = TRUE;
10841 9845
10842 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 9846 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
@@ -10848,19 +9852,19 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10848 /* Find delay (from ROM, internal tables, PCI subsystem) */ 9852 /* Find delay (from ROM, internal tables, PCI subsystem) */
10849 9853
10850 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */ 9854 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
10851 9855
10852 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9856 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10853 romptr = GetRAMDACromptr(SiS_Pr, HwInfo); 9857 romptr = GetRAMDACromptr(SiS_Pr);
10854 } 9858 }
10855 if(romptr) delay = ROMAddr[romptr]; 9859 if(romptr) delay = ROMAddr[romptr];
10856 else { 9860 else {
10857 delay = 0x04; 9861 delay = 0x04;
10858 if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 9862 if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
10859 if(IS_SIS650) { 9863 if(IS_SIS650) {
10860 delay = 0x0a; 9864 delay = 0x0a;
10861 } else if(IS_SIS740) { 9865 } else if(IS_SIS740) {
10862 delay = 0x00; 9866 delay = 0x00;
10863 } else if(HwInfo->jChipType < SIS_330) { 9867 } else if(SiS_Pr->ChipType < SIS_330) {
10864 delay = 0x0c; 9868 delay = 0x0c;
10865 } else { 9869 } else {
10866 delay = 0x0c; 9870 delay = 0x0c;
@@ -10901,8 +9905,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10901 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay); 9905 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
10902 } else { 9906 } else {
10903 delay = 0x0c; 9907 delay = 0x0c;
10904 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03; 9908 if(SiS_Pr->SiS_VBType & VB_SIS301C) {
10905 else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 9909 delay = 0x03;
9910 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
9911 delay = 0x00;
9912 }
9913 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10906 if(IS_SIS740) delay = 0x01; 9914 if(IS_SIS740) delay = 0x01;
10907 else delay = 0x03; 9915 else delay = 0x03;
10908 } 9916 }
@@ -10947,12 +9955,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10947 9955
10948 if(!gotitfrompci) { 9956 if(!gotitfrompci) {
10949 9957
10950 index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo); 9958 index = GetLCDPtrIndexBIOS(SiS_Pr);
10951 myindex = GetLCDPtrIndex(SiS_Pr); 9959 myindex = GetLCDPtrIndex(SiS_Pr);
10952 9960
10953 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 9961 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10954 9962
10955 if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) { 9963 if(SiS_IsNotM650orLater(SiS_Pr)) {
10956 9964
10957 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9965 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
10958 /* Always use the second pointer on 650; some BIOSes */ 9966 /* Always use the second pointer on 650; some BIOSes */
@@ -10978,11 +9986,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10978 (!(SiS_Pr->SiS_ROMNew)) && 9986 (!(SiS_Pr->SiS_ROMNew)) &&
10979 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) && 9987 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
10980 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) && 9988 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
10981 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) { 9989 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
9990 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
9991 ((romptr = GetLCDromptr(SiS_Pr)))) {
10982 9992
10983 /* Data for 1280x1024 wrong in 301B BIOS */ 9993 /* Data for 1280x1024 wrong in 301B BIOS */
10984 romptr = GetLCDromptr(SiS_Pr, HwInfo); 9994 /* Data for 1600x1200 wrong in 301C BIOS */
10985 if(!romptr) return;
10986 delay = ROMAddr[(romptr + index)]; 9995 delay = ROMAddr[(romptr + index)];
10987 9996
10988 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 9997 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -10993,14 +10002,15 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
10993 } else { 10002 } else {
10994 10003
10995 delay = SiS310_LCDDelayCompensation_301[myindex]; 10004 delay = SiS310_LCDDelayCompensation_301[myindex];
10996 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 10005 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
10997 if(IS_SIS740) delay = 0x01; 10006 if(IS_SIS740) delay = 0x01;
10998 else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex]; 10007 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
10999 else delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10008 else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
11000 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10009 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
11001 if(IS_SIS740) delay = 0x01; /* ? */ 10010 if(IS_SIS740) delay = 0x01; /* ? */
11002 else delay = 0x03; 10011 else delay = 0x03;
11003 } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 10012 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
10013 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
11004 if(IS_SIS740) delay = 0x01; 10014 if(IS_SIS740) delay = 0x01;
11005 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex]; 10015 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
11006 } 10016 }
@@ -11013,14 +10023,14 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0)); 10023 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
11014 dochiptest = FALSE; 10024 dochiptest = FALSE;
11015 } 10025 }
11016 10026
11017 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */ 10027 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
11018 10028
11019 index = GetTVPtrIndex(SiS_Pr); 10029 index = GetTVPtrIndex(SiS_Pr);
11020
11021 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
11022 10030
11023 if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) { 10031 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
10032
10033 if(SiS_IsNotM650orLater(SiS_Pr)) {
11024 10034
11025 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10035 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11026 /* Always use the second pointer on 650; some BIOSes */ 10036 /* Always use the second pointer on 650; some BIOSes */
@@ -11062,7 +10072,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11062 10072
11063 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10073 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
11064 10074
11065 romptr = GetTVromptr(SiS_Pr, HwInfo); 10075 romptr = GetTVromptr(SiS_Pr);
11066 if(!romptr) return; 10076 if(!romptr) return;
11067 delay = ROMAddr[romptr + index]; 10077 delay = ROMAddr[romptr + index];
11068 10078
@@ -11073,7 +10083,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11073 } else { 10083 } else {
11074 10084
11075 delay = SiS310_TVDelayCompensation_301[index]; 10085 delay = SiS310_TVDelayCompensation_301[index];
11076 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 10086 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11077 if(IS_SIS740) { 10087 if(IS_SIS740) {
11078 delay = SiS310_TVDelayCompensation_740301B[index]; 10088 delay = SiS310_TVDelayCompensation_740301B[index];
11079 /* LV: use 301 data? BIOS bug? */ 10089 /* LV: use 301 data? BIOS bug? */
@@ -11085,18 +10095,18 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11085 10095
11086 } 10096 }
11087 10097
11088 if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) { 10098 if(SiS_LCDAEnabled(SiS_Pr)) {
11089 delay &= 0x0f; 10099 delay &= 0x0f;
11090 dochiptest = FALSE; 10100 dochiptest = FALSE;
11091 } 10101 }
11092 10102
11093 } else return; 10103 } else return;
11094 10104
11095 /* Write delay */ 10105 /* Write delay */
11096 10106
11097 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10107 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11098 10108
11099 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) { 10109 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
11100 10110
11101 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4; 10111 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
11102 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */ 10112 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
@@ -11134,11 +10144,10 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
11134} 10144}
11135 10145
11136static void 10146static void
11137SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10147SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11138 USHORT ModeNo,USHORT ModeIdIndex)
11139{ 10148{
11140 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10149 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11141 USHORT index,temp,temp1,romptr=0; 10150 unsigned short index,temp,temp1,romptr=0;
11142 10151
11143 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return; 10152 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
11144 10153
@@ -11152,14 +10161,14 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11152 temp1 = temp; 10161 temp1 = temp;
11153 10162
11154 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10163 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11155 if(HwInfo->jChipType >= SIS_661) { 10164 if(SiS_Pr->ChipType >= SIS_661) {
11156 temp1 = GetOEMTVPtr661(SiS_Pr); 10165 temp1 = GetOEMTVPtr661(SiS_Pr);
11157 temp1 >>= 1; 10166 temp1 >>= 1;
11158 romptr = SISGETROMW(0x260); 10167 romptr = SISGETROMW(0x260);
11159 if(HwInfo->jChipType >= SIS_760) { 10168 if(SiS_Pr->ChipType >= SIS_760) {
11160 romptr = SISGETROMW(0x360); 10169 romptr = SISGETROMW(0x360);
11161 } 10170 }
11162 } else if(HwInfo->jChipType >= SIS_330) { 10171 } else if(SiS_Pr->ChipType >= SIS_330) {
11163 romptr = SISGETROMW(0x192); 10172 romptr = SISGETROMW(0x192);
11164 } else { 10173 } else {
11165 romptr = SISGETROMW(0x112); 10174 romptr = SISGETROMW(0x112);
@@ -11178,11 +10187,10 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11178} 10187}
11179 10188
11180static void 10189static void
11181SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10190SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11182 USHORT ModeNo,USHORT ModeIdIndex)
11183{ 10191{
11184 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10192 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11185 USHORT index,temp,temp1,romptr=0; 10193 unsigned short index,temp,temp1,romptr=0;
11186 10194
11187 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10195 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
11188 10196
@@ -11192,14 +10200,14 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11192 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; 10200 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
11193 10201
11194 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10202 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
11195 if(HwInfo->jChipType >= SIS_661) { 10203 if(SiS_Pr->ChipType >= SIS_661) {
11196 romptr = SISGETROMW(0x26c); 10204 romptr = SISGETROMW(0x26c);
11197 if(HwInfo->jChipType >= SIS_760) { 10205 if(SiS_Pr->ChipType >= SIS_760) {
11198 romptr = SISGETROMW(0x36c); 10206 romptr = SISGETROMW(0x36c);
11199 } 10207 }
11200 temp1 = GetOEMTVPtr661(SiS_Pr); 10208 temp1 = GetOEMTVPtr661(SiS_Pr);
11201 temp1 >>= 1; 10209 temp1 >>= 1;
11202 } else if(HwInfo->jChipType >= SIS_330) { 10210 } else if(SiS_Pr->ChipType >= SIS_330) {
11203 romptr = SISGETROMW(0x1a4); 10211 romptr = SISGETROMW(0x1a4);
11204 } else { 10212 } else {
11205 romptr = SISGETROMW(0x124); 10213 romptr = SISGETROMW(0x124);
@@ -11217,10 +10225,9 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11217} 10225}
11218 10226
11219static void 10227static void
11220SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10228SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11221 USHORT ModeNo,USHORT ModeIdIndex)
11222{ 10229{
11223 USHORT index, temp, i, j; 10230 unsigned short index, temp, i, j;
11224 10231
11225 if(ModeNo <= 0x13) { 10232 if(ModeNo <= 0x13) {
11226 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; 10233 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
@@ -11235,7 +10242,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11235 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */ 10242 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
11236 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */ 10243 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
11237 10244
11238 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 10245 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11239 for(i=0x35, j=0; i<=0x38; i++, j++) { 10246 for(i=0x35, j=0; i<=0x38; i++, j++) {
11240 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10247 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
11241 } 10248 }
@@ -11250,23 +10257,22 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11250} 10257}
11251 10258
11252static void 10259static void
11253SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10260SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11254 USHORT ModeNo,USHORT ModeIdIndex)
11255{ 10261{
11256 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10262 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11257 USHORT index,temp,i,j,resinfo,romptr=0; 10263 unsigned short index,temp,i,j,resinfo,romptr=0;
11258 ULONG lindex; 10264 unsigned int lindex;
11259 10265
11260 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 10266 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
11261 10267
11262 /* NTSC-J data not in BIOS, and already set in SetGroup2 */ 10268 /* NTSC-J data not in BIOS, and already set in SetGroup2 */
11263 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return; 10269 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
11264 10270
11265 if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) { 10271 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
11266 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff; 10272 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
11267 lindex <<= 2; 10273 lindex <<= 2;
11268 for(j=0, i=0x31; i<=0x34; i++, j++) { 10274 for(j=0, i=0x31; i<=0x34; i++, j++) {
11269 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]); 10275 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
11270 } 10276 }
11271 return; 10277 return;
11272 } 10278 }
@@ -11286,17 +10292,17 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11286 */ 10292 */
11287 if(SiS_Pr->SiS_UseROM) { 10293 if(SiS_Pr->SiS_UseROM) {
11288 romptr = SISGETROMW(0x116); 10294 romptr = SISGETROMW(0x116);
11289 if(HwInfo->jChipType >= SIS_330) { 10295 if(SiS_Pr->ChipType >= SIS_330) {
11290 romptr = SISGETROMW(0x196); 10296 romptr = SISGETROMW(0x196);
11291 } 10297 }
11292 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 10298 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
11293 romptr = SISGETROMW(0x11c); 10299 romptr = SISGETROMW(0x11c);
11294 if(HwInfo->jChipType >= SIS_330) { 10300 if(SiS_Pr->ChipType >= SIS_330) {
11295 romptr = SISGETROMW(0x19c); 10301 romptr = SISGETROMW(0x19c);
11296 } 10302 }
11297 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) { 10303 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
11298 romptr = SISGETROMW(0x116); 10304 romptr = SISGETROMW(0x116);
11299 if(HwInfo->jChipType >= SIS_330) { 10305 if(SiS_Pr->ChipType >= SIS_330) {
11300 romptr = SISGETROMW(0x196); 10306 romptr = SISGETROMW(0x196);
11301 } 10307 }
11302 } 10308 }
@@ -11311,7 +10317,7 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11311 index = temp % 2; 10317 index = temp % 2;
11312 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */ 10318 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
11313 for(j=0, i=0x31; i<=0x34; i++, j++) { 10319 for(j=0, i=0x31; i<=0x34; i++, j++) {
11314 if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) 10320 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
11315 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10321 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
11316 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) 10322 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
11317 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]); 10323 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
@@ -11320,7 +10326,7 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11320 } 10326 }
11321 } 10327 }
11322 10328
11323 if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) { 10329 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
11324 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) { 10330 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
11325 if((resinfo == SIS_RI_640x480) || 10331 if((resinfo == SIS_RI_640x480) ||
11326 (resinfo == SIS_RI_800x600)) { 10332 (resinfo == SIS_RI_800x600)) {
@@ -11339,11 +10345,11 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11339} 10345}
11340 10346
11341static void 10347static void
11342SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, 10348SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
11343 USHORT ModeIdIndex, USHORT RTI) 10349 unsigned short ModeIdIndex, unsigned short RTI)
11344{ 10350{
11345 USHORT delay = 0, romptr = 0, index, lcdpdcindex; 10351 unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
11346 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10352 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11347 10353
11348 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC))) 10354 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
11349 return; 10355 return;
@@ -11359,7 +10365,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11359 if(SiS_Pr->UseCustomMode) { 10365 if(SiS_Pr->UseCustomMode) {
11360 index = SiS_Pr->CSRClock; 10366 index = SiS_Pr->CSRClock;
11361 } else if(ModeNo > 0x13) { 10367 } else if(ModeNo > 0x13) {
11362 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo); 10368 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
11363 index = SiS_Pr->SiS_VCLKData[index].CLOCK; 10369 index = SiS_Pr->SiS_VCLKData[index].CLOCK;
11364 } 10370 }
11365 if(index < 25) index = 25; 10371 if(index < 25) index = 25;
@@ -11387,7 +10393,36 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11387 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4); 10393 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
11388 delay |= (delay << 8); 10394 delay |= (delay << 8);
11389 10395
11390 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10396 if(SiS_Pr->ChipType >= XGI_20) {
10397
10398 delay = 0x0606;
10399 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10400
10401 delay = 0x0404;
10402 if(SiS_Pr->SiS_XGIROM) {
10403 index = GetTVPtrIndex(SiS_Pr);
10404 if((romptr = SISGETROMW(0x35e))) {
10405 delay = (ROMAddr[romptr + index] & 0x0f) << 1;
10406 delay |= (delay << 8);
10407 }
10408 }
10409
10410 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
10411 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
10412 delay -= 0x0404;
10413 }
10414 }
10415 }
10416
10417 } else if(SiS_Pr->ChipType >= SIS_340) {
10418
10419 delay = 0x0606;
10420 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
10421 delay = 0x0404;
10422 }
10423 /* TODO (eventually) */
10424
10425 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11391 10426
11392 /* 3. TV */ 10427 /* 3. TV */
11393 10428
@@ -11406,7 +10441,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11406 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */ 10441 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
11407 10442
11408 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) && 10443 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
11409 ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) { 10444 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
11410 10445
11411 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12; 10446 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
11412 10447
@@ -11426,6 +10461,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11426 case Panel_1280x768_2:delay = 0x0004; break; 10461 case Panel_1280x768_2:delay = 0x0004; break;
11427 case Panel_1280x800: 10462 case Panel_1280x800:
11428 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */ 10463 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
10464 case Panel_1280x854: delay = 0x0004; break; /* FIXME */
11429 case Panel_1280x1024: delay = 0x1e04; break; 10465 case Panel_1280x1024: delay = 0x1e04; break;
11430 case Panel_1400x1050: delay = 0x0004; break; 10466 case Panel_1400x1050: delay = 0x0004; break;
11431 case Panel_1600x1200: delay = 0x0400; break; 10467 case Panel_1600x1200: delay = 0x0400; break;
@@ -11469,10 +10505,10 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
11469} 10505}
11470 10506
11471static void 10507static void
11472SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI) 10508SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
11473{ 10509{
11474 USHORT infoflag; 10510 unsigned short infoflag;
11475 UCHAR temp; 10511 unsigned char temp;
11476 10512
11477 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10513 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11478 10514
@@ -11513,12 +10549,16 @@ SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, US
11513} 10549}
11514 10550
11515static void 10551static void
11516SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) 10552SetPanelParms661(struct SiS_Private *SiS_Pr)
11517{ 10553{
11518 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10554 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11519 USHORT romptr, temp1, temp2; 10555 unsigned short romptr, temp1, temp2;
10556
10557 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
10558 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
10559 }
11520 10560
11521 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) { 10561 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
11522 if(SiS_Pr->LVDSHL != -1) { 10562 if(SiS_Pr->LVDSHL != -1) {
11523 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10563 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
11524 } 10564 }
@@ -11526,8 +10566,8 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11526 10566
11527 if(SiS_Pr->SiS_ROMNew) { 10567 if(SiS_Pr->SiS_ROMNew) {
11528 10568
11529 if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) { 10569 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
11530 if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) { 10570 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
11531 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c; 10571 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
11532 temp2 = 0xfc; 10572 temp2 = 0xfc;
11533 if(SiS_Pr->LVDSHL != -1) { 10573 if(SiS_Pr->LVDSHL != -1) {
@@ -11546,48 +10586,47 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
11546} 10586}
11547 10587
11548static void 10588static void
11549SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10589SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
11550 USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
11551{ 10590{
11552 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10591 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
11553 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI); 10592 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
11554 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10593 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11555 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI); 10594 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
11556 SetPanelParms661(SiS_Pr,HwInfo); 10595 SetPanelParms661(SiS_Pr);
11557 } 10596 }
11558 } else { 10597 } else {
11559 SetDelayComp(SiS_Pr,HwInfo,ModeNo); 10598 SetDelayComp(SiS_Pr,ModeNo);
11560 } 10599 }
11561 10600
11562 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 10601 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
11563 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10602 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
11564 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10603 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
11565 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10604 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
11566 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10605 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11567 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10606 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
11568 } 10607 }
11569 } 10608 }
11570} 10609}
11571 10610
11572static void 10611static void
11573SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10612SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
11574 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI) 10613 unsigned short ModeIdIndex, unsigned short RRTI)
11575{ 10614{
11576 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10615 if(SiS_Pr->SiS_VBType & VB_SISVB) {
11577 10616
11578 SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI); 10617 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
11579 10618
11580 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10619 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11581 SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI); 10620 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
11582 SetPanelParms661(SiS_Pr,HwInfo); 10621 SetPanelParms661(SiS_Pr);
11583 } 10622 }
11584 10623
11585 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10624 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
11586 SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10625 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
11587 SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10626 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
11588 SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10627 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
11589 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10628 if(SiS_Pr->SiS_VBType & VB_SIS301) {
11590 SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex); 10629 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
11591 } 10630 }
11592 } 10631 }
11593 } 10632 }
@@ -11601,13 +10640,12 @@ SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11601 * pray that we have a backup... 10640 * pray that we have a backup...
11602 */ 10641 */
11603static void 10642static void
11604SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 10643SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11605 PSIS_HW_INFO HwInfo)
11606{ 10644{
11607 USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp; 10645 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
11608 USHORT resinfo,modeflag; 10646 unsigned short resinfo,modeflag;
11609 10647
11610 if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return; 10648 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
11611 if(SiS_Pr->SiS_ROMNew) return; 10649 if(SiS_Pr->SiS_ROMNew) return;
11612 10650
11613 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10651 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11678,7 +10716,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11678 10716
11679 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10717 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
11680 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10718 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
11681 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) { 10719 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
11682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 10720 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
11683#ifdef SET_EMI 10721#ifdef SET_EMI
11684 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 10722 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
@@ -11806,11 +10844,11 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
11806#ifdef SIS300 10844#ifdef SIS300
11807 10845
11808static void 10846static void
11809SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10847SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
11810 USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex) 10848 unsigned short RefTabIndex)
11811{ 10849{
11812 USHORT crt2crtc=0, modeflag, myindex=0; 10850 unsigned short crt2crtc=0, modeflag, myindex=0;
11813 UCHAR temp; 10851 unsigned char temp;
11814 int i; 10852 int i;
11815 10853
11816 if(ModeNo <= 0x13) { 10854 if(ModeNo <= 0x13) {
@@ -11849,21 +10887,21 @@ SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11849 } 10887 }
11850} 10888}
11851 10889
11852static USHORT 10890static unsigned short
11853GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag) 10891GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
11854{ 10892{
11855 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10893 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11856 USHORT tempbx=0,romptr=0; 10894 unsigned short tempbx=0,romptr=0;
11857 UCHAR customtable300[] = { 10895 static const unsigned char customtable300[] = {
11858 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 10896 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11859 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 10897 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11860 }; 10898 };
11861 UCHAR customtable630[] = { 10899 static const unsigned char customtable630[] = {
11862 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 10900 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
11863 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 10901 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
11864 }; 10902 };
11865 10903
11866 if(HwInfo->jChipType == SIS_300) { 10904 if(SiS_Pr->ChipType == SIS_300) {
11867 10905
11868 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f; 10906 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
11869 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07; 10907 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
@@ -11912,11 +10950,10 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
11912} 10950}
11913 10951
11914static void 10952static void
11915SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 10953SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
11916 USHORT ModeNo,USHORT ModeIdIndex)
11917{ 10954{
11918 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 10955 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11919 USHORT index,temp,romptr=0; 10956 unsigned short index,temp,romptr=0;
11920 10957
11921 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 10958 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
11922 10959
@@ -11927,22 +10964,22 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11927 } 10964 }
11928 10965
11929 /* The Panel Compensation Delay should be set according to tables 10966 /* The Panel Compensation Delay should be set according to tables
11930 * here. Unfortunately, various BIOS versions don't case about 10967 * here. Unfortunately, various BIOS versions don't care about
11931 * a uniform way using eg. ROM byte 0x220, but use different 10968 * a uniform way using eg. ROM byte 0x220, but use different
11932 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). 10969 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
11933 * Thus we don't set this if the user select a custom pdc or if 10970 * Thus we don't set this if the user selected a custom pdc or if
11934 * we otherwise detected a valid pdc. 10971 * we otherwise detected a valid pdc.
11935 */ 10972 */
11936 if(SiS_Pr->PDC != -1) return; 10973 if(SiS_Pr->PDC != -1) return;
11937 10974
11938 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0); 10975 temp = GetOEMLCDPtr(SiS_Pr, 0);
11939 10976
11940 if(SiS_Pr->UseCustomMode) 10977 if(SiS_Pr->UseCustomMode)
11941 index = 0; 10978 index = 0;
11942 else 10979 else
11943 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; 10980 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
11944 10981
11945 if(HwInfo->jChipType != SIS_300) { 10982 if(SiS_Pr->ChipType != SIS_300) {
11946 if(romptr) { 10983 if(romptr) {
11947 romptr += (temp * 2); 10984 romptr += (temp * 2);
11948 romptr = SISGETROMW(romptr); 10985 romptr = SISGETROMW(romptr);
@@ -11986,12 +11023,11 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11986} 11023}
11987 11024
11988static void 11025static void
11989SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11026SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
11990 USHORT ModeNo,USHORT ModeIdIndex)
11991{ 11027{
11992#if 0 /* Unfinished; Data table missing */ 11028#if 0 /* Unfinished; Data table missing */
11993 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 11029 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
11994 USHORT index,temp; 11030 unsigned short index,temp;
11995 11031
11996 if((SiS_Pr->SiS_UseROM) { 11032 if((SiS_Pr->SiS_UseROM) {
11997 if(!(ROMAddr[0x237] & 0x01)) return; 11033 if(!(ROMAddr[0x237] & 0x01)) return;
@@ -11999,8 +11035,8 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
11999 /* No rom pointer in BIOS header! */ 11035 /* No rom pointer in BIOS header! */
12000 } 11036 }
12001 11037
12002 temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1); 11038 temp = GetOEMLCDPtr(SiS_Pr, 1);
12003 if(temp = 0xFFFF) return; 11039 if(temp == 0xFFFF) return;
12004 11040
12005 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex; 11041 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
12006 for(i=0x14, j=0; i<=0x17; i++, j++) { 11042 for(i=0x14, j=0; i<=0x17; i++, j++) {
@@ -12018,10 +11054,10 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12018#endif 11054#endif
12019} 11055}
12020 11056
12021static USHORT 11057static unsigned short
12022GetOEMTVPtr(SiS_Private *SiS_Pr) 11058GetOEMTVPtr(struct SiS_Private *SiS_Pr)
12023{ 11059{
12024 USHORT index; 11060 unsigned short index;
12025 11061
12026 index = 0; 11062 index = 0;
12027 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4; 11063 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
@@ -12037,11 +11073,10 @@ GetOEMTVPtr(SiS_Private *SiS_Pr)
12037} 11073}
12038 11074
12039static void 11075static void
12040SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11076SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
12041 USHORT ModeNo,USHORT ModeIdIndex)
12042{ 11077{
12043 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 11078 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
12044 USHORT index,temp,romptr=0; 11079 unsigned short index,temp,romptr=0;
12045 11080
12046 if(SiS_Pr->SiS_UseROM) { 11081 if(SiS_Pr->SiS_UseROM) {
12047 if(!(ROMAddr[0x238] & 0x01)) return; 11082 if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12070,11 +11105,10 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12070} 11105}
12071 11106
12072static void 11107static void
12073SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11108SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
12074 USHORT ModeNo, USHORT ModeIdIndex)
12075{ 11109{
12076 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 11110 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
12077 USHORT index,temp,romptr=0; 11111 unsigned short index,temp,romptr=0;
12078 11112
12079 if(SiS_Pr->SiS_UseROM) { 11113 if(SiS_Pr->SiS_UseROM) {
12080 if(!(ROMAddr[0x238] & 0x01)) return; 11114 if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12099,11 +11133,10 @@ SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12099} 11133}
12100 11134
12101static void 11135static void
12102SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11136SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
12103 USHORT ModeNo,USHORT ModeIdIndex)
12104{ 11137{
12105 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 11138 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
12106 USHORT index,i,j,temp,romptr=0; 11139 unsigned short index,i,j,temp,romptr=0;
12107 11140
12108 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return; 11141 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
12109 11142
@@ -12119,7 +11152,7 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12119 11152
12120 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex; 11153 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
12121 11154
12122 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 11155 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
12123 for(i=0x31, j=0; i<=0x34; i++, j++) { 11156 for(i=0x31, j=0; i<=0x34; i++, j++) {
12124 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]); 11157 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
12125 } 11158 }
@@ -12140,11 +11173,10 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12140} 11173}
12141 11174
12142static void 11175static void
12143SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11176SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
12144 USHORT ModeNo,USHORT ModeIdIndex)
12145{ 11177{
12146 UCHAR *ROMAddr = HwInfo->pjVirtualRomBase; 11178 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
12147 USHORT index,temp,i,j,romptr=0; 11179 unsigned short index,temp,i,j,romptr=0;
12148 11180
12149 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return; 11181 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
12150 11182
@@ -12162,7 +11194,7 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12162 11194
12163 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex; 11195 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
12164 11196
12165 if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { 11197 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
12166 for(i=0x35, j=0; i<=0x38; i++, j++) { 11198 for(i=0x35, j=0; i<=0x38; i++, j++) {
12167 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11199 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
12168 } 11200 }
@@ -12185,11 +11217,11 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12185 } 11217 }
12186} 11218}
12187 11219
12188static USHORT 11220static unsigned short
12189SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo) 11221SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
12190{ 11222{
12191 USHORT ModeIdIndex; 11223 unsigned short ModeIdIndex;
12192 UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO; 11224 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
12193 11225
12194 if(*ModeNo <= 5) *ModeNo |= 1; 11226 if(*ModeNo <= 5) *ModeNo |= 1;
12195 11227
@@ -12210,10 +11242,10 @@ SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
12210} 11242}
12211 11243
12212static void 11244static void
12213SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 11245SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
12214 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex) 11246 unsigned short RefTableIndex)
12215{ 11247{
12216 USHORT OEMModeIdIndex=0; 11248 unsigned short OEMModeIdIndex = 0;
12217 11249
12218 if(!SiS_Pr->UseCustomMode) { 11250 if(!SiS_Pr->UseCustomMode) {
12219 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo); 11251 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
@@ -12221,18 +11253,18 @@ SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
12221 } 11253 }
12222 11254
12223 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 11255 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
12224 SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex); 11256 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
12225 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 11257 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
12226 SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex); 11258 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
12227 } 11259 }
12228 } 11260 }
12229 if(SiS_Pr->UseCustomMode) return; 11261 if(SiS_Pr->UseCustomMode) return;
12230 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 11262 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
12231 SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex); 11263 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
12232 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11264 if(SiS_Pr->SiS_VBType & VB_SISVB) {
12233 SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex); 11265 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
12234 SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex); 11266 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
12235 SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex); 11267 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
12236 } 11268 }
12237 } 11269 }
12238} 11270}
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index f84eb54164a5..f475b21a85cf 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * Data and prototypes for init301.c 4 * Data and prototypes for init301.c
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,18 +50,18 @@
50 * 50 *
51 */ 51 */
52 52
53#ifndef _INIT301_ 53#ifndef _INIT301_H_
54#define _INIT301_ 54#define _INIT301_H_
55 55
56#include "osdef.h" 56#include "osdef.h"
57#include "initdef.h" 57#include "initdef.h"
58 58
59#ifdef LINUX_XF86 59#ifdef SIS_XORG_XF86
60#include "sis.h" 60#include "sis.h"
61#include "sis_regs.h" 61#include "sis_regs.h"
62#endif 62#endif
63 63
64#ifdef LINUX_KERNEL 64#ifdef SIS_LINUX_KERNEL
65#include "vgatypes.h" 65#include "vgatypes.h"
66#include "vstruct.h" 66#include "vstruct.h"
67#ifdef SIS_CP 67#ifdef SIS_CP
@@ -69,8 +69,13 @@
69#endif 69#endif
70#include <linux/config.h> 70#include <linux/config.h>
71#include <linux/version.h> 71#include <linux/version.h>
72#include <asm/io.h>
73#include <linux/types.h> 72#include <linux/types.h>
73#include <asm/io.h>
74#include <linux/fb.h>
75#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
76#include <video/fbcon.h>
77#endif
78#include "sis.h"
74#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 79#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
75#include <linux/sisfb.h> 80#include <linux/sisfb.h>
76#else 81#else
@@ -78,7 +83,7 @@
78#endif 83#endif
79#endif 84#endif
80 85
81static const UCHAR SiS_YPbPrTable[3][64] = { 86static const unsigned char SiS_YPbPrTable[3][64] = {
82 { 87 {
83 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, 88 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
84 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, 89 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -90,17 +95,17 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
90 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 95 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
91 }, 96 },
92 { 97 {
93 0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c, 98 0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
94 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a, 99 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
95 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 100 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
96 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13, 101 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
97 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8, 102 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
98 0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40, 103 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
99 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b, 104 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
100 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00 105 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
101 }, 106 },
102 { 107 {
103#if 1 108#if 0 /* OK, but sticks to left edge */
104 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c, 109 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
105 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a, 110 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
106 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 111 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
@@ -110,20 +115,42 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
110 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27, 115 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
111 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00 116 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
112#endif 117#endif
113#if 0 118#if 1 /* Perfect */
114 0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c, /* TEST (0.93) - BAD */ 119 0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
115 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a, 120 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
116 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 121 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
117 0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13, 122 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
118 0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0, 123 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
119 0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff, 124 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
120 0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f, 125 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
121 0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00 126 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
122#endif 127#endif
123 } 128 }
124}; 129};
125 130
126static const UCHAR SiS_HiTVGroup3_1[] = { 131static const unsigned char SiS_TVPhase[] =
132{
133 0x21,0xED,0xBA,0x08, /* 0x00 SiS_NTSCPhase */
134 0x2A,0x05,0xE3,0x00, /* 0x01 SiS_PALPhase */
135 0x21,0xE4,0x2E,0x9B, /* 0x02 SiS_PALMPhase */
136 0x21,0xF4,0x3E,0xBA, /* 0x03 SiS_PALNPhase */
137 0x1E,0x8B,0xA2,0xA7,
138 0x1E,0x83,0x0A,0xE0, /* 0x05 SiS_SpecialPhaseM */
139 0x00,0x00,0x00,0x00,
140 0x00,0x00,0x00,0x00,
141 0x21,0xF0,0x7B,0xD6, /* 0x08 SiS_NTSCPhase2 */
142 0x2A,0x09,0x86,0xE9, /* 0x09 SiS_PALPhase2 */
143 0x21,0xE6,0xEF,0xA4, /* 0x0a SiS_PALMPhase2 */
144 0x21,0xF6,0x94,0x46, /* 0x0b SiS_PALNPhase2 */
145 0x1E,0x8B,0xA2,0xA7,
146 0x1E,0x83,0x0A,0xE0, /* 0x0d SiS_SpecialPhaseM */
147 0x00,0x00,0x00,0x00,
148 0x00,0x00,0x00,0x00,
149 0x1e,0x8c,0x5c,0x7a, /* 0x10 SiS_SpecialPhase */
150 0x25,0xd4,0xfd,0x5e /* 0x11 SiS_SpecialPhaseJ */
151};
152
153static const unsigned char SiS_HiTVGroup3_1[] = {
127 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, 154 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
128 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6, 155 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
129 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, 156 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -134,7 +161,7 @@ static const UCHAR SiS_HiTVGroup3_1[] = {
134 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01 161 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
135}; 162};
136 163
137static const UCHAR SiS_HiTVGroup3_2[] = { 164static const unsigned char SiS_HiTVGroup3_2[] = {
138 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, 165 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
139 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6, 166 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
140 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, 167 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -147,7 +174,7 @@ static const UCHAR SiS_HiTVGroup3_2[] = {
147 174
148/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */ 175/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
149 176
150static const UCHAR SiS_Part2CLVX_1[] = { 177static const unsigned char SiS_Part2CLVX_1[] = {
151 0x00,0x00, 178 0x00,0x00,
152 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, 179 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
153 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, 180 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
@@ -155,7 +182,7 @@ static const UCHAR SiS_Part2CLVX_1[] = {
155 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E 182 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
156}; 183};
157 184
158static const UCHAR SiS_Part2CLVX_2[] = { 185static const unsigned char SiS_Part2CLVX_2[] = {
159 0x00,0x00, 186 0x00,0x00,
160 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, 187 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
161 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, 188 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
@@ -163,7 +190,7 @@ static const UCHAR SiS_Part2CLVX_2[] = {
163 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E 190 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
164}; 191};
165 192
166static const UCHAR SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */ 193static const unsigned char SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
167 0xE0,0x01, 194 0xE0,0x01,
168 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, 195 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
169 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, 196 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
@@ -182,7 +209,7 @@ static const UCHAR SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
182 0xFF,0xFF 209 0xFF,0xFF
183}; 210};
184 211
185static const UCHAR SiS_Part2CLVX_4[] = { /* PAL */ 212static const unsigned char SiS_Part2CLVX_4[] = { /* PAL */
186 0x58,0x02, 213 0x58,0x02,
187 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, 214 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
188 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, 215 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
@@ -201,7 +228,7 @@ static const UCHAR SiS_Part2CLVX_4[] = { /* PAL */
201 0xFF,0xFF 228 0xFF,0xFF
202}; 229};
203 230
204static const UCHAR SiS_Part2CLVX_5[] = { /* 750p */ 231static const unsigned char SiS_Part2CLVX_5[] = { /* 750p */
205 0x00,0x03, 232 0x00,0x03,
206 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, 233 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
207 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, 234 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
@@ -210,7 +237,7 @@ static const UCHAR SiS_Part2CLVX_5[] = { /* 750p */
210 0xFF,0xFF 237 0xFF,0xFF
211}; 238};
212 239
213static const UCHAR SiS_Part2CLVX_6[] = { /* 1080i */ 240static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
214 0x00,0x04, 241 0x00,0x04,
215 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D, 242 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
216 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C, 243 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
@@ -221,7 +248,7 @@ static const UCHAR SiS_Part2CLVX_6[] = { /* 1080i */
221 248
222#ifdef SIS315H 249#ifdef SIS315H
223/* 661 et al LCD data structure (2.03.00) */ 250/* 661 et al LCD data structure (2.03.00) */
224static const UCHAR SiS_LCDStruct661[] = { 251static const unsigned char SiS_LCDStruct661[] = {
225 /* 1024x768 */ 252 /* 1024x768 */
226/* type|CR37| HDE | VDE | HT | VT | hss | hse */ 253/* type|CR37| HDE | VDE | HT | VT | hss | hse */
227 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88, 254 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
@@ -249,11 +276,20 @@ static const UCHAR SiS_LCDStruct661[] = {
249 /* 1680x1050 */ 276 /* 1680x1050 */
250 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C, 277 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
251 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06, 278 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
279 /* 1280x800_3 */
280 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
281 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
282 /* 800x600 */
283 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
284 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
285 /* 1280x854 */
286 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
287 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
252}; 288};
253#endif 289#endif
254 290
255#ifdef SIS300 291#ifdef SIS300
256static UCHAR SiS300_TrumpionData[7][80] = { 292static unsigned char SiS300_TrumpionData[14][80] = {
257 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 293 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
258 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23, 294 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
259 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23, 295 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
@@ -288,119 +324,182 @@ static UCHAR SiS300_TrumpionData[7][80] = {
288 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23, 324 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
289 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23, 325 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
290 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01, 326 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
291 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 } 327 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
328 /* variant 2 */
329 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
330 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
331 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
332 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
333 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
334 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
335 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
336 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
337 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
338 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
339 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
340 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
341 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
342 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
343 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
344 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
345 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
346 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
347 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
348 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
349 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
350 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
351 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
352 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
353 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
354 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
355 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
356 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
357 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
358 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
359 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
360 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
361 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
362 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
363 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
292}; 364};
293#endif 365#endif
294 366
295void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 367void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
296void SiS_EnableCRT2(SiS_Private *SiS_Pr); 368#ifndef SIS_LINUX_KERNEL
297USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); 369void SiS_LockCRT2(struct SiS_Private *SiS_Pr);
298void SiS_WaitRetrace1(SiS_Private *SiS_Pr); 370#endif
299BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 371void SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
300BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 372unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
301void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo); 373void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
302void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, 374BOOLEAN SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
303 USHORT ModeIdIndex, PSIS_HW_INFO HwInfo, 375BOOLEAN SiS_IsVAMode(struct SiS_Private *SiS_Pr);
304 int checkcrt2mode); 376void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
305void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 377 unsigned short ModeIdIndex, int checkcrt2mode);
306void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); 378void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
307void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); 379void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
308USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, 380 unsigned short ModeIdIndex);
309 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo); 381void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
310USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex); 382 unsigned short ModeIdIndex);
311void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 383unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
312BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo); 384 unsigned short RefreshRateTableIndex);
313void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 385unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
314void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 386void SiS_DisableBridge(struct SiS_Private *SiS_Pr);
387#ifndef SIS_LINUX_KERNEL
388void SiS_EnableBridge(struct SiS_Private *SiS_Pr);
389#endif
390BOOLEAN SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
391void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
392void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
315 393
316void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax); 394void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
317USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax); 395unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
318void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax); 396void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
319USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax); 397unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
320void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); 398#ifndef SIS_LINUX_KERNEL
399void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
400unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax);
401#endif
402void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
403 unsigned char orval,unsigned short andval);
321#ifdef SIS315H 404#ifdef SIS315H
322static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 405static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
323static void SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 406static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
324static void SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 407static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
325static void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 408static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
326void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 409void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
327void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr); 410void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
328#endif /* 315 */ 411#endif /* 315 */
329 412
330#ifdef SIS300 413#ifdef SIS300
331#if 0 414static BOOLEAN SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
332static void SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx); 415void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
333static USHORT SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
334#endif
335static BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
336#endif 416#endif
337 417
338void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime); 418void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
339USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr); 419unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
340USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine, 420unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
341 USHORT adaptnum, USHORT DDCdatatype, UCHAR *buffer); 421 unsigned short adaptnum, unsigned short DDCdatatype,
342#ifdef LINUX_XF86 422 unsigned char *buffer, unsigned int VBFlags2);
343USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
344USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
345#endif
346 423
347static void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr); 424#ifdef SIS_XORG_XF86
348static USHORT SiS_SetStart(SiS_Private *SiS_Pr); 425unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
349static USHORT SiS_SetStop(SiS_Private *SiS_Pr); 426 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
350static USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr); 427 BOOLEAN checkcr32, unsigned int VBFlags2);
351static USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr); 428unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
352static USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax); 429unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
353static USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax); 430 unsigned char *buffer);
354static USHORT SiS_CheckACK(SiS_Private *SiS_Pr); 431#else
355static USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine, 432static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
356 USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32); 433 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
357static USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr); 434 BOOLEAN checkcr32, unsigned int VBFlags2);
358static USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr); 435static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
359static USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr); 436static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
360static void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno); 437 unsigned char *buffer);
361static USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr); 438#endif
362static USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr); 439static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
363static USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, UCHAR *buffer); 440static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
441static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
442static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
443static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
444static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
445static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
446static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
447static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
448static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
449static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
450static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
451static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
364 452
453#ifdef SIS300
454static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
455 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
456static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
457 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
458#endif
365#ifdef SIS315H 459#ifdef SIS315H
366static void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 460static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
367 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI); 461 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
368static void SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 462static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
369 USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI); 463 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
370static void SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO); 464static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
371#endif 465#endif
466
467extern void SiS_SetReg(SISIOADDRESS, unsigned short, unsigned short);
468extern void SiS_SetRegByte(SISIOADDRESS, unsigned short);
469extern void SiS_SetRegShort(SISIOADDRESS, unsigned short);
470extern void SiS_SetRegLong(SISIOADDRESS, unsigned int);
471extern unsigned char SiS_GetReg(SISIOADDRESS, unsigned short);
472extern unsigned char SiS_GetRegByte(SISIOADDRESS);
473extern unsigned short SiS_GetRegShort(SISIOADDRESS);
474extern unsigned int SiS_GetRegLong(SISIOADDRESS);
475extern void SiS_SetRegANDOR(SISIOADDRESS, unsigned short, unsigned short, unsigned short);
476extern void SiS_SetRegOR(SISIOADDRESS, unsigned short, unsigned short);
477extern void SiS_SetRegAND(SISIOADDRESS, unsigned short, unsigned short);
478extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
479extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
480extern BOOLEAN SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
481extern unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
482 unsigned short ModeIdIndex);
483extern unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
484extern unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
485extern unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
486 unsigned short RefreshRateTableIndex);
487extern void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
488 unsigned short ModeIdIndex);
489extern void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
490 unsigned short ModeIdIndex);
491extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
492extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
493extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
372#ifdef SIS300 494#ifdef SIS300
373static void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 495extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
374 USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex); 496 unsigned short *tempcl);
375static void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, 497extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
376 USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex); 498extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
499#ifdef SIS_LINUX_KERNEL
500extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
501extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
377#endif 502#endif
378
379extern void SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
380extern void SiS_SetRegByte(SISIOADDRESS, USHORT);
381extern void SiS_SetRegShort(SISIOADDRESS, USHORT);
382extern void SiS_SetRegLong(SISIOADDRESS, ULONG);
383extern UCHAR SiS_GetReg(SISIOADDRESS, USHORT);
384extern UCHAR SiS_GetRegByte(SISIOADDRESS);
385extern USHORT SiS_GetRegShort(SISIOADDRESS);
386extern ULONG SiS_GetRegLong(SISIOADDRESS);
387extern void SiS_SetRegANDOR(SISIOADDRESS, USHORT, USHORT, USHORT);
388extern void SiS_SetRegOR(SISIOADDRESS, USHORT, USHORT);
389extern void SiS_SetRegAND(SISIOADDRESS, USHORT, USHORT);
390extern void SiS_DisplayOff(SiS_Private *SiS_Pr);
391extern void SiS_DisplayOn(SiS_Private *SiS_Pr);
392extern BOOLEAN SiS_SearchModeID(SiS_Private *, USHORT *, USHORT *);
393extern UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
394extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
395extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
396 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
397extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO, USHORT ModeNo,
398 USHORT ModeIdIndex);
399extern void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
400#ifdef LINUX_XF86
401extern void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
402extern int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct,
403 int *maxx, int *maxy, int *prefx, int *prefy);
404#endif 503#endif
405 504
406#endif 505#endif
diff --git a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
index 55a82d6dc4cf..264b55a5947b 100644
--- a/drivers/video/sis/initdef.h
+++ b/drivers/video/sis/initdef.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * Global definitions for init.c and init301.c 4 * Global definitions for init.c and init301.c
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -53,19 +53,20 @@
53#ifndef _INITDEF_ 53#ifndef _INITDEF_
54#define _INITDEF_ 54#define _INITDEF_
55 55
56#define IS_SIS330 (HwInfo->jChipType == SIS_330) 56#define IS_SIS330 (SiS_Pr->ChipType == SIS_330)
57#define IS_SIS550 (HwInfo->jChipType == SIS_550) 57#define IS_SIS550 (SiS_Pr->ChipType == SIS_550)
58#define IS_SIS650 (HwInfo->jChipType == SIS_650) /* All versions, incl 651, M65x */ 58#define IS_SIS650 (SiS_Pr->ChipType == SIS_650) /* All versions, incl 651, M65x */
59#define IS_SIS740 (HwInfo->jChipType == SIS_740) 59#define IS_SIS740 (SiS_Pr->ChipType == SIS_740)
60#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652)) 60#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
61#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653)) 61#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
62#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */ 62#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */
63#define IS_SIS661 (HwInfo->jChipType == SIS_661) 63#define IS_SIS661 (SiS_Pr->ChipType == SIS_661)
64#define IS_SIS741 (HwInfo->jChipType == SIS_741) 64#define IS_SIS741 (SiS_Pr->ChipType == SIS_741)
65#define IS_SIS660 (HwInfo->jChipType == SIS_660) 65#define IS_SIS660 (SiS_Pr->ChipType == SIS_660)
66#define IS_SIS760 (HwInfo->jChipType == SIS_760) 66#define IS_SIS760 (SiS_Pr->ChipType == SIS_760)
67#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760) 67#define IS_SIS761 (SiS_Pr->ChipType == SIS_761)
68#define IS_SIS650740 ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330)) 68#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760 || IS_SIS761)
69#define IS_SIS650740 ((SiS_Pr->ChipType >= SIS_650) && (SiS_Pr->ChipType < SIS_330))
69#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740) 70#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740)
70#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760) 71#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
71#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660) 72#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
@@ -73,24 +74,37 @@
73#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8)) 74#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
74 75
75/* SiS_VBType */ 76/* SiS_VBType */
76#define VB_SIS301 0x0001 77#define VB_SIS301 0x0001
77#define VB_SIS301B 0x0002 78#define VB_SIS301B 0x0002
78#define VB_SIS302B 0x0004 79#define VB_SIS302B 0x0004
79#define VB_SIS301LV 0x0008 80#define VB_SIS301LV 0x0008
80#define VB_SIS302LV 0x0010 81#define VB_SIS302LV 0x0010
81#define VB_SIS302ELV 0x0020 82#define VB_SIS302ELV 0x0020
82#define VB_SIS301C 0x0040 83#define VB_SIS301C 0x0040
84#define VB_SIS307T 0x0080
85#define VB_SIS307LV 0x0100
83#define VB_UMC 0x4000 86#define VB_UMC 0x4000
84#define VB_NoLCD 0x8000 87#define VB_NoLCD 0x8000
85#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) 88#define VB_SIS30xB (VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
86#define VB_SIS301B302B (VB_SIS301B|VB_SIS301C|VB_SIS302B) 89#define VB_SIS30xC (VB_SIS301C | VB_SIS307T)
87#define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) 90#define VB_SISTMDS (VB_SIS301 | VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
88#define VB_SISVB (VB_SIS301 | VB_SIS301BLV302BLV) 91#define VB_SISLVDS (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
89#define VB_SISTMDS (VB_SIS301 | VB_SIS301B302B) 92#define VB_SIS30xBLV (VB_SIS30xB | VB_SISLVDS)
90#define VB_SISLVDS VB_SIS301LV302LV 93#define VB_SIS30xCLV (VB_SIS30xC | VB_SIS302ELV | VB_SIS307LV)
91#define VB_SISLCDA (VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) 94#define VB_SISVB (VB_SIS301 | VB_SIS30xBLV)
92#define VB_SISYPBPR (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) 95#define VB_SISLCDA (VB_SIS302B | VB_SIS301C | VB_SIS307T | VB_SISLVDS)
93#define VB_SISHIVISION (VB_SIS301|VB_SIS301B|VB_SIS302B) 96#define VB_SISTMDSLCDA (VB_SIS301C | VB_SIS307T)
97#define VB_SISPART4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
98#define VB_SISHIVISION (VB_SIS301 | VB_SIS301B | VB_SIS302B)
99#define VB_SISYPBPR (VB_SIS301C | VB_SIS307T | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
100#define VB_SISTAP4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
101#define VB_SISPART4OVERFLOW (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
102#define VB_SISPWD (VB_SIS301C | VB_SIS307T | VB_SISLVDS)
103#define VB_SISEMI (VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
104#define VB_SISPOWER (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
105#define VB_SISDUALLINK (VB_SIS302LV | VB_SIS302ELV | VB_SIS307T | VB_SIS307LV)
106#define VB_SISVGA2 VB_SISTMDS
107#define VB_SISRAMDAC202 (VB_SIS301C | VB_SIS307T)
94 108
95/* VBInfo */ 109/* VBInfo */
96#define SetSimuScanMode 0x0001 /* CR 30 */ 110#define SetSimuScanMode 0x0001 /* CR 30 */
@@ -160,6 +174,7 @@
160#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ 174#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
161#define InterlaceMode 0x0080 175#define InterlaceMode 0x0080
162#define SyncPP 0x0000 176#define SyncPP 0x0000
177#define HaveWideTiming 0x2000 /* Have specific wide- and non-wide timing */
163#define SyncPN 0x4000 178#define SyncPN 0x4000
164#define SyncNP 0x8000 179#define SyncNP 0x8000
165#define SyncNN 0xc000 180#define SyncNN 0xc000
@@ -188,6 +203,7 @@
188#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */ 203#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
189#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */ 204#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
190#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */ 205#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
206#define TVSet525p1024 0x1000 /* TW */
191#define TVAspect43 0x2000 207#define TVAspect43 0x2000
192#define TVAspect169 0x4000 208#define TVAspect169 0x4000
193#define TVAspect43LB 0x8000 209#define TVAspect43LB 0x8000
@@ -208,7 +224,8 @@
208#define SF_IsM661 0x0020 224#define SF_IsM661 0x0020
209#define SF_IsM741 0x0040 225#define SF_IsM741 0x0040
210#define SF_IsM760 0x0080 226#define SF_IsM760 0x0080
211#define SF_760LFB 0x8000 /* 760: We have LFB */ 227#define SF_760UMA 0x4000 /* 76x: We have UMA */
228#define SF_760LFB 0x8000 /* 76x: We have LFB */
212 229
213/* CR32 (Newer 630, and 315 series) 230/* CR32 (Newer 630, and 315 series)
214 231
@@ -228,25 +245,19 @@
228#define TVOverScanShift 4 245#define TVOverScanShift 4
229 246
230/* CR35 (661 series only) 247/* CR35 (661 series only)
231
232 [0] 1 = PAL, 0 = NTSC 248 [0] 1 = PAL, 0 = NTSC
233 [1] 1 = NTSC-J (if D0 = 0) 249 [1] 1 = NTSC-J (if D0 = 0)
234 [2] 1 = PALM (if D0 = 1) 250 [2] 1 = PALM (if D0 = 1)
235 [3] 1 = PALN (if D0 = 1) 251 [3] 1 = PALN (if D0 = 1)
236 [4] 1 = Overscan (Chrontel only) 252 [4] 1 = Overscan (Chrontel only)
237 [7:5] (only if D2 in CR38 is set) 253 [7:5] (only if D2 in CR38 is set)
238 000 525i 254 000 525i
239 001 525p 255 001 525p
240 010 750p 256 010 750p
241 011 1080i (or HiVision on 301, 301B) 257 011 1080i (or HiVision on 301, 301B)
242
243 These bits are being translated to TVMode flag.
244
245*/ 258*/
246 259
247/* 260/* CR37
248 CR37
249
250 [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS) 261 [0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
251 [3:1] External chip 262 [3:1] External chip
252 300 series: 263 300 series:
@@ -260,7 +271,7 @@
260 010 LVDS 271 010 LVDS
261 011 LVDS + Chrontel 7019 272 011 LVDS + Chrontel 7019
262 660 series [2:1] only: 273 660 series [2:1] only:
263 reserved (now in CR38) 274 reserved (chip type now in CR38)
264 All other combinations reserved 275 All other combinations reserved
265 [3] 661 only: Pass 1:1 data 276 [3] 661 only: Pass 1:1 data
266 [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand 277 [4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand
@@ -320,6 +331,7 @@
320#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */ 331#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
321 332
322/* CR39 (661 and later) 333/* CR39 (661 and later)
334 D[7] LVDS (SiS or third party)
323 D[1:0] YPbPr Aspect Ratio 335 D[1:0] YPbPr Aspect Ratio
324 00 4:3 letterbox 336 00 4:3 letterbox
325 01 4:3 337 01 4:3
@@ -341,7 +353,7 @@
341 0101 Set Contrast event 353 0101 Set Contrast event
342 0110 Set Mute event 354 0110 Set Mute event
343 0111 Set Volume Up/Down event 355 0111 Set Volume Up/Down event
344 [4] Enable Backlight Control by BIOS/driver 356 [4] Enable Backlight Control by BIOS/driver
345 (set by driver; set means that the BIOS should 357 (set by driver; set means that the BIOS should
346 not touch the backlight registers because eg. 358 not touch the backlight registers because eg.
347 the driver already switched off the backlight) 359 the driver already switched off the backlight)
@@ -350,6 +362,26 @@
350 [7] TV UnderScan/OverScan (set by BIOS) 362 [7] TV UnderScan/OverScan (set by BIOS)
351*/ 363*/
352 364
365/* CR7C - 661 and later
366 [7] DualEdge enabled (or: to be enabled)
367 [6] CRT2 = TV/LCD/VGA enabled (or: to be enabled)
368 [5] Init done (set at end of SiS_Init)
369 {4] LVDS LCD capabilities
370 [3] LVDS LCD capabilities
371 [2] LVDS LCD capabilities (PWD)
372 [1] LVDS LCD capabilities (PWD)
373 [0] LVDS=1, TMDS=0 (SiS or third party)
374*/
375
376/* CR7E - 661 and later
377 VBType:
378 [7] LVDS (third party)
379 [3] 301C
380 [2] 302LV
381 [1] 301LV
382 [0] 301B
383*/
384
353/* LCDResInfo */ 385/* LCDResInfo */
354#define Panel300_800x600 0x01 /* CR36 */ 386#define Panel300_800x600 0x01 /* CR36 */
355#define Panel300_1024x768 0x02 387#define Panel300_1024x768 0x02
@@ -359,7 +391,6 @@
359#define Panel300_1024x600 0x06 391#define Panel300_1024x600 0x06
360#define Panel300_1152x768 0x07 392#define Panel300_1152x768 0x07
361#define Panel300_1280x768 0x0a 393#define Panel300_1280x768 0x0a
362#define Panel300_320x480 0x0e /* fstn - This is fake, can be any */
363#define Panel300_Custom 0x0f 394#define Panel300_Custom 0x0f
364#define Panel300_Barco1366 0x10 395#define Panel300_Barco1366 0x10
365 396
@@ -374,9 +405,9 @@
374#define Panel310_1400x1050 0x09 405#define Panel310_1400x1050 0x09
375#define Panel310_1280x768 0x0a 406#define Panel310_1280x768 0x0a
376#define Panel310_1600x1200 0x0b 407#define Panel310_1600x1200 0x0b
377#define Panel310_640x480_2 0x0c 408#define Panel310_320x240_2 0x0c /* xSTN */
378#define Panel310_640x480_3 0x0d 409#define Panel310_320x240_3 0x0d /* xSTN */
379#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */ 410#define Panel310_320x240_1 0x0e /* xSTN - This is fake, can be any */
380#define Panel310_Custom 0x0f 411#define Panel310_Custom 0x0f
381 412
382#define Panel661_800x600 0x01 413#define Panel661_800x600 0x01
@@ -386,7 +417,7 @@
386#define Panel661_1024x600 0x05 417#define Panel661_1024x600 0x05
387#define Panel661_1152x864 0x06 418#define Panel661_1152x864 0x06
388#define Panel661_1280x960 0x07 419#define Panel661_1280x960 0x07
389#define Panel661_1152x768 0x08 420#define Panel661_1280x854 0x08
390#define Panel661_1400x1050 0x09 421#define Panel661_1400x1050 0x09
391#define Panel661_1280x768 0x0a 422#define Panel661_1280x768 0x0a
392#define Panel661_1600x1200 0x0b 423#define Panel661_1600x1200 0x0b
@@ -410,14 +441,16 @@
410#define Panel_1680x1050 0x0d /* 661etc */ 441#define Panel_1680x1050 0x0d /* 661etc */
411#define Panel_1280x720 0x0e /* 661etc */ 442#define Panel_1280x720 0x0e /* 661etc */
412#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */ 443#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */
413#define Panel_320x480 0x10 /* SiS 550 fstn - TW: This is fake, can be any */ 444#define Panel_320x240_1 0x10 /* SiS 550 xSTN */
414#define Panel_Barco1366 0x11 445#define Panel_Barco1366 0x11
415#define Panel_848x480 0x12 446#define Panel_848x480 0x12
416#define Panel_640x480_2 0x13 /* SiS 550 */ 447#define Panel_320x240_2 0x13 /* SiS 550 xSTN */
417#define Panel_640x480_3 0x14 /* SiS 550 */ 448#define Panel_320x240_3 0x14 /* SiS 550 xSTN */
418#define Panel_1280x768_2 0x15 /* 30xLV */ 449#define Panel_1280x768_2 0x15 /* 30xLV */
419#define Panel_1280x768_3 0x16 /* (unused) */ 450#define Panel_1280x768_3 0x16 /* (unused) */
420#define Panel_1280x800_2 0x17 /* 30xLV */ 451#define Panel_1280x800_2 0x17 /* 30xLV */
452#define Panel_856x480 0x18
453#define Panel_1280x854 0x19 /* 661etc */
421 454
422/* Index in ModeResInfo table */ 455/* Index in ModeResInfo table */
423#define SIS_RI_320x200 0 456#define SIS_RI_320x200 0
@@ -454,6 +487,7 @@
454#define SIS_RI_1920x1080 31 487#define SIS_RI_1920x1080 31
455#define SIS_RI_960x540 32 488#define SIS_RI_960x540 32
456#define SIS_RI_960x600 33 489#define SIS_RI_960x600 33
490#define SIS_RI_1280x854 34
457 491
458/* CR5F */ 492/* CR5F */
459#define IsM650 0x80 493#define IsM650 0x80
@@ -482,16 +516,18 @@
482#define VCLK100_300 0x43 /* Index in VCLKData table (300) */ 516#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
483#define VCLK34_300 0x3d /* Index in VCLKData table (300) */ 517#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
484#define VCLK_CUSTOM_300 0x47 518#define VCLK_CUSTOM_300 0x47
485#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */ 519
486#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */ 520#define VCLK65_315 0x0b /* Indices in (VB)VCLKData table (315) */
487#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */ 521#define VCLK108_2_315 0x19
488#define VCLK162_315 0x5e /* Index in (VB)VCLKData table (315) */ 522#define VCLK81_315 0x5b
489#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */ 523#define VCLK162_315 0x5e
490#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */ 524#define VCLK108_3_315 0x45
525#define VCLK100_315 0x46
491#define VCLK34_315 0x55 526#define VCLK34_315 0x55
492#define VCLK68_315 0x0d 527#define VCLK68_315 0x0d
493#define VCLK_1280x800_315_2 0x5c /* Index in VBVCLKData table (315) */ 528#define VCLK_1280x800_315_2 0x5c
494#define VCLK121_315 0x5d /* Index in VBVCLKData table (315) */ 529#define VCLK121_315 0x5d
530#define VCLK130_315 0x72
495#define VCLK_1280x720 0x5f 531#define VCLK_1280x720 0x5f
496#define VCLK_1280x768_2 0x60 532#define VCLK_1280x768_2 0x60
497#define VCLK_1280x768_3 0x61 /* (unused?) */ 533#define VCLK_1280x768_3 0x61 /* (unused?) */
@@ -507,6 +543,7 @@
507#define VCLK_1152x864 0x64 543#define VCLK_1152x864 0x64
508#define VCLK_1360x768 0x58 544#define VCLK_1360x768 0x58
509#define VCLK_1280x800_315 0x6c 545#define VCLK_1280x800_315 0x6c
546#define VCLK_1280x854 0x76
510 547
511#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */ 548#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
512#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */ 549#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
new file mode 100644
index 000000000000..cc856d90903c
--- /dev/null
+++ b/drivers/video/sis/initextlfb.c
@@ -0,0 +1,238 @@
1/*
2 * SiS 300/540/630[S]/730[S]
3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX]
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
6 *
7 * Linux kernel specific extensions to init.c/init301.c
8 *
9 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
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 named License,
14 * or any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24 *
25 * Author: Thomas Winischhofer <thomas@winischhofer.net>
26 */
27
28#include "osdef.h"
29#include "initdef.h"
30#include "vgatypes.h"
31#include "vstruct.h"
32
33#include <linux/config.h>
34#include <linux/version.h>
35#include <linux/types.h>
36#include <linux/fb.h>
37
38#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
39int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
40 unsigned char modeno, unsigned char rateindex);
41int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
42 unsigned char rateindex, struct fb_var_screeninfo *var);
43#endif
44BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
45 int *htotal, int *vtotal, unsigned char rateindex);
46
47extern BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
48extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
49 unsigned short *ModeIdIndex);
50extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
51 int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
52
53#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
54int
55sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
56 unsigned char rateindex)
57{
58 unsigned short ModeNo = modeno;
59 unsigned short ModeIdIndex = 0, ClockIndex = 0;
60 unsigned short RRTI = 0;
61 int Clock;
62
63 if(!SiSInitPtr(SiS_Pr)) return 65000;
64
65 if(rateindex > 0) rateindex--;
66
67#ifdef SIS315H
68 switch(ModeNo) {
69 case 0x5a: ModeNo = 0x50; break;
70 case 0x5b: ModeNo = 0x56;
71 }
72#endif
73
74 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
75 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
76 return 65000;
77 }
78
79 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
80
81 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
82 if(SiS_Pr->SiS_UseWide == 1) {
83 /* Wide screen: Ignore rateindex */
84 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_WIDE;
85 } else {
86 RRTI += rateindex;
87 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_NORM;
88 }
89 } else {
90 RRTI += rateindex;
91 ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK;
92 }
93
94 Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
95
96 return Clock;
97}
98
99int
100sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
101 unsigned char rateindex, struct fb_var_screeninfo *var)
102{
103 unsigned short ModeNo = modeno;
104 unsigned short ModeIdIndex = 0, index = 0, RRTI = 0;
105 int j;
106
107 if(!SiSInitPtr(SiS_Pr)) return 0;
108
109 if(rateindex > 0) rateindex--;
110
111#ifdef SIS315H
112 switch(ModeNo) {
113 case 0x5a: ModeNo = 0x50; break;
114 case 0x5b: ModeNo = 0x56;
115 }
116#endif
117
118 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
119
120 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
121 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
122 if(SiS_Pr->SiS_UseWide == 1) {
123 /* Wide screen: Ignore rateindex */
124 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
125 } else {
126 RRTI += rateindex;
127 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
128 }
129 } else {
130 RRTI += rateindex;
131 index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
132 }
133
134 SiS_Generic_ConvertCRData(SiS_Pr,
135 (unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
136 SiS_Pr->SiS_RefIndex[RRTI].XRes,
137 SiS_Pr->SiS_RefIndex[RRTI].YRes,
138 var, FALSE);
139
140 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
141 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
142 else
143 var->sync |= FB_SYNC_VERT_HIGH_ACT;
144
145 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x4000)
146 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
147 else
148 var->sync |= FB_SYNC_HOR_HIGH_ACT;
149
150 var->vmode = FB_VMODE_NONINTERLACED;
151 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x0080)
152 var->vmode = FB_VMODE_INTERLACED;
153 else {
154 j = 0;
155 while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
156 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
157 SiS_Pr->SiS_RefIndex[RRTI].ModeID) {
158 if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
159 var->vmode = FB_VMODE_DOUBLE;
160 }
161 break;
162 }
163 j++;
164 }
165 }
166
167 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
168#if 0 /* Do this? */
169 var->upper_margin <<= 1;
170 var->lower_margin <<= 1;
171 var->vsync_len <<= 1;
172#endif
173 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
174 var->upper_margin >>= 1;
175 var->lower_margin >>= 1;
176 var->vsync_len >>= 1;
177 }
178
179 return 1;
180}
181#endif /* Linux >= 2.5 */
182
183BOOLEAN
184sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
185 int *vtotal, unsigned char rateindex)
186{
187 unsigned short ModeNo = modeno;
188 unsigned short ModeIdIndex = 0, CRT1Index = 0;
189 unsigned short RRTI = 0;
190 unsigned char sr_data, cr_data, cr_data2;
191
192 if(!SiSInitPtr(SiS_Pr)) return FALSE;
193
194 if(rateindex > 0) rateindex--;
195
196#ifdef SIS315H
197 switch(ModeNo) {
198 case 0x5a: ModeNo = 0x50; break;
199 case 0x5b: ModeNo = 0x56;
200 }
201#endif
202
203 if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
204
205 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
206 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
207 if(SiS_Pr->SiS_UseWide == 1) {
208 /* Wide screen: Ignore rateindex */
209 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
210 } else {
211 RRTI += rateindex;
212 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
213 }
214 } else {
215 RRTI += rateindex;
216 CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
217 }
218
219 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
220 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
221 *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
222
223 sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
224 cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
225 cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
226 *vtotal = ((cr_data & 0xFF) |
227 ((unsigned short)(cr_data2 & 0x01) << 8) |
228 ((unsigned short)(cr_data2 & 0x20) << 4) |
229 ((unsigned short)(sr_data & 0x01) << 10)) + 2;
230
231 if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
232 *vtotal *= 2;
233
234 return TRUE;
235}
236
237
238
diff --git a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
index b1358b750f53..b73f26840143 100644
--- a/drivers/video/sis/oem300.h
+++ b/drivers/video/sis/oem300.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * OEM Data for 300 series 4 * OEM Data for 300 series
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,7 +50,7 @@
50 * 50 *
51 */ 51 */
52 52
53static const UCHAR SiS300_OEMTVDelay301[8][4] = 53static const unsigned char SiS300_OEMTVDelay301[8][4] =
54{ 54{
55 {0x08,0x08,0x08,0x08}, 55 {0x08,0x08,0x08,0x08},
56 {0x08,0x08,0x08,0x08}, 56 {0x08,0x08,0x08,0x08},
@@ -62,7 +62,7 @@ static const UCHAR SiS300_OEMTVDelay301[8][4] =
62 {0x20,0x20,0x20,0x20} 62 {0x20,0x20,0x20,0x20}
63}; 63};
64 64
65static const UCHAR SiS300_OEMTVDelayLVDS[8][4] = 65static const unsigned char SiS300_OEMTVDelayLVDS[8][4] =
66{ 66{
67 {0x20,0x20,0x20,0x20}, 67 {0x20,0x20,0x20,0x20},
68 {0x20,0x20,0x20,0x20}, 68 {0x20,0x20,0x20,0x20},
@@ -74,7 +74,7 @@ static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
74 {0x20,0x20,0x20,0x20} 74 {0x20,0x20,0x20,0x20}
75}; 75};
76 76
77static const UCHAR SiS300_OEMTVFlicker[8][4] = 77static const unsigned char SiS300_OEMTVFlicker[8][4] =
78{ 78{
79 {0x00,0x00,0x00,0x00}, 79 {0x00,0x00,0x00,0x00},
80 {0x00,0x00,0x00,0x00}, 80 {0x00,0x00,0x00,0x00},
@@ -86,25 +86,7 @@ static const UCHAR SiS300_OEMTVFlicker[8][4] =
86 {0x00,0x00,0x00,0x00} 86 {0x00,0x00,0x00,0x00}
87}; 87};
88 88
89#if 0 /* TW: Not used */ 89static const unsigned char SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
90static const UCHAR SiS300_OEMLCDDelay1[12][4]={
91 {0x2c,0x2c,0x2c,0x2c},
92 {0x20,0x20,0x20,0x20},
93 {0x20,0x20,0x20,0x20},
94 {0x2c,0x2c,0x2c,0x2c},
95 {0x2c,0x2c,0x2c,0x2c},
96 {0x20,0x20,0x20,0x20},
97 {0x20,0x20,0x20,0x20},
98 {0x24,0x24,0x24,0x24},
99 {0x24,0x24,0x24,0x24},
100 {0x20,0x20,0x20,0x20},
101 {0x20,0x20,0x20,0x20},
102 {0x24,0x24,0x24,0x24}
103};
104#endif
105
106/* From 630/301B BIOS */
107static const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
108{ 90{
109 {0x20,0x20,0x20,0x20}, 91 {0x20,0x20,0x20,0x20},
110 {0x20,0x20,0x20,0x20}, 92 {0x20,0x20,0x20,0x20},
@@ -172,8 +154,7 @@ static const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302
172 {0x20,0x20,0x20,0x20} 154 {0x20,0x20,0x20,0x20}
173}; 155};
174 156
175/* From 300/301LV BIOS */ 157static const unsigned char SiS300_OEMLCDDelay4[12][4] =
176static const UCHAR SiS300_OEMLCDDelay4[12][4] =
177{ 158{
178 {0x2c,0x2c,0x2c,0x2c}, 159 {0x2c,0x2c,0x2c,0x2c},
179 {0x20,0x20,0x20,0x20}, 160 {0x20,0x20,0x20,0x20},
@@ -189,8 +170,7 @@ static const UCHAR SiS300_OEMLCDDelay4[12][4] =
189 {0x24,0x24,0x24,0x24} 170 {0x24,0x24,0x24,0x24}
190}; 171};
191 172
192/* From 300/301LV BIOS */ 173static const unsigned char SiS300_OEMLCDDelay5[32][4] =
193static const UCHAR SiS300_OEMLCDDelay5[32][4] =
194{ 174{
195 {0x20,0x20,0x20,0x20}, 175 {0x20,0x20,0x20,0x20},
196 {0x20,0x20,0x20,0x20}, 176 {0x20,0x20,0x20,0x20},
@@ -226,8 +206,8 @@ static const UCHAR SiS300_OEMLCDDelay5[32][4] =
226 {0x20,0x20,0x20,0x20}, 206 {0x20,0x20,0x20,0x20},
227}; 207};
228 208
229/* Added for LVDS */ 209static const unsigned char SiS300_OEMLCDDelay3[64][4] = /* For LVDS */
230static const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */ 210{
231 {0x20,0x20,0x20,0x20}, 211 {0x20,0x20,0x20,0x20},
232 {0x20,0x20,0x20,0x20}, 212 {0x20,0x20,0x20,0x20},
233 {0x20,0x20,0x20,0x20}, 213 {0x20,0x20,0x20,0x20},
@@ -294,7 +274,7 @@ static const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */
294 {0x20,0x20,0x20,0x20} 274 {0x20,0x20,0x20,0x20}
295}; 275};
296 276
297static const UCHAR SiS300_Phase1[8][5][4] = 277static const unsigned char SiS300_Phase1[8][5][4] =
298{ 278{
299 { 279 {
300 {0x21,0xed,0x00,0x08}, 280 {0x21,0xed,0x00,0x08},
@@ -354,11 +334,10 @@ static const UCHAR SiS300_Phase1[8][5][4] =
354 } 334 }
355}; 335};
356 336
357 337static const unsigned char SiS300_Phase2[8][5][4] =
358static const UCHAR SiS300_Phase2[8][5][4] =
359{ 338{
360 { 339 {
361 {0x21,0xed,0x00,0x08}, 340 {0x21,0xed,0x00,0x08},
362 {0x21,0xed,0x8a,0x08}, 341 {0x21,0xed,0x8a,0x08},
363 {0x21,0xed,0x8a,0x08}, 342 {0x21,0xed,0x8a,0x08},
364 {0x21,0xed,0x8a,0x08}, 343 {0x21,0xed,0x8a,0x08},
@@ -372,42 +351,42 @@ static const UCHAR SiS300_Phase2[8][5][4] =
372 {0x2a,0x05,0xd3,0x00} 351 {0x2a,0x05,0xd3,0x00}
373 }, 352 },
374 { 353 {
375 {0x2a,0x05,0xd3,0x00}, 354 {0x2a,0x05,0xd3,0x00},
376 {0x2a,0x05,0xd3,0x00}, 355 {0x2a,0x05,0xd3,0x00},
377 {0x2a,0x05,0xd3,0x00}, 356 {0x2a,0x05,0xd3,0x00},
378 {0x2a,0x05,0xd3,0x00}, 357 {0x2a,0x05,0xd3,0x00},
379 {0x2a,0x05,0xd3,0x00} 358 {0x2a,0x05,0xd3,0x00}
380 }, 359 },
381 { 360 {
382 {0x2a,0x05,0xd3,0x00}, 361 {0x2a,0x05,0xd3,0x00},
383 {0x2a,0x05,0xd3,0x00}, 362 {0x2a,0x05,0xd3,0x00},
384 {0x2a,0x05,0xd3,0x00}, 363 {0x2a,0x05,0xd3,0x00},
385 {0x2a,0x05,0xd3,0x00}, 364 {0x2a,0x05,0xd3,0x00},
386 {0x2a,0x05,0xd3,0x00} 365 {0x2a,0x05,0xd3,0x00}
387 }, 366 },
388 { 367 {
389 {0x21,0xed,0x00,0x08}, 368 {0x21,0xed,0x00,0x08},
390 {0x21,0xed,0x8a,0x08}, 369 {0x21,0xed,0x8a,0x08},
391 {0x21,0xed,0x8a,0x08}, 370 {0x21,0xed,0x8a,0x08},
392 {0x21,0xed,0x8a,0x08}, 371 {0x21,0xed,0x8a,0x08},
393 {0x21,0xed,0x8a,0x08} 372 {0x21,0xed,0x8a,0x08}
394 }, 373 },
395 { 374 {
396 {0x2a,0x05,0xd3,0x00}, 375 {0x2a,0x05,0xd3,0x00},
397 {0x2a,0x05,0xd3,0x00}, 376 {0x2a,0x05,0xd3,0x00},
398 {0x2a,0x05,0xd3,0x00}, 377 {0x2a,0x05,0xd3,0x00},
399 {0x2a,0x05,0xd3,0x00}, 378 {0x2a,0x05,0xd3,0x00},
400 {0x2a,0x05,0xd3,0x00} 379 {0x2a,0x05,0xd3,0x00}
401 }, 380 },
402 { 381 {
403 {0x2a,0x05,0xd3,0x00}, 382 {0x2a,0x05,0xd3,0x00},
404 {0x2a,0x05,0xd3,0x00}, 383 {0x2a,0x05,0xd3,0x00},
405 {0x2a,0x05,0xd3,0x00}, 384 {0x2a,0x05,0xd3,0x00},
406 {0x2a,0x05,0xd3,0x00}, 385 {0x2a,0x05,0xd3,0x00},
407 {0x2a,0x05,0xd3,0x00} 386 {0x2a,0x05,0xd3,0x00}
408 }, 387 },
409 { 388 {
410 {0x2a,0x05,0xd3,0x00}, 389 {0x2a,0x05,0xd3,0x00},
411 {0x2a,0x05,0xd3,0x00}, 390 {0x2a,0x05,0xd3,0x00},
412 {0x2a,0x05,0xd3,0x00}, 391 {0x2a,0x05,0xd3,0x00},
413 {0x2a,0x05,0xd3,0x00}, 392 {0x2a,0x05,0xd3,0x00},
@@ -415,7 +394,7 @@ static const UCHAR SiS300_Phase2[8][5][4] =
415 } 394 }
416}; 395};
417 396
418static const UCHAR SiS300_Filter1[10][16][4] = 397static const unsigned char SiS300_Filter1[10][16][4] =
419{ 398{
420 { 399 {
421 {0x00,0xf4,0x10,0x38}, 400 {0x00,0xf4,0x10,0x38},
@@ -599,7 +578,7 @@ static const UCHAR SiS300_Filter1[10][16][4] =
599 }, 578 },
600}; 579};
601 580
602static const UCHAR SiS300_Filter2[10][9][7] = 581static const unsigned char SiS300_Filter2[10][9][7] =
603{ 582{
604 { 583 {
605 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 584 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -714,142 +693,144 @@ static const UCHAR SiS300_Filter2[10][9][7] =
714}; 693};
715 694
716/* Custom data for Barco iQ Pro R300 */ 695/* Custom data for Barco iQ Pro R300 */
717static const UCHAR barco_p1[2][9][7][3] = { 696static const unsigned char barco_p1[2][9][7][3] =
718 { 697{
719 { { 0x16, 0xcf, 0x00 }, 698 {
720 { 0x18, 0x00, 0x00 }, 699 {
721 { 0x1a, 0xe7, 0x00 }, 700 { 0x16, 0xcf, 0x00 },
722 { 0x1b, 0x26, 0x00 }, 701 { 0x18, 0x00, 0x00 },
723 { 0x1c, 0xff, 0x00 }, 702 { 0x1a, 0xe7, 0x00 },
724 { 0x1d, 0x1c, 0x00 }, 703 { 0x1b, 0x26, 0x00 },
725 { 0x1e, 0x19, 0x00 } 704 { 0x1c, 0xff, 0x00 },
726 }, 705 { 0x1d, 0x1c, 0x00 },
727 { 706 { 0x1e, 0x19, 0x00 }
728 { 0x16, 0xcf, 0x00 }, 707 },
729 { 0x18, 0x00, 0x00 }, 708 {
730 { 0x1a, 0xe7, 0x00 }, 709 { 0x16, 0xcf, 0x00 },
731 { 0x1b, 0x1e, 0x00 }, 710 { 0x18, 0x00, 0x00 },
732 { 0x1c, 0xff, 0x00 }, 711 { 0x1a, 0xe7, 0x00 },
733 { 0x1d, 0x1c, 0x00 }, 712 { 0x1b, 0x1e, 0x00 },
734 { 0x1e, 0x16, 0x00 } 713 { 0x1c, 0xff, 0x00 },
735 }, 714 { 0x1d, 0x1c, 0x00 },
736 { 715 { 0x1e, 0x16, 0x00 }
737 { 0x16, 0xcf, 0x00 }, 716 },
738 { 0x1a, 0xe7, 0x00 }, 717 {
739 { 0x1b, 0x26, 0x00 }, 718 { 0x16, 0xcf, 0x00 },
740 { 0x1c, 0xff, 0x00 }, 719 { 0x1a, 0xe7, 0x00 },
741 { 0x1d, 0x1c, 0x00 }, 720 { 0x1b, 0x26, 0x00 },
742 { 0x1e, 0x19, 0x00 }, 721 { 0x1c, 0xff, 0x00 },
743 { 0, 0, 0 } 722 { 0x1d, 0x1c, 0x00 },
744 }, 723 { 0x1e, 0x19, 0x00 },
745 { 724 { 0, 0, 0 }
746 { 0, 0, 0 } 725 },
747 }, 726 {
748 { 727 { 0, 0, 0 }
749 { 0x16, 0xcf, 0x00 }, 728 },
750 { 0x1a, 0xe7, 0x00 }, 729 {
751 { 0x1b, 0x26, 0x00 }, 730 { 0x16, 0xcf, 0x00 },
752 { 0x1c, 0xff, 0x00 }, 731 { 0x1a, 0xe7, 0x00 },
753 { 0x1d, 0x1c, 0x00 }, 732 { 0x1b, 0x26, 0x00 },
754 { 0x1e, 0x1e, 0x00 }, 733 { 0x1c, 0xff, 0x00 },
755 { 0, 0, 0 } 734 { 0x1d, 0x1c, 0x00 },
756 }, 735 { 0x1e, 0x1e, 0x00 },
757 { 736 { 0, 0, 0 }
758 { 0x16, 0xd1, 0x00 }, 737 },
759 { 0x18, 0x00, 0x00 }, 738 {
760 { 0x1a, 0xe7, 0x00 }, 739 { 0x16, 0xd1, 0x00 },
761 { 0x1b, 0x11, 0x00 }, 740 { 0x18, 0x00, 0x00 },
762 { 0x1c, 0xff, 0x00 }, 741 { 0x1a, 0xe7, 0x00 },
763 { 0x1d, 0x1c, 0x00 }, 742 { 0x1b, 0x11, 0x00 },
764 { 0x1e, 0x26, 0x00 } 743 { 0x1c, 0xff, 0x00 },
765 }, 744 { 0x1d, 0x1c, 0x00 },
766 { 745 { 0x1e, 0x26, 0x00 }
767 { 0x16, 0xd1, 0x00 }, 746 },
768 { 0x1a, 0xe7, 0x00 }, 747 {
769 { 0x1b, 0x26, 0x00 }, 748 { 0x16, 0xd1, 0x00 },
770 { 0x1c, 0xff, 0x00 }, 749 { 0x1a, 0xe7, 0x00 },
771 { 0x1d, 0x1c, 0x00 }, 750 { 0x1b, 0x26, 0x00 },
772 { 0x1e, 0x30, 0x00 }, 751 { 0x1c, 0xff, 0x00 },
773 { 0, 0, 0 } 752 { 0x1d, 0x1c, 0x00 },
774 }, 753 { 0x1e, 0x30, 0x00 },
775 { 754 { 0, 0, 0 }
776 { 0x16, 0x00, 0x00 }, 755 },
777 { 0x17, 0xa0, 0x00 }, 756 {
778 { 0x1a, 0xa0, 0x00 }, 757 { 0x16, 0x00, 0x00 },
779 { 0x1b, 0x2a, 0x00 }, 758 { 0x17, 0xa0, 0x00 },
780 { 0x1c, 0xff, 0x00 }, 759 { 0x1a, 0xa0, 0x00 },
781 { 0x1d, 0x1c, 0x00 }, 760 { 0x1b, 0x2a, 0x00 },
782 { 0, 0, 0 } 761 { 0x1c, 0xff, 0x00 },
783 }, 762 { 0x1d, 0x1c, 0x00 },
784 { 763 { 0, 0, 0 }
785 { 0x16, 0x00, 0x00 }, 764 },
786 { 0x17, 0xaa, 0x00 }, 765 {
787 { 0x1a, 0xa0, 0x00 }, 766 { 0x16, 0x00, 0x00 },
788 { 0x1b, 0x2a, 0x00 }, 767 { 0x17, 0xaa, 0x00 },
789 { 0x1c, 0xff, 0x00 }, 768 { 0x1a, 0xa0, 0x00 },
790 { 0x1d, 0x1c, 0x00 }, 769 { 0x1b, 0x2a, 0x00 },
791 { 0, 0, 0 } 770 { 0x1c, 0xff, 0x00 },
792 } 771 { 0x1d, 0x1c, 0x00 },
793 }, 772 { 0, 0, 0 }
794 { 773 }
795 { 774 },
796 { 0x16, 0xcf, 0x00 }, 775 {
797 { 0x18, 0x00, 0x00 }, 776 {
798 { 0x1a, 0xe7, 0x00 }, 777 { 0x16, 0xcf, 0x00 },
799 { 0x1b, 0x26, 0x00 }, 778 { 0x18, 0x00, 0x00 },
800 { 0x1c, 0xff, 0x00 }, 779 { 0x1a, 0xe7, 0x00 },
801 { 0x1d, 0x1c, 0x00 }, 780 { 0x1b, 0x26, 0x00 },
802 { 0x1e, 0x19, 0x00 } 781 { 0x1c, 0xff, 0x00 },
803 }, 782 { 0x1d, 0x1c, 0x00 },
804 { 783 { 0x1e, 0x19, 0x00 }
805 { 0, 0, 0 } 784 },
806 }, 785 {
807 { 786 { 0, 0, 0 }
808 { 0x16, 0xcf, 0x00 }, 787 },
809 { 0x18, 0x00, 0x00 }, 788 {
810 { 0x1a, 0xe7, 0x00 }, 789 { 0x16, 0xcf, 0x00 },
811 { 0x1b, 0x26, 0x00 }, 790 { 0x18, 0x00, 0x00 },
812 { 0x1c, 0xff, 0x00 }, 791 { 0x1a, 0xe7, 0x00 },
813 { 0x1d, 0x1c, 0x00 }, 792 { 0x1b, 0x26, 0x00 },
814 { 0x1e, 0x19, 0x00 }, 793 { 0x1c, 0xff, 0x00 },
815 }, 794 { 0x1d, 0x1c, 0x00 },
816 { 795 { 0x1e, 0x19, 0x00 },
817 { 0, 0, 0 } 796 },
818 }, 797 {
819 { 798 { 0, 0, 0 }
820 { 0x16, 0xcf, 0x00 }, 799 },
821 { 0x18, 0x00, 0x00 }, 800 {
822 { 0x1a, 0xe7, 0x00 }, 801 { 0x16, 0xcf, 0x00 },
823 { 0x1b, 0x26, 0x00 }, 802 { 0x18, 0x00, 0x00 },
824 { 0x1c, 0xff, 0x00 }, 803 { 0x1a, 0xe7, 0x00 },
825 { 0x1d, 0x1c, 0x00 }, 804 { 0x1b, 0x26, 0x00 },
826 { 0x1e, 0x1e, 0x00 } 805 { 0x1c, 0xff, 0x00 },
827 }, 806 { 0x1d, 0x1c, 0x00 },
828 { 807 { 0x1e, 0x1e, 0x00 }
829 { 0x16, 0xd1, 0x00 }, 808 },
830 { 0x18, 0x00, 0x00 }, 809 {
831 { 0x1a, 0xe6, 0x00 }, 810 { 0x16, 0xd1, 0x00 },
832 { 0x1b, 0x11, 0x00 }, 811 { 0x18, 0x00, 0x00 },
833 { 0x1c, 0xff, 0x00 }, 812 { 0x1a, 0xe6, 0x00 },
834 { 0x1d, 0x1c, 0x00 }, 813 { 0x1b, 0x11, 0x00 },
835 { 0x1e, 0x26, 0x00 } 814 { 0x1c, 0xff, 0x00 },
836 }, 815 { 0x1d, 0x1c, 0x00 },
837 { 816 { 0x1e, 0x26, 0x00 }
838 { 0x18, 0x00, 0x00 }, 817 },
839 { 0x1a, 0xe0, 0x00 }, 818 {
840 { 0x1b, 0x26, 0x00 }, 819 { 0x18, 0x00, 0x00 },
841 { 0x1c, 0xff, 0x00 }, 820 { 0x1a, 0xe0, 0x00 },
842 { 0x1d, 0x1c, 0x00 }, 821 { 0x1b, 0x26, 0x00 },
843 { 0x1e, 0x30, 0x00 }, 822 { 0x1c, 0xff, 0x00 },
844 { 0, 0, 0 } 823 { 0x1d, 0x1c, 0x00 },
845 }, 824 { 0x1e, 0x30, 0x00 },
846 { 825 { 0, 0, 0 }
847 { 0, 0, 0 } 826 },
848 }, 827 {
849 { 828 { 0, 0, 0 }
850 { 0, 0, 0 } 829 },
851 } 830 {
852 } 831 { 0, 0, 0 }
832 }
833 }
853}; 834};
854 835
855 836
diff --git a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
index 2b7db916b7e7..8fce56e4482c 100644
--- a/drivers/video/sis/oem310.h
+++ b/drivers/video/sis/oem310.h
@@ -1,9 +1,9 @@
1/* $XFree86$ */ 1/* $XFree86$ */
2/* $XdotOrg$ */ 2/* $XdotOrg$ */
3/* 3/*
4 * OEM Data for 315/330 series 4 * OEM Data for 315/330/340 series
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,206 +50,206 @@
50 * 50 *
51 */ 51 */
52 52
53static const UCHAR SiS310_LCDDelayCompensation_301[] = /* 301 */ 53static const unsigned char SiS310_LCDDelayCompensation_301[] = /* 301 */
54{ 54{
55 0x00,0x00,0x00, /* 800x600 */ 55 0x00,0x00,0x00, /* 800x600 */
56 0x0b,0x0b,0x0b, /* 1024x768 */ 56 0x0b,0x0b,0x0b, /* 1024x768 */
57 0x08,0x08,0x08, /* 1280x1024 */ 57 0x08,0x08,0x08, /* 1280x1024 */
58 0x00,0x00,0x00, /* 640x480 (unknown) */ 58 0x00,0x00,0x00, /* 640x480 (unknown) */
59 0x00,0x00,0x00, /* 1024x600 (unknown) */ 59 0x00,0x00,0x00, /* 1024x600 (unknown) */
60 0x00,0x00,0x00, /* 1152x864 (unknown) */ 60 0x00,0x00,0x00, /* 1152x864 (unknown) */
61 0x08,0x08,0x08, /* 1280x960 (guessed) */ 61 0x08,0x08,0x08, /* 1280x960 (guessed) */
62 0x00,0x00,0x00, /* 1152x768 (unknown) */ 62 0x00,0x00,0x00, /* 1152x768 (unknown) */
63 0x08,0x08,0x08, /* 1400x1050 */ 63 0x08,0x08,0x08, /* 1400x1050 */
64 0x08,0x08,0x08, /* 1280x768 (guessed) */ 64 0x08,0x08,0x08, /* 1280x768 (guessed) */
65 0x00,0x00,0x00, /* 1600x1200 */ 65 0x00,0x00,0x00, /* 1600x1200 */
66 0x00,0x00,0x00, /* 320x480 (unknown) */ 66 0x00,0x00,0x00, /* 320x480 (unknown) */
67 0x00,0x00,0x00, 67 0x00,0x00,0x00,
68 0x00,0x00,0x00, 68 0x00,0x00,0x00,
69 0x00,0x00,0x00 69 0x00,0x00,0x00
70}; 70};
71 71
72/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */ 72/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
73static const UCHAR SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */ 73static const unsigned char SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */
74{ 74{
75 0x01,0x01,0x01, /* 800x600 */ 75 0x01,0x01,0x01, /* 800x600 */
76 0x01,0x01,0x01, /* 1024x768 */ 76 0x01,0x01,0x01, /* 1024x768 */
77 0x01,0x01,0x01, /* 1280x1024 */ 77 0x01,0x01,0x01, /* 1280x1024 */
78 0x01,0x01,0x01, /* 640x480 (unknown) */ 78 0x01,0x01,0x01, /* 640x480 (unknown) */
79 0x01,0x01,0x01, /* 1024x600 (unknown) */ 79 0x01,0x01,0x01, /* 1024x600 (unknown) */
80 0x01,0x01,0x01, /* 1152x864 (unknown) */ 80 0x01,0x01,0x01, /* 1152x864 (unknown) */
81 0x01,0x01,0x01, /* 1280x960 (guessed) */ 81 0x01,0x01,0x01, /* 1280x960 (guessed) */
82 0x01,0x01,0x01, /* 1152x768 (unknown) */ 82 0x01,0x01,0x01, /* 1152x768 (unknown) */
83 0x01,0x01,0x01, /* 1400x1050 */ 83 0x01,0x01,0x01, /* 1400x1050 */
84 0x01,0x01,0x01, /* 1280x768 (guessed) */ 84 0x01,0x01,0x01, /* 1280x768 (guessed) */
85 0x01,0x01,0x01, /* 1600x1200 */ 85 0x01,0x01,0x01, /* 1600x1200 */
86 0x02,0x02,0x02, 86 0x02,0x02,0x02,
87 0x02,0x02,0x02, 87 0x02,0x02,0x02,
88 0x02,0x02,0x02, 88 0x02,0x02,0x02,
89 0x02,0x02,0x02 89 0x02,0x02,0x02
90}; 90};
91 91
92static const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */ 92static const unsigned char SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
93{ 93{
94 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */ 94 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
95 0x33,0x33,0x33, /* 1024x768 */ 95 0x33,0x33,0x33, /* 1024x768 */
96 0x33,0x33,0x33, /* 1280x1024 */ 96 0x33,0x33,0x33, /* 1280x1024 */
97 0x33,0x33,0x33, /* 640x480 (unknown) */ 97 0x33,0x33,0x33, /* 640x480 (unknown) */
98 0x33,0x33,0x33, /* 1024x600 (unknown) */ 98 0x33,0x33,0x33, /* 1024x600 (unknown) */
99 0x33,0x33,0x33, /* 1152x864 (unknown) */ 99 0x33,0x33,0x33, /* 1152x864 (unknown) */
100 0x33,0x33,0x33, /* 1280x960 (guessed) */ 100 0x33,0x33,0x33, /* 1280x960 (guessed) */
101 0x33,0x33,0x33, /* 1152x768 (unknown) */ 101 0x33,0x33,0x33, /* 1152x768 (unknown) */
102 0x33,0x33,0x33, /* 1400x1050 */ 102 0x33,0x33,0x33, /* 1400x1050 */
103 0x33,0x33,0x33, /* 1280x768 (guessed) */ 103 0x33,0x33,0x33, /* 1280x768 (guessed) */
104 0x33,0x33,0x33, /* 1600x1200 */ 104 0x33,0x33,0x33, /* 1600x1200 */
105 0x33,0x33,0x33, 105 0x33,0x33,0x33,
106 0x33,0x33,0x33, 106 0x33,0x33,0x33,
107 0x33,0x33,0x33, 107 0x33,0x33,0x33,
108 0x33,0x33,0x33 108 0x33,0x33,0x33
109}; 109};
110 110
111static const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */ 111static const unsigned char SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
112{ 112{
113 0x33,0x33,0x33, /* 800x600 (guessed) */ 113 0x33,0x33,0x33, /* 800x600 (guessed) */
114 0x33,0x33,0x33, /* 1024x768 */ 114 0x33,0x33,0x33, /* 1024x768 */
115 0x33,0x33,0x33, /* 1280x1024 */ 115 0x33,0x33,0x33, /* 1280x1024 */
116 0x33,0x33,0x33, /* 640x480 (unknown) */ 116 0x33,0x33,0x33, /* 640x480 (unknown) */
117 0x33,0x33,0x33, /* 1024x600 (unknown) */ 117 0x33,0x33,0x33, /* 1024x600 (unknown) */
118 0x33,0x33,0x33, /* 1152x864 (unknown) */ 118 0x33,0x33,0x33, /* 1152x864 (unknown) */
119 0x33,0x33,0x33, /* 1280x960 (guessed) */ 119 0x33,0x33,0x33, /* 1280x960 (guessed) */
120 0x33,0x33,0x33, /* 1152x768 (unknown) */ 120 0x33,0x33,0x33, /* 1152x768 (unknown) */
121 0x33,0x33,0x33, /* 1400x1050 */ 121 0x33,0x33,0x33, /* 1400x1050 */
122 0x33,0x33,0x33, /* 1280x768 (guessed) */ 122 0x33,0x33,0x33, /* 1280x768 (guessed) */
123 0x33,0x33,0x33, /* 1600x1200 */ 123 0x33,0x33,0x33, /* 1600x1200 */
124 0x33,0x33,0x33, 124 0x33,0x33,0x33,
125 0x33,0x33,0x33, 125 0x33,0x33,0x33,
126 0x33,0x33,0x33, 126 0x33,0x33,0x33,
127 0x33,0x33,0x33 127 0x33,0x33,0x33
128}; 128};
129 129
130static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */ 130static const unsigned char SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
131{ 131{
132 0x01,0x01,0x01, /* 800x600 */ 132 0x01,0x01,0x01, /* 800x600 */
133 0x0C,0x0C,0x0C, /* 1024x768 */ 133 0x0C,0x0C,0x0C, /* 1024x768 */
134 0x0C,0x0C,0x0C, /* 1280x1024 */ 134 0x0C,0x0C,0x0C, /* 1280x1024 */
135 0x08,0x08,0x08, /* 640x480 */ 135 0x08,0x08,0x08, /* 640x480 */
136 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */ 136 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
137 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */ 137 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
138 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */ 138 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
139 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */ 139 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
140 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */ 140 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
141 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */ 141 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
142 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */ 142 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
143 0x02,0x02,0x02, 143 0x02,0x02,0x02,
144 0x02,0x02,0x02, 144 0x02,0x02,0x02,
145 0x02,0x02,0x02, 145 0x02,0x02,0x02,
146 0x02,0x02,0x02 146 0x02,0x02,0x02
147}; 147};
148 148
149static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */ 149static const unsigned char SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
150{ 150{
151 0x01,0x01,0x01, /* 800x600 */ 151 0x01,0x01,0x01, /* 800x600 */
152 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */ 152 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
153 0x0C,0x0C,0x0C, /* 1280x1024 */ 153 0x0C,0x0C,0x0C, /* 1280x1024 */
154 0x08,0x08,0x08, /* 640x480 */ 154 0x08,0x08,0x08, /* 640x480 */
155 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */ 155 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
156 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */ 156 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
157 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */ 157 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
158 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */ 158 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
159 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */ 159 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
160 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */ 160 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
161 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */ 161 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
162 0x02,0x02,0x02, 162 0x02,0x02,0x02,
163 0x02,0x02,0x02, 163 0x02,0x02,0x02,
164 0x02,0x02,0x02, 164 0x02,0x02,0x02,
165 0x02,0x02,0x02 165 0x02,0x02,0x02
166}; 166};
167 167
168static const UCHAR SiS310_TVDelayCompensation_301[] = /* 301 */ 168static const unsigned char SiS310_TVDelayCompensation_301[] = /* 301 */
169{ 169{
170 0x02,0x02, /* NTSC Enhanced, Standard */ 170 0x02,0x02, /* NTSC Enhanced, Standard */
171 0x02,0x02, /* PAL */ 171 0x02,0x02, /* PAL */
172 0x08,0x0b /* HiVision */ 172 0x08,0x0b /* HiVision */
173}; 173};
174 174
175static const UCHAR SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */ 175static const unsigned char SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */
176{ 176{
177 0x03,0x03, 177 0x03,0x03,
178 0x03,0x03, 178 0x03,0x03,
179 0x03,0x03 179 0x03,0x03
180}; 180};
181 181
182static const UCHAR SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */ 182static const unsigned char SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */
183{ 183{
184 0x05,0x05, 184 0x05,0x05,
185 0x05,0x05, 185 0x05,0x05,
186 0x05,0x05 186 0x05,0x05
187}; 187};
188 188
189static const UCHAR SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */ 189static const unsigned char SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
190{ 190{
191 0x33,0x33, 191 0x33,0x33,
192 0x33,0x33, 192 0x33,0x33,
193 0x33,0x33 193 0x33,0x33
194}; 194};
195 195
196static const UCHAR SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */ 196static const unsigned char SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */
197{ 197{
198 0x33,0x33, 198 0x33,0x33,
199 0x33,0x33, 199 0x33,0x33,
200 0x33,0x33 200 0x33,0x33
201}; 201};
202 202
203static const UCHAR SiS_TVDelay661_301[] = /* 661, 301 */ 203static const unsigned char SiS_TVDelay661_301[] = /* 661, 301 */
204{ 204{
205 0x44,0x44, 205 0x44,0x44,
206 0x44,0x44, 206 0x44,0x44,
207 0x00,0x00, 207 0x00,0x00,
208 0x44,0x44, 208 0x44,0x44,
209 0x44,0x44, 209 0x44,0x44,
210 0x44,0x44 210 0x44,0x44
211}; 211};
212 212
213static const UCHAR SiS_TVDelay661_301B[] = /* 661, 301B et al */ 213static const unsigned char SiS_TVDelay661_301B[] = /* 661, 301B et al */
214{ 214{
215 0x44,0x44, 215 0x44,0x44,
216 0x44,0x44, 216 0x44,0x44,
217 0x00,0x00, 217 0x00,0x00,
218 0x44,0x44, 218 0x44,0x44,
219 0x44,0x44, 219 0x44,0x44,
220 0x44,0x44 220 0x44,0x44
221}; 221};
222 222
223static const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */ 223static const unsigned char SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
224{ 224{
225 0x0a,0x0a, 225 0x0a,0x0a,
226 0x0a,0x0a, 226 0x0a,0x0a,
227 0x0a,0x0a 227 0x0a,0x0a
228}; 228};
229 229
230static const UCHAR SiS310_TVAntiFlick1[6][2] = 230static const unsigned char SiS310_TVAntiFlick1[6][2] =
231{ 231{
232 {0x4,0x0}, 232 {0x4,0x0},
233 {0x4,0x8}, 233 {0x4,0x8},
234 {0x0,0x0}, 234 {0x0,0x0},
235 {0x0,0x0}, 235 {0x0,0x0},
236 {0x0,0x0}, 236 {0x0,0x0},
237 {0x0,0x0} 237 {0x0,0x0}
238}; 238};
239 239
240static const UCHAR SiS310_TVEdge1[6][2] = 240static const unsigned char SiS310_TVEdge1[6][2] =
241{ 241{
242 {0x0,0x4}, 242 {0x0,0x4},
243 {0x0,0x4}, 243 {0x0,0x4},
244 {0x0,0x0}, 244 {0x0,0x0},
245 {0x0,0x0}, 245 {0x0,0x0},
246 {0x0,0x0}, 246 {0x0,0x0},
247 {0x0,0x0} 247 {0x0,0x0}
248}; 248};
249 249
250static const UCHAR SiS310_TVYFilter1[5][8][4] = 250static const unsigned char SiS310_TVYFilter1[5][8][4] =
251{ 251{
252 { 252 {
253 {0x00,0xf4,0x10,0x38}, /* NTSC */ 253 {0x00,0xf4,0x10,0x38}, /* NTSC */
254 {0x00,0xf4,0x10,0x38}, 254 {0x00,0xf4,0x10,0x38},
255 {0xeb,0x04,0x25,0x18}, 255 {0xeb,0x04,0x25,0x18},
@@ -258,8 +258,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
258 {0xeb,0x04,0x25,0x18}, 258 {0xeb,0x04,0x25,0x18},
259 {0xee,0x0c,0x22,0x08}, 259 {0xee,0x0c,0x22,0x08},
260 {0xeb,0x15,0x25,0xf6} 260 {0xeb,0x15,0x25,0xf6}
261 }, 261 },
262 { 262 {
263 {0x00,0xf4,0x10,0x38}, /* PAL */ 263 {0x00,0xf4,0x10,0x38}, /* PAL */
264 {0x00,0xf4,0x10,0x38}, 264 {0x00,0xf4,0x10,0x38},
265 {0xf1,0xf7,0x1f,0x32}, 265 {0xf1,0xf7,0x1f,0x32},
@@ -268,8 +268,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
268 {0xf1,0xf7,0x1f,0x32}, 268 {0xf1,0xf7,0x1f,0x32},
269 {0xf3,0x00,0x1d,0x20}, 269 {0xf3,0x00,0x1d,0x20},
270 {0xfc,0xfb,0x14,0x2a} 270 {0xfc,0xfb,0x14,0x2a}
271 }, 271 },
272 { 272 {
273 {0x00,0x00,0x00,0x00}, /* HiVision */ 273 {0x00,0x00,0x00,0x00}, /* HiVision */
274 {0x00,0xf4,0x10,0x38}, 274 {0x00,0xf4,0x10,0x38},
275 {0x00,0xf4,0x10,0x38}, 275 {0x00,0xf4,0x10,0x38},
@@ -278,9 +278,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
278 {0x00,0xf4,0x10,0x38}, 278 {0x00,0xf4,0x10,0x38},
279 {0xeb,0x04,0x25,0x18}, 279 {0xeb,0x04,0x25,0x18},
280 {0xee,0x0c,0x22,0x08} 280 {0xee,0x0c,0x22,0x08}
281 }, 281 },
282 { 282 {
283 {0x00,0xf4,0x10,0x38}, /* PAL-M */ 283 {0x00,0xf4,0x10,0x38}, /* PAL-M */
284 {0x00,0xf4,0x10,0x38}, 284 {0x00,0xf4,0x10,0x38},
285 {0xeb,0x04,0x10,0x18}, 285 {0xeb,0x04,0x10,0x18},
286 {0xf7,0x06,0x19,0x14}, 286 {0xf7,0x06,0x19,0x14},
@@ -288,9 +288,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
288 {0xeb,0x04,0x25,0x18}, 288 {0xeb,0x04,0x25,0x18},
289 {0xeb,0x04,0x25,0x18}, 289 {0xeb,0x04,0x25,0x18},
290 {0xeb,0x15,0x25,0xf6} 290 {0xeb,0x15,0x25,0xf6}
291 }, 291 },
292 { 292 {
293 {0x00,0xf4,0x10,0x38}, /* PAL-N */ 293 {0x00,0xf4,0x10,0x38}, /* PAL-N */
294 {0x00,0xf4,0x10,0x38}, 294 {0x00,0xf4,0x10,0x38},
295 {0xeb,0x04,0x10,0x18}, 295 {0xeb,0x04,0x10,0x18},
296 {0xf7,0x06,0x19,0x14}, 296 {0xf7,0x06,0x19,0x14},
@@ -298,12 +298,12 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
298 {0xeb,0x04,0x25,0x18}, 298 {0xeb,0x04,0x25,0x18},
299 {0xeb,0x04,0x25,0x18}, 299 {0xeb,0x04,0x25,0x18},
300 {0xeb,0x15,0x25,0xf6} 300 {0xeb,0x15,0x25,0xf6}
301 } 301 }
302}; 302};
303 303
304static const UCHAR SiS310_TVYFilter2[5][9][7] = 304static const unsigned char SiS310_TVYFilter2[5][9][7] =
305{ 305{
306 { 306 {
307 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* NTSC */ 307 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* NTSC */
308 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 308 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
309 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 309 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -313,8 +313,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
313 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 313 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
314 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, 314 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
315 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} 315 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
316 }, 316 },
317 { 317 {
318 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL */ 318 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL */
319 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 319 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
320 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 320 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -324,8 +324,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
324 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 324 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
325 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, 325 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
326 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} 326 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
327 }, 327 },
328 { 328 {
329 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, /* HiVision */ 329 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, /* HiVision */
330 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, 330 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
331 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, 331 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
@@ -335,9 +335,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
335 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, 335 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
336 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, 336 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
337 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22} 337 {0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
338 }, 338 },
339 { 339 {
340 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */ 340 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */
341 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 341 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
342 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 342 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
343 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 343 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -346,9 +346,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
346 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 346 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
347 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, 347 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
348 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} 348 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
349 }, 349 },
350 { 350 {
351 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */ 351 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */
352 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 352 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
353 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, 353 {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
354 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 354 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -357,58 +357,39 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
357 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C}, 357 {0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
358 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38}, 358 {0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
359 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28} 359 {0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
360 } 360 }
361}; 361};
362 362
363static const UCHAR SiS310_TVPhaseIncr1[3][2][4] = 363static const unsigned char SiS310_TVPhaseIncr1[3][2][4] =
364{ 364{
365 { 365 {
366 {0x21,0xed,0xba,0x08}, 366 {0x21,0xed,0xba,0x08},
367 {0x21,0xed,0xba,0x08} 367 {0x21,0xed,0xba,0x08}
368 }, 368 },
369 { 369 {
370 {0x2a,0x05,0xe3,0x00}, 370 {0x2a,0x05,0xe3,0x00},
371 {0x2a,0x05,0xe3,0x00} 371 {0x2a,0x05,0xe3,0x00}
372 }, 372 },
373 { 373 {
374 {0x2a,0x05,0xd3,0x00}, 374 {0x2a,0x05,0xd3,0x00},
375 {0x2a,0x05,0xd3,0x00} 375 {0x2a,0x05,0xd3,0x00}
376 } 376 }
377}; 377};
378 378
379static const UCHAR SiS310_TVPhaseIncr2[3][2][4] = 379static const unsigned char SiS310_TVPhaseIncr2[3][2][4] =
380{ 380{
381 { 381 {
382 {0x21,0xf0,0x7b,0xd6}, 382 {0x21,0xf0,0x7b,0xd6},
383 {0x21,0xf0,0x7b,0xd6} 383 {0x21,0xf0,0x7b,0xd6}
384 }, 384 },
385 { 385 {
386 {0x2a,0x0a,0x41,0xe9}, 386 {0x2a,0x0a,0x41,0xe9},
387 {0x2a,0x0a,0x41,0xe9} 387 {0x2a,0x0a,0x41,0xe9}
388 }, 388 },
389 { 389 {
390 {0x2a,0x05,0xd3,0x00}, 390 {0x2a,0x05,0xd3,0x00},
391 {0x2a,0x05,0xd3,0x00} 391 {0x2a,0x05,0xd3,0x00}
392 } 392 }
393};
394
395static const UCHAR SiS661_TVPhase[] = {
396 0x21,0xED,0xBA,0x08,
397 0x2A,0x05,0xE3,0x00,
398 0x21,0xE4,0x2E,0x9B,
399 0x21,0xF4,0x3E,0xBA,
400 0x1E,0x8B,0xA2,0xA7,
401 0x1E,0x83,0x0A,0xE0,
402 0x00,0x00,0x00,0x00,
403 0x00,0x00,0x00,0x00,
404 0x21,0xF0,0x7B,0xD6,
405 0x2A,0x09,0x86,0xE9,
406 0x21,0xE6,0xEF,0xA4,
407 0x21,0xF6,0x94,0x46,
408 0x1E,0x8B,0xA2,0xA7,
409 0x1E,0x83,0x0A,0xE0,
410 0x00,0x00,0x00,0x00,
411 0x00,0x00,0x00,0x00
412}; 393};
413 394
414/**************************************************************/ 395/**************************************************************/
@@ -417,7 +398,7 @@ static const UCHAR SiS661_TVPhase[] = {
417 398
418/* Inventec / Compaq Presario 3045US, 3017 */ 399/* Inventec / Compaq Presario 3045US, 3017 */
419 400
420static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] = 401static const struct SiS_LCDData SiS310_ExtCompaq1280x1024Data[] =
421{ 402{
422 { 211, 60,1024, 501,1688,1066}, 403 { 211, 60,1024, 501,1688,1066},
423 { 211, 60,1024, 508,1688,1066}, 404 { 211, 60,1024, 508,1688,1066},
@@ -431,17 +412,17 @@ static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] =
431 412
432/* Asus A2xxxH _2 */ 413/* Asus A2xxxH _2 */
433 414
434static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] = 415static const struct SiS_Part2PortTbl SiS310_CRT2Part2_Asus1024x768_3[] =
435{ 416{
436 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 417 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
437 {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 418 {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
438 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 419 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
439 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 420 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
440 {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, 421 {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
441 {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 422 {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
442 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}, 423 {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
443 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 424 {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
444 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}} 425 {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
445}; 426};
446 427
447 428
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index 15939b057713..841ca3190cd4 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * OS depending defines 4 * OS depending defines
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -55,8 +55,11 @@
55#define _SIS_OSDEF_H_ 55#define _SIS_OSDEF_H_
56 56
57/* The choices are: */ 57/* The choices are: */
58#define LINUX_KERNEL /* Linux kernel framebuffer */ 58#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
59/* #define LINUX_XF86 */ /* XFree86/X.org */ 59#undef SIS_XORG_XF86 /* XFree86/X.org */
60
61#undef SIS_LINUX_KERNEL_24
62#undef SIS_LINUX_KERNEL_26
60 63
61#ifdef OutPortByte 64#ifdef OutPortByte
62#undef OutPortByte 65#undef OutPortByte
@@ -86,8 +89,9 @@
86/* LINUX KERNEL */ 89/* LINUX KERNEL */
87/**********************************************************************/ 90/**********************************************************************/
88 91
89#ifdef LINUX_KERNEL 92#ifdef SIS_LINUX_KERNEL
90#include <linux/config.h> 93#include <linux/config.h>
94#include <linux/version.h>
91 95
92#ifdef CONFIG_FB_SIS_300 96#ifdef CONFIG_FB_SIS_300
93#define SIS300 97#define SIS300
@@ -97,6 +101,12 @@
97#define SIS315H 101#define SIS315H
98#endif 102#endif
99 103
104#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
105#define SIS_LINUX_KERNEL_26
106#else
107#define SIS_LINUX_KERNEL_24
108#endif
109
100#if !defined(SIS300) && !defined(SIS315H) 110#if !defined(SIS300) && !defined(SIS315H)
101#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set 111#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
102#warning sisfb will not work! 112#warning sisfb will not work!
@@ -109,13 +119,15 @@
109#define InPortWord(p) inw((SISIOADDRESS)(p)) 119#define InPortWord(p) inw((SISIOADDRESS)(p))
110#define InPortLong(p) inl((SISIOADDRESS)(p)) 120#define InPortLong(p) inl((SISIOADDRESS)(p))
111#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize) 121#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
112#endif 122
123#endif /* LINUX_KERNEL */
113 124
114/**********************************************************************/ 125/**********************************************************************/
115/* XFree86/X.org */ 126/* XFree86/X.org */
116/**********************************************************************/ 127/**********************************************************************/
117 128
118#ifdef LINUX_XF86 129#ifdef SIS_XORG_XF86
130
119#define SIS300 131#define SIS300
120#define SIS315H 132#define SIS315H
121 133
@@ -126,6 +138,7 @@
126#define InPortWord(p) inSISREGW((IOADDRESS)(p)) 138#define InPortWord(p) inSISREGW((IOADDRESS)(p))
127#define InPortLong(p) inSISREGL((IOADDRESS)(p)) 139#define InPortLong(p) inSISREGL((IOADDRESS)(p))
128#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) 140#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
129#endif 141
142#endif /* XF86 */
130 143
131#endif /* _OSDEF_H_ */ 144#endif /* _OSDEF_H_ */
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index d0103c162e43..0b6e625d7331 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -1,8 +1,10 @@
1/* 1/*
2 * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX] 2 * SiS 300/540/630[S]/730[S],
3 * SiS 315[E|PRO]/550/[M]65x/[M]661[F|M]X/740/[M]741[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
3 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3 5 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
4 * 6 *
5 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria. 7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
6 * 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 as published by 10 * it under the terms of the GNU General Public License as published by
@@ -19,8 +21,8 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 */ 22 */
21 23
22#ifndef _SIS_H 24#ifndef _SIS_H_
23#define _SIS_H 25#define _SIS_H_
24 26
25#include <linux/config.h> 27#include <linux/config.h>
26#include <linux/version.h> 28#include <linux/version.h>
@@ -35,26 +37,37 @@
35#include "vgatypes.h" 37#include "vgatypes.h"
36#include "vstruct.h" 38#include "vstruct.h"
37 39
38#define VER_MAJOR 1 40#define VER_MAJOR 1
39#define VER_MINOR 7 41#define VER_MINOR 8
40#define VER_LEVEL 17 42#define VER_LEVEL 9
41
42#undef SIS_CONFIG_COMPAT
43 43
44#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 44#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
45#include <linux/spinlock.h> 45#include <linux/spinlock.h>
46#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b)
47#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
48#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
49#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
46#ifdef CONFIG_COMPAT 50#ifdef CONFIG_COMPAT
51#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
47#include <linux/ioctl32.h> 52#include <linux/ioctl32.h>
48#define SIS_CONFIG_COMPAT 53#define SIS_OLD_CONFIG_COMPAT
49#endif 54#else
50#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19) 55#include <linux/smp_lock.h>
51#ifdef __x86_64__ 56#define SIS_NEW_CONFIG_COMPAT
52/* Shouldn't we check for CONFIG_IA32_EMULATION here? */ 57#endif
58#endif /* CONFIG_COMPAT */
59#else /* 2.4 */
60#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
61#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
62#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
63#define SIS_PCI_PUT_DEVICE(a)
64#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
65#ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
53#include <asm/ioctl32.h> 66#include <asm/ioctl32.h>
54#define SIS_CONFIG_COMPAT 67#define SIS_OLD_CONFIG_COMPAT
55#endif 68#endif
56#endif 69#endif
57 70#endif /* 2.4 */
58#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) 71#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
59#define SIS_IOTYPE1 void __iomem 72#define SIS_IOTYPE1 void __iomem
60#define SIS_IOTYPE2 __iomem 73#define SIS_IOTYPE2 __iomem
@@ -79,228 +92,312 @@
79 92
80/* To be included in pci_ids.h */ 93/* To be included in pci_ids.h */
81#ifndef PCI_DEVICE_ID_SI_650_VGA 94#ifndef PCI_DEVICE_ID_SI_650_VGA
82#define PCI_DEVICE_ID_SI_650_VGA 0x6325 95#define PCI_DEVICE_ID_SI_650_VGA 0x6325
83#endif 96#endif
84#ifndef PCI_DEVICE_ID_SI_650 97#ifndef PCI_DEVICE_ID_SI_650
85#define PCI_DEVICE_ID_SI_650 0x0650 98#define PCI_DEVICE_ID_SI_650 0x0650
86#endif 99#endif
87#ifndef PCI_DEVICE_ID_SI_651 100#ifndef PCI_DEVICE_ID_SI_651
88#define PCI_DEVICE_ID_SI_651 0x0651 101#define PCI_DEVICE_ID_SI_651 0x0651
89#endif 102#endif
90#ifndef PCI_DEVICE_ID_SI_740 103#ifndef PCI_DEVICE_ID_SI_740
91#define PCI_DEVICE_ID_SI_740 0x0740 104#define PCI_DEVICE_ID_SI_740 0x0740
92#endif 105#endif
93#ifndef PCI_DEVICE_ID_SI_330 106#ifndef PCI_DEVICE_ID_SI_330
94#define PCI_DEVICE_ID_SI_330 0x0330 107#define PCI_DEVICE_ID_SI_330 0x0330
95#endif 108#endif
96#ifndef PCI_DEVICE_ID_SI_660_VGA 109#ifndef PCI_DEVICE_ID_SI_660_VGA
97#define PCI_DEVICE_ID_SI_660_VGA 0x6330 110#define PCI_DEVICE_ID_SI_660_VGA 0x6330
98#endif 111#endif
99#ifndef PCI_DEVICE_ID_SI_661 112#ifndef PCI_DEVICE_ID_SI_661
100#define PCI_DEVICE_ID_SI_661 0x0661 113#define PCI_DEVICE_ID_SI_661 0x0661
101#endif 114#endif
102#ifndef PCI_DEVICE_ID_SI_741 115#ifndef PCI_DEVICE_ID_SI_741
103#define PCI_DEVICE_ID_SI_741 0x0741 116#define PCI_DEVICE_ID_SI_741 0x0741
104#endif 117#endif
105#ifndef PCI_DEVICE_ID_SI_660 118#ifndef PCI_DEVICE_ID_SI_660
106#define PCI_DEVICE_ID_SI_660 0x0660 119#define PCI_DEVICE_ID_SI_660 0x0660
107#endif 120#endif
108#ifndef PCI_DEVICE_ID_SI_760 121#ifndef PCI_DEVICE_ID_SI_760
109#define PCI_DEVICE_ID_SI_760 0x0760 122#define PCI_DEVICE_ID_SI_760 0x0760
123#endif
124#ifndef PCI_DEVICE_ID_SI_761
125#define PCI_DEVICE_ID_SI_761 0x0761
126#endif
127
128#ifndef PCI_VENDOR_ID_XGI
129#define PCI_VENDOR_ID_XGI 0x18ca
130#endif
131
132#ifndef PCI_DEVICE_ID_XGI_20
133#define PCI_DEVICE_ID_XGI_20 0x0020
134#endif
135
136#ifndef PCI_DEVICE_ID_XGI_40
137#define PCI_DEVICE_ID_XGI_40 0x0040
110#endif 138#endif
111 139
112/* To be included in fb.h */ 140/* To be included in fb.h */
113#ifndef FB_ACCEL_SIS_GLAMOUR_2 141#ifndef FB_ACCEL_SIS_GLAMOUR_2
114#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */ 142#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
115#endif 143#endif
116#ifndef FB_ACCEL_SIS_XABRE 144#ifndef FB_ACCEL_SIS_XABRE
117#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 760 */ 145#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 76x */
146#endif
147#ifndef FB_ACCEL_XGI_VOLARI_V
148#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari Vx (V3XT, V5, V8) */
149#endif
150#ifndef FB_ACCEL_XGI_VOLARI_Z
151#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
118#endif 152#endif
119
120#define MAX_ROM_SCAN 0x10000
121 153
122/* ivideo->caps */ 154/* ivideo->caps */
123#define HW_CURSOR_CAP 0x80 155#define HW_CURSOR_CAP 0x80
124#define TURBO_QUEUE_CAP 0x40 156#define TURBO_QUEUE_CAP 0x40
125#define AGP_CMD_QUEUE_CAP 0x20 157#define AGP_CMD_QUEUE_CAP 0x20
126#define VM_CMD_QUEUE_CAP 0x10 158#define VM_CMD_QUEUE_CAP 0x10
127#define MMIO_CMD_QUEUE_CAP 0x08 159#define MMIO_CMD_QUEUE_CAP 0x08
128 160
129/* For 300 series */ 161/* For 300 series */
130#define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */ 162#define TURBO_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
131#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */ 163#define HW_CURSOR_AREA_SIZE_300 4096 /* 4K */
132 164
133/* For 315/Xabre series */ 165/* For 315/Xabre series */
134#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */ 166#define COMMAND_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
135#define COMMAND_QUEUE_THRESHOLD 0x1F 167#define COMMAND_QUEUE_AREA_SIZE_Z7 (128 * 1024) /* 128k for XGI Z7 */
136#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */ 168#define HW_CURSOR_AREA_SIZE_315 16384 /* 16K */
137 169#define COMMAND_QUEUE_THRESHOLD 0x1F
138#define SIS_OH_ALLOC_SIZE 4000 170
139#define SENTINEL 0x7fffffff 171#define SIS_OH_ALLOC_SIZE 4000
140 172#define SENTINEL 0x7fffffff
141#define SEQ_ADR 0x14 173
142#define SEQ_DATA 0x15 174#define SEQ_ADR 0x14
143#define DAC_ADR 0x18 175#define SEQ_DATA 0x15
144#define DAC_DATA 0x19 176#define DAC_ADR 0x18
145#define CRTC_ADR 0x24 177#define DAC_DATA 0x19
146#define CRTC_DATA 0x25 178#define CRTC_ADR 0x24
147#define DAC2_ADR (0x16-0x30) 179#define CRTC_DATA 0x25
148#define DAC2_DATA (0x17-0x30) 180#define DAC2_ADR (0x16-0x30)
149#define VB_PART1_ADR (0x04-0x30) 181#define DAC2_DATA (0x17-0x30)
150#define VB_PART1_DATA (0x05-0x30) 182#define VB_PART1_ADR (0x04-0x30)
151#define VB_PART2_ADR (0x10-0x30) 183#define VB_PART1_DATA (0x05-0x30)
152#define VB_PART2_DATA (0x11-0x30) 184#define VB_PART2_ADR (0x10-0x30)
153#define VB_PART3_ADR (0x12-0x30) 185#define VB_PART2_DATA (0x11-0x30)
154#define VB_PART3_DATA (0x13-0x30) 186#define VB_PART3_ADR (0x12-0x30)
155#define VB_PART4_ADR (0x14-0x30) 187#define VB_PART3_DATA (0x13-0x30)
156#define VB_PART4_DATA (0x15-0x30) 188#define VB_PART4_ADR (0x14-0x30)
157 189#define VB_PART4_DATA (0x15-0x30)
158#define SISSR ivideo->SiS_Pr.SiS_P3c4 190
159#define SISCR ivideo->SiS_Pr.SiS_P3d4 191#define SISSR ivideo->SiS_Pr.SiS_P3c4
160#define SISDACA ivideo->SiS_Pr.SiS_P3c8 192#define SISCR ivideo->SiS_Pr.SiS_P3d4
161#define SISDACD ivideo->SiS_Pr.SiS_P3c9 193#define SISDACA ivideo->SiS_Pr.SiS_P3c8
162#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port 194#define SISDACD ivideo->SiS_Pr.SiS_P3c9
163#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port 195#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
164#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port 196#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
165#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port 197#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
166#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port 198#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
167#define SISDAC2A SISPART5 199#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
168#define SISDAC2D (SISPART5 + 1) 200#define SISDAC2A SISPART5
169#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c) 201#define SISDAC2D (SISPART5 + 1)
170#define SISMISCW ivideo->SiS_Pr.SiS_P3c2 202#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
171#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a) 203#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
172#define SISPEL ivideo->SiS_Pr.SiS_P3c6 204#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
173 205#define SISPEL ivideo->SiS_Pr.SiS_P3c6
174#define IND_SIS_PASSWORD 0x05 /* SRs */ 206#define SISVGAENABLE (ivideo->SiS_Pr.RelIO + 0x13)
175#define IND_SIS_COLOR_MODE 0x06 207#define SISVID (ivideo->SiS_Pr.RelIO + 0x02 - 0x30)
176#define IND_SIS_RAMDAC_CONTROL 0x07 208#define SISCAP (ivideo->SiS_Pr.RelIO + 0x00 - 0x30)
177#define IND_SIS_DRAM_SIZE 0x14 209
178#define IND_SIS_MODULE_ENABLE 0x1E 210#define IND_SIS_PASSWORD 0x05 /* SRs */
179#define IND_SIS_PCI_ADDRESS_SET 0x20 211#define IND_SIS_COLOR_MODE 0x06
180#define IND_SIS_TURBOQUEUE_ADR 0x26 212#define IND_SIS_RAMDAC_CONTROL 0x07
181#define IND_SIS_TURBOQUEUE_SET 0x27 213#define IND_SIS_DRAM_SIZE 0x14
182#define IND_SIS_POWER_ON_TRAP 0x38 214#define IND_SIS_MODULE_ENABLE 0x1E
183#define IND_SIS_POWER_ON_TRAP2 0x39 215#define IND_SIS_PCI_ADDRESS_SET 0x20
184#define IND_SIS_CMDQUEUE_SET 0x26 216#define IND_SIS_TURBOQUEUE_ADR 0x26
185#define IND_SIS_CMDQUEUE_THRESHOLD 0x27 217#define IND_SIS_TURBOQUEUE_SET 0x27
186 218#define IND_SIS_POWER_ON_TRAP 0x38
187#define IND_SIS_AGP_IO_PAD 0x48 219#define IND_SIS_POWER_ON_TRAP2 0x39
188 220#define IND_SIS_CMDQUEUE_SET 0x26
189#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */ 221#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
190#define SIS_CRT2_WENABLE_315 0x2F 222
191 223#define IND_SIS_AGP_IO_PAD 0x48
192#define SIS_PASSWORD 0x86 /* SR05 */ 224
193 225#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
194#define SIS_INTERLACED_MODE 0x20 /* SR06 */ 226#define SIS_CRT2_WENABLE_315 0x2F
195#define SIS_8BPP_COLOR_MODE 0x0 227
196#define SIS_15BPP_COLOR_MODE 0x1 228#define SIS_PASSWORD 0x86 /* SR05 */
197#define SIS_16BPP_COLOR_MODE 0x2 229
198#define SIS_32BPP_COLOR_MODE 0x4 230#define SIS_INTERLACED_MODE 0x20 /* SR06 */
199 231#define SIS_8BPP_COLOR_MODE 0x0
200#define SIS_ENABLE_2D 0x40 /* SR1E */ 232#define SIS_15BPP_COLOR_MODE 0x1
201 233#define SIS_16BPP_COLOR_MODE 0x2
202#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */ 234#define SIS_32BPP_COLOR_MODE 0x4
203#define SIS_PCI_ADDR_ENABLE 0x80 235
204 236#define SIS_ENABLE_2D 0x40 /* SR1E */
205#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330 series SR26 */ 237
206#define SIS_VRAM_CMDQUEUE_ENABLE 0x40 238#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
207#define SIS_MMIO_CMD_ENABLE 0x20 239#define SIS_PCI_ADDR_ENABLE 0x80
208#define SIS_CMD_QUEUE_SIZE_512k 0x00 240
209#define SIS_CMD_QUEUE_SIZE_1M 0x04 241#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */
210#define SIS_CMD_QUEUE_SIZE_2M 0x08 242#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
211#define SIS_CMD_QUEUE_SIZE_4M 0x0C 243#define SIS_MMIO_CMD_ENABLE 0x20
212#define SIS_CMD_QUEUE_RESET 0x01 244#define SIS_CMD_QUEUE_SIZE_512k 0x00
213#define SIS_CMD_AUTO_CORR 0x02 245#define SIS_CMD_QUEUE_SIZE_1M 0x04
214 246#define SIS_CMD_QUEUE_SIZE_2M 0x08
215#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */ 247#define SIS_CMD_QUEUE_SIZE_4M 0x0C
216#define SIS_MODE_SELECT_CRT2 0x02 248#define SIS_CMD_QUEUE_RESET 0x01
217#define SIS_VB_OUTPUT_COMPOSITE 0x04 249#define SIS_CMD_AUTO_CORR 0x02
218#define SIS_VB_OUTPUT_SVIDEO 0x08 250
219#define SIS_VB_OUTPUT_SCART 0x10 251#define SIS_CMD_QUEUE_SIZE_Z7_64k 0x00 /* XGI Z7 */
220#define SIS_VB_OUTPUT_LCD 0x20 252#define SIS_CMD_QUEUE_SIZE_Z7_128k 0x04
221#define SIS_VB_OUTPUT_CRT2 0x40 253
222#define SIS_VB_OUTPUT_HIVISION 0x80 254#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
223 255#define SIS_MODE_SELECT_CRT2 0x02
224#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */ 256#define SIS_VB_OUTPUT_COMPOSITE 0x04
225#define SIS_DRIVER_MODE 0x40 257#define SIS_VB_OUTPUT_SVIDEO 0x08
226 258#define SIS_VB_OUTPUT_SCART 0x10
227#define SIS_VB_COMPOSITE 0x01 /* CR32 */ 259#define SIS_VB_OUTPUT_LCD 0x20
228#define SIS_VB_SVIDEO 0x02 260#define SIS_VB_OUTPUT_CRT2 0x40
229#define SIS_VB_SCART 0x04 261#define SIS_VB_OUTPUT_HIVISION 0x80
230#define SIS_VB_LCD 0x08 262
231#define SIS_VB_CRT2 0x10 263#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
232#define SIS_CRT1 0x20 264#define SIS_DRIVER_MODE 0x40
233#define SIS_VB_HIVISION 0x40 265
234#define SIS_VB_YPBPR 0x80 266#define SIS_VB_COMPOSITE 0x01 /* CR32 */
235#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \ 267#define SIS_VB_SVIDEO 0x02
236 SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR) 268#define SIS_VB_SCART 0x04
237 269#define SIS_VB_LCD 0x08
238#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */ 270#define SIS_VB_CRT2 0x10
239#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */ 271#define SIS_CRT1 0x20
240#define SIS_EXTERNAL_CHIP_LVDS 0x02 272#define SIS_VB_HIVISION 0x40
241#define SIS_EXTERNAL_CHIP_TRUMPION 0x03 273#define SIS_VB_YPBPR 0x80
242#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04 274#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
243#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05 275 SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
244#define SIS310_EXTERNAL_CHIP_LVDS 0x02 276
245#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03 277#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
246 278#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
247#define SIS_AGP_2X 0x20 /* CR48 */ 279#define SIS_EXTERNAL_CHIP_LVDS 0x02
248 280#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
249#define HW_DEVICE_EXTENSION SIS_HW_INFO 281#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
250#define PHW_DEVICE_EXTENSION PSIS_HW_INFO 282#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
283#define SIS310_EXTERNAL_CHIP_LVDS 0x02
284#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
285
286#define SIS_AGP_2X 0x20 /* CR48 */
287
288/* vbflags, private entries (others in sisfb.h) */
289#define VB_CONEXANT 0x00000800 /* 661 series only */
290#define VB_TRUMPION VB_CONEXANT /* 300 series only */
291#define VB_302ELV 0x00004000
292#define VB_301 0x00100000 /* Video bridge type */
293#define VB_301B 0x00200000
294#define VB_302B 0x00400000
295#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
296#define VB_LVDS 0x01000000
297#define VB_CHRONTEL 0x02000000
298#define VB_301LV 0x04000000
299#define VB_302LV 0x08000000
300#define VB_301C 0x10000000
301
302#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
303#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
304
305/* vbflags2 (static stuff only!) */
306#define VB2_SISUMC 0x00000001
307#define VB2_301 0x00000002 /* Video bridge type */
308#define VB2_301B 0x00000004
309#define VB2_301C 0x00000008
310#define VB2_307T 0x00000010
311#define VB2_302B 0x00000800
312#define VB2_301LV 0x00001000
313#define VB2_302LV 0x00002000
314#define VB2_302ELV 0x00004000
315#define VB2_307LV 0x00008000
316#define VB2_30xBDH 0x08000000 /* 30xB DH version (w/o LCD support) */
317#define VB2_CONEXANT 0x10000000
318#define VB2_TRUMPION 0x20000000
319#define VB2_LVDS 0x40000000
320#define VB2_CHRONTEL 0x80000000
321
322#define VB2_SISLVDSBRIDGE (VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
323#define VB2_SISTMDSBRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
324#define VB2_SISBRIDGE (VB2_SISLVDSBRIDGE | VB2_SISTMDSBRIDGE)
325
326#define VB2_SISTMDSLCDABRIDGE (VB2_301C | VB2_307T)
327#define VB2_SISLCDABRIDGE (VB2_SISTMDSLCDABRIDGE | VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
328
329#define VB2_SISHIVISIONBRIDGE (VB2_301 | VB2_301B | VB2_302B)
330#define VB2_SISYPBPRBRIDGE (VB2_301C | VB2_307T | VB2_SISLVDSBRIDGE)
331#define VB2_SISYPBPRARBRIDGE (VB2_301C | VB2_307T | VB2_307LV)
332#define VB2_SISTAP4SCALER (VB2_301C | VB2_307T | VB2_302ELV | VB2_307LV)
333#define VB2_SISTVBRIDGE (VB2_SISHIVISIONBRIDGE | VB2_SISYPBPRBRIDGE)
334
335#define VB2_SISVGA2BRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
336
337#define VB2_VIDEOBRIDGE (VB2_SISBRIDGE | VB2_LVDS | VB2_CHRONTEL | VB2_CONEXANT)
338
339#define VB2_30xB (VB2_301B | VB2_301C | VB2_302B | VB2_307T)
340#define VB2_30xBLV (VB2_30xB | VB2_SISLVDSBRIDGE)
341#define VB2_30xC (VB2_301C | VB2_307T)
342#define VB2_30xCLV (VB2_301C | VB2_307T | VB2_302ELV| VB2_307LV)
343#define VB2_SISEMIBRIDGE (VB2_302LV | VB2_302ELV | VB2_307LV)
344#define VB2_LCD162MHZBRIDGE (VB2_301C | VB2_307T)
345#define VB2_LCDOVER1280BRIDGE (VB2_301C | VB2_307T | VB2_302LV | VB2_302ELV | VB2_307LV)
346#define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV)
347#define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T)
251 348
252/* I/O port access macros */ 349/* I/O port access macros */
253#define inSISREG(base) inb(base) 350#define inSISREG(base) inb(base)
254 351
255#define outSISREG(base,val) outb(val,base) 352#define outSISREG(base,val) outb(val,base)
256 353
257#define orSISREG(base,val) \ 354#define orSISREG(base,val) \
258 do { \ 355 do { \
259 u8 __Temp = inSISREG(base); \ 356 u8 __Temp = inSISREG(base); \
260 outSISREG(base, __Temp | (val)); \ 357 outSISREG(base, __Temp | (val));\
261 } while (0) 358 } while (0)
262 359
263#define andSISREG(base,val) \ 360#define andSISREG(base,val) \
264 do { \ 361 do { \
265 u8 __Temp = inSISREG(base); \ 362 u8 __Temp = inSISREG(base); \
266 outSISREG(base, __Temp & (val)); \ 363 outSISREG(base, __Temp & (val));\
267 } while (0) 364 } while (0)
268 365
269#define inSISIDXREG(base,idx,var) \ 366#define inSISIDXREG(base,idx,var) \
270 do { \ 367 do { \
271 outSISREG(base, idx); \ 368 outSISREG(base, idx); \
272 var = inSISREG((base)+1); \ 369 var = inSISREG((base)+1); \
273 } while (0) 370 } while (0)
274 371
275#define outSISIDXREG(base,idx,val) \ 372#define outSISIDXREG(base,idx,val) \
276 do { \ 373 do { \
277 outSISREG(base, idx); \ 374 outSISREG(base, idx); \
278 outSISREG((base)+1, val); \ 375 outSISREG((base)+1, val); \
279 } while (0) 376 } while (0)
280 377
281#define orSISIDXREG(base,idx,val) \ 378#define orSISIDXREG(base,idx,val) \
282 do { \ 379 do { \
283 u8 __Temp; \ 380 u8 __Temp; \
284 outSISREG(base, idx); \ 381 outSISREG(base, idx); \
285 __Temp = inSISREG((base)+1) | (val); \ 382 __Temp = inSISREG((base)+1) | (val); \
286 outSISREG((base)+1, __Temp); \ 383 outSISREG((base)+1, __Temp); \
287 } while (0) 384 } while (0)
288 385
289#define andSISIDXREG(base,idx,and) \ 386#define andSISIDXREG(base,idx,and) \
290 do { \ 387 do { \
291 u8 __Temp; \ 388 u8 __Temp; \
292 outSISREG(base, idx); \ 389 outSISREG(base, idx); \
293 __Temp = inSISREG((base)+1) & (and); \ 390 __Temp = inSISREG((base)+1) & (and); \
294 outSISREG((base)+1, __Temp); \ 391 outSISREG((base)+1, __Temp); \
295 } while (0) 392 } while (0)
296 393
297#define setSISIDXREG(base,idx,and,or) \ 394#define setSISIDXREG(base,idx,and,or) \
298 do { \ 395 do { \
299 u8 __Temp; \ 396 u8 __Temp; \
300 outSISREG(base, idx); \ 397 outSISREG(base, idx); \
301 __Temp = (inSISREG((base)+1) & (and)) | (or); \ 398 __Temp = (inSISREG((base)+1) & (and)) | (or); \
302 outSISREG((base)+1, __Temp); \ 399 outSISREG((base)+1, __Temp); \
303 } while (0) 400 } while (0)
304 401
305/* MMIO access macros */ 402/* MMIO access macros */
306#define MMIO_IN8(base, offset) readb((base+offset)) 403#define MMIO_IN8(base, offset) readb((base+offset))
@@ -322,19 +419,19 @@
322#define MMIO_QUEUE_READPORT Q_READ_PTR 419#define MMIO_QUEUE_READPORT Q_READ_PTR
323 420
324#ifndef FB_BLANK_UNBLANK 421#ifndef FB_BLANK_UNBLANK
325#define FB_BLANK_UNBLANK 0 422#define FB_BLANK_UNBLANK 0
326#endif 423#endif
327#ifndef FB_BLANK_NORMAL 424#ifndef FB_BLANK_NORMAL
328#define FB_BLANK_NORMAL 1 425#define FB_BLANK_NORMAL 1
329#endif 426#endif
330#ifndef FB_BLANK_VSYNC_SUSPEND 427#ifndef FB_BLANK_VSYNC_SUSPEND
331#define FB_BLANK_VSYNC_SUSPEND 2 428#define FB_BLANK_VSYNC_SUSPEND 2
332#endif 429#endif
333#ifndef FB_BLANK_HSYNC_SUSPEND 430#ifndef FB_BLANK_HSYNC_SUSPEND
334#define FB_BLANK_HSYNC_SUSPEND 3 431#define FB_BLANK_HSYNC_SUSPEND 3
335#endif 432#endif
336#ifndef FB_BLANK_POWERDOWN 433#ifndef FB_BLANK_POWERDOWN
337#define FB_BLANK_POWERDOWN 4 434#define FB_BLANK_POWERDOWN 4
338#endif 435#endif
339 436
340enum _SIS_LCD_TYPE { 437enum _SIS_LCD_TYPE {
@@ -347,18 +444,19 @@ enum _SIS_LCD_TYPE {
347 LCD_1600x1200, 444 LCD_1600x1200,
348 LCD_1920x1440, 445 LCD_1920x1440,
349 LCD_2048x1536, 446 LCD_2048x1536,
350 LCD_320x480, /* FSTN */ 447 LCD_320x240, /* FSTN */
351 LCD_1400x1050, 448 LCD_1400x1050,
352 LCD_1152x864, 449 LCD_1152x864,
353 LCD_1152x768, 450 LCD_1152x768,
354 LCD_1280x768, 451 LCD_1280x768,
355 LCD_1024x600, 452 LCD_1024x600,
356 LCD_640x480_2, /* DSTN */ 453 LCD_320x240_2, /* DSTN */
357 LCD_640x480_3, /* DSTN */ 454 LCD_320x240_3, /* DSTN */
358 LCD_848x480, 455 LCD_848x480,
359 LCD_1280x800, 456 LCD_1280x800,
360 LCD_1680x1050, 457 LCD_1680x1050,
361 LCD_1280x720, 458 LCD_1280x720,
459 LCD_1280x854,
362 LCD_CUSTOM, 460 LCD_CUSTOM,
363 LCD_UNKNOWN 461 LCD_UNKNOWN
364}; 462};
@@ -368,31 +466,50 @@ enum _SIS_CMDTYPE {
368 AGP_CMD_QUEUE, 466 AGP_CMD_QUEUE,
369 VM_CMD_QUEUE, 467 VM_CMD_QUEUE,
370}; 468};
371typedef unsigned int SIS_CMDTYPE; 469
470struct SIS_OH {
471 struct SIS_OH *poh_next;
472 struct SIS_OH *poh_prev;
473 u32 offset;
474 u32 size;
475};
476
477struct SIS_OHALLOC {
478 struct SIS_OHALLOC *poha_next;
479 struct SIS_OH aoh[1];
480};
481
482struct SIS_HEAP {
483 struct SIS_OH oh_free;
484 struct SIS_OH oh_used;
485 struct SIS_OH *poh_freelist;
486 struct SIS_OHALLOC *poha_chain;
487 u32 max_freesize;
488 struct sis_video_info *vinfo;
489};
372 490
373/* Our "par" */ 491/* Our "par" */
374struct sis_video_info { 492struct sis_video_info {
375 int cardnumber; 493 int cardnumber;
376 struct fb_info *memyselfandi; 494 struct fb_info *memyselfandi;
377 495
378 SIS_HW_INFO sishw_ext; 496 struct SiS_Private SiS_Pr;
379 SiS_Private SiS_Pr;
380 497
381 sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */ 498 struct sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
382 499
383 struct fb_var_screeninfo default_var; 500 struct fb_var_screeninfo default_var;
384 501
385#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 502#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
386 struct fb_fix_screeninfo sisfb_fix; 503 struct fb_fix_screeninfo sisfb_fix;
387 u32 pseudo_palette[17]; 504 u32 pseudo_palette[17];
388#endif 505#endif
389 506
390#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 507#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
391 struct display sis_disp; 508 struct display sis_disp;
392 struct display_switch sisfb_sw; 509 struct display_switch sisfb_sw;
393 struct { 510 struct {
394 u16 red, green, blue, pad; 511 u16 red, green, blue, pad;
395 } sis_palette[256]; 512 } sis_palette[256];
396 union { 513 union {
397#ifdef FBCON_HAS_CFB16 514#ifdef FBCON_HAS_CFB16
398 u16 cfb16[16]; 515 u16 cfb16[16];
@@ -400,10 +517,10 @@ struct sis_video_info {
400#ifdef FBCON_HAS_CFB32 517#ifdef FBCON_HAS_CFB32
401 u32 cfb32[16]; 518 u32 cfb32[16];
402#endif 519#endif
403 } sis_fbcon_cmap; 520 } sis_fbcon_cmap;
404#endif 521#endif
405 522
406 struct sisfb_monitor { 523 struct sisfb_monitor {
407 u16 hmin; 524 u16 hmin;
408 u16 hmax; 525 u16 hmax;
409 u16 vmin; 526 u16 vmin;
@@ -411,163 +528,166 @@ struct sis_video_info {
411 u32 dclockmax; 528 u32 dclockmax;
412 u8 feature; 529 u8 feature;
413 BOOLEAN datavalid; 530 BOOLEAN datavalid;
414 } sisfb_thismonitor; 531 } sisfb_thismonitor;
415 532
416 int chip_id; 533 unsigned short chip_id; /* PCI ID of chip */
534 unsigned short chip_vendor; /* PCI ID of vendor */
417 char myid[40]; 535 char myid[40];
418 536
419 struct pci_dev *nbridge; 537 struct pci_dev *nbridge;
538 struct pci_dev *lpcdev;
420 539
421 int mni; /* Mode number index */ 540 int mni; /* Mode number index */
422 541
423#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 542#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
424 int currcon; 543 int currcon;
425#endif 544#endif
426 545
427 unsigned long video_size; 546 unsigned long video_size;
428 unsigned long video_base; 547 unsigned long video_base;
429 unsigned long mmio_size; 548 unsigned long mmio_size;
430 unsigned long mmio_base; 549 unsigned long mmio_base;
431 unsigned long vga_base; 550 unsigned long vga_base;
551
552 unsigned long video_offset;
432 553
433 SIS_IOTYPE1 *video_vbase; 554 unsigned long UMAsize, LFBsize;
434 SIS_IOTYPE1 *mmio_vbase;
435 555
436 unsigned char *bios_abase; 556 SIS_IOTYPE1 *video_vbase;
557 SIS_IOTYPE1 *mmio_vbase;
437 558
438 int mtrr; 559 unsigned char *bios_abase;
560
561 int mtrr;
439 562
440 u32 sisfb_mem; 563 u32 sisfb_mem;
441 564
442 u32 sisfb_parm_mem; 565 u32 sisfb_parm_mem;
443 int sisfb_accel; 566 int sisfb_accel;
444 int sisfb_ypan; 567 int sisfb_ypan;
445 int sisfb_max; 568 int sisfb_max;
446 int sisfb_userom; 569 int sisfb_userom;
447 int sisfb_useoem; 570 int sisfb_useoem;
448 int sisfb_mode_idx; 571 int sisfb_mode_idx;
449 int sisfb_parm_rate; 572 int sisfb_parm_rate;
450 int sisfb_crt1off; 573 int sisfb_crt1off;
451 int sisfb_forcecrt1; 574 int sisfb_forcecrt1;
452 int sisfb_crt2type; 575 int sisfb_crt2type;
453 int sisfb_crt2flags; 576 int sisfb_crt2flags;
454 int sisfb_dstn; 577 int sisfb_dstn;
455 int sisfb_fstn; 578 int sisfb_fstn;
456 int sisfb_tvplug; 579 int sisfb_tvplug;
457 int sisfb_tvstd; 580 int sisfb_tvstd;
458 int sisfb_filter;
459 int sisfb_nocrt2rate; 581 int sisfb_nocrt2rate;
460#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 582#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
461 int sisfb_inverse; 583 int sisfb_inverse;
462#endif 584#endif
463 585
464 u32 heapstart; /* offset */ 586 u32 heapstart; /* offset */
465 SIS_IOTYPE1 *sisfb_heap_start; /* address */ 587 SIS_IOTYPE1 *sisfb_heap_start; /* address */
466 SIS_IOTYPE1 *sisfb_heap_end; /* address */ 588 SIS_IOTYPE1 *sisfb_heap_end; /* address */
467 u32 sisfb_heap_size; 589 u32 sisfb_heap_size;
468 int havenoheap; 590 int havenoheap;
469#if 0
470 SIS_HEAP sisfb_heap;
471#endif
472 591
592 struct SIS_HEAP sisfb_heap; /* This card's vram heap */
473 593
474 int video_bpp; 594 int video_bpp;
475 int video_cmap_len; 595 int video_cmap_len;
476 int video_width; 596 int video_width;
477 int video_height; 597 int video_height;
478 unsigned int refresh_rate; 598 unsigned int refresh_rate;
479 599
480 unsigned int chip; 600 unsigned int chip;
481 u8 revision_id; 601 u8 revision_id;
602 int sisvga_enabled; /* PCI device was enabled */
482 603
483 int video_linelength; /* real pitch */ 604 int video_linelength; /* real pitch */
484 int scrnpitchCRT1; /* pitch regarding interlace */ 605 int scrnpitchCRT1; /* pitch regarding interlace */
485 606
486 u16 DstColor; /* For 2d acceleration */ 607 u16 DstColor; /* For 2d acceleration */
487 u32 SiS310_AccelDepth; 608 u32 SiS310_AccelDepth;
488 u32 CommandReg; 609 u32 CommandReg;
489 int cmdqueuelength; 610 int cmdqueuelength; /* Current (for accel) */
611 u32 cmdQueueSize; /* Total size in KB */
490 612
491 spinlock_t lockaccel; /* Do not use outside of kernel! */ 613 spinlock_t lockaccel; /* Do not use outside of kernel! */
492 614
493 unsigned int pcibus; 615 unsigned int pcibus;
494 unsigned int pcislot; 616 unsigned int pcislot;
495 unsigned int pcifunc; 617 unsigned int pcifunc;
496 618
497 int accel; 619 int accel;
620 int engineok;
498 621
499 u16 subsysvendor; 622 u16 subsysvendor;
500 u16 subsysdevice; 623 u16 subsysdevice;
501 624
502 u32 vbflags; /* Replacing deprecated stuff from above */ 625 u32 vbflags; /* Replacing deprecated stuff from above */
503 u32 currentvbflags; 626 u32 currentvbflags;
627 u32 vbflags2;
504 628
505 int lcdxres, lcdyres; 629 int lcdxres, lcdyres;
506 int lcddefmodeidx, tvdefmodeidx, defmodeidx; 630 int lcddefmodeidx, tvdefmodeidx, defmodeidx;
507 u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */ 631 u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */
508 632 u32 curFSTN, curDSTN;
509 int current_bpp; 633
510 int current_width; 634 int current_bpp;
511 int current_height; 635 int current_width;
512 int current_htotal; 636 int current_height;
513 int current_vtotal; 637 int current_htotal;
638 int current_vtotal;
514 int current_linelength; 639 int current_linelength;
515 __u32 current_pixclock; 640 __u32 current_pixclock;
516 int current_refresh_rate; 641 int current_refresh_rate;
642
643 unsigned int current_base;
517 644
518 u8 mode_no; 645 u8 mode_no;
519 u8 rate_idx; 646 u8 rate_idx;
520 int modechanged; 647 int modechanged;
521 unsigned char modeprechange; 648 unsigned char modeprechange;
522 649
523#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 650#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
524 u8 sisfb_lastrates[128]; 651 u8 sisfb_lastrates[128];
525#endif 652#endif
526 653
527 int newrom; 654 int newrom;
528 int registered; 655 int haveXGIROM;
656 int registered;
529 int warncount; 657 int warncount;
658#ifdef SIS_OLD_CONFIG_COMPAT
659 int ioctl32registered;
660#endif
530 661
531 int sisvga_engine; 662 int sisvga_engine;
532 int hwcursor_size; 663 int hwcursor_size;
533 int CRT2_write_enable; 664 int CRT2_write_enable;
534 u8 caps; 665 u8 caps;
535 666
536 u8 detectedpdc; 667 u8 detectedpdc;
537 u8 detectedpdca; 668 u8 detectedpdca;
538 u8 detectedlcda; 669 u8 detectedlcda;
539 670
540 SIS_IOTYPE1 *hwcursor_vbase; 671 SIS_IOTYPE1 *hwcursor_vbase;
541 672
542 int chronteltype; 673 int chronteltype;
543 int tvxpos, tvypos; 674 int tvxpos, tvypos;
544 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02; 675 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
545 int tvx, tvy; 676 int tvx, tvy;
546 677
547 u8 sisfblocked; 678 u8 sisfblocked;
679
680 struct sisfb_info sisfb_infoblock;
681
682 struct sisfb_cmd sisfb_command;
683
684 u32 sisfb_id;
685
686 u8 sisfb_can_post;
687 u8 sisfb_card_posted;
688 u8 sisfb_was_boot_device;
548 689
549 struct sis_video_info *next; 690 struct sis_video_info *next;
550}; 691};
551 692
552typedef struct _SIS_OH {
553 struct _SIS_OH *poh_next;
554 struct _SIS_OH *poh_prev;
555 u32 offset;
556 u32 size;
557} SIS_OH;
558
559typedef struct _SIS_OHALLOC {
560 struct _SIS_OHALLOC *poha_next;
561 SIS_OH aoh[1];
562} SIS_OHALLOC;
563
564typedef struct _SIS_HEAP {
565 SIS_OH oh_free;
566 SIS_OH oh_used;
567 SIS_OH *poh_freelist;
568 SIS_OHALLOC *poha_chain;
569 u32 max_freesize;
570 struct sis_video_info *vinfo;
571} SIS_HEAP;
572
573#endif 693#endif
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index 30e90a553e80..bab933e6c6a6 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * SiS 300/630/730/540/315/550/65x/74x/330/760 frame buffer driver 2 * SiS 300/540/630[S]/730[S],
3 * for Linux kernels 2.4.x and 2.6.x 3 * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
4 * 6 *
5 * 2D acceleration part 7 * 2D acceleration part
6 * 8 *
@@ -19,7 +21,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20 * 22 *
21 * Based on the XFree86/X.org driver which is 23 * Based on the XFree86/X.org driver which is
22 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 24 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
23 * 25 *
24 * Author: Thomas Winischhofer <thomas@winischhofer.net> 26 * Author: Thomas Winischhofer <thomas@winischhofer.net>
25 * (see http://www.winischhofer.net/ 27 * (see http://www.winischhofer.net/
@@ -30,13 +32,11 @@
30#include <linux/version.h> 32#include <linux/version.h>
31#include <linux/module.h> 33#include <linux/module.h>
32#include <linux/kernel.h> 34#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/fb.h> 35#include <linux/fb.h>
36#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
35#include <linux/console.h> 37#include <linux/console.h>
36#include <linux/selection.h> 38#endif
37#include <linux/ioport.h> 39#include <linux/ioport.h>
38#include <linux/capability.h>
39#include <linux/fs.h>
40#include <linux/types.h> 40#include <linux/types.h>
41 41
42#include <asm/io.h> 42#include <asm/io.h>
@@ -188,7 +188,7 @@ SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
188} 188}
189#endif 189#endif
190 190
191/* 315/330 series ------------------------------------------------- */ 191/* 315/330/340 series ---------------------------------------------- */
192 192
193#ifdef CONFIG_FB_SIS_315 193#ifdef CONFIG_FB_SIS_315
194static void 194static void
@@ -202,7 +202,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
202{ 202{
203 SiS310SetupDSTColorDepth(ivideo->DstColor); 203 SiS310SetupDSTColorDepth(ivideo->DstColor);
204 SiS310SetupSRCPitch(ivideo->video_linelength) 204 SiS310SetupSRCPitch(ivideo->video_linelength)
205 SiS310SetupDSTRect(ivideo->video_linelength, 0xffff) 205 SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
206 if(trans_color != -1) { 206 if(trans_color != -1) {
207 SiS310SetupROP(0x0A) 207 SiS310SetupROP(0x0A)
208 SiS310SetupSRCTrans(trans_color) 208 SiS310SetupSRCTrans(trans_color)
@@ -213,7 +213,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
213 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */ 213 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
214 } 214 }
215 SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth) 215 SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
216 /* The 315 series is smart enough to know the direction */ 216 /* The chip is smart enough to know the direction */
217} 217}
218 218
219static void 219static void
@@ -223,35 +223,38 @@ SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int
223 u32 srcbase = 0, dstbase = 0; 223 u32 srcbase = 0, dstbase = 0;
224 int mymin = min(src_y, dst_y); 224 int mymin = min(src_y, dst_y);
225 int mymax = max(src_y, dst_y); 225 int mymax = max(src_y, dst_y);
226 226
227 /* Although the chip knows the direction to use 227 /* Although the chip knows the direction to use
228 * if the source and destination areas overlap, 228 * if the source and destination areas overlap,
229 * that logic fails if we fiddle with the bitmap 229 * that logic fails if we fiddle with the bitmap
230 * addresses. Therefore, we check if the source 230 * addresses. Therefore, we check if the source
231 * and destination blitting areas overlap and 231 * and destination blitting areas overlap and
232 * adapt the bitmap addresses synchronously 232 * adapt the bitmap addresses synchronously
233 * if the coordinates exceed the valid range. 233 * if the coordinates exceed the valid range.
234 * The the areas do not overlap, we do our 234 * The the areas do not overlap, we do our
235 * normal check. 235 * normal check.
236 */ 236 */
237 if((mymax - mymin) < height) { 237 if((mymax - mymin) < height) {
238 if((src_y >= 2048) || (dst_y >= 2048)) { 238 if((src_y >= 2048) || (dst_y >= 2048)) {
239 srcbase = ivideo->video_linelength * mymin; 239 srcbase = ivideo->video_linelength * mymin;
240 dstbase = ivideo->video_linelength * mymin; 240 dstbase = ivideo->video_linelength * mymin;
241 src_y -= mymin; 241 src_y -= mymin;
242 dst_y -= mymin; 242 dst_y -= mymin;
243 } 243 }
244 } else { 244 } else {
245 if(src_y >= 2048) { 245 if(src_y >= 2048) {
246 srcbase = ivideo->video_linelength * src_y; 246 srcbase = ivideo->video_linelength * src_y;
247 src_y = 0; 247 src_y = 0;
248 } 248 }
249 if(dst_y >= 2048) { 249 if(dst_y >= 2048) {
250 dstbase = ivideo->video_linelength * dst_y; 250 dstbase = ivideo->video_linelength * dst_y;
251 dst_y = 0; 251 dst_y = 0;
252 } 252 }
253 } 253 }
254 254
255 srcbase += ivideo->video_offset;
256 dstbase += ivideo->video_offset;
257
255 SiS310SetupSRCBase(srcbase); 258 SiS310SetupSRCBase(srcbase);
256 SiS310SetupDSTBase(dstbase); 259 SiS310SetupDSTBase(dstbase);
257 SiS310SetupRect(width, height) 260 SiS310SetupRect(width, height)
@@ -264,7 +267,7 @@ static void
264SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop) 267SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
265{ 268{
266 SiS310SetupPATFG(color) 269 SiS310SetupPATFG(color)
267 SiS310SetupDSTRect(ivideo->video_linelength, 0xffff) 270 SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
268 SiS310SetupDSTColorDepth(ivideo->DstColor); 271 SiS310SetupDSTColorDepth(ivideo->DstColor);
269 SiS310SetupROP(sisPatALUConv[rop]) 272 SiS310SetupROP(sisPatALUConv[rop])
270 SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth) 273 SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
@@ -279,6 +282,7 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
279 dstbase = ivideo->video_linelength * y; 282 dstbase = ivideo->video_linelength * y;
280 y = 0; 283 y = 0;
281 } 284 }
285 dstbase += ivideo->video_offset;
282 SiS310SetupDSTBase(dstbase) 286 SiS310SetupDSTBase(dstbase)
283 SiS310SetupDSTXY(x,y) 287 SiS310SetupDSTXY(x,y)
284 SiS310SetupRect(w,h) 288 SiS310SetupRect(w,h)
@@ -294,384 +298,153 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
294int sisfb_initaccel(struct sis_video_info *ivideo) 298int sisfb_initaccel(struct sis_video_info *ivideo)
295{ 299{
296#ifdef SISFB_USE_SPINLOCKS 300#ifdef SISFB_USE_SPINLOCKS
297 spin_lock_init(&ivideo->lockaccel); 301 spin_lock_init(&ivideo->lockaccel);
298#endif 302#endif
299 return(0); 303 return 0;
300} 304}
301 305
302void sisfb_syncaccel(struct sis_video_info *ivideo) 306void sisfb_syncaccel(struct sis_video_info *ivideo)
303{ 307{
304 if(ivideo->sisvga_engine == SIS_300_VGA) { 308 if(ivideo->sisvga_engine == SIS_300_VGA) {
305#ifdef CONFIG_FB_SIS_300 309#ifdef CONFIG_FB_SIS_300
306 SiS300Sync(ivideo); 310 SiS300Sync(ivideo);
307#endif 311#endif
308 } else { 312 } else {
309#ifdef CONFIG_FB_SIS_315 313#ifdef CONFIG_FB_SIS_315
310 SiS310Sync(ivideo); 314 SiS310Sync(ivideo);
311#endif 315#endif
312 } 316 }
313} 317}
314 318
315#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */ 319#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
316 320
317int fbcon_sis_sync(struct fb_info *info) 321int fbcon_sis_sync(struct fb_info *info)
318{ 322{
319 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 323 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
320 CRITFLAGS 324 CRITFLAGS
321 325
322 if(!ivideo->accel) 326 if((!ivideo->accel) || (!ivideo->engineok))
323 return 0; 327 return 0;
324 328
325 if(ivideo->sisvga_engine == SIS_300_VGA) { 329 CRITBEGIN
326#ifdef CONFIG_FB_SIS_300 330 sisfb_syncaccel(ivideo);
327 SiS300Sync(ivideo); 331 CRITEND
328#endif 332
329 } else { 333 return 0;
330#ifdef CONFIG_FB_SIS_315
331 SiS310Sync(ivideo);
332#endif
333 }
334 CRITEND
335 return 0;
336} 334}
337 335
338void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 336void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
339{ 337{
340 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 338 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
341 u32 col = 0; 339 u32 col = 0;
342 u32 vxres = info->var.xres_virtual; 340 u32 vxres = info->var.xres_virtual;
343 u32 vyres = info->var.yres_virtual; 341 u32 vyres = info->var.yres_virtual;
344 int width, height; 342 int width, height;
345 CRITFLAGS 343 CRITFLAGS
346 344
347 if(info->state != FBINFO_STATE_RUNNING) { 345 if(info->state != FBINFO_STATE_RUNNING)
348 return; 346 return;
349 } 347
350 348 if((!ivideo->accel) || (!ivideo->engineok)) {
351 if(!ivideo->accel) { 349 cfb_fillrect(info, rect);
352 cfb_fillrect(info, rect); 350 return;
353 return; 351 }
354 } 352
355 353 if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres)
356 if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) { 354 return;
357 return; 355
358 } 356 /* Clipping */
359 357 width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
360 /* Clipping */ 358 height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
361 width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width; 359
362 height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height; 360 switch(info->var.bits_per_pixel) {
363
364 switch(info->var.bits_per_pixel) {
365 case 8: col = rect->color; 361 case 8: col = rect->color;
366 break; 362 break;
367 case 16: 363 case 16:
368 case 32: col = ((u32 *)(info->pseudo_palette))[rect->color]; 364 case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
369 break; 365 break;
370 } 366 }
371 367
372 if(ivideo->sisvga_engine == SIS_300_VGA) { 368 if(ivideo->sisvga_engine == SIS_300_VGA) {
373#ifdef CONFIG_FB_SIS_300 369#ifdef CONFIG_FB_SIS_300
374 CRITBEGIN 370 CRITBEGIN
375 SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]); 371 SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
376 SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height); 372 SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
377 CRITEND 373 CRITEND
378 SiS300Sync(ivideo);
379#endif 374#endif
380 } else { 375 } else {
381#ifdef CONFIG_FB_SIS_315 376#ifdef CONFIG_FB_SIS_315
382 CRITBEGIN 377 CRITBEGIN
383 SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]); 378 SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
384 SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height); 379 SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
385 CRITEND 380 CRITEND
386 SiS310Sync(ivideo);
387#endif 381#endif
388 } 382 }
389 383
384 sisfb_syncaccel(ivideo);
390} 385}
391 386
392void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area) 387void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
393{ 388{
394 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 389 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
395 u32 vxres = info->var.xres_virtual; 390 u32 vxres = info->var.xres_virtual;
396 u32 vyres = info->var.yres_virtual; 391 u32 vyres = info->var.yres_virtual;
397 int width = area->width; 392 int width = area->width;
398 int height = area->height; 393 int height = area->height;
399 CRITFLAGS
400
401 if(info->state != FBINFO_STATE_RUNNING) {
402 return;
403 }
404
405 if(!ivideo->accel) {
406 cfb_copyarea(info, area);
407 return;
408 }
409
410 if(!width || !height ||
411 area->sx >= vxres || area->sy >= vyres ||
412 area->dx >= vxres || area->dy >= vyres) {
413 return;
414 }
415
416 /* Clipping */
417 if((area->sx + width) > vxres) width = vxres - area->sx;
418 if((area->dx + width) > vxres) width = vxres - area->dx;
419 if((area->sy + height) > vyres) height = vyres - area->sy;
420 if((area->dy + height) > vyres) height = vyres - area->dy;
421
422 if(ivideo->sisvga_engine == SIS_300_VGA) {
423#ifdef CONFIG_FB_SIS_300
424 int xdir, ydir;
425
426 if(area->sx < area->dx) xdir = 0;
427 else xdir = 1;
428 if(area->sy < area->dy) ydir = 0;
429 else ydir = 1;
430
431 CRITBEGIN
432 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
433 SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
434 width, height);
435 CRITEND
436 SiS300Sync(ivideo);
437#endif
438 } else {
439#ifdef CONFIG_FB_SIS_315
440 CRITBEGIN
441 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
442 SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
443 width, height);
444 CRITEND
445 SiS310Sync(ivideo);
446#endif
447 }
448}
449
450#endif
451
452#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
453
454void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
455 int dsty, int dstx, int height, int width)
456{
457 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
458
459 CRITFLAGS 394 CRITFLAGS
460 395
461 if(!ivideo->accel) { 396 if(info->state != FBINFO_STATE_RUNNING)
462 switch(ivideo->video_bpp) { 397 return;
463 case 8:
464#ifdef FBCON_HAS_CFB8
465 fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
466#endif
467 break;
468 case 16:
469#ifdef FBCON_HAS_CFB16
470 fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
471#endif
472 break;
473 case 32:
474#ifdef FBCON_HAS_CFB32
475 fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
476#endif
477 break;
478 }
479 return;
480 }
481
482 srcx *= fontwidth(p);
483 srcy *= fontheight(p);
484 dstx *= fontwidth(p);
485 dsty *= fontheight(p);
486 width *= fontwidth(p);
487 height *= fontheight(p);
488 398
489 if(ivideo->sisvga_engine == SIS_300_VGA) { 399 if((!ivideo->accel) || (!ivideo->engineok)) {
490#ifdef CONFIG_FB_SIS_300 400 cfb_copyarea(info, area);
491 int xdir, ydir; 401 return;
492
493 if(srcx < dstx) xdir = 0;
494 else xdir = 1;
495 if(srcy < dsty) ydir = 0;
496 else ydir = 1;
497
498 CRITBEGIN
499 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
500 SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
501 CRITEND
502 SiS300Sync(ivideo);
503#endif
504 } else {
505#ifdef CONFIG_FB_SIS_315
506 CRITBEGIN
507 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
508 SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
509 CRITEND
510 SiS310Sync(ivideo);
511#endif
512 } 402 }
513}
514 403
515static void fbcon_sis_clear(struct vc_data *conp, struct display *p, 404 if(!width || !height ||
516 int srcy, int srcx, int height, int width, int color) 405 area->sx >= vxres || area->sy >= vyres ||
517{ 406 area->dx >= vxres || area->dy >= vyres)
518 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par; 407 return;
519 CRITFLAGS
520 408
521 srcx *= fontwidth(p); 409 /* Clipping */
522 srcy *= fontheight(p); 410 if((area->sx + width) > vxres) width = vxres - area->sx;
523 width *= fontwidth(p); 411 if((area->dx + width) > vxres) width = vxres - area->dx;
524 height *= fontheight(p); 412 if((area->sy + height) > vyres) height = vyres - area->sy;
413 if((area->dy + height) > vyres) height = vyres - area->dy;
525 414
526 if(ivideo->sisvga_engine == SIS_300_VGA) { 415 if(ivideo->sisvga_engine == SIS_300_VGA) {
527#ifdef CONFIG_FB_SIS_300 416#ifdef CONFIG_FB_SIS_300
528 CRITBEGIN 417 int xdir, ydir;
529 SiS300SetupForSolidFill(ivideo, color, 3); 418
530 SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height); 419 if(area->sx < area->dx) xdir = 0;
531 CRITEND 420 else xdir = 1;
532 SiS300Sync(ivideo); 421 if(area->sy < area->dy) ydir = 0;
422 else ydir = 1;
423
424 CRITBEGIN
425 SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
426 SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
427 area->dx, area->dy, width, height);
428 CRITEND
533#endif 429#endif
534 } else { 430 } else {
535#ifdef CONFIG_FB_SIS_315 431#ifdef CONFIG_FB_SIS_315
536 CRITBEGIN 432 CRITBEGIN
537 SiS310SetupForSolidFill(ivideo, color, 3); 433 SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
538 SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height); 434 SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
539 CRITEND 435 area->dx, area->dy, width, height);
540 SiS310Sync(ivideo); 436 CRITEND
541#endif
542 }
543}
544
545void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
546 int srcy, int srcx, int height, int width)
547{
548 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
549 u32 bgx;
550
551 if(!ivideo->accel) {
552#ifdef FBCON_HAS_CFB8
553 fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
554#endif 437#endif
555 return;
556 } 438 }
557 439
558 bgx = attr_bgcol_ec(p, conp); 440 sisfb_syncaccel(ivideo);
559 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
560} 441}
561 442
562void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
563 int srcy, int srcx, int height, int width)
564{
565 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
566 u32 bgx;
567
568 if(!ivideo->accel) {
569#ifdef FBCON_HAS_CFB16
570 fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
571#endif 443#endif
572 return;
573 }
574
575 bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
576 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
577}
578 444
579void fbcon_sis_clear32(struct vc_data *conp, struct display *p, 445#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
580 int srcy, int srcx, int height, int width)
581{
582 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
583 u32 bgx;
584
585 if(!ivideo->accel) {
586#ifdef FBCON_HAS_CFB32
587 fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
588#endif
589 return;
590 }
591
592 bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
593 fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
594}
595
596void fbcon_sis_revc(struct display *p, int srcx, int srcy)
597{
598 struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
599 CRITFLAGS
600
601 if(!ivideo->accel) {
602 switch(ivideo->video_bpp) {
603 case 16:
604#ifdef FBCON_HAS_CFB16
605 fbcon_cfb16_revc(p, srcx, srcy);
606#endif
607 break;
608 case 32:
609#ifdef FBCON_HAS_CFB32
610 fbcon_cfb32_revc(p, srcx, srcy);
611#endif
612 break;
613 }
614 return;
615 }
616
617 srcx *= fontwidth(p);
618 srcy *= fontheight(p);
619
620 if(ivideo->sisvga_engine == SIS_300_VGA) {
621#ifdef CONFIG_FB_SIS_300
622 CRITBEGIN
623 SiS300SetupForSolidFill(ivideo, 0, 0x0a);
624 SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
625 CRITEND
626 SiS300Sync(ivideo);
627#endif
628 } else {
629#ifdef CONFIG_FB_SIS_315
630 CRITBEGIN
631 SiS310SetupForSolidFill(ivideo, 0, 0x0a);
632 SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
633 CRITEND
634 SiS310Sync(ivideo);
635#endif
636 }
637}
638 446
639#ifdef FBCON_HAS_CFB8 447#include "sisfb_accel_2_4.h"
640struct display_switch fbcon_sis8 = {
641 .setup = fbcon_cfb8_setup,
642 .bmove = fbcon_sis_bmove,
643 .clear = fbcon_sis_clear8,
644 .putc = fbcon_cfb8_putc,
645 .putcs = fbcon_cfb8_putcs,
646 .revc = fbcon_cfb8_revc,
647 .clear_margins = fbcon_cfb8_clear_margins,
648 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
649};
650#endif
651#ifdef FBCON_HAS_CFB16
652struct display_switch fbcon_sis16 = {
653 .setup = fbcon_cfb16_setup,
654 .bmove = fbcon_sis_bmove,
655 .clear = fbcon_sis_clear16,
656 .putc = fbcon_cfb16_putc,
657 .putcs = fbcon_cfb16_putcs,
658 .revc = fbcon_sis_revc,
659 .clear_margins = fbcon_cfb16_clear_margins,
660 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
661};
662#endif
663#ifdef FBCON_HAS_CFB32
664struct display_switch fbcon_sis32 = {
665 .setup = fbcon_cfb32_setup,
666 .bmove = fbcon_sis_bmove,
667 .clear = fbcon_sis_clear32,
668 .putc = fbcon_cfb32_putc,
669 .putcs = fbcon_cfb32_putcs,
670 .revc = fbcon_sis_revc,
671 .clear_margins = fbcon_cfb32_clear_margins,
672 .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
673};
674#endif
675 448
676#endif /* KERNEL VERSION */ 449#endif /* KERNEL VERSION */
677 450
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
index bb28f331d60d..046e2c4a8e09 100644
--- a/drivers/video/sis/sis_accel.h
+++ b/drivers/video/sis/sis_accel.h
@@ -1,6 +1,8 @@
1/* 1/*
2 * SiS 300/630/730/540/315/550/650/740 frame buffer driver 2 * SiS 300/540/630[S]/730[S],
3 * for Linux kernels 2.4.x and 2.5.x 3 * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
4 * XGI V3XT/V5/V8, Z7
5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
4 * 6 *
5 * 2D acceleration part 7 * 2D acceleration part
6 * 8 *
@@ -283,6 +285,8 @@
283 { \ 285 { \
284 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 286 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
285 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ 287 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
288 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
289 while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
286 CmdQueLen = 0; \ 290 CmdQueLen = 0; \
287 } 291 }
288 292
@@ -402,6 +406,7 @@ void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
402 int srcx, int height, int width); 406 int srcx, int height, int width);
403#endif 407#endif
404#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) 408#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
409int fbcon_sis_sync(struct fb_info *info);
405void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 410void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
406void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); 411void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
407#endif 412#endif
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 698266036819..42c54b69726e 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1,9 +1,10 @@
1/* 1/*
2 * SiS 300/305/540/630(S)/730(S) 2 * SiS 300/540/630[S]/730[S],
3 * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760 3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
4 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3 5 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
5 * 6 *
6 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria. 7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
7 * 8 *
8 * 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
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -19,11 +20,11 @@
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
21 * 22 *
22 * Author: Thomas Winischhofer <thomas@winischhofer.net> 23 * Author: Thomas Winischhofer <thomas@winischhofer.net>
23 * 24 *
24 * Author of (practically wiped) code base: 25 * Author of (practically wiped) code base:
25 * SiS (www.sis.com) 26 * SiS (www.sis.com)
26 * Copyright (C) 1999 Silicon Integrated Systems, Inc. 27 * Copyright (C) 1999 Silicon Integrated Systems, Inc.
27 * 28 *
28 * See http://www.winischhofer.net/ for more information and updates 29 * See http://www.winischhofer.net/ for more information and updates
29 * 30 *
@@ -46,16 +47,15 @@
46#include <linux/mm.h> 47#include <linux/mm.h>
47#include <linux/tty.h> 48#include <linux/tty.h>
48#include <linux/slab.h> 49#include <linux/slab.h>
49#include <linux/delay.h>
50#include <linux/fb.h> 50#include <linux/fb.h>
51#include <linux/console.h>
52#include <linux/selection.h> 51#include <linux/selection.h>
53#include <linux/smp_lock.h>
54#include <linux/ioport.h> 52#include <linux/ioport.h>
55#include <linux/init.h> 53#include <linux/init.h>
56#include <linux/pci.h> 54#include <linux/pci.h>
57#include <linux/vmalloc.h> 55#include <linux/vmalloc.h>
56#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
58#include <linux/vt_kern.h> 57#include <linux/vt_kern.h>
58#endif
59#include <linux/capability.h> 59#include <linux/capability.h>
60#include <linux/fs.h> 60#include <linux/fs.h>
61#include <linux/types.h> 61#include <linux/types.h>
@@ -94,71 +94,75 @@ extern struct display_switch fbcon_sis32;
94#endif 94#endif
95#endif 95#endif
96 96
97static void sisfb_handle_command(struct sis_video_info *ivideo,
98 struct sisfb_cmd *sisfb_command);
99
97/* ------------------ Internal helper routines ----------------- */ 100/* ------------------ Internal helper routines ----------------- */
98 101
99static void __init 102static void __init
100sisfb_setdefaultparms(void) 103sisfb_setdefaultparms(void)
101{ 104{
102 sisfb_off = 0; 105 sisfb_off = 0;
103 sisfb_parm_mem = 0; 106 sisfb_parm_mem = 0;
104 sisfb_accel = -1; 107 sisfb_accel = -1;
105 sisfb_ypan = -1; 108 sisfb_ypan = -1;
106 sisfb_max = -1; 109 sisfb_max = -1;
107 sisfb_userom = -1; 110 sisfb_userom = -1;
108 sisfb_useoem = -1; 111 sisfb_useoem = -1;
109#ifdef MODULE 112#ifdef MODULE
110 /* Module: "None" for 2.4, default mode for 2.5+ */ 113 /* Module: "None" for 2.4, default mode for 2.5+ */
111#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 114#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
112 sisfb_mode_idx = -1; 115 sisfb_mode_idx = -1;
113#else 116#else
114 sisfb_mode_idx = MODE_INDEX_NONE; 117 sisfb_mode_idx = MODE_INDEX_NONE;
115#endif 118#endif
116#else 119#else
117 /* Static: Default mode */ 120 /* Static: Default mode */
118 sisfb_mode_idx = -1; 121 sisfb_mode_idx = -1;
119#endif 122#endif
120 sisfb_parm_rate = -1; 123 sisfb_parm_rate = -1;
121 sisfb_crt1off = 0; 124 sisfb_crt1off = 0;
122 sisfb_forcecrt1 = -1; 125 sisfb_forcecrt1 = -1;
123 sisfb_crt2type = -1; 126 sisfb_crt2type = -1;
124 sisfb_crt2flags = 0; 127 sisfb_crt2flags = 0;
125 sisfb_pdc = 0xff; 128 sisfb_pdc = 0xff;
126 sisfb_pdca = 0xff; 129 sisfb_pdca = 0xff;
127 sisfb_scalelcd = -1; 130 sisfb_scalelcd = -1;
128 sisfb_specialtiming = CUT_NONE; 131 sisfb_specialtiming = CUT_NONE;
129 sisfb_lvdshl = -1; 132 sisfb_lvdshl = -1;
130 sisfb_dstn = 0; 133 sisfb_dstn = 0;
131 sisfb_fstn = 0; 134 sisfb_fstn = 0;
132 sisfb_tvplug = -1; 135 sisfb_tvplug = -1;
133 sisfb_tvstd = -1; 136 sisfb_tvstd = -1;
134 sisfb_tvxposoffset = 0; 137 sisfb_tvxposoffset = 0;
135 sisfb_tvyposoffset = 0; 138 sisfb_tvyposoffset = 0;
136 sisfb_filter = -1; 139 sisfb_nocrt2rate = 0;
137 sisfb_nocrt2rate = 0;
138#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 140#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
139 sisfb_inverse = 0; 141 sisfb_inverse = 0;
140 sisfb_fontname[0] = 0; 142 sisfb_fontname[0] = 0;
141#endif 143#endif
142#if !defined(__i386__) && !defined(__x86_64__) 144#if !defined(__i386__) && !defined(__x86_64__)
143 sisfb_resetcard = 0; 145 sisfb_resetcard = 0;
144 sisfb_videoram = 0; 146 sisfb_videoram = 0;
145#endif 147#endif
146} 148}
147 149
150/* ------------- Parameter parsing -------------- */
151
148static void __devinit 152static void __devinit
149sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet) 153sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
150{ 154{
151 int i = 0, j = 0; 155 int i = 0, j = 0;
152 156
153 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */ 157 /* We don't know the hardware specs yet and there is no ivideo */
154 158
155 if(vesamode == 0) { 159 if(vesamode == 0) {
156#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 160#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
157 sisfb_mode_idx = MODE_INDEX_NONE; 161 sisfb_mode_idx = MODE_INDEX_NONE;
158#else 162#else
159 if(!quiet) { 163 if(!quiet)
160 printk(KERN_ERR "sisfb: Invalid mode. Using default.\n"); 164 printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
161 } 165
162 sisfb_mode_idx = DEFAULT_MODE; 166 sisfb_mode_idx = DEFAULT_MODE;
163#endif 167#endif
164 return; 168 return;
@@ -169,95 +173,102 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
169 while(sisbios_mode[i++].mode_no[0] != 0) { 173 while(sisbios_mode[i++].mode_no[0] != 0) {
170 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) || 174 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
171 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) { 175 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
172 if(sisfb_fstn) { 176 if(sisfb_fstn) {
173 if(sisbios_mode[i-1].mode_no[1] == 0x50 || 177 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
174 sisbios_mode[i-1].mode_no[1] == 0x56 || 178 sisbios_mode[i-1].mode_no[1] == 0x56 ||
175 sisbios_mode[i-1].mode_no[1] == 0x53) continue; 179 sisbios_mode[i-1].mode_no[1] == 0x53)
176 } else { 180 continue;
177 if(sisbios_mode[i-1].mode_no[1] == 0x5a || 181 } else {
178 sisbios_mode[i-1].mode_no[1] == 0x5b) continue; 182 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
179 } 183 sisbios_mode[i-1].mode_no[1] == 0x5b)
180 sisfb_mode_idx = i - 1; 184 continue;
181 j = 1; 185 }
182 break; 186 sisfb_mode_idx = i - 1;
187 j = 1;
188 break;
183 } 189 }
184 } 190 }
185 if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode); 191 if((!j) && !quiet)
192 printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
186} 193}
187 194
188static void 195static void __devinit
189sisfb_search_mode(char *name, BOOLEAN quiet) 196sisfb_search_mode(char *name, BOOLEAN quiet)
190{ 197{
191 int i = 0;
192 unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0; 198 unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
199 int i = 0;
193 char strbuf[16], strbuf1[20]; 200 char strbuf[16], strbuf1[20];
194 char *nameptr = name; 201 char *nameptr = name;
195 202
196 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */ 203 /* We don't know the hardware specs yet and there is no ivideo */
197 204
198 if(name == NULL) { 205 if(name == NULL) {
199 if(!quiet) { 206 if(!quiet)
200 printk(KERN_ERR "sisfb: Internal error, using default mode.\n"); 207 printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
201 } 208
202 sisfb_mode_idx = DEFAULT_MODE; 209 sisfb_mode_idx = DEFAULT_MODE;
203 return; 210 return;
204 } 211 }
205 212
206#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 213#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
207 if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { 214 if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
208 if(!quiet) { 215 if(!quiet)
209 printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); 216 printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
210 } 217
211 sisfb_mode_idx = DEFAULT_MODE; 218 sisfb_mode_idx = DEFAULT_MODE;
212 return; 219 return;
213 } 220 }
214#endif 221#endif
215 if(strlen(name) <= 19) { 222 if(strlen(name) <= 19) {
216 strcpy(strbuf1, name); 223 strcpy(strbuf1, name);
217 for(i=0; i<strlen(strbuf1); i++) { 224 for(i = 0; i < strlen(strbuf1); i++) {
218 if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' '; 225 if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
219 } 226 }
220 227
221 /* This does some fuzzy mode naming detection */ 228 /* This does some fuzzy mode naming detection */
222 if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) { 229 if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
223 if((rate <= 32) || (depth > 32)) { 230 if((rate <= 32) || (depth > 32)) {
224 j = rate; rate = depth; depth = j; 231 j = rate; rate = depth; depth = j;
225 } 232 }
226 sprintf(strbuf, "%ux%ux%u", xres, yres, depth); 233 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
227 nameptr = strbuf; 234 nameptr = strbuf;
228 sisfb_parm_rate = rate; 235 sisfb_parm_rate = rate;
229 } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) { 236 } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
230 sprintf(strbuf, "%ux%ux%u", xres, yres, depth); 237 sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
231 nameptr = strbuf; 238 nameptr = strbuf;
232 } else { 239 } else {
233 xres = 0; 240 xres = 0;
234 if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) { 241 if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
235 sprintf(strbuf, "%ux%ux8", xres, yres); 242 sprintf(strbuf, "%ux%ux8", xres, yres);
236 nameptr = strbuf; 243 nameptr = strbuf;
237 } else { 244 } else {
238 sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet); 245 sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
239 return; 246 return;
240 } 247 }
241 } 248 }
242 } 249 }
243 250
244 i = 0; j = 0; 251 i = 0; j = 0;
245 while(sisbios_mode[i].mode_no[0] != 0) { 252 while(sisbios_mode[i].mode_no[0] != 0) {
246 if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { 253 if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
247 if(sisfb_fstn) { 254 if(sisfb_fstn) {
248 if(sisbios_mode[i-1].mode_no[1] == 0x50 || 255 if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
249 sisbios_mode[i-1].mode_no[1] == 0x56 || 256 sisbios_mode[i-1].mode_no[1] == 0x56 ||
250 sisbios_mode[i-1].mode_no[1] == 0x53) continue; 257 sisbios_mode[i-1].mode_no[1] == 0x53)
251 } else { 258 continue;
252 if(sisbios_mode[i-1].mode_no[1] == 0x5a || 259 } else {
253 sisbios_mode[i-1].mode_no[1] == 0x5b) continue; 260 if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
254 } 261 sisbios_mode[i-1].mode_no[1] == 0x5b)
255 sisfb_mode_idx = i - 1; 262 continue;
256 j = 1; 263 }
257 break; 264 sisfb_mode_idx = i - 1;
258 } 265 j = 1;
259 } 266 break;
260 if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr); 267 }
268 }
269
270 if((!j) && !quiet)
271 printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
261} 272}
262 273
263#ifndef MODULE 274#ifndef MODULE
@@ -265,7 +276,7 @@ static void __devinit
265sisfb_get_vga_mode_from_kernel(void) 276sisfb_get_vga_mode_from_kernel(void)
266{ 277{
267#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT) 278#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
268 char mymode[32]; 279 char mymode[32];
269 int mydepth = screen_info.lfb_depth; 280 int mydepth = screen_info.lfb_depth;
270 281
271 if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return; 282 if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
@@ -274,15 +285,17 @@ sisfb_get_vga_mode_from_kernel(void)
274 (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) && 285 (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
275 (mydepth >= 8) && (mydepth <= 32) ) { 286 (mydepth >= 8) && (mydepth <= 32) ) {
276 287
277 if(mydepth == 24) mydepth = 32; 288 if(mydepth == 24) mydepth = 32;
278 289
279 sprintf(mymode, "%ux%ux%u", screen_info.lfb_width, 290 sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
280 screen_info.lfb_height, 291 screen_info.lfb_height,
281 mydepth); 292 mydepth);
282 293
283 printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode); 294 printk(KERN_DEBUG
295 "sisfb: Using vga mode %s pre-set by kernel as default\n",
296 mymode);
284 297
285 sisfb_search_mode(mymode, TRUE); 298 sisfb_search_mode(mymode, TRUE);
286 } 299 }
287#endif 300#endif
288 return; 301 return;
@@ -294,26 +307,25 @@ sisfb_search_crt2type(const char *name)
294{ 307{
295 int i = 0; 308 int i = 0;
296 309
297 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */ 310 /* We don't know the hardware specs yet and there is no ivideo */
298 311
299 if(name == NULL) return; 312 if(name == NULL) return;
300 313
301 while(sis_crt2type[i].type_no != -1) { 314 while(sis_crt2type[i].type_no != -1) {
302 if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { 315 if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
303 sisfb_crt2type = sis_crt2type[i].type_no; 316 sisfb_crt2type = sis_crt2type[i].type_no;
304 sisfb_tvplug = sis_crt2type[i].tvplug_no; 317 sisfb_tvplug = sis_crt2type[i].tvplug_no;
305 sisfb_crt2flags = sis_crt2type[i].flags; 318 sisfb_crt2flags = sis_crt2type[i].flags;
306 break; 319 break;
307 } 320 }
308 i++; 321 i++;
309 } 322 }
310 323
311 sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0; 324 sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
312 sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0; 325 sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
313 326
314 if(sisfb_crt2type < 0) { 327 if(sisfb_crt2type < 0)
315 printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name); 328 printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
316 }
317} 329}
318 330
319static void __init 331static void __init
@@ -321,16 +333,17 @@ sisfb_search_tvstd(const char *name)
321{ 333{
322 int i = 0; 334 int i = 0;
323 335
324 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */ 336 /* We don't know the hardware specs yet and there is no ivideo */
325 337
326 if(name == NULL) return; 338 if(name == NULL)
339 return;
327 340
328 while(sis_tvtype[i].type_no != -1) { 341 while(sis_tvtype[i].type_no != -1) {
329 if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { 342 if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
330 sisfb_tvstd = sis_tvtype[i].type_no; 343 sisfb_tvstd = sis_tvtype[i].type_no;
331 break; 344 break;
332 } 345 }
333 i++; 346 i++;
334 } 347 }
335} 348}
336 349
@@ -340,38 +353,101 @@ sisfb_search_specialtiming(const char *name)
340 int i = 0; 353 int i = 0;
341 BOOLEAN found = FALSE; 354 BOOLEAN found = FALSE;
342 355
343 /* BEWARE: We don't know the hardware specs yet and there is no ivideo */ 356 /* We don't know the hardware specs yet and there is no ivideo */
344 357
345 if(name == NULL) return; 358 if(name == NULL)
359 return;
346 360
347 if(!strnicmp(name, "none", 4)) { 361 if(!strnicmp(name, "none", 4)) {
348 sisfb_specialtiming = CUT_FORCENONE; 362 sisfb_specialtiming = CUT_FORCENONE;
349 printk(KERN_DEBUG "sisfb: Special timing disabled\n"); 363 printk(KERN_DEBUG "sisfb: Special timing disabled\n");
350 } else { 364 } else {
351 while(mycustomttable[i].chipID != 0) { 365 while(mycustomttable[i].chipID != 0) {
352 if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) { 366 if(!strnicmp(name,mycustomttable[i].optionName,
353 sisfb_specialtiming = mycustomttable[i].SpecialID; 367 strlen(mycustomttable[i].optionName))) {
354 found = TRUE; 368 sisfb_specialtiming = mycustomttable[i].SpecialID;
355 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n", 369 found = TRUE;
356 mycustomttable[i].vendorName, mycustomttable[i].cardName, 370 printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
357 mycustomttable[i].optionName); 371 mycustomttable[i].vendorName,
358 break; 372 mycustomttable[i].cardName,
359 } 373 mycustomttable[i].optionName);
360 i++; 374 break;
361 } 375 }
362 if(!found) { 376 i++;
363 printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:"); 377 }
364 printk(KERN_WARNING "\t\"none\" (to disable special timings)\n"); 378 if(!found) {
365 i = 0; 379 printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
366 while(mycustomttable[i].chipID != 0) { 380 printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
367 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n", 381 i = 0;
368 mycustomttable[i].optionName, 382 while(mycustomttable[i].chipID != 0) {
369 mycustomttable[i].vendorName, 383 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
370 mycustomttable[i].cardName); 384 mycustomttable[i].optionName,
371 i++; 385 mycustomttable[i].vendorName,
372 } 386 mycustomttable[i].cardName);
373 } 387 i++;
374 } 388 }
389 }
390 }
391}
392
393/* ----------- Various detection routines ----------- */
394
395static void __devinit
396sisfb_detect_custom_timing(struct sis_video_info *ivideo)
397{
398 unsigned char *biosver = NULL;
399 unsigned char *biosdate = NULL;
400 BOOLEAN footprint;
401 u32 chksum = 0;
402 int i, j;
403
404 if(ivideo->SiS_Pr.UseROM) {
405 biosver = ivideo->SiS_Pr.VirtualRomBase + 0x06;
406 biosdate = ivideo->SiS_Pr.VirtualRomBase + 0x2c;
407 for(i = 0; i < 32768; i++)
408 chksum += ivideo->SiS_Pr.VirtualRomBase[i];
409 }
410
411 i = 0;
412 do {
413 if( (mycustomttable[i].chipID == ivideo->chip) &&
414 ((!strlen(mycustomttable[i].biosversion)) ||
415 (ivideo->SiS_Pr.UseROM &&
416 (!strncmp(mycustomttable[i].biosversion, biosver,
417 strlen(mycustomttable[i].biosversion))))) &&
418 ((!strlen(mycustomttable[i].biosdate)) ||
419 (ivideo->SiS_Pr.UseROM &&
420 (!strncmp(mycustomttable[i].biosdate, biosdate,
421 strlen(mycustomttable[i].biosdate))))) &&
422 ((!mycustomttable[i].bioschksum) ||
423 (ivideo->SiS_Pr.UseROM &&
424 (mycustomttable[i].bioschksum == chksum))) &&
425 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
426 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
427 footprint = TRUE;
428 for(j = 0; j < 5; j++) {
429 if(mycustomttable[i].biosFootprintAddr[j]) {
430 if(ivideo->SiS_Pr.UseROM) {
431 if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
432 mycustomttable[i].biosFootprintData[j]) {
433 footprint = FALSE;
434 }
435 } else
436 footprint = FALSE;
437 }
438 }
439 if(footprint) {
440 ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
441 printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
442 mycustomttable[i].vendorName,
443 mycustomttable[i].cardName);
444 printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
445 mycustomttable[i].optionName);
446 break;
447 }
448 }
449 i++;
450 } while(mycustomttable[i].chipID);
375} 451}
376 452
377static BOOLEAN __devinit 453static BOOLEAN __devinit
@@ -384,22 +460,23 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
384 buffer[2] != 0xff || buffer[3] != 0xff || 460 buffer[2] != 0xff || buffer[3] != 0xff ||
385 buffer[4] != 0xff || buffer[5] != 0xff || 461 buffer[4] != 0xff || buffer[5] != 0xff ||
386 buffer[6] != 0xff || buffer[7] != 0x00) { 462 buffer[6] != 0xff || buffer[7] != 0x00) {
387 printk(KERN_DEBUG "sisfb: Bad EDID header\n"); 463 printk(KERN_DEBUG "sisfb: Bad EDID header\n");
388 return FALSE; 464 return FALSE;
389 } 465 }
390 466
391 if(buffer[0x12] != 0x01) { 467 if(buffer[0x12] != 0x01) {
392 printk(KERN_INFO "sisfb: EDID version %d not supported\n", 468 printk(KERN_INFO "sisfb: EDID version %d not supported\n",
393 buffer[0x12]); 469 buffer[0x12]);
394 return FALSE; 470 return FALSE;
395 } 471 }
396 472
397 monitor->feature = buffer[0x18]; 473 monitor->feature = buffer[0x18];
398 474
399 if(!buffer[0x14] & 0x80) { 475 if(!buffer[0x14] & 0x80) {
400 if(!(buffer[0x14] & 0x08)) { 476 if(!(buffer[0x14] & 0x08)) {
401 printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n"); 477 printk(KERN_INFO
402 } 478 "sisfb: WARNING: Monitor does not support separate syncs\n");
479 }
403 } 480 }
404 481
405 if(buffer[0x13] >= 0x01) { 482 if(buffer[0x13] >= 0x01) {
@@ -409,7 +486,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
409 j = 0x36; 486 j = 0x36;
410 for(i=0; i<4; i++) { 487 for(i=0; i<4; i++) {
411 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 && 488 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
412 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd && 489 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
413 buffer[j + 4] == 0x00) { 490 buffer[j + 4] == 0x00) {
414 monitor->hmin = buffer[j + 7]; 491 monitor->hmin = buffer[j + 7];
415 monitor->hmax = buffer[j + 8]; 492 monitor->hmax = buffer[j + 8];
@@ -435,7 +512,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
435 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16); 512 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
436 for(i = 0; i < 13; i++) { 513 for(i = 0; i < 13; i++) {
437 if(emodes & sisfb_ddcsmodes[i].mask) { 514 if(emodes & sisfb_ddcsmodes[i].mask) {
438 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h; 515 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
439 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1; 516 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
440 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v; 517 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
441 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v; 518 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
@@ -446,80 +523,81 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
446 for(i = 0; i < 8; i++) { 523 for(i = 0; i < 8; i++) {
447 xres = (buffer[index] + 31) * 8; 524 xres = (buffer[index] + 31) * 8;
448 switch(buffer[index + 1] & 0xc0) { 525 switch(buffer[index + 1] & 0xc0) {
449 case 0xc0: yres = (xres * 9) / 16; break; 526 case 0xc0: yres = (xres * 9) / 16; break;
450 case 0x80: yres = (xres * 4) / 5; break; 527 case 0x80: yres = (xres * 4) / 5; break;
451 case 0x40: yres = (xres * 3) / 4; break; 528 case 0x40: yres = (xres * 3) / 4; break;
452 default: yres = xres; break; 529 default: yres = xres; break;
453 } 530 }
454 refresh = (buffer[index + 1] & 0x3f) + 60; 531 refresh = (buffer[index + 1] & 0x3f) + 60;
455 if((xres >= 640) && (yres >= 480)) { 532 if((xres >= 640) && (yres >= 480)) {
456 for(j = 0; j < 8; j++) { 533 for(j = 0; j < 8; j++) {
457 if((xres == sisfb_ddcfmodes[j].x) && 534 if((xres == sisfb_ddcfmodes[j].x) &&
458 (yres == sisfb_ddcfmodes[j].y) && 535 (yres == sisfb_ddcfmodes[j].y) &&
459 (refresh == sisfb_ddcfmodes[j].v)) { 536 (refresh == sisfb_ddcfmodes[j].v)) {
460 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h; 537 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
461 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1; 538 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
462 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v; 539 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
463 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v; 540 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
464 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d; 541 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[j].d;
465 } 542 }
466 } 543 }
467 } 544 }
468 index += 2; 545 index += 2;
469 } 546 }
470 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) { 547 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
471 monitor->datavalid = TRUE; 548 monitor->datavalid = TRUE;
472 } 549 }
473 } 550 }
474 551
475 return(monitor->datavalid); 552 return monitor->datavalid;
476} 553}
477 554
478static void __devinit 555static void __devinit
479sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno) 556sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
480{ 557{
481 USHORT temp, i, realcrtno = crtno; 558 unsigned short temp, i, realcrtno = crtno;
482 u8 buffer[256]; 559 unsigned char buffer[256];
483 560
484 monitor->datavalid = FALSE; 561 monitor->datavalid = FALSE;
485 562
486 if(crtno) { 563 if(crtno) {
487 if(ivideo->vbflags & CRT2_LCD) realcrtno = 1; 564 if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
488 else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2; 565 else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
489 else return; 566 else return;
490 } 567 }
491 568
492 if((ivideo->sisfb_crt1off) && (!crtno)) return; 569 if((ivideo->sisfb_crt1off) && (!crtno))
570 return;
493 571
494 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 572 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
495 realcrtno, 0, &buffer[0]); 573 realcrtno, 0, &buffer[0], ivideo->vbflags2);
496 if((!temp) || (temp == 0xffff)) { 574 if((!temp) || (temp == 0xffff)) {
497 printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1); 575 printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
498 return; 576 return;
499 } else { 577 } else {
500 printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1); 578 printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
501 printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n", 579 printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
502 crtno + 1, 580 crtno + 1,
503 (temp & 0x1a) ? "" : "[none of the supported]", 581 (temp & 0x1a) ? "" : "[none of the supported]",
504 (temp & 0x02) ? "2 " : "", 582 (temp & 0x02) ? "2 " : "",
505 (temp & 0x08) ? "D&P" : "", 583 (temp & 0x08) ? "D&P" : "",
506 (temp & 0x10) ? "FPDI-2" : ""); 584 (temp & 0x10) ? "FPDI-2" : "");
507 if(temp & 0x02) { 585 if(temp & 0x02) {
508 i = 3; /* Number of retrys */ 586 i = 3; /* Number of retrys */
509 do { 587 do {
510 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 588 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
511 realcrtno, 1, &buffer[0]); 589 realcrtno, 1, &buffer[0], ivideo->vbflags2);
512 } while((temp) && i--); 590 } while((temp) && i--);
513 if(!temp) { 591 if(!temp) {
514 if(sisfb_interpret_edid(monitor, &buffer[0])) { 592 if(sisfb_interpret_edid(monitor, &buffer[0])) {
515 printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n", 593 printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
516 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax, 594 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
517 monitor->dclockmax / 1000); 595 monitor->dclockmax / 1000);
518 } else { 596 } else {
519 printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1); 597 printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
520 } 598 }
521 } else { 599 } else {
522 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1); 600 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
523 } 601 }
524 } else { 602 } else {
525 printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n"); 603 printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
@@ -527,6 +605,8 @@ sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, i
527 } 605 }
528} 606}
529 607
608/* -------------- Mode validation --------------- */
609
530static BOOLEAN 610static BOOLEAN
531sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, 611sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
532 int mode_idx, int rate_idx, int rate) 612 int mode_idx, int rate_idx, int rate)
@@ -534,42 +614,49 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
534 int htotal, vtotal; 614 int htotal, vtotal;
535 unsigned int dclock, hsync; 615 unsigned int dclock, hsync;
536 616
537 if(!monitor->datavalid) return TRUE; 617 if(!monitor->datavalid)
618 return TRUE;
538 619
539 if(mode_idx < 0) return FALSE; 620 if(mode_idx < 0)
621 return FALSE;
540 622
541 /* Skip for 320x200, 320x240, 640x400 */ 623 /* Skip for 320x200, 320x240, 640x400 */
542 switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) { 624 switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
543 case 0x59: 625 case 0x59:
544 case 0x41: 626 case 0x41:
545 case 0x4f: 627 case 0x4f:
546 case 0x50: 628 case 0x50:
547 case 0x56: 629 case 0x56:
548 case 0x53: 630 case 0x53:
549 case 0x2f: 631 case 0x2f:
550 case 0x5d: 632 case 0x5d:
551 case 0x5e: 633 case 0x5e:
552 return TRUE; 634 return TRUE;
553#ifdef CONFIG_FB_SIS_315 635#ifdef CONFIG_FB_SIS_315
554 case 0x5a: 636 case 0x5a:
555 case 0x5b: 637 case 0x5b:
556 if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE; 638 if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
557#endif 639#endif
558 } 640 }
559 641
560 if(rate < (monitor->vmin - 1)) return FALSE; 642 if(rate < (monitor->vmin - 1))
561 if(rate > (monitor->vmax + 1)) return FALSE; 643 return FALSE;
644 if(rate > (monitor->vmax + 1))
645 return FALSE;
562 646
563 if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext, 647 if(sisfb_gettotalfrommode(&ivideo->SiS_Pr,
564 sisbios_mode[mode_idx].mode_no[ivideo->mni], 648 sisbios_mode[mode_idx].mode_no[ivideo->mni],
565 &htotal, &vtotal, rate_idx)) { 649 &htotal, &vtotal, rate_idx)) {
566 dclock = (htotal * vtotal * rate) / 1000; 650 dclock = (htotal * vtotal * rate) / 1000;
567 if(dclock > (monitor->dclockmax + 1000)) return FALSE; 651 if(dclock > (monitor->dclockmax + 1000))
652 return FALSE;
568 hsync = dclock / htotal; 653 hsync = dclock / htotal;
569 if(hsync < (monitor->hmin - 1)) return FALSE; 654 if(hsync < (monitor->hmin - 1))
570 if(hsync > (monitor->hmax + 1)) return FALSE; 655 return FALSE;
656 if(hsync > (monitor->hmax + 1))
657 return FALSE;
571 } else { 658 } else {
572 return FALSE; 659 return FALSE;
573 } 660 }
574 return TRUE; 661 return TRUE;
575} 662}
@@ -577,82 +664,79 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
577static int 664static int
578sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags) 665sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
579{ 666{
580 u16 xres=0, yres, myres; 667 u16 xres=0, yres, myres;
581 668
582#ifdef CONFIG_FB_SIS_300 669#ifdef CONFIG_FB_SIS_300
583 if(ivideo->sisvga_engine == SIS_300_VGA) { 670 if(ivideo->sisvga_engine == SIS_300_VGA) {
584 if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1); 671 if(!(sisbios_mode[myindex].chipset & MD_SIS300))
585 } 672 return -1 ;
673 }
586#endif 674#endif
587#ifdef CONFIG_FB_SIS_315 675#ifdef CONFIG_FB_SIS_315
588 if(ivideo->sisvga_engine == SIS_315_VGA) { 676 if(ivideo->sisvga_engine == SIS_315_VGA) {
589 if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1); 677 if(!(sisbios_mode[myindex].chipset & MD_SIS315))
590 } 678 return -1;
679 }
591#endif 680#endif
592 681
593 myres = sisbios_mode[myindex].yres; 682 myres = sisbios_mode[myindex].yres;
594
595 switch(vbflags & VB_DISPTYPE_DISP2) {
596 683
597 case CRT2_LCD: 684 switch(vbflags & VB_DISPTYPE_DISP2) {
598 685
599 xres = ivideo->lcdxres; yres = ivideo->lcdyres; 686 case CRT2_LCD:
687 xres = ivideo->lcdxres; yres = ivideo->lcdyres;
600 688
601 if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) { 689 if((ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) &&
602 if(sisbios_mode[myindex].xres > xres) return(-1); 690 (ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL856)) {
603 if(myres > yres) return(-1); 691 if(sisbios_mode[myindex].xres > xres)
604 } 692 return -1;
693 if(myres > yres)
694 return -1;
695 }
605 696
606 if(vbflags & (VB_LVDS | VB_30xBDH)) { 697 if(ivideo->sisfb_fstn) {
607 if(sisbios_mode[myindex].xres == 320) { 698 if(sisbios_mode[myindex].xres == 320) {
608 if((myres == 240) || (myres == 480)) { 699 if(myres == 240) {
609 if(!ivideo->sisfb_fstn) { 700 switch(sisbios_mode[myindex].mode_no[1]) {
610 if(sisbios_mode[myindex].mode_no[1] == 0x5a || 701 case 0x50: myindex = MODE_FSTN_8; break;
611 sisbios_mode[myindex].mode_no[1] == 0x5b) 702 case 0x56: myindex = MODE_FSTN_16; break;
612 return(-1); 703 case 0x53: return -1;
613 } else { 704 }
614 if(sisbios_mode[myindex].mode_no[1] == 0x50 || 705 }
615 sisbios_mode[myindex].mode_no[1] == 0x56 || 706 }
616 sisbios_mode[myindex].mode_no[1] == 0x53) 707 }
617 return(-1);
618 }
619 }
620 }
621 }
622 708
623 if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 709 if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
624 sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn, 710 sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
625 ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) { 711 ivideo->SiS_Pr.SiS_CustomT, xres, yres, ivideo->vbflags2) < 0x14) {
626 return(-1); 712 return -1;
627 } 713 }
628 break; 714 break;
629 715
630 case CRT2_TV: 716 case CRT2_TV:
631 if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 717 if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
632 sisbios_mode[myindex].yres, 0) < 0x14) { 718 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
633 return(-1); 719 return -1;
634 } 720 }
635 break; 721 break;
636 722
637 case CRT2_VGA: 723 case CRT2_VGA:
638 if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres, 724 if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
639 sisbios_mode[myindex].yres, 0) < 0x14) { 725 sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
640 return(-1); 726 return -1;
727 }
728 break;
641 } 729 }
642 break;
643 }
644 730
645 return(myindex); 731 return myindex;
646} 732}
647 733
648static u8 734static u8
649sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx) 735sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
650{ 736{
651 u16 xres, yres;
652 int i = 0; 737 int i = 0;
653 738 u16 xres = sisbios_mode[mode_idx].xres;
654 xres = sisbios_mode[mode_idx].xres; 739 u16 yres = sisbios_mode[mode_idx].yres;
655 yres = sisbios_mode[mode_idx].yres;
656 740
657 ivideo->rate_idx = 0; 741 ivideo->rate_idx = 0;
658 while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) { 742 while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
@@ -672,14 +756,14 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
672 rate, sisfb_vrate[i-1].refresh); 756 rate, sisfb_vrate[i-1].refresh);
673 ivideo->rate_idx = sisfb_vrate[i-1].idx; 757 ivideo->rate_idx = sisfb_vrate[i-1].idx;
674 ivideo->refresh_rate = sisfb_vrate[i-1].refresh; 758 ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
675 } 759 }
676 break; 760 break;
677 } else if((rate - sisfb_vrate[i].refresh) <= 2) { 761 } else if((rate - sisfb_vrate[i].refresh) <= 2) {
678 DPRINTK("sisfb: Adjusting rate from %d down to %d\n", 762 DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
679 rate, sisfb_vrate[i].refresh); 763 rate, sisfb_vrate[i].refresh);
680 ivideo->rate_idx = sisfb_vrate[i].idx; 764 ivideo->rate_idx = sisfb_vrate[i].idx;
681 break; 765 break;
682 } 766 }
683 } 767 }
684 i++; 768 i++;
685 } 769 }
@@ -695,252 +779,321 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
695static BOOLEAN 779static BOOLEAN
696sisfb_bridgeisslave(struct sis_video_info *ivideo) 780sisfb_bridgeisslave(struct sis_video_info *ivideo)
697{ 781{
698 unsigned char P1_00; 782 unsigned char P1_00;
699 783
700 if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE; 784 if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE))
785 return FALSE;
701 786
702 inSISIDXREG(SISPART1,0x00,P1_00); 787 inSISIDXREG(SISPART1,0x00,P1_00);
703 if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) || 788 if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
704 ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) { 789 ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
705 return TRUE; 790 return TRUE;
706 } else { 791 } else {
707 return FALSE; 792 return FALSE;
708 } 793 }
709} 794}
710 795
711static BOOLEAN 796static BOOLEAN
712sisfballowretracecrt1(struct sis_video_info *ivideo) 797sisfballowretracecrt1(struct sis_video_info *ivideo)
713{ 798{
714 u8 temp; 799 u8 temp;
715 800
716 inSISIDXREG(SISCR,0x17,temp); 801 inSISIDXREG(SISCR,0x17,temp);
717 if(!(temp & 0x80)) return FALSE; 802 if(!(temp & 0x80))
803 return FALSE;
718 804
719 inSISIDXREG(SISSR,0x1f,temp); 805 inSISIDXREG(SISSR,0x1f,temp);
720 if(temp & 0xc0) return FALSE; 806 if(temp & 0xc0)
807 return FALSE;
721 808
722 return TRUE; 809 return TRUE;
723} 810}
724 811
725static BOOLEAN 812static BOOLEAN
726sisfbcheckvretracecrt1(struct sis_video_info *ivideo) 813sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
727{ 814{
728 if(!sisfballowretracecrt1(ivideo)) return FALSE; 815 if(!sisfballowretracecrt1(ivideo))
816 return FALSE;
729 817
730 if(inSISREG(SISINPSTAT) & 0x08) return TRUE; 818 if(inSISREG(SISINPSTAT) & 0x08)
731 else return FALSE; 819 return TRUE;
820 else
821 return FALSE;
732} 822}
733 823
734static void 824static void
735sisfbwaitretracecrt1(struct sis_video_info *ivideo) 825sisfbwaitretracecrt1(struct sis_video_info *ivideo)
736{ 826{
737 int watchdog; 827 int watchdog;
738 828
739 if(!sisfballowretracecrt1(ivideo)) return; 829 if(!sisfballowretracecrt1(ivideo))
830 return;
740 831
741 watchdog = 65536; 832 watchdog = 65536;
742 while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog); 833 while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
743 watchdog = 65536; 834 watchdog = 65536;
744 while((inSISREG(SISINPSTAT) & 0x08) && --watchdog); 835 while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
745} 836}
746 837
747static BOOLEAN 838static BOOLEAN
748sisfbcheckvretracecrt2(struct sis_video_info *ivideo) 839sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
749{ 840{
750 unsigned char temp, reg; 841 unsigned char temp, reg;
751 842
752 switch(ivideo->sisvga_engine) { 843 switch(ivideo->sisvga_engine) {
753 case SIS_300_VGA: reg = 0x25; break; 844 case SIS_300_VGA: reg = 0x25; break;
754 case SIS_315_VGA: reg = 0x30; break; 845 case SIS_315_VGA: reg = 0x30; break;
755 default: return FALSE; 846 default: return FALSE;
756 } 847 }
757 848
758 inSISIDXREG(SISPART1, reg, temp); 849 inSISIDXREG(SISPART1, reg, temp);
759 if(temp & 0x02) return TRUE; 850 if(temp & 0x02)
760 else return FALSE; 851 return TRUE;
852 else
853 return FALSE;
761} 854}
762 855
763static BOOLEAN 856static BOOLEAN
764sisfb_CheckVBRetrace(struct sis_video_info *ivideo) 857sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
765{ 858{
766 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 859 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
767 if(sisfb_bridgeisslave(ivideo)) { 860 if(!sisfb_bridgeisslave(ivideo)) {
768 return(sisfbcheckvretracecrt1(ivideo)); 861 return sisfbcheckvretracecrt2(ivideo);
769 } else { 862 }
770 return(sisfbcheckvretracecrt2(ivideo)); 863 }
771 } 864 return sisfbcheckvretracecrt1(ivideo);
772 }
773 return(sisfbcheckvretracecrt1(ivideo));
774} 865}
775 866
776static u32 867static u32
777sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount) 868sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
778{ 869{
779 u8 idx, reg1, reg2, reg3, reg4; 870 u8 idx, reg1, reg2, reg3, reg4;
780 u32 ret = 0; 871 u32 ret = 0;
781 872
782 (*vcount) = (*hcount) = 0; 873 (*vcount) = (*hcount) = 0;
783 874
784 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) { 875 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
785 ret |= (FB_VBLANK_HAVE_VSYNC | 876
786 FB_VBLANK_HAVE_HBLANK | 877 ret |= (FB_VBLANK_HAVE_VSYNC |
787 FB_VBLANK_HAVE_VBLANK | 878 FB_VBLANK_HAVE_HBLANK |
788 FB_VBLANK_HAVE_VCOUNT | 879 FB_VBLANK_HAVE_VBLANK |
789 FB_VBLANK_HAVE_HCOUNT); 880 FB_VBLANK_HAVE_VCOUNT |
790 switch(ivideo->sisvga_engine) { 881 FB_VBLANK_HAVE_HCOUNT);
791 case SIS_300_VGA: idx = 0x25; break; 882 switch(ivideo->sisvga_engine) {
792 default: 883 case SIS_300_VGA: idx = 0x25; break;
793 case SIS_315_VGA: idx = 0x30; break; 884 default:
794 } 885 case SIS_315_VGA: idx = 0x30; break;
795 inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */ 886 }
796 inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */ 887 inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
797 inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */ 888 inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
798 inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */ 889 inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
799 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; 890 inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
800 if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING; 891 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
801 if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING; 892 if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
802 (*vcount) = reg3 | ((reg4 & 0x70) << 4); 893 if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
803 (*hcount) = reg2 | ((reg4 & 0x0f) << 8); 894 (*vcount) = reg3 | ((reg4 & 0x70) << 4);
804 } else if(sisfballowretracecrt1(ivideo)) { 895 (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
805 ret |= (FB_VBLANK_HAVE_VSYNC | 896
806 FB_VBLANK_HAVE_VBLANK | 897 } else if(sisfballowretracecrt1(ivideo)) {
807 FB_VBLANK_HAVE_VCOUNT | 898
808 FB_VBLANK_HAVE_HCOUNT); 899 ret |= (FB_VBLANK_HAVE_VSYNC |
809 reg1 = inSISREG(SISINPSTAT); 900 FB_VBLANK_HAVE_VBLANK |
810 if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING; 901 FB_VBLANK_HAVE_VCOUNT |
811 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; 902 FB_VBLANK_HAVE_HCOUNT);
812 inSISIDXREG(SISCR,0x20,reg1); 903 reg1 = inSISREG(SISINPSTAT);
813 inSISIDXREG(SISCR,0x1b,reg1); 904 if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
814 inSISIDXREG(SISCR,0x1c,reg2); 905 if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
815 inSISIDXREG(SISCR,0x1d,reg3); 906 inSISIDXREG(SISCR,0x20,reg1);
816 (*vcount) = reg2 | ((reg3 & 0x07) << 8); 907 inSISIDXREG(SISCR,0x1b,reg1);
817 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3; 908 inSISIDXREG(SISCR,0x1c,reg2);
818 } 909 inSISIDXREG(SISCR,0x1d,reg3);
819 return ret; 910 (*vcount) = reg2 | ((reg3 & 0x07) << 8);
911 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
912 }
913
914 return ret;
820} 915}
821 916
822static int 917static int
823sisfb_myblank(struct sis_video_info *ivideo, int blank) 918sisfb_myblank(struct sis_video_info *ivideo, int blank)
824{ 919{
825 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13; 920 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
826 BOOLEAN backlight = TRUE; 921 BOOLEAN backlight = TRUE;
827 922
828 switch(blank) { 923 switch(blank) {
829 case FB_BLANK_UNBLANK: /* on */ 924 case FB_BLANK_UNBLANK: /* on */
830 sr01 = 0x00; 925 sr01 = 0x00;
831 sr11 = 0x00; 926 sr11 = 0x00;
832 sr1f = 0x00; 927 sr1f = 0x00;
833 cr63 = 0x00; 928 cr63 = 0x00;
834 p2_0 = 0x20; 929 p2_0 = 0x20;
835 p1_13 = 0x00; 930 p1_13 = 0x00;
836 backlight = TRUE; 931 backlight = TRUE;
837 break; 932 break;
838 case FB_BLANK_NORMAL: /* blank */ 933 case FB_BLANK_NORMAL: /* blank */
839 sr01 = 0x20; 934 sr01 = 0x20;
840 sr11 = 0x00; 935 sr11 = 0x00;
841 sr1f = 0x00; 936 sr1f = 0x00;
842 cr63 = 0x00; 937 cr63 = 0x00;
843 p2_0 = 0x20; 938 p2_0 = 0x20;
844 p1_13 = 0x00; 939 p1_13 = 0x00;
845 backlight = TRUE; 940 backlight = TRUE;
846 break; 941 break;
847 case FB_BLANK_VSYNC_SUSPEND: /* no vsync */ 942 case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
848 sr01 = 0x20; 943 sr01 = 0x20;
849 sr11 = 0x08; 944 sr11 = 0x08;
850 sr1f = 0x80; 945 sr1f = 0x80;
851 cr63 = 0x40; 946 cr63 = 0x40;
852 p2_0 = 0x40; 947 p2_0 = 0x40;
853 p1_13 = 0x80; 948 p1_13 = 0x80;
854 backlight = FALSE; 949 backlight = FALSE;
855 break; 950 break;
856 case FB_BLANK_HSYNC_SUSPEND: /* no hsync */ 951 case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
857 sr01 = 0x20; 952 sr01 = 0x20;
858 sr11 = 0x08; 953 sr11 = 0x08;
859 sr1f = 0x40; 954 sr1f = 0x40;
860 cr63 = 0x40; 955 cr63 = 0x40;
861 p2_0 = 0x80; 956 p2_0 = 0x80;
862 p1_13 = 0x40; 957 p1_13 = 0x40;
863 backlight = FALSE; 958 backlight = FALSE;
864 break; 959 break;
865 case FB_BLANK_POWERDOWN: /* off */ 960 case FB_BLANK_POWERDOWN: /* off */
866 sr01 = 0x20; 961 sr01 = 0x20;
867 sr11 = 0x08; 962 sr11 = 0x08;
868 sr1f = 0xc0; 963 sr1f = 0xc0;
869 cr63 = 0x40; 964 cr63 = 0x40;
870 p2_0 = 0xc0; 965 p2_0 = 0xc0;
871 p1_13 = 0xc0; 966 p1_13 = 0xc0;
872 backlight = FALSE; 967 backlight = FALSE;
873 break; 968 break;
874 default: 969 default:
875 return 1; 970 return 1;
876 } 971 }
877 972
878 if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) { 973 if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
879 974
880 if( (!ivideo->sisfb_thismonitor.datavalid) || 975 if( (!ivideo->sisfb_thismonitor.datavalid) ||
881 ((ivideo->sisfb_thismonitor.datavalid) && 976 ((ivideo->sisfb_thismonitor.datavalid) &&
882 (ivideo->sisfb_thismonitor.feature & 0xe0))) { 977 (ivideo->sisfb_thismonitor.feature & 0xe0))) {
883 978
884 if(ivideo->sisvga_engine == SIS_315_VGA) { 979 if(ivideo->sisvga_engine == SIS_315_VGA) {
885 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63); 980 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
886 } 981 }
887 982
888 if(!(sisfb_bridgeisslave(ivideo))) { 983 if(!(sisfb_bridgeisslave(ivideo))) {
889 setSISIDXREG(SISSR, 0x01, ~0x20, sr01); 984 setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
890 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f); 985 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
891 } 986 }
892 } 987 }
893 988
894 } 989 }
895 990
896 if(ivideo->currentvbflags & CRT2_LCD) { 991 if(ivideo->currentvbflags & CRT2_LCD) {
897 992
898 if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) { 993 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
899 if(backlight) { 994 if(backlight) {
900 SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext); 995 SiS_SiS30xBLOn(&ivideo->SiS_Pr);
901 } else { 996 } else {
902 SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext); 997 SiS_SiS30xBLOff(&ivideo->SiS_Pr);
903 } 998 }
904 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 999 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
905 if(ivideo->vbflags & VB_CHRONTEL) { 1000#ifdef CONFIG_FB_SIS_315
906 if(backlight) { 1001 if(ivideo->vbflags2 & VB2_CHRONTEL) {
907 SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext); 1002 if(backlight) {
908 } else { 1003 SiS_Chrontel701xBLOn(&ivideo->SiS_Pr);
909 SiS_Chrontel701xBLOff(&ivideo->SiS_Pr); 1004 } else {
910 } 1005 SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
911 } 1006 }
912 } 1007 }
913 1008#endif
914 if(((ivideo->sisvga_engine == SIS_300_VGA) && 1009 }
915 (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) || 1010
916 ((ivideo->sisvga_engine == SIS_315_VGA) && 1011 if(((ivideo->sisvga_engine == SIS_300_VGA) &&
917 ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) { 1012 (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) ||
918 setSISIDXREG(SISSR, 0x11, ~0x0c, sr11); 1013 ((ivideo->sisvga_engine == SIS_315_VGA) &&
919 } 1014 ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) {
920 1015 setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
921 if(ivideo->sisvga_engine == SIS_300_VGA) { 1016 }
922 if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) && 1017
923 (!(ivideo->vbflags & VB_30xBDH))) { 1018 if(ivideo->sisvga_engine == SIS_300_VGA) {
924 setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13); 1019 if((ivideo->vbflags2 & VB2_30xB) &&
925 } 1020 (!(ivideo->vbflags2 & VB2_30xBDH))) {
926 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 1021 setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
927 if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) && 1022 }
928 (!(ivideo->vbflags & VB_30xBDH))) { 1023 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
929 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); 1024 if((ivideo->vbflags2 & VB2_30xB) &&
930 } 1025 (!(ivideo->vbflags2 & VB2_30xBDH))) {
931 } 1026 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
932 1027 }
933 } else if(ivideo->currentvbflags & CRT2_VGA) { 1028 }
934 1029
935 if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) { 1030 } else if(ivideo->currentvbflags & CRT2_VGA) {
936 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); 1031
937 } 1032 if(ivideo->vbflags2 & VB2_30xB) {
938 1033 setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
939 } 1034 }
940 1035
941 return(0); 1036 }
1037
1038 return 0;
1039}
1040
1041/* ------------- Callbacks from init.c/init301.c -------------- */
1042
1043#ifdef CONFIG_FB_SIS_300
1044unsigned int
1045sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg)
1046{
1047 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1048 u32 val = 0;
1049
1050 pci_read_config_dword(ivideo->nbridge, reg, &val);
1051 return (unsigned int)val;
1052}
1053
1054void
1055sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val)
1056{
1057 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1058
1059 pci_write_config_dword(ivideo->nbridge, reg, (u32)val);
942} 1060}
943 1061
1062unsigned int
1063sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg)
1064{
1065 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1066 u32 val = 0;
1067
1068 if(!ivideo->lpcdev) return 0;
1069
1070 pci_read_config_dword(ivideo->lpcdev, reg, &val);
1071 return (unsigned int)val;
1072}
1073#endif
1074
1075#ifdef CONFIG_FB_SIS_315
1076void
1077sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val)
1078{
1079 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1080
1081 pci_write_config_byte(ivideo->nbridge, reg, (u8)val);
1082}
1083
1084unsigned int
1085sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg)
1086{
1087 struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
1088 u16 val = 0;
1089
1090 if(!ivideo->lpcdev) return 0;
1091
1092 pci_read_config_word(ivideo->lpcdev, reg, &val);
1093 return (unsigned int)val;
1094}
1095#endif
1096
944/* ----------- FBDev related routines for all series ----------- */ 1097/* ----------- FBDev related routines for all series ----------- */
945 1098
946static int 1099static int
@@ -952,7 +1105,7 @@ sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
952static void 1105static void
953sisfb_set_vparms(struct sis_video_info *ivideo) 1106sisfb_set_vparms(struct sis_video_info *ivideo)
954{ 1107{
955 switch(ivideo->video_bpp) { 1108 switch(ivideo->video_bpp) {
956 case 8: 1109 case 8:
957 ivideo->DstColor = 0x0000; 1110 ivideo->DstColor = 0x0000;
958 ivideo->SiS310_AccelDepth = 0x00000000; 1111 ivideo->SiS310_AccelDepth = 0x00000000;
@@ -972,14 +1125,13 @@ sisfb_set_vparms(struct sis_video_info *ivideo)
972 ivideo->video_cmap_len = 16; 1125 ivideo->video_cmap_len = 16;
973 printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp); 1126 printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
974 ivideo->accel = 0; 1127 ivideo->accel = 0;
975 break; 1128 }
976 }
977} 1129}
978 1130
979static int 1131static int
980sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1132sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
981{ 1133{
982 int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3)); 1134 int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3));
983 1135
984 if(maxyres > 32767) maxyres = 32767; 1136 if(maxyres > 32767) maxyres = 32767;
985 1137
@@ -996,30 +1148,29 @@ sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
996 ivideo->scrnpitchCRT1 <<= 1; 1148 ivideo->scrnpitchCRT1 <<= 1;
997 } 1149 }
998 } 1150 }
999
1000} 1151}
1001 1152
1002static void 1153static void
1003sisfb_set_pitch(struct sis_video_info *ivideo) 1154sisfb_set_pitch(struct sis_video_info *ivideo)
1004{ 1155{
1005 BOOLEAN isslavemode = FALSE; 1156 BOOLEAN isslavemode = FALSE;
1006 unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3; 1157 unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
1007 unsigned short HDisplay2 = ivideo->video_linelength >> 3; 1158 unsigned short HDisplay2 = ivideo->video_linelength >> 3;
1008 1159
1009 if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE; 1160 if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
1010 1161
1011 /* We need to set pitch for CRT1 if bridge is in slave mode, too */ 1162 /* We need to set pitch for CRT1 if bridge is in slave mode, too */
1012 if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) { 1163 if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
1013 outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF)); 1164 outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
1014 setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8)); 1165 setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
1015 } 1166 }
1016 1167
1017 /* We must not set the pitch for CRT2 if bridge is in slave mode */ 1168 /* We must not set the pitch for CRT2 if bridge is in slave mode */
1018 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) { 1169 if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
1019 orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01); 1170 orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
1020 outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF)); 1171 outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
1021 setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8)); 1172 setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
1022 } 1173 }
1023} 1174}
1024 1175
1025static void 1176static void
@@ -1056,12 +1207,41 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1056} 1207}
1057 1208
1058static int 1209static int
1210sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
1211{
1212 unsigned short modeno = ivideo->mode_no;
1213
1214 /* >=2.6.12's fbcon clears the screen anyway */
1215#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
1216 if(!clrscrn) modeno |= 0x80;
1217#else
1218 modeno |= 0x80;
1219#endif
1220
1221 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1222
1223 sisfb_pre_setmode(ivideo);
1224
1225 if(SiSSetMode(&ivideo->SiS_Pr, modeno) == 0) {
1226 printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
1227 return -EINVAL;
1228 }
1229
1230 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1231
1232 sisfb_post_setmode(ivideo);
1233
1234 return 0;
1235}
1236
1237
1238static int
1059sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info) 1239sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
1060{ 1240{
1061 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1241 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1062 unsigned int htotal = 0, vtotal = 0; 1242 unsigned int htotal = 0, vtotal = 0;
1063 unsigned int drate = 0, hrate = 0; 1243 unsigned int drate = 0, hrate = 0;
1064 int found_mode = 0; 1244 int found_mode = 0, ret;
1065 int old_mode; 1245 int old_mode;
1066 u32 pixclock; 1246 u32 pixclock;
1067 1247
@@ -1088,11 +1268,11 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1088 } 1268 }
1089 1269
1090 if(pixclock && htotal && vtotal) { 1270 if(pixclock && htotal && vtotal) {
1091 drate = 1000000000 / pixclock; 1271 drate = 1000000000 / pixclock;
1092 hrate = (drate * 1000) / htotal; 1272 hrate = (drate * 1000) / htotal;
1093 ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1273 ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1094 } else { 1274 } else {
1095 ivideo->refresh_rate = 60; 1275 ivideo->refresh_rate = 60;
1096 } 1276 }
1097 1277
1098 old_mode = ivideo->sisfb_mode_idx; 1278 old_mode = ivideo->sisfb_mode_idx;
@@ -1113,6 +1293,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1113 if(found_mode) { 1293 if(found_mode) {
1114 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, 1294 ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
1115 ivideo->sisfb_mode_idx, ivideo->currentvbflags); 1295 ivideo->sisfb_mode_idx, ivideo->currentvbflags);
1296 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
1116 } else { 1297 } else {
1117 ivideo->sisfb_mode_idx = -1; 1298 ivideo->sisfb_mode_idx = -1;
1118 } 1299 }
@@ -1131,10 +1312,10 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1131 1312
1132#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 1313#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1133 if(ivideo->sisfb_thismonitor.datavalid) { 1314 if(ivideo->sisfb_thismonitor.datavalid) {
1134 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx, 1315 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
1135 ivideo->rate_idx, ivideo->refresh_rate)) { 1316 ivideo->rate_idx, ivideo->refresh_rate)) {
1136 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); 1317 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1137 } 1318 }
1138 } 1319 }
1139#endif 1320#endif
1140 1321
@@ -1143,24 +1324,9 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1143#else 1324#else
1144 if(isactive) { 1325 if(isactive) {
1145#endif 1326#endif
1146 sisfb_pre_setmode(ivideo); 1327 /* If acceleration to be used? Need to know
1147 1328 * before pre/post_set_mode()
1148 if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) { 1329 */
1149 printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
1150 return -EINVAL;
1151 }
1152
1153 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1154
1155 sisfb_post_setmode(ivideo);
1156
1157 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
1158 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
1159 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
1160
1161 sisfb_calc_pitch(ivideo, var);
1162 sisfb_set_pitch(ivideo);
1163
1164 ivideo->accel = 0; 1330 ivideo->accel = 0;
1165#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN) 1331#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
1166#ifdef STUPID_ACCELF_TEXT_SHIT 1332#ifdef STUPID_ACCELF_TEXT_SHIT
@@ -1175,6 +1341,17 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1175 if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1; 1341 if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
1176#endif 1342#endif
1177 1343
1344 if((ret = sisfb_set_mode(ivideo, 1))) {
1345 return ret;
1346 }
1347
1348 ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
1349 ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
1350 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
1351
1352 sisfb_calc_pitch(ivideo, var);
1353 sisfb_set_pitch(ivideo);
1354
1178 sisfb_set_vparms(ivideo); 1355 sisfb_set_vparms(ivideo);
1179 1356
1180 ivideo->current_width = ivideo->video_width; 1357 ivideo->current_width = ivideo->video_width;
@@ -1186,572 +1363,79 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
1186 ivideo->current_pixclock = var->pixclock; 1363 ivideo->current_pixclock = var->pixclock;
1187 ivideo->current_refresh_rate = ivideo->refresh_rate; 1364 ivideo->current_refresh_rate = ivideo->refresh_rate;
1188#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 1365#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1189 ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate; 1366 ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
1190#endif 1367#endif
1191 } 1368 }
1192 1369
1193 return 0; 1370 return 0;
1194} 1371}
1195 1372
1196static int 1373static void
1197sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1374sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base)
1198{ 1375{
1199 unsigned int base;
1200
1201 if(var->xoffset > (var->xres_virtual - var->xres)) {
1202 return -EINVAL;
1203 }
1204 if(var->yoffset > (var->yres_virtual - var->yres)) {
1205 return -EINVAL;
1206 }
1207
1208 base = (var->yoffset * var->xres_virtual) + var->xoffset;
1209
1210 /* calculate base bpp dep. */
1211 switch(var->bits_per_pixel) {
1212 case 32:
1213 break;
1214 case 16:
1215 base >>= 1;
1216 break;
1217 case 8:
1218 default:
1219 base >>= 2;
1220 break;
1221 }
1222
1223 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 1376 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1224 1377
1225 outSISIDXREG(SISCR, 0x0D, base & 0xFF); 1378 outSISIDXREG(SISCR, 0x0D, base & 0xFF);
1226 outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); 1379 outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
1227 outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); 1380 outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
1228 if(ivideo->sisvga_engine == SIS_315_VGA) { 1381 if(ivideo->sisvga_engine == SIS_315_VGA) {
1229 setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); 1382 setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
1230 } 1383 }
1231 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1232 orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
1233 outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
1234 outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
1235 outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
1236 if(ivideo->sisvga_engine == SIS_315_VGA) {
1237 setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1238 }
1239 }
1240 return 0;
1241} 1384}
1242 1385
1243/* ------------ FBDev related routines for 2.4 series ----------- */
1244
1245#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1246
1247static void 1386static void
1248sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) 1387sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
1249{
1250 u16 VRE, VBE, VRS, VBS, VDE, VT;
1251 u16 HRE, HBE, HRS, HBS, HDE, HT;
1252 u8 sr_data, cr_data, cr_data2, cr_data3, mr_data;
1253 int A, B, C, D, E, F, temp;
1254 unsigned int hrate, drate, maxyres;
1255
1256 inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
1257
1258 if(sr_data & SIS_INTERLACED_MODE)
1259 var->vmode = FB_VMODE_INTERLACED;
1260 else
1261 var->vmode = FB_VMODE_NONINTERLACED;
1262
1263 switch((sr_data & 0x1C) >> 2) {
1264 case SIS_8BPP_COLOR_MODE:
1265 var->bits_per_pixel = 8;
1266 break;
1267 case SIS_16BPP_COLOR_MODE:
1268 var->bits_per_pixel = 16;
1269 break;
1270 case SIS_32BPP_COLOR_MODE:
1271 var->bits_per_pixel = 32;
1272 break;
1273 }
1274
1275 sisfb_bpp_to_var(ivideo, var);
1276
1277 inSISIDXREG(SISSR, 0x0A, sr_data);
1278 inSISIDXREG(SISCR, 0x06, cr_data);
1279 inSISIDXREG(SISCR, 0x07, cr_data2);
1280
1281 VT = (cr_data & 0xFF) |
1282 ((u16) (cr_data2 & 0x01) << 8) |
1283 ((u16) (cr_data2 & 0x20) << 4) |
1284 ((u16) (sr_data & 0x01) << 10);
1285 A = VT + 2;
1286
1287 inSISIDXREG(SISCR, 0x12, cr_data);
1288
1289 VDE = (cr_data & 0xff) |
1290 ((u16) (cr_data2 & 0x02) << 7) |
1291 ((u16) (cr_data2 & 0x40) << 3) |
1292 ((u16) (sr_data & 0x02) << 9);
1293 E = VDE + 1;
1294
1295 inSISIDXREG(SISCR, 0x10, cr_data);
1296
1297 VRS = (cr_data & 0xff) |
1298 ((u16) (cr_data2 & 0x04) << 6) |
1299 ((u16) (cr_data2 & 0x80) << 2) |
1300 ((u16) (sr_data & 0x08) << 7);
1301 F = VRS + 1 - E;
1302
1303 inSISIDXREG(SISCR, 0x15, cr_data);
1304 inSISIDXREG(SISCR, 0x09, cr_data3);
1305
1306 if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
1307
1308 VBS = (cr_data & 0xff) |
1309 ((u16) (cr_data2 & 0x08) << 5) |
1310 ((u16) (cr_data3 & 0x20) << 4) |
1311 ((u16) (sr_data & 0x04) << 8);
1312
1313 inSISIDXREG(SISCR, 0x16, cr_data);
1314
1315 VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
1316 temp = VBE - ((E - 1) & 511);
1317 B = (temp > 0) ? temp : (temp + 512);
1318
1319 inSISIDXREG(SISCR, 0x11, cr_data);
1320
1321 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
1322 temp = VRE - ((E + F - 1) & 31);
1323 C = (temp > 0) ? temp : (temp + 32);
1324
1325 D = B - F - C;
1326
1327 var->yres = E;
1328 var->upper_margin = D;
1329 var->lower_margin = F;
1330 var->vsync_len = C;
1331
1332 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1333 var->yres <<= 1;
1334 var->upper_margin <<= 1;
1335 var->lower_margin <<= 1;
1336 var->vsync_len <<= 1;
1337 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1338 var->yres >>= 1;
1339 var->upper_margin >>= 1;
1340 var->lower_margin >>= 1;
1341 var->vsync_len >>= 1;
1342 }
1343
1344 inSISIDXREG(SISSR, 0x0b, sr_data);
1345 inSISIDXREG(SISCR, 0x00, cr_data);
1346
1347 HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
1348 A = HT + 5;
1349
1350 inSISIDXREG(SISCR, 0x01, cr_data);
1351
1352 HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
1353 E = HDE + 1;
1354
1355 inSISIDXREG(SISCR, 0x04, cr_data);
1356
1357 HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
1358 F = HRS - E - 3;
1359
1360 inSISIDXREG(SISCR, 0x02, cr_data);
1361
1362 HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
1363
1364 inSISIDXREG(SISSR, 0x0c, sr_data);
1365 inSISIDXREG(SISCR, 0x03, cr_data);
1366 inSISIDXREG(SISCR, 0x05, cr_data2);
1367
1368 HBE = (cr_data & 0x1f) |
1369 ((u16) (cr_data2 & 0x80) >> 2) |
1370 ((u16) (sr_data & 0x03) << 6);
1371 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
1372
1373 temp = HBE - ((E - 1) & 255);
1374 B = (temp > 0) ? temp : (temp + 256);
1375
1376 temp = HRE - ((E + F + 3) & 63);
1377 C = (temp > 0) ? temp : (temp + 64);
1378
1379 D = B - F - C;
1380
1381 var->xres = E * 8;
1382 if(var->xres_virtual < var->xres) {
1383 var->xres_virtual = var->xres;
1384 }
1385
1386 if((var->xres == 320) &&
1387 (var->yres == 200 || var->yres == 240)) {
1388 /* Terrible hack, but the correct CRTC data for
1389 * these modes only produces a black screen...
1390 */
1391 var->left_margin = (400 - 376);
1392 var->right_margin = (328 - 320);
1393 var->hsync_len = (376 - 328);
1394 } else {
1395 var->left_margin = D * 8;
1396 var->right_margin = F * 8;
1397 var->hsync_len = C * 8;
1398 }
1399 var->activate = FB_ACTIVATE_NOW;
1400
1401 var->sync = 0;
1402
1403 mr_data = inSISREG(SISMISCR);
1404 if(mr_data & 0x80)
1405 var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
1406 else
1407 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1408
1409 if(mr_data & 0x40)
1410 var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
1411 else
1412 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1413
1414 VT += 2;
1415 VT <<= 1;
1416 HT = (HT + 5) * 8;
1417
1418 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1419 VT <<= 1;
1420 }
1421 hrate = ivideo->refresh_rate * VT / 2;
1422 drate = (hrate * HT) / 1000;
1423 var->pixclock = (u32) (1000000000 / drate);
1424
1425 if(ivideo->sisfb_ypan) {
1426 maxyres = sisfb_calc_maxyres(ivideo, var);
1427 if(ivideo->sisfb_max) {
1428 var->yres_virtual = maxyres;
1429 } else {
1430 if(var->yres_virtual > maxyres) {
1431 var->yres_virtual = maxyres;
1432 }
1433 }
1434 if(var->yres_virtual <= var->yres) {
1435 var->yres_virtual = var->yres;
1436 }
1437 } else {
1438 var->yres_virtual = var->yres;
1439 }
1440
1441}
1442
1443static int
1444sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
1445 unsigned *transp, struct fb_info *info)
1446{ 1388{
1447 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1389 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1448 1390 orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
1449 if(regno >= ivideo->video_cmap_len) return 1; 1391 outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
1450 1392 outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
1451 *red = ivideo->sis_palette[regno].red; 1393 outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
1452 *green = ivideo->sis_palette[regno].green; 1394 if(ivideo->sisvga_engine == SIS_315_VGA) {
1453 *blue = ivideo->sis_palette[regno].blue; 1395 setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1454 *transp = 0;
1455
1456 return 0;
1457}
1458
1459static int
1460sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1461 unsigned transp, struct fb_info *info)
1462{
1463 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1464
1465 if(regno >= ivideo->video_cmap_len) return 1;
1466
1467 ivideo->sis_palette[regno].red = red;
1468 ivideo->sis_palette[regno].green = green;
1469 ivideo->sis_palette[regno].blue = blue;
1470
1471 switch(ivideo->video_bpp) {
1472#ifdef FBCON_HAS_CFB8
1473 case 8:
1474 outSISREG(SISDACA, regno);
1475 outSISREG(SISDACD, (red >> 10));
1476 outSISREG(SISDACD, (green >> 10));
1477 outSISREG(SISDACD, (blue >> 10));
1478 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1479 outSISREG(SISDAC2A, regno);
1480 outSISREG(SISDAC2D, (red >> 8));
1481 outSISREG(SISDAC2D, (green >> 8));
1482 outSISREG(SISDAC2D, (blue >> 8));
1483 } 1396 }
1484 break;
1485#endif
1486#ifdef FBCON_HAS_CFB16
1487 case 16:
1488 ivideo->sis_fbcon_cmap.cfb16[regno] =
1489 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
1490 break;
1491#endif
1492#ifdef FBCON_HAS_CFB32
1493 case 32:
1494 red >>= 8;
1495 green >>= 8;
1496 blue >>= 8;
1497 ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
1498 break;
1499#endif
1500 }
1501
1502 return 0;
1503}
1504
1505static void
1506sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
1507{
1508 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1509 struct display *display;
1510 struct display_switch *sw;
1511 struct fb_fix_screeninfo fix;
1512 long flags;
1513
1514 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
1515
1516 sisfb_get_fix(&fix, con, info);
1517
1518 display->var = *var;
1519 display->screen_base = (char *)ivideo->video_vbase;
1520 display->visual = fix.visual;
1521 display->type = fix.type;
1522 display->type_aux = fix.type_aux;
1523 display->ypanstep = fix.ypanstep;
1524 display->ywrapstep = fix.ywrapstep;
1525 display->line_length = fix.line_length;
1526 display->can_soft_blank = 1;
1527 display->inverse = ivideo->sisfb_inverse;
1528 display->next_line = fix.line_length;
1529
1530 save_flags(flags);
1531
1532 switch(ivideo->video_bpp) {
1533#ifdef FBCON_HAS_CFB8
1534 case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
1535 break;
1536#endif
1537#ifdef FBCON_HAS_CFB16
1538 case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
1539 display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
1540 break;
1541#endif
1542#ifdef FBCON_HAS_CFB32
1543 case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
1544 display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
1545 break;
1546#endif
1547 default:sw = &fbcon_dummy;
1548 break;
1549 }
1550 memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
1551 display->dispsw = &ivideo->sisfb_sw;
1552
1553 restore_flags(flags);
1554
1555 if(ivideo->sisfb_ypan) {
1556 /* display->scrollmode = 0; */
1557 } else {
1558 display->scrollmode = SCROLL_YREDRAW;
1559 ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
1560 }
1561}
1562
1563static void
1564sisfb_do_install_cmap(int con, struct fb_info *info)
1565{
1566 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1567
1568 if(con != ivideo->currcon) return;
1569
1570 if(fb_display[con].cmap.len) {
1571 fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
1572 } else {
1573 int size = sisfb_get_cmap_len(&fb_display[con].var);
1574 fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
1575 } 1397 }
1576} 1398}
1577 1399
1578static int 1400static int
1579sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 1401sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
1580{
1581 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1582
1583 if(con == -1) {
1584 memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
1585 } else {
1586 *var = fb_display[con].var;
1587 }
1588
1589 if(ivideo->sisfb_fstn) {
1590 if(var->xres == 320 && var->yres == 480) var->yres = 240;
1591 }
1592
1593 return 0;
1594}
1595
1596static int
1597sisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
1598{ 1402{
1599 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1403 if(var->xoffset > (var->xres_virtual - var->xres)) {
1600 int err;
1601
1602 fb_display[con].var.activate = FB_ACTIVATE_NOW;
1603
1604 if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
1605 sisfb_crtc_to_var(ivideo, var);
1606 return -EINVAL; 1404 return -EINVAL;
1607 } 1405 }
1608 1406 if(var->yoffset > (var->yres_virtual - var->yres)) {
1609 sisfb_crtc_to_var(ivideo, var); 1407 return -EINVAL;
1610
1611 sisfb_set_disp(con, var, info);
1612
1613 if(info->changevar) {
1614 (*info->changevar)(con);
1615 }
1616
1617 if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
1618 return err;
1619 }
1620
1621 sisfb_do_install_cmap(con, info);
1622
1623#if 0 /* Why was this called here? */
1624 unsigned int cols, rows;
1625 cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
1626 rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
1627 vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
1628#endif
1629 return 0;
1630}
1631
1632static int
1633sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
1634{
1635 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1636 struct display *display;
1637
1638 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
1639
1640 if(con == ivideo->currcon) {
1641
1642 return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
1643
1644 } else if(display->cmap.len) {
1645
1646 fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
1647
1648 } else {
1649
1650 int size = sisfb_get_cmap_len(&display->var);
1651 fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
1652
1653 } 1408 }
1654 1409
1655 return 0; 1410 ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
1656}
1657 1411
1658static int 1412 /* calculate base bpp dep. */
1659sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) 1413 switch(var->bits_per_pixel) {
1660{ 1414 case 32:
1661 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1415 break;
1662 struct display *display; 1416 case 16:
1663 int err, size; 1417 ivideo->current_base >>= 1;
1664 1418 break;
1665 display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp; 1419 case 8:
1666 1420 default:
1667 size = sisfb_get_cmap_len(&display->var); 1421 ivideo->current_base >>= 2;
1668 if(display->cmap.len != size) { 1422 break;
1669 err = fb_alloc_cmap(&display->cmap, size, 0);
1670 if(err) return err;
1671 }
1672
1673 if(con == ivideo->currcon) {
1674 return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
1675 } else {
1676 fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
1677 }
1678
1679 return 0;
1680}
1681
1682static int
1683sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
1684{
1685 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1686 int err;
1687
1688 if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
1689
1690 if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
1691 (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
1692 return -EINVAL;
1693 } 1423 }
1694 1424
1695 if(con == ivideo->currcon) { 1425 ivideo->current_base += (ivideo->video_offset >> 2);
1696 if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
1697 }
1698 1426
1699 fb_display[con].var.xoffset = var->xoffset; 1427 sisfb_set_base_CRT1(ivideo, ivideo->current_base);
1700 fb_display[con].var.yoffset = var->yoffset; 1428 sisfb_set_base_CRT2(ivideo, ivideo->current_base);
1701 1429
1702 return 0; 1430 return 0;
1703} 1431}
1704 1432
1705static int 1433/* ------------ FBDev related routines for 2.4 series ----------- */
1706sisfb_update_var(int con, struct fb_info *info)
1707{
1708 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1709
1710 return(sisfb_pan_var(ivideo, &fb_display[con].var));
1711}
1712
1713static int
1714sisfb_switch(int con, struct fb_info *info)
1715{
1716 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1717 int cols, rows;
1718
1719 if(fb_display[ivideo->currcon].cmap.len) {
1720 fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
1721 }
1722
1723 fb_display[con].var.activate = FB_ACTIVATE_NOW;
1724
1725 if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
1726 sizeof(struct fb_var_screeninfo))) {
1727 ivideo->currcon = con;
1728 return 1;
1729 }
1730
1731 ivideo->currcon = con;
1732
1733 sisfb_do_set_var(&fb_display[con].var, 1, info);
1734
1735 sisfb_set_disp(con, &fb_display[con].var, info);
1736
1737 sisfb_do_install_cmap(con, info);
1738
1739 cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
1740 rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
1741 vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
1742
1743 sisfb_update_var(con, info);
1744 1434
1745 return 1; 1435#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1746}
1747 1436
1748static void 1437#include "sisfb_fbdev_2_4.h"
1749sisfb_blank(int blank, struct fb_info *info)
1750{
1751 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1752 1438
1753 sisfb_myblank(ivideo, blank);
1754}
1755#endif 1439#endif
1756 1440
1757/* ------------ FBDev related routines for 2.6 series ----------- */ 1441/* ------------ FBDev related routines for 2.6 series ----------- */
@@ -1761,13 +1445,13 @@ sisfb_blank(int blank, struct fb_info *info)
1761static int 1445static int
1762sisfb_open(struct fb_info *info, int user) 1446sisfb_open(struct fb_info *info, int user)
1763{ 1447{
1764 return 0; 1448 return 0;
1765} 1449}
1766 1450
1767static int 1451static int
1768sisfb_release(struct fb_info *info, int user) 1452sisfb_release(struct fb_info *info, int user)
1769{ 1453{
1770 return 0; 1454 return 0;
1771} 1455}
1772 1456
1773static int 1457static int
@@ -1776,16 +1460,17 @@ sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1776{ 1460{
1777 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1461 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1778 1462
1779 if(regno >= sisfb_get_cmap_len(&info->var)) return 1; 1463 if(regno >= sisfb_get_cmap_len(&info->var))
1464 return 1;
1780 1465
1781 switch(info->var.bits_per_pixel) { 1466 switch(info->var.bits_per_pixel) {
1782 case 8: 1467 case 8:
1783 outSISREG(SISDACA, regno); 1468 outSISREG(SISDACA, regno);
1784 outSISREG(SISDACD, (red >> 10)); 1469 outSISREG(SISDACD, (red >> 10));
1785 outSISREG(SISDACD, (green >> 10)); 1470 outSISREG(SISDACD, (green >> 10));
1786 outSISREG(SISDACD, (blue >> 10)); 1471 outSISREG(SISDACD, (blue >> 10));
1787 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 1472 if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
1788 outSISREG(SISDAC2A, regno); 1473 outSISREG(SISDAC2A, regno);
1789 outSISREG(SISDAC2D, (red >> 8)); 1474 outSISREG(SISDAC2D, (red >> 8));
1790 outSISREG(SISDAC2D, (green >> 8)); 1475 outSISREG(SISDAC2D, (green >> 8));
1791 outSISREG(SISDAC2D, (blue >> 8)); 1476 outSISREG(SISDAC2D, (blue >> 8));
@@ -1793,7 +1478,9 @@ sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1793 break; 1478 break;
1794 case 16: 1479 case 16:
1795 ((u32 *)(info->pseudo_palette))[regno] = 1480 ((u32 *)(info->pseudo_palette))[regno] =
1796 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); 1481 (red & 0xf800) |
1482 ((green & 0xfc00) >> 5) |
1483 ((blue & 0xf800) >> 11);
1797 break; 1484 break;
1798 case 32: 1485 case 32:
1799 red >>= 8; 1486 red >>= 8;
@@ -1811,13 +1498,13 @@ sisfb_set_par(struct fb_info *info)
1811{ 1498{
1812 int err; 1499 int err;
1813 1500
1814 if((err = sisfb_do_set_var(&info->var, 1, info))) { 1501 if((err = sisfb_do_set_var(&info->var, 1, info)))
1815 return err; 1502 return err;
1816 } 1503
1817#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) 1504#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
1818 sisfb_get_fix(&info->fix, info->currcon, info); 1505 sisfb_get_fix(&info->fix, info->currcon, info);
1819#else 1506#else
1820 sisfb_get_fix(&info->fix, -1, info); 1507 sisfb_get_fix(&info->fix, -1, info);
1821#endif 1508#endif
1822 return 0; 1509 return 0;
1823} 1510}
@@ -1829,7 +1516,7 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1829 unsigned int htotal = 0, vtotal = 0, myrateindex = 0; 1516 unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
1830 unsigned int drate = 0, hrate = 0, maxyres; 1517 unsigned int drate = 0, hrate = 0, maxyres;
1831 int found_mode = 0; 1518 int found_mode = 0;
1832 int refresh_rate, search_idx; 1519 int refresh_rate, search_idx, tidx;
1833 BOOLEAN recalc_clock = FALSE; 1520 BOOLEAN recalc_clock = FALSE;
1834 u32 pixclock; 1521 u32 pixclock;
1835 1522
@@ -1848,7 +1535,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1848 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { 1535 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1849 vtotal += var->yres; 1536 vtotal += var->yres;
1850 vtotal <<= 1; 1537 vtotal <<= 1;
1851 } else vtotal += var->yres; 1538 } else
1539 vtotal += var->yres;
1852 1540
1853 if(!(htotal) || !(vtotal)) { 1541 if(!(htotal) || !(vtotal)) {
1854 SISFAIL("sisfb: no valid timing data"); 1542 SISFAIL("sisfb: no valid timing data");
@@ -1860,60 +1548,68 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1860 if( (sisbios_mode[search_idx].xres == var->xres) && 1548 if( (sisbios_mode[search_idx].xres == var->xres) &&
1861 (sisbios_mode[search_idx].yres == var->yres) && 1549 (sisbios_mode[search_idx].yres == var->yres) &&
1862 (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) { 1550 (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1863 if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) { 1551 if((tidx = sisfb_validate_mode(ivideo, search_idx,
1864 found_mode = 1; 1552 ivideo->currentvbflags)) > 0) {
1865 break; 1553 found_mode = 1;
1554 search_idx = tidx;
1555 break;
1866 } 1556 }
1867 } 1557 }
1868 search_idx++; 1558 search_idx++;
1869 } 1559 }
1870 1560
1871 if(!found_mode) { 1561 if(!found_mode) {
1872 search_idx = 0; 1562 search_idx = 0;
1873 while(sisbios_mode[search_idx].mode_no[0] != 0) { 1563 while(sisbios_mode[search_idx].mode_no[0] != 0) {
1874 if( (var->xres <= sisbios_mode[search_idx].xres) && 1564 if( (var->xres <= sisbios_mode[search_idx].xres) &&
1875 (var->yres <= sisbios_mode[search_idx].yres) && 1565 (var->yres <= sisbios_mode[search_idx].yres) &&
1876 (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) { 1566 (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
1877 if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) { 1567 if((tidx = sisfb_validate_mode(ivideo,search_idx,
1878 found_mode = 1; 1568 ivideo->currentvbflags)) > 0) {
1879 break; 1569 found_mode = 1;
1880 } 1570 search_idx = tidx;
1571 break;
1572 }
1881 } 1573 }
1882 search_idx++; 1574 search_idx++;
1883 } 1575 }
1884 if(found_mode) { 1576 if(found_mode) {
1885 printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n", 1577 printk(KERN_DEBUG
1886 var->xres, var->yres, var->bits_per_pixel, 1578 "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
1579 var->xres, var->yres, var->bits_per_pixel,
1887 sisbios_mode[search_idx].xres, 1580 sisbios_mode[search_idx].xres,
1888 sisbios_mode[search_idx].yres, 1581 sisbios_mode[search_idx].yres,
1889 var->bits_per_pixel); 1582 var->bits_per_pixel);
1890 var->xres = sisbios_mode[search_idx].xres; 1583 var->xres = sisbios_mode[search_idx].xres;
1891 var->yres = sisbios_mode[search_idx].yres; 1584 var->yres = sisbios_mode[search_idx].yres;
1892
1893
1894 } else { 1585 } else {
1895 printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n", 1586 printk(KERN_ERR
1587 "sisfb: Failed to find supported mode near %dx%dx%d\n",
1896 var->xres, var->yres, var->bits_per_pixel); 1588 var->xres, var->yres, var->bits_per_pixel);
1897 return -EINVAL; 1589 return -EINVAL;
1898 } 1590 }
1899 } 1591 }
1900 1592
1901 if( ((ivideo->vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */ 1593 if( ((ivideo->vbflags2 & VB2_LVDS) ||
1902 ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) && 1594 ((ivideo->vbflags2 & VB2_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
1903 (var->bits_per_pixel == 8) ) { 1595 (var->bits_per_pixel == 8) ) {
1904 refresh_rate = 60; 1596 /* Slave modes on LVDS and 301B-DH */
1597 refresh_rate = 60;
1905 recalc_clock = TRUE; 1598 recalc_clock = TRUE;
1906 } else if( (ivideo->current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */ 1599 } else if( (ivideo->current_htotal == htotal) &&
1907 (ivideo->current_vtotal == vtotal) && 1600 (ivideo->current_vtotal == vtotal) &&
1908 (ivideo->current_pixclock == pixclock) ) { 1601 (ivideo->current_pixclock == pixclock) ) {
1602 /* x=x & y=y & c=c -> assume depth change */
1909 drate = 1000000000 / pixclock; 1603 drate = 1000000000 / pixclock;
1910 hrate = (drate * 1000) / htotal; 1604 hrate = (drate * 1000) / htotal;
1911 refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1605 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1912 } else if( ( (ivideo->current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */ 1606 } else if( ( (ivideo->current_htotal != htotal) ||
1913 (ivideo->current_vtotal != vtotal) ) && 1607 (ivideo->current_vtotal != vtotal) ) &&
1914 (ivideo->current_pixclock == var->pixclock) ) { 1608 (ivideo->current_pixclock == var->pixclock) ) {
1609 /* x!=x | y!=y & c=c -> invalid pixclock */
1915 if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) { 1610 if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
1916 refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]; 1611 refresh_rate =
1612 ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
1917 } else if(ivideo->sisfb_parm_rate != -1) { 1613 } else if(ivideo->sisfb_parm_rate != -1) {
1918 /* Sic, sisfb_parm_rate - want to know originally desired rate here */ 1614 /* Sic, sisfb_parm_rate - want to know originally desired rate here */
1919 refresh_rate = ivideo->sisfb_parm_rate; 1615 refresh_rate = ivideo->sisfb_parm_rate;
@@ -1923,8 +1619,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1923 recalc_clock = TRUE; 1619 recalc_clock = TRUE;
1924 } else if((pixclock) && (htotal) && (vtotal)) { 1620 } else if((pixclock) && (htotal) && (vtotal)) {
1925 drate = 1000000000 / pixclock; 1621 drate = 1000000000 / pixclock;
1926 hrate = (drate * 1000) / htotal; 1622 hrate = (drate * 1000) / htotal;
1927 refresh_rate = (unsigned int) (hrate * 2 / vtotal); 1623 refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1928 } else if(ivideo->current_refresh_rate) { 1624 } else if(ivideo->current_refresh_rate) {
1929 refresh_rate = ivideo->current_refresh_rate; 1625 refresh_rate = ivideo->current_refresh_rate;
1930 recalc_clock = TRUE; 1626 recalc_clock = TRUE;
@@ -1937,72 +1633,72 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1937 1633
1938 /* Eventually recalculate timing and clock */ 1634 /* Eventually recalculate timing and clock */
1939 if(recalc_clock) { 1635 if(recalc_clock) {
1940 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx; 1636 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
1941 var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, 1637 var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
1942 &ivideo->sishw_ext,
1943 sisbios_mode[search_idx].mode_no[ivideo->mni], 1638 sisbios_mode[search_idx].mode_no[ivideo->mni],
1944 myrateindex)); 1639 myrateindex));
1945 sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext, 1640 sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr,
1946 sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var); 1641 sisbios_mode[search_idx].mode_no[ivideo->mni],
1947 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 1642 myrateindex, var);
1948 var->pixclock <<= 1; 1643 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1949 } 1644 var->pixclock <<= 1;
1645 }
1950 } 1646 }
1951 1647
1952 if(ivideo->sisfb_thismonitor.datavalid) { 1648 if(ivideo->sisfb_thismonitor.datavalid) {
1953 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx, 1649 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
1954 myrateindex, refresh_rate)) { 1650 myrateindex, refresh_rate)) {
1955 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); 1651 printk(KERN_INFO
1956 } 1652 "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1653 }
1957 } 1654 }
1958 1655
1959 /* Adapt RGB settings */ 1656 /* Adapt RGB settings */
1960 sisfb_bpp_to_var(ivideo, var); 1657 sisfb_bpp_to_var(ivideo, var);
1961 1658
1962 /* Sanity check for offsets */ 1659 /* Sanity check for offsets */
1963 if(var->xoffset < 0) var->xoffset = 0; 1660 if(var->xoffset < 0) var->xoffset = 0;
1964 if(var->yoffset < 0) var->yoffset = 0; 1661 if(var->yoffset < 0) var->yoffset = 0;
1965 1662
1966 if(var->xres > var->xres_virtual) { 1663 if(var->xres > var->xres_virtual)
1967 var->xres_virtual = var->xres; 1664 var->xres_virtual = var->xres;
1968 }
1969 1665
1970 if(ivideo->sisfb_ypan) { 1666 if(ivideo->sisfb_ypan) {
1971 maxyres = sisfb_calc_maxyres(ivideo, var); 1667 maxyres = sisfb_calc_maxyres(ivideo, var);
1972 if(ivideo->sisfb_max) { 1668 if(ivideo->sisfb_max) {
1973 var->yres_virtual = maxyres; 1669 var->yres_virtual = maxyres;
1974 } else { 1670 } else {
1975 if(var->yres_virtual > maxyres) { 1671 if(var->yres_virtual > maxyres) {
1976 var->yres_virtual = maxyres; 1672 var->yres_virtual = maxyres;
1977 } 1673 }
1978 } 1674 }
1979 if(var->yres_virtual <= var->yres) { 1675 if(var->yres_virtual <= var->yres) {
1980 var->yres_virtual = var->yres; 1676 var->yres_virtual = var->yres;
1981 } 1677 }
1982 } else { 1678 } else {
1983 if(var->yres != var->yres_virtual) { 1679 if(var->yres != var->yres_virtual) {
1984 var->yres_virtual = var->yres; 1680 var->yres_virtual = var->yres;
1985 } 1681 }
1986 var->xoffset = 0; 1682 var->xoffset = 0;
1987 var->yoffset = 0; 1683 var->yoffset = 0;
1988 } 1684 }
1989 1685
1990 /* Truncate offsets to maximum if too high */ 1686 /* Truncate offsets to maximum if too high */
1991 if(var->xoffset > var->xres_virtual - var->xres) { 1687 if(var->xoffset > var->xres_virtual - var->xres) {
1992 var->xoffset = var->xres_virtual - var->xres - 1; 1688 var->xoffset = var->xres_virtual - var->xres - 1;
1993 } 1689 }
1994 1690
1995 if(var->yoffset > var->yres_virtual - var->yres) { 1691 if(var->yoffset > var->yres_virtual - var->yres) {
1996 var->yoffset = var->yres_virtual - var->yres - 1; 1692 var->yoffset = var->yres_virtual - var->yres - 1;
1997 } 1693 }
1998 1694
1999 /* Set everything else to 0 */ 1695 /* Set everything else to 0 */
2000 var->red.msb_right = 1696 var->red.msb_right =
2001 var->green.msb_right = 1697 var->green.msb_right =
2002 var->blue.msb_right = 1698 var->blue.msb_right =
2003 var->transp.offset = 1699 var->transp.offset =
2004 var->transp.length = 1700 var->transp.length =
2005 var->transp.msb_right = 0; 1701 var->transp.msb_right = 0;
2006 1702
2007 return 0; 1703 return 0;
2008} 1704}
@@ -2013,21 +1709,21 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
2013 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1709 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2014 int err; 1710 int err;
2015 1711
2016 if(var->xoffset > (var->xres_virtual - var->xres)) { 1712 if(var->xoffset > (var->xres_virtual - var->xres))
2017 return -EINVAL; 1713 return -EINVAL;
2018 } 1714
2019 if(var->yoffset > (var->yres_virtual - var->yres)) { 1715 if(var->yoffset > (var->yres_virtual - var->yres))
2020 return -EINVAL; 1716 return -EINVAL;
2021 }
2022 1717
2023 if(var->vmode & FB_VMODE_YWRAP) return -EINVAL; 1718 if(var->vmode & FB_VMODE_YWRAP)
1719 return -EINVAL;
2024 1720
2025 if(var->xoffset + info->var.xres > info->var.xres_virtual || 1721 if(var->xoffset + info->var.xres > info->var.xres_virtual ||
2026 var->yoffset + info->var.yres > info->var.yres_virtual) { 1722 var->yoffset + info->var.yres > info->var.yres_virtual)
2027 return -EINVAL; 1723 return -EINVAL;
2028 }
2029 1724
2030 if((err = sisfb_pan_var(ivideo, var)) < 0) return err; 1725 if((err = sisfb_pan_var(ivideo, var)) < 0)
1726 return err;
2031 1727
2032 info->var.xoffset = var->xoffset; 1728 info->var.xoffset = var->xoffset;
2033 info->var.yoffset = var->yoffset; 1729 info->var.yoffset = var->yoffset;
@@ -2040,7 +1736,7 @@ sisfb_blank(int blank, struct fb_info *info)
2040{ 1736{
2041 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1737 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2042 1738
2043 return(sisfb_myblank(ivideo, blank)); 1739 return sisfb_myblank(ivideo, blank);
2044} 1740}
2045 1741
2046#endif 1742#endif
@@ -2056,153 +1752,184 @@ sisfb_ioctl(struct inode *inode, struct file *file,
2056 struct fb_info *info) 1752 struct fb_info *info)
2057{ 1753{
2058 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1754 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
2059 struct sis_memreq sismemreq; 1755 struct sis_memreq sismemreq;
2060 struct fb_vblank sisvbblank; 1756 struct fb_vblank sisvbblank;
2061 sisfb_info x;
2062 u32 gpu32 = 0; 1757 u32 gpu32 = 0;
2063#ifndef __user 1758#ifndef __user
2064#define __user 1759#define __user
2065#endif 1760#endif
2066 u32 __user *argp = (u32 __user *)arg; 1761 u32 __user *argp = (u32 __user *)arg;
2067 1762
2068 switch (cmd) { 1763 switch(cmd) {
2069 case FBIO_ALLOC: 1764 case FBIO_ALLOC:
2070 if(!capable(CAP_SYS_RAWIO)) { 1765 if(!capable(CAP_SYS_RAWIO))
2071 return -EPERM; 1766 return -EPERM;
2072 } 1767
2073 if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) { 1768 if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq)))
2074 return -EFAULT; 1769 return -EFAULT;
2075 } 1770
2076 sis_malloc(&sismemreq); 1771 sis_malloc(&sismemreq);
1772
2077 if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) { 1773 if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
2078 sis_free((u32)sismemreq.offset); 1774 sis_free((u32)sismemreq.offset);
2079 return -EFAULT; 1775 return -EFAULT;
2080 } 1776 }
2081 break; 1777 break;
2082 1778
2083 case FBIO_FREE: 1779 case FBIO_FREE:
2084 if(!capable(CAP_SYS_RAWIO)) { 1780 if(!capable(CAP_SYS_RAWIO))
2085 return -EPERM; 1781 return -EPERM;
2086 } 1782
2087 if(get_user(gpu32, argp)) { 1783 if(get_user(gpu32, argp))
2088 return -EFAULT; 1784 return -EFAULT;
2089 } 1785
2090 sis_free(gpu32); 1786 sis_free(gpu32);
2091 break; 1787 break;
2092 1788
2093 case FBIOGET_VBLANK: 1789 case FBIOGET_VBLANK:
2094 sisvbblank.count = 0; 1790 sisvbblank.count = 0;
2095 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); 1791 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
2096 if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) { 1792
1793 if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank)))
2097 return -EFAULT; 1794 return -EFAULT;
2098 } 1795
2099 break; 1796 break;
2100 1797
2101 case SISFB_GET_INFO_SIZE: 1798 case SISFB_GET_INFO_SIZE:
2102 return put_user(sizeof(sisfb_info), argp); 1799 return put_user(sizeof(struct sisfb_info), argp);
2103 1800
2104 case SISFB_GET_INFO_OLD: 1801 case SISFB_GET_INFO_OLD:
2105 if(ivideo->warncount++ < 50) { 1802 if(ivideo->warncount++ < 10)
2106 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n"); 1803 printk(KERN_INFO
2107 } 1804 "sisfb: Deprecated ioctl call received - update your application!\n");
2108 case SISFB_GET_INFO: /* For communication with X driver */ 1805 case SISFB_GET_INFO: /* For communication with X driver */
2109 x.sisfb_id = SISFB_ID; 1806 ivideo->sisfb_infoblock.sisfb_id = SISFB_ID;
2110 x.sisfb_version = VER_MAJOR; 1807 ivideo->sisfb_infoblock.sisfb_version = VER_MAJOR;
2111 x.sisfb_revision = VER_MINOR; 1808 ivideo->sisfb_infoblock.sisfb_revision = VER_MINOR;
2112 x.sisfb_patchlevel = VER_LEVEL; 1809 ivideo->sisfb_infoblock.sisfb_patchlevel = VER_LEVEL;
2113 x.chip_id = ivideo->chip_id; 1810 ivideo->sisfb_infoblock.chip_id = ivideo->chip_id;
2114 x.memory = ivideo->video_size / 1024; 1811 ivideo->sisfb_infoblock.sisfb_pci_vendor = ivideo->chip_vendor;
2115 x.heapstart = ivideo->heapstart / 1024; 1812 ivideo->sisfb_infoblock.memory = ivideo->video_size / 1024;
1813 ivideo->sisfb_infoblock.heapstart = ivideo->heapstart / 1024;
2116 if(ivideo->modechanged) { 1814 if(ivideo->modechanged) {
2117 x.fbvidmode = ivideo->mode_no; 1815 ivideo->sisfb_infoblock.fbvidmode = ivideo->mode_no;
2118 } else { 1816 } else {
2119 x.fbvidmode = ivideo->modeprechange; 1817 ivideo->sisfb_infoblock.fbvidmode = ivideo->modeprechange;
2120 }
2121 x.sisfb_caps = ivideo->caps;
2122 x.sisfb_tqlen = 512; /* yet fixed */
2123 x.sisfb_pcibus = ivideo->pcibus;
2124 x.sisfb_pcislot = ivideo->pcislot;
2125 x.sisfb_pcifunc = ivideo->pcifunc;
2126 x.sisfb_lcdpdc = ivideo->detectedpdc;
2127 x.sisfb_lcdpdca = ivideo->detectedpdca;
2128 x.sisfb_lcda = ivideo->detectedlcda;
2129 x.sisfb_vbflags = ivideo->vbflags;
2130 x.sisfb_currentvbflags = ivideo->currentvbflags;
2131 x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
2132 x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
2133 x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
2134 x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
2135 x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
2136 x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
2137 x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
2138 x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
2139 x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
2140 x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
2141
2142 if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
2143 return -EFAULT;
2144 } 1818 }
1819 ivideo->sisfb_infoblock.sisfb_caps = ivideo->caps;
1820 ivideo->sisfb_infoblock.sisfb_tqlen = ivideo->cmdQueueSize / 1024;
1821 ivideo->sisfb_infoblock.sisfb_pcibus = ivideo->pcibus;
1822 ivideo->sisfb_infoblock.sisfb_pcislot = ivideo->pcislot;
1823 ivideo->sisfb_infoblock.sisfb_pcifunc = ivideo->pcifunc;
1824 ivideo->sisfb_infoblock.sisfb_lcdpdc = ivideo->detectedpdc;
1825 ivideo->sisfb_infoblock.sisfb_lcdpdca = ivideo->detectedpdca;
1826 ivideo->sisfb_infoblock.sisfb_lcda = ivideo->detectedlcda;
1827 ivideo->sisfb_infoblock.sisfb_vbflags = ivideo->vbflags;
1828 ivideo->sisfb_infoblock.sisfb_currentvbflags = ivideo->currentvbflags;
1829 ivideo->sisfb_infoblock.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
1830 ivideo->sisfb_infoblock.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
1831 ivideo->sisfb_infoblock.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
1832 ivideo->sisfb_infoblock.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
1833 ivideo->sisfb_infoblock.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
1834 ivideo->sisfb_infoblock.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
1835 ivideo->sisfb_infoblock.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
1836 ivideo->sisfb_infoblock.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
1837 ivideo->sisfb_infoblock.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
1838 ivideo->sisfb_infoblock.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
1839 ivideo->sisfb_infoblock.sisfb_heapsize = ivideo->sisfb_heap_size / 1024;
1840 ivideo->sisfb_infoblock.sisfb_videooffset = ivideo->video_offset;
1841 ivideo->sisfb_infoblock.sisfb_curfstn = ivideo->curFSTN;
1842 ivideo->sisfb_infoblock.sisfb_curdstn = ivideo->curDSTN;
1843 ivideo->sisfb_infoblock.sisfb_vbflags2 = ivideo->vbflags2;
1844 ivideo->sisfb_infoblock.sisfb_can_post = ivideo->sisfb_can_post ? 1 : 0;
1845 ivideo->sisfb_infoblock.sisfb_card_posted = ivideo->sisfb_card_posted ? 1 : 0;
1846 ivideo->sisfb_infoblock.sisfb_was_boot_device = ivideo->sisfb_was_boot_device ? 1 : 0;
1847
1848 if(copy_to_user((void __user *)arg, &ivideo->sisfb_infoblock,
1849 sizeof(ivideo->sisfb_infoblock)))
1850 return -EFAULT;
1851
2145 break; 1852 break;
2146 1853
2147 case SISFB_GET_VBRSTATUS_OLD: 1854 case SISFB_GET_VBRSTATUS_OLD:
2148 if(ivideo->warncount++ < 50) { 1855 if(ivideo->warncount++ < 10)
2149 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n"); 1856 printk(KERN_INFO
2150 } 1857 "sisfb: Deprecated ioctl call received - update your application!\n");
2151 case SISFB_GET_VBRSTATUS: 1858 case SISFB_GET_VBRSTATUS:
2152 if(sisfb_CheckVBRetrace(ivideo)) { 1859 if(sisfb_CheckVBRetrace(ivideo))
2153 return put_user((u32)1, argp); 1860 return put_user((u32)1, argp);
2154 } else { 1861 else
2155 return put_user((u32)0, argp); 1862 return put_user((u32)0, argp);
2156 }
2157 1863
2158 case SISFB_GET_AUTOMAXIMIZE_OLD: 1864 case SISFB_GET_AUTOMAXIMIZE_OLD:
2159 if(ivideo->warncount++ < 50) { 1865 if(ivideo->warncount++ < 10)
2160 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n"); 1866 printk(KERN_INFO
2161 } 1867 "sisfb: Deprecated ioctl call received - update your application!\n");
2162 case SISFB_GET_AUTOMAXIMIZE: 1868 case SISFB_GET_AUTOMAXIMIZE:
2163 if(ivideo->sisfb_max) return put_user((u32)1, argp); 1869 if(ivideo->sisfb_max)
2164 else return put_user((u32)0, argp); 1870 return put_user((u32)1, argp);
1871 else
1872 return put_user((u32)0, argp);
2165 1873
2166 case SISFB_SET_AUTOMAXIMIZE_OLD: 1874 case SISFB_SET_AUTOMAXIMIZE_OLD:
2167 if(ivideo->warncount++ < 50) { 1875 if(ivideo->warncount++ < 10)
2168 printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n"); 1876 printk(KERN_INFO
2169 } 1877 "sisfb: Deprecated ioctl call received - update your application!\n");
2170 case SISFB_SET_AUTOMAXIMIZE: 1878 case SISFB_SET_AUTOMAXIMIZE:
2171 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) { 1879 if(get_user(gpu32, argp))
2172 return -EFAULT; 1880 return -EFAULT;
2173 } 1881
2174 ivideo->sisfb_max = (gpu32) ? 1 : 0; 1882 ivideo->sisfb_max = (gpu32) ? 1 : 0;
2175 break; 1883 break;
2176 1884
2177 case SISFB_SET_TVPOSOFFSET: 1885 case SISFB_SET_TVPOSOFFSET:
2178 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) { 1886 if(get_user(gpu32, argp))
2179 return -EFAULT; 1887 return -EFAULT;
2180 } 1888
2181 sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32); 1889 sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
2182 sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32); 1890 sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
2183 break; 1891 break;
2184 1892
2185 case SISFB_GET_TVPOSOFFSET: 1893 case SISFB_GET_TVPOSOFFSET:
2186 return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), 1894 return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
2187 argp); 1895 argp);
1896
1897 case SISFB_COMMAND:
1898 if(copy_from_user(&ivideo->sisfb_command, (void __user *)arg,
1899 sizeof(struct sisfb_cmd)))
1900 return -EFAULT;
1901
1902 sisfb_handle_command(ivideo, &ivideo->sisfb_command);
1903
1904 if(copy_to_user((void __user *)arg, &ivideo->sisfb_command,
1905 sizeof(struct sisfb_cmd)))
1906 return -EFAULT;
1907
1908 break;
2188 1909
2189 case SISFB_SET_LOCK: 1910 case SISFB_SET_LOCK:
2190 if(copy_from_user(&gpu32, argp, sizeof(gpu32))) { 1911 if(get_user(gpu32, argp))
2191 return -EFAULT; 1912 return -EFAULT;
2192 } 1913
2193 ivideo->sisfblocked = (gpu32) ? 1 : 0; 1914 ivideo->sisfblocked = (gpu32) ? 1 : 0;
2194 break; 1915 break;
2195 1916
2196 default: 1917 default:
1918#ifdef SIS_NEW_CONFIG_COMPAT
2197 return -ENOIOCTLCMD; 1919 return -ENOIOCTLCMD;
1920#else
1921 return -EINVAL;
1922#endif
2198 } 1923 }
2199 return 0; 1924 return 0;
2200} 1925}
2201 1926
2202#ifdef CONFIG_COMPAT 1927#ifdef SIS_NEW_CONFIG_COMPAT
2203static long sisfb_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info) 1928static long
1929sisfb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg, struct fb_info *info)
2204{ 1930{
2205 int ret; 1931 int ret;
1932
2206 lock_kernel(); 1933 lock_kernel();
2207 ret = sisfb_ioctl(NULL, f, cmd, arg, info); 1934 ret = sisfb_ioctl(NULL, f, cmd, arg, info);
2208 unlock_kernel(); 1935 unlock_kernel();
@@ -2219,7 +1946,7 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
2219 1946
2220 strcpy(fix->id, ivideo->myid); 1947 strcpy(fix->id, ivideo->myid);
2221 1948
2222 fix->smem_start = ivideo->video_base; 1949 fix->smem_start = ivideo->video_base + ivideo->video_offset;
2223 fix->smem_len = ivideo->sisfb_mem; 1950 fix->smem_len = ivideo->sisfb_mem;
2224 fix->type = FB_TYPE_PACKED_PIXELS; 1951 fix->type = FB_TYPE_PACKED_PIXELS;
2225 fix->type_aux = 0; 1952 fix->type_aux = 0;
@@ -2231,11 +1958,17 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
2231 fix->mmio_start = ivideo->mmio_base; 1958 fix->mmio_start = ivideo->mmio_base;
2232 fix->mmio_len = ivideo->mmio_size; 1959 fix->mmio_len = ivideo->mmio_size;
2233 if(ivideo->sisvga_engine == SIS_300_VGA) { 1960 if(ivideo->sisvga_engine == SIS_300_VGA) {
2234 fix->accel = FB_ACCEL_SIS_GLAMOUR; 1961 fix->accel = FB_ACCEL_SIS_GLAMOUR;
2235 } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) { 1962 } else if((ivideo->chip == SIS_330) ||
2236 fix->accel = FB_ACCEL_SIS_XABRE; 1963 (ivideo->chip == SIS_760) ||
1964 (ivideo->chip == SIS_761)) {
1965 fix->accel = FB_ACCEL_SIS_XABRE;
1966 } else if(ivideo->chip == XGI_20) {
1967 fix->accel = FB_ACCEL_XGI_VOLARI_Z;
1968 } else if(ivideo->chip >= XGI_40) {
1969 fix->accel = FB_ACCEL_XGI_VOLARI_V;
2237 } else { 1970 } else {
2238 fix->accel = FB_ACCEL_SIS_GLAMOUR_2; 1971 fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
2239 } 1972 }
2240 1973
2241 return 0; 1974 return 0;
@@ -2251,40 +1984,41 @@ static struct fb_ops sisfb_ops = {
2251 .fb_set_var = sisfb_set_var, 1984 .fb_set_var = sisfb_set_var,
2252 .fb_get_cmap = sisfb_get_cmap, 1985 .fb_get_cmap = sisfb_get_cmap,
2253 .fb_set_cmap = sisfb_set_cmap, 1986 .fb_set_cmap = sisfb_set_cmap,
2254 .fb_pan_display = sisfb_pan_display, 1987 .fb_pan_display = sisfb_pan_display,
2255 .fb_ioctl = sisfb_ioctl 1988 .fb_ioctl = sisfb_ioctl
2256}; 1989};
2257#endif 1990#endif
2258 1991
2259#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 1992#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2260static struct fb_ops sisfb_ops = { 1993static struct fb_ops sisfb_ops = {
2261 .owner = THIS_MODULE, 1994 .owner = THIS_MODULE,
2262 .fb_open = sisfb_open, 1995 .fb_open = sisfb_open,
2263 .fb_release = sisfb_release, 1996 .fb_release = sisfb_release,
2264 .fb_check_var = sisfb_check_var, 1997 .fb_check_var = sisfb_check_var,
2265 .fb_set_par = sisfb_set_par, 1998 .fb_set_par = sisfb_set_par,
2266 .fb_setcolreg = sisfb_setcolreg, 1999 .fb_setcolreg = sisfb_setcolreg,
2267 .fb_pan_display = sisfb_pan_display, 2000 .fb_pan_display = sisfb_pan_display,
2268 .fb_blank = sisfb_blank, 2001 .fb_blank = sisfb_blank,
2269 .fb_fillrect = fbcon_sis_fillrect, 2002 .fb_fillrect = fbcon_sis_fillrect,
2270 .fb_copyarea = fbcon_sis_copyarea, 2003 .fb_copyarea = fbcon_sis_copyarea,
2271 .fb_imageblit = cfb_imageblit, 2004 .fb_imageblit = cfb_imageblit,
2272 .fb_cursor = soft_cursor, 2005 .fb_cursor = soft_cursor,
2273 .fb_sync = fbcon_sis_sync, 2006 .fb_sync = fbcon_sis_sync,
2274 .fb_ioctl = sisfb_ioctl, 2007#ifdef SIS_NEW_CONFIG_COMPAT
2275#ifdef CONFIG_COMPAT 2008 .fb_compat_ioctl= sisfb_compat_ioctl,
2276 .fb_compat_ioctl = sisfb_compat_ioctl,
2277#endif 2009#endif
2010 .fb_ioctl = sisfb_ioctl
2278}; 2011};
2279#endif 2012#endif
2280 2013
2281/* ---------------- Chip generation dependent routines ---------------- */ 2014/* ---------------- Chip generation dependent routines ---------------- */
2282 2015
2283static struct pci_dev * sisfb_get_northbridge(int basechipid) 2016static struct pci_dev * __devinit
2017sisfb_get_northbridge(int basechipid)
2284{ 2018{
2285 struct pci_dev *pdev = NULL; 2019 struct pci_dev *pdev = NULL;
2286 int nbridgenum, nbridgeidx, i; 2020 int nbridgenum, nbridgeidx, i;
2287 const unsigned short nbridgeids[] = { 2021 static const unsigned short nbridgeids[] = {
2288 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */ 2022 PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */
2289 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */ 2023 PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */
2290 PCI_DEVICE_ID_SI_730, 2024 PCI_DEVICE_ID_SI_730,
@@ -2292,13 +2026,14 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
2292 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */ 2026 PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */
2293 PCI_DEVICE_ID_SI_651, 2027 PCI_DEVICE_ID_SI_651,
2294 PCI_DEVICE_ID_SI_740, 2028 PCI_DEVICE_ID_SI_740,
2295 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760 VGA */ 2029 PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760/761 VGA */
2296 PCI_DEVICE_ID_SI_741, 2030 PCI_DEVICE_ID_SI_741,
2297 PCI_DEVICE_ID_SI_660, 2031 PCI_DEVICE_ID_SI_660,
2298 PCI_DEVICE_ID_SI_760 2032 PCI_DEVICE_ID_SI_760,
2033 PCI_DEVICE_ID_SI_761
2299 }; 2034 };
2300 2035
2301 switch(basechipid) { 2036 switch(basechipid) {
2302#ifdef CONFIG_FB_SIS_300 2037#ifdef CONFIG_FB_SIS_300
2303 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break; 2038 case SIS_540: nbridgeidx = 0; nbridgenum = 1; break;
2304 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break; 2039 case SIS_630: nbridgeidx = 1; nbridgenum = 2; break;
@@ -2306,35 +2041,40 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
2306#ifdef CONFIG_FB_SIS_315 2041#ifdef CONFIG_FB_SIS_315
2307 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break; 2042 case SIS_550: nbridgeidx = 3; nbridgenum = 1; break;
2308 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break; 2043 case SIS_650: nbridgeidx = 4; nbridgenum = 3; break;
2309 case SIS_660: nbridgeidx = 7; nbridgenum = 4; break; 2044 case SIS_660: nbridgeidx = 7; nbridgenum = 5; break;
2310#endif 2045#endif
2311 default: return NULL; 2046 default: return NULL;
2312 } 2047 }
2313 for(i = 0; i < nbridgenum; i++) { 2048 for(i = 0; i < nbridgenum; i++) {
2314 if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break; 2049 if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI,
2050 nbridgeids[nbridgeidx+i], NULL)))
2051 break;
2315 } 2052 }
2316 return pdev; 2053 return pdev;
2317} 2054}
2318 2055
2319static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo) 2056static int __devinit
2057sisfb_get_dram_size(struct sis_video_info *ivideo)
2320{ 2058{
2321#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2059#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2322 u8 reg; 2060 u8 reg;
2323#endif 2061#endif
2324 2062
2325 ivideo->video_size = 0; 2063 ivideo->video_size = 0;
2064 ivideo->UMAsize = ivideo->LFBsize = 0;
2326 2065
2327 switch(ivideo->chip) { 2066 switch(ivideo->chip) {
2328#ifdef CONFIG_FB_SIS_300 2067#ifdef CONFIG_FB_SIS_300
2329 case SIS_300: 2068 case SIS_300:
2330 inSISIDXREG(SISSR, 0x14, reg); 2069 inSISIDXREG(SISSR, 0x14, reg);
2331 ivideo->video_size = ((reg & 0x3F) + 1) << 20; 2070 ivideo->video_size = ((reg & 0x3F) + 1) << 20;
2332 break; 2071 break;
2333 case SIS_540: 2072 case SIS_540:
2334 case SIS_630: 2073 case SIS_630:
2335 case SIS_730: 2074 case SIS_730:
2336 if(!ivideo->nbridge) return -1; 2075 if(!ivideo->nbridge)
2337 pci_read_config_byte(ivideo->nbridge, 0x63, &reg); 2076 return -1;
2077 pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
2338 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21); 2078 ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
2339 break; 2079 break;
2340#endif 2080#endif
@@ -2342,45 +2082,68 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
2342 case SIS_315H: 2082 case SIS_315H:
2343 case SIS_315PRO: 2083 case SIS_315PRO:
2344 case SIS_315: 2084 case SIS_315:
2345 inSISIDXREG(SISSR, 0x14, reg); 2085 inSISIDXREG(SISSR, 0x14, reg);
2346 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2086 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2347 switch((reg >> 2) & 0x03) { 2087 switch((reg >> 2) & 0x03) {
2348 case 0x01: 2088 case 0x01:
2349 case 0x03: 2089 case 0x03:
2350 ivideo->video_size <<= 1; 2090 ivideo->video_size <<= 1;
2351 break; 2091 break;
2352 case 0x02: 2092 case 0x02:
2353 ivideo->video_size += (ivideo->video_size/2); 2093 ivideo->video_size += (ivideo->video_size/2);
2354 } 2094 }
2355 break; 2095 break;
2356 case SIS_330: 2096 case SIS_330:
2357 inSISIDXREG(SISSR, 0x14, reg); 2097 inSISIDXREG(SISSR, 0x14, reg);
2358 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2098 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2359 if(reg & 0x0c) ivideo->video_size <<= 1; 2099 if(reg & 0x0c) ivideo->video_size <<= 1;
2360 break; 2100 break;
2361 case SIS_550: 2101 case SIS_550:
2362 case SIS_650: 2102 case SIS_650:
2363 case SIS_740: 2103 case SIS_740:
2364 inSISIDXREG(SISSR, 0x14, reg); 2104 inSISIDXREG(SISSR, 0x14, reg);
2365 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20; 2105 ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
2366 break; 2106 break;
2367 case SIS_661: 2107 case SIS_661:
2368 case SIS_741: 2108 case SIS_741:
2369 inSISIDXREG(SISCR, 0x79, reg); 2109 inSISIDXREG(SISCR, 0x79, reg);
2370 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; 2110 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2371 break; 2111 break;
2372 case SIS_660: 2112 case SIS_660:
2373 case SIS_760: 2113 case SIS_760:
2114 case SIS_761:
2374 inSISIDXREG(SISCR, 0x79, reg); 2115 inSISIDXREG(SISCR, 0x79, reg);
2375 reg = (reg & 0xf0) >> 4; 2116 reg = (reg & 0xf0) >> 4;
2376 if(reg) ivideo->video_size = (1 << reg) << 20; 2117 if(reg) {
2118 ivideo->video_size = (1 << reg) << 20;
2119 ivideo->UMAsize = ivideo->video_size;
2120 }
2377 inSISIDXREG(SISCR, 0x78, reg); 2121 inSISIDXREG(SISCR, 0x78, reg);
2378 reg &= 0x30; 2122 reg &= 0x30;
2379 if(reg) { 2123 if(reg) {
2380 if(reg == 0x10) ivideo->video_size += (32 << 20); 2124 if(reg == 0x10) {
2381 else ivideo->video_size += (64 << 20); 2125 ivideo->LFBsize = (32 << 20);
2126 } else {
2127 ivideo->LFBsize = (64 << 20);
2128 }
2129 ivideo->video_size += ivideo->LFBsize;
2382 } 2130 }
2383 break; 2131 break;
2132 case SIS_340:
2133 case XGI_20:
2134 case XGI_40:
2135 inSISIDXREG(SISSR, 0x14, reg);
2136 ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2137 if(ivideo->chip != XGI_20) {
2138 reg = (reg & 0x0c) >> 2;
2139 if(ivideo->revision_id == 2) {
2140 if(reg & 0x01) reg = 0x02;
2141 else reg = 0x00;
2142 }
2143 if(reg == 0x02) ivideo->video_size <<= 1;
2144 else if(reg == 0x03) ivideo->video_size <<= 2;
2145 }
2146 break;
2384#endif 2147#endif
2385 default: 2148 default:
2386 return -1; 2149 return -1;
@@ -2390,17 +2153,24 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
2390 2153
2391/* -------------- video bridge device detection --------------- */ 2154/* -------------- video bridge device detection --------------- */
2392 2155
2393static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo) 2156static void __devinit
2157sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2394{ 2158{
2395 u8 cr32, temp; 2159 u8 cr32, temp;
2396 2160
2161 /* No CRT2 on XGI Z7 */
2162 if(ivideo->chip == XGI_20) {
2163 ivideo->sisfb_crt1off = 0;
2164 return;
2165 }
2166
2397#ifdef CONFIG_FB_SIS_300 2167#ifdef CONFIG_FB_SIS_300
2398 if(ivideo->sisvga_engine == SIS_300_VGA) { 2168 if(ivideo->sisvga_engine == SIS_300_VGA) {
2399 inSISIDXREG(SISSR, 0x17, temp); 2169 inSISIDXREG(SISSR, 0x17, temp);
2400 if((temp & 0x0F) && (ivideo->chip != SIS_300)) { 2170 if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
2401 /* PAL/NTSC is stored on SR16 on such machines */ 2171 /* PAL/NTSC is stored on SR16 on such machines */
2402 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) { 2172 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
2403 inSISIDXREG(SISSR, 0x16, temp); 2173 inSISIDXREG(SISSR, 0x16, temp);
2404 if(temp & 0x20) 2174 if(temp & 0x20)
2405 ivideo->vbflags |= TV_PAL; 2175 ivideo->vbflags |= TV_PAL;
2406 else 2176 else
@@ -2435,28 +2205,29 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2435 2205
2436 if(ivideo->sisfb_tvplug != -1) { 2206 if(ivideo->sisfb_tvplug != -1) {
2437 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2207 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2438 (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) { 2208 (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) {
2439 if(ivideo->sisfb_tvplug & TV_YPBPR) { 2209 if(ivideo->sisfb_tvplug & TV_YPBPR) {
2440 ivideo->sisfb_tvplug = -1; 2210 ivideo->sisfb_tvplug = -1;
2441 printk(KERN_ERR "sisfb: YPbPr not supported\n"); 2211 printk(KERN_ERR "sisfb: YPbPr not supported\n");
2442 } 2212 }
2443 } 2213 }
2444 } 2214 }
2445 if(ivideo->sisfb_tvplug != -1) { 2215 if(ivideo->sisfb_tvplug != -1) {
2446 if( (ivideo->sisvga_engine != SIS_315_VGA) || 2216 if( (ivideo->sisvga_engine != SIS_315_VGA) ||
2447 (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) { 2217 (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) {
2448 if(ivideo->sisfb_tvplug & TV_HIVISION) { 2218 if(ivideo->sisfb_tvplug & TV_HIVISION) {
2449 ivideo->sisfb_tvplug = -1; 2219 ivideo->sisfb_tvplug = -1;
2450 printk(KERN_ERR "sisfb: HiVision not supported\n"); 2220 printk(KERN_ERR "sisfb: HiVision not supported\n");
2451 } 2221 }
2452 } 2222 }
2453 } 2223 }
2454 if(ivideo->sisfb_tvstd != -1) { 2224 if(ivideo->sisfb_tvstd != -1) {
2455 if( (!(ivideo->vbflags & VB_SISBRIDGE)) && 2225 if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) &&
2456 (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) { 2226 (!((ivideo->sisvga_engine == SIS_315_VGA) &&
2227 (ivideo->vbflags2 & VB2_CHRONTEL))) ) {
2457 if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) { 2228 if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
2458 ivideo->sisfb_tvstd = -1; 2229 ivideo->sisfb_tvstd = -1;
2459 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n"); 2230 printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
2460 } 2231 }
2461 } 2232 }
2462 } 2233 }
@@ -2468,7 +2239,7 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2468 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */ 2239 if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
2469 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION; 2240 else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION;
2470 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART; 2241 else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART;
2471 else { 2242 else {
2472 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO; 2243 if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO;
2473 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO; 2244 if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
2474 } 2245 }
@@ -2485,165 +2256,44 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
2485 } 2256 }
2486 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) { 2257 if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
2487 if(ivideo->sisvga_engine == SIS_300_VGA) { 2258 if(ivideo->sisvga_engine == SIS_300_VGA) {
2488 inSISIDXREG(SISSR, 0x38, temp); 2259 inSISIDXREG(SISSR, 0x38, temp);
2489 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2260 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2490 else ivideo->vbflags |= TV_NTSC; 2261 else ivideo->vbflags |= TV_NTSC;
2491 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) { 2262 } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
2492 inSISIDXREG(SISSR, 0x38, temp); 2263 inSISIDXREG(SISSR, 0x38, temp);
2493 if(temp & 0x01) ivideo->vbflags |= TV_PAL; 2264 if(temp & 0x01) ivideo->vbflags |= TV_PAL;
2494 else ivideo->vbflags |= TV_NTSC; 2265 else ivideo->vbflags |= TV_NTSC;
2495 } else { 2266 } else {
2496 inSISIDXREG(SISCR, 0x79, temp); 2267 inSISIDXREG(SISCR, 0x79, temp);
2497 if(temp & 0x20) ivideo->vbflags |= TV_PAL; 2268 if(temp & 0x20) ivideo->vbflags |= TV_PAL;
2498 else ivideo->vbflags |= TV_NTSC; 2269 else ivideo->vbflags |= TV_NTSC;
2499 } 2270 }
2500 } 2271 }
2501 } 2272 }
2502 2273
2503 /* Copy forceCRT1 option to CRT1off if option is given */ 2274 /* Copy forceCRT1 option to CRT1off if option is given */
2504 if(ivideo->sisfb_forcecrt1 != -1) { 2275 if(ivideo->sisfb_forcecrt1 != -1) {
2505 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1; 2276 ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
2506 }
2507}
2508
2509static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
2510{
2511 char stdstr[] = "sisfb: Detected";
2512 char bridgestr[] = "video bridge";
2513 u8 vb_chipid;
2514 u8 reg;
2515
2516 inSISIDXREG(SISPART4, 0x00, vb_chipid);
2517 switch(vb_chipid) {
2518 case 0x01:
2519 inSISIDXREG(SISPART4, 0x01, reg);
2520 if(reg < 0xb0) {
2521 ivideo->vbflags |= VB_301;
2522 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
2523 } else if(reg < 0xc0) {
2524 ivideo->vbflags |= VB_301B;
2525 inSISIDXREG(SISPART4,0x23,reg);
2526 if(!(reg & 0x02)) {
2527 ivideo->vbflags |= VB_30xBDH;
2528 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
2529 } else {
2530 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
2531 }
2532 } else if(reg < 0xd0) {
2533 ivideo->vbflags |= VB_301C;
2534 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
2535 } else if(reg < 0xe0) {
2536 ivideo->vbflags |= VB_301LV;
2537 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
2538 } else if(reg <= 0xe1) {
2539 inSISIDXREG(SISPART4,0x39,reg);
2540 if(reg == 0xff) {
2541 ivideo->vbflags |= VB_302LV;
2542 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
2543 } else {
2544 ivideo->vbflags |= VB_301C;
2545 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
2546#if 0
2547 ivideo->vbflags |= VB_302ELV;
2548 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
2549#endif
2550 }
2551 }
2552 break;
2553 case 0x02:
2554 ivideo->vbflags |= VB_302B;
2555 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
2556 break;
2557 }
2558
2559 if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
2560 inSISIDXREG(SISCR, 0x37, reg);
2561 reg &= SIS_EXTERNAL_CHIP_MASK;
2562 reg >>= 1;
2563 if(ivideo->sisvga_engine == SIS_300_VGA) {
2564#ifdef CONFIG_FB_SIS_300
2565 switch(reg) {
2566 case SIS_EXTERNAL_CHIP_LVDS:
2567 ivideo->vbflags |= VB_LVDS;
2568 break;
2569 case SIS_EXTERNAL_CHIP_TRUMPION:
2570 ivideo->vbflags |= VB_TRUMPION;
2571 break;
2572 case SIS_EXTERNAL_CHIP_CHRONTEL:
2573 ivideo->vbflags |= VB_CHRONTEL;
2574 break;
2575 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
2576 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2577 break;
2578 }
2579 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
2580#endif
2581 } else if(ivideo->chip < SIS_661) {
2582#ifdef CONFIG_FB_SIS_315
2583 switch (reg) {
2584 case SIS310_EXTERNAL_CHIP_LVDS:
2585 ivideo->vbflags |= VB_LVDS;
2586 break;
2587 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
2588 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2589 break;
2590 }
2591 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
2592#endif
2593 } else if(ivideo->chip >= SIS_661) {
2594#ifdef CONFIG_FB_SIS_315
2595 inSISIDXREG(SISCR, 0x38, reg);
2596 reg >>= 5;
2597 switch(reg) {
2598 case 0x02:
2599 ivideo->vbflags |= VB_LVDS;
2600 break;
2601 case 0x03:
2602 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
2603 break;
2604 case 0x04:
2605 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
2606 break;
2607 }
2608 if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
2609#endif
2610 }
2611 if(ivideo->vbflags & VB_LVDS) {
2612 printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
2613 }
2614 if(ivideo->vbflags & VB_TRUMPION) {
2615 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
2616 }
2617 if(ivideo->vbflags & VB_CHRONTEL) {
2618 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
2619 }
2620 if(ivideo->vbflags & VB_CONEXANT) {
2621 printk(KERN_INFO "%s Conexant external device\n", stdstr);
2622 }
2623 }
2624
2625 if(ivideo->vbflags & VB_SISBRIDGE) {
2626 SiS_Sense30x(ivideo);
2627 } else if(ivideo->vbflags & VB_CHRONTEL) {
2628 SiS_SenseCh(ivideo);
2629 } 2277 }
2630} 2278}
2631 2279
2632/* ------------------ Sensing routines ------------------ */ 2280/* ------------------ Sensing routines ------------------ */
2633 2281
2634static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo) 2282static BOOLEAN __devinit
2283sisfb_test_DDC1(struct sis_video_info *ivideo)
2635{ 2284{
2636 unsigned short old; 2285 unsigned short old;
2637 int count = 48; 2286 int count = 48;
2638 2287
2639 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr); 2288 old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
2640 do { 2289 do {
2641 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break; 2290 if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
2642 } while(count--); 2291 } while(count--);
2643 return (count == -1) ? FALSE : TRUE; 2292 return (count == -1) ? FALSE : TRUE;
2644} 2293}
2645 2294
2646static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo) 2295static void __devinit
2296sisfb_sense_crt1(struct sis_video_info *ivideo)
2647{ 2297{
2648 BOOLEAN mustwait = FALSE; 2298 BOOLEAN mustwait = FALSE;
2649 u8 sr1F, cr17; 2299 u8 sr1F, cr17;
@@ -2699,7 +2349,8 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
2699 if(temp == 0xffff) { 2349 if(temp == 0xffff) {
2700 i = 3; 2350 i = 3;
2701 do { 2351 do {
2702 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL); 2352 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
2353 ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2);
2703 } while(((temp == 0) || (temp == 0xffff)) && i--); 2354 } while(((temp == 0) || (temp == 0xffff)) && i--);
2704 2355
2705 if((temp == 0) || (temp == 0xffff)) { 2356 if((temp == 0) || (temp == 0xffff)) {
@@ -2723,7 +2374,96 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
2723} 2374}
2724 2375
2725/* Determine and detect attached devices on SiS30x */ 2376/* Determine and detect attached devices on SiS30x */
2726static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test) 2377static void __devinit
2378SiS_SenseLCD(struct sis_video_info *ivideo)
2379{
2380 unsigned char buffer[256];
2381 unsigned short temp, realcrtno, i;
2382 u8 reg, cr37 = 0, paneltype = 0;
2383 u16 xres, yres;
2384
2385 ivideo->SiS_Pr.PanelSelfDetected = FALSE;
2386
2387 /* LCD detection only for TMDS bridges */
2388 if(!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE))
2389 return;
2390 if(ivideo->vbflags2 & VB2_30xBDH)
2391 return;
2392
2393 /* If LCD already set up by BIOS, skip it */
2394 inSISIDXREG(SISCR, 0x32, reg);
2395 if(reg & 0x08)
2396 return;
2397
2398 realcrtno = 1;
2399 if(ivideo->SiS_Pr.DDCPortMixup)
2400 realcrtno = 0;
2401
2402 /* Check DDC capabilities */
2403 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
2404 realcrtno, 0, &buffer[0], ivideo->vbflags2);
2405
2406 if((!temp) || (temp == 0xffff) || (!(temp & 0x02)))
2407 return;
2408
2409 /* Read DDC data */
2410 i = 3; /* Number of retrys */
2411 do {
2412 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
2413 ivideo->sisvga_engine, realcrtno, 1,
2414 &buffer[0], ivideo->vbflags2);
2415 } while((temp) && i--);
2416
2417 if(temp)
2418 return;
2419
2420 /* No digital device */
2421 if(!(buffer[0x14] & 0x80))
2422 return;
2423
2424 /* First detailed timing preferred timing? */
2425 if(!(buffer[0x18] & 0x02))
2426 return;
2427
2428 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
2429 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
2430
2431 switch(xres) {
2432 case 1024:
2433 if(yres == 768)
2434 paneltype = 0x02;
2435 break;
2436 case 1280:
2437 if(yres == 1024)
2438 paneltype = 0x03;
2439 break;
2440 case 1600:
2441 if((yres == 1200) && (ivideo->vbflags2 & VB2_30xC))
2442 paneltype = 0x0b;
2443 break;
2444 }
2445
2446 if(!paneltype)
2447 return;
2448
2449 if(buffer[0x23])
2450 cr37 |= 0x10;
2451
2452 if((buffer[0x47] & 0x18) == 0x18)
2453 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
2454 else
2455 cr37 |= 0xc0;
2456
2457 outSISIDXREG(SISCR, 0x36, paneltype);
2458 cr37 &= 0xf1;
2459 setSISIDXREG(SISCR, 0x37, 0x0c, cr37);
2460 orSISIDXREG(SISCR, 0x32, 0x08);
2461
2462 ivideo->SiS_Pr.PanelSelfDetected = TRUE;
2463}
2464
2465static int __devinit
2466SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
2727{ 2467{
2728 int temp, mytest, result, i, j; 2468 int temp, mytest, result, i, j;
2729 2469
@@ -2749,10 +2489,11 @@ static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 tes
2749 } 2489 }
2750 if((result == 0) || (result >= 2)) break; 2490 if((result == 0) || (result >= 2)) break;
2751 } 2491 }
2752 return(result); 2492 return result;
2753} 2493}
2754 2494
2755static void __devinit SiS_Sense30x(struct sis_video_info *ivideo) 2495static void __devinit
2496SiS_Sense30x(struct sis_video_info *ivideo)
2756{ 2497{
2757 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0; 2498 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
2758 u16 svhs=0, svhs_c=0; 2499 u16 svhs=0, svhs_c=0;
@@ -2762,36 +2503,51 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2762 char stdstr[] = "sisfb: Detected"; 2503 char stdstr[] = "sisfb: Detected";
2763 char tvstr[] = "TV connected to"; 2504 char tvstr[] = "TV connected to";
2764 2505
2765 if(ivideo->vbflags & VB_301) { 2506 if(ivideo->vbflags2 & VB2_301) {
2766 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1; 2507 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
2767 inSISIDXREG(SISPART4,0x01,myflag); 2508 inSISIDXREG(SISPART4,0x01,myflag);
2768 if(myflag & 0x04) { 2509 if(myflag & 0x04) {
2769 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd; 2510 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
2770 } 2511 }
2771 } else if(ivideo->vbflags & (VB_301B | VB_302B)) { 2512 } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) {
2772 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190; 2513 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
2773 } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) { 2514 } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) {
2774 svhs = 0x0200; cvbs = 0x0100; 2515 svhs = 0x0200; cvbs = 0x0100;
2775 } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) { 2516 } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) {
2776 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190; 2517 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
2777 } else return; 2518 } else
2519 return;
2778 2520
2779 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804; 2521 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
2780 if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) { 2522 if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) {
2781 svhs_c = 0x0408; cvbs_c = 0x0808; 2523 svhs_c = 0x0408; cvbs_c = 0x0808;
2782 } 2524 }
2525
2783 biosflag = 2; 2526 biosflag = 2;
2527 if(ivideo->haveXGIROM) {
2528 biosflag = ivideo->bios_abase[0x58] & 0x03;
2529 } else if(ivideo->newrom) {
2530 if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01;
2531 } else if(ivideo->sisvga_engine == SIS_300_VGA) {
2532 if(ivideo->bios_abase) {
2533 biosflag = ivideo->bios_abase[0xfe] & 0x03;
2534 }
2535 }
2784 2536
2785 if(ivideo->chip == SIS_300) { 2537 if(ivideo->chip == SIS_300) {
2786 inSISIDXREG(SISSR,0x3b,myflag); 2538 inSISIDXREG(SISSR,0x3b,myflag);
2787 if(!(myflag & 0x01)) vga2 = vga2_c = 0; 2539 if(!(myflag & 0x01)) vga2 = vga2_c = 0;
2788 } 2540 }
2789 2541
2542 if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) {
2543 vga2 = vga2_c = 0;
2544 }
2545
2790 inSISIDXREG(SISSR,0x1e,backupSR_1e); 2546 inSISIDXREG(SISSR,0x1e,backupSR_1e);
2791 orSISIDXREG(SISSR,0x1e,0x20); 2547 orSISIDXREG(SISSR,0x1e,0x20);
2792 2548
2793 inSISIDXREG(SISPART4,0x0d,backupP4_0d); 2549 inSISIDXREG(SISPART4,0x0d,backupP4_0d);
2794 if(ivideo->vbflags & VB_301C) { 2550 if(ivideo->vbflags2 & VB2_30xC) {
2795 setSISIDXREG(SISPART4,0x0d,~0x07,0x01); 2551 setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
2796 } else { 2552 } else {
2797 orSISIDXREG(SISPART4,0x0d,0x04); 2553 orSISIDXREG(SISPART4,0x0d,0x04);
@@ -2802,11 +2558,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2802 outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc)); 2558 outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
2803 2559
2804 inSISIDXREG(SISPART2,0x4d,backupP2_4d); 2560 inSISIDXREG(SISPART2,0x4d,backupP2_4d);
2805 if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) { 2561 if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) {
2806 outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10)); 2562 outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
2807 } 2563 }
2808 2564
2809 if(!(ivideo->vbflags & VB_301C)) { 2565 if(!(ivideo->vbflags2 & VB2_30xCLV)) {
2810 SISDoSense(ivideo, 0, 0); 2566 SISDoSense(ivideo, 0, 0);
2811 } 2567 }
2812 2568
@@ -2826,12 +2582,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2826 2582
2827 andSISIDXREG(SISCR, 0x32, 0x3f); 2583 andSISIDXREG(SISCR, 0x32, 0x3f);
2828 2584
2829 if(ivideo->vbflags & VB_301C) { 2585 if(ivideo->vbflags2 & VB2_30xCLV) {
2830 orSISIDXREG(SISPART4,0x0d,0x04); 2586 orSISIDXREG(SISPART4,0x0d,0x04);
2831 } 2587 }
2832 2588
2833 if((ivideo->sisvga_engine == SIS_315_VGA) && 2589 if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
2834 (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
2835 outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10)); 2590 outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
2836 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); 2591 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
2837 if((result = SISDoSense(ivideo, svhs, 0x0604))) { 2592 if((result = SISDoSense(ivideo, svhs, 0x0604))) {
@@ -2864,7 +2619,7 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2864 outSISIDXREG(SISPART4,0x0d,backupP4_0d); 2619 outSISIDXREG(SISPART4,0x0d,backupP4_0d);
2865 outSISIDXREG(SISSR,0x1e,backupSR_1e); 2620 outSISIDXREG(SISSR,0x1e,backupSR_1e);
2866 2621
2867 if(ivideo->vbflags & VB_301C) { 2622 if(ivideo->vbflags2 & VB2_30xCLV) {
2868 inSISIDXREG(SISPART2,0x00,biosflag); 2623 inSISIDXREG(SISPART2,0x00,biosflag);
2869 if(biosflag & 0x20) { 2624 if(biosflag & 0x20) {
2870 for(myflag = 2; myflag > 0; myflag--) { 2625 for(myflag = 2; myflag > 0; myflag--) {
@@ -2878,7 +2633,8 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
2878} 2633}
2879 2634
2880/* Determine and detect attached TV's on Chrontel */ 2635/* Determine and detect attached TV's on Chrontel */
2881static void __devinit SiS_SenseCh(struct sis_video_info *ivideo) 2636static void __devinit
2637SiS_SenseCh(struct sis_video_info *ivideo)
2882{ 2638{
2883#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2639#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2884 u8 temp1, temp2; 2640 u8 temp1, temp2;
@@ -2899,7 +2655,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2899 /* See Chrontel TB31 for explanation */ 2655 /* See Chrontel TB31 for explanation */
2900 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2656 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2901 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) { 2657 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
2902 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e); 2658 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b);
2903 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2659 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2904 } 2660 }
2905 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25); 2661 temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
@@ -2909,15 +2665,15 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2909 /* Read power status */ 2665 /* Read power status */
2910 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e); 2666 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
2911 if((temp1 & 0x03) != 0x03) { 2667 if((temp1 & 0x03) != 0x03) {
2912 /* Power all outputs */ 2668 /* Power all outputs */
2913 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E); 2669 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b);
2914 SiS_DDC2Delay(&ivideo->SiS_Pr, 300); 2670 SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
2915 } 2671 }
2916 /* Sense connected TV devices */ 2672 /* Sense connected TV devices */
2917 for(i = 0; i < 3; i++) { 2673 for(i = 0; i < 3; i++) {
2918 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110); 2674 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01);
2919 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2675 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2920 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010); 2676 SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00);
2921 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2677 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2922 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10); 2678 temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
2923 if(!(temp1 & 0x08)) test[i] = 0x02; 2679 if(!(temp1 & 0x08)) test[i] = 0x02;
@@ -2930,7 +2686,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2930 else if(test[0] == test[2]) temp1 = test[0]; 2686 else if(test[0] == test[2]) temp1 = test[0];
2931 else if(test[1] == test[2]) temp1 = test[1]; 2687 else if(test[1] == test[2]) temp1 = test[1];
2932 else { 2688 else {
2933 printk(KERN_INFO 2689 printk(KERN_INFO
2934 "sisfb: TV detection unreliable - test results varied\n"); 2690 "sisfb: TV detection unreliable - test results varied\n");
2935 temp1 = test[2]; 2691 temp1 = test[2];
2936 } 2692 }
@@ -2945,11 +2701,11 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2945 orSISIDXREG(SISCR, 0x32, 0x01); 2701 orSISIDXREG(SISCR, 0x32, 0x01);
2946 andSISIDXREG(SISCR, 0x32, ~0x06); 2702 andSISIDXREG(SISCR, 0x32, ~0x06);
2947 } else { 2703 } else {
2948 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8); 2704 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
2949 andSISIDXREG(SISCR, 0x32, ~0x07); 2705 andSISIDXREG(SISCR, 0x32, ~0x07);
2950 } 2706 }
2951 } else if(temp1 == 0) { 2707 } else if(temp1 == 0) {
2952 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8); 2708 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
2953 andSISIDXREG(SISCR, 0x32, ~0x07); 2709 andSISIDXREG(SISCR, 0x32, ~0x07);
2954 } 2710 }
2955 /* Set general purpose IO for Chrontel communication */ 2711 /* Set general purpose IO for Chrontel communication */
@@ -2960,19 +2716,19 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2960 2716
2961#ifdef CONFIG_FB_SIS_315 2717#ifdef CONFIG_FB_SIS_315
2962 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */ 2718 ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
2963 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49); 2719 temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
2964 SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049); 2720 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20);
2965 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2721 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2966 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2722 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2967 temp2 |= 0x01; 2723 temp2 |= 0x01;
2968 SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20); 2724 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
2969 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2725 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2970 temp2 ^= 0x01; 2726 temp2 ^= 0x01;
2971 SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20); 2727 SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
2972 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96); 2728 SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
2973 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20); 2729 temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
2974 SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49); 2730 SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1);
2975 temp1 = 0; 2731 temp1 = 0;
2976 if(temp2 & 0x02) temp1 |= 0x01; 2732 if(temp2 & 0x02) temp1 |= 0x01;
2977 if(temp2 & 0x10) temp1 |= 0x01; 2733 if(temp2 & 0x10) temp1 |= 0x01;
2978 if(temp2 & 0x04) temp1 |= 0x02; 2734 if(temp2 & 0x04) temp1 |= 0x02;
@@ -2983,18 +2739,18 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
2983 ivideo->vbflags |= TV_AVIDEO; 2739 ivideo->vbflags |= TV_AVIDEO;
2984 orSISIDXREG(SISCR, 0x32, 0x01); 2740 orSISIDXREG(SISCR, 0x32, 0x01);
2985 andSISIDXREG(SISCR, 0x32, ~0x06); 2741 andSISIDXREG(SISCR, 0x32, ~0x06);
2986 break; 2742 break;
2987 case 0x02: 2743 case 0x02:
2988 printk(KERN_INFO "%s SVIDEO output\n", stdstr); 2744 printk(KERN_INFO "%s SVIDEO output\n", stdstr);
2989 ivideo->vbflags |= TV_SVIDEO; 2745 ivideo->vbflags |= TV_SVIDEO;
2990 orSISIDXREG(SISCR, 0x32, 0x02); 2746 orSISIDXREG(SISCR, 0x32, 0x02);
2991 andSISIDXREG(SISCR, 0x32, ~0x05); 2747 andSISIDXREG(SISCR, 0x32, ~0x05);
2992 break; 2748 break;
2993 case 0x04: 2749 case 0x04:
2994 printk(KERN_INFO "%s SCART output\n", stdstr); 2750 printk(KERN_INFO "%s SCART output\n", stdstr);
2995 orSISIDXREG(SISCR, 0x32, 0x04); 2751 orSISIDXREG(SISCR, 0x32, 0x04);
2996 andSISIDXREG(SISCR, 0x32, ~0x03); 2752 andSISIDXREG(SISCR, 0x32, ~0x03);
2997 break; 2753 break;
2998 default: 2754 default:
2999 andSISIDXREG(SISCR, 0x32, ~0x07); 2755 andSISIDXREG(SISCR, 0x32, ~0x07);
3000 } 2756 }
@@ -3002,165 +2758,589 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
3002 } 2758 }
3003} 2759}
3004 2760
3005/* ------------------------ Heap routines -------------------------- */ 2761static void __devinit
3006 2762sisfb_get_VB_type(struct sis_video_info *ivideo)
3007static u32 __devinit
3008sisfb_getheapstart(struct sis_video_info *ivideo)
3009{ 2763{
3010 u32 ret = ivideo->sisfb_parm_mem * 1024; 2764 char stdstr[] = "sisfb: Detected";
3011 u32 max = ivideo->video_size - ivideo->hwcursor_size; 2765 char bridgestr[] = "video bridge";
3012 u32 def; 2766 u8 vb_chipid;
2767 u8 reg;
3013 2768
3014 /* Calculate heap start = end of memory for console 2769 /* No CRT2 on XGI Z7 */
3015 * 2770 if(ivideo->chip == XGI_20)
3016 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ 2771 return;
3017 * C = console, D = heap, H = HWCursor, Q = cmd-queue
3018 *
3019 * Basically given by "mem" parameter
3020 *
3021 * maximum = videosize - cmd_queue - hwcursor
3022 * (results in a heap of size 0)
3023 * default = SiS 300: depends on videosize
3024 * SiS 315/330: 32k below max
3025 */
3026 2772
3027 if(ivideo->sisvga_engine == SIS_300_VGA) { 2773 inSISIDXREG(SISPART4, 0x00, vb_chipid);
3028 max -= TURBO_QUEUE_AREA_SIZE; 2774 switch(vb_chipid) {
3029 if(ivideo->video_size > 0x1000000) { 2775 case 0x01:
3030 def = 0xc00000; 2776 inSISIDXREG(SISPART4, 0x01, reg);
3031 } else if(ivideo->video_size > 0x800000) { 2777 if(reg < 0xb0) {
3032 def = 0x800000; 2778 ivideo->vbflags |= VB_301; /* Deprecated */
3033 } else { 2779 ivideo->vbflags2 |= VB2_301;
3034 def = 0x400000; 2780 printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
3035 } 2781 } else if(reg < 0xc0) {
3036 } else { 2782 ivideo->vbflags |= VB_301B; /* Deprecated */
3037 max -= COMMAND_QUEUE_AREA_SIZE; 2783 ivideo->vbflags2 |= VB2_301B;
3038 def = max - 0x8000; 2784 inSISIDXREG(SISPART4,0x23,reg);
2785 if(!(reg & 0x02)) {
2786 ivideo->vbflags |= VB_30xBDH; /* Deprecated */
2787 ivideo->vbflags2 |= VB2_30xBDH;
2788 printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
2789 } else {
2790 printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
2791 }
2792 } else if(reg < 0xd0) {
2793 ivideo->vbflags |= VB_301C; /* Deprecated */
2794 ivideo->vbflags2 |= VB2_301C;
2795 printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
2796 } else if(reg < 0xe0) {
2797 ivideo->vbflags |= VB_301LV; /* Deprecated */
2798 ivideo->vbflags2 |= VB2_301LV;
2799 printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
2800 } else if(reg <= 0xe1) {
2801 inSISIDXREG(SISPART4,0x39,reg);
2802 if(reg == 0xff) {
2803 ivideo->vbflags |= VB_302LV; /* Deprecated */
2804 ivideo->vbflags2 |= VB2_302LV;
2805 printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
2806 } else {
2807 ivideo->vbflags |= VB_301C; /* Deprecated */
2808 ivideo->vbflags2 |= VB2_301C;
2809 printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
2810#if 0
2811 ivideo->vbflags |= VB_302ELV; /* Deprecated */
2812 ivideo->vbflags2 |= VB2_302ELV;
2813 printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
2814#endif
2815 }
2816 }
2817 break;
2818 case 0x02:
2819 ivideo->vbflags |= VB_302B; /* Deprecated */
2820 ivideo->vbflags2 |= VB2_302B;
2821 printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
2822 break;
3039 } 2823 }
3040 2824
3041 if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) { 2825 if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
3042 ret = def; 2826 inSISIDXREG(SISCR, 0x37, reg);
3043 } 2827 reg &= SIS_EXTERNAL_CHIP_MASK;
2828 reg >>= 1;
2829 if(ivideo->sisvga_engine == SIS_300_VGA) {
2830#ifdef CONFIG_FB_SIS_300
2831 switch(reg) {
2832 case SIS_EXTERNAL_CHIP_LVDS:
2833 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2834 ivideo->vbflags2 |= VB2_LVDS;
2835 break;
2836 case SIS_EXTERNAL_CHIP_TRUMPION:
2837 ivideo->vbflags |= (VB_LVDS | VB_TRUMPION); /* Deprecated */
2838 ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION);
2839 break;
2840 case SIS_EXTERNAL_CHIP_CHRONTEL:
2841 ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */
2842 ivideo->vbflags2 |= VB2_CHRONTEL;
2843 break;
2844 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
2845 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2846 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2847 break;
2848 }
2849 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1;
2850#endif
2851 } else if(ivideo->chip < SIS_661) {
2852#ifdef CONFIG_FB_SIS_315
2853 switch (reg) {
2854 case SIS310_EXTERNAL_CHIP_LVDS:
2855 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2856 ivideo->vbflags2 |= VB2_LVDS;
2857 break;
2858 case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
2859 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2860 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2861 break;
2862 }
2863 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
2864#endif
2865 } else if(ivideo->chip >= SIS_661) {
2866#ifdef CONFIG_FB_SIS_315
2867 inSISIDXREG(SISCR, 0x38, reg);
2868 reg >>= 5;
2869 switch(reg) {
2870 case 0x02:
2871 ivideo->vbflags |= VB_LVDS; /* Deprecated */
2872 ivideo->vbflags2 |= VB2_LVDS;
2873 break;
2874 case 0x03:
2875 ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
2876 ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
2877 break;
2878 case 0x04:
2879 ivideo->vbflags |= (VB_LVDS | VB_CONEXANT); /* Deprecated */
2880 ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT);
2881 break;
2882 }
2883 if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
2884#endif
2885 }
2886 if(ivideo->vbflags2 & VB2_LVDS) {
2887 printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
2888 }
2889 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) {
2890 printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
2891 }
2892 if(ivideo->vbflags2 & VB2_CHRONTEL) {
2893 printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
2894 }
2895 if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) {
2896 printk(KERN_INFO "%s Conexant external device\n", stdstr);
2897 }
2898 }
3044 2899
3045 return ret; 2900 if(ivideo->vbflags2 & VB2_SISBRIDGE) {
2901 SiS_SenseLCD(ivideo);
2902 SiS_Sense30x(ivideo);
2903 } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
2904 SiS_SenseCh(ivideo);
2905 }
3046} 2906}
3047 2907
3048static int __devinit 2908/* ---------- Engine initialization routines ------------ */
3049sisfb_heap_init(struct sis_video_info *ivideo) 2909
2910static void
2911sisfb_engine_init(struct sis_video_info *ivideo)
3050{ 2912{
3051 SIS_OH *poh;
3052 2913
3053 ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo); 2914 /* Initialize command queue (we use MMIO only) */
3054 2915
3055 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart; 2916 /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */
3056 ivideo->sisfb_heap_end = ivideo->video_vbase + ivideo->video_size;
3057 2917
3058 /* Initialize command queue (We use MMIO only) */ 2918 ivideo->caps &= ~(TURBO_QUEUE_CAP |
2919 MMIO_CMD_QUEUE_CAP |
2920 VM_CMD_QUEUE_CAP |
2921 AGP_CMD_QUEUE_CAP);
2922
2923#ifdef CONFIG_FB_SIS_300
2924 if(ivideo->sisvga_engine == SIS_300_VGA) {
2925 u32 tqueue_pos;
2926 u8 tq_state;
2927
2928 tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024);
2929
2930 inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
2931 tq_state |= 0xf0;
2932 tq_state &= 0xfc;
2933 tq_state |= (u8)(tqueue_pos >> 8);
2934 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
2935
2936 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
2937
2938 ivideo->caps |= TURBO_QUEUE_CAP;
2939 }
2940#endif
3059 2941
3060#ifdef CONFIG_FB_SIS_315 2942#ifdef CONFIG_FB_SIS_315
3061 if(ivideo->sisvga_engine == SIS_315_VGA) { 2943 if(ivideo->sisvga_engine == SIS_315_VGA) {
3062 u32 tempq = 0; 2944 u32 tempq = 0, templ;
3063 u8 temp = 0; 2945 u8 temp;
2946
2947 if(ivideo->chip == XGI_20) {
2948 switch(ivideo->cmdQueueSize) {
2949 case (64 * 1024):
2950 temp = SIS_CMD_QUEUE_SIZE_Z7_64k;
2951 break;
2952 case (128 * 1024):
2953 default:
2954 temp = SIS_CMD_QUEUE_SIZE_Z7_128k;
2955 }
2956 } else {
2957 switch(ivideo->cmdQueueSize) {
2958 case (4 * 1024 * 1024):
2959 temp = SIS_CMD_QUEUE_SIZE_4M;
2960 break;
2961 case (2 * 1024 * 1024):
2962 temp = SIS_CMD_QUEUE_SIZE_2M;
2963 break;
2964 case (1 * 1024 * 1024):
2965 temp = SIS_CMD_QUEUE_SIZE_1M;
2966 break;
2967 default:
2968 case (512 * 1024):
2969 temp = SIS_CMD_QUEUE_SIZE_512k;
2970 }
2971 }
2972
2973 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2974 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
2975
2976 if((ivideo->chip >= XGI_40) && ivideo->modechanged) {
2977 /* Must disable dual pipe on XGI_40. Can't do
2978 * this in MMIO mode, because it requires
2979 * setting/clearing a bit in the MMIO fire trigger
2980 * register.
2981 */
2982 if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) {
2983
2984 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0);
2985
2986 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE));
2987
2988 tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR);
2989 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq);
2990
2991 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
2992 MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq);
2993
2994 writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq);
2995 writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4);
2996 writel(0x168F0000, ivideo->video_vbase + tempq + 8);
2997 writel(0x168F0000, ivideo->video_vbase + tempq + 12);
2998
2999 MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16));
3000
3001 sisfb_syncaccel(ivideo);
3002
3003 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
3004
3005 }
3006 }
3007
3008 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
3009 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
3010
3011 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
3012 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
3013
3014 tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
3015 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
3064 3016
3065 ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; 3017 ivideo->caps |= MMIO_CMD_QUEUE_CAP;
3018 }
3019#endif
3066 3020
3067 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); 3021 ivideo->engineok = 1;
3068 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); 3022}
3069 3023
3070 tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT); 3024static void __devinit
3071 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq); 3025sisfb_detect_lcd_type(struct sis_video_info *ivideo)
3026{
3027 u8 reg;
3028 int i;
3072 3029
3073 temp = SIS_CMD_QUEUE_SIZE_512k; 3030 inSISIDXREG(SISCR, 0x36, reg);
3074 temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR); 3031 reg &= 0x0f;
3075 outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp); 3032 if(ivideo->sisvga_engine == SIS_300_VGA) {
3033 ivideo->CRT2LCDType = sis300paneltype[reg];
3034 } else if(ivideo->chip >= SIS_661) {
3035 ivideo->CRT2LCDType = sis661paneltype[reg];
3036 } else {
3037 ivideo->CRT2LCDType = sis310paneltype[reg];
3038 if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
3039 if((ivideo->CRT2LCDType != LCD_320x240_2) &&
3040 (ivideo->CRT2LCDType != LCD_320x240_3)) {
3041 ivideo->CRT2LCDType = LCD_320x240;
3042 }
3043 }
3044 }
3076 3045
3077 tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE); 3046 if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
3078 MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq); 3047 /* For broken BIOSes: Assume 1024x768, RGB18 */
3048 ivideo->CRT2LCDType = LCD_1024x768;
3049 setSISIDXREG(SISCR,0x36,0xf0,0x02);
3050 setSISIDXREG(SISCR,0x37,0xee,0x01);
3051 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
3052 }
3079 3053
3080 ivideo->caps |= MMIO_CMD_QUEUE_CAP; 3054 for(i = 0; i < SIS_LCD_NUMBER; i++) {
3081 } 3055 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
3056 ivideo->lcdxres = sis_lcd_data[i].xres;
3057 ivideo->lcdyres = sis_lcd_data[i].yres;
3058 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
3059 break;
3060 }
3061 }
3062
3063#ifdef CONFIG_FB_SIS_300
3064 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
3065 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024;
3066 ivideo->lcddefmodeidx = DEFAULT_MODE_1360;
3067 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
3068 ivideo->lcdxres = 848; ivideo->lcdyres = 480;
3069 ivideo->lcddefmodeidx = DEFAULT_MODE_848;
3070 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) {
3071 ivideo->lcdxres = 856; ivideo->lcdyres = 480;
3072 ivideo->lcddefmodeidx = DEFAULT_MODE_856;
3073 }
3082#endif 3074#endif
3083 3075
3076 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
3077 ivideo->lcdxres, ivideo->lcdyres);
3078}
3079
3080static void __devinit
3081sisfb_save_pdc_emi(struct sis_video_info *ivideo)
3082{
3084#ifdef CONFIG_FB_SIS_300 3083#ifdef CONFIG_FB_SIS_300
3085 if(ivideo->sisvga_engine == SIS_300_VGA) { 3084 /* Save the current PanelDelayCompensation if the LCD is currently used */
3086 unsigned long tqueue_pos; 3085 if(ivideo->sisvga_engine == SIS_300_VGA) {
3087 u8 tq_state; 3086 if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) {
3087 int tmp;
3088 inSISIDXREG(SISCR,0x30,tmp);
3089 if(tmp & 0x20) {
3090 /* Currently on LCD? If yes, read current pdc */
3091 inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
3092 ivideo->detectedpdc &= 0x3c;
3093 if(ivideo->SiS_Pr.PDC == -1) {
3094 /* Let option override detection */
3095 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
3096 }
3097 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
3098 ivideo->detectedpdc);
3099 }
3100 if((ivideo->SiS_Pr.PDC != -1) &&
3101 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
3102 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
3103 ivideo->SiS_Pr.PDC);
3104 }
3105 }
3106 }
3107#endif
3088 3108
3089 ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE; 3109#ifdef CONFIG_FB_SIS_315
3110 if(ivideo->sisvga_engine == SIS_315_VGA) {
3090 3111
3091 tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024); 3112 /* Try to find about LCDA */
3113 if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) {
3114 int tmp;
3115 inSISIDXREG(SISPART1,0x13,tmp);
3116 if(tmp & 0x04) {
3117 ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
3118 ivideo->detectedlcda = 0x03;
3119 }
3120 }
3092 3121
3093 inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); 3122 /* Save PDC */
3094 tq_state |= 0xf0; 3123 if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
3095 tq_state &= 0xfc; 3124 int tmp;
3096 tq_state |= (u8)(tqueue_pos >> 8); 3125 inSISIDXREG(SISCR,0x30,tmp);
3097 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); 3126 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
3127 /* Currently on LCD? If yes, read current pdc */
3128 u8 pdc;
3129 inSISIDXREG(SISPART1,0x2D,pdc);
3130 ivideo->detectedpdc = (pdc & 0x0f) << 1;
3131 ivideo->detectedpdca = (pdc & 0xf0) >> 3;
3132 inSISIDXREG(SISPART1,0x35,pdc);
3133 ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
3134 inSISIDXREG(SISPART1,0x20,pdc);
3135 ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
3136 if(ivideo->newrom) {
3137 /* New ROM invalidates other PDC resp. */
3138 if(ivideo->detectedlcda != 0xff) {
3139 ivideo->detectedpdc = 0xff;
3140 } else {
3141 ivideo->detectedpdca = 0xff;
3142 }
3143 }
3144 if(ivideo->SiS_Pr.PDC == -1) {
3145 if(ivideo->detectedpdc != 0xff) {
3146 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
3147 }
3148 }
3149 if(ivideo->SiS_Pr.PDCA == -1) {
3150 if(ivideo->detectedpdca != 0xff) {
3151 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
3152 }
3153 }
3154 if(ivideo->detectedpdc != 0xff) {
3155 printk(KERN_INFO
3156 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
3157 ivideo->detectedpdc);
3158 }
3159 if(ivideo->detectedpdca != 0xff) {
3160 printk(KERN_INFO
3161 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
3162 ivideo->detectedpdca);
3163 }
3164 }
3098 3165
3099 outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff)); 3166 /* Save EMI */
3167 if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) {
3168 inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
3169 inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
3170 inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
3171 inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
3172 ivideo->SiS_Pr.HaveEMI = TRUE;
3173 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
3174 ivideo->SiS_Pr.HaveEMILCD = TRUE;
3175 }
3176 }
3177 }
3100 3178
3101 ivideo->caps |= TURBO_QUEUE_CAP; 3179 /* Let user override detected PDCs (all bridges) */
3102 } 3180 if(ivideo->vbflags2 & VB2_30xBLV) {
3181 if((ivideo->SiS_Pr.PDC != -1) &&
3182 (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
3183 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
3184 ivideo->SiS_Pr.PDC);
3185 }
3186 if((ivideo->SiS_Pr.PDCA != -1) &&
3187 (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
3188 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
3189 ivideo->SiS_Pr.PDCA);
3190 }
3191 }
3192
3193 }
3103#endif 3194#endif
3195}
3104 3196
3105 /* Reserve memory for the HWCursor */ 3197/* -------------------- Memory manager routines ---------------------- */
3106 ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
3107 ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
3108 ivideo->caps |= HW_CURSOR_CAP;
3109 3198
3110 ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start; 3199static u32 __devinit
3200sisfb_getheapstart(struct sis_video_info *ivideo)
3201{
3202 u32 ret = ivideo->sisfb_parm_mem * 1024;
3203 u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
3204 u32 def;
3111 3205
3112 if(ivideo->cardnumber == 0) { 3206 /* Calculate heap start = end of memory for console
3207 *
3208 * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
3209 * C = console, D = heap, H = HWCursor, Q = cmd-queue
3210 *
3211 * On 76x in UMA+LFB mode, the layout is as follows:
3212 * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ
3213 * where the heap is the entire UMA area, eventually
3214 * into the LFB area if the given mem parameter is
3215 * higher than the size of the UMA memory.
3216 *
3217 * Basically given by "mem" parameter
3218 *
3219 * maximum = videosize - cmd_queue - hwcursor
3220 * (results in a heap of size 0)
3221 * default = SiS 300: depends on videosize
3222 * SiS 315/330/340/XGI: 32k below max
3223 */
3113 3224
3114 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n", 3225 if(ivideo->sisvga_engine == SIS_300_VGA) {
3115 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024)); 3226 if(ivideo->video_size > 0x1000000) {
3227 def = 0xc00000;
3228 } else if(ivideo->video_size > 0x800000) {
3229 def = 0x800000;
3230 } else {
3231 def = 0x400000;
3232 }
3233 } else if(ivideo->UMAsize && ivideo->LFBsize) {
3234 ret = def = 0;
3235 } else {
3236 def = maxoffs - 0x8000;
3237 }
3116 3238
3117 sisfb_heap.vinfo = ivideo; 3239 /* Use default for secondary card for now (FIXME) */
3240 if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0))
3241 ret = def;
3118 3242
3119 sisfb_heap.poha_chain = NULL; 3243 return ret;
3120 sisfb_heap.poh_freelist = NULL; 3244}
3121 3245
3122 poh = sisfb_poh_new_node(); 3246static u32 __devinit
3123 if(poh == NULL) return 1; 3247sisfb_getheapsize(struct sis_video_info *ivideo)
3248{
3249 u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
3250 u32 ret = 0;
3251
3252 if(ivideo->UMAsize && ivideo->LFBsize) {
3253 if( (!ivideo->sisfb_parm_mem) ||
3254 ((ivideo->sisfb_parm_mem * 1024) > max) ||
3255 ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) {
3256 ret = ivideo->UMAsize;
3257 max -= ivideo->UMAsize;
3258 } else {
3259 ret = max - (ivideo->sisfb_parm_mem * 1024);
3260 max = ivideo->sisfb_parm_mem * 1024;
3261 }
3262 ivideo->video_offset = ret;
3263 ivideo->sisfb_mem = max;
3264 } else {
3265 ret = max - ivideo->heapstart;
3266 ivideo->sisfb_mem = ivideo->heapstart;
3267 }
3124 3268
3125 poh->poh_next = &sisfb_heap.oh_free; 3269 return ret;
3126 poh->poh_prev = &sisfb_heap.oh_free; 3270}
3127 poh->size = ivideo->sisfb_heap_size;
3128 poh->offset = ivideo->heapstart;
3129 3271
3130 sisfb_heap.oh_free.poh_next = poh; 3272static int __devinit
3131 sisfb_heap.oh_free.poh_prev = poh; 3273sisfb_heap_init(struct sis_video_info *ivideo)
3132 sisfb_heap.oh_free.size = 0; 3274{
3133 sisfb_heap.max_freesize = poh->size; 3275 struct SIS_OH *poh;
3134 3276
3135 sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used; 3277 ivideo->video_offset = 0;
3136 sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used; 3278 if(ivideo->sisfb_parm_mem) {
3137 sisfb_heap.oh_used.size = SENTINEL; 3279 if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) ||
3280 (ivideo->sisfb_parm_mem > ivideo->video_size) ) {
3281 ivideo->sisfb_parm_mem = 0;
3282 }
3283 }
3138 3284
3139 } else { 3285 ivideo->heapstart = sisfb_getheapstart(ivideo);
3286 ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo);
3140 3287
3141 printk(KERN_INFO "Skipped heap initialization for secondary cards\n"); 3288 ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
3289 ivideo->sisfb_heap_end = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size;
3142 3290
3143 } 3291 printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
3292 (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
3144 3293
3145 return 0; 3294 ivideo->sisfb_heap.vinfo = ivideo;
3295
3296 ivideo->sisfb_heap.poha_chain = NULL;
3297 ivideo->sisfb_heap.poh_freelist = NULL;
3298
3299 poh = sisfb_poh_new_node(&ivideo->sisfb_heap);
3300 if(poh == NULL)
3301 return 1;
3302
3303 poh->poh_next = &ivideo->sisfb_heap.oh_free;
3304 poh->poh_prev = &ivideo->sisfb_heap.oh_free;
3305 poh->size = ivideo->sisfb_heap_size;
3306 poh->offset = ivideo->heapstart;
3307
3308 ivideo->sisfb_heap.oh_free.poh_next = poh;
3309 ivideo->sisfb_heap.oh_free.poh_prev = poh;
3310 ivideo->sisfb_heap.oh_free.size = 0;
3311 ivideo->sisfb_heap.max_freesize = poh->size;
3312
3313 ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used;
3314 ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used;
3315 ivideo->sisfb_heap.oh_used.size = SENTINEL;
3316
3317 if(ivideo->cardnumber == 0) {
3318 /* For the first card, make this heap the "global" one
3319 * for old DRM (which could handle only one card)
3320 */
3321 sisfb_heap = &ivideo->sisfb_heap;
3322 }
3323
3324 return 0;
3146} 3325}
3147 3326
3148static SIS_OH * 3327static struct SIS_OH *
3149sisfb_poh_new_node(void) 3328sisfb_poh_new_node(struct SIS_HEAP *memheap)
3150{ 3329{
3151 int i; 3330 struct SIS_OHALLOC *poha;
3152 unsigned long cOhs; 3331 struct SIS_OH *poh;
3153 SIS_OHALLOC *poha; 3332 unsigned long cOhs;
3154 SIS_OH *poh; 3333 int i;
3155 3334
3156 if(sisfb_heap.poh_freelist == NULL) { 3335 if(memheap->poh_freelist == NULL) {
3157 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL); 3336 poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
3158 if(!poha) return NULL; 3337 if(!poha)
3338 return NULL;
3159 3339
3160 poha->poha_next = sisfb_heap.poha_chain; 3340 poha->poha_next = memheap->poha_chain;
3161 sisfb_heap.poha_chain = poha; 3341 memheap->poha_chain = poha;
3162 3342
3163 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1; 3343 cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1;
3164 3344
3165 poh = &poha->aoh[0]; 3345 poh = &poha->aoh[0];
3166 for(i = cOhs - 1; i != 0; i--) { 3346 for(i = cOhs - 1; i != 0; i--) {
@@ -3169,32 +3349,32 @@ sisfb_poh_new_node(void)
3169 } 3349 }
3170 3350
3171 poh->poh_next = NULL; 3351 poh->poh_next = NULL;
3172 sisfb_heap.poh_freelist = &poha->aoh[0]; 3352 memheap->poh_freelist = &poha->aoh[0];
3173 } 3353 }
3174 3354
3175 poh = sisfb_heap.poh_freelist; 3355 poh = memheap->poh_freelist;
3176 sisfb_heap.poh_freelist = poh->poh_next; 3356 memheap->poh_freelist = poh->poh_next;
3177 3357
3178 return (poh); 3358 return poh;
3179} 3359}
3180 3360
3181static SIS_OH * 3361static struct SIS_OH *
3182sisfb_poh_allocate(u32 size) 3362sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size)
3183{ 3363{
3184 SIS_OH *pohThis; 3364 struct SIS_OH *pohThis;
3185 SIS_OH *pohRoot; 3365 struct SIS_OH *pohRoot;
3186 int bAllocated = 0; 3366 int bAllocated = 0;
3187 3367
3188 if(size > sisfb_heap.max_freesize) { 3368 if(size > memheap->max_freesize) {
3189 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3369 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3190 (unsigned int) size / 1024); 3370 (unsigned int) size / 1024);
3191 return (NULL); 3371 return NULL;
3192 } 3372 }
3193 3373
3194 pohThis = sisfb_heap.oh_free.poh_next; 3374 pohThis = memheap->oh_free.poh_next;
3195 3375
3196 while(pohThis != &sisfb_heap.oh_free) { 3376 while(pohThis != &memheap->oh_free) {
3197 if (size <= pohThis->size) { 3377 if(size <= pohThis->size) {
3198 bAllocated = 1; 3378 bAllocated = 1;
3199 break; 3379 break;
3200 } 3380 }
@@ -3204,18 +3384,16 @@ sisfb_poh_allocate(u32 size)
3204 if(!bAllocated) { 3384 if(!bAllocated) {
3205 DPRINTK("sisfb: Can't allocate %dk video memory\n", 3385 DPRINTK("sisfb: Can't allocate %dk video memory\n",
3206 (unsigned int) size / 1024); 3386 (unsigned int) size / 1024);
3207 return (NULL); 3387 return NULL;
3208 } 3388 }
3209 3389
3210 if(size == pohThis->size) { 3390 if(size == pohThis->size) {
3211 pohRoot = pohThis; 3391 pohRoot = pohThis;
3212 sisfb_delete_node(pohThis); 3392 sisfb_delete_node(pohThis);
3213 } else { 3393 } else {
3214 pohRoot = sisfb_poh_new_node(); 3394 pohRoot = sisfb_poh_new_node(memheap);
3215 3395 if(pohRoot == NULL)
3216 if(pohRoot == NULL) { 3396 return NULL;
3217 return (NULL);
3218 }
3219 3397
3220 pohRoot->offset = pohThis->offset; 3398 pohRoot->offset = pohThis->offset;
3221 pohRoot->size = size; 3399 pohRoot->size = size;
@@ -3224,33 +3402,25 @@ sisfb_poh_allocate(u32 size)
3224 pohThis->size -= size; 3402 pohThis->size -= size;
3225 } 3403 }
3226 3404
3227 sisfb_heap.max_freesize -= size; 3405 memheap->max_freesize -= size;
3228 3406
3229 pohThis = &sisfb_heap.oh_used; 3407 pohThis = &memheap->oh_used;
3230 sisfb_insert_node(pohThis, pohRoot); 3408 sisfb_insert_node(pohThis, pohRoot);
3231 3409
3232 return (pohRoot); 3410 return pohRoot;
3233} 3411}
3234 3412
3235static void 3413static void
3236sisfb_delete_node(SIS_OH *poh) 3414sisfb_delete_node(struct SIS_OH *poh)
3237{ 3415{
3238 SIS_OH *poh_prev; 3416 poh->poh_prev->poh_next = poh->poh_next;
3239 SIS_OH *poh_next; 3417 poh->poh_next->poh_prev = poh->poh_prev;
3240
3241 poh_prev = poh->poh_prev;
3242 poh_next = poh->poh_next;
3243
3244 poh_prev->poh_next = poh_next;
3245 poh_next->poh_prev = poh_prev;
3246} 3418}
3247 3419
3248static void 3420static void
3249sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh) 3421sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh)
3250{ 3422{
3251 SIS_OH *pohTemp; 3423 struct SIS_OH *pohTemp = pohList->poh_next;
3252
3253 pohTemp = pohList->poh_next;
3254 3424
3255 pohList->poh_next = poh; 3425 pohList->poh_next = poh;
3256 pohTemp->poh_prev = poh; 3426 pohTemp->poh_prev = poh;
@@ -3259,20 +3429,20 @@ sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
3259 poh->poh_next = pohTemp; 3429 poh->poh_next = pohTemp;
3260} 3430}
3261 3431
3262static SIS_OH * 3432static struct SIS_OH *
3263sisfb_poh_free(u32 base) 3433sisfb_poh_free(struct SIS_HEAP *memheap, u32 base)
3264{ 3434{
3265 SIS_OH *pohThis; 3435 struct SIS_OH *pohThis;
3266 SIS_OH *poh_freed; 3436 struct SIS_OH *poh_freed;
3267 SIS_OH *poh_prev; 3437 struct SIS_OH *poh_prev;
3268 SIS_OH *poh_next; 3438 struct SIS_OH *poh_next;
3269 u32 ulUpper; 3439 u32 ulUpper;
3270 u32 ulLower; 3440 u32 ulLower;
3271 int foundNode = 0; 3441 int foundNode = 0;
3272 3442
3273 poh_freed = sisfb_heap.oh_used.poh_next; 3443 poh_freed = memheap->oh_used.poh_next;
3274 3444
3275 while(poh_freed != &sisfb_heap.oh_used) { 3445 while(poh_freed != &memheap->oh_used) {
3276 if(poh_freed->offset == base) { 3446 if(poh_freed->offset == base) {
3277 foundNode = 1; 3447 foundNode = 1;
3278 break; 3448 break;
@@ -3281,17 +3451,18 @@ sisfb_poh_free(u32 base)
3281 poh_freed = poh_freed->poh_next; 3451 poh_freed = poh_freed->poh_next;
3282 } 3452 }
3283 3453
3284 if(!foundNode) return(NULL); 3454 if(!foundNode)
3455 return NULL;
3285 3456
3286 sisfb_heap.max_freesize += poh_freed->size; 3457 memheap->max_freesize += poh_freed->size;
3287 3458
3288 poh_prev = poh_next = NULL; 3459 poh_prev = poh_next = NULL;
3289 ulUpper = poh_freed->offset + poh_freed->size; 3460 ulUpper = poh_freed->offset + poh_freed->size;
3290 ulLower = poh_freed->offset; 3461 ulLower = poh_freed->offset;
3291 3462
3292 pohThis = sisfb_heap.oh_free.poh_next; 3463 pohThis = memheap->oh_free.poh_next;
3293 3464
3294 while(pohThis != &sisfb_heap.oh_free) { 3465 while(pohThis != &memheap->oh_free) {
3295 if(pohThis->offset == ulUpper) { 3466 if(pohThis->offset == ulUpper) {
3296 poh_next = pohThis; 3467 poh_next = pohThis;
3297 } else if((pohThis->offset + pohThis->size) == ulLower) { 3468 } else if((pohThis->offset + pohThis->size) == ulLower) {
@@ -3305,70 +3476,88 @@ sisfb_poh_free(u32 base)
3305 if(poh_prev && poh_next) { 3476 if(poh_prev && poh_next) {
3306 poh_prev->size += (poh_freed->size + poh_next->size); 3477 poh_prev->size += (poh_freed->size + poh_next->size);
3307 sisfb_delete_node(poh_next); 3478 sisfb_delete_node(poh_next);
3308 sisfb_free_node(poh_freed); 3479 sisfb_free_node(memheap, poh_freed);
3309 sisfb_free_node(poh_next); 3480 sisfb_free_node(memheap, poh_next);
3310 return(poh_prev); 3481 return poh_prev;
3311 } 3482 }
3312 3483
3313 if(poh_prev) { 3484 if(poh_prev) {
3314 poh_prev->size += poh_freed->size; 3485 poh_prev->size += poh_freed->size;
3315 sisfb_free_node(poh_freed); 3486 sisfb_free_node(memheap, poh_freed);
3316 return(poh_prev); 3487 return poh_prev;
3317 } 3488 }
3318 3489
3319 if(poh_next) { 3490 if(poh_next) {
3320 poh_next->size += poh_freed->size; 3491 poh_next->size += poh_freed->size;
3321 poh_next->offset = poh_freed->offset; 3492 poh_next->offset = poh_freed->offset;
3322 sisfb_free_node(poh_freed); 3493 sisfb_free_node(memheap, poh_freed);
3323 return(poh_next); 3494 return poh_next;
3324 } 3495 }
3325 3496
3326 sisfb_insert_node(&sisfb_heap.oh_free, poh_freed); 3497 sisfb_insert_node(&memheap->oh_free, poh_freed);
3327 3498
3328 return(poh_freed); 3499 return poh_freed;
3329} 3500}
3330 3501
3331static void 3502static void
3332sisfb_free_node(SIS_OH *poh) 3503sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh)
3333{ 3504{
3334 if(poh == NULL) return; 3505 if(poh == NULL)
3506 return;
3335 3507
3336 poh->poh_next = sisfb_heap.poh_freelist; 3508 poh->poh_next = memheap->poh_freelist;
3337 sisfb_heap.poh_freelist = poh; 3509 memheap->poh_freelist = poh;
3338} 3510}
3339 3511
3340void 3512static void
3341sis_malloc(struct sis_memreq *req) 3513sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req)
3342{ 3514{
3343 struct sis_video_info *ivideo = sisfb_heap.vinfo; 3515 struct SIS_OH *poh = NULL;
3344 SIS_OH *poh = NULL;
3345 3516
3346 if((ivideo) && (!ivideo->havenoheap)) { 3517 if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap))
3347 poh = sisfb_poh_allocate((u32)req->size); 3518 poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size);
3348 }
3349 3519
3350 if(poh == NULL) { 3520 if(poh == NULL) {
3351 req->offset = req->size = 0; 3521 req->offset = req->size = 0;
3352 DPRINTK("sisfb: Video RAM allocation failed\n"); 3522 DPRINTK("sisfb: Video RAM allocation failed\n");
3353 } else { 3523 } else {
3354 req->offset = poh->offset; 3524 req->offset = poh->offset;
3355 req->size = poh->size; 3525 req->size = poh->size;
3356 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n", 3526 DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
3357 (poh->offset + ivideo->video_vbase)); 3527 (poh->offset + ivideo->video_vbase));
3358 } 3528 }
3359} 3529}
3360 3530
3361/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */ 3531void
3532sis_malloc(struct sis_memreq *req)
3533{
3534 struct sis_video_info *ivideo = sisfb_heap->vinfo;
3535
3536 if(&ivideo->sisfb_heap == sisfb_heap)
3537 sis_int_malloc(ivideo, req);
3538 else
3539 req->offset = req->size = 0;
3540}
3362 3541
3363void 3542void
3364sis_free(u32 base) 3543sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req)
3365{ 3544{
3366 struct sis_video_info *ivideo = sisfb_heap.vinfo; 3545 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3367 SIS_OH *poh; 3546
3547 sis_int_malloc(ivideo, req);
3548}
3549
3550/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
3368 3551
3369 if((!ivideo) || (ivideo->havenoheap)) return; 3552static void
3553sis_int_free(struct sis_video_info *ivideo, u32 base)
3554{
3555 struct SIS_OH *poh;
3370 3556
3371 poh = sisfb_poh_free((u32)base); 3557 if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap))
3558 return;
3559
3560 poh = sisfb_poh_free(&ivideo->sisfb_heap, base);
3372 3561
3373 if(poh == NULL) { 3562 if(poh == NULL) {
3374 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n", 3563 DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
@@ -3376,9 +3565,63 @@ sis_free(u32 base)
3376 } 3565 }
3377} 3566}
3378 3567
3568void
3569sis_free(u32 base)
3570{
3571 struct sis_video_info *ivideo = sisfb_heap->vinfo;
3572
3573 sis_int_free(ivideo, base);
3574}
3575
3576void
3577sis_free_new(struct pci_dev *pdev, u32 base)
3578{
3579 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3580
3581 sis_int_free(ivideo, base);
3582}
3583
3379/* --------------------- SetMode routines ------------------------- */ 3584/* --------------------- SetMode routines ------------------------- */
3380 3585
3381static void 3586static void
3587sisfb_check_engine_and_sync(struct sis_video_info *ivideo)
3588{
3589 u8 cr30, cr31;
3590
3591 /* Check if MMIO and engines are enabled,
3592 * and sync in case they are. Can't use
3593 * ivideo->accel here, as this might have
3594 * been changed before this is called.
3595 */
3596 inSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, cr30);
3597 inSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, cr31);
3598 /* MMIO and 2D/3D engine enabled? */
3599 if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) {
3600#ifdef CONFIG_FB_SIS_300
3601 if(ivideo->sisvga_engine == SIS_300_VGA) {
3602 /* Don't care about TurboQueue. It's
3603 * enough to know that the engines
3604 * are enabled
3605 */
3606 sisfb_syncaccel(ivideo);
3607 }
3608#endif
3609#ifdef CONFIG_FB_SIS_315
3610 if(ivideo->sisvga_engine == SIS_315_VGA) {
3611 /* Check that any queue mode is
3612 * enabled, and that the queue
3613 * is not in the state of "reset"
3614 */
3615 inSISIDXREG(SISSR, 0x26, cr30);
3616 if((cr30 & 0xe0) && (!(cr30 & 0x01))) {
3617 sisfb_syncaccel(ivideo);
3618 }
3619 }
3620#endif
3621 }
3622}
3623
3624static void
3382sisfb_pre_setmode(struct sis_video_info *ivideo) 3625sisfb_pre_setmode(struct sis_video_info *ivideo)
3383{ 3626{
3384 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0; 3627 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
@@ -3386,6 +3629,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3386 3629
3387 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2); 3630 ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
3388 3631
3632 outSISIDXREG(SISSR, 0x05, 0x86);
3633
3389 inSISIDXREG(SISCR, 0x31, cr31); 3634 inSISIDXREG(SISCR, 0x31, cr31);
3390 cr31 &= ~0x60; 3635 cr31 &= ~0x60;
3391 cr31 |= 0x04; 3636 cr31 |= 0x04;
@@ -3413,41 +3658,43 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3413 3658
3414 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE); 3659 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
3415 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE); 3660 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
3661 ivideo->curFSTN = ivideo->curDSTN = 0;
3416 3662
3417 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { 3663 switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
3418 3664
3419 case CRT2_TV: 3665 case CRT2_TV:
3420 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */ 3666 cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */
3421 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) { 3667 if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
3422#ifdef CONFIG_FB_SIS_315 3668#ifdef CONFIG_FB_SIS_315
3423 if(ivideo->chip >= SIS_661) { 3669 if(ivideo->chip >= SIS_661) {
3424 cr38 |= 0x04; 3670 cr38 |= 0x04;
3425 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20; 3671 if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
3426 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40; 3672 else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40;
3427 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60; 3673 else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
3428 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3674 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3429 cr35 &= ~0x01; 3675 cr35 &= ~0x01;
3430 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3676 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3431 } else if(ivideo->sisvga_engine == SIS_315_VGA) { 3677 } else if(ivideo->sisvga_engine == SIS_315_VGA) {
3432 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE); 3678 cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
3433 cr38 |= 0x08; 3679 cr38 |= 0x08;
3434 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10; 3680 if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
3435 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20; 3681 else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20;
3436 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30; 3682 else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
3437 cr31 &= ~0x01; 3683 cr31 &= ~0x01;
3438 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL)); 3684 ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
3439 } 3685 }
3440#endif 3686#endif
3441 } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) { 3687 } else if((ivideo->vbflags & TV_HIVISION) &&
3442 if(ivideo->chip >= SIS_661) { 3688 (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) {
3443 cr38 |= 0x04; 3689 if(ivideo->chip >= SIS_661) {
3444 cr35 |= 0x60; 3690 cr38 |= 0x04;
3445 } else { 3691 cr35 |= 0x60;
3446 cr30 |= 0x80; 3692 } else {
3447 } 3693 cr30 |= 0x80;
3694 }
3448 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE; 3695 cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
3449 cr31 |= 0x01; 3696 cr31 |= 0x01;
3450 cr35 |= 0x01; 3697 cr35 |= 0x01;
3451 ivideo->currentvbflags |= TV_HIVISION; 3698 ivideo->currentvbflags |= TV_HIVISION;
3452 } else if(ivideo->vbflags & TV_SCART) { 3699 } else if(ivideo->vbflags & TV_SCART) {
3453 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE); 3700 cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
@@ -3466,8 +3713,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3466 } 3713 }
3467 cr31 |= SIS_DRIVER_MODE; 3714 cr31 |= SIS_DRIVER_MODE;
3468 3715
3469 if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) { 3716 if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) {
3470 if(ivideo->vbflags & TV_PAL) { 3717 if(ivideo->vbflags & TV_PAL) {
3471 cr31 |= 0x01; cr35 |= 0x01; 3718 cr31 |= 0x01; cr35 |= 0x01;
3472 ivideo->currentvbflags |= TV_PAL; 3719 ivideo->currentvbflags |= TV_PAL;
3473 if(ivideo->vbflags & TV_PALM) { 3720 if(ivideo->vbflags & TV_PALM) {
@@ -3476,14 +3723,14 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3476 } else if(ivideo->vbflags & TV_PALN) { 3723 } else if(ivideo->vbflags & TV_PALN) {
3477 cr38 |= 0x80; cr35 |= 0x08; 3724 cr38 |= 0x80; cr35 |= 0x08;
3478 ivideo->currentvbflags |= TV_PALN; 3725 ivideo->currentvbflags |= TV_PALN;
3479 } 3726 }
3480 } else { 3727 } else {
3481 cr31 &= ~0x01; cr35 &= ~0x01; 3728 cr31 &= ~0x01; cr35 &= ~0x01;
3482 ivideo->currentvbflags |= TV_NTSC; 3729 ivideo->currentvbflags |= TV_NTSC;
3483 if(ivideo->vbflags & TV_NTSCJ) { 3730 if(ivideo->vbflags & TV_NTSCJ) {
3484 cr38 |= 0x40; cr35 |= 0x02; 3731 cr38 |= 0x40; cr35 |= 0x02;
3485 ivideo->currentvbflags |= TV_NTSCJ; 3732 ivideo->currentvbflags |= TV_NTSCJ;
3486 } 3733 }
3487 } 3734 }
3488 } 3735 }
3489 break; 3736 break;
@@ -3493,6 +3740,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3493 cr31 |= SIS_DRIVER_MODE; 3740 cr31 |= SIS_DRIVER_MODE;
3494 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn); 3741 SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
3495 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn); 3742 SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
3743 ivideo->curFSTN = ivideo->sisfb_fstn;
3744 ivideo->curDSTN = ivideo->sisfb_dstn;
3496 break; 3745 break;
3497 3746
3498 case CRT2_VGA: 3747 case CRT2_VGA:
@@ -3525,9 +3774,9 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3525 } 3774 }
3526 outSISIDXREG(SISCR, 0x31, cr31); 3775 outSISIDXREG(SISCR, 0x31, cr31);
3527 3776
3528 if(ivideo->accel) sisfb_syncaccel(ivideo);
3529
3530 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem; 3777 ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
3778
3779 sisfb_check_engine_and_sync(ivideo);
3531} 3780}
3532 3781
3533/* Fix SR11 for 661 and later */ 3782/* Fix SR11 for 661 and later */
@@ -3535,125 +3784,129 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
3535static void 3784static void
3536sisfb_fixup_SR11(struct sis_video_info *ivideo) 3785sisfb_fixup_SR11(struct sis_video_info *ivideo)
3537{ 3786{
3538 u8 tmpreg; 3787 u8 tmpreg;
3539 3788
3540 if(ivideo->chip >= SIS_661) { 3789 if(ivideo->chip >= SIS_661) {
3541 inSISIDXREG(SISSR,0x11,tmpreg); 3790 inSISIDXREG(SISSR,0x11,tmpreg);
3542 if(tmpreg & 0x20) { 3791 if(tmpreg & 0x20) {
3543 inSISIDXREG(SISSR,0x3e,tmpreg); 3792 inSISIDXREG(SISSR,0x3e,tmpreg);
3544 tmpreg = (tmpreg + 1) & 0xff; 3793 tmpreg = (tmpreg + 1) & 0xff;
3545 outSISIDXREG(SISSR,0x3e,tmpreg); 3794 outSISIDXREG(SISSR,0x3e,tmpreg);
3546 inSISIDXREG(SISSR,0x11,tmpreg); 3795 inSISIDXREG(SISSR,0x11,tmpreg);
3547 } 3796 }
3548 if(tmpreg & 0xf0) { 3797 if(tmpreg & 0xf0) {
3549 andSISIDXREG(SISSR,0x11,0x0f); 3798 andSISIDXREG(SISSR,0x11,0x0f);
3550 } 3799 }
3551 } 3800 }
3552} 3801}
3553#endif 3802#endif
3554 3803
3555static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val) 3804static void
3805sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
3556{ 3806{
3557 if(val > 32) val = 32; 3807 if(val > 32) val = 32;
3558 if(val < -32) val = -32; 3808 if(val < -32) val = -32;
3559 ivideo->tvxpos = val; 3809 ivideo->tvxpos = val;
3560 3810
3561 if(ivideo->sisfblocked) return; 3811 if(ivideo->sisfblocked) return;
3562 if(!ivideo->modechanged) return; 3812 if(!ivideo->modechanged) return;
3563 3813
3564 if(ivideo->currentvbflags & CRT2_TV) { 3814 if(ivideo->currentvbflags & CRT2_TV) {
3565 3815
3566 if(ivideo->vbflags & VB_CHRONTEL) { 3816 if(ivideo->vbflags2 & VB2_CHRONTEL) {
3567 3817
3568 int x = ivideo->tvx; 3818 int x = ivideo->tvx;
3569 3819
3570 switch(ivideo->chronteltype) { 3820 switch(ivideo->chronteltype) {
3571 case 1: 3821 case 1:
3572 x += val; 3822 x += val;
3573 if(x < 0) x = 0; 3823 if(x < 0) x = 0;
3574 outSISIDXREG(SISSR,0x05,0x86); 3824 outSISIDXREG(SISSR,0x05,0x86);
3575 SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a)); 3825 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff));
3576 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD); 3826 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD);
3577 break; 3827 break;
3578 case 2: 3828 case 2:
3579 /* Not supported by hardware */ 3829 /* Not supported by hardware */
3580 break; 3830 break;
3581 } 3831 }
3582 3832
3583 } else if(ivideo->vbflags & VB_SISBRIDGE) { 3833 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3584 3834
3585 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43; 3835 u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
3586 unsigned short temp; 3836 unsigned short temp;
3587 3837
3588 p2_1f = ivideo->p2_1f; 3838 p2_1f = ivideo->p2_1f;
3589 p2_20 = ivideo->p2_20; 3839 p2_20 = ivideo->p2_20;
3590 p2_2b = ivideo->p2_2b; 3840 p2_2b = ivideo->p2_2b;
3591 p2_42 = ivideo->p2_42; 3841 p2_42 = ivideo->p2_42;
3592 p2_43 = ivideo->p2_43; 3842 p2_43 = ivideo->p2_43;
3593 3843
3594 temp = p2_1f | ((p2_20 & 0xf0) << 4); 3844 temp = p2_1f | ((p2_20 & 0xf0) << 4);
3595 temp += (val * 2); 3845 temp += (val * 2);
3596 p2_1f = temp & 0xff; 3846 p2_1f = temp & 0xff;
3597 p2_20 = (temp & 0xf00) >> 4; 3847 p2_20 = (temp & 0xf00) >> 4;
3598 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f; 3848 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
3599 temp = p2_43 | ((p2_42 & 0xf0) << 4); 3849 temp = p2_43 | ((p2_42 & 0xf0) << 4);
3600 temp += (val * 2); 3850 temp += (val * 2);
3601 p2_43 = temp & 0xff; 3851 p2_43 = temp & 0xff;
3602 p2_42 = (temp & 0xf00) >> 4; 3852 p2_42 = (temp & 0xf00) >> 4;
3603 outSISIDXREG(SISPART2,0x1f,p2_1f); 3853 outSISIDXREG(SISPART2,0x1f,p2_1f);
3604 setSISIDXREG(SISPART2,0x20,0x0F,p2_20); 3854 setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
3605 setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b); 3855 setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
3606 setSISIDXREG(SISPART2,0x42,0x0F,p2_42); 3856 setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
3607 outSISIDXREG(SISPART2,0x43,p2_43); 3857 outSISIDXREG(SISPART2,0x43,p2_43);
3608 } 3858 }
3609 } 3859 }
3610} 3860}
3611 3861
3612static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val) 3862static void
3863sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
3613{ 3864{
3614 if(val > 32) val = 32; 3865 if(val > 32) val = 32;
3615 if(val < -32) val = -32; 3866 if(val < -32) val = -32;
3616 ivideo->tvypos = val; 3867 ivideo->tvypos = val;
3617 3868
3618 if(ivideo->sisfblocked) return; 3869 if(ivideo->sisfblocked) return;
3619 if(!ivideo->modechanged) return; 3870 if(!ivideo->modechanged) return;
3620 3871
3621 if(ivideo->currentvbflags & CRT2_TV) { 3872 if(ivideo->currentvbflags & CRT2_TV) {
3622 3873
3623 if(ivideo->vbflags & VB_CHRONTEL) { 3874 if(ivideo->vbflags2 & VB2_CHRONTEL) {
3624 3875
3625 int y = ivideo->tvy; 3876 int y = ivideo->tvy;
3626 3877
3627 switch(ivideo->chronteltype) { 3878 switch(ivideo->chronteltype) {
3628 case 1: 3879 case 1:
3629 y -= val; 3880 y -= val;
3630 if(y < 0) y = 0; 3881 if(y < 0) y = 0;
3631 outSISIDXREG(SISSR,0x05,0x86); 3882 outSISIDXREG(SISSR,0x05,0x86);
3632 SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b)); 3883 SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff));
3633 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE); 3884 SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE);
3634 break; 3885 break;
3635 case 2: 3886 case 2:
3636 /* Not supported by hardware */ 3887 /* Not supported by hardware */
3637 break; 3888 break;
3638 } 3889 }
3639 3890
3640 } else if(ivideo->vbflags & VB_SISBRIDGE) { 3891 } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3641 3892
3642 char p2_01, p2_02; 3893 char p2_01, p2_02;
3643 val /= 2; 3894 val /= 2;
3644 p2_01 = ivideo->p2_01; 3895 p2_01 = ivideo->p2_01;
3645 p2_02 = ivideo->p2_02; 3896 p2_02 = ivideo->p2_02;
3646 3897
3647 p2_01 += val; 3898 p2_01 += val;
3648 p2_02 += val; 3899 p2_02 += val;
3649 while((p2_01 <= 0) || (p2_02 <= 0)) { 3900 if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) {
3650 p2_01 += 2; 3901 while((p2_01 <= 0) || (p2_02 <= 0)) {
3651 p2_02 += 2; 3902 p2_01 += 2;
3652 } 3903 p2_02 += 2;
3653 outSISIDXREG(SISPART2,0x01,p2_01); 3904 }
3654 outSISIDXREG(SISPART2,0x02,p2_02); 3905 }
3655 } 3906 outSISIDXREG(SISPART2,0x01,p2_01);
3656 } 3907 outSISIDXREG(SISPART2,0x02,p2_02);
3908 }
3909 }
3657} 3910}
3658 3911
3659static void 3912static void
@@ -3668,207 +3921,172 @@ sisfb_post_setmode(struct sis_video_info *ivideo)
3668 u8 reg1; 3921 u8 reg1;
3669#endif 3922#endif
3670 3923
3671 outSISIDXREG(SISSR,0x05,0x86); 3924 outSISIDXREG(SISSR, 0x05, 0x86);
3672 3925
3673#ifdef CONFIG_FB_SIS_315 3926#ifdef CONFIG_FB_SIS_315
3674 sisfb_fixup_SR11(ivideo); 3927 sisfb_fixup_SR11(ivideo);
3675#endif 3928#endif
3676 3929
3677 /* Now we actually HAVE changed the display mode */ 3930 /* Now we actually HAVE changed the display mode */
3678 ivideo->modechanged = 1; 3931 ivideo->modechanged = 1;
3679 3932
3680 /* We can't switch off CRT1 if bridge is in slave mode */ 3933 /* We can't switch off CRT1 if bridge is in slave mode */
3681 if(ivideo->vbflags & VB_VIDEOBRIDGE) { 3934 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
3682 if(sisfb_bridgeisslave(ivideo)) doit = FALSE; 3935 if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
3683 } else ivideo->sisfb_crt1off = 0; 3936 } else
3937 ivideo->sisfb_crt1off = 0;
3684 3938
3685#ifdef CONFIG_FB_SIS_300 3939#ifdef CONFIG_FB_SIS_300
3686 if(ivideo->sisvga_engine == SIS_300_VGA) { 3940 if(ivideo->sisvga_engine == SIS_300_VGA) {
3687 if((ivideo->sisfb_crt1off) && (doit)) { 3941 if((ivideo->sisfb_crt1off) && (doit)) {
3688 crt1isoff = TRUE; 3942 crt1isoff = TRUE;
3689 reg = 0x00; 3943 reg = 0x00;
3690 } else { 3944 } else {
3691 crt1isoff = FALSE; 3945 crt1isoff = FALSE;
3692 reg = 0x80; 3946 reg = 0x80;
3693 } 3947 }
3694 setSISIDXREG(SISCR, 0x17, 0x7f, reg); 3948 setSISIDXREG(SISCR, 0x17, 0x7f, reg);
3695 } 3949 }
3696#endif 3950#endif
3697#ifdef CONFIG_FB_SIS_315 3951#ifdef CONFIG_FB_SIS_315
3698 if(ivideo->sisvga_engine == SIS_315_VGA) { 3952 if(ivideo->sisvga_engine == SIS_315_VGA) {
3699 if((ivideo->sisfb_crt1off) && (doit)) { 3953 if((ivideo->sisfb_crt1off) && (doit)) {
3700 crt1isoff = TRUE; 3954 crt1isoff = TRUE;
3701 reg = 0x40; 3955 reg = 0x40;
3702 reg1 = 0xc0; 3956 reg1 = 0xc0;
3703 } else { 3957 } else {
3704 crt1isoff = FALSE; 3958 crt1isoff = FALSE;
3705 reg = 0x00; 3959 reg = 0x00;
3706 reg1 = 0x00; 3960 reg1 = 0x00;
3707 3961 }
3708 } 3962 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
3709 setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg); 3963 setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
3710 setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
3711 } 3964 }
3712#endif 3965#endif
3713 3966
3714 if(crt1isoff) { 3967 if(crt1isoff) {
3715 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1; 3968 ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
3716 ivideo->currentvbflags |= VB_SINGLE_MODE; 3969 ivideo->currentvbflags |= VB_SINGLE_MODE;
3717 } else { 3970 } else {
3718 ivideo->currentvbflags |= VB_DISPTYPE_CRT1; 3971 ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
3719 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) { 3972 if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
3720 ivideo->currentvbflags |= VB_MIRROR_MODE; 3973 ivideo->currentvbflags |= VB_MIRROR_MODE;
3721 } else { 3974 } else {
3722 ivideo->currentvbflags |= VB_SINGLE_MODE; 3975 ivideo->currentvbflags |= VB_SINGLE_MODE;
3723 } 3976 }
3724 } 3977 }
3725 3978
3726 andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04); 3979 andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
3727 3980
3728 if(ivideo->currentvbflags & CRT2_TV) { 3981 if(ivideo->currentvbflags & CRT2_TV) {
3729 if(ivideo->vbflags & VB_SISBRIDGE) { 3982 if(ivideo->vbflags2 & VB2_SISBRIDGE) {
3730 inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f); 3983 inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
3731 inSISIDXREG(SISPART2,0x20,ivideo->p2_20); 3984 inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
3732 inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b); 3985 inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
3733 inSISIDXREG(SISPART2,0x42,ivideo->p2_42); 3986 inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
3734 inSISIDXREG(SISPART2,0x43,ivideo->p2_43); 3987 inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
3735 inSISIDXREG(SISPART2,0x01,ivideo->p2_01); 3988 inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
3736 inSISIDXREG(SISPART2,0x02,ivideo->p2_02); 3989 inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
3737 } else if(ivideo->vbflags & VB_CHRONTEL) { 3990 } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
3738 if(ivideo->chronteltype == 1) { 3991 if(ivideo->chronteltype == 1) {
3739 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a); 3992 ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
3740 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8); 3993 ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
3741 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b); 3994 ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
3742 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8); 3995 ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
3743 } 3996 }
3744 } 3997 }
3745 } 3998 }
3746 3999
3747 if(ivideo->tvxpos) { 4000 if(ivideo->tvxpos) {
3748 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos); 4001 sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
3749 } 4002 }
3750 if(ivideo->tvypos) { 4003 if(ivideo->tvypos) {
3751 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos); 4004 sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
3752 } 4005 }
3753 4006
3754 if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) { /* Set filter for SiS301 */ 4007 /* Eventually sync engines */
4008 sisfb_check_engine_and_sync(ivideo);
3755 4009
3756 unsigned char filter_tb = 0; 4010 /* (Re-)Initialize chip engines */
4011 if(ivideo->accel) {
4012 sisfb_engine_init(ivideo);
4013 } else {
4014 ivideo->engineok = 0;
4015 }
4016}
3757 4017
3758 switch (ivideo->video_width) { 4018static int
3759 case 320: 4019sisfb_reset_mode(struct sis_video_info *ivideo)
3760 filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12; 4020{
3761 break; 4021 if(sisfb_set_mode(ivideo, 0))
3762 case 640: 4022 return 1;
3763 filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
3764 break;
3765 case 720:
3766 filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
3767 break;
3768 case 400:
3769 case 800:
3770 filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
3771 break;
3772 default:
3773 ivideo->sisfb_filter = -1;
3774 break;
3775 }
3776 4023
3777 orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01); 4024 sisfb_set_pitch(ivideo);
4025 sisfb_set_base_CRT1(ivideo, ivideo->current_base);
4026 sisfb_set_base_CRT2(ivideo, ivideo->current_base);
3778 4027
3779 if(ivideo->vbflags & TV_NTSC) { 4028 return 0;
3780 4029}
3781 andSISIDXREG(SISPART2, 0x3a, 0x1f); 4030
3782 4031static void
3783 if (ivideo->vbflags & TV_SVIDEO) { 4032sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command)
3784 4033{
3785 andSISIDXREG(SISPART2, 0x30, 0xdf); 4034 int mycrt1off;
3786
3787 } else if (ivideo->vbflags & TV_AVIDEO) {
3788
3789 orSISIDXREG(SISPART2, 0x30, 0x20);
3790
3791 switch (ivideo->video_width) {
3792 case 640:
3793 outSISIDXREG(SISPART2, 0x35, 0xEB);
3794 outSISIDXREG(SISPART2, 0x36, 0x04);
3795 outSISIDXREG(SISPART2, 0x37, 0x25);
3796 outSISIDXREG(SISPART2, 0x38, 0x18);
3797 break;
3798 case 720:
3799 outSISIDXREG(SISPART2, 0x35, 0xEE);
3800 outSISIDXREG(SISPART2, 0x36, 0x0C);
3801 outSISIDXREG(SISPART2, 0x37, 0x22);
3802 outSISIDXREG(SISPART2, 0x38, 0x08);
3803 break;
3804 case 400:
3805 case 800:
3806 outSISIDXREG(SISPART2, 0x35, 0xEB);
3807 outSISIDXREG(SISPART2, 0x36, 0x15);
3808 outSISIDXREG(SISPART2, 0x37, 0x25);
3809 outSISIDXREG(SISPART2, 0x38, 0xF6);
3810 break;
3811 }
3812 }
3813 4035
3814 } else if(ivideo->vbflags & TV_PAL) { 4036 switch(sisfb_command->sisfb_cmd) {
3815 4037 case SISFB_CMD_GETVBFLAGS:
3816 andSISIDXREG(SISPART2, 0x3A, 0x1F); 4038 if(!ivideo->modechanged) {
3817 4039 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
3818 if (ivideo->vbflags & TV_SVIDEO) { 4040 } else {
3819 4041 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3820 andSISIDXREG(SISPART2, 0x30, 0xDF); 4042 sisfb_command->sisfb_result[1] = ivideo->currentvbflags;
3821 4043 sisfb_command->sisfb_result[2] = ivideo->vbflags2;
3822 } else if (ivideo->vbflags & TV_AVIDEO) { 4044 }
3823 4045 break;
3824 orSISIDXREG(SISPART2, 0x30, 0x20); 4046 case SISFB_CMD_SWITCHCRT1:
3825 4047 /* arg[0]: 0 = off, 1 = on, 99 = query */
3826 switch (ivideo->video_width) { 4048 if(!ivideo->modechanged) {
3827 case 640: 4049 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
3828 outSISIDXREG(SISPART2, 0x35, 0xF1); 4050 } else if(sisfb_command->sisfb_arg[0] == 99) {
3829 outSISIDXREG(SISPART2, 0x36, 0xF7); 4051 /* Query */
3830 outSISIDXREG(SISPART2, 0x37, 0x1F); 4052 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
3831 outSISIDXREG(SISPART2, 0x38, 0x32); 4053 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3832 break; 4054 } else if(ivideo->sisfblocked) {
3833 case 720: 4055 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED;
3834 outSISIDXREG(SISPART2, 0x35, 0xF3); 4056 } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) &&
3835 outSISIDXREG(SISPART2, 0x36, 0x00); 4057 (sisfb_command->sisfb_arg[0] == 0)) {
3836 outSISIDXREG(SISPART2, 0x37, 0x1D); 4058 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2;
3837 outSISIDXREG(SISPART2, 0x38, 0x20); 4059 } else {
3838 break; 4060 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
3839 case 400: 4061 mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1;
3840 case 800: 4062 if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) ||
3841 outSISIDXREG(SISPART2, 0x35, 0xFC); 4063 ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) {
3842 outSISIDXREG(SISPART2, 0x36, 0xFB); 4064 ivideo->sisfb_crt1off = mycrt1off;
3843 outSISIDXREG(SISPART2, 0x37, 0x14); 4065 if(sisfb_reset_mode(ivideo)) {
3844 outSISIDXREG(SISPART2, 0x38, 0x2A); 4066 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER;
3845 break;
3846 } 4067 }
3847 } 4068 }
4069 sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
3848 } 4070 }
3849 4071 break;
3850 if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) { 4072 /* more to come */
3851 outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0])); 4073 default:
3852 outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1])); 4074 sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN;
3853 outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2])); 4075 printk(KERN_ERR "sisfb: Unknown command 0x%x\n",
3854 outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3])); 4076 sisfb_command->sisfb_cmd);
3855 }
3856
3857 } 4077 }
3858} 4078}
3859 4079
3860#ifndef MODULE 4080#ifndef MODULE
3861SISINITSTATIC int __init sisfb_setup(char *options) 4081SISINITSTATIC int __init
4082sisfb_setup(char *options)
3862{ 4083{
3863 char *this_opt; 4084 char *this_opt;
3864
3865 sisfb_setdefaultparms();
3866 4085
3867 printk(KERN_DEBUG "sisfb: Options %s\n", options); 4086 sisfb_setdefaultparms();
3868 4087
3869 if(!options || !(*options)) { 4088 if(!options || !(*options))
3870 return 0; 4089 return 0;
3871 }
3872 4090
3873 while((this_opt = strsep(&options, ",")) != NULL) { 4091 while((this_opt = strsep(&options, ",")) != NULL) {
3874 4092
@@ -3880,9 +4098,9 @@ SISINITSTATIC int __init sisfb_setup(char *options)
3880 /* Need to check crt2 type first for fstn/dstn */ 4098 /* Need to check crt2 type first for fstn/dstn */
3881 sisfb_search_crt2type(this_opt + 14); 4099 sisfb_search_crt2type(this_opt + 14);
3882 } else if(!strnicmp(this_opt, "tvmode:",7)) { 4100 } else if(!strnicmp(this_opt, "tvmode:",7)) {
3883 sisfb_search_tvstd(this_opt + 7);
3884 } else if(!strnicmp(this_opt, "tvstandard:",11)) {
3885 sisfb_search_tvstd(this_opt + 7); 4101 sisfb_search_tvstd(this_opt + 7);
4102 } else if(!strnicmp(this_opt, "tvstandard:",11)) {
4103 sisfb_search_tvstd(this_opt + 11);
3886 } else if(!strnicmp(this_opt, "mode:", 5)) { 4104 } else if(!strnicmp(this_opt, "mode:", 5)) {
3887 sisfb_search_mode(this_opt + 5, FALSE); 4105 sisfb_search_mode(this_opt + 5, FALSE);
3888 } else if(!strnicmp(this_opt, "vesa:", 5)) { 4106 } else if(!strnicmp(this_opt, "vesa:", 5)) {
@@ -3892,74 +4110,72 @@ SISINITSTATIC int __init sisfb_setup(char *options)
3892 sisfb_inverse = 1; 4110 sisfb_inverse = 1;
3893 /* fb_invert_cmaps(); */ 4111 /* fb_invert_cmaps(); */
3894 } else if(!strnicmp(this_opt, "font:", 5)) { 4112 } else if(!strnicmp(this_opt, "font:", 5)) {
3895 if(strlen(this_opt + 5) < 40) { 4113 if(strlen(this_opt + 5) < 40) {
3896 strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1); 4114 strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
3897 sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0'; 4115 sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
3898 } 4116 }
3899#endif 4117#endif
3900 } else if(!strnicmp(this_opt, "rate:", 5)) { 4118 } else if(!strnicmp(this_opt, "rate:", 5)) {
3901 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); 4119 sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
3902 } else if(!strnicmp(this_opt, "filter:", 7)) {
3903 sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
3904 } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { 4120 } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
3905 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); 4121 sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
3906 } else if(!strnicmp(this_opt, "mem:",4)) { 4122 } else if(!strnicmp(this_opt, "mem:",4)) {
3907 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); 4123 sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
3908 } else if(!strnicmp(this_opt, "pdc:", 4)) { 4124 } else if(!strnicmp(this_opt, "pdc:", 4)) {
3909 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); 4125 sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
3910 } else if(!strnicmp(this_opt, "pdc1:", 5)) { 4126 } else if(!strnicmp(this_opt, "pdc1:", 5)) {
3911 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); 4127 sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
3912 } else if(!strnicmp(this_opt, "noaccel", 7)) { 4128 } else if(!strnicmp(this_opt, "noaccel", 7)) {
3913 sisfb_accel = 0; 4129 sisfb_accel = 0;
3914 } else if(!strnicmp(this_opt, "accel", 5)) { 4130 } else if(!strnicmp(this_opt, "accel", 5)) {
3915 sisfb_accel = -1; 4131 sisfb_accel = -1;
3916 } else if(!strnicmp(this_opt, "noypan", 6)) { 4132 } else if(!strnicmp(this_opt, "noypan", 6)) {
3917 sisfb_ypan = 0; 4133 sisfb_ypan = 0;
3918 } else if(!strnicmp(this_opt, "ypan", 4)) { 4134 } else if(!strnicmp(this_opt, "ypan", 4)) {
3919 sisfb_ypan = -1; 4135 sisfb_ypan = -1;
3920 } else if(!strnicmp(this_opt, "nomax", 5)) { 4136 } else if(!strnicmp(this_opt, "nomax", 5)) {
3921 sisfb_max = 0; 4137 sisfb_max = 0;
3922 } else if(!strnicmp(this_opt, "max", 3)) { 4138 } else if(!strnicmp(this_opt, "max", 3)) {
3923 sisfb_max = -1; 4139 sisfb_max = -1;
3924 } else if(!strnicmp(this_opt, "userom:", 7)) { 4140 } else if(!strnicmp(this_opt, "userom:", 7)) {
3925 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); 4141 sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
3926 } else if(!strnicmp(this_opt, "useoem:", 7)) { 4142 } else if(!strnicmp(this_opt, "useoem:", 7)) {
3927 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); 4143 sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
3928 } else if(!strnicmp(this_opt, "nocrt2rate", 10)) { 4144 } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
3929 sisfb_nocrt2rate = 1; 4145 sisfb_nocrt2rate = 1;
3930 } else if(!strnicmp(this_opt, "scalelcd:", 9)) { 4146 } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
3931 unsigned long temp = 2; 4147 unsigned long temp = 2;
3932 temp = simple_strtoul(this_opt + 9, NULL, 0); 4148 temp = simple_strtoul(this_opt + 9, NULL, 0);
3933 if((temp == 0) || (temp == 1)) { 4149 if((temp == 0) || (temp == 1)) {
3934 sisfb_scalelcd = temp ^ 1; 4150 sisfb_scalelcd = temp ^ 1;
3935 } 4151 }
3936 } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) { 4152 } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
3937 int temp = 0; 4153 int temp = 0;
3938 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4154 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
3939 if((temp >= -32) && (temp <= 32)) { 4155 if((temp >= -32) && (temp <= 32)) {
3940 sisfb_tvxposoffset = temp; 4156 sisfb_tvxposoffset = temp;
3941 } 4157 }
3942 } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) { 4158 } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
3943 int temp = 0; 4159 int temp = 0;
3944 temp = (int)simple_strtol(this_opt + 13, NULL, 0); 4160 temp = (int)simple_strtol(this_opt + 13, NULL, 0);
3945 if((temp >= -32) && (temp <= 32)) { 4161 if((temp >= -32) && (temp <= 32)) {
3946 sisfb_tvyposoffset = temp; 4162 sisfb_tvyposoffset = temp;
3947 } 4163 }
3948 } else if(!strnicmp(this_opt, "specialtiming:", 14)) { 4164 } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
3949 sisfb_search_specialtiming(this_opt + 14); 4165 sisfb_search_specialtiming(this_opt + 14);
3950 } else if(!strnicmp(this_opt, "lvdshl:", 7)) { 4166 } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
3951 int temp = 4; 4167 int temp = 4;
3952 temp = simple_strtoul(this_opt + 7, NULL, 0); 4168 temp = simple_strtoul(this_opt + 7, NULL, 0);
3953 if((temp >= 0) && (temp <= 3)) { 4169 if((temp >= 0) && (temp <= 3)) {
3954 sisfb_lvdshl = temp; 4170 sisfb_lvdshl = temp;
3955 } 4171 }
3956 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { 4172 } else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
3957 sisfb_search_mode(this_opt, TRUE); 4173 sisfb_search_mode(this_opt, TRUE);
3958#if !defined(__i386__) && !defined(__x86_64__) 4174#if !defined(__i386__) && !defined(__x86_64__)
3959 } else if(!strnicmp(this_opt, "resetcard", 9)) { 4175 } else if(!strnicmp(this_opt, "resetcard", 9)) {
3960 sisfb_resetcard = 1; 4176 sisfb_resetcard = 1;
3961 } else if(!strnicmp(this_opt, "videoram:", 9)) { 4177 } else if(!strnicmp(this_opt, "videoram:", 9)) {
3962 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); 4178 sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
3963#endif 4179#endif
3964 } else { 4180 } else {
3965 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt); 4181 printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
@@ -3967,63 +4183,99 @@ SISINITSTATIC int __init sisfb_setup(char *options)
3967 4183
3968 } 4184 }
3969 4185
3970
3971
3972 return 0; 4186 return 0;
3973} 4187}
3974#endif 4188#endif
3975 4189
3976static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev) 4190static int __devinit
4191sisfb_check_rom(SIS_IOTYPE1 *rom_base, struct sis_video_info *ivideo)
4192{
4193 SIS_IOTYPE1 *rom;
4194 int romptr;
4195
4196 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa))
4197 return 0;
4198
4199 romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
4200 if(romptr > (0x10000 - 8))
4201 return 0;
4202
4203 rom = rom_base + romptr;
4204
4205 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
4206 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R'))
4207 return 0;
4208
4209 if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor)
4210 return 0;
4211
4212 if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id)
4213 return 0;
4214
4215 return 1;
4216}
4217
4218static unsigned char * __devinit
4219sisfb_find_rom(struct pci_dev *pdev)
3977{ 4220{
3978 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4221 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
3979 USHORT pciid; 4222 SIS_IOTYPE1 *rom_base;
3980 int romptr; 4223 unsigned char *myrombase = NULL;
3981 UCHAR *myrombase; 4224 u32 temp;
3982 u32 temp; 4225#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
3983 SIS_IOTYPE1 *rom_base, *rom; 4226 size_t romsize;
4227
4228 /* First, try the official pci ROM functions (except
4229 * on integrated chipsets which have no ROM).
4230 */
3984 4231
3985 if(!(myrombase = vmalloc(65536))) return NULL; 4232 if(!ivideo->nbridge) {
3986 4233
3987#if defined(__i386__) || defined(__x86_64__) 4234 if((rom_base = pci_map_rom(pdev, &romsize))) {
3988 4235
3989 for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) { 4236 if(sisfb_check_rom(rom_base, ivideo)) {
3990 4237
3991 rom_base = ioremap(temp, 0x10000); 4238 if((myrombase = vmalloc(65536))) {
3992 if(!rom_base) continue;
3993 4239
3994 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) { 4240 /* Work around bug in pci/rom.c: Folks forgot to check
3995 iounmap(rom_base); 4241 * whether the size retrieved from the BIOS image eventually
3996 continue; 4242 * is larger than the mapped size
3997 } 4243 */
4244 if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize)
4245 romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE);
3998 4246
3999 romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8)); 4247 memcpy_fromio(myrombase, rom_base,
4000 if(romptr > (0x10000 - 8)) { 4248 (romsize > 65536) ? 65536 : romsize);
4001 iounmap(rom_base); 4249 }
4002 continue; 4250 }
4003 } 4251 pci_unmap_rom(pdev, rom_base);
4252 }
4253 }
4004 4254
4005 rom = rom_base + romptr; 4255 if(myrombase) return myrombase;
4256#endif
4006 4257
4007 if((readb(rom) != 'P') || (readb(rom + 1) != 'C') || 4258 /* Otherwise do it the conventional way. */
4008 (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
4009 iounmap(rom_base);
4010 continue;
4011 }
4012 4259
4013 pciid = readb(rom + 4) | (readb(rom + 5) << 8); 4260#if defined(__i386__) || defined(__x86_64__)
4014 if(pciid != 0x1039) {
4015 iounmap(rom_base);
4016 continue;
4017 }
4018 4261
4019 pciid = readb(rom + 6) | (readb(rom + 7) << 8); 4262 for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
4020 if(pciid == ivideo->chip_id) { 4263
4021 memcpy_fromio(myrombase, rom_base, 65536); 4264 rom_base = ioremap(temp, 65536);
4022 iounmap(rom_base); 4265 if(!rom_base)
4023 return myrombase; 4266 continue;
4024 } 4267
4268 if(!sisfb_check_rom(rom_base, ivideo)) {
4269 iounmap(rom_base);
4270 continue;
4271 }
4272
4273 if((myrombase = vmalloc(65536)))
4274 memcpy_fromio(myrombase, rom_base, 65536);
4275
4276 iounmap(rom_base);
4277 break;
4025 4278
4026 iounmap(rom_base);
4027 } 4279 }
4028 4280
4029#else 4281#else
@@ -4034,752 +4286,1603 @@ static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
4034 4286
4035 rom_base = ioremap(ivideo->video_base, 65536); 4287 rom_base = ioremap(ivideo->video_base, 65536);
4036 if(rom_base) { 4288 if(rom_base) {
4037 if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) { 4289 if(sisfb_check_rom(rom_base, ivideo)) {
4038 romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8)); 4290 if((myrombase = vmalloc(65536)))
4039 if(romptr <= (0x10000 - 8)) { 4291 memcpy_fromio(myrombase, rom_base, 65536);
4040 rom = rom_base + romptr; 4292 }
4041 if((readb(rom) == 'P') && (readb(rom + 1) == 'C') && 4293 iounmap(rom_base);
4042 (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
4043 pciid = readb(rom + 4) | (readb(rom + 5) << 8);
4044 if(pciid == 0x1039) {
4045 pciid = readb(rom + 6) | (readb(rom + 7) << 8);
4046 if(pciid == ivideo->chip_id) {
4047 memcpy_fromio(myrombase, rom_base, 65536);
4048 iounmap(rom_base);
4049 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
4050 return myrombase;
4051 }
4052 }
4053 }
4054 }
4055 }
4056 iounmap(rom_base);
4057 } 4294 }
4058 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp); 4295
4296 pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
4059 4297
4060#endif 4298#endif
4061 4299
4062 vfree(myrombase); 4300 return myrombase;
4063 return NULL; 4301}
4302
4303static void __devinit
4304sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
4305 unsigned int min)
4306{
4307 ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize));
4308
4309 if(!ivideo->video_vbase) {
4310 printk(KERN_ERR
4311 "sisfb: Unable to map maximum video RAM for size detection\n");
4312 (*mapsize) >>= 1;
4313 while((!(ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize))))) {
4314 (*mapsize) >>= 1;
4315 if((*mapsize) < (min << 20))
4316 break;
4317 }
4318 if(ivideo->video_vbase) {
4319 printk(KERN_ERR
4320 "sisfb: Video RAM size detection limited to %dMB\n",
4321 (int)((*mapsize) >> 20));
4322 }
4323 }
4064} 4324}
4065 4325
4066#ifdef CONFIG_FB_SIS_300 4326#ifdef CONFIG_FB_SIS_300
4067static int __devinit 4327static int __devinit
4068sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress) 4328sisfb_post_300_buswidth(struct sis_video_info *ivideo)
4069{ 4329{
4070 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4330 SIS_IOTYPE1 *FBAddress = ivideo->video_vbase;
4331 unsigned short temp;
4332 unsigned char reg;
4071 int i, j; 4333 int i, j;
4072 USHORT temp; 4334
4073 UCHAR reg; 4335 andSISIDXREG(SISSR, 0x15, 0xFB);
4074 4336 orSISIDXREG(SISSR, 0x15, 0x04);
4075 andSISIDXREG(SISSR,0x15,0xFB); 4337 outSISIDXREG(SISSR, 0x13, 0x00);
4076 orSISIDXREG(SISSR,0x15,0x04); 4338 outSISIDXREG(SISSR, 0x14, 0xBF);
4077 outSISIDXREG(SISSR,0x13,0x00); 4339
4078 outSISIDXREG(SISSR,0x14,0xBF); 4340 for(i = 0; i < 2; i++) {
4079 4341 temp = 0x1234;
4080 for(i=0; i<2; i++) { 4342 for(j = 0; j < 4; j++) {
4081 temp = 0x1234; 4343 writew(temp, FBAddress);
4082 for(j=0; j<4; j++) { 4344 if(readw(FBAddress) == temp)
4083 writew(temp, FBAddress); 4345 break;
4084 if(readw(FBAddress) == temp) break; 4346 orSISIDXREG(SISSR, 0x3c, 0x01);
4085 orSISIDXREG(SISSR,0x3c,0x01); 4347 inSISIDXREG(SISSR, 0x05, reg);
4086 inSISIDXREG(SISSR,0x05,reg); 4348 inSISIDXREG(SISSR, 0x05, reg);
4087 inSISIDXREG(SISSR,0x05,reg); 4349 andSISIDXREG(SISSR, 0x3c, 0xfe);
4088 andSISIDXREG(SISSR,0x3c,0xfe); 4350 inSISIDXREG(SISSR, 0x05, reg);
4089 inSISIDXREG(SISSR,0x05,reg); 4351 inSISIDXREG(SISSR, 0x05, reg);
4090 inSISIDXREG(SISSR,0x05,reg); 4352 temp++;
4091 temp++; 4353 }
4092 }
4093 } 4354 }
4094 4355
4095 writel(0x01234567L, FBAddress); 4356 writel(0x01234567L, FBAddress);
4096 writel(0x456789ABL, (FBAddress+4)); 4357 writel(0x456789ABL, (FBAddress + 4));
4097 writel(0x89ABCDEFL, (FBAddress+8)); 4358 writel(0x89ABCDEFL, (FBAddress + 8));
4098 writel(0xCDEF0123L, (FBAddress+12)); 4359 writel(0xCDEF0123L, (FBAddress + 12));
4099 inSISIDXREG(SISSR,0x3b,reg); 4360
4361 inSISIDXREG(SISSR, 0x3b, reg);
4100 if(reg & 0x01) { 4362 if(reg & 0x01) {
4101 if(readl((FBAddress+12)) == 0xCDEF0123L) return(4); /* Channel A 128bit */ 4363 if(readl((FBAddress + 12)) == 0xCDEF0123L)
4364 return 4; /* Channel A 128bit */
4102 } 4365 }
4103 if(readl((FBAddress+4)) == 0x456789ABL) return(2); /* Channel B 64bit */ 4366
4104 return(1); /* 32bit */ 4367 if(readl((FBAddress + 4)) == 0x456789ABL)
4368 return 2; /* Channel B 64bit */
4369
4370 return 1; /* 32bit */
4371}
4372
4373static int __devinit
4374sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth,
4375 int PseudoRankCapacity, int PseudoAdrPinCount,
4376 unsigned int mapsize)
4377{
4378 SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
4379 unsigned short sr14;
4380 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
4381 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
4382 static const unsigned short SiS_DRAMType[17][5] = {
4383 {0x0C,0x0A,0x02,0x40,0x39},
4384 {0x0D,0x0A,0x01,0x40,0x48},
4385 {0x0C,0x09,0x02,0x20,0x35},
4386 {0x0D,0x09,0x01,0x20,0x44},
4387 {0x0C,0x08,0x02,0x10,0x31},
4388 {0x0D,0x08,0x01,0x10,0x40},
4389 {0x0C,0x0A,0x01,0x20,0x34},
4390 {0x0C,0x09,0x01,0x08,0x32},
4391 {0x0B,0x08,0x02,0x08,0x21},
4392 {0x0C,0x08,0x01,0x08,0x30},
4393 {0x0A,0x08,0x02,0x04,0x11},
4394 {0x0B,0x0A,0x01,0x10,0x28},
4395 {0x09,0x08,0x02,0x02,0x01},
4396 {0x0B,0x09,0x01,0x08,0x24},
4397 {0x0B,0x08,0x01,0x04,0x20},
4398 {0x0A,0x08,0x01,0x02,0x10},
4399 {0x09,0x08,0x01,0x01,0x00}
4400 };
4401
4402 for(k = 0; k <= 16; k++) {
4403
4404 RankCapacity = buswidth * SiS_DRAMType[k][3];
4405
4406 if(RankCapacity != PseudoRankCapacity)
4407 continue;
4408
4409 if((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount)
4410 continue;
4411
4412 BankNumHigh = RankCapacity * 16 * iteration - 1;
4413 if(iteration == 3) { /* Rank No */
4414 BankNumMid = RankCapacity * 16 - 1;
4415 } else {
4416 BankNumMid = RankCapacity * 16 * iteration / 2 - 1;
4417 }
4418
4419 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
4420 PhysicalAdrHigh = BankNumHigh;
4421 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
4422 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
4423
4424 andSISIDXREG(SISSR, 0x15, 0xFB); /* Test */
4425 orSISIDXREG(SISSR, 0x15, 0x04); /* Test */
4426 sr14 = (SiS_DRAMType[k][3] * buswidth) - 1;
4427 if(buswidth == 4) sr14 |= 0x80;
4428 else if(buswidth == 2) sr14 |= 0x40;
4429 outSISIDXREG(SISSR, 0x13, SiS_DRAMType[k][4]);
4430 outSISIDXREG(SISSR, 0x14, sr14);
4431
4432 BankNumHigh <<= 16;
4433 BankNumMid <<= 16;
4434
4435 if((BankNumHigh + PhysicalAdrHigh >= mapsize) ||
4436 (BankNumMid + PhysicalAdrHigh >= mapsize) ||
4437 (BankNumHigh + PhysicalAdrHalfPage >= mapsize) ||
4438 (BankNumHigh + PhysicalAdrOtherPage >= mapsize))
4439 continue;
4440
4441 /* Write data */
4442 writew(((unsigned short)PhysicalAdrHigh),
4443 (FBAddr + BankNumHigh + PhysicalAdrHigh));
4444 writew(((unsigned short)BankNumMid),
4445 (FBAddr + BankNumMid + PhysicalAdrHigh));
4446 writew(((unsigned short)PhysicalAdrHalfPage),
4447 (FBAddr + BankNumHigh + PhysicalAdrHalfPage));
4448 writew(((unsigned short)PhysicalAdrOtherPage),
4449 (FBAddr + BankNumHigh + PhysicalAdrOtherPage));
4450
4451 /* Read data */
4452 if(readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh)
4453 return 1;
4454 }
4455
4456 return 0;
4105} 4457}
4106 4458
4107static void __devinit 4459static void __devinit
4108sisfb_setramsize300(struct pci_dev *pdev) 4460sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
4109{ 4461{
4110 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4462 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4111 SIS_IOTYPE1 *FBAddr = ivideo->video_vbase; 4463 int i, j, buswidth;
4112 SIS_IOTYPE1 *Addr; 4464 int PseudoRankCapacity, PseudoAdrPinCount;
4113 USHORT sr13, sr14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0; 4465
4114 int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount; 4466 buswidth = sisfb_post_300_buswidth(ivideo);
4115 int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank; 4467
4116 int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k; 4468 for(i = 6; i >= 0; i--) {
4117 const USHORT SiS_DRAMType[17][5] = { 4469 PseudoRankCapacity = 1 << i;
4118 {0x0C,0x0A,0x02,0x40,0x39}, 4470 for(j = 4; j >= 1; j--) {
4119 {0x0D,0x0A,0x01,0x40,0x48}, 4471 PseudoAdrPinCount = 15 - j;
4120 {0x0C,0x09,0x02,0x20,0x35}, 4472 if((PseudoRankCapacity * j) <= 64) {
4121 {0x0D,0x09,0x01,0x20,0x44}, 4473 if(sisfb_post_300_rwtest(ivideo,
4122 {0x0C,0x08,0x02,0x10,0x31}, 4474 j,
4123 {0x0D,0x08,0x01,0x10,0x40}, 4475 buswidth,
4124 {0x0C,0x0A,0x01,0x20,0x34}, 4476 PseudoRankCapacity,
4125 {0x0C,0x09,0x01,0x08,0x32}, 4477 PseudoAdrPinCount,
4126 {0x0B,0x08,0x02,0x08,0x21}, 4478 mapsize))
4127 {0x0C,0x08,0x01,0x08,0x30}, 4479 return;
4128 {0x0A,0x08,0x02,0x04,0x11}, 4480 }
4129 {0x0B,0x0A,0x01,0x10,0x28}, 4481 }
4130 {0x09,0x08,0x02,0x02,0x01}, 4482 }
4131 {0x0B,0x09,0x01,0x08,0x24},
4132 {0x0B,0x08,0x01,0x04,0x20},
4133 {0x0A,0x08,0x01,0x02,0x10},
4134 {0x09,0x08,0x01,0x01,0x00}
4135 };
4136
4137 buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
4138
4139 MB2Bank = 16;
4140 Done = 0;
4141 for(i = 6; i >= 0; i--) {
4142 if(Done) break;
4143 PseudoRankCapacity = 1 << i;
4144 for(j = 4; j >= 1; j--) {
4145 if(Done) break;
4146 PseudoTotalCapacity = PseudoRankCapacity * j;
4147 PseudoAdrPinCount = 15 - j;
4148 if(PseudoTotalCapacity <= 64) {
4149 for(k = 0; k <= 16; k++) {
4150 if(Done) break;
4151 RankCapacity = buswidth * SiS_DRAMType[k][3];
4152 AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
4153 if(RankCapacity == PseudoRankCapacity)
4154 if(AdrPinCount <= PseudoAdrPinCount) {
4155 if(j == 3) { /* Rank No */
4156 BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
4157 BankNumMid = RankCapacity * MB2Bank * 1 - 1;
4158 } else {
4159 BankNumHigh = RankCapacity * MB2Bank * j - 1;
4160 BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
4161 }
4162 PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
4163 PhysicalAdrHigh = BankNumHigh;
4164 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
4165 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
4166 /* Write data */
4167 andSISIDXREG(SISSR,0x15,0xFB); /* Test */
4168 orSISIDXREG(SISSR,0x15,0x04); /* Test */
4169 TotalCapacity = SiS_DRAMType[k][3] * buswidth;
4170 sr13 = SiS_DRAMType[k][4];
4171 if(buswidth == 4) sr14 = (TotalCapacity - 1) | 0x80;
4172 if(buswidth == 2) sr14 = (TotalCapacity - 1) | 0x40;
4173 if(buswidth == 1) sr14 = (TotalCapacity - 1) | 0x00;
4174 outSISIDXREG(SISSR,0x13,sr13);
4175 outSISIDXREG(SISSR,0x14,sr14);
4176 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
4177 /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
4178 writew(((USHORT)PhysicalAdrHigh), Addr);
4179 Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
4180 /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
4181 writew(((USHORT)BankNumMid), Addr);
4182 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
4183 /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
4184 writew(((USHORT)PhysicalAdrHalfPage), Addr);
4185 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
4186 /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
4187 writew(((USHORT)PhysicalAdrOtherPage), Addr);
4188 /* Read data */
4189 Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
4190 data = readw(Addr); /* *((USHORT *)(Addr)); */
4191 if(data == PhysicalAdrHigh) Done = 1;
4192 } /* if */
4193 } /* for k */
4194 } /* if */
4195 } /* for j */
4196 } /* for i */
4197} 4483}
4198 4484
4199static void __devinit sisfb_post_sis300(struct pci_dev *pdev) 4485static void __devinit
4486sisfb_post_sis300(struct pci_dev *pdev)
4200{ 4487{
4201 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4488 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4489 unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
4202 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8; 4490 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
4203 u16 index, rindex, memtype = 0; 4491 u16 index, rindex, memtype = 0;
4492 unsigned int mapsize;
4204 4493
4205 outSISIDXREG(SISSR,0x05,0x86); 4494 if(!ivideo->SiS_Pr.UseROM)
4495 bios = NULL;
4206 4496
4207 if(ivideo->sishw_ext.UseROM) { 4497 outSISIDXREG(SISSR, 0x05, 0x86);
4208 if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) { 4498
4209 memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52]; 4499 if(bios) {
4210 } else { 4500 if(bios[0x52] & 0x80) {
4211 inSISIDXREG(SISSR,0x3a,memtype); 4501 memtype = bios[0x52];
4212 } 4502 } else {
4213 memtype &= 0x07; 4503 inSISIDXREG(SISSR, 0x3a, memtype);
4504 }
4505 memtype &= 0x07;
4214 } 4506 }
4215 4507
4508 v3 = 0x80; v6 = 0x80;
4216 if(ivideo->revision_id <= 0x13) { 4509 if(ivideo->revision_id <= 0x13) {
4217 v1 = 0x44; v2 = 0x42; v3 = 0x80; 4510 v1 = 0x44; v2 = 0x42;
4218 v4 = 0x44; v5 = 0x42; v6 = 0x80; 4511 v4 = 0x44; v5 = 0x42;
4219 } else { 4512 } else {
4220 v1 = 0x68; v2 = 0x43; v3 = 0x80; /* Assume 125Mhz MCLK */ 4513 v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */
4221 v4 = 0x68; v5 = 0x43; v6 = 0x80; /* Assume 125Mhz ECLK */ 4514 v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */
4222 if(ivideo->sishw_ext.UseROM) { 4515 if(bios) {
4223 index = memtype * 5; 4516 index = memtype * 5;
4224 rindex = index + 0x54; 4517 rindex = index + 0x54;
4225 v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4518 v1 = bios[rindex++];
4226 v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4519 v2 = bios[rindex++];
4227 v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4520 v3 = bios[rindex++];
4228 rindex = index + 0x7c; 4521 rindex = index + 0x7c;
4229 v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4522 v4 = bios[rindex++];
4230 v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4523 v5 = bios[rindex++];
4231 v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 4524 v6 = bios[rindex++];
4232 } 4525 }
4233 } 4526 }
4234 outSISIDXREG(SISSR,0x28,v1); 4527 outSISIDXREG(SISSR, 0x28, v1);
4235 outSISIDXREG(SISSR,0x29,v2); 4528 outSISIDXREG(SISSR, 0x29, v2);
4236 outSISIDXREG(SISSR,0x2a,v3); 4529 outSISIDXREG(SISSR, 0x2a, v3);
4237 outSISIDXREG(SISSR,0x2e,v4); 4530 outSISIDXREG(SISSR, 0x2e, v4);
4238 outSISIDXREG(SISSR,0x2f,v5); 4531 outSISIDXREG(SISSR, 0x2f, v5);
4239 outSISIDXREG(SISSR,0x30,v6); 4532 outSISIDXREG(SISSR, 0x30, v6);
4533
4240 v1 = 0x10; 4534 v1 = 0x10;
4241 if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4]; 4535 if(bios)
4242 outSISIDXREG(SISSR,0x07,v1); /* DAC speed */ 4536 v1 = bios[0xa4];
4243 outSISIDXREG(SISSR,0x11,0x0f); /* DDC, power save */ 4537 outSISIDXREG(SISSR, 0x07, v1); /* DAC speed */
4538
4539 outSISIDXREG(SISSR, 0x11, 0x0f); /* DDC, power save */
4540
4244 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a; 4541 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
4245 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00; 4542 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
4246 if(ivideo->sishw_ext.UseROM) { 4543 if(bios) {
4247 memtype += 0xa5; 4544 memtype += 0xa5;
4248 v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype]; 4545 v1 = bios[memtype];
4249 v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8]; 4546 v2 = bios[memtype + 8];
4250 v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16]; 4547 v3 = bios[memtype + 16];
4251 v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24]; 4548 v4 = bios[memtype + 24];
4252 v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32]; 4549 v5 = bios[memtype + 32];
4253 v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40]; 4550 v6 = bios[memtype + 40];
4254 v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48]; 4551 v7 = bios[memtype + 48];
4255 v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56]; 4552 v8 = bios[memtype + 56];
4256 } 4553 }
4257 if(ivideo->revision_id >= 0x80) v3 &= 0xfd; 4554 if(ivideo->revision_id >= 0x80)
4258 outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */ 4555 v3 &= 0xfd;
4259 outSISIDXREG(SISSR,0x16,v2); 4556 outSISIDXREG(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
4260 outSISIDXREG(SISSR,0x17,v3); 4557 outSISIDXREG(SISSR, 0x16, v2);
4261 outSISIDXREG(SISSR,0x18,v4); 4558 outSISIDXREG(SISSR, 0x17, v3);
4262 outSISIDXREG(SISSR,0x19,v5); 4559 outSISIDXREG(SISSR, 0x18, v4);
4263 outSISIDXREG(SISSR,0x1a,v6); 4560 outSISIDXREG(SISSR, 0x19, v5);
4264 outSISIDXREG(SISSR,0x1b,v7); 4561 outSISIDXREG(SISSR, 0x1a, v6);
4265 outSISIDXREG(SISSR,0x1c,v8); /* ---- */ 4562 outSISIDXREG(SISSR, 0x1b, v7);
4266 andSISIDXREG(SISSR,0x15,0xfb); 4563 outSISIDXREG(SISSR, 0x1c, v8); /* ---- */
4267 orSISIDXREG(SISSR,0x15,0x04); 4564 andSISIDXREG(SISSR, 0x15 ,0xfb);
4268 if(ivideo->sishw_ext.UseROM) { 4565 orSISIDXREG(SISSR, 0x15, 0x04);
4269 if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) { 4566 if(bios) {
4270 orSISIDXREG(SISSR,0x19,0x20); 4567 if(bios[0x53] & 0x02) {
4271 } 4568 orSISIDXREG(SISSR, 0x19, 0x20);
4569 }
4272 } 4570 }
4273 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */ 4571 v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */
4274 if(ivideo->revision_id >= 0x80) v1 |= 0x01; 4572 if(ivideo->revision_id >= 0x80)
4275 outSISIDXREG(SISSR,0x1f,v1); 4573 v1 |= 0x01;
4276 outSISIDXREG(SISSR,0x20,0xa0); /* linear & relocated io */ 4574 outSISIDXREG(SISSR, 0x1f, v1);
4575 outSISIDXREG(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */
4277 v1 = 0xf6; v2 = 0x0d; v3 = 0x00; 4576 v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
4278 if(ivideo->sishw_ext.UseROM) { 4577 if(bios) {
4279 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8]; 4578 v1 = bios[0xe8];
4280 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9]; 4579 v2 = bios[0xe9];
4281 v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea]; 4580 v3 = bios[0xea];
4282 } 4581 }
4283 outSISIDXREG(SISSR,0x23,v1); 4582 outSISIDXREG(SISSR, 0x23, v1);
4284 outSISIDXREG(SISSR,0x24,v2); 4583 outSISIDXREG(SISSR, 0x24, v2);
4285 outSISIDXREG(SISSR,0x25,v3); 4584 outSISIDXREG(SISSR, 0x25, v3);
4286 outSISIDXREG(SISSR,0x21,0x84); 4585 outSISIDXREG(SISSR, 0x21, 0x84);
4287 outSISIDXREG(SISSR,0x22,0x00); 4586 outSISIDXREG(SISSR, 0x22, 0x00);
4288 outSISIDXREG(SISCR,0x37,0x00); 4587 outSISIDXREG(SISCR, 0x37, 0x00);
4289 orSISIDXREG(SISPART1,0x24,0x01); /* unlock crt2 */ 4588 orSISIDXREG(SISPART1, 0x24, 0x01); /* unlock crt2 */
4290 outSISIDXREG(SISPART1,0x00,0x00); 4589 outSISIDXREG(SISPART1, 0x00, 0x00);
4291 v1 = 0x40; v2 = 0x11; 4590 v1 = 0x40; v2 = 0x11;
4292 if(ivideo->sishw_ext.UseROM) { 4591 if(bios) {
4293 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec]; 4592 v1 = bios[0xec];
4294 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb]; 4593 v2 = bios[0xeb];
4295 } 4594 }
4296 outSISIDXREG(SISPART1,0x02,v1); 4595 outSISIDXREG(SISPART1, 0x02, v1);
4297 if(ivideo->revision_id >= 0x80) v2 &= ~0x01; 4596
4298 inSISIDXREG(SISPART4,0x00,reg); 4597 if(ivideo->revision_id >= 0x80)
4598 v2 &= ~0x01;
4599
4600 inSISIDXREG(SISPART4, 0x00, reg);
4299 if((reg == 1) || (reg == 2)) { 4601 if((reg == 1) || (reg == 2)) {
4300 outSISIDXREG(SISCR,0x37,0x02); 4602 outSISIDXREG(SISCR, 0x37, 0x02);
4301 outSISIDXREG(SISPART2,0x00,0x1c); 4603 outSISIDXREG(SISPART2, 0x00, 0x1c);
4302 v4 = 0x00; v5 = 0x00; v6 = 0x10; 4604 v4 = 0x00; v5 = 0x00; v6 = 0x10;
4303 if(ivideo->sishw_ext.UseROM) { 4605 if(ivideo->SiS_Pr.UseROM) {
4304 v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5]; 4606 v4 = bios[0xf5];
4305 v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6]; 4607 v5 = bios[0xf6];
4306 v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7]; 4608 v6 = bios[0xf7];
4307 } 4609 }
4308 outSISIDXREG(SISPART4,0x0d,v4); 4610 outSISIDXREG(SISPART4, 0x0d, v4);
4309 outSISIDXREG(SISPART4,0x0e,v5); 4611 outSISIDXREG(SISPART4, 0x0e, v5);
4310 outSISIDXREG(SISPART4,0x10,v6); 4612 outSISIDXREG(SISPART4, 0x10, v6);
4311 outSISIDXREG(SISPART4,0x0f,0x3f); 4613 outSISIDXREG(SISPART4, 0x0f, 0x3f);
4312 inSISIDXREG(SISPART4,0x01,reg); 4614 inSISIDXREG(SISPART4, 0x01, reg);
4313 if(reg >= 0xb0) { 4615 if(reg >= 0xb0) {
4314 inSISIDXREG(SISPART4,0x23,reg); 4616 inSISIDXREG(SISPART4, 0x23, reg);
4315 reg &= 0x20; 4617 reg &= 0x20;
4316 reg <<= 1; 4618 reg <<= 1;
4317 outSISIDXREG(SISPART4,0x23,reg); 4619 outSISIDXREG(SISPART4, 0x23, reg);
4318 } 4620 }
4319 } else { 4621 } else {
4320 v2 &= ~0x10; 4622 v2 &= ~0x10;
4321 } 4623 }
4322 outSISIDXREG(SISSR,0x32,v2); 4624 outSISIDXREG(SISSR, 0x32, v2);
4323 andSISIDXREG(SISPART1,0x24,0xfe); /* Lock CRT2 */ 4625
4324 inSISIDXREG(SISSR,0x16,reg); 4626 andSISIDXREG(SISPART1, 0x24, 0xfe); /* Lock CRT2 */
4627
4628 inSISIDXREG(SISSR, 0x16, reg);
4325 reg &= 0xc3; 4629 reg &= 0xc3;
4326 outSISIDXREG(SISCR,0x35,reg); 4630 outSISIDXREG(SISCR, 0x35, reg);
4327 outSISIDXREG(SISCR,0x83,0x00); 4631 outSISIDXREG(SISCR, 0x83, 0x00);
4328#if !defined(__i386__) && !defined(__x86_64__) 4632#if !defined(__i386__) && !defined(__x86_64__)
4329 if(sisfb_videoram) { 4633 if(sisfb_videoram) {
4330 outSISIDXREG(SISSR,0x13,0x28); /* ? */ 4634 outSISIDXREG(SISSR, 0x13, 0x28); /* ? */
4331 reg = ((sisfb_videoram >> 10) - 1) | 0x40; 4635 reg = ((sisfb_videoram >> 10) - 1) | 0x40;
4332 outSISIDXREG(SISSR,0x14,reg); 4636 outSISIDXREG(SISSR, 0x14, reg);
4333 } else { 4637 } else {
4334#endif 4638#endif
4335 /* Need to map max FB size for finding out about RAM size */ 4639 /* Need to map max FB size for finding out about RAM size */
4336 ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000); 4640 mapsize = 64 << 20;
4337 if(ivideo->video_vbase) { 4641 sisfb_post_map_vram(ivideo, &mapsize, 4);
4338 sisfb_setramsize300(pdev); 4642
4339 iounmap(ivideo->video_vbase); 4643 if(ivideo->video_vbase) {
4340 } else { 4644 sisfb_post_300_ramsize(pdev, mapsize);
4341 printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n"); 4645 iounmap(ivideo->video_vbase);
4342 outSISIDXREG(SISSR,0x13,0x28); /* ? */ 4646 } else {
4343 outSISIDXREG(SISSR,0x14,0x47); /* 8MB, 64bit default */ 4647 printk(KERN_DEBUG
4344 } 4648 "sisfb: Failed to map memory for size detection, assuming 8MB\n");
4649 outSISIDXREG(SISSR, 0x13, 0x28); /* ? */
4650 outSISIDXREG(SISSR, 0x14, 0x47); /* 8MB, 64bit default */
4651 }
4345#if !defined(__i386__) && !defined(__x86_64__) 4652#if !defined(__i386__) && !defined(__x86_64__)
4346 } 4653 }
4347#endif 4654#endif
4348 if(ivideo->sishw_ext.UseROM) { 4655 if(bios) {
4349 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6]; 4656 v1 = bios[0xe6];
4350 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7]; 4657 v2 = bios[0xe7];
4351 } else { 4658 } else {
4352 inSISIDXREG(SISSR,0x3a,reg); 4659 inSISIDXREG(SISSR, 0x3a, reg);
4353 if((reg & 0x30) == 0x30) { 4660 if((reg & 0x30) == 0x30) {
4354 v1 = 0x04; /* PCI */ 4661 v1 = 0x04; /* PCI */
4355 v2 = 0x92; 4662 v2 = 0x92;
4356 } else { 4663 } else {
4357 v1 = 0x14; /* AGP */ 4664 v1 = 0x14; /* AGP */
4358 v2 = 0xb2; 4665 v2 = 0xb2;
4359 } 4666 }
4360 } 4667 }
4361 outSISIDXREG(SISSR,0x21,v1); 4668 outSISIDXREG(SISSR, 0x21, v1);
4362 outSISIDXREG(SISSR,0x22,v2); 4669 outSISIDXREG(SISSR, 0x22, v2);
4670
4671 /* Sense CRT1 */
4672 sisfb_sense_crt1(ivideo);
4673
4674 /* Set default mode, don't clear screen */
4675 ivideo->SiS_Pr.SiS_UseOEM = FALSE;
4676 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
4677 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
4678 ivideo->curFSTN = ivideo->curDSTN = 0;
4679 ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
4680 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
4681
4682 outSISIDXREG(SISSR, 0x05, 0x86);
4683
4684 /* Display off */
4685 orSISIDXREG(SISSR, 0x01, 0x20);
4686
4687 /* Save mode number in CR34 */
4688 outSISIDXREG(SISCR, 0x34, 0x2e);
4689
4690 /* Let everyone know what the current mode is */
4691 ivideo->modeprechange = 0x2e;
4363} 4692}
4364#endif 4693#endif
4365 4694
4366#ifdef CONFIG_FB_SIS_315 4695#ifdef CONFIG_FB_SIS_315
4367static void __devinit sisfb_post_sis315330(struct pci_dev *pdev) 4696#if 0
4697static void __devinit
4698sisfb_post_sis315330(struct pci_dev *pdev)
4368{ 4699{
4369#ifdef YET_TO_BE_DONE 4700 /* TODO */
4370 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4701}
4371 u8 reg, v1, v2, v3, v4, v5, v6, v7, v8; 4702#endif
4372 u16 index, rindex, memtype = 0; 4703
4373 u32 reg1_32, reg2_32, reg3_32; 4704static void __devinit
4705sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4706{
4707 unsigned int i;
4708 u8 reg;
4709
4710 for(i = 0; i <= (delay * 10 * 36); i++) {
4711 inSISIDXREG(SISSR, 0x05, reg);
4712 reg++;
4713 }
4714}
4715
4716static int __devinit
4717sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
4718 unsigned short pcivendor)
4719{
4720 struct pci_dev *pdev = NULL;
4721 unsigned short temp;
4722 int ret = 0;
4723
4724 while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) {
4725 temp = pdev->vendor;
4726 SIS_PCI_PUT_DEVICE(pdev);
4727 if(temp == pcivendor) {
4728 ret = 1;
4729 break;
4730 }
4731 }
4732
4733 return ret;
4734}
4735
4736static int __devinit
4737sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4738 unsigned int enda, unsigned int mapsize)
4739{
4740 unsigned int pos;
4374 int i; 4741 int i;
4375 4742
4376 /* Unlock */ 4743 writel(0, ivideo->video_vbase);
4377 /* outSISIDXREG(0x3c4,0x05,0x86); */
4378 outSISIDXREG(SISSR,0x05,0x86);
4379 4744
4380 /* Enable relocated i/o ports */ 4745 for(i = starta; i <= enda; i++) {
4381 /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */ 4746 pos = 1 << i;
4382 setSISIDXREG(SISSR,0x20,~0x10,0x20); 4747 if(pos < mapsize)
4748 writel(pos, ivideo->video_vbase + pos);
4749 }
4750
4751 sisfb_post_xgi_delay(ivideo, 150);
4752
4753 if(readl(ivideo->video_vbase) != 0)
4754 return 0;
4383 4755
4384 /* Clear regs */ 4756 for(i = starta; i <= enda; i++) {
4757 pos = 1 << i;
4758 if(pos < mapsize) {
4759 if(readl(ivideo->video_vbase + pos) != pos)
4760 return 0;
4761 } else
4762 return 0;
4763 }
4764
4765 return 1;
4766}
4767
4768static void __devinit
4769sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4770{
4771 unsigned int buswidth, ranksize, channelab, mapsize;
4772 int i, j, k, l;
4773 u8 reg, sr14;
4774 static const u8 dramsr13[12 * 5] = {
4775 0x02, 0x0e, 0x0b, 0x80, 0x5d,
4776 0x02, 0x0e, 0x0a, 0x40, 0x59,
4777 0x02, 0x0d, 0x0b, 0x40, 0x4d,
4778 0x02, 0x0e, 0x09, 0x20, 0x55,
4779 0x02, 0x0d, 0x0a, 0x20, 0x49,
4780 0x02, 0x0c, 0x0b, 0x20, 0x3d,
4781 0x02, 0x0e, 0x08, 0x10, 0x51,
4782 0x02, 0x0d, 0x09, 0x10, 0x45,
4783 0x02, 0x0c, 0x0a, 0x10, 0x39,
4784 0x02, 0x0d, 0x08, 0x08, 0x41,
4785 0x02, 0x0c, 0x09, 0x08, 0x35,
4786 0x02, 0x0c, 0x08, 0x04, 0x31
4787 };
4788 static const u8 dramsr13_4[4 * 5] = {
4789 0x02, 0x0d, 0x09, 0x40, 0x45,
4790 0x02, 0x0c, 0x09, 0x20, 0x35,
4791 0x02, 0x0c, 0x08, 0x10, 0x31,
4792 0x02, 0x0b, 0x08, 0x08, 0x21
4793 };
4794
4795 /* Enable linear mode, disable 0xa0000 address decoding */
4796 /* We disable a0000 address decoding, because
4797 * - if running on x86, if the card is disabled, it means
4798 * that another card is in the system. We don't want
4799 * to interphere with that primary card's textmode.
4800 * - if running on non-x86, there usually is no VGA window
4801 * at a0000.
4802 */
4803 orSISIDXREG(SISSR, 0x20, (0x80 | 0x04));
4804
4805 /* Need to map max FB size for finding out about RAM size */
4806 mapsize = 256 << 20;
4807 sisfb_post_map_vram(ivideo, &mapsize, 32);
4808
4809 if(!ivideo->video_vbase) {
4810 printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n");
4811 outSISIDXREG(SISSR, 0x13, 0x35);
4812 outSISIDXREG(SISSR, 0x14, 0x41);
4813 /* TODO */
4814 return;
4815 }
4816
4817 /* Non-interleaving */
4818 outSISIDXREG(SISSR, 0x15, 0x00);
4819 /* No tiling */
4820 outSISIDXREG(SISSR, 0x1c, 0x00);
4821
4822 if(ivideo->chip == XGI_20) {
4823
4824 channelab = 1;
4825 inSISIDXREG(SISCR, 0x97, reg);
4826 if(!(reg & 0x01)) { /* Single 32/16 */
4827 buswidth = 32;
4828 outSISIDXREG(SISSR, 0x13, 0xb1);
4829 outSISIDXREG(SISSR, 0x14, 0x52);
4830 sisfb_post_xgi_delay(ivideo, 1);
4831 sr14 = 0x02;
4832 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4833 goto bail_out;
4834
4835 outSISIDXREG(SISSR, 0x13, 0x31);
4836 outSISIDXREG(SISSR, 0x14, 0x42);
4837 sisfb_post_xgi_delay(ivideo, 1);
4838 if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize))
4839 goto bail_out;
4840
4841 buswidth = 16;
4842 outSISIDXREG(SISSR, 0x13, 0xb1);
4843 outSISIDXREG(SISSR, 0x14, 0x41);
4844 sisfb_post_xgi_delay(ivideo, 1);
4845 sr14 = 0x01;
4846 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4847 goto bail_out;
4848 else
4849 outSISIDXREG(SISSR, 0x13, 0x31);
4850 } else { /* Dual 16/8 */
4851 buswidth = 16;
4852 outSISIDXREG(SISSR, 0x13, 0xb1);
4853 outSISIDXREG(SISSR, 0x14, 0x41);
4854 sisfb_post_xgi_delay(ivideo, 1);
4855 sr14 = 0x01;
4856 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4857 goto bail_out;
4858
4859 outSISIDXREG(SISSR, 0x13, 0x31);
4860 outSISIDXREG(SISSR, 0x14, 0x31);
4861 sisfb_post_xgi_delay(ivideo, 1);
4862 if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize))
4863 goto bail_out;
4864
4865 buswidth = 8;
4866 outSISIDXREG(SISSR, 0x13, 0xb1);
4867 outSISIDXREG(SISSR, 0x14, 0x30);
4868 sisfb_post_xgi_delay(ivideo, 1);
4869 sr14 = 0x00;
4870 if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize))
4871 goto bail_out;
4872 else
4873 outSISIDXREG(SISSR, 0x13, 0x31);
4874 }
4875
4876 } else { /* XGI_40 */
4877
4878 inSISIDXREG(SISCR, 0x97, reg);
4879 if(!(reg & 0x10)) {
4880 inSISIDXREG(SISSR, 0x39, reg);
4881 reg >>= 1;
4882 }
4883
4884 if(reg & 0x01) { /* DDRII */
4885 buswidth = 32;
4886 if(ivideo->revision_id == 2) {
4887 channelab = 2;
4888 outSISIDXREG(SISSR, 0x13, 0xa1);
4889 outSISIDXREG(SISSR, 0x14, 0x44);
4890 sr14 = 0x04;
4891 sisfb_post_xgi_delay(ivideo, 1);
4892 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4893 goto bail_out;
4894
4895 outSISIDXREG(SISSR, 0x13, 0x21);
4896 outSISIDXREG(SISSR, 0x14, 0x34);
4897 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4898 goto bail_out;
4899
4900 channelab = 1;
4901 outSISIDXREG(SISSR, 0x13, 0xa1);
4902 outSISIDXREG(SISSR, 0x14, 0x40);
4903 sr14 = 0x00;
4904 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4905 goto bail_out;
4906
4907 outSISIDXREG(SISSR, 0x13, 0x21);
4908 outSISIDXREG(SISSR, 0x14, 0x30);
4909 } else {
4910 channelab = 3;
4911 outSISIDXREG(SISSR, 0x13, 0xa1);
4912 outSISIDXREG(SISSR, 0x14, 0x4c);
4913 sr14 = 0x0c;
4914 sisfb_post_xgi_delay(ivideo, 1);
4915 if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize))
4916 goto bail_out;
4917
4918 channelab = 2;
4919 outSISIDXREG(SISSR, 0x14, 0x48);
4920 sisfb_post_xgi_delay(ivideo, 1);
4921 sr14 = 0x08;
4922 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4923 goto bail_out;
4924
4925 outSISIDXREG(SISSR, 0x13, 0x21);
4926 outSISIDXREG(SISSR, 0x14, 0x3c);
4927 sr14 = 0x0c;
4928
4929 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) {
4930 channelab = 3;
4931 } else {
4932 channelab = 2;
4933 outSISIDXREG(SISSR, 0x14, 0x38);
4934 sr14 = 0x08;
4935 }
4936 }
4937 sisfb_post_xgi_delay(ivideo, 1);
4938
4939 } else { /* DDR */
4940
4941 buswidth = 64;
4942 if(ivideo->revision_id == 2) {
4943 channelab = 1;
4944 outSISIDXREG(SISSR, 0x13, 0xa1);
4945 outSISIDXREG(SISSR, 0x14, 0x52);
4946 sisfb_post_xgi_delay(ivideo, 1);
4947 sr14 = 0x02;
4948 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4949 goto bail_out;
4950
4951 outSISIDXREG(SISSR, 0x13, 0x21);
4952 outSISIDXREG(SISSR, 0x14, 0x42);
4953 } else {
4954 channelab = 2;
4955 outSISIDXREG(SISSR, 0x13, 0xa1);
4956 outSISIDXREG(SISSR, 0x14, 0x5a);
4957 sisfb_post_xgi_delay(ivideo, 1);
4958 sr14 = 0x0a;
4959 if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize))
4960 goto bail_out;
4961
4962 outSISIDXREG(SISSR, 0x13, 0x21);
4963 outSISIDXREG(SISSR, 0x14, 0x4a);
4964 }
4965 sisfb_post_xgi_delay(ivideo, 1);
4966
4967 }
4968 }
4969
4970bail_out:
4971 setSISIDXREG(SISSR, 0x14, 0xf0, sr14);
4972 sisfb_post_xgi_delay(ivideo, 1);
4973
4974 j = (ivideo->chip == XGI_20) ? 5 : 9;
4975 k = (ivideo->chip == XGI_20) ? 12 : 4;
4976
4977 for(i = 0; i < k; i++) {
4978
4979 reg = (ivideo->chip == XGI_20) ?
4980 dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4];
4981 setSISIDXREG(SISSR, 0x13, 0x80, reg);
4982 sisfb_post_xgi_delay(ivideo, 50);
4983
4984 ranksize = (ivideo->chip == XGI_20) ?
4985 dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3];
4986
4987 inSISIDXREG(SISSR, 0x13, reg);
4988 if(reg & 0x80) ranksize <<= 1;
4989
4990 if(ivideo->chip == XGI_20) {
4991 if(buswidth == 16) ranksize <<= 1;
4992 else if(buswidth == 32) ranksize <<= 2;
4993 } else {
4994 if(buswidth == 64) ranksize <<= 1;
4995 }
4996
4997 reg = 0;
4998 l = channelab;
4999 if(l == 3) l = 4;
5000 if((ranksize * l) <= 256) {
5001 while((ranksize >>= 1)) reg += 0x10;
5002 }
5003
5004 if(!reg) continue;
5005
5006 setSISIDXREG(SISSR, 0x14, 0x0f, (reg & 0xf0));
5007 sisfb_post_xgi_delay(ivideo, 1);
5008
5009 if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
5010 break;
5011 }
5012
5013 iounmap(ivideo->video_vbase);
5014}
5015
5016static void __devinit
5017sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
5018{
5019 u8 v1, v2, v3;
5020 int index;
5021 static const u8 cs90[8 * 3] = {
5022 0x16, 0x01, 0x01,
5023 0x3e, 0x03, 0x01,
5024 0x7c, 0x08, 0x01,
5025 0x79, 0x06, 0x01,
5026 0x29, 0x01, 0x81,
5027 0x5c, 0x23, 0x01,
5028 0x5c, 0x23, 0x01,
5029 0x5c, 0x23, 0x01
5030 };
5031 static const u8 csb8[8 * 3] = {
5032 0x5c, 0x23, 0x01,
5033 0x29, 0x01, 0x01,
5034 0x7c, 0x08, 0x01,
5035 0x79, 0x06, 0x01,
5036 0x29, 0x01, 0x81,
5037 0x5c, 0x23, 0x01,
5038 0x5c, 0x23, 0x01,
5039 0x5c, 0x23, 0x01
5040 };
5041
5042 regb = 0; /* ! */
5043
5044 index = regb * 3;
5045 v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2];
5046 if(ivideo->haveXGIROM) {
5047 v1 = ivideo->bios_abase[0x90 + index];
5048 v2 = ivideo->bios_abase[0x90 + index + 1];
5049 v3 = ivideo->bios_abase[0x90 + index + 2];
5050 }
5051 outSISIDXREG(SISSR, 0x28, v1);
5052 outSISIDXREG(SISSR, 0x29, v2);
5053 outSISIDXREG(SISSR, 0x2a, v3);
5054 sisfb_post_xgi_delay(ivideo, 0x43);
5055 sisfb_post_xgi_delay(ivideo, 0x43);
5056 sisfb_post_xgi_delay(ivideo, 0x43);
5057 index = regb * 3;
5058 v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2];
5059 if(ivideo->haveXGIROM) {
5060 v1 = ivideo->bios_abase[0xb8 + index];
5061 v2 = ivideo->bios_abase[0xb8 + index + 1];
5062 v3 = ivideo->bios_abase[0xb8 + index + 2];
5063 }
5064 outSISIDXREG(SISSR, 0x2e, v1);
5065 outSISIDXREG(SISSR, 0x2f, v2);
5066 outSISIDXREG(SISSR, 0x30, v3);
5067 sisfb_post_xgi_delay(ivideo, 0x43);
5068 sisfb_post_xgi_delay(ivideo, 0x43);
5069 sisfb_post_xgi_delay(ivideo, 0x43);
5070}
5071
5072static int __devinit
5073sisfb_post_xgi(struct pci_dev *pdev)
5074{
5075 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
5076 unsigned char *bios = ivideo->bios_abase;
5077 struct pci_dev *mypdev = NULL;
5078 const u8 *ptr, *ptr2;
5079 u8 v1, v2, v3, v4, v5, reg, ramtype;
5080 u32 rega, regb, regd;
5081 int i, j, k, index;
5082 static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
5083 static const u8 cs76[2] = { 0xa3, 0xfb };
5084 static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
5085 static const u8 cs158[8] = {
5086 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5087 };
5088 static const u8 cs160[8] = {
5089 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5090 };
5091 static const u8 cs168[8] = {
5092 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5093 };
5094 static const u8 cs128[3 * 8] = {
5095 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
5096 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5097 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
5098 };
5099 static const u8 cs148[2 * 8] = {
5100 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
5101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5102 };
5103 static const u8 cs31a[8 * 4] = {
5104 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
5105 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
5106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5108 };
5109 static const u8 cs33a[8 * 4] = {
5110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5114 };
5115 static const u8 cs45a[8 * 2] = {
5116 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
5117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5118 };
5119 static const u8 cs170[7 * 8] = {
5120 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5121 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5122 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
5123 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5124 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
5125 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
5126 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
5127 };
5128 static const u8 cs1a8[3 * 8] = {
5129 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
5130 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
5131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5132 };
5133 static const u8 cs100[2 * 8] = {
5134 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
5135 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
5136 };
5137
5138 /* VGA enable */
5139 reg = inSISREG(SISVGAENABLE) | 0x01;
5140 outSISREG(SISVGAENABLE, reg);
5141
5142 /* Misc */
5143 reg = inSISREG(SISMISCR) | 0x01;
5144 outSISREG(SISMISCW, reg);
5145
5146 /* Unlock SR */
5147 outSISIDXREG(SISSR, 0x05, 0x86);
5148 inSISIDXREG(SISSR, 0x05, reg);
5149 if(reg != 0xa1)
5150 return 0;
5151
5152 /* Clear some regs */
4385 for(i = 0; i < 0x22; i++) { 5153 for(i = 0; i < 0x22; i++) {
4386 outSISIDXREG(SISSR,(0x06 + i),0x00); 5154 if(0x06 + i == 0x20) continue;
5155 outSISIDXREG(SISSR, 0x06 + i, 0x00);
4387 } 5156 }
4388 v1 = 0x0d; 5157 for(i = 0; i < 0x0b; i++) {
4389 if( is 330) v1 = 0x0b; 5158 outSISIDXREG(SISSR, 0x31 + i, 0x00);
4390 for(i = 0; i < v1; i++) {
4391 outSISIDXREG(SISSR,(0x31 + i),0x00);
4392 } 5159 }
4393 for(i = 0; i < 0x10; i++) { 5160 for(i = 0; i < 0x10; i++) {
4394 outSISIDXREG(SISCR,(0x30 + i),0x00); 5161 outSISIDXREG(SISCR, 0x30 + i, 0x00);
4395 }
4396
4397 /* Reset clocks */
4398 reg = inSISREG(SISMISCR);
4399 outSISIDXREG(SISSR,0x28,0x81);
4400 outSISIDXREG(SISSR,0x2A,0x00);
4401 outSISIDXREG(SISSR,0x29,0xE1);
4402 outSISREG(SISMISCW,(reg | 0x0c));
4403 outSISIDXREG(SISSR,0x2B,0x81);
4404 outSISIDXREG(SISSR,0x2D,0x00);
4405 outSISIDXREG(SISSR,0x2C,0xE1);
4406 outSISIDXREG(SISSR,0x2E,0x81);
4407 outSISIDXREG(SISSR,0x30,0x00);
4408 outSISIDXREG(SISSR,0x2F,0xE1);
4409 SiS_DDC2Delay(....);
4410 outSISREG(SISMISCW,reg);
4411
4412 /* Get memory type */
4413 if(ivideo->sishw_ext.UseROM) {
4414 if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
4415 memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
4416 } else {
4417 inSISIDXREG(SISSR,0x3a,memtype);
4418 }
4419 memtype &= 0x03;
4420 if( is 330 ) {
4421 if(memtype <= 1) memtype = 0;
4422 else {
4423 inSISIDXREG(SISCR,0x5F,reg);
4424 reg &= 0x30;
4425 switch(reg) {
4426 case 0x00: memtype = 1; break;
4427 case 0x10: memtype = 3; break;
4428 case 0x20: memtype = 3; break;
4429 default: memtype = 2;
4430 }
4431 }
4432 }
4433 } 5162 }
4434 5163
4435 /* Set clocks */ 5164 ptr = cs78;
4436 v1 = 0x3b; v2 = 0x22; v3 = 0x01; /* Assume 143Mhz MCLK */ 5165 if(ivideo->haveXGIROM) {
4437 v4 = 0x5c; v5 = 0x23; v6 = 0x01; /* Assume 166Mhz ECLK */ 5166 ptr = (const u8 *)&bios[0x78];
4438 if(ivideo->sishw_ext.UseROM) { 5167 }
4439 index = memtype * 5; 5168 for(i = 0; i < 3; i++) {
4440 rindex = index + 0x54; 5169 outSISIDXREG(SISSR, 0x23 + i, ptr[i]);
4441 v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5170 }
4442 v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5171
4443 v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5172 ptr = cs76;
4444 rindex = index + 0x68; 5173 if(ivideo->haveXGIROM) {
4445 v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5174 ptr = (const u8 *)&bios[0x76];
4446 v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5175 }
4447 v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++]; 5176 for(i = 0; i < 2; i++) {
4448 } 5177 outSISIDXREG(SISSR, 0x21 + i, ptr[i]);
4449 outSISIDXREG(SISSR,0x28,v1); 5178 }
4450 outSISIDXREG(SISSR,0x29,v2); 5179
4451 outSISIDXREG(SISSR,0x2a,v3); 5180 v1 = 0x18; v2 = 0x00;
4452 if( is 330 ) { 5181 if(ivideo->haveXGIROM) {
4453 inSISIDXREG(SISSR,0x3a,reg); 5182 v1 = bios[0x74];
4454 reg &= 0x03; 5183 v2 = bios[0x75];
4455 if(reg >= 2) { 5184 }
4456 ... 5185 outSISIDXREG(SISSR, 0x07, v1);
4457 } 5186 outSISIDXREG(SISSR, 0x11, 0x0f);
5187 outSISIDXREG(SISSR, 0x1f, v2);
5188 /* PCI linear mode, RelIO enabled, A0000 decoding disabled */
5189 outSISIDXREG(SISSR, 0x20, 0x80 | 0x20 | 0x04);
5190 outSISIDXREG(SISSR, 0x27, 0x74);
5191
5192 ptr = cs7b;
5193 if(ivideo->haveXGIROM) {
5194 ptr = (const u8 *)&bios[0x7b];
5195 }
5196 for(i = 0; i < 3; i++) {
5197 outSISIDXREG(SISSR, 0x31 + i, ptr[i]);
4458 } 5198 }
4459 outSISIDXREG(SISSR,0x2e,v4);
4460 outSISIDXREG(SISSR,0x2f,v5);
4461 outSISIDXREG(SISSR,0x30,v6);
4462
4463 /* End of comp with 330 */
4464
4465 v1 = 0x18;
4466 if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
4467 outSISIDXREG(SISSR,0x07,v1);
4468 outSISIDXREG(SISSR,0x11,0x0f);
4469
4470 v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
4471 v5 = 0xa0; v6 = 0x00; v7 = 0x30;
4472 if(ivideo->sishw_ext.UseROM) {
4473 index = memtype + 0x7d;
4474 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4475 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4476 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4477 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4478 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4479 v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
4480 v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
4481 }
4482 outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0x7d step 4) */
4483 outSISIDXREG(SISSR,0x16,v2);
4484 outSISIDXREG(SISSR,0x17,v3);
4485 outSISIDXREG(SISSR,0x18,v4);
4486 outSISIDXREG(SISSR,0x19,v5);
4487 outSISIDXREG(SISSR,0x1a,v6);
4488 outSISIDXREG(SISSR,0x1b,v7);
4489 outSISIDXREG(SISSR,0x1c,v8); /* ---- */
4490
4491 v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
4492 if(ivideo->sishw_ext.UseROM) {
4493 index = memtype + 0xa2;
4494 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4495 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4496 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4497 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4498 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4499 }
4500 outSISIDXREG(SISCR,0x40,v1);
4501 outSISIDXREG(SISCR,0x41,v2);
4502 outSISIDXREG(SISCR,0x42,v3);
4503 outSISIDXREG(SISCR,0x43,v4);
4504 outSISIDXREG(SISCR,0x44,v5);
4505
4506 if( is 330 ) {
4507
4508 v1 = 0x;
4509 if(ivideo->sishw_ext.UseROM) {
4510 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
4511 }
4512 outSISIDXREG(SISCR,0x59,v1);
4513
4514 v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
4515 v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
4516 if(ivideo->sishw_ext.UseROM) {
4517 index = memtype + 0xbe;
4518 v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
4519 v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
4520 v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
4521 v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
4522 v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
4523 v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
4524 v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
4525 v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
4526 }
4527 outSISIDXREG(SISCR,0x68,v1);
4528 outSISIDXREG(SISCR,0x69,v2);
4529 outSISIDXREG(SISCR,0x6a,v3);
4530 outSISIDXREG(SISCR,0x6b,v4);
4531 outSISIDXREG(SISCR,0x6c,v5);
4532 outSISIDXREG(SISCR,0x6d,v6);
4533 outSISIDXREG(SISCR,0x6e,v7);
4534 outSISIDXREG(SISCR,0x6f,v8);
4535
4536 v1 = 0x20;
4537 inSISIDXREG(SISSR,0x3b,reg);
4538
4539 if(!(reg & 0x04)) {
4540 inSISIDXREG(SISCR,0x5F,reg);
4541 reg &= 0x30;
4542 if(reg) v1 = 0x23;
4543 }
4544 outSISIDXREG(SISCR,0x48,v1);
4545 outSISIDXREG(SISCR,0x4c,0x20);
4546
4547 xx= xxx();
4548 if(xx >= 1) {
4549 v1 = 0x;
4550 if(ivideo->sishw_ext.UseROM) {
4551 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
4552 }
4553 outSISIDXREG(SISCR,0x59,v1);
4554 }
4555 5199
5200 if(ivideo->chip == XGI_40) {
5201 if(ivideo->revision_id == 2) {
5202 setSISIDXREG(SISSR, 0x3b, 0x3f, 0xc0);
5203 }
5204 outSISIDXREG(SISCR, 0x7d, 0xfe);
5205 outSISIDXREG(SISCR, 0x7e, 0x0f);
5206 }
5207 if(ivideo->revision_id == 0) { /* 40 *and* 20? */
5208 andSISIDXREG(SISCR, 0x58, 0xd7);
5209 inSISIDXREG(SISCR, 0xcb, reg);
5210 if(reg & 0x20) {
5211 setSISIDXREG(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */
5212 }
5213 }
4556 5214
5215 reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00;
5216 setSISIDXREG(SISCR, 0x38, 0x1f, reg);
4557 5217
5218 if(ivideo->chip == XGI_20) {
5219 outSISIDXREG(SISSR, 0x36, 0x70);
4558 } else { 5220 } else {
5221 outSISIDXREG(SISVID, 0x00, 0x86);
5222 outSISIDXREG(SISVID, 0x32, 0x00);
5223 outSISIDXREG(SISVID, 0x30, 0x00);
5224 outSISIDXREG(SISVID, 0x32, 0x01);
5225 outSISIDXREG(SISVID, 0x30, 0x00);
5226 andSISIDXREG(SISVID, 0x2f, 0xdf);
5227 andSISIDXREG(SISCAP, 0x00, 0x3f);
5228
5229 outSISIDXREG(SISPART1, 0x2f, 0x01);
5230 outSISIDXREG(SISPART1, 0x00, 0x00);
5231 outSISIDXREG(SISPART1, 0x02, bios[0x7e]);
5232 outSISIDXREG(SISPART1, 0x2e, 0x08);
5233 andSISIDXREG(SISPART1, 0x35, 0x7f);
5234 andSISIDXREG(SISPART1, 0x50, 0xfe);
5235
5236 inSISIDXREG(SISPART4, 0x00, reg);
5237 if(reg == 1 || reg == 2) {
5238 outSISIDXREG(SISPART2, 0x00, 0x1c);
5239 outSISIDXREG(SISPART4, 0x0d, bios[0x7f]);
5240 outSISIDXREG(SISPART4, 0x0e, bios[0x80]);
5241 outSISIDXREG(SISPART4, 0x10, bios[0x81]);
5242 andSISIDXREG(SISPART4, 0x0f, 0x3f);
5243
5244 inSISIDXREG(SISPART4, 0x01, reg);
5245 if((reg & 0xf0) >= 0xb0) {
5246 inSISIDXREG(SISPART4, 0x23, reg);
5247 if(reg & 0x20) reg |= 0x40;
5248 outSISIDXREG(SISPART4, 0x23, reg);
5249 reg = (reg & 0x20) ? 0x02 : 0x00;
5250 setSISIDXREG(SISPART1, 0x1e, 0xfd, reg);
5251 }
5252 }
4559 5253
4560 outSISIDXREG(SISCR,0x48,0x23); 5254 v1 = bios[0x77];
5255
5256 inSISIDXREG(SISSR, 0x3b, reg);
5257 if(reg & 0x02) {
5258 inSISIDXREG(SISSR, 0x3a, reg);
5259 v2 = (reg & 0x30) >> 3;
5260 if(!(v2 & 0x04)) v2 ^= 0x02;
5261 inSISIDXREG(SISSR, 0x39, reg);
5262 if(reg & 0x80) v2 |= 0x80;
5263 v2 |= 0x01;
5264
5265 if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
5266 SIS_PCI_PUT_DEVICE(mypdev);
5267 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
5268 v2 &= 0xf9;
5269 v2 |= 0x08;
5270 v1 &= 0xfe;
5271 } else {
5272 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL);
5273 if(!mypdev)
5274 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL);
5275 if(!mypdev)
5276 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL);
5277 if(mypdev) {
5278 pci_read_config_dword(mypdev, 0x94, &regd);
5279 regd &= 0xfffffeff;
5280 pci_write_config_dword(mypdev, 0x94, regd);
5281 v1 &= 0xfe;
5282 SIS_PCI_PUT_DEVICE(mypdev);
5283 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
5284 v1 &= 0xfe;
5285 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
5286 sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
5287 sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
5288 sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
5289 if((v2 & 0x06) == 4)
5290 v2 ^= 0x06;
5291 v2 |= 0x08;
5292 }
5293 }
5294 setSISIDXREG(SISCR, 0x5f, 0xf0, v2);
5295 }
5296 outSISIDXREG(SISSR, 0x22, v1);
5297
5298 if(ivideo->revision_id == 2) {
5299 inSISIDXREG(SISSR, 0x3b, v1);
5300 inSISIDXREG(SISSR, 0x3a, v2);
5301 regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
5302 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
5303 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
5304
5305 if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) {
5306 /* TODO: set CR5f &0xf1 | 0x01 for version 6570
5307 * of nforce 2 ROM
5308 */
5309 if(0)
5310 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
5311 SIS_PCI_PUT_DEVICE(mypdev);
5312 }
5313 }
4561 5314
4562 andSISIDXREG(SISSR,0x16,0x0f); 5315 v1 = 0x30;
4563 if(memtype <= 1) { 5316 inSISIDXREG(SISSR, 0x3b, reg);
4564 orSISIDXREG(SISSR,0x16,0x80); 5317 inSISIDXREG(SISCR, 0x5f, v2);
4565 } else { 5318 if((!(reg & 0x02)) && (v2 & 0x0e))
4566 v1 = 0x0f; 5319 v1 |= 0x08;
4567 if(ivideo->sishw_ext.UseROM) { 5320 outSISIDXREG(SISSR, 0x27, v1);
4568 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype]; 5321
4569 } 5322 if(bios[0x64] & 0x01) {
4570 if(!(v1 & 0x10)) v2 = 0xc0; 5323 setSISIDXREG(SISCR, 0x5f, 0xf0, bios[0x64]);
4571 else v2 = 0xd0; 5324 }
4572 orSISIDXREG(SISSR,0x16,v2);
4573 andSISIDXREG(SISSR,0x16,0x0f);
4574 if(!(v1 & 0x10)) v2 = 0x80;
4575 else v2 = 0xA0;
4576 orSISIDXREG(SISSR,0x16,v2);
4577 }
4578
4579 if(memtype >= 2) {
4580 const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
4581 const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
4582 for(i = 0; i < 11; i++) {
4583 outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
4584 }
4585 outSISIDXREG(SISSR,0x3d,0x00);
4586 outSISIDXREG(SISSR,0x3d,0x04);
4587 SiS_DDC2Delay(0x200);
4588 v1 = inSISIDXREG(SISCR,0xEC);
4589 v2 = inSISIDXREG(SISCR,0xED);
4590 reg1_32 = (v2 << 8) | v1;
4591 outSISIDXREG(SISSR,0x3D,0x00);
4592 for(i = 0; i < 11; i++) {
4593 outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
4594 }
4595 outSISIDXREG(SISSR,0x3d,0x00);
4596 outSISIDXREG(SISSR,0x3d,0x04);
4597 SiS_DDC2Delay(0x200);
4598 v1 = inSISIDXREG(SISCR,0xEC);
4599 v2 = inSISIDXREG(SISCR,0xED);
4600 reg2_32 = (v2 << 8) | v1;
4601 outSISIDXREG(SISSR,0x3D,0x00);
4602 reg3_32 = reg2_32 << 1;
4603 reg2_32 >>= 1;
4604 reg3_32 += reg2_32;
4605 v1 = 0x40;
4606 if(reg3_32 > reg1_32) v1 = 0x10;
4607 outSISIDXREG(SISCR,0x59,v1);
4608 }
4609 5325
5326 v1 = bios[0x4f7];
5327 pci_read_config_dword(pdev, 0x50, &regd);
5328 regd = (regd >> 20) & 0x0f;
5329 if(regd == 1) {
5330 v1 &= 0xfc;
5331 orSISIDXREG(SISCR, 0x5f, 0x08);
5332 }
5333 outSISIDXREG(SISCR, 0x48, v1);
5334
5335 setSISIDXREG(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb);
5336 setSISIDXREG(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f);
5337 setSISIDXREG(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f);
5338 setSISIDXREG(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7);
5339 setSISIDXREG(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f);
5340 outSISIDXREG(SISCR, 0x70, bios[0x4fc]);
5341 setSISIDXREG(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f);
5342 outSISIDXREG(SISCR, 0x74, 0xd0);
5343 setSISIDXREG(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30);
5344 setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
5345 setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
5346 v1 = bios[0x501];
5347 if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) {
5348 v1 = 0xf0;
5349 SIS_PCI_PUT_DEVICE(mypdev);
5350 }
5351 outSISIDXREG(SISCR, 0x77, v1);
4610 } 5352 }
4611 5353
4612 v1 = 0x00; 5354 /* RAM type */
4613 if(ivideo->sishw_ext.UseROM) { 5355
4614 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99]; 5356 regb = 0; /* ! */
5357
5358 v1 = 0xff;
5359 if(ivideo->haveXGIROM) {
5360 v1 = bios[0x140 + regb];
4615 } 5361 }
4616 outSISIDXREG(SISSR,0x1f,v1); 5362 outSISIDXREG(SISCR, 0x6d, v1);
4617 5363
4618 outSISIDXREG(SISSR,0x20,0x20); 5364 ptr = cs128;
5365 if(ivideo->haveXGIROM) {
5366 ptr = (const u8 *)&bios[0x128];
5367 }
5368 for(i = 0, j = 0; i < 3; i++, j += 8) {
5369 outSISIDXREG(SISCR, 0x68 + i, ptr[j + regb]);
5370 }
4619 5371
4620 v1 = 0xf6; v2 = 0x0d; v3 = 0x33; 5372 ptr = cs31a;
4621 if(ivideo->sishw_ext.UseROM) { 5373 ptr2 = cs33a;
4622 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c]; 5374 if(ivideo->haveXGIROM) {
4623 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d]; 5375 index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6;
4624 v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e]; 5376 ptr = (const u8 *)&bios[index];
5377 ptr2 = (const u8 *)&bios[index + 0x20];
5378 }
5379 for(i = 0; i < 2; i++) {
5380 if(i == 0) {
5381 regd = le32_to_cpu(((u32 *)ptr)[regb]);
5382 rega = 0x6b;
5383 } else {
5384 regd = le32_to_cpu(((u32 *)ptr2)[regb]);
5385 rega = 0x6e;
5386 }
5387 reg = 0x00;
5388 for(j = 0; j < 16; j++) {
5389 reg &= 0xf3;
5390 if(regd & 0x01) reg |= 0x04;
5391 if(regd & 0x02) reg |= 0x08;
5392 regd >>= 2;
5393 outSISIDXREG(SISCR, rega, reg);
5394 inSISIDXREG(SISCR, rega, reg);
5395 inSISIDXREG(SISCR, rega, reg);
5396 reg += 0x10;
5397 }
4625 } 5398 }
4626 outSISIDXREG(SISSR,0x23,v1);
4627 outSISIDXREG(SISSR,0x24,v2);
4628 outSISIDXREG(SISSR,0x25,v3);
4629 5399
4630 outSISIDXREG(SISSR,0x21,0x84); 5400 andSISIDXREG(SISCR, 0x6e, 0xfc);
4631 outSISIDXREG(SISSR,0x22,0x00);
4632 outSISIDXREG(SISSR,0x27,0x1f);
4633 5401
4634 v1 = 0x00; v2 = 0x00; 5402 ptr = NULL;
4635 if(ivideo->sishw_ext.UseROM) { 5403 if(ivideo->haveXGIROM) {
4636 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F]; 5404 index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6;
4637 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1]; 5405 ptr = (const u8 *)&bios[index];
4638 } 5406 }
4639 outSISIDXREG(SISSR,0x31,v1); 5407 for(i = 0; i < 4; i++) {
4640 outSISIDXREG(SISSR,0x33,v2); 5408 setSISIDXREG(SISCR, 0x6e, 0xfc, i);
4641 5409 reg = 0x00;
4642 v1 = 0x11; 5410 for(j = 0; j < 2; j++) {
4643 if(ivideo->sishw_ext.UseROM) { 5411 regd = 0;
4644 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0]; 5412 if(ptr) {
4645 } 5413 regd = le32_to_cpu(((u32 *)ptr)[regb * 8]);
4646 v2 = inSISIDXREG(SISPART4,0x00); 5414 ptr += 4;
4647 if((v2 != 1) && (v2 != 2)) v1 &= 0xef; 5415 }
4648 outSISIDXREG(SISSR,0x32,v1); 5416 /* reg = 0x00; */
4649 5417 for(k = 0; k < 16; k++) {
4650 /* AGP */ 5418 reg &= 0xfc;
4651 pci_read_config_long(pdev, 0x50, &reg1_32); 5419 if(regd & 0x01) reg |= 0x01;
4652 reg1_32 >>= 20; 5420 if(regd & 0x02) reg |= 0x02;
4653 reg1_32 &= 0x0f; 5421 regd >>= 2;
4654 if(reg1_32 == 1) { 5422 outSISIDXREG(SISCR, 0x6f, reg);
4655 v1 = 0xAA; v2 = 0x33; 5423 inSISIDXREG(SISCR, 0x6f, reg);
4656 if(ivideo->sishw_ext.UseROM) { 5424 inSISIDXREG(SISCR, 0x6f, reg);
4657 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7]; 5425 reg += 0x08;
4658 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E]; 5426 }
4659 } 5427 }
4660 } else {
4661 v1 = 0x88; v2 = 0x03;
4662 if(ivideo->sishw_ext.UseROM) {
4663 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
4664 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
4665 }
4666 } 5428 }
4667 outSISIDXREG(SISCR,0x49,v1);
4668 outSISIDXREG(SISSR,0x25,v2);
4669 5429
4670 v1 = inSISIDXREG(SISPART4,0x00); 5430 ptr = cs148;
4671 if((v1 == 1) || (v1 == 2)) { 5431 if(ivideo->haveXGIROM) {
4672 orSISIDXREG(SISPART1,0x2F,0x01); /* Unlock CRT2 */ 5432 ptr = (const u8 *)&bios[0x148];
4673 outSISIDXREG(SISPART1,0x00,0x00); 5433 }
4674 v1 = 0x00; 5434 for(i = 0, j = 0; i < 2; i++, j += 8) {
4675 if(ivideo->sishw_ext.UseROM) { 5435 outSISIDXREG(SISCR, 0x80 + i, ptr[j + regb]);
4676 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
4677 }
4678 outSISIDXREG(SISPART1,0x02,v1);
4679 outSISIDXREG(SISPART1,0x2E,0x08);
4680 outSISIDXREG(SISPART2,0x00,0x1c);
4681 v1 = 0x40; v2 = 0x00; v3 = 0x80;
4682 if(ivideo->sishw_ext.UseROM) {
4683 v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
4684 v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
4685 v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
4686 }
4687 outSISIDXREG(SISPART4,0x0d,v1);
4688 outSISIDXREG(SISPART4,0x0e,v2);
4689 outSISIDXREG(SISPART4,0x10,v3);
4690 outSISIDXREG(SISPART4,0x0F,0x3F);
4691
4692 inSISIDXREG(SISPART4,0x01,reg);
4693 if(reg >= 0xb0) {
4694 inSISIDXREG(SISPART4,0x23,reg);
4695 reg &= 0x20;
4696 reg <<= 1;
4697 outSISIDXREG(SISPART4,0x23,reg);
4698 }
4699 } 5436 }
4700 outSISIDXREG(SISCR,0x37,0x02); /* Why? */
4701
4702 outSISIDXREG(SISCR,0x83,0x00);
4703 outSISIDXREG(SISCR,0x90,0x00);
4704 andSISIDXREG(SISSR,0x5B,0xDF);
4705 outSISIDXREG(SISVID,0x00,0x86);
4706 outSISIDXREG(SISVID,0x32,0x00);
4707 outSISIDXREG(SISVID,0x30,0x00);
4708 outSISIDXREG(SISVID,0x32,0x01);
4709 outSISIDXREG(SISVID,0x30,0x00);
4710 orSISIDXREG(SISCR,0x63,0x80);
4711 /* End of Init1 */
4712
4713 /* Set Mode 0x2e */
4714
4715 /* Ramsize */
4716 orSISIDXREG(SISSR,0x16,0x0f);
4717 orSISIDXREG(SISSR,0x18,0xA9);
4718 orSISIDXREG(SISSR,0x19,0xA0);
4719 orSISIDXREG(SISSR,0x1B,0x30);
4720 andSISIDXREG(SISSR,0x17,0xF8);
4721 orSISIDXREG(SISSR,0x19,0x03);
4722 andSIDIDXREG(SISSR,0x13,0x00);
4723 5437
4724 /* Need to map max FB size for finding out about RAM size */ 5438 andSISIDXREG(SISCR, 0x89, 0x8f);
4725 ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
4726 if(ivideo->video_vbase) {
4727 /* Find out about bus width */
4728 if(memtype <= 1) {
4729 outSISIDXREG(SISSR,0x14,0x02);
4730 andSISIDXREG(SISSR,0x16,0x0F);
4731 orSISIDXREG(SISSR,0x16,0x80);
4732 5439
4733 ... 5440 ptr = cs45a;
5441 if(ivideo->haveXGIROM) {
5442 index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6;
5443 ptr = (const u8 *)&bios[index];
5444 }
5445 regd = le16_to_cpu(((const u16 *)ptr)[regb]);
5446 reg = 0x80;
5447 for(i = 0; i < 5; i++) {
5448 reg &= 0xfc;
5449 if(regd & 0x01) reg |= 0x01;
5450 if(regd & 0x02) reg |= 0x02;
5451 regd >>= 2;
5452 outSISIDXREG(SISCR, 0x89, reg);
5453 inSISIDXREG(SISCR, 0x89, reg);
5454 inSISIDXREG(SISCR, 0x89, reg);
5455 reg += 0x10;
5456 }
4734 5457
4735 } else { 5458 v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
5459 if(ivideo->haveXGIROM) {
5460 v1 = bios[0x118 + regb];
5461 v2 = bios[0xf8 + regb];
5462 v3 = bios[0x120 + regb];
5463 v4 = bios[0x1ca];
5464 }
5465 outSISIDXREG(SISCR, 0x45, v1 & 0x0f);
5466 outSISIDXREG(SISCR, 0x99, (v1 >> 4) & 0x07);
5467 orSISIDXREG(SISCR, 0x40, v1 & 0x80);
5468 outSISIDXREG(SISCR, 0x41, v2);
4736 5469
4737 ... 5470 ptr = cs170;
5471 if(ivideo->haveXGIROM) {
5472 ptr = (const u8 *)&bios[0x170];
5473 }
5474 for(i = 0, j = 0; i < 7; i++, j += 8) {
5475 outSISIDXREG(SISCR, 0x90 + i, ptr[j + regb]);
5476 }
4738 5477
4739 } 5478 outSISIDXREG(SISCR, 0x59, v3);
4740 5479
4741 /* Find out about size */ 5480 ptr = cs1a8;
5481 if(ivideo->haveXGIROM) {
5482 ptr = (const u8 *)&bios[0x1a8];
5483 }
5484 for(i = 0, j = 0; i < 3; i++, j += 8) {
5485 outSISIDXREG(SISCR, 0xc3 + i, ptr[j + regb]);
5486 }
4742 5487
5488 ptr = cs100;
5489 if(ivideo->haveXGIROM) {
5490 ptr = (const u8 *)&bios[0x100];
5491 }
5492 for(i = 0, j = 0; i < 2; i++, j += 8) {
5493 outSISIDXREG(SISCR, 0x8a + i, ptr[j + regb]);
5494 }
4743 5495
4744 iounmap(ivideo->video_vbase); 5496 outSISIDXREG(SISCR, 0xcf, v4);
4745 } else { 5497
4746 printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n"); 5498 outSISIDXREG(SISCR, 0x83, 0x09);
4747 outSISIDXREG(SISSR,0x14,0x??); /* 8MB, 64bit default */ 5499 outSISIDXREG(SISCR, 0x87, 0x00);
5500
5501 if(ivideo->chip == XGI_40) {
5502 if( (ivideo->revision_id == 1) ||
5503 (ivideo->revision_id == 2) ) {
5504 outSISIDXREG(SISCR, 0x8c, 0x87);
5505 }
5506 }
5507
5508 outSISIDXREG(SISSR, 0x17, 0x00);
5509 outSISIDXREG(SISSR, 0x1a, 0x87);
5510
5511 if(ivideo->chip == XGI_20) {
5512 outSISIDXREG(SISSR, 0x15, 0x00);
5513 outSISIDXREG(SISSR, 0x1c, 0x00);
5514 }
5515
5516 ramtype = 0x00; v1 = 0x10;
5517 if(ivideo->haveXGIROM) {
5518 ramtype = bios[0x62];
5519 v1 = bios[0x1d2];
5520 }
5521 if(!(ramtype & 0x80)) {
5522 if(ivideo->chip == XGI_20) {
5523 outSISIDXREG(SISCR, 0x97, v1);
5524 inSISIDXREG(SISCR, 0x97, reg);
5525 if(reg & 0x10) {
5526 ramtype = (reg & 0x01) << 1;
5527 }
5528 } else {
5529 inSISIDXREG(SISSR, 0x39, reg);
5530 ramtype = reg & 0x02;
5531 if(!(ramtype)) {
5532 inSISIDXREG(SISSR, 0x3a, reg);
5533 ramtype = (reg >> 1) & 0x01;
5534 }
5535 }
5536 }
5537 ramtype &= 0x07;
5538
5539 regb = 0; /* ! */
5540
5541 switch(ramtype) {
5542 case 0:
5543 sisfb_post_xgi_setclocks(ivideo, regb);
5544 if((ivideo->chip == XGI_20) ||
5545 (ivideo->revision_id == 1) ||
5546 (ivideo->revision_id == 2)) {
5547 v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
5548 if(ivideo->haveXGIROM) {
5549 v1 = bios[regb + 0x158];
5550 v2 = bios[regb + 0x160];
5551 v3 = bios[regb + 0x168];
5552 }
5553 outSISIDXREG(SISCR, 0x82, v1);
5554 outSISIDXREG(SISCR, 0x85, v2);
5555 outSISIDXREG(SISCR, 0x86, v3);
5556 } else {
5557 outSISIDXREG(SISCR, 0x82, 0x88);
5558 outSISIDXREG(SISCR, 0x86, 0x00);
5559 inSISIDXREG(SISCR, 0x86, reg);
5560 outSISIDXREG(SISCR, 0x86, 0x88);
5561 inSISIDXREG(SISCR, 0x86, reg);
5562 outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
5563 outSISIDXREG(SISCR, 0x82, 0x77);
5564 outSISIDXREG(SISCR, 0x85, 0x00);
5565 inSISIDXREG(SISCR, 0x85, reg);
5566 outSISIDXREG(SISCR, 0x85, 0x88);
5567 inSISIDXREG(SISCR, 0x85, reg);
5568 outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
5569 outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
5570 }
5571 if(ivideo->chip == XGI_40) {
5572 outSISIDXREG(SISCR, 0x97, 0x00);
5573 }
5574 outSISIDXREG(SISCR, 0x98, 0x01);
5575 outSISIDXREG(SISCR, 0x9a, 0x02);
5576
5577 outSISIDXREG(SISSR, 0x18, 0x01);
5578 if((ivideo->chip == XGI_20) ||
5579 (ivideo->revision_id == 2)) {
5580 outSISIDXREG(SISSR, 0x19, 0x40);
5581 } else {
5582 outSISIDXREG(SISSR, 0x19, 0x20);
5583 }
5584 outSISIDXREG(SISSR, 0x16, 0x00);
5585 outSISIDXREG(SISSR, 0x16, 0x80);
5586 if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) {
5587 sisfb_post_xgi_delay(ivideo, 0x43);
5588 sisfb_post_xgi_delay(ivideo, 0x43);
5589 sisfb_post_xgi_delay(ivideo, 0x43);
5590 outSISIDXREG(SISSR, 0x18, 0x00);
5591 if((ivideo->chip == XGI_20) ||
5592 (ivideo->revision_id == 2)) {
5593 outSISIDXREG(SISSR, 0x19, 0x40);
5594 } else {
5595 outSISIDXREG(SISSR, 0x19, 0x20);
5596 }
5597 } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) {
5598 /* outSISIDXREG(SISSR, 0x16, 0x0c); */ /* ? */
5599 }
5600 outSISIDXREG(SISSR, 0x16, 0x00);
5601 outSISIDXREG(SISSR, 0x16, 0x80);
5602 sisfb_post_xgi_delay(ivideo, 4);
5603 v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
5604 if(ivideo->haveXGIROM) {
5605 v1 = bios[0xf0];
5606 index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e;
5607 v2 = bios[index];
5608 v3 = bios[index + 1];
5609 v4 = bios[index + 2];
5610 v5 = bios[index + 3];
5611 }
5612 outSISIDXREG(SISSR, 0x18, v1);
5613 outSISIDXREG(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01));
5614 outSISIDXREG(SISSR, 0x16, v2);
5615 outSISIDXREG(SISSR, 0x16, v3);
5616 sisfb_post_xgi_delay(ivideo, 0x43);
5617 outSISIDXREG(SISSR, 0x1b, 0x03);
5618 sisfb_post_xgi_delay(ivideo, 0x22);
5619 outSISIDXREG(SISSR, 0x18, v1);
5620 outSISIDXREG(SISSR, 0x19, 0x00);
5621 outSISIDXREG(SISSR, 0x16, v4);
5622 outSISIDXREG(SISSR, 0x16, v5);
5623 outSISIDXREG(SISSR, 0x1b, 0x00);
5624 break;
5625 case 1:
5626 outSISIDXREG(SISCR, 0x82, 0x77);
5627 outSISIDXREG(SISCR, 0x86, 0x00);
5628 inSISIDXREG(SISCR, 0x86, reg);
5629 outSISIDXREG(SISCR, 0x86, 0x88);
5630 inSISIDXREG(SISCR, 0x86, reg);
5631 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5632 if(ivideo->haveXGIROM) {
5633 v1 = bios[regb + 0x168];
5634 v2 = bios[regb + 0x160];
5635 v3 = bios[regb + 0x158];
5636 }
5637 outSISIDXREG(SISCR, 0x86, v1);
5638 outSISIDXREG(SISCR, 0x82, 0x77);
5639 outSISIDXREG(SISCR, 0x85, 0x00);
5640 inSISIDXREG(SISCR, 0x85, reg);
5641 outSISIDXREG(SISCR, 0x85, 0x88);
5642 inSISIDXREG(SISCR, 0x85, reg);
5643 outSISIDXREG(SISCR, 0x85, v2);
5644 outSISIDXREG(SISCR, 0x82, v3);
5645 outSISIDXREG(SISCR, 0x98, 0x01);
5646 outSISIDXREG(SISCR, 0x9a, 0x02);
5647
5648 outSISIDXREG(SISSR, 0x28, 0x64);
5649 outSISIDXREG(SISSR, 0x29, 0x63);
5650 sisfb_post_xgi_delay(ivideo, 15);
5651 outSISIDXREG(SISSR, 0x18, 0x00);
5652 outSISIDXREG(SISSR, 0x19, 0x20);
5653 outSISIDXREG(SISSR, 0x16, 0x00);
5654 outSISIDXREG(SISSR, 0x16, 0x80);
5655 outSISIDXREG(SISSR, 0x18, 0xc5);
5656 outSISIDXREG(SISSR, 0x19, 0x23);
5657 outSISIDXREG(SISSR, 0x16, 0x00);
5658 outSISIDXREG(SISSR, 0x16, 0x80);
5659 sisfb_post_xgi_delay(ivideo, 1);
5660 outSISIDXREG(SISCR, 0x97,0x11);
5661 sisfb_post_xgi_setclocks(ivideo, regb);
5662 sisfb_post_xgi_delay(ivideo, 0x46);
5663 outSISIDXREG(SISSR, 0x18, 0xc5);
5664 outSISIDXREG(SISSR, 0x19, 0x23);
5665 outSISIDXREG(SISSR, 0x16, 0x00);
5666 outSISIDXREG(SISSR, 0x16, 0x80);
5667 sisfb_post_xgi_delay(ivideo, 1);
5668 outSISIDXREG(SISSR, 0x1b, 0x04);
5669 sisfb_post_xgi_delay(ivideo, 1);
5670 outSISIDXREG(SISSR, 0x1b, 0x00);
5671 sisfb_post_xgi_delay(ivideo, 1);
5672 v1 = 0x31;
5673 if(ivideo->haveXGIROM) {
5674 v1 = bios[0xf0];
5675 }
5676 outSISIDXREG(SISSR, 0x18, v1);
5677 outSISIDXREG(SISSR, 0x19, 0x06);
5678 outSISIDXREG(SISSR, 0x16, 0x04);
5679 outSISIDXREG(SISSR, 0x16, 0x84);
5680 sisfb_post_xgi_delay(ivideo, 1);
5681 break;
5682 default:
5683 sisfb_post_xgi_setclocks(ivideo, regb);
5684 if((ivideo->chip == XGI_40) &&
5685 ((ivideo->revision_id == 1) ||
5686 (ivideo->revision_id == 2))) {
5687 outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
5688 outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
5689 outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
5690 } else {
5691 outSISIDXREG(SISCR, 0x82, 0x88);
5692 outSISIDXREG(SISCR, 0x86, 0x00);
5693 inSISIDXREG(SISCR, 0x86, reg);
5694 outSISIDXREG(SISCR, 0x86, 0x88);
5695 outSISIDXREG(SISCR, 0x82, 0x77);
5696 outSISIDXREG(SISCR, 0x85, 0x00);
5697 inSISIDXREG(SISCR, 0x85, reg);
5698 outSISIDXREG(SISCR, 0x85, 0x88);
5699 inSISIDXREG(SISCR, 0x85, reg);
5700 v1 = cs160[regb]; v2 = cs158[regb];
5701 if(ivideo->haveXGIROM) {
5702 v1 = bios[regb + 0x160];
5703 v2 = bios[regb + 0x158];
5704 }
5705 outSISIDXREG(SISCR, 0x85, v1);
5706 outSISIDXREG(SISCR, 0x82, v2);
5707 }
5708 if(ivideo->chip == XGI_40) {
5709 outSISIDXREG(SISCR, 0x97, 0x11);
5710 }
5711 if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) {
5712 outSISIDXREG(SISCR, 0x98, 0x01);
5713 } else {
5714 outSISIDXREG(SISCR, 0x98, 0x03);
5715 }
5716 outSISIDXREG(SISCR, 0x9a, 0x02);
5717
5718 if(ivideo->chip == XGI_40) {
5719 outSISIDXREG(SISSR, 0x18, 0x01);
5720 } else {
5721 outSISIDXREG(SISSR, 0x18, 0x00);
5722 }
5723 outSISIDXREG(SISSR, 0x19, 0x40);
5724 outSISIDXREG(SISSR, 0x16, 0x00);
5725 outSISIDXREG(SISSR, 0x16, 0x80);
5726 if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) {
5727 sisfb_post_xgi_delay(ivideo, 0x43);
5728 sisfb_post_xgi_delay(ivideo, 0x43);
5729 sisfb_post_xgi_delay(ivideo, 0x43);
5730 outSISIDXREG(SISSR, 0x18, 0x00);
5731 outSISIDXREG(SISSR, 0x19, 0x40);
5732 outSISIDXREG(SISSR, 0x16, 0x00);
5733 outSISIDXREG(SISSR, 0x16, 0x80);
5734 }
5735 sisfb_post_xgi_delay(ivideo, 4);
5736 v1 = 0x31;
5737 if(ivideo->haveXGIROM) {
5738 v1 = bios[0xf0];
5739 }
5740 outSISIDXREG(SISSR, 0x18, v1);
5741 outSISIDXREG(SISSR, 0x19, 0x01);
5742 if(ivideo->chip == XGI_40) {
5743 outSISIDXREG(SISSR, 0x16, bios[0x53e]);
5744 outSISIDXREG(SISSR, 0x16, bios[0x53f]);
5745 } else {
5746 outSISIDXREG(SISSR, 0x16, 0x05);
5747 outSISIDXREG(SISSR, 0x16, 0x85);
5748 }
5749 sisfb_post_xgi_delay(ivideo, 0x43);
5750 if(ivideo->chip == XGI_40) {
5751 outSISIDXREG(SISSR, 0x1b, 0x01);
5752 } else {
5753 outSISIDXREG(SISSR, 0x1b, 0x03);
5754 }
5755 sisfb_post_xgi_delay(ivideo, 0x22);
5756 outSISIDXREG(SISSR, 0x18, v1);
5757 outSISIDXREG(SISSR, 0x19, 0x00);
5758 if(ivideo->chip == XGI_40) {
5759 outSISIDXREG(SISSR, 0x16, bios[0x540]);
5760 outSISIDXREG(SISSR, 0x16, bios[0x541]);
5761 } else {
5762 outSISIDXREG(SISSR, 0x16, 0x05);
5763 outSISIDXREG(SISSR, 0x16, 0x85);
5764 }
5765 outSISIDXREG(SISSR, 0x1b, 0x00);
5766 }
5767
5768 regb = 0; /* ! */
5769 v1 = 0x03;
5770 if(ivideo->haveXGIROM) {
5771 v1 = bios[0x110 + regb];
5772 }
5773 outSISIDXREG(SISSR, 0x1b, v1);
5774
5775 /* RAM size */
5776 v1 = 0x00; v2 = 0x00;
5777 if(ivideo->haveXGIROM) {
5778 v1 = bios[0x62];
5779 v2 = bios[0x63];
4748 } 5780 }
5781 regb = 0; /* ! */
5782 regd = 1 << regb;
5783 if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) {
5784
5785 outSISIDXREG(SISSR, 0x13, bios[regb + 0xe0]);
5786 outSISIDXREG(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5787
5788 } else {
5789
5790 /* Set default mode, don't clear screen */
5791 ivideo->SiS_Pr.SiS_UseOEM = FALSE;
5792 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
5793 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
5794 ivideo->curFSTN = ivideo->curDSTN = 0;
5795 ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
5796 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
5797
5798 outSISIDXREG(SISSR, 0x05, 0x86);
5799
5800 /* Disable read-cache */
5801 andSISIDXREG(SISSR, 0x21, 0xdf);
5802 sisfb_post_xgi_ramsize(ivideo);
5803 /* Enable read-cache */
5804 orSISIDXREG(SISSR, 0x21, 0x20);
4749 5805
4750 /* AGP (Missing: Checks for VIA and AMD hosts) */
4751 v1 = 0xA5; v2 = 0xFB;
4752 if(ivideo->sishw_ext.UseROM) {
4753 v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
4754 v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
4755 } 5806 }
4756 outSISIDXREG(SISSR,0x21,v1);
4757 outSISIDXREG(SISSR,0x22,v2);
4758 5807
5808#if 0
5809 printk(KERN_DEBUG "-----------------\n");
5810 for(i = 0; i < 0xff; i++) {
5811 inSISIDXREG(SISCR, i, reg);
5812 printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg);
5813 }
5814 for(i = 0; i < 0x40; i++) {
5815 inSISIDXREG(SISSR, i, reg);
5816 printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg);
5817 }
5818 printk(KERN_DEBUG "-----------------\n");
4759#endif 5819#endif
4760 return; 5820
5821 /* Sense CRT1 */
5822 if(ivideo->chip == XGI_20) {
5823 orSISIDXREG(SISCR, 0x32, 0x20);
5824 } else {
5825 inSISIDXREG(SISPART4, 0x00, reg);
5826 if((reg == 1) || (reg == 2)) {
5827 sisfb_sense_crt1(ivideo);
5828 } else {
5829 orSISIDXREG(SISCR, 0x32, 0x20);
5830 }
5831 }
5832
5833 /* Set default mode, don't clear screen */
5834 ivideo->SiS_Pr.SiS_UseOEM = FALSE;
5835 SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
5836 SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
5837 ivideo->curFSTN = ivideo->curDSTN = 0;
5838 SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
5839
5840 outSISIDXREG(SISSR, 0x05, 0x86);
5841
5842 /* Display off */
5843 orSISIDXREG(SISSR, 0x01, 0x20);
5844
5845 /* Save mode number in CR34 */
5846 outSISIDXREG(SISCR, 0x34, 0x2e);
5847
5848 /* Let everyone know what the current mode is */
5849 ivideo->modeprechange = 0x2e;
5850
5851 if(ivideo->chip == XGI_40) {
5852 inSISIDXREG(SISCR, 0xca, reg);
5853 inSISIDXREG(SISCR, 0xcc, v1);
5854 if((reg & 0x10) && (!(v1 & 0x04))) {
5855 printk(KERN_ERR
5856 "sisfb: Please connect power to the card.\n");
5857 return 0;
5858 }
5859 }
5860
5861 return 1;
4761} 5862}
4762#endif 5863#endif
4763 5864
4764 5865static int __devinit
4765static int __devinit sisfb_probe(struct pci_dev *pdev, 5866sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4766 const struct pci_device_id *ent)
4767{ 5867{
4768 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data]; 5868 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
4769 struct sis_video_info *ivideo = NULL; 5869 struct sis_video_info *ivideo = NULL;
4770 struct fb_info *sis_fb_info = NULL; 5870 struct fb_info *sis_fb_info = NULL;
4771 u16 reg16; 5871 u16 reg16;
4772 u8 reg; 5872 u8 reg;
4773 int sisvga_enabled = 0, i; 5873 int i, ret;
4774 5874
4775 if(sisfb_off) return -ENXIO; 5875 if(sisfb_off)
5876 return -ENXIO;
4776 5877
4777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)) 5878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
4778 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); 5879 sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
4779 if(!sis_fb_info) return -ENOMEM; 5880 if(!sis_fb_info)
5881 return -ENOMEM;
4780#else 5882#else
4781 sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL); 5883 sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
4782 if(!sis_fb_info) return -ENOMEM; 5884 if(!sis_fb_info)
5885 return -ENOMEM;
4783 memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo)); 5886 memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
4784 sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info)); 5887 sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
4785#endif 5888#endif
@@ -4787,27 +5890,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4787 ivideo = (struct sis_video_info *)sis_fb_info->par; 5890 ivideo = (struct sis_video_info *)sis_fb_info->par;
4788 ivideo->memyselfandi = sis_fb_info; 5891 ivideo->memyselfandi = sis_fb_info;
4789 5892
5893 ivideo->sisfb_id = SISFB_ID;
5894
4790 if(card_list == NULL) { 5895 if(card_list == NULL) {
4791 ivideo->cardnumber = 0; 5896 ivideo->cardnumber = 0;
4792 } else { 5897 } else {
4793 struct sis_video_info *countvideo = card_list; 5898 struct sis_video_info *countvideo = card_list;
4794 ivideo->cardnumber = 1; 5899 ivideo->cardnumber = 1;
4795 while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++; 5900 while((countvideo = countvideo->next) != 0)
5901 ivideo->cardnumber++;
4796 } 5902 }
4797 5903
4798 strncpy(ivideo->myid, chipinfo->chip_name, 30); 5904 strncpy(ivideo->myid, chipinfo->chip_name, 30);
4799 5905
4800 ivideo->warncount = 0; 5906 ivideo->warncount = 0;
4801 ivideo->chip_id = pdev->device; 5907 ivideo->chip_id = pdev->device;
5908 ivideo->chip_vendor = pdev->vendor;
4802 pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id); 5909 pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
4803 ivideo->sishw_ext.jChipRevision = ivideo->revision_id; 5910 ivideo->SiS_Pr.ChipRevision = ivideo->revision_id;
4804 pci_read_config_word(pdev, PCI_COMMAND, &reg16); 5911 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
4805 sisvga_enabled = reg16 & 0x01; 5912 ivideo->sisvga_enabled = reg16 & 0x01;
4806 ivideo->pcibus = pdev->bus->number; 5913 ivideo->pcibus = pdev->bus->number;
4807 ivideo->pcislot = PCI_SLOT(pdev->devfn); 5914 ivideo->pcislot = PCI_SLOT(pdev->devfn);
4808 ivideo->pcifunc = PCI_FUNC(pdev->devfn); 5915 ivideo->pcifunc = PCI_FUNC(pdev->devfn);
4809 ivideo->subsysvendor = pdev->subsystem_vendor; 5916 ivideo->subsysvendor = pdev->subsystem_vendor;
4810 ivideo->subsysdevice = pdev->subsystem_device; 5917 ivideo->subsysdevice = pdev->subsystem_device;
5918#ifdef SIS_OLD_CONFIG_COMPAT
5919 ivideo->ioctl32registered = 0;
5920#endif
4811 5921
4812#ifndef MODULE 5922#ifndef MODULE
4813 if(sisfb_mode_idx == -1) { 5923 if(sisfb_mode_idx == -1) {
@@ -4827,6 +5937,24 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4827 5937
4828 ivideo->sisfb_thismonitor.datavalid = FALSE; 5938 ivideo->sisfb_thismonitor.datavalid = FALSE;
4829 5939
5940 ivideo->current_base = 0;
5941
5942 ivideo->engineok = 0;
5943
5944 ivideo->sisfb_was_boot_device = 0;
5945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
5946 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) {
5947 if(ivideo->sisvga_enabled)
5948 ivideo->sisfb_was_boot_device = 1;
5949 else {
5950 printk(KERN_DEBUG "sisfb: PCI device is disabled, "
5951 "but marked as boot video device ???\n");
5952 printk(KERN_DEBUG "sisfb: I will not accept this "
5953 "as the primary VGA device\n");
5954 }
5955 }
5956#endif
5957
4830 ivideo->sisfb_parm_mem = sisfb_parm_mem; 5958 ivideo->sisfb_parm_mem = sisfb_parm_mem;
4831 ivideo->sisfb_accel = sisfb_accel; 5959 ivideo->sisfb_accel = sisfb_accel;
4832 ivideo->sisfb_ypan = sisfb_ypan; 5960 ivideo->sisfb_ypan = sisfb_ypan;
@@ -4846,7 +5974,6 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4846 ivideo->sisfb_tvstd = sisfb_tvstd; 5974 ivideo->sisfb_tvstd = sisfb_tvstd;
4847 ivideo->tvxpos = sisfb_tvxposoffset; 5975 ivideo->tvxpos = sisfb_tvxposoffset;
4848 ivideo->tvypos = sisfb_tvyposoffset; 5976 ivideo->tvypos = sisfb_tvyposoffset;
4849 ivideo->sisfb_filter = sisfb_filter;
4850 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; 5977 ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
4851#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) 5978#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
4852 ivideo->sisfb_inverse = sisfb_inverse; 5979 ivideo->sisfb_inverse = sisfb_inverse;
@@ -4854,7 +5981,7 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4854 5981
4855 ivideo->refresh_rate = 0; 5982 ivideo->refresh_rate = 0;
4856 if(ivideo->sisfb_parm_rate != -1) { 5983 if(ivideo->sisfb_parm_rate != -1) {
4857 ivideo->refresh_rate = ivideo->sisfb_parm_rate; 5984 ivideo->refresh_rate = ivideo->sisfb_parm_rate;
4858 } 5985 }
4859 5986
4860 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd; 5987 ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
@@ -4863,8 +5990,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4863 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl; 5990 ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
4864 5991
4865 ivideo->SiS_Pr.SiS_Backup70xx = 0xff; 5992 ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
4866 ivideo->SiS_Pr.SiS_CHOverScan = -1; 5993 ivideo->SiS_Pr.SiS_CHOverScan = -1;
4867 ivideo->SiS_Pr.SiS_ChSW = FALSE; 5994 ivideo->SiS_Pr.SiS_ChSW = FALSE;
4868 ivideo->SiS_Pr.SiS_UseLCDA = FALSE; 5995 ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
4869 ivideo->SiS_Pr.HaveEMI = FALSE; 5996 ivideo->SiS_Pr.HaveEMI = FALSE;
4870 ivideo->SiS_Pr.HaveEMILCD = FALSE; 5997 ivideo->SiS_Pr.HaveEMILCD = FALSE;
@@ -4873,12 +6000,13 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4873 ivideo->SiS_Pr.SiS_MyCR63 = 0x63; 6000 ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
4874 ivideo->SiS_Pr.PDC = -1; 6001 ivideo->SiS_Pr.PDC = -1;
4875 ivideo->SiS_Pr.PDCA = -1; 6002 ivideo->SiS_Pr.PDCA = -1;
6003 ivideo->SiS_Pr.DDCPortMixup = FALSE;
4876#ifdef CONFIG_FB_SIS_315 6004#ifdef CONFIG_FB_SIS_315
4877 if(ivideo->chip >= SIS_330) { 6005 if(ivideo->chip >= SIS_330) {
4878 ivideo->SiS_Pr.SiS_MyCR63 = 0x53; 6006 ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
4879 if(ivideo->chip >= SIS_661) { 6007 if(ivideo->chip >= SIS_661) {
4880 ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE; 6008 ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
4881 } 6009 }
4882 } 6010 }
4883#endif 6011#endif
4884 6012
@@ -4891,9 +6019,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4891 switch(ivideo->nbridge->device) { 6019 switch(ivideo->nbridge->device) {
4892#ifdef CONFIG_FB_SIS_300 6020#ifdef CONFIG_FB_SIS_300
4893 case PCI_DEVICE_ID_SI_730: 6021 case PCI_DEVICE_ID_SI_730:
4894 ivideo->chip = SIS_730; 6022 ivideo->chip = SIS_730;
4895 strcpy(ivideo->myid, "SiS 730"); 6023 strcpy(ivideo->myid, "SiS 730");
4896 break; 6024 break;
4897#endif 6025#endif
4898#ifdef CONFIG_FB_SIS_315 6026#ifdef CONFIG_FB_SIS_315
4899 case PCI_DEVICE_ID_SI_651: 6027 case PCI_DEVICE_ID_SI_651:
@@ -4901,22 +6029,28 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4901 strcpy(ivideo->myid, "SiS 651"); 6029 strcpy(ivideo->myid, "SiS 651");
4902 break; 6030 break;
4903 case PCI_DEVICE_ID_SI_740: 6031 case PCI_DEVICE_ID_SI_740:
4904 ivideo->chip = SIS_740; 6032 ivideo->chip = SIS_740;
4905 strcpy(ivideo->myid, "SiS 740"); 6033 strcpy(ivideo->myid, "SiS 740");
4906 break; 6034 break;
4907 case PCI_DEVICE_ID_SI_661: 6035 case PCI_DEVICE_ID_SI_661:
4908 ivideo->chip = SIS_661; 6036 ivideo->chip = SIS_661;
4909 strcpy(ivideo->myid, "SiS 661"); 6037 strcpy(ivideo->myid, "SiS 661");
4910 break; 6038 break;
4911 case PCI_DEVICE_ID_SI_741: 6039 case PCI_DEVICE_ID_SI_741:
4912 ivideo->chip = SIS_741; 6040 ivideo->chip = SIS_741;
4913 strcpy(ivideo->myid, "SiS 741"); 6041 strcpy(ivideo->myid, "SiS 741");
4914 break; 6042 break;
4915 case PCI_DEVICE_ID_SI_760: 6043 case PCI_DEVICE_ID_SI_760:
4916 ivideo->chip = SIS_760; 6044 ivideo->chip = SIS_760;
4917 strcpy(ivideo->myid, "SiS 760"); 6045 strcpy(ivideo->myid, "SiS 760");
4918 break; 6046 break;
6047 case PCI_DEVICE_ID_SI_761:
6048 ivideo->chip = SIS_761;
6049 strcpy(ivideo->myid, "SiS 761");
6050 break;
4919#endif 6051#endif
6052 default:
6053 break;
4920 } 6054 }
4921 } 6055 }
4922 6056
@@ -4924,71 +6058,83 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4924 strcpy(sis_fb_info->modename, ivideo->myid); 6058 strcpy(sis_fb_info->modename, ivideo->myid);
4925#endif 6059#endif
4926 6060
4927 ivideo->sishw_ext.jChipType = ivideo->chip; 6061 ivideo->SiS_Pr.ChipType = ivideo->chip;
6062
6063 ivideo->SiS_Pr.ivideo = (void *)ivideo;
4928 6064
4929#ifdef CONFIG_FB_SIS_315 6065#ifdef CONFIG_FB_SIS_315
4930 if((ivideo->sishw_ext.jChipType == SIS_315PRO) || 6066 if((ivideo->SiS_Pr.ChipType == SIS_315PRO) ||
4931 (ivideo->sishw_ext.jChipType == SIS_315)) { 6067 (ivideo->SiS_Pr.ChipType == SIS_315)) {
4932 ivideo->sishw_ext.jChipType = SIS_315H; 6068 ivideo->SiS_Pr.ChipType = SIS_315H;
4933 } 6069 }
4934#endif 6070#endif
4935 6071
6072 if(!ivideo->sisvga_enabled) {
6073 if(pci_enable_device(pdev)) {
6074 if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge);
6075 pci_set_drvdata(pdev, NULL);
6076 kfree(sis_fb_info);
6077 return -EIO;
6078 }
6079 }
6080
4936 ivideo->video_base = pci_resource_start(pdev, 0); 6081 ivideo->video_base = pci_resource_start(pdev, 0);
4937 ivideo->mmio_base = pci_resource_start(pdev, 1); 6082 ivideo->mmio_base = pci_resource_start(pdev, 1);
4938 ivideo->mmio_size = pci_resource_len(pdev, 1); 6083 ivideo->mmio_size = pci_resource_len(pdev, 1);
4939 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30; 6084 ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
4940 ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO; 6085 ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
4941 6086
4942 if(!sisvga_enabled) { 6087 SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress);
4943 if(pci_enable_device(pdev)) {
4944 pci_set_drvdata(pdev, NULL);
4945 kfree(sis_fb_info);
4946 return -EIO;
4947 }
4948 }
4949
4950 SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
4951 6088
4952#ifdef CONFIG_FB_SIS_300 6089#ifdef CONFIG_FB_SIS_300
4953 /* Find PCI systems for Chrontel/GPIO communication setup */ 6090 /* Find PCI systems for Chrontel/GPIO communication setup */
4954 if(ivideo->chip == SIS_630) { 6091 if(ivideo->chip == SIS_630) {
4955 i=0; 6092 i = 0;
4956 do { 6093 do {
4957 if(mychswtable[i].subsysVendor == ivideo->subsysvendor && 6094 if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
4958 mychswtable[i].subsysCard == ivideo->subsysdevice) { 6095 mychswtable[i].subsysCard == ivideo->subsysdevice) {
4959 ivideo->SiS_Pr.SiS_ChSW = TRUE; 6096 ivideo->SiS_Pr.SiS_ChSW = TRUE;
4960 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n", 6097 printk(KERN_DEBUG "sisfb: Identified [%s %s] "
4961 mychswtable[i].vendorName, mychswtable[i].cardName); 6098 "requiring Chrontel/GPIO setup\n",
4962 break; 6099 mychswtable[i].vendorName,
4963 } 6100 mychswtable[i].cardName);
4964 i++; 6101 ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL);
4965 } while(mychswtable[i].subsysVendor != 0); 6102 break;
6103 }
6104 i++;
6105 } while(mychswtable[i].subsysVendor != 0);
6106 }
6107#endif
6108
6109#ifdef CONFIG_FB_SIS_315
6110 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
6111 ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3));
4966 } 6112 }
4967#endif 6113#endif
4968 6114
4969 outSISIDXREG(SISSR, 0x05, 0x86); 6115 outSISIDXREG(SISSR, 0x05, 0x86);
4970 6116
4971 if( (!sisvga_enabled) 6117 if( (!ivideo->sisvga_enabled)
4972#if !defined(__i386__) && !defined(__x86_64__) 6118#if !defined(__i386__) && !defined(__x86_64__)
4973 || (sisfb_resetcard) 6119 || (sisfb_resetcard)
4974#endif 6120#endif
4975 ) { 6121 ) {
4976 for(i = 0x30; i <= 0x3f; i++) { 6122 for(i = 0x30; i <= 0x3f; i++) {
4977 outSISIDXREG(SISCR,i,0x00); 6123 outSISIDXREG(SISCR, i, 0x00);
4978 } 6124 }
4979 } 6125 }
4980 6126
4981 /* Find out about current video mode */ 6127 /* Find out about current video mode */
4982 ivideo->modeprechange = 0x03; 6128 ivideo->modeprechange = 0x03;
4983 inSISIDXREG(SISCR,0x34,reg); 6129 inSISIDXREG(SISCR, 0x34, reg);
4984 if(reg & 0x7f) { 6130 if(reg & 0x7f) {
4985 ivideo->modeprechange = reg & 0x7f; 6131 ivideo->modeprechange = reg & 0x7f;
4986 } else if(sisvga_enabled) { 6132 } else if(ivideo->sisvga_enabled) {
4987#if defined(__i386__) || defined(__x86_64__) 6133#if defined(__i386__) || defined(__x86_64__)
4988 unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000); 6134 unsigned char SIS_IOTYPE2 *tt = ioremap(0x400, 0x100);
4989 if(tt) { 6135 if(tt) {
4990 ivideo->modeprechange = readb(tt + 0x449); 6136 ivideo->modeprechange = readb(tt + 0x49);
4991 iounmap(tt); 6137 iounmap(tt);
4992 } 6138 }
4993#endif 6139#endif
4994 } 6140 }
@@ -4996,219 +6142,221 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
4996#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 6142#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
4997#ifdef MODULE 6143#ifdef MODULE
4998 if((reg & 0x80) && (reg != 0xff)) { 6144 if((reg & 0x80) && (reg != 0xff)) {
4999 if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF) { 6145 if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
5000 printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n"); 6146 != 0xFF) {
5001 pci_set_drvdata(pdev, NULL); 6147 printk(KERN_INFO "sisfb: Cannot initialize display mode, "
5002 kfree(sis_fb_info); 6148 "X server is active\n");
5003 return -EBUSY; 6149 ret = -EBUSY;
5004 } 6150 goto error_4;
6151 }
5005 } 6152 }
5006#endif
5007#endif 6153#endif
5008
5009 ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
5010#ifdef CONFIG_FB_SIS_300
5011 if(ivideo->sisvga_engine == SIS_300_VGA) {
5012 if(ivideo->chip != SIS_300) {
5013 inSISIDXREG(SISSR, 0x1a, reg);
5014 if(!(reg & 0x10)) {
5015 ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
5016 }
5017 }
5018 }
5019#endif 6154#endif
5020 6155
6156 /* Search and copy ROM image */
5021 ivideo->bios_abase = NULL; 6157 ivideo->bios_abase = NULL;
6158 ivideo->SiS_Pr.VirtualRomBase = NULL;
6159 ivideo->SiS_Pr.UseROM = FALSE;
6160 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = FALSE;
5022 if(ivideo->sisfb_userom) { 6161 if(ivideo->sisfb_userom) {
5023 ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev); 6162 ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
5024 ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase; 6163 ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase;
5025 if(ivideo->sishw_ext.pjVirtualRomBase) { 6164 ivideo->SiS_Pr.UseROM = (ivideo->SiS_Pr.VirtualRomBase) ? TRUE : FALSE;
5026 printk(KERN_INFO "sisfb: Video ROM found and copied\n"); 6165 printk(KERN_INFO "sisfb: Video ROM %sfound\n",
5027 ivideo->sishw_ext.UseROM = TRUE; 6166 ivideo->SiS_Pr.UseROM ? "" : "not ");
5028 } else { 6167 if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) {
5029 ivideo->sishw_ext.UseROM = FALSE; 6168 ivideo->SiS_Pr.UseROM = FALSE;
5030 printk(KERN_INFO "sisfb: Video ROM not found\n"); 6169 ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = TRUE;
5031 } 6170 if( (ivideo->revision_id == 2) &&
6171 (!(ivideo->bios_abase[0x1d1] & 0x01)) ) {
6172 ivideo->SiS_Pr.DDCPortMixup = TRUE;
6173 }
6174 }
5032 } else { 6175 } else {
5033 ivideo->sishw_ext.pjVirtualRomBase = NULL; 6176 printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
5034 ivideo->sishw_ext.UseROM = FALSE;
5035 printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
5036 } 6177 }
5037 6178
5038 /* Find systems for special custom timing */ 6179 /* Find systems for special custom timing */
5039 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) { 6180 if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
5040 int j; 6181 sisfb_detect_custom_timing(ivideo);
5041 unsigned char *biosver = NULL;
5042 unsigned char *biosdate = NULL;
5043 BOOLEAN footprint;
5044 u32 chksum = 0;
5045
5046 if(ivideo->sishw_ext.UseROM) {
5047 biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
5048 biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
5049 for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
5050 }
5051
5052 i=0;
5053 do {
5054 if( (mycustomttable[i].chipID == ivideo->chip) &&
5055 ((!strlen(mycustomttable[i].biosversion)) ||
5056 (ivideo->sishw_ext.UseROM &&
5057 (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
5058 ((!strlen(mycustomttable[i].biosdate)) ||
5059 (ivideo->sishw_ext.UseROM &&
5060 (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
5061 ((!mycustomttable[i].bioschksum) ||
5062 (ivideo->sishw_ext.UseROM &&
5063 (mycustomttable[i].bioschksum == chksum))) &&
5064 (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
5065 (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
5066 footprint = TRUE;
5067 for(j = 0; j < 5; j++) {
5068 if(mycustomttable[i].biosFootprintAddr[j]) {
5069 if(ivideo->sishw_ext.UseROM) {
5070 if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
5071 mycustomttable[i].biosFootprintData[j]) {
5072 footprint = FALSE;
5073 }
5074 } else footprint = FALSE;
5075 }
5076 }
5077 if(footprint) {
5078 ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
5079 printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
5080 mycustomttable[i].vendorName,
5081 mycustomttable[i].cardName);
5082 printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
5083 mycustomttable[i].optionName);
5084 break;
5085 }
5086 }
5087 i++;
5088 } while(mycustomttable[i].chipID);
5089 } 6182 }
5090 6183
5091#ifdef CONFIG_FB_SIS_300 6184 /* POST card in case this has not been done by the BIOS */
5092 if(ivideo->sisvga_engine == SIS_300_VGA) { 6185 if( (!ivideo->sisvga_enabled)
5093 if( (!sisvga_enabled)
5094#if !defined(__i386__) && !defined(__x86_64__) 6186#if !defined(__i386__) && !defined(__x86_64__)
5095 || (sisfb_resetcard) 6187 || (sisfb_resetcard)
5096#endif 6188#endif
5097 ) { 6189 ) {
6190#ifdef CONFIG_FB_SIS_300
6191 if(ivideo->sisvga_engine == SIS_300_VGA) {
5098 if(ivideo->chip == SIS_300) { 6192 if(ivideo->chip == SIS_300) {
5099 sisfb_post_sis300(pdev); 6193 sisfb_post_sis300(pdev);
6194 ivideo->sisfb_can_post = 1;
5100 } 6195 }
5101 } 6196 }
5102 }
5103#endif 6197#endif
5104 6198
5105#ifdef CONFIG_FB_SIS_315 6199#ifdef CONFIG_FB_SIS_315
5106 if(ivideo->sisvga_engine == SIS_315_VGA) { 6200 if(ivideo->sisvga_engine == SIS_315_VGA) {
5107 if( (!sisvga_enabled) 6201 int result = 1;
5108#if !defined(__i386__) && !defined(__x86_64__) 6202 /* if((ivideo->chip == SIS_315H) ||
5109 || (sisfb_resetcard)
5110#endif
5111 ) {
5112 if((ivideo->chip == SIS_315H) ||
5113 (ivideo->chip == SIS_315) || 6203 (ivideo->chip == SIS_315) ||
5114 (ivideo->chip == SIS_315PRO) || 6204 (ivideo->chip == SIS_315PRO) ||
5115 (ivideo->chip == SIS_330)) { 6205 (ivideo->chip == SIS_330)) {
5116 sisfb_post_sis315330(pdev); 6206 sisfb_post_sis315330(pdev);
6207 } else */ if(ivideo->chip == XGI_20) {
6208 result = sisfb_post_xgi(pdev);
6209 ivideo->sisfb_can_post = 1;
6210 } else if((ivideo->chip == XGI_40) && ivideo->haveXGIROM) {
6211 result = sisfb_post_xgi(pdev);
6212 ivideo->sisfb_can_post = 1;
6213 } else {
6214 printk(KERN_INFO "sisfb: Card is not "
6215 "POSTed and sisfb can't do this either.\n");
6216 }
6217 if(!result) {
6218 printk(KERN_ERR "sisfb: Failed to POST card\n");
6219 ret = -ENODEV;
6220 goto error_3;
5117 } 6221 }
5118 } 6222 }
5119 }
5120#endif 6223#endif
6224 }
5121 6225
6226 ivideo->sisfb_card_posted = 1;
6227
6228 /* Find out about RAM size */
5122 if(sisfb_get_dram_size(ivideo)) { 6229 if(sisfb_get_dram_size(ivideo)) {
5123 printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n"); 6230 printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n");
5124 if(ivideo->bios_abase) vfree(ivideo->bios_abase); 6231 ret = -ENODEV;
5125 pci_set_drvdata(pdev, NULL); 6232 goto error_3;
5126 kfree(sis_fb_info);
5127 return -ENODEV;
5128 } 6233 }
5129 6234
6235
6236 /* Enable PCI addressing and MMIO */
5130 if((ivideo->sisfb_mode_idx < 0) || 6237 if((ivideo->sisfb_mode_idx < 0) ||
5131 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6238 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
5132 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ 6239 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
5133 orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); 6240 orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
5134 /* Enable 2D accelerator engine */ 6241 /* Enable 2D accelerator engine */
5135 orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); 6242 orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
5136 } 6243 }
5137 6244
5138 if(sisfb_pdc != 0xff) { 6245 if(sisfb_pdc != 0xff) {
5139 if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c; 6246 if(ivideo->sisvga_engine == SIS_300_VGA)
5140 else sisfb_pdc &= 0x1f; 6247 sisfb_pdc &= 0x3c;
5141 ivideo->SiS_Pr.PDC = sisfb_pdc; 6248 else
6249 sisfb_pdc &= 0x1f;
6250 ivideo->SiS_Pr.PDC = sisfb_pdc;
5142 } 6251 }
5143#ifdef CONFIG_FB_SIS_315 6252#ifdef CONFIG_FB_SIS_315
5144 if(ivideo->sisvga_engine == SIS_315_VGA) { 6253 if(ivideo->sisvga_engine == SIS_315_VGA) {
5145 if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f; 6254 if(sisfb_pdca != 0xff)
6255 ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
5146 } 6256 }
5147#endif 6257#endif
5148 6258
5149 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) { 6259 if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
5150 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n"); 6260 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n",
6261 (int)(ivideo->video_size >> 20));
5151 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n"); 6262 printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
5152 if(ivideo->bios_abase) vfree(ivideo->bios_abase); 6263 ret = -ENODEV;
5153 pci_set_drvdata(pdev, NULL); 6264 goto error_3;
5154 kfree(sis_fb_info);
5155 return -ENODEV;
5156 } 6265 }
5157 6266
5158 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) { 6267 if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
5159 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n"); 6268 printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
5160 release_mem_region(ivideo->video_base, ivideo->video_size); 6269 ret = -ENODEV;
5161 if(ivideo->bios_abase) vfree(ivideo->bios_abase); 6270 goto error_2;
5162 pci_set_drvdata(pdev, NULL);
5163 kfree(sis_fb_info);
5164 return -ENODEV;
5165 } 6271 }
5166 6272
5167 ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size); 6273 ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size);
5168 ivideo->sishw_ext.pjVideoMemoryAddress = ivideo->video_vbase; 6274 ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase;
5169 if(!ivideo->video_vbase) { 6275 if(!ivideo->video_vbase) {
5170 printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n"); 6276 printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
5171 release_mem_region(ivideo->video_base, ivideo->video_size); 6277 ret = -ENODEV;
5172 release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6278 goto error_1;
5173 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5174 pci_set_drvdata(pdev, NULL);
5175 kfree(sis_fb_info);
5176 return -ENODEV;
5177 } 6279 }
5178 6280
5179 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size); 6281 ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size);
5180 if(!ivideo->mmio_vbase) { 6282 if(!ivideo->mmio_vbase) {
5181 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n"); 6283 printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
5182 iounmap(ivideo->video_vbase); 6284 ret = -ENODEV;
5183 release_mem_region(ivideo->video_base, ivideo->video_size); 6285error_0: iounmap(ivideo->video_vbase);
5184 release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6286error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
5185 if(ivideo->bios_abase) vfree(ivideo->bios_abase); 6287error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6288error_3: vfree(ivideo->bios_abase);
6289#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6290error_4:
6291#endif
6292 if(ivideo->lpcdev)
6293 SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
6294 if(ivideo->nbridge)
6295 SIS_PCI_PUT_DEVICE(ivideo->nbridge);
5186 pci_set_drvdata(pdev, NULL); 6296 pci_set_drvdata(pdev, NULL);
5187 kfree(sis_fb_info); 6297 if(!ivideo->sisvga_enabled)
5188 return -ENODEV; 6298 pci_disable_device(pdev);
6299 kfree(sis_fb_info);
6300 return ret;
5189 } 6301 }
5190 6302
5191 printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n", 6303 printk(KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n",
5192 ivideo->video_base, (ULONG)ivideo->video_vbase, ivideo->video_size / 1024); 6304 ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024);
6305
6306 if(ivideo->video_offset) {
6307 printk(KERN_INFO "sisfb: Viewport offset %ldk\n",
6308 ivideo->video_offset / 1024);
6309 }
5193 6310
5194 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n", 6311 printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
5195 ivideo->mmio_base, (ULONG)ivideo->mmio_vbase, ivideo->mmio_size / 1024); 6312 ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
6313
5196 6314
6315 /* Determine the size of the command queue */
6316 if(ivideo->sisvga_engine == SIS_300_VGA) {
6317 ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE;
6318 } else {
6319 if(ivideo->chip == XGI_20) {
6320 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7;
6321 } else {
6322 ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE;
6323 }
6324 }
6325
6326 /* Engines are no longer initialized here; this is
6327 * now done after the first mode-switch (if the
6328 * submitted var has its acceleration flags set).
6329 */
6330
6331 /* Calculate the base of the (unused) hw cursor */
6332 ivideo->hwcursor_vbase = ivideo->video_vbase
6333 + ivideo->video_size
6334 - ivideo->cmdQueueSize
6335 - ivideo->hwcursor_size;
6336 ivideo->caps |= HW_CURSOR_CAP;
6337
6338 /* Initialize offscreen memory manager */
5197 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) { 6339 if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
5198 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n"); 6340 printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
5199 } 6341 }
5200 6342
5201 /* Used for clearing the screen only, therefore respect our mem limit */ 6343 /* Used for clearing the screen only, therefore respect our mem limit */
5202 ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem; 6344 ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset;
6345 ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem;
5203 6346
5204 ivideo->mtrr = 0; 6347 ivideo->mtrr = -1;
5205 6348
5206 ivideo->vbflags = 0; 6349 ivideo->vbflags = 0;
5207 ivideo->lcddefmodeidx = DEFAULT_LCDMODE; 6350 ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
5208 ivideo->tvdefmodeidx = DEFAULT_TVMODE; 6351 ivideo->tvdefmodeidx = DEFAULT_TVMODE;
5209 ivideo->defmodeidx = DEFAULT_MODE; 6352 ivideo->defmodeidx = DEFAULT_MODE;
5210 6353
5211 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext); 6354 ivideo->newrom = 0;
6355 if(ivideo->chip < XGI_20) {
6356 if(ivideo->bios_abase) {
6357 ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr);
6358 }
6359 }
5212 6360
5213 if((ivideo->sisfb_mode_idx < 0) || 6361 if((ivideo->sisfb_mode_idx < 0) ||
5214 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { 6362 ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
@@ -5217,192 +6365,57 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5217 6365
5218 sisfb_get_VB_type(ivideo); 6366 sisfb_get_VB_type(ivideo);
5219 6367
5220 if(ivideo->vbflags & VB_VIDEOBRIDGE) { 6368 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
5221 sisfb_detect_VB_connect(ivideo); 6369 sisfb_detect_VB_connect(ivideo);
5222 } 6370 }
5223 6371
5224 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD); 6372 ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
5225 6373
5226 if(ivideo->vbflags & VB_VIDEOBRIDGE) { 6374 /* Decide on which CRT2 device to use */
5227 if(ivideo->sisfb_crt2type != -1) { 6375 if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
5228 if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) { 6376 if(ivideo->sisfb_crt2type != -1) {
5229 ivideo->currentvbflags |= CRT2_LCD; 6377 if((ivideo->sisfb_crt2type == CRT2_LCD) &&
5230 } else if(ivideo->sisfb_crt2type != CRT2_LCD) { 6378 (ivideo->vbflags & CRT2_LCD)) {
5231 ivideo->currentvbflags |= ivideo->sisfb_crt2type; 6379 ivideo->currentvbflags |= CRT2_LCD;
5232 } 6380 } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
5233 } else { 6381 ivideo->currentvbflags |= ivideo->sisfb_crt2type;
5234 /* Chrontel 700x TV detection often unreliable, therefore use a 6382 }
5235 * different default order on such machines 6383 } else {
5236 */ 6384 /* Chrontel 700x TV detection often unreliable, therefore
5237 if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) { 6385 * use a different default order on such machines
5238 if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD; 6386 */
5239 else if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV; 6387 if((ivideo->sisvga_engine == SIS_300_VGA) &&
5240 else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA; 6388 (ivideo->vbflags2 & VB2_CHRONTEL)) {
5241 } else { 6389 if(ivideo->vbflags & CRT2_LCD)
5242 if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV; 6390 ivideo->currentvbflags |= CRT2_LCD;
5243 else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD; 6391 else if(ivideo->vbflags & CRT2_TV)
5244 else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA; 6392 ivideo->currentvbflags |= CRT2_TV;
5245 } 6393 else if(ivideo->vbflags & CRT2_VGA)
5246 } 6394 ivideo->currentvbflags |= CRT2_VGA;
6395 } else {
6396 if(ivideo->vbflags & CRT2_TV)
6397 ivideo->currentvbflags |= CRT2_TV;
6398 else if(ivideo->vbflags & CRT2_LCD)
6399 ivideo->currentvbflags |= CRT2_LCD;
6400 else if(ivideo->vbflags & CRT2_VGA)
6401 ivideo->currentvbflags |= CRT2_VGA;
6402 }
6403 }
5247 } 6404 }
5248 6405
5249 if(ivideo->vbflags & CRT2_LCD) { 6406 if(ivideo->vbflags & CRT2_LCD) {
5250 inSISIDXREG(SISCR, 0x36, reg); 6407 sisfb_detect_lcd_type(ivideo);
5251 reg &= 0x0f;
5252 if(ivideo->sisvga_engine == SIS_300_VGA) {
5253 ivideo->CRT2LCDType = sis300paneltype[reg];
5254 } else if(ivideo->chip >= SIS_661) {
5255 ivideo->CRT2LCDType = sis661paneltype[reg];
5256 } else {
5257 ivideo->CRT2LCDType = sis310paneltype[reg];
5258 if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
5259 if((ivideo->CRT2LCDType != LCD_640x480_2) &&
5260 (ivideo->CRT2LCDType != LCD_640x480_3)) {
5261 ivideo->CRT2LCDType = LCD_320x480;
5262 }
5263 }
5264 }
5265 if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
5266 /* For broken BIOSes: Assume 1024x768, RGB18 */
5267 ivideo->CRT2LCDType = LCD_1024x768;
5268 setSISIDXREG(SISCR,0x36,0xf0,0x02);
5269 setSISIDXREG(SISCR,0x37,0xee,0x01);
5270 printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
5271 }
5272 for(i = 0; i < SIS_LCD_NUMBER; i++) {
5273 if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
5274 ivideo->lcdxres = sis_lcd_data[i].xres;
5275 ivideo->lcdyres = sis_lcd_data[i].yres;
5276 ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
5277 break;
5278 }
5279 }
5280 if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
5281 ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
5282 } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
5283 ivideo->lcdxres = 848; ivideo->lcdyres = 480; ivideo->lcddefmodeidx = 47;
5284 }
5285 printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
5286 ivideo->lcdxres, ivideo->lcdyres);
5287 }
5288
5289#ifdef CONFIG_FB_SIS_300
5290 /* Save the current PanelDelayCompensation if the LCD is currently used */
5291 if(ivideo->sisvga_engine == SIS_300_VGA) {
5292 if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
5293 int tmp;
5294 inSISIDXREG(SISCR,0x30,tmp);
5295 if(tmp & 0x20) {
5296 /* Currently on LCD? If yes, read current pdc */
5297 inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
5298 ivideo->detectedpdc &= 0x3c;
5299 if(ivideo->SiS_Pr.PDC == -1) {
5300 /* Let option override detection */
5301 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
5302 }
5303 printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
5304 ivideo->detectedpdc);
5305 }
5306 if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
5307 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
5308 ivideo->SiS_Pr.PDC);
5309 }
5310 }
5311 } 6408 }
5312#endif
5313
5314#ifdef CONFIG_FB_SIS_315
5315 if(ivideo->sisvga_engine == SIS_315_VGA) {
5316
5317 /* Try to find about LCDA */
5318 if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
5319 int tmp;
5320 inSISIDXREG(SISPART1,0x13,tmp);
5321 if(tmp & 0x04) {
5322 ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
5323 ivideo->detectedlcda = 0x03;
5324 }
5325 }
5326
5327 /* Save PDC */
5328 if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
5329 int tmp;
5330 inSISIDXREG(SISCR,0x30,tmp);
5331 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
5332 /* Currently on LCD? If yes, read current pdc */
5333 u8 pdc;
5334 inSISIDXREG(SISPART1,0x2D,pdc);
5335 ivideo->detectedpdc = (pdc & 0x0f) << 1;
5336 ivideo->detectedpdca = (pdc & 0xf0) >> 3;
5337 inSISIDXREG(SISPART1,0x35,pdc);
5338 ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
5339 inSISIDXREG(SISPART1,0x20,pdc);
5340 ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
5341 if(ivideo->newrom) {
5342 /* New ROM invalidates other PDC resp. */
5343 if(ivideo->detectedlcda != 0xff) {
5344 ivideo->detectedpdc = 0xff;
5345 } else {
5346 ivideo->detectedpdca = 0xff;
5347 }
5348 }
5349 if(ivideo->SiS_Pr.PDC == -1) {
5350 if(ivideo->detectedpdc != 0xff) {
5351 ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
5352 }
5353 }
5354 if(ivideo->SiS_Pr.PDCA == -1) {
5355 if(ivideo->detectedpdca != 0xff) {
5356 ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
5357 }
5358 }
5359 if(ivideo->detectedpdc != 0xff) {
5360 printk(KERN_INFO
5361 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
5362 ivideo->detectedpdc);
5363 }
5364 if(ivideo->detectedpdca != 0xff) {
5365 printk(KERN_INFO
5366 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
5367 ivideo->detectedpdca);
5368 }
5369 }
5370
5371 /* Save EMI */
5372 if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
5373 inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
5374 inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
5375 inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
5376 inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
5377 ivideo->SiS_Pr.HaveEMI = TRUE;
5378 if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
5379 ivideo->SiS_Pr.HaveEMILCD = TRUE;
5380 }
5381 }
5382 }
5383
5384 /* Let user override detected PDCs (all bridges) */
5385 if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
5386 if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
5387 printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
5388 ivideo->SiS_Pr.PDC);
5389 }
5390 if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
5391 printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
5392 ivideo->SiS_Pr.PDCA);
5393 }
5394 }
5395 6409
5396 } 6410 sisfb_save_pdc_emi(ivideo);
5397#endif
5398 6411
5399 if(!ivideo->sisfb_crt1off) { 6412 if(!ivideo->sisfb_crt1off) {
5400 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0); 6413 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
5401 } else { 6414 } else {
5402 if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) && 6415 if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) &&
5403 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) { 6416 (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
5404 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1); 6417 sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
5405 } 6418 }
5406 } 6419 }
5407 6420
5408 if(ivideo->sisfb_mode_idx >= 0) { 6421 if(ivideo->sisfb_mode_idx >= 0) {
@@ -5434,7 +6447,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5434 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]; 6447 ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
5435 6448
5436 if(ivideo->refresh_rate != 0) { 6449 if(ivideo->refresh_rate != 0) {
5437 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx); 6450 sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate,
6451 ivideo->sisfb_mode_idx);
5438 } 6452 }
5439 6453
5440 if(ivideo->rate_idx == 0) { 6454 if(ivideo->rate_idx == 0) {
@@ -5443,9 +6457,12 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5443 } 6457 }
5444 6458
5445 if(ivideo->sisfb_thismonitor.datavalid) { 6459 if(ivideo->sisfb_thismonitor.datavalid) {
5446 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx, 6460 if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor,
5447 ivideo->rate_idx, ivideo->refresh_rate)) { 6461 ivideo->sisfb_mode_idx,
5448 printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); 6462 ivideo->rate_idx,
6463 ivideo->refresh_rate)) {
6464 printk(KERN_INFO "sisfb: WARNING: Refresh rate "
6465 "exceeds monitor specs!\n");
5449 } 6466 }
5450 } 6467 }
5451 6468
@@ -5454,28 +6471,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5454 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres; 6471 ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
5455 6472
5456 sisfb_set_vparms(ivideo); 6473 sisfb_set_vparms(ivideo);
5457
5458#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5459 6474
5460 /* ---------------- For 2.4: Now switch the mode ------------------ */ 6475#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5461 6476
5462 printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n", 6477 /* ---------------- For 2.4: Now switch the mode ------------------ */
5463 ivideo->video_width, ivideo->video_height, ivideo->video_bpp, 6478
6479 printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
6480 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
5464 ivideo->refresh_rate); 6481 ivideo->refresh_rate);
5465 6482
6483 /* Determine whether or not acceleration is to be
6484 * used. Need to know before pre/post_set_mode()
6485 */
6486 ivideo->accel = 0;
6487 ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
6488 if(ivideo->sisfb_accel) {
6489 ivideo->accel = -1;
6490 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
6491 }
6492
6493 /* Now switch the mode */
5466 sisfb_pre_setmode(ivideo); 6494 sisfb_pre_setmode(ivideo);
5467 6495
5468 if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) { 6496 if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
5469 printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n", 6497 printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
5470 ivideo->mode_no); 6498 ivideo->mode_no);
5471 iounmap(ivideo->video_vbase); 6499 ret = -EINVAL;
5472 iounmap(ivideo->mmio_vbase); 6500 iounmap(ivideo->mmio_vbase);
5473 release_mem_region(ivideo->video_base, ivideo->video_size); 6501 goto error_0;
5474 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5475 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5476 pci_set_drvdata(pdev, NULL);
5477 kfree(sis_fb_info);
5478 return -EINVAL;
5479 } 6502 }
5480 6503
5481 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 6504 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
@@ -5488,18 +6511,17 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5488 /* Force reset of x virtual in crtc_to_var */ 6511 /* Force reset of x virtual in crtc_to_var */
5489 ivideo->default_var.xres_virtual = 0; 6512 ivideo->default_var.xres_virtual = 0;
5490 6513
6514 /* Copy mode timing to var */
5491 sisfb_crtc_to_var(ivideo, &ivideo->default_var); 6515 sisfb_crtc_to_var(ivideo, &ivideo->default_var);
5492 6516
6517 /* Find out about screen pitch */
5493 sisfb_calc_pitch(ivideo, &ivideo->default_var); 6518 sisfb_calc_pitch(ivideo, &ivideo->default_var);
5494 sisfb_set_pitch(ivideo); 6519 sisfb_set_pitch(ivideo);
5495 6520
5496 ivideo->accel = 0; 6521 /* Init the accelerator (does nothing currently) */
5497 if(ivideo->sisfb_accel) {
5498 ivideo->accel = -1;
5499 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
5500 }
5501 sisfb_initaccel(ivideo); 6522 sisfb_initaccel(ivideo);
5502 6523
6524 /* Init some fbinfo entries */
5503 sis_fb_info->node = -1; 6525 sis_fb_info->node = -1;
5504 sis_fb_info->flags = FBINFO_FLAG_DEFAULT; 6526 sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
5505 sis_fb_info->fbops = &sisfb_ops; 6527 sis_fb_info->fbops = &sisfb_ops;
@@ -5515,41 +6537,42 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5515#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */ 6537#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
5516 6538
5517 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", 6539 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
5518 ivideo->video_width, ivideo->video_height, ivideo->video_bpp, 6540 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
5519 ivideo->refresh_rate); 6541 ivideo->refresh_rate);
5520 6542
6543 /* Set up the default var according to chosen default display mode */
5521 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width; 6544 ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
5522 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height; 6545 ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
5523 ivideo->default_var.bits_per_pixel = ivideo->video_bpp; 6546 ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
5524 6547
5525 sisfb_bpp_to_var(ivideo, &ivideo->default_var); 6548 sisfb_bpp_to_var(ivideo, &ivideo->default_var);
5526 6549
5527 ivideo->default_var.pixclock = (u32) (1000000000 / 6550 ivideo->default_var.pixclock = (u32) (1000000000 /
5528 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext, 6551 sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx));
5529 ivideo->mode_no, ivideo->rate_idx)); 6552
5530 6553 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no,
5531 if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext, 6554 ivideo->rate_idx, &ivideo->default_var)) {
5532 ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) { 6555 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
5533 if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 6556 ivideo->default_var.pixclock <<= 1;
5534 ivideo->default_var.pixclock <<= 1; 6557 }
5535 } 6558 }
5536 }
5537 6559
5538 if(ivideo->sisfb_ypan) { 6560 if(ivideo->sisfb_ypan) {
5539 /* Maximize regardless of sisfb_max at startup */ 6561 /* Maximize regardless of sisfb_max at startup */
5540 ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var); 6562 ivideo->default_var.yres_virtual =
5541 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) { 6563 sisfb_calc_maxyres(ivideo, &ivideo->default_var);
5542 ivideo->default_var.yres_virtual = ivideo->default_var.yres; 6564 if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
5543 } 6565 ivideo->default_var.yres_virtual = ivideo->default_var.yres;
6566 }
5544 } 6567 }
5545 6568
5546 sisfb_calc_pitch(ivideo, &ivideo->default_var); 6569 sisfb_calc_pitch(ivideo, &ivideo->default_var);
5547 6570
5548 ivideo->accel = 0; 6571 ivideo->accel = 0;
5549 if(ivideo->sisfb_accel) { 6572 if(ivideo->sisfb_accel) {
5550 ivideo->accel = -1; 6573 ivideo->accel = -1;
5551#ifdef STUPID_ACCELF_TEXT_SHIT 6574#ifdef STUPID_ACCELF_TEXT_SHIT
5552 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT; 6575 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
5553#endif 6576#endif
5554 } 6577 }
5555 sisfb_initaccel(ivideo); 6578 sisfb_initaccel(ivideo);
@@ -5566,21 +6589,21 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5566#endif 6589#endif
5567 sis_fb_info->var = ivideo->default_var; 6590 sis_fb_info->var = ivideo->default_var;
5568 sis_fb_info->fix = ivideo->sisfb_fix; 6591 sis_fb_info->fix = ivideo->sisfb_fix;
5569 sis_fb_info->screen_base = ivideo->video_vbase; 6592 sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
5570 sis_fb_info->fbops = &sisfb_ops; 6593 sis_fb_info->fbops = &sisfb_ops;
5571 6594
5572 sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); 6595 sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
5573 sis_fb_info->pseudo_palette = ivideo->pseudo_palette; 6596 sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
5574 6597
5575 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); 6598 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
5576#endif /* 2.6 */ 6599#endif /* 2.6 */
5577 6600
5578 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags); 6601 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
5579 6602
5580#ifdef CONFIG_MTRR 6603#ifdef CONFIG_MTRR
5581 ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size, 6604 ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
5582 MTRR_TYPE_WRCOMB, 1); 6605 MTRR_TYPE_WRCOMB, 1);
5583 if(!ivideo->mtrr) { 6606 if(ivideo->mtrr < 0) {
5584 printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n"); 6607 printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
5585 } 6608 }
5586#endif 6609#endif
@@ -5591,14 +6614,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5591 6614
5592 if(register_framebuffer(sis_fb_info) < 0) { 6615 if(register_framebuffer(sis_fb_info) < 0) {
5593 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); 6616 printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
5594 iounmap(ivideo->video_vbase); 6617 ret = -EINVAL;
5595 iounmap(ivideo->mmio_vbase); 6618 iounmap(ivideo->mmio_vbase);
5596 release_mem_region(ivideo->video_base, ivideo->video_size); 6619 goto error_0;
5597 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5598 if(ivideo->bios_abase) vfree(ivideo->bios_abase);
5599 pci_set_drvdata(pdev, NULL);
5600 kfree(sis_fb_info);
5601 return -EINVAL;
5602 } 6620 }
5603 6621
5604 ivideo->registered = 1; 6622 ivideo->registered = 1;
@@ -5607,21 +6625,47 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5607 ivideo->next = card_list; 6625 ivideo->next = card_list;
5608 card_list = ivideo; 6626 card_list = ivideo;
5609 6627
6628#ifdef SIS_OLD_CONFIG_COMPAT
6629 {
6630 int ret;
6631 /* Our ioctls are all "32/64bit compatible" */
6632 ret = register_ioctl32_conversion(FBIO_ALLOC, NULL);
6633 ret |= register_ioctl32_conversion(FBIO_FREE, NULL);
6634 ret |= register_ioctl32_conversion(FBIOGET_VBLANK, NULL);
6635 ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE, NULL);
6636 ret |= register_ioctl32_conversion(SISFB_GET_INFO, NULL);
6637 ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET, NULL);
6638 ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET, NULL);
6639 ret |= register_ioctl32_conversion(SISFB_SET_LOCK, NULL);
6640 ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS, NULL);
6641 ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
6642 ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
6643 ret |= register_ioctl32_conversion(SISFB_COMMAND, NULL);
6644 if(ret)
6645 printk(KERN_ERR
6646 "sisfb: Error registering ioctl32 translations\n");
6647 else
6648 ivideo->ioctl32registered = 1;
6649 }
6650#endif
6651
5610 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n", 6652 printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
5611 ivideo->sisfb_accel ? "enabled" : "disabled", 6653 ivideo->sisfb_accel ? "enabled" : "disabled",
5612 ivideo->sisfb_ypan ? 6654 ivideo->sisfb_ypan ?
5613 (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled"); 6655 (ivideo->sisfb_max ? "enabled (auto-max)" :
6656 "enabled (no auto-max)") :
6657 "disabled");
5614 6658
5615 6659
5616 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n", 6660 printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
5617#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 6661#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5618 GET_FB_IDX(sis_fb_info->node), 6662 GET_FB_IDX(sis_fb_info->node),
5619#else 6663#else
5620 sis_fb_info->node, 6664 sis_fb_info->node,
5621#endif 6665#endif
5622 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); 6666 ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
5623 6667
5624 printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n"); 6668 printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
5625 6669
5626 } /* if mode = "none" */ 6670 } /* if mode = "none" */
5627 6671
@@ -5634,26 +6678,62 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
5634 6678
5635static void __devexit sisfb_remove(struct pci_dev *pdev) 6679static void __devexit sisfb_remove(struct pci_dev *pdev)
5636{ 6680{
5637 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 6681 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
5638 struct fb_info *sis_fb_info = ivideo->memyselfandi; 6682 struct fb_info *sis_fb_info = ivideo->memyselfandi;
5639 int registered = ivideo->registered; 6683 int registered = ivideo->registered;
6684 int modechanged = ivideo->modechanged;
6685
6686#ifdef SIS_OLD_CONFIG_COMPAT
6687 if(ivideo->ioctl32registered) {
6688 int ret;
6689 ret = unregister_ioctl32_conversion(FBIO_ALLOC);
6690 ret |= unregister_ioctl32_conversion(FBIO_FREE);
6691 ret |= unregister_ioctl32_conversion(FBIOGET_VBLANK);
6692 ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
6693 ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
6694 ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
6695 ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
6696 ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
6697 ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
6698 ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
6699 ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
6700 ret |= unregister_ioctl32_conversion(SISFB_COMMAND);
6701 if(ret)
6702 printk(KERN_ERR
6703 "sisfb: Error unregistering ioctl32 translations\n");
6704 }
6705#endif
5640 6706
5641 /* Unmap */ 6707 /* Unmap */
5642 iounmap(ivideo->video_vbase);
5643 iounmap(ivideo->mmio_vbase); 6708 iounmap(ivideo->mmio_vbase);
5644 vfree(ivideo->bios_abase); 6709 iounmap(ivideo->video_vbase);
5645 6710
5646 /* Release mem regions */ 6711 /* Release mem regions */
5647 release_mem_region(ivideo->video_base, ivideo->video_size); 6712 release_mem_region(ivideo->video_base, ivideo->video_size);
5648 release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6713 release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
5649 6714
6715 vfree(ivideo->bios_abase);
6716
6717 if(ivideo->lpcdev)
6718 SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
6719
6720 if(ivideo->nbridge)
6721 SIS_PCI_PUT_DEVICE(ivideo->nbridge);
6722
5650#ifdef CONFIG_MTRR 6723#ifdef CONFIG_MTRR
5651 /* Release MTRR region */ 6724 /* Release MTRR region */
5652 if(ivideo->mtrr) { 6725 if(ivideo->mtrr >= 0)
5653 mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size); 6726 mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
5654 }
5655#endif 6727#endif
5656 6728
6729 pci_set_drvdata(pdev, NULL);
6730
6731 /* If device was disabled when starting, disable
6732 * it when quitting.
6733 */
6734 if(!ivideo->sisvga_enabled)
6735 pci_disable_device(pdev);
6736
5657 /* Unregister the framebuffer */ 6737 /* Unregister the framebuffer */
5658 if(ivideo->registered) { 6738 if(ivideo->registered) {
5659 unregister_framebuffer(sis_fb_info); 6739 unregister_framebuffer(sis_fb_info);
@@ -5664,7 +6744,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
5664#endif 6744#endif
5665 } 6745 }
5666 6746
5667 pci_set_drvdata(pdev, NULL); 6747 /* OK, our ivideo is gone for good from here. */
5668 6748
5669 /* TODO: Restore the initial mode 6749 /* TODO: Restore the initial mode
5670 * This sounds easy but is as good as impossible 6750 * This sounds easy but is as good as impossible
@@ -5673,15 +6753,15 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
5673 * from machine to machine. Depends on the type 6753 * from machine to machine. Depends on the type
5674 * of integration between chipset and bridge. 6754 * of integration between chipset and bridge.
5675 */ 6755 */
5676 if(registered) { 6756 if(registered && modechanged)
5677 printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n"); 6757 printk(KERN_INFO
5678 } 6758 "sisfb: Restoring of text mode not supported yet\n");
5679}; 6759};
5680 6760
5681static struct pci_driver sisfb_driver = { 6761static struct pci_driver sisfb_driver = {
5682 .name = "sisfb", 6762 .name = "sisfb",
5683 .id_table = sisfb_pci_table, 6763 .id_table = sisfb_pci_table,
5684 .probe = sisfb_probe, 6764 .probe = sisfb_probe,
5685 .remove = __devexit_p(sisfb_remove) 6765 .remove = __devexit_p(sisfb_remove)
5686}; 6766};
5687 6767
@@ -5693,10 +6773,11 @@ SISINITSTATIC int __init sisfb_init(void)
5693 6773
5694 if(fb_get_options("sisfb", &options)) 6774 if(fb_get_options("sisfb", &options))
5695 return -ENODEV; 6775 return -ENODEV;
6776
5696 sisfb_setup(options); 6777 sisfb_setup(options);
5697#endif 6778#endif
5698#endif 6779#endif
5699 return(pci_register_driver(&sisfb_driver)); 6780 return pci_register_driver(&sisfb_driver);
5700} 6781}
5701 6782
5702#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) 6783#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
@@ -5711,36 +6792,129 @@ module_init(sisfb_init);
5711 6792
5712#ifdef MODULE 6793#ifdef MODULE
5713 6794
5714static char *mode = NULL; 6795static char *mode = NULL;
5715static int vesa = -1; 6796static int vesa = -1;
5716static unsigned int rate = 0; 6797static unsigned int rate = 0;
5717static unsigned int crt1off = 1; 6798static unsigned int crt1off = 1;
5718static unsigned int mem = 0; 6799static unsigned int mem = 0;
5719static char *forcecrt2type = NULL; 6800static char *forcecrt2type = NULL;
5720static int forcecrt1 = -1; 6801static int forcecrt1 = -1;
5721static int pdc = -1; 6802static int pdc = -1;
5722static int pdc1 = -1; 6803static int pdc1 = -1;
5723static int noaccel = -1; 6804static int noaccel = -1;
5724static int noypan = -1; 6805static int noypan = -1;
5725static int nomax = -1; 6806static int nomax = -1;
6807#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6808static int inverse = 0;
6809#endif
6810static int userom = -1;
6811static int useoem = -1;
6812static char *tvstandard = NULL;
6813static int nocrt2rate = 0;
6814static int scalelcd = -1;
6815static char *specialtiming = NULL;
6816static int lvdshl = -1;
6817static int tvxposoffset = 0, tvyposoffset = 0;
6818#if !defined(__i386__) && !defined(__x86_64__)
6819static int resetcard = 0;
6820static int videoram = 0;
6821#endif
6822
6823static int __init sisfb_init_module(void)
6824{
6825 sisfb_setdefaultparms();
6826
6827 if(rate)
6828 sisfb_parm_rate = rate;
6829
6830 if((scalelcd == 0) || (scalelcd == 1))
6831 sisfb_scalelcd = scalelcd ^ 1;
6832
6833 /* Need to check crt2 type first for fstn/dstn */
6834
6835 if(forcecrt2type)
6836 sisfb_search_crt2type(forcecrt2type);
6837
6838 if(tvstandard)
6839 sisfb_search_tvstd(tvstandard);
6840
6841 if(mode)
6842 sisfb_search_mode(mode, FALSE);
6843 else if(vesa != -1)
6844 sisfb_search_vesamode(vesa, FALSE);
6845
6846 sisfb_crt1off = (crt1off == 0) ? 1 : 0;
6847
6848 sisfb_forcecrt1 = forcecrt1;
6849 if(forcecrt1 == 1)
6850 sisfb_crt1off = 0;
6851 else if(forcecrt1 == 0)
6852 sisfb_crt1off = 1;
6853
6854 if(noaccel == 1)
6855 sisfb_accel = 0;
6856 else if(noaccel == 0)
6857 sisfb_accel = 1;
6858
6859 if(noypan == 1)
6860 sisfb_ypan = 0;
6861 else if(noypan == 0)
6862 sisfb_ypan = 1;
6863
6864 if(nomax == 1)
6865 sisfb_max = 0;
6866 else if(nomax == 0)
6867 sisfb_max = 1;
6868
5726#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 6869#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5727static int inverse = 0; 6870 if(inverse) sisfb_inverse = 1;
5728#endif 6871#endif
5729static int userom = -1; 6872
5730static int useoem = -1; 6873 if(mem)
5731static char *tvstandard = NULL; 6874 sisfb_parm_mem = mem;
5732static int nocrt2rate = 0; 6875
5733static int scalelcd = -1; 6876 if(userom != -1)
5734static char *specialtiming = NULL; 6877 sisfb_userom = userom;
5735static int lvdshl = -1; 6878
5736static int tvxposoffset = 0, tvyposoffset = 0; 6879 if(useoem != -1)
5737static int filter = -1; 6880 sisfb_useoem = useoem;
6881
6882 if(pdc != -1)
6883 sisfb_pdc = (pdc & 0x7f);
6884
6885 if(pdc1 != -1)
6886 sisfb_pdca = (pdc1 & 0x1f);
6887
6888 sisfb_nocrt2rate = nocrt2rate;
6889
6890 if(specialtiming)
6891 sisfb_search_specialtiming(specialtiming);
6892
6893 if((lvdshl >= 0) && (lvdshl <= 3))
6894 sisfb_lvdshl = lvdshl;
6895
6896 sisfb_tvxposoffset = tvxposoffset;
6897 sisfb_tvyposoffset = tvyposoffset;
6898
5738#if !defined(__i386__) && !defined(__x86_64__) 6899#if !defined(__i386__) && !defined(__x86_64__)
5739static int resetcard = 0; 6900 sisfb_resetcard = (resetcard) ? 1 : 0;
5740static int videoram = 0; 6901 if(videoram)
6902 sisfb_videoram = videoram;
5741#endif 6903#endif
5742 6904
5743MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver"); 6905 return sisfb_init();
6906}
6907
6908static void __exit sisfb_remove_module(void)
6909{
6910 pci_unregister_driver(&sisfb_driver);
6911 printk(KERN_DEBUG "sisfb: Module unloaded\n");
6912}
6913
6914module_init(sisfb_init_module);
6915module_exit(sisfb_remove_module);
6916
6917MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver");
5744MODULE_LICENSE("GPL"); 6918MODULE_LICENSE("GPL");
5745MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); 6919MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
5746 6920
@@ -5764,7 +6938,6 @@ MODULE_PARM(lvdshl, "i");
5764MODULE_PARM(tvstandard, "s"); 6938MODULE_PARM(tvstandard, "s");
5765MODULE_PARM(tvxposoffset, "i"); 6939MODULE_PARM(tvxposoffset, "i");
5766MODULE_PARM(tvyposoffset, "i"); 6940MODULE_PARM(tvyposoffset, "i");
5767MODULE_PARM(filter, "i");
5768MODULE_PARM(nocrt2rate, "i"); 6941MODULE_PARM(nocrt2rate, "i");
5769MODULE_PARM(inverse, "i"); 6942MODULE_PARM(inverse, "i");
5770#if !defined(__i386__) && !defined(__x86_64__) 6943#if !defined(__i386__) && !defined(__x86_64__)
@@ -5793,7 +6966,6 @@ module_param(lvdshl, int, 0);
5793module_param(tvstandard, charp, 0); 6966module_param(tvstandard, charp, 0);
5794module_param(tvxposoffset, int, 0); 6967module_param(tvxposoffset, int, 0);
5795module_param(tvyposoffset, int, 0); 6968module_param(tvyposoffset, int, 0);
5796module_param(filter, int, 0);
5797module_param(nocrt2rate, int, 0); 6969module_param(nocrt2rate, int, 0);
5798#if !defined(__i386__) && !defined(__x86_64__) 6970#if !defined(__i386__) && !defined(__x86_64__)
5799module_param(resetcard, int, 0); 6971module_param(resetcard, int, 0);
@@ -5801,25 +6973,35 @@ module_param(videoram, int, 0);
5801#endif 6973#endif
5802#endif 6974#endif
5803 6975
6976#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5804MODULE_PARM_DESC(mem, 6977MODULE_PARM_DESC(mem,
5805 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" 6978 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
5806 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" 6979 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
5807 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" 6980 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
5808 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" 6981 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
5809 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n" 6982 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
5810 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n" 6983 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
5811 "for XFree86 4.x/X.org 6.7 and later.\n"); 6984 "for XFree86 4.x/X.org 6.7 and later.\n");
6985#else
6986MODULE_PARM_DESC(mem,
6987 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
6988 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
6989 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
6990 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
6991 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
6992 "The value is to be specified without 'KB'.\n");
6993#endif
5812 6994
5813MODULE_PARM_DESC(noaccel, 6995MODULE_PARM_DESC(noaccel,
5814 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" 6996 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
5815 "(default: 0)\n"); 6997 "(default: 0)\n");
5816 6998
5817MODULE_PARM_DESC(noypan, 6999MODULE_PARM_DESC(noypan,
5818 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" 7000 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
5819 "will be performed by redrawing the screen. (default: 0)\n"); 7001 "will be performed by redrawing the screen. (default: 0)\n");
5820 7002
5821MODULE_PARM_DESC(nomax, 7003MODULE_PARM_DESC(nomax,
5822 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n" 7004 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
5823 "memory for the virtual screen in order to optimize scrolling performance. If\n" 7005 "memory for the virtual screen in order to optimize scrolling performance. If\n"
5824 "this is set to anything other than 0, sisfb will not do this and thereby \n" 7006 "this is set to anything other than 0, sisfb will not do this and thereby \n"
5825 "enable the user to positively specify a virtual Y size of the screen using\n" 7007 "enable the user to positively specify a virtual Y size of the screen using\n"
@@ -5827,30 +7009,30 @@ MODULE_PARM_DESC(nomax,
5827 7009
5828#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 7010#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5829MODULE_PARM_DESC(mode, 7011MODULE_PARM_DESC(mode,
5830 "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n" 7012 "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
5831 "1024x768x16. Other formats supported include XxY-Depth and\n" 7013 "1024x768x16. Other formats supported include XxY-Depth and\n"
5832 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" 7014 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
5833 "number, it will be interpreted as a VESA mode number. (default: none if\n" 7015 "number, it will be interpreted as a VESA mode number. (default: none if\n"
5834 "sisfb is a module; this leaves the console untouched and the driver will\n" 7016 "sisfb is a module; this leaves the console untouched and the driver will\n"
5835 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n" 7017 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
5836 "is in the kernel)\n"); 7018 "is in the kernel)\n");
5837MODULE_PARM_DESC(vesa, 7019MODULE_PARM_DESC(vesa,
5838 "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n" 7020 "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
5839 "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n" 7021 "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
5840 "and the driver will only do the video memory management for eg. DRM/DRI;\n" 7022 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
5841 "0x0103 if sisfb is in the kernel)\n"); 7023 "0x0103 if sisfb is in the kernel)\n");
5842#endif 7024#endif
5843 7025
5844#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 7026#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
5845MODULE_PARM_DESC(mode, 7027MODULE_PARM_DESC(mode,
5846 "\nSelects the desired default display mode in the format XxYxDepth,\n" 7028 "\nSelects the desired default display mode in the format XxYxDepth,\n"
5847 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" 7029 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
5848 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" 7030 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
5849 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n"); 7031 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
5850 7032
5851MODULE_PARM_DESC(vesa, 7033MODULE_PARM_DESC(vesa,
5852 "\nSelects the desired default display mode by VESA defined mode number, eg.\n" 7034 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
5853 "0x117 (default: 0x0103)\n"); 7035 "0x117 (default: 0x0103)\n");
5854#endif 7036#endif
5855 7037
5856MODULE_PARM_DESC(rate, 7038MODULE_PARM_DESC(rate,
@@ -5880,16 +7062,16 @@ MODULE_PARM_DESC(scalelcd,
5880 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n"); 7062 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
5881 7063
5882MODULE_PARM_DESC(pdc, 7064MODULE_PARM_DESC(pdc,
5883 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n" 7065 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
5884 "should detect this correctly in most cases; however, sometimes this is not\n" 7066 "should detect this correctly in most cases; however, sometimes this is not\n"
5885 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n" 7067 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
5886 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n" 7068 "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n"
5887 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n" 7069 "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n"
5888 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n"); 7070 "value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
5889 7071
5890#ifdef CONFIG_FB_SIS_315 7072#ifdef CONFIG_FB_SIS_315
5891MODULE_PARM_DESC(pdc1, 7073MODULE_PARM_DESC(pdc1,
5892 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n" 7074 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n"
5893 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n" 7075 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
5894 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n" 7076 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
5895 "implemented yet.\n"); 7077 "implemented yet.\n");
@@ -5913,17 +7095,13 @@ MODULE_PARM_DESC(tvyposoffset,
5913 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n" 7095 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
5914 "Default: 0\n"); 7096 "Default: 0\n");
5915 7097
5916MODULE_PARM_DESC(filter,
5917 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
5918 "(Possible values 0-7, default: [no filter])\n");
5919
5920MODULE_PARM_DESC(nocrt2rate, 7098MODULE_PARM_DESC(nocrt2rate,
5921 "\nSetting this to 1 will force the driver to use the default refresh rate for\n" 7099 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
5922 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); 7100 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
5923 7101
5924#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 7102#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5925MODULE_PARM_DESC(inverse, 7103MODULE_PARM_DESC(inverse,
5926 "\nSetting this to anything but 0 should invert the display colors, but this\n" 7104 "\nSetting this to anything but 0 should invert the display colors, but this\n"
5927 "does not seem to work. (default: 0)\n"); 7105 "does not seem to work. (default: 0)\n");
5928#endif 7106#endif
5929 7107
@@ -5931,98 +7109,23 @@ MODULE_PARM_DESC(inverse,
5931#ifdef CONFIG_FB_SIS_300 7109#ifdef CONFIG_FB_SIS_300
5932MODULE_PARM_DESC(resetcard, 7110MODULE_PARM_DESC(resetcard,
5933 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n" 7111 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
5934 "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n" 7112 "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n"
5935 "Default: 0\n"); 7113 "currently). Default: 0\n");
5936 7114
5937MODULE_PARM_DESC(videoram, 7115MODULE_PARM_DESC(videoram,
5938 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n" 7116 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
5939 "some non-x86 architectures where the memory auto detection fails. Only\n" 7117 "some non-x86 architectures where the memory auto detection fails. Only\n"
5940 "relevant if resetcard is set, too. Default: [auto-detect]\n"); 7118 "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n");
5941#endif
5942#endif 7119#endif
5943
5944static int __devinit sisfb_init_module(void)
5945{
5946 sisfb_setdefaultparms();
5947
5948 if(rate) sisfb_parm_rate = rate;
5949
5950 if((scalelcd == 0) || (scalelcd == 1)) {
5951 sisfb_scalelcd = scalelcd ^ 1;
5952 }
5953
5954 /* Need to check crt2 type first for fstn/dstn */
5955
5956 if(forcecrt2type)
5957 sisfb_search_crt2type(forcecrt2type);
5958
5959 if(tvstandard)
5960 sisfb_search_tvstd(tvstandard);
5961
5962 if(mode)
5963 sisfb_search_mode(mode, FALSE);
5964 else if(vesa != -1)
5965 sisfb_search_vesamode(vesa, FALSE);
5966
5967 sisfb_crt1off = (crt1off == 0) ? 1 : 0;
5968
5969 sisfb_forcecrt1 = forcecrt1;
5970 if(forcecrt1 == 1) sisfb_crt1off = 0;
5971 else if(forcecrt1 == 0) sisfb_crt1off = 1;
5972
5973 if(noaccel == 1) sisfb_accel = 0;
5974 else if(noaccel == 0) sisfb_accel = 1;
5975
5976 if(noypan == 1) sisfb_ypan = 0;
5977 else if(noypan == 0) sisfb_ypan = 1;
5978
5979 if(nomax == 1) sisfb_max = 0;
5980 else if(nomax == 0) sisfb_max = 1;
5981
5982#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5983 if(inverse) sisfb_inverse = 1;
5984#endif 7120#endif
5985 7121
5986 if(mem) sisfb_parm_mem = mem;
5987
5988 if(userom != -1) sisfb_userom = userom;
5989 if(useoem != -1) sisfb_useoem = useoem;
5990
5991 if(pdc != -1) sisfb_pdc = (pdc & 0x7f);
5992 if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
5993
5994 sisfb_nocrt2rate = nocrt2rate;
5995
5996 if(specialtiming)
5997 sisfb_search_specialtiming(specialtiming);
5998
5999 if((lvdshl >= 0) && (lvdshl <= 3)) sisfb_lvdshl = lvdshl;
6000
6001 if(filter != -1) sisfb_filter = filter;
6002
6003 sisfb_tvxposoffset = tvxposoffset;
6004 sisfb_tvyposoffset = tvyposoffset;
6005
6006#if !defined(__i386__) && !defined(__x86_64__)
6007 sisfb_resetcard = (resetcard) ? 1 : 0;
6008 if(videoram) sisfb_videoram = videoram;
6009#endif
6010
6011 return(sisfb_init());
6012}
6013
6014static void __exit sisfb_remove_module(void)
6015{
6016 pci_unregister_driver(&sisfb_driver);
6017 printk(KERN_DEBUG "sisfb: Module unloaded\n");
6018}
6019
6020module_init(sisfb_init_module);
6021module_exit(sisfb_remove_module);
6022
6023#endif /* /MODULE */ 7122#endif /* /MODULE */
6024 7123
7124/* _GPL only for new symbols. */
6025EXPORT_SYMBOL(sis_malloc); 7125EXPORT_SYMBOL(sis_malloc);
6026EXPORT_SYMBOL(sis_free); 7126EXPORT_SYMBOL(sis_free);
7127EXPORT_SYMBOL_GPL(sis_malloc_new);
7128EXPORT_SYMBOL_GPL(sis_free_new);
7129
6027 7130
6028 7131
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index a6678a7aff35..445bcbba03ae 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -1,9 +1,10 @@
1/* 1/*
2 * SiS 300/305/540/630(S)/730(S) 2 * SiS 300/305/540/630(S)/730(S),
3 * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760 3 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
4 * XGI V3XT/V5/V8, Z7
4 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3 5 * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
5 * 6 *
6 * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria. 7 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
7 * 8 *
8 * 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
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -23,13 +24,9 @@
23#ifndef _SISFB_MAIN 24#ifndef _SISFB_MAIN
24#define _SISFB_MAIN 25#define _SISFB_MAIN
25 26
26#include <linux/spinlock.h>
27
28#include "vstruct.h" 27#include "vstruct.h"
29#include "sis.h" 28#include "sis.h"
30 29
31#define MODE_INDEX_NONE 0 /* index for mode=none */
32
33/* Fbcon stuff */ 30/* Fbcon stuff */
34static struct fb_var_screeninfo my_default_var = { 31static struct fb_var_screeninfo my_default_var = {
35 .xres = 0, 32 .xres = 0,
@@ -60,6 +57,8 @@ static struct fb_var_screeninfo my_default_var = {
60 .vmode = FB_VMODE_NONINTERLACED, 57 .vmode = FB_VMODE_NONINTERLACED,
61}; 58};
62 59
60#define MODE_INDEX_NONE 0 /* index for mode=none */
61
63/* Boot-time parameters */ 62/* Boot-time parameters */
64static int sisfb_off = 0; 63static int sisfb_off = 0;
65static int sisfb_parm_mem = 0; 64static int sisfb_parm_mem = 0;
@@ -93,7 +92,6 @@ static int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
93static int sisfb_tvstd = -1; 92static int sisfb_tvstd = -1;
94static int sisfb_tvxposoffset = 0; 93static int sisfb_tvxposoffset = 0;
95static int sisfb_tvyposoffset = 0; 94static int sisfb_tvyposoffset = 0;
96static int sisfb_filter = -1;
97static int sisfb_nocrt2rate = 0; 95static int sisfb_nocrt2rate = 0;
98#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 96#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
99static int sisfb_inverse = 0; 97static int sisfb_inverse = 0;
@@ -106,12 +104,12 @@ static int sisfb_videoram = 0;
106 104
107/* List of supported chips */ 105/* List of supported chips */
108static struct sisfb_chip_info { 106static struct sisfb_chip_info {
109 int chip; 107 int chip;
110 int vgaengine; 108 int vgaengine;
111 int mni; 109 int mni;
112 int hwcursor_size; 110 int hwcursor_size;
113 int CRT2_write_enable; 111 int CRT2_write_enable;
114 const char *chip_name; 112 const char *chip_name;
115} sisfb_chip_info[] __devinitdata = { 113} sisfb_chip_info[] __devinitdata = {
116 { SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" }, 114 { SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
117 { SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" }, 115 { SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
@@ -123,6 +121,8 @@ static struct sisfb_chip_info {
123 { SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" }, 121 { SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
124 { SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" }, 122 { SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
125 { SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" }, 123 { SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
124 { XGI_20, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI Z7" },
125 { XGI_40, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI V3XT/V5/V8" },
126}; 126};
127 127
128static struct pci_device_id __devinitdata sisfb_pci_table[] = { 128static struct pci_device_id __devinitdata sisfb_pci_table[] = {
@@ -139,6 +139,8 @@ static struct pci_device_id __devinitdata sisfb_pci_table[] = {
139 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, 139 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
140 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, 140 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
141 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, 141 { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
142 { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0,10},
143 { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0,11},
142#endif 144#endif
143 { 0 } 145 { 0 }
144}; 146};
@@ -147,13 +149,12 @@ MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
147 149
148static struct sis_video_info *card_list = NULL; 150static struct sis_video_info *card_list = NULL;
149 151
150/* TODO: This is not handled card-wise because the DRM 152/* The memory heap is now handled card-wise, by using
151 does not refer to a unique fb when calling sis_alloc 153 sis_malloc_new/sis_free_new. However, the DRM does
152 or sis_free. Therefore, this is handled globally for 154 not do this yet. Until it does, we keep a "global"
153 now (hoping that nobody is crazy enough to run two 155 heap which is actually the first card's one.
154 SiS cards at the same time).
155 */ 156 */
156static SIS_HEAP sisfb_heap; 157static struct SIS_HEAP *sisfb_heap;
157 158
158#define MD_SIS300 1 159#define MD_SIS300 1
159#define MD_SIS315 2 160#define MD_SIS315 2
@@ -181,8 +182,10 @@ static const struct _sisbios_mode {
181 {"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315}, 182 {"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
182 {"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315}, 183 {"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
183 {"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315}, 184 {"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
184 {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* FSTN */ 185#define MODE_FSTN_8 9
185/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* FSTN */ 186#define MODE_FSTN_16 10
187 {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS315}, /* FSTN */
188/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS315}, /* FSTN */
186 {"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315}, 189 {"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
187 {"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315}, 190 {"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
188 {"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315}, 191 {"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
@@ -215,18 +218,20 @@ static const struct _sisbios_mode {
215/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315}, 218/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
216 {"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315}, 219 {"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
217 {"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315}, 220 {"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
218#define DEFAULT_MODE 43 /* index for 800x600x8 */ 221#define DEFAULT_MODE 43 /* index for 800x600x8 */
219#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */ 222#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
220#define DEFAULT_TVMODE 43 /* index for 800x600x8 */ 223#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
221 {"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315}, 224 {"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
222 {"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315}, 225 {"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
223 {"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315}, 226 {"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
224 {"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315}, 227 {"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
225 {"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315}, 228 {"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
229#define DEFAULT_MODE_848 48
226 {"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315}, 230 {"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
227 {"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315}, 231 {"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
228/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315}, 232/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
229 {"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315}, 233 {"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
234#define DEFAULT_MODE_856 52
230 {"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315}, 235 {"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
231 {"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315}, 236 {"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
232 {"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315}, 237 {"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
@@ -270,42 +275,47 @@ static const struct _sisbios_mode {
270 {"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315}, 275 {"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315},
271 {"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315}, 276 {"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
272 {"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315}, 277 {"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
278 {"1280x854x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 854, 8, 1, 160, 53, MD_SIS315},
279 {"1280x854x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 854, 16, 1, 160, 53, MD_SIS315},
280 {"1280x854x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
281 {"1280x854x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
273 {"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315}, 282 {"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
274 {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315}, 283/*100*/ {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
275 {"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315}, 284 {"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
276 {"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315}, 285 {"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
277 {"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315}, 286 {"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
278/*100*/ {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315}, 287 {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
279 {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315}, 288 {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
280 {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315}, 289 {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
281 {"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315}, 290 {"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
282 {"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315}, 291 {"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
283 {"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315}, 292 {"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
284 {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315}, 293/*110*/ {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
285 {"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 }, 294 {"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
295#define DEFAULT_MODE_1360 112
286 {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 }, 296 {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
287 {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 }, 297 {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
288/*110*/ {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 }, 298 {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
289 {"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315}, 299 {"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
290 {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315}, 300 {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
291 {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315}, 301 {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
292 {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315}, 302 {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
293 {"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315}, 303 {"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
294 {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315}, 304/*120*/ {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
295 {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315}, 305 {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
296 {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315}, 306 {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
297 {"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315}, 307 {"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315},
298/*120*/ {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315}, 308 {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
299 {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315}, 309 {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
300 {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315}, 310 {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
301 {"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315}, 311 {"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315},
302 {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315}, 312 {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315},
303 {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315}, 313 {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
304 {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315}, 314/*130*/ {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
305 {"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315}, 315 {"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
306 {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315}, 316 {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
307 {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315}, 317 {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
308/*130*/ {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315}, 318 {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
309 {"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315}, 319 {"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
310 {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315}, 320 {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
311 {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315}, 321 {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
@@ -313,13 +323,13 @@ static const struct _sisbios_mode {
313 {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0} 323 {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
314}; 324};
315 325
316#define SIS_LCD_NUMBER 17 326#define SIS_LCD_NUMBER 18
317static const struct _sis_lcd_data { 327static struct _sis_lcd_data {
318 u32 lcdtype; 328 u32 lcdtype;
319 u16 xres; 329 u16 xres;
320 u16 yres; 330 u16 yres;
321 u8 default_mode_idx; 331 u8 default_mode_idx;
322} sis_lcd_data[] = { 332} sis_lcd_data[] __devinitdata = {
323 { LCD_640x480, 640, 480, 23 }, 333 { LCD_640x480, 640, 480, 23 },
324 { LCD_800x600, 800, 600, 43 }, 334 { LCD_800x600, 800, 600, 43 },
325 { LCD_1024x600, 1024, 600, 67 }, 335 { LCD_1024x600, 1024, 600, 67 },
@@ -329,34 +339,38 @@ static const struct _sis_lcd_data {
329 { LCD_1280x720, 1280, 720, 83 }, 339 { LCD_1280x720, 1280, 720, 83 },
330 { LCD_1280x768, 1280, 768, 87 }, 340 { LCD_1280x768, 1280, 768, 87 },
331 { LCD_1280x800, 1280, 800, 91 }, 341 { LCD_1280x800, 1280, 800, 91 },
332 { LCD_1280x960, 1280, 960, 95 }, 342 { LCD_1280x854, 1280, 854, 95 },
333 { LCD_1280x1024, 1280, 1024, 99 }, 343 { LCD_1280x960, 1280, 960, 99 },
334 { LCD_1400x1050, 1400, 1050, 111 }, 344 { LCD_1280x1024, 1280, 1024, 103 },
335 { LCD_1680x1050, 1680, 1050, 119 }, 345 { LCD_1400x1050, 1400, 1050, 115 },
336 { LCD_1600x1200, 1600, 1200, 115 }, 346 { LCD_1680x1050, 1680, 1050, 123 },
337 { LCD_640x480_2, 640, 480, 23 }, 347 { LCD_1600x1200, 1600, 1200, 119 },
338 { LCD_640x480_3, 640, 480, 23 }, 348 { LCD_320x240_2, 320, 240, 9 },
339 { LCD_320x480, 320, 480, 9 }, 349 { LCD_320x240_3, 320, 240, 9 },
350 { LCD_320x240, 320, 240, 9 },
340}; 351};
341 352
342/* CR36 evaluation */ 353/* CR36 evaluation */
343static const USHORT sis300paneltype[] = 354static unsigned short sis300paneltype[] __devinitdata = {
344 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, 355 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
345 LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768, 356 LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
346 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, 357 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
347 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN }; 358 LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN
348 359};
349static const USHORT sis310paneltype[] = 360
350 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, 361static unsigned short sis310paneltype[] __devinitdata = {
351 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, 362 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
352 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200, 363 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
353 LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN, LCD_UNKNOWN }; 364 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
354 365 LCD_320x240_2, LCD_320x240_3, LCD_UNKNOWN, LCD_UNKNOWN
355static const USHORT sis661paneltype[] = 366};
356 { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, 367
357 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, 368static unsigned short sis661paneltype[] __devinitdata = {
358 LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200, 369 LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
359 LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN }; 370 LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
371 LCD_1280x854, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
372 LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN
373};
360 374
361#define FL_550_DSTN 0x01 375#define FL_550_DSTN 0x01
362#define FL_550_FSTN 0x02 376#define FL_550_FSTN 0x02
@@ -413,7 +427,6 @@ static const struct _sis_vrate {
413} sisfb_vrate[] = { 427} sisfb_vrate[] = {
414 {1, 320, 200, 70, TRUE}, 428 {1, 320, 200, 70, TRUE},
415 {1, 320, 240, 60, TRUE}, 429 {1, 320, 240, 60, TRUE},
416 {1, 320, 480, 60, TRUE},
417 {1, 400, 300, 60, TRUE}, 430 {1, 400, 300, 60, TRUE},
418 {1, 512, 384, 60, TRUE}, 431 {1, 512, 384, 60, TRUE},
419 {1, 640, 400, 72, TRUE}, 432 {1, 640, 400, 72, TRUE},
@@ -437,10 +450,11 @@ static const struct _sis_vrate {
437 {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE}, 450 {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
438 {7, 1024, 768, 120, TRUE}, 451 {7, 1024, 768, 120, TRUE},
439 {1, 1152, 768, 60, TRUE}, 452 {1, 1152, 768, 60, TRUE},
440 {1, 1152, 864, 60, TRUE}, {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE}, 453 {1, 1152, 864, 60, TRUE}, {2, 1152, 864, 75, TRUE}, {3, 1152, 864, 84, TRUE},
441 {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE}, 454 {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
442 {1, 1280, 768, 60, TRUE}, 455 {1, 1280, 768, 60, TRUE},
443 {1, 1280, 800, 60, TRUE}, 456 {1, 1280, 800, 60, TRUE},
457 {1, 1280, 854, 60, TRUE},
444 {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE}, 458 {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
445 {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE}, 459 {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
446 {4, 1280, 1024, 85, TRUE}, 460 {4, 1280, 1024, 85, TRUE},
@@ -459,12 +473,12 @@ static const struct _sis_vrate {
459 {0, 0, 0, 0, FALSE} 473 {0, 0, 0, 0, FALSE}
460}; 474};
461 475
462static const struct _sisfbddcsmodes { 476static struct _sisfbddcsmodes {
463 u32 mask; 477 u32 mask;
464 u16 h; 478 u16 h;
465 u16 v; 479 u16 v;
466 u32 d; 480 u32 d;
467} sisfb_ddcsmodes[] = { 481} sisfb_ddcsmodes[] __devinitdata = {
468 { 0x10000, 67, 75, 108000}, 482 { 0x10000, 67, 75, 108000},
469 { 0x08000, 48, 72, 50000}, 483 { 0x08000, 48, 72, 50000},
470 { 0x04000, 46, 75, 49500}, 484 { 0x04000, 46, 75, 49500},
@@ -480,49 +494,49 @@ static const struct _sisfbddcsmodes {
480 { 0x00001, 38, 60, 40000} 494 { 0x00001, 38, 60, 40000}
481}; 495};
482 496
483static const struct _sisfbddcfmodes { 497static struct _sisfbddcfmodes {
484 u16 x; 498 u16 x;
485 u16 y; 499 u16 y;
486 u16 v; 500 u16 v;
487 u16 h; 501 u16 h;
488 u32 d; 502 u32 d;
489} sisfb_ddcfmodes[] = { 503} sisfb_ddcfmodes[] __devinitdata = {
490 { 1280, 1024, 85, 92, 157500}, 504 { 1280, 1024, 85, 92, 157500},
491 { 1600, 1200, 60, 75, 162000}, 505 { 1600, 1200, 60, 75, 162000},
492 { 1600, 1200, 65, 82, 175500}, 506 { 1600, 1200, 65, 82, 175500},
493 { 1600, 1200, 70, 88, 189000}, 507 { 1600, 1200, 70, 88, 189000},
494 { 1600, 1200, 75, 94, 202500}, 508 { 1600, 1200, 75, 94, 202500},
495 { 1600, 1200, 85, 107,229500}, 509 { 1600, 1200, 85, 107,229500},
496 { 1920, 1440, 60, 90, 234000}, 510 { 1920, 1440, 60, 90, 234000},
497 { 1920, 1440, 75, 113,297000} 511 { 1920, 1440, 75, 113,297000}
498}; 512};
499 513
500#ifdef CONFIG_FB_SIS_300 514#ifdef CONFIG_FB_SIS_300
501static struct _chswtable { 515static struct _chswtable {
502 u16 subsysVendor; 516 u16 subsysVendor;
503 u16 subsysCard; 517 u16 subsysCard;
504 char *vendorName; 518 char *vendorName;
505 char *cardName; 519 char *cardName;
506} mychswtable[] __devinitdata = { 520} mychswtable[] __devinitdata = {
507 { 0x1631, 0x1002, "Mitachi", "0x1002" }, 521 { 0x1631, 0x1002, "Mitachi", "0x1002" },
508 { 0x1071, 0x7521, "Mitac" , "7521P" }, 522 { 0x1071, 0x7521, "Mitac" , "7521P" },
509 { 0, 0, "" , "" } 523 { 0, 0, "" , "" }
510}; 524};
511#endif 525#endif
512 526
513static struct _customttable { 527static struct _customttable {
514 u16 chipID; 528 u16 chipID;
515 char *biosversion; 529 char *biosversion;
516 char *biosdate; 530 char *biosdate;
517 u32 bioschksum; 531 u32 bioschksum;
518 u16 biosFootprintAddr[5]; 532 u16 biosFootprintAddr[5];
519 u8 biosFootprintData[5]; 533 u8 biosFootprintData[5];
520 u16 pcisubsysvendor; 534 u16 pcisubsysvendor;
521 u16 pcisubsyscard; 535 u16 pcisubsyscard;
522 char *vendorName; 536 char *vendorName;
523 char *cardName; 537 char *cardName;
524 u32 SpecialID; 538 u32 SpecialID;
525 char *optionName; 539 char *optionName;
526} mycustomttable[] __devinitdata = { 540} mycustomttable[] __devinitdata = {
527 { SIS_630, "2.00.07", "09/27/2002-13:38:25", 541 { SIS_630, "2.00.07", "09/27/2002-13:38:25",
528 0x3240A8, 542 0x3240A8,
@@ -643,6 +657,13 @@ static struct _customttable {
643 0, 0, 657 0, 0,
644 "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480" 658 "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
645 }, 659 },
660 { 4322, "", "", /* never autodetected */
661 0,
662 { 0, 0, 0, 0, 0 },
663 { 0, 0, 0, 0, 0 },
664 0, 0,
665 "Generic", "LVDS/Parallel 856x480", CUT_PANEL856, "PANEL856x480"
666 },
646 { 0, "", "", 667 { 0, "", "",
647 0, 668 0,
648 { 0, 0, 0, 0 }, 669 { 0, 0, 0, 0 },
@@ -652,155 +673,6 @@ static struct _customttable {
652 } 673 }
653}; 674};
654 675
655static const struct _sis_TV_filter {
656 u8 filter[9][4];
657} sis_TV_filter[] = {
658 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_0 */
659 {0x00,0xE0,0x10,0x60},
660 {0x00,0xEE,0x10,0x44},
661 {0x00,0xF4,0x10,0x38},
662 {0xF8,0xF4,0x18,0x38},
663 {0xFC,0xFB,0x14,0x2A},
664 {0x00,0x00,0x10,0x20},
665 {0x00,0x04,0x10,0x18},
666 {0xFF,0xFF,0xFF,0xFF} }},
667 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_1 */
668 {0x00,0xE0,0x10,0x60},
669 {0x00,0xEE,0x10,0x44},
670 {0x00,0xF4,0x10,0x38},
671 {0xF8,0xF4,0x18,0x38},
672 {0xFC,0xFB,0x14,0x2A},
673 {0x00,0x00,0x10,0x20},
674 {0x00,0x04,0x10,0x18},
675 {0xFF,0xFF,0xFF,0xFF} }},
676 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_2 */
677 {0xF5,0xEE,0x1B,0x44},
678 {0xF8,0xF4,0x18,0x38},
679 {0xEB,0x04,0x25,0x18},
680 {0xF1,0x05,0x1F,0x16},
681 {0xF6,0x06,0x1A,0x14},
682 {0xFA,0x06,0x16,0x14},
683 {0x00,0x04,0x10,0x18},
684 {0xFF,0xFF,0xFF,0xFF} }},
685 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_3 */
686 {0xF1,0x04,0x1F,0x18},
687 {0xEE,0x0D,0x22,0x06},
688 {0xF7,0x06,0x19,0x14},
689 {0xF4,0x0B,0x1C,0x0A},
690 {0xFA,0x07,0x16,0x12},
691 {0xF9,0x0A,0x17,0x0C},
692 {0x00,0x07,0x10,0x12},
693 {0xFF,0xFF,0xFF,0xFF} }},
694 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_4 - 320 */
695 {0x00,0xE0,0x10,0x60},
696 {0x00,0xEE,0x10,0x44},
697 {0x00,0xF4,0x10,0x38},
698 {0xF8,0xF4,0x18,0x38},
699 {0xFC,0xFB,0x14,0x2A},
700 {0x00,0x00,0x10,0x20},
701 {0x00,0x04,0x10,0x18},
702 {0xFF,0xFF,0xFF,0xFF} }},
703 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_5 - 640 */
704 {0xF5,0xEE,0x1B,0x44},
705 {0xF8,0xF4,0x18,0x38},
706 {0xEB,0x04,0x25,0x18},
707 {0xF1,0x05,0x1F,0x16},
708 {0xF6,0x06,0x1A,0x14},
709 {0xFA,0x06,0x16,0x14},
710 {0x00,0x04,0x10,0x18},
711 {0xFF,0xFF,0xFF,0xFF} }},
712 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_6 - 720 */
713 {0xEB,0x04,0x25,0x18},
714 {0xE7,0x0E,0x29,0x04},
715 {0xEE,0x0C,0x22,0x08},
716 {0xF6,0x0B,0x1A,0x0A},
717 {0xF9,0x0A,0x17,0x0C},
718 {0xFC,0x0A,0x14,0x0C},
719 {0x00,0x08,0x10,0x10},
720 {0xFF,0xFF,0xFF,0xFF} }},
721 { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_7 - 800 */
722 {0xEC,0x02,0x24,0x1C},
723 {0xF2,0x04,0x1E,0x18},
724 {0xEB,0x15,0x25,0xF6},
725 {0xF4,0x10,0x1C,0x00},
726 {0xF8,0x0F,0x18,0x02},
727 {0x00,0x04,0x10,0x18},
728 {0x01,0x06,0x0F,0x14},
729 {0xFF,0xFF,0xFF,0xFF} }},
730 { {{0x00,0x00,0x00,0x40}, /* PALFilter_0 */
731 {0x00,0xE0,0x10,0x60},
732 {0x00,0xEE,0x10,0x44},
733 {0x00,0xF4,0x10,0x38},
734 {0xF8,0xF4,0x18,0x38},
735 {0xFC,0xFB,0x14,0x2A},
736 {0x00,0x00,0x10,0x20},
737 {0x00,0x04,0x10,0x18},
738 {0xFF,0xFF,0xFF,0xFF} }},
739 { {{0x00,0x00,0x00,0x40}, /* PALFilter_1 */
740 {0x00,0xE0,0x10,0x60},
741 {0x00,0xEE,0x10,0x44},
742 {0x00,0xF4,0x10,0x38},
743 {0xF8,0xF4,0x18,0x38},
744 {0xFC,0xFB,0x14,0x2A},
745 {0x00,0x00,0x10,0x20},
746 {0x00,0x04,0x10,0x18},
747 {0xFF,0xFF,0xFF,0xFF} }},
748 { {{0x00,0x00,0x00,0x40}, /* PALFilter_2 */
749 {0xF5,0xEE,0x1B,0x44},
750 {0xF8,0xF4,0x18,0x38},
751 {0xF1,0xF7,0x01,0x32},
752 {0xF5,0xFB,0x1B,0x2A},
753 {0xF9,0xFF,0x17,0x22},
754 {0xFB,0x01,0x15,0x1E},
755 {0x00,0x04,0x10,0x18},
756 {0xFF,0xFF,0xFF,0xFF} }},
757 { {{0x00,0x00,0x00,0x40}, /* PALFilter_3 */
758 {0xF5,0xFB,0x1B,0x2A},
759 {0xEE,0xFE,0x22,0x24},
760 {0xF3,0x00,0x1D,0x20},
761 {0xF9,0x03,0x17,0x1A},
762 {0xFB,0x02,0x14,0x1E},
763 {0xFB,0x04,0x15,0x18},
764 {0x00,0x06,0x10,0x14},
765 {0xFF,0xFF,0xFF,0xFF} }},
766 { {{0x00,0x00,0x00,0x40}, /* PALFilter_4 - 320 */
767 {0x00,0xE0,0x10,0x60},
768 {0x00,0xEE,0x10,0x44},
769 {0x00,0xF4,0x10,0x38},
770 {0xF8,0xF4,0x18,0x38},
771 {0xFC,0xFB,0x14,0x2A},
772 {0x00,0x00,0x10,0x20},
773 {0x00,0x04,0x10,0x18},
774 {0xFF,0xFF,0xFF,0xFF} }},
775 { {{0x00,0x00,0x00,0x40}, /* PALFilter_5 - 640 */
776 {0xF5,0xEE,0x1B,0x44},
777 {0xF8,0xF4,0x18,0x38},
778 {0xF1,0xF7,0x1F,0x32},
779 {0xF5,0xFB,0x1B,0x2A},
780 {0xF9,0xFF,0x17,0x22},
781 {0xFB,0x01,0x15,0x1E},
782 {0x00,0x04,0x10,0x18},
783 {0xFF,0xFF,0xFF,0xFF} }},
784 { {{0x00,0x00,0x00,0x40}, /* PALFilter_6 - 720 */
785 {0xF5,0xEE,0x1B,0x2A},
786 {0xEE,0xFE,0x22,0x24},
787 {0xF3,0x00,0x1D,0x20},
788 {0xF9,0x03,0x17,0x1A},
789 {0xFB,0x02,0x14,0x1E},
790 {0xFB,0x04,0x15,0x18},
791 {0x00,0x06,0x10,0x14},
792 {0xFF,0xFF,0xFF,0xFF} }},
793 { {{0x00,0x00,0x00,0x40}, /* PALFilter_7 - 800 */
794 {0xF5,0xEE,0x1B,0x44},
795 {0xF8,0xF4,0x18,0x38},
796 {0xFC,0xFB,0x14,0x2A},
797 {0xEB,0x05,0x25,0x16},
798 {0xF1,0x05,0x1F,0x16},
799 {0xFA,0x07,0x16,0x12},
800 {0x00,0x07,0x10,0x12},
801 {0xFF,0xFF,0xFF,0xFF} }}
802};
803
804/* ---------------------- Prototypes ------------------------- */ 676/* ---------------------- Prototypes ------------------------- */
805 677
806/* Interface used by the world */ 678/* Interface used by the world */
@@ -811,145 +683,159 @@ SISINITSTATIC int sisfb_setup(char *options);
811/* Interface to the low level console driver */ 683/* Interface to the low level console driver */
812SISINITSTATIC int sisfb_init(void); 684SISINITSTATIC int sisfb_init(void);
813 685
814
815/* fbdev routines */ 686/* fbdev routines */
816static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, 687static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
817 struct fb_info *info); 688 struct fb_info *info);
818 689
819#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 690#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
820static int sisfb_get_fix(struct fb_fix_screeninfo *fix, 691static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
821 int con, 692 int con,
822 struct fb_info *info); 693 struct fb_info *info);
823static int sisfb_get_var(struct fb_var_screeninfo *var, 694static int sisfb_get_var(struct fb_var_screeninfo *var,
824 int con, 695 int con,
825 struct fb_info *info); 696 struct fb_info *info);
826static int sisfb_set_var(struct fb_var_screeninfo *var, 697static int sisfb_set_var(struct fb_var_screeninfo *var,
827 int con, 698 int con,
828 struct fb_info *info); 699 struct fb_info *info);
829static void sisfb_crtc_to_var(struct sis_video_info *ivideo, 700static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
830 struct fb_var_screeninfo *var); 701 struct fb_var_screeninfo *var);
831static int sisfb_get_cmap(struct fb_cmap *cmap, 702static int sisfb_get_cmap(struct fb_cmap *cmap,
832 int kspc, 703 int kspc,
833 int con, 704 int con,
834 struct fb_info *info); 705 struct fb_info *info);
835static int sisfb_set_cmap(struct fb_cmap *cmap, 706static int sisfb_set_cmap(struct fb_cmap *cmap,
836 int kspc, 707 int kspc,
837 int con, 708 int con,
838 struct fb_info *info); 709 struct fb_info *info);
839static int sisfb_update_var(int con, 710static int sisfb_update_var(int con,
840 struct fb_info *info); 711 struct fb_info *info);
841static int sisfb_switch(int con, 712static int sisfb_switch(int con,
842 struct fb_info *info); 713 struct fb_info *info);
843static void sisfb_blank(int blank, 714static void sisfb_blank(int blank,
844 struct fb_info *info); 715 struct fb_info *info);
845static void sisfb_set_disp(int con, 716static void sisfb_set_disp(int con,
846 struct fb_var_screeninfo *var, 717 struct fb_var_screeninfo *var,
847 struct fb_info *info); 718 struct fb_info *info);
848static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, 719static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
849 unsigned *blue, unsigned *transp, 720 unsigned *blue, unsigned *transp,
850 struct fb_info *fb_info); 721 struct fb_info *fb_info);
851static void sisfb_do_install_cmap(int con, 722static void sisfb_do_install_cmap(int con,
852 struct fb_info *info); 723 struct fb_info *info);
853static int sisfb_ioctl(struct inode *inode, struct file *file, 724static int sisfb_ioctl(struct inode *inode, struct file *file,
854 unsigned int cmd, unsigned long arg, int con, 725 unsigned int cmd, unsigned long arg, int con,
855 struct fb_info *info); 726 struct fb_info *info);
856#endif 727#endif
857 728
858#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 729#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
859static int sisfb_ioctl(struct inode *inode, struct file *file, 730static int sisfb_ioctl(struct inode *inode, struct file *file,
860 unsigned int cmd, unsigned long arg, 731 unsigned int cmd, unsigned long arg,
861 struct fb_info *info); 732 struct fb_info *info);
862static int sisfb_set_par(struct fb_info *info); 733static int sisfb_set_par(struct fb_info *info);
863static int sisfb_blank(int blank, 734static int sisfb_blank(int blank,
864 struct fb_info *info); 735 struct fb_info *info);
865extern void fbcon_sis_fillrect(struct fb_info *info, 736extern void fbcon_sis_fillrect(struct fb_info *info,
866 const struct fb_fillrect *rect); 737 const struct fb_fillrect *rect);
867extern void fbcon_sis_copyarea(struct fb_info *info, 738extern void fbcon_sis_copyarea(struct fb_info *info,
868 const struct fb_copyarea *area); 739 const struct fb_copyarea *area);
869extern int fbcon_sis_sync(struct fb_info *info); 740extern int fbcon_sis_sync(struct fb_info *info);
870#endif 741#endif
871 742
872/* Internal 2D accelerator functions */ 743/* Internal 2D accelerator functions */
873extern int sisfb_initaccel(struct sis_video_info *ivideo); 744extern int sisfb_initaccel(struct sis_video_info *ivideo);
874extern void sisfb_syncaccel(struct sis_video_info *ivideo); 745extern void sisfb_syncaccel(struct sis_video_info *ivideo);
875 746
876/* Internal general routines */ 747/* Internal general routines */
877static void sisfb_search_mode(char *name, BOOLEAN quiet); 748static void sisfb_search_mode(char *name, BOOLEAN quiet);
878static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags); 749static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
879static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, 750static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
880 int index); 751 int index);
881static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, 752static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
882 unsigned blue, unsigned transp, 753 unsigned blue, unsigned transp,
883 struct fb_info *fb_info); 754 struct fb_info *fb_info);
884static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, 755static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
885 struct fb_info *info); 756 struct fb_info *info);
886static void sisfb_pre_setmode(struct sis_video_info *ivideo); 757static void sisfb_pre_setmode(struct sis_video_info *ivideo);
887static void sisfb_post_setmode(struct sis_video_info *ivideo); 758static void sisfb_post_setmode(struct sis_video_info *ivideo);
888static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo); 759static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
889static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo); 760static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
890static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo); 761static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
891static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo); 762static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
892static void sisfb_detect_VB_connect(struct sis_video_info *ivideo); 763static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
893static void sisfb_get_VB_type(struct sis_video_info *ivideo); 764static void sisfb_get_VB_type(struct sis_video_info *ivideo);
894static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val); 765static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
895static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val); 766static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
767#ifdef CONFIG_FB_SIS_300
768unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
769void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val);
770unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
771#endif
772#ifdef CONFIG_FB_SIS_315
773void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val);
774unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
775#endif
896 776
897/* SiS-specific exported functions */ 777/* SiS-specific exported functions */
898void sis_malloc(struct sis_memreq *req); 778void sis_malloc(struct sis_memreq *req);
899void sis_free(u32 base); 779void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
780void sis_free(u32 base);
781void sis_free_new(struct pci_dev *pdev, u32 base);
900 782
901/* Internal heap routines */ 783/* Internal heap routines */
902static int sisfb_heap_init(struct sis_video_info *ivideo); 784static int sisfb_heap_init(struct sis_video_info *ivideo);
903static SIS_OH *sisfb_poh_new_node(void); 785static struct SIS_OH * sisfb_poh_new_node(struct SIS_HEAP *memheap);
904static SIS_OH *sisfb_poh_allocate(u32 size); 786static struct SIS_OH * sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size);
905static void sisfb_delete_node(SIS_OH *poh); 787static void sisfb_delete_node(struct SIS_OH *poh);
906static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh); 788static void sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh);
907static SIS_OH *sisfb_poh_free(u32 base); 789static struct SIS_OH * sisfb_poh_free(struct SIS_HEAP *memheap, u32 base);
908static void sisfb_free_node(SIS_OH *poh); 790static void sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh);
909
910/* Sensing routines */
911static void SiS_Sense30x(struct sis_video_info *ivideo);
912static void SiS_SenseCh(struct sis_video_info *ivideo);
913 791
914/* Routines from init.c/init301.c */ 792/* Routines from init.c/init301.c */
915extern USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, 793extern unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
916 BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight); 794 int VDisplay, int Depth, BOOLEAN FSTN, unsigned short CustomT,
917extern USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth); 795 int LCDwith, int LCDheight, unsigned int VBFlags2);
918extern USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth); 796extern unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
919 797 int VDisplay, int Depth, unsigned int VBFlags2);
920extern void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); 798extern unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
921extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHORT ModeNo); 799 int VDisplay, int Depth, unsigned int VBFlags2);
922extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); 800extern void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
923extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); 801extern BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
924 802extern void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
925extern BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); 803extern void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
926 804
927extern BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension, 805extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
928 unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex); 806
807extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
808 int *htotal, int *vtotal, unsigned char rateindex);
929#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) 809#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
930extern int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, 810extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
931 PSIS_HW_INFO HwDeviceExtension, 811 unsigned char modeno, unsigned char rateindex);
932 unsigned char modeno, unsigned char rateindex); 812extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
933extern int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension, 813 unsigned char rateindex, struct fb_var_screeninfo *var);
934 unsigned char modeno, unsigned char rateindex, 814#endif
935 struct fb_var_screeninfo *var); 815#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
816extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
817 int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
936#endif 818#endif
937 819
938/* Chrontel TV, DDC and DPMS functions */ 820/* Chrontel TV, DDC and DPMS functions */
939extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx); 821extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
940extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx); 822extern void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
941extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx); 823extern unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg);
942extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx); 824extern void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
943extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); 825extern void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
944extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime); 826 unsigned char myor, unsigned char myand);
945extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo); 827extern void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
946extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine, 828extern void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
947 USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer); 829extern unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
948extern USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr); 830 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
949extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo); 831 unsigned int VBFlags2);
950extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr); 832extern unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
951extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo); 833#ifdef CONFIG_FB_SIS_315
952extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo); 834extern void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
835extern void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
836#endif
837extern void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
838extern void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
953#endif 839#endif
954 840
955 841
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 507bba1a71b5..831b9f42264b 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * General type definitions for universal mode switching modules 4 * General type definitions for universal mode switching modules
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,11 +50,10 @@
50 * 50 *
51 */ 51 */
52 52
53#ifndef _VGATYPES_ 53#ifndef _VGATYPES_H_
54#define _VGATYPES_ 54#define _VGATYPES_H_
55 55
56#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */ 56#ifdef SIS_LINUX_KERNEL
57#include <linux/ioctl.h>
58#include <linux/version.h> 57#include <linux/version.h>
59#endif 58#endif
60 59
@@ -66,41 +65,13 @@
66#define TRUE 1 65#define TRUE 1
67#endif 66#endif
68 67
69#ifndef NULL
70#define NULL 0
71#endif
72
73#ifndef CHAR
74typedef char CHAR;
75#endif
76
77#ifndef SHORT
78typedef short SHORT;
79#endif
80
81#ifndef LONG
82typedef long LONG;
83#endif
84
85#ifndef UCHAR
86typedef unsigned char UCHAR;
87#endif
88
89#ifndef USHORT
90typedef unsigned short USHORT;
91#endif
92
93#ifndef ULONG
94typedef unsigned long ULONG;
95#endif
96
97#ifndef BOOLEAN 68#ifndef BOOLEAN
98typedef unsigned char BOOLEAN; 69typedef unsigned int BOOLEAN;
99#endif 70#endif
100 71
101#define SISIOMEMTYPE 72#define SISIOMEMTYPE
102 73
103#ifdef LINUX_KERNEL 74#ifdef SIS_LINUX_KERNEL
104typedef unsigned long SISIOADDRESS; 75typedef unsigned long SISIOADDRESS;
105#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) 76#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
106#include <linux/types.h> /* Need __iomem */ 77#include <linux/types.h> /* Need __iomem */
@@ -109,7 +80,7 @@ typedef unsigned long SISIOADDRESS;
109#endif 80#endif
110#endif 81#endif
111 82
112#ifdef LINUX_XF86 83#ifdef SIS_XORG_XF86
113#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) 84#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
114typedef unsigned long IOADDRESS; 85typedef unsigned long IOADDRESS;
115typedef unsigned long SISIOADDRESS; 86typedef unsigned long SISIOADDRESS;
@@ -118,7 +89,7 @@ typedef IOADDRESS SISIOADDRESS;
118#endif 89#endif
119#endif 90#endif
120 91
121enum _SIS_CHIP_TYPE { 92typedef enum _SIS_CHIP_TYPE {
122 SIS_VGALegacy = 0, 93 SIS_VGALegacy = 0,
123 SIS_530, 94 SIS_530,
124 SIS_OLD, 95 SIS_OLD,
@@ -128,115 +99,27 @@ enum _SIS_CHIP_TYPE {
128 SIS_540, 99 SIS_540,
129 SIS_315H, /* SiS 310 */ 100 SIS_315H, /* SiS 310 */
130 SIS_315, 101 SIS_315,
131 SIS_315PRO, 102 SIS_315PRO, /* SiS 325 */
132 SIS_550, 103 SIS_550,
133 SIS_650, 104 SIS_650,
134 SIS_740, 105 SIS_740,
135 SIS_330, 106 SIS_330,
136 SIS_661, 107 SIS_661,
137 SIS_741, 108 SIS_741,
138 SIS_660, 109 SIS_670,
110 SIS_660 = 35,
139 SIS_760, 111 SIS_760,
140 SIS_761, 112 SIS_761,
141 SIS_340, 113 SIS_762,
114 SIS_770,
115 SIS_340 = 55,
116 SIS_341,
117 SIS_342,
118 XGI_20 = 75,
119 XGI_40,
142 MAX_SIS_CHIP 120 MAX_SIS_CHIP
143}; 121} SIS_CHIP_TYPE;
144
145#ifndef SIS_HW_INFO
146typedef struct _SIS_HW_INFO SIS_HW_INFO, *PSIS_HW_INFO;
147
148struct _SIS_HW_INFO
149{
150#ifdef LINUX_XF86
151 PCITAG PciTag; /* PCI Tag */
152#endif
153
154 UCHAR *pjVirtualRomBase; /* ROM image */
155
156 BOOLEAN UseROM; /* Use the ROM image if provided */
157
158#ifdef LINUX_KERNEL
159 UCHAR SISIOMEMTYPE *pjVideoMemoryAddress;
160 /* base virtual memory address */
161 /* of Linear VGA memory */
162
163 ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
164#endif
165
166 SISIOADDRESS ulIOAddress; /* base I/O address of VGA ports (0x3B0; relocated) */
167
168 UCHAR jChipType; /* Used to Identify SiS Graphics Chip */
169 /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
170 122
171 UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */
172
173 BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
174};
175#endif
176
177/* Addtional IOCTLs for communication sisfb <> X driver */
178/* If changing this, sisfb.h must also be changed (for sisfb) */
179
180#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
181
182/* ioctl for identifying and giving some info (esp. memory heap start) */
183#define SISFB_GET_INFO_SIZE 0x8004f300
184#define SISFB_GET_INFO 0x8000f301 /* Must be patched with result from ..._SIZE at D[29:16] */
185/* deprecated ioctl number (for older versions of sisfb) */
186#define SISFB_GET_INFO_OLD 0x80046ef8
187
188/* ioctls for tv parameters (position) */
189#define SISFB_SET_TVPOSOFFSET 0x4004f304
190
191/* lock sisfb from register access */
192#define SISFB_SET_LOCK 0x4004f306
193
194/* Structure argument for SISFB_GET_INFO ioctl */
195typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
196
197struct _SISFB_INFO {
198 CARD32 sisfb_id; /* for identifying sisfb */
199#ifndef SISFB_ID
200#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
201#endif
202 CARD32 chip_id; /* PCI ID of detected chip */
203 CARD32 memory; /* video memory in KB which sisfb manages */
204 CARD32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
205 CARD8 fbvidmode; /* current sisfb mode */
206
207 CARD8 sisfb_version;
208 CARD8 sisfb_revision;
209 CARD8 sisfb_patchlevel;
210
211 CARD8 sisfb_caps; /* sisfb's capabilities */
212
213 CARD32 sisfb_tqlen; /* turbo queue length (in KB) */
214
215 CARD32 sisfb_pcibus; /* The card's PCI ID */
216 CARD32 sisfb_pcislot;
217 CARD32 sisfb_pcifunc;
218
219 CARD8 sisfb_lcdpdc;
220
221 CARD8 sisfb_lcda;
222
223 CARD32 sisfb_vbflags;
224 CARD32 sisfb_currentvbflags;
225
226 CARD32 sisfb_scalelcd;
227 CARD32 sisfb_specialtiming;
228
229 CARD8 sisfb_haveemi;
230 CARD8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
231 CARD8 sisfb_haveemilcd;
232
233 CARD8 sisfb_lcdpdca;
234
235 CARD16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
236
237 CARD8 reserved[208]; /* for future use */
238};
239#endif
240 123
241#endif 124#endif
242 125
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index d4d55c98bce6..9ae32923c142 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -3,7 +3,7 @@
3/* 3/*
4 * General structure definitions for universal mode switching modules 4 * General structure definitions for universal mode switching modules
5 * 5 *
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * 7 *
8 * If distributed as part of the Linux kernel, the following license terms 8 * If distributed as part of the Linux kernel, the following license terms
9 * apply: 9 * apply:
@@ -50,627 +50,514 @@
50 * 50 *
51 */ 51 */
52 52
53#ifndef _VSTRUCT_ 53#ifndef _VSTRUCT_H_
54#define _VSTRUCT_ 54#define _VSTRUCT_H_
55 55
56typedef struct _SiS_PanelDelayTblStruct 56struct SiS_PanelDelayTbl {
57{ 57 unsigned char timer[2];
58 UCHAR timer[2]; 58};
59} SiS_PanelDelayTblStruct; 59
60 60struct SiS_LCDData {
61typedef struct _SiS_LCDDataStruct 61 unsigned short RVBHCMAX;
62{ 62 unsigned short RVBHCFACT;
63 USHORT RVBHCMAX; 63 unsigned short VGAHT;
64 USHORT RVBHCFACT; 64 unsigned short VGAVT;
65 USHORT VGAHT; 65 unsigned short LCDHT;
66 USHORT VGAVT; 66 unsigned short LCDVT;
67 USHORT LCDHT; 67};
68 USHORT LCDVT; 68
69} SiS_LCDDataStruct; 69struct SiS_TVData {
70 70 unsigned short RVBHCMAX;
71typedef struct _SiS_TVDataStruct 71 unsigned short RVBHCFACT;
72{ 72 unsigned short VGAHT;
73 USHORT RVBHCMAX; 73 unsigned short VGAVT;
74 USHORT RVBHCFACT; 74 unsigned short TVHDE;
75 USHORT VGAHT; 75 unsigned short TVVDE;
76 USHORT VGAVT; 76 unsigned short RVBHRS;
77 USHORT TVHDE; 77 unsigned char FlickerMode;
78 USHORT TVVDE; 78 unsigned short HALFRVBHRS;
79 USHORT RVBHRS; 79 unsigned short RVBHRS2;
80 UCHAR FlickerMode; 80 unsigned char RY1COE;
81 USHORT HALFRVBHRS; 81 unsigned char RY2COE;
82 UCHAR RY1COE; 82 unsigned char RY3COE;
83 UCHAR RY2COE; 83 unsigned char RY4COE;
84 UCHAR RY3COE; 84};
85 UCHAR RY4COE; 85
86} SiS_TVDataStruct; 86struct SiS_LVDSData {
87 87 unsigned short VGAHT;
88typedef struct _SiS_LVDSDataStruct 88 unsigned short VGAVT;
89{ 89 unsigned short LCDHT;
90 USHORT VGAHT; 90 unsigned short LCDVT;
91 USHORT VGAVT; 91};
92 USHORT LCDHT; 92
93 USHORT LCDVT; 93struct SiS_LVDSDes {
94} SiS_LVDSDataStruct; 94 unsigned short LCDHDES;
95 95 unsigned short LCDVDES;
96typedef struct _SiS_LVDSDesStruct 96};
97{ 97
98 USHORT LCDHDES; 98struct SiS_LVDSCRT1Data {
99 USHORT LCDVDES; 99 unsigned char CR[15];
100} SiS_LVDSDesStruct; 100};
101 101
102typedef struct _SiS_LVDSCRT1DataStruct 102struct SiS_CHTVRegData {
103{ 103 unsigned char Reg[16];
104 UCHAR CR[15]; 104};
105} SiS_LVDSCRT1DataStruct; 105
106 106struct SiS_St {
107typedef struct _SiS_LCDACRT1DataStruct 107 unsigned char St_ModeID;
108{ 108 unsigned short St_ModeFlag;
109 UCHAR CR[17]; 109 unsigned char St_StTableIndex;
110} SiS_LCDACRT1DataStruct; 110 unsigned char St_CRT2CRTC;
111 111 unsigned char St_ResInfo;
112typedef struct _SiS_CHTVRegDataStruct 112 unsigned char VB_StTVFlickerIndex;
113{ 113 unsigned char VB_StTVEdgeIndex;
114 UCHAR Reg[16]; 114 unsigned char VB_StTVYFilterIndex;
115} SiS_CHTVRegDataStruct; 115 unsigned char St_PDC;
116 116};
117typedef struct _SiS_StStruct 117
118{ 118struct SiS_VBMode {
119 UCHAR St_ModeID; 119 unsigned char ModeID;
120 USHORT St_ModeFlag; 120 unsigned char VB_TVDelayIndex;
121 UCHAR St_StTableIndex; 121 unsigned char VB_TVFlickerIndex;
122 UCHAR St_CRT2CRTC; 122 unsigned char VB_TVPhaseIndex;
123 UCHAR St_ResInfo; 123 unsigned char VB_TVYFilterIndex;
124 UCHAR VB_StTVFlickerIndex; 124 unsigned char VB_LCDDelayIndex;
125 UCHAR VB_StTVEdgeIndex; 125 unsigned char _VB_LCDHIndex;
126 UCHAR VB_StTVYFilterIndex; 126 unsigned char _VB_LCDVIndex;
127 UCHAR St_PDC; 127};
128} SiS_StStruct; 128
129 129struct SiS_StandTable_S {
130typedef struct _SiS_VBModeStruct 130 unsigned char CRT_COLS;
131{ 131 unsigned char ROWS;
132 UCHAR ModeID; 132 unsigned char CHAR_HEIGHT;
133 UCHAR VB_TVDelayIndex; 133 unsigned short CRT_LEN;
134 UCHAR VB_TVFlickerIndex; 134 unsigned char SR[4];
135 UCHAR VB_TVPhaseIndex; 135 unsigned char MISC;
136 UCHAR VB_TVYFilterIndex; 136 unsigned char CRTC[0x19];
137 UCHAR VB_LCDDelayIndex; 137 unsigned char ATTR[0x14];
138 UCHAR _VB_LCDHIndex; 138 unsigned char GRC[9];
139 UCHAR _VB_LCDVIndex; 139};
140} SiS_VBModeStruct; 140
141 141struct SiS_Ext {
142typedef struct _SiS_StandTableStruct 142 unsigned char Ext_ModeID;
143{ 143 unsigned short Ext_ModeFlag;
144 UCHAR CRT_COLS; 144 unsigned short Ext_VESAID;
145 UCHAR ROWS; 145 unsigned char Ext_RESINFO;
146 UCHAR CHAR_HEIGHT; 146 unsigned char VB_ExtTVFlickerIndex;
147 USHORT CRT_LEN; 147 unsigned char VB_ExtTVEdgeIndex;
148 UCHAR SR[4]; 148 unsigned char VB_ExtTVYFilterIndex;
149 UCHAR MISC; 149 unsigned char VB_ExtTVYFilterIndexROM661;
150 UCHAR CRTC[0x19]; 150 unsigned char REFindex;
151 UCHAR ATTR[0x14]; 151 char ROMMODEIDX661;
152 UCHAR GRC[9]; 152};
153} SiS_StandTableStruct; 153
154 154struct SiS_Ext2 {
155typedef struct _SiS_ExtStruct 155 unsigned short Ext_InfoFlag;
156{ 156 unsigned char Ext_CRT1CRTC;
157 UCHAR Ext_ModeID; 157 unsigned char Ext_CRTVCLK;
158 USHORT Ext_ModeFlag; 158 unsigned char Ext_CRT2CRTC;
159 USHORT Ext_VESAID; 159 unsigned char Ext_CRT2CRTC_NS;
160 UCHAR Ext_RESINFO; 160 unsigned char ModeID;
161 UCHAR VB_ExtTVFlickerIndex; 161 unsigned short XRes;
162 UCHAR VB_ExtTVEdgeIndex; 162 unsigned short YRes;
163 UCHAR VB_ExtTVYFilterIndex; 163 unsigned char Ext_PDC;
164 UCHAR VB_ExtTVYFilterIndexROM661; 164 unsigned char Ext_FakeCRT2CRTC;
165 UCHAR REFindex; 165 unsigned char Ext_FakeCRT2Clk;
166 CHAR ROMMODEIDX661; 166 unsigned char Ext_CRT1CRTC_NORM;
167} SiS_ExtStruct; 167 unsigned char Ext_CRTVCLK_NORM;
168 168 unsigned char Ext_CRT1CRTC_WIDE;
169typedef struct _SiS_Ext2Struct 169 unsigned char Ext_CRTVCLK_WIDE;
170{ 170};
171 USHORT Ext_InfoFlag; 171
172 UCHAR Ext_CRT1CRTC; 172struct SiS_Part2PortTbl {
173 UCHAR Ext_CRTVCLK; 173 unsigned char CR[12];
174 UCHAR Ext_CRT2CRTC; 174};
175 UCHAR Ext_CRT2CRTC_NS; 175
176 UCHAR ModeID; 176struct SiS_CRT1Table {
177 USHORT XRes; 177 unsigned char CR[17];
178 USHORT YRes; 178};
179 UCHAR Ext_PDC; 179
180} SiS_Ext2Struct; 180struct SiS_MCLKData {
181 181 unsigned char SR28,SR29,SR2A;
182typedef struct _SiS_Part2PortTblStruct 182 unsigned short CLOCK;
183{ 183};
184 UCHAR CR[12]; 184
185} SiS_Part2PortTblStruct; 185struct SiS_VCLKData {
186 186 unsigned char SR2B,SR2C;
187typedef struct _SiS_CRT1TableStruct 187 unsigned short CLOCK;
188{ 188};
189 UCHAR CR[17]; 189
190} SiS_CRT1TableStruct; 190struct SiS_VBVCLKData {
191 191 unsigned char Part4_A,Part4_B;
192typedef struct _SiS_MCLKDataStruct 192 unsigned short CLOCK;
193{ 193};
194 UCHAR SR28,SR29,SR2A; 194
195 USHORT CLOCK; 195struct SiS_StResInfo_S {
196} SiS_MCLKDataStruct; 196 unsigned short HTotal;
197 197 unsigned short VTotal;
198typedef struct _SiS_VCLKDataStruct 198};
199{ 199
200 UCHAR SR2B,SR2C; 200struct SiS_ModeResInfo_S {
201 USHORT CLOCK; 201 unsigned short HTotal;
202} SiS_VCLKDataStruct; 202 unsigned short VTotal;
203 203 unsigned char XChar;
204typedef struct _SiS_VBVCLKDataStruct 204 unsigned char YChar;
205{ 205};
206 UCHAR Part4_A,Part4_B;
207 USHORT CLOCK;
208} SiS_VBVCLKDataStruct;
209
210typedef struct _SiS_StResInfoStruct
211{
212 USHORT HTotal;
213 USHORT VTotal;
214} SiS_StResInfoStruct;
215
216typedef struct _SiS_ModeResInfoStruct
217{
218 USHORT HTotal;
219 USHORT VTotal;
220 UCHAR XChar;
221 UCHAR YChar;
222} SiS_ModeResInfoStruct;
223
224
225
226typedef UCHAR DRAM4Type[4];
227 206
228/* Defines for SiS_CustomT */ 207/* Defines for SiS_CustomT */
229/* Never change these for sisfb compatibility */ 208/* Never change these for sisfb compatibility */
230#define CUT_NONE 0 209#define CUT_NONE 0
231#define CUT_FORCENONE 1 210#define CUT_FORCENONE 1
232#define CUT_BARCO1366 2 211#define CUT_BARCO1366 2
233#define CUT_BARCO1024 3 212#define CUT_BARCO1024 3
234#define CUT_COMPAQ1280 4 213#define CUT_COMPAQ1280 4
235#define CUT_COMPAQ12802 5 214#define CUT_COMPAQ12802 5
236#define CUT_PANEL848 6 215#define CUT_PANEL848 6
237#define CUT_CLEVO1024 7 216#define CUT_CLEVO1024 7
238#define CUT_CLEVO10242 8 217#define CUT_CLEVO10242 8
239#define CUT_CLEVO1400 9 218#define CUT_CLEVO1400 9
240#define CUT_CLEVO14002 10 219#define CUT_CLEVO14002 10
241#define CUT_UNIWILL1024 11 220#define CUT_UNIWILL1024 11
242#define CUT_ASUSL3000D 12 221#define CUT_ASUSL3000D 12
243#define CUT_UNIWILL10242 13 222#define CUT_UNIWILL10242 13
244#define CUT_ACER1280 14 223#define CUT_ACER1280 14
245#define CUT_COMPAL1400_1 15 224#define CUT_COMPAL1400_1 15
246#define CUT_COMPAL1400_2 16 225#define CUT_COMPAL1400_2 16
247#define CUT_ASUSA2H_1 17 226#define CUT_ASUSA2H_1 17
248#define CUT_ASUSA2H_2 18 227#define CUT_ASUSA2H_2 18
249 228#define CUT_UNKNOWNLCD 19
250typedef struct _SiS_Private 229#define CUT_AOP8060 20
230#define CUT_PANEL856 21
231
232struct SiS_Private
251{ 233{
252#ifdef LINUX_KERNEL 234 unsigned char ChipType;
253 SISIOADDRESS RelIO; 235 unsigned char ChipRevision;
236#ifdef SIS_XORG_XF86
237 PCITAG PciTag;
254#endif 238#endif
255 SISIOADDRESS SiS_P3c4; 239#ifdef SIS_LINUX_KERNEL
256 SISIOADDRESS SiS_P3d4; 240 void *ivideo;
257 SISIOADDRESS SiS_P3c0;
258 SISIOADDRESS SiS_P3ce;
259 SISIOADDRESS SiS_P3c2;
260 SISIOADDRESS SiS_P3ca;
261 SISIOADDRESS SiS_P3c6;
262 SISIOADDRESS SiS_P3c7;
263 SISIOADDRESS SiS_P3c8;
264 SISIOADDRESS SiS_P3c9;
265 SISIOADDRESS SiS_P3cb;
266 SISIOADDRESS SiS_P3cd;
267 SISIOADDRESS SiS_P3da;
268 SISIOADDRESS SiS_Part1Port;
269 SISIOADDRESS SiS_Part2Port;
270 SISIOADDRESS SiS_Part3Port;
271 SISIOADDRESS SiS_Part4Port;
272 SISIOADDRESS SiS_Part5Port;
273 SISIOADDRESS SiS_VidCapt;
274 SISIOADDRESS SiS_VidPlay;
275 USHORT SiS_IF_DEF_LVDS;
276 USHORT SiS_IF_DEF_CH70xx;
277 USHORT SiS_IF_DEF_CONEX;
278 USHORT SiS_IF_DEF_TRUMPION;
279 USHORT SiS_IF_DEF_DSTN;
280 USHORT SiS_IF_DEF_FSTN;
281 USHORT SiS_SysFlags;
282 UCHAR SiS_VGAINFO;
283#ifdef LINUX_XF86
284 USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
285#endif 241#endif
286 BOOLEAN SiS_UseROM; 242 unsigned char *VirtualRomBase;
287 BOOLEAN SiS_ROMNew; 243 BOOLEAN UseROM;
288 BOOLEAN SiS_NeedRomModeData; 244#ifdef SIS_LINUX_KERNEL
289 BOOLEAN PanelSelfDetected; 245 unsigned char SISIOMEMTYPE *VideoMemoryAddress;
290 int SiS_CHOverScan; 246 unsigned int VideoMemorySize;
291 BOOLEAN SiS_CHSOverScan;
292 BOOLEAN SiS_ChSW;
293 BOOLEAN SiS_UseLCDA;
294 int SiS_UseOEM;
295 ULONG SiS_CustomT;
296 USHORT SiS_Backup70xx;
297 BOOLEAN HaveEMI;
298 BOOLEAN HaveEMILCD;
299 BOOLEAN OverruleEMI;
300 UCHAR EMI_30,EMI_31,EMI_32,EMI_33;
301 USHORT SiS_EMIOffset;
302 SHORT PDC, PDCA;
303 UCHAR SiS_MyCR63;
304 USHORT SiS_CRT1Mode;
305 USHORT SiS_flag_clearbuffer;
306 int SiS_RAMType;
307 UCHAR SiS_ChannelAB;
308 UCHAR SiS_DataBusWidth;
309 USHORT SiS_ModeType;
310 USHORT SiS_VBInfo;
311 USHORT SiS_TVMode;
312 USHORT SiS_LCDResInfo;
313 USHORT SiS_LCDTypeInfo;
314 USHORT SiS_LCDInfo;
315 USHORT SiS_LCDInfo661;
316 USHORT SiS_VBType;
317 USHORT SiS_VBExtInfo;
318 USHORT SiS_YPbPr;
319 USHORT SiS_SelectCRT2Rate;
320 USHORT SiS_SetFlag;
321 USHORT SiS_RVBHCFACT;
322 USHORT SiS_RVBHCMAX;
323 USHORT SiS_RVBHRS;
324 USHORT SiS_VGAVT;
325 USHORT SiS_VGAHT;
326 USHORT SiS_VT;
327 USHORT SiS_HT;
328 USHORT SiS_VGAVDE;
329 USHORT SiS_VGAHDE;
330 USHORT SiS_VDE;
331 USHORT SiS_HDE;
332 USHORT SiS_NewFlickerMode;
333 USHORT SiS_RY1COE;
334 USHORT SiS_RY2COE;
335 USHORT SiS_RY3COE;
336 USHORT SiS_RY4COE;
337 USHORT SiS_LCDHDES;
338 USHORT SiS_LCDVDES;
339 USHORT SiS_DDC_Port;
340 USHORT SiS_DDC_Index;
341 USHORT SiS_DDC_Data;
342 USHORT SiS_DDC_NData;
343 USHORT SiS_DDC_Clk;
344 USHORT SiS_DDC_NClk;
345 USHORT SiS_DDC_DeviceAddr;
346 USHORT SiS_DDC_ReadAddr;
347 USHORT SiS_DDC_SecAddr;
348 USHORT SiS_ChrontelInit;
349 BOOLEAN SiS_SensibleSR11;
350 USHORT SiS661LCD2TableSize;
351
352 USHORT SiS_PanelMinLVDS;
353 USHORT SiS_PanelMin301;
354
355 const SiS_StStruct *SiS_SModeIDTable;
356 const SiS_StandTableStruct *SiS_StandTable;
357 const SiS_ExtStruct *SiS_EModeIDTable;
358 const SiS_Ext2Struct *SiS_RefIndex;
359 const SiS_VBModeStruct *SiS_VBModeIDTable;
360 const SiS_CRT1TableStruct *SiS_CRT1Table;
361 const SiS_MCLKDataStruct *SiS_MCLKData_0;
362 const SiS_MCLKDataStruct *SiS_MCLKData_1;
363 SiS_VCLKDataStruct *SiS_VCLKData;
364 SiS_VBVCLKDataStruct *SiS_VBVCLKData;
365 const SiS_StResInfoStruct *SiS_StResInfo;
366 const SiS_ModeResInfoStruct *SiS_ModeResInfo;
367
368 const UCHAR *pSiS_OutputSelect;
369 const UCHAR *pSiS_SoftSetting;
370
371 const DRAM4Type *SiS_SR15; /* pointer : point to array */
372#ifdef LINUX_KERNEL
373 UCHAR *pSiS_SR07;
374 const DRAM4Type *SiS_CR40; /* pointer : point to array */
375 UCHAR *SiS_CR49;
376 UCHAR *SiS_SR25;
377 UCHAR *pSiS_SR1F;
378 UCHAR *pSiS_SR21;
379 UCHAR *pSiS_SR22;
380 UCHAR *pSiS_SR23;
381 UCHAR *pSiS_SR24;
382 UCHAR *pSiS_SR31;
383 UCHAR *pSiS_SR32;
384 UCHAR *pSiS_SR33;
385 UCHAR *pSiS_CRT2Data_1_2;
386 UCHAR *pSiS_CRT2Data_4_D;
387 UCHAR *pSiS_CRT2Data_4_E;
388 UCHAR *pSiS_CRT2Data_4_10;
389 const USHORT *pSiS_RGBSenseData;
390 const USHORT *pSiS_VideoSenseData;
391 const USHORT *pSiS_YCSenseData;
392 const USHORT *pSiS_RGBSenseData2;
393 const USHORT *pSiS_VideoSenseData2;
394 const USHORT *pSiS_YCSenseData2;
395#endif 247#endif
248 SISIOADDRESS IOAddress;
249 SISIOADDRESS IOAddress2; /* For dual chip XGI volari */
396 250
397 const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl; 251#ifdef SIS_LINUX_KERNEL
398 const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS; 252 SISIOADDRESS RelIO;
253#endif
254 SISIOADDRESS SiS_P3c4;
255 SISIOADDRESS SiS_P3d4;
256 SISIOADDRESS SiS_P3c0;
257 SISIOADDRESS SiS_P3ce;
258 SISIOADDRESS SiS_P3c2;
259 SISIOADDRESS SiS_P3ca;
260 SISIOADDRESS SiS_P3c6;
261 SISIOADDRESS SiS_P3c7;
262 SISIOADDRESS SiS_P3c8;
263 SISIOADDRESS SiS_P3c9;
264 SISIOADDRESS SiS_P3cb;
265 SISIOADDRESS SiS_P3cc;
266 SISIOADDRESS SiS_P3cd;
267 SISIOADDRESS SiS_P3da;
268 SISIOADDRESS SiS_Part1Port;
269 SISIOADDRESS SiS_Part2Port;
270 SISIOADDRESS SiS_Part3Port;
271 SISIOADDRESS SiS_Part4Port;
272 SISIOADDRESS SiS_Part5Port;
273 SISIOADDRESS SiS_VidCapt;
274 SISIOADDRESS SiS_VidPlay;
275 unsigned short SiS_IF_DEF_LVDS;
276 unsigned short SiS_IF_DEF_CH70xx;
277 unsigned short SiS_IF_DEF_CONEX;
278 unsigned short SiS_IF_DEF_TRUMPION;
279 unsigned short SiS_IF_DEF_DSTN;
280 unsigned short SiS_IF_DEF_FSTN;
281 unsigned short SiS_SysFlags;
282 unsigned char SiS_VGAINFO;
283#ifdef SIS_XORG_XF86
284 unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
285#endif
286 BOOLEAN SiS_UseROM;
287 BOOLEAN SiS_ROMNew;
288 BOOLEAN SiS_XGIROM;
289 BOOLEAN SiS_NeedRomModeData;
290 BOOLEAN PanelSelfDetected;
291 BOOLEAN DDCPortMixup;
292 int SiS_CHOverScan;
293 BOOLEAN SiS_CHSOverScan;
294 BOOLEAN SiS_ChSW;
295 BOOLEAN SiS_UseLCDA;
296 int SiS_UseOEM;
297 unsigned int SiS_CustomT;
298 int SiS_UseWide, SiS_UseWideCRT2;
299 int SiS_TVBlue;
300 unsigned short SiS_Backup70xx;
301 BOOLEAN HaveEMI;
302 BOOLEAN HaveEMILCD;
303 BOOLEAN OverruleEMI;
304 unsigned char EMI_30,EMI_31,EMI_32,EMI_33;
305 unsigned short SiS_EMIOffset;
306 unsigned short SiS_PWDOffset;
307 short PDC, PDCA;
308 unsigned char SiS_MyCR63;
309 unsigned short SiS_CRT1Mode;
310 unsigned short SiS_flag_clearbuffer;
311 int SiS_RAMType;
312 unsigned char SiS_ChannelAB;
313 unsigned char SiS_DataBusWidth;
314 unsigned short SiS_ModeType;
315 unsigned short SiS_VBInfo;
316 unsigned short SiS_TVMode;
317 unsigned short SiS_LCDResInfo;
318 unsigned short SiS_LCDTypeInfo;
319 unsigned short SiS_LCDInfo;
320 unsigned short SiS_LCDInfo661;
321 unsigned short SiS_VBType;
322 unsigned short SiS_VBExtInfo;
323 unsigned short SiS_YPbPr;
324 unsigned short SiS_SelectCRT2Rate;
325 unsigned short SiS_SetFlag;
326 unsigned short SiS_RVBHCFACT;
327 unsigned short SiS_RVBHCMAX;
328 unsigned short SiS_RVBHRS;
329 unsigned short SiS_RVBHRS2;
330 unsigned short SiS_VGAVT;
331 unsigned short SiS_VGAHT;
332 unsigned short SiS_VT;
333 unsigned short SiS_HT;
334 unsigned short SiS_VGAVDE;
335 unsigned short SiS_VGAHDE;
336 unsigned short SiS_VDE;
337 unsigned short SiS_HDE;
338 unsigned short SiS_NewFlickerMode;
339 unsigned short SiS_RY1COE;
340 unsigned short SiS_RY2COE;
341 unsigned short SiS_RY3COE;
342 unsigned short SiS_RY4COE;
343 unsigned short SiS_LCDHDES;
344 unsigned short SiS_LCDVDES;
345 unsigned short SiS_DDC_Port;
346 unsigned short SiS_DDC_Index;
347 unsigned short SiS_DDC_Data;
348 unsigned short SiS_DDC_NData;
349 unsigned short SiS_DDC_Clk;
350 unsigned short SiS_DDC_NClk;
351 unsigned short SiS_DDC_DeviceAddr;
352 unsigned short SiS_DDC_ReadAddr;
353 unsigned short SiS_DDC_SecAddr;
354 unsigned short SiS_ChrontelInit;
355 BOOLEAN SiS_SensibleSR11;
356 unsigned short SiS661LCD2TableSize;
357
358 unsigned short SiS_PanelMinLVDS;
359 unsigned short SiS_PanelMin301;
360
361 const struct SiS_St *SiS_SModeIDTable;
362 const struct SiS_StandTable_S *SiS_StandTable;
363 const struct SiS_Ext *SiS_EModeIDTable;
364 const struct SiS_Ext2 *SiS_RefIndex;
365 const struct SiS_VBMode *SiS_VBModeIDTable;
366 const struct SiS_CRT1Table *SiS_CRT1Table;
367 const struct SiS_MCLKData *SiS_MCLKData_0;
368 const struct SiS_MCLKData *SiS_MCLKData_1;
369 struct SiS_VCLKData *SiS_VCLKData;
370 struct SiS_VBVCLKData *SiS_VBVCLKData;
371 const struct SiS_StResInfo_S *SiS_StResInfo;
372 const struct SiS_ModeResInfo_S *SiS_ModeResInfo;
373
374 const unsigned char *pSiS_OutputSelect;
375 const unsigned char *pSiS_SoftSetting;
376
377 const unsigned char *SiS_SR15;
378
379 const struct SiS_PanelDelayTbl *SiS_PanelDelayTbl;
380 const struct SiS_PanelDelayTbl *SiS_PanelDelayTblLVDS;
399 381
400 /* SiS bridge */ 382 /* SiS bridge */
401 383
402 const UCHAR *SiS_NTSCPhase; 384 const struct SiS_LCDData *SiS_ExtLCD1024x768Data;
403 const UCHAR *SiS_PALPhase; 385 const struct SiS_LCDData *SiS_St2LCD1024x768Data;
404 const UCHAR *SiS_NTSCPhase2; 386 const struct SiS_LCDData *SiS_LCD1280x720Data;
405 const UCHAR *SiS_PALPhase2; 387 const struct SiS_LCDData *SiS_StLCD1280x768_2Data;
406 const UCHAR *SiS_PALMPhase; 388 const struct SiS_LCDData *SiS_ExtLCD1280x768_2Data;
407 const UCHAR *SiS_PALNPhase; 389 const struct SiS_LCDData *SiS_LCD1280x800Data;
408 const UCHAR *SiS_PALMPhase2; 390 const struct SiS_LCDData *SiS_LCD1280x800_2Data;
409 const UCHAR *SiS_PALNPhase2; 391 const struct SiS_LCDData *SiS_LCD1280x854Data;
410 const UCHAR *SiS_SpecialPhase; 392 const struct SiS_LCDData *SiS_LCD1280x960Data;
411 const UCHAR *SiS_SpecialPhaseM; 393 const struct SiS_LCDData *SiS_ExtLCD1280x1024Data;
412 const UCHAR *SiS_SpecialPhaseJ; 394 const struct SiS_LCDData *SiS_St2LCD1280x1024Data;
413 const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data; 395 const struct SiS_LCDData *SiS_StLCD1400x1050Data;
414 const SiS_LCDDataStruct *SiS_St2LCD1024x768Data; 396 const struct SiS_LCDData *SiS_ExtLCD1400x1050Data;
415 const SiS_LCDDataStruct *SiS_LCD1280x720Data; 397 const struct SiS_LCDData *SiS_StLCD1600x1200Data;
416 const SiS_LCDDataStruct *SiS_StLCD1280x768_2Data; 398 const struct SiS_LCDData *SiS_ExtLCD1600x1200Data;
417 const SiS_LCDDataStruct *SiS_ExtLCD1280x768_2Data; 399 const struct SiS_LCDData *SiS_LCD1680x1050Data;
418 const SiS_LCDDataStruct *SiS_LCD1280x800Data; 400 const struct SiS_LCDData *SiS_NoScaleData;
419 const SiS_LCDDataStruct *SiS_LCD1280x800_2Data; 401 const struct SiS_TVData *SiS_StPALData;
420 const SiS_LCDDataStruct *SiS_LCD1280x960Data; 402 const struct SiS_TVData *SiS_ExtPALData;
421 const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data; 403 const struct SiS_TVData *SiS_StNTSCData;
422 const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data; 404 const struct SiS_TVData *SiS_ExtNTSCData;
423 const SiS_LCDDataStruct *SiS_StLCD1400x1050Data; 405 const struct SiS_TVData *SiS_St1HiTVData;
424 const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data; 406 const struct SiS_TVData *SiS_St2HiTVData;
425 const SiS_LCDDataStruct *SiS_StLCD1600x1200Data; 407 const struct SiS_TVData *SiS_ExtHiTVData;
426 const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data; 408 const struct SiS_TVData *SiS_St525iData;
427 const SiS_LCDDataStruct *SiS_LCD1680x1050Data; 409 const struct SiS_TVData *SiS_St525pData;
428 const SiS_LCDDataStruct *SiS_NoScaleData; 410 const struct SiS_TVData *SiS_St750pData;
429 const SiS_TVDataStruct *SiS_StPALData; 411 const struct SiS_TVData *SiS_Ext525iData;
430 const SiS_TVDataStruct *SiS_ExtPALData; 412 const struct SiS_TVData *SiS_Ext525pData;
431 const SiS_TVDataStruct *SiS_StNTSCData; 413 const struct SiS_TVData *SiS_Ext750pData;
432 const SiS_TVDataStruct *SiS_ExtNTSCData; 414 const unsigned char *SiS_NTSCTiming;
433 const SiS_TVDataStruct *SiS_St1HiTVData; 415 const unsigned char *SiS_PALTiming;
434 const SiS_TVDataStruct *SiS_St2HiTVData; 416 const unsigned char *SiS_HiTVExtTiming;
435 const SiS_TVDataStruct *SiS_ExtHiTVData; 417 const unsigned char *SiS_HiTVSt1Timing;
436 const SiS_TVDataStruct *SiS_St525iData; 418 const unsigned char *SiS_HiTVSt2Timing;
437 const SiS_TVDataStruct *SiS_St525pData; 419 const unsigned char *SiS_HiTVGroup3Data;
438 const SiS_TVDataStruct *SiS_St750pData; 420 const unsigned char *SiS_HiTVGroup3Simu;
439 const SiS_TVDataStruct *SiS_Ext525iData;
440 const SiS_TVDataStruct *SiS_Ext525pData;
441 const SiS_TVDataStruct *SiS_Ext750pData;
442 const UCHAR *SiS_NTSCTiming;
443 const UCHAR *SiS_PALTiming;
444 const UCHAR *SiS_HiTVExtTiming;
445 const UCHAR *SiS_HiTVSt1Timing;
446 const UCHAR *SiS_HiTVSt2Timing;
447 const UCHAR *SiS_HiTVGroup3Data;
448 const UCHAR *SiS_HiTVGroup3Simu;
449#if 0 421#if 0
450 const UCHAR *SiS_HiTVTextTiming; 422 const unsigned char *SiS_HiTVTextTiming;
451 const UCHAR *SiS_HiTVGroup3Text; 423 const unsigned char *SiS_HiTVGroup3Text;
452#endif 424#endif
453 425
454 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1; 426 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_1;
455 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1; 427 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_2;
456 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2; 428 const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_3;
457 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
458 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
459 const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
460 429
461 /* LVDS, Chrontel */ 430 /* LVDS, Chrontel */
462 431
463 const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1; 432 const struct SiS_LVDSData *SiS_LVDS320x240Data_1;
464 const SiS_LVDSDataStruct *SiS_LVDS800x600Data_2; 433 const struct SiS_LVDSData *SiS_LVDS320x240Data_2;
465 const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1; 434 const struct SiS_LVDSData *SiS_LVDS640x480Data_1;
466 const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2; 435 const struct SiS_LVDSData *SiS_LVDS800x600Data_1;
467 const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1; 436 const struct SiS_LVDSData *SiS_LVDS1024x600Data_1;
468 const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2; 437 const struct SiS_LVDSData *SiS_LVDS1024x768Data_1;
469 const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_1; 438 const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_1;
470 const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_2; 439 const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_2;
471 const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_1; 440 const struct SiS_LVDSData *SiS_LVDSBARCO1024Data_1;
472 const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_2; 441 const struct SiS_LVDSData *SiS_LVDS848x480Data_1;
473 const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_1; 442 const struct SiS_LVDSData *SiS_LVDS848x480Data_2;
474 const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_2; 443 const struct SiS_LVDSData *SiS_CHTVUNTSCData;
475 const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_1; 444 const struct SiS_LVDSData *SiS_CHTVONTSCData;
476 const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_2; 445 const struct SiS_LVDSData *SiS_CHTVUPALData;
477 const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_1; 446 const struct SiS_LVDSData *SiS_CHTVOPALData;
478 const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_2; 447 const struct SiS_LVDSData *SiS_CHTVUPALMData;
479 const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1; 448 const struct SiS_LVDSData *SiS_CHTVOPALMData;
480 const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2; 449 const struct SiS_LVDSData *SiS_CHTVUPALNData;
481 const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1; 450 const struct SiS_LVDSData *SiS_CHTVOPALNData;
482 const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2; 451 const struct SiS_LVDSData *SiS_CHTVSOPALData;
483 const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1; 452
484 const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1; 453 const struct SiS_LVDSDes *SiS_PanelType04_1a;
485 const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1; 454 const struct SiS_LVDSDes *SiS_PanelType04_2a;
486 const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2; 455 const struct SiS_LVDSDes *SiS_PanelType04_1b;
487 const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_1; 456 const struct SiS_LVDSDes *SiS_PanelType04_2b;
488 const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_2; 457
489 const SiS_LVDSDataStruct *SiS_LVDS848x480Data_1; 458 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_1;
490 const SiS_LVDSDataStruct *SiS_LVDS848x480Data_2; 459 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2;
491 const SiS_LVDSDataStruct *SiS_CHTVUNTSCData; 460 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2_H;
492 const SiS_LVDSDataStruct *SiS_CHTVONTSCData; 461 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3;
493 const SiS_LVDSDataStruct *SiS_CHTVUPALData; 462 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3_H;
494 const SiS_LVDSDataStruct *SiS_CHTVOPALData; 463 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1;
495 const SiS_LVDSDataStruct *SiS_CHTVUPALMData; 464 const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1_H;
496 const SiS_LVDSDataStruct *SiS_CHTVOPALMData; 465 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UNTSC;
497 const SiS_LVDSDataStruct *SiS_CHTVUPALNData; 466 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1ONTSC;
498 const SiS_LVDSDataStruct *SiS_CHTVOPALNData; 467 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UPAL;
499 const SiS_LVDSDataStruct *SiS_CHTVSOPALData; 468 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1OPAL;
500 469 const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1SOPAL;
501 const SiS_LVDSDesStruct *SiS_PanelType00_1; 470
502 const SiS_LVDSDesStruct *SiS_PanelType01_1; 471 const struct SiS_CHTVRegData *SiS_CHTVReg_UNTSC;
503 const SiS_LVDSDesStruct *SiS_PanelType02_1; 472 const struct SiS_CHTVRegData *SiS_CHTVReg_ONTSC;
504 const SiS_LVDSDesStruct *SiS_PanelType03_1; 473 const struct SiS_CHTVRegData *SiS_CHTVReg_UPAL;
505 const SiS_LVDSDesStruct *SiS_PanelType04_1; 474 const struct SiS_CHTVRegData *SiS_CHTVReg_OPAL;
506 const SiS_LVDSDesStruct *SiS_PanelType05_1; 475 const struct SiS_CHTVRegData *SiS_CHTVReg_UPALM;
507 const SiS_LVDSDesStruct *SiS_PanelType06_1; 476 const struct SiS_CHTVRegData *SiS_CHTVReg_OPALM;
508 const SiS_LVDSDesStruct *SiS_PanelType07_1; 477 const struct SiS_CHTVRegData *SiS_CHTVReg_UPALN;
509 const SiS_LVDSDesStruct *SiS_PanelType08_1; 478 const struct SiS_CHTVRegData *SiS_CHTVReg_OPALN;
510 const SiS_LVDSDesStruct *SiS_PanelType09_1; 479 const struct SiS_CHTVRegData *SiS_CHTVReg_SOPAL;
511 const SiS_LVDSDesStruct *SiS_PanelType0a_1; 480
512 const SiS_LVDSDesStruct *SiS_PanelType0b_1; 481 const unsigned char *SiS_CHTVVCLKUNTSC;
513 const SiS_LVDSDesStruct *SiS_PanelType0c_1; 482 const unsigned char *SiS_CHTVVCLKONTSC;
514 const SiS_LVDSDesStruct *SiS_PanelType0d_1; 483 const unsigned char *SiS_CHTVVCLKUPAL;
515 const SiS_LVDSDesStruct *SiS_PanelType0e_1; 484 const unsigned char *SiS_CHTVVCLKOPAL;
516 const SiS_LVDSDesStruct *SiS_PanelType0f_1; 485 const unsigned char *SiS_CHTVVCLKUPALM;
517 const SiS_LVDSDesStruct *SiS_PanelTypeNS_1; 486 const unsigned char *SiS_CHTVVCLKOPALM;
518 const SiS_LVDSDesStruct *SiS_PanelType00_2; 487 const unsigned char *SiS_CHTVVCLKUPALN;
519 const SiS_LVDSDesStruct *SiS_PanelType01_2; 488 const unsigned char *SiS_CHTVVCLKOPALN;
520 const SiS_LVDSDesStruct *SiS_PanelType02_2; 489 const unsigned char *SiS_CHTVVCLKSOPAL;
521 const SiS_LVDSDesStruct *SiS_PanelType03_2; 490
522 const SiS_LVDSDesStruct *SiS_PanelType04_2; 491 unsigned short PanelXRes, PanelHT;
523 const SiS_LVDSDesStruct *SiS_PanelType05_2; 492 unsigned short PanelYRes, PanelVT;
524 const SiS_LVDSDesStruct *SiS_PanelType06_2; 493 unsigned short PanelHRS, PanelHRE;
525 const SiS_LVDSDesStruct *SiS_PanelType07_2; 494 unsigned short PanelVRS, PanelVRE;
526 const SiS_LVDSDesStruct *SiS_PanelType08_2; 495 unsigned short PanelVCLKIdx300;
527 const SiS_LVDSDesStruct *SiS_PanelType09_2; 496 unsigned short PanelVCLKIdx315;
528 const SiS_LVDSDesStruct *SiS_PanelType0a_2; 497 BOOLEAN Alternate1600x1200;
529 const SiS_LVDSDesStruct *SiS_PanelType0b_2; 498
530 const SiS_LVDSDesStruct *SiS_PanelType0c_2; 499 BOOLEAN UseCustomMode;
531 const SiS_LVDSDesStruct *SiS_PanelType0d_2; 500 BOOLEAN CRT1UsesCustomMode;
532 const SiS_LVDSDesStruct *SiS_PanelType0e_2; 501 unsigned short CHDisplay;
533 const SiS_LVDSDesStruct *SiS_PanelType0f_2; 502 unsigned short CHSyncStart;
534 const SiS_LVDSDesStruct *SiS_PanelTypeNS_2; 503 unsigned short CHSyncEnd;
535 const SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData; 504 unsigned short CHTotal;
536 const SiS_LVDSDesStruct *SiS_CHTVONTSCDesData; 505 unsigned short CHBlankStart;
537 const SiS_LVDSDesStruct *SiS_CHTVUPALDesData; 506 unsigned short CHBlankEnd;
538 const SiS_LVDSDesStruct *SiS_CHTVOPALDesData; 507 unsigned short CVDisplay;
539 508 unsigned short CVSyncStart;
540 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1; 509 unsigned short CVSyncEnd;
541 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1; 510 unsigned short CVTotal;
542 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1; 511 unsigned short CVBlankStart;
543 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1; 512 unsigned short CVBlankEnd;
544 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1; 513 unsigned int CDClock;
545 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1; 514 unsigned int CFlags;
546 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1; 515 unsigned char CCRT1CRTC[17];
547 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1; 516 unsigned char CSR2B;
548 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H; 517 unsigned char CSR2C;
549 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H; 518 unsigned short CSRClock;
550 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H; 519 unsigned short CSRClock_CRT1;
551 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1_H; 520 unsigned short CModeFlag;
552 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1_H; 521 unsigned short CModeFlag_CRT1;
553 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1_H; 522 unsigned short CInfoFlag;
554 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1_H; 523
555 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1_H; 524 int LVDSHL;
556 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2; 525
557 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2; 526 BOOLEAN Backup;
558 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2; 527 unsigned char Backup_Mode;
559 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2; 528 unsigned char Backup_14;
560 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2; 529 unsigned char Backup_15;
561 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2; 530 unsigned char Backup_16;
562 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2; 531 unsigned char Backup_17;
563 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2; 532 unsigned char Backup_18;
564 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H; 533 unsigned char Backup_19;
565 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H; 534 unsigned char Backup_1a;
566 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H; 535 unsigned char Backup_1b;
567 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2_H; 536 unsigned char Backup_1c;
568 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2_H; 537 unsigned char Backup_1d;
569 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2_H; 538
570 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2_H; 539 unsigned char Init_P4_0E;
571 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H; 540
572 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1; 541 int UsePanelScaler;
573 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H; 542 int CenterScreen;
574 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1; 543
575 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1_H; 544 unsigned short CP_Vendor, CP_Product;
576 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2; 545 BOOLEAN CP_HaveCustomData;
577 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H; 546 int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
578 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3; 547 int CP_MaxX, CP_MaxY, CP_MaxClock;
579 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H; 548 unsigned char CP_PrefSR2B, CP_PrefSR2C;
580 const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1; 549 unsigned short CP_PrefClock;
581 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC; 550 BOOLEAN CP_Supports64048075;
582 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC; 551 int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
583 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL; 552 int CP_HTotal[7], CP_VTotal[7];
584 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL; 553 int CP_HSyncStart[7], CP_VSyncStart[7];
585 const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL; 554 int CP_HSyncEnd[7], CP_VSyncEnd[7];
586 555 int CP_HBlankStart[7], CP_VBlankStart[7];
587 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC; 556 int CP_HBlankEnd[7], CP_VBlankEnd[7];
588 const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC; 557 int CP_Clock[7];
589 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL; 558 BOOLEAN CP_DataValid[7];
590 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL; 559 BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
591 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM; 560};
592 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM;
593 const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
594 const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
595 const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
596
597 const UCHAR *SiS_CHTVVCLKUNTSC;
598 const UCHAR *SiS_CHTVVCLKONTSC;
599 const UCHAR *SiS_CHTVVCLKUPAL;
600 const UCHAR *SiS_CHTVVCLKOPAL;
601 const UCHAR *SiS_CHTVVCLKUPALM;
602 const UCHAR *SiS_CHTVVCLKOPALM;
603 const UCHAR *SiS_CHTVVCLKUPALN;
604 const UCHAR *SiS_CHTVVCLKOPALN;
605 const UCHAR *SiS_CHTVVCLKSOPAL;
606
607 USHORT PanelXRes, PanelHT;
608 USHORT PanelYRes, PanelVT;
609 USHORT PanelHRS, PanelHRE;
610 USHORT PanelVRS, PanelVRE;
611 USHORT PanelVCLKIdx300;
612 USHORT PanelVCLKIdx315;
613
614 BOOLEAN UseCustomMode;
615 BOOLEAN CRT1UsesCustomMode;
616 USHORT CHDisplay;
617 USHORT CHSyncStart;
618 USHORT CHSyncEnd;
619 USHORT CHTotal;
620 USHORT CHBlankStart;
621 USHORT CHBlankEnd;
622 USHORT CVDisplay;
623 USHORT CVSyncStart;
624 USHORT CVSyncEnd;
625 USHORT CVTotal;
626 USHORT CVBlankStart;
627 USHORT CVBlankEnd;
628 ULONG CDClock;
629 ULONG CFlags;
630 UCHAR CCRT1CRTC[17];
631 UCHAR CSR2B;
632 UCHAR CSR2C;
633 USHORT CSRClock;
634 USHORT CSRClock_CRT1;
635 USHORT CModeFlag;
636 USHORT CModeFlag_CRT1;
637 USHORT CInfoFlag;
638
639 int LVDSHL;
640
641 BOOLEAN Backup;
642 UCHAR Backup_Mode;
643 UCHAR Backup_14;
644 UCHAR Backup_15;
645 UCHAR Backup_16;
646 UCHAR Backup_17;
647 UCHAR Backup_18;
648 UCHAR Backup_19;
649 UCHAR Backup_1a;
650 UCHAR Backup_1b;
651 UCHAR Backup_1c;
652 UCHAR Backup_1d;
653
654 int UsePanelScaler;
655 int CenterScreen;
656
657 USHORT CP_Vendor, CP_Product;
658 BOOLEAN CP_HaveCustomData;
659 int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
660 int CP_MaxX, CP_MaxY, CP_MaxClock;
661 UCHAR CP_PrefSR2B, CP_PrefSR2C;
662 USHORT CP_PrefClock;
663 BOOLEAN CP_Supports64048075;
664 int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
665 int CP_HTotal[7], CP_VTotal[7];
666 int CP_HSyncStart[7], CP_VSyncStart[7];
667 int CP_HSyncEnd[7], CP_VSyncEnd[7];
668 int CP_HBlankStart[7], CP_VBlankStart[7];
669 int CP_HBlankEnd[7], CP_VBlankEnd[7];
670 int CP_Clock[7];
671 BOOLEAN CP_DataValid[7];
672 BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
673} SiS_Private;
674 561
675#endif 562#endif
676 563
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 698ca9232e73..81a6d9f188cf 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1061,6 +1061,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1061 1061
1062 chip_id = id->device; 1062 chip_id = id->device;
1063 1063
1064 if(chip_id == CYBERBLADEi1)
1065 output("*** Please do use cyblafb, Cyberblade/i1 support "
1066 "will soon be removed from tridentfb!\n");
1067
1068
1064 /* If PCI id is 0x9660 then further detect chip type */ 1069 /* If PCI id is 0x9660 then further detect chip type */
1065 1070
1066 if (chip_id == TGUI9660) { 1071 if (chip_id == TGUI9660) {
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index a272592b0373..1ca80264c7b0 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -19,6 +19,7 @@
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/ioport.h> 20#include <linux/ioport.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <video/vga.h>
22#include <asm/io.h> 23#include <asm/io.h>
23#include <asm/mtrr.h> 24#include <asm/mtrr.h>
24 25
@@ -54,6 +55,7 @@ static unsigned short *pmi_base = NULL;
54static void (*pmi_start)(void); 55static void (*pmi_start)(void);
55static void (*pmi_pal)(void); 56static void (*pmi_pal)(void);
56static int depth; 57static int depth;
58static int vga_compat;
57 59
58/* --------------------------------------------------------------------- */ 60/* --------------------------------------------------------------------- */
59 61
@@ -86,6 +88,37 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
86 return 0; 88 return 0;
87} 89}
88 90
91static int vesafb_blank(int blank, struct fb_info *info)
92{
93 int err = 1;
94
95 if (vga_compat) {
96 int loop = 10000;
97 u8 seq = 0, crtc17 = 0;
98
99 err = 0;
100
101 if (blank) {
102 seq = 0x20;
103 crtc17 = 0x00;
104 } else {
105 seq = 0x00;
106 crtc17 = 0x80;
107 }
108
109 vga_wseq(NULL, 0x00, 0x01);
110 seq |= vga_rseq(NULL, 0x01) & ~0x20;
111 vga_wseq(NULL, 0x00, seq);
112
113 crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
114 while (loop--);
115 vga_wcrt(NULL, 0x17, crtc17);
116 vga_wseq(NULL, 0x00, 0x03);
117 }
118
119 return err;
120}
121
89static void vesa_setpalette(int regno, unsigned red, unsigned green, 122static void vesa_setpalette(int regno, unsigned red, unsigned green,
90 unsigned blue) 123 unsigned blue)
91{ 124{
@@ -176,6 +209,7 @@ static struct fb_ops vesafb_ops = {
176 .owner = THIS_MODULE, 209 .owner = THIS_MODULE,
177 .fb_setcolreg = vesafb_setcolreg, 210 .fb_setcolreg = vesafb_setcolreg,
178 .fb_pan_display = vesafb_pan_display, 211 .fb_pan_display = vesafb_pan_display,
212 .fb_blank = vesafb_blank,
179 .fb_fillrect = cfb_fillrect, 213 .fb_fillrect = cfb_fillrect,
180 .fb_copyarea = cfb_copyarea, 214 .fb_copyarea = cfb_copyarea,
181 .fb_imageblit = cfb_imageblit, 215 .fb_imageblit = cfb_imageblit,
@@ -429,6 +463,10 @@ static int __init vesafb_probe(struct device *device)
429 info->flags = FBINFO_FLAG_DEFAULT | 463 info->flags = FBINFO_FLAG_DEFAULT |
430 (ypan) ? FBINFO_HWACCEL_YPAN : 0; 464 (ypan) ? FBINFO_HWACCEL_YPAN : 0;
431 465
466 vga_compat = (screen_info.capabilities & 2) ? 0 : 1;
467 printk("vesafb: Mode is %sVGA compatible\n",
468 (vga_compat) ? "" : "not ");
469
432 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { 470 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
433 err = -ENOMEM; 471 err = -ENOMEM;
434 goto err; 472 goto err;
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 711b90903e7b..9a1e00dd3e02 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -54,4 +54,20 @@ config W1_SMEM
54 Say Y here if you want to connect 1-wire 54 Say Y here if you want to connect 1-wire
55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire. 55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
56 56
57config W1_DS2433
58 tristate "4kb EEPROM family support (DS2433)"
59 depends on W1
60 help
61 Say Y here if you want to use a 1-wire
62 4kb EEPROM family device (DS2433).
63
64config W1_DS2433_CRC
65 bool "Protect DS2433 data with a CRC16"
66 depends on W1_DS2433
67 select CRC16
68 help
69 Say Y here to protect DS2433 data with a CRC16.
70 Each block has 30 bytes of data and a two byte CRC16.
71 Full block writes are only allowed if the CRC is valid.
72
57endmenu 73endmenu
diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile
index 80725c348e70..01fb54391470 100644
--- a/drivers/w1/Makefile
+++ b/drivers/w1/Makefile
@@ -6,6 +6,10 @@ ifneq ($(CONFIG_NET), y)
6EXTRA_CFLAGS += -DNETLINK_DISABLED 6EXTRA_CFLAGS += -DNETLINK_DISABLED
7endif 7endif
8 8
9ifeq ($(CONFIG_W1_DS2433_CRC), y)
10EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC
11endif
12
9obj-$(CONFIG_W1) += wire.o 13obj-$(CONFIG_W1) += wire.o
10wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o 14wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o
11 15
@@ -13,8 +17,9 @@ obj-$(CONFIG_W1_MATROX) += matrox_w1.o
13obj-$(CONFIG_W1_THERM) += w1_therm.o 17obj-$(CONFIG_W1_THERM) += w1_therm.o
14obj-$(CONFIG_W1_SMEM) += w1_smem.o 18obj-$(CONFIG_W1_SMEM) += w1_smem.o
15 19
16obj-$(CONFIG_W1_DS9490) += ds9490r.o 20obj-$(CONFIG_W1_DS9490) += ds9490r.o
17ds9490r-objs := dscore.o 21ds9490r-objs := dscore.o
18 22
19obj-$(CONFIG_W1_DS9490_BRIDGE) += ds_w1_bridge.o 23obj-$(CONFIG_W1_DS9490_BRIDGE) += ds_w1_bridge.o
20 24
25obj-$(CONFIG_W1_DS2433) += w1_ds2433.o
diff --git a/drivers/w1/ds_w1_bridge.c b/drivers/w1/ds_w1_bridge.c
index 7bddd8ac7d7f..a79d16d5666f 100644
--- a/drivers/w1/ds_w1_bridge.c
+++ b/drivers/w1/ds_w1_bridge.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * ds_w1_bridge.c 2 * ds_w1_bridge.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
25#include "../w1/w1.h" 25#include "../w1/w1.h"
26#include "../w1/w1_int.h" 26#include "../w1/w1_int.h"
27#include "dscore.h" 27#include "dscore.h"
28 28
29static struct ds_device *ds_dev; 29static struct ds_device *ds_dev;
30static struct w1_bus_master *ds_bus_master; 30static struct w1_bus_master *ds_bus_master;
31 31
@@ -120,7 +120,7 @@ static u8 ds9490r_reset(unsigned long data)
120static int __devinit ds_w1_init(void) 120static int __devinit ds_w1_init(void)
121{ 121{
122 int err; 122 int err;
123 123
124 ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL); 124 ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL);
125 if (!ds_bus_master) { 125 if (!ds_bus_master) {
126 printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n"); 126 printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n");
@@ -136,14 +136,14 @@ static int __devinit ds_w1_init(void)
136 136
137 memset(ds_bus_master, 0, sizeof(*ds_bus_master)); 137 memset(ds_bus_master, 0, sizeof(*ds_bus_master));
138 138
139 ds_bus_master->data = (unsigned long)ds_dev; 139 ds_bus_master->data = (unsigned long)ds_dev;
140 ds_bus_master->touch_bit = &ds9490r_touch_bit; 140 ds_bus_master->touch_bit = &ds9490r_touch_bit;
141 ds_bus_master->read_bit = &ds9490r_read_bit; 141 ds_bus_master->read_bit = &ds9490r_read_bit;
142 ds_bus_master->write_bit = &ds9490r_write_bit; 142 ds_bus_master->write_bit = &ds9490r_write_bit;
143 ds_bus_master->read_byte = &ds9490r_read_byte; 143 ds_bus_master->read_byte = &ds9490r_read_byte;
144 ds_bus_master->write_byte = &ds9490r_write_byte; 144 ds_bus_master->write_byte = &ds9490r_write_byte;
145 ds_bus_master->read_block = &ds9490r_read_block; 145 ds_bus_master->read_block = &ds9490r_read_block;
146 ds_bus_master->write_block = &ds9490r_write_block; 146 ds_bus_master->write_block = &ds9490r_write_block;
147 ds_bus_master->reset_bus = &ds9490r_reset; 147 ds_bus_master->reset_bus = &ds9490r_reset;
148 148
149 err = w1_add_master_device(ds_bus_master); 149 err = w1_add_master_device(ds_bus_master);
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c
index eee6644d33d6..15fb250451e5 100644
--- a/drivers/w1/dscore.c
+++ b/drivers/w1/dscore.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * dscore.c 2 * dscore.c
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
@@ -32,19 +32,16 @@ static struct usb_device_id ds_id_table [] = {
32}; 32};
33MODULE_DEVICE_TABLE(usb, ds_id_table); 33MODULE_DEVICE_TABLE(usb, ds_id_table);
34 34
35int ds_probe(struct usb_interface *, const struct usb_device_id *); 35static int ds_probe(struct usb_interface *, const struct usb_device_id *);
36void ds_disconnect(struct usb_interface *); 36static void ds_disconnect(struct usb_interface *);
37 37
38int ds_touch_bit(struct ds_device *, u8, u8 *); 38int ds_touch_bit(struct ds_device *, u8, u8 *);
39int ds_read_byte(struct ds_device *, u8 *); 39int ds_read_byte(struct ds_device *, u8 *);
40int ds_read_bit(struct ds_device *, u8 *); 40int ds_read_bit(struct ds_device *, u8 *);
41int ds_write_byte(struct ds_device *, u8); 41int ds_write_byte(struct ds_device *, u8);
42int ds_write_bit(struct ds_device *, u8); 42int ds_write_bit(struct ds_device *, u8);
43int ds_start_pulse(struct ds_device *, int); 43static int ds_start_pulse(struct ds_device *, int);
44int ds_set_speed(struct ds_device *, int);
45int ds_reset(struct ds_device *, struct ds_status *); 44int ds_reset(struct ds_device *, struct ds_status *);
46int ds_detect(struct ds_device *, struct ds_status *);
47int ds_stop_pulse(struct ds_device *, int);
48struct ds_device * ds_get_device(void); 45struct ds_device * ds_get_device(void);
49void ds_put_device(struct ds_device *); 46void ds_put_device(struct ds_device *);
50 47
@@ -79,11 +76,11 @@ void ds_put_device(struct ds_device *dev)
79static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) 76static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
80{ 77{
81 int err; 78 int err;
82 79
83 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 80 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
84 CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); 81 CONTROL_CMD, 0x40, value, index, NULL, 0, 1000);
85 if (err < 0) { 82 if (err < 0) {
86 printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", 83 printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",
87 value, index, err); 84 value, index, err);
88 return err; 85 return err;
89 } 86 }
@@ -94,11 +91,11 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
94static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) 91static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
95{ 92{
96 int err; 93 int err;
97 94
98 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 95 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
99 MODE_CMD, 0x40, value, index, NULL, 0, 1000); 96 MODE_CMD, 0x40, value, index, NULL, 0, 1000);
100 if (err < 0) { 97 if (err < 0) {
101 printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", 98 printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",
102 value, index, err); 99 value, index, err);
103 return err; 100 return err;
104 } 101 }
@@ -109,11 +106,11 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
109static int ds_send_control(struct ds_device *dev, u16 value, u16 index) 106static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
110{ 107{
111 int err; 108 int err;
112 109
113 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), 110 err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
114 COMM_CMD, 0x40, value, index, NULL, 0, 1000); 111 COMM_CMD, 0x40, value, index, NULL, 0, 1000);
115 if (err < 0) { 112 if (err < 0) {
116 printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", 113 printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",
117 value, index, err); 114 value, index, err);
118 return err; 115 return err;
119 } 116 }
@@ -126,19 +123,20 @@ static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int of
126 printk("%45s: %8x\n", str, buf[off]); 123 printk("%45s: %8x\n", str, buf[off]);
127} 124}
128 125
129int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, unsigned char *buf, int size) 126static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
127 unsigned char *buf, int size)
130{ 128{
131 int count, err; 129 int count, err;
132 130
133 memset(st, 0, sizeof(st)); 131 memset(st, 0, sizeof(st));
134 132
135 count = 0; 133 count = 0;
136 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); 134 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);
137 if (err < 0) { 135 if (err < 0) {
138 printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); 136 printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);
139 return err; 137 return err;
140 } 138 }
141 139
142 if (count >= sizeof(*st)) 140 if (count >= sizeof(*st))
143 memcpy(st, buf, sizeof(*st)); 141 memcpy(st, buf, sizeof(*st));
144 142
@@ -149,13 +147,13 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
149{ 147{
150 unsigned char buf[64]; 148 unsigned char buf[64];
151 int count, err = 0, i; 149 int count, err = 0, i;
152 150
153 memcpy(st, buf, sizeof(*st)); 151 memcpy(st, buf, sizeof(*st));
154 152
155 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 153 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
156 if (count < 0) 154 if (count < 0)
157 return err; 155 return err;
158 156
159 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); 157 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
160 for (i=0; i<count; ++i) 158 for (i=0; i<count; ++i)
161 printk("%02x ", buf[i]); 159 printk("%02x ", buf[i]);
@@ -199,7 +197,7 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
199 return err; 197 return err;
200 } 198 }
201#endif 199#endif
202 200
203 return err; 201 return err;
204} 202}
205 203
@@ -207,9 +205,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
207{ 205{
208 int count, err; 206 int count, err;
209 struct ds_status st; 207 struct ds_status st;
210 208
211 count = 0; 209 count = 0;
212 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), 210 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
213 buf, size, &count, 1000); 211 buf, size, &count, 1000);
214 if (err < 0) { 212 if (err < 0) {
215 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); 213 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
@@ -234,7 +232,7 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
234static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) 232static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
235{ 233{
236 int count, err; 234 int count, err;
237 235
238 count = 0; 236 count = 0;
239 err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); 237 err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
240 if (err < 0) { 238 if (err < 0) {
@@ -245,12 +243,14 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
245 return err; 243 return err;
246} 244}
247 245
246#if 0
247
248int ds_stop_pulse(struct ds_device *dev, int limit) 248int ds_stop_pulse(struct ds_device *dev, int limit)
249{ 249{
250 struct ds_status st; 250 struct ds_status st;
251 int count = 0, err = 0; 251 int count = 0, err = 0;
252 u8 buf[0x20]; 252 u8 buf[0x20];
253 253
254 do { 254 do {
255 err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); 255 err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
256 if (err) 256 if (err)
@@ -275,7 +275,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
275int ds_detect(struct ds_device *dev, struct ds_status *st) 275int ds_detect(struct ds_device *dev, struct ds_status *st)
276{ 276{
277 int err; 277 int err;
278 278
279 err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 279 err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
280 if (err) 280 if (err)
281 return err; 281 return err;
@@ -283,11 +283,11 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
283 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); 283 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
284 if (err) 284 if (err)
285 return err; 285 return err;
286 286
287 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); 287 err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
288 if (err) 288 if (err)
289 return err; 289 return err;
290 290
291 err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); 291 err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
292 if (err) 292 if (err)
293 return err; 293 return err;
@@ -297,7 +297,9 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
297 return err; 297 return err;
298} 298}
299 299
300int ds_wait_status(struct ds_device *dev, struct ds_status *st) 300#endif /* 0 */
301
302static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
301{ 303{
302 u8 buf[0x20]; 304 u8 buf[0x20];
303 int err, count = 0; 305 int err, count = 0;
@@ -305,7 +307,7 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
305 do { 307 do {
306 err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 308 err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
307#if 0 309#if 0
308 if (err >= 0) { 310 if (err >= 0) {
309 int i; 311 int i;
310 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); 312 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
311 for (i=0; i<err; ++i) 313 for (i=0; i<err; ++i)
@@ -319,10 +321,8 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
319 if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { 321 if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
320 ds_recv_status(dev, st); 322 ds_recv_status(dev, st);
321 return -1; 323 return -1;
322 } 324 } else
323 else {
324 return 0; 325 return 0;
325 }
326} 326}
327 327
328int ds_reset(struct ds_device *dev, struct ds_status *st) 328int ds_reset(struct ds_device *dev, struct ds_status *st)
@@ -345,6 +345,7 @@ int ds_reset(struct ds_device *dev, struct ds_status *st)
345 return 0; 345 return 0;
346} 346}
347 347
348#if 0
348int ds_set_speed(struct ds_device *dev, int speed) 349int ds_set_speed(struct ds_device *dev, int speed)
349{ 350{
350 int err; 351 int err;
@@ -356,20 +357,21 @@ int ds_set_speed(struct ds_device *dev, int speed)
356 speed = SPEED_FLEXIBLE; 357 speed = SPEED_FLEXIBLE;
357 358
358 speed &= 0xff; 359 speed &= 0xff;
359 360
360 err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); 361 err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
361 if (err) 362 if (err)
362 return err; 363 return err;
363 364
364 return err; 365 return err;
365} 366}
367#endif /* 0 */
366 368
367int ds_start_pulse(struct ds_device *dev, int delay) 369static int ds_start_pulse(struct ds_device *dev, int delay)
368{ 370{
369 int err; 371 int err;
370 u8 del = 1 + (u8)(delay >> 4); 372 u8 del = 1 + (u8)(delay >> 4);
371 struct ds_status st; 373 struct ds_status st;
372 374
373#if 0 375#if 0
374 err = ds_stop_pulse(dev, 10); 376 err = ds_stop_pulse(dev, 10);
375 if (err) 377 if (err)
@@ -390,7 +392,7 @@ int ds_start_pulse(struct ds_device *dev, int delay)
390 mdelay(delay); 392 mdelay(delay);
391 393
392 ds_wait_status(dev, &st); 394 ds_wait_status(dev, &st);
393 395
394 return err; 396 return err;
395} 397}
396 398
@@ -400,7 +402,7 @@ int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
400 struct ds_status st; 402 struct ds_status st;
401 u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0); 403 u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
402 u16 cmd; 404 u16 cmd;
403 405
404 err = ds_send_control(dev, value, 0); 406 err = ds_send_control(dev, value, 0);
405 if (err) 407 if (err)
406 return err; 408 return err;
@@ -430,7 +432,7 @@ int ds_write_bit(struct ds_device *dev, u8 bit)
430{ 432{
431 int err; 433 int err;
432 struct ds_status st; 434 struct ds_status st;
433 435
434 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); 436 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
435 if (err) 437 if (err)
436 return err; 438 return err;
@@ -445,7 +447,7 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
445 int err; 447 int err;
446 struct ds_status st; 448 struct ds_status st;
447 u8 rbyte; 449 u8 rbyte;
448 450
449 err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); 451 err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
450 if (err) 452 if (err)
451 return err; 453 return err;
@@ -453,11 +455,11 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
453 err = ds_wait_status(dev, &st); 455 err = ds_wait_status(dev, &st);
454 if (err) 456 if (err)
455 return err; 457 return err;
456 458
457 err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); 459 err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
458 if (err < 0) 460 if (err < 0)
459 return err; 461 return err;
460 462
461 ds_start_pulse(dev, PULLUP_PULSE_DURATION); 463 ds_start_pulse(dev, PULLUP_PULSE_DURATION);
462 464
463 return !(byte == rbyte); 465 return !(byte == rbyte);
@@ -470,11 +472,11 @@ int ds_read_bit(struct ds_device *dev, u8 *bit)
470 err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); 472 err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
471 if (err) 473 if (err)
472 return err; 474 return err;
473 475
474 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0); 476 err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0);
475 if (err) 477 if (err)
476 return err; 478 return err;
477 479
478 err = ds_recv_data(dev, bit, sizeof(*bit)); 480 err = ds_recv_data(dev, bit, sizeof(*bit));
479 if (err < 0) 481 if (err < 0)
480 return err; 482 return err;
@@ -492,7 +494,7 @@ int ds_read_byte(struct ds_device *dev, u8 *byte)
492 return err; 494 return err;
493 495
494 ds_wait_status(dev, &st); 496 ds_wait_status(dev, &st);
495 497
496 err = ds_recv_data(dev, byte, sizeof(*byte)); 498 err = ds_recv_data(dev, byte, sizeof(*byte));
497 if (err < 0) 499 if (err < 0)
498 return err; 500 return err;
@@ -509,17 +511,17 @@ int ds_read_block(struct ds_device *dev, u8 *buf, int len)
509 return -E2BIG; 511 return -E2BIG;
510 512
511 memset(buf, 0xFF, len); 513 memset(buf, 0xFF, len);
512 514
513 err = ds_send_data(dev, buf, len); 515 err = ds_send_data(dev, buf, len);
514 if (err < 0) 516 if (err < 0)
515 return err; 517 return err;
516 518
517 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); 519 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
518 if (err) 520 if (err)
519 return err; 521 return err;
520 522
521 ds_wait_status(dev, &st); 523 ds_wait_status(dev, &st);
522 524
523 memset(buf, 0x00, len); 525 memset(buf, 0x00, len);
524 err = ds_recv_data(dev, buf, len); 526 err = ds_recv_data(dev, buf, len);
525 527
@@ -530,11 +532,11 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len)
530{ 532{
531 int err; 533 int err;
532 struct ds_status st; 534 struct ds_status st;
533 535
534 err = ds_send_data(dev, buf, len); 536 err = ds_send_data(dev, buf, len);
535 if (err < 0) 537 if (err < 0)
536 return err; 538 return err;
537 539
538 ds_wait_status(dev, &st); 540 ds_wait_status(dev, &st);
539 541
540 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); 542 err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
@@ -548,10 +550,12 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len)
548 return err; 550 return err;
549 551
550 ds_start_pulse(dev, PULLUP_PULSE_DURATION); 552 ds_start_pulse(dev, PULLUP_PULSE_DURATION);
551 553
552 return !(err == len); 554 return !(err == len);
553} 555}
554 556
557#if 0
558
555int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) 559int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search)
556{ 560{
557 int err; 561 int err;
@@ -559,11 +563,11 @@ int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int condi
559 struct ds_status st; 563 struct ds_status st;
560 564
561 memset(buf, 0, sizeof(buf)); 565 memset(buf, 0, sizeof(buf));
562 566
563 err = ds_send_data(ds_dev, (unsigned char *)&init, 8); 567 err = ds_send_data(ds_dev, (unsigned char *)&init, 8);
564 if (err) 568 if (err)
565 return err; 569 return err;
566 570
567 ds_wait_status(ds_dev, &st); 571 ds_wait_status(ds_dev, &st);
568 572
569 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; 573 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS;
@@ -589,7 +593,7 @@ int ds_match_access(struct ds_device *dev, u64 init)
589 err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); 593 err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
590 if (err) 594 if (err)
591 return err; 595 return err;
592 596
593 ds_wait_status(dev, &st); 597 ds_wait_status(dev, &st);
594 598
595 err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); 599 err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055);
@@ -609,11 +613,11 @@ int ds_set_path(struct ds_device *dev, u64 init)
609 613
610 memcpy(buf, &init, 8); 614 memcpy(buf, &init, 8);
611 buf[8] = BRANCH_MAIN; 615 buf[8] = BRANCH_MAIN;
612 616
613 err = ds_send_data(dev, buf, sizeof(buf)); 617 err = ds_send_data(dev, buf, sizeof(buf));
614 if (err) 618 if (err)
615 return err; 619 return err;
616 620
617 ds_wait_status(dev, &st); 621 ds_wait_status(dev, &st);
618 622
619 err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); 623 err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0);
@@ -625,7 +629,10 @@ int ds_set_path(struct ds_device *dev, u64 init)
625 return 0; 629 return 0;
626} 630}
627 631
628int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id) 632#endif /* 0 */
633
634static int ds_probe(struct usb_interface *intf,
635 const struct usb_device_id *udev_id)
629{ 636{
630 struct usb_device *udev = interface_to_usbdev(intf); 637 struct usb_device *udev = interface_to_usbdev(intf);
631 struct usb_endpoint_descriptor *endpoint; 638 struct usb_endpoint_descriptor *endpoint;
@@ -653,7 +660,7 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
653 printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); 660 printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err);
654 return err; 661 return err;
655 } 662 }
656 663
657 iface_desc = &intf->altsetting[0]; 664 iface_desc = &intf->altsetting[0];
658 if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { 665 if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
659 printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); 666 printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints);
@@ -662,37 +669,37 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
662 669
663 atomic_set(&ds_dev->refcnt, 0); 670 atomic_set(&ds_dev->refcnt, 0);
664 memset(ds_dev->ep, 0, sizeof(ds_dev->ep)); 671 memset(ds_dev->ep, 0, sizeof(ds_dev->ep));
665 672
666 /* 673 /*
667 * This loop doesn'd show control 0 endpoint, 674 * This loop doesn'd show control 0 endpoint,
668 * so we will fill only 1-3 endpoints entry. 675 * so we will fill only 1-3 endpoints entry.
669 */ 676 */
670 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 677 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
671 endpoint = &iface_desc->endpoint[i].desc; 678 endpoint = &iface_desc->endpoint[i].desc;
672 679
673 ds_dev->ep[i+1] = endpoint->bEndpointAddress; 680 ds_dev->ep[i+1] = endpoint->bEndpointAddress;
674 681
675 printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", 682 printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
676 i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), 683 i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
677 (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", 684 (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
678 endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); 685 endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
679 } 686 }
680 687
681#if 0 688#if 0
682 { 689 {
683 int err, i; 690 int err, i;
684 u64 buf[3]; 691 u64 buf[3];
685 u64 init=0xb30000002078ee81ull; 692 u64 init=0xb30000002078ee81ull;
686 struct ds_status st; 693 struct ds_status st;
687 694
688 ds_reset(ds_dev, &st); 695 ds_reset(ds_dev, &st);
689 err = ds_search(ds_dev, init, buf, 3, 0); 696 err = ds_search(ds_dev, init, buf, 3, 0);
690 if (err < 0) 697 if (err < 0)
691 return err; 698 return err;
692 for (i=0; i<err; ++i) 699 for (i=0; i<err; ++i)
693 printk("%d: %llx\n", i, buf[i]); 700 printk("%d: %llx\n", i, buf[i]);
694 701
695 printk("Resetting...\n"); 702 printk("Resetting...\n");
696 ds_reset(ds_dev, &st); 703 ds_reset(ds_dev, &st);
697 printk("Setting path for %llx.\n", init); 704 printk("Setting path for %llx.\n", init);
698 err = ds_set_path(ds_dev, init); 705 err = ds_set_path(ds_dev, init);
@@ -707,12 +714,12 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
707 err = ds_search(ds_dev, init, buf, 3, 0); 714 err = ds_search(ds_dev, init, buf, 3, 0);
708 715
709 printk("ds_search() returned %d\n", err); 716 printk("ds_search() returned %d\n", err);
710 717
711 if (err < 0) 718 if (err < 0)
712 return err; 719 return err;
713 for (i=0; i<err; ++i) 720 for (i=0; i<err; ++i)
714 printk("%d: %llx\n", i, buf[i]); 721 printk("%d: %llx\n", i, buf[i]);
715 722
716 return 0; 723 return 0;
717 } 724 }
718#endif 725#endif
@@ -720,10 +727,10 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
720 return 0; 727 return 0;
721} 728}
722 729
723void ds_disconnect(struct usb_interface *intf) 730static void ds_disconnect(struct usb_interface *intf)
724{ 731{
725 struct ds_device *dev; 732 struct ds_device *dev;
726 733
727 dev = usb_get_intfdata(intf); 734 dev = usb_get_intfdata(intf);
728 usb_set_intfdata(intf, NULL); 735 usb_set_intfdata(intf, NULL);
729 736
@@ -740,7 +747,7 @@ void ds_disconnect(struct usb_interface *intf)
740 ds_dev = NULL; 747 ds_dev = NULL;
741} 748}
742 749
743int ds_init(void) 750static int ds_init(void)
744{ 751{
745 int err; 752 int err;
746 753
@@ -753,7 +760,7 @@ int ds_init(void)
753 return 0; 760 return 0;
754} 761}
755 762
756void ds_fini(void) 763static void ds_fini(void)
757{ 764{
758 usb_deregister(&ds_driver); 765 usb_deregister(&ds_driver);
759} 766}
@@ -776,8 +783,8 @@ EXPORT_SYMBOL(ds_get_device);
776EXPORT_SYMBOL(ds_put_device); 783EXPORT_SYMBOL(ds_put_device);
777 784
778/* 785/*
779 * This functions can be used for EEPROM programming, 786 * This functions can be used for EEPROM programming,
780 * when driver will be included into mainline this will 787 * when driver will be included into mainline this will
781 * require uncommenting. 788 * require uncommenting.
782 */ 789 */
783#if 0 790#if 0
diff --git a/drivers/w1/dscore.h b/drivers/w1/dscore.h
index 9c767ef4ac24..6cf5671d6ebe 100644
--- a/drivers/w1/dscore.h
+++ b/drivers/w1/dscore.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * dscore.h 2 * dscore.h
3 * 3 *
4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * 5 *
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@
122 122
123struct ds_device 123struct ds_device
124{ 124{
125 struct usb_device *udev; 125 struct usb_device *udev;
126 struct usb_interface *intf; 126 struct usb_interface *intf;
127 127
128 int ep[NUM_EP]; 128 int ep[NUM_EP];
@@ -156,11 +156,7 @@ int ds_read_byte(struct ds_device *, u8 *);
156int ds_read_bit(struct ds_device *, u8 *); 156int ds_read_bit(struct ds_device *, u8 *);
157int ds_write_byte(struct ds_device *, u8); 157int ds_write_byte(struct ds_device *, u8);
158int ds_write_bit(struct ds_device *, u8); 158int ds_write_bit(struct ds_device *, u8);
159int ds_start_pulse(struct ds_device *, int);
160int ds_set_speed(struct ds_device *, int);
161int ds_reset(struct ds_device *, struct ds_status *); 159int ds_reset(struct ds_device *, struct ds_status *);
162int ds_detect(struct ds_device *, struct ds_status *);
163int ds_stop_pulse(struct ds_device *, int);
164struct ds_device * ds_get_device(void); 160struct ds_device * ds_get_device(void);
165void ds_put_device(struct ds_device *); 161void ds_put_device(struct ds_device *);
166int ds_write_block(struct ds_device *, u8 *, int); 162int ds_write_block(struct ds_device *, u8 *, int);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 0bbf029b1ef1..1b6b74c116a9 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -45,10 +45,12 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
45MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); 45MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
46 46
47static int w1_timeout = 10; 47static int w1_timeout = 10;
48static int w1_control_timeout = 1;
48int w1_max_slave_count = 10; 49int w1_max_slave_count = 10;
49int w1_max_slave_ttl = 10; 50int w1_max_slave_ttl = 10;
50 51
51module_param_named(timeout, w1_timeout, int, 0); 52module_param_named(timeout, w1_timeout, int, 0);
53module_param_named(control_timeout, w1_control_timeout, int, 0);
52module_param_named(max_slave_count, w1_max_slave_count, int, 0); 54module_param_named(max_slave_count, w1_max_slave_count, int, 0);
53module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); 55module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
54 56
@@ -59,19 +61,6 @@ static pid_t control_thread;
59static int control_needs_exit; 61static int control_needs_exit;
60static DECLARE_COMPLETION(w1_control_complete); 62static DECLARE_COMPLETION(w1_control_complete);
61 63
62/* stuff for the default family */
63static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)
64{
65 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
66 return(sprintf(buf, "%s\n", sl->name));
67}
68static struct w1_family_ops w1_default_fops = {
69 .rname = &w1_famdefault_read_name,
70};
71static struct w1_family w1_default_family = {
72 .fops = &w1_default_fops,
73};
74
75static int w1_master_match(struct device *dev, struct device_driver *drv) 64static int w1_master_match(struct device *dev, struct device_driver *drv)
76{ 65{
77 return 1; 66 return 1;
@@ -82,73 +71,116 @@ static int w1_master_probe(struct device *dev)
82 return -ENODEV; 71 return -ENODEV;
83} 72}
84 73
85static int w1_master_remove(struct device *dev)
86{
87 return 0;
88}
89
90static void w1_master_release(struct device *dev) 74static void w1_master_release(struct device *dev)
91{ 75{
92 struct w1_master *md = container_of(dev, struct w1_master, dev); 76 struct w1_master *md = dev_to_w1_master(dev);
93 77
94 complete(&md->dev_released); 78 dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name);
79
80 if (md->nls && md->nls->sk_socket)
81 sock_release(md->nls->sk_socket);
82 memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
83 kfree(md);
95} 84}
96 85
97static void w1_slave_release(struct device *dev) 86static void w1_slave_release(struct device *dev)
98{ 87{
99 struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 88 struct w1_slave *sl = dev_to_w1_slave(dev);
89
90 dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
91
92 while (atomic_read(&sl->refcnt)) {
93 dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
94 sl->name, atomic_read(&sl->refcnt));
95 if (msleep_interruptible(1000))
96 flush_signals(current);
97 }
98
99 w1_family_put(sl->family);
100 sl->master->slave_count--;
100 101
101 complete(&sl->dev_released); 102 complete(&sl->released);
102} 103}
103 104
104static ssize_t w1_default_read_name(struct device *dev, struct device_attribute *attr, char *buf) 105static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf)
105{ 106{
106 return sprintf(buf, "No family registered.\n"); 107 struct w1_slave *sl = dev_to_w1_slave(dev);
108
109 return sprintf(buf, "%s\n", sl->name);
107} 110}
108 111
109static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off, 112static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
110 size_t count)
111{ 113{
112 return sprintf(buf, "No family registered.\n"); 114 struct w1_slave *sl = kobj_to_w1_slave(kobj);
115
116 atomic_inc(&sl->refcnt);
117 if (off > 8) {
118 count = 0;
119 } else {
120 if (off + count > 8)
121 count = 8 - off;
122
123 memcpy(buf, (u8 *)&sl->reg_num, count);
124 }
125 atomic_dec(&sl->refcnt);
126
127 return count;
113} 128}
114 129
115static struct device_attribute w1_slave_attribute = 130static struct device_attribute w1_slave_attr_name =
116 __ATTR(name, S_IRUGO, w1_default_read_name, NULL); 131 __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
117 132
118static struct bin_attribute w1_slave_bin_attribute = { 133static struct bin_attribute w1_slave_attr_bin_id = {
119 .attr = { 134 .attr = {
120 .name = "w1_slave", 135 .name = "id",
121 .mode = S_IRUGO, 136 .mode = S_IRUGO,
122 .owner = THIS_MODULE, 137 .owner = THIS_MODULE,
123 }, 138 },
124 .size = W1_SLAVE_DATA_SIZE, 139 .size = 8,
125 .read = &w1_default_read_bin, 140 .read = w1_slave_read_id,
126}; 141};
127 142
143/* Default family */
144static struct w1_family w1_default_family;
145
146static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
128 147
129static struct bus_type w1_bus_type = { 148static struct bus_type w1_bus_type = {
130 .name = "w1", 149 .name = "w1",
131 .match = w1_master_match, 150 .match = w1_master_match,
151 .hotplug = w1_hotplug,
132}; 152};
133 153
134struct device_driver w1_driver = { 154struct device_driver w1_master_driver = {
135 .name = "w1_driver", 155 .name = "w1_master_driver",
136 .bus = &w1_bus_type, 156 .bus = &w1_bus_type,
137 .probe = w1_master_probe, 157 .probe = w1_master_probe,
138 .remove = w1_master_remove,
139}; 158};
140 159
141struct device w1_device = { 160struct device w1_master_device = {
142 .parent = NULL, 161 .parent = NULL,
143 .bus = &w1_bus_type, 162 .bus = &w1_bus_type,
144 .bus_id = "w1 bus master", 163 .bus_id = "w1 bus master",
145 .driver = &w1_driver, 164 .driver = &w1_master_driver,
146 .release = &w1_master_release 165 .release = &w1_master_release
147}; 166};
148 167
168struct device_driver w1_slave_driver = {
169 .name = "w1_slave_driver",
170 .bus = &w1_bus_type,
171};
172
173struct device w1_slave_device = {
174 .parent = NULL,
175 .bus = &w1_bus_type,
176 .bus_id = "w1 bus slave",
177 .driver = &w1_slave_driver,
178 .release = &w1_slave_release
179};
180
149static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) 181static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
150{ 182{
151 struct w1_master *md = container_of(dev, struct w1_master, dev); 183 struct w1_master *md = dev_to_w1_master(dev);
152 ssize_t count; 184 ssize_t count;
153 185
154 if (down_interruptible (&md->mutex)) 186 if (down_interruptible (&md->mutex))
@@ -165,7 +197,7 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
165 struct device_attribute *attr, 197 struct device_attribute *attr,
166 const char * buf, size_t count) 198 const char * buf, size_t count)
167{ 199{
168 struct w1_master *md = container_of(dev, struct w1_master, dev); 200 struct w1_master *md = dev_to_w1_master(dev);
169 201
170 if (down_interruptible (&md->mutex)) 202 if (down_interruptible (&md->mutex))
171 return -EBUSY; 203 return -EBUSY;
@@ -181,7 +213,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
181 struct device_attribute *attr, 213 struct device_attribute *attr,
182 char *buf) 214 char *buf)
183{ 215{
184 struct w1_master *md = container_of(dev, struct w1_master, dev); 216 struct w1_master *md = dev_to_w1_master(dev);
185 ssize_t count; 217 ssize_t count;
186 218
187 if (down_interruptible (&md->mutex)) 219 if (down_interruptible (&md->mutex))
@@ -196,7 +228,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
196 228
197static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf) 229static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
198{ 230{
199 struct w1_master *md = container_of(dev, struct w1_master, dev); 231 struct w1_master *md = dev_to_w1_master(dev);
200 ssize_t count; 232 ssize_t count;
201 233
202 if (down_interruptible(&md->mutex)) 234 if (down_interruptible(&md->mutex))
@@ -217,7 +249,7 @@ static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct devic
217 249
218static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf) 250static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
219{ 251{
220 struct w1_master *md = container_of(dev, struct w1_master, dev); 252 struct w1_master *md = dev_to_w1_master(dev);
221 ssize_t count; 253 ssize_t count;
222 254
223 if (down_interruptible(&md->mutex)) 255 if (down_interruptible(&md->mutex))
@@ -231,7 +263,7 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru
231 263
232static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf) 264static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf)
233{ 265{
234 struct w1_master *md = container_of(dev, struct w1_master, dev); 266 struct w1_master *md = dev_to_w1_master(dev);
235 ssize_t count; 267 ssize_t count;
236 268
237 if (down_interruptible(&md->mutex)) 269 if (down_interruptible(&md->mutex))
@@ -245,7 +277,7 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi
245 277
246static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf) 278static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
247{ 279{
248 struct w1_master *md = container_of(dev, struct w1_master, dev); 280 struct w1_master *md = dev_to_w1_master(dev);
249 ssize_t count; 281 ssize_t count;
250 282
251 if (down_interruptible(&md->mutex)) 283 if (down_interruptible(&md->mutex))
@@ -259,7 +291,7 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
259 291
260static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf) 292static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
261{ 293{
262 struct w1_master *md = container_of(dev, struct w1_master, dev); 294 struct w1_master *md = dev_to_w1_master(dev);
263 int c = PAGE_SIZE; 295 int c = PAGE_SIZE;
264 296
265 if (down_interruptible(&md->mutex)) 297 if (down_interruptible(&md->mutex))
@@ -329,12 +361,55 @@ void w1_destroy_master_attributes(struct w1_master *master)
329 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); 361 sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
330} 362}
331 363
364#ifdef CONFIG_HOTPLUG
365static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
366{
367 struct w1_master *md = NULL;
368 struct w1_slave *sl = NULL;
369 char *event_owner, *name;
370 int err, cur_index=0, cur_len=0;
371
372 if (dev->driver == &w1_master_driver) {
373 md = container_of(dev, struct w1_master, dev);
374 event_owner = "master";
375 name = md->name;
376 } else if (dev->driver == &w1_slave_driver) {
377 sl = container_of(dev, struct w1_slave, dev);
378 event_owner = "slave";
379 name = sl->name;
380 } else {
381 dev_dbg(dev, "Unknown hotplug event.\n");
382 return -EINVAL;
383 }
384
385 dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id);
386
387 if (dev->driver != &w1_slave_driver || !sl)
388 return 0;
389
390 err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
391 if (err)
392 return err;
393
394 err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
395 if (err)
396 return err;
397
398 return 0;
399};
400#else
401static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
402{
403 return 0;
404}
405#endif
406
332static int __w1_attach_slave_device(struct w1_slave *sl) 407static int __w1_attach_slave_device(struct w1_slave *sl)
333{ 408{
334 int err; 409 int err;
335 410
336 sl->dev.parent = &sl->master->dev; 411 sl->dev.parent = &sl->master->dev;
337 sl->dev.driver = sl->master->driver; 412 sl->dev.driver = &w1_slave_driver;
338 sl->dev.bus = &w1_bus_type; 413 sl->dev.bus = &w1_bus_type;
339 sl->dev.release = &w1_slave_release; 414 sl->dev.release = &w1_slave_release;
340 415
@@ -347,8 +422,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
347 (unsigned int) sl->reg_num.family, 422 (unsigned int) sl->reg_num.family,
348 (unsigned long long) sl->reg_num.id); 423 (unsigned long long) sl->reg_num.id);
349 424
350 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__, 425 dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]);
351 &sl->dev.bus_id[0]);
352 426
353 err = device_register(&sl->dev); 427 err = device_register(&sl->dev);
354 if (err < 0) { 428 if (err < 0) {
@@ -358,36 +432,44 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
358 return err; 432 return err;
359 } 433 }
360 434
361 memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin)); 435 /* Create "name" entry */
362 memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name)); 436 err = device_create_file(&sl->dev, &w1_slave_attr_name);
363 437 if (err < 0) {
364 sl->attr_bin.read = sl->family->fops->rbin; 438 dev_err(&sl->dev,
365 sl->attr_name.show = sl->family->fops->rname; 439 "sysfs file creation for [%s] failed. err=%d\n",
440 sl->dev.bus_id, err);
441 goto out_unreg;
442 }
366 443
367 err = device_create_file(&sl->dev, &sl->attr_name); 444 /* Create "id" entry */
445 err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
368 if (err < 0) { 446 if (err < 0) {
369 dev_err(&sl->dev, 447 dev_err(&sl->dev,
370 "sysfs file creation for [%s] failed. err=%d\n", 448 "sysfs file creation for [%s] failed. err=%d\n",
371 sl->dev.bus_id, err); 449 sl->dev.bus_id, err);
372 device_unregister(&sl->dev); 450 goto out_rem1;
373 return err;
374 } 451 }
375 452
376 if ( sl->attr_bin.read ) { 453 /* if the family driver needs to initialize something... */
377 err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin); 454 if (sl->family->fops && sl->family->fops->add_slave &&
378 if (err < 0) { 455 ((err = sl->family->fops->add_slave(sl)) < 0)) {
379 dev_err(&sl->dev, 456 dev_err(&sl->dev,
380 "sysfs file creation for [%s] failed. err=%d\n", 457 "sysfs file creation for [%s] failed. err=%d\n",
381 sl->dev.bus_id, err); 458 sl->dev.bus_id, err);
382 device_remove_file(&sl->dev, &sl->attr_name); 459 goto out_rem2;
383 device_unregister(&sl->dev);
384 return err;
385 }
386 } 460 }
387 461
388 list_add_tail(&sl->w1_slave_entry, &sl->master->slist); 462 list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
389 463
390 return 0; 464 return 0;
465
466out_rem2:
467 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
468out_rem1:
469 device_remove_file(&sl->dev, &w1_slave_attr_name);
470out_unreg:
471 device_unregister(&sl->dev);
472 return err;
391} 473}
392 474
393static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) 475static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
@@ -413,7 +495,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
413 495
414 memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); 496 memcpy(&sl->reg_num, rn, sizeof(sl->reg_num));
415 atomic_set(&sl->refcnt, 0); 497 atomic_set(&sl->refcnt, 0);
416 init_completion(&sl->dev_released); 498 init_completion(&sl->released);
417 499
418 spin_lock(&w1_flock); 500 spin_lock(&w1_flock);
419 f = w1_family_registered(rn->family); 501 f = w1_family_registered(rn->family);
@@ -452,28 +534,23 @@ static void w1_slave_detach(struct w1_slave *sl)
452{ 534{
453 struct w1_netlink_msg msg; 535 struct w1_netlink_msg msg;
454 536
455 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name); 537 dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl);
456
457 while (atomic_read(&sl->refcnt)) {
458 printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
459 sl->name, atomic_read(&sl->refcnt));
460 538
461 if (msleep_interruptible(1000)) 539 list_del(&sl->w1_slave_entry);
462 flush_signals(current);
463 }
464
465 if ( sl->attr_bin.read ) {
466 sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
467 }
468 device_remove_file(&sl->dev, &sl->attr_name);
469 device_unregister(&sl->dev);
470 w1_family_put(sl->family);
471 540
472 sl->master->slave_count--; 541 if (sl->family->fops && sl->family->fops->remove_slave)
542 sl->family->fops->remove_slave(sl);
473 543
474 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); 544 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
475 msg.type = W1_SLAVE_REMOVE; 545 msg.type = W1_SLAVE_REMOVE;
476 w1_netlink_send(sl->master, &msg); 546 w1_netlink_send(sl->master, &msg);
547
548 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
549 device_remove_file(&sl->dev, &w1_slave_attr_name);
550 device_unregister(&sl->dev);
551
552 wait_for_completion(&sl->released);
553 kfree(sl);
477} 554}
478 555
479static struct w1_master *w1_search_master(unsigned long data) 556static struct w1_master *w1_search_master(unsigned long data)
@@ -500,14 +577,13 @@ void w1_reconnect_slaves(struct w1_family *f)
500 577
501 spin_lock_bh(&w1_mlock); 578 spin_lock_bh(&w1_mlock);
502 list_for_each_entry(dev, &w1_masters, w1_master_entry) { 579 list_for_each_entry(dev, &w1_masters, w1_master_entry) {
503 dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", 580 dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
504 dev->name, f->fid); 581 dev->name, f->fid);
505 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); 582 set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
506 } 583 }
507 spin_unlock_bh(&w1_mlock); 584 spin_unlock_bh(&w1_mlock);
508} 585}
509 586
510
511static void w1_slave_found(unsigned long data, u64 rn) 587static void w1_slave_found(unsigned long data, u64 rn)
512{ 588{
513 int slave_count; 589 int slave_count;
@@ -646,7 +722,7 @@ static int w1_control(void *data)
646 have_to_wait = 0; 722 have_to_wait = 0;
647 723
648 try_to_freeze(); 724 try_to_freeze();
649 msleep_interruptible(w1_timeout * 1000); 725 msleep_interruptible(w1_control_timeout * 1000);
650 726
651 if (signal_pending(current)) 727 if (signal_pending(current))
652 flush_signals(current); 728 flush_signals(current);
@@ -679,33 +755,30 @@ static int w1_control(void *data)
679 list_del(&dev->w1_master_entry); 755 list_del(&dev->w1_master_entry);
680 spin_unlock_bh(&w1_mlock); 756 spin_unlock_bh(&w1_mlock);
681 757
758 down(&dev->mutex);
682 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { 759 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
683 list_del(&sl->w1_slave_entry);
684
685 w1_slave_detach(sl); 760 w1_slave_detach(sl);
686 kfree(sl);
687 } 761 }
688 w1_destroy_master_attributes(dev); 762 w1_destroy_master_attributes(dev);
763 up(&dev->mutex);
689 atomic_dec(&dev->refcnt); 764 atomic_dec(&dev->refcnt);
690 continue; 765 continue;
691 } 766 }
692 767
693 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { 768 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
694 dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); 769 dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
695 down(&dev->mutex); 770 down(&dev->mutex);
696 list_for_each_entry(sl, &dev->slist, w1_slave_entry) { 771 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
697 if (sl->family->fid == W1_FAMILY_DEFAULT) { 772 if (sl->family->fid == W1_FAMILY_DEFAULT) {
698 struct w1_reg_num rn; 773 struct w1_reg_num rn;
699 list_del(&sl->w1_slave_entry);
700 w1_slave_detach(sl);
701 774
702 memcpy(&rn, &sl->reg_num, sizeof(rn)); 775 memcpy(&rn, &sl->reg_num, sizeof(rn));
703 776 w1_slave_detach(sl);
704 kfree(sl);
705 777
706 w1_attach_slave_device(dev, &rn); 778 w1_attach_slave_device(dev, &rn);
707 } 779 }
708 } 780 }
781 dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
709 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); 782 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
710 up(&dev->mutex); 783 up(&dev->mutex);
711 } 784 }
@@ -749,10 +822,7 @@ int w1_process(void *data)
749 822
750 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { 823 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
751 if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { 824 if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
752 list_del (&sl->w1_slave_entry); 825 w1_slave_detach(sl);
753
754 w1_slave_detach (sl);
755 kfree (sl);
756 826
757 dev->slave_count--; 827 dev->slave_count--;
758 } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) 828 } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
@@ -783,7 +853,7 @@ static int w1_init(void)
783 goto err_out_exit_init; 853 goto err_out_exit_init;
784 } 854 }
785 855
786 retval = driver_register(&w1_driver); 856 retval = driver_register(&w1_master_driver);
787 if (retval) { 857 if (retval) {
788 printk(KERN_ERR 858 printk(KERN_ERR
789 "Failed to register master driver. err=%d.\n", 859 "Failed to register master driver. err=%d.\n",
@@ -791,18 +861,29 @@ static int w1_init(void)
791 goto err_out_bus_unregister; 861 goto err_out_bus_unregister;
792 } 862 }
793 863
864 retval = driver_register(&w1_slave_driver);
865 if (retval) {
866 printk(KERN_ERR
867 "Failed to register master driver. err=%d.\n",
868 retval);
869 goto err_out_master_unregister;
870 }
871
794 control_thread = kernel_thread(&w1_control, NULL, 0); 872 control_thread = kernel_thread(&w1_control, NULL, 0);
795 if (control_thread < 0) { 873 if (control_thread < 0) {
796 printk(KERN_ERR "Failed to create control thread. err=%d\n", 874 printk(KERN_ERR "Failed to create control thread. err=%d\n",
797 control_thread); 875 control_thread);
798 retval = control_thread; 876 retval = control_thread;
799 goto err_out_driver_unregister; 877 goto err_out_slave_unregister;
800 } 878 }
801 879
802 return 0; 880 return 0;
803 881
804err_out_driver_unregister: 882err_out_slave_unregister:
805 driver_unregister(&w1_driver); 883 driver_unregister(&w1_slave_driver);
884
885err_out_master_unregister:
886 driver_unregister(&w1_master_driver);
806 887
807err_out_bus_unregister: 888err_out_bus_unregister:
808 bus_unregister(&w1_bus_type); 889 bus_unregister(&w1_bus_type);
@@ -821,7 +902,8 @@ static void w1_fini(void)
821 control_needs_exit = 1; 902 control_needs_exit = 1;
822 wait_for_completion(&w1_control_complete); 903 wait_for_completion(&w1_control_complete);
823 904
824 driver_unregister(&w1_driver); 905 driver_unregister(&w1_slave_driver);
906 driver_unregister(&w1_master_driver);
825 bus_unregister(&w1_bus_type); 907 bus_unregister(&w1_bus_type);
826} 908}
827 909
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index 4f0a986e33e3..d8900780c3bf 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -75,11 +75,9 @@ struct w1_slave
75 75
76 struct w1_master *master; 76 struct w1_master *master;
77 struct w1_family *family; 77 struct w1_family *family;
78 void *family_data;
78 struct device dev; 79 struct device dev;
79 struct completion dev_released; 80 struct completion released;
80
81 struct bin_attribute attr_bin;
82 struct device_attribute attr_name;
83}; 81};
84 82
85typedef void (* w1_slave_found_callback)(unsigned long, u64); 83typedef void (* w1_slave_found_callback)(unsigned long, u64);
@@ -179,7 +177,6 @@ struct w1_master
179 177
180 struct device_driver *driver; 178 struct device_driver *driver;
181 struct device dev; 179 struct device dev;
182 struct completion dev_released;
183 struct completion dev_exited; 180 struct completion dev_exited;
184 181
185 struct w1_bus_master *bus_master; 182 struct w1_bus_master *bus_master;
@@ -191,6 +188,21 @@ struct w1_master
191int w1_create_master_attributes(struct w1_master *); 188int w1_create_master_attributes(struct w1_master *);
192void w1_search(struct w1_master *dev, w1_slave_found_callback cb); 189void w1_search(struct w1_master *dev, w1_slave_found_callback cb);
193 190
191static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
192{
193 return container_of(dev, struct w1_slave, dev);
194}
195
196static inline struct w1_slave* kobj_to_w1_slave(struct kobject *kobj)
197{
198 return dev_to_w1_slave(container_of(kobj, struct device, kobj));
199}
200
201static inline struct w1_master* dev_to_w1_master(struct device *dev)
202{
203 return container_of(dev, struct w1_master, dev);
204}
205
194#endif /* __KERNEL__ */ 206#endif /* __KERNEL__ */
195 207
196#endif /* __W1_H */ 208#endif /* __W1_H */
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
new file mode 100644
index 000000000000..b7c24b34d270
--- /dev/null
+++ b/drivers/w1/w1_ds2433.c
@@ -0,0 +1,327 @@
1/*
2 * w1_ds2433.c - w1 family 23 (DS2433) driver
3 *
4 * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
5 *
6 * This source code is licensed under the GNU General Public License,
7 * Version 2. See the file COPYING for more details.
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/device.h>
14#include <linux/types.h>
15#include <linux/delay.h>
16#ifdef CONFIG_W1_F23_CRC
17#include <linux/crc16.h>
18#endif
19
20#include "w1.h"
21#include "w1_io.h"
22#include "w1_int.h"
23#include "w1_family.h"
24
25MODULE_LICENSE("GPL");
26MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
27MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM");
28
29#define W1_EEPROM_SIZE 512
30#define W1_PAGE_COUNT 16
31#define W1_PAGE_SIZE 32
32#define W1_PAGE_BITS 5
33#define W1_PAGE_MASK 0x1F
34
35#define W1_F23_TIME 300
36
37#define W1_F23_READ_EEPROM 0xF0
38#define W1_F23_WRITE_SCRATCH 0x0F
39#define W1_F23_READ_SCRATCH 0xAA
40#define W1_F23_COPY_SCRATCH 0x55
41
42struct w1_f23_data {
43 u8 memory[W1_EEPROM_SIZE];
44 u32 validcrc;
45};
46
47/**
48 * Check the file size bounds and adjusts count as needed.
49 * This would not be needed if the file size didn't reset to 0 after a write.
50 */
51static inline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size)
52{
53 if (off > size)
54 return 0;
55
56 if ((off + count) > size)
57 return (size - off);
58
59 return count;
60}
61
62#ifdef CONFIG_W1_F23_CRC
63static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
64 int block)
65{
66 u8 wrbuf[3];
67 int off = block * W1_PAGE_SIZE;
68
69 if (data->validcrc & (1 << block))
70 return 0;
71
72 if (w1_reset_select_slave(sl)) {
73 data->validcrc = 0;
74 return -EIO;
75 }
76
77 wrbuf[0] = W1_F23_READ_EEPROM;
78 wrbuf[1] = off & 0xff;
79 wrbuf[2] = off >> 8;
80 w1_write_block(sl->master, wrbuf, 3);
81 w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
82
83 /* cache the block if the CRC is valid */
84 if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
85 data->validcrc |= (1 << block);
86
87 return 0;
88}
89#endif /* CONFIG_W1_F23_CRC */
90
91static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
92 size_t count)
93{
94 struct w1_slave *sl = kobj_to_w1_slave(kobj);
95#ifdef CONFIG_W1_F23_CRC
96 struct w1_f23_data *data = sl->family_data;
97 int i, min_page, max_page;
98#else
99 u8 wrbuf[3];
100#endif
101
102 if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
103 return 0;
104
105 atomic_inc(&sl->refcnt);
106 if (down_interruptible(&sl->master->mutex)) {
107 count = 0;
108 goto out_dec;
109 }
110
111#ifdef CONFIG_W1_F23_CRC
112
113 min_page = (off >> W1_PAGE_BITS);
114 max_page = (off + count - 1) >> W1_PAGE_BITS;
115 for (i = min_page; i <= max_page; i++) {
116 if (w1_f23_refresh_block(sl, data, i)) {
117 count = -EIO;
118 goto out_up;
119 }
120 }
121 memcpy(buf, &data->memory[off], count);
122
123#else /* CONFIG_W1_F23_CRC */
124
125 /* read directly from the EEPROM */
126 if (w1_reset_select_slave(sl)) {
127 count = -EIO;
128 goto out_up;
129 }
130
131 wrbuf[0] = W1_F23_READ_EEPROM;
132 wrbuf[1] = off & 0xff;
133 wrbuf[2] = off >> 8;
134 w1_write_block(sl->master, wrbuf, 3);
135 w1_read_block(sl->master, buf, count);
136
137#endif /* CONFIG_W1_F23_CRC */
138
139out_up:
140 up(&sl->master->mutex);
141out_dec:
142 atomic_dec(&sl->refcnt);
143
144 return count;
145}
146
147/**
148 * Writes to the scratchpad and reads it back for verification.
149 * Then copies the scratchpad to EEPROM.
150 * The data must be on one page.
151 * The master must be locked.
152 *
153 * @param sl The slave structure
154 * @param addr Address for the write
155 * @param len length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
156 * @param data The data to write
157 * @return 0=Success -1=failure
158 */
159static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
160{
161 u8 wrbuf[4];
162 u8 rdbuf[W1_PAGE_SIZE + 3];
163 u8 es = (addr + len - 1) & 0x1f;
164
165 /* Write the data to the scratchpad */
166 if (w1_reset_select_slave(sl))
167 return -1;
168
169 wrbuf[0] = W1_F23_WRITE_SCRATCH;
170 wrbuf[1] = addr & 0xff;
171 wrbuf[2] = addr >> 8;
172
173 w1_write_block(sl->master, wrbuf, 3);
174 w1_write_block(sl->master, data, len);
175
176 /* Read the scratchpad and verify */
177 if (w1_reset_select_slave(sl))
178 return -1;
179
180 w1_write_8(sl->master, W1_F23_READ_SCRATCH);
181 w1_read_block(sl->master, rdbuf, len + 3);
182
183 /* Compare what was read against the data written */
184 if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
185 (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
186 return -1;
187
188 /* Copy the scratchpad to EEPROM */
189 if (w1_reset_select_slave(sl))
190 return -1;
191
192 wrbuf[0] = W1_F23_COPY_SCRATCH;
193 wrbuf[3] = es;
194 w1_write_block(sl->master, wrbuf, 4);
195
196 /* Sleep for 5 ms to wait for the write to complete */
197 msleep(5);
198
199 /* Reset the bus to wake up the EEPROM (this may not be needed) */
200 w1_reset_bus(sl->master);
201
202 return 0;
203}
204
205static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
206 size_t count)
207{
208 struct w1_slave *sl = kobj_to_w1_slave(kobj);
209 int addr, len, idx;
210
211 if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
212 return 0;
213
214#ifdef CONFIG_W1_F23_CRC
215 /* can only write full blocks in cached mode */
216 if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
217 dev_err(&sl->dev, "invalid offset/count off=%d cnt=%d\n",
218 (int)off, count);
219 return -EINVAL;
220 }
221
222 /* make sure the block CRCs are valid */
223 for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
224 if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) != CRC16_VALID) {
225 dev_err(&sl->dev, "bad CRC at offset %d\n", (int)off);
226 return -EINVAL;
227 }
228 }
229#endif /* CONFIG_W1_F23_CRC */
230
231 atomic_inc(&sl->refcnt);
232 if (down_interruptible(&sl->master->mutex)) {
233 count = 0;
234 goto out_dec;
235 }
236
237 /* Can only write data to one page at a time */
238 idx = 0;
239 while (idx < count) {
240 addr = off + idx;
241 len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
242 if (len > (count - idx))
243 len = count - idx;
244
245 if (w1_f23_write(sl, addr, len, &buf[idx]) < 0) {
246 count = -EIO;
247 goto out_up;
248 }
249 idx += len;
250 }
251
252out_up:
253 up(&sl->master->mutex);
254out_dec:
255 atomic_dec(&sl->refcnt);
256
257 return count;
258}
259
260static struct bin_attribute w1_f23_bin_attr = {
261 .attr = {
262 .name = "eeprom",
263 .mode = S_IRUGO | S_IWUSR,
264 .owner = THIS_MODULE,
265 },
266 .size = W1_EEPROM_SIZE,
267 .read = w1_f23_read_bin,
268 .write = w1_f23_write_bin,
269};
270
271static int w1_f23_add_slave(struct w1_slave *sl)
272{
273 int err;
274#ifdef CONFIG_W1_F23_CRC
275 struct w1_f23_data *data;
276
277 data = kmalloc(sizeof(struct w1_f23_data), GFP_KERNEL);
278 if (!data)
279 return -ENOMEM;
280 memset(data, 0, sizeof(struct w1_f23_data));
281 sl->family_data = data;
282
283#endif /* CONFIG_W1_F23_CRC */
284
285 err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
286
287#ifdef CONFIG_W1_F23_CRC
288 if (err)
289 kfree(data);
290#endif /* CONFIG_W1_F23_CRC */
291
292 return err;
293}
294
295static void w1_f23_remove_slave(struct w1_slave *sl)
296{
297#ifdef CONFIG_W1_F23_CRC
298 if (sl->family_data) {
299 kfree(sl->family_data);
300 sl->family_data = NULL;
301 }
302#endif /* CONFIG_W1_F23_CRC */
303 sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
304}
305
306static struct w1_family_ops w1_f23_fops = {
307 .add_slave = w1_f23_add_slave,
308 .remove_slave = w1_f23_remove_slave,
309};
310
311static struct w1_family w1_family_23 = {
312 .fid = W1_EEPROM_DS2433,
313 .fops = &w1_f23_fops,
314};
315
316static int __init w1_f23_init(void)
317{
318 return w1_register_family(&w1_family_23);
319}
320
321static void __exit w1_f23_fini(void)
322{
323 w1_unregister_family(&w1_family_23);
324}
325
326module_init(w1_f23_init);
327module_exit(w1_f23_fini);
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index 02eee57d3c0c..88c517a4c178 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -29,23 +29,12 @@ DEFINE_SPINLOCK(w1_flock);
29static LIST_HEAD(w1_families); 29static LIST_HEAD(w1_families);
30extern void w1_reconnect_slaves(struct w1_family *f); 30extern void w1_reconnect_slaves(struct w1_family *f);
31 31
32static int w1_check_family(struct w1_family *f)
33{
34 if (!f->fops->rname || !f->fops->rbin)
35 return -EINVAL;
36
37 return 0;
38}
39
40int w1_register_family(struct w1_family *newf) 32int w1_register_family(struct w1_family *newf)
41{ 33{
42 struct list_head *ent, *n; 34 struct list_head *ent, *n;
43 struct w1_family *f; 35 struct w1_family *f;
44 int ret = 0; 36 int ret = 0;
45 37
46 if (w1_check_family(newf))
47 return -EINVAL;
48
49 spin_lock(&w1_flock); 38 spin_lock(&w1_flock);
50 list_for_each_safe(ent, n, &w1_families) { 39 list_for_each_safe(ent, n, &w1_families) {
51 f = list_entry(ent, struct w1_family, family_entry); 40 f = list_entry(ent, struct w1_family, family_entry);
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index b26da01bbc38..2ca0489c716a 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -31,14 +31,17 @@
31#define W1_FAMILY_SMEM_81 0x81 31#define W1_FAMILY_SMEM_81 0x81
32#define W1_THERM_DS18S20 0x10 32#define W1_THERM_DS18S20 0x10
33#define W1_THERM_DS1822 0x22 33#define W1_THERM_DS1822 0x22
34#define W1_EEPROM_DS2433 0x23
34#define W1_THERM_DS18B20 0x28 35#define W1_THERM_DS18B20 0x28
35 36
36#define MAXNAMELEN 32 37#define MAXNAMELEN 32
37 38
39struct w1_slave;
40
38struct w1_family_ops 41struct w1_family_ops
39{ 42{
40 ssize_t (* rname)(struct device *, struct device_attribute *, char *); 43 int (* add_slave)(struct w1_slave *);
41 ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t); 44 void (* remove_slave)(struct w1_slave *);
42}; 45};
43 46
44struct w1_family 47struct w1_family
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 498ad505fa5f..c3f67eafc7ec 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -29,9 +29,9 @@
29 29
30static u32 w1_ids = 1; 30static u32 w1_ids = 1;
31 31
32extern struct device_driver w1_driver; 32extern struct device_driver w1_master_driver;
33extern struct bus_type w1_bus_type; 33extern struct bus_type w1_bus_type;
34extern struct device w1_device; 34extern struct device w1_master_device;
35extern int w1_max_slave_count; 35extern int w1_max_slave_count;
36extern int w1_max_slave_ttl; 36extern int w1_max_slave_ttl;
37extern struct list_head w1_masters; 37extern struct list_head w1_masters;
@@ -76,7 +76,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
76 INIT_LIST_HEAD(&dev->slist); 76 INIT_LIST_HEAD(&dev->slist);
77 init_MUTEX(&dev->mutex); 77 init_MUTEX(&dev->mutex);
78 78
79 init_completion(&dev->dev_released);
80 init_completion(&dev->dev_exited); 79 init_completion(&dev->dev_exited);
81 80
82 memcpy(&dev->dev, device, sizeof(struct device)); 81 memcpy(&dev->dev, device, sizeof(struct device));
@@ -88,17 +87,14 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
88 87
89 dev->groups = 1; 88 dev->groups = 1;
90 dev->seq = 1; 89 dev->seq = 1;
91 dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE); 90 dev_init_netlink(dev);
92 if (!dev->nls) {
93 printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
94 NETLINK_NFLOG, dev->dev.bus_id);
95 }
96 91
97 err = device_register(&dev->dev); 92 err = device_register(&dev->dev);
98 if (err) { 93 if (err) {
99 printk(KERN_ERR "Failed to register master device. err=%d\n", err); 94 printk(KERN_ERR "Failed to register master device. err=%d\n", err);
100 if (dev->nls && dev->nls->sk_socket) 95
101 sock_release(dev->nls->sk_socket); 96 dev_fini_netlink(dev);
97
102 memset(dev, 0, sizeof(struct w1_master)); 98 memset(dev, 0, sizeof(struct w1_master));
103 kfree(dev); 99 kfree(dev);
104 dev = NULL; 100 dev = NULL;
@@ -107,13 +103,9 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
107 return dev; 103 return dev;
108} 104}
109 105
110static void w1_free_dev(struct w1_master *dev) 106void w1_free_dev(struct w1_master *dev)
111{ 107{
112 device_unregister(&dev->dev); 108 device_unregister(&dev->dev);
113 if (dev->nls && dev->nls->sk_socket)
114 sock_release(dev->nls->sk_socket);
115 memset(dev, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
116 kfree(dev);
117} 109}
118 110
119int w1_add_master_device(struct w1_bus_master *master) 111int w1_add_master_device(struct w1_bus_master *master)
@@ -129,7 +121,7 @@ int w1_add_master_device(struct w1_bus_master *master)
129 return(-EINVAL); 121 return(-EINVAL);
130 } 122 }
131 123
132 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device); 124 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
133 if (!dev) 125 if (!dev)
134 return -ENOMEM; 126 return -ENOMEM;
135 127
@@ -188,7 +180,7 @@ void __w1_remove_master_device(struct w1_master *dev)
188 __func__, dev->kpid); 180 __func__, dev->kpid);
189 181
190 while (atomic_read(&dev->refcnt)) { 182 while (atomic_read(&dev->refcnt)) {
191 printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n", 183 dev_dbg(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
192 dev->name, atomic_read(&dev->refcnt)); 184 dev->name, atomic_read(&dev->refcnt));
193 185
194 if (msleep_interruptible(1000)) 186 if (msleep_interruptible(1000))
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 00f032220173..e2a043354ddf 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -277,6 +277,29 @@ void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
277 w1_search(dev, cb); 277 w1_search(dev, cb);
278} 278}
279 279
280/**
281 * Resets the bus and then selects the slave by sending either a skip rom
282 * or a rom match.
283 * The w1 master lock must be held.
284 *
285 * @param sl the slave to select
286 * @return 0=success, anything else=error
287 */
288int w1_reset_select_slave(struct w1_slave *sl)
289{
290 if (w1_reset_bus(sl->master))
291 return -1;
292
293 if (sl->master->slave_count == 1)
294 w1_write_8(sl->master, W1_SKIP_ROM);
295 else {
296 u8 match[9] = {W1_MATCH_ROM, };
297 memcpy(&match[1], (u8 *)&sl->reg_num, 8);
298 w1_write_block(sl->master, match, 9);
299 }
300 return 0;
301}
302
280EXPORT_SYMBOL(w1_touch_bit); 303EXPORT_SYMBOL(w1_touch_bit);
281EXPORT_SYMBOL(w1_write_8); 304EXPORT_SYMBOL(w1_write_8);
282EXPORT_SYMBOL(w1_read_8); 305EXPORT_SYMBOL(w1_read_8);
@@ -286,3 +309,4 @@ EXPORT_SYMBOL(w1_delay);
286EXPORT_SYMBOL(w1_read_block); 309EXPORT_SYMBOL(w1_read_block);
287EXPORT_SYMBOL(w1_write_block); 310EXPORT_SYMBOL(w1_write_block);
288EXPORT_SYMBOL(w1_search_devices); 311EXPORT_SYMBOL(w1_search_devices);
312EXPORT_SYMBOL(w1_reset_select_slave);
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
index af5829778aaa..232860184a29 100644
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -34,5 +34,6 @@ u8 w1_calc_crc8(u8 *, int);
34void w1_write_block(struct w1_master *, const u8 *, int); 34void w1_write_block(struct w1_master *, const u8 *, int);
35u8 w1_read_block(struct w1_master *, u8 *, int); 35u8 w1_read_block(struct w1_master *, u8 *, int);
36void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb); 36void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
37int w1_reset_select_slave(struct w1_slave *sl);
37 38
38#endif /* __W1_IO_H */ 39#endif /* __W1_IO_H */
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index e7b774423dd6..328645da7972 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -57,10 +57,36 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
57nlmsg_failure: 57nlmsg_failure:
58 return; 58 return;
59} 59}
60
61int dev_init_netlink(struct w1_master *dev)
62{
63 dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
64 if (!dev->nls) {
65 printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
66 NETLINK_W1, dev->dev.bus_id);
67 }
68
69 return 0;
70}
71
72void dev_fini_netlink(struct w1_master *dev)
73{
74 if (dev->nls && dev->nls->sk_socket)
75 sock_release(dev->nls->sk_socket);
76}
60#else 77#else
61#warning Netlink support is disabled. Please compile with NET support enabled. 78#warning Netlink support is disabled. Please compile with NET support enabled.
62 79
63void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) 80void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
64{ 81{
65} 82}
83
84int dev_init_netlink(struct w1_master *dev)
85{
86 return 0;
87}
88
89void dev_fini_netlink(struct w1_master *dev)
90{
91}
66#endif 92#endif
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
index 8615756946df..eb0c8b3152c8 100644
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -52,6 +52,8 @@ struct w1_netlink_msg
52#ifdef __KERNEL__ 52#ifdef __KERNEL__
53 53
54void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *); 54void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *);
55int dev_init_netlink(struct w1_master *dev);
56void dev_fini_netlink(struct w1_master *dev);
55 57
56#endif /* __KERNEL__ */ 58#endif /* __KERNEL__ */
57#endif /* __W1_NETLINK_H */ 59#endif /* __W1_NETLINK_H */
diff --git a/drivers/w1/w1_smem.c b/drivers/w1/w1_smem.c
index 70d2d469963c..e3209d0aca9b 100644
--- a/drivers/w1/w1_smem.c
+++ b/drivers/w1/w1_smem.c
@@ -36,61 +36,12 @@ MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); 36MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
37MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family."); 37MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
38 38
39static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
40static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
41
42static struct w1_family_ops w1_smem_fops = {
43 .rname = &w1_smem_read_name,
44 .rbin = &w1_smem_read_bin,
45};
46
47static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
48{
49 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
50
51 return sprintf(buf, "%s\n", sl->name);
52}
53
54static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
55{
56 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
57 struct w1_slave, dev);
58 int i;
59
60 atomic_inc(&sl->refcnt);
61 if (down_interruptible(&sl->master->mutex)) {
62 count = 0;
63 goto out_dec;
64 }
65
66 if (off > W1_SLAVE_DATA_SIZE) {
67 count = 0;
68 goto out;
69 }
70 if (off + count > W1_SLAVE_DATA_SIZE) {
71 count = 0;
72 goto out;
73 }
74 for (i = 0; i < 8; ++i)
75 count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
76 count += sprintf(buf + count, "\n");
77
78out:
79 up(&sl->master->mutex);
80out_dec:
81 atomic_dec(&sl->refcnt);
82
83 return count;
84}
85
86static struct w1_family w1_smem_family_01 = { 39static struct w1_family w1_smem_family_01 = {
87 .fid = W1_FAMILY_SMEM_01, 40 .fid = W1_FAMILY_SMEM_01,
88 .fops = &w1_smem_fops,
89}; 41};
90 42
91static struct w1_family w1_smem_family_81 = { 43static struct w1_family w1_smem_family_81 = {
92 .fid = W1_FAMILY_SMEM_81, 44 .fid = W1_FAMILY_SMEM_81,
93 .fops = &w1_smem_fops,
94}; 45};
95 46
96static int __init w1_smem_init(void) 47static int __init w1_smem_init(void)
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
index 165526c9360a..4577df3cfc48 100644
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -42,12 +42,31 @@ static u8 bad_roms[][9] = {
42 {} 42 {}
43 }; 43 };
44 44
45static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
46static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t); 45static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
47 46
47static struct bin_attribute w1_therm_bin_attr = {
48 .attr = {
49 .name = "w1_slave",
50 .mode = S_IRUGO,
51 .owner = THIS_MODULE,
52 },
53 .size = W1_SLAVE_DATA_SIZE,
54 .read = w1_therm_read_bin,
55};
56
57static int w1_therm_add_slave(struct w1_slave *sl)
58{
59 return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
60}
61
62static void w1_therm_remove_slave(struct w1_slave *sl)
63{
64 sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
65}
66
48static struct w1_family_ops w1_therm_fops = { 67static struct w1_family_ops w1_therm_fops = {
49 .rname = &w1_therm_read_name, 68 .add_slave = w1_therm_add_slave,
50 .rbin = &w1_therm_read_bin, 69 .remove_slave = w1_therm_remove_slave,
51}; 70};
52 71
53static struct w1_family w1_therm_family_DS18S20 = { 72static struct w1_family w1_therm_family_DS18S20 = {
@@ -59,6 +78,7 @@ static struct w1_family w1_therm_family_DS18B20 = {
59 .fid = W1_THERM_DS18B20, 78 .fid = W1_THERM_DS18B20,
60 .fops = &w1_therm_fops, 79 .fops = &w1_therm_fops,
61}; 80};
81
62static struct w1_family w1_therm_family_DS1822 = { 82static struct w1_family w1_therm_family_DS1822 = {
63 .fid = W1_THERM_DS1822, 83 .fid = W1_THERM_DS1822,
64 .fops = &w1_therm_fops, 84 .fops = &w1_therm_fops,
@@ -90,13 +110,6 @@ static struct w1_therm_family_converter w1_therm_families[] = {
90 }, 110 },
91}; 111};
92 112
93static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
94{
95 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
96
97 return sprintf(buf, "%s\n", sl->name);
98}
99
100static inline int w1_DS18B20_convert_temp(u8 rom[9]) 113static inline int w1_DS18B20_convert_temp(u8 rom[9])
101{ 114{
102 int t = (rom[1] << 8) | rom[0]; 115 int t = (rom[1] << 8) | rom[0];
@@ -148,8 +161,7 @@ static int w1_therm_check_rom(u8 rom[9])
148 161
149static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count) 162static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
150{ 163{
151 struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj), 164 struct w1_slave *sl = kobj_to_w1_slave(kobj);
152 struct w1_slave, dev);
153 struct w1_master *dev = sl->master; 165 struct w1_master *dev = sl->master;
154 u8 rom[9], crc, verdict; 166 u8 rom[9], crc, verdict;
155 int i, max_trying = 10; 167 int i, max_trying = 10;
@@ -178,15 +190,10 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
178 crc = 0; 190 crc = 0;
179 191
180 while (max_trying--) { 192 while (max_trying--) {
181 if (!w1_reset_bus (dev)) { 193 if (!w1_reset_select_slave(sl)) {
182 int count = 0; 194 int count = 0;
183 u8 match[9] = {W1_MATCH_ROM, };
184 unsigned int tm = 750; 195 unsigned int tm = 750;
185 196
186 memcpy(&match[1], (u64 *) & sl->reg_num, 8);
187
188 w1_write_block(dev, match, 9);
189
190 w1_write_8(dev, W1_CONVERT_TEMP); 197 w1_write_8(dev, W1_CONVERT_TEMP);
191 198
192 while (tm) { 199 while (tm) {
@@ -195,8 +202,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
195 flush_signals(current); 202 flush_signals(current);
196 } 203 }
197 204
198 if (!w1_reset_bus (dev)) { 205 if (!w1_reset_select_slave(sl)) {
199 w1_write_block(dev, match, 9);
200 206
201 w1_write_8(dev, W1_READ_SCRATCHPAD); 207 w1_write_8(dev, W1_READ_SCRATCHPAD);
202 if ((count = w1_read_block(dev, rom, 9)) != 9) { 208 if ((count = w1_read_block(dev, rom, 9)) != 9) {
@@ -207,7 +213,6 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
207 213
208 if (rom[8] == crc && rom[0]) 214 if (rom[8] == crc && rom[0])
209 verdict = 1; 215 verdict = 1;
210
211 } 216 }
212 } 217 }
213 218
diff --git a/fs/9p/9p.c b/fs/9p/9p.c
new file mode 100644
index 000000000000..e847f504a47c
--- /dev/null
+++ b/fs/9p/9p.c
@@ -0,0 +1,359 @@
1/*
2 * linux/fs/9p/9p.c
3 *
4 * This file contains functions 9P2000 functions
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/idr.h>
32
33#include "debug.h"
34#include "v9fs.h"
35#include "9p.h"
36#include "mux.h"
37
38/**
39 * v9fs_t_version - negotiate protocol parameters with sever
40 * @v9ses: 9P2000 session information
41 * @msize: requested max size packet
42 * @version: requested version.extension string
43 * @fcall: pointer to response fcall pointer
44 *
45 */
46
47int
48v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
49 char *version, struct v9fs_fcall **fcall)
50{
51 struct v9fs_fcall msg;
52
53 dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version);
54 msg.id = TVERSION;
55 msg.params.tversion.msize = msize;
56 msg.params.tversion.version = version;
57
58 return v9fs_mux_rpc(v9ses, &msg, fcall);
59}
60
61/**
62 * v9fs_t_attach - mount the server
63 * @v9ses: 9P2000 session information
64 * @uname: user name doing the attach
65 * @aname: remote name being attached to
66 * @fid: mount fid to attatch to root node
67 * @afid: authentication fid (in this case result key)
68 * @fcall: pointer to response fcall pointer
69 *
70 */
71
72int
73v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
74 u32 fid, u32 afid, struct v9fs_fcall **fcall)
75{
76 struct v9fs_fcall msg;
77
78 dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname,
79 aname, fid, afid);
80 msg.id = TATTACH;
81 msg.params.tattach.fid = fid;
82 msg.params.tattach.afid = afid;
83 msg.params.tattach.uname = uname;
84 msg.params.tattach.aname = aname;
85
86 return v9fs_mux_rpc(v9ses, &msg, fcall);
87}
88
89/**
90 * v9fs_t_clunk - release a fid (finish a transaction)
91 * @v9ses: 9P2000 session information
92 * @fid: fid to release
93 * @fcall: pointer to response fcall pointer
94 *
95 */
96
97int
98v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
99 struct v9fs_fcall **fcall)
100{
101 struct v9fs_fcall msg;
102
103 dprintk(DEBUG_9P, "fid %d\n", fid);
104 msg.id = TCLUNK;
105 msg.params.tclunk.fid = fid;
106
107 return v9fs_mux_rpc(v9ses, &msg, fcall);
108}
109
110/**
111 * v9fs_v9fs_t_flush - flush a pending transaction
112 * @v9ses: 9P2000 session information
113 * @tag: tid to release
114 *
115 */
116
117int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag)
118{
119 struct v9fs_fcall msg;
120
121 dprintk(DEBUG_9P, "oldtag %d\n", tag);
122 msg.id = TFLUSH;
123 msg.params.tflush.oldtag = tag;
124 return v9fs_mux_rpc(v9ses, &msg, NULL);
125}
126
127/**
128 * v9fs_t_stat - read a file's meta-data
129 * @v9ses: 9P2000 session information
130 * @fid: fid pointing to file or directory to get info about
131 * @fcall: pointer to response fcall
132 *
133 */
134
135int
136v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall)
137{
138 struct v9fs_fcall msg;
139
140 dprintk(DEBUG_9P, "fid %d\n", fid);
141 if (fcall)
142 *fcall = NULL;
143
144 msg.id = TSTAT;
145 msg.params.tstat.fid = fid;
146 return v9fs_mux_rpc(v9ses, &msg, fcall);
147}
148
149/**
150 * v9fs_t_wstat - write a file's meta-data
151 * @v9ses: 9P2000 session information
152 * @fid: fid pointing to file or directory to write info about
153 * @stat: metadata
154 * @fcall: pointer to response fcall
155 *
156 */
157
158int
159v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
160 struct v9fs_stat *stat, struct v9fs_fcall **fcall)
161{
162 struct v9fs_fcall msg;
163
164 dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length);
165 msg.id = TWSTAT;
166 msg.params.twstat.fid = fid;
167 msg.params.twstat.stat = stat;
168
169 return v9fs_mux_rpc(v9ses, &msg, fcall);
170}
171
172/**
173 * v9fs_t_walk - walk a fid to a new file or directory
174 * @v9ses: 9P2000 session information
175 * @fid: fid to walk
176 * @newfid: new fid (for clone operations)
177 * @name: path to walk fid to
178 * @fcall: pointer to response fcall
179 *
180 */
181
182/* TODO: support multiple walk */
183
184int
185v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
186 char *name, struct v9fs_fcall **fcall)
187{
188 struct v9fs_fcall msg;
189
190 dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name);
191 msg.id = TWALK;
192 msg.params.twalk.fid = fid;
193 msg.params.twalk.newfid = newfid;
194
195 if (name) {
196 msg.params.twalk.nwname = 1;
197 msg.params.twalk.wnames = &name;
198 } else {
199 msg.params.twalk.nwname = 0;
200 }
201
202 return v9fs_mux_rpc(v9ses, &msg, fcall);
203}
204
205/**
206 * v9fs_t_open - open a file
207 *
208 * @v9ses - 9P2000 session information
209 * @fid - fid to open
210 * @mode - mode to open file (R, RW, etc)
211 * @fcall - pointer to response fcall
212 *
213 */
214
215int
216v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
217 struct v9fs_fcall **fcall)
218{
219 struct v9fs_fcall msg;
220 long errorno = -1;
221
222 dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode);
223 msg.id = TOPEN;
224 msg.params.topen.fid = fid;
225 msg.params.topen.mode = mode;
226
227 errorno = v9fs_mux_rpc(v9ses, &msg, fcall);
228
229 return errorno;
230}
231
232/**
233 * v9fs_t_remove - remove a file or directory
234 * @v9ses: 9P2000 session information
235 * @fid: fid to remove
236 * @fcall: pointer to response fcall
237 *
238 */
239
240int
241v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
242 struct v9fs_fcall **fcall)
243{
244 struct v9fs_fcall msg;
245
246 dprintk(DEBUG_9P, "fid %d\n", fid);
247 msg.id = TREMOVE;
248 msg.params.tremove.fid = fid;
249 return v9fs_mux_rpc(v9ses, &msg, fcall);
250}
251
252/**
253 * v9fs_t_create - create a file or directory
254 * @v9ses: 9P2000 session information
255 * @fid: fid to create
256 * @name: name of the file or directory to create
257 * @perm: permissions to create with
258 * @mode: mode to open file (R, RW, etc)
259 * @fcall: pointer to response fcall
260 *
261 */
262
263int
264v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
265 u32 perm, u8 mode, struct v9fs_fcall **fcall)
266{
267 struct v9fs_fcall msg;
268
269 dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
270 fid, name, perm, mode);
271
272 msg.id = TCREATE;
273 msg.params.tcreate.fid = fid;
274 msg.params.tcreate.name = name;
275 msg.params.tcreate.perm = perm;
276 msg.params.tcreate.mode = mode;
277
278 return v9fs_mux_rpc(v9ses, &msg, fcall);
279}
280
281/**
282 * v9fs_t_read - read data
283 * @v9ses: 9P2000 session information
284 * @fid: fid to read from
285 * @offset: offset to start read at
286 * @count: how many bytes to read
287 * @fcall: pointer to response fcall (with data)
288 *
289 */
290
291int
292v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
293 u32 count, struct v9fs_fcall **fcall)
294{
295 struct v9fs_fcall msg;
296 struct v9fs_fcall *rc = NULL;
297 long errorno = -1;
298
299 dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid,
300 (long unsigned int)offset, count);
301 msg.id = TREAD;
302 msg.params.tread.fid = fid;
303 msg.params.tread.offset = offset;
304 msg.params.tread.count = count;
305 errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
306
307 if (!errorno) {
308 errorno = rc->params.rread.count;
309 dump_data(rc->params.rread.data, rc->params.rread.count);
310 }
311
312 if (fcall)
313 *fcall = rc;
314 else
315 kfree(rc);
316
317 return errorno;
318}
319
320/**
321 * v9fs_t_write - write data
322 * @v9ses: 9P2000 session information
323 * @fid: fid to write to
324 * @offset: offset to start write at
325 * @count: how many bytes to write
326 * @fcall: pointer to response fcall
327 *
328 */
329
330int
331v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid,
332 u64 offset, u32 count, void *data, struct v9fs_fcall **fcall)
333{
334 struct v9fs_fcall msg;
335 struct v9fs_fcall *rc = NULL;
336 long errorno = -1;
337
338 dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid,
339 (unsigned long long)offset, count);
340 dump_data(data, count);
341
342 msg.id = TWRITE;
343 msg.params.twrite.fid = fid;
344 msg.params.twrite.offset = offset;
345 msg.params.twrite.count = count;
346 msg.params.twrite.data = data;
347
348 errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
349
350 if (!errorno)
351 errorno = rc->params.rwrite.count;
352
353 if (fcall)
354 *fcall = rc;
355 else
356 kfree(rc);
357
358 return errorno;
359}
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
new file mode 100644
index 000000000000..f55424216be2
--- /dev/null
+++ b/fs/9p/9p.h
@@ -0,0 +1,341 @@
1/*
2 * linux/fs/9p/9p.h
3 *
4 * 9P protocol definitions.
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27/* Message Types */
28enum {
29 TVERSION = 100,
30 RVERSION,
31 TAUTH = 102,
32 RAUTH,
33 TATTACH = 104,
34 RATTACH,
35 TERROR = 106,
36 RERROR,
37 TFLUSH = 108,
38 RFLUSH,
39 TWALK = 110,
40 RWALK,
41 TOPEN = 112,
42 ROPEN,
43 TCREATE = 114,
44 RCREATE,
45 TREAD = 116,
46 RREAD,
47 TWRITE = 118,
48 RWRITE,
49 TCLUNK = 120,
50 RCLUNK,
51 TREMOVE = 122,
52 RREMOVE,
53 TSTAT = 124,
54 RSTAT,
55 TWSTAT = 126,
56 RWSTAT,
57};
58
59/* modes */
60enum {
61 V9FS_OREAD = 0x00,
62 V9FS_OWRITE = 0x01,
63 V9FS_ORDWR = 0x02,
64 V9FS_OEXEC = 0x03,
65 V9FS_OEXCL = 0x04,
66 V9FS_OTRUNC = 0x10,
67 V9FS_OREXEC = 0x20,
68 V9FS_ORCLOSE = 0x40,
69 V9FS_OAPPEND = 0x80,
70};
71
72/* permissions */
73enum {
74 V9FS_DMDIR = 0x80000000,
75 V9FS_DMAPPEND = 0x40000000,
76 V9FS_DMEXCL = 0x20000000,
77 V9FS_DMMOUNT = 0x10000000,
78 V9FS_DMAUTH = 0x08000000,
79 V9FS_DMTMP = 0x04000000,
80 V9FS_DMSYMLINK = 0x02000000,
81 V9FS_DMLINK = 0x01000000,
82 /* 9P2000.u extensions */
83 V9FS_DMDEVICE = 0x00800000,
84 V9FS_DMNAMEDPIPE = 0x00200000,
85 V9FS_DMSOCKET = 0x00100000,
86 V9FS_DMSETUID = 0x00080000,
87 V9FS_DMSETGID = 0x00040000,
88};
89
90/* qid.types */
91enum {
92 V9FS_QTDIR = 0x80,
93 V9FS_QTAPPEND = 0x40,
94 V9FS_QTEXCL = 0x20,
95 V9FS_QTMOUNT = 0x10,
96 V9FS_QTAUTH = 0x08,
97 V9FS_QTTMP = 0x04,
98 V9FS_QTSYMLINK = 0x02,
99 V9FS_QTLINK = 0x01,
100 V9FS_QTFILE = 0x00,
101};
102
103/* ample room for Twrite/Rread header (iounit) */
104#define V9FS_IOHDRSZ 24
105
106/* qids are the unique ID for a file (like an inode */
107struct v9fs_qid {
108 u8 type;
109 u32 version;
110 u64 path;
111};
112
113/* Plan 9 file metadata (stat) structure */
114struct v9fs_stat {
115 u16 size;
116 u16 type;
117 u32 dev;
118 struct v9fs_qid qid;
119 u32 mode;
120 u32 atime;
121 u32 mtime;
122 u64 length;
123 char *name;
124 char *uid;
125 char *gid;
126 char *muid;
127 char *extension; /* 9p2000.u extensions */
128 u32 n_uid; /* 9p2000.u extensions */
129 u32 n_gid; /* 9p2000.u extensions */
130 u32 n_muid; /* 9p2000.u extensions */
131 char data[0];
132};
133
134/* Structures for Protocol Operations */
135
136struct Tversion {
137 u32 msize;
138 char *version;
139};
140
141struct Rversion {
142 u32 msize;
143 char *version;
144};
145
146struct Tauth {
147 u32 afid;
148 char *uname;
149 char *aname;
150};
151
152struct Rauth {
153 struct v9fs_qid qid;
154};
155
156struct Rerror {
157 char *error;
158 u32 errno; /* 9p2000.u extension */
159};
160
161struct Tflush {
162 u32 oldtag;
163};
164
165struct Rflush {
166};
167
168struct Tattach {
169 u32 fid;
170 u32 afid;
171 char *uname;
172 char *aname;
173};
174
175struct Rattach {
176 struct v9fs_qid qid;
177};
178
179struct Twalk {
180 u32 fid;
181 u32 newfid;
182 u32 nwname;
183 char **wnames;
184};
185
186struct Rwalk {
187 u32 nwqid;
188 struct v9fs_qid *wqids;
189};
190
191struct Topen {
192 u32 fid;
193 u8 mode;
194};
195
196struct Ropen {
197 struct v9fs_qid qid;
198 u32 iounit;
199};
200
201struct Tcreate {
202 u32 fid;
203 char *name;
204 u32 perm;
205 u8 mode;
206};
207
208struct Rcreate {
209 struct v9fs_qid qid;
210 u32 iounit;
211};
212
213struct Tread {
214 u32 fid;
215 u64 offset;
216 u32 count;
217};
218
219struct Rread {
220 u32 count;
221 u8 *data;
222};
223
224struct Twrite {
225 u32 fid;
226 u64 offset;
227 u32 count;
228 u8 *data;
229};
230
231struct Rwrite {
232 u32 count;
233};
234
235struct Tclunk {
236 u32 fid;
237};
238
239struct Rclunk {
240};
241
242struct Tremove {
243 u32 fid;
244};
245
246struct Rremove {
247};
248
249struct Tstat {
250 u32 fid;
251};
252
253struct Rstat {
254 struct v9fs_stat *stat;
255};
256
257struct Twstat {
258 u32 fid;
259 struct v9fs_stat *stat;
260};
261
262struct Rwstat {
263};
264
265/*
266 * fcall is the primary packet structure
267 *
268 */
269
270struct v9fs_fcall {
271 u32 size;
272 u8 id;
273 u16 tag;
274
275 union {
276 struct Tversion tversion;
277 struct Rversion rversion;
278 struct Tauth tauth;
279 struct Rauth rauth;
280 struct Rerror rerror;
281 struct Tflush tflush;
282 struct Rflush rflush;
283 struct Tattach tattach;
284 struct Rattach rattach;
285 struct Twalk twalk;
286 struct Rwalk rwalk;
287 struct Topen topen;
288 struct Ropen ropen;
289 struct Tcreate tcreate;
290 struct Rcreate rcreate;
291 struct Tread tread;
292 struct Rread rread;
293 struct Twrite twrite;
294 struct Rwrite rwrite;
295 struct Tclunk tclunk;
296 struct Rclunk rclunk;
297 struct Tremove tremove;
298 struct Rremove rremove;
299 struct Tstat tstat;
300 struct Rstat rstat;
301 struct Twstat twstat;
302 struct Rwstat rwstat;
303 } params;
304};
305
306#define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "")
307
308int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
309 char *version, struct v9fs_fcall **rcall);
310
311int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
312 u32 fid, u32 afid, struct v9fs_fcall **rcall);
313
314int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
315 struct v9fs_fcall **rcall);
316
317int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag);
318
319int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid,
320 struct v9fs_fcall **rcall);
321
322int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
323 struct v9fs_stat *stat, struct v9fs_fcall **rcall);
324
325int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
326 char *name, struct v9fs_fcall **rcall);
327
328int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
329 struct v9fs_fcall **rcall);
330
331int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
332 struct v9fs_fcall **rcall);
333
334int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
335 u32 perm, u8 mode, struct v9fs_fcall **rcall);
336
337int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
338 u64 offset, u32 count, struct v9fs_fcall **rcall);
339
340int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
341 u32 count, void *data, struct v9fs_fcall **rcall);
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
new file mode 100644
index 000000000000..e4e4ffe5a7dc
--- /dev/null
+++ b/fs/9p/Makefile
@@ -0,0 +1,17 @@
1obj-$(CONFIG_9P_FS) := 9p2000.o
2
39p2000-objs := \
4 vfs_super.o \
5 vfs_inode.o \
6 vfs_file.o \
7 vfs_dir.o \
8 vfs_dentry.o \
9 error.o \
10 mux.o \
11 trans_fd.o \
12 trans_sock.o \
13 9p.o \
14 conv.o \
15 v9fs.o \
16 fid.o
17
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
new file mode 100644
index 000000000000..1554731bd653
--- /dev/null
+++ b/fs/9p/conv.c
@@ -0,0 +1,693 @@
1/*
2 * linux/fs/9p/conv.c
3 *
4 * 9P protocol conversion functions
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/idr.h>
32
33#include "debug.h"
34#include "v9fs.h"
35#include "9p.h"
36#include "conv.h"
37
38/*
39 * Buffer to help with string parsing
40 */
41struct cbuf {
42 unsigned char *sp;
43 unsigned char *p;
44 unsigned char *ep;
45};
46
47static inline void buf_init(struct cbuf *buf, void *data, int datalen)
48{
49 buf->sp = buf->p = data;
50 buf->ep = data + datalen;
51}
52
53static inline int buf_check_overflow(struct cbuf *buf)
54{
55 return buf->p > buf->ep;
56}
57
58static inline void buf_check_size(struct cbuf *buf, int len)
59{
60 if (buf->p+len > buf->ep) {
61 if (buf->p < buf->ep) {
62 eprintk(KERN_ERR, "buffer overflow\n");
63 buf->p = buf->ep + 1;
64 }
65 }
66}
67
68static inline void *buf_alloc(struct cbuf *buf, int len)
69{
70 void *ret = NULL;
71
72 buf_check_size(buf, len);
73 ret = buf->p;
74 buf->p += len;
75
76 return ret;
77}
78
79static inline void buf_put_int8(struct cbuf *buf, u8 val)
80{
81 buf_check_size(buf, 1);
82
83 buf->p[0] = val;
84 buf->p++;
85}
86
87static inline void buf_put_int16(struct cbuf *buf, u16 val)
88{
89 buf_check_size(buf, 2);
90
91 *(__le16 *) buf->p = cpu_to_le16(val);
92 buf->p += 2;
93}
94
95static inline void buf_put_int32(struct cbuf *buf, u32 val)
96{
97 buf_check_size(buf, 4);
98
99 *(__le32 *)buf->p = cpu_to_le32(val);
100 buf->p += 4;
101}
102
103static inline void buf_put_int64(struct cbuf *buf, u64 val)
104{
105 buf_check_size(buf, 8);
106
107 *(__le64 *)buf->p = cpu_to_le64(val);
108 buf->p += 8;
109}
110
111static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
112{
113 buf_check_size(buf, slen + 2);
114
115 buf_put_int16(buf, slen);
116 memcpy(buf->p, s, slen);
117 buf->p += slen;
118}
119
120static inline void buf_put_string(struct cbuf *buf, const char *s)
121{
122 buf_put_stringn(buf, s, strlen(s));
123}
124
125static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
126{
127 buf_check_size(buf, datalen);
128
129 memcpy(buf->p, data, datalen);
130 buf->p += datalen;
131}
132
133static inline u8 buf_get_int8(struct cbuf *buf)
134{
135 u8 ret = 0;
136
137 buf_check_size(buf, 1);
138 ret = buf->p[0];
139
140 buf->p++;
141
142 return ret;
143}
144
145static inline u16 buf_get_int16(struct cbuf *buf)
146{
147 u16 ret = 0;
148
149 buf_check_size(buf, 2);
150 ret = le16_to_cpu(*(__le16 *)buf->p);
151
152 buf->p += 2;
153
154 return ret;
155}
156
157static inline u32 buf_get_int32(struct cbuf *buf)
158{
159 u32 ret = 0;
160
161 buf_check_size(buf, 4);
162 ret = le32_to_cpu(*(__le32 *)buf->p);
163
164 buf->p += 4;
165
166 return ret;
167}
168
169static inline u64 buf_get_int64(struct cbuf *buf)
170{
171 u64 ret = 0;
172
173 buf_check_size(buf, 8);
174 ret = le64_to_cpu(*(__le64 *)buf->p);
175
176 buf->p += 8;
177
178 return ret;
179}
180
181static inline int
182buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
183{
184
185 u16 len = buf_get_int16(buf);
186 buf_check_size(buf, len);
187 if (len + 1 > datalen)
188 return 0;
189
190 memcpy(data, buf->p, len);
191 data[len] = 0;
192 buf->p += len;
193
194 return len + 1;
195}
196
197static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
198{
199 char *ret = NULL;
200 int n = buf_get_string(buf, sbuf->p, sbuf->ep - sbuf->p);
201
202 if (n > 0) {
203 ret = sbuf->p;
204 sbuf->p += n;
205 }
206
207 return ret;
208}
209
210static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
211{
212 buf_check_size(buf, datalen);
213
214 memcpy(data, buf->p, datalen);
215 buf->p += datalen;
216
217 return datalen;
218}
219
220static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
221 int datalen)
222{
223 char *ret = NULL;
224 int n = 0;
225
226 buf_check_size(dbuf, datalen);
227
228 n = buf_get_data(buf, dbuf->p, datalen);
229
230 if (n > 0) {
231 ret = dbuf->p;
232 dbuf->p += n;
233 }
234
235 return ret;
236}
237
238/**
239 * v9fs_size_stat - calculate the size of a variable length stat struct
240 * @v9ses: session information
241 * @stat: metadata (stat) structure
242 *
243 */
244
245static int v9fs_size_stat(struct v9fs_session_info *v9ses,
246 struct v9fs_stat *stat)
247{
248 int size = 0;
249
250 if (stat == NULL) {
251 eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n");
252 return 0;
253 }
254
255 size = /* 2 + *//* size[2] */
256 2 + /* type[2] */
257 4 + /* dev[4] */
258 1 + /* qid.type[1] */
259 4 + /* qid.vers[4] */
260 8 + /* qid.path[8] */
261 4 + /* mode[4] */
262 4 + /* atime[4] */
263 4 + /* mtime[4] */
264 8 + /* length[8] */
265 8; /* minimum sum of string lengths */
266
267 if (stat->name)
268 size += strlen(stat->name);
269 if (stat->uid)
270 size += strlen(stat->uid);
271 if (stat->gid)
272 size += strlen(stat->gid);
273 if (stat->muid)
274 size += strlen(stat->muid);
275
276 if (v9ses->extended) {
277 size += 4 + /* n_uid[4] */
278 4 + /* n_gid[4] */
279 4 + /* n_muid[4] */
280 2; /* string length of extension[4] */
281 if (stat->extension)
282 size += strlen(stat->extension);
283 }
284
285 return size;
286}
287
288/**
289 * serialize_stat - safely format a stat structure for transmission
290 * @v9ses: session info
291 * @stat: metadata (stat) structure
292 * @bufp: buffer to serialize structure into
293 *
294 */
295
296static int
297serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
298 struct cbuf *bufp)
299{
300 buf_put_int16(bufp, stat->size);
301 buf_put_int16(bufp, stat->type);
302 buf_put_int32(bufp, stat->dev);
303 buf_put_int8(bufp, stat->qid.type);
304 buf_put_int32(bufp, stat->qid.version);
305 buf_put_int64(bufp, stat->qid.path);
306 buf_put_int32(bufp, stat->mode);
307 buf_put_int32(bufp, stat->atime);
308 buf_put_int32(bufp, stat->mtime);
309 buf_put_int64(bufp, stat->length);
310
311 buf_put_string(bufp, stat->name);
312 buf_put_string(bufp, stat->uid);
313 buf_put_string(bufp, stat->gid);
314 buf_put_string(bufp, stat->muid);
315
316 if (v9ses->extended) {
317 buf_put_string(bufp, stat->extension);
318 buf_put_int32(bufp, stat->n_uid);
319 buf_put_int32(bufp, stat->n_gid);
320 buf_put_int32(bufp, stat->n_muid);
321 }
322
323 if (buf_check_overflow(bufp))
324 return 0;
325
326 return stat->size;
327}
328
329/**
330 * deserialize_stat - safely decode a recieved metadata (stat) structure
331 * @v9ses: session info
332 * @bufp: buffer to deserialize
333 * @stat: metadata (stat) structure
334 * @dbufp: buffer to deserialize variable strings into
335 *
336 */
337
338static inline int
339deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
340 struct v9fs_stat *stat, struct cbuf *dbufp)
341{
342
343 stat->size = buf_get_int16(bufp);
344 stat->type = buf_get_int16(bufp);
345 stat->dev = buf_get_int32(bufp);
346 stat->qid.type = buf_get_int8(bufp);
347 stat->qid.version = buf_get_int32(bufp);
348 stat->qid.path = buf_get_int64(bufp);
349 stat->mode = buf_get_int32(bufp);
350 stat->atime = buf_get_int32(bufp);
351 stat->mtime = buf_get_int32(bufp);
352 stat->length = buf_get_int64(bufp);
353 stat->name = buf_get_stringb(bufp, dbufp);
354 stat->uid = buf_get_stringb(bufp, dbufp);
355 stat->gid = buf_get_stringb(bufp, dbufp);
356 stat->muid = buf_get_stringb(bufp, dbufp);
357
358 if (v9ses->extended) {
359 stat->extension = buf_get_stringb(bufp, dbufp);
360 stat->n_uid = buf_get_int32(bufp);
361 stat->n_gid = buf_get_int32(bufp);
362 stat->n_muid = buf_get_int32(bufp);
363 }
364
365 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
366 return 0;
367
368 return stat->size + 2;
369}
370
371/**
372 * deserialize_statb - wrapper for decoding a received metadata structure
373 * @v9ses: session info
374 * @bufp: buffer to deserialize
375 * @dbufp: buffer to deserialize variable strings into
376 *
377 */
378
379static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info
380 *v9ses, struct cbuf *bufp,
381 struct cbuf *dbufp)
382{
383 struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat));
384
385 if (ret) {
386 int n = deserialize_stat(v9ses, bufp, ret, dbufp);
387 if (n <= 0)
388 return NULL;
389 }
390
391 return ret;
392}
393
394/**
395 * v9fs_deserialize_stat - decode a received metadata structure
396 * @v9ses: session info
397 * @buf: buffer to deserialize
398 * @buflen: length of received buffer
399 * @stat: metadata structure to decode into
400 * @statlen: length of destination metadata structure
401 *
402 */
403
404int
405v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf,
406 u32 buflen, struct v9fs_stat *stat, u32 statlen)
407{
408 struct cbuf buffer;
409 struct cbuf *bufp = &buffer;
410 struct cbuf dbuffer;
411 struct cbuf *dbufp = &dbuffer;
412
413 buf_init(bufp, buf, buflen);
414 buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat),
415 statlen - sizeof(struct v9fs_stat));
416
417 return deserialize_stat(v9ses, bufp, stat, dbufp);
418}
419
420static inline int
421v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
422{
423 int size = 4 + 1 + 2; /* size[4] msg[1] tag[2] */
424 int i = 0;
425
426 switch (fcall->id) {
427 default:
428 eprintk(KERN_ERR, "bad msg type %d\n", fcall->id);
429 return 0;
430 case TVERSION: /* msize[4] version[s] */
431 size += 4 + 2 + strlen(fcall->params.tversion.version);
432 break;
433 case TAUTH: /* afid[4] uname[s] aname[s] */
434 size += 4 + 2 + strlen(fcall->params.tauth.uname) +
435 2 + strlen(fcall->params.tauth.aname);
436 break;
437 case TFLUSH: /* oldtag[2] */
438 size += 2;
439 break;
440 case TATTACH: /* fid[4] afid[4] uname[s] aname[s] */
441 size += 4 + 4 + 2 + strlen(fcall->params.tattach.uname) +
442 2 + strlen(fcall->params.tattach.aname);
443 break;
444 case TWALK: /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
445 size += 4 + 4 + 2;
446 /* now compute total for the array of names */
447 for (i = 0; i < fcall->params.twalk.nwname; i++)
448 size += 2 + strlen(fcall->params.twalk.wnames[i]);
449 break;
450 case TOPEN: /* fid[4] mode[1] */
451 size += 4 + 1;
452 break;
453 case TCREATE: /* fid[4] name[s] perm[4] mode[1] */
454 size += 4 + 2 + strlen(fcall->params.tcreate.name) + 4 + 1;
455 break;
456 case TREAD: /* fid[4] offset[8] count[4] */
457 size += 4 + 8 + 4;
458 break;
459 case TWRITE: /* fid[4] offset[8] count[4] data[count] */
460 size += 4 + 8 + 4 + fcall->params.twrite.count;
461 break;
462 case TCLUNK: /* fid[4] */
463 size += 4;
464 break;
465 case TREMOVE: /* fid[4] */
466 size += 4;
467 break;
468 case TSTAT: /* fid[4] */
469 size += 4;
470 break;
471 case TWSTAT: /* fid[4] stat[n] */
472 fcall->params.twstat.stat->size =
473 v9fs_size_stat(v9ses, fcall->params.twstat.stat);
474 size += 4 + 2 + 2 + fcall->params.twstat.stat->size;
475 }
476 return size;
477}
478
479/*
480 * v9fs_serialize_fcall - marshall fcall struct into a packet
481 * @v9ses: session information
482 * @fcall: structure to convert
483 * @data: buffer to serialize fcall into
484 * @datalen: length of buffer to serialize fcall into
485 *
486 */
487
488int
489v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
490 void *data, u32 datalen)
491{
492 int i = 0;
493 struct v9fs_stat *stat = NULL;
494 struct cbuf buffer;
495 struct cbuf *bufp = &buffer;
496
497 buf_init(bufp, data, datalen);
498
499 if (!fcall) {
500 eprintk(KERN_ERR, "no fcall\n");
501 return -EINVAL;
502 }
503
504 fcall->size = v9fs_size_fcall(v9ses, fcall);
505
506 buf_put_int32(bufp, fcall->size);
507 buf_put_int8(bufp, fcall->id);
508 buf_put_int16(bufp, fcall->tag);
509
510 dprintk(DEBUG_CONV, "size %d id %d tag %d\n", fcall->size, fcall->id,
511 fcall->tag);
512
513 /* now encode it */
514 switch (fcall->id) {
515 default:
516 eprintk(KERN_ERR, "bad msg type: %d\n", fcall->id);
517 return -EPROTO;
518 case TVERSION:
519 buf_put_int32(bufp, fcall->params.tversion.msize);
520 buf_put_string(bufp, fcall->params.tversion.version);
521 break;
522 case TAUTH:
523 buf_put_int32(bufp, fcall->params.tauth.afid);
524 buf_put_string(bufp, fcall->params.tauth.uname);
525 buf_put_string(bufp, fcall->params.tauth.aname);
526 break;
527 case TFLUSH:
528 buf_put_int16(bufp, fcall->params.tflush.oldtag);
529 break;
530 case TATTACH:
531 buf_put_int32(bufp, fcall->params.tattach.fid);
532 buf_put_int32(bufp, fcall->params.tattach.afid);
533 buf_put_string(bufp, fcall->params.tattach.uname);
534 buf_put_string(bufp, fcall->params.tattach.aname);
535 break;
536 case TWALK:
537 buf_put_int32(bufp, fcall->params.twalk.fid);
538 buf_put_int32(bufp, fcall->params.twalk.newfid);
539 buf_put_int16(bufp, fcall->params.twalk.nwname);
540 for (i = 0; i < fcall->params.twalk.nwname; i++)
541 buf_put_string(bufp, fcall->params.twalk.wnames[i]);
542 break;
543 case TOPEN:
544 buf_put_int32(bufp, fcall->params.topen.fid);
545 buf_put_int8(bufp, fcall->params.topen.mode);
546 break;
547 case TCREATE:
548 buf_put_int32(bufp, fcall->params.tcreate.fid);
549 buf_put_string(bufp, fcall->params.tcreate.name);
550 buf_put_int32(bufp, fcall->params.tcreate.perm);
551 buf_put_int8(bufp, fcall->params.tcreate.mode);
552 break;
553 case TREAD:
554 buf_put_int32(bufp, fcall->params.tread.fid);
555 buf_put_int64(bufp, fcall->params.tread.offset);
556 buf_put_int32(bufp, fcall->params.tread.count);
557 break;
558 case TWRITE:
559 buf_put_int32(bufp, fcall->params.twrite.fid);
560 buf_put_int64(bufp, fcall->params.twrite.offset);
561 buf_put_int32(bufp, fcall->params.twrite.count);
562 buf_put_data(bufp, fcall->params.twrite.data,
563 fcall->params.twrite.count);
564 break;
565 case TCLUNK:
566 buf_put_int32(bufp, fcall->params.tclunk.fid);
567 break;
568 case TREMOVE:
569 buf_put_int32(bufp, fcall->params.tremove.fid);
570 break;
571 case TSTAT:
572 buf_put_int32(bufp, fcall->params.tstat.fid);
573 break;
574 case TWSTAT:
575 buf_put_int32(bufp, fcall->params.twstat.fid);
576 stat = fcall->params.twstat.stat;
577
578 buf_put_int16(bufp, stat->size + 2);
579 serialize_stat(v9ses, stat, bufp);
580 break;
581 }
582
583 if (buf_check_overflow(bufp))
584 return -EIO;
585
586 return fcall->size;
587}
588
589/**
590 * deserialize_fcall - unmarshal a response
591 * @v9ses: session information
592 * @msgsize: size of rcall message
593 * @buf: recieved buffer
594 * @buflen: length of received buffer
595 * @rcall: fcall structure to populate
596 * @rcalllen: length of fcall structure to populate
597 *
598 */
599
600int
601v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
602 void *buf, u32 buflen, struct v9fs_fcall *rcall,
603 int rcalllen)
604{
605
606 struct cbuf buffer;
607 struct cbuf *bufp = &buffer;
608 struct cbuf dbuffer;
609 struct cbuf *dbufp = &dbuffer;
610 int i = 0;
611
612 buf_init(bufp, buf, buflen);
613 buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall),
614 rcalllen - sizeof(struct v9fs_fcall));
615
616 rcall->size = msgsize;
617 rcall->id = buf_get_int8(bufp);
618 rcall->tag = buf_get_int16(bufp);
619
620 dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id,
621 rcall->tag);
622 switch (rcall->id) {
623 default:
624 eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id);
625 return -EPROTO;
626 case RVERSION:
627 rcall->params.rversion.msize = buf_get_int32(bufp);
628 rcall->params.rversion.version = buf_get_stringb(bufp, dbufp);
629 break;
630 case RFLUSH:
631 break;
632 case RATTACH:
633 rcall->params.rattach.qid.type = buf_get_int8(bufp);
634 rcall->params.rattach.qid.version = buf_get_int32(bufp);
635 rcall->params.rattach.qid.path = buf_get_int64(bufp);
636 break;
637 case RWALK:
638 rcall->params.rwalk.nwqid = buf_get_int16(bufp);
639 rcall->params.rwalk.wqids = buf_alloc(bufp,
640 rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid));
641 if (rcall->params.rwalk.wqids)
642 for (i = 0; i < rcall->params.rwalk.nwqid; i++) {
643 rcall->params.rwalk.wqids[i].type =
644 buf_get_int8(bufp);
645 rcall->params.rwalk.wqids[i].version =
646 buf_get_int16(bufp);
647 rcall->params.rwalk.wqids[i].path =
648 buf_get_int64(bufp);
649 }
650 break;
651 case ROPEN:
652 rcall->params.ropen.qid.type = buf_get_int8(bufp);
653 rcall->params.ropen.qid.version = buf_get_int32(bufp);
654 rcall->params.ropen.qid.path = buf_get_int64(bufp);
655 rcall->params.ropen.iounit = buf_get_int32(bufp);
656 break;
657 case RCREATE:
658 rcall->params.rcreate.qid.type = buf_get_int8(bufp);
659 rcall->params.rcreate.qid.version = buf_get_int32(bufp);
660 rcall->params.rcreate.qid.path = buf_get_int64(bufp);
661 rcall->params.rcreate.iounit = buf_get_int32(bufp);
662 break;
663 case RREAD:
664 rcall->params.rread.count = buf_get_int32(bufp);
665 rcall->params.rread.data = buf_get_datab(bufp, dbufp,
666 rcall->params.rread.count);
667 break;
668 case RWRITE:
669 rcall->params.rwrite.count = buf_get_int32(bufp);
670 break;
671 case RCLUNK:
672 break;
673 case RREMOVE:
674 break;
675 case RSTAT:
676 buf_get_int16(bufp);
677 rcall->params.rstat.stat =
678 deserialize_statb(v9ses, bufp, dbufp);
679 break;
680 case RWSTAT:
681 break;
682 case RERROR:
683 rcall->params.rerror.error = buf_get_stringb(bufp, dbufp);
684 if (v9ses->extended)
685 rcall->params.rerror.errno = buf_get_int16(bufp);
686 break;
687 }
688
689 if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
690 return -EIO;
691
692 return rcall->size;
693}
diff --git a/fs/9p/conv.h b/fs/9p/conv.h
new file mode 100644
index 000000000000..ee849613c61a
--- /dev/null
+++ b/fs/9p/conv.h
@@ -0,0 +1,36 @@
1/*
2 * linux/fs/9p/conv.h
3 *
4 * 9P protocol conversion definitions
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf,
28 u32 buflen, struct v9fs_stat *stat, u32 statlen);
29int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall,
30 void *buf, u32 buflen);
31int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen,
32 void *buf, u32 buflen, struct v9fs_fcall *rcall,
33 int rcalllen);
34
35/* this one is actually in error.c right now */
36int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/debug.h b/fs/9p/debug.h
new file mode 100644
index 000000000000..4445f06919d9
--- /dev/null
+++ b/fs/9p/debug.h
@@ -0,0 +1,70 @@
1/*
2 * linux/fs/9p/debug.h - V9FS Debug Definitions
3 *
4 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
19 * Free Software Foundation
20 * 51 Franklin Street, Fifth Floor
21 * Boston, MA 02111-1301 USA
22 *
23 */
24
25#define DEBUG_ERROR (1<<0)
26#define DEBUG_CURRENT (1<<1)
27#define DEBUG_9P (1<<2)
28#define DEBUG_VFS (1<<3)
29#define DEBUG_CONV (1<<4)
30#define DEBUG_MUX (1<<5)
31#define DEBUG_TRANS (1<<6)
32#define DEBUG_SLABS (1<<7)
33
34#define DEBUG_DUMP_PKT 0
35
36extern int v9fs_debug_level;
37
38#define dprintk(level, format, arg...) \
39do { \
40 if((v9fs_debug_level & level)==level) \
41 printk(KERN_NOTICE "-- %s (%d): " \
42 format , __FUNCTION__, current->pid , ## arg); \
43} while(0)
44
45#define eprintk(level, format, arg...) \
46do { \
47 printk(level "v9fs: %s (%d): " \
48 format , __FUNCTION__, current->pid , ## arg); \
49} while(0)
50
51#if DEBUG_DUMP_PKT
52static inline void dump_data(const unsigned char *data, unsigned int datalen)
53{
54 int i, j;
55 int len = datalen;
56
57 printk(KERN_DEBUG "data ");
58 for (i = 0; i < len; i += 4) {
59 for (j = 0; (j < 4) && (i + j < len); j++)
60 printk(KERN_DEBUG "%02x", data[i + j]);
61 printk(KERN_DEBUG " ");
62 }
63 printk(KERN_DEBUG "\n");
64}
65#else /* DEBUG_DUMP_PKT */
66static inline void dump_data(const unsigned char *data, unsigned int datalen)
67{
68
69}
70#endif /* DEBUG_DUMP_PKT */
diff --git a/fs/9p/error.c b/fs/9p/error.c
new file mode 100644
index 000000000000..fee5d19179c5
--- /dev/null
+++ b/fs/9p/error.c
@@ -0,0 +1,93 @@
1/*
2 * linux/fs/9p/error.c
3 *
4 * Error string handling
5 *
6 * Plan 9 uses error strings, Unix uses error numbers. These functions
7 * try to help manage that and provide for dynamically adding error
8 * mappings.
9 *
10 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
11 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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 as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to:
25 * Free Software Foundation
26 * 51 Franklin Street, Fifth Floor
27 * Boston, MA 02111-1301 USA
28 *
29 */
30
31#include <linux/config.h>
32#include <linux/module.h>
33
34#include <linux/list.h>
35#include <linux/jhash.h>
36
37#include "debug.h"
38#include "error.h"
39
40/**
41 * v9fs_error_init - preload
42 * @errstr: error string
43 *
44 */
45
46int v9fs_error_init(void)
47{
48 struct errormap *c;
49 int bucket;
50
51 /* initialize hash table */
52 for (bucket = 0; bucket < ERRHASHSZ; bucket++)
53 INIT_HLIST_HEAD(&hash_errmap[bucket]);
54
55 /* load initial error map into hash table */
56 for (c = errmap; c->name != NULL; c++) {
57 bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ;
58 INIT_HLIST_NODE(&c->list);
59 hlist_add_head(&c->list, &hash_errmap[bucket]);
60 }
61
62 return 1;
63}
64
65/**
66 * errstr2errno - convert error string to error number
67 * @errstr: error string
68 *
69 */
70
71int v9fs_errstr2errno(char *errstr)
72{
73 int errno = 0;
74 struct hlist_node *p = NULL;
75 struct errormap *c = NULL;
76 int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ;
77
78 hlist_for_each_entry(c, p, &hash_errmap[bucket], list) {
79 if (!strcmp(c->name, errstr)) {
80 errno = c->val;
81 break;
82 }
83 }
84
85 if (errno == 0) {
86 /* TODO: if error isn't found, add it dynamically */
87 printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__,
88 errstr);
89 errno = 1;
90 }
91
92 return -errno;
93}
diff --git a/fs/9p/error.h b/fs/9p/error.h
new file mode 100644
index 000000000000..78f89acf7c9a
--- /dev/null
+++ b/fs/9p/error.h
@@ -0,0 +1,178 @@
1/*
2 * linux/fs/9p/error.h
3 *
4 * Huge Nasty Error Table
5 *
6 * Plan 9 uses error strings, Unix uses error numbers. This table tries to
7 * match UNIX strings and Plan 9 strings to unix error numbers. It is used
8 * to preload the dynamic error table which can also track user-specific error
9 * strings.
10 *
11 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
12 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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 as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to:
26 * Free Software Foundation
27 * 51 Franklin Street, Fifth Floor
28 * Boston, MA 02111-1301 USA
29 *
30 */
31
32#include <linux/errno.h>
33#include <asm/errno.h>
34
35struct errormap {
36 char *name;
37 int val;
38
39 struct hlist_node list;
40};
41
42#define ERRHASHSZ 32
43static struct hlist_head hash_errmap[ERRHASHSZ];
44
45/* FixMe - reduce to a reasonable size */
46static struct errormap errmap[] = {
47 {"Operation not permitted", EPERM},
48 {"wstat prohibited", EPERM},
49 {"No such file or directory", ENOENT},
50 {"directory entry not found", ENOENT},
51 {"file not found", ENOENT},
52 {"Interrupted system call", EINTR},
53 {"Input/output error", EIO},
54 {"No such device or address", ENXIO},
55 {"Argument list too long", E2BIG},
56 {"Bad file descriptor", EBADF},
57 {"Resource temporarily unavailable", EAGAIN},
58 {"Cannot allocate memory", ENOMEM},
59 {"Permission denied", EACCES},
60 {"Bad address", EFAULT},
61 {"Block device required", ENOTBLK},
62 {"Device or resource busy", EBUSY},
63 {"File exists", EEXIST},
64 {"Invalid cross-device link", EXDEV},
65 {"No such device", ENODEV},
66 {"Not a directory", ENOTDIR},
67 {"Is a directory", EISDIR},
68 {"Invalid argument", EINVAL},
69 {"Too many open files in system", ENFILE},
70 {"Too many open files", EMFILE},
71 {"Text file busy", ETXTBSY},
72 {"File too large", EFBIG},
73 {"No space left on device", ENOSPC},
74 {"Illegal seek", ESPIPE},
75 {"Read-only file system", EROFS},
76 {"Too many links", EMLINK},
77 {"Broken pipe", EPIPE},
78 {"Numerical argument out of domain", EDOM},
79 {"Numerical result out of range", ERANGE},
80 {"Resource deadlock avoided", EDEADLK},
81 {"File name too long", ENAMETOOLONG},
82 {"No locks available", ENOLCK},
83 {"Function not implemented", ENOSYS},
84 {"Directory not empty", ENOTEMPTY},
85 {"Too many levels of symbolic links", ELOOP},
86 {"No message of desired type", ENOMSG},
87 {"Identifier removed", EIDRM},
88 {"No data available", ENODATA},
89 {"Machine is not on the network", ENONET},
90 {"Package not installed", ENOPKG},
91 {"Object is remote", EREMOTE},
92 {"Link has been severed", ENOLINK},
93 {"Communication error on send", ECOMM},
94 {"Protocol error", EPROTO},
95 {"Bad message", EBADMSG},
96 {"File descriptor in bad state", EBADFD},
97 {"Streams pipe error", ESTRPIPE},
98 {"Too many users", EUSERS},
99 {"Socket operation on non-socket", ENOTSOCK},
100 {"Message too long", EMSGSIZE},
101 {"Protocol not available", ENOPROTOOPT},
102 {"Protocol not supported", EPROTONOSUPPORT},
103 {"Socket type not supported", ESOCKTNOSUPPORT},
104 {"Operation not supported", EOPNOTSUPP},
105 {"Protocol family not supported", EPFNOSUPPORT},
106 {"Network is down", ENETDOWN},
107 {"Network is unreachable", ENETUNREACH},
108 {"Network dropped connection on reset", ENETRESET},
109 {"Software caused connection abort", ECONNABORTED},
110 {"Connection reset by peer", ECONNRESET},
111 {"No buffer space available", ENOBUFS},
112 {"Transport endpoint is already connected", EISCONN},
113 {"Transport endpoint is not connected", ENOTCONN},
114 {"Cannot send after transport endpoint shutdown", ESHUTDOWN},
115 {"Connection timed out", ETIMEDOUT},
116 {"Connection refused", ECONNREFUSED},
117 {"Host is down", EHOSTDOWN},
118 {"No route to host", EHOSTUNREACH},
119 {"Operation already in progress", EALREADY},
120 {"Operation now in progress", EINPROGRESS},
121 {"Is a named type file", EISNAM},
122 {"Remote I/O error", EREMOTEIO},
123 {"Disk quota exceeded", EDQUOT},
124/* errors from fossil, vacfs, and u9fs */
125 {"fid unknown or out of range", EBADF},
126 {"permission denied", EACCES},
127 {"file does not exist", ENOENT},
128 {"authentication failed", ECONNREFUSED},
129 {"bad offset in directory read", ESPIPE},
130 {"bad use of fid", EBADF},
131 {"wstat can't convert between files and directories", EPERM},
132 {"directory is not empty", ENOTEMPTY},
133 {"file exists", EEXIST},
134 {"file already exists", EEXIST},
135 {"file or directory already exists", EEXIST},
136 {"fid already in use", EBADF},
137 {"file in use", ETXTBSY},
138 {"i/o error", EIO},
139 {"file already open for I/O", ETXTBSY},
140 {"illegal mode", EINVAL},
141 {"illegal name", ENAMETOOLONG},
142 {"not a directory", ENOTDIR},
143 {"not a member of proposed group", EPERM},
144 {"not owner", EACCES},
145 {"only owner can change group in wstat", EACCES},
146 {"read only file system", EROFS},
147 {"no access to special file", EPERM},
148 {"i/o count too large", EIO},
149 {"unknown group", EINVAL},
150 {"unknown user", EINVAL},
151 {"bogus wstat buffer", EPROTO},
152 {"exclusive use file already open", EAGAIN},
153 {"corrupted directory entry", EIO},
154 {"corrupted file entry", EIO},
155 {"corrupted block label", EIO},
156 {"corrupted meta data", EIO},
157 {"illegal offset", EINVAL},
158 {"illegal path element", ENOENT},
159 {"root of file system is corrupted", EIO},
160 {"corrupted super block", EIO},
161 {"protocol botch", EPROTO},
162 {"file system is full", ENOSPC},
163 {"file is in use", EAGAIN},
164 {"directory entry is not allocated", ENOENT},
165 {"file is read only", EROFS},
166 {"file has been removed", EIDRM},
167 {"only support truncation to zero length", EPERM},
168 {"cannot remove root", EPERM},
169 {"file too big", EFBIG},
170 {"venti i/o error", EIO},
171 /* these are not errors */
172 {"u9fs rhostsauth: no authentication required", 0},
173 {"u9fs authnone: no authentication required", 0},
174 {NULL, -1}
175};
176
177extern int v9fs_error_init(void);
178extern int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
new file mode 100644
index 000000000000..821c9c4d76aa
--- /dev/null
+++ b/fs/9p/fid.c
@@ -0,0 +1,241 @@
1/*
2 * V9FS FID Management
3 *
4 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
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:
18 * Free Software Foundation
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02111-1301 USA
21 *
22 */
23
24#include <linux/config.h>
25#include <linux/module.h>
26#include <linux/errno.h>
27#include <linux/fs.h>
28#include <linux/idr.h>
29
30#include "debug.h"
31#include "v9fs.h"
32#include "9p.h"
33#include "v9fs_vfs.h"
34#include "transport.h"
35#include "mux.h"
36#include "conv.h"
37#include "fid.h"
38
39/**
40 * v9fs_fid_insert - add a fid to a dentry
41 * @fid: fid to add
42 * @dentry: dentry that it is being added to
43 *
44 */
45
46static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry)
47{
48 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
49 dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid,
50 dentry->d_iname, dentry);
51 if (dentry->d_fsdata == NULL) {
52 dentry->d_fsdata =
53 kmalloc(sizeof(struct list_head), GFP_KERNEL);
54 if (dentry->d_fsdata == NULL) {
55 dprintk(DEBUG_ERROR, "Out of memory\n");
56 return -ENOMEM;
57 }
58 fid_list = (struct list_head *)dentry->d_fsdata;
59 INIT_LIST_HEAD(fid_list); /* Initialize list head */
60 }
61
62 fid->uid = current->uid;
63 fid->pid = current->pid;
64 list_add(&fid->list, fid_list);
65 return 0;
66}
67
68/**
69 * v9fs_fid_create - allocate a FID structure
70 * @dentry - dentry to link newly created fid to
71 *
72 */
73
74struct v9fs_fid *v9fs_fid_create(struct dentry *dentry)
75{
76 struct v9fs_fid *new;
77
78 new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
79 if (new == NULL) {
80 dprintk(DEBUG_ERROR, "Out of Memory\n");
81 return ERR_PTR(-ENOMEM);
82 }
83
84 new->fid = -1;
85 new->fidopen = 0;
86 new->fidcreate = 0;
87 new->fidclunked = 0;
88 new->iounit = 0;
89
90 if (v9fs_fid_insert(new, dentry) == 0)
91 return new;
92 else {
93 dprintk(DEBUG_ERROR, "Problems inserting to dentry\n");
94 kfree(new);
95 return NULL;
96 }
97}
98
99/**
100 * v9fs_fid_destroy - deallocate a FID structure
101 * @fid: fid to destroy
102 *
103 */
104
105void v9fs_fid_destroy(struct v9fs_fid *fid)
106{
107 list_del(&fid->list);
108 kfree(fid);
109}
110
111/**
112 * v9fs_fid_lookup - retrieve the right fid from a particular dentry
113 * @dentry: dentry to look for fid in
114 * @type: intent of lookup (operation or traversal)
115 *
116 * search list of fids associated with a dentry for a fid with a matching
117 * thread id or uid. If that fails, look up the dentry's parents to see if you
118 * can find a matching fid.
119 *
120 */
121
122struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type)
123{
124 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
125 struct v9fs_fid *current_fid = NULL;
126 struct v9fs_fid *temp = NULL;
127 struct v9fs_fid *return_fid = NULL;
128 int found_parent = 0;
129 int found_user = 0;
130
131 dprintk(DEBUG_9P, " dentry: %s (%p) type %d\n", dentry->d_iname, dentry,
132 type);
133
134 if (fid_list && !list_empty(fid_list)) {
135 list_for_each_entry_safe(current_fid, temp, fid_list, list) {
136 if (current_fid->uid == current->uid) {
137 if (return_fid == NULL) {
138 if ((type == FID_OP)
139 || (!current_fid->fidopen)) {
140 return_fid = current_fid;
141 found_user = 1;
142 }
143 }
144 }
145 if (current_fid->pid == current->real_parent->pid) {
146 if ((return_fid == NULL) || (found_parent)
147 || (found_user)) {
148 if ((type == FID_OP)
149 || (!current_fid->fidopen)) {
150 return_fid = current_fid;
151 found_parent = 1;
152 found_user = 0;
153 }
154 }
155 }
156 if (current_fid->pid == current->pid) {
157 if ((type == FID_OP) ||
158 (!current_fid->fidopen)) {
159 return_fid = current_fid;
160 found_parent = 0;
161 found_user = 0;
162 }
163 }
164 }
165 }
166
167 /* we are at the root but didn't match */
168 if ((!return_fid) && (dentry->d_parent == dentry)) {
169 /* TODO: clone attach with new uid */
170 return_fid = current_fid;
171 }
172
173 if (!return_fid) {
174 struct dentry *par = current->fs->pwd->d_parent;
175 int count = 1;
176 while (par != NULL) {
177 if (par == dentry)
178 break;
179 count++;
180 if (par == par->d_parent) {
181 dprintk(DEBUG_ERROR,
182 "got to root without finding dentry\n");
183 break;
184 }
185 par = par->d_parent;
186 }
187
188/* XXX - there may be some duplication we can get rid of */
189 if (par == dentry) {
190 /* we need to fid_lookup the starting point */
191 int fidnum = -1;
192 int oldfid = -1;
193 int result = -1;
194 struct v9fs_session_info *v9ses =
195 v9fs_inode2v9ses(current->fs->pwd->d_inode);
196
197 current_fid =
198 v9fs_fid_lookup(current->fs->pwd, FID_WALK);
199 if (current_fid == NULL) {
200 dprintk(DEBUG_ERROR,
201 "process cwd doesn't have a fid\n");
202 return return_fid;
203 }
204 oldfid = current_fid->fid;
205 par = current->fs->pwd;
206 /* TODO: take advantage of multiwalk */
207
208 fidnum = v9fs_get_idpool(&v9ses->fidpool);
209 if (fidnum < 0) {
210 dprintk(DEBUG_ERROR,
211 "could not get a new fid num\n");
212 return return_fid;
213 }
214
215 while (par != dentry) {
216 result =
217 v9fs_t_walk(v9ses, oldfid, fidnum, "..",
218 NULL);
219 if (result < 0) {
220 dprintk(DEBUG_ERROR,
221 "problem walking to parent\n");
222
223 break;
224 }
225 oldfid = fidnum;
226 if (par == par->d_parent) {
227 dprintk(DEBUG_ERROR,
228 "can't find dentry\n");
229 break;
230 }
231 par = par->d_parent;
232 }
233 if (par == dentry) {
234 return_fid = v9fs_fid_create(dentry);
235 return_fid->fid = fidnum;
236 }
237 }
238 }
239
240 return return_fid;
241}
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
new file mode 100644
index 000000000000..7db478ccca36
--- /dev/null
+++ b/fs/9p/fid.h
@@ -0,0 +1,57 @@
1/*
2 * V9FS FID Management
3 *
4 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
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:
18 * Free Software Foundation
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02111-1301 USA
21 *
22 */
23
24#include <linux/list.h>
25
26#define FID_OP 0
27#define FID_WALK 1
28
29struct v9fs_fid {
30 struct list_head list; /* list of fids associated with a dentry */
31 struct list_head active; /* XXX - debug */
32
33 u32 fid;
34 unsigned char fidopen; /* set when fid is opened */
35 unsigned char fidcreate; /* set when fid was just created */
36 unsigned char fidclunked; /* set when fid has already been clunked */
37
38 struct v9fs_qid qid;
39 u32 iounit;
40
41 /* readdir stuff */
42 int rdir_fpos;
43 loff_t rdir_pos;
44 struct v9fs_fcall *rdir_fcall;
45
46 /* management stuff */
47 pid_t pid; /* thread associated with this fid */
48 uid_t uid; /* user associated with this fid */
49
50 /* private data */
51 struct file *filp; /* backpointer to File struct for open files */
52 struct v9fs_session_info *v9ses; /* session info for this FID */
53};
54
55struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type);
56void v9fs_fid_destroy(struct v9fs_fid *fid);
57struct v9fs_fid *v9fs_fid_create(struct dentry *);
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
new file mode 100644
index 000000000000..8835b576f744
--- /dev/null
+++ b/fs/9p/mux.c
@@ -0,0 +1,475 @@
1/*
2 * linux/fs/9p/mux.c
3 *
4 * Protocol Multiplexer
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/kthread.h>
32#include <linux/idr.h>
33
34#include "debug.h"
35#include "v9fs.h"
36#include "9p.h"
37#include "transport.h"
38#include "conv.h"
39#include "mux.h"
40
41/**
42 * dprintcond - print condition of session info
43 * @v9ses: session info structure
44 * @req: RPC request structure
45 *
46 */
47
48static inline int
49dprintcond(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
50{
51 dprintk(DEBUG_MUX, "condition: %d, %p\n", v9ses->transport->status,
52 req->rcall);
53 return 0;
54}
55
56/**
57 * xread - force read of a certain number of bytes
58 * @v9ses: session info structure
59 * @ptr: pointer to buffer
60 * @sz: number of bytes to read
61 *
62 * Chuck Cranor CS-533 project1
63 */
64
65static int xread(struct v9fs_session_info *v9ses, void *ptr, unsigned long sz)
66{
67 int rd = 0;
68 int ret = 0;
69 while (rd < sz) {
70 ret = v9ses->transport->read(v9ses->transport, ptr, sz - rd);
71 if (ret <= 0) {
72 dprintk(DEBUG_ERROR, "xread errno %d\n", ret);
73 return ret;
74 }
75 rd += ret;
76 ptr += ret;
77 }
78 return (rd);
79}
80
81/**
82 * read_message - read a full 9P2000 fcall packet
83 * @v9ses: session info structure
84 * @rcall: fcall structure to read into
85 * @rcalllen: size of fcall buffer
86 *
87 */
88
89static int
90read_message(struct v9fs_session_info *v9ses,
91 struct v9fs_fcall *rcall, int rcalllen)
92{
93 unsigned char buf[4];
94 void *data;
95 int size = 0;
96 int res = 0;
97
98 res = xread(v9ses, buf, sizeof(buf));
99 if (res < 0) {
100 dprintk(DEBUG_ERROR,
101 "Reading of count field failed returned: %d\n", res);
102 return res;
103 }
104
105 if (res < 4) {
106 dprintk(DEBUG_ERROR,
107 "Reading of count field failed returned: %d\n", res);
108 return -EIO;
109 }
110
111 size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
112 dprintk(DEBUG_MUX, "got a packet count: %d\n", size);
113
114 /* adjust for the four bytes of size */
115 size -= 4;
116
117 if (size > v9ses->maxdata) {
118 dprintk(DEBUG_ERROR, "packet too big: %d\n", size);
119 return -E2BIG;
120 }
121
122 data = kmalloc(size, GFP_KERNEL);
123 if (!data) {
124 eprintk(KERN_WARNING, "out of memory\n");
125 return -ENOMEM;
126 }
127
128 res = xread(v9ses, data, size);
129 if (res < size) {
130 dprintk(DEBUG_ERROR, "Reading of fcall failed returned: %d\n",
131 res);
132 kfree(data);
133 return res;
134 }
135
136 /* we now have an in-memory string that is the reply.
137 * deserialize it. There is very little to go wrong at this point
138 * save for v9fs_alloc errors.
139 */
140 res = v9fs_deserialize_fcall(v9ses, size, data, v9ses->maxdata,
141 rcall, rcalllen);
142
143 kfree(data);
144
145 if (res < 0)
146 return res;
147
148 return 0;
149}
150
151/**
152 * v9fs_recv - receive an RPC response for a particular tag
153 * @v9ses: session info structure
154 * @req: RPC request structure
155 *
156 */
157
158static int v9fs_recv(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
159{
160 int ret = 0;
161
162 dprintk(DEBUG_MUX, "waiting for response: %d\n", req->tcall->tag);
163 ret = wait_event_interruptible(v9ses->read_wait,
164 ((v9ses->transport->status != Connected) ||
165 (req->rcall != 0) || (req->err < 0) ||
166 dprintcond(v9ses, req)));
167
168 dprintk(DEBUG_MUX, "got it: rcall %p\n", req->rcall);
169
170 spin_lock(&v9ses->muxlock);
171 list_del(&req->next);
172 spin_unlock(&v9ses->muxlock);
173
174 if (req->err < 0)
175 return req->err;
176
177 if (v9ses->transport->status == Disconnected)
178 return -ECONNRESET;
179
180 return ret;
181}
182
183/**
184 * v9fs_send - send a 9P request
185 * @v9ses: session info structure
186 * @req: RPC request to send
187 *
188 */
189
190static int v9fs_send(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
191{
192 int ret = -1;
193 void *data = NULL;
194 struct v9fs_fcall *tcall = req->tcall;
195
196 data = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
197 if (!data)
198 return -ENOMEM;
199
200 tcall->size = 0; /* enforce size recalculation */
201 ret =
202 v9fs_serialize_fcall(v9ses, tcall, data,
203 v9ses->maxdata + V9FS_IOHDRSZ);
204 if (ret < 0)
205 goto free_data;
206
207 spin_lock(&v9ses->muxlock);
208 list_add(&req->next, &v9ses->mux_fcalls);
209 spin_unlock(&v9ses->muxlock);
210
211 dprintk(DEBUG_MUX, "sending message: tag %d size %d\n", tcall->tag,
212 tcall->size);
213 ret = v9ses->transport->write(v9ses->transport, data, tcall->size);
214
215 if (ret != tcall->size) {
216 spin_lock(&v9ses->muxlock);
217 list_del(&req->next);
218 kfree(req->rcall);
219
220 spin_unlock(&v9ses->muxlock);
221 if (ret >= 0)
222 ret = -EREMOTEIO;
223 } else
224 ret = 0;
225
226 free_data:
227 kfree(data);
228 return ret;
229}
230
231/**
232 * v9fs_mux_rpc - send a request, receive a response
233 * @v9ses: session info structure
234 * @tcall: fcall to send
235 * @rcall: buffer to place response into
236 *
237 */
238
239long
240v9fs_mux_rpc(struct v9fs_session_info *v9ses, struct v9fs_fcall *tcall,
241 struct v9fs_fcall **rcall)
242{
243 int tid = -1;
244 struct v9fs_fcall *fcall = NULL;
245 struct v9fs_rpcreq req;
246 int ret = -1;
247
248 if (!v9ses)
249 return -EINVAL;
250
251 if (!v9ses->transport || v9ses->transport->status != Connected)
252 return -EIO;
253
254 if (rcall)
255 *rcall = NULL;
256
257 if (tcall->id != TVERSION) {
258 tid = v9fs_get_idpool(&v9ses->tidpool);
259 if (tid < 0)
260 return -ENOMEM;
261 }
262
263 tcall->tag = tid;
264
265 req.tcall = tcall;
266 req.err = 0;
267 req.rcall = NULL;
268
269 ret = v9fs_send(v9ses, &req);
270
271 if (ret < 0) {
272 if (tcall->id != TVERSION)
273 v9fs_put_idpool(tid, &v9ses->tidpool);
274 dprintk(DEBUG_MUX, "error %d\n", ret);
275 return ret;
276 }
277
278 ret = v9fs_recv(v9ses, &req);
279
280 fcall = req.rcall;
281
282 dprintk(DEBUG_MUX, "received: tag=%x, ret=%d\n", tcall->tag, ret);
283 if (ret == -ERESTARTSYS) {
284 if (v9ses->transport->status != Disconnected
285 && tcall->id != TFLUSH) {
286 unsigned long flags;
287
288 dprintk(DEBUG_MUX, "flushing the tag: %d\n",
289 tcall->tag);
290 clear_thread_flag(TIF_SIGPENDING);
291 v9fs_t_flush(v9ses, tcall->tag);
292 spin_lock_irqsave(&current->sighand->siglock, flags);
293 recalc_sigpending();
294 spin_unlock_irqrestore(&current->sighand->siglock,
295 flags);
296 dprintk(DEBUG_MUX, "flushing done\n");
297 }
298
299 goto release_req;
300 } else if (ret < 0)
301 goto release_req;
302
303 if (!fcall)
304 ret = -EIO;
305 else {
306 if (fcall->id == RERROR) {
307 ret = v9fs_errstr2errno(fcall->params.rerror.error);
308 if (ret == 0) { /* string match failed */
309 if (fcall->params.rerror.errno)
310 ret = -(fcall->params.rerror.errno);
311 else
312 ret = -ESERVERFAULT;
313 }
314 } else if (fcall->id != tcall->id + 1) {
315 dprintk(DEBUG_ERROR,
316 "fcall mismatch: expected %d, got %d\n",
317 tcall->id + 1, fcall->id);
318 ret = -EIO;
319 }
320 }
321
322 release_req:
323 if (tcall->id != TVERSION)
324 v9fs_put_idpool(tid, &v9ses->tidpool);
325 if (rcall)
326 *rcall = fcall;
327 else
328 kfree(fcall);
329
330 return ret;
331}
332
333/**
334 * v9fs_mux_cancel_requests - cancels all pending requests
335 *
336 * @v9ses: session info structure
337 * @err: error code to return to the requests
338 */
339void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err)
340{
341 struct v9fs_rpcreq *rptr;
342 struct v9fs_rpcreq *rreq;
343
344 dprintk(DEBUG_MUX, " %d\n", err);
345 spin_lock(&v9ses->muxlock);
346 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
347 rreq->err = err;
348 }
349 spin_unlock(&v9ses->muxlock);
350 wake_up_all(&v9ses->read_wait);
351}
352
353/**
354 * v9fs_recvproc - kproc to handle demultiplexing responses
355 * @data: session info structure
356 *
357 */
358
359static int v9fs_recvproc(void *data)
360{
361 struct v9fs_session_info *v9ses = (struct v9fs_session_info *)data;
362 struct v9fs_fcall *rcall = NULL;
363 struct v9fs_rpcreq *rptr;
364 struct v9fs_rpcreq *req;
365 struct v9fs_rpcreq *rreq;
366 int err = 0;
367
368 allow_signal(SIGKILL);
369 set_current_state(TASK_INTERRUPTIBLE);
370 complete(&v9ses->proccmpl);
371 while (!kthread_should_stop() && err >= 0) {
372 req = rptr = rreq = NULL;
373
374 rcall = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
375 if (!rcall) {
376 eprintk(KERN_ERR, "no memory for buffers\n");
377 break;
378 }
379
380 err = read_message(v9ses, rcall, v9ses->maxdata + V9FS_IOHDRSZ);
381 spin_lock(&v9ses->muxlock);
382 if (err < 0) {
383 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
384 rreq->err = err;
385 }
386 if(err != -ERESTARTSYS)
387 eprintk(KERN_ERR,
388 "Transport error while reading message %d\n", err);
389 } else {
390 list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
391 if (rreq->tcall->tag == rcall->tag) {
392 req = rreq;
393 req->rcall = rcall;
394 break;
395 }
396 }
397 }
398
399 if (req && (req->tcall->id == TFLUSH)) {
400 struct v9fs_rpcreq *treq = NULL;
401 list_for_each_entry_safe(treq, rptr, &v9ses->mux_fcalls, next) {
402 if (treq->tcall->tag ==
403 req->tcall->params.tflush.oldtag) {
404 list_del(&rptr->next);
405 kfree(treq->rcall);
406 break;
407 }
408 }
409 }
410
411 spin_unlock(&v9ses->muxlock);
412
413 if (!req) {
414 if (err >= 0)
415 dprintk(DEBUG_ERROR,
416 "unexpected response: id %d tag %d\n",
417 rcall->id, rcall->tag);
418
419 kfree(rcall);
420 }
421
422 wake_up_all(&v9ses->read_wait);
423 set_current_state(TASK_INTERRUPTIBLE);
424 }
425
426 v9ses->transport->close(v9ses->transport);
427
428 /* Inform all pending processes about the failure */
429 wake_up_all(&v9ses->read_wait);
430
431 if (signal_pending(current))
432 complete(&v9ses->proccmpl);
433
434 dprintk(DEBUG_MUX, "recvproc: end\n");
435 v9ses->recvproc = NULL;
436
437 return err >= 0;
438}
439
440/**
441 * v9fs_mux_init - initialize multiplexer (spawn kproc)
442 * @v9ses: session info structure
443 * @dev_name: mount device information (to create unique kproc)
444 *
445 */
446
447int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name)
448{
449 char procname[60];
450
451 strncpy(procname, dev_name, sizeof(procname));
452 procname[sizeof(procname) - 1] = 0;
453
454 init_waitqueue_head(&v9ses->read_wait);
455 init_completion(&v9ses->fcread);
456 init_completion(&v9ses->proccmpl);
457 spin_lock_init(&v9ses->muxlock);
458 INIT_LIST_HEAD(&v9ses->mux_fcalls);
459 v9ses->recvproc = NULL;
460 v9ses->curfcall = NULL;
461
462 v9ses->recvproc = kthread_create(v9fs_recvproc, v9ses,
463 "v9fs_recvproc %s", procname);
464
465 if (IS_ERR(v9ses->recvproc)) {
466 eprintk(KERN_ERR, "cannot create receiving thread\n");
467 v9fs_session_close(v9ses);
468 return -ECONNABORTED;
469 }
470
471 wake_up_process(v9ses->recvproc);
472 wait_for_completion(&v9ses->proccmpl);
473
474 return 0;
475}
diff --git a/fs/9p/mux.h b/fs/9p/mux.h
new file mode 100644
index 000000000000..4994cb10badf
--- /dev/null
+++ b/fs/9p/mux.h
@@ -0,0 +1,41 @@
1/*
2 * linux/fs/9p/mux.h
3 *
4 * Multiplexer Definitions
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.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:
20 * Free Software Foundation
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02111-1301 USA
23 *
24 */
25
26/* structure to manage each RPC transaction */
27
28struct v9fs_rpcreq {
29 struct v9fs_fcall *tcall;
30 struct v9fs_fcall *rcall;
31 int err; /* error code if response failed */
32
33 /* XXX - could we put scatter/gather buffers here? */
34
35 struct list_head next;
36};
37
38int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name);
39long v9fs_mux_rpc(struct v9fs_session_info *v9ses,
40 struct v9fs_fcall *tcall, struct v9fs_fcall **rcall);
41void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err);
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c
new file mode 100644
index 000000000000..63b58ce98ff4
--- /dev/null
+++ b/fs/9p/trans_fd.c
@@ -0,0 +1,172 @@
1/*
2 * linux/fs/9p/trans_fd.c
3 *
4 * File Descriptor Transport Layer
5 *
6 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.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:
20 * Free Software Foundation
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02111-1301 USA
23 *
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/net.h>
29#include <linux/ipv6.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
32#include <linux/un.h>
33#include <asm/uaccess.h>
34#include <linux/inet.h>
35#include <linux/idr.h>
36#include <linux/file.h>
37
38#include "debug.h"
39#include "v9fs.h"
40#include "transport.h"
41
42struct v9fs_trans_fd {
43 struct file *in_file;
44 struct file *out_file;
45};
46
47/**
48 * v9fs_fd_recv - receive from a socket
49 * @v9ses: session information
50 * @v: buffer to receive data into
51 * @len: size of receive buffer
52 *
53 */
54
55static int v9fs_fd_recv(struct v9fs_transport *trans, void *v, int len)
56{
57 struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;
58
59 if (!trans || trans->status != Connected || !ts)
60 return -EIO;
61
62 return kernel_read(ts->in_file, ts->in_file->f_pos, v, len);
63}
64
65/**
66 * v9fs_fd_send - send to a socket
67 * @v9ses: session information
68 * @v: buffer to send data from
69 * @len: size of send buffer
70 *
71 */
72
73static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len)
74{
75 struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;
76 mm_segment_t oldfs = get_fs();
77 int ret = 0;
78
79 if (!trans || trans->status != Connected || !ts)
80 return -EIO;
81
82 set_fs(get_ds());
83 /* The cast to a user pointer is valid due to the set_fs() */
84 ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos);
85 set_fs(oldfs);
86
87 return ret;
88}
89
90/**
91 * v9fs_fd_init - initialize file descriptor transport
92 * @v9ses: session information
93 * @addr: address of server to mount
94 * @data: mount options
95 *
96 */
97
98static int
99v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
100{
101 struct v9fs_trans_fd *ts = NULL;
102 struct v9fs_transport *trans = v9ses->transport;
103
104 if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) {
105 printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
106 return -ENOPROTOOPT;
107 }
108
109 sema_init(&trans->writelock, 1);
110 sema_init(&trans->readlock, 1);
111
112 ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL);
113
114 if (!ts)
115 return -ENOMEM;
116
117 ts->in_file = fget( v9ses->rfdno );
118 ts->out_file = fget( v9ses->wfdno );
119
120 if (!ts->in_file || !ts->out_file) {
121 if (ts->in_file)
122 fput(ts->in_file);
123
124 if (ts->out_file)
125 fput(ts->out_file);
126
127 kfree(ts);
128 return -EIO;
129 }
130
131 trans->priv = ts;
132 trans->status = Connected;
133
134 return 0;
135}
136
137
138/**
139 * v9fs_fd_close - shutdown file descriptor
140 * @trans: private socket structure
141 *
142 */
143
144static void v9fs_fd_close(struct v9fs_transport *trans)
145{
146 struct v9fs_trans_fd *ts;
147
148 if (!trans)
149 return;
150
151 trans->status = Disconnected;
152 ts = trans->priv;
153
154 if (!ts)
155 return;
156
157 if (ts->in_file)
158 fput(ts->in_file);
159
160 if (ts->out_file)
161 fput(ts->out_file);
162
163 kfree(ts);
164}
165
166struct v9fs_transport v9fs_trans_fd = {
167 .init = v9fs_fd_init,
168 .write = v9fs_fd_send,
169 .read = v9fs_fd_recv,
170 .close = v9fs_fd_close,
171};
172
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
new file mode 100644
index 000000000000..01e26f0013ac
--- /dev/null
+++ b/fs/9p/trans_sock.c
@@ -0,0 +1,290 @@
1/*
2 * linux/fs/9p/trans_socket.c
3 *
4 * Socket Transport Layer
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
8 * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.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:
22 * Free Software Foundation
23 * 51 Franklin Street, Fifth Floor
24 * Boston, MA 02111-1301 USA
25 *
26 */
27
28#include <linux/config.h>
29#include <linux/module.h>
30#include <linux/net.h>
31#include <linux/ipv6.h>
32#include <linux/errno.h>
33#include <linux/kernel.h>
34#include <linux/un.h>
35#include <asm/uaccess.h>
36#include <linux/inet.h>
37#include <linux/idr.h>
38
39#include "debug.h"
40#include "v9fs.h"
41#include "transport.h"
42
43#define V9FS_PORT 564
44
45struct v9fs_trans_sock {
46 struct socket *s;
47};
48
49/**
50 * v9fs_sock_recv - receive from a socket
51 * @v9ses: session information
52 * @v: buffer to receive data into
53 * @len: size of receive buffer
54 *
55 */
56
57static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
58{
59 struct msghdr msg;
60 struct kvec iov;
61 int result;
62 mm_segment_t oldfs;
63 struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
64
65 if (trans->status == Disconnected)
66 return -EREMOTEIO;
67
68 result = -EINVAL;
69
70 oldfs = get_fs();
71 set_fs(get_ds());
72
73 iov.iov_base = v;
74 iov.iov_len = len;
75 msg.msg_name = NULL;
76 msg.msg_namelen = 0;
77 msg.msg_iovlen = 1;
78 msg.msg_control = NULL;
79 msg.msg_controllen = 0;
80 msg.msg_namelen = 0;
81 msg.msg_flags = MSG_NOSIGNAL;
82
83 result = kernel_recvmsg(ts->s, &msg, &iov, 1, len, 0);
84
85 dprintk(DEBUG_TRANS, "socket state %d\n", ts->s->state);
86 set_fs(oldfs);
87
88 if (result <= 0) {
89 if (result != -ERESTARTSYS)
90 trans->status = Disconnected;
91 }
92
93 return result;
94}
95
96/**
97 * v9fs_sock_send - send to a socket
98 * @v9ses: session information
99 * @v: buffer to send data from
100 * @len: size of send buffer
101 *
102 */
103
104static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
105{
106 struct kvec iov;
107 struct msghdr msg;
108 int result = -1;
109 mm_segment_t oldfs;
110 struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
111
112 dprintk(DEBUG_TRANS, "Sending packet size %d (%x)\n", len, len);
113 dump_data(v, len);
114
115 down(&trans->writelock);
116
117 oldfs = get_fs();
118 set_fs(get_ds());
119 iov.iov_base = v;
120 iov.iov_len = len;
121 msg.msg_name = NULL;
122 msg.msg_namelen = 0;
123 msg.msg_iovlen = 1;
124 msg.msg_control = NULL;
125 msg.msg_controllen = 0;
126 msg.msg_namelen = 0;
127 msg.msg_flags = MSG_NOSIGNAL;
128 result = kernel_sendmsg(ts->s, &msg, &iov, 1, len);
129 set_fs(oldfs);
130
131 if (result < 0) {
132 if (result != -ERESTARTSYS)
133 trans->status = Disconnected;
134 }
135
136 up(&trans->writelock);
137 return result;
138}
139
140/**
141 * v9fs_tcp_init - initialize TCP socket
142 * @v9ses: session information
143 * @addr: address of server to mount
144 * @data: mount options
145 *
146 */
147
148static int
149v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
150{
151 struct socket *csocket = NULL;
152 struct sockaddr_in sin_server;
153 int rc = 0;
154 struct v9fs_trans_sock *ts = NULL;
155 struct v9fs_transport *trans = v9ses->transport;
156
157 sema_init(&trans->writelock, 1);
158 sema_init(&trans->readlock, 1);
159
160 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
161
162 if (!ts)
163 return -ENOMEM;
164
165 trans->priv = ts;
166 ts->s = NULL;
167
168 if (!addr)
169 return -EINVAL;
170
171 dprintk(DEBUG_TRANS, "Connecting to %s\n", addr);
172
173 sin_server.sin_family = AF_INET;
174 sin_server.sin_addr.s_addr = in_aton(addr);
175 sin_server.sin_port = htons(v9ses->port);
176 sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
177 rc = csocket->ops->connect(csocket,
178 (struct sockaddr *)&sin_server,
179 sizeof(struct sockaddr_in), 0);
180 if (rc < 0) {
181 eprintk(KERN_ERR,
182 "v9fs_trans_tcp: problem connecting socket to %s\n",
183 addr);
184 return rc;
185 }
186 csocket->sk->sk_allocation = GFP_NOIO;
187 ts->s = csocket;
188 trans->status = Connected;
189
190 return 0;
191}
192
193/**
194 * v9fs_unix_init - initialize UNIX domain socket
195 * @v9ses: session information
196 * @dev_name: path to named pipe
197 * @data: mount options
198 *
199 */
200
201static int
202v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
203 char *data)
204{
205 int rc;
206 struct socket *csocket;
207 struct sockaddr_un sun_server;
208 struct v9fs_transport *trans;
209 struct v9fs_trans_sock *ts;
210
211 rc = 0;
212 csocket = NULL;
213 trans = v9ses->transport;
214
215 if (strlen(dev_name) > UNIX_PATH_MAX) {
216 eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
217 dev_name);
218 return -ENOMEM;
219 }
220
221 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
222 if (!ts)
223 return -ENOMEM;
224
225 trans->priv = ts;
226 ts->s = NULL;
227
228 sema_init(&trans->writelock, 1);
229 sema_init(&trans->readlock, 1);
230
231 sun_server.sun_family = PF_UNIX;
232 strcpy(sun_server.sun_path, dev_name);
233 sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
234 rc = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
235 sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */
236 if (rc < 0) {
237 eprintk(KERN_ERR,
238 "v9fs_trans_unix: problem connecting socket: %s: %d\n",
239 dev_name, rc);
240 return rc;
241 }
242 csocket->sk->sk_allocation = GFP_NOIO;
243 ts->s = csocket;
244 trans->status = Connected;
245
246 return 0;
247}
248
249/**
250 * v9fs_sock_close - shutdown socket
251 * @trans: private socket structure
252 *
253 */
254
255static void v9fs_sock_close(struct v9fs_transport *trans)
256{
257 struct v9fs_trans_sock *ts;
258
259 if (!trans)
260 return;
261
262 ts = trans->priv;
263
264 if ((ts) && (ts->s)) {
265 dprintk(DEBUG_TRANS, "closing the socket %p\n", ts->s);
266 sock_release(ts->s);
267 ts->s = NULL;
268 trans->status = Disconnected;
269 dprintk(DEBUG_TRANS, "socket closed\n");
270 }
271
272 if (ts)
273 kfree(ts);
274
275 trans->priv = NULL;
276}
277
278struct v9fs_transport v9fs_trans_tcp = {
279 .init = v9fs_tcp_init,
280 .write = v9fs_sock_send,
281 .read = v9fs_sock_recv,
282 .close = v9fs_sock_close,
283};
284
285struct v9fs_transport v9fs_trans_unix = {
286 .init = v9fs_unix_init,
287 .write = v9fs_sock_send,
288 .read = v9fs_sock_recv,
289 .close = v9fs_sock_close,
290};
diff --git a/fs/9p/transport.h b/fs/9p/transport.h
new file mode 100644
index 000000000000..9e9cd418efd5
--- /dev/null
+++ b/fs/9p/transport.h
@@ -0,0 +1,46 @@
1/*
2 * linux/fs/9p/transport.h
3 *
4 * Transport Definition
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.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:
20 * Free Software Foundation
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02111-1301 USA
23 *
24 */
25
26enum v9fs_transport_status {
27 Connected,
28 Disconnected,
29 Hung,
30};
31
32struct v9fs_transport {
33 enum v9fs_transport_status status;
34 struct semaphore writelock;
35 struct semaphore readlock;
36 void *priv;
37
38 int (*init) (struct v9fs_session_info *, const char *, char *);
39 int (*write) (struct v9fs_transport *, void *, int);
40 int (*read) (struct v9fs_transport *, void *, int);
41 void (*close) (struct v9fs_transport *);
42};
43
44extern struct v9fs_transport v9fs_trans_tcp;
45extern struct v9fs_transport v9fs_trans_unix;
46extern struct v9fs_transport v9fs_trans_fd;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
new file mode 100644
index 000000000000..13bdbbab4387
--- /dev/null
+++ b/fs/9p/v9fs.c
@@ -0,0 +1,452 @@
1/*
2 * linux/fs/9p/v9fs.c
3 *
4 * This file contains functions assisting in mapping VFS to 9P2000
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/parser.h>
32#include <linux/idr.h>
33
34#include "debug.h"
35#include "v9fs.h"
36#include "9p.h"
37#include "v9fs_vfs.h"
38#include "transport.h"
39#include "mux.h"
40#include "conv.h"
41
42/* TODO: sysfs or debugfs interface */
43int v9fs_debug_level = 0; /* feature-rific global debug level */
44
45/*
46 * Option Parsing (code inspired by NFS code)
47 *
48 */
49
50enum {
51 /* Options that take integer arguments */
52 Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug,
53 Opt_rfdno, Opt_wfdno,
54 /* String options */
55 Opt_name, Opt_remotename,
56 /* Options that take no arguments */
57 Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
58 /* Error token */
59 Opt_err
60};
61
62static match_table_t tokens = {
63 {Opt_port, "port=%u"},
64 {Opt_msize, "msize=%u"},
65 {Opt_uid, "uid=%u"},
66 {Opt_gid, "gid=%u"},
67 {Opt_afid, "afid=%u"},
68 {Opt_rfdno, "rfdno=%u"},
69 {Opt_wfdno, "wfdno=%u"},
70 {Opt_debug, "debug=%u"},
71 {Opt_name, "name=%s"},
72 {Opt_remotename, "aname=%s"},
73 {Opt_unix, "proto=unix"},
74 {Opt_tcp, "proto=tcp"},
75 {Opt_fd, "proto=fd"},
76 {Opt_tcp, "tcp"},
77 {Opt_unix, "unix"},
78 {Opt_fd, "fd"},
79 {Opt_legacy, "noextend"},
80 {Opt_nodevmap, "nodevmap"},
81 {Opt_err, NULL}
82};
83
84/*
85 * Parse option string.
86 */
87
88/**
89 * v9fs_parse_options - parse mount options into session structure
90 * @options: options string passed from mount
91 * @v9ses: existing v9fs session information
92 *
93 */
94
95static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
96{
97 char *p;
98 substring_t args[MAX_OPT_ARGS];
99 int option;
100 int ret;
101
102 /* setup defaults */
103 v9ses->port = V9FS_PORT;
104 v9ses->maxdata = 9000;
105 v9ses->proto = PROTO_TCP;
106 v9ses->extended = 1;
107 v9ses->afid = ~0;
108 v9ses->debug = 0;
109 v9ses->rfdno = ~0;
110 v9ses->wfdno = ~0;
111
112 if (!options)
113 return;
114
115 while ((p = strsep(&options, ",")) != NULL) {
116 int token;
117 if (!*p)
118 continue;
119 token = match_token(p, tokens, args);
120 if (token < Opt_name) {
121 if ((ret = match_int(&args[0], &option)) < 0) {
122 dprintk(DEBUG_ERROR,
123 "integer field, but no integer?\n");
124 continue;
125 }
126
127 }
128 switch (token) {
129 case Opt_port:
130 v9ses->port = option;
131 break;
132 case Opt_msize:
133 v9ses->maxdata = option;
134 break;
135 case Opt_uid:
136 v9ses->uid = option;
137 break;
138 case Opt_gid:
139 v9ses->gid = option;
140 break;
141 case Opt_afid:
142 v9ses->afid = option;
143 break;
144 case Opt_rfdno:
145 v9ses->rfdno = option;
146 break;
147 case Opt_wfdno:
148 v9ses->wfdno = option;
149 break;
150 case Opt_debug:
151 v9ses->debug = option;
152 break;
153 case Opt_tcp:
154 v9ses->proto = PROTO_TCP;
155 break;
156 case Opt_unix:
157 v9ses->proto = PROTO_UNIX;
158 break;
159 case Opt_fd:
160 v9ses->proto = PROTO_FD;
161 break;
162 case Opt_name:
163 match_strcpy(v9ses->name, &args[0]);
164 break;
165 case Opt_remotename:
166 match_strcpy(v9ses->remotename, &args[0]);
167 break;
168 case Opt_legacy:
169 v9ses->extended = 0;
170 break;
171 case Opt_nodevmap:
172 v9ses->nodev = 1;
173 break;
174 default:
175 continue;
176 }
177 }
178}
179
180/**
181 * v9fs_inode2v9ses - safely extract v9fs session info from super block
182 * @inode: inode to extract information from
183 *
184 * Paranoid function to extract v9ses information from superblock,
185 * if anything is missing it will report an error.
186 *
187 */
188
189struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
190{
191 return (inode->i_sb->s_fs_info);
192}
193
194/**
195 * v9fs_get_idpool - allocate numeric id from pool
196 * @p - pool to allocate from
197 *
198 * XXX - This seems to be an awful generic function, should it be in idr.c with
199 * the lock included in struct idr?
200 */
201
202int v9fs_get_idpool(struct v9fs_idpool *p)
203{
204 int i = 0;
205 int error;
206
207retry:
208 if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
209 return 0;
210
211 if (down_interruptible(&p->lock) == -EINTR) {
212 eprintk(KERN_WARNING, "Interrupted while locking\n");
213 return -1;
214 }
215
216 error = idr_get_new(&p->pool, NULL, &i);
217 up(&p->lock);
218
219 if (error == -EAGAIN)
220 goto retry;
221 else if (error)
222 return -1;
223
224 return i;
225}
226
227/**
228 * v9fs_put_idpool - release numeric id from pool
229 * @p - pool to allocate from
230 *
231 * XXX - This seems to be an awful generic function, should it be in idr.c with
232 * the lock included in struct idr?
233 */
234
235void v9fs_put_idpool(int id, struct v9fs_idpool *p)
236{
237 if (down_interruptible(&p->lock) == -EINTR) {
238 eprintk(KERN_WARNING, "Interrupted while locking\n");
239 return;
240 }
241 idr_remove(&p->pool, id);
242 up(&p->lock);
243}
244
245/**
246 * v9fs_session_init - initialize session
247 * @v9ses: session information structure
248 * @dev_name: device being mounted
249 * @data: options
250 *
251 */
252
253int
254v9fs_session_init(struct v9fs_session_info *v9ses,
255 const char *dev_name, char *data)
256{
257 struct v9fs_fcall *fcall = NULL;
258 struct v9fs_transport *trans_proto;
259 int n = 0;
260 int newfid = -1;
261 int retval = -EINVAL;
262
263 v9ses->name = __getname();
264 if (!v9ses->name)
265 return -ENOMEM;
266
267 v9ses->remotename = __getname();
268 if (!v9ses->remotename) {
269 putname(v9ses->name);
270 return -ENOMEM;
271 }
272
273 strcpy(v9ses->name, V9FS_DEFUSER);
274 strcpy(v9ses->remotename, V9FS_DEFANAME);
275
276 v9fs_parse_options(data, v9ses);
277
278 /* set global debug level */
279 v9fs_debug_level = v9ses->debug;
280
281 /* id pools that are session-dependent: FIDs and TIDs */
282 idr_init(&v9ses->fidpool.pool);
283 init_MUTEX(&v9ses->fidpool.lock);
284 idr_init(&v9ses->tidpool.pool);
285 init_MUTEX(&v9ses->tidpool.lock);
286
287
288 switch (v9ses->proto) {
289 case PROTO_TCP:
290 trans_proto = &v9fs_trans_tcp;
291 break;
292 case PROTO_UNIX:
293 trans_proto = &v9fs_trans_unix;
294 *v9ses->remotename = 0;
295 break;
296 case PROTO_FD:
297 trans_proto = &v9fs_trans_fd;
298 *v9ses->remotename = 0;
299 break;
300 default:
301 printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
302 retval = -ENOPROTOOPT;
303 goto SessCleanUp;
304 };
305
306 v9ses->transport = trans_proto;
307
308 if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) {
309 eprintk(KERN_ERR, "problem initializing transport\n");
310 goto SessCleanUp;
311 }
312
313 v9ses->inprogress = 0;
314 v9ses->shutdown = 0;
315 v9ses->session_hung = 0;
316
317 if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) {
318 dprintk(DEBUG_ERROR, "problem initializing mux\n");
319 goto SessCleanUp;
320 }
321
322 if (v9ses->afid == ~0) {
323 if (v9ses->extended)
324 retval =
325 v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u",
326 &fcall);
327 else
328 retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000",
329 &fcall);
330
331 if (retval < 0) {
332 dprintk(DEBUG_ERROR, "v9fs_t_version failed\n");
333 goto FreeFcall;
334 }
335
336 /* Really should check for 9P1 and report error */
337 if (!strcmp(fcall->params.rversion.version, "9P2000.u")) {
338 dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
339 v9ses->extended = 1;
340 } else {
341 dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
342 v9ses->extended = 0;
343 }
344
345 n = fcall->params.rversion.msize;
346 kfree(fcall);
347
348 if (n < v9ses->maxdata)
349 v9ses->maxdata = n;
350 }
351
352 newfid = v9fs_get_idpool(&v9ses->fidpool);
353 if (newfid < 0) {
354 eprintk(KERN_WARNING, "couldn't allocate FID\n");
355 retval = -ENOMEM;
356 goto SessCleanUp;
357 }
358 /* it is a little bit ugly, but we have to prevent newfid */
359 /* being the same as afid, so if it is, get a new fid */
360 if (v9ses->afid != ~0 && newfid == v9ses->afid) {
361 newfid = v9fs_get_idpool(&v9ses->fidpool);
362 if (newfid < 0) {
363 eprintk(KERN_WARNING, "couldn't allocate FID\n");
364 retval = -ENOMEM;
365 goto SessCleanUp;
366 }
367 }
368
369 if ((retval =
370 v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid,
371 v9ses->afid, NULL))
372 < 0) {
373 dprintk(DEBUG_ERROR, "cannot attach\n");
374 goto SessCleanUp;
375 }
376
377 if (v9ses->afid != ~0) {
378 if (v9fs_t_clunk(v9ses, v9ses->afid, NULL))
379 dprintk(DEBUG_ERROR, "clunk failed\n");
380 }
381
382 return newfid;
383
384 FreeFcall:
385 kfree(fcall);
386
387 SessCleanUp:
388 v9fs_session_close(v9ses);
389 return retval;
390}
391
392/**
393 * v9fs_session_close - shutdown a session
394 * @v9ses: session information structure
395 *
396 */
397
398void v9fs_session_close(struct v9fs_session_info *v9ses)
399{
400 if (v9ses->recvproc) {
401 send_sig(SIGKILL, v9ses->recvproc, 1);
402 wait_for_completion(&v9ses->proccmpl);
403 }
404
405 if (v9ses->transport)
406 v9ses->transport->close(v9ses->transport);
407
408 putname(v9ses->name);
409 putname(v9ses->remotename);
410}
411
412/**
413 * v9fs_session_cancel - mark transport as disconnected
414 * and cancel all pending requests.
415 */
416void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
417 v9ses->transport->status = Disconnected;
418 v9fs_mux_cancel_requests(v9ses, -EIO);
419}
420
421extern int v9fs_error_init(void);
422
423/**
424 * v9fs_init - Initialize module
425 *
426 */
427
428static int __init init_v9fs(void)
429{
430 v9fs_error_init();
431
432 printk(KERN_INFO "Installing v9fs 9P2000 file system support\n");
433
434 return register_filesystem(&v9fs_fs_type);
435}
436
437/**
438 * v9fs_init - shutdown module
439 *
440 */
441
442static void __exit exit_v9fs(void)
443{
444 unregister_filesystem(&v9fs_fs_type);
445}
446
447module_init(init_v9fs)
448module_exit(exit_v9fs)
449
450MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
451MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
452MODULE_LICENSE("GPL");
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
new file mode 100644
index 000000000000..45dcef42bdd6
--- /dev/null
+++ b/fs/9p/v9fs.h
@@ -0,0 +1,103 @@
1/*
2 * V9FS definitions.
3 *
4 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
19 * Free Software Foundation
20 * 51 Franklin Street, Fifth Floor
21 * Boston, MA 02111-1301 USA
22 *
23 */
24
25/*
26 * Idpool structure provides lock and id management
27 *
28 */
29
30struct v9fs_idpool {
31 struct semaphore lock;
32 struct idr pool;
33};
34
35/*
36 * Session structure provides information for an opened session
37 *
38 */
39
40struct v9fs_session_info {
41 /* options */
42 unsigned int maxdata;
43 unsigned char extended; /* set to 1 if we are using UNIX extensions */
44 unsigned char nodev; /* set to 1 if no disable device mapping */
45 unsigned short port; /* port to connect to */
46 unsigned short debug; /* debug level */
47 unsigned short proto; /* protocol to use */
48 unsigned int afid; /* authentication fid */
49 unsigned int rfdno; /* read file descriptor number */
50 unsigned int wfdno; /* write file descriptor number */
51
52
53 char *name; /* user name to mount as */
54 char *remotename; /* name of remote hierarchy being mounted */
55 unsigned int uid; /* default uid/muid for legacy support */
56 unsigned int gid; /* default gid for legacy support */
57
58 /* book keeping */
59 struct v9fs_idpool fidpool; /* The FID pool for file descriptors */
60 struct v9fs_idpool tidpool; /* The TID pool for transactions ids */
61
62 /* transport information */
63 struct v9fs_transport *transport;
64
65 int inprogress; /* session in progress => true */
66 int shutdown; /* session shutting down. no more attaches. */
67 unsigned char session_hung;
68
69 /* mux private data */
70 struct v9fs_fcall *curfcall;
71 wait_queue_head_t read_wait;
72 struct completion fcread;
73 struct completion proccmpl;
74 struct task_struct *recvproc;
75
76 spinlock_t muxlock;
77 struct list_head mux_fcalls;
78};
79
80/* possible values of ->proto */
81enum {
82 PROTO_TCP,
83 PROTO_UNIX,
84 PROTO_FD,
85};
86
87int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
88struct v9fs_session_info *v9fs_inode2v9ses(struct inode *);
89void v9fs_session_close(struct v9fs_session_info *v9ses);
90int v9fs_get_idpool(struct v9fs_idpool *p);
91void v9fs_put_idpool(int id, struct v9fs_idpool *p);
92void v9fs_session_cancel(struct v9fs_session_info *v9ses);
93
94#define V9FS_MAGIC 0x01021997
95
96/* other default globals */
97#define V9FS_PORT 564
98#define V9FS_DEFUSER "nobody"
99#define V9FS_DEFANAME ""
100
101/* inital pool sizes for fids and tags */
102#define V9FS_START_FIDS 8192
103#define V9FS_START_TIDS 256
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
new file mode 100644
index 000000000000..2f2cea7ee3e7
--- /dev/null
+++ b/fs/9p/v9fs_vfs.h
@@ -0,0 +1,53 @@
1/*
2 * V9FS VFS extensions.
3 *
4 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
19 * Free Software Foundation
20 * 51 Franklin Street, Fifth Floor
21 * Boston, MA 02111-1301 USA
22 *
23 */
24
25/* plan9 semantics are that created files are implicitly opened.
26 * But linux semantics are that you call create, then open.
27 * the plan9 approach is superior as it provides an atomic
28 * open.
29 * we track the create fid here. When the file is opened, if fidopen is
30 * non-zero, we use the fid and can skip some steps.
31 * there may be a better way to do this, but I don't know it.
32 * one BAD way is to clunk the fid on create, then open it again:
33 * you lose the atomicity of file open
34 */
35
36/* special case:
37 * unlink calls remove, which is an implicit clunk. So we have to track
38 * that kind of thing so that we don't try to clunk a dead fid.
39 */
40
41extern struct file_system_type v9fs_fs_type;
42extern struct file_operations v9fs_file_operations;
43extern struct file_operations v9fs_dir_operations;
44extern struct dentry_operations v9fs_dentry_operations;
45
46struct inode *v9fs_get_inode(struct super_block *sb, int mode);
47ino_t v9fs_qid2ino(struct v9fs_qid *qid);
48void v9fs_mistat2inode(struct v9fs_stat *, struct inode *,
49 struct super_block *);
50int v9fs_dir_release(struct inode *inode, struct file *filp);
51int v9fs_file_open(struct inode *inode, struct file *file);
52void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat);
53void v9fs_dentry_release(struct dentry *);
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
new file mode 100644
index 000000000000..306c96741f81
--- /dev/null
+++ b/fs/9p/vfs_dentry.c
@@ -0,0 +1,126 @@
1/*
2 * linux/fs/9p/vfs_dentry.c
3 *
4 * This file contians vfs dentry ops for the 9P2000 protocol.
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/file.h>
31#include <linux/pagemap.h>
32#include <linux/stat.h>
33#include <linux/string.h>
34#include <linux/smp_lock.h>
35#include <linux/inet.h>
36#include <linux/namei.h>
37#include <linux/idr.h>
38
39#include "debug.h"
40#include "v9fs.h"
41#include "9p.h"
42#include "v9fs_vfs.h"
43#include "conv.h"
44#include "fid.h"
45
46/**
47 * v9fs_dentry_validate - VFS dcache hook to validate cache
48 * @dentry: dentry that is being validated
49 * @nd: path data
50 *
51 * dcache really shouldn't be used for 9P2000 as at all due to
52 * potential attached semantics to directory traversal (walk).
53 *
54 * FUTURE: look into how to use dcache to allow multi-stage
55 * walks in Plan 9 & potential for better dcache operation which
56 * would remain valid for Plan 9 semantics. Older versions
57 * had validation via stat for those interested. However, since
58 * stat has the same approximate overhead as walk there really
59 * is no difference. The only improvement would be from a
60 * time-decay cache like NFS has and that undermines the
61 * synchronous nature of 9P2000.
62 *
63 */
64
65static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd)
66{
67 struct dentry *dc = current->fs->pwd;
68
69 dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry);
70 if (v9fs_fid_lookup(dentry, FID_OP)) {
71 dprintk(DEBUG_VFS, "VALID\n");
72 return 1;
73 }
74
75 while (dc != NULL) {
76 if (dc == dentry) {
77 dprintk(DEBUG_VFS, "VALID\n");
78 return 1;
79 }
80 if (dc == dc->d_parent)
81 break;
82
83 dc = dc->d_parent;
84 }
85
86 dprintk(DEBUG_VFS, "INVALID\n");
87 return 0;
88}
89
90/**
91 * v9fs_dentry_release - called when dentry is going to be freed
92 * @dentry: dentry that is being release
93 *
94 */
95
96void v9fs_dentry_release(struct dentry *dentry)
97{
98 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
99
100 if (dentry->d_fsdata != NULL) {
101 struct list_head *fid_list = dentry->d_fsdata;
102 struct v9fs_fid *temp = NULL;
103 struct v9fs_fid *current_fid = NULL;
104 struct v9fs_fcall *fcall = NULL;
105
106 list_for_each_entry_safe(current_fid, temp, fid_list, list) {
107 if (v9fs_t_clunk
108 (current_fid->v9ses, current_fid->fid, &fcall))
109 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
110 FCALL_ERROR(fcall));
111
112 v9fs_put_idpool(current_fid->fid,
113 &current_fid->v9ses->fidpool);
114
115 kfree(fcall);
116 v9fs_fid_destroy(current_fid);
117 }
118
119 kfree(dentry->d_fsdata); /* free the list_head */
120 }
121}
122
123struct dentry_operations v9fs_dentry_operations = {
124 .d_revalidate = v9fs_dentry_validate,
125 .d_release = v9fs_dentry_release,
126};
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
new file mode 100644
index 000000000000..c478a7384186
--- /dev/null
+++ b/fs/9p/vfs_dir.c
@@ -0,0 +1,226 @@
1/*
2 * linux/fs/9p/vfs_dir.c
3 *
4 * This file contains vfs directory ops for the 9P2000 protocol.
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/file.h>
31#include <linux/stat.h>
32#include <linux/string.h>
33#include <linux/smp_lock.h>
34#include <linux/inet.h>
35#include <linux/idr.h>
36
37#include "debug.h"
38#include "v9fs.h"
39#include "9p.h"
40#include "v9fs_vfs.h"
41#include "conv.h"
42#include "fid.h"
43
44/**
45 * dt_type - return file type
46 * @mistat: mistat structure
47 *
48 */
49
50static inline int dt_type(struct v9fs_stat *mistat)
51{
52 unsigned long perm = mistat->mode;
53 int rettype = DT_REG;
54
55 if (perm & V9FS_DMDIR)
56 rettype = DT_DIR;
57 if (perm & V9FS_DMSYMLINK)
58 rettype = DT_LNK;
59
60 return rettype;
61}
62
63/**
64 * v9fs_dir_readdir - read a directory
65 * @filep: opened file structure
66 * @dirent: directory structure ???
67 * @filldir: function to populate directory structure ???
68 *
69 */
70
71static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
72{
73 struct v9fs_fcall *fcall = NULL;
74 struct inode *inode = filp->f_dentry->d_inode;
75 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
76 struct v9fs_fid *file = filp->private_data;
77 unsigned int i, n;
78 int fid = -1;
79 int ret = 0;
80 struct v9fs_stat *mi = NULL;
81 int over = 0;
82
83 dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name);
84
85 fid = file->fid;
86
87 mi = kmalloc(v9ses->maxdata, GFP_KERNEL);
88 if (!mi)
89 return -ENOMEM;
90
91 if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) {
92 kfree(file->rdir_fcall);
93 file->rdir_fcall = NULL;
94 }
95
96 if (file->rdir_fcall) {
97 n = file->rdir_fcall->params.rread.count;
98 i = file->rdir_fpos;
99 while (i < n) {
100 int s = v9fs_deserialize_stat(v9ses,
101 file->rdir_fcall->params.rread.data + i,
102 n - i, mi, v9ses->maxdata);
103
104 if (s == 0) {
105 dprintk(DEBUG_ERROR,
106 "error while deserializing mistat\n");
107 ret = -EIO;
108 goto FreeStructs;
109 }
110
111 over = filldir(dirent, mi->name, strlen(mi->name),
112 filp->f_pos, v9fs_qid2ino(&mi->qid),
113 dt_type(mi));
114
115 if (over) {
116 file->rdir_fpos = i;
117 file->rdir_pos = filp->f_pos;
118 break;
119 }
120
121 i += s;
122 filp->f_pos += s;
123 }
124
125 if (!over) {
126 kfree(file->rdir_fcall);
127 file->rdir_fcall = NULL;
128 }
129 }
130
131 while (!over) {
132 ret = v9fs_t_read(v9ses, fid, filp->f_pos,
133 v9ses->maxdata-V9FS_IOHDRSZ, &fcall);
134 if (ret < 0) {
135 dprintk(DEBUG_ERROR, "error while reading: %d: %p\n",
136 ret, fcall);
137 goto FreeStructs;
138 } else if (ret == 0)
139 break;
140
141 n = ret;
142 i = 0;
143 while (i < n) {
144 int s = v9fs_deserialize_stat(v9ses,
145 fcall->params.rread.data + i, n - i, mi,
146 v9ses->maxdata);
147
148 if (s == 0) {
149 dprintk(DEBUG_ERROR,
150 "error while deserializing mistat\n");
151 return -EIO;
152 }
153
154 over = filldir(dirent, mi->name, strlen(mi->name),
155 filp->f_pos, v9fs_qid2ino(&mi->qid),
156 dt_type(mi));
157
158 if (over) {
159 file->rdir_fcall = fcall;
160 file->rdir_fpos = i;
161 file->rdir_pos = filp->f_pos;
162 fcall = NULL;
163 break;
164 }
165
166 i += s;
167 filp->f_pos += s;
168 }
169
170 kfree(fcall);
171 }
172
173 FreeStructs:
174 kfree(fcall);
175 kfree(mi);
176 return ret;
177}
178
179/**
180 * v9fs_dir_release - close a directory
181 * @inode: inode of the directory
182 * @filp: file pointer to a directory
183 *
184 */
185
186int v9fs_dir_release(struct inode *inode, struct file *filp)
187{
188 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
189 struct v9fs_fid *fid = filp->private_data;
190 int fidnum = -1;
191
192 dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp,
193 fid->fid);
194 fidnum = fid->fid;
195
196 filemap_fdatawrite(inode->i_mapping);
197 filemap_fdatawait(inode->i_mapping);
198
199 if (fidnum >= 0) {
200 fid->fidopen--;
201 dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
202 fid->fid);
203
204 if (fid->fidopen == 0) {
205 if (v9fs_t_clunk(v9ses, fidnum, NULL))
206 dprintk(DEBUG_ERROR, "clunk failed\n");
207
208 v9fs_put_idpool(fid->fid, &v9ses->fidpool);
209 }
210
211 kfree(fid->rdir_fcall);
212
213 filp->private_data = NULL;
214 v9fs_fid_destroy(fid);
215 }
216
217 d_drop(filp->f_dentry);
218 return 0;
219}
220
221struct file_operations v9fs_dir_operations = {
222 .read = generic_read_dir,
223 .readdir = v9fs_dir_readdir,
224 .open = v9fs_file_open,
225 .release = v9fs_dir_release,
226};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
new file mode 100644
index 000000000000..1f8ae7d580ab
--- /dev/null
+++ b/fs/9p/vfs_file.c
@@ -0,0 +1,401 @@
1/*
2 * linux/fs/9p/vfs_file.c
3 *
4 * This file contians vfs file ops for 9P2000.
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/file.h>
31#include <linux/stat.h>
32#include <linux/string.h>
33#include <linux/smp_lock.h>
34#include <linux/inet.h>
35#include <linux/version.h>
36#include <linux/list.h>
37#include <asm/uaccess.h>
38#include <linux/idr.h>
39
40#include "debug.h"
41#include "v9fs.h"
42#include "9p.h"
43#include "v9fs_vfs.h"
44#include "fid.h"
45
46/**
47 * v9fs_file_open - open a file (or directory)
48 * @inode: inode to be opened
49 * @file: file being opened
50 *
51 */
52
53int v9fs_file_open(struct inode *inode, struct file *file)
54{
55 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
56 struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK);
57 struct v9fs_fid *v9newfid = NULL;
58 struct v9fs_fcall *fcall = NULL;
59 int open_mode = 0;
60 unsigned int iounit = 0;
61 int newfid = -1;
62 long result = -1;
63
64 dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file,
65 v9fid);
66
67 if (!v9fid) {
68 struct dentry *dentry = file->f_dentry;
69 dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
70
71 /* XXX - some duplication from lookup, generalize later */
72 /* basically vfs_lookup is too heavy weight */
73 v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP);
74 if (!v9fid)
75 return -EBADF;
76
77 v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
78 if (!v9fid)
79 return -EBADF;
80
81 newfid = v9fs_get_idpool(&v9ses->fidpool);
82 if (newfid < 0) {
83 eprintk(KERN_WARNING, "newfid fails!\n");
84 return -ENOSPC;
85 }
86
87 result =
88 v9fs_t_walk(v9ses, v9fid->fid, newfid,
89 (char *)file->f_dentry->d_name.name, NULL);
90 if (result < 0) {
91 v9fs_put_idpool(newfid, &v9ses->fidpool);
92 dprintk(DEBUG_ERROR, "rewalk didn't work\n");
93 return -EBADF;
94 }
95
96 v9fid = v9fs_fid_create(dentry);
97 if (v9fid == NULL) {
98 dprintk(DEBUG_ERROR, "couldn't insert\n");
99 return -ENOMEM;
100 }
101 v9fid->fid = newfid;
102 }
103
104 if (v9fid->fidcreate) {
105 /* create case */
106 newfid = v9fid->fid;
107 iounit = v9fid->iounit;
108 v9fid->fidcreate = 0;
109 } else {
110 if (!S_ISDIR(inode->i_mode))
111 newfid = v9fid->fid;
112 else {
113 newfid = v9fs_get_idpool(&v9ses->fidpool);
114 if (newfid < 0) {
115 eprintk(KERN_WARNING, "allocation failed\n");
116 return -ENOSPC;
117 }
118 /* This would be a somewhat critical clone */
119 result =
120 v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL,
121 &fcall);
122 if (result < 0) {
123 dprintk(DEBUG_ERROR, "clone error: %s\n",
124 FCALL_ERROR(fcall));
125 kfree(fcall);
126 return result;
127 }
128
129 v9newfid = v9fs_fid_create(file->f_dentry);
130 v9newfid->fid = newfid;
131 v9newfid->qid = v9fid->qid;
132 v9newfid->iounit = v9fid->iounit;
133 v9newfid->fidopen = 0;
134 v9newfid->fidclunked = 0;
135 v9newfid->v9ses = v9ses;
136 v9fid = v9newfid;
137 kfree(fcall);
138 }
139
140 /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
141 /* translate open mode appropriately */
142 open_mode = file->f_flags & 0x3;
143
144 if (file->f_flags & O_EXCL)
145 open_mode |= V9FS_OEXCL;
146
147 if (v9ses->extended) {
148 if (file->f_flags & O_TRUNC)
149 open_mode |= V9FS_OTRUNC;
150
151 if (file->f_flags & O_APPEND)
152 open_mode |= V9FS_OAPPEND;
153 }
154
155 result = v9fs_t_open(v9ses, newfid, open_mode, &fcall);
156 if (result < 0) {
157 dprintk(DEBUG_ERROR,
158 "open failed, open_mode 0x%x: %s\n", open_mode,
159 FCALL_ERROR(fcall));
160 kfree(fcall);
161 return result;
162 }
163
164 iounit = fcall->params.ropen.iounit;
165 kfree(fcall);
166 }
167
168
169 file->private_data = v9fid;
170
171 v9fid->rdir_pos = 0;
172 v9fid->rdir_fcall = NULL;
173 v9fid->fidopen = 1;
174 v9fid->filp = file;
175 v9fid->iounit = iounit;
176
177 return 0;
178}
179
180/**
181 * v9fs_file_lock - lock a file (or directory)
182 * @inode: inode to be opened
183 * @file: file being opened
184 *
185 * XXX - this looks like a local only lock, we should extend into 9P
186 * by using open exclusive
187 */
188
189static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
190{
191 int res = 0;
192 struct inode *inode = filp->f_dentry->d_inode;
193
194 dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
195
196 /* No mandatory locks */
197 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
198 return -ENOLCK;
199
200 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
201 filemap_fdatawrite(inode->i_mapping);
202 filemap_fdatawait(inode->i_mapping);
203 invalidate_inode_pages(&inode->i_data);
204 }
205
206 return res;
207}
208
209/**
210 * v9fs_read - read from a file (internal)
211 * @filep: file pointer to read
212 * @data: data buffer to read data into
213 * @count: size of buffer
214 * @offset: offset at which to read data
215 *
216 */
217
218static ssize_t
219v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
220{
221 struct inode *inode = filp->f_dentry->d_inode;
222 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
223 struct v9fs_fid *v9f = filp->private_data;
224 struct v9fs_fcall *fcall = NULL;
225 int fid = v9f->fid;
226 int rsize = 0;
227 int result = 0;
228 int total = 0;
229
230 dprintk(DEBUG_VFS, "\n");
231
232 rsize = v9ses->maxdata - V9FS_IOHDRSZ;
233 if (v9f->iounit != 0 && rsize > v9f->iounit)
234 rsize = v9f->iounit;
235
236 do {
237 if (count < rsize)
238 rsize = count;
239
240 result = v9fs_t_read(v9ses, fid, *offset, rsize, &fcall);
241
242 if (result < 0) {
243 printk(KERN_ERR "9P2000: v9fs_t_read returned %d\n",
244 result);
245
246 kfree(fcall);
247 return total;
248 } else
249 *offset += result;
250
251 /* XXX - extra copy */
252 memcpy(buffer, fcall->params.rread.data, result);
253 count -= result;
254 buffer += result;
255 total += result;
256
257 kfree(fcall);
258
259 if (result < rsize)
260 break;
261 } while (count);
262
263 return total;
264}
265
266/**
267 * v9fs_file_read - read from a file
268 * @filep: file pointer to read
269 * @data: data buffer to read data into
270 * @count: size of buffer
271 * @offset: offset at which to read data
272 *
273 */
274
275static ssize_t
276v9fs_file_read(struct file *filp, char __user * data, size_t count,
277 loff_t * offset)
278{
279 int retval = -1;
280 int ret = 0;
281 char *buffer;
282
283 buffer = kmalloc(count, GFP_KERNEL);
284 if (!buffer)
285 return -ENOMEM;
286
287 retval = v9fs_read(filp, buffer, count, offset);
288 if (retval > 0) {
289 if ((ret = copy_to_user(data, buffer, retval)) != 0) {
290 dprintk(DEBUG_ERROR, "Problem copying to user %d\n",
291 ret);
292 retval = ret;
293 }
294 }
295
296 kfree(buffer);
297
298 return retval;
299}
300
301/**
302 * v9fs_write - write to a file
303 * @filep: file pointer to write
304 * @data: data buffer to write data from
305 * @count: size of buffer
306 * @offset: offset at which to write data
307 *
308 */
309
310static ssize_t
311v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
312{
313 struct inode *inode = filp->f_dentry->d_inode;
314 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
315 struct v9fs_fid *v9fid = filp->private_data;
316 struct v9fs_fcall *fcall;
317 int fid = v9fid->fid;
318 int result = -EIO;
319 int rsize = 0;
320 int total = 0;
321
322 dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count,
323 (int)*offset);
324 rsize = v9ses->maxdata - V9FS_IOHDRSZ;
325 if (v9fid->iounit != 0 && rsize > v9fid->iounit)
326 rsize = v9fid->iounit;
327
328 dump_data(buffer, count);
329
330 do {
331 if (count < rsize)
332 rsize = count;
333
334 result =
335 v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall);
336 if (result < 0) {
337 eprintk(KERN_ERR, "error while writing: %s(%d)\n",
338 FCALL_ERROR(fcall), result);
339 kfree(fcall);
340 return result;
341 } else
342 *offset += result;
343
344 kfree(fcall);
345
346 if (result != rsize) {
347 eprintk(KERN_ERR,
348 "short write: v9fs_t_write returned %d\n",
349 result);
350 break;
351 }
352
353 count -= result;
354 buffer += result;
355 total += result;
356 } while (count);
357
358 return total;
359}
360
361/**
362 * v9fs_file_write - write to a file
363 * @filep: file pointer to write
364 * @data: data buffer to write data from
365 * @count: size of buffer
366 * @offset: offset at which to write data
367 *
368 */
369
370static ssize_t
371v9fs_file_write(struct file *filp, const char __user * data,
372 size_t count, loff_t * offset)
373{
374 int ret = -1;
375 char *buffer;
376
377 buffer = kmalloc(count, GFP_KERNEL);
378 if (buffer == NULL)
379 return -ENOMEM;
380
381 ret = copy_from_user(buffer, data, count);
382 if (ret) {
383 dprintk(DEBUG_ERROR, "Problem copying from user\n");
384 ret = -EFAULT;
385 } else {
386 ret = v9fs_write(filp, buffer, count, offset);
387 }
388
389 kfree(buffer);
390
391 return ret;
392}
393
394struct file_operations v9fs_file_operations = {
395 .llseek = generic_file_llseek,
396 .read = v9fs_file_read,
397 .write = v9fs_file_write,
398 .open = v9fs_file_open,
399 .release = v9fs_dir_release,
400 .lock = v9fs_file_lock,
401};
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
new file mode 100644
index 000000000000..0c13fc600049
--- /dev/null
+++ b/fs/9p/vfs_inode.c
@@ -0,0 +1,1338 @@
1/*
2 * linux/fs/9p/vfs_inode.c
3 *
4 * This file contains vfs inode ops for the 9P2000 protocol.
5 *
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/file.h>
31#include <linux/pagemap.h>
32#include <linux/stat.h>
33#include <linux/string.h>
34#include <linux/smp_lock.h>
35#include <linux/inet.h>
36#include <linux/namei.h>
37#include <linux/idr.h>
38
39#include "debug.h"
40#include "v9fs.h"
41#include "9p.h"
42#include "v9fs_vfs.h"
43#include "conv.h"
44#include "fid.h"
45
46static struct inode_operations v9fs_dir_inode_operations;
47static struct inode_operations v9fs_dir_inode_operations_ext;
48static struct inode_operations v9fs_file_inode_operations;
49static struct inode_operations v9fs_symlink_inode_operations;
50
51/**
52 * unixmode2p9mode - convert unix mode bits to plan 9
53 * @v9ses: v9fs session information
54 * @mode: mode to convert
55 *
56 */
57
58static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
59{
60 int res;
61 res = mode & 0777;
62 if (S_ISDIR(mode))
63 res |= V9FS_DMDIR;
64 if (v9ses->extended) {
65 if (S_ISLNK(mode))
66 res |= V9FS_DMSYMLINK;
67 if (v9ses->nodev == 0) {
68 if (S_ISSOCK(mode))
69 res |= V9FS_DMSOCKET;
70 if (S_ISFIFO(mode))
71 res |= V9FS_DMNAMEDPIPE;
72 if (S_ISBLK(mode))
73 res |= V9FS_DMDEVICE;
74 if (S_ISCHR(mode))
75 res |= V9FS_DMDEVICE;
76 }
77
78 if ((mode & S_ISUID) == S_ISUID)
79 res |= V9FS_DMSETUID;
80 if ((mode & S_ISGID) == S_ISGID)
81 res |= V9FS_DMSETGID;
82 if ((mode & V9FS_DMLINK))
83 res |= V9FS_DMLINK;
84 }
85
86 return res;
87}
88
89/**
90 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
91 * @v9ses: v9fs session information
92 * @mode: mode to convert
93 *
94 */
95
96static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
97{
98 int res;
99
100 res = mode & 0777;
101
102 if ((mode & V9FS_DMDIR) == V9FS_DMDIR)
103 res |= S_IFDIR;
104 else if ((mode & V9FS_DMSYMLINK) && (v9ses->extended))
105 res |= S_IFLNK;
106 else if ((mode & V9FS_DMSOCKET) && (v9ses->extended)
107 && (v9ses->nodev == 0))
108 res |= S_IFSOCK;
109 else if ((mode & V9FS_DMNAMEDPIPE) && (v9ses->extended)
110 && (v9ses->nodev == 0))
111 res |= S_IFIFO;
112 else if ((mode & V9FS_DMDEVICE) && (v9ses->extended)
113 && (v9ses->nodev == 0))
114 res |= S_IFBLK;
115 else
116 res |= S_IFREG;
117
118 if (v9ses->extended) {
119 if ((mode & V9FS_DMSETUID) == V9FS_DMSETUID)
120 res |= S_ISUID;
121
122 if ((mode & V9FS_DMSETGID) == V9FS_DMSETGID)
123 res |= S_ISGID;
124 }
125
126 return res;
127}
128
129/**
130 * v9fs_blank_mistat - helper function to setup a 9P stat structure
131 * @v9ses: 9P session info (for determining extended mode)
132 * @mistat: structure to initialize
133 *
134 */
135
136static void
137v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat)
138{
139 mistat->type = ~0;
140 mistat->dev = ~0;
141 mistat->qid.type = ~0;
142 mistat->qid.version = ~0;
143 *((long long *)&mistat->qid.path) = ~0;
144 mistat->mode = ~0;
145 mistat->atime = ~0;
146 mistat->mtime = ~0;
147 mistat->length = ~0;
148 mistat->name = mistat->data;
149 mistat->uid = mistat->data;
150 mistat->gid = mistat->data;
151 mistat->muid = mistat->data;
152 if (v9ses->extended) {
153 mistat->n_uid = ~0;
154 mistat->n_gid = ~0;
155 mistat->n_muid = ~0;
156 mistat->extension = mistat->data;
157 }
158 *mistat->data = 0;
159}
160
161/**
162 * v9fs_mistat2unix - convert mistat to unix stat
163 * @mistat: Plan 9 metadata (mistat) structure
164 * @buf: unix metadata (stat) structure to populate
165 * @sb: superblock
166 *
167 */
168
169static void
170v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
171 struct super_block *sb)
172{
173 struct v9fs_session_info *v9ses = sb ? sb->s_fs_info : NULL;
174
175 buf->st_nlink = 1;
176
177 buf->st_atime = mistat->atime;
178 buf->st_mtime = mistat->mtime;
179 buf->st_ctime = mistat->mtime;
180
181 buf->st_uid = (unsigned short)-1;
182 buf->st_gid = (unsigned short)-1;
183
184 if (v9ses && v9ses->extended) {
185 /* TODO: string to uid mapping via user-space daemon */
186 if (mistat->n_uid != -1)
187 sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
188
189 if (mistat->n_gid != -1)
190 sscanf(mistat->gid, "%x", (unsigned int *)&buf->st_gid);
191 }
192
193 if (buf->st_uid == (unsigned short)-1)
194 buf->st_uid = v9ses->uid;
195 if (buf->st_gid == (unsigned short)-1)
196 buf->st_gid = v9ses->gid;
197
198 buf->st_mode = p9mode2unixmode(v9ses, mistat->mode);
199 if ((S_ISBLK(buf->st_mode)) || (S_ISCHR(buf->st_mode))) {
200 char type = 0;
201 int major = -1;
202 int minor = -1;
203 sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
204 switch (type) {
205 case 'c':
206 buf->st_mode &= ~S_IFBLK;
207 buf->st_mode |= S_IFCHR;
208 break;
209 case 'b':
210 break;
211 default:
212 dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
213 type, mistat->extension);
214 };
215 buf->st_rdev = MKDEV(major, minor);
216 } else
217 buf->st_rdev = 0;
218
219 buf->st_size = mistat->length;
220
221 buf->st_blksize = sb->s_blocksize;
222 buf->st_blocks =
223 (buf->st_size + buf->st_blksize - 1) >> sb->s_blocksize_bits;
224}
225
226/**
227 * v9fs_get_inode - helper function to setup an inode
228 * @sb: superblock
229 * @mode: mode to setup inode with
230 *
231 */
232
233struct inode *v9fs_get_inode(struct super_block *sb, int mode)
234{
235 struct inode *inode = NULL;
236 struct v9fs_session_info *v9ses = sb->s_fs_info;
237
238 dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
239
240 inode = new_inode(sb);
241 if (inode) {
242 inode->i_mode = mode;
243 inode->i_uid = current->fsuid;
244 inode->i_gid = current->fsgid;
245 inode->i_blksize = sb->s_blocksize;
246 inode->i_blocks = 0;
247 inode->i_rdev = 0;
248 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
249
250 switch (mode & S_IFMT) {
251 case S_IFIFO:
252 case S_IFBLK:
253 case S_IFCHR:
254 case S_IFSOCK:
255 if(!v9ses->extended) {
256 dprintk(DEBUG_ERROR, "special files without extended mode\n");
257 return ERR_PTR(-EINVAL);
258 }
259 init_special_inode(inode, inode->i_mode,
260 inode->i_rdev);
261 break;
262 case S_IFREG:
263 inode->i_op = &v9fs_file_inode_operations;
264 inode->i_fop = &v9fs_file_operations;
265 break;
266 case S_IFLNK:
267 if(!v9ses->extended) {
268 dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n");
269 return ERR_PTR(-EINVAL);
270 }
271 inode->i_op = &v9fs_symlink_inode_operations;
272 break;
273 case S_IFDIR:
274 inode->i_nlink++;
275 if(v9ses->extended)
276 inode->i_op = &v9fs_dir_inode_operations_ext;
277 else
278 inode->i_op = &v9fs_dir_inode_operations;
279 inode->i_fop = &v9fs_dir_operations;
280 break;
281 default:
282 dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
283 mode, mode & S_IFMT);
284 return ERR_PTR(-EINVAL);
285 }
286 } else {
287 eprintk(KERN_WARNING, "Problem allocating inode\n");
288 return ERR_PTR(-ENOMEM);
289 }
290 return inode;
291}
292
293/**
294 * v9fs_create - helper function to create files and directories
295 * @dir: directory inode file is being created in
296 * @file_dentry: dentry file is being created in
297 * @perm: permissions file is being created with
298 * @open_mode: resulting open mode for file
299 *
300 */
301
302static int
303v9fs_create(struct inode *dir,
304 struct dentry *file_dentry,
305 unsigned int perm, unsigned int open_mode)
306{
307 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
308 struct super_block *sb = dir->i_sb;
309 struct v9fs_fid *dirfid =
310 v9fs_fid_lookup(file_dentry->d_parent, FID_WALK);
311 struct v9fs_fid *fid = NULL;
312 struct inode *file_inode = NULL;
313 struct v9fs_fcall *fcall = NULL;
314 struct v9fs_qid qid;
315 struct stat newstat;
316 int dirfidnum = -1;
317 long newfid = -1;
318 int result = 0;
319 unsigned int iounit = 0;
320
321 perm = unixmode2p9mode(v9ses, perm);
322
323 dprintk(DEBUG_VFS, "dir: %p dentry: %p perm: %o mode: %o\n", dir,
324 file_dentry, perm, open_mode);
325
326 if (!dirfid)
327 return -EBADF;
328
329 dirfidnum = dirfid->fid;
330 if (dirfidnum < 0) {
331 dprintk(DEBUG_ERROR, "No fid for the directory #%lu\n",
332 dir->i_ino);
333 return -EBADF;
334 }
335
336 if (file_dentry->d_inode) {
337 dprintk(DEBUG_ERROR,
338 "Odd. There is an inode for dir %lu, name :%s:\n",
339 dir->i_ino, file_dentry->d_name.name);
340 return -EEXIST;
341 }
342
343 newfid = v9fs_get_idpool(&v9ses->fidpool);
344 if (newfid < 0) {
345 eprintk(KERN_WARNING, "no free fids available\n");
346 return -ENOSPC;
347 }
348
349 result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall);
350 if (result < 0) {
351 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
352 v9fs_put_idpool(newfid, &v9ses->fidpool);
353 newfid = 0;
354 goto CleanUpFid;
355 }
356
357 kfree(fcall);
358
359 result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name,
360 perm, open_mode, &fcall);
361 if (result < 0) {
362 dprintk(DEBUG_ERROR, "create fails: %s(%d)\n",
363 FCALL_ERROR(fcall), result);
364
365 goto CleanUpFid;
366 }
367
368 iounit = fcall->params.rcreate.iounit;
369 qid = fcall->params.rcreate.qid;
370 kfree(fcall);
371
372 fid = v9fs_fid_create(file_dentry);
373 if (!fid) {
374 result = -ENOMEM;
375 goto CleanUpFid;
376 }
377
378 fid->fid = newfid;
379 fid->fidopen = 0;
380 fid->fidcreate = 1;
381 fid->qid = qid;
382 fid->iounit = iounit;
383 fid->rdir_pos = 0;
384 fid->rdir_fcall = NULL;
385 fid->v9ses = v9ses;
386
387 if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) ||
388 (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) ||
389 (perm & V9FS_DMDEVICE))
390 return 0;
391
392 result = v9fs_t_stat(v9ses, newfid, &fcall);
393 if (result < 0) {
394 dprintk(DEBUG_ERROR, "stat error: %s(%d)\n", FCALL_ERROR(fcall),
395 result);
396 goto CleanUpFid;
397 }
398
399 v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
400
401 file_inode = v9fs_get_inode(sb, newstat.st_mode);
402 if ((!file_inode) || IS_ERR(file_inode)) {
403 dprintk(DEBUG_ERROR, "create inode failed\n");
404 result = -EBADF;
405 goto CleanUpFid;
406 }
407
408 v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb);
409 kfree(fcall);
410 d_instantiate(file_dentry, file_inode);
411
412 if (perm & V9FS_DMDIR) {
413 if (v9fs_t_clunk(v9ses, newfid, &fcall))
414 dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
415 FCALL_ERROR(fcall));
416
417 v9fs_put_idpool(newfid, &v9ses->fidpool);
418 kfree(fcall);
419 fid->fidopen = 0;
420 fid->fidcreate = 0;
421 d_drop(file_dentry);
422 }
423
424 return 0;
425
426 CleanUpFid:
427 kfree(fcall);
428
429 if (newfid) {
430 if (v9fs_t_clunk(v9ses, newfid, &fcall))
431 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
432 FCALL_ERROR(fcall));
433
434 v9fs_put_idpool(newfid, &v9ses->fidpool);
435 kfree(fcall);
436 }
437 return result;
438}
439
440/**
441 * v9fs_remove - helper function to remove files and directories
442 * @dir: directory inode that is being deleted
443 * @file: dentry that is being deleted
444 * @rmdir: removing a directory
445 *
446 */
447
448static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
449{
450 struct v9fs_fcall *fcall = NULL;
451 struct super_block *sb = NULL;
452 struct v9fs_session_info *v9ses = NULL;
453 struct v9fs_fid *v9fid = NULL;
454 struct inode *file_inode = NULL;
455 int fid = -1;
456 int result = 0;
457
458 dprintk(DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
459 rmdir);
460
461 file_inode = file->d_inode;
462 sb = file_inode->i_sb;
463 v9ses = v9fs_inode2v9ses(file_inode);
464 v9fid = v9fs_fid_lookup(file, FID_OP);
465
466 if (!v9fid) {
467 dprintk(DEBUG_ERROR,
468 "no v9fs_fid\n");
469 return -EBADF;
470 }
471
472 fid = v9fid->fid;
473 if (fid < 0) {
474 dprintk(DEBUG_ERROR, "inode #%lu, no fid!\n",
475 file_inode->i_ino);
476 return -EBADF;
477 }
478
479 result = v9fs_t_remove(v9ses, fid, &fcall);
480 if (result < 0)
481 dprintk(DEBUG_ERROR, "remove of file fails: %s(%d)\n",
482 FCALL_ERROR(fcall), result);
483 else {
484 v9fs_put_idpool(fid, &v9ses->fidpool);
485 v9fs_fid_destroy(v9fid);
486 }
487
488 kfree(fcall);
489 return result;
490}
491
492/**
493 * v9fs_vfs_create - VFS hook to create files
494 * @inode: directory inode that is being deleted
495 * @dentry: dentry that is being deleted
496 * @perm: create permissions
497 * @nd: path information
498 *
499 */
500
501static int
502v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm,
503 struct nameidata *nd)
504{
505 return v9fs_create(inode, dentry, perm, O_RDWR);
506}
507
508/**
509 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
510 * @inode: inode that is being unlinked
511 * @dentry: dentry that is being unlinked
512 * @mode: mode for new directory
513 *
514 */
515
516static int v9fs_vfs_mkdir(struct inode *inode, struct dentry *dentry, int mode)
517{
518 return v9fs_create(inode, dentry, mode | S_IFDIR, O_RDONLY);
519}
520
521/**
522 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
523 * @dir: inode that is being walked from
524 * @dentry: dentry that is being walked to?
525 * @nameidata: path data
526 *
527 */
528
529static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
530 struct nameidata *nameidata)
531{
532 struct super_block *sb;
533 struct v9fs_session_info *v9ses;
534 struct v9fs_fid *dirfid;
535 struct v9fs_fid *fid;
536 struct inode *inode;
537 struct v9fs_fcall *fcall = NULL;
538 struct stat newstat;
539 int dirfidnum = -1;
540 int newfid = -1;
541 int result = 0;
542
543 dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
544 dir, dentry->d_iname, dentry, nameidata);
545
546 sb = dir->i_sb;
547 v9ses = v9fs_inode2v9ses(dir);
548 dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
549
550 if (!dirfid) {
551 dprintk(DEBUG_ERROR, "no dirfid\n");
552 return ERR_PTR(-EINVAL);
553 }
554
555 dirfidnum = dirfid->fid;
556
557 if (dirfidnum < 0) {
558 dprintk(DEBUG_ERROR, "no dirfid for inode %p, #%lu\n",
559 dir, dir->i_ino);
560 return ERR_PTR(-EBADF);
561 }
562
563 newfid = v9fs_get_idpool(&v9ses->fidpool);
564 if (newfid < 0) {
565 eprintk(KERN_WARNING, "newfid fails!\n");
566 return ERR_PTR(-ENOSPC);
567 }
568
569 result =
570 v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name,
571 NULL);
572 if (result < 0) {
573 v9fs_put_idpool(newfid, &v9ses->fidpool);
574 if (result == -ENOENT) {
575 d_add(dentry, NULL);
576 dprintk(DEBUG_ERROR,
577 "Return negative dentry %p count %d\n",
578 dentry, atomic_read(&dentry->d_count));
579 return NULL;
580 }
581 dprintk(DEBUG_ERROR, "walk error:%d\n", result);
582 goto FreeFcall;
583 }
584
585 result = v9fs_t_stat(v9ses, newfid, &fcall);
586 if (result < 0) {
587 dprintk(DEBUG_ERROR, "stat error\n");
588 goto FreeFcall;
589 }
590
591 v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
592 inode = v9fs_get_inode(sb, newstat.st_mode);
593
594 if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) {
595 eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n",
596 PTR_ERR(inode));
597
598 result = -ENOSPC;
599 goto FreeFcall;
600 }
601
602 inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
603
604 fid = v9fs_fid_create(dentry);
605 if (fid == NULL) {
606 dprintk(DEBUG_ERROR, "couldn't insert\n");
607 result = -ENOMEM;
608 goto FreeFcall;
609 }
610
611 fid->fid = newfid;
612 fid->fidopen = 0;
613 fid->v9ses = v9ses;
614 fid->qid = fcall->params.rstat.stat->qid;
615
616 dentry->d_op = &v9fs_dentry_operations;
617 v9fs_mistat2inode(fcall->params.rstat.stat, inode, inode->i_sb);
618
619 d_add(dentry, inode);
620 kfree(fcall);
621
622 return NULL;
623
624 FreeFcall:
625 kfree(fcall);
626 return ERR_PTR(result);
627}
628
629/**
630 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
631 * @i: inode that is being unlinked
632 * @d: dentry that is being unlinked
633 *
634 */
635
636static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
637{
638 return v9fs_remove(i, d, 0);
639}
640
641/**
642 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
643 * @i: inode that is being unlinked
644 * @d: dentry that is being unlinked
645 *
646 */
647
648static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
649{
650 return v9fs_remove(i, d, 1);
651}
652
653/**
654 * v9fs_vfs_rename - VFS hook to rename an inode
655 * @old_dir: old dir inode
656 * @old_dentry: old dentry
657 * @new_dir: new dir inode
658 * @new_dentry: new dentry
659 *
660 */
661
662static int
663v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
664 struct inode *new_dir, struct dentry *new_dentry)
665{
666 struct inode *old_inode = old_dentry->d_inode;
667 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
668 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK);
669 struct v9fs_fid *olddirfid =
670 v9fs_fid_lookup(old_dentry->d_parent, FID_WALK);
671 struct v9fs_fid *newdirfid =
672 v9fs_fid_lookup(new_dentry->d_parent, FID_WALK);
673 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
674 struct v9fs_fcall *fcall = NULL;
675 int fid = -1;
676 int olddirfidnum = -1;
677 int newdirfidnum = -1;
678 int retval = 0;
679
680 dprintk(DEBUG_VFS, "\n");
681
682 if (!mistat)
683 return -ENOMEM;
684
685 if ((!oldfid) || (!olddirfid) || (!newdirfid)) {
686 dprintk(DEBUG_ERROR, "problem with arguments\n");
687 return -EBADF;
688 }
689
690 /* 9P can only handle file rename in the same directory */
691 if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) {
692 dprintk(DEBUG_ERROR, "old dir and new dir are different\n");
693 retval = -EPERM;
694 goto FreeFcallnBail;
695 }
696
697 fid = oldfid->fid;
698 olddirfidnum = olddirfid->fid;
699 newdirfidnum = newdirfid->fid;
700
701 if (fid < 0) {
702 dprintk(DEBUG_ERROR, "no fid for old file #%lu\n",
703 old_inode->i_ino);
704 retval = -EBADF;
705 goto FreeFcallnBail;
706 }
707
708 v9fs_blank_mistat(v9ses, mistat);
709
710 strcpy(mistat->data + 1, v9ses->name);
711 mistat->name = mistat->data + 1 + strlen(v9ses->name);
712
713 if (new_dentry->d_name.len >
714 (v9ses->maxdata - strlen(v9ses->name) - sizeof(struct v9fs_stat))) {
715 dprintk(DEBUG_ERROR, "new name too long\n");
716 goto FreeFcallnBail;
717 }
718
719 strcpy(mistat->name, new_dentry->d_name.name);
720 retval = v9fs_t_wstat(v9ses, fid, mistat, &fcall);
721
722 FreeFcallnBail:
723 kfree(mistat);
724
725 if (retval < 0)
726 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
727 FCALL_ERROR(fcall));
728
729 kfree(fcall);
730 return retval;
731}
732
733/**
734 * v9fs_vfs_getattr - retreive file metadata
735 * @mnt - mount information
736 * @dentry - file to get attributes on
737 * @stat - metadata structure to populate
738 *
739 */
740
741static int
742v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
743 struct kstat *stat)
744{
745 struct v9fs_fcall *fcall = NULL;
746 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
747 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
748 int err = -EPERM;
749
750 dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
751 if (!fid) {
752 dprintk(DEBUG_ERROR,
753 "couldn't find fid associated with dentry\n");
754 return -EBADF;
755 }
756
757 err = v9fs_t_stat(v9ses, fid->fid, &fcall);
758
759 if (err < 0)
760 dprintk(DEBUG_ERROR, "stat error\n");
761 else {
762 v9fs_mistat2inode(fcall->params.rstat.stat, dentry->d_inode,
763 dentry->d_inode->i_sb);
764 generic_fillattr(dentry->d_inode, stat);
765 }
766
767 kfree(fcall);
768 return err;
769}
770
771/**
772 * v9fs_vfs_setattr - set file metadata
773 * @dentry: file whose metadata to set
774 * @iattr: metadata assignment structure
775 *
776 */
777
778static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
779{
780 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
781 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
782 struct v9fs_fcall *fcall = NULL;
783 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
784 int res = -EPERM;
785
786 dprintk(DEBUG_VFS, "\n");
787
788 if (!mistat)
789 return -ENOMEM;
790
791 if (!fid) {
792 dprintk(DEBUG_ERROR,
793 "Couldn't find fid associated with dentry\n");
794 return -EBADF;
795 }
796
797 v9fs_blank_mistat(v9ses, mistat);
798 if (iattr->ia_valid & ATTR_MODE)
799 mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode);
800
801 if (iattr->ia_valid & ATTR_MTIME)
802 mistat->mtime = iattr->ia_mtime.tv_sec;
803
804 if (iattr->ia_valid & ATTR_ATIME)
805 mistat->atime = iattr->ia_atime.tv_sec;
806
807 if (iattr->ia_valid & ATTR_SIZE)
808 mistat->length = iattr->ia_size;
809
810 if (v9ses->extended) {
811 char *ptr = mistat->data+1;
812
813 if (iattr->ia_valid & ATTR_UID) {
814 mistat->uid = ptr;
815 ptr += 1+sprintf(ptr, "%08x", iattr->ia_uid);
816 mistat->n_uid = iattr->ia_uid;
817 }
818
819 if (iattr->ia_valid & ATTR_GID) {
820 mistat->gid = ptr;
821 ptr += 1+sprintf(ptr, "%08x", iattr->ia_gid);
822 mistat->n_gid = iattr->ia_gid;
823 }
824 }
825
826 res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall);
827
828 if (res < 0)
829 dprintk(DEBUG_ERROR, "wstat error: %s\n", FCALL_ERROR(fcall));
830
831 kfree(mistat);
832 kfree(fcall);
833
834 if (res >= 0)
835 res = inode_setattr(dentry->d_inode, iattr);
836
837 return res;
838}
839
840/**
841 * v9fs_mistat2inode - populate an inode structure with mistat info
842 * @mistat: Plan 9 metadata (mistat) structure
843 * @inode: inode to populate
844 * @sb: superblock of filesystem
845 *
846 */
847
848void
849v9fs_mistat2inode(struct v9fs_stat *mistat, struct inode *inode,
850 struct super_block *sb)
851{
852 struct v9fs_session_info *v9ses = sb->s_fs_info;
853
854 inode->i_nlink = 1;
855
856 inode->i_atime.tv_sec = mistat->atime;
857 inode->i_mtime.tv_sec = mistat->mtime;
858 inode->i_ctime.tv_sec = mistat->mtime;
859
860 inode->i_uid = -1;
861 inode->i_gid = -1;
862
863 if (v9ses->extended) {
864 /* TODO: string to uid mapping via user-space daemon */
865 inode->i_uid = mistat->n_uid;
866 inode->i_gid = mistat->n_gid;
867
868 if (mistat->n_uid == -1)
869 sscanf(mistat->uid, "%x", &inode->i_uid);
870
871 if (mistat->n_gid == -1)
872 sscanf(mistat->gid, "%x", &inode->i_gid);
873 }
874
875 if (inode->i_uid == -1)
876 inode->i_uid = v9ses->uid;
877 if (inode->i_gid == -1)
878 inode->i_gid = v9ses->gid;
879
880 inode->i_mode = p9mode2unixmode(v9ses, mistat->mode);
881 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
882 char type = 0;
883 int major = -1;
884 int minor = -1;
885 sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
886 switch (type) {
887 case 'c':
888 inode->i_mode &= ~S_IFBLK;
889 inode->i_mode |= S_IFCHR;
890 break;
891 case 'b':
892 break;
893 default:
894 dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
895 type, mistat->extension);
896 };
897 inode->i_rdev = MKDEV(major, minor);
898 } else
899 inode->i_rdev = 0;
900
901 inode->i_size = mistat->length;
902
903 inode->i_blksize = sb->s_blocksize;
904 inode->i_blocks =
905 (inode->i_size + inode->i_blksize - 1) >> sb->s_blocksize_bits;
906}
907
908/**
909 * v9fs_qid2ino - convert qid into inode number
910 * @qid: qid to hash
911 *
912 * BUG: potential for inode number collisions?
913 */
914
915ino_t v9fs_qid2ino(struct v9fs_qid *qid)
916{
917 u64 path = qid->path + 2;
918 ino_t i = 0;
919
920 if (sizeof(ino_t) == sizeof(path))
921 memcpy(&i, &path, sizeof(ino_t));
922 else
923 i = (ino_t) (path ^ (path >> 32));
924
925 return i;
926}
927
928/**
929 * v9fs_vfs_symlink - helper function to create symlinks
930 * @dir: directory inode containing symlink
931 * @dentry: dentry for symlink
932 * @symname: symlink data
933 *
934 * See 9P2000.u RFC for more information
935 *
936 */
937
938static int
939v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
940{
941 int retval = -EPERM;
942 struct v9fs_fid *newfid;
943 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
944 struct v9fs_fcall *fcall = NULL;
945 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
946
947 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
948 symname);
949
950 if (!mistat)
951 return -ENOMEM;
952
953 if (!v9ses->extended) {
954 dprintk(DEBUG_ERROR, "not extended\n");
955 goto FreeFcall;
956 }
957
958 /* issue a create */
959 retval = v9fs_create(dir, dentry, S_IFLNK, 0);
960 if (retval != 0)
961 goto FreeFcall;
962
963 newfid = v9fs_fid_lookup(dentry, FID_OP);
964
965 /* issue a twstat */
966 v9fs_blank_mistat(v9ses, mistat);
967 strcpy(mistat->data + 1, symname);
968 mistat->extension = mistat->data + 1;
969 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
970 if (retval < 0) {
971 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
972 FCALL_ERROR(fcall));
973 goto FreeFcall;
974 }
975
976 kfree(fcall);
977
978 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
979 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
980 FCALL_ERROR(fcall));
981 goto FreeFcall;
982 }
983
984 d_drop(dentry); /* FID - will this also clunk? */
985
986 FreeFcall:
987 kfree(mistat);
988 kfree(fcall);
989
990 return retval;
991}
992
993/**
994 * v9fs_readlink - read a symlink's location (internal version)
995 * @dentry: dentry for symlink
996 * @buffer: buffer to load symlink location into
997 * @buflen: length of buffer
998 *
999 */
1000
1001static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1002{
1003 int retval = -EPERM;
1004
1005 struct v9fs_fcall *fcall = NULL;
1006 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
1007 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
1008
1009 if (!fid) {
1010 dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n");
1011 retval = -EBADF;
1012 goto FreeFcall;
1013 }
1014
1015 if (!v9ses->extended) {
1016 retval = -EBADF;
1017 dprintk(DEBUG_ERROR, "not extended\n");
1018 goto FreeFcall;
1019 }
1020
1021 dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name);
1022 retval = v9fs_t_stat(v9ses, fid->fid, &fcall);
1023
1024 if (retval < 0) {
1025 dprintk(DEBUG_ERROR, "stat error\n");
1026 goto FreeFcall;
1027 }
1028
1029 if (!fcall)
1030 return -EIO;
1031
1032 if (!(fcall->params.rstat.stat->mode & V9FS_DMSYMLINK)) {
1033 retval = -EINVAL;
1034 goto FreeFcall;
1035 }
1036
1037 /* copy extension buffer into buffer */
1038 if (strlen(fcall->params.rstat.stat->extension) < buflen)
1039 buflen = strlen(fcall->params.rstat.stat->extension);
1040
1041 memcpy(buffer, fcall->params.rstat.stat->extension, buflen + 1);
1042
1043 retval = buflen;
1044
1045 FreeFcall:
1046 kfree(fcall);
1047
1048 return retval;
1049}
1050
1051/**
1052 * v9fs_vfs_readlink - read a symlink's location
1053 * @dentry: dentry for symlink
1054 * @buf: buffer to load symlink location into
1055 * @buflen: length of buffer
1056 *
1057 */
1058
1059static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
1060 int buflen)
1061{
1062 int retval;
1063 int ret;
1064 char *link = __getname();
1065
1066 if (strlen(link) < buflen)
1067 buflen = strlen(link);
1068
1069 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
1070
1071 retval = v9fs_readlink(dentry, link, buflen);
1072
1073 if (retval > 0) {
1074 if ((ret = copy_to_user(buffer, link, retval)) != 0) {
1075 dprintk(DEBUG_ERROR, "problem copying to user: %d\n",
1076 ret);
1077 retval = ret;
1078 }
1079 }
1080
1081 putname(link);
1082 return retval;
1083}
1084
1085/**
1086 * v9fs_vfs_follow_link - follow a symlink path
1087 * @dentry: dentry for symlink
1088 * @nd: nameidata
1089 *
1090 */
1091
1092static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
1093{
1094 int len = 0;
1095 char *link = __getname();
1096
1097 dprintk(DEBUG_VFS, "%s n", dentry->d_name.name);
1098
1099 if (!link)
1100 link = ERR_PTR(-ENOMEM);
1101 else {
1102 len = v9fs_readlink(dentry, link, strlen(link));
1103
1104 if (len < 0) {
1105 putname(link);
1106 link = ERR_PTR(len);
1107 } else
1108 link[len] = 0;
1109 }
1110 nd_set_link(nd, link);
1111
1112 return NULL;
1113}
1114
1115/**
1116 * v9fs_vfs_put_link - release a symlink path
1117 * @dentry: dentry for symlink
1118 * @nd: nameidata
1119 *
1120 */
1121
1122static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
1123{
1124 char *s = nd_get_link(nd);
1125
1126 dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
1127 if (!IS_ERR(s))
1128 putname(s);
1129}
1130
1131/**
1132 * v9fs_vfs_link - create a hardlink
1133 * @old_dentry: dentry for file to link to
1134 * @dir: inode destination for new link
1135 * @dentry: dentry for link
1136 *
1137 */
1138
1139/* XXX - lots of code dup'd from symlink and creates,
1140 * figure out a better reuse strategy
1141 */
1142
1143static int
1144v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1145 struct dentry *dentry)
1146{
1147 int retval = -EPERM;
1148 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1149 struct v9fs_fcall *fcall = NULL;
1150 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
1151 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP);
1152 struct v9fs_fid *newfid = NULL;
1153 char *symname = __getname();
1154
1155 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
1156 old_dentry->d_name.name);
1157
1158 if (!v9ses->extended) {
1159 dprintk(DEBUG_ERROR, "not extended\n");
1160 goto FreeMem;
1161 }
1162
1163 /* get fid of old_dentry */
1164 sprintf(symname, "hardlink(%d)\n", oldfid->fid);
1165
1166 /* issue a create */
1167 retval = v9fs_create(dir, dentry, V9FS_DMLINK, 0);
1168 if (retval != 0)
1169 goto FreeMem;
1170
1171 newfid = v9fs_fid_lookup(dentry, FID_OP);
1172 if (!newfid) {
1173 dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
1174 goto FreeMem;
1175 }
1176
1177 /* issue a twstat */
1178 v9fs_blank_mistat(v9ses, mistat);
1179 strcpy(mistat->data + 1, symname);
1180 mistat->extension = mistat->data + 1;
1181 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
1182 if (retval < 0) {
1183 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
1184 FCALL_ERROR(fcall));
1185 goto FreeMem;
1186 }
1187
1188 kfree(fcall);
1189
1190 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
1191 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
1192 FCALL_ERROR(fcall));
1193 goto FreeMem;
1194 }
1195
1196 d_drop(dentry); /* FID - will this also clunk? */
1197
1198 kfree(fcall);
1199 fcall = NULL;
1200
1201 FreeMem:
1202 kfree(mistat);
1203 kfree(fcall);
1204 putname(symname);
1205 return retval;
1206}
1207
1208/**
1209 * v9fs_vfs_mknod - create a special file
1210 * @dir: inode destination for new link
1211 * @dentry: dentry for file
1212 * @mode: mode for creation
1213 * @dev_t: device associated with special file
1214 *
1215 */
1216
1217static int
1218v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1219{
1220 int retval = -EPERM;
1221 struct v9fs_fid *newfid;
1222 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1223 struct v9fs_fcall *fcall = NULL;
1224 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
1225 char *symname = __getname();
1226
1227 dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1228 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1229
1230 if (!mistat)
1231 return -ENOMEM;
1232
1233 if (!new_valid_dev(rdev)) {
1234 retval = -EINVAL;
1235 goto FreeMem;
1236 }
1237
1238 if (!v9ses->extended) {
1239 dprintk(DEBUG_ERROR, "not extended\n");
1240 goto FreeMem;
1241 }
1242
1243 /* issue a create */
1244 retval = v9fs_create(dir, dentry, mode, 0);
1245
1246 if (retval != 0)
1247 goto FreeMem;
1248
1249 newfid = v9fs_fid_lookup(dentry, FID_OP);
1250 if (!newfid) {
1251 dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
1252 retval = -EINVAL;
1253 goto FreeMem;
1254 }
1255
1256 /* build extension */
1257 if (S_ISBLK(mode))
1258 sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev));
1259 else if (S_ISCHR(mode))
1260 sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev));
1261 else if (S_ISFIFO(mode))
1262 ; /* DO NOTHING */
1263 else {
1264 retval = -EINVAL;
1265 goto FreeMem;
1266 }
1267
1268 if (!S_ISFIFO(mode)) {
1269 /* issue a twstat */
1270 v9fs_blank_mistat(v9ses, mistat);
1271 strcpy(mistat->data + 1, symname);
1272 mistat->extension = mistat->data + 1;
1273 retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
1274 if (retval < 0) {
1275 dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
1276 FCALL_ERROR(fcall));
1277 goto FreeMem;
1278 }
1279 }
1280
1281 /* need to update dcache so we show up */
1282 kfree(fcall);
1283
1284 if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
1285 dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
1286 FCALL_ERROR(fcall));
1287 goto FreeMem;
1288 }
1289
1290 d_drop(dentry); /* FID - will this also clunk? */
1291
1292 FreeMem:
1293 kfree(mistat);
1294 kfree(fcall);
1295 putname(symname);
1296
1297 return retval;
1298}
1299
1300static struct inode_operations v9fs_dir_inode_operations_ext = {
1301 .create = v9fs_vfs_create,
1302 .lookup = v9fs_vfs_lookup,
1303 .symlink = v9fs_vfs_symlink,
1304 .link = v9fs_vfs_link,
1305 .unlink = v9fs_vfs_unlink,
1306 .mkdir = v9fs_vfs_mkdir,
1307 .rmdir = v9fs_vfs_rmdir,
1308 .mknod = v9fs_vfs_mknod,
1309 .rename = v9fs_vfs_rename,
1310 .readlink = v9fs_vfs_readlink,
1311 .getattr = v9fs_vfs_getattr,
1312 .setattr = v9fs_vfs_setattr,
1313};
1314
1315static struct inode_operations v9fs_dir_inode_operations = {
1316 .create = v9fs_vfs_create,
1317 .lookup = v9fs_vfs_lookup,
1318 .unlink = v9fs_vfs_unlink,
1319 .mkdir = v9fs_vfs_mkdir,
1320 .rmdir = v9fs_vfs_rmdir,
1321 .mknod = v9fs_vfs_mknod,
1322 .rename = v9fs_vfs_rename,
1323 .getattr = v9fs_vfs_getattr,
1324 .setattr = v9fs_vfs_setattr,
1325};
1326
1327static struct inode_operations v9fs_file_inode_operations = {
1328 .getattr = v9fs_vfs_getattr,
1329 .setattr = v9fs_vfs_setattr,
1330};
1331
1332static struct inode_operations v9fs_symlink_inode_operations = {
1333 .readlink = v9fs_vfs_readlink,
1334 .follow_link = v9fs_vfs_follow_link,
1335 .put_link = v9fs_vfs_put_link,
1336 .getattr = v9fs_vfs_getattr,
1337 .setattr = v9fs_vfs_setattr,
1338};
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
new file mode 100644
index 000000000000..868f350b2c5f
--- /dev/null
+++ b/fs/9p/vfs_super.c
@@ -0,0 +1,280 @@
1/*
2 * linux/fs/9p/vfs_super.c
3 *
4 * This file contians superblock ops for 9P2000. It is intended that
5 * you mount this file system on directories.
6 *
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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:
22 * Free Software Foundation
23 * 51 Franklin Street, Fifth Floor
24 * Boston, MA 02111-1301 USA
25 *
26 */
27
28#include <linux/kernel.h>
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/errno.h>
32#include <linux/fs.h>
33#include <linux/file.h>
34#include <linux/stat.h>
35#include <linux/string.h>
36#include <linux/smp_lock.h>
37#include <linux/inet.h>
38#include <linux/pagemap.h>
39#include <linux/seq_file.h>
40#include <linux/mount.h>
41#include <linux/idr.h>
42
43#include "debug.h"
44#include "v9fs.h"
45#include "9p.h"
46#include "v9fs_vfs.h"
47#include "conv.h"
48#include "fid.h"
49
50static void v9fs_clear_inode(struct inode *);
51static struct super_operations v9fs_super_ops;
52
53/**
54 * v9fs_clear_inode - release an inode
55 * @inode: inode to release
56 *
57 */
58
59static void v9fs_clear_inode(struct inode *inode)
60{
61 filemap_fdatawrite(inode->i_mapping);
62}
63
64/**
65 * v9fs_set_super - set the superblock
66 * @s: super block
67 * @data: file system specific data
68 *
69 */
70
71static int v9fs_set_super(struct super_block *s, void *data)
72{
73 s->s_fs_info = data;
74 return set_anon_super(s, data);
75}
76
77/**
78 * v9fs_fill_super - populate superblock with info
79 * @sb: superblock
80 * @v9ses: session information
81 *
82 */
83
84static void
85v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
86 int flags)
87{
88 sb->s_maxbytes = MAX_LFS_FILESIZE;
89 sb->s_blocksize_bits = fls(v9ses->maxdata - 1);
90 sb->s_blocksize = 1 << sb->s_blocksize_bits;
91 sb->s_magic = V9FS_MAGIC;
92 sb->s_op = &v9fs_super_ops;
93
94 sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
95 MS_NODIRATIME | MS_NOATIME;
96}
97
98/**
99 * v9fs_get_sb - mount a superblock
100 * @fs_type: file system type
101 * @flags: mount flags
102 * @dev_name: device name that was mounted
103 * @data: mount options
104 *
105 */
106
107static struct super_block *v9fs_get_sb(struct file_system_type
108 *fs_type, int flags,
109 const char *dev_name, void *data)
110{
111 struct super_block *sb = NULL;
112 struct v9fs_fcall *fcall = NULL;
113 struct inode *inode = NULL;
114 struct dentry *root = NULL;
115 struct v9fs_session_info *v9ses = NULL;
116 struct v9fs_fid *root_fid = NULL;
117 int mode = S_IRWXUGO | S_ISVTX;
118 uid_t uid = current->fsuid;
119 gid_t gid = current->fsgid;
120 int stat_result = 0;
121 int newfid = 0;
122 int retval = 0;
123
124 dprintk(DEBUG_VFS, " \n");
125
126 v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL);
127 if (!v9ses)
128 return ERR_PTR(-ENOMEM);
129
130 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
131 dprintk(DEBUG_ERROR, "problem initiating session\n");
132 retval = newfid;
133 goto free_session;
134 }
135
136 sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
137
138 v9fs_fill_super(sb, v9ses, flags);
139
140 inode = v9fs_get_inode(sb, S_IFDIR | mode);
141 if (IS_ERR(inode)) {
142 retval = PTR_ERR(inode);
143 goto put_back_sb;
144 }
145
146 inode->i_uid = uid;
147 inode->i_gid = gid;
148
149 root = d_alloc_root(inode);
150
151 if (!root) {
152 retval = -ENOMEM;
153 goto release_inode;
154 }
155
156 sb->s_root = root;
157
158 /* Setup the Root Inode */
159 root_fid = v9fs_fid_create(root);
160 if (root_fid == NULL) {
161 retval = -ENOMEM;
162 goto release_dentry;
163 }
164
165 root_fid->fidopen = 0;
166 root_fid->v9ses = v9ses;
167
168 stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
169 if (stat_result < 0) {
170 dprintk(DEBUG_ERROR, "stat error\n");
171 v9fs_t_clunk(v9ses, newfid, NULL);
172 v9fs_put_idpool(newfid, &v9ses->fidpool);
173 } else {
174 root_fid->fid = newfid;
175 root_fid->qid = fcall->params.rstat.stat->qid;
176 root->d_inode->i_ino =
177 v9fs_qid2ino(&fcall->params.rstat.stat->qid);
178 v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb);
179 }
180
181 kfree(fcall);
182
183 if (stat_result < 0) {
184 retval = stat_result;
185 goto release_dentry;
186 }
187
188 return sb;
189
190 release_dentry:
191 dput(sb->s_root);
192
193 release_inode:
194 iput(inode);
195
196 put_back_sb:
197 up_write(&sb->s_umount);
198 deactivate_super(sb);
199 v9fs_session_close(v9ses);
200
201 free_session:
202 kfree(v9ses);
203
204 return ERR_PTR(retval);
205}
206
207/**
208 * v9fs_kill_super - Kill Superblock
209 * @s: superblock
210 *
211 */
212
213static void v9fs_kill_super(struct super_block *s)
214{
215 struct v9fs_session_info *v9ses = s->s_fs_info;
216
217 dprintk(DEBUG_VFS, " %p\n", s);
218
219 v9fs_dentry_release(s->s_root); /* clunk root */
220
221 kill_anon_super(s);
222
223 v9fs_session_close(v9ses);
224 kfree(v9ses);
225 dprintk(DEBUG_VFS, "exiting kill_super\n");
226}
227
228/**
229 * v9fs_show_options - Show mount options in /proc/mounts
230 * @m: seq_file to write to
231 * @mnt: mount descriptor
232 *
233 */
234
235static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
236{
237 struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
238
239 if (v9ses->debug != 0)
240 seq_printf(m, ",debug=%u", v9ses->debug);
241 if (v9ses->port != V9FS_PORT)
242 seq_printf(m, ",port=%u", v9ses->port);
243 if (v9ses->maxdata != 9000)
244 seq_printf(m, ",msize=%u", v9ses->maxdata);
245 if (v9ses->afid != ~0)
246 seq_printf(m, ",afid=%u", v9ses->afid);
247 if (v9ses->proto == PROTO_UNIX)
248 seq_puts(m, ",proto=unix");
249 if (v9ses->extended == 0)
250 seq_puts(m, ",noextend");
251 if (v9ses->nodev == 1)
252 seq_puts(m, ",nodevmap");
253 seq_printf(m, ",name=%s", v9ses->name);
254 seq_printf(m, ",aname=%s", v9ses->remotename);
255 seq_printf(m, ",uid=%u", v9ses->uid);
256 seq_printf(m, ",gid=%u", v9ses->gid);
257 return 0;
258}
259
260static void
261v9fs_umount_begin(struct super_block *sb)
262{
263 struct v9fs_session_info *v9ses = sb->s_fs_info;
264
265 v9fs_session_cancel(v9ses);
266}
267
268static struct super_operations v9fs_super_ops = {
269 .statfs = simple_statfs,
270 .clear_inode = v9fs_clear_inode,
271 .show_options = v9fs_show_options,
272 .umount_begin = v9fs_umount_begin,
273};
274
275struct file_system_type v9fs_fs_type = {
276 .name = "9P",
277 .get_sb = v9fs_get_sb,
278 .kill_sb = v9fs_kill_super,
279 .owner = THIS_MODULE,
280};
diff --git a/fs/Kconfig b/fs/Kconfig
index 5e817902cb3b..068ccea2f184 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -462,6 +462,19 @@ config AUTOFS4_FS
462 local network, you probably do not need an automounter, and can say 462 local network, you probably do not need an automounter, and can say
463 N here. 463 N here.
464 464
465config FUSE_FS
466 tristate "Filesystem in Userspace support"
467 help
468 With FUSE it is possible to implement a fully functional filesystem
469 in a userspace program.
470
471 There's also companion library: libfuse. This library along with
472 utilities is available from the FUSE homepage:
473 <http://fuse.sourceforge.net/>
474
475 If you want to develop a userspace FS, or if you want to use
476 a filesystem based on FUSE, answer Y or M.
477
465menu "CD-ROM/DVD Filesystems" 478menu "CD-ROM/DVD Filesystems"
466 479
467config ISO9660_FS 480config ISO9660_FS
@@ -1703,6 +1716,17 @@ config AFS_FS
1703config RXRPC 1716config RXRPC
1704 tristate 1717 tristate
1705 1718
1719config 9P_FS
1720 tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)"
1721 depends on INET && EXPERIMENTAL
1722 help
1723 If you say Y here, you will get experimental support for
1724 Plan 9 resource sharing via the 9P2000 protocol.
1725
1726 See <http://v9fs.sf.net> for more information.
1727
1728 If unsure, say N.
1729
1706endmenu 1730endmenu
1707 1731
1708menu "Partition Types" 1732menu "Partition Types"
diff --git a/fs/Makefile b/fs/Makefile
index 15158309dee4..1972da186272 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -89,11 +89,13 @@ obj-$(CONFIG_QNX4FS_FS) += qnx4/
89obj-$(CONFIG_AUTOFS_FS) += autofs/ 89obj-$(CONFIG_AUTOFS_FS) += autofs/
90obj-$(CONFIG_AUTOFS4_FS) += autofs4/ 90obj-$(CONFIG_AUTOFS4_FS) += autofs4/
91obj-$(CONFIG_ADFS_FS) += adfs/ 91obj-$(CONFIG_ADFS_FS) += adfs/
92obj-$(CONFIG_FUSE_FS) += fuse/
92obj-$(CONFIG_UDF_FS) += udf/ 93obj-$(CONFIG_UDF_FS) += udf/
93obj-$(CONFIG_RELAYFS_FS) += relayfs/ 94obj-$(CONFIG_RELAYFS_FS) += relayfs/
94obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ 95obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/
95obj-$(CONFIG_JFS_FS) += jfs/ 96obj-$(CONFIG_JFS_FS) += jfs/
96obj-$(CONFIG_XFS_FS) += xfs/ 97obj-$(CONFIG_XFS_FS) += xfs/
98obj-$(CONFIG_9P_FS) += 9p/
97obj-$(CONFIG_AFS_FS) += afs/ 99obj-$(CONFIG_AFS_FS) += afs/
98obj-$(CONFIG_BEFS_FS) += befs/ 100obj-$(CONFIG_BEFS_FS) += befs/
99obj-$(CONFIG_HOSTFS) += hostfs/ 101obj-$(CONFIG_HOSTFS) += hostfs/
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 7aa6f2004536..9ebe881c6786 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -255,6 +255,7 @@ void
255affs_delete_inode(struct inode *inode) 255affs_delete_inode(struct inode *inode)
256{ 256{
257 pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); 257 pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
258 truncate_inode_pages(&inode->i_data, 0);
258 inode->i_size = 0; 259 inode->i_size = 0;
259 if (S_ISREG(inode->i_mode)) 260 if (S_ISREG(inode->i_mode))
260 affs_truncate(inode); 261 affs_truncate(inode);
diff --git a/fs/aio.c b/fs/aio.c
index 4f641abac3c0..38f62680fd63 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -29,6 +29,7 @@
29#include <linux/highmem.h> 29#include <linux/highmem.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/security.h> 31#include <linux/security.h>
32#include <linux/rcuref.h>
32 33
33#include <asm/kmap_types.h> 34#include <asm/kmap_types.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -499,7 +500,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
499 /* Must be done under the lock to serialise against cancellation. 500 /* Must be done under the lock to serialise against cancellation.
500 * Call this aio_fput as it duplicates fput via the fput_work. 501 * Call this aio_fput as it duplicates fput via the fput_work.
501 */ 502 */
502 if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) { 503 if (unlikely(rcuref_dec_and_test(&req->ki_filp->f_count))) {
503 get_ioctx(ctx); 504 get_ioctx(ctx);
504 spin_lock(&fput_lock); 505 spin_lock(&fput_lock);
505 list_add(&req->ki_list, &fput_head); 506 list_add(&req->ki_list, &fput_head);
@@ -546,6 +547,24 @@ struct kioctx *lookup_ioctx(unsigned long ctx_id)
546 return ioctx; 547 return ioctx;
547} 548}
548 549
550static int lock_kiocb_action(void *param)
551{
552 schedule();
553 return 0;
554}
555
556static inline void lock_kiocb(struct kiocb *iocb)
557{
558 wait_on_bit_lock(&iocb->ki_flags, KIF_LOCKED, lock_kiocb_action,
559 TASK_UNINTERRUPTIBLE);
560}
561
562static inline void unlock_kiocb(struct kiocb *iocb)
563{
564 kiocbClearLocked(iocb);
565 wake_up_bit(&iocb->ki_flags, KIF_LOCKED);
566}
567
549/* 568/*
550 * use_mm 569 * use_mm
551 * Makes the calling kernel thread take on the specified 570 * Makes the calling kernel thread take on the specified
@@ -786,7 +805,9 @@ static int __aio_run_iocbs(struct kioctx *ctx)
786 * Hold an extra reference while retrying i/o. 805 * Hold an extra reference while retrying i/o.
787 */ 806 */
788 iocb->ki_users++; /* grab extra reference */ 807 iocb->ki_users++; /* grab extra reference */
808 lock_kiocb(iocb);
789 aio_run_iocb(iocb); 809 aio_run_iocb(iocb);
810 unlock_kiocb(iocb);
790 if (__aio_put_req(ctx, iocb)) /* drop extra ref */ 811 if (__aio_put_req(ctx, iocb)) /* drop extra ref */
791 put_ioctx(ctx); 812 put_ioctx(ctx);
792 } 813 }
@@ -1527,10 +1548,9 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1527 goto out_put_req; 1548 goto out_put_req;
1528 1549
1529 spin_lock_irq(&ctx->ctx_lock); 1550 spin_lock_irq(&ctx->ctx_lock);
1530 if (likely(list_empty(&ctx->run_list))) { 1551 aio_run_iocb(req);
1531 aio_run_iocb(req); 1552 unlock_kiocb(req);
1532 } else { 1553 if (!list_empty(&ctx->run_list)) {
1533 list_add_tail(&req->ki_run_list, &ctx->run_list);
1534 /* drain the run list */ 1554 /* drain the run list */
1535 while (__aio_run_iocbs(ctx)) 1555 while (__aio_run_iocbs(ctx))
1536 ; 1556 ;
@@ -1661,6 +1681,7 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
1661 if (NULL != cancel) { 1681 if (NULL != cancel) {
1662 struct io_event tmp; 1682 struct io_event tmp;
1663 pr_debug("calling cancel\n"); 1683 pr_debug("calling cancel\n");
1684 lock_kiocb(kiocb);
1664 memset(&tmp, 0, sizeof(tmp)); 1685 memset(&tmp, 0, sizeof(tmp));
1665 tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user; 1686 tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user;
1666 tmp.data = kiocb->ki_user_data; 1687 tmp.data = kiocb->ki_user_data;
@@ -1672,8 +1693,9 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
1672 if (copy_to_user(result, &tmp, sizeof(tmp))) 1693 if (copy_to_user(result, &tmp, sizeof(tmp)))
1673 ret = -EFAULT; 1694 ret = -EFAULT;
1674 } 1695 }
1696 unlock_kiocb(kiocb);
1675 } else 1697 } else
1676 printk(KERN_DEBUG "iocb has no cancel operation\n"); 1698 ret = -EINVAL;
1677 1699
1678 put_ioctx(ctx); 1700 put_ioctx(ctx);
1679 1701
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 6171431272dc..990c28da5aec 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -105,6 +105,7 @@ struct autofs_sb_info {
105 struct file *pipe; 105 struct file *pipe;
106 pid_t oz_pgrp; 106 pid_t oz_pgrp;
107 int catatonic; 107 int catatonic;
108 struct super_block *sb;
108 unsigned long exp_timeout; 109 unsigned long exp_timeout;
109 ino_t next_dir_ino; 110 ino_t next_dir_ino;
110 struct autofs_wait_queue *queues; /* Wait queue pointer */ 111 struct autofs_wait_queue *queues; /* Wait queue pointer */
@@ -134,7 +135,7 @@ void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
134void autofs_hash_delete(struct autofs_dir_ent *); 135void autofs_hash_delete(struct autofs_dir_ent *);
135struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *); 136struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *);
136void autofs_hash_dputall(struct autofs_dirhash *); 137void autofs_hash_dputall(struct autofs_dirhash *);
137void autofs_hash_nuke(struct autofs_dirhash *); 138void autofs_hash_nuke(struct autofs_sb_info *);
138 139
139/* Expiration-handling functions */ 140/* Expiration-handling functions */
140 141
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
index 448143fd0796..5ccfcf26310d 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -232,13 +232,13 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
232 232
233/* Delete everything. This is used on filesystem destruction, so we 233/* Delete everything. This is used on filesystem destruction, so we
234 make no attempt to keep the pointers valid */ 234 make no attempt to keep the pointers valid */
235void autofs_hash_nuke(struct autofs_dirhash *dh) 235void autofs_hash_nuke(struct autofs_sb_info *sbi)
236{ 236{
237 int i; 237 int i;
238 struct autofs_dir_ent *ent, *nent; 238 struct autofs_dir_ent *ent, *nent;
239 239
240 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { 240 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
241 for ( ent = dh->h[i] ; ent ; ent = nent ) { 241 for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
242 nent = ent->next; 242 nent = ent->next;
243 if ( ent->dentry ) 243 if ( ent->dentry )
244 dput(ent->dentry); 244 dput(ent->dentry);
@@ -246,4 +246,5 @@ void autofs_hash_nuke(struct autofs_dirhash *dh)
246 kfree(ent); 246 kfree(ent);
247 } 247 }
248 } 248 }
249 shrink_dcache_sb(sbi->sb);
249} 250}
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index 4888c1fabbf7..65e5ed42190e 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -27,7 +27,7 @@ static void autofs_put_super(struct super_block *sb)
27 if ( !sbi->catatonic ) 27 if ( !sbi->catatonic )
28 autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ 28 autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
29 29
30 autofs_hash_nuke(&sbi->dirhash); 30 autofs_hash_nuke(sbi);
31 for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) { 31 for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
32 if ( test_bit(n, sbi->symlink_bitmap) ) 32 if ( test_bit(n, sbi->symlink_bitmap) )
33 kfree(sbi->symlink[n].data); 33 kfree(sbi->symlink[n].data);
@@ -148,6 +148,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
148 s->s_magic = AUTOFS_SUPER_MAGIC; 148 s->s_magic = AUTOFS_SUPER_MAGIC;
149 s->s_op = &autofs_sops; 149 s->s_op = &autofs_sops;
150 s->s_time_gran = 1; 150 s->s_time_gran = 1;
151 sbi->sb = s;
151 152
152 root_inode = iget(s, AUTOFS_ROOT_INO); 153 root_inode = iget(s, AUTOFS_ROOT_INO);
153 root = d_alloc_root(root_inode); 154 root = d_alloc_root(root_inode);
diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h
index 1020dbc88bec..1fbc53f14aba 100644
--- a/fs/bfs/bfs.h
+++ b/fs/bfs/bfs.h
@@ -20,7 +20,6 @@ struct bfs_sb_info {
20 unsigned long si_lasti; 20 unsigned long si_lasti;
21 unsigned long * si_imap; 21 unsigned long * si_imap;
22 struct buffer_head * si_sbh; /* buffer header w/superblock */ 22 struct buffer_head * si_sbh; /* buffer header w/superblock */
23 struct bfs_super_block * si_bfs_sb; /* superblock in si_sbh->b_data */
24}; 23};
25 24
26/* 25/*
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 5a1e5ce057ff..e240c335eb23 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -2,6 +2,7 @@
2 * fs/bfs/dir.c 2 * fs/bfs/dir.c
3 * BFS directory operations. 3 * BFS directory operations.
4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> 4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
5 * Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
5 */ 6 */
6 7
7#include <linux/time.h> 8#include <linux/time.h>
@@ -20,9 +21,9 @@
20#define dprintf(x...) 21#define dprintf(x...)
21#endif 22#endif
22 23
23static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ino); 24static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino);
24static struct buffer_head * bfs_find_entry(struct inode * dir, 25static struct buffer_head * bfs_find_entry(struct inode * dir,
25 const char * name, int namelen, struct bfs_dirent ** res_dir); 26 const unsigned char * name, int namelen, struct bfs_dirent ** res_dir);
26 27
27static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) 28static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
28{ 29{
@@ -53,7 +54,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
53 de = (struct bfs_dirent *)(bh->b_data + offset); 54 de = (struct bfs_dirent *)(bh->b_data + offset);
54 if (de->ino) { 55 if (de->ino) {
55 int size = strnlen(de->name, BFS_NAMELEN); 56 int size = strnlen(de->name, BFS_NAMELEN);
56 if (filldir(dirent, de->name, size, f->f_pos, de->ino, DT_UNKNOWN) < 0) { 57 if (filldir(dirent, de->name, size, f->f_pos, le16_to_cpu(de->ino), DT_UNKNOWN) < 0) {
57 brelse(bh); 58 brelse(bh);
58 unlock_kernel(); 59 unlock_kernel();
59 return 0; 60 return 0;
@@ -107,7 +108,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
107 inode->i_mapping->a_ops = &bfs_aops; 108 inode->i_mapping->a_ops = &bfs_aops;
108 inode->i_mode = mode; 109 inode->i_mode = mode;
109 inode->i_ino = ino; 110 inode->i_ino = ino;
110 BFS_I(inode)->i_dsk_ino = ino; 111 BFS_I(inode)->i_dsk_ino = cpu_to_le16(ino);
111 BFS_I(inode)->i_sblock = 0; 112 BFS_I(inode)->i_sblock = 0;
112 BFS_I(inode)->i_eblock = 0; 113 BFS_I(inode)->i_eblock = 0;
113 insert_inode_hash(inode); 114 insert_inode_hash(inode);
@@ -139,7 +140,7 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, st
139 lock_kernel(); 140 lock_kernel();
140 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); 141 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
141 if (bh) { 142 if (bh) {
142 unsigned long ino = le32_to_cpu(de->ino); 143 unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
143 brelse(bh); 144 brelse(bh);
144 inode = iget(dir->i_sb, ino); 145 inode = iget(dir->i_sb, ino);
145 if (!inode) { 146 if (!inode) {
@@ -183,7 +184,7 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry)
183 inode = dentry->d_inode; 184 inode = dentry->d_inode;
184 lock_kernel(); 185 lock_kernel();
185 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); 186 bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
186 if (!bh || de->ino != inode->i_ino) 187 if (!bh || le16_to_cpu(de->ino) != inode->i_ino)
187 goto out_brelse; 188 goto out_brelse;
188 189
189 if (!inode->i_nlink) { 190 if (!inode->i_nlink) {
@@ -224,7 +225,7 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
224 old_dentry->d_name.name, 225 old_dentry->d_name.name,
225 old_dentry->d_name.len, &old_de); 226 old_dentry->d_name.len, &old_de);
226 227
227 if (!old_bh || old_de->ino != old_inode->i_ino) 228 if (!old_bh || le16_to_cpu(old_de->ino) != old_inode->i_ino)
228 goto end_rename; 229 goto end_rename;
229 230
230 error = -EPERM; 231 error = -EPERM;
@@ -270,7 +271,7 @@ struct inode_operations bfs_dir_inops = {
270 .rename = bfs_rename, 271 .rename = bfs_rename,
271}; 272};
272 273
273static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ino) 274static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino)
274{ 275{
275 struct buffer_head * bh; 276 struct buffer_head * bh;
276 struct bfs_dirent * de; 277 struct bfs_dirent * de;
@@ -304,7 +305,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
304 } 305 }
305 dir->i_mtime = CURRENT_TIME_SEC; 306 dir->i_mtime = CURRENT_TIME_SEC;
306 mark_inode_dirty(dir); 307 mark_inode_dirty(dir);
307 de->ino = ino; 308 de->ino = cpu_to_le16((u16)ino);
308 for (i=0; i<BFS_NAMELEN; i++) 309 for (i=0; i<BFS_NAMELEN; i++)
309 de->name[i] = (i < namelen) ? name[i] : 0; 310 de->name[i] = (i < namelen) ? name[i] : 0;
310 mark_buffer_dirty(bh); 311 mark_buffer_dirty(bh);
@@ -317,7 +318,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
317 return -ENOSPC; 318 return -ENOSPC;
318} 319}
319 320
320static inline int bfs_namecmp(int len, const char * name, const char * buffer) 321static inline int bfs_namecmp(int len, const unsigned char * name, const char * buffer)
321{ 322{
322 if (len < BFS_NAMELEN && buffer[len]) 323 if (len < BFS_NAMELEN && buffer[len])
323 return 0; 324 return 0;
@@ -325,7 +326,7 @@ static inline int bfs_namecmp(int len, const char * name, const char * buffer)
325} 326}
326 327
327static struct buffer_head * bfs_find_entry(struct inode * dir, 328static struct buffer_head * bfs_find_entry(struct inode * dir,
328 const char * name, int namelen, struct bfs_dirent ** res_dir) 329 const unsigned char * name, int namelen, struct bfs_dirent ** res_dir)
329{ 330{
330 unsigned long block, offset; 331 unsigned long block, offset;
331 struct buffer_head * bh; 332 struct buffer_head * bh;
@@ -346,7 +347,7 @@ static struct buffer_head * bfs_find_entry(struct inode * dir,
346 } 347 }
347 de = (struct bfs_dirent *)(bh->b_data + offset); 348 de = (struct bfs_dirent *)(bh->b_data + offset);
348 offset += BFS_DIRENT_SIZE; 349 offset += BFS_DIRENT_SIZE;
349 if (de->ino && bfs_namecmp(namelen, name, de->name)) { 350 if (le16_to_cpu(de->ino) && bfs_namecmp(namelen, name, de->name)) {
350 *res_dir = de; 351 *res_dir = de;
351 return bh; 352 return bh;
352 } 353 }
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 747fd1ea55e0..807723b65daf 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -40,8 +40,8 @@ static int bfs_move_block(unsigned long from, unsigned long to, struct super_blo
40 return 0; 40 return 0;
41} 41}
42 42
43static int bfs_move_blocks(struct super_block *sb, unsigned long start, unsigned long end, 43static int bfs_move_blocks(struct super_block *sb, unsigned long start,
44 unsigned long where) 44 unsigned long end, unsigned long where)
45{ 45{
46 unsigned long i; 46 unsigned long i;
47 47
@@ -57,20 +57,21 @@ static int bfs_move_blocks(struct super_block *sb, unsigned long start, unsigned
57static int bfs_get_block(struct inode * inode, sector_t block, 57static int bfs_get_block(struct inode * inode, sector_t block,
58 struct buffer_head * bh_result, int create) 58 struct buffer_head * bh_result, int create)
59{ 59{
60 long phys; 60 unsigned long phys;
61 int err; 61 int err;
62 struct super_block *sb = inode->i_sb; 62 struct super_block *sb = inode->i_sb;
63 struct bfs_sb_info *info = BFS_SB(sb); 63 struct bfs_sb_info *info = BFS_SB(sb);
64 struct bfs_inode_info *bi = BFS_I(inode); 64 struct bfs_inode_info *bi = BFS_I(inode);
65 struct buffer_head *sbh = info->si_sbh; 65 struct buffer_head *sbh = info->si_sbh;
66 66
67 if (block < 0 || block > info->si_blocks) 67 if (block > info->si_blocks)
68 return -EIO; 68 return -EIO;
69 69
70 phys = bi->i_sblock + block; 70 phys = bi->i_sblock + block;
71 if (!create) { 71 if (!create) {
72 if (phys <= bi->i_eblock) { 72 if (phys <= bi->i_eblock) {
73 dprintf("c=%d, b=%08lx, phys=%08lx (granted)\n", create, block, phys); 73 dprintf("c=%d, b=%08lx, phys=%09lx (granted)\n",
74 create, (unsigned long)block, phys);
74 map_bh(bh_result, sb, phys); 75 map_bh(bh_result, sb, phys);
75 } 76 }
76 return 0; 77 return 0;
@@ -80,7 +81,7 @@ static int bfs_get_block(struct inode * inode, sector_t block,
80 of blocks allocated for this file, we can grant it */ 81 of blocks allocated for this file, we can grant it */
81 if (inode->i_size && phys <= bi->i_eblock) { 82 if (inode->i_size && phys <= bi->i_eblock) {
82 dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n", 83 dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n",
83 create, block, phys); 84 create, (unsigned long)block, phys);
84 map_bh(bh_result, sb, phys); 85 map_bh(bh_result, sb, phys);
85 return 0; 86 return 0;
86 } 87 }
@@ -88,11 +89,12 @@ static int bfs_get_block(struct inode * inode, sector_t block,
88 /* the rest has to be protected against itself */ 89 /* the rest has to be protected against itself */
89 lock_kernel(); 90 lock_kernel();
90 91
91 /* if the last data block for this file is the last allocated block, we can 92 /* if the last data block for this file is the last allocated
92 extend the file trivially, without moving it anywhere */ 93 block, we can extend the file trivially, without moving it
94 anywhere */
93 if (bi->i_eblock == info->si_lf_eblk) { 95 if (bi->i_eblock == info->si_lf_eblk) {
94 dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n", 96 dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n",
95 create, block, phys); 97 create, (unsigned long)block, phys);
96 map_bh(bh_result, sb, phys); 98 map_bh(bh_result, sb, phys);
97 info->si_freeb -= phys - bi->i_eblock; 99 info->si_freeb -= phys - bi->i_eblock;
98 info->si_lf_eblk = bi->i_eblock = phys; 100 info->si_lf_eblk = bi->i_eblock = phys;
@@ -114,7 +116,8 @@ static int bfs_get_block(struct inode * inode, sector_t block,
114 } else 116 } else
115 err = 0; 117 err = 0;
116 118
117 dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys); 119 dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n",
120 create, (unsigned long)block, phys);
118 bi->i_sblock = phys; 121 bi->i_sblock = phys;
119 phys += block; 122 phys += block;
120 info->si_lf_eblk = bi->i_eblock = phys; 123 info->si_lf_eblk = bi->i_eblock = phys;
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 64e0fb33fc0c..c7b39aa279d7 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -3,6 +3,8 @@
3 * BFS superblock and inode operations. 3 * BFS superblock and inode operations.
4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> 4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. 5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
6 *
7 * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
6 */ 8 */
7 9
8#include <linux/module.h> 10#include <linux/module.h>
@@ -54,46 +56,50 @@ static void bfs_read_inode(struct inode * inode)
54 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; 56 off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
55 di = (struct bfs_inode *)bh->b_data + off; 57 di = (struct bfs_inode *)bh->b_data + off;
56 58
57 inode->i_mode = 0x0000FFFF & di->i_mode; 59 inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
58 if (di->i_vtype == BFS_VDIR) { 60 if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
59 inode->i_mode |= S_IFDIR; 61 inode->i_mode |= S_IFDIR;
60 inode->i_op = &bfs_dir_inops; 62 inode->i_op = &bfs_dir_inops;
61 inode->i_fop = &bfs_dir_operations; 63 inode->i_fop = &bfs_dir_operations;
62 } else if (di->i_vtype == BFS_VREG) { 64 } else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
63 inode->i_mode |= S_IFREG; 65 inode->i_mode |= S_IFREG;
64 inode->i_op = &bfs_file_inops; 66 inode->i_op = &bfs_file_inops;
65 inode->i_fop = &bfs_file_operations; 67 inode->i_fop = &bfs_file_operations;
66 inode->i_mapping->a_ops = &bfs_aops; 68 inode->i_mapping->a_ops = &bfs_aops;
67 } 69 }
68 70
69 inode->i_uid = di->i_uid; 71 BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock);
70 inode->i_gid = di->i_gid; 72 BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock);
71 inode->i_nlink = di->i_nlink; 73 inode->i_uid = le32_to_cpu(di->i_uid);
74 inode->i_gid = le32_to_cpu(di->i_gid);
75 inode->i_nlink = le32_to_cpu(di->i_nlink);
72 inode->i_size = BFS_FILESIZE(di); 76 inode->i_size = BFS_FILESIZE(di);
73 inode->i_blocks = BFS_FILEBLOCKS(di); 77 inode->i_blocks = BFS_FILEBLOCKS(di);
78 if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks\n", inode->i_size, inode->i_blocks);
74 inode->i_blksize = PAGE_SIZE; 79 inode->i_blksize = PAGE_SIZE;
75 inode->i_atime.tv_sec = di->i_atime; 80 inode->i_atime.tv_sec = le32_to_cpu(di->i_atime);
76 inode->i_mtime.tv_sec = di->i_mtime; 81 inode->i_mtime.tv_sec = le32_to_cpu(di->i_mtime);
77 inode->i_ctime.tv_sec = di->i_ctime; 82 inode->i_ctime.tv_sec = le32_to_cpu(di->i_ctime);
78 inode->i_atime.tv_nsec = 0; 83 inode->i_atime.tv_nsec = 0;
79 inode->i_mtime.tv_nsec = 0; 84 inode->i_mtime.tv_nsec = 0;
80 inode->i_ctime.tv_nsec = 0; 85 inode->i_ctime.tv_nsec = 0;
81 BFS_I(inode)->i_dsk_ino = di->i_ino; /* can be 0 so we store a copy */ 86 BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */
82 BFS_I(inode)->i_sblock = di->i_sblock;
83 BFS_I(inode)->i_eblock = di->i_eblock;
84 87
85 brelse(bh); 88 brelse(bh);
86} 89}
87 90
88static int bfs_write_inode(struct inode * inode, int unused) 91static int bfs_write_inode(struct inode * inode, int unused)
89{ 92{
90 unsigned long ino = inode->i_ino; 93 unsigned int ino = (u16)inode->i_ino;
94 unsigned long i_sblock;
91 struct bfs_inode * di; 95 struct bfs_inode * di;
92 struct buffer_head * bh; 96 struct buffer_head * bh;
93 int block, off; 97 int block, off;
94 98
99 dprintf("ino=%08x\n", ino);
100
95 if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) { 101 if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
96 printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino); 102 printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
97 return -EIO; 103 return -EIO;
98 } 104 }
99 105
@@ -101,7 +107,7 @@ static int bfs_write_inode(struct inode * inode, int unused)
101 block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1; 107 block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
102 bh = sb_bread(inode->i_sb, block); 108 bh = sb_bread(inode->i_sb, block);
103 if (!bh) { 109 if (!bh) {
104 printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); 110 printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino);
105 unlock_kernel(); 111 unlock_kernel();
106 return -EIO; 112 return -EIO;
107 } 113 }
@@ -109,24 +115,26 @@ static int bfs_write_inode(struct inode * inode, int unused)
109 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; 115 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
110 di = (struct bfs_inode *)bh->b_data + off; 116 di = (struct bfs_inode *)bh->b_data + off;
111 117
112 if (inode->i_ino == BFS_ROOT_INO) 118 if (ino == BFS_ROOT_INO)
113 di->i_vtype = BFS_VDIR; 119 di->i_vtype = cpu_to_le32(BFS_VDIR);
114 else 120 else
115 di->i_vtype = BFS_VREG; 121 di->i_vtype = cpu_to_le32(BFS_VREG);
116 122
117 di->i_ino = inode->i_ino; 123 di->i_ino = cpu_to_le16(ino);
118 di->i_mode = inode->i_mode; 124 di->i_mode = cpu_to_le32(inode->i_mode);
119 di->i_uid = inode->i_uid; 125 di->i_uid = cpu_to_le32(inode->i_uid);
120 di->i_gid = inode->i_gid; 126 di->i_gid = cpu_to_le32(inode->i_gid);
121 di->i_nlink = inode->i_nlink; 127 di->i_nlink = cpu_to_le32(inode->i_nlink);
122 di->i_atime = inode->i_atime.tv_sec; 128 di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
123 di->i_mtime = inode->i_mtime.tv_sec; 129 di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
124 di->i_ctime = inode->i_ctime.tv_sec; 130 di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
125 di->i_sblock = BFS_I(inode)->i_sblock; 131 i_sblock = BFS_I(inode)->i_sblock;
126 di->i_eblock = BFS_I(inode)->i_eblock; 132 di->i_sblock = cpu_to_le32(i_sblock);
127 di->i_eoffset = di->i_sblock * BFS_BSIZE + inode->i_size - 1; 133 di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
134 di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
128 135
129 mark_buffer_dirty(bh); 136 mark_buffer_dirty(bh);
137 dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di->i_ino),block,off);
130 brelse(bh); 138 brelse(bh);
131 unlock_kernel(); 139 unlock_kernel();
132 return 0; 140 return 0;
@@ -140,11 +148,14 @@ static void bfs_delete_inode(struct inode * inode)
140 int block, off; 148 int block, off;
141 struct super_block * s = inode->i_sb; 149 struct super_block * s = inode->i_sb;
142 struct bfs_sb_info * info = BFS_SB(s); 150 struct bfs_sb_info * info = BFS_SB(s);
151 struct bfs_inode_info * bi = BFS_I(inode);
143 152
144 dprintf("ino=%08lx\n", inode->i_ino); 153 dprintf("ino=%08lx\n", ino);
145 154
146 if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > info->si_lasti) { 155 truncate_inode_pages(&inode->i_data, 0);
147 printf("invalid ino=%08lx\n", inode->i_ino); 156
157 if (ino < BFS_ROOT_INO || ino > info->si_lasti) {
158 printf("invalid ino=%08lx\n", ino);
148 return; 159 return;
149 } 160 }
150 161
@@ -160,13 +171,13 @@ static void bfs_delete_inode(struct inode * inode)
160 return; 171 return;
161 } 172 }
162 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK; 173 off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
163 di = (struct bfs_inode *)bh->b_data + off; 174 di = (struct bfs_inode *) bh->b_data + off;
164 if (di->i_ino) { 175 if (bi->i_dsk_ino) {
165 info->si_freeb += BFS_FILEBLOCKS(di); 176 info->si_freeb += 1 + bi->i_eblock - bi->i_sblock;
166 info->si_freei++; 177 info->si_freei++;
167 clear_bit(di->i_ino, info->si_imap); 178 clear_bit(ino, info->si_imap);
168 dump_imap("delete_inode", s); 179 dump_imap("delete_inode", s);
169 } 180 }
170 di->i_ino = 0; 181 di->i_ino = 0;
171 di->i_sblock = 0; 182 di->i_sblock = 0;
172 mark_buffer_dirty(bh); 183 mark_buffer_dirty(bh);
@@ -272,14 +283,14 @@ static struct super_operations bfs_sops = {
272 283
273void dump_imap(const char *prefix, struct super_block * s) 284void dump_imap(const char *prefix, struct super_block * s)
274{ 285{
275#if 0 286#ifdef DEBUG
276 int i; 287 int i;
277 char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL); 288 char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
278 289
279 if (!tmpbuf) 290 if (!tmpbuf)
280 return; 291 return;
281 for (i=BFS_SB(s)->si_lasti; i>=0; i--) { 292 for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
282 if (i>PAGE_SIZE-100) break; 293 if (i > PAGE_SIZE-100) break;
283 if (test_bit(i, BFS_SB(s)->si_imap)) 294 if (test_bit(i, BFS_SB(s)->si_imap))
284 strcat(tmpbuf, "1"); 295 strcat(tmpbuf, "1");
285 else 296 else
@@ -295,7 +306,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
295 struct buffer_head * bh; 306 struct buffer_head * bh;
296 struct bfs_super_block * bfs_sb; 307 struct bfs_super_block * bfs_sb;
297 struct inode * inode; 308 struct inode * inode;
298 int i, imap_len; 309 unsigned i, imap_len;
299 struct bfs_sb_info * info; 310 struct bfs_sb_info * info;
300 311
301 info = kmalloc(sizeof(*info), GFP_KERNEL); 312 info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -310,19 +321,18 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
310 if(!bh) 321 if(!bh)
311 goto out; 322 goto out;
312 bfs_sb = (struct bfs_super_block *)bh->b_data; 323 bfs_sb = (struct bfs_super_block *)bh->b_data;
313 if (bfs_sb->s_magic != BFS_MAGIC) { 324 if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
314 if (!silent) 325 if (!silent)
315 printf("No BFS filesystem on %s (magic=%08x)\n", 326 printf("No BFS filesystem on %s (magic=%08x)\n",
316 s->s_id, bfs_sb->s_magic); 327 s->s_id, le32_to_cpu(bfs_sb->s_magic));
317 goto out; 328 goto out;
318 } 329 }
319 if (BFS_UNCLEAN(bfs_sb, s) && !silent) 330 if (BFS_UNCLEAN(bfs_sb, s) && !silent)
320 printf("%s is unclean, continuing\n", s->s_id); 331 printf("%s is unclean, continuing\n", s->s_id);
321 332
322 s->s_magic = BFS_MAGIC; 333 s->s_magic = BFS_MAGIC;
323 info->si_bfs_sb = bfs_sb;
324 info->si_sbh = bh; 334 info->si_sbh = bh;
325 info->si_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode) 335 info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode)
326 + BFS_ROOT_INO - 1; 336 + BFS_ROOT_INO - 1;
327 337
328 imap_len = info->si_lasti/8 + 1; 338 imap_len = info->si_lasti/8 + 1;
@@ -346,8 +356,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
346 goto out; 356 goto out;
347 } 357 }
348 358
349 info->si_blocks = (bfs_sb->s_end + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */ 359 info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
350 info->si_freeb = (bfs_sb->s_end + 1 - bfs_sb->s_start)>>BFS_BSIZE_BITS; 360 info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - cpu_to_le32(bfs_sb->s_start))>>BFS_BSIZE_BITS;
351 info->si_freei = 0; 361 info->si_freei = 0;
352 info->si_lf_eblk = 0; 362 info->si_lf_eblk = 0;
353 info->si_lf_sblk = 0; 363 info->si_lf_sblk = 0;
diff --git a/fs/bio.c b/fs/bio.c
index a7d4fd3a3299..83a349574567 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -683,7 +683,7 @@ struct bio *bio_map_user(request_queue_t *q, struct block_device *bdev,
683{ 683{
684 struct sg_iovec iov; 684 struct sg_iovec iov;
685 685
686 iov.iov_base = (__user void *)uaddr; 686 iov.iov_base = (void __user *)uaddr;
687 iov.iov_len = len; 687 iov.iov_len = len;
688 688
689 return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm); 689 return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm);
diff --git a/fs/compat.c b/fs/compat.c
index 8c665705c6a0..ac3fb9ed8eea 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1619,6 +1619,7 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1619 char *bits; 1619 char *bits;
1620 long timeout; 1620 long timeout;
1621 int size, max_fdset, ret = -EINVAL; 1621 int size, max_fdset, ret = -EINVAL;
1622 struct fdtable *fdt;
1622 1623
1623 timeout = MAX_SCHEDULE_TIMEOUT; 1624 timeout = MAX_SCHEDULE_TIMEOUT;
1624 if (tvp) { 1625 if (tvp) {
@@ -1644,7 +1645,10 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1644 goto out_nofds; 1645 goto out_nofds;
1645 1646
1646 /* max_fdset can increase, so grab it once to avoid race */ 1647 /* max_fdset can increase, so grab it once to avoid race */
1647 max_fdset = current->files->max_fdset; 1648 rcu_read_lock();
1649 fdt = files_fdtable(current->files);
1650 max_fdset = fdt->max_fdset;
1651 rcu_read_unlock();
1648 if (n > max_fdset) 1652 if (n > max_fdset)
1649 n = max_fdset; 1653 n = max_fdset;
1650 1654
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 155e612635f1..e28a74203f3b 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -798,13 +798,16 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
798 r = (void *) &r4; 798 r = (void *) &r4;
799 } 799 }
800 800
801 if (ret) 801 if (ret) {
802 return -EFAULT; 802 ret = -EFAULT;
803 goto out;
804 }
803 805
804 set_fs (KERNEL_DS); 806 set_fs (KERNEL_DS);
805 ret = sys_ioctl (fd, cmd, (unsigned long) r); 807 ret = sys_ioctl (fd, cmd, (unsigned long) r);
806 set_fs (old_fs); 808 set_fs (old_fs);
807 809
810out:
808 if (mysock) 811 if (mysock)
809 sockfd_put(mysock); 812 sockfd_put(mysock);
810 813
diff --git a/fs/exec.c b/fs/exec.c
index 222ab1c572d8..14dd03907ccb 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -798,6 +798,7 @@ no_thread_group:
798static inline void flush_old_files(struct files_struct * files) 798static inline void flush_old_files(struct files_struct * files)
799{ 799{
800 long j = -1; 800 long j = -1;
801 struct fdtable *fdt;
801 802
802 spin_lock(&files->file_lock); 803 spin_lock(&files->file_lock);
803 for (;;) { 804 for (;;) {
@@ -805,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files)
805 806
806 j++; 807 j++;
807 i = j * __NFDBITS; 808 i = j * __NFDBITS;
808 if (i >= files->max_fds || i >= files->max_fdset) 809 fdt = files_fdtable(files);
810 if (i >= fdt->max_fds || i >= fdt->max_fdset)
809 break; 811 break;
810 set = files->close_on_exec->fds_bits[j]; 812 set = fdt->close_on_exec->fds_bits[j];
811 if (!set) 813 if (!set)
812 continue; 814 continue;
813 files->close_on_exec->fds_bits[j] = 0; 815 fdt->close_on_exec->fds_bits[j] = 0;
814 spin_unlock(&files->file_lock); 816 spin_unlock(&files->file_lock);
815 for ( ; set ; i++,set >>= 1) { 817 for ( ; set ; i++,set >>= 1) {
816 if (set & 1) { 818 if (set & 1) {
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 161f156d98c8..c8d07030c897 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -615,6 +615,11 @@ got:
615 DQUOT_DROP(inode); 615 DQUOT_DROP(inode);
616 goto fail2; 616 goto fail2;
617 } 617 }
618 err = ext2_init_security(inode,dir);
619 if (err) {
620 DQUOT_FREE_INODE(inode);
621 goto fail2;
622 }
618 mark_inode_dirty(inode); 623 mark_inode_dirty(inode);
619 ext2_debug("allocating inode %lu\n", inode->i_ino); 624 ext2_debug("allocating inode %lu\n", inode->i_ino);
620 ext2_preread_inode(inode); 625 ext2_preread_inode(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 53dceb0c6593..fdba4d1d3c60 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -71,6 +71,8 @@ void ext2_put_inode(struct inode *inode)
71 */ 71 */
72void ext2_delete_inode (struct inode * inode) 72void ext2_delete_inode (struct inode * inode)
73{ 73{
74 truncate_inode_pages(&inode->i_data, 0);
75
74 if (is_bad_inode(inode)) 76 if (is_bad_inode(inode))
75 goto no_delete; 77 goto no_delete;
76 EXT2_I(inode)->i_dtime = get_seconds(); 78 EXT2_I(inode)->i_dtime = get_seconds();
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 5f3bfde3b810..67cfeb66e897 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -116,3 +116,11 @@ exit_ext2_xattr(void)
116 116
117# endif /* CONFIG_EXT2_FS_XATTR */ 117# endif /* CONFIG_EXT2_FS_XATTR */
118 118
119#ifdef CONFIG_EXT2_FS_SECURITY
120extern int ext2_init_security(struct inode *inode, struct inode *dir);
121#else
122static inline int ext2_init_security(struct inode *inode, struct inode *dir)
123{
124 return 0;
125}
126#endif
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 6a6c59fbe599..a26612798471 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -8,6 +8,7 @@
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/smp_lock.h> 9#include <linux/smp_lock.h>
10#include <linux/ext2_fs.h> 10#include <linux/ext2_fs.h>
11#include <linux/security.h>
11#include "xattr.h" 12#include "xattr.h"
12 13
13static size_t 14static size_t
@@ -45,6 +46,27 @@ ext2_xattr_security_set(struct inode *inode, const char *name,
45 value, size, flags); 46 value, size, flags);
46} 47}
47 48
49int
50ext2_init_security(struct inode *inode, struct inode *dir)
51{
52 int err;
53 size_t len;
54 void *value;
55 char *name;
56
57 err = security_inode_init_security(inode, dir, &name, &value, &len);
58 if (err) {
59 if (err == -EOPNOTSUPP)
60 return 0;
61 return err;
62 }
63 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
64 name, value, len, 0);
65 kfree(name);
66 kfree(value);
67 return err;
68}
69
48struct xattr_handler ext2_xattr_security_handler = { 70struct xattr_handler ext2_xattr_security_handler = {
49 .prefix = XATTR_SECURITY_PREFIX, 71 .prefix = XATTR_SECURITY_PREFIX,
50 .list = ext2_xattr_security_list, 72 .list = ext2_xattr_security_list,
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 6981bd014ede..96552769d039 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -607,6 +607,11 @@ got:
607 DQUOT_DROP(inode); 607 DQUOT_DROP(inode);
608 goto fail2; 608 goto fail2;
609 } 609 }
610 err = ext3_init_security(handle,inode, dir);
611 if (err) {
612 DQUOT_FREE_INODE(inode);
613 goto fail2;
614 }
610 err = ext3_mark_inode_dirty(handle, inode); 615 err = ext3_mark_inode_dirty(handle, inode);
611 if (err) { 616 if (err) {
612 ext3_std_error(sb, err); 617 ext3_std_error(sb, err);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 9989fdcf4d5a..b5177c90d6f1 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -187,6 +187,8 @@ void ext3_delete_inode (struct inode * inode)
187{ 187{
188 handle_t *handle; 188 handle_t *handle;
189 189
190 truncate_inode_pages(&inode->i_data, 0);
191
190 if (is_bad_inode(inode)) 192 if (is_bad_inode(inode))
191 goto no_delete; 193 goto no_delete;
192 194
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index eb31a69e82dc..2ceae38f3d49 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -133,3 +133,14 @@ exit_ext3_xattr(void)
133#define ext3_xattr_handlers NULL 133#define ext3_xattr_handlers NULL
134 134
135# endif /* CONFIG_EXT3_FS_XATTR */ 135# endif /* CONFIG_EXT3_FS_XATTR */
136
137#ifdef CONFIG_EXT3_FS_SECURITY
138extern int ext3_init_security(handle_t *handle, struct inode *inode,
139 struct inode *dir);
140#else
141static inline int ext3_init_security(handle_t *handle, struct inode *inode,
142 struct inode *dir)
143{
144 return 0;
145}
146#endif
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index ddc1c41750e1..b9c40c15647b 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -9,6 +9,7 @@
9#include <linux/smp_lock.h> 9#include <linux/smp_lock.h>
10#include <linux/ext3_jbd.h> 10#include <linux/ext3_jbd.h>
11#include <linux/ext3_fs.h> 11#include <linux/ext3_fs.h>
12#include <linux/security.h>
12#include "xattr.h" 13#include "xattr.h"
13 14
14static size_t 15static size_t
@@ -47,6 +48,27 @@ ext3_xattr_security_set(struct inode *inode, const char *name,
47 value, size, flags); 48 value, size, flags);
48} 49}
49 50
51int
52ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
53{
54 int err;
55 size_t len;
56 void *value;
57 char *name;
58
59 err = security_inode_init_security(inode, dir, &name, &value, &len);
60 if (err) {
61 if (err == -EOPNOTSUPP)
62 return 0;
63 return err;
64 }
65 err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
66 name, value, len, 0);
67 kfree(name);
68 kfree(value);
69 return err;
70}
71
50struct xattr_handler ext3_xattr_security_handler = { 72struct xattr_handler ext3_xattr_security_handler = {
51 .prefix = XATTR_SECURITY_PREFIX, 73 .prefix = XATTR_SECURITY_PREFIX,
52 .list = ext3_xattr_security_list, 74 .list = ext3_xattr_security_list,
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 96ae85b67eba..a7cbe68e2259 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -335,6 +335,8 @@ EXPORT_SYMBOL(fat_build_inode);
335 335
336static void fat_delete_inode(struct inode *inode) 336static void fat_delete_inode(struct inode *inode)
337{ 337{
338 truncate_inode_pages(&inode->i_data, 0);
339
338 if (!is_bad_inode(inode)) { 340 if (!is_bad_inode(inode)) {
339 inode->i_size = 0; 341 inode->i_size = 0;
340 fat_truncate(inode); 342 fat_truncate(inode);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6fbc9d8fcc36..863b46e0d78a 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -16,6 +16,7 @@
16#include <linux/security.h> 16#include <linux/security.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/signal.h> 18#include <linux/signal.h>
19#include <linux/rcupdate.h>
19 20
20#include <asm/poll.h> 21#include <asm/poll.h>
21#include <asm/siginfo.h> 22#include <asm/siginfo.h>
@@ -24,21 +25,25 @@
24void fastcall set_close_on_exec(unsigned int fd, int flag) 25void fastcall set_close_on_exec(unsigned int fd, int flag)
25{ 26{
26 struct files_struct *files = current->files; 27 struct files_struct *files = current->files;
28 struct fdtable *fdt;
27 spin_lock(&files->file_lock); 29 spin_lock(&files->file_lock);
30 fdt = files_fdtable(files);
28 if (flag) 31 if (flag)
29 FD_SET(fd, files->close_on_exec); 32 FD_SET(fd, fdt->close_on_exec);
30 else 33 else
31 FD_CLR(fd, files->close_on_exec); 34 FD_CLR(fd, fdt->close_on_exec);
32 spin_unlock(&files->file_lock); 35 spin_unlock(&files->file_lock);
33} 36}
34 37
35static inline int get_close_on_exec(unsigned int fd) 38static inline int get_close_on_exec(unsigned int fd)
36{ 39{
37 struct files_struct *files = current->files; 40 struct files_struct *files = current->files;
41 struct fdtable *fdt;
38 int res; 42 int res;
39 spin_lock(&files->file_lock); 43 rcu_read_lock();
40 res = FD_ISSET(fd, files->close_on_exec); 44 fdt = files_fdtable(files);
41 spin_unlock(&files->file_lock); 45 res = FD_ISSET(fd, fdt->close_on_exec);
46 rcu_read_unlock();
42 return res; 47 return res;
43} 48}
44 49
@@ -54,24 +59,26 @@ static int locate_fd(struct files_struct *files,
54 unsigned int newfd; 59 unsigned int newfd;
55 unsigned int start; 60 unsigned int start;
56 int error; 61 int error;
62 struct fdtable *fdt;
57 63
58 error = -EINVAL; 64 error = -EINVAL;
59 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 65 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
60 goto out; 66 goto out;
61 67
62repeat: 68repeat:
69 fdt = files_fdtable(files);
63 /* 70 /*
64 * Someone might have closed fd's in the range 71 * Someone might have closed fd's in the range
65 * orig_start..files->next_fd 72 * orig_start..fdt->next_fd
66 */ 73 */
67 start = orig_start; 74 start = orig_start;
68 if (start < files->next_fd) 75 if (start < fdt->next_fd)
69 start = files->next_fd; 76 start = fdt->next_fd;
70 77
71 newfd = start; 78 newfd = start;
72 if (start < files->max_fdset) { 79 if (start < fdt->max_fdset) {
73 newfd = find_next_zero_bit(files->open_fds->fds_bits, 80 newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
74 files->max_fdset, start); 81 fdt->max_fdset, start);
75 } 82 }
76 83
77 error = -EMFILE; 84 error = -EMFILE;
@@ -89,9 +96,15 @@ repeat:
89 if (error) 96 if (error)
90 goto repeat; 97 goto repeat;
91 98
92 if (start <= files->next_fd) 99 /*
93 files->next_fd = newfd + 1; 100 * We reacquired files_lock, so we are safe as long as
94 101 * we reacquire the fdtable pointer and use it while holding
102 * the lock, no one can free it during that time.
103 */
104 fdt = files_fdtable(files);
105 if (start <= fdt->next_fd)
106 fdt->next_fd = newfd + 1;
107
95 error = newfd; 108 error = newfd;
96 109
97out: 110out:
@@ -101,13 +114,16 @@ out:
101static int dupfd(struct file *file, unsigned int start) 114static int dupfd(struct file *file, unsigned int start)
102{ 115{
103 struct files_struct * files = current->files; 116 struct files_struct * files = current->files;
117 struct fdtable *fdt;
104 int fd; 118 int fd;
105 119
106 spin_lock(&files->file_lock); 120 spin_lock(&files->file_lock);
107 fd = locate_fd(files, file, start); 121 fd = locate_fd(files, file, start);
108 if (fd >= 0) { 122 if (fd >= 0) {
109 FD_SET(fd, files->open_fds); 123 /* locate_fd() may have expanded fdtable, load the ptr */
110 FD_CLR(fd, files->close_on_exec); 124 fdt = files_fdtable(files);
125 FD_SET(fd, fdt->open_fds);
126 FD_CLR(fd, fdt->close_on_exec);
111 spin_unlock(&files->file_lock); 127 spin_unlock(&files->file_lock);
112 fd_install(fd, file); 128 fd_install(fd, file);
113 } else { 129 } else {
@@ -123,6 +139,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
123 int err = -EBADF; 139 int err = -EBADF;
124 struct file * file, *tofree; 140 struct file * file, *tofree;
125 struct files_struct * files = current->files; 141 struct files_struct * files = current->files;
142 struct fdtable *fdt;
126 143
127 spin_lock(&files->file_lock); 144 spin_lock(&files->file_lock);
128 if (!(file = fcheck(oldfd))) 145 if (!(file = fcheck(oldfd)))
@@ -148,13 +165,14 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
148 165
149 /* Yes. It's a race. In user space. Nothing sane to do */ 166 /* Yes. It's a race. In user space. Nothing sane to do */
150 err = -EBUSY; 167 err = -EBUSY;
151 tofree = files->fd[newfd]; 168 fdt = files_fdtable(files);
152 if (!tofree && FD_ISSET(newfd, files->open_fds)) 169 tofree = fdt->fd[newfd];
170 if (!tofree && FD_ISSET(newfd, fdt->open_fds))
153 goto out_fput; 171 goto out_fput;
154 172
155 files->fd[newfd] = file; 173 rcu_assign_pointer(fdt->fd[newfd], file);
156 FD_SET(newfd, files->open_fds); 174 FD_SET(newfd, fdt->open_fds);
157 FD_CLR(newfd, files->close_on_exec); 175 FD_CLR(newfd, fdt->close_on_exec);
158 spin_unlock(&files->file_lock); 176 spin_unlock(&files->file_lock);
159 177
160 if (tofree) 178 if (tofree)
diff --git a/fs/file.c b/fs/file.c
index 92b5f25985d2..2127a7b9dc3a 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -13,6 +13,25 @@
13#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
14#include <linux/file.h> 14#include <linux/file.h>
15#include <linux/bitops.h> 15#include <linux/bitops.h>
16#include <linux/interrupt.h>
17#include <linux/spinlock.h>
18#include <linux/rcupdate.h>
19#include <linux/workqueue.h>
20
21struct fdtable_defer {
22 spinlock_t lock;
23 struct work_struct wq;
24 struct timer_list timer;
25 struct fdtable *next;
26};
27
28/*
29 * We use this list to defer free fdtables that have vmalloced
30 * sets/arrays. By keeping a per-cpu list, we avoid having to embed
31 * the work_struct in fdtable itself which avoids a 64 byte (i386) increase in
32 * this per-task structure.
33 */
34static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);
16 35
17 36
18/* 37/*
@@ -48,82 +67,143 @@ void free_fd_array(struct file **array, int num)
48 vfree(array); 67 vfree(array);
49} 68}
50 69
51/* 70static void __free_fdtable(struct fdtable *fdt)
52 * Expand the fd array in the files_struct. Called with the files 71{
53 * spinlock held for write. 72 int fdset_size, fdarray_size;
54 */
55 73
56static int expand_fd_array(struct files_struct *files, int nr) 74 fdset_size = fdt->max_fdset / 8;
57 __releases(files->file_lock) 75 fdarray_size = fdt->max_fds * sizeof(struct file *);
58 __acquires(files->file_lock) 76 free_fdset(fdt->open_fds, fdset_size);
77 free_fdset(fdt->close_on_exec, fdset_size);
78 free_fd_array(fdt->fd, fdarray_size);
79 kfree(fdt);
80}
81
82static void fdtable_timer(unsigned long data)
59{ 83{
60 struct file **new_fds; 84 struct fdtable_defer *fddef = (struct fdtable_defer *)data;
61 int error, nfds;
62 85
63 86 spin_lock(&fddef->lock);
64 error = -EMFILE; 87 /*
65 if (files->max_fds >= NR_OPEN || nr >= NR_OPEN) 88 * If someone already emptied the queue return.
89 */
90 if (!fddef->next)
66 goto out; 91 goto out;
92 if (!schedule_work(&fddef->wq))
93 mod_timer(&fddef->timer, 5);
94out:
95 spin_unlock(&fddef->lock);
96}
67 97
68 nfds = files->max_fds; 98static void free_fdtable_work(struct fdtable_defer *f)
69 spin_unlock(&files->file_lock); 99{
100 struct fdtable *fdt;
70 101
71 /* 102 spin_lock_bh(&f->lock);
72 * Expand to the max in easy steps, and keep expanding it until 103 fdt = f->next;
73 * we have enough for the requested fd array size. 104 f->next = NULL;
74 */ 105 spin_unlock_bh(&f->lock);
106 while(fdt) {
107 struct fdtable *next = fdt->next;
108 __free_fdtable(fdt);
109 fdt = next;
110 }
111}
75 112
76 do { 113static void free_fdtable_rcu(struct rcu_head *rcu)
77#if NR_OPEN_DEFAULT < 256 114{
78 if (nfds < 256) 115 struct fdtable *fdt = container_of(rcu, struct fdtable, rcu);
79 nfds = 256; 116 int fdset_size, fdarray_size;
80 else 117 struct fdtable_defer *fddef;
81#endif
82 if (nfds < (PAGE_SIZE / sizeof(struct file *)))
83 nfds = PAGE_SIZE / sizeof(struct file *);
84 else {
85 nfds = nfds * 2;
86 if (nfds > NR_OPEN)
87 nfds = NR_OPEN;
88 }
89 } while (nfds <= nr);
90 118
91 error = -ENOMEM; 119 BUG_ON(!fdt);
92 new_fds = alloc_fd_array(nfds); 120 fdset_size = fdt->max_fdset / 8;
93 spin_lock(&files->file_lock); 121 fdarray_size = fdt->max_fds * sizeof(struct file *);
94 if (!new_fds)
95 goto out;
96 122
97 /* Copy the existing array and install the new pointer */ 123 if (fdt->free_files) {
98 124 /*
99 if (nfds > files->max_fds) { 125 * The this fdtable was embedded in the files structure
100 struct file **old_fds; 126 * and the files structure itself was getting destroyed.
101 int i; 127 * It is now safe to free the files structure.
102 128 */
103 old_fds = xchg(&files->fd, new_fds); 129 kmem_cache_free(files_cachep, fdt->free_files);
104 i = xchg(&files->max_fds, nfds); 130 return;
105 131 }
106 /* Don't copy/clear the array if we are creating a new 132 if (fdt->max_fdset <= __FD_SETSIZE && fdt->max_fds <= NR_OPEN_DEFAULT) {
107 fd array for fork() */ 133 /*
108 if (i) { 134 * The fdtable was embedded
109 memcpy(new_fds, old_fds, i * sizeof(struct file *)); 135 */
110 /* clear the remainder of the array */ 136 return;
111 memset(&new_fds[i], 0, 137 }
112 (nfds-i) * sizeof(struct file *)); 138 if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) {
113 139 kfree(fdt->open_fds);
114 spin_unlock(&files->file_lock); 140 kfree(fdt->close_on_exec);
115 free_fd_array(old_fds, i); 141 kfree(fdt->fd);
116 spin_lock(&files->file_lock); 142 kfree(fdt);
117 }
118 } else { 143 } else {
119 /* Somebody expanded the array while we slept ... */ 144 fddef = &get_cpu_var(fdtable_defer_list);
120 spin_unlock(&files->file_lock); 145 spin_lock(&fddef->lock);
121 free_fd_array(new_fds, nfds); 146 fdt->next = fddef->next;
122 spin_lock(&files->file_lock); 147 fddef->next = fdt;
148 /*
149 * vmallocs are handled from the workqueue context.
150 * If the per-cpu workqueue is running, then we
151 * defer work scheduling through a timer.
152 */
153 if (!schedule_work(&fddef->wq))
154 mod_timer(&fddef->timer, 5);
155 spin_unlock(&fddef->lock);
156 put_cpu_var(fdtable_defer_list);
123 } 157 }
124 error = 0; 158}
125out: 159
126 return error; 160void free_fdtable(struct fdtable *fdt)
161{
162 if (fdt->free_files || fdt->max_fdset > __FD_SETSIZE ||
163 fdt->max_fds > NR_OPEN_DEFAULT)
164 call_rcu(&fdt->rcu, free_fdtable_rcu);
165}
166
167/*
168 * Expand the fdset in the files_struct. Called with the files spinlock
169 * held for write.
170 */
171static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt)
172{
173 int i;
174 int count;
175
176 BUG_ON(nfdt->max_fdset < fdt->max_fdset);
177 BUG_ON(nfdt->max_fds < fdt->max_fds);
178 /* Copy the existing tables and install the new pointers */
179
180 i = fdt->max_fdset / (sizeof(unsigned long) * 8);
181 count = (nfdt->max_fdset - fdt->max_fdset) / 8;
182
183 /*
184 * Don't copy the entire array if the current fdset is
185 * not yet initialised.
186 */
187 if (i) {
188 memcpy (nfdt->open_fds, fdt->open_fds,
189 fdt->max_fdset/8);
190 memcpy (nfdt->close_on_exec, fdt->close_on_exec,
191 fdt->max_fdset/8);
192 memset (&nfdt->open_fds->fds_bits[i], 0, count);
193 memset (&nfdt->close_on_exec->fds_bits[i], 0, count);
194 }
195
196 /* Don't copy/clear the array if we are creating a new
197 fd array for fork() */
198 if (fdt->max_fds) {
199 memcpy(nfdt->fd, fdt->fd,
200 fdt->max_fds * sizeof(struct file *));
201 /* clear the remainder of the array */
202 memset(&nfdt->fd[fdt->max_fds], 0,
203 (nfdt->max_fds - fdt->max_fds) *
204 sizeof(struct file *));
205 }
206 nfdt->next_fd = fdt->next_fd;
127} 207}
128 208
129/* 209/*
@@ -154,26 +234,21 @@ void free_fdset(fd_set *array, int num)
154 vfree(array); 234 vfree(array);
155} 235}
156 236
157/* 237static struct fdtable *alloc_fdtable(int nr)
158 * Expand the fdset in the files_struct. Called with the files spinlock
159 * held for write.
160 */
161static int expand_fdset(struct files_struct *files, int nr)
162 __releases(file->file_lock)
163 __acquires(file->file_lock)
164{ 238{
165 fd_set *new_openset = NULL, *new_execset = NULL; 239 struct fdtable *fdt = NULL;
166 int error, nfds = 0; 240 int nfds = 0;
167 241 fd_set *new_openset = NULL, *new_execset = NULL;
168 error = -EMFILE; 242 struct file **new_fds;
169 if (files->max_fdset >= NR_OPEN || nr >= NR_OPEN)
170 goto out;
171 243
172 nfds = files->max_fdset; 244 fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
173 spin_unlock(&files->file_lock); 245 if (!fdt)
246 goto out;
247 memset(fdt, 0, sizeof(*fdt));
174 248
175 /* Expand to the max in easy steps */ 249 nfds = __FD_SETSIZE;
176 do { 250 /* Expand to the max in easy steps */
251 do {
177 if (nfds < (PAGE_SIZE * 8)) 252 if (nfds < (PAGE_SIZE * 8))
178 nfds = PAGE_SIZE * 8; 253 nfds = PAGE_SIZE * 8;
179 else { 254 else {
@@ -183,49 +258,88 @@ static int expand_fdset(struct files_struct *files, int nr)
183 } 258 }
184 } while (nfds <= nr); 259 } while (nfds <= nr);
185 260
186 error = -ENOMEM; 261 new_openset = alloc_fdset(nfds);
187 new_openset = alloc_fdset(nfds); 262 new_execset = alloc_fdset(nfds);
188 new_execset = alloc_fdset(nfds); 263 if (!new_openset || !new_execset)
189 spin_lock(&files->file_lock); 264 goto out;
190 if (!new_openset || !new_execset) 265 fdt->open_fds = new_openset;
266 fdt->close_on_exec = new_execset;
267 fdt->max_fdset = nfds;
268
269 nfds = NR_OPEN_DEFAULT;
270 /*
271 * Expand to the max in easy steps, and keep expanding it until
272 * we have enough for the requested fd array size.
273 */
274 do {
275#if NR_OPEN_DEFAULT < 256
276 if (nfds < 256)
277 nfds = 256;
278 else
279#endif
280 if (nfds < (PAGE_SIZE / sizeof(struct file *)))
281 nfds = PAGE_SIZE / sizeof(struct file *);
282 else {
283 nfds = nfds * 2;
284 if (nfds > NR_OPEN)
285 nfds = NR_OPEN;
286 }
287 } while (nfds <= nr);
288 new_fds = alloc_fd_array(nfds);
289 if (!new_fds)
290 goto out;
291 fdt->fd = new_fds;
292 fdt->max_fds = nfds;
293 fdt->free_files = NULL;
294 return fdt;
295out:
296 if (new_openset)
297 free_fdset(new_openset, nfds);
298 if (new_execset)
299 free_fdset(new_execset, nfds);
300 kfree(fdt);
301 return NULL;
302}
303
304/*
305 * Expands the file descriptor table - it will allocate a new fdtable and
306 * both fd array and fdset. It is expected to be called with the
307 * files_lock held.
308 */
309static int expand_fdtable(struct files_struct *files, int nr)
310 __releases(files->file_lock)
311 __acquires(files->file_lock)
312{
313 int error = 0;
314 struct fdtable *fdt;
315 struct fdtable *nfdt = NULL;
316
317 spin_unlock(&files->file_lock);
318 nfdt = alloc_fdtable(nr);
319 if (!nfdt) {
320 error = -ENOMEM;
321 spin_lock(&files->file_lock);
191 goto out; 322 goto out;
323 }
192 324
193 error = 0; 325 spin_lock(&files->file_lock);
194 326 fdt = files_fdtable(files);
195 /* Copy the existing tables and install the new pointers */ 327 /*
196 if (nfds > files->max_fdset) { 328 * Check again since another task may have expanded the
197 int i = files->max_fdset / (sizeof(unsigned long) * 8); 329 * fd table while we dropped the lock
198 int count = (nfds - files->max_fdset) / 8; 330 */
199 331 if (nr >= fdt->max_fds || nr >= fdt->max_fdset) {
200 /* 332 copy_fdtable(nfdt, fdt);
201 * Don't copy the entire array if the current fdset is 333 } else {
202 * not yet initialised. 334 /* Somebody expanded while we dropped file_lock */
203 */
204 if (i) {
205 memcpy (new_openset, files->open_fds, files->max_fdset/8);
206 memcpy (new_execset, files->close_on_exec, files->max_fdset/8);
207 memset (&new_openset->fds_bits[i], 0, count);
208 memset (&new_execset->fds_bits[i], 0, count);
209 }
210
211 nfds = xchg(&files->max_fdset, nfds);
212 new_openset = xchg(&files->open_fds, new_openset);
213 new_execset = xchg(&files->close_on_exec, new_execset);
214 spin_unlock(&files->file_lock); 335 spin_unlock(&files->file_lock);
215 free_fdset (new_openset, nfds); 336 __free_fdtable(nfdt);
216 free_fdset (new_execset, nfds);
217 spin_lock(&files->file_lock); 337 spin_lock(&files->file_lock);
218 return 0; 338 goto out;
219 } 339 }
220 /* Somebody expanded the array while we slept ... */ 340 rcu_assign_pointer(files->fdt, nfdt);
221 341 free_fdtable(fdt);
222out: 342out:
223 spin_unlock(&files->file_lock);
224 if (new_openset)
225 free_fdset(new_openset, nfds);
226 if (new_execset)
227 free_fdset(new_execset, nfds);
228 spin_lock(&files->file_lock);
229 return error; 343 return error;
230} 344}
231 345
@@ -237,18 +351,39 @@ out:
237int expand_files(struct files_struct *files, int nr) 351int expand_files(struct files_struct *files, int nr)
238{ 352{
239 int err, expand = 0; 353 int err, expand = 0;
354 struct fdtable *fdt;
240 355
241 if (nr >= files->max_fdset) { 356 fdt = files_fdtable(files);
242 expand = 1; 357 if (nr >= fdt->max_fdset || nr >= fdt->max_fds) {
243 if ((err = expand_fdset(files, nr))) 358 if (fdt->max_fdset >= NR_OPEN ||
359 fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) {
360 err = -EMFILE;
244 goto out; 361 goto out;
245 } 362 }
246 if (nr >= files->max_fds) {
247 expand = 1; 363 expand = 1;
248 if ((err = expand_fd_array(files, nr))) 364 if ((err = expand_fdtable(files, nr)))
249 goto out; 365 goto out;
250 } 366 }
251 err = expand; 367 err = expand;
252out: 368out:
253 return err; 369 return err;
254} 370}
371
372static void __devinit fdtable_defer_list_init(int cpu)
373{
374 struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu);
375 spin_lock_init(&fddef->lock);
376 INIT_WORK(&fddef->wq, (void (*)(void *))free_fdtable_work, fddef);
377 init_timer(&fddef->timer);
378 fddef->timer.data = (unsigned long)fddef;
379 fddef->timer.function = fdtable_timer;
380 fddef->next = NULL;
381}
382
383void __init files_defer_init(void)
384{
385 int i;
386 /* Really early - can't use for_each_cpu */
387 for (i = 0; i < NR_CPUS; i++)
388 fdtable_defer_list_init(i);
389}
diff --git a/fs/file_table.c b/fs/file_table.c
index 43e9e1737de2..86ec8ae985b4 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -14,6 +14,7 @@
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/eventpoll.h> 16#include <linux/eventpoll.h>
17#include <linux/rcupdate.h>
17#include <linux/mount.h> 18#include <linux/mount.h>
18#include <linux/cdev.h> 19#include <linux/cdev.h>
19#include <linux/fsnotify.h> 20#include <linux/fsnotify.h>
@@ -53,11 +54,17 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
53 spin_unlock_irqrestore(&filp_count_lock, flags); 54 spin_unlock_irqrestore(&filp_count_lock, flags);
54} 55}
55 56
56static inline void file_free(struct file *f) 57static inline void file_free_rcu(struct rcu_head *head)
57{ 58{
59 struct file *f = container_of(head, struct file, f_rcuhead);
58 kmem_cache_free(filp_cachep, f); 60 kmem_cache_free(filp_cachep, f);
59} 61}
60 62
63static inline void file_free(struct file *f)
64{
65 call_rcu(&f->f_rcuhead, file_free_rcu);
66}
67
61/* Find an unused file structure and return a pointer to it. 68/* Find an unused file structure and return a pointer to it.
62 * Returns NULL, if there are no more free file structures or 69 * Returns NULL, if there are no more free file structures or
63 * we run out of memory. 70 * we run out of memory.
@@ -110,7 +117,7 @@ EXPORT_SYMBOL(get_empty_filp);
110 117
111void fastcall fput(struct file *file) 118void fastcall fput(struct file *file)
112{ 119{
113 if (atomic_dec_and_test(&file->f_count)) 120 if (rcuref_dec_and_test(&file->f_count))
114 __fput(file); 121 __fput(file);
115} 122}
116 123
@@ -156,11 +163,17 @@ struct file fastcall *fget(unsigned int fd)
156 struct file *file; 163 struct file *file;
157 struct files_struct *files = current->files; 164 struct files_struct *files = current->files;
158 165
159 spin_lock(&files->file_lock); 166 rcu_read_lock();
160 file = fcheck_files(files, fd); 167 file = fcheck_files(files, fd);
161 if (file) 168 if (file) {
162 get_file(file); 169 if (!rcuref_inc_lf(&file->f_count)) {
163 spin_unlock(&files->file_lock); 170 /* File object ref couldn't be taken */
171 rcu_read_unlock();
172 return NULL;
173 }
174 }
175 rcu_read_unlock();
176
164 return file; 177 return file;
165} 178}
166 179
@@ -182,21 +195,25 @@ struct file fastcall *fget_light(unsigned int fd, int *fput_needed)
182 if (likely((atomic_read(&files->count) == 1))) { 195 if (likely((atomic_read(&files->count) == 1))) {
183 file = fcheck_files(files, fd); 196 file = fcheck_files(files, fd);
184 } else { 197 } else {
185 spin_lock(&files->file_lock); 198 rcu_read_lock();
186 file = fcheck_files(files, fd); 199 file = fcheck_files(files, fd);
187 if (file) { 200 if (file) {
188 get_file(file); 201 if (rcuref_inc_lf(&file->f_count))
189 *fput_needed = 1; 202 *fput_needed = 1;
203 else
204 /* Didn't get the reference, someone's freed */
205 file = NULL;
190 } 206 }
191 spin_unlock(&files->file_lock); 207 rcu_read_unlock();
192 } 208 }
209
193 return file; 210 return file;
194} 211}
195 212
196 213
197void put_filp(struct file *file) 214void put_filp(struct file *file)
198{ 215{
199 if (atomic_dec_and_test(&file->f_count)) { 216 if (rcuref_dec_and_test(&file->f_count)) {
200 security_file_free(file); 217 security_file_free(file);
201 file_kill(file); 218 file_kill(file);
202 file_free(file); 219 file_free(file);
@@ -257,4 +274,5 @@ void __init files_init(unsigned long mempages)
257 files_stat.max_files = n; 274 files_stat.max_files = n;
258 if (files_stat.max_files < NR_FILE) 275 if (files_stat.max_files < NR_FILE)
259 files_stat.max_files = NR_FILE; 276 files_stat.max_files = NR_FILE;
277 files_defer_init();
260} 278}
diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
new file mode 100644
index 000000000000..c3e1f760cac9
--- /dev/null
+++ b/fs/fuse/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the FUSE filesystem.
3#
4
5obj-$(CONFIG_FUSE_FS) += fuse.o
6
7fuse-objs := dev.o dir.o file.o inode.o
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
new file mode 100644
index 000000000000..d4c869c6d01b
--- /dev/null
+++ b/fs/fuse/dev.c
@@ -0,0 +1,877 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/poll.h>
14#include <linux/uio.h>
15#include <linux/miscdevice.h>
16#include <linux/pagemap.h>
17#include <linux/file.h>
18#include <linux/slab.h>
19
20MODULE_ALIAS_MISCDEV(FUSE_MINOR);
21
22static kmem_cache_t *fuse_req_cachep;
23
24static inline struct fuse_conn *fuse_get_conn(struct file *file)
25{
26 struct fuse_conn *fc;
27 spin_lock(&fuse_lock);
28 fc = file->private_data;
29 if (fc && !fc->mounted)
30 fc = NULL;
31 spin_unlock(&fuse_lock);
32 return fc;
33}
34
35static inline void fuse_request_init(struct fuse_req *req)
36{
37 memset(req, 0, sizeof(*req));
38 INIT_LIST_HEAD(&req->list);
39 init_waitqueue_head(&req->waitq);
40 atomic_set(&req->count, 1);
41}
42
43struct fuse_req *fuse_request_alloc(void)
44{
45 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL);
46 if (req)
47 fuse_request_init(req);
48 return req;
49}
50
51void fuse_request_free(struct fuse_req *req)
52{
53 kmem_cache_free(fuse_req_cachep, req);
54}
55
56static inline void block_sigs(sigset_t *oldset)
57{
58 sigset_t mask;
59
60 siginitsetinv(&mask, sigmask(SIGKILL));
61 sigprocmask(SIG_BLOCK, &mask, oldset);
62}
63
64static inline void restore_sigs(sigset_t *oldset)
65{
66 sigprocmask(SIG_SETMASK, oldset, NULL);
67}
68
69void fuse_reset_request(struct fuse_req *req)
70{
71 int preallocated = req->preallocated;
72 BUG_ON(atomic_read(&req->count) != 1);
73 fuse_request_init(req);
74 req->preallocated = preallocated;
75}
76
77static void __fuse_get_request(struct fuse_req *req)
78{
79 atomic_inc(&req->count);
80}
81
82/* Must be called with > 1 refcount */
83static void __fuse_put_request(struct fuse_req *req)
84{
85 BUG_ON(atomic_read(&req->count) < 2);
86 atomic_dec(&req->count);
87}
88
89static struct fuse_req *do_get_request(struct fuse_conn *fc)
90{
91 struct fuse_req *req;
92
93 spin_lock(&fuse_lock);
94 BUG_ON(list_empty(&fc->unused_list));
95 req = list_entry(fc->unused_list.next, struct fuse_req, list);
96 list_del_init(&req->list);
97 spin_unlock(&fuse_lock);
98 fuse_request_init(req);
99 req->preallocated = 1;
100 req->in.h.uid = current->fsuid;
101 req->in.h.gid = current->fsgid;
102 req->in.h.pid = current->pid;
103 return req;
104}
105
106/* This can return NULL, but only in case it's interrupted by a SIGKILL */
107struct fuse_req *fuse_get_request(struct fuse_conn *fc)
108{
109 int intr;
110 sigset_t oldset;
111
112 block_sigs(&oldset);
113 intr = down_interruptible(&fc->outstanding_sem);
114 restore_sigs(&oldset);
115 return intr ? NULL : do_get_request(fc);
116}
117
118static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
119{
120 spin_lock(&fuse_lock);
121 if (req->preallocated)
122 list_add(&req->list, &fc->unused_list);
123 else
124 fuse_request_free(req);
125
126 /* If we are in debt decrease that first */
127 if (fc->outstanding_debt)
128 fc->outstanding_debt--;
129 else
130 up(&fc->outstanding_sem);
131 spin_unlock(&fuse_lock);
132}
133
134void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
135{
136 if (atomic_dec_and_test(&req->count))
137 fuse_putback_request(fc, req);
138}
139
140void fuse_release_background(struct fuse_req *req)
141{
142 iput(req->inode);
143 iput(req->inode2);
144 if (req->file)
145 fput(req->file);
146 spin_lock(&fuse_lock);
147 list_del(&req->bg_entry);
148 spin_unlock(&fuse_lock);
149}
150
151/*
152 * This function is called when a request is finished. Either a reply
153 * has arrived or it was interrupted (and not yet sent) or some error
154 * occured during communication with userspace, or the device file was
155 * closed. It decreases the referece count for the request. In case
156 * of a background request the referece to the stored objects are
157 * released. The requester thread is woken up (if still waiting), and
158 * finally the request is either freed or put on the unused_list
159 *
160 * Called with fuse_lock, unlocks it
161 */
162static void request_end(struct fuse_conn *fc, struct fuse_req *req)
163{
164 int putback;
165 req->finished = 1;
166 putback = atomic_dec_and_test(&req->count);
167 spin_unlock(&fuse_lock);
168 if (req->background) {
169 down_read(&fc->sbput_sem);
170 if (fc->mounted)
171 fuse_release_background(req);
172 up_read(&fc->sbput_sem);
173 }
174 wake_up(&req->waitq);
175 if (req->in.h.opcode == FUSE_INIT) {
176 int i;
177
178 if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
179 fc->conn_error = 1;
180
181 /* After INIT reply is received other requests can go
182 out. So do (FUSE_MAX_OUTSTANDING - 1) number of
183 up()s on outstanding_sem. The last up() is done in
184 fuse_putback_request() */
185 for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
186 up(&fc->outstanding_sem);
187 }
188 if (putback)
189 fuse_putback_request(fc, req);
190}
191
192/*
193 * Unfortunately request interruption not just solves the deadlock
194 * problem, it causes problems too. These stem from the fact, that an
195 * interrupted request is continued to be processed in userspace,
196 * while all the locks and object references (inode and file) held
197 * during the operation are released.
198 *
199 * To release the locks is exactly why there's a need to interrupt the
200 * request, so there's not a lot that can be done about this, except
201 * introduce additional locking in userspace.
202 *
203 * More important is to keep inode and file references until userspace
204 * has replied, otherwise FORGET and RELEASE could be sent while the
205 * inode/file is still used by the filesystem.
206 *
207 * For this reason the concept of "background" request is introduced.
208 * An interrupted request is backgrounded if it has been already sent
209 * to userspace. Backgrounding involves getting an extra reference to
210 * inode(s) or file used in the request, and adding the request to
211 * fc->background list. When a reply is received for a background
212 * request, the object references are released, and the request is
213 * removed from the list. If the filesystem is unmounted while there
214 * are still background requests, the list is walked and references
215 * are released as if a reply was received.
216 *
217 * There's one more use for a background request. The RELEASE message is
218 * always sent as background, since it doesn't return an error or
219 * data.
220 */
221static void background_request(struct fuse_conn *fc, struct fuse_req *req)
222{
223 req->background = 1;
224 list_add(&req->bg_entry, &fc->background);
225 if (req->inode)
226 req->inode = igrab(req->inode);
227 if (req->inode2)
228 req->inode2 = igrab(req->inode2);
229 if (req->file)
230 get_file(req->file);
231}
232
233/* Called with fuse_lock held. Releases, and then reacquires it. */
234static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
235{
236 sigset_t oldset;
237
238 spin_unlock(&fuse_lock);
239 block_sigs(&oldset);
240 wait_event_interruptible(req->waitq, req->finished);
241 restore_sigs(&oldset);
242 spin_lock(&fuse_lock);
243 if (req->finished)
244 return;
245
246 req->out.h.error = -EINTR;
247 req->interrupted = 1;
248 if (req->locked) {
249 /* This is uninterruptible sleep, because data is
250 being copied to/from the buffers of req. During
251 locked state, there mustn't be any filesystem
252 operation (e.g. page fault), since that could lead
253 to deadlock */
254 spin_unlock(&fuse_lock);
255 wait_event(req->waitq, !req->locked);
256 spin_lock(&fuse_lock);
257 }
258 if (!req->sent && !list_empty(&req->list)) {
259 list_del(&req->list);
260 __fuse_put_request(req);
261 } else if (!req->finished && req->sent)
262 background_request(fc, req);
263}
264
265static unsigned len_args(unsigned numargs, struct fuse_arg *args)
266{
267 unsigned nbytes = 0;
268 unsigned i;
269
270 for (i = 0; i < numargs; i++)
271 nbytes += args[i].size;
272
273 return nbytes;
274}
275
276static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
277{
278 fc->reqctr++;
279 /* zero is special */
280 if (fc->reqctr == 0)
281 fc->reqctr = 1;
282 req->in.h.unique = fc->reqctr;
283 req->in.h.len = sizeof(struct fuse_in_header) +
284 len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
285 if (!req->preallocated) {
286 /* If request is not preallocated (either FORGET or
287 RELEASE), then still decrease outstanding_sem, so
288 user can't open infinite number of files while not
289 processing the RELEASE requests. However for
290 efficiency do it without blocking, so if down()
291 would block, just increase the debt instead */
292 if (down_trylock(&fc->outstanding_sem))
293 fc->outstanding_debt++;
294 }
295 list_add_tail(&req->list, &fc->pending);
296 wake_up(&fc->waitq);
297}
298
299/*
300 * This can only be interrupted by a SIGKILL
301 */
302void request_send(struct fuse_conn *fc, struct fuse_req *req)
303{
304 req->isreply = 1;
305 spin_lock(&fuse_lock);
306 if (!fc->connected)
307 req->out.h.error = -ENOTCONN;
308 else if (fc->conn_error)
309 req->out.h.error = -ECONNREFUSED;
310 else {
311 queue_request(fc, req);
312 /* acquire extra reference, since request is still needed
313 after request_end() */
314 __fuse_get_request(req);
315
316 request_wait_answer(fc, req);
317 }
318 spin_unlock(&fuse_lock);
319}
320
321static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
322{
323 spin_lock(&fuse_lock);
324 if (fc->connected) {
325 queue_request(fc, req);
326 spin_unlock(&fuse_lock);
327 } else {
328 req->out.h.error = -ENOTCONN;
329 request_end(fc, req);
330 }
331}
332
333void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
334{
335 req->isreply = 0;
336 request_send_nowait(fc, req);
337}
338
339void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
340{
341 req->isreply = 1;
342 spin_lock(&fuse_lock);
343 background_request(fc, req);
344 spin_unlock(&fuse_lock);
345 request_send_nowait(fc, req);
346}
347
348void fuse_send_init(struct fuse_conn *fc)
349{
350 /* This is called from fuse_read_super() so there's guaranteed
351 to be a request available */
352 struct fuse_req *req = do_get_request(fc);
353 struct fuse_init_in_out *arg = &req->misc.init_in_out;
354 arg->major = FUSE_KERNEL_VERSION;
355 arg->minor = FUSE_KERNEL_MINOR_VERSION;
356 req->in.h.opcode = FUSE_INIT;
357 req->in.numargs = 1;
358 req->in.args[0].size = sizeof(*arg);
359 req->in.args[0].value = arg;
360 req->out.numargs = 1;
361 req->out.args[0].size = sizeof(*arg);
362 req->out.args[0].value = arg;
363 request_send_background(fc, req);
364}
365
366/*
367 * Lock the request. Up to the next unlock_request() there mustn't be
368 * anything that could cause a page-fault. If the request was already
369 * interrupted bail out.
370 */
371static inline int lock_request(struct fuse_req *req)
372{
373 int err = 0;
374 if (req) {
375 spin_lock(&fuse_lock);
376 if (req->interrupted)
377 err = -ENOENT;
378 else
379 req->locked = 1;
380 spin_unlock(&fuse_lock);
381 }
382 return err;
383}
384
385/*
386 * Unlock request. If it was interrupted during being locked, the
387 * requester thread is currently waiting for it to be unlocked, so
388 * wake it up.
389 */
390static inline void unlock_request(struct fuse_req *req)
391{
392 if (req) {
393 spin_lock(&fuse_lock);
394 req->locked = 0;
395 if (req->interrupted)
396 wake_up(&req->waitq);
397 spin_unlock(&fuse_lock);
398 }
399}
400
401struct fuse_copy_state {
402 int write;
403 struct fuse_req *req;
404 const struct iovec *iov;
405 unsigned long nr_segs;
406 unsigned long seglen;
407 unsigned long addr;
408 struct page *pg;
409 void *mapaddr;
410 void *buf;
411 unsigned len;
412};
413
414static void fuse_copy_init(struct fuse_copy_state *cs, int write,
415 struct fuse_req *req, const struct iovec *iov,
416 unsigned long nr_segs)
417{
418 memset(cs, 0, sizeof(*cs));
419 cs->write = write;
420 cs->req = req;
421 cs->iov = iov;
422 cs->nr_segs = nr_segs;
423}
424
425/* Unmap and put previous page of userspace buffer */
426static inline void fuse_copy_finish(struct fuse_copy_state *cs)
427{
428 if (cs->mapaddr) {
429 kunmap_atomic(cs->mapaddr, KM_USER0);
430 if (cs->write) {
431 flush_dcache_page(cs->pg);
432 set_page_dirty_lock(cs->pg);
433 }
434 put_page(cs->pg);
435 cs->mapaddr = NULL;
436 }
437}
438
439/*
440 * Get another pagefull of userspace buffer, and map it to kernel
441 * address space, and lock request
442 */
443static int fuse_copy_fill(struct fuse_copy_state *cs)
444{
445 unsigned long offset;
446 int err;
447
448 unlock_request(cs->req);
449 fuse_copy_finish(cs);
450 if (!cs->seglen) {
451 BUG_ON(!cs->nr_segs);
452 cs->seglen = cs->iov[0].iov_len;
453 cs->addr = (unsigned long) cs->iov[0].iov_base;
454 cs->iov ++;
455 cs->nr_segs --;
456 }
457 down_read(&current->mm->mmap_sem);
458 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
459 &cs->pg, NULL);
460 up_read(&current->mm->mmap_sem);
461 if (err < 0)
462 return err;
463 BUG_ON(err != 1);
464 offset = cs->addr % PAGE_SIZE;
465 cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
466 cs->buf = cs->mapaddr + offset;
467 cs->len = min(PAGE_SIZE - offset, cs->seglen);
468 cs->seglen -= cs->len;
469 cs->addr += cs->len;
470
471 return lock_request(cs->req);
472}
473
474/* Do as much copy to/from userspace buffer as we can */
475static inline int fuse_copy_do(struct fuse_copy_state *cs, void **val,
476 unsigned *size)
477{
478 unsigned ncpy = min(*size, cs->len);
479 if (val) {
480 if (cs->write)
481 memcpy(cs->buf, *val, ncpy);
482 else
483 memcpy(*val, cs->buf, ncpy);
484 *val += ncpy;
485 }
486 *size -= ncpy;
487 cs->len -= ncpy;
488 cs->buf += ncpy;
489 return ncpy;
490}
491
492/*
493 * Copy a page in the request to/from the userspace buffer. Must be
494 * done atomically
495 */
496static inline int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
497 unsigned offset, unsigned count, int zeroing)
498{
499 if (page && zeroing && count < PAGE_SIZE) {
500 void *mapaddr = kmap_atomic(page, KM_USER1);
501 memset(mapaddr, 0, PAGE_SIZE);
502 kunmap_atomic(mapaddr, KM_USER1);
503 }
504 while (count) {
505 int err;
506 if (!cs->len && (err = fuse_copy_fill(cs)))
507 return err;
508 if (page) {
509 void *mapaddr = kmap_atomic(page, KM_USER1);
510 void *buf = mapaddr + offset;
511 offset += fuse_copy_do(cs, &buf, &count);
512 kunmap_atomic(mapaddr, KM_USER1);
513 } else
514 offset += fuse_copy_do(cs, NULL, &count);
515 }
516 if (page && !cs->write)
517 flush_dcache_page(page);
518 return 0;
519}
520
521/* Copy pages in the request to/from userspace buffer */
522static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
523 int zeroing)
524{
525 unsigned i;
526 struct fuse_req *req = cs->req;
527 unsigned offset = req->page_offset;
528 unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
529
530 for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
531 struct page *page = req->pages[i];
532 int err = fuse_copy_page(cs, page, offset, count, zeroing);
533 if (err)
534 return err;
535
536 nbytes -= count;
537 count = min(nbytes, (unsigned) PAGE_SIZE);
538 offset = 0;
539 }
540 return 0;
541}
542
543/* Copy a single argument in the request to/from userspace buffer */
544static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
545{
546 while (size) {
547 int err;
548 if (!cs->len && (err = fuse_copy_fill(cs)))
549 return err;
550 fuse_copy_do(cs, &val, &size);
551 }
552 return 0;
553}
554
555/* Copy request arguments to/from userspace buffer */
556static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
557 unsigned argpages, struct fuse_arg *args,
558 int zeroing)
559{
560 int err = 0;
561 unsigned i;
562
563 for (i = 0; !err && i < numargs; i++) {
564 struct fuse_arg *arg = &args[i];
565 if (i == numargs - 1 && argpages)
566 err = fuse_copy_pages(cs, arg->size, zeroing);
567 else
568 err = fuse_copy_one(cs, arg->value, arg->size);
569 }
570 return err;
571}
572
573/* Wait until a request is available on the pending list */
574static void request_wait(struct fuse_conn *fc)
575{
576 DECLARE_WAITQUEUE(wait, current);
577
578 add_wait_queue_exclusive(&fc->waitq, &wait);
579 while (fc->mounted && list_empty(&fc->pending)) {
580 set_current_state(TASK_INTERRUPTIBLE);
581 if (signal_pending(current))
582 break;
583
584 spin_unlock(&fuse_lock);
585 schedule();
586 spin_lock(&fuse_lock);
587 }
588 set_current_state(TASK_RUNNING);
589 remove_wait_queue(&fc->waitq, &wait);
590}
591
592/*
593 * Read a single request into the userspace filesystem's buffer. This
594 * function waits until a request is available, then removes it from
595 * the pending list and copies request data to userspace buffer. If
596 * no reply is needed (FORGET) or request has been interrupted or
597 * there was an error during the copying then it's finished by calling
598 * request_end(). Otherwise add it to the processing list, and set
599 * the 'sent' flag.
600 */
601static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
602 unsigned long nr_segs, loff_t *off)
603{
604 int err;
605 struct fuse_conn *fc;
606 struct fuse_req *req;
607 struct fuse_in *in;
608 struct fuse_copy_state cs;
609 unsigned reqsize;
610
611 spin_lock(&fuse_lock);
612 fc = file->private_data;
613 err = -EPERM;
614 if (!fc)
615 goto err_unlock;
616 request_wait(fc);
617 err = -ENODEV;
618 if (!fc->mounted)
619 goto err_unlock;
620 err = -ERESTARTSYS;
621 if (list_empty(&fc->pending))
622 goto err_unlock;
623
624 req = list_entry(fc->pending.next, struct fuse_req, list);
625 list_del_init(&req->list);
626 spin_unlock(&fuse_lock);
627
628 in = &req->in;
629 reqsize = req->in.h.len;
630 fuse_copy_init(&cs, 1, req, iov, nr_segs);
631 err = -EINVAL;
632 if (iov_length(iov, nr_segs) >= reqsize) {
633 err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
634 if (!err)
635 err = fuse_copy_args(&cs, in->numargs, in->argpages,
636 (struct fuse_arg *) in->args, 0);
637 }
638 fuse_copy_finish(&cs);
639
640 spin_lock(&fuse_lock);
641 req->locked = 0;
642 if (!err && req->interrupted)
643 err = -ENOENT;
644 if (err) {
645 if (!req->interrupted)
646 req->out.h.error = -EIO;
647 request_end(fc, req);
648 return err;
649 }
650 if (!req->isreply)
651 request_end(fc, req);
652 else {
653 req->sent = 1;
654 list_add_tail(&req->list, &fc->processing);
655 spin_unlock(&fuse_lock);
656 }
657 return reqsize;
658
659 err_unlock:
660 spin_unlock(&fuse_lock);
661 return err;
662}
663
664static ssize_t fuse_dev_read(struct file *file, char __user *buf,
665 size_t nbytes, loff_t *off)
666{
667 struct iovec iov;
668 iov.iov_len = nbytes;
669 iov.iov_base = buf;
670 return fuse_dev_readv(file, &iov, 1, off);
671}
672
673/* Look up request on processing list by unique ID */
674static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
675{
676 struct list_head *entry;
677
678 list_for_each(entry, &fc->processing) {
679 struct fuse_req *req;
680 req = list_entry(entry, struct fuse_req, list);
681 if (req->in.h.unique == unique)
682 return req;
683 }
684 return NULL;
685}
686
687static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
688 unsigned nbytes)
689{
690 unsigned reqsize = sizeof(struct fuse_out_header);
691
692 if (out->h.error)
693 return nbytes != reqsize ? -EINVAL : 0;
694
695 reqsize += len_args(out->numargs, out->args);
696
697 if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
698 return -EINVAL;
699 else if (reqsize > nbytes) {
700 struct fuse_arg *lastarg = &out->args[out->numargs-1];
701 unsigned diffsize = reqsize - nbytes;
702 if (diffsize > lastarg->size)
703 return -EINVAL;
704 lastarg->size -= diffsize;
705 }
706 return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
707 out->page_zeroing);
708}
709
710/*
711 * Write a single reply to a request. First the header is copied from
712 * the write buffer. The request is then searched on the processing
713 * list by the unique ID found in the header. If found, then remove
714 * it from the list and copy the rest of the buffer to the request.
715 * The request is finished by calling request_end()
716 */
717static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
718 unsigned long nr_segs, loff_t *off)
719{
720 int err;
721 unsigned nbytes = iov_length(iov, nr_segs);
722 struct fuse_req *req;
723 struct fuse_out_header oh;
724 struct fuse_copy_state cs;
725 struct fuse_conn *fc = fuse_get_conn(file);
726 if (!fc)
727 return -ENODEV;
728
729 fuse_copy_init(&cs, 0, NULL, iov, nr_segs);
730 if (nbytes < sizeof(struct fuse_out_header))
731 return -EINVAL;
732
733 err = fuse_copy_one(&cs, &oh, sizeof(oh));
734 if (err)
735 goto err_finish;
736 err = -EINVAL;
737 if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
738 oh.len != nbytes)
739 goto err_finish;
740
741 spin_lock(&fuse_lock);
742 req = request_find(fc, oh.unique);
743 err = -EINVAL;
744 if (!req)
745 goto err_unlock;
746
747 list_del_init(&req->list);
748 if (req->interrupted) {
749 request_end(fc, req);
750 fuse_copy_finish(&cs);
751 return -ENOENT;
752 }
753 req->out.h = oh;
754 req->locked = 1;
755 cs.req = req;
756 spin_unlock(&fuse_lock);
757
758 err = copy_out_args(&cs, &req->out, nbytes);
759 fuse_copy_finish(&cs);
760
761 spin_lock(&fuse_lock);
762 req->locked = 0;
763 if (!err) {
764 if (req->interrupted)
765 err = -ENOENT;
766 } else if (!req->interrupted)
767 req->out.h.error = -EIO;
768 request_end(fc, req);
769
770 return err ? err : nbytes;
771
772 err_unlock:
773 spin_unlock(&fuse_lock);
774 err_finish:
775 fuse_copy_finish(&cs);
776 return err;
777}
778
779static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
780 size_t nbytes, loff_t *off)
781{
782 struct iovec iov;
783 iov.iov_len = nbytes;
784 iov.iov_base = (char __user *) buf;
785 return fuse_dev_writev(file, &iov, 1, off);
786}
787
788static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
789{
790 struct fuse_conn *fc = fuse_get_conn(file);
791 unsigned mask = POLLOUT | POLLWRNORM;
792
793 if (!fc)
794 return -ENODEV;
795
796 poll_wait(file, &fc->waitq, wait);
797
798 spin_lock(&fuse_lock);
799 if (!list_empty(&fc->pending))
800 mask |= POLLIN | POLLRDNORM;
801 spin_unlock(&fuse_lock);
802
803 return mask;
804}
805
806/* Abort all requests on the given list (pending or processing) */
807static void end_requests(struct fuse_conn *fc, struct list_head *head)
808{
809 while (!list_empty(head)) {
810 struct fuse_req *req;
811 req = list_entry(head->next, struct fuse_req, list);
812 list_del_init(&req->list);
813 req->out.h.error = -ECONNABORTED;
814 request_end(fc, req);
815 spin_lock(&fuse_lock);
816 }
817}
818
819static int fuse_dev_release(struct inode *inode, struct file *file)
820{
821 struct fuse_conn *fc;
822
823 spin_lock(&fuse_lock);
824 fc = file->private_data;
825 if (fc) {
826 fc->connected = 0;
827 end_requests(fc, &fc->pending);
828 end_requests(fc, &fc->processing);
829 fuse_release_conn(fc);
830 }
831 spin_unlock(&fuse_lock);
832 return 0;
833}
834
835struct file_operations fuse_dev_operations = {
836 .owner = THIS_MODULE,
837 .llseek = no_llseek,
838 .read = fuse_dev_read,
839 .readv = fuse_dev_readv,
840 .write = fuse_dev_write,
841 .writev = fuse_dev_writev,
842 .poll = fuse_dev_poll,
843 .release = fuse_dev_release,
844};
845
846static struct miscdevice fuse_miscdevice = {
847 .minor = FUSE_MINOR,
848 .name = "fuse",
849 .fops = &fuse_dev_operations,
850};
851
852int __init fuse_dev_init(void)
853{
854 int err = -ENOMEM;
855 fuse_req_cachep = kmem_cache_create("fuse_request",
856 sizeof(struct fuse_req),
857 0, 0, NULL, NULL);
858 if (!fuse_req_cachep)
859 goto out;
860
861 err = misc_register(&fuse_miscdevice);
862 if (err)
863 goto out_cache_clean;
864
865 return 0;
866
867 out_cache_clean:
868 kmem_cache_destroy(fuse_req_cachep);
869 out:
870 return err;
871}
872
873void fuse_dev_cleanup(void)
874{
875 misc_deregister(&fuse_miscdevice);
876 kmem_cache_destroy(fuse_req_cachep);
877}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
new file mode 100644
index 000000000000..e79e49b3eec7
--- /dev/null
+++ b/fs/fuse/dir.c
@@ -0,0 +1,982 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/file.h>
13#include <linux/gfp.h>
14#include <linux/sched.h>
15#include <linux/namei.h>
16
17static inline unsigned long time_to_jiffies(unsigned long sec,
18 unsigned long nsec)
19{
20 struct timespec ts = {sec, nsec};
21 return jiffies + timespec_to_jiffies(&ts);
22}
23
24static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
25 struct dentry *entry,
26 struct fuse_entry_out *outarg)
27{
28 req->in.h.opcode = FUSE_LOOKUP;
29 req->in.h.nodeid = get_node_id(dir);
30 req->inode = dir;
31 req->in.numargs = 1;
32 req->in.args[0].size = entry->d_name.len + 1;
33 req->in.args[0].value = entry->d_name.name;
34 req->out.numargs = 1;
35 req->out.args[0].size = sizeof(struct fuse_entry_out);
36 req->out.args[0].value = outarg;
37}
38
39static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
40{
41 if (!entry->d_inode || is_bad_inode(entry->d_inode))
42 return 0;
43 else if (time_after(jiffies, entry->d_time)) {
44 int err;
45 struct fuse_entry_out outarg;
46 struct inode *inode = entry->d_inode;
47 struct fuse_inode *fi = get_fuse_inode(inode);
48 struct fuse_conn *fc = get_fuse_conn(inode);
49 struct fuse_req *req = fuse_get_request(fc);
50 if (!req)
51 return 0;
52
53 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
54 request_send(fc, req);
55 err = req->out.h.error;
56 if (!err) {
57 if (outarg.nodeid != get_node_id(inode)) {
58 fuse_send_forget(fc, req, outarg.nodeid, 1);
59 return 0;
60 }
61 fi->nlookup ++;
62 }
63 fuse_put_request(fc, req);
64 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
65 return 0;
66
67 fuse_change_attributes(inode, &outarg.attr);
68 entry->d_time = time_to_jiffies(outarg.entry_valid,
69 outarg.entry_valid_nsec);
70 fi->i_time = time_to_jiffies(outarg.attr_valid,
71 outarg.attr_valid_nsec);
72 }
73 return 1;
74}
75
76static struct dentry_operations fuse_dentry_operations = {
77 .d_revalidate = fuse_dentry_revalidate,
78};
79
80static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
81 struct inode **inodep)
82{
83 int err;
84 struct fuse_entry_out outarg;
85 struct inode *inode = NULL;
86 struct fuse_conn *fc = get_fuse_conn(dir);
87 struct fuse_req *req;
88
89 if (entry->d_name.len > FUSE_NAME_MAX)
90 return -ENAMETOOLONG;
91
92 req = fuse_get_request(fc);
93 if (!req)
94 return -EINTR;
95
96 fuse_lookup_init(req, dir, entry, &outarg);
97 request_send(fc, req);
98 err = req->out.h.error;
99 if (!err) {
100 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
101 &outarg.attr);
102 if (!inode) {
103 fuse_send_forget(fc, req, outarg.nodeid, 1);
104 return -ENOMEM;
105 }
106 }
107 fuse_put_request(fc, req);
108 if (err && err != -ENOENT)
109 return err;
110
111 if (inode) {
112 struct fuse_inode *fi = get_fuse_inode(inode);
113 entry->d_time = time_to_jiffies(outarg.entry_valid,
114 outarg.entry_valid_nsec);
115 fi->i_time = time_to_jiffies(outarg.attr_valid,
116 outarg.attr_valid_nsec);
117 }
118
119 entry->d_op = &fuse_dentry_operations;
120 *inodep = inode;
121 return 0;
122}
123
124void fuse_invalidate_attr(struct inode *inode)
125{
126 get_fuse_inode(inode)->i_time = jiffies - 1;
127}
128
129static void fuse_invalidate_entry(struct dentry *entry)
130{
131 d_invalidate(entry);
132 entry->d_time = jiffies - 1;
133}
134
135static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
136 struct inode *dir, struct dentry *entry,
137 int mode)
138{
139 struct fuse_entry_out outarg;
140 struct inode *inode;
141 struct fuse_inode *fi;
142 int err;
143
144 req->in.h.nodeid = get_node_id(dir);
145 req->inode = dir;
146 req->out.numargs = 1;
147 req->out.args[0].size = sizeof(outarg);
148 req->out.args[0].value = &outarg;
149 request_send(fc, req);
150 err = req->out.h.error;
151 if (err) {
152 fuse_put_request(fc, req);
153 return err;
154 }
155 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
156 &outarg.attr);
157 if (!inode) {
158 fuse_send_forget(fc, req, outarg.nodeid, 1);
159 return -ENOMEM;
160 }
161 fuse_put_request(fc, req);
162
163 /* Don't allow userspace to do really stupid things... */
164 if ((inode->i_mode ^ mode) & S_IFMT) {
165 iput(inode);
166 return -EIO;
167 }
168
169 entry->d_time = time_to_jiffies(outarg.entry_valid,
170 outarg.entry_valid_nsec);
171
172 fi = get_fuse_inode(inode);
173 fi->i_time = time_to_jiffies(outarg.attr_valid,
174 outarg.attr_valid_nsec);
175
176 d_instantiate(entry, inode);
177 fuse_invalidate_attr(dir);
178 return 0;
179}
180
181static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
182 dev_t rdev)
183{
184 struct fuse_mknod_in inarg;
185 struct fuse_conn *fc = get_fuse_conn(dir);
186 struct fuse_req *req = fuse_get_request(fc);
187 if (!req)
188 return -EINTR;
189
190 memset(&inarg, 0, sizeof(inarg));
191 inarg.mode = mode;
192 inarg.rdev = new_encode_dev(rdev);
193 req->in.h.opcode = FUSE_MKNOD;
194 req->in.numargs = 2;
195 req->in.args[0].size = sizeof(inarg);
196 req->in.args[0].value = &inarg;
197 req->in.args[1].size = entry->d_name.len + 1;
198 req->in.args[1].value = entry->d_name.name;
199 return create_new_entry(fc, req, dir, entry, mode);
200}
201
202static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
203 struct nameidata *nd)
204{
205 return fuse_mknod(dir, entry, mode, 0);
206}
207
208static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
209{
210 struct fuse_mkdir_in inarg;
211 struct fuse_conn *fc = get_fuse_conn(dir);
212 struct fuse_req *req = fuse_get_request(fc);
213 if (!req)
214 return -EINTR;
215
216 memset(&inarg, 0, sizeof(inarg));
217 inarg.mode = mode;
218 req->in.h.opcode = FUSE_MKDIR;
219 req->in.numargs = 2;
220 req->in.args[0].size = sizeof(inarg);
221 req->in.args[0].value = &inarg;
222 req->in.args[1].size = entry->d_name.len + 1;
223 req->in.args[1].value = entry->d_name.name;
224 return create_new_entry(fc, req, dir, entry, S_IFDIR);
225}
226
227static int fuse_symlink(struct inode *dir, struct dentry *entry,
228 const char *link)
229{
230 struct fuse_conn *fc = get_fuse_conn(dir);
231 unsigned len = strlen(link) + 1;
232 struct fuse_req *req;
233
234 if (len > FUSE_SYMLINK_MAX)
235 return -ENAMETOOLONG;
236
237 req = fuse_get_request(fc);
238 if (!req)
239 return -EINTR;
240
241 req->in.h.opcode = FUSE_SYMLINK;
242 req->in.numargs = 2;
243 req->in.args[0].size = entry->d_name.len + 1;
244 req->in.args[0].value = entry->d_name.name;
245 req->in.args[1].size = len;
246 req->in.args[1].value = link;
247 return create_new_entry(fc, req, dir, entry, S_IFLNK);
248}
249
250static int fuse_unlink(struct inode *dir, struct dentry *entry)
251{
252 int err;
253 struct fuse_conn *fc = get_fuse_conn(dir);
254 struct fuse_req *req = fuse_get_request(fc);
255 if (!req)
256 return -EINTR;
257
258 req->in.h.opcode = FUSE_UNLINK;
259 req->in.h.nodeid = get_node_id(dir);
260 req->inode = dir;
261 req->in.numargs = 1;
262 req->in.args[0].size = entry->d_name.len + 1;
263 req->in.args[0].value = entry->d_name.name;
264 request_send(fc, req);
265 err = req->out.h.error;
266 fuse_put_request(fc, req);
267 if (!err) {
268 struct inode *inode = entry->d_inode;
269
270 /* Set nlink to zero so the inode can be cleared, if
271 the inode does have more links this will be
272 discovered at the next lookup/getattr */
273 inode->i_nlink = 0;
274 fuse_invalidate_attr(inode);
275 fuse_invalidate_attr(dir);
276 } else if (err == -EINTR)
277 fuse_invalidate_entry(entry);
278 return err;
279}
280
281static int fuse_rmdir(struct inode *dir, struct dentry *entry)
282{
283 int err;
284 struct fuse_conn *fc = get_fuse_conn(dir);
285 struct fuse_req *req = fuse_get_request(fc);
286 if (!req)
287 return -EINTR;
288
289 req->in.h.opcode = FUSE_RMDIR;
290 req->in.h.nodeid = get_node_id(dir);
291 req->inode = dir;
292 req->in.numargs = 1;
293 req->in.args[0].size = entry->d_name.len + 1;
294 req->in.args[0].value = entry->d_name.name;
295 request_send(fc, req);
296 err = req->out.h.error;
297 fuse_put_request(fc, req);
298 if (!err) {
299 entry->d_inode->i_nlink = 0;
300 fuse_invalidate_attr(dir);
301 } else if (err == -EINTR)
302 fuse_invalidate_entry(entry);
303 return err;
304}
305
306static int fuse_rename(struct inode *olddir, struct dentry *oldent,
307 struct inode *newdir, struct dentry *newent)
308{
309 int err;
310 struct fuse_rename_in inarg;
311 struct fuse_conn *fc = get_fuse_conn(olddir);
312 struct fuse_req *req = fuse_get_request(fc);
313 if (!req)
314 return -EINTR;
315
316 memset(&inarg, 0, sizeof(inarg));
317 inarg.newdir = get_node_id(newdir);
318 req->in.h.opcode = FUSE_RENAME;
319 req->in.h.nodeid = get_node_id(olddir);
320 req->inode = olddir;
321 req->inode2 = newdir;
322 req->in.numargs = 3;
323 req->in.args[0].size = sizeof(inarg);
324 req->in.args[0].value = &inarg;
325 req->in.args[1].size = oldent->d_name.len + 1;
326 req->in.args[1].value = oldent->d_name.name;
327 req->in.args[2].size = newent->d_name.len + 1;
328 req->in.args[2].value = newent->d_name.name;
329 request_send(fc, req);
330 err = req->out.h.error;
331 fuse_put_request(fc, req);
332 if (!err) {
333 fuse_invalidate_attr(olddir);
334 if (olddir != newdir)
335 fuse_invalidate_attr(newdir);
336 } else if (err == -EINTR) {
337 /* If request was interrupted, DEITY only knows if the
338 rename actually took place. If the invalidation
339 fails (e.g. some process has CWD under the renamed
340 directory), then there can be inconsistency between
341 the dcache and the real filesystem. Tough luck. */
342 fuse_invalidate_entry(oldent);
343 if (newent->d_inode)
344 fuse_invalidate_entry(newent);
345 }
346
347 return err;
348}
349
350static int fuse_link(struct dentry *entry, struct inode *newdir,
351 struct dentry *newent)
352{
353 int err;
354 struct fuse_link_in inarg;
355 struct inode *inode = entry->d_inode;
356 struct fuse_conn *fc = get_fuse_conn(inode);
357 struct fuse_req *req = fuse_get_request(fc);
358 if (!req)
359 return -EINTR;
360
361 memset(&inarg, 0, sizeof(inarg));
362 inarg.oldnodeid = get_node_id(inode);
363 req->in.h.opcode = FUSE_LINK;
364 req->inode2 = inode;
365 req->in.numargs = 2;
366 req->in.args[0].size = sizeof(inarg);
367 req->in.args[0].value = &inarg;
368 req->in.args[1].size = newent->d_name.len + 1;
369 req->in.args[1].value = newent->d_name.name;
370 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
371 /* Contrary to "normal" filesystems it can happen that link
372 makes two "logical" inodes point to the same "physical"
373 inode. We invalidate the attributes of the old one, so it
374 will reflect changes in the backing inode (link count,
375 etc.)
376 */
377 if (!err || err == -EINTR)
378 fuse_invalidate_attr(inode);
379 return err;
380}
381
382int fuse_do_getattr(struct inode *inode)
383{
384 int err;
385 struct fuse_attr_out arg;
386 struct fuse_conn *fc = get_fuse_conn(inode);
387 struct fuse_req *req = fuse_get_request(fc);
388 if (!req)
389 return -EINTR;
390
391 req->in.h.opcode = FUSE_GETATTR;
392 req->in.h.nodeid = get_node_id(inode);
393 req->inode = inode;
394 req->out.numargs = 1;
395 req->out.args[0].size = sizeof(arg);
396 req->out.args[0].value = &arg;
397 request_send(fc, req);
398 err = req->out.h.error;
399 fuse_put_request(fc, req);
400 if (!err) {
401 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
402 make_bad_inode(inode);
403 err = -EIO;
404 } else {
405 struct fuse_inode *fi = get_fuse_inode(inode);
406 fuse_change_attributes(inode, &arg.attr);
407 fi->i_time = time_to_jiffies(arg.attr_valid,
408 arg.attr_valid_nsec);
409 }
410 }
411 return err;
412}
413
414/*
415 * Calling into a user-controlled filesystem gives the filesystem
416 * daemon ptrace-like capabilities over the requester process. This
417 * means, that the filesystem daemon is able to record the exact
418 * filesystem operations performed, and can also control the behavior
419 * of the requester process in otherwise impossible ways. For example
420 * it can delay the operation for arbitrary length of time allowing
421 * DoS against the requester.
422 *
423 * For this reason only those processes can call into the filesystem,
424 * for which the owner of the mount has ptrace privilege. This
425 * excludes processes started by other users, suid or sgid processes.
426 */
427static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
428{
429 if (fc->flags & FUSE_ALLOW_OTHER)
430 return 1;
431
432 if (task->euid == fc->user_id &&
433 task->suid == fc->user_id &&
434 task->uid == fc->user_id &&
435 task->egid == fc->group_id &&
436 task->sgid == fc->group_id &&
437 task->gid == fc->group_id)
438 return 1;
439
440 return 0;
441}
442
443static int fuse_revalidate(struct dentry *entry)
444{
445 struct inode *inode = entry->d_inode;
446 struct fuse_inode *fi = get_fuse_inode(inode);
447 struct fuse_conn *fc = get_fuse_conn(inode);
448
449 if (!fuse_allow_task(fc, current))
450 return -EACCES;
451 if (get_node_id(inode) != FUSE_ROOT_ID &&
452 time_before_eq(jiffies, fi->i_time))
453 return 0;
454
455 return fuse_do_getattr(inode);
456}
457
458static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
459{
460 struct fuse_conn *fc = get_fuse_conn(inode);
461
462 if (!fuse_allow_task(fc, current))
463 return -EACCES;
464 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
465 int err = generic_permission(inode, mask, NULL);
466
467 /* If permission is denied, try to refresh file
468 attributes. This is also needed, because the root
469 node will at first have no permissions */
470 if (err == -EACCES) {
471 err = fuse_do_getattr(inode);
472 if (!err)
473 err = generic_permission(inode, mask, NULL);
474 }
475
476 /* FIXME: Need some mechanism to revoke permissions:
477 currently if the filesystem suddenly changes the
478 file mode, we will not be informed about it, and
479 continue to allow access to the file/directory.
480
481 This is actually not so grave, since the user can
482 simply keep access to the file/directory anyway by
483 keeping it open... */
484
485 return err;
486 } else {
487 int mode = inode->i_mode;
488 if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
489 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
490 return -EROFS;
491 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
492 return -EACCES;
493 return 0;
494 }
495}
496
497static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
498 void *dstbuf, filldir_t filldir)
499{
500 while (nbytes >= FUSE_NAME_OFFSET) {
501 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
502 size_t reclen = FUSE_DIRENT_SIZE(dirent);
503 int over;
504 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
505 return -EIO;
506 if (reclen > nbytes)
507 break;
508
509 over = filldir(dstbuf, dirent->name, dirent->namelen,
510 file->f_pos, dirent->ino, dirent->type);
511 if (over)
512 break;
513
514 buf += reclen;
515 nbytes -= reclen;
516 file->f_pos = dirent->off;
517 }
518
519 return 0;
520}
521
522static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
523 struct inode *inode, loff_t pos,
524 size_t count)
525{
526 return fuse_send_read_common(req, file, inode, pos, count, 1);
527}
528
529static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
530{
531 int err;
532 size_t nbytes;
533 struct page *page;
534 struct inode *inode = file->f_dentry->d_inode;
535 struct fuse_conn *fc = get_fuse_conn(inode);
536 struct fuse_req *req = fuse_get_request(fc);
537 if (!req)
538 return -EINTR;
539
540 page = alloc_page(GFP_KERNEL);
541 if (!page) {
542 fuse_put_request(fc, req);
543 return -ENOMEM;
544 }
545 req->num_pages = 1;
546 req->pages[0] = page;
547 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
548 err = req->out.h.error;
549 fuse_put_request(fc, req);
550 if (!err)
551 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
552 filldir);
553
554 __free_page(page);
555 fuse_invalidate_attr(inode); /* atime changed */
556 return err;
557}
558
559static char *read_link(struct dentry *dentry)
560{
561 struct inode *inode = dentry->d_inode;
562 struct fuse_conn *fc = get_fuse_conn(inode);
563 struct fuse_req *req = fuse_get_request(fc);
564 char *link;
565
566 if (!req)
567 return ERR_PTR(-EINTR);
568
569 link = (char *) __get_free_page(GFP_KERNEL);
570 if (!link) {
571 link = ERR_PTR(-ENOMEM);
572 goto out;
573 }
574 req->in.h.opcode = FUSE_READLINK;
575 req->in.h.nodeid = get_node_id(inode);
576 req->inode = inode;
577 req->out.argvar = 1;
578 req->out.numargs = 1;
579 req->out.args[0].size = PAGE_SIZE - 1;
580 req->out.args[0].value = link;
581 request_send(fc, req);
582 if (req->out.h.error) {
583 free_page((unsigned long) link);
584 link = ERR_PTR(req->out.h.error);
585 } else
586 link[req->out.args[0].size] = '\0';
587 out:
588 fuse_put_request(fc, req);
589 fuse_invalidate_attr(inode); /* atime changed */
590 return link;
591}
592
593static void free_link(char *link)
594{
595 if (!IS_ERR(link))
596 free_page((unsigned long) link);
597}
598
599static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
600{
601 nd_set_link(nd, read_link(dentry));
602 return NULL;
603}
604
605static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
606{
607 free_link(nd_get_link(nd));
608}
609
610static int fuse_dir_open(struct inode *inode, struct file *file)
611{
612 return fuse_open_common(inode, file, 1);
613}
614
615static int fuse_dir_release(struct inode *inode, struct file *file)
616{
617 return fuse_release_common(inode, file, 1);
618}
619
620static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
621{
622 /* nfsd can call this with no file */
623 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
624}
625
626static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
627{
628 unsigned ivalid = iattr->ia_valid;
629 unsigned fvalid = 0;
630
631 memset(fattr, 0, sizeof(*fattr));
632
633 if (ivalid & ATTR_MODE)
634 fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
635 if (ivalid & ATTR_UID)
636 fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
637 if (ivalid & ATTR_GID)
638 fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
639 if (ivalid & ATTR_SIZE)
640 fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
641 /* You can only _set_ these together (they may change by themselves) */
642 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
643 fvalid |= FATTR_ATIME | FATTR_MTIME;
644 fattr->atime = iattr->ia_atime.tv_sec;
645 fattr->mtime = iattr->ia_mtime.tv_sec;
646 }
647
648 return fvalid;
649}
650
651static int fuse_setattr(struct dentry *entry, struct iattr *attr)
652{
653 struct inode *inode = entry->d_inode;
654 struct fuse_conn *fc = get_fuse_conn(inode);
655 struct fuse_inode *fi = get_fuse_inode(inode);
656 struct fuse_req *req;
657 struct fuse_setattr_in inarg;
658 struct fuse_attr_out outarg;
659 int err;
660 int is_truncate = 0;
661
662 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
663 err = inode_change_ok(inode, attr);
664 if (err)
665 return err;
666 }
667
668 if (attr->ia_valid & ATTR_SIZE) {
669 unsigned long limit;
670 is_truncate = 1;
671 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
672 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
673 send_sig(SIGXFSZ, current, 0);
674 return -EFBIG;
675 }
676 }
677
678 req = fuse_get_request(fc);
679 if (!req)
680 return -EINTR;
681
682 memset(&inarg, 0, sizeof(inarg));
683 inarg.valid = iattr_to_fattr(attr, &inarg.attr);
684 req->in.h.opcode = FUSE_SETATTR;
685 req->in.h.nodeid = get_node_id(inode);
686 req->inode = inode;
687 req->in.numargs = 1;
688 req->in.args[0].size = sizeof(inarg);
689 req->in.args[0].value = &inarg;
690 req->out.numargs = 1;
691 req->out.args[0].size = sizeof(outarg);
692 req->out.args[0].value = &outarg;
693 request_send(fc, req);
694 err = req->out.h.error;
695 fuse_put_request(fc, req);
696 if (!err) {
697 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
698 make_bad_inode(inode);
699 err = -EIO;
700 } else {
701 if (is_truncate) {
702 loff_t origsize = i_size_read(inode);
703 i_size_write(inode, outarg.attr.size);
704 if (origsize > outarg.attr.size)
705 vmtruncate(inode, outarg.attr.size);
706 }
707 fuse_change_attributes(inode, &outarg.attr);
708 fi->i_time = time_to_jiffies(outarg.attr_valid,
709 outarg.attr_valid_nsec);
710 }
711 } else if (err == -EINTR)
712 fuse_invalidate_attr(inode);
713
714 return err;
715}
716
717static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
718 struct kstat *stat)
719{
720 struct inode *inode = entry->d_inode;
721 int err = fuse_revalidate(entry);
722 if (!err)
723 generic_fillattr(inode, stat);
724
725 return err;
726}
727
728static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
729 struct nameidata *nd)
730{
731 struct inode *inode;
732 int err = fuse_lookup_iget(dir, entry, &inode);
733 if (err)
734 return ERR_PTR(err);
735 if (inode && S_ISDIR(inode->i_mode)) {
736 /* Don't allow creating an alias to a directory */
737 struct dentry *alias = d_find_alias(inode);
738 if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
739 dput(alias);
740 iput(inode);
741 return ERR_PTR(-EIO);
742 }
743 }
744 return d_splice_alias(inode, entry);
745}
746
747static int fuse_setxattr(struct dentry *entry, const char *name,
748 const void *value, size_t size, int flags)
749{
750 struct inode *inode = entry->d_inode;
751 struct fuse_conn *fc = get_fuse_conn(inode);
752 struct fuse_req *req;
753 struct fuse_setxattr_in inarg;
754 int err;
755
756 if (size > FUSE_XATTR_SIZE_MAX)
757 return -E2BIG;
758
759 if (fc->no_setxattr)
760 return -EOPNOTSUPP;
761
762 req = fuse_get_request(fc);
763 if (!req)
764 return -EINTR;
765
766 memset(&inarg, 0, sizeof(inarg));
767 inarg.size = size;
768 inarg.flags = flags;
769 req->in.h.opcode = FUSE_SETXATTR;
770 req->in.h.nodeid = get_node_id(inode);
771 req->inode = inode;
772 req->in.numargs = 3;
773 req->in.args[0].size = sizeof(inarg);
774 req->in.args[0].value = &inarg;
775 req->in.args[1].size = strlen(name) + 1;
776 req->in.args[1].value = name;
777 req->in.args[2].size = size;
778 req->in.args[2].value = value;
779 request_send(fc, req);
780 err = req->out.h.error;
781 fuse_put_request(fc, req);
782 if (err == -ENOSYS) {
783 fc->no_setxattr = 1;
784 err = -EOPNOTSUPP;
785 }
786 return err;
787}
788
789static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
790 void *value, size_t size)
791{
792 struct inode *inode = entry->d_inode;
793 struct fuse_conn *fc = get_fuse_conn(inode);
794 struct fuse_req *req;
795 struct fuse_getxattr_in inarg;
796 struct fuse_getxattr_out outarg;
797 ssize_t ret;
798
799 if (fc->no_getxattr)
800 return -EOPNOTSUPP;
801
802 req = fuse_get_request(fc);
803 if (!req)
804 return -EINTR;
805
806 memset(&inarg, 0, sizeof(inarg));
807 inarg.size = size;
808 req->in.h.opcode = FUSE_GETXATTR;
809 req->in.h.nodeid = get_node_id(inode);
810 req->inode = inode;
811 req->in.numargs = 2;
812 req->in.args[0].size = sizeof(inarg);
813 req->in.args[0].value = &inarg;
814 req->in.args[1].size = strlen(name) + 1;
815 req->in.args[1].value = name;
816 /* This is really two different operations rolled into one */
817 req->out.numargs = 1;
818 if (size) {
819 req->out.argvar = 1;
820 req->out.args[0].size = size;
821 req->out.args[0].value = value;
822 } else {
823 req->out.args[0].size = sizeof(outarg);
824 req->out.args[0].value = &outarg;
825 }
826 request_send(fc, req);
827 ret = req->out.h.error;
828 if (!ret)
829 ret = size ? req->out.args[0].size : outarg.size;
830 else {
831 if (ret == -ENOSYS) {
832 fc->no_getxattr = 1;
833 ret = -EOPNOTSUPP;
834 }
835 }
836 fuse_put_request(fc, req);
837 return ret;
838}
839
840static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
841{
842 struct inode *inode = entry->d_inode;
843 struct fuse_conn *fc = get_fuse_conn(inode);
844 struct fuse_req *req;
845 struct fuse_getxattr_in inarg;
846 struct fuse_getxattr_out outarg;
847 ssize_t ret;
848
849 if (fc->no_listxattr)
850 return -EOPNOTSUPP;
851
852 req = fuse_get_request(fc);
853 if (!req)
854 return -EINTR;
855
856 memset(&inarg, 0, sizeof(inarg));
857 inarg.size = size;
858 req->in.h.opcode = FUSE_LISTXATTR;
859 req->in.h.nodeid = get_node_id(inode);
860 req->inode = inode;
861 req->in.numargs = 1;
862 req->in.args[0].size = sizeof(inarg);
863 req->in.args[0].value = &inarg;
864 /* This is really two different operations rolled into one */
865 req->out.numargs = 1;
866 if (size) {
867 req->out.argvar = 1;
868 req->out.args[0].size = size;
869 req->out.args[0].value = list;
870 } else {
871 req->out.args[0].size = sizeof(outarg);
872 req->out.args[0].value = &outarg;
873 }
874 request_send(fc, req);
875 ret = req->out.h.error;
876 if (!ret)
877 ret = size ? req->out.args[0].size : outarg.size;
878 else {
879 if (ret == -ENOSYS) {
880 fc->no_listxattr = 1;
881 ret = -EOPNOTSUPP;
882 }
883 }
884 fuse_put_request(fc, req);
885 return ret;
886}
887
888static int fuse_removexattr(struct dentry *entry, const char *name)
889{
890 struct inode *inode = entry->d_inode;
891 struct fuse_conn *fc = get_fuse_conn(inode);
892 struct fuse_req *req;
893 int err;
894
895 if (fc->no_removexattr)
896 return -EOPNOTSUPP;
897
898 req = fuse_get_request(fc);
899 if (!req)
900 return -EINTR;
901
902 req->in.h.opcode = FUSE_REMOVEXATTR;
903 req->in.h.nodeid = get_node_id(inode);
904 req->inode = inode;
905 req->in.numargs = 1;
906 req->in.args[0].size = strlen(name) + 1;
907 req->in.args[0].value = name;
908 request_send(fc, req);
909 err = req->out.h.error;
910 fuse_put_request(fc, req);
911 if (err == -ENOSYS) {
912 fc->no_removexattr = 1;
913 err = -EOPNOTSUPP;
914 }
915 return err;
916}
917
918static struct inode_operations fuse_dir_inode_operations = {
919 .lookup = fuse_lookup,
920 .mkdir = fuse_mkdir,
921 .symlink = fuse_symlink,
922 .unlink = fuse_unlink,
923 .rmdir = fuse_rmdir,
924 .rename = fuse_rename,
925 .link = fuse_link,
926 .setattr = fuse_setattr,
927 .create = fuse_create,
928 .mknod = fuse_mknod,
929 .permission = fuse_permission,
930 .getattr = fuse_getattr,
931 .setxattr = fuse_setxattr,
932 .getxattr = fuse_getxattr,
933 .listxattr = fuse_listxattr,
934 .removexattr = fuse_removexattr,
935};
936
937static struct file_operations fuse_dir_operations = {
938 .llseek = generic_file_llseek,
939 .read = generic_read_dir,
940 .readdir = fuse_readdir,
941 .open = fuse_dir_open,
942 .release = fuse_dir_release,
943 .fsync = fuse_dir_fsync,
944};
945
946static struct inode_operations fuse_common_inode_operations = {
947 .setattr = fuse_setattr,
948 .permission = fuse_permission,
949 .getattr = fuse_getattr,
950 .setxattr = fuse_setxattr,
951 .getxattr = fuse_getxattr,
952 .listxattr = fuse_listxattr,
953 .removexattr = fuse_removexattr,
954};
955
956static struct inode_operations fuse_symlink_inode_operations = {
957 .setattr = fuse_setattr,
958 .follow_link = fuse_follow_link,
959 .put_link = fuse_put_link,
960 .readlink = generic_readlink,
961 .getattr = fuse_getattr,
962 .setxattr = fuse_setxattr,
963 .getxattr = fuse_getxattr,
964 .listxattr = fuse_listxattr,
965 .removexattr = fuse_removexattr,
966};
967
968void fuse_init_common(struct inode *inode)
969{
970 inode->i_op = &fuse_common_inode_operations;
971}
972
973void fuse_init_dir(struct inode *inode)
974{
975 inode->i_op = &fuse_dir_inode_operations;
976 inode->i_fop = &fuse_dir_operations;
977}
978
979void fuse_init_symlink(struct inode *inode)
980{
981 inode->i_op = &fuse_symlink_inode_operations;
982}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
new file mode 100644
index 000000000000..6454022b0536
--- /dev/null
+++ b/fs/fuse/file.c
@@ -0,0 +1,555 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/slab.h>
13#include <linux/kernel.h>
14
15static struct file_operations fuse_direct_io_file_operations;
16
17int fuse_open_common(struct inode *inode, struct file *file, int isdir)
18{
19 struct fuse_conn *fc = get_fuse_conn(inode);
20 struct fuse_req *req;
21 struct fuse_open_in inarg;
22 struct fuse_open_out outarg;
23 struct fuse_file *ff;
24 int err;
25
26 err = generic_file_open(inode, file);
27 if (err)
28 return err;
29
30 /* If opening the root node, no lookup has been performed on
31 it, so the attributes must be refreshed */
32 if (get_node_id(inode) == FUSE_ROOT_ID) {
33 int err = fuse_do_getattr(inode);
34 if (err)
35 return err;
36 }
37
38 req = fuse_get_request(fc);
39 if (!req)
40 return -EINTR;
41
42 err = -ENOMEM;
43 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
44 if (!ff)
45 goto out_put_request;
46
47 ff->release_req = fuse_request_alloc();
48 if (!ff->release_req) {
49 kfree(ff);
50 goto out_put_request;
51 }
52
53 memset(&inarg, 0, sizeof(inarg));
54 inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
55 req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
56 req->in.h.nodeid = get_node_id(inode);
57 req->inode = inode;
58 req->in.numargs = 1;
59 req->in.args[0].size = sizeof(inarg);
60 req->in.args[0].value = &inarg;
61 req->out.numargs = 1;
62 req->out.args[0].size = sizeof(outarg);
63 req->out.args[0].value = &outarg;
64 request_send(fc, req);
65 err = req->out.h.error;
66 if (err) {
67 fuse_request_free(ff->release_req);
68 kfree(ff);
69 } else {
70 if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
71 file->f_op = &fuse_direct_io_file_operations;
72 if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
73 invalidate_inode_pages(inode->i_mapping);
74 ff->fh = outarg.fh;
75 file->private_data = ff;
76 }
77
78 out_put_request:
79 fuse_put_request(fc, req);
80 return err;
81}
82
83int fuse_release_common(struct inode *inode, struct file *file, int isdir)
84{
85 struct fuse_conn *fc = get_fuse_conn(inode);
86 struct fuse_file *ff = file->private_data;
87 struct fuse_req *req = ff->release_req;
88 struct fuse_release_in *inarg = &req->misc.release_in;
89
90 inarg->fh = ff->fh;
91 inarg->flags = file->f_flags & ~O_EXCL;
92 req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
93 req->in.h.nodeid = get_node_id(inode);
94 req->inode = inode;
95 req->in.numargs = 1;
96 req->in.args[0].size = sizeof(struct fuse_release_in);
97 req->in.args[0].value = inarg;
98 request_send_background(fc, req);
99 kfree(ff);
100
101 /* Return value is ignored by VFS */
102 return 0;
103}
104
105static int fuse_open(struct inode *inode, struct file *file)
106{
107 return fuse_open_common(inode, file, 0);
108}
109
110static int fuse_release(struct inode *inode, struct file *file)
111{
112 return fuse_release_common(inode, file, 0);
113}
114
115static int fuse_flush(struct file *file)
116{
117 struct inode *inode = file->f_dentry->d_inode;
118 struct fuse_conn *fc = get_fuse_conn(inode);
119 struct fuse_file *ff = file->private_data;
120 struct fuse_req *req;
121 struct fuse_flush_in inarg;
122 int err;
123
124 if (fc->no_flush)
125 return 0;
126
127 req = fuse_get_request(fc);
128 if (!req)
129 return -EINTR;
130
131 memset(&inarg, 0, sizeof(inarg));
132 inarg.fh = ff->fh;
133 req->in.h.opcode = FUSE_FLUSH;
134 req->in.h.nodeid = get_node_id(inode);
135 req->inode = inode;
136 req->file = file;
137 req->in.numargs = 1;
138 req->in.args[0].size = sizeof(inarg);
139 req->in.args[0].value = &inarg;
140 request_send(fc, req);
141 err = req->out.h.error;
142 fuse_put_request(fc, req);
143 if (err == -ENOSYS) {
144 fc->no_flush = 1;
145 err = 0;
146 }
147 return err;
148}
149
150int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
151 int isdir)
152{
153 struct inode *inode = de->d_inode;
154 struct fuse_conn *fc = get_fuse_conn(inode);
155 struct fuse_file *ff = file->private_data;
156 struct fuse_req *req;
157 struct fuse_fsync_in inarg;
158 int err;
159
160 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
161 return 0;
162
163 req = fuse_get_request(fc);
164 if (!req)
165 return -EINTR;
166
167 memset(&inarg, 0, sizeof(inarg));
168 inarg.fh = ff->fh;
169 inarg.fsync_flags = datasync ? 1 : 0;
170 req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
171 req->in.h.nodeid = get_node_id(inode);
172 req->inode = inode;
173 req->file = file;
174 req->in.numargs = 1;
175 req->in.args[0].size = sizeof(inarg);
176 req->in.args[0].value = &inarg;
177 request_send(fc, req);
178 err = req->out.h.error;
179 fuse_put_request(fc, req);
180 if (err == -ENOSYS) {
181 if (isdir)
182 fc->no_fsyncdir = 1;
183 else
184 fc->no_fsync = 1;
185 err = 0;
186 }
187 return err;
188}
189
190static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
191{
192 return fuse_fsync_common(file, de, datasync, 0);
193}
194
195size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
196 struct inode *inode, loff_t pos, size_t count,
197 int isdir)
198{
199 struct fuse_conn *fc = get_fuse_conn(inode);
200 struct fuse_file *ff = file->private_data;
201 struct fuse_read_in inarg;
202
203 memset(&inarg, 0, sizeof(struct fuse_read_in));
204 inarg.fh = ff->fh;
205 inarg.offset = pos;
206 inarg.size = count;
207 req->in.h.opcode = isdir ? FUSE_READDIR : FUSE_READ;
208 req->in.h.nodeid = get_node_id(inode);
209 req->inode = inode;
210 req->file = file;
211 req->in.numargs = 1;
212 req->in.args[0].size = sizeof(struct fuse_read_in);
213 req->in.args[0].value = &inarg;
214 req->out.argpages = 1;
215 req->out.argvar = 1;
216 req->out.numargs = 1;
217 req->out.args[0].size = count;
218 request_send(fc, req);
219 return req->out.args[0].size;
220}
221
222static inline size_t fuse_send_read(struct fuse_req *req, struct file *file,
223 struct inode *inode, loff_t pos,
224 size_t count)
225{
226 return fuse_send_read_common(req, file, inode, pos, count, 0);
227}
228
229static int fuse_readpage(struct file *file, struct page *page)
230{
231 struct inode *inode = page->mapping->host;
232 struct fuse_conn *fc = get_fuse_conn(inode);
233 loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
234 struct fuse_req *req = fuse_get_request(fc);
235 int err = -EINTR;
236 if (!req)
237 goto out;
238
239 req->out.page_zeroing = 1;
240 req->num_pages = 1;
241 req->pages[0] = page;
242 fuse_send_read(req, file, inode, pos, PAGE_CACHE_SIZE);
243 err = req->out.h.error;
244 fuse_put_request(fc, req);
245 if (!err)
246 SetPageUptodate(page);
247 fuse_invalidate_attr(inode); /* atime changed */
248 out:
249 unlock_page(page);
250 return err;
251}
252
253static int fuse_send_readpages(struct fuse_req *req, struct file *file,
254 struct inode *inode)
255{
256 loff_t pos = (loff_t) req->pages[0]->index << PAGE_CACHE_SHIFT;
257 size_t count = req->num_pages << PAGE_CACHE_SHIFT;
258 unsigned i;
259 req->out.page_zeroing = 1;
260 fuse_send_read(req, file, inode, pos, count);
261 for (i = 0; i < req->num_pages; i++) {
262 struct page *page = req->pages[i];
263 if (!req->out.h.error)
264 SetPageUptodate(page);
265 unlock_page(page);
266 }
267 return req->out.h.error;
268}
269
270struct fuse_readpages_data {
271 struct fuse_req *req;
272 struct file *file;
273 struct inode *inode;
274};
275
276static int fuse_readpages_fill(void *_data, struct page *page)
277{
278 struct fuse_readpages_data *data = _data;
279 struct fuse_req *req = data->req;
280 struct inode *inode = data->inode;
281 struct fuse_conn *fc = get_fuse_conn(inode);
282
283 if (req->num_pages &&
284 (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
285 (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
286 req->pages[req->num_pages - 1]->index + 1 != page->index)) {
287 int err = fuse_send_readpages(req, data->file, inode);
288 if (err) {
289 unlock_page(page);
290 return err;
291 }
292 fuse_reset_request(req);
293 }
294 req->pages[req->num_pages] = page;
295 req->num_pages ++;
296 return 0;
297}
298
299static int fuse_readpages(struct file *file, struct address_space *mapping,
300 struct list_head *pages, unsigned nr_pages)
301{
302 struct inode *inode = mapping->host;
303 struct fuse_conn *fc = get_fuse_conn(inode);
304 struct fuse_readpages_data data;
305 int err;
306 data.file = file;
307 data.inode = inode;
308 data.req = fuse_get_request(fc);
309 if (!data.req)
310 return -EINTR;
311
312 err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
313 if (!err && data.req->num_pages)
314 err = fuse_send_readpages(data.req, file, inode);
315 fuse_put_request(fc, data.req);
316 fuse_invalidate_attr(inode); /* atime changed */
317 return err;
318}
319
320static size_t fuse_send_write(struct fuse_req *req, struct file *file,
321 struct inode *inode, loff_t pos, size_t count)
322{
323 struct fuse_conn *fc = get_fuse_conn(inode);
324 struct fuse_file *ff = file->private_data;
325 struct fuse_write_in inarg;
326 struct fuse_write_out outarg;
327
328 memset(&inarg, 0, sizeof(struct fuse_write_in));
329 inarg.fh = ff->fh;
330 inarg.offset = pos;
331 inarg.size = count;
332 req->in.h.opcode = FUSE_WRITE;
333 req->in.h.nodeid = get_node_id(inode);
334 req->inode = inode;
335 req->file = file;
336 req->in.argpages = 1;
337 req->in.numargs = 2;
338 req->in.args[0].size = sizeof(struct fuse_write_in);
339 req->in.args[0].value = &inarg;
340 req->in.args[1].size = count;
341 req->out.numargs = 1;
342 req->out.args[0].size = sizeof(struct fuse_write_out);
343 req->out.args[0].value = &outarg;
344 request_send(fc, req);
345 return outarg.size;
346}
347
348static int fuse_prepare_write(struct file *file, struct page *page,
349 unsigned offset, unsigned to)
350{
351 /* No op */
352 return 0;
353}
354
355static int fuse_commit_write(struct file *file, struct page *page,
356 unsigned offset, unsigned to)
357{
358 int err;
359 size_t nres;
360 unsigned count = to - offset;
361 struct inode *inode = page->mapping->host;
362 struct fuse_conn *fc = get_fuse_conn(inode);
363 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
364 struct fuse_req *req = fuse_get_request(fc);
365 if (!req)
366 return -EINTR;
367
368 req->num_pages = 1;
369 req->pages[0] = page;
370 req->page_offset = offset;
371 nres = fuse_send_write(req, file, inode, pos, count);
372 err = req->out.h.error;
373 fuse_put_request(fc, req);
374 if (!err && nres != count)
375 err = -EIO;
376 if (!err) {
377 pos += count;
378 if (pos > i_size_read(inode))
379 i_size_write(inode, pos);
380
381 if (offset == 0 && to == PAGE_CACHE_SIZE) {
382 clear_page_dirty(page);
383 SetPageUptodate(page);
384 }
385 }
386 fuse_invalidate_attr(inode);
387 return err;
388}
389
390static void fuse_release_user_pages(struct fuse_req *req, int write)
391{
392 unsigned i;
393
394 for (i = 0; i < req->num_pages; i++) {
395 struct page *page = req->pages[i];
396 if (write)
397 set_page_dirty_lock(page);
398 put_page(page);
399 }
400}
401
402static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
403 unsigned nbytes, int write)
404{
405 unsigned long user_addr = (unsigned long) buf;
406 unsigned offset = user_addr & ~PAGE_MASK;
407 int npages;
408
409 /* This doesn't work with nfsd */
410 if (!current->mm)
411 return -EPERM;
412
413 nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
414 npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
415 npages = min(npages, FUSE_MAX_PAGES_PER_REQ);
416 down_read(&current->mm->mmap_sem);
417 npages = get_user_pages(current, current->mm, user_addr, npages, write,
418 0, req->pages, NULL);
419 up_read(&current->mm->mmap_sem);
420 if (npages < 0)
421 return npages;
422
423 req->num_pages = npages;
424 req->page_offset = offset;
425 return 0;
426}
427
428static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
429 size_t count, loff_t *ppos, int write)
430{
431 struct inode *inode = file->f_dentry->d_inode;
432 struct fuse_conn *fc = get_fuse_conn(inode);
433 size_t nmax = write ? fc->max_write : fc->max_read;
434 loff_t pos = *ppos;
435 ssize_t res = 0;
436 struct fuse_req *req = fuse_get_request(fc);
437 if (!req)
438 return -EINTR;
439
440 while (count) {
441 size_t tmp;
442 size_t nres;
443 size_t nbytes = min(count, nmax);
444 int err = fuse_get_user_pages(req, buf, nbytes, !write);
445 if (err) {
446 res = err;
447 break;
448 }
449 tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset;
450 nbytes = min(nbytes, tmp);
451 if (write)
452 nres = fuse_send_write(req, file, inode, pos, nbytes);
453 else
454 nres = fuse_send_read(req, file, inode, pos, nbytes);
455 fuse_release_user_pages(req, !write);
456 if (req->out.h.error) {
457 if (!res)
458 res = req->out.h.error;
459 break;
460 } else if (nres > nbytes) {
461 res = -EIO;
462 break;
463 }
464 count -= nres;
465 res += nres;
466 pos += nres;
467 buf += nres;
468 if (nres != nbytes)
469 break;
470 if (count)
471 fuse_reset_request(req);
472 }
473 fuse_put_request(fc, req);
474 if (res > 0) {
475 if (write && pos > i_size_read(inode))
476 i_size_write(inode, pos);
477 *ppos = pos;
478 }
479 fuse_invalidate_attr(inode);
480
481 return res;
482}
483
484static ssize_t fuse_direct_read(struct file *file, char __user *buf,
485 size_t count, loff_t *ppos)
486{
487 return fuse_direct_io(file, buf, count, ppos, 0);
488}
489
490static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
491 size_t count, loff_t *ppos)
492{
493 struct inode *inode = file->f_dentry->d_inode;
494 ssize_t res;
495 /* Don't allow parallel writes to the same file */
496 down(&inode->i_sem);
497 res = fuse_direct_io(file, buf, count, ppos, 1);
498 up(&inode->i_sem);
499 return res;
500}
501
502static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
503{
504 if ((vma->vm_flags & VM_SHARED)) {
505 if ((vma->vm_flags & VM_WRITE))
506 return -ENODEV;
507 else
508 vma->vm_flags &= ~VM_MAYWRITE;
509 }
510 return generic_file_mmap(file, vma);
511}
512
513static int fuse_set_page_dirty(struct page *page)
514{
515 printk("fuse_set_page_dirty: should not happen\n");
516 dump_stack();
517 return 0;
518}
519
520static struct file_operations fuse_file_operations = {
521 .llseek = generic_file_llseek,
522 .read = generic_file_read,
523 .write = generic_file_write,
524 .mmap = fuse_file_mmap,
525 .open = fuse_open,
526 .flush = fuse_flush,
527 .release = fuse_release,
528 .fsync = fuse_fsync,
529 .sendfile = generic_file_sendfile,
530};
531
532static struct file_operations fuse_direct_io_file_operations = {
533 .llseek = generic_file_llseek,
534 .read = fuse_direct_read,
535 .write = fuse_direct_write,
536 .open = fuse_open,
537 .flush = fuse_flush,
538 .release = fuse_release,
539 .fsync = fuse_fsync,
540 /* no mmap and sendfile */
541};
542
543static struct address_space_operations fuse_file_aops = {
544 .readpage = fuse_readpage,
545 .prepare_write = fuse_prepare_write,
546 .commit_write = fuse_commit_write,
547 .readpages = fuse_readpages,
548 .set_page_dirty = fuse_set_page_dirty,
549};
550
551void fuse_init_file_inode(struct inode *inode)
552{
553 inode->i_fop = &fuse_file_operations;
554 inode->i_data.a_ops = &fuse_file_aops;
555}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
new file mode 100644
index 000000000000..24d761518d86
--- /dev/null
+++ b/fs/fuse/fuse_i.h
@@ -0,0 +1,451 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include <linux/fuse.h>
10#include <linux/fs.h>
11#include <linux/wait.h>
12#include <linux/list.h>
13#include <linux/spinlock.h>
14#include <linux/mm.h>
15#include <linux/backing-dev.h>
16#include <asm/semaphore.h>
17
18/** Max number of pages that can be used in a single read request */
19#define FUSE_MAX_PAGES_PER_REQ 32
20
21/** If more requests are outstanding, then the operation will block */
22#define FUSE_MAX_OUTSTANDING 10
23
24/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
25 module will check permissions based on the file mode. Otherwise no
26 permission checking is done in the kernel */
27#define FUSE_DEFAULT_PERMISSIONS (1 << 0)
28
29/** If the FUSE_ALLOW_OTHER flag is given, then not only the user
30 doing the mount will be allowed to access the filesystem */
31#define FUSE_ALLOW_OTHER (1 << 1)
32
33
34/** FUSE inode */
35struct fuse_inode {
36 /** Inode data */
37 struct inode inode;
38
39 /** Unique ID, which identifies the inode between userspace
40 * and kernel */
41 u64 nodeid;
42
43 /** Number of lookups on this inode */
44 u64 nlookup;
45
46 /** The request used for sending the FORGET message */
47 struct fuse_req *forget_req;
48
49 /** Time in jiffies until the file attributes are valid */
50 unsigned long i_time;
51};
52
53/** FUSE specific file data */
54struct fuse_file {
55 /** Request reserved for flush and release */
56 struct fuse_req *release_req;
57
58 /** File handle used by userspace */
59 u64 fh;
60};
61
62/** One input argument of a request */
63struct fuse_in_arg {
64 unsigned size;
65 const void *value;
66};
67
68/** The request input */
69struct fuse_in {
70 /** The request header */
71 struct fuse_in_header h;
72
73 /** True if the data for the last argument is in req->pages */
74 unsigned argpages:1;
75
76 /** Number of arguments */
77 unsigned numargs;
78
79 /** Array of arguments */
80 struct fuse_in_arg args[3];
81};
82
83/** One output argument of a request */
84struct fuse_arg {
85 unsigned size;
86 void *value;
87};
88
89/** The request output */
90struct fuse_out {
91 /** Header returned from userspace */
92 struct fuse_out_header h;
93
94 /** Last argument is variable length (can be shorter than
95 arg->size) */
96 unsigned argvar:1;
97
98 /** Last argument is a list of pages to copy data to */
99 unsigned argpages:1;
100
101 /** Zero partially or not copied pages */
102 unsigned page_zeroing:1;
103
104 /** Number or arguments */
105 unsigned numargs;
106
107 /** Array of arguments */
108 struct fuse_arg args[3];
109};
110
111struct fuse_req;
112struct fuse_conn;
113
114/**
115 * A request to the client
116 */
117struct fuse_req {
118 /** This can be on either unused_list, pending or processing
119 lists in fuse_conn */
120 struct list_head list;
121
122 /** Entry on the background list */
123 struct list_head bg_entry;
124
125 /** refcount */
126 atomic_t count;
127
128 /** True if the request has reply */
129 unsigned isreply:1;
130
131 /** The request is preallocated */
132 unsigned preallocated:1;
133
134 /** The request was interrupted */
135 unsigned interrupted:1;
136
137 /** Request is sent in the background */
138 unsigned background:1;
139
140 /** Data is being copied to/from the request */
141 unsigned locked:1;
142
143 /** Request has been sent to userspace */
144 unsigned sent:1;
145
146 /** The request is finished */
147 unsigned finished:1;
148
149 /** The request input */
150 struct fuse_in in;
151
152 /** The request output */
153 struct fuse_out out;
154
155 /** Used to wake up the task waiting for completion of request*/
156 wait_queue_head_t waitq;
157
158 /** Data for asynchronous requests */
159 union {
160 struct fuse_forget_in forget_in;
161 struct fuse_release_in release_in;
162 struct fuse_init_in_out init_in_out;
163 } misc;
164
165 /** page vector */
166 struct page *pages[FUSE_MAX_PAGES_PER_REQ];
167
168 /** number of pages in vector */
169 unsigned num_pages;
170
171 /** offset of data on first page */
172 unsigned page_offset;
173
174 /** Inode used in the request */
175 struct inode *inode;
176
177 /** Second inode used in the request (or NULL) */
178 struct inode *inode2;
179
180 /** File used in the request (or NULL) */
181 struct file *file;
182};
183
184/**
185 * A Fuse connection.
186 *
187 * This structure is created, when the filesystem is mounted, and is
188 * destroyed, when the client device is closed and the filesystem is
189 * unmounted.
190 */
191struct fuse_conn {
192 /** Reference count */
193 int count;
194
195 /** The user id for this mount */
196 uid_t user_id;
197
198 /** The group id for this mount */
199 gid_t group_id;
200
201 /** The fuse mount flags for this mount */
202 unsigned flags;
203
204 /** Maximum read size */
205 unsigned max_read;
206
207 /** Maximum write size */
208 unsigned max_write;
209
210 /** Readers of the connection are waiting on this */
211 wait_queue_head_t waitq;
212
213 /** The list of pending requests */
214 struct list_head pending;
215
216 /** The list of requests being processed */
217 struct list_head processing;
218
219 /** Requests put in the background (RELEASE or any other
220 interrupted request) */
221 struct list_head background;
222
223 /** Controls the maximum number of outstanding requests */
224 struct semaphore outstanding_sem;
225
226 /** This counts the number of outstanding requests if
227 outstanding_sem would go negative */
228 unsigned outstanding_debt;
229
230 /** RW semaphore for exclusion with fuse_put_super() */
231 struct rw_semaphore sbput_sem;
232
233 /** The list of unused requests */
234 struct list_head unused_list;
235
236 /** The next unique request id */
237 u64 reqctr;
238
239 /** Mount is active */
240 unsigned mounted : 1;
241
242 /** Connection established */
243 unsigned connected : 1;
244
245 /** Connection failed (version mismatch) */
246 unsigned conn_error : 1;
247
248 /** Is fsync not implemented by fs? */
249 unsigned no_fsync : 1;
250
251 /** Is fsyncdir not implemented by fs? */
252 unsigned no_fsyncdir : 1;
253
254 /** Is flush not implemented by fs? */
255 unsigned no_flush : 1;
256
257 /** Is setxattr not implemented by fs? */
258 unsigned no_setxattr : 1;
259
260 /** Is getxattr not implemented by fs? */
261 unsigned no_getxattr : 1;
262
263 /** Is listxattr not implemented by fs? */
264 unsigned no_listxattr : 1;
265
266 /** Is removexattr not implemented by fs? */
267 unsigned no_removexattr : 1;
268
269 /** Backing dev info */
270 struct backing_dev_info bdi;
271};
272
273static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
274{
275 return (struct fuse_conn **) &sb->s_fs_info;
276}
277
278static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
279{
280 return *get_fuse_conn_super_p(sb);
281}
282
283static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
284{
285 return get_fuse_conn_super(inode->i_sb);
286}
287
288static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
289{
290 return container_of(inode, struct fuse_inode, inode);
291}
292
293static inline u64 get_node_id(struct inode *inode)
294{
295 return get_fuse_inode(inode)->nodeid;
296}
297
298/** Device operations */
299extern struct file_operations fuse_dev_operations;
300
301/**
302 * This is the single global spinlock which protects FUSE's structures
303 *
304 * The following data is protected by this lock:
305 *
306 * - the private_data field of the device file
307 * - the s_fs_info field of the super block
308 * - unused_list, pending, processing lists in fuse_conn
309 * - background list in fuse_conn
310 * - the unique request ID counter reqctr in fuse_conn
311 * - the sb (super_block) field in fuse_conn
312 * - the file (device file) field in fuse_conn
313 */
314extern spinlock_t fuse_lock;
315
316/**
317 * Get a filled in inode
318 */
319struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
320 int generation, struct fuse_attr *attr);
321
322/**
323 * Send FORGET command
324 */
325void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
326 unsigned long nodeid, u64 nlookup);
327
328/**
329 * Send READ or READDIR request
330 */
331size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
332 struct inode *inode, loff_t pos, size_t count,
333 int isdir);
334
335/**
336 * Send OPEN or OPENDIR request
337 */
338int fuse_open_common(struct inode *inode, struct file *file, int isdir);
339
340/**
341 * Send RELEASE or RELEASEDIR request
342 */
343int fuse_release_common(struct inode *inode, struct file *file, int isdir);
344
345/**
346 * Send FSYNC or FSYNCDIR request
347 */
348int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
349 int isdir);
350
351/**
352 * Initialise file operations on a regular file
353 */
354void fuse_init_file_inode(struct inode *inode);
355
356/**
357 * Initialise inode operations on regular files and special files
358 */
359void fuse_init_common(struct inode *inode);
360
361/**
362 * Initialise inode and file operations on a directory
363 */
364void fuse_init_dir(struct inode *inode);
365
366/**
367 * Initialise inode operations on a symlink
368 */
369void fuse_init_symlink(struct inode *inode);
370
371/**
372 * Change attributes of an inode
373 */
374void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
375
376/**
377 * Check if the connection can be released, and if yes, then free the
378 * connection structure
379 */
380void fuse_release_conn(struct fuse_conn *fc);
381
382/**
383 * Initialize the client device
384 */
385int fuse_dev_init(void);
386
387/**
388 * Cleanup the client device
389 */
390void fuse_dev_cleanup(void);
391
392/**
393 * Allocate a request
394 */
395struct fuse_req *fuse_request_alloc(void);
396
397/**
398 * Free a request
399 */
400void fuse_request_free(struct fuse_req *req);
401
402/**
403 * Reinitialize a request, the preallocated flag is left unmodified
404 */
405void fuse_reset_request(struct fuse_req *req);
406
407/**
408 * Reserve a preallocated request
409 */
410struct fuse_req *fuse_get_request(struct fuse_conn *fc);
411
412/**
413 * Decrement reference count of a request. If count goes to zero put
414 * on unused list (preallocated) or free reqest (not preallocated).
415 */
416void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
417
418/**
419 * Send a request (synchronous)
420 */
421void request_send(struct fuse_conn *fc, struct fuse_req *req);
422
423/**
424 * Send a request with no reply
425 */
426void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
427
428/**
429 * Send a request in the background
430 */
431void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
432
433/**
434 * Release inodes and file assiciated with background request
435 */
436void fuse_release_background(struct fuse_req *req);
437
438/**
439 * Get the attributes of a file
440 */
441int fuse_do_getattr(struct inode *inode);
442
443/**
444 * Invalidate inode attributes
445 */
446void fuse_invalidate_attr(struct inode *inode);
447
448/**
449 * Send the INIT message
450 */
451void fuse_send_init(struct fuse_conn *fc);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
new file mode 100644
index 000000000000..e69a546844d0
--- /dev/null
+++ b/fs/fuse/inode.c
@@ -0,0 +1,591 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/slab.h>
13#include <linux/file.h>
14#include <linux/mount.h>
15#include <linux/seq_file.h>
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/parser.h>
19#include <linux/statfs.h>
20
21MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
22MODULE_DESCRIPTION("Filesystem in Userspace");
23MODULE_LICENSE("GPL");
24
25spinlock_t fuse_lock;
26static kmem_cache_t *fuse_inode_cachep;
27
28#define FUSE_SUPER_MAGIC 0x65735546
29
30struct fuse_mount_data {
31 int fd;
32 unsigned rootmode;
33 unsigned user_id;
34 unsigned group_id;
35 unsigned fd_present : 1;
36 unsigned rootmode_present : 1;
37 unsigned user_id_present : 1;
38 unsigned group_id_present : 1;
39 unsigned flags;
40 unsigned max_read;
41};
42
43static struct inode *fuse_alloc_inode(struct super_block *sb)
44{
45 struct inode *inode;
46 struct fuse_inode *fi;
47
48 inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL);
49 if (!inode)
50 return NULL;
51
52 fi = get_fuse_inode(inode);
53 fi->i_time = jiffies - 1;
54 fi->nodeid = 0;
55 fi->nlookup = 0;
56 fi->forget_req = fuse_request_alloc();
57 if (!fi->forget_req) {
58 kmem_cache_free(fuse_inode_cachep, inode);
59 return NULL;
60 }
61
62 return inode;
63}
64
65static void fuse_destroy_inode(struct inode *inode)
66{
67 struct fuse_inode *fi = get_fuse_inode(inode);
68 if (fi->forget_req)
69 fuse_request_free(fi->forget_req);
70 kmem_cache_free(fuse_inode_cachep, inode);
71}
72
73static void fuse_read_inode(struct inode *inode)
74{
75 /* No op */
76}
77
78void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
79 unsigned long nodeid, u64 nlookup)
80{
81 struct fuse_forget_in *inarg = &req->misc.forget_in;
82 inarg->nlookup = nlookup;
83 req->in.h.opcode = FUSE_FORGET;
84 req->in.h.nodeid = nodeid;
85 req->in.numargs = 1;
86 req->in.args[0].size = sizeof(struct fuse_forget_in);
87 req->in.args[0].value = inarg;
88 request_send_noreply(fc, req);
89}
90
91static void fuse_clear_inode(struct inode *inode)
92{
93 if (inode->i_sb->s_flags & MS_ACTIVE) {
94 struct fuse_conn *fc = get_fuse_conn(inode);
95 struct fuse_inode *fi = get_fuse_inode(inode);
96 fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
97 fi->forget_req = NULL;
98 }
99}
100
101void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
102{
103 if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
104 invalidate_inode_pages(inode->i_mapping);
105
106 inode->i_ino = attr->ino;
107 inode->i_mode = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
108 inode->i_nlink = attr->nlink;
109 inode->i_uid = attr->uid;
110 inode->i_gid = attr->gid;
111 i_size_write(inode, attr->size);
112 inode->i_blksize = PAGE_CACHE_SIZE;
113 inode->i_blocks = attr->blocks;
114 inode->i_atime.tv_sec = attr->atime;
115 inode->i_atime.tv_nsec = attr->atimensec;
116 inode->i_mtime.tv_sec = attr->mtime;
117 inode->i_mtime.tv_nsec = attr->mtimensec;
118 inode->i_ctime.tv_sec = attr->ctime;
119 inode->i_ctime.tv_nsec = attr->ctimensec;
120}
121
122static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
123{
124 inode->i_mode = attr->mode & S_IFMT;
125 i_size_write(inode, attr->size);
126 if (S_ISREG(inode->i_mode)) {
127 fuse_init_common(inode);
128 fuse_init_file_inode(inode);
129 } else if (S_ISDIR(inode->i_mode))
130 fuse_init_dir(inode);
131 else if (S_ISLNK(inode->i_mode))
132 fuse_init_symlink(inode);
133 else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
134 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
135 fuse_init_common(inode);
136 init_special_inode(inode, inode->i_mode,
137 new_decode_dev(attr->rdev));
138 } else {
139 /* Don't let user create weird files */
140 inode->i_mode = S_IFREG;
141 fuse_init_common(inode);
142 fuse_init_file_inode(inode);
143 }
144}
145
146static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
147{
148 unsigned long nodeid = *(unsigned long *) _nodeidp;
149 if (get_node_id(inode) == nodeid)
150 return 1;
151 else
152 return 0;
153}
154
155static int fuse_inode_set(struct inode *inode, void *_nodeidp)
156{
157 unsigned long nodeid = *(unsigned long *) _nodeidp;
158 get_fuse_inode(inode)->nodeid = nodeid;
159 return 0;
160}
161
162struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
163 int generation, struct fuse_attr *attr)
164{
165 struct inode *inode;
166 struct fuse_inode *fi;
167 struct fuse_conn *fc = get_fuse_conn_super(sb);
168 int retried = 0;
169
170 retry:
171 inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
172 if (!inode)
173 return NULL;
174
175 if ((inode->i_state & I_NEW)) {
176 inode->i_flags |= S_NOATIME|S_NOCMTIME;
177 inode->i_generation = generation;
178 inode->i_data.backing_dev_info = &fc->bdi;
179 fuse_init_inode(inode, attr);
180 unlock_new_inode(inode);
181 } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
182 BUG_ON(retried);
183 /* Inode has changed type, any I/O on the old should fail */
184 make_bad_inode(inode);
185 iput(inode);
186 retried = 1;
187 goto retry;
188 }
189
190 fi = get_fuse_inode(inode);
191 fi->nlookup ++;
192 fuse_change_attributes(inode, attr);
193 return inode;
194}
195
196static void fuse_put_super(struct super_block *sb)
197{
198 struct fuse_conn *fc = get_fuse_conn_super(sb);
199
200 down_write(&fc->sbput_sem);
201 while (!list_empty(&fc->background))
202 fuse_release_background(list_entry(fc->background.next,
203 struct fuse_req, bg_entry));
204
205 spin_lock(&fuse_lock);
206 fc->mounted = 0;
207 fc->user_id = 0;
208 fc->group_id = 0;
209 fc->flags = 0;
210 /* Flush all readers on this fs */
211 wake_up_all(&fc->waitq);
212 up_write(&fc->sbput_sem);
213 fuse_release_conn(fc);
214 spin_unlock(&fuse_lock);
215}
216
217static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
218{
219 stbuf->f_type = FUSE_SUPER_MAGIC;
220 stbuf->f_bsize = attr->bsize;
221 stbuf->f_blocks = attr->blocks;
222 stbuf->f_bfree = attr->bfree;
223 stbuf->f_bavail = attr->bavail;
224 stbuf->f_files = attr->files;
225 stbuf->f_ffree = attr->ffree;
226 stbuf->f_namelen = attr->namelen;
227 /* fsid is left zero */
228}
229
230static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
231{
232 struct fuse_conn *fc = get_fuse_conn_super(sb);
233 struct fuse_req *req;
234 struct fuse_statfs_out outarg;
235 int err;
236
237 req = fuse_get_request(fc);
238 if (!req)
239 return -EINTR;
240
241 req->in.numargs = 0;
242 req->in.h.opcode = FUSE_STATFS;
243 req->out.numargs = 1;
244 req->out.args[0].size = sizeof(outarg);
245 req->out.args[0].value = &outarg;
246 request_send(fc, req);
247 err = req->out.h.error;
248 if (!err)
249 convert_fuse_statfs(buf, &outarg.st);
250 fuse_put_request(fc, req);
251 return err;
252}
253
254enum {
255 OPT_FD,
256 OPT_ROOTMODE,
257 OPT_USER_ID,
258 OPT_GROUP_ID,
259 OPT_DEFAULT_PERMISSIONS,
260 OPT_ALLOW_OTHER,
261 OPT_MAX_READ,
262 OPT_ERR
263};
264
265static match_table_t tokens = {
266 {OPT_FD, "fd=%u"},
267 {OPT_ROOTMODE, "rootmode=%o"},
268 {OPT_USER_ID, "user_id=%u"},
269 {OPT_GROUP_ID, "group_id=%u"},
270 {OPT_DEFAULT_PERMISSIONS, "default_permissions"},
271 {OPT_ALLOW_OTHER, "allow_other"},
272 {OPT_MAX_READ, "max_read=%u"},
273 {OPT_ERR, NULL}
274};
275
276static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
277{
278 char *p;
279 memset(d, 0, sizeof(struct fuse_mount_data));
280 d->max_read = ~0;
281
282 while ((p = strsep(&opt, ",")) != NULL) {
283 int token;
284 int value;
285 substring_t args[MAX_OPT_ARGS];
286 if (!*p)
287 continue;
288
289 token = match_token(p, tokens, args);
290 switch (token) {
291 case OPT_FD:
292 if (match_int(&args[0], &value))
293 return 0;
294 d->fd = value;
295 d->fd_present = 1;
296 break;
297
298 case OPT_ROOTMODE:
299 if (match_octal(&args[0], &value))
300 return 0;
301 d->rootmode = value;
302 d->rootmode_present = 1;
303 break;
304
305 case OPT_USER_ID:
306 if (match_int(&args[0], &value))
307 return 0;
308 d->user_id = value;
309 d->user_id_present = 1;
310 break;
311
312 case OPT_GROUP_ID:
313 if (match_int(&args[0], &value))
314 return 0;
315 d->group_id = value;
316 d->group_id_present = 1;
317 break;
318
319 case OPT_DEFAULT_PERMISSIONS:
320 d->flags |= FUSE_DEFAULT_PERMISSIONS;
321 break;
322
323 case OPT_ALLOW_OTHER:
324 d->flags |= FUSE_ALLOW_OTHER;
325 break;
326
327 case OPT_MAX_READ:
328 if (match_int(&args[0], &value))
329 return 0;
330 d->max_read = value;
331 break;
332
333 default:
334 return 0;
335 }
336 }
337
338 if (!d->fd_present || !d->rootmode_present ||
339 !d->user_id_present || !d->group_id_present)
340 return 0;
341
342 return 1;
343}
344
345static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
346{
347 struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb);
348
349 seq_printf(m, ",user_id=%u", fc->user_id);
350 seq_printf(m, ",group_id=%u", fc->group_id);
351 if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
352 seq_puts(m, ",default_permissions");
353 if (fc->flags & FUSE_ALLOW_OTHER)
354 seq_puts(m, ",allow_other");
355 if (fc->max_read != ~0)
356 seq_printf(m, ",max_read=%u", fc->max_read);
357 return 0;
358}
359
360static void free_conn(struct fuse_conn *fc)
361{
362 while (!list_empty(&fc->unused_list)) {
363 struct fuse_req *req;
364 req = list_entry(fc->unused_list.next, struct fuse_req, list);
365 list_del(&req->list);
366 fuse_request_free(req);
367 }
368 kfree(fc);
369}
370
371/* Must be called with the fuse lock held */
372void fuse_release_conn(struct fuse_conn *fc)
373{
374 fc->count--;
375 if (!fc->count)
376 free_conn(fc);
377}
378
379static struct fuse_conn *new_conn(void)
380{
381 struct fuse_conn *fc;
382
383 fc = kmalloc(sizeof(*fc), GFP_KERNEL);
384 if (fc != NULL) {
385 int i;
386 memset(fc, 0, sizeof(*fc));
387 init_waitqueue_head(&fc->waitq);
388 INIT_LIST_HEAD(&fc->pending);
389 INIT_LIST_HEAD(&fc->processing);
390 INIT_LIST_HEAD(&fc->unused_list);
391 INIT_LIST_HEAD(&fc->background);
392 sema_init(&fc->outstanding_sem, 0);
393 init_rwsem(&fc->sbput_sem);
394 for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
395 struct fuse_req *req = fuse_request_alloc();
396 if (!req) {
397 free_conn(fc);
398 return NULL;
399 }
400 list_add(&req->list, &fc->unused_list);
401 }
402 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
403 fc->bdi.unplug_io_fn = default_unplug_io_fn;
404 fc->reqctr = 0;
405 }
406 return fc;
407}
408
409static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
410{
411 struct fuse_conn *fc;
412
413 if (file->f_op != &fuse_dev_operations)
414 return ERR_PTR(-EINVAL);
415 fc = new_conn();
416 if (fc == NULL)
417 return ERR_PTR(-ENOMEM);
418 spin_lock(&fuse_lock);
419 if (file->private_data) {
420 free_conn(fc);
421 fc = ERR_PTR(-EINVAL);
422 } else {
423 file->private_data = fc;
424 *get_fuse_conn_super_p(sb) = fc;
425 fc->mounted = 1;
426 fc->connected = 1;
427 fc->count = 2;
428 }
429 spin_unlock(&fuse_lock);
430 return fc;
431}
432
433static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
434{
435 struct fuse_attr attr;
436 memset(&attr, 0, sizeof(attr));
437
438 attr.mode = mode;
439 attr.ino = FUSE_ROOT_ID;
440 return fuse_iget(sb, 1, 0, &attr);
441}
442
443static struct super_operations fuse_super_operations = {
444 .alloc_inode = fuse_alloc_inode,
445 .destroy_inode = fuse_destroy_inode,
446 .read_inode = fuse_read_inode,
447 .clear_inode = fuse_clear_inode,
448 .put_super = fuse_put_super,
449 .statfs = fuse_statfs,
450 .show_options = fuse_show_options,
451};
452
453static int fuse_fill_super(struct super_block *sb, void *data, int silent)
454{
455 struct fuse_conn *fc;
456 struct inode *root;
457 struct fuse_mount_data d;
458 struct file *file;
459 int err;
460
461 if (!parse_fuse_opt((char *) data, &d))
462 return -EINVAL;
463
464 sb->s_blocksize = PAGE_CACHE_SIZE;
465 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
466 sb->s_magic = FUSE_SUPER_MAGIC;
467 sb->s_op = &fuse_super_operations;
468 sb->s_maxbytes = MAX_LFS_FILESIZE;
469
470 file = fget(d.fd);
471 if (!file)
472 return -EINVAL;
473
474 fc = get_conn(file, sb);
475 fput(file);
476 if (IS_ERR(fc))
477 return PTR_ERR(fc);
478
479 fc->flags = d.flags;
480 fc->user_id = d.user_id;
481 fc->group_id = d.group_id;
482 fc->max_read = d.max_read;
483 if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
484 fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
485 fc->max_write = FUSE_MAX_IN / 2;
486
487 err = -ENOMEM;
488 root = get_root_inode(sb, d.rootmode);
489 if (root == NULL)
490 goto err;
491
492 sb->s_root = d_alloc_root(root);
493 if (!sb->s_root) {
494 iput(root);
495 goto err;
496 }
497 fuse_send_init(fc);
498 return 0;
499
500 err:
501 spin_lock(&fuse_lock);
502 fuse_release_conn(fc);
503 spin_unlock(&fuse_lock);
504 return err;
505}
506
507static struct super_block *fuse_get_sb(struct file_system_type *fs_type,
508 int flags, const char *dev_name,
509 void *raw_data)
510{
511 return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);
512}
513
514static struct file_system_type fuse_fs_type = {
515 .owner = THIS_MODULE,
516 .name = "fuse",
517 .get_sb = fuse_get_sb,
518 .kill_sb = kill_anon_super,
519};
520
521static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep,
522 unsigned long flags)
523{
524 struct inode * inode = foo;
525
526 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
527 SLAB_CTOR_CONSTRUCTOR)
528 inode_init_once(inode);
529}
530
531static int __init fuse_fs_init(void)
532{
533 int err;
534
535 err = register_filesystem(&fuse_fs_type);
536 if (err)
537 printk("fuse: failed to register filesystem\n");
538 else {
539 fuse_inode_cachep = kmem_cache_create("fuse_inode",
540 sizeof(struct fuse_inode),
541 0, SLAB_HWCACHE_ALIGN,
542 fuse_inode_init_once, NULL);
543 if (!fuse_inode_cachep) {
544 unregister_filesystem(&fuse_fs_type);
545 err = -ENOMEM;
546 }
547 }
548
549 return err;
550}
551
552static void fuse_fs_cleanup(void)
553{
554 unregister_filesystem(&fuse_fs_type);
555 kmem_cache_destroy(fuse_inode_cachep);
556}
557
558static int __init fuse_init(void)
559{
560 int res;
561
562 printk("fuse init (API version %i.%i)\n",
563 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
564
565 spin_lock_init(&fuse_lock);
566 res = fuse_fs_init();
567 if (res)
568 goto err;
569
570 res = fuse_dev_init();
571 if (res)
572 goto err_fs_cleanup;
573
574 return 0;
575
576 err_fs_cleanup:
577 fuse_fs_cleanup();
578 err:
579 return res;
580}
581
582static void __exit fuse_exit(void)
583{
584 printk(KERN_DEBUG "fuse exit\n");
585
586 fuse_fs_cleanup();
587 fuse_dev_cleanup();
588}
589
590module_init(fuse_init);
591module_exit(fuse_exit);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index b2d18200a003..59c5062cd63f 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -284,6 +284,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
284 284
285static void hostfs_delete_inode(struct inode *inode) 285static void hostfs_delete_inode(struct inode *inode)
286{ 286{
287 truncate_inode_pages(&inode->i_data, 0);
287 if(HOSTFS_I(inode)->fd != -1) { 288 if(HOSTFS_I(inode)->fd != -1) {
288 close_file(&HOSTFS_I(inode)->fd); 289 close_file(&HOSTFS_I(inode)->fd);
289 HOSTFS_I(inode)->fd = -1; 290 HOSTFS_I(inode)->fd = -1;
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index 38b1741fa539..e3d17e9ea6c1 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -284,6 +284,7 @@ void hpfs_write_if_changed(struct inode *inode)
284 284
285void hpfs_delete_inode(struct inode *inode) 285void hpfs_delete_inode(struct inode *inode)
286{ 286{
287 truncate_inode_pages(&inode->i_data, 0);
287 lock_kernel(); 288 lock_kernel();
288 hpfs_remove_fnode(inode->i_sb, inode->i_ino); 289 hpfs_remove_fnode(inode->i_sb, inode->i_ino);
289 unlock_kernel(); 290 unlock_kernel();
diff --git a/fs/inode.c b/fs/inode.c
index 71df1b1e8f75..f80a79ff156b 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1034,19 +1034,21 @@ void generic_delete_inode(struct inode *inode)
1034 inodes_stat.nr_inodes--; 1034 inodes_stat.nr_inodes--;
1035 spin_unlock(&inode_lock); 1035 spin_unlock(&inode_lock);
1036 1036
1037 if (inode->i_data.nrpages)
1038 truncate_inode_pages(&inode->i_data, 0);
1039
1040 security_inode_delete(inode); 1037 security_inode_delete(inode);
1041 1038
1042 if (op->delete_inode) { 1039 if (op->delete_inode) {
1043 void (*delete)(struct inode *) = op->delete_inode; 1040 void (*delete)(struct inode *) = op->delete_inode;
1044 if (!is_bad_inode(inode)) 1041 if (!is_bad_inode(inode))
1045 DQUOT_INIT(inode); 1042 DQUOT_INIT(inode);
1046 /* s_op->delete_inode internally recalls clear_inode() */ 1043 /* Filesystems implementing their own
1044 * s_op->delete_inode are required to call
1045 * truncate_inode_pages and clear_inode()
1046 * internally */
1047 delete(inode); 1047 delete(inode);
1048 } else 1048 } else {
1049 truncate_inode_pages(&inode->i_data, 0);
1049 clear_inode(inode); 1050 clear_inode(inode);
1051 }
1050 spin_lock(&inode_lock); 1052 spin_lock(&inode_lock);
1051 hlist_del_init(&inode->i_hash); 1053 hlist_del_init(&inode->i_hash);
1052 spin_unlock(&inode_lock); 1054 spin_unlock(&inode_lock);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 777b90057b89..3dcc6d2162cb 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1744,6 +1744,7 @@ jffs_delete_inode(struct inode *inode)
1744 D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n", 1744 D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
1745 inode->i_ino)); 1745 inode->i_ino));
1746 1746
1747 truncate_inode_pages(&inode->i_data, 0);
1747 lock_kernel(); 1748 lock_kernel();
1748 inode->i_size = 0; 1749 inode->i_size = 0;
1749 inode->i_blocks = 0; 1750 inode->i_blocks = 0;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 767c7ecb429e..cff352f4ec18 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -132,6 +132,8 @@ void jfs_delete_inode(struct inode *inode)
132 (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I))) 132 (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I)))
133 return; 133 return;
134 134
135 truncate_inode_pages(&inode->i_data, 0);
136
135 if (test_cflag(COMMIT_Freewmap, inode)) 137 if (test_cflag(COMMIT_Freewmap, inode))
136 jfs_free_zero_link(inode); 138 jfs_free_zero_link(inode);
137 139
diff --git a/fs/locks.c b/fs/locks.c
index 11956b6179ff..c2c09b4798d6 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2198,21 +2198,23 @@ void steal_locks(fl_owner_t from)
2198{ 2198{
2199 struct files_struct *files = current->files; 2199 struct files_struct *files = current->files;
2200 int i, j; 2200 int i, j;
2201 struct fdtable *fdt;
2201 2202
2202 if (from == files) 2203 if (from == files)
2203 return; 2204 return;
2204 2205
2205 lock_kernel(); 2206 lock_kernel();
2206 j = 0; 2207 j = 0;
2208 fdt = files_fdtable(files);
2207 for (;;) { 2209 for (;;) {
2208 unsigned long set; 2210 unsigned long set;
2209 i = j * __NFDBITS; 2211 i = j * __NFDBITS;
2210 if (i >= files->max_fdset || i >= files->max_fds) 2212 if (i >= fdt->max_fdset || i >= fdt->max_fds)
2211 break; 2213 break;
2212 set = files->open_fds->fds_bits[j++]; 2214 set = fdt->open_fds->fds_bits[j++];
2213 while (set) { 2215 while (set) {
2214 if (set & 1) { 2216 if (set & 1) {
2215 struct file *file = files->fd[i]; 2217 struct file *file = fdt->fd[i];
2216 if (file) 2218 if (file)
2217 __steal_locks(file, from); 2219 __steal_locks(file, from);
2218 } 2220 }
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 3f18c21198d7..790cc0d0e970 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -24,6 +24,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data);
24 24
25static void minix_delete_inode(struct inode *inode) 25static void minix_delete_inode(struct inode *inode)
26{ 26{
27 truncate_inode_pages(&inode->i_data, 0);
27 inode->i_size = 0; 28 inode->i_size = 0;
28 minix_truncate(inode); 29 minix_truncate(inode);
29 minix_free_inode(inode); 30 minix_free_inode(inode);
diff --git a/fs/namei.c b/fs/namei.c
index 145e852c4bd0..21d85f1ac839 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1316,10 +1316,8 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1316 return error; 1316 return error;
1317 DQUOT_INIT(dir); 1317 DQUOT_INIT(dir);
1318 error = dir->i_op->create(dir, dentry, mode, nd); 1318 error = dir->i_op->create(dir, dentry, mode, nd);
1319 if (!error) { 1319 if (!error)
1320 fsnotify_create(dir, dentry->d_name.name); 1320 fsnotify_create(dir, dentry->d_name.name);
1321 security_inode_post_create(dir, dentry, mode);
1322 }
1323 return error; 1321 return error;
1324} 1322}
1325 1323
@@ -1635,10 +1633,8 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1635 1633
1636 DQUOT_INIT(dir); 1634 DQUOT_INIT(dir);
1637 error = dir->i_op->mknod(dir, dentry, mode, dev); 1635 error = dir->i_op->mknod(dir, dentry, mode, dev);
1638 if (!error) { 1636 if (!error)
1639 fsnotify_create(dir, dentry->d_name.name); 1637 fsnotify_create(dir, dentry->d_name.name);
1640 security_inode_post_mknod(dir, dentry, mode, dev);
1641 }
1642 return error; 1638 return error;
1643} 1639}
1644 1640
@@ -1708,10 +1704,8 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1708 1704
1709 DQUOT_INIT(dir); 1705 DQUOT_INIT(dir);
1710 error = dir->i_op->mkdir(dir, dentry, mode); 1706 error = dir->i_op->mkdir(dir, dentry, mode);
1711 if (!error) { 1707 if (!error)
1712 fsnotify_mkdir(dir, dentry->d_name.name); 1708 fsnotify_mkdir(dir, dentry->d_name.name);
1713 security_inode_post_mkdir(dir,dentry, mode);
1714 }
1715 return error; 1709 return error;
1716} 1710}
1717 1711
@@ -1947,10 +1941,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
1947 1941
1948 DQUOT_INIT(dir); 1942 DQUOT_INIT(dir);
1949 error = dir->i_op->symlink(dir, dentry, oldname); 1943 error = dir->i_op->symlink(dir, dentry, oldname);
1950 if (!error) { 1944 if (!error)
1951 fsnotify_create(dir, dentry->d_name.name); 1945 fsnotify_create(dir, dentry->d_name.name);
1952 security_inode_post_symlink(dir, dentry, oldname);
1953 }
1954 return error; 1946 return error;
1955} 1947}
1956 1948
@@ -2020,10 +2012,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2020 DQUOT_INIT(dir); 2012 DQUOT_INIT(dir);
2021 error = dir->i_op->link(old_dentry, dir, new_dentry); 2013 error = dir->i_op->link(old_dentry, dir, new_dentry);
2022 up(&old_dentry->d_inode->i_sem); 2014 up(&old_dentry->d_inode->i_sem);
2023 if (!error) { 2015 if (!error)
2024 fsnotify_create(dir, new_dentry->d_name.name); 2016 fsnotify_create(dir, new_dentry->d_name.name);
2025 security_inode_post_link(old_dentry, dir, new_dentry);
2026 }
2027 return error; 2017 return error;
2028} 2018}
2029 2019
@@ -2142,11 +2132,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2142 d_rehash(new_dentry); 2132 d_rehash(new_dentry);
2143 dput(new_dentry); 2133 dput(new_dentry);
2144 } 2134 }
2145 if (!error) { 2135 if (!error)
2146 d_move(old_dentry,new_dentry); 2136 d_move(old_dentry,new_dentry);
2147 security_inode_post_rename(old_dir, old_dentry,
2148 new_dir, new_dentry);
2149 }
2150 return error; 2137 return error;
2151} 2138}
2152 2139
@@ -2172,7 +2159,6 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
2172 /* The following d_move() should become unconditional */ 2159 /* The following d_move() should become unconditional */
2173 if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) 2160 if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
2174 d_move(old_dentry, new_dentry); 2161 d_move(old_dentry, new_dentry);
2175 security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry);
2176 } 2162 }
2177 if (target) 2163 if (target)
2178 up(&target->i_sem); 2164 up(&target->i_sem);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 44795d2f4b30..8c8839203cd5 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -286,6 +286,8 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
286static void 286static void
287ncp_delete_inode(struct inode *inode) 287ncp_delete_inode(struct inode *inode)
288{ 288{
289 truncate_inode_pages(&inode->i_data, 0);
290
289 if (S_ISDIR(inode->i_mode)) { 291 if (S_ISDIR(inode->i_mode)) {
290 DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino); 292 DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino);
291 } 293 }
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 541b418327c8..6922469d6fc5 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -146,6 +146,8 @@ nfs_delete_inode(struct inode * inode)
146{ 146{
147 dprintk("NFS: delete_inode(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); 147 dprintk("NFS: delete_inode(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
148 148
149 truncate_inode_pages(&inode->i_data, 0);
150
149 nfs_wb_all(inode); 151 nfs_wb_all(inode);
150 /* 152 /*
151 * The following should never happen... 153 * The following should never happen...
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 9eecc9939dfe..e4fd6134244d 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,6 +22,76 @@ ToDo/Notes:
22 - Enable the code for setting the NT4 compatibility flag when we start 22 - Enable the code for setting the NT4 compatibility flag when we start
23 making NTFS 1.2 specific modifications. 23 making NTFS 1.2 specific modifications.
24 24
252.1.24 - Lots of bug fixes and support more clean journal states.
26
27 - Support journals ($LogFile) which have been modified by chkdsk. This
28 means users can boot into Windows after we marked the volume dirty.
29 The Windows boot will run chkdsk and then reboot. The user can then
30 immediately boot into Linux rather than having to do a full Windows
31 boot first before rebooting into Linux and we will recognize such a
32 journal and empty it as it is clean by definition.
33 - Support journals ($LogFile) with only one restart page as well as
34 journals with two different restart pages. We sanity check both and
35 either use the only sane one or the more recent one of the two in the
36 case that both are valid.
37 - Modify fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc() based
38 allocations with __GFP_HIGHMEM, analogous to how the vmalloc() based
39 allocations are done.
40 - Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
41 ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
42 hence cannot fail.
43 - Use ntfs_malloc_nofs_nofail() in the two critical regions in
44 fs/ntfs/runlist.c::ntfs_runlists_merge(). This means we no longer
45 need to panic() if the allocation fails as it now cannot fail.
46 - Fix two nasty runlist merging bugs that had gone unnoticed so far.
47 Thanks to Stefano Picerno for the bug report.
48 - Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
49 - Fix handling of valid but empty mapping pairs array in
50 fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
51 - Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
52 messages and include the inode number. Thanks to Yura Pakhuchiy for
53 pointing this out.
54 - Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
55 length is zero.
56 - Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
57 specified hole into a runlist.
58 - Fix a bug in fs/ntfs/index.c::ntfs_index_lookup(). When the returned
59 index entry is in the index root, we forgot to set the @ir pointer in
60 the index context. Thanks to Yura Pakhuchiy for finding this bug.
61 - Remove bogus setting of PageError in ntfs_read_compressed_block().
62 - Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
63 - Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
64 access to the allocated size in the ntfs inode with the size lock.
65 - Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
66 return LCN_ENOENT when there is no runlist and the allocated size is
67 zero.
68 - Fix load_attribute_list() to handle the case of a NULL runlist.
69 - Fix handling of sparse attributes in ntfs_attr_make_non_resident().
70 - Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
71 to ensure that these functions are never called for compressed or
72 encrypted attributes.
73 - Fix cluster (de)allocators to work when the runlist is NULL and more
74 importantly to take a locked runlist rather than them locking it
75 which leads to lock reversal.
76 - Truncate {a,c,m}time to the ntfs supported time granularity when
77 updating the times in the inode in ntfs_setattr().
78 - Fixup handling of sparse, compressed, and encrypted attributes in
79 fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
80 fs/ntfs/aops.c::ntfs_{read,write}page().
81 - Make ntfs_write_block() not instantiate sparse blocks if they contain
82 only zeroes.
83 - Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
84 lock protection over the buffer submission for i/o which allows the
85 removal of the get_bh()/put_bh() pairs for each buffer.
86 - Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
87 where a concurrent truncate has truncated the runlist under our feet.
88 - Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
89 - In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
90 in the first buffer head instead of a driver global spin lock to
91 improve scalability.
92 - Minor fix to error handling and error message display in
93 fs/ntfs/aops.c::ntfs_prepare_nonresident_write().
94
252.1.23 - Implement extension of resident files and make writing safe as well as 952.1.23 - Implement extension of resident files and make writing safe as well as
26 many bug fixes, cleanups, and enhancements... 96 many bug fixes, cleanups, and enhancements...
27 97
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index f083f27d8b69..894b2b876d35 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ 6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
7 unistr.o upcase.o 7 unistr.o upcase.o
8 8
9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23\" 9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
10 10
11ifeq ($(CONFIG_NTFS_DEBUG),y) 11ifeq ($(CONFIG_NTFS_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG 12EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 78adad7a988d..545236414d59 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -55,9 +55,8 @@
55 */ 55 */
56static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) 56static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
57{ 57{
58 static DEFINE_SPINLOCK(page_uptodate_lock);
59 unsigned long flags; 58 unsigned long flags;
60 struct buffer_head *tmp; 59 struct buffer_head *first, *tmp;
61 struct page *page; 60 struct page *page;
62 ntfs_inode *ni; 61 ntfs_inode *ni;
63 int page_uptodate = 1; 62 int page_uptodate = 1;
@@ -89,11 +88,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
89 } 88 }
90 } else { 89 } else {
91 clear_buffer_uptodate(bh); 90 clear_buffer_uptodate(bh);
91 SetPageError(page);
92 ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.", 92 ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.",
93 (unsigned long long)bh->b_blocknr); 93 (unsigned long long)bh->b_blocknr);
94 SetPageError(page);
95 } 94 }
96 spin_lock_irqsave(&page_uptodate_lock, flags); 95 first = page_buffers(page);
96 local_irq_save(flags);
97 bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
97 clear_buffer_async_read(bh); 98 clear_buffer_async_read(bh);
98 unlock_buffer(bh); 99 unlock_buffer(bh);
99 tmp = bh; 100 tmp = bh;
@@ -108,7 +109,8 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
108 } 109 }
109 tmp = tmp->b_this_page; 110 tmp = tmp->b_this_page;
110 } while (tmp != bh); 111 } while (tmp != bh);
111 spin_unlock_irqrestore(&page_uptodate_lock, flags); 112 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
113 local_irq_restore(flags);
112 /* 114 /*
113 * If none of the buffers had errors then we can set the page uptodate, 115 * If none of the buffers had errors then we can set the page uptodate,
114 * but we first have to perform the post read mst fixups, if the 116 * but we first have to perform the post read mst fixups, if the
@@ -141,7 +143,8 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
141 unlock_page(page); 143 unlock_page(page);
142 return; 144 return;
143still_busy: 145still_busy:
144 spin_unlock_irqrestore(&page_uptodate_lock, flags); 146 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
147 local_irq_restore(flags);
145 return; 148 return;
146} 149}
147 150
@@ -185,13 +188,15 @@ static int ntfs_read_block(struct page *page)
185 blocksize_bits = VFS_I(ni)->i_blkbits; 188 blocksize_bits = VFS_I(ni)->i_blkbits;
186 blocksize = 1 << blocksize_bits; 189 blocksize = 1 << blocksize_bits;
187 190
188 if (!page_has_buffers(page)) 191 if (!page_has_buffers(page)) {
189 create_empty_buffers(page, blocksize, 0); 192 create_empty_buffers(page, blocksize, 0);
190 bh = head = page_buffers(page); 193 if (unlikely(!page_has_buffers(page))) {
191 if (unlikely(!bh)) { 194 unlock_page(page);
192 unlock_page(page); 195 return -ENOMEM;
193 return -ENOMEM; 196 }
194 } 197 }
198 bh = head = page_buffers(page);
199 BUG_ON(!bh);
195 200
196 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 201 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
197 read_lock_irqsave(&ni->size_lock, flags); 202 read_lock_irqsave(&ni->size_lock, flags);
@@ -204,6 +209,7 @@ static int ntfs_read_block(struct page *page)
204 nr = i = 0; 209 nr = i = 0;
205 do { 210 do {
206 u8 *kaddr; 211 u8 *kaddr;
212 int err;
207 213
208 if (unlikely(buffer_uptodate(bh))) 214 if (unlikely(buffer_uptodate(bh)))
209 continue; 215 continue;
@@ -211,6 +217,7 @@ static int ntfs_read_block(struct page *page)
211 arr[nr++] = bh; 217 arr[nr++] = bh;
212 continue; 218 continue;
213 } 219 }
220 err = 0;
214 bh->b_bdev = vol->sb->s_bdev; 221 bh->b_bdev = vol->sb->s_bdev;
215 /* Is the block within the allowed limits? */ 222 /* Is the block within the allowed limits? */
216 if (iblock < lblock) { 223 if (iblock < lblock) {
@@ -252,7 +259,6 @@ lock_retry_remap:
252 goto handle_hole; 259 goto handle_hole;
253 /* If first try and runlist unmapped, map and retry. */ 260 /* If first try and runlist unmapped, map and retry. */
254 if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { 261 if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
255 int err;
256 is_retry = TRUE; 262 is_retry = TRUE;
257 /* 263 /*
258 * Attempt to map runlist, dropping lock for 264 * Attempt to map runlist, dropping lock for
@@ -263,20 +269,30 @@ lock_retry_remap:
263 if (likely(!err)) 269 if (likely(!err))
264 goto lock_retry_remap; 270 goto lock_retry_remap;
265 rl = NULL; 271 rl = NULL;
266 lcn = err;
267 } else if (!rl) 272 } else if (!rl)
268 up_read(&ni->runlist.lock); 273 up_read(&ni->runlist.lock);
274 /*
275 * If buffer is outside the runlist, treat it as a
276 * hole. This can happen due to concurrent truncate
277 * for example.
278 */
279 if (err == -ENOENT || lcn == LCN_ENOENT) {
280 err = 0;
281 goto handle_hole;
282 }
269 /* Hard error, zero out region. */ 283 /* Hard error, zero out region. */
284 if (!err)
285 err = -EIO;
270 bh->b_blocknr = -1; 286 bh->b_blocknr = -1;
271 SetPageError(page); 287 SetPageError(page);
272 ntfs_error(vol->sb, "Failed to read from inode 0x%lx, " 288 ntfs_error(vol->sb, "Failed to read from inode 0x%lx, "
273 "attribute type 0x%x, vcn 0x%llx, " 289 "attribute type 0x%x, vcn 0x%llx, "
274 "offset 0x%x because its location on " 290 "offset 0x%x because its location on "
275 "disk could not be determined%s " 291 "disk could not be determined%s "
276 "(error code %lli).", ni->mft_no, 292 "(error code %i).", ni->mft_no,
277 ni->type, (unsigned long long)vcn, 293 ni->type, (unsigned long long)vcn,
278 vcn_ofs, is_retry ? " even after " 294 vcn_ofs, is_retry ? " even after "
279 "retrying" : "", (long long)lcn); 295 "retrying" : "", err);
280 } 296 }
281 /* 297 /*
282 * Either iblock was outside lblock limits or 298 * Either iblock was outside lblock limits or
@@ -289,9 +305,10 @@ handle_hole:
289handle_zblock: 305handle_zblock:
290 kaddr = kmap_atomic(page, KM_USER0); 306 kaddr = kmap_atomic(page, KM_USER0);
291 memset(kaddr + i * blocksize, 0, blocksize); 307 memset(kaddr + i * blocksize, 0, blocksize);
292 flush_dcache_page(page);
293 kunmap_atomic(kaddr, KM_USER0); 308 kunmap_atomic(kaddr, KM_USER0);
294 set_buffer_uptodate(bh); 309 flush_dcache_page(page);
310 if (likely(!err))
311 set_buffer_uptodate(bh);
295 } while (i++, iblock++, (bh = bh->b_this_page) != head); 312 } while (i++, iblock++, (bh = bh->b_this_page) != head);
296 313
297 /* Release the lock if we took it. */ 314 /* Release the lock if we took it. */
@@ -367,31 +384,38 @@ retry_readpage:
367 return 0; 384 return 0;
368 } 385 }
369 ni = NTFS_I(page->mapping->host); 386 ni = NTFS_I(page->mapping->host);
370 387 /*
388 * Only $DATA attributes can be encrypted and only unnamed $DATA
389 * attributes can be compressed. Index root can have the flags set but
390 * this means to create compressed/encrypted files, not that the
391 * attribute is compressed/encrypted.
392 */
393 if (ni->type != AT_INDEX_ROOT) {
394 /* If attribute is encrypted, deny access, just like NT4. */
395 if (NInoEncrypted(ni)) {
396 BUG_ON(ni->type != AT_DATA);
397 err = -EACCES;
398 goto err_out;
399 }
400 /* Compressed data streams are handled in compress.c. */
401 if (NInoNonResident(ni) && NInoCompressed(ni)) {
402 BUG_ON(ni->type != AT_DATA);
403 BUG_ON(ni->name_len);
404 return ntfs_read_compressed_block(page);
405 }
406 }
371 /* NInoNonResident() == NInoIndexAllocPresent() */ 407 /* NInoNonResident() == NInoIndexAllocPresent() */
372 if (NInoNonResident(ni)) { 408 if (NInoNonResident(ni)) {
373 /* 409 /* Normal, non-resident data stream. */
374 * Only unnamed $DATA attributes can be compressed or
375 * encrypted.
376 */
377 if (ni->type == AT_DATA && !ni->name_len) {
378 /* If file is encrypted, deny access, just like NT4. */
379 if (NInoEncrypted(ni)) {
380 err = -EACCES;
381 goto err_out;
382 }
383 /* Compressed data streams are handled in compress.c. */
384 if (NInoCompressed(ni))
385 return ntfs_read_compressed_block(page);
386 }
387 /* Normal data stream. */
388 return ntfs_read_block(page); 410 return ntfs_read_block(page);
389 } 411 }
390 /* 412 /*
391 * Attribute is resident, implying it is not compressed or encrypted. 413 * Attribute is resident, implying it is not compressed or encrypted.
392 * This also means the attribute is smaller than an mft record and 414 * This also means the attribute is smaller than an mft record and
393 * hence smaller than a page, so can simply zero out any pages with 415 * hence smaller than a page, so can simply zero out any pages with
394 * index above 0. 416 * index above 0. Note the attribute can actually be marked compressed
417 * but if it is resident the actual data is not compressed so we are
418 * ok to ignore the compressed flag here.
395 */ 419 */
396 if (unlikely(page->index > 0)) { 420 if (unlikely(page->index > 0)) {
397 kaddr = kmap_atomic(page, KM_USER0); 421 kaddr = kmap_atomic(page, KM_USER0);
@@ -511,19 +535,21 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
511 BUG_ON(!PageUptodate(page)); 535 BUG_ON(!PageUptodate(page));
512 create_empty_buffers(page, blocksize, 536 create_empty_buffers(page, blocksize,
513 (1 << BH_Uptodate) | (1 << BH_Dirty)); 537 (1 << BH_Uptodate) | (1 << BH_Dirty));
538 if (unlikely(!page_has_buffers(page))) {
539 ntfs_warning(vol->sb, "Error allocating page "
540 "buffers. Redirtying page so we try "
541 "again later.");
542 /*
543 * Put the page back on mapping->dirty_pages, but leave
544 * its buffers' dirty state as-is.
545 */
546 redirty_page_for_writepage(wbc, page);
547 unlock_page(page);
548 return 0;
549 }
514 } 550 }
515 bh = head = page_buffers(page); 551 bh = head = page_buffers(page);
516 if (unlikely(!bh)) { 552 BUG_ON(!bh);
517 ntfs_warning(vol->sb, "Error allocating page buffers. "
518 "Redirtying page so we try again later.");
519 /*
520 * Put the page back on mapping->dirty_pages, but leave its
521 * buffer's dirty state as-is.
522 */
523 redirty_page_for_writepage(wbc, page);
524 unlock_page(page);
525 return 0;
526 }
527 553
528 /* NOTE: Different naming scheme to ntfs_read_block()! */ 554 /* NOTE: Different naming scheme to ntfs_read_block()! */
529 555
@@ -670,6 +696,27 @@ lock_retry_remap:
670 } 696 }
671 /* It is a hole, need to instantiate it. */ 697 /* It is a hole, need to instantiate it. */
672 if (lcn == LCN_HOLE) { 698 if (lcn == LCN_HOLE) {
699 u8 *kaddr;
700 unsigned long *bpos, *bend;
701
702 /* Check if the buffer is zero. */
703 kaddr = kmap_atomic(page, KM_USER0);
704 bpos = (unsigned long *)(kaddr + bh_offset(bh));
705 bend = (unsigned long *)((u8*)bpos + blocksize);
706 do {
707 if (unlikely(*bpos))
708 break;
709 } while (likely(++bpos < bend));
710 kunmap_atomic(kaddr, KM_USER0);
711 if (bpos == bend) {
712 /*
713 * Buffer is zero and sparse, no need to write
714 * it.
715 */
716 bh->b_blocknr = -1;
717 clear_buffer_dirty(bh);
718 continue;
719 }
673 // TODO: Instantiate the hole. 720 // TODO: Instantiate the hole.
674 // clear_buffer_new(bh); 721 // clear_buffer_new(bh);
675 // unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); 722 // unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
@@ -690,20 +737,37 @@ lock_retry_remap:
690 if (likely(!err)) 737 if (likely(!err))
691 goto lock_retry_remap; 738 goto lock_retry_remap;
692 rl = NULL; 739 rl = NULL;
693 lcn = err;
694 } else if (!rl) 740 } else if (!rl)
695 up_read(&ni->runlist.lock); 741 up_read(&ni->runlist.lock);
742 /*
743 * If buffer is outside the runlist, truncate has cut it out
744 * of the runlist. Just clean and clear the buffer and set it
745 * uptodate so it can get discarded by the VM.
746 */
747 if (err == -ENOENT || lcn == LCN_ENOENT) {
748 u8 *kaddr;
749
750 bh->b_blocknr = -1;
751 clear_buffer_dirty(bh);
752 kaddr = kmap_atomic(page, KM_USER0);
753 memset(kaddr + bh_offset(bh), 0, blocksize);
754 kunmap_atomic(kaddr, KM_USER0);
755 flush_dcache_page(page);
756 set_buffer_uptodate(bh);
757 err = 0;
758 continue;
759 }
696 /* Failed to map the buffer, even after retrying. */ 760 /* Failed to map the buffer, even after retrying. */
761 if (!err)
762 err = -EIO;
697 bh->b_blocknr = -1; 763 bh->b_blocknr = -1;
698 ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " 764 ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
699 "attribute type 0x%x, vcn 0x%llx, offset 0x%x " 765 "attribute type 0x%x, vcn 0x%llx, offset 0x%x "
700 "because its location on disk could not be " 766 "because its location on disk could not be "
701 "determined%s (error code %lli).", ni->mft_no, 767 "determined%s (error code %i).", ni->mft_no,
702 ni->type, (unsigned long long)vcn, 768 ni->type, (unsigned long long)vcn,
703 vcn_ofs, is_retry ? " even after " 769 vcn_ofs, is_retry ? " even after "
704 "retrying" : "", (long long)lcn); 770 "retrying" : "", err);
705 if (!err)
706 err = -EIO;
707 break; 771 break;
708 } while (block++, (bh = bh->b_this_page) != head); 772 } while (block++, (bh = bh->b_this_page) != head);
709 773
@@ -714,7 +778,7 @@ lock_retry_remap:
714 /* For the error case, need to reset bh to the beginning. */ 778 /* For the error case, need to reset bh to the beginning. */
715 bh = head; 779 bh = head;
716 780
717 /* Just an optimization, so ->readpage() isn't called later. */ 781 /* Just an optimization, so ->readpage() is not called later. */
718 if (unlikely(!PageUptodate(page))) { 782 if (unlikely(!PageUptodate(page))) {
719 int uptodate = 1; 783 int uptodate = 1;
720 do { 784 do {
@@ -730,7 +794,6 @@ lock_retry_remap:
730 794
731 /* Setup all mapped, dirty buffers for async write i/o. */ 795 /* Setup all mapped, dirty buffers for async write i/o. */
732 do { 796 do {
733 get_bh(bh);
734 if (buffer_mapped(bh) && buffer_dirty(bh)) { 797 if (buffer_mapped(bh) && buffer_dirty(bh)) {
735 lock_buffer(bh); 798 lock_buffer(bh);
736 if (test_clear_buffer_dirty(bh)) { 799 if (test_clear_buffer_dirty(bh)) {
@@ -768,14 +831,8 @@ lock_retry_remap:
768 831
769 BUG_ON(PageWriteback(page)); 832 BUG_ON(PageWriteback(page));
770 set_page_writeback(page); /* Keeps try_to_free_buffers() away. */ 833 set_page_writeback(page); /* Keeps try_to_free_buffers() away. */
771 unlock_page(page);
772 834
773 /* 835 /* Submit the prepared buffers for i/o. */
774 * Submit the prepared buffers for i/o. Note the page is unlocked,
775 * and the async write i/o completion handler can end_page_writeback()
776 * at any time after the *first* submit_bh(). So the buffers can then
777 * disappear...
778 */
779 need_end_writeback = TRUE; 836 need_end_writeback = TRUE;
780 do { 837 do {
781 struct buffer_head *next = bh->b_this_page; 838 struct buffer_head *next = bh->b_this_page;
@@ -783,9 +840,9 @@ lock_retry_remap:
783 submit_bh(WRITE, bh); 840 submit_bh(WRITE, bh);
784 need_end_writeback = FALSE; 841 need_end_writeback = FALSE;
785 } 842 }
786 put_bh(bh);
787 bh = next; 843 bh = next;
788 } while (bh != head); 844 } while (bh != head);
845 unlock_page(page);
789 846
790 /* If no i/o was started, need to end_page_writeback(). */ 847 /* If no i/o was started, need to end_page_writeback(). */
791 if (unlikely(need_end_writeback)) 848 if (unlikely(need_end_writeback))
@@ -860,7 +917,6 @@ static int ntfs_write_mst_block(struct page *page,
860 sync = (wbc->sync_mode == WB_SYNC_ALL); 917 sync = (wbc->sync_mode == WB_SYNC_ALL);
861 918
862 /* Make sure we have mapped buffers. */ 919 /* Make sure we have mapped buffers. */
863 BUG_ON(!page_has_buffers(page));
864 bh = head = page_buffers(page); 920 bh = head = page_buffers(page);
865 BUG_ON(!bh); 921 BUG_ON(!bh);
866 922
@@ -1280,38 +1336,42 @@ retry_writepage:
1280 ntfs_debug("Write outside i_size - truncated?"); 1336 ntfs_debug("Write outside i_size - truncated?");
1281 return 0; 1337 return 0;
1282 } 1338 }
1339 /*
1340 * Only $DATA attributes can be encrypted and only unnamed $DATA
1341 * attributes can be compressed. Index root can have the flags set but
1342 * this means to create compressed/encrypted files, not that the
1343 * attribute is compressed/encrypted.
1344 */
1345 if (ni->type != AT_INDEX_ROOT) {
1346 /* If file is encrypted, deny access, just like NT4. */
1347 if (NInoEncrypted(ni)) {
1348 unlock_page(page);
1349 BUG_ON(ni->type != AT_DATA);
1350 ntfs_debug("Denying write access to encrypted "
1351 "file.");
1352 return -EACCES;
1353 }
1354 /* Compressed data streams are handled in compress.c. */
1355 if (NInoNonResident(ni) && NInoCompressed(ni)) {
1356 BUG_ON(ni->type != AT_DATA);
1357 BUG_ON(ni->name_len);
1358 // TODO: Implement and replace this with
1359 // return ntfs_write_compressed_block(page);
1360 unlock_page(page);
1361 ntfs_error(vi->i_sb, "Writing to compressed files is "
1362 "not supported yet. Sorry.");
1363 return -EOPNOTSUPP;
1364 }
1365 // TODO: Implement and remove this check.
1366 if (NInoNonResident(ni) && NInoSparse(ni)) {
1367 unlock_page(page);
1368 ntfs_error(vi->i_sb, "Writing to sparse files is not "
1369 "supported yet. Sorry.");
1370 return -EOPNOTSUPP;
1371 }
1372 }
1283 /* NInoNonResident() == NInoIndexAllocPresent() */ 1373 /* NInoNonResident() == NInoIndexAllocPresent() */
1284 if (NInoNonResident(ni)) { 1374 if (NInoNonResident(ni)) {
1285 /*
1286 * Only unnamed $DATA attributes can be compressed, encrypted,
1287 * and/or sparse.
1288 */
1289 if (ni->type == AT_DATA && !ni->name_len) {
1290 /* If file is encrypted, deny access, just like NT4. */
1291 if (NInoEncrypted(ni)) {
1292 unlock_page(page);
1293 ntfs_debug("Denying write access to encrypted "
1294 "file.");
1295 return -EACCES;
1296 }
1297 /* Compressed data streams are handled in compress.c. */
1298 if (NInoCompressed(ni)) {
1299 // TODO: Implement and replace this check with
1300 // return ntfs_write_compressed_block(page);
1301 unlock_page(page);
1302 ntfs_error(vi->i_sb, "Writing to compressed "
1303 "files is not supported yet. "
1304 "Sorry.");
1305 return -EOPNOTSUPP;
1306 }
1307 // TODO: Implement and remove this check.
1308 if (NInoSparse(ni)) {
1309 unlock_page(page);
1310 ntfs_error(vi->i_sb, "Writing to sparse files "
1311 "is not supported yet. Sorry.");
1312 return -EOPNOTSUPP;
1313 }
1314 }
1315 /* We have to zero every time due to mmap-at-end-of-file. */ 1375 /* We have to zero every time due to mmap-at-end-of-file. */
1316 if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) { 1376 if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) {
1317 /* The page straddles i_size. */ 1377 /* The page straddles i_size. */
@@ -1324,14 +1384,16 @@ retry_writepage:
1324 /* Handle mst protected attributes. */ 1384 /* Handle mst protected attributes. */
1325 if (NInoMstProtected(ni)) 1385 if (NInoMstProtected(ni))
1326 return ntfs_write_mst_block(page, wbc); 1386 return ntfs_write_mst_block(page, wbc);
1327 /* Normal data stream. */ 1387 /* Normal, non-resident data stream. */
1328 return ntfs_write_block(page, wbc); 1388 return ntfs_write_block(page, wbc);
1329 } 1389 }
1330 /* 1390 /*
1331 * Attribute is resident, implying it is not compressed, encrypted, 1391 * Attribute is resident, implying it is not compressed, encrypted, or
1332 * sparse, or mst protected. This also means the attribute is smaller 1392 * mst protected. This also means the attribute is smaller than an mft
1333 * than an mft record and hence smaller than a page, so can simply 1393 * record and hence smaller than a page, so can simply return error on
1334 * return error on any pages with index above 0. 1394 * any pages with index above 0. Note the attribute can actually be
1395 * marked compressed but if it is resident the actual data is not
1396 * compressed so we are ok to ignore the compressed flag here.
1335 */ 1397 */
1336 BUG_ON(page_has_buffers(page)); 1398 BUG_ON(page_has_buffers(page));
1337 BUG_ON(!PageUptodate(page)); 1399 BUG_ON(!PageUptodate(page));
@@ -1380,30 +1442,14 @@ retry_writepage:
1380 BUG_ON(PageWriteback(page)); 1442 BUG_ON(PageWriteback(page));
1381 set_page_writeback(page); 1443 set_page_writeback(page);
1382 unlock_page(page); 1444 unlock_page(page);
1383
1384 /* 1445 /*
1385 * Here, we don't need to zero the out of bounds area everytime because 1446 * Here, we do not need to zero the out of bounds area everytime
1386 * the below memcpy() already takes care of the mmap-at-end-of-file 1447 * because the below memcpy() already takes care of the
1387 * requirements. If the file is converted to a non-resident one, then 1448 * mmap-at-end-of-file requirements. If the file is converted to a
1388 * the code path use is switched to the non-resident one where the 1449 * non-resident one, then the code path use is switched to the
1389 * zeroing happens on each ntfs_writepage() invocation. 1450 * non-resident one where the zeroing happens on each ntfs_writepage()
1390 * 1451 * invocation.
1391 * The above also applies nicely when i_size is decreased.
1392 *
1393 * When i_size is increased, the memory between the old and new i_size
1394 * _must_ be zeroed (or overwritten with new data). Otherwise we will
1395 * expose data to userspace/disk which should never have been exposed.
1396 *
1397 * FIXME: Ensure that i_size increases do the zeroing/overwriting and
1398 * if we cannot guarantee that, then enable the zeroing below. If the
1399 * zeroing below is enabled, we MUST move the unlock_page() from above
1400 * to after the kunmap_atomic(), i.e. just before the
1401 * end_page_writeback().
1402 * UPDATE: ntfs_prepare/commit_write() do the zeroing on i_size
1403 * increases for resident attributes so those are ok.
1404 * TODO: ntfs_truncate(), others?
1405 */ 1452 */
1406
1407 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); 1453 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
1408 i_size = i_size_read(vi); 1454 i_size = i_size_read(vi);
1409 if (unlikely(attr_len > i_size)) { 1455 if (unlikely(attr_len > i_size)) {
@@ -1681,27 +1727,25 @@ lock_retry_remap:
1681 if (likely(!err)) 1727 if (likely(!err))
1682 goto lock_retry_remap; 1728 goto lock_retry_remap;
1683 rl = NULL; 1729 rl = NULL;
1684 lcn = err;
1685 } else if (!rl) 1730 } else if (!rl)
1686 up_read(&ni->runlist.lock); 1731 up_read(&ni->runlist.lock);
1687 /* 1732 /*
1688 * Failed to map the buffer, even after 1733 * Failed to map the buffer, even after
1689 * retrying. 1734 * retrying.
1690 */ 1735 */
1736 if (!err)
1737 err = -EIO;
1691 bh->b_blocknr = -1; 1738 bh->b_blocknr = -1;
1692 ntfs_error(vol->sb, "Failed to write to inode " 1739 ntfs_error(vol->sb, "Failed to write to inode "
1693 "0x%lx, attribute type 0x%x, " 1740 "0x%lx, attribute type 0x%x, "
1694 "vcn 0x%llx, offset 0x%x " 1741 "vcn 0x%llx, offset 0x%x "
1695 "because its location on disk " 1742 "because its location on disk "
1696 "could not be determined%s " 1743 "could not be determined%s "
1697 "(error code %lli).", 1744 "(error code %i).",
1698 ni->mft_no, ni->type, 1745 ni->mft_no, ni->type,
1699 (unsigned long long)vcn, 1746 (unsigned long long)vcn,
1700 vcn_ofs, is_retry ? " even " 1747 vcn_ofs, is_retry ? " even "
1701 "after retrying" : "", 1748 "after retrying" : "", err);
1702 (long long)lcn);
1703 if (!err)
1704 err = -EIO;
1705 goto err_out; 1749 goto err_out;
1706 } 1750 }
1707 /* We now have a successful remap, i.e. lcn >= 0. */ 1751 /* We now have a successful remap, i.e. lcn >= 0. */
@@ -2357,6 +2401,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) {
2357 buffers_to_free = bh; 2401 buffers_to_free = bh;
2358 } 2402 }
2359 bh = head = page_buffers(page); 2403 bh = head = page_buffers(page);
2404 BUG_ON(!bh);
2360 do { 2405 do {
2361 bh_ofs = bh_offset(bh); 2406 bh_ofs = bh_offset(bh);
2362 if (bh_ofs + bh_size <= ofs) 2407 if (bh_ofs + bh_size <= ofs)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index cd0f9e740b14..3f9a4ff42ee5 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -43,6 +43,9 @@
43 * which is not an error as such. This is -ENOENT. It means that @vcn is out 43 * which is not an error as such. This is -ENOENT. It means that @vcn is out
44 * of bounds of the runlist. 44 * of bounds of the runlist.
45 * 45 *
46 * Note the runlist can be NULL after this function returns if @vcn is zero and
47 * the attribute has zero allocated size, i.e. there simply is no runlist.
48 *
46 * Locking: - The runlist must be locked for writing. 49 * Locking: - The runlist must be locked for writing.
47 * - This function modifies the runlist. 50 * - This function modifies the runlist.
48 */ 51 */
@@ -54,6 +57,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
54 ATTR_RECORD *a; 57 ATTR_RECORD *a;
55 ntfs_attr_search_ctx *ctx; 58 ntfs_attr_search_ctx *ctx;
56 runlist_element *rl; 59 runlist_element *rl;
60 unsigned long flags;
57 int err = 0; 61 int err = 0;
58 62
59 ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 63 ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
@@ -85,8 +89,11 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
85 * ntfs_mapping_pairs_decompress() fails. 89 * ntfs_mapping_pairs_decompress() fails.
86 */ 90 */
87 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1; 91 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
88 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) 92 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
93 read_lock_irqsave(&ni->size_lock, flags);
89 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits; 94 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
95 read_unlock_irqrestore(&ni->size_lock, flags);
96 }
90 if (unlikely(vcn >= end_vcn)) { 97 if (unlikely(vcn >= end_vcn)) {
91 err = -ENOENT; 98 err = -ENOENT;
92 goto err_out; 99 goto err_out;
@@ -165,6 +172,7 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
165 const BOOL write_locked) 172 const BOOL write_locked)
166{ 173{
167 LCN lcn; 174 LCN lcn;
175 unsigned long flags;
168 BOOL is_retry = FALSE; 176 BOOL is_retry = FALSE;
169 177
170 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", 178 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
@@ -173,6 +181,14 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
173 BUG_ON(!ni); 181 BUG_ON(!ni);
174 BUG_ON(!NInoNonResident(ni)); 182 BUG_ON(!NInoNonResident(ni));
175 BUG_ON(vcn < 0); 183 BUG_ON(vcn < 0);
184 if (!ni->runlist.rl) {
185 read_lock_irqsave(&ni->size_lock, flags);
186 if (!ni->allocated_size) {
187 read_unlock_irqrestore(&ni->size_lock, flags);
188 return LCN_ENOENT;
189 }
190 read_unlock_irqrestore(&ni->size_lock, flags);
191 }
176retry_remap: 192retry_remap:
177 /* Convert vcn to lcn. If that fails map the runlist and retry once. */ 193 /* Convert vcn to lcn. If that fails map the runlist and retry once. */
178 lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn); 194 lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
@@ -255,6 +271,7 @@ retry_remap:
255runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, 271runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
256 const BOOL write_locked) 272 const BOOL write_locked)
257{ 273{
274 unsigned long flags;
258 runlist_element *rl; 275 runlist_element *rl;
259 int err = 0; 276 int err = 0;
260 BOOL is_retry = FALSE; 277 BOOL is_retry = FALSE;
@@ -265,6 +282,14 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
265 BUG_ON(!ni); 282 BUG_ON(!ni);
266 BUG_ON(!NInoNonResident(ni)); 283 BUG_ON(!NInoNonResident(ni));
267 BUG_ON(vcn < 0); 284 BUG_ON(vcn < 0);
285 if (!ni->runlist.rl) {
286 read_lock_irqsave(&ni->size_lock, flags);
287 if (!ni->allocated_size) {
288 read_unlock_irqrestore(&ni->size_lock, flags);
289 return ERR_PTR(-ENOENT);
290 }
291 read_unlock_irqrestore(&ni->size_lock, flags);
292 }
268retry_remap: 293retry_remap:
269 rl = ni->runlist.rl; 294 rl = ni->runlist.rl;
270 if (likely(rl && vcn >= rl[0].vcn)) { 295 if (likely(rl && vcn >= rl[0].vcn)) {
@@ -528,6 +553,11 @@ int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
528 block_size_bits = sb->s_blocksize_bits; 553 block_size_bits = sb->s_blocksize_bits;
529 down_read(&runlist->lock); 554 down_read(&runlist->lock);
530 rl = runlist->rl; 555 rl = runlist->rl;
556 if (!rl) {
557 ntfs_error(sb, "Cannot read attribute list since runlist is "
558 "missing.");
559 goto err_out;
560 }
531 /* Read all clusters specified by the runlist one run at a time. */ 561 /* Read all clusters specified by the runlist one run at a time. */
532 while (rl->length) { 562 while (rl->length) {
533 lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn); 563 lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);
@@ -1247,6 +1277,46 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
1247} 1277}
1248 1278
1249/** 1279/**
1280 * ntfs_resident_attr_value_resize - resize the value of a resident attribute
1281 * @m: mft record containing attribute record
1282 * @a: attribute record whose value to resize
1283 * @new_size: new size in bytes to which to resize the attribute value of @a
1284 *
1285 * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
1286 * If the value is made bigger, the newly allocated space is cleared.
1287 *
1288 * Return 0 on success and -errno on error. The following error codes are
1289 * defined:
1290 * -ENOSPC - Not enough space in the mft record @m to perform the resize.
1291 *
1292 * Note: On error, no modifications have been performed whatsoever.
1293 *
1294 * Warning: If you make a record smaller without having copied all the data you
1295 * are interested in the data may be overwritten.
1296 */
1297int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
1298 const u32 new_size)
1299{
1300 u32 old_size;
1301
1302 /* Resize the resident part of the attribute record. */
1303 if (ntfs_attr_record_resize(m, a,
1304 le16_to_cpu(a->data.resident.value_offset) + new_size))
1305 return -ENOSPC;
1306 /*
1307 * The resize succeeded! If we made the attribute value bigger, clear
1308 * the area between the old size and @new_size.
1309 */
1310 old_size = le32_to_cpu(a->data.resident.value_length);
1311 if (new_size > old_size)
1312 memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
1313 old_size, 0, new_size - old_size);
1314 /* Finally update the length of the attribute value. */
1315 a->data.resident.value_length = cpu_to_le32(new_size);
1316 return 0;
1317}
1318
1319/**
1250 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute 1320 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
1251 * @ni: ntfs inode describing the attribute to convert 1321 * @ni: ntfs inode describing the attribute to convert
1252 * 1322 *
@@ -1302,6 +1372,12 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1302 return err; 1372 return err;
1303 } 1373 }
1304 /* 1374 /*
1375 * FIXME: Compressed and encrypted attributes are not supported when
1376 * writing and we should never have gotten here for them.
1377 */
1378 BUG_ON(NInoCompressed(ni));
1379 BUG_ON(NInoEncrypted(ni));
1380 /*
1305 * The size needs to be aligned to a cluster boundary for allocation 1381 * The size needs to be aligned to a cluster boundary for allocation
1306 * purposes. 1382 * purposes.
1307 */ 1383 */
@@ -1377,10 +1453,15 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1377 BUG_ON(a->non_resident); 1453 BUG_ON(a->non_resident);
1378 /* 1454 /*
1379 * Calculate new offsets for the name and the mapping pairs array. 1455 * Calculate new offsets for the name and the mapping pairs array.
1380 * We assume the attribute is not compressed or sparse.
1381 */ 1456 */
1382 name_ofs = (offsetof(ATTR_REC, 1457 if (NInoSparse(ni) || NInoCompressed(ni))
1383 data.non_resident.compressed_size) + 7) & ~7; 1458 name_ofs = (offsetof(ATTR_REC,
1459 data.non_resident.compressed_size) +
1460 sizeof(a->data.non_resident.compressed_size) +
1461 7) & ~7;
1462 else
1463 name_ofs = (offsetof(ATTR_REC,
1464 data.non_resident.compressed_size) + 7) & ~7;
1384 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7; 1465 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
1385 /* 1466 /*
1386 * Determine the size of the resident part of the now non-resident 1467 * Determine the size of the resident part of the now non-resident
@@ -1419,24 +1500,23 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1419 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), 1500 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
1420 a->name_length * sizeof(ntfschar)); 1501 a->name_length * sizeof(ntfschar));
1421 a->name_offset = cpu_to_le16(name_ofs); 1502 a->name_offset = cpu_to_le16(name_ofs);
1422 /*
1423 * FIXME: For now just clear all of these as we do not support them
1424 * when writing.
1425 */
1426 a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
1427 ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
1428 /* Setup the fields specific to non-resident attributes. */ 1503 /* Setup the fields specific to non-resident attributes. */
1429 a->data.non_resident.lowest_vcn = 0; 1504 a->data.non_resident.lowest_vcn = 0;
1430 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >> 1505 a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
1431 vol->cluster_size_bits); 1506 vol->cluster_size_bits);
1432 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs); 1507 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
1433 a->data.non_resident.compression_unit = 0;
1434 memset(&a->data.non_resident.reserved, 0, 1508 memset(&a->data.non_resident.reserved, 0,
1435 sizeof(a->data.non_resident.reserved)); 1509 sizeof(a->data.non_resident.reserved));
1436 a->data.non_resident.allocated_size = cpu_to_sle64(new_size); 1510 a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
1437 a->data.non_resident.data_size = 1511 a->data.non_resident.data_size =
1438 a->data.non_resident.initialized_size = 1512 a->data.non_resident.initialized_size =
1439 cpu_to_sle64(attr_size); 1513 cpu_to_sle64(attr_size);
1514 if (NInoSparse(ni) || NInoCompressed(ni)) {
1515 a->data.non_resident.compression_unit = 4;
1516 a->data.non_resident.compressed_size =
1517 a->data.non_resident.allocated_size;
1518 } else
1519 a->data.non_resident.compression_unit = 0;
1440 /* Generate the mapping pairs array into the attribute record. */ 1520 /* Generate the mapping pairs array into the attribute record. */
1441 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, 1521 err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
1442 arec_size - mp_ofs, rl, 0, -1, NULL); 1522 arec_size - mp_ofs, rl, 0, -1, NULL);
@@ -1446,16 +1526,19 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1446 goto undo_err_out; 1526 goto undo_err_out;
1447 } 1527 }
1448 /* Setup the in-memory attribute structure to be non-resident. */ 1528 /* Setup the in-memory attribute structure to be non-resident. */
1449 /*
1450 * FIXME: For now just clear all of these as we do not support them
1451 * when writing.
1452 */
1453 NInoClearSparse(ni);
1454 NInoClearEncrypted(ni);
1455 NInoClearCompressed(ni);
1456 ni->runlist.rl = rl; 1529 ni->runlist.rl = rl;
1457 write_lock_irqsave(&ni->size_lock, flags); 1530 write_lock_irqsave(&ni->size_lock, flags);
1458 ni->allocated_size = new_size; 1531 ni->allocated_size = new_size;
1532 if (NInoSparse(ni) || NInoCompressed(ni)) {
1533 ni->itype.compressed.size = ni->allocated_size;
1534 ni->itype.compressed.block_size = 1U <<
1535 (a->data.non_resident.compression_unit +
1536 vol->cluster_size_bits);
1537 ni->itype.compressed.block_size_bits =
1538 ffs(ni->itype.compressed.block_size) - 1;
1539 ni->itype.compressed.block_clusters = 1U <<
1540 a->data.non_resident.compression_unit;
1541 }
1459 write_unlock_irqrestore(&ni->size_lock, flags); 1542 write_unlock_irqrestore(&ni->size_lock, flags);
1460 /* 1543 /*
1461 * This needs to be last since the address space operations ->readpage 1544 * This needs to be last since the address space operations ->readpage
@@ -1603,6 +1686,12 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1603 BUG_ON(cnt < 0); 1686 BUG_ON(cnt < 0);
1604 if (!cnt) 1687 if (!cnt)
1605 goto done; 1688 goto done;
1689 /*
1690 * FIXME: Compressed and encrypted attributes are not supported when
1691 * writing and we should never have gotten here for them.
1692 */
1693 BUG_ON(NInoCompressed(ni));
1694 BUG_ON(NInoEncrypted(ni));
1606 mapping = VFS_I(ni)->i_mapping; 1695 mapping = VFS_I(ni)->i_mapping;
1607 /* Work out the starting index and page offset. */ 1696 /* Work out the starting index and page offset. */
1608 idx = ofs >> PAGE_CACHE_SHIFT; 1697 idx = ofs >> PAGE_CACHE_SHIFT;
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
index 0e4ac6d3c0e7..0618ed6fd7b3 100644
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -99,6 +99,8 @@ extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
99 const ATTR_TYPE type); 99 const ATTR_TYPE type);
100 100
101extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size); 101extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
102extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
103 const u32 new_size);
102 104
103extern int ntfs_attr_make_non_resident(ntfs_inode *ni); 105extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
104 106
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 6d265cfd49aa..25d24106f893 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -539,7 +539,6 @@ int ntfs_read_compressed_block(struct page *page)
539 if (unlikely(!pages || !bhs)) { 539 if (unlikely(!pages || !bhs)) {
540 kfree(bhs); 540 kfree(bhs);
541 kfree(pages); 541 kfree(pages);
542 SetPageError(page);
543 unlock_page(page); 542 unlock_page(page);
544 ntfs_error(vol->sb, "Failed to allocate internal buffers."); 543 ntfs_error(vol->sb, "Failed to allocate internal buffers.");
545 return -ENOMEM; 544 return -ENOMEM;
@@ -871,9 +870,6 @@ lock_retry_remap:
871 for (; prev_cur_page < cur_page; prev_cur_page++) { 870 for (; prev_cur_page < cur_page; prev_cur_page++) {
872 page = pages[prev_cur_page]; 871 page = pages[prev_cur_page];
873 if (page) { 872 if (page) {
874 if (prev_cur_page == xpage &&
875 !xpage_done)
876 SetPageError(page);
877 flush_dcache_page(page); 873 flush_dcache_page(page);
878 kunmap(page); 874 kunmap(page);
879 unlock_page(page); 875 unlock_page(page);
@@ -904,8 +900,6 @@ lock_retry_remap:
904 "Terminating them with extreme " 900 "Terminating them with extreme "
905 "prejudice. Inode 0x%lx, page index " 901 "prejudice. Inode 0x%lx, page index "
906 "0x%lx.", ni->mft_no, page->index); 902 "0x%lx.", ni->mft_no, page->index);
907 if (cur_page == xpage && !xpage_done)
908 SetPageError(page);
909 flush_dcache_page(page); 903 flush_dcache_page(page);
910 kunmap(page); 904 kunmap(page);
911 unlock_page(page); 905 unlock_page(page);
@@ -953,8 +947,6 @@ err_out:
953 for (i = cur_page; i < max_page; i++) { 947 for (i = cur_page; i < max_page; i++) {
954 page = pages[i]; 948 page = pages[i];
955 if (page) { 949 if (page) {
956 if (i == xpage && !xpage_done)
957 SetPageError(page);
958 flush_dcache_page(page); 950 flush_dcache_page(page);
959 kunmap(page); 951 kunmap(page);
960 unlock_page(page); 952 unlock_page(page);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 46779471c542..795c3d1930f5 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1051,7 +1051,8 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
1051 ie->key.file_name.file_name_length, &name, 1051 ie->key.file_name.file_name_length, &name,
1052 NTFS_MAX_NAME_LEN * NLS_MAX_CHARSET_SIZE + 1); 1052 NTFS_MAX_NAME_LEN * NLS_MAX_CHARSET_SIZE + 1);
1053 if (name_len <= 0) { 1053 if (name_len <= 0) {
1054 ntfs_debug("Skipping unrepresentable file."); 1054 ntfs_warning(vol->sb, "Skipping unrepresentable inode 0x%llx.",
1055 (long long)MREF_LE(ie->data.dir.indexed_file));
1055 return 0; 1056 return 0;
1056 } 1057 }
1057 if (ie->key.file_name.file_attributes & 1058 if (ie->key.file_name.file_attributes &
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index e0f530ce6b99..be9fd1dd423d 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. 2 * file.c - NTFS kernel file operations. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2004 Anton Altaparmakov 4 * Copyright (c) 2001-2005 Anton Altaparmakov
5 * 5 *
6 * This program/include file is free software; you can redistribute it and/or 6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published 7 * modify it under the terms of the GNU General Public License as published
@@ -94,6 +94,11 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
94 if (!datasync || !NInoNonResident(NTFS_I(vi))) 94 if (!datasync || !NInoNonResident(NTFS_I(vi)))
95 ret = ntfs_write_inode(vi, 1); 95 ret = ntfs_write_inode(vi, 1);
96 write_inode_now(vi, !datasync); 96 write_inode_now(vi, !datasync);
97 /*
98 * NOTE: If we were to use mapping->private_list (see ext2 and
99 * fs/buffer.c) for dirty blocks then we could optimize the below to be
100 * sync_mapping_buffers(vi->i_mapping).
101 */
97 err = sync_blockdev(vi->i_sb->s_bdev); 102 err = sync_blockdev(vi->i_sb->s_bdev);
98 if (unlikely(err && !ret)) 103 if (unlikely(err && !ret))
99 ret = err; 104 ret = err;
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 11fd5307d780..8f2d5727546f 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -205,6 +205,7 @@ int ntfs_index_lookup(const void *key, const int key_len,
205 &ie->key, key_len)) { 205 &ie->key, key_len)) {
206ir_done: 206ir_done:
207 ictx->is_in_root = TRUE; 207 ictx->is_in_root = TRUE;
208 ictx->ir = ir;
208 ictx->actx = actx; 209 ictx->actx = actx;
209 ictx->base_ni = base_ni; 210 ictx->base_ni = base_ni;
210 ictx->ia = NULL; 211 ictx->ia = NULL;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 886214a77f90..dc4bbe3acf5c 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1013,41 +1013,50 @@ skip_large_dir_stuff:
1013 } 1013 }
1014 a = ctx->attr; 1014 a = ctx->attr;
1015 /* Setup the state. */ 1015 /* Setup the state. */
1016 if (a->non_resident) { 1016 if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
1017 NInoSetNonResident(ni); 1017 if (a->flags & ATTR_COMPRESSION_MASK) {
1018 if (a->flags & (ATTR_COMPRESSION_MASK | 1018 NInoSetCompressed(ni);
1019 ATTR_IS_SPARSE)) { 1019 if (vol->cluster_size > 4096) {
1020 if (a->flags & ATTR_COMPRESSION_MASK) { 1020 ntfs_error(vi->i_sb, "Found "
1021 NInoSetCompressed(ni);
1022 if (vol->cluster_size > 4096) {
1023 ntfs_error(vi->i_sb, "Found "
1024 "compressed data but " 1021 "compressed data but "
1025 "compression is " 1022 "compression is "
1026 "disabled due to " 1023 "disabled due to "
1027 "cluster size (%i) > " 1024 "cluster size (%i) > "
1028 "4kiB.", 1025 "4kiB.",
1029 vol->cluster_size); 1026 vol->cluster_size);
1030 goto unm_err_out; 1027 goto unm_err_out;
1031 } 1028 }
1032 if ((a->flags & ATTR_COMPRESSION_MASK) 1029 if ((a->flags & ATTR_COMPRESSION_MASK)
1033 != ATTR_IS_COMPRESSED) { 1030 != ATTR_IS_COMPRESSED) {
1034 ntfs_error(vi->i_sb, "Found " 1031 ntfs_error(vi->i_sb, "Found unknown "
1035 "unknown compression " 1032 "compression method "
1036 "method or corrupt " 1033 "or corrupt file.");
1037 "file."); 1034 goto unm_err_out;
1038 goto unm_err_out;
1039 }
1040 } 1035 }
1041 if (a->flags & ATTR_IS_SPARSE) 1036 }
1042 NInoSetSparse(ni); 1037 if (a->flags & ATTR_IS_SPARSE)
1038 NInoSetSparse(ni);
1039 }
1040 if (a->flags & ATTR_IS_ENCRYPTED) {
1041 if (NInoCompressed(ni)) {
1042 ntfs_error(vi->i_sb, "Found encrypted and "
1043 "compressed data.");
1044 goto unm_err_out;
1045 }
1046 NInoSetEncrypted(ni);
1047 }
1048 if (a->non_resident) {
1049 NInoSetNonResident(ni);
1050 if (NInoCompressed(ni) || NInoSparse(ni)) {
1043 if (a->data.non_resident.compression_unit != 1051 if (a->data.non_resident.compression_unit !=
1044 4) { 1052 4) {
1045 ntfs_error(vi->i_sb, "Found " 1053 ntfs_error(vi->i_sb, "Found "
1046 "nonstandard compression unit " 1054 "nonstandard "
1047 "(%u instead of 4). Cannot " 1055 "compression unit (%u "
1048 "handle this.", 1056 "instead of 4). "
1049 a->data.non_resident. 1057 "Cannot handle this.",
1050 compression_unit); 1058 a->data.non_resident.
1059 compression_unit);
1051 err = -EOPNOTSUPP; 1060 err = -EOPNOTSUPP;
1052 goto unm_err_out; 1061 goto unm_err_out;
1053 } 1062 }
@@ -1065,14 +1074,6 @@ skip_large_dir_stuff:
1065 a->data.non_resident. 1074 a->data.non_resident.
1066 compressed_size); 1075 compressed_size);
1067 } 1076 }
1068 if (a->flags & ATTR_IS_ENCRYPTED) {
1069 if (a->flags & ATTR_COMPRESSION_MASK) {
1070 ntfs_error(vi->i_sb, "Found encrypted "
1071 "and compressed data.");
1072 goto unm_err_out;
1073 }
1074 NInoSetEncrypted(ni);
1075 }
1076 if (a->data.non_resident.lowest_vcn) { 1077 if (a->data.non_resident.lowest_vcn) {
1077 ntfs_error(vi->i_sb, "First extent of $DATA " 1078 ntfs_error(vi->i_sb, "First extent of $DATA "
1078 "attribute has non zero " 1079 "attribute has non zero "
@@ -1212,6 +1213,75 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1212 if (unlikely(err)) 1213 if (unlikely(err))
1213 goto unm_err_out; 1214 goto unm_err_out;
1214 a = ctx->attr; 1215 a = ctx->attr;
1216 if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
1217 if (a->flags & ATTR_COMPRESSION_MASK) {
1218 NInoSetCompressed(ni);
1219 if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&
1220 ni->name_len)) {
1221 ntfs_error(vi->i_sb, "Found compressed "
1222 "non-data or named data "
1223 "attribute. Please report "
1224 "you saw this message to "
1225 "linux-ntfs-dev@lists."
1226 "sourceforge.net");
1227 goto unm_err_out;
1228 }
1229 if (vol->cluster_size > 4096) {
1230 ntfs_error(vi->i_sb, "Found compressed "
1231 "attribute but compression is "
1232 "disabled due to cluster size "
1233 "(%i) > 4kiB.",
1234 vol->cluster_size);
1235 goto unm_err_out;
1236 }
1237 if ((a->flags & ATTR_COMPRESSION_MASK) !=
1238 ATTR_IS_COMPRESSED) {
1239 ntfs_error(vi->i_sb, "Found unknown "
1240 "compression method.");
1241 goto unm_err_out;
1242 }
1243 }
1244 /*
1245 * The encryption flag set in an index root just means to
1246 * compress all files.
1247 */
1248 if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
1249 ntfs_error(vi->i_sb, "Found mst protected attribute "
1250 "but the attribute is %s. Please "
1251 "report you saw this message to "
1252 "linux-ntfs-dev@lists.sourceforge.net",
1253 NInoCompressed(ni) ? "compressed" :
1254 "sparse");
1255 goto unm_err_out;
1256 }
1257 if (a->flags & ATTR_IS_SPARSE)
1258 NInoSetSparse(ni);
1259 }
1260 if (a->flags & ATTR_IS_ENCRYPTED) {
1261 if (NInoCompressed(ni)) {
1262 ntfs_error(vi->i_sb, "Found encrypted and compressed "
1263 "data.");
1264 goto unm_err_out;
1265 }
1266 /*
1267 * The encryption flag set in an index root just means to
1268 * encrypt all files.
1269 */
1270 if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
1271 ntfs_error(vi->i_sb, "Found mst protected attribute "
1272 "but the attribute is encrypted. "
1273 "Please report you saw this message "
1274 "to linux-ntfs-dev@lists.sourceforge."
1275 "net");
1276 goto unm_err_out;
1277 }
1278 if (ni->type != AT_DATA) {
1279 ntfs_error(vi->i_sb, "Found encrypted non-data "
1280 "attribute.");
1281 goto unm_err_out;
1282 }
1283 NInoSetEncrypted(ni);
1284 }
1215 if (!a->non_resident) { 1285 if (!a->non_resident) {
1216 /* Ensure the attribute name is placed before the value. */ 1286 /* Ensure the attribute name is placed before the value. */
1217 if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 1287 if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
@@ -1220,11 +1290,10 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1220 "the attribute value."); 1290 "the attribute value.");
1221 goto unm_err_out; 1291 goto unm_err_out;
1222 } 1292 }
1223 if (NInoMstProtected(ni) || a->flags) { 1293 if (NInoMstProtected(ni)) {
1224 ntfs_error(vi->i_sb, "Found mst protected attribute " 1294 ntfs_error(vi->i_sb, "Found mst protected attribute "
1225 "or attribute with non-zero flags but " 1295 "but the attribute is resident. "
1226 "the attribute is resident. Please " 1296 "Please report you saw this message to "
1227 "report you saw this message to "
1228 "linux-ntfs-dev@lists.sourceforge.net"); 1297 "linux-ntfs-dev@lists.sourceforge.net");
1229 goto unm_err_out; 1298 goto unm_err_out;
1230 } 1299 }
@@ -1250,50 +1319,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1250 "the mapping pairs array."); 1319 "the mapping pairs array.");
1251 goto unm_err_out; 1320 goto unm_err_out;
1252 } 1321 }
1253 if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) { 1322 if ((NInoCompressed(ni) || NInoSparse(ni)) &&
1254 if (a->flags & ATTR_COMPRESSION_MASK) { 1323 ni->type != AT_INDEX_ROOT) {
1255 NInoSetCompressed(ni);
1256 if ((ni->type != AT_DATA) || (ni->type ==
1257 AT_DATA && ni->name_len)) {
1258 ntfs_error(vi->i_sb, "Found compressed "
1259 "non-data or named "
1260 "data attribute. "
1261 "Please report you "
1262 "saw this message to "
1263 "linux-ntfs-dev@lists."
1264 "sourceforge.net");
1265 goto unm_err_out;
1266 }
1267 if (vol->cluster_size > 4096) {
1268 ntfs_error(vi->i_sb, "Found compressed "
1269 "attribute but "
1270 "compression is "
1271 "disabled due to "
1272 "cluster size (%i) > "
1273 "4kiB.",
1274 vol->cluster_size);
1275 goto unm_err_out;
1276 }
1277 if ((a->flags & ATTR_COMPRESSION_MASK) !=
1278 ATTR_IS_COMPRESSED) {
1279 ntfs_error(vi->i_sb, "Found unknown "
1280 "compression method.");
1281 goto unm_err_out;
1282 }
1283 }
1284 if (NInoMstProtected(ni)) {
1285 ntfs_error(vi->i_sb, "Found mst protected "
1286 "attribute but the attribute "
1287 "is %s. Please report you "
1288 "saw this message to "
1289 "linux-ntfs-dev@lists."
1290 "sourceforge.net",
1291 NInoCompressed(ni) ?
1292 "compressed" : "sparse");
1293 goto unm_err_out;
1294 }
1295 if (a->flags & ATTR_IS_SPARSE)
1296 NInoSetSparse(ni);
1297 if (a->data.non_resident.compression_unit != 4) { 1324 if (a->data.non_resident.compression_unit != 4) {
1298 ntfs_error(vi->i_sb, "Found nonstandard " 1325 ntfs_error(vi->i_sb, "Found nonstandard "
1299 "compression unit (%u instead " 1326 "compression unit (%u instead "
@@ -1313,23 +1340,6 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1313 ni->itype.compressed.size = sle64_to_cpu( 1340 ni->itype.compressed.size = sle64_to_cpu(
1314 a->data.non_resident.compressed_size); 1341 a->data.non_resident.compressed_size);
1315 } 1342 }
1316 if (a->flags & ATTR_IS_ENCRYPTED) {
1317 if (a->flags & ATTR_COMPRESSION_MASK) {
1318 ntfs_error(vi->i_sb, "Found encrypted and "
1319 "compressed data.");
1320 goto unm_err_out;
1321 }
1322 if (NInoMstProtected(ni)) {
1323 ntfs_error(vi->i_sb, "Found mst protected "
1324 "attribute but the attribute "
1325 "is encrypted. Please report "
1326 "you saw this message to "
1327 "linux-ntfs-dev@lists."
1328 "sourceforge.net");
1329 goto unm_err_out;
1330 }
1331 NInoSetEncrypted(ni);
1332 }
1333 if (a->data.non_resident.lowest_vcn) { 1343 if (a->data.non_resident.lowest_vcn) {
1334 ntfs_error(vi->i_sb, "First extent of attribute has " 1344 ntfs_error(vi->i_sb, "First extent of attribute has "
1335 "non-zero lowest_vcn."); 1345 "non-zero lowest_vcn.");
@@ -1348,12 +1358,12 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
1348 vi->i_mapping->a_ops = &ntfs_mst_aops; 1358 vi->i_mapping->a_ops = &ntfs_mst_aops;
1349 else 1359 else
1350 vi->i_mapping->a_ops = &ntfs_aops; 1360 vi->i_mapping->a_ops = &ntfs_aops;
1351 if (NInoCompressed(ni) || NInoSparse(ni)) 1361 if ((NInoCompressed(ni) || NInoSparse(ni)) && ni->type != AT_INDEX_ROOT)
1352 vi->i_blocks = ni->itype.compressed.size >> 9; 1362 vi->i_blocks = ni->itype.compressed.size >> 9;
1353 else 1363 else
1354 vi->i_blocks = ni->allocated_size >> 9; 1364 vi->i_blocks = ni->allocated_size >> 9;
1355 /* 1365 /*
1356 * Make sure the base inode doesn't go away and attach it to the 1366 * Make sure the base inode does not go away and attach it to the
1357 * attribute inode. 1367 * attribute inode.
1358 */ 1368 */
1359 igrab(base_vi); 1369 igrab(base_vi);
@@ -1480,7 +1490,10 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
1480 "after the attribute value."); 1490 "after the attribute value.");
1481 goto unm_err_out; 1491 goto unm_err_out;
1482 } 1492 }
1483 /* Compressed/encrypted/sparse index root is not allowed. */ 1493 /*
1494 * Compressed/encrypted/sparse index root is not allowed, except for
1495 * directories of course but those are not dealt with here.
1496 */
1484 if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED | 1497 if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
1485 ATTR_IS_SPARSE)) { 1498 ATTR_IS_SPARSE)) {
1486 ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index " 1499 ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "
@@ -2430,16 +2443,18 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
2430 * We skipped the truncate but must still update 2443 * We skipped the truncate but must still update
2431 * timestamps. 2444 * timestamps.
2432 */ 2445 */
2433 ia_valid |= ATTR_MTIME|ATTR_CTIME; 2446 ia_valid |= ATTR_MTIME | ATTR_CTIME;
2434 } 2447 }
2435 } 2448 }
2436
2437 if (ia_valid & ATTR_ATIME) 2449 if (ia_valid & ATTR_ATIME)
2438 vi->i_atime = attr->ia_atime; 2450 vi->i_atime = timespec_trunc(attr->ia_atime,
2451 vi->i_sb->s_time_gran);
2439 if (ia_valid & ATTR_MTIME) 2452 if (ia_valid & ATTR_MTIME)
2440 vi->i_mtime = attr->ia_mtime; 2453 vi->i_mtime = timespec_trunc(attr->ia_mtime,
2454 vi->i_sb->s_time_gran);
2441 if (ia_valid & ATTR_CTIME) 2455 if (ia_valid & ATTR_CTIME)
2442 vi->i_ctime = attr->ia_ctime; 2456 vi->i_ctime = timespec_trunc(attr->ia_ctime,
2457 vi->i_sb->s_time_gran);
2443 mark_inode_dirty(vi); 2458 mark_inode_dirty(vi);
2444out: 2459out:
2445 return err; 2460 return err;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index a4bc07616e5d..7b5934290685 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -54,6 +54,8 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
54 int ret = 0; 54 int ret = 0;
55 55
56 ntfs_debug("Entering."); 56 ntfs_debug("Entering.");
57 if (!rl)
58 return 0;
57 for (; rl->length; rl++) { 59 for (; rl->length; rl++) {
58 int err; 60 int err;
59 61
@@ -163,17 +165,9 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
163 BUG_ON(zone < FIRST_ZONE); 165 BUG_ON(zone < FIRST_ZONE);
164 BUG_ON(zone > LAST_ZONE); 166 BUG_ON(zone > LAST_ZONE);
165 167
166 /* Return empty runlist if @count == 0 */ 168 /* Return NULL if @count is zero. */
167 // FIXME: Do we want to just return NULL instead? (AIA) 169 if (!count)
168 if (!count) { 170 return NULL;
169 rl = ntfs_malloc_nofs(PAGE_SIZE);
170 if (!rl)
171 return ERR_PTR(-ENOMEM);
172 rl[0].vcn = start_vcn;
173 rl[0].lcn = LCN_RL_NOT_MAPPED;
174 rl[0].length = 0;
175 return rl;
176 }
177 /* Take the lcnbmp lock for writing. */ 171 /* Take the lcnbmp lock for writing. */
178 down_write(&vol->lcnbmp_lock); 172 down_write(&vol->lcnbmp_lock);
179 /* 173 /*
@@ -788,7 +782,8 @@ out:
788 * @vi: vfs inode whose runlist describes the clusters to free 782 * @vi: vfs inode whose runlist describes the clusters to free
789 * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters 783 * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters
790 * @count: number of clusters to free or -1 for all clusters 784 * @count: number of clusters to free or -1 for all clusters
791 * @is_rollback: if TRUE this is a rollback operation 785 * @write_locked: true if the runlist is locked for writing
786 * @is_rollback: true if this is a rollback operation
792 * 787 *
793 * Free @count clusters starting at the cluster @start_vcn in the runlist 788 * Free @count clusters starting at the cluster @start_vcn in the runlist
794 * described by the vfs inode @vi. 789 * described by the vfs inode @vi.
@@ -806,17 +801,17 @@ out:
806 * Return the number of deallocated clusters (not counting sparse ones) on 801 * Return the number of deallocated clusters (not counting sparse ones) on
807 * success and -errno on error. 802 * success and -errno on error.
808 * 803 *
809 * Locking: - The runlist described by @vi must be unlocked on entry and is 804 * Locking: - The runlist described by @vi must be locked on entry and is
810 * unlocked on return. 805 * locked on return. Note if the runlist is locked for reading the
811 * - This function takes the runlist lock of @vi for reading and 806 * lock may be dropped and reacquired. Note the runlist may be
812 * sometimes for writing and sometimes modifies the runlist. 807 * modified when needed runlist fragments need to be mapped.
813 * - The volume lcn bitmap must be unlocked on entry and is unlocked 808 * - The volume lcn bitmap must be unlocked on entry and is unlocked
814 * on return. 809 * on return.
815 * - This function takes the volume lcn bitmap lock for writing and 810 * - This function takes the volume lcn bitmap lock for writing and
816 * modifies the bitmap contents. 811 * modifies the bitmap contents.
817 */ 812 */
818s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, 813s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
819 const BOOL is_rollback) 814 const BOOL write_locked, const BOOL is_rollback)
820{ 815{
821 s64 delta, to_free, total_freed, real_freed; 816 s64 delta, to_free, total_freed, real_freed;
822 ntfs_inode *ni; 817 ntfs_inode *ni;
@@ -848,8 +843,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
848 843
849 total_freed = real_freed = 0; 844 total_freed = real_freed = 0;
850 845
851 down_read(&ni->runlist.lock); 846 rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, write_locked);
852 rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);
853 if (IS_ERR(rl)) { 847 if (IS_ERR(rl)) {
854 if (!is_rollback) 848 if (!is_rollback)
855 ntfs_error(vol->sb, "Failed to find first runlist " 849 ntfs_error(vol->sb, "Failed to find first runlist "
@@ -903,7 +897,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
903 897
904 /* Attempt to map runlist. */ 898 /* Attempt to map runlist. */
905 vcn = rl->vcn; 899 vcn = rl->vcn;
906 rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE); 900 rl = ntfs_attr_find_vcn_nolock(ni, vcn, write_locked);
907 if (IS_ERR(rl)) { 901 if (IS_ERR(rl)) {
908 err = PTR_ERR(rl); 902 err = PTR_ERR(rl);
909 if (!is_rollback) 903 if (!is_rollback)
@@ -950,7 +944,6 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
950 /* Update the total done clusters. */ 944 /* Update the total done clusters. */
951 total_freed += to_free; 945 total_freed += to_free;
952 } 946 }
953 up_read(&ni->runlist.lock);
954 if (likely(!is_rollback)) 947 if (likely(!is_rollback))
955 up_write(&vol->lcnbmp_lock); 948 up_write(&vol->lcnbmp_lock);
956 949
@@ -960,7 +953,6 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
960 ntfs_debug("Done."); 953 ntfs_debug("Done.");
961 return real_freed; 954 return real_freed;
962err_out: 955err_out:
963 up_read(&ni->runlist.lock);
964 if (is_rollback) 956 if (is_rollback)
965 return err; 957 return err;
966 /* If no real clusters were freed, no need to rollback. */ 958 /* If no real clusters were freed, no need to rollback. */
@@ -973,7 +965,8 @@ err_out:
973 * If rollback fails, set the volume errors flag, emit an error 965 * If rollback fails, set the volume errors flag, emit an error
974 * message, and return the error code. 966 * message, and return the error code.
975 */ 967 */
976 delta = __ntfs_cluster_free(vi, start_vcn, total_freed, TRUE); 968 delta = __ntfs_cluster_free(vi, start_vcn, total_freed, write_locked,
969 TRUE);
977 if (delta < 0) { 970 if (delta < 0) {
978 ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " 971 ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
979 "inconsistent metadata! Unmount and run " 972 "inconsistent metadata! Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index 4cac1c024af6..e4d7fb98d685 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -43,13 +43,14 @@ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
43 const NTFS_CLUSTER_ALLOCATION_ZONES zone); 43 const NTFS_CLUSTER_ALLOCATION_ZONES zone);
44 44
45extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, 45extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
46 s64 count, const BOOL is_rollback); 46 s64 count, const BOOL write_locked, const BOOL is_rollback);
47 47
48/** 48/**
49 * ntfs_cluster_free - free clusters on an ntfs volume 49 * ntfs_cluster_free - free clusters on an ntfs volume
50 * @vi: vfs inode whose runlist describes the clusters to free 50 * @vi: vfs inode whose runlist describes the clusters to free
51 * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters 51 * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters
52 * @count: number of clusters to free or -1 for all clusters 52 * @count: number of clusters to free or -1 for all clusters
53 * @write_locked: true if the runlist is locked for writing
53 * 54 *
54 * Free @count clusters starting at the cluster @start_vcn in the runlist 55 * Free @count clusters starting at the cluster @start_vcn in the runlist
55 * described by the vfs inode @vi. 56 * described by the vfs inode @vi.
@@ -64,19 +65,19 @@ extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
64 * Return the number of deallocated clusters (not counting sparse ones) on 65 * Return the number of deallocated clusters (not counting sparse ones) on
65 * success and -errno on error. 66 * success and -errno on error.
66 * 67 *
67 * Locking: - The runlist described by @vi must be unlocked on entry and is 68 * Locking: - The runlist described by @vi must be locked on entry and is
68 * unlocked on return. 69 * locked on return. Note if the runlist is locked for reading the
69 * - This function takes the runlist lock of @vi for reading and 70 * lock may be dropped and reacquired. Note the runlist may be
70 * sometimes for writing and sometimes modifies the runlist. 71 * modified when needed runlist fragments need to be mapped.
71 * - The volume lcn bitmap must be unlocked on entry and is unlocked 72 * - The volume lcn bitmap must be unlocked on entry and is unlocked
72 * on return. 73 * on return.
73 * - This function takes the volume lcn bitmap lock for writing and 74 * - This function takes the volume lcn bitmap lock for writing and
74 * modifies the bitmap contents. 75 * modifies the bitmap contents.
75 */ 76 */
76static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn, 77static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
77 s64 count) 78 s64 count, const BOOL write_locked)
78{ 79{
79 return __ntfs_cluster_free(vi, start_vcn, count, FALSE); 80 return __ntfs_cluster_free(vi, start_vcn, count, write_locked, FALSE);
80} 81}
81 82
82extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, 83extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
@@ -93,8 +94,10 @@ extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
93 * 94 *
94 * Return 0 on success and -errno on error. 95 * Return 0 on success and -errno on error.
95 * 96 *
96 * Locking: This function takes the volume lcn bitmap lock for writing and 97 * Locking: - This function takes the volume lcn bitmap lock for writing and
97 * modifies the bitmap contents. 98 * modifies the bitmap contents.
99 * - The caller must have locked the runlist @rl for reading or
100 * writing.
98 */ 101 */
99static inline int ntfs_cluster_free_from_rl(ntfs_volume *vol, 102static inline int ntfs_cluster_free_from_rl(ntfs_volume *vol,
100 const runlist_element *rl) 103 const runlist_element *rl)
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 8edb8e20fb08..0173e95500d9 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -121,7 +121,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi,
121 */ 121 */
122 if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) { 122 if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
123 ntfs_error(vi->i_sb, "$LogFile restart page is not modified " 123 ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
124 "chkdsk but a chkdsk LSN is specified."); 124 "by chkdsk but a chkdsk LSN is specified.");
125 return FALSE; 125 return FALSE;
126 } 126 }
127 ntfs_debug("Done."); 127 ntfs_debug("Done.");
@@ -312,10 +312,12 @@ err_out:
312 * @vi: $LogFile inode to which the restart page belongs 312 * @vi: $LogFile inode to which the restart page belongs
313 * @rp: restart page to check 313 * @rp: restart page to check
314 * @pos: position in @vi at which the restart page resides 314 * @pos: position in @vi at which the restart page resides
315 * @wrp: copy of the multi sector transfer deprotected restart page 315 * @wrp: [OUT] copy of the multi sector transfer deprotected restart page
316 * @lsn: [OUT] set to the current logfile lsn on success
316 * 317 *
317 * Check the restart page @rp for consistency and return TRUE if it is 318 * Check the restart page @rp for consistency and return 0 if it is consistent
318 * consistent and FALSE otherwise. 319 * and -errno otherwise. The restart page may have been modified by chkdsk in
320 * which case its magic is CHKD instead of RSTR.
319 * 321 *
320 * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not 322 * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
321 * require the full restart page. 323 * require the full restart page.
@@ -323,25 +325,33 @@ err_out:
323 * If @wrp is not NULL, on success, *@wrp will point to a buffer containing a 325 * If @wrp is not NULL, on success, *@wrp will point to a buffer containing a
324 * copy of the complete multi sector transfer deprotected page. On failure, 326 * copy of the complete multi sector transfer deprotected page. On failure,
325 * *@wrp is undefined. 327 * *@wrp is undefined.
328 *
329 * Simillarly, if @lsn is not NULL, on succes *@lsn will be set to the current
330 * logfile lsn according to this restart page. On failure, *@lsn is undefined.
331 *
332 * The following error codes are defined:
333 * -EINVAL - The restart page is inconsistent.
334 * -ENOMEM - Not enough memory to load the restart page.
335 * -EIO - Failed to reading from $LogFile.
326 */ 336 */
327static BOOL ntfs_check_and_load_restart_page(struct inode *vi, 337static int ntfs_check_and_load_restart_page(struct inode *vi,
328 RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp) 338 RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp,
339 LSN *lsn)
329{ 340{
330 RESTART_AREA *ra; 341 RESTART_AREA *ra;
331 RESTART_PAGE_HEADER *trp; 342 RESTART_PAGE_HEADER *trp;
332 int size; 343 int size, err;
333 BOOL ret;
334 344
335 ntfs_debug("Entering."); 345 ntfs_debug("Entering.");
336 /* Check the restart page header for consistency. */ 346 /* Check the restart page header for consistency. */
337 if (!ntfs_check_restart_page_header(vi, rp, pos)) { 347 if (!ntfs_check_restart_page_header(vi, rp, pos)) {
338 /* Error output already done inside the function. */ 348 /* Error output already done inside the function. */
339 return FALSE; 349 return -EINVAL;
340 } 350 }
341 /* Check the restart area for consistency. */ 351 /* Check the restart area for consistency. */
342 if (!ntfs_check_restart_area(vi, rp)) { 352 if (!ntfs_check_restart_area(vi, rp)) {
343 /* Error output already done inside the function. */ 353 /* Error output already done inside the function. */
344 return FALSE; 354 return -EINVAL;
345 } 355 }
346 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); 356 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
347 /* 357 /*
@@ -352,7 +362,7 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
352 if (!trp) { 362 if (!trp) {
353 ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile " 363 ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
354 "restart page buffer."); 364 "restart page buffer.");
355 return FALSE; 365 return -ENOMEM;
356 } 366 }
357 /* 367 /*
358 * Read the whole of the restart page into the buffer. If it fits 368 * Read the whole of the restart page into the buffer. If it fits
@@ -379,6 +389,9 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
379 if (IS_ERR(page)) { 389 if (IS_ERR(page)) {
380 ntfs_error(vi->i_sb, "Error mapping $LogFile " 390 ntfs_error(vi->i_sb, "Error mapping $LogFile "
381 "page (index %lu).", idx); 391 "page (index %lu).", idx);
392 err = PTR_ERR(page);
393 if (err != -EIO && err != -ENOMEM)
394 err = -EIO;
382 goto err_out; 395 goto err_out;
383 } 396 }
384 size = min_t(int, to_read, PAGE_CACHE_SIZE); 397 size = min_t(int, to_read, PAGE_CACHE_SIZE);
@@ -392,29 +405,57 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
392 /* Perform the multi sector transfer deprotection on the buffer. */ 405 /* Perform the multi sector transfer deprotection on the buffer. */
393 if (post_read_mst_fixup((NTFS_RECORD*)trp, 406 if (post_read_mst_fixup((NTFS_RECORD*)trp,
394 le32_to_cpu(rp->system_page_size))) { 407 le32_to_cpu(rp->system_page_size))) {
395 ntfs_error(vi->i_sb, "Multi sector transfer error detected in " 408 /*
396 "$LogFile restart page."); 409 * A multi sector tranfer error was detected. We only need to
397 goto err_out; 410 * abort if the restart page contents exceed the multi sector
411 * transfer fixup of the first sector.
412 */
413 if (le16_to_cpu(rp->restart_area_offset) +
414 le16_to_cpu(ra->restart_area_length) >
415 NTFS_BLOCK_SIZE - sizeof(u16)) {
416 ntfs_error(vi->i_sb, "Multi sector transfer error "
417 "detected in $LogFile restart page.");
418 err = -EINVAL;
419 goto err_out;
420 }
421 }
422 /*
423 * If the restart page is modified by chkdsk or there are no active
424 * logfile clients, the logfile is consistent. Otherwise, need to
425 * check the log client records for consistency, too.
426 */
427 err = 0;
428 if (ntfs_is_rstr_record(rp->magic) &&
429 ra->client_in_use_list != LOGFILE_NO_CLIENT) {
430 if (!ntfs_check_log_client_array(vi, trp)) {
431 err = -EINVAL;
432 goto err_out;
433 }
434 }
435 if (lsn) {
436 if (ntfs_is_rstr_record(rp->magic))
437 *lsn = sle64_to_cpu(ra->current_lsn);
438 else /* if (ntfs_is_chkd_record(rp->magic)) */
439 *lsn = sle64_to_cpu(rp->chkdsk_lsn);
398 } 440 }
399 /* Check the log client records for consistency. */
400 ret = ntfs_check_log_client_array(vi, trp);
401 if (ret && wrp)
402 *wrp = trp;
403 else
404 ntfs_free(trp);
405 ntfs_debug("Done."); 441 ntfs_debug("Done.");
406 return ret; 442 if (wrp)
443 *wrp = trp;
444 else {
407err_out: 445err_out:
408 ntfs_free(trp); 446 ntfs_free(trp);
409 return FALSE; 447 }
448 return err;
410} 449}
411 450
412/** 451/**
413 * ntfs_check_logfile - check the journal for consistency 452 * ntfs_check_logfile - check the journal for consistency
414 * @log_vi: struct inode of loaded journal $LogFile to check 453 * @log_vi: struct inode of loaded journal $LogFile to check
454 * @rp: [OUT] on success this is a copy of the current restart page
415 * 455 *
416 * Check the $LogFile journal for consistency and return TRUE if it is 456 * Check the $LogFile journal for consistency and return TRUE if it is
417 * consistent and FALSE if not. 457 * consistent and FALSE if not. On success, the current restart page is
458 * returned in *@rp. Caller must call ntfs_free(*@rp) when finished with it.
418 * 459 *
419 * At present we only check the two restart pages and ignore the log record 460 * At present we only check the two restart pages and ignore the log record
420 * pages. 461 * pages.
@@ -424,19 +465,18 @@ err_out:
424 * if the $LogFile was created on a system with a different page size to ours 465 * if the $LogFile was created on a system with a different page size to ours
425 * yet and mst deprotection would fail if our page size is smaller. 466 * yet and mst deprotection would fail if our page size is smaller.
426 */ 467 */
427BOOL ntfs_check_logfile(struct inode *log_vi) 468BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
428{ 469{
429 s64 size, pos, rstr1_pos, rstr2_pos; 470 s64 size, pos;
471 LSN rstr1_lsn, rstr2_lsn;
430 ntfs_volume *vol = NTFS_SB(log_vi->i_sb); 472 ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
431 struct address_space *mapping = log_vi->i_mapping; 473 struct address_space *mapping = log_vi->i_mapping;
432 struct page *page = NULL; 474 struct page *page = NULL;
433 u8 *kaddr = NULL; 475 u8 *kaddr = NULL;
434 RESTART_PAGE_HEADER *rstr1_ph = NULL; 476 RESTART_PAGE_HEADER *rstr1_ph = NULL;
435 RESTART_PAGE_HEADER *rstr2_ph = NULL; 477 RESTART_PAGE_HEADER *rstr2_ph = NULL;
436 int log_page_size, log_page_mask, ofs; 478 int log_page_size, log_page_mask, err;
437 BOOL logfile_is_empty = TRUE; 479 BOOL logfile_is_empty = TRUE;
438 BOOL rstr1_found = FALSE;
439 BOOL rstr2_found = FALSE;
440 u8 log_page_bits; 480 u8 log_page_bits;
441 481
442 ntfs_debug("Entering."); 482 ntfs_debug("Entering.");
@@ -491,7 +531,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
491 if (IS_ERR(page)) { 531 if (IS_ERR(page)) {
492 ntfs_error(vol->sb, "Error mapping $LogFile " 532 ntfs_error(vol->sb, "Error mapping $LogFile "
493 "page (index %lu).", idx); 533 "page (index %lu).", idx);
494 return FALSE; 534 goto err_out;
495 } 535 }
496 } 536 }
497 kaddr = (u8*)page_address(page) + (pos & ~PAGE_CACHE_MASK); 537 kaddr = (u8*)page_address(page) + (pos & ~PAGE_CACHE_MASK);
@@ -510,99 +550,95 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
510 */ 550 */
511 if (ntfs_is_rcrd_recordp((le32*)kaddr)) 551 if (ntfs_is_rcrd_recordp((le32*)kaddr))
512 break; 552 break;
513 /* 553 /* If not a (modified by chkdsk) restart page, continue. */
514 * A modified by chkdsk restart page means we cannot handle 554 if (!ntfs_is_rstr_recordp((le32*)kaddr) &&
515 * this log file. 555 !ntfs_is_chkd_recordp((le32*)kaddr)) {
516 */
517 if (ntfs_is_chkd_recordp((le32*)kaddr)) {
518 ntfs_error(vol->sb, "$LogFile has been modified by "
519 "chkdsk. Mount this volume in "
520 "Windows.");
521 goto err_out;
522 }
523 /* If not a restart page, continue. */
524 if (!ntfs_is_rstr_recordp((le32*)kaddr)) {
525 /* Skip to the minimum page size for the next one. */
526 if (!pos) 556 if (!pos)
527 pos = NTFS_BLOCK_SIZE >> 1; 557 pos = NTFS_BLOCK_SIZE >> 1;
528 continue; 558 continue;
529 } 559 }
530 /* We now know we have a restart page. */
531 if (!pos) {
532 rstr1_found = TRUE;
533 rstr1_pos = pos;
534 } else {
535 if (rstr2_found) {
536 ntfs_error(vol->sb, "Found more than two "
537 "restart pages in $LogFile.");
538 goto err_out;
539 }
540 rstr2_found = TRUE;
541 rstr2_pos = pos;
542 }
543 /* 560 /*
544 * Check the restart page for consistency and get a copy of the 561 * Check the (modified by chkdsk) restart page for consistency
545 * complete multi sector transfer deprotected restart page. 562 * and get a copy of the complete multi sector transfer
563 * deprotected restart page.
546 */ 564 */
547 if (!ntfs_check_and_load_restart_page(log_vi, 565 err = ntfs_check_and_load_restart_page(log_vi,
548 (RESTART_PAGE_HEADER*)kaddr, pos, 566 (RESTART_PAGE_HEADER*)kaddr, pos,
549 !pos ? &rstr1_ph : &rstr2_ph)) { 567 !rstr1_ph ? &rstr1_ph : &rstr2_ph,
550 /* Error output already done inside the function. */ 568 !rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
551 goto err_out; 569 if (!err) {
570 /*
571 * If we have now found the first (modified by chkdsk)
572 * restart page, continue looking for the second one.
573 */
574 if (!pos) {
575 pos = NTFS_BLOCK_SIZE >> 1;
576 continue;
577 }
578 /*
579 * We have now found the second (modified by chkdsk)
580 * restart page, so we can stop looking.
581 */
582 break;
552 } 583 }
553 /* 584 /*
554 * We have a valid restart page. The next one must be after 585 * Error output already done inside the function. Note, we do
555 * a whole system page size as specified by the valid restart 586 * not abort if the restart page was invalid as we might still
556 * page. 587 * find a valid one further in the file.
557 */ 588 */
589 if (err != -EINVAL) {
590 ntfs_unmap_page(page);
591 goto err_out;
592 }
593 /* Continue looking. */
558 if (!pos) 594 if (!pos)
559 pos = le32_to_cpu(rstr1_ph->system_page_size) >> 1; 595 pos = NTFS_BLOCK_SIZE >> 1;
560 } 596 }
561 if (page) { 597 if (page)
562 ntfs_unmap_page(page); 598 ntfs_unmap_page(page);
563 page = NULL;
564 }
565 if (logfile_is_empty) { 599 if (logfile_is_empty) {
566 NVolSetLogFileEmpty(vol); 600 NVolSetLogFileEmpty(vol);
567is_empty: 601is_empty:
568 ntfs_debug("Done. ($LogFile is empty.)"); 602 ntfs_debug("Done. ($LogFile is empty.)");
569 return TRUE; 603 return TRUE;
570 } 604 }
571 if (!rstr1_found || !rstr2_found) { 605 if (!rstr1_ph) {
572 ntfs_error(vol->sb, "Did not find two restart pages in " 606 BUG_ON(rstr2_ph);
573 "$LogFile."); 607 ntfs_error(vol->sb, "Did not find any restart pages in "
574 goto err_out; 608 "$LogFile and it was not empty.");
609 return FALSE;
610 }
611 /* If both restart pages were found, use the more recent one. */
612 if (rstr2_ph) {
613 /*
614 * If the second restart area is more recent, switch to it.
615 * Otherwise just throw it away.
616 */
617 if (rstr2_lsn > rstr1_lsn) {
618 ntfs_free(rstr1_ph);
619 rstr1_ph = rstr2_ph;
620 /* rstr1_lsn = rstr2_lsn; */
621 } else
622 ntfs_free(rstr2_ph);
623 rstr2_ph = NULL;
575 } 624 }
576 /*
577 * The two restart areas must be identical except for the update
578 * sequence number.
579 */
580 ofs = le16_to_cpu(rstr1_ph->usa_ofs);
581 if (memcmp(rstr1_ph, rstr2_ph, ofs) || (ofs += sizeof(u16),
582 memcmp((u8*)rstr1_ph + ofs, (u8*)rstr2_ph + ofs,
583 le32_to_cpu(rstr1_ph->system_page_size) - ofs))) {
584 ntfs_error(vol->sb, "The two restart pages in $LogFile do not "
585 "match.");
586 goto err_out;
587 }
588 ntfs_free(rstr1_ph);
589 ntfs_free(rstr2_ph);
590 /* All consistency checks passed. */ 625 /* All consistency checks passed. */
626 if (rp)
627 *rp = rstr1_ph;
628 else
629 ntfs_free(rstr1_ph);
591 ntfs_debug("Done."); 630 ntfs_debug("Done.");
592 return TRUE; 631 return TRUE;
593err_out: 632err_out:
594 if (page)
595 ntfs_unmap_page(page);
596 if (rstr1_ph) 633 if (rstr1_ph)
597 ntfs_free(rstr1_ph); 634 ntfs_free(rstr1_ph);
598 if (rstr2_ph)
599 ntfs_free(rstr2_ph);
600 return FALSE; 635 return FALSE;
601} 636}
602 637
603/** 638/**
604 * ntfs_is_logfile_clean - check in the journal if the volume is clean 639 * ntfs_is_logfile_clean - check in the journal if the volume is clean
605 * @log_vi: struct inode of loaded journal $LogFile to check 640 * @log_vi: struct inode of loaded journal $LogFile to check
641 * @rp: copy of the current restart page
606 * 642 *
607 * Analyze the $LogFile journal and return TRUE if it indicates the volume was 643 * Analyze the $LogFile journal and return TRUE if it indicates the volume was
608 * shutdown cleanly and FALSE if not. 644 * shutdown cleanly and FALSE if not.
@@ -619,11 +655,9 @@ err_out:
619 * is empty this function requires that NVolLogFileEmpty() is true otherwise an 655 * is empty this function requires that NVolLogFileEmpty() is true otherwise an
620 * empty volume will be reported as dirty. 656 * empty volume will be reported as dirty.
621 */ 657 */
622BOOL ntfs_is_logfile_clean(struct inode *log_vi) 658BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
623{ 659{
624 ntfs_volume *vol = NTFS_SB(log_vi->i_sb); 660 ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
625 struct page *page;
626 RESTART_PAGE_HEADER *rp;
627 RESTART_AREA *ra; 661 RESTART_AREA *ra;
628 662
629 ntfs_debug("Entering."); 663 ntfs_debug("Entering.");
@@ -632,24 +666,15 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi)
632 ntfs_debug("Done. ($LogFile is empty.)"); 666 ntfs_debug("Done. ($LogFile is empty.)");
633 return TRUE; 667 return TRUE;
634 } 668 }
635 /* 669 BUG_ON(!rp);
636 * Read the first restart page. It will be possibly incomplete and 670 if (!ntfs_is_rstr_record(rp->magic) &&
637 * will not be multi sector transfer deprotected but we only need the 671 !ntfs_is_chkd_record(rp->magic)) {
638 * first NTFS_BLOCK_SIZE bytes so it does not matter. 672 ntfs_error(vol->sb, "Restart page buffer is invalid. This is "
639 */ 673 "probably a bug in that the $LogFile should "
640 page = ntfs_map_page(log_vi->i_mapping, 0); 674 "have been consistency checked before calling "
641 if (IS_ERR(page)) { 675 "this function.");
642 ntfs_error(vol->sb, "Error mapping $LogFile page (index 0).");
643 return FALSE; 676 return FALSE;
644 } 677 }
645 rp = (RESTART_PAGE_HEADER*)page_address(page);
646 if (!ntfs_is_rstr_record(rp->magic)) {
647 ntfs_error(vol->sb, "No restart page found at offset zero in "
648 "$LogFile. This is probably a bug in that "
649 "the $LogFile should have been consistency "
650 "checked before calling this function.");
651 goto err_out;
652 }
653 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); 678 ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
654 /* 679 /*
655 * If the $LogFile has active clients, i.e. it is open, and we do not 680 * If the $LogFile has active clients, i.e. it is open, and we do not
@@ -659,15 +684,11 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi)
659 if (ra->client_in_use_list != LOGFILE_NO_CLIENT && 684 if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
660 !(ra->flags & RESTART_VOLUME_IS_CLEAN)) { 685 !(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
661 ntfs_debug("Done. $LogFile indicates a dirty shutdown."); 686 ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
662 goto err_out; 687 return FALSE;
663 } 688 }
664 ntfs_unmap_page(page);
665 /* $LogFile indicates a clean shutdown. */ 689 /* $LogFile indicates a clean shutdown. */
666 ntfs_debug("Done. $LogFile indicates a clean shutdown."); 690 ntfs_debug("Done. $LogFile indicates a clean shutdown.");
667 return TRUE; 691 return TRUE;
668err_out:
669 ntfs_unmap_page(page);
670 return FALSE;
671} 692}
672 693
673/** 694/**
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
index 4ee4378de061..42388f95ea6d 100644
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -2,7 +2,7 @@
2 * logfile.h - Defines for NTFS kernel journal ($LogFile) handling. Part of 2 * logfile.h - Defines for NTFS kernel journal ($LogFile) handling. Part of
3 * the Linux-NTFS project. 3 * the Linux-NTFS project.
4 * 4 *
5 * Copyright (c) 2000-2004 Anton Altaparmakov 5 * Copyright (c) 2000-2005 Anton Altaparmakov
6 * 6 *
7 * This program/include file is free software; you can redistribute it and/or 7 * This program/include file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as published 8 * modify it under the terms of the GNU General Public License as published
@@ -296,9 +296,11 @@ typedef struct {
296/* sizeof() = 160 (0xa0) bytes */ 296/* sizeof() = 160 (0xa0) bytes */
297} __attribute__ ((__packed__)) LOG_CLIENT_RECORD; 297} __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
298 298
299extern BOOL ntfs_check_logfile(struct inode *log_vi); 299extern BOOL ntfs_check_logfile(struct inode *log_vi,
300 RESTART_PAGE_HEADER **rp);
300 301
301extern BOOL ntfs_is_logfile_clean(struct inode *log_vi); 302extern BOOL ntfs_is_logfile_clean(struct inode *log_vi,
303 const RESTART_PAGE_HEADER *rp);
302 304
303extern BOOL ntfs_empty_logfile(struct inode *log_vi); 305extern BOOL ntfs_empty_logfile(struct inode *log_vi);
304 306
diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
index fac5944df6d8..9994e019a3cf 100644
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -27,27 +27,63 @@
27#include <linux/highmem.h> 27#include <linux/highmem.h>
28 28
29/** 29/**
30 * ntfs_malloc_nofs - allocate memory in multiples of pages 30 * __ntfs_malloc - allocate memory in multiples of pages
31 * @size number of bytes to allocate 31 * @size: number of bytes to allocate
32 * @gfp_mask: extra flags for the allocator
33 *
34 * Internal function. You probably want ntfs_malloc_nofs()...
32 * 35 *
33 * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and 36 * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
34 * returns a pointer to the allocated memory. 37 * returns a pointer to the allocated memory.
35 * 38 *
36 * If there was insufficient memory to complete the request, return NULL. 39 * If there was insufficient memory to complete the request, return NULL.
40 * Depending on @gfp_mask the allocation may be guaranteed to succeed.
37 */ 41 */
38static inline void *ntfs_malloc_nofs(unsigned long size) 42static inline void *__ntfs_malloc(unsigned long size,
43 unsigned int __nocast gfp_mask)
39{ 44{
40 if (likely(size <= PAGE_SIZE)) { 45 if (likely(size <= PAGE_SIZE)) {
41 BUG_ON(!size); 46 BUG_ON(!size);
42 /* kmalloc() has per-CPU caches so is faster for now. */ 47 /* kmalloc() has per-CPU caches so is faster for now. */
43 return kmalloc(PAGE_SIZE, GFP_NOFS); 48 return kmalloc(PAGE_SIZE, gfp_mask);
44 /* return (void *)__get_free_page(GFP_NOFS | __GFP_HIGHMEM); */ 49 /* return (void *)__get_free_page(gfp_mask); */
45 } 50 }
46 if (likely(size >> PAGE_SHIFT < num_physpages)) 51 if (likely(size >> PAGE_SHIFT < num_physpages))
47 return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL); 52 return __vmalloc(size, gfp_mask, PAGE_KERNEL);
48 return NULL; 53 return NULL;
49} 54}
50 55
56/**
57 * ntfs_malloc_nofs - allocate memory in multiples of pages
58 * @size: number of bytes to allocate
59 *
60 * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
61 * returns a pointer to the allocated memory.
62 *
63 * If there was insufficient memory to complete the request, return NULL.
64 */
65static inline void *ntfs_malloc_nofs(unsigned long size)
66{
67 return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM);
68}
69
70/**
71 * ntfs_malloc_nofs_nofail - allocate memory in multiples of pages
72 * @size: number of bytes to allocate
73 *
74 * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
75 * returns a pointer to the allocated memory.
76 *
77 * This function guarantees that the allocation will succeed. It will sleep
78 * for as long as it takes to complete the allocation.
79 *
80 * If there was insufficient memory to complete the request, return NULL.
81 */
82static inline void *ntfs_malloc_nofs_nofail(unsigned long size)
83{
84 return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM | __GFP_NOFAIL);
85}
86
51static inline void ntfs_free(void *addr) 87static inline void ntfs_free(void *addr)
52{ 88{
53 if (likely(((unsigned long)addr < VMALLOC_START) || 89 if (likely(((unsigned long)addr < VMALLOC_START) ||
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 317f7c679fd3..2c32b84385a8 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -511,7 +511,6 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
511 } while (bh); 511 } while (bh);
512 tail->b_this_page = head; 512 tail->b_this_page = head;
513 attach_page_buffers(page, head); 513 attach_page_buffers(page, head);
514 BUG_ON(!page_has_buffers(page));
515 } 514 }
516 bh = head = page_buffers(page); 515 bh = head = page_buffers(page);
517 BUG_ON(!bh); 516 BUG_ON(!bh);
@@ -692,7 +691,6 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
692 */ 691 */
693 if (!NInoTestClearDirty(ni)) 692 if (!NInoTestClearDirty(ni))
694 goto done; 693 goto done;
695 BUG_ON(!page_has_buffers(page));
696 bh = head = page_buffers(page); 694 bh = head = page_buffers(page);
697 BUG_ON(!bh); 695 BUG_ON(!bh);
698 rl = NULL; 696 rl = NULL;
@@ -1955,7 +1953,7 @@ restore_undo_alloc:
1955 a = ctx->attr; 1953 a = ctx->attr;
1956 a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); 1954 a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
1957undo_alloc: 1955undo_alloc:
1958 if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1) < 0) { 1956 if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1, TRUE) < 0) {
1959 ntfs_error(vol->sb, "Failed to free clusters from mft data " 1957 ntfs_error(vol->sb, "Failed to free clusters from mft data "
1960 "attribute.%s", es); 1958 "attribute.%s", es);
1961 NVolSetErrors(vol); 1959 NVolSetErrors(vol);
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index 758855b0414e..f5b2ac929081 100644
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -35,7 +35,7 @@ static inline void ntfs_rl_mm(runlist_element *base, int dst, int src,
35 int size) 35 int size)
36{ 36{
37 if (likely((dst != src) && (size > 0))) 37 if (likely((dst != src) && (size > 0)))
38 memmove(base + dst, base + src, size * sizeof (*base)); 38 memmove(base + dst, base + src, size * sizeof(*base));
39} 39}
40 40
41/** 41/**
@@ -95,6 +95,51 @@ static inline runlist_element *ntfs_rl_realloc(runlist_element *rl,
95} 95}
96 96
97/** 97/**
98 * ntfs_rl_realloc_nofail - Reallocate memory for runlists
99 * @rl: original runlist
100 * @old_size: number of runlist elements in the original runlist @rl
101 * @new_size: number of runlist elements we need space for
102 *
103 * As the runlists grow, more memory will be required. To prevent the
104 * kernel having to allocate and reallocate large numbers of small bits of
105 * memory, this function returns an entire page of memory.
106 *
107 * This function guarantees that the allocation will succeed. It will sleep
108 * for as long as it takes to complete the allocation.
109 *
110 * It is up to the caller to serialize access to the runlist @rl.
111 *
112 * N.B. If the new allocation doesn't require a different number of pages in
113 * memory, the function will return the original pointer.
114 *
115 * On success, return a pointer to the newly allocated, or recycled, memory.
116 * On error, return -errno. The following error codes are defined:
117 * -ENOMEM - Not enough memory to allocate runlist array.
118 * -EINVAL - Invalid parameters were passed in.
119 */
120static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl,
121 int old_size, int new_size)
122{
123 runlist_element *new_rl;
124
125 old_size = PAGE_ALIGN(old_size * sizeof(*rl));
126 new_size = PAGE_ALIGN(new_size * sizeof(*rl));
127 if (old_size == new_size)
128 return rl;
129
130 new_rl = ntfs_malloc_nofs_nofail(new_size);
131 BUG_ON(!new_rl);
132
133 if (likely(rl != NULL)) {
134 if (unlikely(old_size > new_size))
135 old_size = new_size;
136 memcpy(new_rl, rl, old_size);
137 ntfs_free(rl);
138 }
139 return new_rl;
140}
141
142/**
98 * ntfs_are_rl_mergeable - test if two runlists can be joined together 143 * ntfs_are_rl_mergeable - test if two runlists can be joined together
99 * @dst: original runlist 144 * @dst: original runlist
100 * @src: new runlist to test for mergeability with @dst 145 * @src: new runlist to test for mergeability with @dst
@@ -497,6 +542,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
497 /* Scan to the end of the source runlist. */ 542 /* Scan to the end of the source runlist. */
498 for (dend = 0; likely(drl[dend].length); dend++) 543 for (dend = 0; likely(drl[dend].length); dend++)
499 ; 544 ;
545 dend++;
500 drl = ntfs_rl_realloc(drl, dend, dend + 1); 546 drl = ntfs_rl_realloc(drl, dend, dend + 1);
501 if (IS_ERR(drl)) 547 if (IS_ERR(drl))
502 return drl; 548 return drl;
@@ -566,8 +612,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
566 ((drl[dins].vcn + drl[dins].length) <= /* End of hole */ 612 ((drl[dins].vcn + drl[dins].length) <= /* End of hole */
567 (srl[send - 1].vcn + srl[send - 1].length))); 613 (srl[send - 1].vcn + srl[send - 1].length)));
568 614
569 /* Or we'll lose an end marker */ 615 /* Or we will lose an end marker. */
570 if (start && finish && (drl[dins].length == 0)) 616 if (finish && !drl[dins].length)
571 ss++; 617 ss++;
572 if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn)) 618 if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
573 finish = FALSE; 619 finish = FALSE;
@@ -621,11 +667,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
621 if (drl[ds].lcn != LCN_RL_NOT_MAPPED) { 667 if (drl[ds].lcn != LCN_RL_NOT_MAPPED) {
622 /* Add an unmapped runlist element. */ 668 /* Add an unmapped runlist element. */
623 if (!slots) { 669 if (!slots) {
624 /* FIXME/TODO: We need to have the 670 drl = ntfs_rl_realloc_nofail(drl, ds,
625 * extra memory already! (AIA) */ 671 ds + 2);
626 drl = ntfs_rl_realloc(drl, ds, ds + 2);
627 if (!drl)
628 goto critical_error;
629 slots = 2; 672 slots = 2;
630 } 673 }
631 ds++; 674 ds++;
@@ -640,13 +683,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
640 drl[ds].length = marker_vcn - drl[ds].vcn; 683 drl[ds].length = marker_vcn - drl[ds].vcn;
641 /* Finally add the ENOENT terminator. */ 684 /* Finally add the ENOENT terminator. */
642 ds++; 685 ds++;
643 if (!slots) { 686 if (!slots)
644 /* FIXME/TODO: We need to have the extra 687 drl = ntfs_rl_realloc_nofail(drl, ds, ds + 1);
645 * memory already! (AIA) */
646 drl = ntfs_rl_realloc(drl, ds, ds + 1);
647 if (!drl)
648 goto critical_error;
649 }
650 drl[ds].vcn = marker_vcn; 688 drl[ds].vcn = marker_vcn;
651 drl[ds].lcn = LCN_ENOENT; 689 drl[ds].lcn = LCN_ENOENT;
652 drl[ds].length = (s64)0; 690 drl[ds].length = (s64)0;
@@ -659,11 +697,6 @@ finished:
659 ntfs_debug("Merged runlist:"); 697 ntfs_debug("Merged runlist:");
660 ntfs_debug_dump_runlist(drl); 698 ntfs_debug_dump_runlist(drl);
661 return drl; 699 return drl;
662
663critical_error:
664 /* Critical error! We cannot afford to fail here. */
665 ntfs_error(NULL, "Critical error! Not enough memory.");
666 panic("NTFS: Cannot continue.");
667} 700}
668 701
669/** 702/**
@@ -727,6 +760,9 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
727 ntfs_error(vol->sb, "Corrupt attribute."); 760 ntfs_error(vol->sb, "Corrupt attribute.");
728 return ERR_PTR(-EIO); 761 return ERR_PTR(-EIO);
729 } 762 }
763 /* If the mapping pairs array is valid but empty, nothing to do. */
764 if (!vcn && !*buf)
765 return old_rl;
730 /* Current position in runlist array. */ 766 /* Current position in runlist array. */
731 rlpos = 0; 767 rlpos = 0;
732 /* Allocate first page and set current runlist size to one page. */ 768 /* Allocate first page and set current runlist size to one page. */
@@ -1419,6 +1455,7 @@ err_out:
1419 1455
1420/** 1456/**
1421 * ntfs_rl_truncate_nolock - truncate a runlist starting at a specified vcn 1457 * ntfs_rl_truncate_nolock - truncate a runlist starting at a specified vcn
1458 * @vol: ntfs volume (needed for error output)
1422 * @runlist: runlist to truncate 1459 * @runlist: runlist to truncate
1423 * @new_length: the new length of the runlist in VCNs 1460 * @new_length: the new length of the runlist in VCNs
1424 * 1461 *
@@ -1426,12 +1463,16 @@ err_out:
1426 * holding the runlist elements to a length of @new_length VCNs. 1463 * holding the runlist elements to a length of @new_length VCNs.
1427 * 1464 *
1428 * If @new_length lies within the runlist, the runlist elements with VCNs of 1465 * If @new_length lies within the runlist, the runlist elements with VCNs of
1429 * @new_length and above are discarded. 1466 * @new_length and above are discarded. As a special case if @new_length is
1467 * zero, the runlist is discarded and set to NULL.
1430 * 1468 *
1431 * If @new_length lies beyond the runlist, a sparse runlist element is added to 1469 * If @new_length lies beyond the runlist, a sparse runlist element is added to
1432 * the end of the runlist @runlist or if the last runlist element is a sparse 1470 * the end of the runlist @runlist or if the last runlist element is a sparse
1433 * one already, this is extended. 1471 * one already, this is extended.
1434 * 1472 *
1473 * Note, no checking is done for unmapped runlist elements. It is assumed that
1474 * the caller has mapped any elements that need to be mapped already.
1475 *
1435 * Return 0 on success and -errno on error. 1476 * Return 0 on success and -errno on error.
1436 * 1477 *
1437 * Locking: The caller must hold @runlist->lock for writing. 1478 * Locking: The caller must hold @runlist->lock for writing.
@@ -1446,6 +1487,13 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
1446 BUG_ON(!runlist); 1487 BUG_ON(!runlist);
1447 BUG_ON(new_length < 0); 1488 BUG_ON(new_length < 0);
1448 rl = runlist->rl; 1489 rl = runlist->rl;
1490 if (!new_length) {
1491 ntfs_debug("Freeing runlist.");
1492 runlist->rl = NULL;
1493 if (rl)
1494 ntfs_free(rl);
1495 return 0;
1496 }
1449 if (unlikely(!rl)) { 1497 if (unlikely(!rl)) {
1450 /* 1498 /*
1451 * Create a runlist consisting of a sparse runlist element of 1499 * Create a runlist consisting of a sparse runlist element of
@@ -1553,4 +1601,288 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
1553 return 0; 1601 return 0;
1554} 1602}
1555 1603
1604/**
1605 * ntfs_rl_punch_nolock - punch a hole into a runlist
1606 * @vol: ntfs volume (needed for error output)
1607 * @runlist: runlist to punch a hole into
1608 * @start: starting VCN of the hole to be created
1609 * @length: size of the hole to be created in units of clusters
1610 *
1611 * Punch a hole into the runlist @runlist starting at VCN @start and of size
1612 * @length clusters.
1613 *
1614 * Return 0 on success and -errno on error, in which case @runlist has not been
1615 * modified.
1616 *
1617 * If @start and/or @start + @length are outside the runlist return error code
1618 * -ENOENT.
1619 *
1620 * If the runlist contains unmapped or error elements between @start and @start
1621 * + @length return error code -EINVAL.
1622 *
1623 * Locking: The caller must hold @runlist->lock for writing.
1624 */
1625int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
1626 const VCN start, const s64 length)
1627{
1628 const VCN end = start + length;
1629 s64 delta;
1630 runlist_element *rl, *rl_end, *rl_real_end, *trl;
1631 int old_size;
1632 BOOL lcn_fixup = FALSE;
1633
1634 ntfs_debug("Entering for start 0x%llx, length 0x%llx.",
1635 (long long)start, (long long)length);
1636 BUG_ON(!runlist);
1637 BUG_ON(start < 0);
1638 BUG_ON(length < 0);
1639 BUG_ON(end < 0);
1640 rl = runlist->rl;
1641 if (unlikely(!rl)) {
1642 if (likely(!start && !length))
1643 return 0;
1644 return -ENOENT;
1645 }
1646 /* Find @start in the runlist. */
1647 while (likely(rl->length && start >= rl[1].vcn))
1648 rl++;
1649 rl_end = rl;
1650 /* Find @end in the runlist. */
1651 while (likely(rl_end->length && end >= rl_end[1].vcn)) {
1652 /* Verify there are no unmapped or error elements. */
1653 if (unlikely(rl_end->lcn < LCN_HOLE))
1654 return -EINVAL;
1655 rl_end++;
1656 }
1657 /* Check the last element. */
1658 if (unlikely(rl_end->length && rl_end->lcn < LCN_HOLE))
1659 return -EINVAL;
1660 /* This covers @start being out of bounds, too. */
1661 if (!rl_end->length && end > rl_end->vcn)
1662 return -ENOENT;
1663 if (!length)
1664 return 0;
1665 if (!rl->length)
1666 return -ENOENT;
1667 rl_real_end = rl_end;
1668 /* Determine the runlist size. */
1669 while (likely(rl_real_end->length))
1670 rl_real_end++;
1671 old_size = rl_real_end - runlist->rl + 1;
1672 /* If @start is in a hole simply extend the hole. */
1673 if (rl->lcn == LCN_HOLE) {
1674 /*
1675 * If both @start and @end are in the same sparse run, we are
1676 * done.
1677 */
1678 if (end <= rl[1].vcn) {
1679 ntfs_debug("Done (requested hole is already sparse).");
1680 return 0;
1681 }
1682extend_hole:
1683 /* Extend the hole. */
1684 rl->length = end - rl->vcn;
1685 /* If @end is in a hole, merge it with the current one. */
1686 if (rl_end->lcn == LCN_HOLE) {
1687 rl_end++;
1688 rl->length = rl_end->vcn - rl->vcn;
1689 }
1690 /* We have done the hole. Now deal with the remaining tail. */
1691 rl++;
1692 /* Cut out all runlist elements up to @end. */
1693 if (rl < rl_end)
1694 memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
1695 sizeof(*rl));
1696 /* Adjust the beginning of the tail if necessary. */
1697 if (end > rl->vcn) {
1698 s64 delta = end - rl->vcn;
1699 rl->vcn = end;
1700 rl->length -= delta;
1701 /* Only adjust the lcn if it is real. */
1702 if (rl->lcn >= 0)
1703 rl->lcn += delta;
1704 }
1705shrink_allocation:
1706 /* Reallocate memory if the allocation changed. */
1707 if (rl < rl_end) {
1708 rl = ntfs_rl_realloc(runlist->rl, old_size,
1709 old_size - (rl_end - rl));
1710 if (IS_ERR(rl))
1711 ntfs_warning(vol->sb, "Failed to shrink "
1712 "runlist buffer. This just "
1713 "wastes a bit of memory "
1714 "temporarily so we ignore it "
1715 "and return success.");
1716 else
1717 runlist->rl = rl;
1718 }
1719 ntfs_debug("Done (extend hole).");
1720 return 0;
1721 }
1722 /*
1723 * If @start is at the beginning of a run things are easier as there is
1724 * no need to split the first run.
1725 */
1726 if (start == rl->vcn) {
1727 /*
1728 * @start is at the beginning of a run.
1729 *
1730 * If the previous run is sparse, extend its hole.
1731 *
1732 * If @end is not in the same run, switch the run to be sparse
1733 * and extend the newly created hole.
1734 *
1735 * Thus both of these cases reduce the problem to the above
1736 * case of "@start is in a hole".
1737 */
1738 if (rl > runlist->rl && (rl - 1)->lcn == LCN_HOLE) {
1739 rl--;
1740 goto extend_hole;
1741 }
1742 if (end >= rl[1].vcn) {
1743 rl->lcn = LCN_HOLE;
1744 goto extend_hole;
1745 }
1746 /*
1747 * The final case is when @end is in the same run as @start.
1748 * For this need to split the run into two. One run for the
1749 * sparse region between the beginning of the old run, i.e.
1750 * @start, and @end and one for the remaining non-sparse
1751 * region, i.e. between @end and the end of the old run.
1752 */
1753 trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
1754 if (IS_ERR(trl))
1755 goto enomem_out;
1756 old_size++;
1757 if (runlist->rl != trl) {
1758 rl = trl + (rl - runlist->rl);
1759 rl_end = trl + (rl_end - runlist->rl);
1760 rl_real_end = trl + (rl_real_end - runlist->rl);
1761 runlist->rl = trl;
1762 }
1763split_end:
1764 /* Shift all the runs up by one. */
1765 memmove(rl + 1, rl, (rl_real_end - rl + 1) * sizeof(*rl));
1766 /* Finally, setup the two split runs. */
1767 rl->lcn = LCN_HOLE;
1768 rl->length = length;
1769 rl++;
1770 rl->vcn += length;
1771 /* Only adjust the lcn if it is real. */
1772 if (rl->lcn >= 0 || lcn_fixup)
1773 rl->lcn += length;
1774 rl->length -= length;
1775 ntfs_debug("Done (split one).");
1776 return 0;
1777 }
1778 /*
1779 * @start is neither in a hole nor at the beginning of a run.
1780 *
1781 * If @end is in a hole, things are easier as simply truncating the run
1782 * @start is in to end at @start - 1, deleting all runs after that up
1783 * to @end, and finally extending the beginning of the run @end is in
1784 * to be @start is all that is needed.
1785 */
1786 if (rl_end->lcn == LCN_HOLE) {
1787 /* Truncate the run containing @start. */
1788 rl->length = start - rl->vcn;
1789 rl++;
1790 /* Cut out all runlist elements up to @end. */
1791 if (rl < rl_end)
1792 memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
1793 sizeof(*rl));
1794 /* Extend the beginning of the run @end is in to be @start. */
1795 rl->vcn = start;
1796 rl->length = rl[1].vcn - start;
1797 goto shrink_allocation;
1798 }
1799 /*
1800 * If @end is not in a hole there are still two cases to distinguish.
1801 * Either @end is or is not in the same run as @start.
1802 *
1803 * The second case is easier as it can be reduced to an already solved
1804 * problem by truncating the run @start is in to end at @start - 1.
1805 * Then, if @end is in the next run need to split the run into a sparse
1806 * run followed by a non-sparse run (already covered above) and if @end
1807 * is not in the next run switching it to be sparse, again reduces the
1808 * problem to the already covered case of "@start is in a hole".
1809 */
1810 if (end >= rl[1].vcn) {
1811 /*
1812 * If @end is not in the next run, reduce the problem to the
1813 * case of "@start is in a hole".
1814 */
1815 if (rl[1].length && end >= rl[2].vcn) {
1816 /* Truncate the run containing @start. */
1817 rl->length = start - rl->vcn;
1818 rl++;
1819 rl->vcn = start;
1820 rl->lcn = LCN_HOLE;
1821 goto extend_hole;
1822 }
1823 trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
1824 if (IS_ERR(trl))
1825 goto enomem_out;
1826 old_size++;
1827 if (runlist->rl != trl) {
1828 rl = trl + (rl - runlist->rl);
1829 rl_end = trl + (rl_end - runlist->rl);
1830 rl_real_end = trl + (rl_real_end - runlist->rl);
1831 runlist->rl = trl;
1832 }
1833 /* Truncate the run containing @start. */
1834 rl->length = start - rl->vcn;
1835 rl++;
1836 /*
1837 * @end is in the next run, reduce the problem to the case
1838 * where "@start is at the beginning of a run and @end is in
1839 * the same run as @start".
1840 */
1841 delta = rl->vcn - start;
1842 rl->vcn = start;
1843 if (rl->lcn >= 0) {
1844 rl->lcn -= delta;
1845 /* Need this in case the lcn just became negative. */
1846 lcn_fixup = TRUE;
1847 }
1848 rl->length += delta;
1849 goto split_end;
1850 }
1851 /*
1852 * The first case from above, i.e. @end is in the same run as @start.
1853 * We need to split the run into three. One run for the non-sparse
1854 * region between the beginning of the old run and @start, one for the
1855 * sparse region between @start and @end, and one for the remaining
1856 * non-sparse region, i.e. between @end and the end of the old run.
1857 */
1858 trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 2);
1859 if (IS_ERR(trl))
1860 goto enomem_out;
1861 old_size += 2;
1862 if (runlist->rl != trl) {
1863 rl = trl + (rl - runlist->rl);
1864 rl_end = trl + (rl_end - runlist->rl);
1865 rl_real_end = trl + (rl_real_end - runlist->rl);
1866 runlist->rl = trl;
1867 }
1868 /* Shift all the runs up by two. */
1869 memmove(rl + 2, rl, (rl_real_end - rl + 1) * sizeof(*rl));
1870 /* Finally, setup the three split runs. */
1871 rl->length = start - rl->vcn;
1872 rl++;
1873 rl->vcn = start;
1874 rl->lcn = LCN_HOLE;
1875 rl->length = length;
1876 rl++;
1877 delta = end - rl->vcn;
1878 rl->vcn = end;
1879 rl->lcn += delta;
1880 rl->length -= delta;
1881 ntfs_debug("Done (split both).");
1882 return 0;
1883enomem_out:
1884 ntfs_error(vol->sb, "Not enough memory to extend runlist buffer.");
1885 return -ENOMEM;
1886}
1887
1556#endif /* NTFS_RW */ 1888#endif /* NTFS_RW */
diff --git a/fs/ntfs/runlist.h b/fs/ntfs/runlist.h
index aa0ee6540e7c..47728fbb610b 100644
--- a/fs/ntfs/runlist.h
+++ b/fs/ntfs/runlist.h
@@ -94,6 +94,9 @@ extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
94extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol, 94extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,
95 runlist *const runlist, const s64 new_length); 95 runlist *const runlist, const s64 new_length);
96 96
97int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
98 const VCN start, const s64 length);
99
97#endif /* NTFS_RW */ 100#endif /* NTFS_RW */
98 101
99#endif /* _LINUX_NTFS_RUNLIST_H */ 102#endif /* _LINUX_NTFS_RUNLIST_H */
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 41aa8eb6755b..b2b392961268 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1133,7 +1133,8 @@ mft_unmap_out:
1133 * 1133 *
1134 * Return TRUE on success or FALSE on error. 1134 * Return TRUE on success or FALSE on error.
1135 */ 1135 */
1136static BOOL load_and_check_logfile(ntfs_volume *vol) 1136static BOOL load_and_check_logfile(ntfs_volume *vol,
1137 RESTART_PAGE_HEADER **rp)
1137{ 1138{
1138 struct inode *tmp_ino; 1139 struct inode *tmp_ino;
1139 1140
@@ -1145,7 +1146,7 @@ static BOOL load_and_check_logfile(ntfs_volume *vol)
1145 /* Caller will display error message. */ 1146 /* Caller will display error message. */
1146 return FALSE; 1147 return FALSE;
1147 } 1148 }
1148 if (!ntfs_check_logfile(tmp_ino)) { 1149 if (!ntfs_check_logfile(tmp_ino, rp)) {
1149 iput(tmp_ino); 1150 iput(tmp_ino);
1150 /* ntfs_check_logfile() will have displayed error output. */ 1151 /* ntfs_check_logfile() will have displayed error output. */
1151 return FALSE; 1152 return FALSE;
@@ -1689,6 +1690,7 @@ static BOOL load_system_files(ntfs_volume *vol)
1689 VOLUME_INFORMATION *vi; 1690 VOLUME_INFORMATION *vi;
1690 ntfs_attr_search_ctx *ctx; 1691 ntfs_attr_search_ctx *ctx;
1691#ifdef NTFS_RW 1692#ifdef NTFS_RW
1693 RESTART_PAGE_HEADER *rp;
1692 int err; 1694 int err;
1693#endif /* NTFS_RW */ 1695#endif /* NTFS_RW */
1694 1696
@@ -1841,8 +1843,9 @@ get_ctx_vol_failed:
1841 * Get the inode for the logfile, check it and determine if the volume 1843 * Get the inode for the logfile, check it and determine if the volume
1842 * was shutdown cleanly. 1844 * was shutdown cleanly.
1843 */ 1845 */
1844 if (!load_and_check_logfile(vol) || 1846 rp = NULL;
1845 !ntfs_is_logfile_clean(vol->logfile_ino)) { 1847 if (!load_and_check_logfile(vol, &rp) ||
1848 !ntfs_is_logfile_clean(vol->logfile_ino, rp)) {
1846 static const char *es1a = "Failed to load $LogFile"; 1849 static const char *es1a = "Failed to load $LogFile";
1847 static const char *es1b = "$LogFile is not clean"; 1850 static const char *es1b = "$LogFile is not clean";
1848 static const char *es2 = ". Mount in Windows."; 1851 static const char *es2 = ". Mount in Windows.";
@@ -1857,6 +1860,10 @@ get_ctx_vol_failed:
1857 "continue nor on_errors=" 1860 "continue nor on_errors="
1858 "remount-ro was specified%s", 1861 "remount-ro was specified%s",
1859 es1, es2); 1862 es1, es2);
1863 if (vol->logfile_ino) {
1864 BUG_ON(!rp);
1865 ntfs_free(rp);
1866 }
1860 goto iput_logfile_err_out; 1867 goto iput_logfile_err_out;
1861 } 1868 }
1862 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 1869 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
@@ -1867,6 +1874,7 @@ get_ctx_vol_failed:
1867 /* This will prevent a read-write remount. */ 1874 /* This will prevent a read-write remount. */
1868 NVolSetErrors(vol); 1875 NVolSetErrors(vol);
1869 } 1876 }
1877 ntfs_free(rp);
1870#endif /* NTFS_RW */ 1878#endif /* NTFS_RW */
1871 /* Get the root directory inode so we can do path lookups. */ 1879 /* Get the root directory inode so we can do path lookups. */
1872 vol->root_ino = ntfs_iget(sb, FILE_root); 1880 vol->root_ino = ntfs_iget(sb, FILE_root);
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index 19c42e231b44..a389a5a16c84 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -372,7 +372,8 @@ retry: wc = nls->uni2char(le16_to_cpu(ins[i]), ns + o,
372 return -EINVAL; 372 return -EINVAL;
373conversion_err: 373conversion_err:
374 ntfs_error(vol->sb, "Unicode name contains characters that cannot be " 374 ntfs_error(vol->sb, "Unicode name contains characters that cannot be "
375 "converted to character set %s.", nls->charset); 375 "converted to character set %s. You might want to "
376 "try to use the mount option nls=utf8.", nls->charset);
376 if (ns != *outs) 377 if (ns != *outs)
377 kfree(ns); 378 kfree(ns);
378 if (wc != -ENAMETOOLONG) 379 if (wc != -ENAMETOOLONG)
diff --git a/fs/open.c b/fs/open.c
index 4ee2dcc31c28..2fac58c51910 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -24,6 +24,7 @@
24#include <linux/personality.h> 24#include <linux/personality.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26#include <linux/syscalls.h> 26#include <linux/syscalls.h>
27#include <linux/rcupdate.h>
27 28
28#include <asm/unistd.h> 29#include <asm/unistd.h>
29 30
@@ -842,14 +843,16 @@ int get_unused_fd(void)
842{ 843{
843 struct files_struct * files = current->files; 844 struct files_struct * files = current->files;
844 int fd, error; 845 int fd, error;
846 struct fdtable *fdt;
845 847
846 error = -EMFILE; 848 error = -EMFILE;
847 spin_lock(&files->file_lock); 849 spin_lock(&files->file_lock);
848 850
849repeat: 851repeat:
850 fd = find_next_zero_bit(files->open_fds->fds_bits, 852 fdt = files_fdtable(files);
851 files->max_fdset, 853 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
852 files->next_fd); 854 fdt->max_fdset,
855 fdt->next_fd);
853 856
854 /* 857 /*
855 * N.B. For clone tasks sharing a files structure, this test 858 * N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +875,14 @@ repeat:
872 goto repeat; 875 goto repeat;
873 } 876 }
874 877
875 FD_SET(fd, files->open_fds); 878 FD_SET(fd, fdt->open_fds);
876 FD_CLR(fd, files->close_on_exec); 879 FD_CLR(fd, fdt->close_on_exec);
877 files->next_fd = fd + 1; 880 fdt->next_fd = fd + 1;
878#if 1 881#if 1
879 /* Sanity check */ 882 /* Sanity check */
880 if (files->fd[fd] != NULL) { 883 if (fdt->fd[fd] != NULL) {
881 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); 884 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
882 files->fd[fd] = NULL; 885 fdt->fd[fd] = NULL;
883 } 886 }
884#endif 887#endif
885 error = fd; 888 error = fd;
@@ -893,9 +896,10 @@ EXPORT_SYMBOL(get_unused_fd);
893 896
894static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 897static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
895{ 898{
896 __FD_CLR(fd, files->open_fds); 899 struct fdtable *fdt = files_fdtable(files);
897 if (fd < files->next_fd) 900 __FD_CLR(fd, fdt->open_fds);
898 files->next_fd = fd; 901 if (fd < fdt->next_fd)
902 fdt->next_fd = fd;
899} 903}
900 904
901void fastcall put_unused_fd(unsigned int fd) 905void fastcall put_unused_fd(unsigned int fd)
@@ -924,10 +928,11 @@ EXPORT_SYMBOL(put_unused_fd);
924void fastcall fd_install(unsigned int fd, struct file * file) 928void fastcall fd_install(unsigned int fd, struct file * file)
925{ 929{
926 struct files_struct *files = current->files; 930 struct files_struct *files = current->files;
931 struct fdtable *fdt;
927 spin_lock(&files->file_lock); 932 spin_lock(&files->file_lock);
928 if (unlikely(files->fd[fd] != NULL)) 933 fdt = files_fdtable(files);
929 BUG(); 934 BUG_ON(fdt->fd[fd] != NULL);
930 files->fd[fd] = file; 935 rcu_assign_pointer(fdt->fd[fd], file);
931 spin_unlock(&files->file_lock); 936 spin_unlock(&files->file_lock);
932} 937}
933 938
@@ -1010,15 +1015,17 @@ asmlinkage long sys_close(unsigned int fd)
1010{ 1015{
1011 struct file * filp; 1016 struct file * filp;
1012 struct files_struct *files = current->files; 1017 struct files_struct *files = current->files;
1018 struct fdtable *fdt;
1013 1019
1014 spin_lock(&files->file_lock); 1020 spin_lock(&files->file_lock);
1015 if (fd >= files->max_fds) 1021 fdt = files_fdtable(files);
1022 if (fd >= fdt->max_fds)
1016 goto out_unlock; 1023 goto out_unlock;
1017 filp = files->fd[fd]; 1024 filp = fdt->fd[fd];
1018 if (!filp) 1025 if (!filp)
1019 goto out_unlock; 1026 goto out_unlock;
1020 files->fd[fd] = NULL; 1027 rcu_assign_pointer(fdt->fd[fd], NULL);
1021 FD_CLR(fd, files->close_on_exec); 1028 FD_CLR(fd, fdt->close_on_exec);
1022 __put_unused_fd(files, fd); 1029 __put_unused_fd(files, fd);
1023 spin_unlock(&files->file_lock); 1030 spin_unlock(&files->file_lock);
1024 return filp_close(filp, files); 1031 return filp_close(filp, files);
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 37668fe998ad..d88d518d30f6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -159,6 +159,7 @@ static inline char * task_state(struct task_struct *p, char *buffer)
159{ 159{
160 struct group_info *group_info; 160 struct group_info *group_info;
161 int g; 161 int g;
162 struct fdtable *fdt = NULL;
162 163
163 read_lock(&tasklist_lock); 164 read_lock(&tasklist_lock);
164 buffer += sprintf(buffer, 165 buffer += sprintf(buffer,
@@ -179,10 +180,12 @@ static inline char * task_state(struct task_struct *p, char *buffer)
179 p->gid, p->egid, p->sgid, p->fsgid); 180 p->gid, p->egid, p->sgid, p->fsgid);
180 read_unlock(&tasklist_lock); 181 read_unlock(&tasklist_lock);
181 task_lock(p); 182 task_lock(p);
183 if (p->files)
184 fdt = files_fdtable(p->files);
182 buffer += sprintf(buffer, 185 buffer += sprintf(buffer,
183 "FDSize:\t%d\n" 186 "FDSize:\t%d\n"
184 "Groups:\t", 187 "Groups:\t",
185 p->files ? p->files->max_fds : 0); 188 fdt ? fdt->max_fds : 0);
186 189
187 group_info = p->group_info; 190 group_info = p->group_info;
188 get_group_info(group_info); 191 get_group_info(group_info);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 84751f3f52d5..23db452ab428 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -62,6 +62,7 @@
62#include <linux/namespace.h> 62#include <linux/namespace.h>
63#include <linux/mm.h> 63#include <linux/mm.h>
64#include <linux/smp_lock.h> 64#include <linux/smp_lock.h>
65#include <linux/rcupdate.h>
65#include <linux/kallsyms.h> 66#include <linux/kallsyms.h>
66#include <linux/mount.h> 67#include <linux/mount.h>
67#include <linux/security.h> 68#include <linux/security.h>
@@ -283,16 +284,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
283 284
284 files = get_files_struct(task); 285 files = get_files_struct(task);
285 if (files) { 286 if (files) {
286 spin_lock(&files->file_lock); 287 rcu_read_lock();
287 file = fcheck_files(files, fd); 288 file = fcheck_files(files, fd);
288 if (file) { 289 if (file) {
289 *mnt = mntget(file->f_vfsmnt); 290 *mnt = mntget(file->f_vfsmnt);
290 *dentry = dget(file->f_dentry); 291 *dentry = dget(file->f_dentry);
291 spin_unlock(&files->file_lock); 292 rcu_read_unlock();
292 put_files_struct(files); 293 put_files_struct(files);
293 return 0; 294 return 0;
294 } 295 }
295 spin_unlock(&files->file_lock); 296 rcu_read_unlock();
296 put_files_struct(files); 297 put_files_struct(files);
297 } 298 }
298 return -ENOENT; 299 return -ENOENT;
@@ -1039,6 +1040,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1039 int retval; 1040 int retval;
1040 char buf[NUMBUF]; 1041 char buf[NUMBUF];
1041 struct files_struct * files; 1042 struct files_struct * files;
1043 struct fdtable *fdt;
1042 1044
1043 retval = -ENOENT; 1045 retval = -ENOENT;
1044 if (!pid_alive(p)) 1046 if (!pid_alive(p))
@@ -1061,15 +1063,16 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1061 files = get_files_struct(p); 1063 files = get_files_struct(p);
1062 if (!files) 1064 if (!files)
1063 goto out; 1065 goto out;
1064 spin_lock(&files->file_lock); 1066 rcu_read_lock();
1067 fdt = files_fdtable(files);
1065 for (fd = filp->f_pos-2; 1068 for (fd = filp->f_pos-2;
1066 fd < files->max_fds; 1069 fd < fdt->max_fds;
1067 fd++, filp->f_pos++) { 1070 fd++, filp->f_pos++) {
1068 unsigned int i,j; 1071 unsigned int i,j;
1069 1072
1070 if (!fcheck_files(files, fd)) 1073 if (!fcheck_files(files, fd))
1071 continue; 1074 continue;
1072 spin_unlock(&files->file_lock); 1075 rcu_read_unlock();
1073 1076
1074 j = NUMBUF; 1077 j = NUMBUF;
1075 i = fd; 1078 i = fd;
@@ -1081,12 +1084,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1081 1084
1082 ino = fake_ino(tid, PROC_TID_FD_DIR + fd); 1085 ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
1083 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) { 1086 if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
1084 spin_lock(&files->file_lock); 1087 rcu_read_lock();
1085 break; 1088 break;
1086 } 1089 }
1087 spin_lock(&files->file_lock); 1090 rcu_read_lock();
1088 } 1091 }
1089 spin_unlock(&files->file_lock); 1092 rcu_read_unlock();
1090 put_files_struct(files); 1093 put_files_struct(files);
1091 } 1094 }
1092out: 1095out:
@@ -1261,9 +1264,9 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1261 1264
1262 files = get_files_struct(task); 1265 files = get_files_struct(task);
1263 if (files) { 1266 if (files) {
1264 spin_lock(&files->file_lock); 1267 rcu_read_lock();
1265 if (fcheck_files(files, fd)) { 1268 if (fcheck_files(files, fd)) {
1266 spin_unlock(&files->file_lock); 1269 rcu_read_unlock();
1267 put_files_struct(files); 1270 put_files_struct(files);
1268 if (task_dumpable(task)) { 1271 if (task_dumpable(task)) {
1269 inode->i_uid = task->euid; 1272 inode->i_uid = task->euid;
@@ -1275,7 +1278,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1275 security_task_to_inode(task, inode); 1278 security_task_to_inode(task, inode);
1276 return 1; 1279 return 1;
1277 } 1280 }
1278 spin_unlock(&files->file_lock); 1281 rcu_read_unlock();
1279 put_files_struct(files); 1282 put_files_struct(files);
1280 } 1283 }
1281 d_drop(dentry); 1284 d_drop(dentry);
@@ -1367,7 +1370,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1367 if (!files) 1370 if (!files)
1368 goto out_unlock; 1371 goto out_unlock;
1369 inode->i_mode = S_IFLNK; 1372 inode->i_mode = S_IFLNK;
1370 spin_lock(&files->file_lock); 1373 rcu_read_lock();
1371 file = fcheck_files(files, fd); 1374 file = fcheck_files(files, fd);
1372 if (!file) 1375 if (!file)
1373 goto out_unlock2; 1376 goto out_unlock2;
@@ -1375,7 +1378,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1375 inode->i_mode |= S_IRUSR | S_IXUSR; 1378 inode->i_mode |= S_IRUSR | S_IXUSR;
1376 if (file->f_mode & 2) 1379 if (file->f_mode & 2)
1377 inode->i_mode |= S_IWUSR | S_IXUSR; 1380 inode->i_mode |= S_IWUSR | S_IXUSR;
1378 spin_unlock(&files->file_lock); 1381 rcu_read_unlock();
1379 put_files_struct(files); 1382 put_files_struct(files);
1380 inode->i_op = &proc_pid_link_inode_operations; 1383 inode->i_op = &proc_pid_link_inode_operations;
1381 inode->i_size = 64; 1384 inode->i_size = 64;
@@ -1385,7 +1388,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1385 return NULL; 1388 return NULL;
1386 1389
1387out_unlock2: 1390out_unlock2:
1388 spin_unlock(&files->file_lock); 1391 rcu_read_unlock();
1389 put_files_struct(files); 1392 put_files_struct(files);
1390out_unlock: 1393out_unlock:
1391 iput(inode); 1394 iput(inode);
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 133c28685105..effa6c0c467a 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -60,6 +60,8 @@ static void proc_delete_inode(struct inode *inode)
60 struct proc_dir_entry *de; 60 struct proc_dir_entry *de;
61 struct task_struct *tsk; 61 struct task_struct *tsk;
62 62
63 truncate_inode_pages(&inode->i_data, 0);
64
63 /* Let go of any associated process */ 65 /* Let go of any associated process */
64 tsk = PROC_I(inode)->task; 66 tsk = PROC_I(inode)->task;
65 if (tsk) 67 if (tsk)
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index b79162a35478..80f32911c0cb 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -63,6 +63,7 @@ int qnx4_sync_inode(struct inode *inode)
63static void qnx4_delete_inode(struct inode *inode) 63static void qnx4_delete_inode(struct inode *inode)
64{ 64{
65 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino)); 65 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
66 truncate_inode_pages(&inode->i_data, 0);
66 inode->i_size = 0; 67 inode->i_size = 0;
67 qnx4_truncate(inode); 68 qnx4_truncate(inode);
68 lock_kernel(); 69 lock_kernel();
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ff291c973a56..1a8a1bf2154d 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -33,6 +33,8 @@ void reiserfs_delete_inode(struct inode *inode)
33 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); 33 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
34 struct reiserfs_transaction_handle th; 34 struct reiserfs_transaction_handle th;
35 35
36 truncate_inode_pages(&inode->i_data, 0);
37
36 reiserfs_write_lock(inode->i_sb); 38 reiserfs_write_lock(inode->i_sb);
37 39
38 /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ 40 /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
diff --git a/fs/select.c b/fs/select.c
index b80e7eb0ac0d..f10a10317d54 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -22,6 +22,7 @@
22#include <linux/personality.h> /* for STICKY_TIMEOUTS */ 22#include <linux/personality.h> /* for STICKY_TIMEOUTS */
23#include <linux/file.h> 23#include <linux/file.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/rcupdate.h>
25 26
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
27 28
@@ -132,11 +133,13 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds)
132 unsigned long *open_fds; 133 unsigned long *open_fds;
133 unsigned long set; 134 unsigned long set;
134 int max; 135 int max;
136 struct fdtable *fdt;
135 137
136 /* handle last in-complete long-word first */ 138 /* handle last in-complete long-word first */
137 set = ~(~0UL << (n & (__NFDBITS-1))); 139 set = ~(~0UL << (n & (__NFDBITS-1)));
138 n /= __NFDBITS; 140 n /= __NFDBITS;
139 open_fds = current->files->open_fds->fds_bits+n; 141 fdt = files_fdtable(current->files);
142 open_fds = fdt->open_fds->fds_bits+n;
140 max = 0; 143 max = 0;
141 if (set) { 144 if (set) {
142 set &= BITS(fds, n); 145 set &= BITS(fds, n);
@@ -183,9 +186,9 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
183 int retval, i; 186 int retval, i;
184 long __timeout = *timeout; 187 long __timeout = *timeout;
185 188
186 spin_lock(&current->files->file_lock); 189 rcu_read_lock();
187 retval = max_select_fd(n, fds); 190 retval = max_select_fd(n, fds);
188 spin_unlock(&current->files->file_lock); 191 rcu_read_unlock();
189 192
190 if (retval < 0) 193 if (retval < 0)
191 return retval; 194 return retval;
@@ -299,6 +302,7 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
299 char *bits; 302 char *bits;
300 long timeout; 303 long timeout;
301 int ret, size, max_fdset; 304 int ret, size, max_fdset;
305 struct fdtable *fdt;
302 306
303 timeout = MAX_SCHEDULE_TIMEOUT; 307 timeout = MAX_SCHEDULE_TIMEOUT;
304 if (tvp) { 308 if (tvp) {
@@ -326,7 +330,10 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
326 goto out_nofds; 330 goto out_nofds;
327 331
328 /* max_fdset can increase, so grab it once to avoid race */ 332 /* max_fdset can increase, so grab it once to avoid race */
329 max_fdset = current->files->max_fdset; 333 rcu_read_lock();
334 fdt = files_fdtable(current->files);
335 max_fdset = fdt->max_fdset;
336 rcu_read_unlock();
330 if (n > max_fdset) 337 if (n > max_fdset)
331 n = max_fdset; 338 n = max_fdset;
332 339
@@ -464,9 +471,15 @@ asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long ti
464 unsigned int i; 471 unsigned int i;
465 struct poll_list *head; 472 struct poll_list *head;
466 struct poll_list *walk; 473 struct poll_list *walk;
474 struct fdtable *fdt;
475 int max_fdset;
467 476
468 /* Do a sanity check on nfds ... */ 477 /* Do a sanity check on nfds ... */
469 if (nfds > current->files->max_fdset && nfds > OPEN_MAX) 478 rcu_read_lock();
479 fdt = files_fdtable(current->files);
480 max_fdset = fdt->max_fdset;
481 rcu_read_unlock();
482 if (nfds > max_fdset && nfds > OPEN_MAX)
470 return -EINVAL; 483 return -EINVAL;
471 484
472 if (timeout) { 485 if (timeout) {
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 4765aaac9fd2..10b994428fef 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -331,6 +331,7 @@ static void
331smb_delete_inode(struct inode *ino) 331smb_delete_inode(struct inode *ino)
332{ 332{
333 DEBUG1("ino=%ld\n", ino->i_ino); 333 DEBUG1("ino=%ld\n", ino->i_ino);
334 truncate_inode_pages(&ino->i_data, 0);
334 lock_kernel(); 335 lock_kernel();
335 if (smb_close(ino)) 336 if (smb_close(ino))
336 PARANOIA("could not close inode %ld\n", ino->i_ino); 337 PARANOIA("could not close inode %ld\n", ino->i_ino);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 0530077d9dd8..fa33eceb0011 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -292,6 +292,7 @@ int sysv_sync_inode(struct inode * inode)
292 292
293static void sysv_delete_inode(struct inode *inode) 293static void sysv_delete_inode(struct inode *inode)
294{ 294{
295 truncate_inode_pages(&inode->i_data, 0);
295 inode->i_size = 0; 296 inode->i_size = 0;
296 sysv_truncate(inode); 297 sysv_truncate(inode);
297 lock_kernel(); 298 lock_kernel();
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 3d68de39fad6..b83890beaaac 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -87,6 +87,8 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
87 */ 87 */
88void udf_delete_inode(struct inode * inode) 88void udf_delete_inode(struct inode * inode)
89{ 89{
90 truncate_inode_pages(&inode->i_data, 0);
91
90 if (is_bad_inode(inode)) 92 if (is_bad_inode(inode))
91 goto no_delete; 93 goto no_delete;
92 94
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 718627ca8b5c..55f4aa16e3fc 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -804,6 +804,7 @@ int ufs_sync_inode (struct inode *inode)
804 804
805void ufs_delete_inode (struct inode * inode) 805void ufs_delete_inode (struct inode * inode)
806{ 806{
807 truncate_inode_pages(&inode->i_data, 0);
807 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ 808 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
808 lock_kernel(); 809 lock_kernel();
809 mark_inode_dirty(inode); 810 mark_inode_dirty(inode);
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 8e18ff157247..d8c87fa21ad1 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -1,5 +1,5 @@
1# 1#
2# Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2# Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3# 3#
4# This program is free software; you can redistribute it and/or modify it 4# This program is free software; you can redistribute it and/or modify it
5# under the terms of version 2 of the GNU General Public License as 5# under the terms of version 2 of the GNU General Public License as
@@ -55,7 +55,18 @@ ifeq ($(CONFIG_XFS_TRACE),y)
55endif 55endif
56 56
57obj-$(CONFIG_XFS_FS) += xfs.o 57obj-$(CONFIG_XFS_FS) += xfs.o
58xfs-$(CONFIG_XFS_QUOTA) += quota/ 58
59xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
60 xfs_dquot.o \
61 xfs_dquot_item.o \
62 xfs_trans_dquot.o \
63 xfs_qm_syscalls.o \
64 xfs_qm_bhv.o \
65 xfs_qm.o)
66
67ifeq ($(CONFIG_XFS_QUOTA),y)
68xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
69endif
59 70
60xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o 71xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
61xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o 72xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
index 3dae14c8c55a..fa8394f9437d 100644
--- a/fs/xfs/support/ktrace.c
+++ b/fs/xfs/support/ktrace.c
@@ -170,7 +170,7 @@ ktrace_enter(
170 void *val14, 170 void *val14,
171 void *val15) 171 void *val15)
172{ 172{
173 static lock_t wrap_lock = SPIN_LOCK_UNLOCKED; 173 static DEFINE_SPINLOCK(wrap_lock);
174 unsigned long flags; 174 unsigned long flags;
175 int index; 175 int index;
176 ktrace_entry_t *ktep; 176 ktrace_entry_t *ktep;
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
index f681e675b823..4e115f368d5f 100644
--- a/include/asm-alpha/pci.h
+++ b/include/asm-alpha/pci.h
@@ -254,6 +254,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
254extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 254extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
255 struct pci_bus_region *region); 255 struct pci_bus_region *region);
256 256
257static inline struct resource *
258pcibios_select_root(struct pci_dev *pdev, struct resource *res)
259{
260 struct resource *root = NULL;
261
262 if (res->flags & IORESOURCE_IO)
263 root = &ioport_resource;
264 if (res->flags & IORESOURCE_MEM)
265 root = &iomem_resource;
266
267 return root;
268}
269
257#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index 270#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
258 271
259static inline int pci_proc_domain(struct pci_bus *bus) 272static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
index 72b04d846a23..cf35721cfa45 100644
--- a/include/asm-arm/arch-pxa/hardware.h
+++ b/include/asm-arm/arch-pxa/hardware.h
@@ -44,24 +44,12 @@
44 44
45#ifndef __ASSEMBLY__ 45#ifndef __ASSEMBLY__
46 46
47#if 0 47# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
48# define __REG(x) (*((volatile u32 *)io_p2v(x)))
49#else
50/*
51 * This __REG() version gives the same results as the one above, except
52 * that we are fooling gcc somehow so it generates far better and smaller
53 * assembly code for access to contigous registers. It's a shame that gcc
54 * doesn't guess this by itself.
55 */
56#include <asm/types.h>
57typedef struct { volatile u32 offset[4096]; } __regbase;
58# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
59# define __REG(x) __REGP(io_p2v(x))
60#endif
61 48
62/* With indexed regs we don't want to feed the index through io_p2v() 49/* With indexed regs we don't want to feed the index through io_p2v()
63 especially if it is a variable, otherwise horrible code will result. */ 50 especially if it is a variable, otherwise horrible code will result. */
64# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) 51# define __REG2(x,y) \
52 (*(volatile unsigned long *)((unsigned long)&__REG(x) + (y)))
65 53
66# define __PREG(x) (io_v2p((u32)&(x))) 54# define __PREG(x) (io_v2p((u32)&(x)))
67 55
diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h
new file mode 100644
index 000000000000..46ec2243974a
--- /dev/null
+++ b/include/asm-arm/arch-pxa/i2c.h
@@ -0,0 +1,70 @@
1/*
2 * i2c_pxa.h
3 *
4 * Copyright (C) 2002 Intrinsyc Software 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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#ifndef _I2C_PXA_H_
12#define _I2C_PXA_H_
13
14#if 0
15#define DEF_TIMEOUT 3
16#else
17/* need a longer timeout if we're dealing with the fact we may well be
18 * looking at a multi-master environment
19*/
20#define DEF_TIMEOUT 32
21#endif
22
23#define BUS_ERROR (-EREMOTEIO)
24#define XFER_NAKED (-ECONNREFUSED)
25#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
26
27/* ICR initialize bit values
28*
29* 15. FM 0 (100 Khz operation)
30* 14. UR 0 (No unit reset)
31* 13. SADIE 0 (Disables the unit from interrupting on slave addresses
32* matching its slave address)
33* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration
34* in master mode)
35* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
36* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
37* 9. IRFIE 1 (Enable interrupts from full buffer received)
38* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
39* 7. GCD 1 (Disables i2c unit response to general call messages as a slave)
40* 6. IUE 0 (Disable unit until we change settings)
41* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
42* 4. MA 0 (Only send stop with the ICR stop bit)
43* 3. TB 0 (We are not transmitting a byte initially)
44* 2. ACKNAK 0 (Send an ACK after the unit receives a byte)
45* 1. STOP 0 (Do not send a STOP)
46* 0. START 0 (Do not send a START)
47*
48*/
49#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
50
51/* I2C status register init values
52 *
53 * 10. BED 1 (Clear bus error detected)
54 * 9. SAD 1 (Clear slave address detected)
55 * 7. IRF 1 (Clear IDBR Receive Full)
56 * 6. ITE 1 (Clear IDBR Transmit Empty)
57 * 5. ALD 1 (Clear Arbitration Loss Detected)
58 * 4. SSD 1 (Clear Slave Stop Detected)
59 */
60#define I2C_ISR_INIT 0x7FF /* status register init */
61
62struct i2c_slave_client;
63
64struct i2c_pxa_platform_data {
65 unsigned int slave_addr;
66 struct i2c_slave_client *slave;
67};
68
69extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
70#endif
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
index 9718063a2119..88c17dd02ed2 100644
--- a/include/asm-arm/arch-pxa/mmc.h
+++ b/include/asm-arm/arch-pxa/mmc.h
@@ -9,6 +9,7 @@ struct mmc_host;
9 9
10struct pxamci_platform_data { 10struct pxamci_platform_data {
11 unsigned int ocr_mask; /* available voltages */ 11 unsigned int ocr_mask; /* available voltages */
12 unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */
12 int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *); 13 int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
13 int (*get_ro)(struct device *); 14 int (*get_ro)(struct device *);
14 void (*setpower)(struct device *, unsigned int); 15 void (*setpower)(struct device *, unsigned int);
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index 27d71e9d413b..21c0e16dce5f 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -66,3 +66,4 @@ struct pxafb_mach_info {
66 66
67}; 67};
68void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info); 68void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
69unsigned long pxafb_get_hsync_time(struct device *dev);
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
new file mode 100644
index 000000000000..ac57bc887d82
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -0,0 +1,69 @@
1/* linux/include/asm/arch-s3c2410/fb.h
2 *
3 * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
4 *
5 * Inspired by pxafb.h
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 *
12 * Changelog:
13 * 07-Sep-2004 RTP Created file
14 * 03-Nov-2004 BJD Updated and minor cleanups
15 * 03-Aug-2005 RTP Renamed to fb.h
16*/
17
18#ifndef __ASM_ARM_FB_H
19#define __ASM_ARM_FB_H
20
21#include <asm/arch/regs-lcd.h>
22
23struct s3c2410fb_val {
24 unsigned int defval;
25 unsigned int min;
26 unsigned int max;
27};
28
29struct s3c2410fb_hw {
30 unsigned long lcdcon1;
31 unsigned long lcdcon2;
32 unsigned long lcdcon3;
33 unsigned long lcdcon4;
34 unsigned long lcdcon5;
35};
36
37struct s3c2410fb_mach_info {
38 unsigned char fixed_syncs; /* do not update sync/border */
39
40 /* Screen size */
41 int width;
42 int height;
43
44 /* Screen info */
45 struct s3c2410fb_val xres;
46 struct s3c2410fb_val yres;
47 struct s3c2410fb_val bpp;
48
49 /* lcd configuration registers */
50 struct s3c2410fb_hw regs;
51
52 /* GPIOs */
53
54 unsigned long gpcup;
55 unsigned long gpcup_mask;
56 unsigned long gpccon;
57 unsigned long gpccon_mask;
58 unsigned long gpdup;
59 unsigned long gpdup_mask;
60 unsigned long gpdcon;
61 unsigned long gpdcon_mask;
62
63 /* lpc3600 control register */
64 unsigned long lpcsel;
65};
66
67void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info);
68
69#endif /* __ASM_ARM_FB_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h
index 7f882ea92b2a..b6b1b4e8bbeb 100644
--- a/include/asm-arm/arch-s3c2410/regs-lcd.h
+++ b/include/asm-arm/arch-s3c2410/regs-lcd.h
@@ -51,21 +51,32 @@
51 51
52#define S3C2410_LCDCON1_ENVID (1) 52#define S3C2410_LCDCON1_ENVID (1)
53 53
54#define S3C2410_LCDCON1_MODEMASK 0x1E
55
54#define S3C2410_LCDCON2_VBPD(x) ((x) << 24) 56#define S3C2410_LCDCON2_VBPD(x) ((x) << 24)
55#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14) 57#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14)
56#define S3C2410_LCDCON2_VFPD(x) ((x) << 6) 58#define S3C2410_LCDCON2_VFPD(x) ((x) << 6)
57#define S3C2410_LCDCON2_VSPW(x) ((x) << 0) 59#define S3C2410_LCDCON2_VSPW(x) ((x) << 0)
58 60
61#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
62#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF)
63#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F)
64
59#define S3C2410_LCDCON3_HBPD(x) ((x) << 19) 65#define S3C2410_LCDCON3_HBPD(x) ((x) << 19)
60#define S3C2410_LCDCON3_WDLY(x) ((x) << 19) 66#define S3C2410_LCDCON3_WDLY(x) ((x) << 19)
61#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8) 67#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8)
62#define S3C2410_LCDCON3_HFPD(x) ((x) << 0) 68#define S3C2410_LCDCON3_HFPD(x) ((x) << 0)
63#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0) 69#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
64 70
71#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
72#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF)
73
65#define S3C2410_LCDCON4_MVAL(x) ((x) << 8) 74#define S3C2410_LCDCON4_MVAL(x) ((x) << 8)
66#define S3C2410_LCDCON4_HSPW(x) ((x) << 0) 75#define S3C2410_LCDCON4_HSPW(x) ((x) << 0)
67#define S3C2410_LCDCON4_WLH(x) ((x) << 0) 76#define S3C2410_LCDCON4_WLH(x) ((x) << 0)
68 77
78#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF)
79
69#define S3C2410_LCDCON5_BPP24BL (1<<12) 80#define S3C2410_LCDCON5_BPP24BL (1<<12)
70#define S3C2410_LCDCON5_FRM565 (1<<11) 81#define S3C2410_LCDCON5_FRM565 (1<<11)
71#define S3C2410_LCDCON5_INVVCLK (1<<10) 82#define S3C2410_LCDCON5_INVVCLK (1<<10)
@@ -100,10 +111,16 @@
100#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C) 111#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C)
101#define S3C2410_TPAL S3C2410_LCDREG(0x50) 112#define S3C2410_TPAL S3C2410_LCDREG(0x50)
102 113
114#define S3C2410_TPAL_EN (1<<24)
115
103/* interrupt info */ 116/* interrupt info */
104#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54) 117#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54)
105#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58) 118#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58)
106#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C) 119#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C)
120#define S3C2410_LCDINT_FIWSEL (1<<2)
121#define S3C2410_LCDINT_FRSYNC (1<<1)
122#define S3C2410_LCDINT_FICNT (1<<0)
123
107#define S3C2410_LPCSEL S3C2410_LCDREG(0x60) 124#define S3C2410_LPCSEL S3C2410_LCDREG(0x60)
108 125
109#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4)) 126#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4))
diff --git a/include/asm-arm/arch-sa1100/hardware.h b/include/asm-arm/arch-sa1100/hardware.h
index 10c62db34362..19c3b1e186bb 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -49,23 +49,9 @@
49 ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START ) 49 ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
50 50
51#ifndef __ASSEMBLY__ 51#ifndef __ASSEMBLY__
52#include <asm/types.h>
53 52
54#if 0 53# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
55# define __REG(x) (*((volatile u32 *)io_p2v(x))) 54# define __PREG(x) (io_v2p((unsigned long)&(x)))
56#else
57/*
58 * This __REG() version gives the same results as the one above, except
59 * that we are fooling gcc somehow so it generates far better and smaller
60 * assembly code for access to contigous registers. It's a shame that gcc
61 * doesn't guess this by itself.
62 */
63typedef struct { volatile u32 offset[4096]; } __regbase;
64# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
65# define __REG(x) __REGP(io_p2v(x))
66#endif
67
68# define __PREG(x) (io_v2p((u32)&(x)))
69 55
70#else 56#else
71 57
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 035cdcff43d2..e81baff4f54b 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -256,7 +256,7 @@ extern void dmac_flush_range(unsigned long, unsigned long);
256 * Convert calls to our calling convention. 256 * Convert calls to our calling convention.
257 */ 257 */
258#define flush_cache_all() __cpuc_flush_kern_all() 258#define flush_cache_all() __cpuc_flush_kern_all()
259 259#ifndef CONFIG_CPU_CACHE_VIPT
260static inline void flush_cache_mm(struct mm_struct *mm) 260static inline void flush_cache_mm(struct mm_struct *mm)
261{ 261{
262 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) 262 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
@@ -279,6 +279,11 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l
279 __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); 279 __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
280 } 280 }
281} 281}
282#else
283extern void flush_cache_mm(struct mm_struct *mm);
284extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
285extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
286#endif
282 287
283/* 288/*
284 * flush_cache_user_range is used when we want to ensure that the 289 * flush_cache_user_range is used when we want to ensure that the
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index 38ea5899a580..ead3ced38cb8 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -64,6 +64,19 @@ extern void
64pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 64pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
65 struct pci_bus_region *region); 65 struct pci_bus_region *region);
66 66
67static inline struct resource *
68pcibios_select_root(struct pci_dev *pdev, struct resource *res)
69{
70 struct resource *root = NULL;
71
72 if (res->flags & IORESOURCE_IO)
73 root = &ioport_resource;
74 if (res->flags & IORESOURCE_MEM)
75 root = &iomem_resource;
76
77 return root;
78}
79
67static inline void pcibios_add_platform_entries(struct pci_dev *dev) 80static inline void pcibios_add_platform_entries(struct pci_dev *dev)
68{ 81{
69} 82}
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index ee1d8b5d8168..c36a77d3bf44 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -30,6 +30,19 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
30 res->end = region->end; 30 res->end = region->end;
31} 31}
32 32
33static inline struct resource *
34pcibios_select_root(struct pci_dev *pdev, struct resource *res)
35{
36 struct resource *root = NULL;
37
38 if (res->flags & IORESOURCE_IO)
39 root = &ioport_resource;
40 if (res->flags & IORESOURCE_MEM)
41 root = &iomem_resource;
42
43 return root;
44}
45
33#define pcibios_scan_all_fns(a, b) 0 46#define pcibios_scan_all_fns(a, b) 0
34 47
35#ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ 48#ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
diff --git a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-i386/mach-default/mach_reboot.h
index 521e227db679..06ae4d81ba6a 100644
--- a/include/asm-i386/mach-default/mach_reboot.h
+++ b/include/asm-i386/mach-default/mach_reboot.h
@@ -22,7 +22,15 @@ static inline void mach_reboot(void)
22 for (i = 0; i < 100; i++) { 22 for (i = 0; i < 100; i++) {
23 kb_wait(); 23 kb_wait();
24 udelay(50); 24 udelay(50);
25 outb(0xfe, 0x64); /* pulse reset low */ 25 outb(0x60, 0x64); /* write Controller Command Byte */
26 udelay(50);
27 kb_wait();
28 udelay(50);
29 outb(0x14, 0x60); /* set "System flag" */
30 udelay(50);
31 kb_wait();
32 udelay(50);
33 outb(0xfe, 0x64); /* pulse reset low */
26 udelay(50); 34 udelay(50);
27 } 35 }
28} 36}
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 516421300ea2..348fe3a4879d 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -29,7 +29,7 @@ static inline void get_memcfg_numa(void)
29#ifdef CONFIG_X86_NUMAQ 29#ifdef CONFIG_X86_NUMAQ
30 if (get_memcfg_numaq()) 30 if (get_memcfg_numaq())
31 return; 31 return;
32#elif CONFIG_ACPI_SRAT 32#elif defined(CONFIG_ACPI_SRAT)
33 if (get_memcfg_from_srat()) 33 if (get_memcfg_from_srat())
34 return; 34 return;
35#endif 35#endif
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index a429fe225b07..20f98f1751a1 100644
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -80,12 +80,9 @@ extern int iosapic_remove (unsigned int gsi_base);
80#endif /* CONFIG_HOTPLUG */ 80#endif /* CONFIG_HOTPLUG */
81extern int gsi_to_vector (unsigned int gsi); 81extern int gsi_to_vector (unsigned int gsi);
82extern int gsi_to_irq (unsigned int gsi); 82extern int gsi_to_irq (unsigned int gsi);
83extern void iosapic_enable_intr (unsigned int vector);
84extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity, 83extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
85 unsigned long trigger); 84 unsigned long trigger);
86#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
87extern void iosapic_unregister_intr (unsigned int irq); 85extern void iosapic_unregister_intr (unsigned int irq);
88#endif
89extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, 86extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
90 unsigned long polarity, 87 unsigned long polarity,
91 unsigned long trigger); 88 unsigned long trigger);
@@ -97,7 +94,6 @@ extern int __init iosapic_register_platform_intr (u32 int_type,
97 unsigned long trigger); 94 unsigned long trigger);
98extern unsigned int iosapic_version (char __iomem *addr); 95extern unsigned int iosapic_version (char __iomem *addr);
99 96
100extern void iosapic_pci_fixup (int);
101#ifdef CONFIG_NUMA 97#ifdef CONFIG_NUMA
102extern void __devinit map_iosapic_to_node (unsigned int, int); 98extern void __devinit map_iosapic_to_node (unsigned int, int);
103#endif 99#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index cd984d08fd15..dbe86c0bbce5 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -35,8 +35,4 @@ extern void disable_irq_nosync (unsigned int);
35extern void enable_irq (unsigned int); 35extern void enable_irq (unsigned int);
36extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); 36extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
37 37
38struct irqaction;
39struct pt_regs;
40int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
41
42#endif /* _ASM_IA64_IRQ_H */ 38#endif /* _ASM_IA64_IRQ_H */
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index dba9f220be71..ef616fd4cb1b 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -156,6 +156,19 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
156extern void pcibios_bus_to_resource(struct pci_dev *dev, 156extern void pcibios_bus_to_resource(struct pci_dev *dev,
157 struct resource *res, struct pci_bus_region *region); 157 struct resource *res, struct pci_bus_region *region);
158 158
159static inline struct resource *
160pcibios_select_root(struct pci_dev *pdev, struct resource *res)
161{
162 struct resource *root = NULL;
163
164 if (res->flags & IORESOURCE_IO)
165 root = &ioport_resource;
166 if (res->flags & IORESOURCE_MEM)
167 root = &iomem_resource;
168
169 return root;
170}
171
159#define pcibios_scan_all_fns(a, b) 0 172#define pcibios_scan_all_fns(a, b) 0
160 173
161#endif /* _ASM_IA64_PCI_H */ 174#endif /* _ASM_IA64_PCI_H */
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 33256db4a7cf..635235fa1e32 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -275,6 +275,7 @@ extern void ia64_load_extra (struct task_struct *task);
275 */ 275 */
276#define __ARCH_WANT_UNLOCKED_CTXSW 276#define __ARCH_WANT_UNLOCKED_CTXSW
277 277
278#define ARCH_HAS_PREFETCH_SWITCH_STACK
278#define ia64_platform_is(x) (strcmp(x, platform_name) == 0) 279#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
279 280
280void cpu_idle_wait(void); 281void cpu_idle_wait(void);
diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
index 16f32cc80c40..1df3f666a28e 100644
--- a/include/asm-m68knommu/coldfire.h
+++ b/include/asm-m68knommu/coldfire.h
@@ -22,7 +22,7 @@
22#define MCF_MBAR2 0x80000000 22#define MCF_MBAR2 0x80000000
23#define MCF_IPSBAR 0x40000000 23#define MCF_IPSBAR 0x40000000
24 24
25#if defined(CONFIG_M527x) || defined(CONFIG_M528x) 25#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
26#undef MCF_MBAR 26#undef MCF_MBAR
27#define MCF_MBAR MCF_IPSBAR 27#define MCF_MBAR MCF_IPSBAR
28#endif 28#endif
@@ -54,6 +54,8 @@
54#define MCF_CLK 54000000 54#define MCF_CLK 54000000
55#elif defined(CONFIG_CLOCK_60MHz) 55#elif defined(CONFIG_CLOCK_60MHz)
56#define MCF_CLK 60000000 56#define MCF_CLK 60000000
57#elif defined(CONFIG_CLOCK_62_5MHz)
58#define MCF_CLK 62500000
57#elif defined(CONFIG_CLOCK_64MHz) 59#elif defined(CONFIG_CLOCK_64MHz)
58#define MCF_CLK 64000000 60#define MCF_CLK 64000000
59#elif defined(CONFIG_CLOCK_66MHz) 61#elif defined(CONFIG_CLOCK_66MHz)
@@ -76,7 +78,7 @@
76 * One some ColdFire family members the bus clock (used by internal 78 * One some ColdFire family members the bus clock (used by internal
77 * peripherals) is not the same as the CPU clock. 79 * peripherals) is not the same as the CPU clock.
78 */ 80 */
79#if defined(CONFIG_M5249) || defined(CONFIG_M527x) 81#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
80#define MCF_BUSCLK (MCF_CLK / 2) 82#define MCF_BUSCLK (MCF_CLK / 2)
81#else 83#else
82#define MCF_BUSCLK MCF_CLK 84#define MCF_BUSCLK MCF_CLK
diff --git a/include/asm-m68knommu/m523xsim.h b/include/asm-m68knommu/m523xsim.h
new file mode 100644
index 000000000000..926cfb805df7
--- /dev/null
+++ b/include/asm-m68knommu/m523xsim.h
@@ -0,0 +1,46 @@
1/****************************************************************************/
2
3/*
4 * m523xsim.h -- ColdFire 523x System Integration Module support.
5 *
6 * (C) Copyright 2003-2005, Greg Ungerer <gerg@snapgear.com>
7 */
8
9/****************************************************************************/
10#ifndef m523xsim_h
11#define m523xsim_h
12/****************************************************************************/
13
14#include <linux/config.h>
15
16/*
17 * Define the 523x SIM register set addresses.
18 */
19#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */
20#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */
21#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
22#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */
23#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */
24#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
25#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
26#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
27#define MCFINTC_IRLR 0x18 /* */
28#define MCFINTC_IACKL 0x19 /* */
29#define MCFINTC_ICR0 0x40 /* Base ICR register */
30
31#define MCFINT_VECBASE 64 /* Vector base number */
32#define MCFINT_UART0 13 /* Interrupt number for UART0 */
33#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
34#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
35
36/*
37 * SDRAM configuration registers.
38 */
39#define MCFSIM_DCR 0x44 /* SDRAM control */
40#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */
41#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */
42#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */
43#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
44
45/****************************************************************************/
46#endif /* m523xsim_h */
diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
index 522e513c2bc6..b0c7736f7a99 100644
--- a/include/asm-m68knommu/mcfsim.h
+++ b/include/asm-m68knommu/mcfsim.h
@@ -15,13 +15,15 @@
15#include <linux/config.h> 15#include <linux/config.h>
16 16
17/* 17/*
18 * Include 5204, 5206/e, 5249, 5270/5271, 5272, 5280/5282, 5307 or 18 * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
19 * 5407 specific addresses. 19 * 5307 or 5407 specific addresses.
20 */ 20 */
21#if defined(CONFIG_M5204) 21#if defined(CONFIG_M5204)
22#include <asm/m5204sim.h> 22#include <asm/m5204sim.h>
23#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) 23#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
24#include <asm/m5206sim.h> 24#include <asm/m5206sim.h>
25#elif defined(CONFIG_M523x)
26#include <asm/m523xsim.h>
25#elif defined(CONFIG_M5249) 27#elif defined(CONFIG_M5249)
26#include <asm/m5249sim.h> 28#include <asm/m5249sim.h>
27#elif defined(CONFIG_M527x) 29#elif defined(CONFIG_M527x)
diff --git a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
index 54d4a85f4fdf..9c1210613bc7 100644
--- a/include/asm-m68knommu/mcfuart.h
+++ b/include/asm-m68knommu/mcfuart.h
@@ -29,7 +29,7 @@
29#define MCFUART_BASE1 0x140 /* Base address of UART1 */ 29#define MCFUART_BASE1 0x140 /* Base address of UART1 */
30#define MCFUART_BASE2 0x180 /* Base address of UART2 */ 30#define MCFUART_BASE2 0x180 /* Base address of UART2 */
31#endif 31#endif
32#elif defined(CONFIG_M527x) || defined(CONFIG_M528x) 32#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
33#define MCFUART_BASE1 0x200 /* Base address of UART1 */ 33#define MCFUART_BASE1 0x200 /* Base address of UART1 */
34#define MCFUART_BASE2 0x240 /* Base address of UART2 */ 34#define MCFUART_BASE2 0x240 /* Base address of UART2 */
35#define MCFUART_BASE3 0x280 /* Base address of UART3 */ 35#define MCFUART_BASE3 0x280 /* Base address of UART3 */
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index b90b11d0b886..3f2470e9e678 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -49,7 +49,4 @@ do { \
49 49
50extern void arch_init_irq(void); 50extern void arch_init_irq(void);
51 51
52struct irqaction;
53int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
54
55#endif /* _ASM_IRQ_H */ 52#endif /* _ASM_IRQ_H */
diff --git a/include/asm-mips/vr41xx/tb0287.h b/include/asm-mips/vr41xx/tb0287.h
new file mode 100644
index 000000000000..dd9832313afe
--- /dev/null
+++ b/include/asm-mips/vr41xx/tb0287.h
@@ -0,0 +1,43 @@
1/*
2 * tb0287.h, Include file for TANBAC TB0287 mini-ITX board.
3 *
4 * Copyright (C) 2005 Media Lab Inc. <ito@mlb.co.jp>
5 *
6 * This code is largely based on tb0219.h.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#ifndef __TANBAC_TB0287_H
23#define __TANBAC_TB0287_H
24
25#include <asm/vr41xx/vr41xx.h>
26
27/*
28 * General-Purpose I/O Pin Number
29 */
30#define TB0287_PCI_SLOT_PIN 2
31#define TB0287_SM501_PIN 3
32#define TB0287_SIL680A_PIN 8
33#define TB0287_RTL8110_PIN 13
34
35/*
36 * Interrupt Number
37 */
38#define TB0287_PCI_SLOT_IRQ GIU_IRQ(TB0287_PCI_SLOT_PIN)
39#define TB0287_SM501_IRQ GIU_IRQ(TB0287_SM501_PIN)
40#define TB0287_SIL680A_IRQ GIU_IRQ(TB0287_SIL680A_PIN)
41#define TB0287_RTL8110_IRQ GIU_IRQ(TB0287_RTL8110_PIN)
42
43#endif /* __TANBAC_TB0287_H */
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 98d79a3d54fa..d0b761f690b5 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -257,6 +257,19 @@ extern void
257pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 257pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
258 struct pci_bus_region *region); 258 struct pci_bus_region *region);
259 259
260static inline struct resource *
261pcibios_select_root(struct pci_dev *pdev, struct resource *res)
262{
263 struct resource *root = NULL;
264
265 if (res->flags & IORESOURCE_IO)
266 root = &ioport_resource;
267 if (res->flags & IORESOURCE_MEM)
268 root = &iomem_resource;
269
270 return root;
271}
272
260static inline void pcibios_add_platform_entries(struct pci_dev *dev) 273static inline void pcibios_add_platform_entries(struct pci_dev *dev)
261{ 274{
262} 275}
diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h
index 862708a749b0..b70d6e53b303 100644
--- a/include/asm-powerpc/8253pit.h
+++ b/include/asm-powerpc/8253pit.h
@@ -1,10 +1,10 @@
1#ifndef _ASM_POWERPC_8253PIT_H
2#define _ASM_POWERPC_8253PIT_H
3
1/* 4/*
2 * 8253/8254 Programmable Interval Timer 5 * 8253/8254 Programmable Interval Timer
3 */ 6 */
4 7
5#ifndef _8253PIT_H
6#define _8253PIT_H
7
8#define PIT_TICK_RATE 1193182UL 8#define PIT_TICK_RATE 1193182UL
9 9
10#endif 10#endif /* _ASM_POWERPC_8253PIT_H */
diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h
index ca9e423307f4..885b4631a6cf 100644
--- a/include/asm-powerpc/agp.h
+++ b/include/asm-powerpc/agp.h
@@ -1,10 +1,8 @@
1#ifndef AGP_H 1#ifndef _ASM_POWERPC_AGP_H
2#define AGP_H 1 2#define _ASM_POWERPC_AGP_H
3 3
4#include <asm/io.h> 4#include <asm/io.h>
5 5
6/* nothing much needed here */
7
8#define map_page_into_agp(page) 6#define map_page_into_agp(page)
9#define unmap_page_from_agp(page) 7#define unmap_page_from_agp(page)
10#define flush_agp_mappings() 8#define flush_agp_mappings()
@@ -20,4 +18,4 @@
20#define free_gatt_pages(table, order) \ 18#define free_gatt_pages(table, order) \
21 free_pages((unsigned long)(table), (order)) 19 free_pages((unsigned long)(table), (order))
22 20
23#endif 21#endif /* _ASM_POWERPC_AGP_H */
diff --git a/include/asm-powerpc/bugs.h b/include/asm-powerpc/bugs.h
index 310187d0e33a..42fdb73e3068 100644
--- a/include/asm-powerpc/bugs.h
+++ b/include/asm-powerpc/bugs.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_BUGS_H 1#ifndef _ASM_POWERPC_BUGS_H
2#define _POWERPC_BUGS_H 2#define _ASM_POWERPC_BUGS_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -13,6 +13,6 @@
13 * architecture-dependent bugs. 13 * architecture-dependent bugs.
14 */ 14 */
15 15
16extern void check_bugs(void); 16static inline void check_bugs(void) { }
17 17
18#endif /* _POWERPC_BUGS_H */ 18#endif /* _ASM_POWERPC_BUGS_H */
diff --git a/include/asm-powerpc/errno.h b/include/asm-powerpc/errno.h
index 19f20bd41ae6..8c145fd17d86 100644
--- a/include/asm-powerpc/errno.h
+++ b/include/asm-powerpc/errno.h
@@ -1,5 +1,5 @@
1#ifndef _PPC_ERRNO_H 1#ifndef _ASM_POWERPC_ERRNO_H
2#define _PPC_ERRNO_H 2#define _ASM_POWERPC_ERRNO_H
3 3
4#include <asm-generic/errno.h> 4#include <asm-generic/errno.h>
5 5
@@ -8,4 +8,4 @@
8 8
9#define _LAST_ERRNO 516 9#define _LAST_ERRNO 516
10 10
11#endif 11#endif /* _ASM_POWERPC_ERRNO_H */
diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h
index 93c6acfdd0fd..8eb99848c402 100644
--- a/include/asm-powerpc/ioctl.h
+++ b/include/asm-powerpc/ioctl.h
@@ -1,5 +1,5 @@
1#ifndef _PPC_IOCTL_H 1#ifndef _ASM_POWERPC_IOCTL_H
2#define _PPC_IOCTL_H 2#define _ASM_POWERPC_IOCTL_H
3 3
4 4
5/* 5/*
@@ -66,4 +66,4 @@ extern unsigned int __invalid_size_argument_for_IOC;
66#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) 66#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
67#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) 67#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
68 68
69#endif 69#endif /* _ASM_POWERPC_IOCTL_H */
diff --git a/include/asm-powerpc/ioctls.h b/include/asm-powerpc/ioctls.h
index f5b7f2b055e7..5b94ff489b8b 100644
--- a/include/asm-powerpc/ioctls.h
+++ b/include/asm-powerpc/ioctls.h
@@ -1,5 +1,5 @@
1#ifndef _ASM_PPC_IOCTLS_H 1#ifndef _ASM_POWERPC_IOCTLS_H
2#define _ASM_PPC_IOCTLS_H 2#define _ASM_POWERPC_IOCTLS_H
3 3
4#include <asm/ioctl.h> 4#include <asm/ioctl.h>
5 5
@@ -104,4 +104,4 @@
104#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ 104#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
105#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ 105#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
106 106
107#endif /* _ASM_PPC_IOCTLS_H */ 107#endif /* _ASM_POWERPC_IOCTLS_H */
diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h
index 291c2d01c44f..e1c4ac1cc4ba 100644
--- a/include/asm-powerpc/linkage.h
+++ b/include/asm-powerpc/linkage.h
@@ -1,6 +1,6 @@
1#ifndef __ASM_LINKAGE_H 1#ifndef _ASM_POWERPC_LINKAGE_H
2#define __ASM_LINKAGE_H 2#define _ASM_POWERPC_LINKAGE_H
3 3
4/* Nothing to see here... */ 4/* Nothing to see here... */
5 5
6#endif 6#endif /* _ASM_POWERPC_LINKAGE_H */
diff --git a/include/asm-powerpc/mc146818rtc.h b/include/asm-powerpc/mc146818rtc.h
index a5619a2a1393..f2741c8b59a1 100644
--- a/include/asm-powerpc/mc146818rtc.h
+++ b/include/asm-powerpc/mc146818rtc.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_MC146818RTC_H 1#ifndef _ASM_POWERPC_MC146818RTC_H
2#define _POWERPC_MC146818RTC_H 2#define _ASM_POWERPC_MC146818RTC_H
3 3
4/* 4/*
5 * Machine dependent access functions for RTC registers. 5 * Machine dependent access functions for RTC registers.
@@ -33,4 +33,4 @@ outb_p((val),RTC_PORT(1)); \
33}) 33})
34 34
35#endif /* __KERNEL__ */ 35#endif /* __KERNEL__ */
36#endif /* _POWERPC_MC146818RTC_H */ 36#endif /* _ASM_POWERPC_MC146818RTC_H */
diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h
index f2d55988d749..f5e5342fcac5 100644
--- a/include/asm-powerpc/mman.h
+++ b/include/asm-powerpc/mman.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_MMAN_H 1#ifndef _ASM_POWERPC_MMAN_H
2#define _POWERPC_MMAN_H 2#define _ASM_POWERPC_MMAN_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -49,4 +49,4 @@
49#define MAP_ANON MAP_ANONYMOUS 49#define MAP_ANON MAP_ANONYMOUS
50#define MAP_FILE 0 50#define MAP_FILE 0
51 51
52#endif /* _POWERPC_MMAN_H */ 52#endif /* _ASM_POWERPC_MMAN_H */
diff --git a/include/asm-powerpc/module.h b/include/asm-powerpc/module.h
index 4438f4fd6524..7ecd05e03051 100644
--- a/include/asm-powerpc/module.h
+++ b/include/asm-powerpc/module.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_MODULE_H 1#ifndef _ASM_POWERPC_MODULE_H
2#define _POWERPC_MODULE_H 2#define _ASM_POWERPC_MODULE_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -74,4 +74,4 @@ struct exception_table_entry;
74void sort_ex_table(struct exception_table_entry *start, 74void sort_ex_table(struct exception_table_entry *start,
75 struct exception_table_entry *finish); 75 struct exception_table_entry *finish);
76 76
77#endif /* _POWERPC_MODULE_H */ 77#endif /* _ASM_POWERPC_MODULE_H */
diff --git a/include/asm-ppc/msgbuf.h b/include/asm-powerpc/msgbuf.h
index 1053452a9376..dd76743c7537 100644
--- a/include/asm-ppc/msgbuf.h
+++ b/include/asm-powerpc/msgbuf.h
@@ -1,17 +1,25 @@
1#ifndef _PPC_MSGBUF_H 1#ifndef _ASM_POWERPC_MSGBUF_H
2#define _PPC_MSGBUF_H 2#define _ASM_POWERPC_MSGBUF_H
3 3
4/* 4/*
5 * The msqid64_ds structure for the PPC architecture. 5 * The msqid64_ds structure for the PowerPC architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
6 */ 8 */
7 9
8struct msqid64_ds { 10struct msqid64_ds {
9 struct ipc64_perm msg_perm; 11 struct ipc64_perm msg_perm;
12#ifndef __powerpc64__
10 unsigned int __unused1; 13 unsigned int __unused1;
14#endif
11 __kernel_time_t msg_stime; /* last msgsnd time */ 15 __kernel_time_t msg_stime; /* last msgsnd time */
16#ifndef __powerpc64__
12 unsigned int __unused2; 17 unsigned int __unused2;
18#endif
13 __kernel_time_t msg_rtime; /* last msgrcv time */ 19 __kernel_time_t msg_rtime; /* last msgrcv time */
20#ifndef __powerpc64__
14 unsigned int __unused3; 21 unsigned int __unused3;
22#endif
15 __kernel_time_t msg_ctime; /* last change time */ 23 __kernel_time_t msg_ctime; /* last change time */
16 unsigned long msg_cbytes; /* current number of bytes on queue */ 24 unsigned long msg_cbytes; /* current number of bytes on queue */
17 unsigned long msg_qnum; /* number of messages in queue */ 25 unsigned long msg_qnum; /* number of messages in queue */
@@ -22,4 +30,4 @@ struct msqid64_ds {
22 unsigned long __unused5; 30 unsigned long __unused5;
23}; 31};
24 32
25#endif /* _PPC_MSGBUF_H */ 33#endif /* _ASM_POWERPC_MSGBUF_H */
diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h
index 29c9ec832133..657443474a6a 100644
--- a/include/asm-powerpc/namei.h
+++ b/include/asm-powerpc/namei.h
@@ -1,14 +1,14 @@
1#ifndef _ASM_POWERPC_NAMEI_H
2#define _ASM_POWERPC_NAMEI_H
3
4#ifdef __KERNEL__
5
1/* 6/*
2 * include/asm-ppc/namei.h
3 * Adapted from include/asm-alpha/namei.h 7 * Adapted from include/asm-alpha/namei.h
4 * 8 *
5 * Included from fs/namei.c 9 * Included from fs/namei.c
6 */ 10 */
7 11
8#ifdef __KERNEL__
9#ifndef __PPC_NAMEI_H
10#define __PPC_NAMEI_H
11
12/* This dummy routine maybe changed to something useful 12/* This dummy routine maybe changed to something useful
13 * for /usr/gnemul/ emulation stuff. 13 * for /usr/gnemul/ emulation stuff.
14 * Look at asm-sparc/namei.h for details. 14 * Look at asm-sparc/namei.h for details.
@@ -16,5 +16,5 @@
16 16
17#define __emul_prefix() NULL 17#define __emul_prefix() NULL
18 18
19#endif /* __PPC_NAMEI_H */ 19#endif /* __KERNEL__ */
20#endif /* __KERNEL__ */ 20#endif /* _ASM_POWERPC_NAMEI_H */
diff --git a/include/asm-ppc/param.h b/include/asm-powerpc/param.h
index 6198b1657a45..bdc724f70884 100644
--- a/include/asm-ppc/param.h
+++ b/include/asm-powerpc/param.h
@@ -1,10 +1,10 @@
1#ifndef _ASM_PPC_PARAM_H 1#ifndef _ASM_POWERPC_PARAM_H
2#define _ASM_PPC_PARAM_H 2#define _ASM_POWERPC_PARAM_H
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5 5
6#ifdef __KERNEL__ 6#ifdef __KERNEL__
7#define HZ CONFIG_HZ /* internal timer frequency */ 7#define HZ CONFIG_HZ /* internal kernel timer frequency */
8#define USER_HZ 100 /* for user interfaces in "ticks" */ 8#define USER_HZ 100 /* for user interfaces in "ticks" */
9#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ 9#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
10#endif /* __KERNEL__ */ 10#endif /* __KERNEL__ */
@@ -21,4 +21,4 @@
21 21
22#define MAXHOSTNAMELEN 64 /* max length of hostname */ 22#define MAXHOSTNAMELEN 64 /* max length of hostname */
23 23
24#endif 24#endif /* _ASM_POWERPC_PARAM_H */
diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h
index be5024913c62..edd2054da86b 100644
--- a/include/asm-powerpc/poll.h
+++ b/include/asm-powerpc/poll.h
@@ -1,5 +1,5 @@
1#ifndef __PPC_POLL_H 1#ifndef _ASM_POWERPC_POLL_H
2#define __PPC_POLL_H 2#define _ASM_POWERPC_POLL_H
3 3
4#define POLLIN 0x0001 4#define POLLIN 0x0001
5#define POLLPRI 0x0002 5#define POLLPRI 0x0002
@@ -20,4 +20,4 @@ struct pollfd {
20 short revents; 20 short revents;
21}; 21};
22 22
23#endif 23#endif /* _ASM_POWERPC_POLL_H */
diff --git a/include/asm-powerpc/sembuf.h b/include/asm-powerpc/sembuf.h
index c98fc18fe805..99a41938ae3d 100644
--- a/include/asm-powerpc/sembuf.h
+++ b/include/asm-powerpc/sembuf.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_SEMBUF_H 1#ifndef _ASM_POWERPC_SEMBUF_H
2#define _POWERPC_SEMBUF_H 2#define _ASM_POWERPC_SEMBUF_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -33,4 +33,4 @@ struct semid64_ds {
33 unsigned long __unused4; 33 unsigned long __unused4;
34}; 34};
35 35
36#endif /* _POWERPC_SEMBUF_H */ 36#endif /* _ASM_POWERPC_SEMBUF_H */
diff --git a/include/asm-powerpc/setup.h b/include/asm-powerpc/setup.h
new file mode 100644
index 000000000000..3d9740aae018
--- /dev/null
+++ b/include/asm-powerpc/setup.h
@@ -0,0 +1,9 @@
1#ifndef _ASM_POWERPC_SETUP_H
2#define _ASM_POWERPC_SETUP_H
3
4#ifdef __KERNEL__
5
6#define COMMAND_LINE_SIZE 512
7
8#endif /* __KERNEL__ */
9#endif /* _ASM_POWERPC_SETUP_H */
diff --git a/include/asm-powerpc/shmbuf.h b/include/asm-powerpc/shmbuf.h
index 29632db3b178..8efa39698b6c 100644
--- a/include/asm-powerpc/shmbuf.h
+++ b/include/asm-powerpc/shmbuf.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_SHMBUF_H 1#ifndef _ASM_POWERPC_SHMBUF_H
2#define _POWERPC_SHMBUF_H 2#define _ASM_POWERPC_SHMBUF_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -21,19 +21,19 @@
21 21
22struct shmid64_ds { 22struct shmid64_ds {
23 struct ipc64_perm shm_perm; /* operation perms */ 23 struct ipc64_perm shm_perm; /* operation perms */
24#ifndef __power64__ 24#ifndef __powerpc64__
25 unsigned long __unused1; 25 unsigned long __unused1;
26#endif 26#endif
27 __kernel_time_t shm_atime; /* last attach time */ 27 __kernel_time_t shm_atime; /* last attach time */
28#ifndef __power64__ 28#ifndef __powerpc64__
29 unsigned long __unused2; 29 unsigned long __unused2;
30#endif 30#endif
31 __kernel_time_t shm_dtime; /* last detach time */ 31 __kernel_time_t shm_dtime; /* last detach time */
32#ifndef __power64__ 32#ifndef __powerpc64__
33 unsigned long __unused3; 33 unsigned long __unused3;
34#endif 34#endif
35 __kernel_time_t shm_ctime; /* last change time */ 35 __kernel_time_t shm_ctime; /* last change time */
36#ifndef __power64__ 36#ifndef __powerpc64__
37 unsigned long __unused4; 37 unsigned long __unused4;
38#endif 38#endif
39 size_t shm_segsz; /* size of segment (bytes) */ 39 size_t shm_segsz; /* size of segment (bytes) */
@@ -56,4 +56,4 @@ struct shminfo64 {
56 unsigned long __unused4; 56 unsigned long __unused4;
57}; 57};
58 58
59#endif /* _POWERPC_SHMBUF_H */ 59#endif /* _ASM_POWERPC_SHMBUF_H */
diff --git a/include/asm-powerpc/shmparam.h b/include/asm-powerpc/shmparam.h
index d6250602ae64..5cda42a6d39e 100644
--- a/include/asm-powerpc/shmparam.h
+++ b/include/asm-powerpc/shmparam.h
@@ -1,6 +1,6 @@
1#ifndef _PPC_SHMPARAM_H 1#ifndef _ASM_POWERPC_SHMPARAM_H
2#define _PPC_SHMPARAM_H 2#define _ASM_POWERPC_SHMPARAM_H
3 3
4#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ 4#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
5 5
6#endif /* _PPC_SHMPARAM_H */ 6#endif /* _ASM_POWERPC_SHMPARAM_H */
diff --git a/include/asm-powerpc/siginfo.h b/include/asm-powerpc/siginfo.h
index ae70b8010b19..538ea8ef509b 100644
--- a/include/asm-powerpc/siginfo.h
+++ b/include/asm-powerpc/siginfo.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_SIGINFO_H 1#ifndef _ASM_POWERPC_SIGINFO_H
2#define _POWERPC_SIGINFO_H 2#define _ASM_POWERPC_SIGINFO_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -15,4 +15,4 @@
15 15
16#include <asm-generic/siginfo.h> 16#include <asm-generic/siginfo.h>
17 17
18#endif /* _POWERPC_SIGINFO_H */ 18#endif /* _ASM_POWERPC_SIGINFO_H */
diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h
index 51a0cf5ee9f0..e4b8177d4acc 100644
--- a/include/asm-powerpc/socket.h
+++ b/include/asm-powerpc/socket.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_SOCKET_H 1#ifndef _ASM_POWERPC_SOCKET_H
2#define _POWERPC_SOCKET_H 2#define _ASM_POWERPC_SOCKET_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -56,4 +56,4 @@
56 56
57#define SO_PEERSEC 31 57#define SO_PEERSEC 31
58 58
59#endif /* _POWERPC_SOCKET_H */ 59#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/include/asm-powerpc/sockios.h b/include/asm-powerpc/sockios.h
index ef7ff664167e..590078d8ed28 100644
--- a/include/asm-powerpc/sockios.h
+++ b/include/asm-powerpc/sockios.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_SOCKIOS_H 1#ifndef _ASM_POWERPC_SOCKIOS_H
2#define _POWERPC_SOCKIOS_H 2#define _ASM_POWERPC_SOCKIOS_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -16,4 +16,4 @@
16#define SIOCATMARK 0x8905 16#define SIOCATMARK 0x8905
17#define SIOCGSTAMP 0x8906 /* Get stamp */ 17#define SIOCGSTAMP 0x8906 /* Get stamp */
18 18
19#endif /* _POWERPC_SOCKIOS_H */ 19#endif /* _ASM_POWERPC_SOCKIOS_H */
diff --git a/include/asm-powerpc/string.h b/include/asm-powerpc/string.h
index 225575997392..8606a696c088 100644
--- a/include/asm-powerpc/string.h
+++ b/include/asm-powerpc/string.h
@@ -1,5 +1,5 @@
1#ifndef _PPC_STRING_H_ 1#ifndef _ASM_POWERPC_STRING_H
2#define _PPC_STRING_H_ 2#define _ASM_POWERPC_STRING_H
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
@@ -29,4 +29,4 @@ extern void * memchr(const void *,int,__kernel_size_t);
29 29
30#endif /* __KERNEL__ */ 30#endif /* __KERNEL__ */
31 31
32#endif 32#endif /* _ASM_POWERPC_STRING_H */
diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h
index 2c5bf85a8c3c..ebf6055481dc 100644
--- a/include/asm-powerpc/termbits.h
+++ b/include/asm-powerpc/termbits.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_TERMBITS_H 1#ifndef _ASM_POWERPC_TERMBITS_H
2#define _POWERPC_TERMBITS_H 2#define _ASM_POWERPC_TERMBITS_H
3 3
4/* 4/*
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -188,4 +188,4 @@ struct termios {
188#define TCSADRAIN 1 188#define TCSADRAIN 1
189#define TCSAFLUSH 2 189#define TCSAFLUSH 2
190 190
191#endif /* _POWERPC_TERMBITS_H */ 191#endif /* _ASM_POWERPC_TERMBITS_H */
diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h
index 237533bb0e9f..c5b8e5358f83 100644
--- a/include/asm-powerpc/termios.h
+++ b/include/asm-powerpc/termios.h
@@ -1,5 +1,5 @@
1#ifndef _POWERPC_TERMIOS_H 1#ifndef _ASM_POWERPC_TERMIOS_H
2#define _POWERPC_TERMIOS_H 2#define _ASM_POWERPC_TERMIOS_H
3 3
4/* 4/*
5 * Liberally adapted from alpha/termios.h. In particular, the c_cc[] 5 * Liberally adapted from alpha/termios.h. In particular, the c_cc[]
@@ -233,4 +233,4 @@ struct termio {
233 233
234#endif /* __KERNEL__ */ 234#endif /* __KERNEL__ */
235 235
236#endif /* _POWERPC_TERMIOS_H */ 236#endif /* _ASM_POWERPC_TERMIOS_H */
diff --git a/include/asm-ppc/timex.h b/include/asm-powerpc/timex.h
index cffc8712077c..51c5b316be55 100644
--- a/include/asm-ppc/timex.h
+++ b/include/asm-powerpc/timex.h
@@ -1,11 +1,11 @@
1#ifndef _ASM_POWERPC_TIMEX_H
2#define _ASM_POWERPC_TIMEX_H
3
4#ifdef __KERNEL__
5
1/* 6/*
2 * include/asm-ppc/timex.h 7 * PowerPC architecture timex specifications
3 *
4 * ppc architecture timex specifications
5 */ 8 */
6#ifdef __KERNEL__
7#ifndef _ASMppc_TIMEX_H
8#define _ASMppc_TIMEX_H
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <asm/cputable.h> 11#include <asm/cputable.h>
@@ -14,14 +14,21 @@
14 14
15typedef unsigned long cycles_t; 15typedef unsigned long cycles_t;
16 16
17/*
18 * For the "cycle" counter we use the timebase lower half.
19 * Currently only used on SMP.
20 */
21
22static inline cycles_t get_cycles(void) 17static inline cycles_t get_cycles(void)
23{ 18{
24 cycles_t ret = 0; 19 cycles_t ret;
20
21#ifdef __powerpc64__
22
23 __asm__ __volatile__("mftb %0" : "=r" (ret) : );
24
25#else
26 /*
27 * For the "cycle" counter we use the timebase lower half.
28 * Currently only used on SMP.
29 */
30
31 ret = 0;
25 32
26 __asm__ __volatile__( 33 __asm__ __volatile__(
27 "98: mftb %0\n" 34 "98: mftb %0\n"
@@ -33,8 +40,10 @@ static inline cycles_t get_cycles(void)
33 " .long 99b\n" 40 " .long 99b\n"
34 ".previous" 41 ".previous"
35 : "=r" (ret) : "i" (CPU_FTR_601)); 42 : "=r" (ret) : "i" (CPU_FTR_601));
43#endif
44
36 return ret; 45 return ret;
37} 46}
38 47
39#endif 48#endif /* __KERNEL__ */
40#endif /* __KERNEL__ */ 49#endif /* _ASM_POWERPC_TIMEX_H */
diff --git a/include/asm-ppc64/topology.h b/include/asm-powerpc/topology.h
index 1e9b19073230..2512e3836bf4 100644
--- a/include/asm-ppc64/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -1,11 +1,12 @@
1#ifndef _ASM_PPC64_TOPOLOGY_H 1#ifndef _ASM_POWERPC_TOPOLOGY_H
2#define _ASM_PPC64_TOPOLOGY_H 2#define _ASM_POWERPC_TOPOLOGY_H
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5#include <asm/mmzone.h>
6 5
7#ifdef CONFIG_NUMA 6#ifdef CONFIG_NUMA
8 7
8#include <asm/mmzone.h>
9
9static inline int cpu_to_node(int cpu) 10static inline int cpu_to_node(int cpu)
10{ 11{
11 int node; 12 int node;
@@ -66,4 +67,4 @@ static inline int node_to_first_cpu(int node)
66 67
67#endif /* CONFIG_NUMA */ 68#endif /* CONFIG_NUMA */
68 69
69#endif /* _ASM_PPC64_TOPOLOGY_H */ 70#endif /* _ASM_POWERPC_TOPOLOGY_H */
diff --git a/include/asm-powerpc/unaligned.h b/include/asm-powerpc/unaligned.h
index 45520d9b85d1..6c95dfa2652f 100644
--- a/include/asm-powerpc/unaligned.h
+++ b/include/asm-powerpc/unaligned.h
@@ -1,6 +1,7 @@
1#ifndef _ASM_POWERPC_UNALIGNED_H
2#define _ASM_POWERPC_UNALIGNED_H
3
1#ifdef __KERNEL__ 4#ifdef __KERNEL__
2#ifndef __PPC_UNALIGNED_H
3#define __PPC_UNALIGNED_H
4 5
5/* 6/*
6 * The PowerPC can do unaligned accesses itself in big endian mode. 7 * The PowerPC can do unaligned accesses itself in big endian mode.
@@ -14,5 +15,5 @@
14 15
15#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) 16#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
16 17
17#endif 18#endif /* __KERNEL__ */
18#endif /* __KERNEL__ */ 19#endif /* _ASM_POWERPC_UNALIGNED_H */
diff --git a/include/asm-ppc/user.h b/include/asm-powerpc/user.h
index d662b2151370..e59ade4b3dfb 100644
--- a/include/asm-ppc/user.h
+++ b/include/asm-powerpc/user.h
@@ -1,13 +1,14 @@
1#ifdef __KERNEL__ 1#ifndef _ASM_POWERPC_USER_H
2#ifndef _PPC_USER_H 2#define _ASM_POWERPC_USER_H
3#define _PPC_USER_H
4 3
5/* Adapted from <asm-alpha/user.h> */ 4#ifdef __KERNEL__
6 5
7#include <linux/ptrace.h> 6#include <asm/ptrace.h>
8#include <asm/page.h> 7#include <asm/page.h>
9 8
10/* 9/*
10 * Adapted from <asm-alpha/user.h>
11 *
11 * Core file format: The core file is written in such a way that gdb 12 * Core file format: The core file is written in such a way that gdb
12 * can understand it and provide useful information to the user (under 13 * can understand it and provide useful information to the user (under
13 * linux we use the `trad-core' bfd, NOT the osf-core). The file contents 14 * linux we use the `trad-core' bfd, NOT the osf-core). The file contents
@@ -50,5 +51,5 @@ struct user {
50#define HOST_DATA_START_ADDR (u.start_data) 51#define HOST_DATA_START_ADDR (u.start_data)
51#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) 52#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
52 53
53#endif /* _PPC_USER_H */ 54#endif /* __KERNEL__ */
54#endif /* __KERNEL__ */ 55#endif /* _ASM_POWERPC_USER_H */
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index b4b270457edd..55752474d0d9 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -404,9 +404,5 @@ extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
404extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; 404extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
405extern atomic_t ppc_n_lost_interrupts; 405extern atomic_t ppc_n_lost_interrupts;
406 406
407struct irqaction;
408struct pt_regs;
409int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
410
411#endif /* _ASM_IRQ_H */ 407#endif /* _ASM_IRQ_H */
412#endif /* __KERNEL__ */ 408#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index a811e440c978..9dd06cd40096 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -109,6 +109,19 @@ extern void
109pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 109pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
110 struct pci_bus_region *region); 110 struct pci_bus_region *region);
111 111
112static inline struct resource *
113pcibios_select_root(struct pci_dev *pdev, struct resource *res)
114{
115 struct resource *root = NULL;
116
117 if (res->flags & IORESOURCE_IO)
118 root = &ioport_resource;
119 if (res->flags & IORESOURCE_MEM)
120 root = &iomem_resource;
121
122 return root;
123}
124
112extern void pcibios_add_platform_entries(struct pci_dev *dev); 125extern void pcibios_add_platform_entries(struct pci_dev *dev);
113 126
114struct file; 127struct file;
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
index 88b4222154d4..73c33e3ef9c6 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-ppc/reg.h
@@ -366,12 +366,6 @@
366#define PVR_STB03XXX 0x40310000 366#define PVR_STB03XXX 0x40310000
367#define PVR_NP405H 0x41410000 367#define PVR_NP405H 0x41410000
368#define PVR_NP405L 0x41610000 368#define PVR_NP405L 0x41610000
369#define PVR_440GP_RB 0x40120440
370#define PVR_440GP_RC1 0x40120481
371#define PVR_440GP_RC2 0x40200481
372#define PVR_440GX_RA 0x51b21850
373#define PVR_440GX_RB 0x51b21851
374#define PVR_440GX_RC 0x51b21892
375#define PVR_601 0x00010000 369#define PVR_601 0x00010000
376#define PVR_602 0x00050000 370#define PVR_602 0x00050000
377#define PVR_603 0x00030000 371#define PVR_603 0x00030000
diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h
deleted file mode 100644
index d2d19ee103df..000000000000
--- a/include/asm-ppc/setup.h
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifdef __KERNEL__
2#ifndef _PPC_SETUP_H
3#define _PPC_SETUP_H
4
5#define m68k_num_memory num_memory
6#define m68k_memory memory
7
8#include <asm-m68k/setup.h>
9/* We have a bigger command line buffer. */
10#undef COMMAND_LINE_SIZE
11#define COMMAND_LINE_SIZE 512
12
13#endif /* _PPC_SETUP_H */
14#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/topology.h b/include/asm-ppc/topology.h
deleted file mode 100644
index 6a029bbba6e1..000000000000
--- a/include/asm-ppc/topology.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASM_PPC_TOPOLOGY_H
2#define _ASM_PPC_TOPOLOGY_H
3
4#include <asm-generic/topology.h>
5
6#endif /* _ASM_PPC_TOPOLOGY_H */
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
index 94298b106a4b..40c8eb57493e 100644
--- a/include/asm-ppc64/eeh.h
+++ b/include/asm-ppc64/eeh.h
@@ -219,23 +219,24 @@ static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
219static inline void eeh_memset_io(volatile void __iomem *addr, int c, 219static inline void eeh_memset_io(volatile void __iomem *addr, int c,
220 unsigned long n) 220 unsigned long n)
221{ 221{
222 void *p = (void __force *)addr;
222 u32 lc = c; 223 u32 lc = c;
223 lc |= lc << 8; 224 lc |= lc << 8;
224 lc |= lc << 16; 225 lc |= lc << 16;
225 226
226 while(n && !EEH_CHECK_ALIGN(addr, 4)) { 227 while(n && !EEH_CHECK_ALIGN(p, 4)) {
227 *((volatile u8 *)addr) = c; 228 *((volatile u8 *)p) = c;
228 addr = (void *)((unsigned long)addr + 1); 229 p++;
229 n--; 230 n--;
230 } 231 }
231 while(n >= 4) { 232 while(n >= 4) {
232 *((volatile u32 *)addr) = lc; 233 *((volatile u32 *)p) = lc;
233 addr = (void *)((unsigned long)addr + 4); 234 p += 4;
234 n -= 4; 235 n -= 4;
235 } 236 }
236 while(n) { 237 while(n) {
237 *((volatile u8 *)addr) = c; 238 *((volatile u8 *)p) = c;
238 addr = (void *)((unsigned long)addr + 1); 239 p++;
239 n--; 240 n--;
240 } 241 }
241 __asm__ __volatile__ ("sync" : : : "memory"); 242 __asm__ __volatile__ ("sync" : : : "memory");
@@ -250,22 +251,22 @@ static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *sr
250 while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) { 251 while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
251 *((u8 *)dest) = *((volatile u8 *)vsrc); 252 *((u8 *)dest) = *((volatile u8 *)vsrc);
252 __asm__ __volatile__ ("eieio" : : : "memory"); 253 __asm__ __volatile__ ("eieio" : : : "memory");
253 vsrc = (void *)((unsigned long)vsrc + 1); 254 vsrc++;
254 dest = (void *)((unsigned long)dest + 1); 255 dest++;
255 n--; 256 n--;
256 } 257 }
257 while(n > 4) { 258 while(n > 4) {
258 *((u32 *)dest) = *((volatile u32 *)vsrc); 259 *((u32 *)dest) = *((volatile u32 *)vsrc);
259 __asm__ __volatile__ ("eieio" : : : "memory"); 260 __asm__ __volatile__ ("eieio" : : : "memory");
260 vsrc = (void *)((unsigned long)vsrc + 4); 261 vsrc += 4;
261 dest = (void *)((unsigned long)dest + 4); 262 dest += 4;
262 n -= 4; 263 n -= 4;
263 } 264 }
264 while(n) { 265 while(n) {
265 *((u8 *)dest) = *((volatile u8 *)vsrc); 266 *((u8 *)dest) = *((volatile u8 *)vsrc);
266 __asm__ __volatile__ ("eieio" : : : "memory"); 267 __asm__ __volatile__ ("eieio" : : : "memory");
267 vsrc = (void *)((unsigned long)vsrc + 1); 268 vsrc++;
268 dest = (void *)((unsigned long)dest + 1); 269 dest++;
269 n--; 270 n--;
270 } 271 }
271 __asm__ __volatile__ ("sync" : : : "memory"); 272 __asm__ __volatile__ ("sync" : : : "memory");
@@ -286,20 +287,20 @@ static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
286 287
287 while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) { 288 while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
288 *((volatile u8 *)vdest) = *((u8 *)src); 289 *((volatile u8 *)vdest) = *((u8 *)src);
289 src = (void *)((unsigned long)src + 1); 290 src++;
290 vdest = (void *)((unsigned long)vdest + 1); 291 vdest++;
291 n--; 292 n--;
292 } 293 }
293 while(n > 4) { 294 while(n > 4) {
294 *((volatile u32 *)vdest) = *((volatile u32 *)src); 295 *((volatile u32 *)vdest) = *((volatile u32 *)src);
295 src = (void *)((unsigned long)src + 4); 296 src += 4;
296 vdest = (void *)((unsigned long)vdest + 4); 297 vdest += 4;
297 n-=4; 298 n-=4;
298 } 299 }
299 while(n) { 300 while(n) {
300 *((volatile u8 *)vdest) = *((u8 *)src); 301 *((volatile u8 *)vdest) = *((u8 *)src);
301 src = (void *)((unsigned long)src + 1); 302 src++;
302 vdest = (void *)((unsigned long)vdest + 1); 303 vdest++;
303 n--; 304 n--;
304 } 305 }
305 __asm__ __volatile__ ("sync" : : : "memory"); 306 __asm__ __volatile__ ("sync" : : : "memory");
diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
index aba1dfa388ba..59c958aea4db 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-ppc64/io.h
@@ -20,10 +20,10 @@
20 20
21#include <asm-generic/iomap.h> 21#include <asm-generic/iomap.h>
22 22
23#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 *)(p), (a), (c)) 23#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c))
24#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 *)(p), (a), (c)) 24#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c))
25#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 *)(p), (a), (c)) 25#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c))
26#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 *)(p), (a), (c)) 26#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c))
27 27
28 28
29#define SIO_CONFIG_RA 0x398 29#define SIO_CONFIG_RA 0x398
@@ -71,8 +71,8 @@ extern unsigned long io_page_mask;
71 * Neither do the standard versions now, these are just here 71 * Neither do the standard versions now, these are just here
72 * for older code. 72 * for older code.
73 */ 73 */
74#define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+pci_io_base), (buf), (ns)) 74#define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
75#define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+pci_io_base), (buf), (nl)) 75#define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
76#else 76#else
77 77
78static inline unsigned char __raw_readb(const volatile void __iomem *addr) 78static inline unsigned char __raw_readb(const volatile void __iomem *addr)
@@ -136,9 +136,9 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
136#define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns)) 136#define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns))
137#define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl)) 137#define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl))
138 138
139#define outsb(port, buf, ns) _outsb((u8 *)((port)+pci_io_base), (buf), (ns)) 139#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
140#define outsw(port, buf, ns) _outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns)) 140#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
141#define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl)) 141#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
142 142
143#endif 143#endif
144 144
@@ -147,16 +147,16 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
147#define readl_relaxed(addr) readl(addr) 147#define readl_relaxed(addr) readl(addr)
148#define readq_relaxed(addr) readq(addr) 148#define readq_relaxed(addr) readq(addr)
149 149
150extern void _insb(volatile u8 *port, void *buf, int ns); 150extern void _insb(volatile u8 __iomem *port, void *buf, int ns);
151extern void _outsb(volatile u8 *port, const void *buf, int ns); 151extern void _outsb(volatile u8 __iomem *port, const void *buf, int ns);
152extern void _insw(volatile u16 *port, void *buf, int ns); 152extern void _insw(volatile u16 __iomem *port, void *buf, int ns);
153extern void _outsw(volatile u16 *port, const void *buf, int ns); 153extern void _outsw(volatile u16 __iomem *port, const void *buf, int ns);
154extern void _insl(volatile u32 *port, void *buf, int nl); 154extern void _insl(volatile u32 __iomem *port, void *buf, int nl);
155extern void _outsl(volatile u32 *port, const void *buf, int nl); 155extern void _outsl(volatile u32 __iomem *port, const void *buf, int nl);
156extern void _insw_ns(volatile u16 *port, void *buf, int ns); 156extern void _insw_ns(volatile u16 __iomem *port, void *buf, int ns);
157extern void _outsw_ns(volatile u16 *port, const void *buf, int ns); 157extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, int ns);
158extern void _insl_ns(volatile u32 *port, void *buf, int nl); 158extern void _insl_ns(volatile u32 __iomem *port, void *buf, int nl);
159extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); 159extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, int nl);
160 160
161#define mmiowb() 161#define mmiowb()
162 162
@@ -176,8 +176,8 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
176 * Neither do the standard versions now, these are just here 176 * Neither do the standard versions now, these are just here
177 * for older code. 177 * for older code.
178 */ 178 */
179#define outsw_ns(port, buf, ns) _outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns)) 179#define outsw_ns(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
180#define outsl_ns(port, buf, nl) _outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl)) 180#define outsl_ns(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
181 181
182 182
183#define IO_SPACE_LIMIT ~(0UL) 183#define IO_SPACE_LIMIT ~(0UL)
diff --git a/include/asm-ppc64/msgbuf.h b/include/asm-ppc64/msgbuf.h
deleted file mode 100644
index 31c1cbf133cc..000000000000
--- a/include/asm-ppc64/msgbuf.h
+++ /dev/null
@@ -1,27 +0,0 @@
1#ifndef _PPC64_MSGBUF_H
2#define _PPC64_MSGBUF_H
3
4/*
5 * The msqid64_ds structure for the PPC architecture.
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
13struct msqid64_ds {
14 struct ipc64_perm msg_perm;
15 __kernel_time_t msg_stime; /* last msgsnd time */
16 __kernel_time_t msg_rtime; /* last msgrcv time */
17 __kernel_time_t msg_ctime; /* last change time */
18 unsigned long msg_cbytes; /* current number of bytes on queue */
19 unsigned long msg_qnum; /* number of messages in queue */
20 unsigned long msg_qbytes; /* max number of bytes on queue */
21 __kernel_pid_t msg_lspid; /* pid of last msgsnd */
22 __kernel_pid_t msg_lrpid; /* last receive pid */
23 unsigned long __unused1;
24 unsigned long __unused2;
25};
26
27#endif /* _PPC64_MSGBUF_H */
diff --git a/include/asm-ppc64/param.h b/include/asm-ppc64/param.h
deleted file mode 100644
index 76c212d475b3..000000000000
--- a/include/asm-ppc64/param.h
+++ /dev/null
@@ -1,31 +0,0 @@
1#ifndef _ASM_PPC64_PARAM_H
2#define _ASM_PPC64_PARAM_H
3
4#include <linux/config.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#ifdef __KERNEL__
14# define HZ CONFIG_HZ /* Internal kernel timer frequency */
15# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
16# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
17#endif
18
19#ifndef HZ
20#define HZ 100
21#endif
22
23#define EXEC_PAGESIZE 4096
24
25#ifndef NOGROUP
26#define NOGROUP (-1)
27#endif
28
29#define MAXHOSTNAMELEN 64 /* max length of hostname */
30
31#endif /* _ASM_PPC64_PARAM_H */
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index c4f9023ea5ed..6b4a5b1f695e 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -48,19 +48,52 @@ struct pci_controller {
48 unsigned long dma_window_size; 48 unsigned long dma_window_size;
49}; 49};
50 50
51/*
52 * PCI stuff, for nodes representing PCI devices, pointed to
53 * by device_node->data.
54 */
55struct pci_controller;
56struct iommu_table;
57
58struct pci_dn {
59 int busno; /* for pci devices */
60 int bussubno; /* for pci devices */
61 int devfn; /* for pci devices */
62 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
63 int eeh_config_addr;
64 int eeh_capable; /* from firmware */
65 int eeh_check_count; /* # times driver ignored error */
66 int eeh_freeze_count; /* # times this device froze up. */
67 int eeh_is_bridge; /* device is pci-to-pci bridge */
68
69 int pci_ext_config_space; /* for pci devices */
70 struct pci_controller *phb; /* for pci devices */
71 struct iommu_table *iommu_table; /* for phb's or bridges */
72 struct pci_dev *pcidev; /* back-pointer to the pci device */
73 struct device_node *node; /* back-pointer to the device_node */
74 u32 config_space[16]; /* saved PCI config space */
75};
76
77/* Get the pointer to a device_node's pci_dn */
78#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
79
51struct device_node *fetch_dev_dn(struct pci_dev *dev); 80struct device_node *fetch_dev_dn(struct pci_dev *dev);
52 81
53/* Get a device_node from a pci_dev. This code must be fast except in the case 82/* Get a device_node from a pci_dev. This code must be fast except
54 * where the sysdata is incorrect and needs to be fixed up (hopefully just once) 83 * in the case where the sysdata is incorrect and needs to be fixed
84 * up (this will only happen once).
85 * In this case the sysdata will have been inherited from a PCI host
86 * bridge or a PCI-PCI bridge further up the tree, so it will point
87 * to a valid struct pci_dn, just not the one we want.
55 */ 88 */
56static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) 89static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
57{ 90{
58 struct device_node *dn = dev->sysdata; 91 struct device_node *dn = dev->sysdata;
92 struct pci_dn *pdn = dn->data;
59 93
60 if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) 94 if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number)
61 return dn; /* fast path. sysdata is good */ 95 return dn; /* fast path. sysdata is good */
62 else 96 return fetch_dev_dn(dev);
63 return fetch_dev_dn(dev);
64} 97}
65 98
66static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) 99static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
@@ -83,7 +116,7 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
83 struct device_node *busdn = bus->sysdata; 116 struct device_node *busdn = bus->sysdata;
84 117
85 BUG_ON(busdn == NULL); 118 BUG_ON(busdn == NULL);
86 return busdn->phb; 119 return PCI_DN(busdn)->phb;
87} 120}
88 121
89#endif 122#endif
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index 4d057452f59b..a88bbfc26967 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -138,6 +138,19 @@ extern void
138pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 138pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
139 struct pci_bus_region *region); 139 struct pci_bus_region *region);
140 140
141static inline struct resource *
142pcibios_select_root(struct pci_dev *pdev, struct resource *res)
143{
144 struct resource *root = NULL;
145
146 if (res->flags & IORESOURCE_IO)
147 root = &ioport_resource;
148 if (res->flags & IORESOURCE_MEM)
149 root = &iomem_resource;
150
151 return root;
152}
153
141extern int 154extern int
142unmap_bus_range(struct pci_bus *bus); 155unmap_bus_range(struct pci_bus *bus);
143 156
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index dc5330b39509..c02ec1d6b909 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -116,14 +116,6 @@ struct property {
116 struct property *next; 116 struct property *next;
117}; 117};
118 118
119/* NOTE: the device_node contains PCI specific info for pci devices.
120 * This perhaps could be hung off the device_node with another struct,
121 * but for now it is directly in the node. The phb ptr is a good
122 * indication of a real PCI node. Other nodes leave these fields zeroed.
123 */
124struct pci_controller;
125struct iommu_table;
126
127struct device_node { 119struct device_node {
128 char *name; 120 char *name;
129 char *type; 121 char *type;
@@ -135,16 +127,6 @@ struct device_node {
135 struct interrupt_info *intrs; 127 struct interrupt_info *intrs;
136 char *full_name; 128 char *full_name;
137 129
138 /* PCI stuff probably doesn't belong here */
139 int busno; /* for pci devices */
140 int bussubno; /* for pci devices */
141 int devfn; /* for pci devices */
142 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
143 int eeh_config_addr;
144 int pci_ext_config_space; /* for pci devices */
145 struct pci_controller *phb; /* for pci devices */
146 struct iommu_table *iommu_table; /* for phb's or bridges */
147
148 struct property *properties; 130 struct property *properties;
149 struct device_node *parent; 131 struct device_node *parent;
150 struct device_node *child; 132 struct device_node *child;
@@ -154,6 +136,7 @@ struct device_node {
154 struct proc_dir_entry *pde; /* this node's proc directory */ 136 struct proc_dir_entry *pde; /* this node's proc directory */
155 struct kref kref; 137 struct kref kref;
156 unsigned long _flags; 138 unsigned long _flags;
139 void *data;
157}; 140};
158 141
159extern struct device_node *of_chosen; 142extern struct device_node *of_chosen;
diff --git a/include/asm-ppc64/segment.h b/include/asm-ppc64/segment.h
deleted file mode 100644
index d80fb68cc79e..000000000000
--- a/include/asm-ppc64/segment.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __PPC64_SEGMENT_H
2#define __PPC64_SEGMENT_H
3
4/* Only here because we have some old header files that expect it.. */
5
6#endif /* __PPC64_SEGMENT_H */
diff --git a/include/asm-ppc64/setup.h b/include/asm-ppc64/setup.h
deleted file mode 100644
index b257b8348c73..000000000000
--- a/include/asm-ppc64/setup.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _PPC_SETUP_H
2#define _PPC_SETUP_H
3
4#define COMMAND_LINE_SIZE 512
5
6#endif /* _PPC_SETUP_H */
diff --git a/include/asm-ppc64/timex.h b/include/asm-ppc64/timex.h
deleted file mode 100644
index 8db4da4064cd..000000000000
--- a/include/asm-ppc64/timex.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * linux/include/asm-ppc/timex.h
3 *
4 * PPC64 architecture timex specifications
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#ifndef _ASMPPC64_TIMEX_H
12#define _ASMPPC64_TIMEX_H
13
14#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
15
16typedef unsigned long cycles_t;
17
18static inline cycles_t get_cycles(void)
19{
20 cycles_t ret;
21
22 __asm__ __volatile__("mftb %0" : "=r" (ret) : );
23 return ret;
24}
25
26#endif
diff --git a/include/asm-ppc64/user.h b/include/asm-ppc64/user.h
deleted file mode 100644
index d7d6554a421f..000000000000
--- a/include/asm-ppc64/user.h
+++ /dev/null
@@ -1,58 +0,0 @@
1#ifndef _PPC_USER_H
2#define _PPC_USER_H
3
4/* Adapted from <asm-alpha/user.h>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <asm/ptrace.h>
13#include <asm/page.h>
14
15/*
16 * Core file format: The core file is written in such a way that gdb
17 * can understand it and provide useful information to the user (under
18 * linux we use the `trad-core' bfd, NOT the osf-core). The file contents
19 * are as follows:
20 *
21 * upage: 1 page consisting of a user struct that tells gdb
22 * what is present in the file. Directly after this is a
23 * copy of the task_struct, which is currently not used by gdb,
24 * but it may come in handy at some point. All of the registers
25 * are stored as part of the upage. The upage should always be
26 * only one page long.
27 * data: The data segment follows next. We use current->end_text to
28 * current->brk to pick up all of the user variables, plus any memory
29 * that may have been sbrk'ed. No attempt is made to determine if a
30 * page is demand-zero or if a page is totally unused, we just cover
31 * the entire range. All of the addresses are rounded in such a way
32 * that an integral number of pages is written.
33 * stack: We need the stack information in order to get a meaningful
34 * backtrace. We need to write the data from usp to
35 * current->start_stack, so we round each of these in order to be able
36 * to write an integer number of pages.
37 */
38struct user {
39 struct pt_regs regs; /* entire machine state */
40 size_t u_tsize; /* text size (pages) */
41 size_t u_dsize; /* data size (pages) */
42 size_t u_ssize; /* stack size (pages) */
43 unsigned long start_code; /* text starting address */
44 unsigned long start_data; /* data starting address */
45 unsigned long start_stack; /* stack starting address */
46 long int signal; /* signal causing core dump */
47 struct regs * u_ar0; /* help gdb find registers */
48 unsigned long magic; /* identifies a core file */
49 char u_comm[32]; /* user command name */
50};
51
52#define NBPG PAGE_SIZE
53#define UPAGES 1
54#define HOST_TEXT_START_ADDR (u.start_code)
55#define HOST_DATA_START_ADDR (u.start_data)
56#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
57
58#endif /* _PPC_USER_H */
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 831e52ee45b5..614a8c13b721 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -587,10 +587,6 @@ static inline int generic_irq_demux(int irq)
587#define irq_canonicalize(irq) (irq) 587#define irq_canonicalize(irq) (irq)
588#define irq_demux(irq) __irq_demux(sh_mv.mv_irq_demux(irq)) 588#define irq_demux(irq) __irq_demux(sh_mv.mv_irq_demux(irq))
589 589
590struct irqaction;
591struct pt_regs;
592int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
593
594#if defined(CONFIG_CPU_SUBTYPE_SH73180) 590#if defined(CONFIG_CPU_SUBTYPE_SH73180)
595#include <asm/irq-sh73180.h> 591#include <asm/irq-sh73180.h>
596#endif 592#endif
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index a4ab0ec7143a..89bd71b1c0d8 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -269,6 +269,8 @@ extern void
269pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 269pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
270 struct pci_bus_region *region); 270 struct pci_bus_region *region);
271 271
272extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
273
272static inline void pcibios_add_platform_entries(struct pci_dev *dev) 274static inline void pcibios_add_platform_entries(struct pci_dev *dev)
273{ 275{
274} 276}
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 5e94c05dc2fc..b5417529f6f1 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -28,13 +28,48 @@ enum sparc_cpu {
28#define ARCH_SUN4C_SUN4 0 28#define ARCH_SUN4C_SUN4 0
29#define ARCH_SUN4 0 29#define ARCH_SUN4 0
30 30
31extern void mb(void); 31/* These are here in an effort to more fully work around Spitfire Errata
32extern void rmb(void); 32 * #51. Essentially, if a memory barrier occurs soon after a mispredicted
33extern void wmb(void); 33 * branch, the chip can stop executing instructions until a trap occurs.
34extern void membar_storeload(void); 34 * Therefore, if interrupts are disabled, the chip can hang forever.
35extern void membar_storeload_storestore(void); 35 *
36extern void membar_storeload_loadload(void); 36 * It used to be believed that the memory barrier had to be right in the
37extern void membar_storestore_loadstore(void); 37 * delay slot, but a case has been traced recently wherein the memory barrier
38 * was one instruction after the branch delay slot and the chip still hung.
39 * The offending sequence was the following in sym_wakeup_done() of the
40 * sym53c8xx_2 driver:
41 *
42 * call sym_ccb_from_dsa, 0
43 * movge %icc, 0, %l0
44 * brz,pn %o0, .LL1303
45 * mov %o0, %l2
46 * membar #LoadLoad
47 *
48 * The branch has to be mispredicted for the bug to occur. Therefore, we put
49 * the memory barrier explicitly into a "branch always, predicted taken"
50 * delay slot to avoid the problem case.
51 */
52#define membar_safe(type) \
53do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
54 " membar " type "\n" \
55 "1:\n" \
56 : : : "memory"); \
57} while (0)
58
59#define mb() \
60 membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
61#define rmb() \
62 membar_safe("#LoadLoad")
63#define wmb() \
64 membar_safe("#StoreStore")
65#define membar_storeload() \
66 membar_safe("#StoreLoad")
67#define membar_storeload_storestore() \
68 membar_safe("#StoreLoad | #StoreStore")
69#define membar_storeload_loadload() \
70 membar_safe("#StoreLoad | #LoadLoad")
71#define membar_storestore_loadstore() \
72 membar_safe("#StoreStore | #LoadStore")
38 73
39#endif 74#endif
40 75
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
index 4482657777bb..fb724ba37ae6 100644
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -48,10 +48,6 @@ static __inline__ int irq_canonicalize(int irq)
48#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ 48#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
49#endif 49#endif
50 50
51struct irqaction;
52struct pt_regs;
53int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
54
55#ifdef CONFIG_HOTPLUG_CPU 51#ifdef CONFIG_HOTPLUG_CPU
56#include <linux/cpumask.h> 52#include <linux/cpumask.h>
57extern void fixup_irqs(cpumask_t map); 53extern void fixup_irqs(cpumask_t map);
diff --git a/include/linux/bfs_fs.h b/include/linux/bfs_fs.h
index f7f0913cd110..c1237aa92e38 100644
--- a/include/linux/bfs_fs.h
+++ b/include/linux/bfs_fs.h
@@ -14,8 +14,9 @@
14#define BFS_INODES_PER_BLOCK 8 14#define BFS_INODES_PER_BLOCK 8
15 15
16/* SVR4 vnode type values (bfs_inode->i_vtype) */ 16/* SVR4 vnode type values (bfs_inode->i_vtype) */
17#define BFS_VDIR 2 17#define BFS_VDIR 2L
18#define BFS_VREG 1 18#define BFS_VREG 1L
19
19 20
20/* BFS inode layout on disk */ 21/* BFS inode layout on disk */
21struct bfs_inode { 22struct bfs_inode {
@@ -58,22 +59,22 @@ struct bfs_super_block {
58 __u32 s_padding[118]; 59 __u32 s_padding[118];
59}; 60};
60 61
61#define BFS_NZFILESIZE(ip) \
62 (((ip)->i_eoffset + 1) - (ip)->i_sblock * BFS_BSIZE)
63
64#define BFS_FILESIZE(ip) \
65 ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
66
67#define BFS_FILEBLOCKS(ip) \
68 ((ip)->i_sblock == 0 ? 0 : ((ip)->i_eblock + 1) - (ip)->i_sblock)
69 62
70#define BFS_OFF2INO(offset) \ 63#define BFS_OFF2INO(offset) \
71 ((((offset) - BFS_BSIZE) / sizeof(struct bfs_inode)) + BFS_ROOT_INO) 64 ((((offset) - BFS_BSIZE) / sizeof(struct bfs_inode)) + BFS_ROOT_INO)
72 65
73#define BFS_INO2OFF(ino) \ 66#define BFS_INO2OFF(ino) \
74 ((__u32)(((ino) - BFS_ROOT_INO) * sizeof(struct bfs_inode)) + BFS_BSIZE) 67 ((__u32)(((ino) - BFS_ROOT_INO) * sizeof(struct bfs_inode)) + BFS_BSIZE)
68#define BFS_NZFILESIZE(ip) \
69 ((cpu_to_le32((ip)->i_eoffset) + 1) - cpu_to_le32((ip)->i_sblock) * BFS_BSIZE)
70
71#define BFS_FILESIZE(ip) \
72 ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
75 73
74#define BFS_FILEBLOCKS(ip) \
75 ((ip)->i_sblock == 0 ? 0 : (cpu_to_le32((ip)->i_eblock) + 1) - cpu_to_le32((ip)->i_sblock))
76#define BFS_UNCLEAN(bfs_sb, sb) \ 76#define BFS_UNCLEAN(bfs_sb, sb) \
77 ((bfs_sb->s_from != -1) && (bfs_sb->s_to != -1) && !(sb->s_flags & MS_RDONLY)) 77 ((cpu_to_le32(bfs_sb->s_from) != -1) && (cpu_to_le32(bfs_sb->s_to) != -1) && !(sb->s_flags & MS_RDONLY))
78
78 79
79#endif /* _LINUX_BFS_FS_H */ 80#endif /* _LINUX_BFS_FS_H */
diff --git a/include/linux/crc16.h b/include/linux/crc16.h
new file mode 100644
index 000000000000..bdedf825b04a
--- /dev/null
+++ b/include/linux/crc16.h
@@ -0,0 +1,44 @@
1/*
2 * crc16.h - CRC-16 routine
3 *
4 * Implements the standard CRC-16, as used with 1-wire devices:
5 * Width 16
6 * Poly 0x8005 (x^16 + x^15 + x^2 + 1)
7 * Init 0
8 *
9 * For 1-wire devices, the CRC is stored inverted, LSB-first
10 *
11 * Example buffer with the CRC attached:
12 * 31 32 33 34 35 36 37 38 39 C2 44
13 *
14 * The CRC over a buffer with the CRC attached is 0xB001.
15 * So, if (crc16(0, buf, size) == 0xB001) then the buffer is valid.
16 *
17 * Refer to "Application Note 937: Book of iButton Standards" for details.
18 * http://www.maxim-ic.com/appnotes.cfm/appnote_number/937
19 *
20 * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
21 *
22 * This source code is licensed under the GNU General Public License,
23 * Version 2. See the file COPYING for more details.
24 */
25
26#ifndef __CRC16_H
27#define __CRC16_H
28
29#include <linux/types.h>
30
31#define CRC16_INIT 0
32#define CRC16_VALID 0xb001
33
34extern u16 const crc16_table[256];
35
36extern u16 crc16(u16 crc, const u8 *buffer, size_t len);
37
38static inline u16 crc16_byte(u16 crc, const u8 data)
39{
40 return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
41}
42
43#endif /* __CRC16_H */
44
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 007c290f74d4..8bf4bacb5051 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -432,7 +432,10 @@ struct dccp_sock {
432 struct ccid *dccps_hc_rx_ccid; 432 struct ccid *dccps_hc_rx_ccid;
433 struct ccid *dccps_hc_tx_ccid; 433 struct ccid *dccps_hc_tx_ccid;
434 struct dccp_options_received dccps_options_received; 434 struct dccp_options_received dccps_options_received;
435 struct timeval dccps_epoch;
435 enum dccp_role dccps_role:2; 436 enum dccp_role dccps_role:2;
437 __u8 dccps_hc_rx_insert_options:1;
438 __u8 dccps_hc_tx_insert_options:1;
436}; 439};
437 440
438static inline struct dccp_sock *dccp_sk(const struct sock *sk) 441static inline struct dccp_sock *dccp_sk(const struct sock *sk)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24beeed971..82e39cd0c4fb 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -107,6 +107,8 @@
107#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */ 107#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */
108#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */ 108#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */
109#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */ 109#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */
110#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
111#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
110#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ 112#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
111#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ 113#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
112#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ 114#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
@@ -495,6 +497,9 @@ struct fb_cursor_user {
495#define FB_EVENT_BLANK 0x08 497#define FB_EVENT_BLANK 0x08
496/* Private modelist is to be replaced */ 498/* Private modelist is to be replaced */
497#define FB_EVENT_NEW_MODELIST 0x09 499#define FB_EVENT_NEW_MODELIST 0x09
500/* The resolution of the passed in fb_info about to change and
501 all vc's should be changed */
502#define FB_EVENT_MODE_CHANGE_ALL 0x0A
498 503
499struct fb_event { 504struct fb_event {
500 struct fb_info *info; 505 struct fb_info *info;
@@ -820,13 +825,29 @@ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
820 u32 height, u32 shift_high, u32 shift_low, u32 mod); 825 u32 height, u32 shift_high, u32 shift_low, u32 mod);
821extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height); 826extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height);
822extern void fb_set_suspend(struct fb_info *info, int state); 827extern void fb_set_suspend(struct fb_info *info, int state);
823extern int fb_get_color_depth(struct fb_var_screeninfo *var); 828extern int fb_get_color_depth(struct fb_var_screeninfo *var,
829 struct fb_fix_screeninfo *fix);
824extern int fb_get_options(char *name, char **option); 830extern int fb_get_options(char *name, char **option);
825extern int fb_new_modelist(struct fb_info *info); 831extern int fb_new_modelist(struct fb_info *info);
826 832
827extern struct fb_info *registered_fb[FB_MAX]; 833extern struct fb_info *registered_fb[FB_MAX];
828extern int num_registered_fb; 834extern int num_registered_fb;
829 835
836static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
837 u8 *src, u32 s_pitch, u32 height)
838{
839 int i, j;
840
841 d_pitch -= s_pitch;
842
843 for (i = height; i--; ) {
844 /* s_pitch is a few bytes at the most, memcpy is suboptimal */
845 for (j = 0; j < s_pitch; j++)
846 *dst++ = *src++;
847 dst += d_pitch;
848 }
849}
850
830/* drivers/video/fbsysfs.c */ 851/* drivers/video/fbsysfs.c */
831extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); 852extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
832extern void framebuffer_release(struct fb_info *info); 853extern void framebuffer_release(struct fb_info *info);
@@ -856,8 +877,11 @@ extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
856extern int fb_validate_mode(const struct fb_var_screeninfo *var, 877extern int fb_validate_mode(const struct fb_var_screeninfo *var,
857 struct fb_info *info); 878 struct fb_info *info);
858extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var); 879extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var);
859extern void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs); 880extern const unsigned char *fb_firmware_edid(struct device *device);
881extern void fb_edid_to_monspecs(unsigned char *edid,
882 struct fb_monspecs *specs);
860extern void fb_destroy_modedb(struct fb_videomode *modedb); 883extern void fb_destroy_modedb(struct fb_videomode *modedb);
884extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
861 885
862/* drivers/video/modedb.c */ 886/* drivers/video/modedb.c */
863#define VESA_MODEDB_SIZE 34 887#define VESA_MODEDB_SIZE 34
diff --git a/include/linux/file.h b/include/linux/file.h
index 5206beb9a80e..f5bbd4c508b3 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -9,6 +9,7 @@
9#include <linux/posix_types.h> 9#include <linux/posix_types.h>
10#include <linux/compiler.h> 10#include <linux/compiler.h>
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <linux/rcupdate.h>
12 13
13/* 14/*
14 * The default fd array needs to be at least BITS_PER_LONG, 15 * The default fd array needs to be at least BITS_PER_LONG,
@@ -16,23 +17,33 @@
16 */ 17 */
17#define NR_OPEN_DEFAULT BITS_PER_LONG 18#define NR_OPEN_DEFAULT BITS_PER_LONG
18 19
20struct fdtable {
21 unsigned int max_fds;
22 int max_fdset;
23 int next_fd;
24 struct file ** fd; /* current fd array */
25 fd_set *close_on_exec;
26 fd_set *open_fds;
27 struct rcu_head rcu;
28 struct files_struct *free_files;
29 struct fdtable *next;
30};
31
19/* 32/*
20 * Open file table structure 33 * Open file table structure
21 */ 34 */
22struct files_struct { 35struct files_struct {
23 atomic_t count; 36 atomic_t count;
24 spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */ 37 spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */
25 int max_fds; 38 struct fdtable *fdt;
26 int max_fdset; 39 struct fdtable fdtab;
27 int next_fd;
28 struct file ** fd; /* current fd array */
29 fd_set *close_on_exec;
30 fd_set *open_fds;
31 fd_set close_on_exec_init; 40 fd_set close_on_exec_init;
32 fd_set open_fds_init; 41 fd_set open_fds_init;
33 struct file * fd_array[NR_OPEN_DEFAULT]; 42 struct file * fd_array[NR_OPEN_DEFAULT];
34}; 43};
35 44
45#define files_fdtable(files) (rcu_dereference((files)->fdt))
46
36extern void FASTCALL(__fput(struct file *)); 47extern void FASTCALL(__fput(struct file *));
37extern void FASTCALL(fput(struct file *)); 48extern void FASTCALL(fput(struct file *));
38 49
@@ -59,13 +70,16 @@ extern fd_set *alloc_fdset(int);
59extern void free_fdset(fd_set *, int); 70extern void free_fdset(fd_set *, int);
60 71
61extern int expand_files(struct files_struct *, int nr); 72extern int expand_files(struct files_struct *, int nr);
73extern void free_fdtable(struct fdtable *fdt);
74extern void __init files_defer_init(void);
62 75
63static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) 76static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
64{ 77{
65 struct file * file = NULL; 78 struct file * file = NULL;
79 struct fdtable *fdt = files_fdtable(files);
66 80
67 if (fd < files->max_fds) 81 if (fd < fdt->max_fds)
68 file = files->fd[fd]; 82 file = rcu_dereference(fdt->fd[fd]);
69 return file; 83 return file;
70} 84}
71 85
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd93ab7da905..7f61227827d7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -9,6 +9,7 @@
9#include <linux/config.h> 9#include <linux/config.h>
10#include <linux/limits.h> 10#include <linux/limits.h>
11#include <linux/ioctl.h> 11#include <linux/ioctl.h>
12#include <linux/rcuref.h>
12 13
13/* 14/*
14 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change 15 * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -597,12 +598,13 @@ struct file {
597 spinlock_t f_ep_lock; 598 spinlock_t f_ep_lock;
598#endif /* #ifdef CONFIG_EPOLL */ 599#endif /* #ifdef CONFIG_EPOLL */
599 struct address_space *f_mapping; 600 struct address_space *f_mapping;
601 struct rcu_head f_rcuhead;
600}; 602};
601extern spinlock_t files_lock; 603extern spinlock_t files_lock;
602#define file_list_lock() spin_lock(&files_lock); 604#define file_list_lock() spin_lock(&files_lock);
603#define file_list_unlock() spin_unlock(&files_lock); 605#define file_list_unlock() spin_unlock(&files_lock);
604 606
605#define get_file(x) atomic_inc(&(x)->f_count) 607#define get_file(x) rcuref_inc(&(x)->f_count)
606#define file_count(x) atomic_read(&(x)->f_count) 608#define file_count(x) atomic_read(&(x)->f_count)
607 609
608#define MAX_NON_LFS ((1UL<<31) - 1) 610#define MAX_NON_LFS ((1UL<<31) - 1)
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
new file mode 100644
index 000000000000..acbeb96a3353
--- /dev/null
+++ b/include/linux/fuse.h
@@ -0,0 +1,259 @@
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9/* This file defines the kernel interface of FUSE */
10
11#include <asm/types.h>
12
13/** Version number of this interface */
14#define FUSE_KERNEL_VERSION 7
15
16/** Minor version number of this interface */
17#define FUSE_KERNEL_MINOR_VERSION 2
18
19/** The node ID of the root inode */
20#define FUSE_ROOT_ID 1
21
22/** The major number of the fuse character device */
23#define FUSE_MAJOR 10
24
25/** The minor number of the fuse character device */
26#define FUSE_MINOR 229
27
28/* Make sure all structures are padded to 64bit boundary, so 32bit
29 userspace works under 64bit kernels */
30
31struct fuse_attr {
32 __u64 ino;
33 __u64 size;
34 __u64 blocks;
35 __u64 atime;
36 __u64 mtime;
37 __u64 ctime;
38 __u32 atimensec;
39 __u32 mtimensec;
40 __u32 ctimensec;
41 __u32 mode;
42 __u32 nlink;
43 __u32 uid;
44 __u32 gid;
45 __u32 rdev;
46};
47
48struct fuse_kstatfs {
49 __u64 blocks;
50 __u64 bfree;
51 __u64 bavail;
52 __u64 files;
53 __u64 ffree;
54 __u32 bsize;
55 __u32 namelen;
56};
57
58#define FATTR_MODE (1 << 0)
59#define FATTR_UID (1 << 1)
60#define FATTR_GID (1 << 2)
61#define FATTR_SIZE (1 << 3)
62#define FATTR_ATIME (1 << 4)
63#define FATTR_MTIME (1 << 5)
64#define FATTR_CTIME (1 << 6)
65
66/**
67 * Flags returned by the OPEN request
68 *
69 * FOPEN_DIRECT_IO: bypass page cache for this open file
70 * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
71 */
72#define FOPEN_DIRECT_IO (1 << 0)
73#define FOPEN_KEEP_CACHE (1 << 1)
74
75enum fuse_opcode {
76 FUSE_LOOKUP = 1,
77 FUSE_FORGET = 2, /* no reply */
78 FUSE_GETATTR = 3,
79 FUSE_SETATTR = 4,
80 FUSE_READLINK = 5,
81 FUSE_SYMLINK = 6,
82 FUSE_MKNOD = 8,
83 FUSE_MKDIR = 9,
84 FUSE_UNLINK = 10,
85 FUSE_RMDIR = 11,
86 FUSE_RENAME = 12,
87 FUSE_LINK = 13,
88 FUSE_OPEN = 14,
89 FUSE_READ = 15,
90 FUSE_WRITE = 16,
91 FUSE_STATFS = 17,
92 FUSE_RELEASE = 18,
93 FUSE_FSYNC = 20,
94 FUSE_SETXATTR = 21,
95 FUSE_GETXATTR = 22,
96 FUSE_LISTXATTR = 23,
97 FUSE_REMOVEXATTR = 24,
98 FUSE_FLUSH = 25,
99 FUSE_INIT = 26,
100 FUSE_OPENDIR = 27,
101 FUSE_READDIR = 28,
102 FUSE_RELEASEDIR = 29,
103 FUSE_FSYNCDIR = 30
104};
105
106/* Conservative buffer size for the client */
107#define FUSE_MAX_IN 8192
108
109#define FUSE_NAME_MAX 1024
110#define FUSE_SYMLINK_MAX 4096
111#define FUSE_XATTR_SIZE_MAX 4096
112
113struct fuse_entry_out {
114 __u64 nodeid; /* Inode ID */
115 __u64 generation; /* Inode generation: nodeid:gen must
116 be unique for the fs's lifetime */
117 __u64 entry_valid; /* Cache timeout for the name */
118 __u64 attr_valid; /* Cache timeout for the attributes */
119 __u32 entry_valid_nsec;
120 __u32 attr_valid_nsec;
121 struct fuse_attr attr;
122};
123
124struct fuse_forget_in {
125 __u64 nlookup;
126};
127
128struct fuse_attr_out {
129 __u64 attr_valid; /* Cache timeout for the attributes */
130 __u32 attr_valid_nsec;
131 __u32 dummy;
132 struct fuse_attr attr;
133};
134
135struct fuse_mknod_in {
136 __u32 mode;
137 __u32 rdev;
138};
139
140struct fuse_mkdir_in {
141 __u32 mode;
142 __u32 padding;
143};
144
145struct fuse_rename_in {
146 __u64 newdir;
147};
148
149struct fuse_link_in {
150 __u64 oldnodeid;
151};
152
153struct fuse_setattr_in {
154 __u32 valid;
155 __u32 padding;
156 struct fuse_attr attr;
157};
158
159struct fuse_open_in {
160 __u32 flags;
161 __u32 padding;
162};
163
164struct fuse_open_out {
165 __u64 fh;
166 __u32 open_flags;
167 __u32 padding;
168};
169
170struct fuse_release_in {
171 __u64 fh;
172 __u32 flags;
173 __u32 padding;
174};
175
176struct fuse_flush_in {
177 __u64 fh;
178 __u32 flush_flags;
179 __u32 padding;
180};
181
182struct fuse_read_in {
183 __u64 fh;
184 __u64 offset;
185 __u32 size;
186 __u32 padding;
187};
188
189struct fuse_write_in {
190 __u64 fh;
191 __u64 offset;
192 __u32 size;
193 __u32 write_flags;
194};
195
196struct fuse_write_out {
197 __u32 size;
198 __u32 padding;
199};
200
201struct fuse_statfs_out {
202 struct fuse_kstatfs st;
203};
204
205struct fuse_fsync_in {
206 __u64 fh;
207 __u32 fsync_flags;
208 __u32 padding;
209};
210
211struct fuse_setxattr_in {
212 __u32 size;
213 __u32 flags;
214};
215
216struct fuse_getxattr_in {
217 __u32 size;
218 __u32 padding;
219};
220
221struct fuse_getxattr_out {
222 __u32 size;
223 __u32 padding;
224};
225
226struct fuse_init_in_out {
227 __u32 major;
228 __u32 minor;
229};
230
231struct fuse_in_header {
232 __u32 len;
233 __u32 opcode;
234 __u64 unique;
235 __u64 nodeid;
236 __u32 uid;
237 __u32 gid;
238 __u32 pid;
239 __u32 padding;
240};
241
242struct fuse_out_header {
243 __u32 len;
244 __s32 error;
245 __u64 unique;
246};
247
248struct fuse_dirent {
249 __u64 ino;
250 __u64 off;
251 __u32 namelen;
252 __u32 type;
253 char name[0];
254};
255
256#define FUSE_NAME_OFFSET ((unsigned) ((struct fuse_dirent *) 0)->name)
257#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
258#define FUSE_DIRENT_SIZE(d) \
259 FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
diff --git a/include/linux/i2c-pxa.h b/include/linux/i2c-pxa.h
new file mode 100644
index 000000000000..5f3eaf802223
--- /dev/null
+++ b/include/linux/i2c-pxa.h
@@ -0,0 +1,48 @@
1#ifndef _LINUX_I2C_ALGO_PXA_H
2#define _LINUX_I2C_ALGO_PXA_H
3
4struct i2c_eeprom_emu_watcher {
5 void (*write)(void *, unsigned int addr, unsigned char newval);
6};
7
8struct i2c_eeprom_emu_watch {
9 struct list_head node;
10 unsigned int start;
11 unsigned int end;
12 struct i2c_eeprom_emu_watcher *ops;
13 void *data;
14};
15
16#define I2C_EEPROM_EMU_SIZE (256)
17
18struct i2c_eeprom_emu {
19 unsigned int size;
20 unsigned int ptr;
21 unsigned int seen_start;
22 struct list_head watch;
23
24 unsigned char bytes[I2C_EEPROM_EMU_SIZE];
25};
26
27typedef enum i2c_slave_event_e {
28 I2C_SLAVE_EVENT_START_READ,
29 I2C_SLAVE_EVENT_START_WRITE,
30 I2C_SLAVE_EVENT_STOP
31} i2c_slave_event_t;
32
33struct i2c_slave_client {
34 void *data;
35 void (*event)(void *ptr, i2c_slave_event_t event);
36 int (*read) (void *ptr);
37 void (*write)(void *ptr, unsigned int val);
38};
39
40extern int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *, void *data,
41 unsigned int addr, unsigned int size,
42 struct i2c_eeprom_emu_watcher *);
43
44extern void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *, void *data, struct i2c_eeprom_emu_watcher *watcher);
45
46extern struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void);
47
48#endif /* _LINUX_I2C_ALGO_PXA_H */
diff --git a/include/linux/in6.h b/include/linux/in6.h
index dcf5720ffcbb..bd32b79d6295 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -148,13 +148,13 @@ struct in6_flowlabel_req
148 */ 148 */
149 149
150#define IPV6_ADDRFORM 1 150#define IPV6_ADDRFORM 1
151#define IPV6_PKTINFO 2 151#define IPV6_2292PKTINFO 2
152#define IPV6_HOPOPTS 3 152#define IPV6_2292HOPOPTS 3
153#define IPV6_DSTOPTS 4 153#define IPV6_2292DSTOPTS 4
154#define IPV6_RTHDR 5 154#define IPV6_2292RTHDR 5
155#define IPV6_PKTOPTIONS 6 155#define IPV6_2292PKTOPTIONS 6
156#define IPV6_CHECKSUM 7 156#define IPV6_CHECKSUM 7
157#define IPV6_HOPLIMIT 8 157#define IPV6_2292HOPLIMIT 8
158#define IPV6_NEXTHOP 9 158#define IPV6_NEXTHOP 9
159#define IPV6_AUTHHDR 10 /* obsolete */ 159#define IPV6_AUTHHDR 10 /* obsolete */
160#define IPV6_FLOWINFO 11 160#define IPV6_FLOWINFO 11
@@ -198,4 +198,28 @@ struct in6_flowlabel_req
198 * MCAST_MSFILTER 48 198 * MCAST_MSFILTER 48
199 */ 199 */
200 200
201/* RFC3542 advanced socket options (50-67) */
202#define IPV6_RECVPKTINFO 50
203#define IPV6_PKTINFO 51
204#if 0
205#define IPV6_RECVPATHMTU 52
206#define IPV6_PATHMTU 53
207#define IPV6_DONTFRAG 54
208#define IPV6_USE_MIN_MTU 55
209#endif
210#define IPV6_RECVHOPOPTS 56
211#define IPV6_HOPOPTS 57
212#if 0
213#define IPV6_RECVRTHDRDSTOPTS 58 /* Unused, see net/ipv6/datagram.c */
214#endif
215#define IPV6_RTHDRDSTOPTS 59
216#define IPV6_RECVRTHDR 60
217#define IPV6_RTHDR 61
218#define IPV6_RECVDSTOPTS 62
219#define IPV6_DSTOPTS 63
220#define IPV6_RECVHOPLIMIT 64
221#define IPV6_HOPLIMIT 65
222#define IPV6_RECVTCLASS 66
223#define IPV6_TCLASS 67
224
201#endif 225#endif
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index c727c195a91a..68ab5f2ab9cd 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -2,17 +2,27 @@
2#define _LINUX__INIT_TASK_H 2#define _LINUX__INIT_TASK_H
3 3
4#include <linux/file.h> 4#include <linux/file.h>
5#include <linux/rcupdate.h>
5 6
6#define INIT_FILES \ 7#define INIT_FDTABLE \
7{ \ 8{ \
8 .count = ATOMIC_INIT(1), \
9 .file_lock = SPIN_LOCK_UNLOCKED, \
10 .max_fds = NR_OPEN_DEFAULT, \ 9 .max_fds = NR_OPEN_DEFAULT, \
11 .max_fdset = __FD_SETSIZE, \ 10 .max_fdset = __FD_SETSIZE, \
12 .next_fd = 0, \ 11 .next_fd = 0, \
13 .fd = &init_files.fd_array[0], \ 12 .fd = &init_files.fd_array[0], \
14 .close_on_exec = &init_files.close_on_exec_init, \ 13 .close_on_exec = &init_files.close_on_exec_init, \
15 .open_fds = &init_files.open_fds_init, \ 14 .open_fds = &init_files.open_fds_init, \
15 .rcu = RCU_HEAD_INIT, \
16 .free_files = NULL, \
17 .next = NULL, \
18}
19
20#define INIT_FILES \
21{ \
22 .count = ATOMIC_INIT(1), \
23 .file_lock = SPIN_LOCK_UNLOCKED, \
24 .fdt = &init_files.fdtab, \
25 .fdtab = INIT_FDTABLE, \
16 .close_on_exec_init = { { 0, } }, \ 26 .close_on_exec_init = { { 0, } }, \
17 .open_fds_init = { { 0, } }, \ 27 .open_fds_init = { { 0, } }, \
18 .fd_array = { NULL, } \ 28 .fd_array = { NULL, } \
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 3c7dbc6a0a70..6c5f7b39a4b0 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -189,6 +189,7 @@ struct inet6_skb_parm {
189 __u16 dst0; 189 __u16 dst0;
190 __u16 srcrt; 190 __u16 srcrt;
191 __u16 dst1; 191 __u16 dst1;
192 __u16 lastopt;
192}; 193};
193 194
194#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) 195#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
@@ -234,14 +235,20 @@ struct ipv6_pinfo {
234 /* pktoption flags */ 235 /* pktoption flags */
235 union { 236 union {
236 struct { 237 struct {
237 __u8 srcrt:2, 238 __u16 srcrt:2,
239 osrcrt:2,
238 rxinfo:1, 240 rxinfo:1,
241 rxoinfo:1,
239 rxhlim:1, 242 rxhlim:1,
243 rxohlim:1,
240 hopopts:1, 244 hopopts:1,
245 ohopopts:1,
241 dstopts:1, 246 dstopts:1,
242 rxflow:1; 247 odstopts:1,
248 rxflow:1,
249 rxtclass:1;
243 } bits; 250 } bits;
244 __u8 all; 251 __u16 all;
245 } rxopt; 252 } rxopt;
246 253
247 /* sockopt flags */ 254 /* sockopt flags */
@@ -250,6 +257,7 @@ struct ipv6_pinfo {
250 sndflow:1, 257 sndflow:1,
251 pmtudisc:2, 258 pmtudisc:2,
252 ipv6only:1; 259 ipv6only:1;
260 __u8 tclass;
253 261
254 __u32 dst_cookie; 262 __u32 dst_cookie;
255 263
@@ -263,6 +271,7 @@ struct ipv6_pinfo {
263 struct ipv6_txoptions *opt; 271 struct ipv6_txoptions *opt;
264 struct rt6_info *rt; 272 struct rt6_info *rt;
265 int hop_limit; 273 int hop_limit;
274 int tclass;
266 } cork; 275 } cork;
267}; 276};
268 277
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 94a46f38c532..58385ee1c0ac 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
155 155
156extern void numa_default_policy(void); 156extern void numa_default_policy(void);
157extern void numa_policy_init(void); 157extern void numa_policy_init(void);
158extern struct mempolicy default_policy;
158 159
159#else 160#else
160 161
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6014160d9c06..c1f021eddffa 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -109,6 +109,8 @@ struct mmc_host {
109 struct mmc_card *card_selected; /* the selected MMC card */ 109 struct mmc_card *card_selected; /* the selected MMC card */
110 110
111 struct work_struct detect; 111 struct work_struct detect;
112
113 unsigned long private[0] ____cacheline_aligned;
112}; 114};
113 115
114extern struct mmc_host *mmc_alloc_host(int extra, struct device *); 116extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
@@ -116,14 +118,18 @@ extern int mmc_add_host(struct mmc_host *);
116extern void mmc_remove_host(struct mmc_host *); 118extern void mmc_remove_host(struct mmc_host *);
117extern void mmc_free_host(struct mmc_host *); 119extern void mmc_free_host(struct mmc_host *);
118 120
119#define mmc_priv(x) ((void *)((x) + 1)) 121static inline void *mmc_priv(struct mmc_host *host)
122{
123 return (void *)host->private;
124}
125
120#define mmc_dev(x) ((x)->dev) 126#define mmc_dev(x) ((x)->dev)
121#define mmc_hostname(x) ((x)->class_dev.class_id) 127#define mmc_hostname(x) ((x)->class_dev.class_id)
122 128
123extern int mmc_suspend_host(struct mmc_host *, pm_message_t); 129extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
124extern int mmc_resume_host(struct mmc_host *); 130extern int mmc_resume_host(struct mmc_host *);
125 131
126extern void mmc_detect_change(struct mmc_host *); 132extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
127extern void mmc_request_done(struct mmc_host *, struct mmc_request *); 133extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
128 134
129#endif 135#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bc4c40000c0d..7349058ed778 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -19,436 +19,10 @@
19 19
20#include <linux/mod_devicetable.h> 20#include <linux/mod_devicetable.h>
21 21
22/* 22/* Include the pci register defines */
23 * Under PCI, each device has 256 bytes of configuration address space, 23#include <linux/pci_regs.h>
24 * of which the first 64 bytes are standardized as follows:
25 */
26#define PCI_VENDOR_ID 0x00 /* 16 bits */
27#define PCI_DEVICE_ID 0x02 /* 16 bits */
28#define PCI_COMMAND 0x04 /* 16 bits */
29#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
30#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
31#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
32#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
33#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
34#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
35#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
36#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
37#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
38#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
39#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
40
41#define PCI_STATUS 0x06 /* 16 bits */
42#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
43#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
44#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
45#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
46#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
47#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
48#define PCI_STATUS_DEVSEL_FAST 0x000
49#define PCI_STATUS_DEVSEL_MEDIUM 0x200
50#define PCI_STATUS_DEVSEL_SLOW 0x400
51#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
52#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
53#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
54#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
55#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
56
57#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
58 revision */
59#define PCI_REVISION_ID 0x08 /* Revision ID */
60#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
61#define PCI_CLASS_DEVICE 0x0a /* Device class */
62
63#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
64#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
65#define PCI_HEADER_TYPE 0x0e /* 8 bits */
66#define PCI_HEADER_TYPE_NORMAL 0
67#define PCI_HEADER_TYPE_BRIDGE 1
68#define PCI_HEADER_TYPE_CARDBUS 2
69
70#define PCI_BIST 0x0f /* 8 bits */
71#define PCI_BIST_CODE_MASK 0x0f /* Return result */
72#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
73#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
74
75/*
76 * Base addresses specify locations in memory or I/O space.
77 * Decoded size can be determined by writing a value of
78 * 0xffffffff to the register, and reading it back. Only
79 * 1 bits are decoded.
80 */
81#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
82#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
83#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
84#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
85#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
86#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
87#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
88#define PCI_BASE_ADDRESS_SPACE_IO 0x01
89#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
90#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
91#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
92#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
93#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
94#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
95#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
96#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
97/* bit 1 is reserved if address_space = 1 */
98
99/* Header type 0 (normal devices) */
100#define PCI_CARDBUS_CIS 0x28
101#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
102#define PCI_SUBSYSTEM_ID 0x2e
103#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
104#define PCI_ROM_ADDRESS_ENABLE 0x01
105#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
106
107#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
108
109/* 0x35-0x3b are reserved */
110#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
111#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
112#define PCI_MIN_GNT 0x3e /* 8 bits */
113#define PCI_MAX_LAT 0x3f /* 8 bits */
114
115/* Header type 1 (PCI-to-PCI bridges) */
116#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
117#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
118#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
119#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
120#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
121#define PCI_IO_LIMIT 0x1d
122#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
123#define PCI_IO_RANGE_TYPE_16 0x00
124#define PCI_IO_RANGE_TYPE_32 0x01
125#define PCI_IO_RANGE_MASK (~0x0fUL)
126#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
127#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
128#define PCI_MEMORY_LIMIT 0x22
129#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
130#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
131#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
132#define PCI_PREF_MEMORY_LIMIT 0x26
133#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
134#define PCI_PREF_RANGE_TYPE_32 0x00
135#define PCI_PREF_RANGE_TYPE_64 0x01
136#define PCI_PREF_RANGE_MASK (~0x0fUL)
137#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
138#define PCI_PREF_LIMIT_UPPER32 0x2c
139#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
140#define PCI_IO_LIMIT_UPPER16 0x32
141/* 0x34 same as for htype 0 */
142/* 0x35-0x3b is reserved */
143#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
144/* 0x3c-0x3d are same as for htype 0 */
145#define PCI_BRIDGE_CONTROL 0x3e
146#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
147#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
148#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
149#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
150#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
151#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
152#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
153
154/* Header type 2 (CardBus bridges) */
155#define PCI_CB_CAPABILITY_LIST 0x14
156/* 0x15 reserved */
157#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
158#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
159#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
160#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
161#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
162#define PCI_CB_MEMORY_BASE_0 0x1c
163#define PCI_CB_MEMORY_LIMIT_0 0x20
164#define PCI_CB_MEMORY_BASE_1 0x24
165#define PCI_CB_MEMORY_LIMIT_1 0x28
166#define PCI_CB_IO_BASE_0 0x2c
167#define PCI_CB_IO_BASE_0_HI 0x2e
168#define PCI_CB_IO_LIMIT_0 0x30
169#define PCI_CB_IO_LIMIT_0_HI 0x32
170#define PCI_CB_IO_BASE_1 0x34
171#define PCI_CB_IO_BASE_1_HI 0x36
172#define PCI_CB_IO_LIMIT_1 0x38
173#define PCI_CB_IO_LIMIT_1_HI 0x3a
174#define PCI_CB_IO_RANGE_MASK (~0x03UL)
175/* 0x3c-0x3d are same as for htype 0 */
176#define PCI_CB_BRIDGE_CONTROL 0x3e
177#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
178#define PCI_CB_BRIDGE_CTL_SERR 0x02
179#define PCI_CB_BRIDGE_CTL_ISA 0x04
180#define PCI_CB_BRIDGE_CTL_VGA 0x08
181#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
182#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
183#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
184#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
185#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
186#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
187#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
188#define PCI_CB_SUBSYSTEM_ID 0x42
189#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
190/* 0x48-0x7f reserved */
191
192/* Capability lists */
193
194#define PCI_CAP_LIST_ID 0 /* Capability ID */
195#define PCI_CAP_ID_PM 0x01 /* Power Management */
196#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
197#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
198#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
199#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
200#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
201#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
202#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
203#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
204#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
205#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
206#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
207#define PCI_CAP_SIZEOF 4
208
209/* Power Management Registers */
210
211#define PCI_PM_PMC 2 /* PM Capabilities Register */
212#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
213#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
214#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
215#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
216#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
217#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
218#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
219#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
220#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
221#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
222#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
223#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
224#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
225#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
226#define PCI_PM_CTRL 4 /* PM control and status register */
227#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
228#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
229#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
230#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
231#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
232#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
233#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
234#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
235#define PCI_PM_DATA_REGISTER 7 /* (??) */
236#define PCI_PM_SIZEOF 8
237
238/* AGP registers */
239
240#define PCI_AGP_VERSION 2 /* BCD version number */
241#define PCI_AGP_RFU 3 /* Rest of capability flags */
242#define PCI_AGP_STATUS 4 /* Status register */
243#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
244#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
245#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
246#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
247#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
248#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
249#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
250#define PCI_AGP_COMMAND 8 /* Control register */
251#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
252#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
253#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
254#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
255#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
256#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
257#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
258#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
259#define PCI_AGP_SIZEOF 12
260
261/* Vital Product Data */
262
263#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
264#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
265#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
266#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
267
268/* Slot Identification */
269
270#define PCI_SID_ESR 2 /* Expansion Slot Register */
271#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
272#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
273#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
274
275/* Message Signalled Interrupts registers */
276
277#define PCI_MSI_FLAGS 2 /* Various flags */
278#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
279#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
280#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
281#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
282#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */
283#define PCI_MSI_RFU 3 /* Rest of capability flags */
284#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
285#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
286#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
287#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
288#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
289
290/* CompactPCI Hotswap Register */
291
292#define PCI_CHSWP_CSR 2 /* Control and Status Register */
293#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
294#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
295#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
296#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
297#define PCI_CHSWP_PI 0x30 /* Programming Interface */
298#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
299#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
300
301/* PCI-X registers */
302
303#define PCI_X_CMD 2 /* Modes & Features */
304#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
305#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
306#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
307#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
308#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
309#define PCI_X_STATUS 4 /* PCI-X capabilities */
310#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
311#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
312#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
313#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
314#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
315#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
316#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
317#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
318#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
319#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
320#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
321#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
322#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
323
324/* PCI Express capability registers */
325
326#define PCI_EXP_FLAGS 2 /* Capabilities register */
327#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
328#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
329#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
330#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
331#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
332#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
333#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
334#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
335#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
336#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
337#define PCI_EXP_DEVCAP 4 /* Device capabilities */
338#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
339#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
340#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
341#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
342#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
343#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
344#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
345#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
346#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
347#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
348#define PCI_EXP_DEVCTL 8 /* Device Control */
349#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
350#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
351#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
352#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
353#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
354#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
355#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
356#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
357#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
358#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
359#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
360#define PCI_EXP_DEVSTA 10 /* Device Status */
361#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
362#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
363#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
364#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
365#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
366#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
367#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
368#define PCI_EXP_LNKCTL 16 /* Link Control */
369#define PCI_EXP_LNKSTA 18 /* Link Status */
370#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
371#define PCI_EXP_SLTCTL 24 /* Slot Control */
372#define PCI_EXP_SLTSTA 26 /* Slot Status */
373#define PCI_EXP_RTCTL 28 /* Root Control */
374#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
375#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
376#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
377#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
378#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
379#define PCI_EXP_RTCAP 30 /* Root Capabilities */
380#define PCI_EXP_RTSTA 32 /* Root Status */
381
382/* Extended Capabilities (PCI-X 2.0 and Express) */
383#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
384#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
385#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
386
387#define PCI_EXT_CAP_ID_ERR 1
388#define PCI_EXT_CAP_ID_VC 2
389#define PCI_EXT_CAP_ID_DSN 3
390#define PCI_EXT_CAP_ID_PWR 4
391
392/* Advanced Error Reporting */
393#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
394#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
395#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
396#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
397#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
398#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
399#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
400#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
401#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
402#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
403#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
404#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
405#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
406 /* Same bits as above */
407#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
408 /* Same bits as above */
409#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
410#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
411#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
412#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
413#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
414#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
415#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
416 /* Same bits as above */
417#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
418#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
419#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
420#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
421#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
422#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
423#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
424#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
425#define PCI_ERR_ROOT_STATUS 48
426#define PCI_ERR_ROOT_COR_SRC 52
427#define PCI_ERR_ROOT_SRC 54
428
429/* Virtual Channel */
430#define PCI_VC_PORT_REG1 4
431#define PCI_VC_PORT_REG2 8
432#define PCI_VC_PORT_CTRL 12
433#define PCI_VC_PORT_STATUS 14
434#define PCI_VC_RES_CAP 16
435#define PCI_VC_RES_CTRL 20
436#define PCI_VC_RES_STATUS 26
437
438/* Power Budgeting */
439#define PCI_PWR_DSR 4 /* Data Select Register */
440#define PCI_PWR_DATA 8 /* Data Register */
441#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
442#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
443#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
444#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
445#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
446#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
447#define PCI_PWR_CAP 12 /* Capability */
448#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
449 24
450/* Include the ID list */ 25/* Include the ID list */
451
452#include <linux/pci_ids.h> 26#include <linux/pci_ids.h>
453 27
454/* 28/*
@@ -496,11 +70,12 @@ enum pci_mmap_state {
496 70
497typedef int __bitwise pci_power_t; 71typedef int __bitwise pci_power_t;
498 72
499#define PCI_D0 ((pci_power_t __force) 0) 73#define PCI_D0 ((pci_power_t __force) 0)
500#define PCI_D1 ((pci_power_t __force) 1) 74#define PCI_D1 ((pci_power_t __force) 1)
501#define PCI_D2 ((pci_power_t __force) 2) 75#define PCI_D2 ((pci_power_t __force) 2)
502#define PCI_D3hot ((pci_power_t __force) 3) 76#define PCI_D3hot ((pci_power_t __force) 3)
503#define PCI_D3cold ((pci_power_t __force) 4) 77#define PCI_D3cold ((pci_power_t __force) 4)
78#define PCI_UNKNOWN ((pci_power_t __force) 5)
504#define PCI_POWER_ERROR ((pci_power_t __force) -1) 79#define PCI_POWER_ERROR ((pci_power_t __force) -1)
505 80
506/* 81/*
@@ -562,11 +137,6 @@ struct pci_dev {
562 struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ 137 struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
563 int rom_attr_enabled; /* has display of the rom attribute been enabled? */ 138 int rom_attr_enabled; /* has display of the rom attribute been enabled? */
564 struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ 139 struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
565#ifdef CONFIG_PCI_NAMES
566#define PCI_NAME_SIZE 255
567#define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */
568 char pretty_name[PCI_NAME_SIZE]; /* pretty name for users to see */
569#endif
570}; 140};
571 141
572#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) 142#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
@@ -582,15 +152,15 @@ struct pci_dev {
582 * 7-10 bridges: address space assigned to buses behind the bridge 152 * 7-10 bridges: address space assigned to buses behind the bridge
583 */ 153 */
584 154
585#define PCI_ROM_RESOURCE 6 155#define PCI_ROM_RESOURCE 6
586#define PCI_BRIDGE_RESOURCES 7 156#define PCI_BRIDGE_RESOURCES 7
587#define PCI_NUM_RESOURCES 11 157#define PCI_NUM_RESOURCES 11
588 158
589#ifndef PCI_BUS_NUM_RESOURCES 159#ifndef PCI_BUS_NUM_RESOURCES
590#define PCI_BUS_NUM_RESOURCES 8 160#define PCI_BUS_NUM_RESOURCES 8
591#endif 161#endif
592 162
593#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ 163#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
594 164
595struct pci_bus { 165struct pci_bus {
596 struct list_head node; /* node in list of buses */ 166 struct list_head node; /* node in list of buses */
@@ -699,7 +269,7 @@ struct pci_driver {
699 * @dev_class_mask: the class mask for this device 269 * @dev_class_mask: the class mask for this device
700 * 270 *
701 * This macro is used to create a struct pci_device_id that matches a 271 * This macro is used to create a struct pci_device_id that matches a
702 * specific PCI class. The vendor, device, subvendor, and subdevice 272 * specific PCI class. The vendor, device, subvendor, and subdevice
703 * fields will be set to PCI_ANY_ID. 273 * fields will be set to PCI_ANY_ID.
704 */ 274 */
705#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \ 275#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \
@@ -707,7 +277,7 @@ struct pci_driver {
707 .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ 277 .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
708 .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID 278 .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
709 279
710/* 280/*
711 * pci_module_init is obsolete, this stays here till we fix up all usages of it 281 * pci_module_init is obsolete, this stays here till we fix up all usages of it
712 * in the tree. 282 * in the tree.
713 */ 283 */
@@ -745,12 +315,13 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s
745 pci_bus_add_devices(root_bus); 315 pci_bus_add_devices(root_bus);
746 return root_bus; 316 return root_bus;
747} 317}
318struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
319struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
748int pci_scan_slot(struct pci_bus *bus, int devfn); 320int pci_scan_slot(struct pci_bus *bus, int devfn);
749struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); 321struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
322void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
750unsigned int pci_scan_child_bus(struct pci_bus *bus); 323unsigned int pci_scan_child_bus(struct pci_bus *bus);
751void pci_bus_add_device(struct pci_dev *dev); 324void pci_bus_add_device(struct pci_dev *dev);
752void pci_name_device(struct pci_dev *dev);
753char *pci_class_name(u32 class);
754void pci_read_bridge_bases(struct pci_bus *child); 325void pci_read_bridge_bases(struct pci_bus *child);
755struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); 326struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
756int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); 327int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
@@ -758,6 +329,7 @@ extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
758extern void pci_dev_put(struct pci_dev *dev); 329extern void pci_dev_put(struct pci_dev *dev);
759extern void pci_remove_bus(struct pci_bus *b); 330extern void pci_remove_bus(struct pci_bus *b);
760extern void pci_remove_bus_device(struct pci_dev *dev); 331extern void pci_remove_bus_device(struct pci_dev *dev);
332void pci_setup_cardbus(struct pci_bus *bus);
761 333
762/* Generic PCI functions exported to card drivers */ 334/* Generic PCI functions exported to card drivers */
763 335
@@ -815,13 +387,16 @@ void pci_set_master(struct pci_dev *dev);
815#define HAVE_PCI_SET_MWI 387#define HAVE_PCI_SET_MWI
816int pci_set_mwi(struct pci_dev *dev); 388int pci_set_mwi(struct pci_dev *dev);
817void pci_clear_mwi(struct pci_dev *dev); 389void pci_clear_mwi(struct pci_dev *dev);
390void pci_intx(struct pci_dev *dev, int enable);
818int pci_set_dma_mask(struct pci_dev *dev, u64 mask); 391int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
819int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 392int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
393void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
820int pci_assign_resource(struct pci_dev *dev, int i); 394int pci_assign_resource(struct pci_dev *dev, int i);
395void pci_restore_bars(struct pci_dev *dev);
821 396
822/* ROM control related routines */ 397/* ROM control related routines */
823void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size); 398void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
824void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size); 399void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
825void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); 400void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
826void pci_remove_rom(struct pci_dev *pdev); 401void pci_remove_rom(struct pci_dev *pdev);
827 402
@@ -865,6 +440,9 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_
865const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); 440const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
866int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); 441int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
867 442
443void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
444 void *userdata);
445
868/* kmem_cache style wrapper around pci_alloc_consistent() */ 446/* kmem_cache style wrapper around pci_alloc_consistent() */
869 447
870#include <linux/dmapool.h> 448#include <linux/dmapool.h>
@@ -912,18 +490,26 @@ extern void pci_disable_msix(struct pci_dev *dev);
912extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); 490extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
913#endif 491#endif
914 492
915#endif /* CONFIG_PCI */ 493/*
916 494 * PCI domain support. Sometimes called PCI segment (eg by ACPI),
917/* Include architecture-dependent settings and functions */ 495 * a PCI domain is defined to be a set of PCI busses which share
496 * configuration space.
497 */
498#ifndef CONFIG_PCI_DOMAINS
499static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
500static inline int pci_proc_domain(struct pci_bus *bus)
501{
502 return 0;
503}
504#endif
918 505
919#include <asm/pci.h> 506#else /* CONFIG_PCI is not enabled */
920 507
921/* 508/*
922 * If the system does not have PCI, clearly these return errors. Define 509 * If the system does not have PCI, clearly these return errors. Define
923 * these as simple inline functions to avoid hair in drivers. 510 * these as simple inline functions to avoid hair in drivers.
924 */ 511 */
925 512
926#ifndef CONFIG_PCI
927#define _PCI_NOP(o,s,t) \ 513#define _PCI_NOP(o,s,t) \
928 static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ 514 static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \
929 { return PCIBIOS_FUNC_NOT_SUPPORTED; } 515 { return PCIBIOS_FUNC_NOT_SUPPORTED; }
@@ -974,21 +560,11 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en
974 560
975#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) 561#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
976 562
977#else 563#endif /* CONFIG_PCI */
978 564
979/* 565/* Include architecture-dependent settings and functions */
980 * PCI domain support. Sometimes called PCI segment (eg by ACPI), 566
981 * a PCI domain is defined to be a set of PCI busses which share 567#include <asm/pci.h>
982 * configuration space.
983 */
984#ifndef CONFIG_PCI_DOMAINS
985static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
986static inline int pci_proc_domain(struct pci_bus *bus)
987{
988 return 0;
989}
990#endif
991#endif /* !CONFIG_PCI */
992 568
993/* these helpers provide future and backwards compatibility 569/* these helpers provide future and backwards compatibility
994 * for accessing popular PCI BAR info */ 570 * for accessing popular PCI BAR info */
@@ -1025,13 +601,6 @@ static inline char *pci_name(struct pci_dev *pdev)
1025 return pdev->dev.bus_id; 601 return pdev->dev.bus_id;
1026} 602}
1027 603
1028/* Some archs want to see the pretty pci name, so use this macro */
1029#ifdef CONFIG_PCI_NAMES
1030#define pci_pretty_name(dev) ((dev)->pretty_name)
1031#else
1032#define pci_pretty_name(dev) ""
1033#endif
1034
1035 604
1036/* Some archs don't want to expose struct resource to userland as-is 605/* Some archs don't want to expose struct resource to userland as-is
1037 * in sysfs and /proc 606 * in sysfs and /proc
@@ -1067,7 +636,7 @@ enum pci_fixup_pass {
1067 636
1068/* Anonymous variables would be nice... */ 637/* Anonymous variables would be nice... */
1069#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \ 638#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
1070 static struct pci_fixup __pci_fixup_##name __attribute_used__ \ 639 static const struct pci_fixup __pci_fixup_##name __attribute_used__ \
1071 __attribute__((__section__(#section))) = { vendor, device, hook }; 640 __attribute__((__section__(#section))) = { vendor, device, hook };
1072#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ 641#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
1073 DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ 642 DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
new file mode 100644
index 000000000000..e2a089b051ed
--- /dev/null
+++ b/include/linux/pci_regs.h
@@ -0,0 +1,448 @@
1/*
2 * pci_regs.h
3 *
4 * PCI standard defines
5 * Copyright 1994, Drew Eckhardt
6 * Copyright 1997--1999 Martin Mares <mj@ucw.cz>
7 *
8 * For more information, please consult the following manuals (look at
9 * http://www.pcisig.com/ for how to get them):
10 *
11 * PCI BIOS Specification
12 * PCI Local Bus Specification
13 * PCI to PCI Bridge Specification
14 * PCI System Design Guide
15 */
16
17#ifndef LINUX_PCI_REGS_H
18#define LINUX_PCI_REGS_H
19
20/*
21 * Under PCI, each device has 256 bytes of configuration address space,
22 * of which the first 64 bytes are standardized as follows:
23 */
24#define PCI_VENDOR_ID 0x00 /* 16 bits */
25#define PCI_DEVICE_ID 0x02 /* 16 bits */
26#define PCI_COMMAND 0x04 /* 16 bits */
27#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
28#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
29#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
30#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
31#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
32#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
33#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
34#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
35#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
36#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
37#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
38
39#define PCI_STATUS 0x06 /* 16 bits */
40#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
41#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
42#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
43#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
44#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
45#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
46#define PCI_STATUS_DEVSEL_FAST 0x000
47#define PCI_STATUS_DEVSEL_MEDIUM 0x200
48#define PCI_STATUS_DEVSEL_SLOW 0x400
49#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
50#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
51#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
52#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
53#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
54
55#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
56#define PCI_REVISION_ID 0x08 /* Revision ID */
57#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
58#define PCI_CLASS_DEVICE 0x0a /* Device class */
59
60#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
61#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
62#define PCI_HEADER_TYPE 0x0e /* 8 bits */
63#define PCI_HEADER_TYPE_NORMAL 0
64#define PCI_HEADER_TYPE_BRIDGE 1
65#define PCI_HEADER_TYPE_CARDBUS 2
66
67#define PCI_BIST 0x0f /* 8 bits */
68#define PCI_BIST_CODE_MASK 0x0f /* Return result */
69#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
70#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
71
72/*
73 * Base addresses specify locations in memory or I/O space.
74 * Decoded size can be determined by writing a value of
75 * 0xffffffff to the register, and reading it back. Only
76 * 1 bits are decoded.
77 */
78#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
79#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
80#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
81#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
82#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
83#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
84#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
85#define PCI_BASE_ADDRESS_SPACE_IO 0x01
86#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
87#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
88#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
89#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
90#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
91#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
92#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
93#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
94/* bit 1 is reserved if address_space = 1 */
95
96/* Header type 0 (normal devices) */
97#define PCI_CARDBUS_CIS 0x28
98#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
99#define PCI_SUBSYSTEM_ID 0x2e
100#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
101#define PCI_ROM_ADDRESS_ENABLE 0x01
102#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
103
104#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
105
106/* 0x35-0x3b are reserved */
107#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
108#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
109#define PCI_MIN_GNT 0x3e /* 8 bits */
110#define PCI_MAX_LAT 0x3f /* 8 bits */
111
112/* Header type 1 (PCI-to-PCI bridges) */
113#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
114#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
115#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
116#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
117#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
118#define PCI_IO_LIMIT 0x1d
119#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
120#define PCI_IO_RANGE_TYPE_16 0x00
121#define PCI_IO_RANGE_TYPE_32 0x01
122#define PCI_IO_RANGE_MASK (~0x0fUL)
123#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
124#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
125#define PCI_MEMORY_LIMIT 0x22
126#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
127#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
128#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
129#define PCI_PREF_MEMORY_LIMIT 0x26
130#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
131#define PCI_PREF_RANGE_TYPE_32 0x00
132#define PCI_PREF_RANGE_TYPE_64 0x01
133#define PCI_PREF_RANGE_MASK (~0x0fUL)
134#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
135#define PCI_PREF_LIMIT_UPPER32 0x2c
136#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
137#define PCI_IO_LIMIT_UPPER16 0x32
138/* 0x34 same as for htype 0 */
139/* 0x35-0x3b is reserved */
140#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
141/* 0x3c-0x3d are same as for htype 0 */
142#define PCI_BRIDGE_CONTROL 0x3e
143#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
144#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
145#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
146#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
147#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
148#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
149#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
150
151/* Header type 2 (CardBus bridges) */
152#define PCI_CB_CAPABILITY_LIST 0x14
153/* 0x15 reserved */
154#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
155#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
156#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
157#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
158#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
159#define PCI_CB_MEMORY_BASE_0 0x1c
160#define PCI_CB_MEMORY_LIMIT_0 0x20
161#define PCI_CB_MEMORY_BASE_1 0x24
162#define PCI_CB_MEMORY_LIMIT_1 0x28
163#define PCI_CB_IO_BASE_0 0x2c
164#define PCI_CB_IO_BASE_0_HI 0x2e
165#define PCI_CB_IO_LIMIT_0 0x30
166#define PCI_CB_IO_LIMIT_0_HI 0x32
167#define PCI_CB_IO_BASE_1 0x34
168#define PCI_CB_IO_BASE_1_HI 0x36
169#define PCI_CB_IO_LIMIT_1 0x38
170#define PCI_CB_IO_LIMIT_1_HI 0x3a
171#define PCI_CB_IO_RANGE_MASK (~0x03UL)
172/* 0x3c-0x3d are same as for htype 0 */
173#define PCI_CB_BRIDGE_CONTROL 0x3e
174#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
175#define PCI_CB_BRIDGE_CTL_SERR 0x02
176#define PCI_CB_BRIDGE_CTL_ISA 0x04
177#define PCI_CB_BRIDGE_CTL_VGA 0x08
178#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
179#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
180#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
181#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
182#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
183#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
184#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
185#define PCI_CB_SUBSYSTEM_ID 0x42
186#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
187/* 0x48-0x7f reserved */
188
189/* Capability lists */
190
191#define PCI_CAP_LIST_ID 0 /* Capability ID */
192#define PCI_CAP_ID_PM 0x01 /* Power Management */
193#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
194#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
195#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
196#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
197#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
198#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
199#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
200#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
201#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
202#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
203#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
204#define PCI_CAP_SIZEOF 4
205
206/* Power Management Registers */
207
208#define PCI_PM_PMC 2 /* PM Capabilities Register */
209#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
210#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
211#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
212#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
213#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
214#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
215#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
216#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
217#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
218#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
219#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
220#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
221#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
222#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
223#define PCI_PM_CTRL 4 /* PM control and status register */
224#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
225#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */
226#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
227#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
228#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
229#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
230#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
231#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
232#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
233#define PCI_PM_DATA_REGISTER 7 /* (??) */
234#define PCI_PM_SIZEOF 8
235
236/* AGP registers */
237
238#define PCI_AGP_VERSION 2 /* BCD version number */
239#define PCI_AGP_RFU 3 /* Rest of capability flags */
240#define PCI_AGP_STATUS 4 /* Status register */
241#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
242#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
243#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
244#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
245#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
246#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
247#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
248#define PCI_AGP_COMMAND 8 /* Control register */
249#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
250#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
251#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
252#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
253#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
254#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
255#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
256#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
257#define PCI_AGP_SIZEOF 12
258
259/* Vital Product Data */
260
261#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
262#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
263#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
264#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
265
266/* Slot Identification */
267
268#define PCI_SID_ESR 2 /* Expansion Slot Register */
269#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
270#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
271#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
272
273/* Message Signalled Interrupts registers */
274
275#define PCI_MSI_FLAGS 2 /* Various flags */
276#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
277#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
278#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
279#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
280#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */
281#define PCI_MSI_RFU 3 /* Rest of capability flags */
282#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
283#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
284#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
285#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
286#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
287
288/* CompactPCI Hotswap Register */
289
290#define PCI_CHSWP_CSR 2 /* Control and Status Register */
291#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
292#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
293#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
294#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
295#define PCI_CHSWP_PI 0x30 /* Programming Interface */
296#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
297#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
298
299/* PCI-X registers */
300
301#define PCI_X_CMD 2 /* Modes & Features */
302#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
303#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
304#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
305#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
306#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
307#define PCI_X_STATUS 4 /* PCI-X capabilities */
308#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
309#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
310#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
311#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
312#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
313#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
314#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
315#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
316#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
317#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
318#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
319#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
320#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
321
322/* PCI Express capability registers */
323
324#define PCI_EXP_FLAGS 2 /* Capabilities register */
325#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
326#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
327#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
328#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
329#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
330#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
331#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
332#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
333#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
334#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
335#define PCI_EXP_DEVCAP 4 /* Device capabilities */
336#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
337#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
338#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
339#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
340#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
341#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
342#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
343#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
344#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
345#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
346#define PCI_EXP_DEVCTL 8 /* Device Control */
347#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
348#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
349#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
350#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
351#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
352#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
353#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
354#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
355#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
356#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
357#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
358#define PCI_EXP_DEVSTA 10 /* Device Status */
359#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
360#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
361#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
362#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
363#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
364#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
365#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
366#define PCI_EXP_LNKCTL 16 /* Link Control */
367#define PCI_EXP_LNKSTA 18 /* Link Status */
368#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
369#define PCI_EXP_SLTCTL 24 /* Slot Control */
370#define PCI_EXP_SLTSTA 26 /* Slot Status */
371#define PCI_EXP_RTCTL 28 /* Root Control */
372#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
373#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
374#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
375#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
376#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
377#define PCI_EXP_RTCAP 30 /* Root Capabilities */
378#define PCI_EXP_RTSTA 32 /* Root Status */
379
380/* Extended Capabilities (PCI-X 2.0 and Express) */
381#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
382#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
383#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
384
385#define PCI_EXT_CAP_ID_ERR 1
386#define PCI_EXT_CAP_ID_VC 2
387#define PCI_EXT_CAP_ID_DSN 3
388#define PCI_EXT_CAP_ID_PWR 4
389
390/* Advanced Error Reporting */
391#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
392#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
393#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
394#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
395#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
396#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
397#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
398#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
399#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
400#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
401#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
402#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
403#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
404 /* Same bits as above */
405#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
406 /* Same bits as above */
407#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
408#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
409#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
410#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
411#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
412#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
413#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
414 /* Same bits as above */
415#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
416#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
417#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
418#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
419#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
420#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
421#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
422#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
423#define PCI_ERR_ROOT_STATUS 48
424#define PCI_ERR_ROOT_COR_SRC 52
425#define PCI_ERR_ROOT_SRC 54
426
427/* Virtual Channel */
428#define PCI_VC_PORT_REG1 4
429#define PCI_VC_PORT_REG2 8
430#define PCI_VC_PORT_CTRL 12
431#define PCI_VC_PORT_STATUS 14
432#define PCI_VC_RES_CAP 16
433#define PCI_VC_RES_CTRL 20
434#define PCI_VC_RES_STATUS 26
435
436/* Power Budgeting */
437#define PCI_PWR_DSR 4 /* Data Select Register */
438#define PCI_PWR_DATA 8 /* Data Register */
439#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
440#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
441#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
442#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
443#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
444#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
445#define PCI_PWR_CAP 12 /* Capability */
446#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
447
448#endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index fd276adf0fd5..4e65eb44adfd 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -52,8 +52,8 @@ struct rcu_head {
52 void (*func)(struct rcu_head *head); 52 void (*func)(struct rcu_head *head);
53}; 53};
54 54
55#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL } 55#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
56#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head) 56#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
57#define INIT_RCU_HEAD(ptr) do { \ 57#define INIT_RCU_HEAD(ptr) do { \
58 (ptr)->next = NULL; (ptr)->func = NULL; \ 58 (ptr)->next = NULL; (ptr)->func = NULL; \
59} while (0) 59} while (0)
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
new file mode 100644
index 000000000000..e1adbba14b67
--- /dev/null
+++ b/include/linux/rcuref.h
@@ -0,0 +1,220 @@
1/*
2 * rcuref.h
3 *
4 * Reference counting for elements of lists/arrays protected by
5 * RCU.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Copyright (C) IBM Corporation, 2005
22 *
23 * Author: Dipankar Sarma <dipankar@in.ibm.com>
24 * Ravikiran Thirumalai <kiran_th@gmail.com>
25 *
26 * See Documentation/RCU/rcuref.txt for detailed user guide.
27 *
28 */
29
30#ifndef _RCUREF_H_
31#define _RCUREF_H_
32
33#ifdef __KERNEL__
34
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <asm/atomic.h>
39
40/*
41 * These APIs work on traditional atomic_t counters used in the
42 * kernel for reference counting. Under special circumstances
43 * where a lock-free get() operation races with a put() operation
44 * these APIs can be used. See Documentation/RCU/rcuref.txt.
45 */
46
47#ifdef __HAVE_ARCH_CMPXCHG
48
49/**
50 * rcuref_inc - increment refcount for object.
51 * @rcuref: reference counter in the object in question.
52 *
53 * This should be used only for objects where we use RCU and
54 * use the rcuref_inc_lf() api to acquire a reference
55 * in a lock-free reader-side critical section.
56 */
57static inline void rcuref_inc(atomic_t *rcuref)
58{
59 atomic_inc(rcuref);
60}
61
62/**
63 * rcuref_dec - decrement refcount for object.
64 * @rcuref: reference counter in the object in question.
65 *
66 * This should be used only for objects where we use RCU and
67 * use the rcuref_inc_lf() api to acquire a reference
68 * in a lock-free reader-side critical section.
69 */
70static inline void rcuref_dec(atomic_t *rcuref)
71{
72 atomic_dec(rcuref);
73}
74
75/**
76 * rcuref_dec_and_test - decrement refcount for object and test
77 * @rcuref: reference counter in the object.
78 * @release: pointer to the function that will clean up the object
79 * when the last reference to the object is released.
80 * This pointer is required.
81 *
82 * Decrement the refcount, and if 0, return 1. Else return 0.
83 *
84 * This should be used only for objects where we use RCU and
85 * use the rcuref_inc_lf() api to acquire a reference
86 * in a lock-free reader-side critical section.
87 */
88static inline int rcuref_dec_and_test(atomic_t *rcuref)
89{
90 return atomic_dec_and_test(rcuref);
91}
92
93/*
94 * cmpxchg is needed on UP too, if deletions to the list/array can happen
95 * in interrupt context.
96 */
97
98/**
99 * rcuref_inc_lf - Take reference to an object in a read-side
100 * critical section protected by RCU.
101 * @rcuref: reference counter in the object in question.
102 *
103 * Try and increment the refcount by 1. The increment might fail if
104 * the reference counter has been through a 1 to 0 transition and
105 * is no longer part of the lock-free list.
106 * Returns non-zero on successful increment and zero otherwise.
107 */
108static inline int rcuref_inc_lf(atomic_t *rcuref)
109{
110 int c, old;
111 c = atomic_read(rcuref);
112 while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)
113 c = old;
114 return c;
115}
116
117#else /* !__HAVE_ARCH_CMPXCHG */
118
119extern spinlock_t __rcuref_hash[];
120
121/*
122 * Use a hash table of locks to protect the reference count
123 * since cmpxchg is not available in this arch.
124 */
125#ifdef CONFIG_SMP
126#define RCUREF_HASH_SIZE 4
127#define RCUREF_HASH(k) \
128 (&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])
129#else
130#define RCUREF_HASH_SIZE 1
131#define RCUREF_HASH(k) &__rcuref_hash[0]
132#endif /* CONFIG_SMP */
133
134/**
135 * rcuref_inc - increment refcount for object.
136 * @rcuref: reference counter in the object in question.
137 *
138 * This should be used only for objects where we use RCU and
139 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
140 * reader-side critical section.
141 */
142static inline void rcuref_inc(atomic_t *rcuref)
143{
144 unsigned long flags;
145 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
146 rcuref->counter += 1;
147 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
148}
149
150/**
151 * rcuref_dec - decrement refcount for object.
152 * @rcuref: reference counter in the object in question.
153 *
154 * This should be used only for objects where we use RCU and
155 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
156 * reader-side critical section.
157 */
158static inline void rcuref_dec(atomic_t *rcuref)
159{
160 unsigned long flags;
161 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
162 rcuref->counter -= 1;
163 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
164}
165
166/**
167 * rcuref_dec_and_test - decrement refcount for object and test
168 * @rcuref: reference counter in the object.
169 * @release: pointer to the function that will clean up the object
170 * when the last reference to the object is released.
171 * This pointer is required.
172 *
173 * Decrement the refcount, and if 0, return 1. Else return 0.
174 *
175 * This should be used only for objects where we use RCU and
176 * use the rcuref_inc_lf() api to acquire a reference in a lock-free
177 * reader-side critical section.
178 */
179static inline int rcuref_dec_and_test(atomic_t *rcuref)
180{
181 unsigned long flags;
182 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
183 rcuref->counter--;
184 if (!rcuref->counter) {
185 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
186 return 1;
187 } else {
188 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
189 return 0;
190 }
191}
192
193/**
194 * rcuref_inc_lf - Take reference to an object of a lock-free collection
195 * by traversing a lock-free list/array.
196 * @rcuref: reference counter in the object in question.
197 *
198 * Try and increment the refcount by 1. The increment might fail if
199 * the reference counter has been through a 1 to 0 transition and
200 * object is no longer part of the lock-free list.
201 * Returns non-zero on successful increment and zero otherwise.
202 */
203static inline int rcuref_inc_lf(atomic_t *rcuref)
204{
205 int ret;
206 unsigned long flags;
207 spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
208 if (rcuref->counter)
209 ret = rcuref->counter++;
210 else
211 ret = 0;
212 spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
213 return ret;
214}
215
216
217#endif /* !__HAVE_ARCH_CMPXCHG */
218
219#endif /* __KERNEL__ */
220#endif /* _RCUREF_H_ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ea1b5f32ec5c..c551e6a1447e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -604,6 +604,11 @@ extern int groups_search(struct group_info *group_info, gid_t grp);
604#define GROUP_AT(gi, i) \ 604#define GROUP_AT(gi, i) \
605 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) 605 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
606 606
607#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
608extern void prefetch_stack(struct task_struct*);
609#else
610static inline void prefetch_stack(struct task_struct *t) { }
611#endif
607 612
608struct audit_context; /* See audit.c */ 613struct audit_context; /* See audit.c */
609struct mempolicy; 614struct mempolicy;
diff --git a/include/linux/security.h b/include/linux/security.h
index 7aab6ab7c57f..55b02e1c73f4 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -250,29 +250,37 @@ struct swap_info_struct;
250 * @inode contains the inode structure. 250 * @inode contains the inode structure.
251 * Deallocate the inode security structure and set @inode->i_security to 251 * Deallocate the inode security structure and set @inode->i_security to
252 * NULL. 252 * NULL.
253 * @inode_init_security:
254 * Obtain the security attribute name suffix and value to set on a newly
255 * created inode and set up the incore security field for the new inode.
256 * This hook is called by the fs code as part of the inode creation
257 * transaction and provides for atomic labeling of the inode, unlike
258 * the post_create/mkdir/... hooks called by the VFS. The hook function
259 * is expected to allocate the name and value via kmalloc, with the caller
260 * being responsible for calling kfree after using them.
261 * If the security module does not use security attributes or does
262 * not wish to put a security attribute on this particular inode,
263 * then it should return -EOPNOTSUPP to skip this processing.
264 * @inode contains the inode structure of the newly created inode.
265 * @dir contains the inode structure of the parent directory.
266 * @name will be set to the allocated name suffix (e.g. selinux).
267 * @value will be set to the allocated attribute value.
268 * @len will be set to the length of the value.
269 * Returns 0 if @name and @value have been successfully set,
270 * -EOPNOTSUPP if no security attribute is needed, or
271 * -ENOMEM on memory allocation failure.
253 * @inode_create: 272 * @inode_create:
254 * Check permission to create a regular file. 273 * Check permission to create a regular file.
255 * @dir contains inode structure of the parent of the new file. 274 * @dir contains inode structure of the parent of the new file.
256 * @dentry contains the dentry structure for the file to be created. 275 * @dentry contains the dentry structure for the file to be created.
257 * @mode contains the file mode of the file to be created. 276 * @mode contains the file mode of the file to be created.
258 * Return 0 if permission is granted. 277 * Return 0 if permission is granted.
259 * @inode_post_create:
260 * Set the security attributes on a newly created regular file. This hook
261 * is called after a file has been successfully created.
262 * @dir contains the inode structure of the parent directory of the new file.
263 * @dentry contains the the dentry structure for the newly created file.
264 * @mode contains the file mode.
265 * @inode_link: 278 * @inode_link:
266 * Check permission before creating a new hard link to a file. 279 * Check permission before creating a new hard link to a file.
267 * @old_dentry contains the dentry structure for an existing link to the file. 280 * @old_dentry contains the dentry structure for an existing link to the file.
268 * @dir contains the inode structure of the parent directory of the new link. 281 * @dir contains the inode structure of the parent directory of the new link.
269 * @new_dentry contains the dentry structure for the new link. 282 * @new_dentry contains the dentry structure for the new link.
270 * Return 0 if permission is granted. 283 * Return 0 if permission is granted.
271 * @inode_post_link:
272 * Set security attributes for a new hard link to a file.
273 * @old_dentry contains the dentry structure for the existing link.
274 * @dir contains the inode structure of the parent directory of the new file.
275 * @new_dentry contains the dentry structure for the new file link.
276 * @inode_unlink: 284 * @inode_unlink:
277 * Check the permission to remove a hard link to a file. 285 * Check the permission to remove a hard link to a file.
278 * @dir contains the inode structure of parent directory of the file. 286 * @dir contains the inode structure of parent directory of the file.
@@ -284,13 +292,6 @@ struct swap_info_struct;
284 * @dentry contains the dentry structure of the symbolic link. 292 * @dentry contains the dentry structure of the symbolic link.
285 * @old_name contains the pathname of file. 293 * @old_name contains the pathname of file.
286 * Return 0 if permission is granted. 294 * Return 0 if permission is granted.
287 * @inode_post_symlink:
288 * @dir contains the inode structure of the parent directory of the new link.
289 * @dentry contains the dentry structure of new symbolic link.
290 * @old_name contains the pathname of file.
291 * Set security attributes for a newly created symbolic link. Note that
292 * @dentry->d_inode may be NULL, since the filesystem might not
293 * instantiate the dentry (e.g. NFS).
294 * @inode_mkdir: 295 * @inode_mkdir:
295 * Check permissions to create a new directory in the existing directory 296 * Check permissions to create a new directory in the existing directory
296 * associated with inode strcture @dir. 297 * associated with inode strcture @dir.
@@ -298,11 +299,6 @@ struct swap_info_struct;
298 * @dentry contains the dentry structure of new directory. 299 * @dentry contains the dentry structure of new directory.
299 * @mode contains the mode of new directory. 300 * @mode contains the mode of new directory.
300 * Return 0 if permission is granted. 301 * Return 0 if permission is granted.
301 * @inode_post_mkdir:
302 * Set security attributes on a newly created directory.
303 * @dir contains the inode structure of parent of the directory to be created.
304 * @dentry contains the dentry structure of new directory.
305 * @mode contains the mode of new directory.
306 * @inode_rmdir: 302 * @inode_rmdir:
307 * Check the permission to remove a directory. 303 * Check the permission to remove a directory.
308 * @dir contains the inode structure of parent of the directory to be removed. 304 * @dir contains the inode structure of parent of the directory to be removed.
@@ -318,13 +314,6 @@ struct swap_info_struct;
318 * @mode contains the mode of the new file. 314 * @mode contains the mode of the new file.
319 * @dev contains the the device number. 315 * @dev contains the the device number.
320 * Return 0 if permission is granted. 316 * Return 0 if permission is granted.
321 * @inode_post_mknod:
322 * Set security attributes on a newly created special file (or socket or
323 * fifo file created via the mknod system call).
324 * @dir contains the inode structure of parent of the new node.
325 * @dentry contains the dentry structure of the new node.
326 * @mode contains the mode of the new node.
327 * @dev contains the the device number.
328 * @inode_rename: 317 * @inode_rename:
329 * Check for permission to rename a file or directory. 318 * Check for permission to rename a file or directory.
330 * @old_dir contains the inode structure for parent of the old link. 319 * @old_dir contains the inode structure for parent of the old link.
@@ -332,12 +321,6 @@ struct swap_info_struct;
332 * @new_dir contains the inode structure for parent of the new link. 321 * @new_dir contains the inode structure for parent of the new link.
333 * @new_dentry contains the dentry structure of the new link. 322 * @new_dentry contains the dentry structure of the new link.
334 * Return 0 if permission is granted. 323 * Return 0 if permission is granted.
335 * @inode_post_rename:
336 * Set security attributes on a renamed file or directory.
337 * @old_dir contains the inode structure for parent of the old link.
338 * @old_dentry contains the dentry structure of the old link.
339 * @new_dir contains the inode structure for parent of the new link.
340 * @new_dentry contains the dentry structure of the new link.
341 * @inode_readlink: 324 * @inode_readlink:
342 * Check the permission to read the symbolic link. 325 * Check the permission to read the symbolic link.
343 * @dentry contains the dentry structure for the file link. 326 * @dentry contains the dentry structure for the file link.
@@ -1080,34 +1063,21 @@ struct security_operations {
1080 1063
1081 int (*inode_alloc_security) (struct inode *inode); 1064 int (*inode_alloc_security) (struct inode *inode);
1082 void (*inode_free_security) (struct inode *inode); 1065 void (*inode_free_security) (struct inode *inode);
1066 int (*inode_init_security) (struct inode *inode, struct inode *dir,
1067 char **name, void **value, size_t *len);
1083 int (*inode_create) (struct inode *dir, 1068 int (*inode_create) (struct inode *dir,
1084 struct dentry *dentry, int mode); 1069 struct dentry *dentry, int mode);
1085 void (*inode_post_create) (struct inode *dir,
1086 struct dentry *dentry, int mode);
1087 int (*inode_link) (struct dentry *old_dentry, 1070 int (*inode_link) (struct dentry *old_dentry,
1088 struct inode *dir, struct dentry *new_dentry); 1071 struct inode *dir, struct dentry *new_dentry);
1089 void (*inode_post_link) (struct dentry *old_dentry,
1090 struct inode *dir, struct dentry *new_dentry);
1091 int (*inode_unlink) (struct inode *dir, struct dentry *dentry); 1072 int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
1092 int (*inode_symlink) (struct inode *dir, 1073 int (*inode_symlink) (struct inode *dir,
1093 struct dentry *dentry, const char *old_name); 1074 struct dentry *dentry, const char *old_name);
1094 void (*inode_post_symlink) (struct inode *dir,
1095 struct dentry *dentry,
1096 const char *old_name);
1097 int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode); 1075 int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
1098 void (*inode_post_mkdir) (struct inode *dir, struct dentry *dentry,
1099 int mode);
1100 int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); 1076 int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
1101 int (*inode_mknod) (struct inode *dir, struct dentry *dentry, 1077 int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
1102 int mode, dev_t dev); 1078 int mode, dev_t dev);
1103 void (*inode_post_mknod) (struct inode *dir, struct dentry *dentry,
1104 int mode, dev_t dev);
1105 int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, 1079 int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
1106 struct inode *new_dir, struct dentry *new_dentry); 1080 struct inode *new_dir, struct dentry *new_dentry);
1107 void (*inode_post_rename) (struct inode *old_dir,
1108 struct dentry *old_dentry,
1109 struct inode *new_dir,
1110 struct dentry *new_dentry);
1111 int (*inode_readlink) (struct dentry *dentry); 1081 int (*inode_readlink) (struct dentry *dentry);
1112 int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); 1082 int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
1113 int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); 1083 int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
@@ -1442,6 +1412,17 @@ static inline void security_inode_free (struct inode *inode)
1442 return; 1412 return;
1443 security_ops->inode_free_security (inode); 1413 security_ops->inode_free_security (inode);
1444} 1414}
1415
1416static inline int security_inode_init_security (struct inode *inode,
1417 struct inode *dir,
1418 char **name,
1419 void **value,
1420 size_t *len)
1421{
1422 if (unlikely (IS_PRIVATE (inode)))
1423 return -EOPNOTSUPP;
1424 return security_ops->inode_init_security (inode, dir, name, value, len);
1425}
1445 1426
1446static inline int security_inode_create (struct inode *dir, 1427static inline int security_inode_create (struct inode *dir,
1447 struct dentry *dentry, 1428 struct dentry *dentry,
@@ -1452,15 +1433,6 @@ static inline int security_inode_create (struct inode *dir,
1452 return security_ops->inode_create (dir, dentry, mode); 1433 return security_ops->inode_create (dir, dentry, mode);
1453} 1434}
1454 1435
1455static inline void security_inode_post_create (struct inode *dir,
1456 struct dentry *dentry,
1457 int mode)
1458{
1459 if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
1460 return;
1461 security_ops->inode_post_create (dir, dentry, mode);
1462}
1463
1464static inline int security_inode_link (struct dentry *old_dentry, 1436static inline int security_inode_link (struct dentry *old_dentry,
1465 struct inode *dir, 1437 struct inode *dir,
1466 struct dentry *new_dentry) 1438 struct dentry *new_dentry)
@@ -1470,15 +1442,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
1470 return security_ops->inode_link (old_dentry, dir, new_dentry); 1442 return security_ops->inode_link (old_dentry, dir, new_dentry);
1471} 1443}
1472 1444
1473static inline void security_inode_post_link (struct dentry *old_dentry,
1474 struct inode *dir,
1475 struct dentry *new_dentry)
1476{
1477 if (new_dentry->d_inode && unlikely (IS_PRIVATE (new_dentry->d_inode)))
1478 return;
1479 security_ops->inode_post_link (old_dentry, dir, new_dentry);
1480}
1481
1482static inline int security_inode_unlink (struct inode *dir, 1445static inline int security_inode_unlink (struct inode *dir,
1483 struct dentry *dentry) 1446 struct dentry *dentry)
1484{ 1447{
@@ -1496,15 +1459,6 @@ static inline int security_inode_symlink (struct inode *dir,
1496 return security_ops->inode_symlink (dir, dentry, old_name); 1459 return security_ops->inode_symlink (dir, dentry, old_name);
1497} 1460}
1498 1461
1499static inline void security_inode_post_symlink (struct inode *dir,
1500 struct dentry *dentry,
1501 const char *old_name)
1502{
1503 if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
1504 return;
1505 security_ops->inode_post_symlink (dir, dentry, old_name);
1506}
1507
1508static inline int security_inode_mkdir (struct inode *dir, 1462static inline int security_inode_mkdir (struct inode *dir,
1509 struct dentry *dentry, 1463 struct dentry *dentry,
1510 int mode) 1464 int mode)
@@ -1514,15 +1468,6 @@ static inline int security_inode_mkdir (struct inode *dir,
1514 return security_ops->inode_mkdir (dir, dentry, mode); 1468 return security_ops->inode_mkdir (dir, dentry, mode);
1515} 1469}
1516 1470
1517static inline void security_inode_post_mkdir (struct inode *dir,
1518 struct dentry *dentry,
1519 int mode)
1520{
1521 if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
1522 return;
1523 security_ops->inode_post_mkdir (dir, dentry, mode);
1524}
1525
1526static inline int security_inode_rmdir (struct inode *dir, 1471static inline int security_inode_rmdir (struct inode *dir,
1527 struct dentry *dentry) 1472 struct dentry *dentry)
1528{ 1473{
@@ -1540,15 +1485,6 @@ static inline int security_inode_mknod (struct inode *dir,
1540 return security_ops->inode_mknod (dir, dentry, mode, dev); 1485 return security_ops->inode_mknod (dir, dentry, mode, dev);
1541} 1486}
1542 1487
1543static inline void security_inode_post_mknod (struct inode *dir,
1544 struct dentry *dentry,
1545 int mode, dev_t dev)
1546{
1547 if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
1548 return;
1549 security_ops->inode_post_mknod (dir, dentry, mode, dev);
1550}
1551
1552static inline int security_inode_rename (struct inode *old_dir, 1488static inline int security_inode_rename (struct inode *old_dir,
1553 struct dentry *old_dentry, 1489 struct dentry *old_dentry,
1554 struct inode *new_dir, 1490 struct inode *new_dir,
@@ -1561,18 +1497,6 @@ static inline int security_inode_rename (struct inode *old_dir,
1561 new_dir, new_dentry); 1497 new_dir, new_dentry);
1562} 1498}
1563 1499
1564static inline void security_inode_post_rename (struct inode *old_dir,
1565 struct dentry *old_dentry,
1566 struct inode *new_dir,
1567 struct dentry *new_dentry)
1568{
1569 if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
1570 (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
1571 return;
1572 security_ops->inode_post_rename (old_dir, old_dentry,
1573 new_dir, new_dentry);
1574}
1575
1576static inline int security_inode_readlink (struct dentry *dentry) 1500static inline int security_inode_readlink (struct dentry *dentry)
1577{ 1501{
1578 if (unlikely (IS_PRIVATE (dentry->d_inode))) 1502 if (unlikely (IS_PRIVATE (dentry->d_inode)))
@@ -2171,6 +2095,15 @@ static inline int security_inode_alloc (struct inode *inode)
2171 2095
2172static inline void security_inode_free (struct inode *inode) 2096static inline void security_inode_free (struct inode *inode)
2173{ } 2097{ }
2098
2099static inline int security_inode_init_security (struct inode *inode,
2100 struct inode *dir,
2101 char **name,
2102 void **value,
2103 size_t *len)
2104{
2105 return -EOPNOTSUPP;
2106}
2174 2107
2175static inline int security_inode_create (struct inode *dir, 2108static inline int security_inode_create (struct inode *dir,
2176 struct dentry *dentry, 2109 struct dentry *dentry,
@@ -2179,11 +2112,6 @@ static inline int security_inode_create (struct inode *dir,
2179 return 0; 2112 return 0;
2180} 2113}
2181 2114
2182static inline void security_inode_post_create (struct inode *dir,
2183 struct dentry *dentry,
2184 int mode)
2185{ }
2186
2187static inline int security_inode_link (struct dentry *old_dentry, 2115static inline int security_inode_link (struct dentry *old_dentry,
2188 struct inode *dir, 2116 struct inode *dir,
2189 struct dentry *new_dentry) 2117 struct dentry *new_dentry)
@@ -2191,11 +2119,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
2191 return 0; 2119 return 0;
2192} 2120}
2193 2121
2194static inline void security_inode_post_link (struct dentry *old_dentry,
2195 struct inode *dir,
2196 struct dentry *new_dentry)
2197{ }
2198
2199static inline int security_inode_unlink (struct inode *dir, 2122static inline int security_inode_unlink (struct inode *dir,
2200 struct dentry *dentry) 2123 struct dentry *dentry)
2201{ 2124{
@@ -2209,11 +2132,6 @@ static inline int security_inode_symlink (struct inode *dir,
2209 return 0; 2132 return 0;
2210} 2133}
2211 2134
2212static inline void security_inode_post_symlink (struct inode *dir,
2213 struct dentry *dentry,
2214 const char *old_name)
2215{ }
2216
2217static inline int security_inode_mkdir (struct inode *dir, 2135static inline int security_inode_mkdir (struct inode *dir,
2218 struct dentry *dentry, 2136 struct dentry *dentry,
2219 int mode) 2137 int mode)
@@ -2221,11 +2139,6 @@ static inline int security_inode_mkdir (struct inode *dir,
2221 return 0; 2139 return 0;
2222} 2140}
2223 2141
2224static inline void security_inode_post_mkdir (struct inode *dir,
2225 struct dentry *dentry,
2226 int mode)
2227{ }
2228
2229static inline int security_inode_rmdir (struct inode *dir, 2142static inline int security_inode_rmdir (struct inode *dir,
2230 struct dentry *dentry) 2143 struct dentry *dentry)
2231{ 2144{
@@ -2239,11 +2152,6 @@ static inline int security_inode_mknod (struct inode *dir,
2239 return 0; 2152 return 0;
2240} 2153}
2241 2154
2242static inline void security_inode_post_mknod (struct inode *dir,
2243 struct dentry *dentry,
2244 int mode, dev_t dev)
2245{ }
2246
2247static inline int security_inode_rename (struct inode *old_dir, 2155static inline int security_inode_rename (struct inode *old_dir,
2248 struct dentry *old_dentry, 2156 struct dentry *old_dentry,
2249 struct inode *new_dir, 2157 struct inode *new_dir,
@@ -2252,12 +2160,6 @@ static inline int security_inode_rename (struct inode *old_dir,
2252 return 0; 2160 return 0;
2253} 2161}
2254 2162
2255static inline void security_inode_post_rename (struct inode *old_dir,
2256 struct dentry *old_dentry,
2257 struct inode *new_dir,
2258 struct dentry *new_dentry)
2259{ }
2260
2261static inline int security_inode_readlink (struct dentry *dentry) 2163static inline int security_inode_readlink (struct dentry *dentry)
2262{ 2164{
2263 return 0; 2165 return 0;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index d8a023d804d4..317a979b24de 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -30,6 +30,21 @@ struct plat_serial8250_port {
30}; 30};
31 31
32/* 32/*
33 * Allocate 8250 platform device IDs. Nothing is implied by
34 * the numbering here, except for the legacy entry being -1.
35 */
36enum {
37 PLAT8250_DEV_LEGACY = -1,
38 PLAT8250_DEV_PLATFORM,
39 PLAT8250_DEV_PLATFORM1,
40 PLAT8250_DEV_FOURPORT,
41 PLAT8250_DEV_ACCENT,
42 PLAT8250_DEV_BOCA,
43 PLAT8250_DEV_HUB6,
44 PLAT8250_DEV_MCA,
45};
46
47/*
33 * This should be used by drivers which want to register 48 * This should be used by drivers which want to register
34 * their own 8250 ports without registering their own 49 * their own 8250 ports without registering their own
35 * platform device. Using these will make your driver 50 * platform device. Using these will make your driver
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 9b12fe731612..27db8da43aa4 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -401,6 +401,9 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
401#endif 401#endif
402 return 0; 402 return 0;
403} 403}
404#ifndef SUPPORT_SYSRQ
405#define uart_handle_sysrq_char(port,ch,regs) uart_handle_sysrq_char(port, 0, NULL)
406#endif
404 407
405/* 408/*
406 * We do the SysRQ and SAK checking like this... 409 * We do the SysRQ and SAK checking like this...
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index da7da9c0ed1b..2741c0c55e83 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1167,7 +1167,7 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb,
1167 1167
1168static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) 1168static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
1169{ 1169{
1170 if (len >= skb->len) 1170 if (likely(len >= skb->len))
1171 return 0; 1171 return 0;
1172 if (skb->ip_summed == CHECKSUM_HW) 1172 if (skb->ip_summed == CHECKSUM_HW)
1173 skb->ip_summed = CHECKSUM_NONE; 1173 skb->ip_summed = CHECKSUM_NONE;
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 221f81ac2002..3340f3bd135d 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -32,6 +32,10 @@ extern struct timer_base_s __init_timer_base;
32 .magic = TIMER_MAGIC, \ 32 .magic = TIMER_MAGIC, \
33 } 33 }
34 34
35#define DEFINE_TIMER(_name, _function, _expires, _data) \
36 struct timer_list _name = \
37 TIMER_INITIALIZER(_function, _expires, _data)
38
35void fastcall init_timer(struct timer_list * timer); 39void fastcall init_timer(struct timer_list * timer);
36 40
37/*** 41/***
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 59ff42c629ec..1267f88ece6e 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -74,7 +74,8 @@ struct screen_info {
74 u16 vesapm_off; /* 0x30 */ 74 u16 vesapm_off; /* 0x30 */
75 u16 pages; /* 0x32 */ 75 u16 pages; /* 0x32 */
76 u16 vesa_attributes; /* 0x34 */ 76 u16 vesa_attributes; /* 0x34 */
77 /* 0x36 -- 0x3f reserved for future expansion */ 77 u32 capabilities; /* 0x36 */
78 /* 0x3a -- 0x3f reserved for future expansion */
78}; 79};
79 80
80extern struct screen_info screen_info; 81extern struct screen_info screen_info;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 724637792996..4dbe580f9335 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -5,6 +5,7 @@
5#include <linux/usb_ch9.h> 5#include <linux/usb_ch9.h>
6 6
7#define USB_MAJOR 180 7#define USB_MAJOR 180
8#define USB_DEVICE_MAJOR 189
8 9
9 10
10#ifdef __KERNEL__ 11#ifdef __KERNEL__
@@ -349,6 +350,7 @@ struct usb_device {
349 char *manufacturer; 350 char *manufacturer;
350 char *serial; /* static strings from the device */ 351 char *serial; /* static strings from the device */
351 struct list_head filelist; 352 struct list_head filelist;
353 struct class_device *class_dev;
352 struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ 354 struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
353 355
354 /* 356 /*
@@ -614,7 +616,6 @@ extern int usb_disabled(void);
614#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ 616#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
615#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ 617#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
616#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */ 618#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
617#define URB_ASYNC_UNLINK 0x0010 /* usb_unlink_urb() returns asap */
618#define URB_NO_FSBR 0x0020 /* UHCI-specific */ 619#define URB_NO_FSBR 0x0020 /* UHCI-specific */
619#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ 620#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
620#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ 621#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
@@ -722,13 +723,7 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
722 * Initialization: 723 * Initialization:
723 * 724 *
724 * All URBs submitted must initialize the dev, pipe, transfer_flags (may be 725 * All URBs submitted must initialize the dev, pipe, transfer_flags (may be
725 * zero), and complete fields. 726 * zero), and complete fields. All URBs must also initialize
726 * The URB_ASYNC_UNLINK transfer flag affects later invocations of
727 * the usb_unlink_urb() routine. Note: Failure to set URB_ASYNC_UNLINK
728 * with usb_unlink_urb() is deprecated. For synchronous unlinks use
729 * usb_kill_urb() instead.
730 *
731 * All URBs must also initialize
732 * transfer_buffer and transfer_buffer_length. They may provide the 727 * transfer_buffer and transfer_buffer_length. They may provide the
733 * URB_SHORT_NOT_OK transfer flag, indicating that short reads are 728 * URB_SHORT_NOT_OK transfer flag, indicating that short reads are
734 * to be treated as errors; that flag is invalid for write requests. 729 * to be treated as errors; that flag is invalid for write requests.
diff --git a/include/linux/usb_isp116x.h b/include/linux/usb_isp116x.h
index 5f5a9d9bd6c2..436dd8a2b64a 100644
--- a/include/linux/usb_isp116x.h
+++ b/include/linux/usb_isp116x.h
@@ -7,36 +7,18 @@
7struct isp116x_platform_data { 7struct isp116x_platform_data {
8 /* Enable internal resistors on downstream ports */ 8 /* Enable internal resistors on downstream ports */
9 unsigned sel15Kres:1; 9 unsigned sel15Kres:1;
10 /* Chip's internal clock won't be stopped in suspended state. 10 /* On-chip overcurrent detection */
11 Setting/unsetting this bit takes effect only if
12 'remote_wakeup_enable' below is not set. */
13 unsigned clknotstop:1;
14 /* On-chip overcurrent protection */
15 unsigned oc_enable:1; 11 unsigned oc_enable:1;
16 /* INT output polarity */ 12 /* INT output polarity */
17 unsigned int_act_high:1; 13 unsigned int_act_high:1;
18 /* INT edge or level triggered */ 14 /* INT edge or level triggered */
19 unsigned int_edge_triggered:1; 15 unsigned int_edge_triggered:1;
20 /* WAKEUP pin connected - NOT SUPPORTED */ 16 /* Enable wakeup by devices on usb bus (e.g. wakeup
21 /* unsigned remote_wakeup_connected:1; */ 17 by attachment/detachment or by device activity
22 /* Wakeup by devices on usb bus enabled */ 18 such as moving a mouse). When chosen, this option
19 prevents stopping internal clock, increasing
20 thereby power consumption in suspended state. */
23 unsigned remote_wakeup_enable:1; 21 unsigned remote_wakeup_enable:1;
24 /* Switch or not to switch (keep always powered) */
25 unsigned no_power_switching:1;
26 /* Ganged port power switching (0) or individual port
27 power switching (1) */
28 unsigned power_switching_mode:1;
29 /* Given port_power, msec/2 after power on till power good */
30 u8 potpg;
31 /* Hardware reset set/clear. If implemented, this function must:
32 if set == 0, deassert chip's HW reset pin
33 otherwise, assert chip's HW reset pin */
34 void (*reset) (struct device * dev, int set);
35 /* Hardware clock start/stop. If implemented, this function must:
36 if start == 0, stop the external clock
37 otherwise, start the external clock
38 */
39 void (*clock) (struct device * dev, int start);
40 /* Inter-io delay (ns). The chip is picky about access timings; it 22 /* Inter-io delay (ns). The chip is picky about access timings; it
41 expects at least: 23 expects at least:
42 150ns delay between consecutive accesses to DATA_REG, 24 150ns delay between consecutive accesses to DATA_REG,
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 9d6fbde3d29c..1cc8c31b7988 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -3,7 +3,6 @@
3 3
4#include <linux/compiler.h> 4#include <linux/compiler.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/version.h>
7 6
8#define HAVE_V4L2 1 7#define HAVE_V4L2 1
9#include <linux/videodev2.h> 8#include <linux/videodev2.h>
@@ -29,7 +28,6 @@ struct video_device
29 void (*release)(struct video_device *vfd); 28 void (*release)(struct video_device *vfd);
30 29
31 30
32#if 1 /* to be removed in 2.7.x */
33 /* obsolete -- fops->owner is used instead */ 31 /* obsolete -- fops->owner is used instead */
34 struct module *owner; 32 struct module *owner;
35 /* dev->driver_data will be used instead some day. 33 /* dev->driver_data will be used instead some day.
@@ -37,7 +35,6 @@ struct video_device
37 * so the switch over will be transparent for you. 35 * so the switch over will be transparent for you.
38 * Or use {pci|usb}_{get|set}_drvdata() directly. */ 36 * Or use {pci|usb}_{get|set}_drvdata() directly. */
39 void *priv; 37 void *priv;
40#endif
41 38
42 /* for videodev.c intenal usage -- please don't touch */ 39 /* for videodev.c intenal usage -- please don't touch */
43 int users; /* video_exclusive_{open|close} ... */ 40 int users; /* video_exclusive_{open|close} ... */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index acbfc525576d..f623a33b9abe 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -270,7 +270,6 @@ struct v4l2_timecode
270/* The above is based on SMPTE timecodes */ 270/* The above is based on SMPTE timecodes */
271 271
272 272
273#if 1
274/* 273/*
275 * M P E G C O M P R E S S I O N P A R A M E T E R S 274 * M P E G C O M P R E S S I O N P A R A M E T E R S
276 * 275 *
@@ -357,7 +356,6 @@ struct v4l2_mpeg_compression {
357 /* I don't expect the above being perfect yet ;) */ 356 /* I don't expect the above being perfect yet ;) */
358 __u32 reserved_5[8]; 357 __u32 reserved_5[8];
359}; 358};
360#endif
361 359
362struct v4l2_jpegcompression 360struct v4l2_jpegcompression
363{ 361{
@@ -871,10 +869,8 @@ struct v4l2_streamparm
871#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) 869#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
872#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) 870#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
873#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) 871#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
874#if 1 /* experimental */
875#define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression) 872#define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression)
876#define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression) 873#define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression)
877#endif
878#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) 874#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
879#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) 875#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
880#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) 876#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index cd831168fdc1..a7ceee9fc5e9 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: audiochip.h,v 1.5 2005/06/16 22:59:16 hhackmann Exp $
3 */ 2 */
4 3
5#ifndef AUDIOCHIP_H 4#ifndef AUDIOCHIP_H
diff --git a/include/media/id.h b/include/media/id.h
index 801ddef301aa..6d02c94cdc0d 100644
--- a/include/media/id.h
+++ b/include/media/id.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: id.h,v 1.4 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4 3
5/* FIXME: this temporarely, until these are included in linux/i2c-id.h */ 4/* FIXME: this temporarely, until these are included in linux/i2c-id.h */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 698670547f16..01b56822df4d 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: ir-common.h,v 1.9 2005/05/15 19:01:26 mchehab Exp $
3 * 2 *
4 * some common structs and functions to handle infrared remotes via 3 * some common structs and functions to handle infrared remotes via
5 * input layer ... 4 * input layer ...
@@ -21,11 +20,11 @@
21 * 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
22 */ 21 */
23 22
24#include <linux/version.h>
25#include <linux/input.h> 23#include <linux/input.h>
26 24
27 25
28#define IR_TYPE_RC5 1 26#define IR_TYPE_RC5 1
27#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
29#define IR_TYPE_OTHER 99 28#define IR_TYPE_OTHER 99
30 29
31#define IR_KEYTAB_TYPE u32 30#define IR_KEYTAB_TYPE u32
@@ -60,6 +59,7 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
60u32 ir_extract_bits(u32 data, u32 mask); 59u32 ir_extract_bits(u32 data, u32 mask);
61int ir_dump_samples(u32 *samples, int count); 60int ir_dump_samples(u32 *samples, int count);
62int ir_decode_biphase(u32 *samples, int count, int low, int high); 61int ir_decode_biphase(u32 *samples, int count, int low, int high);
62int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
63 63
64/* 64/*
65 * Local variables: 65 * Local variables:
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 3dfb8d670eb7..2a897c3a6a9a 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -1,7 +1,6 @@
1#ifndef __SAA7146__ 1#ifndef __SAA7146__
2#define __SAA7146__ 2#define __SAA7146__
3 3
4#include <linux/version.h> /* for version macros */
5#include <linux/module.h> /* for module-version */ 4#include <linux/module.h> /* for module-version */
6#include <linux/delay.h> /* for delay-stuff */ 5#include <linux/delay.h> /* for delay-stuff */
7#include <linux/slab.h> /* for kmalloc/kfree */ 6#include <linux/slab.h> /* for kmalloc/kfree */
@@ -15,12 +14,7 @@
15#include <linux/vmalloc.h> /* for vmalloc() */ 14#include <linux/vmalloc.h> /* for vmalloc() */
16#include <linux/mm.h> /* for vmalloc_to_page() */ 15#include <linux/mm.h> /* for vmalloc_to_page() */
17 16
18/* ugly, but necessary to build the dvb stuff under 2.4. */ 17#define SAA7146_VERSION_CODE 0x000500 /* 0.5.0 */
19#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
20 #include "dvb_functions.h"
21#endif
22
23#define SAA7146_VERSION_CODE KERNEL_VERSION(0,5,0)
24 18
25#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr))) 19#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr)))
26#define saa7146_read(sxy,adr) readl(sxy->mem+(adr)) 20#define saa7146_read(sxy,adr) readl(sxy->mem+(adr))
@@ -33,13 +27,8 @@ extern unsigned int saa7146_debug;
33 #define DEBUG_VARIABLE saa7146_debug 27 #define DEBUG_VARIABLE saa7146_debug
34#endif 28#endif
35 29
36#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
37#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_BASENAME),__FUNCTION__)
38#define INFO(x) { printk("%s: ",__stringify(KBUILD_BASENAME)); printk x; }
39#else
40#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__) 30#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
41#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; } 31#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; }
42#endif
43 32
44#define ERR(x) { DEBUG_PROLOG; printk x; } 33#define ERR(x) { DEBUG_PROLOG; printk x; }
45 34
diff --git a/include/media/tuner.h b/include/media/tuner.h
index eeaa15ddee85..4ad08e24a1aa 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -1,6 +1,4 @@
1 1/*
2/* $Id: tuner.h,v 1.45 2005/07/28 18:41:21 mchehab Exp $
3 *
4 tuner.h - definition for different tuners 2 tuner.h - definition for different tuners
5 3
6 Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) 4 Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
@@ -28,88 +26,90 @@
28 26
29#define ADDR_UNSET (255) 27#define ADDR_UNSET (255)
30 28
31#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ 29#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
32#define TUNER_PHILIPS_PAL_I 1 30#define TUNER_PHILIPS_PAL_I 1
33#define TUNER_PHILIPS_NTSC 2 31#define TUNER_PHILIPS_NTSC 2
34#define TUNER_PHILIPS_SECAM 3 /* you must actively select B/G, L, L` */ 32#define TUNER_PHILIPS_SECAM 3 /* you must actively select B/G, L, L` */
35 33
36#define TUNER_ABSENT 4 34#define TUNER_ABSENT 4
37#define TUNER_PHILIPS_PAL 5 35#define TUNER_PHILIPS_PAL 5
38#define TUNER_TEMIC_NTSC 6 /* 4032 FY5 (3X 7004, 9498, 9789) */ 36#define TUNER_TEMIC_NTSC 6 /* 4032 FY5 (3X 7004, 9498, 9789) */
39#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5 (3X 8501, 9957) */ 37#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5 (3X 8501, 9957) */
40 38
41#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 (3X 1223, 1981, 7686) */ 39#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 (3X 1223, 1981, 7686) */
42#define TUNER_ALPS_TSBH1_NTSC 9 40#define TUNER_ALPS_TSBH1_NTSC 9
43#define TUNER_ALPS_TSBE1_PAL 10 41#define TUNER_ALPS_TSBE1_PAL 10
44#define TUNER_ALPS_TSBB5_PAL_I 11 42#define TUNER_ALPS_TSBB5_PAL_I 11
45 43
46#define TUNER_ALPS_TSBE5_PAL 12 44#define TUNER_ALPS_TSBE5_PAL 12
47#define TUNER_ALPS_TSBC5_PAL 13 45#define TUNER_ALPS_TSBC5_PAL 13
48#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 (3X 9500, 9501, 7291) */ 46#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 (3X 9500, 9501, 7291) */
49#define TUNER_ALPS_TSHC6_NTSC 15 47#define TUNER_ALPS_TSHC6_NTSC 15
50 48
51#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 (3X 1392, 1393) */ 49#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 (3X 1392, 1393) */
52#define TUNER_PHILIPS_NTSC_M 17 50#define TUNER_PHILIPS_NTSC_M 17
53#define TUNER_TEMIC_4066FY5_PAL_I 18 /* 4066 FY5 (3X 7032, 7035) */ 51#define TUNER_TEMIC_4066FY5_PAL_I 18 /* 4066 FY5 (3X 7032, 7035) */
54#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected (3X 7595, 7606, 7657)*/ 52#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected (3X 7595, 7606, 7657) */
55 53
56#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio (3X 7607, 7488, 7711)*/ 54#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio (3X 7607, 7488, 7711) */
57#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio (3X 7246, 7578, 7732)*/ 55#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio (3X 7246, 7578, 7732) */
58#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! (3X 7804, 7806, 8103, 8104)*/ 56#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! (3X 7804, 7806, 8103, 8104) */
59#define TUNER_PHILIPS_PAL_DK 23 57#define TUNER_PHILIPS_PAL_DK 23
60 58
61#define TUNER_PHILIPS_FQ1216ME 24 /* you must actively select B/G/D/K, I, L, L` */ 59#define TUNER_PHILIPS_FQ1216ME 24 /* you must actively select B/G/D/K, I, L, L` */
62#define TUNER_LG_PAL_I_FM 25 60#define TUNER_LG_PAL_I_FM 25
63#define TUNER_LG_PAL_I 26 61#define TUNER_LG_PAL_I 26
64#define TUNER_LG_NTSC_FM 27 62#define TUNER_LG_NTSC_FM 27
65 63
66#define TUNER_LG_PAL_FM 28 64#define TUNER_LG_PAL_FM 28
67#define TUNER_LG_PAL 29 65#define TUNER_LG_PAL 29
68#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected (3X 8155, 8160, 8163)*/ 66#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected (3X 8155, 8160, 8163) */
69#define TUNER_SHARP_2U5JF5540_NTSC 31 67#define TUNER_SHARP_2U5JF5540_NTSC 31
70 68
71#define TUNER_Samsung_PAL_TCPM9091PD27 32 69#define TUNER_Samsung_PAL_TCPM9091PD27 32
72#define TUNER_MT2032 33 70#define TUNER_MT2032 33
73#define TUNER_TEMIC_4106FH5 34 /* 4106 FH5 (3X 7808, 7865)*/ 71#define TUNER_TEMIC_4106FH5 34 /* 4106 FH5 (3X 7808, 7865) */
74#define TUNER_TEMIC_4012FY5 35 /* 4012 FY5 (3X 0971, 1099)*/ 72#define TUNER_TEMIC_4012FY5 35 /* 4012 FY5 (3X 0971, 1099) */
75 73
76#define TUNER_TEMIC_4136FY5 36 /* 4136 FY5 (3X 7708, 7746)*/ 74#define TUNER_TEMIC_4136FY5 36 /* 4136 FY5 (3X 7708, 7746) */
77#define TUNER_LG_PAL_NEW_TAPC 37 75#define TUNER_LG_PAL_NEW_TAPC 37
78#define TUNER_PHILIPS_FM1216ME_MK3 38 76#define TUNER_PHILIPS_FM1216ME_MK3 38
79#define TUNER_LG_NTSC_NEW_TAPC 39 77#define TUNER_LG_NTSC_NEW_TAPC 39
80 78
81#define TUNER_HITACHI_NTSC 40 79#define TUNER_HITACHI_NTSC 40
82#define TUNER_PHILIPS_PAL_MK 41 80#define TUNER_PHILIPS_PAL_MK 41
83#define TUNER_PHILIPS_ATSC 42 81#define TUNER_PHILIPS_ATSC 42
84#define TUNER_PHILIPS_FM1236_MK3 43 82#define TUNER_PHILIPS_FM1236_MK3 43
85 83
86#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */ 84#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */
87/* Microtune mergeged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */ 85/* Microtune mergeged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */
88#define TUNER_MICROTUNE_4049FM5 45 86#define TUNER_MICROTUNE_4049FM5 45
89#define TUNER_LG_NTSC_TAPE 47 87#define TUNER_MICROTUNE_4042_FI5 46
90 88#define TUNER_LG_NTSC_TAPE 47
91#define TUNER_TNF_8831BGFF 48 89
92#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */ 90#define TUNER_TNF_8831BGFF 48
93#define TUNER_TCL_2002N 50 91#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
94#define TUNER_PHILIPS_FM1256_IH3 51 92#define TUNER_TCL_2002N 50
95 93#define TUNER_PHILIPS_FM1256_IH3 51
96#define TUNER_THOMSON_DTT7610 52 94
97#define TUNER_PHILIPS_FQ1286 53 95#define TUNER_THOMSON_DTT7610 52
98#define TUNER_PHILIPS_TDA8290 54 96#define TUNER_PHILIPS_FQ1286 53
99#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ 97#define TUNER_PHILIPS_TDA8290 54
100 98#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */
101#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ 99
102#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ 100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
103 101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
104#define TUNER_YMEC_TVF_8531MF 58 102#define TUNER_YMEC_TVF_8531MF 58
105#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ 103#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
106#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */ 104
107#define TUNER_TENA_9533_DI 61 105#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */
108 106#define TUNER_TENA_9533_DI 61
109#define TUNER_TEA5767 62 /* Only FM Radio Tuner */ 107#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
110#define TUNER_PHILIPS_FMD1216ME_MK3 63 108#define TUNER_PHILIPS_FMD1216ME_MK3 63
111#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ 109
112#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ 110#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
111#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
112#define TUNER_LG_NTSC_TALN_MINI 66
113 113
114#define NOTUNER 0 114#define NOTUNER 0
115#define PAL 1 /* PAL_BG */ 115#define PAL 1 /* PAL_BG */
@@ -117,7 +117,7 @@
117#define NTSC 3 117#define NTSC 3
118#define SECAM 4 118#define SECAM 4
119#define ATSC 5 119#define ATSC 5
120#define RADIO 6 120#define RADIO 6
121 121
122#define NoTuner 0 122#define NoTuner 0
123#define Philips 1 123#define Philips 1
@@ -134,6 +134,7 @@
134#define THOMSON 12 134#define THOMSON 12
135 135
136#define TUNER_SET_TYPE_ADDR _IOW('T',3,int) 136#define TUNER_SET_TYPE_ADDR _IOW('T',3,int)
137#define TUNER_SET_STANDBY _IOW('T',4,int)
137#define TDA9887_SET_CONFIG _IOW('t',5,int) 138#define TDA9887_SET_CONFIG _IOW('t',5,int)
138 139
139/* tv card specific */ 140/* tv card specific */
@@ -153,9 +154,6 @@
153 154
154#ifdef __KERNEL__ 155#ifdef __KERNEL__
155 156
156#define I2C_ADDR_TDA8290 0x4b
157#define I2C_ADDR_TDA8275 0x61
158
159enum tuner_mode { 157enum tuner_mode {
160 T_UNINITIALIZED = 0, 158 T_UNINITIALIZED = 0,
161 T_RADIO = 1 << V4L2_TUNER_RADIO, 159 T_RADIO = 1 << V4L2_TUNER_RADIO,
@@ -165,21 +163,21 @@ enum tuner_mode {
165}; 163};
166 164
167struct tuner_setup { 165struct tuner_setup {
168 unsigned short addr; 166 unsigned short addr;
169 unsigned int type; 167 unsigned int type;
170 unsigned int mode_mask; 168 unsigned int mode_mask;
171}; 169};
172 170
173struct tuner { 171struct tuner {
174 /* device */ 172 /* device */
175 struct i2c_client i2c; 173 struct i2c_client i2c;
176 174
177 unsigned int type; /* chip type */ 175 unsigned int type; /* chip type */
178 176
179 unsigned int mode; 177 unsigned int mode;
180 unsigned int mode_mask; /* Combination of allowable modes */ 178 unsigned int mode_mask; /* Combination of allowable modes */
181 179
182 unsigned int freq; /* keep track of the current settings */ 180 unsigned int freq; /* keep track of the current settings */
183 unsigned int audmode; 181 unsigned int audmode;
184 v4l2_std_id std; 182 v4l2_std_id std;
185 183
@@ -198,6 +196,7 @@ struct tuner {
198 void (*radio_freq)(struct i2c_client *c, unsigned int freq); 196 void (*radio_freq)(struct i2c_client *c, unsigned int freq);
199 int (*has_signal)(struct i2c_client *c); 197 int (*has_signal)(struct i2c_client *c);
200 int (*is_stereo)(struct i2c_client *c); 198 int (*is_stereo)(struct i2c_client *c);
199 void (*standby)(struct i2c_client *c);
201}; 200};
202 201
203extern unsigned int tuner_debug; 202extern unsigned int tuner_debug;
@@ -209,16 +208,20 @@ extern int tea5767_tuner_init(struct i2c_client *c);
209extern int default_tuner_init(struct i2c_client *c); 208extern int default_tuner_init(struct i2c_client *c);
210extern int tea5767_autodetection(struct i2c_client *c); 209extern int tea5767_autodetection(struct i2c_client *c);
211 210
212#define tuner_warn(fmt, arg...) \ 211#define tuner_warn(fmt, arg...) do {\
213 dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg) 212 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
214#define tuner_info(fmt, arg...) \ 213 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
215 dev_printk(KERN_INFO , &t->i2c.dev , fmt , ## arg) 214#define tuner_info(fmt, arg...) do {\
216#define tuner_dbg(fmt, arg...) \ 215 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
217 if (tuner_debug) dev_printk(KERN_DEBUG , &t->i2c.dev , fmt , ## arg) 216 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
217#define tuner_dbg(fmt, arg...) do {\
218 if (tuner_debug) \
219 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
220 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
218 221
219#endif /* __KERNEL__ */ 222#endif /* __KERNEL__ */
220 223
221#endif 224#endif /* _TUNER_H */
222 225
223/* 226/*
224 * Overrides for Emacs so that we follow Linus's tabbing style. 227 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index 854a2c2f105b..e2035c7da094 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,18 +1,21 @@
1/* 1/*
2 * $Id: tveeprom.h,v 1.2 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4 3
5struct tveeprom { 4struct tveeprom {
6 u32 has_radio; 5 u32 has_radio;
6 u32 has_ir; /* 0: no IR, 1: IR present, 2: unknown */
7 7
8 u32 tuner_type; 8 u32 tuner_type;
9 u32 tuner_formats; 9 u32 tuner_formats;
10 10
11 u32 tuner2_type;
12 u32 tuner2_formats;
13
11 u32 digitizer; 14 u32 digitizer;
12 u32 digitizer_formats; 15 u32 digitizer_formats;
13 16
14 u32 audio_processor; 17 u32 audio_processor;
15 /* a_p_fmts? */ 18 u32 decoder_processor;
16 19
17 u32 model; 20 u32 model;
18 u32 revision; 21 u32 revision;
@@ -20,7 +23,7 @@ struct tveeprom {
20 char rev_str[5]; 23 char rev_str[5];
21}; 24};
22 25
23void tveeprom_hauppauge_analog(struct tveeprom *tvee, 26void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
24 unsigned char *eeprom_data); 27 unsigned char *eeprom_data);
25 28
26int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len); 29int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len);
diff --git a/include/media/video-buf.h b/include/media/video-buf.h
index ae6da6de98de..ae8d7a000440 100644
--- a/include/media/video-buf.h
+++ b/include/media/video-buf.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: video-buf.h,v 1.9 2004/11/07 13:17:15 kraxel Exp $
3 * 2 *
4 * generic helper functions for video4linux capture buffers, to handle 3 * generic helper functions for video4linux capture buffers, to handle
5 * memory management and PCI DMA. Right now bttv + saa7134 use it. 4 * memory management and PCI DMA. Right now bttv + saa7134 use it.
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 364b046e9f47..227d3378decd 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -258,7 +258,7 @@ extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
258/* ax25_addr.c */ 258/* ax25_addr.c */
259extern ax25_address null_ax25_address; 259extern ax25_address null_ax25_address;
260extern char *ax2asc(char *buf, ax25_address *); 260extern char *ax2asc(char *buf, ax25_address *);
261extern ax25_address *asc2ax(char *); 261extern void asc2ax(ax25_address *addr, char *callsign);
262extern int ax25cmp(ax25_address *, ax25_address *); 262extern int ax25cmp(ax25_address *, ax25_address *);
263extern int ax25digicmp(ax25_digi *, ax25_digi *); 263extern int ax25digicmp(ax25_digi *, ax25_digi *);
264extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *); 264extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *);
diff --git a/include/net/compat.h b/include/net/compat.h
index 482eb820f13a..290bab46d457 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -33,7 +33,8 @@ extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsi
33extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); 33extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
34extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); 34extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
35extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); 35extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
36extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, 36
37 int); 37struct sock;
38extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
38 39
39#endif /* NET_COMPAT_H */ 40#endif /* NET_COMPAT_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 3203eaff4bd4..65ec86678a08 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -233,6 +233,10 @@ extern int ip6_ra_control(struct sock *sk, int sel,
233extern int ipv6_parse_hopopts(struct sk_buff *skb, int); 233extern int ipv6_parse_hopopts(struct sk_buff *skb, int);
234 234
235extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); 235extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
236extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
237 int newtype,
238 struct ipv6_opt_hdr __user *newopt,
239 int newoptlen);
236 240
237extern int ip6_frag_nqueues; 241extern int ip6_frag_nqueues;
238extern atomic_t ip6_frag_mem; 242extern atomic_t ip6_frag_mem;
@@ -373,6 +377,7 @@ extern int ip6_append_data(struct sock *sk,
373 int length, 377 int length,
374 int transhdrlen, 378 int transhdrlen,
375 int hlimit, 379 int hlimit,
380 int tclass,
376 struct ipv6_txoptions *opt, 381 struct ipv6_txoptions *opt,
377 struct flowi *fl, 382 struct flowi *fl,
378 struct rt6_info *rt, 383 struct rt6_info *rt,
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 8b075ab7a26c..4e86f2de6638 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -37,7 +37,7 @@ extern int datagram_recv_ctl(struct sock *sk,
37extern int datagram_send_ctl(struct msghdr *msg, 37extern int datagram_send_ctl(struct msghdr *msg,
38 struct flowi *fl, 38 struct flowi *fl,
39 struct ipv6_txoptions *opt, 39 struct ipv6_txoptions *opt,
40 int *hlimit); 40 int *hlimit, int *tclass);
41 41
42#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006) 42#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006)
43 43
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index b707a603351b..cb8b6e6ce66c 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -151,6 +151,8 @@ struct pcmcia_device {
151 uniquely define a pcmcia_device */ 151 uniquely define a pcmcia_device */
152 struct pcmcia_socket *socket; 152 struct pcmcia_socket *socket;
153 153
154 char *devname;
155
154 u8 device_no; 156 u8 device_no;
155 157
156 /* the hardware "function" device; certain subdevices can 158 /* the hardware "function" device; certain subdevices can
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 389e8ebe9c19..d6361dab0370 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -910,11 +910,10 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format);
910 * Returns 1 if the given PCM format is CPU-endian, 0 if 910 * Returns 1 if the given PCM format is CPU-endian, 0 if
911 * opposite, or a negative error code if endian not specified. 911 * opposite, or a negative error code if endian not specified.
912 */ 912 */
913/* int snd_pcm_format_cpu_endian(snd_pcm_format_t format); */
914#ifdef SNDRV_LITTLE_ENDIAN 913#ifdef SNDRV_LITTLE_ENDIAN
915#define snd_pcm_format_cpu_endian snd_pcm_format_little_endian 914#define snd_pcm_format_cpu_endian(format) snd_pcm_format_little_endian(format)
916#else 915#else
917#define snd_pcm_format_cpu_endian snd_pcm_format_big_endian 916#define snd_pcm_format_cpu_endian(format) snd_pcm_format_big_endian(format)
918#endif 917#endif
919int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */ 918int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */
920int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */ 919int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index ad3c3be33c03..b82e408e758f 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -34,9 +34,7 @@ struct snd_tea575x_ops {
34struct snd_tea575x { 34struct snd_tea575x {
35 snd_card_t *card; 35 snd_card_t *card;
36 struct video_device vd; /* video device */ 36 struct video_device vd; /* video device */
37#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
38 struct file_operations fops; 37 struct file_operations fops;
39#endif
40 int dev_nr; /* requested device number + 1 */ 38 int dev_nr; /* requested device number + 1 */
41 int vd_registered; /* video device is registered */ 39 int vd_registered; /* video device is registered */
42 int tea5759; /* 5759 chip is present */ 40 int tea5759; /* 5759 chip is present */
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
new file mode 100644
index 000000000000..a9948232b131
--- /dev/null
+++ b/include/video/cyblafb.h
@@ -0,0 +1,171 @@
1
2#ifndef CYBLAFB_DEBUG
3#define CYBLAFB_DEBUG 0
4#endif
5
6#if CYBLAFB_DEBUG
7#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a);
8#else
9#define debug(f,a...)
10#endif
11
12#define output(f, a...) printk("cyblafb: " f, ## a)
13
14#define Kb (1024)
15#define Mb (Kb*Kb)
16
17/* PCI IDS of supported cards temporarily here */
18
19#define CYBERBLADEi1 0x8500
20
21/* these defines are for 'lcd' variable */
22#define LCD_STRETCH 0
23#define LCD_CENTER 1
24#define LCD_BIOS 2
25
26/* display types */
27#define DISPLAY_CRT 0
28#define DISPLAY_FP 1
29
30#define ROP_S 0xCC
31
32#define point(x,y) ((y)<<16|(x))
33
34//
35// Attribute Regs, ARxx, 3c0/3c1
36//
37#define AR00 0x00
38#define AR01 0x01
39#define AR02 0x02
40#define AR03 0x03
41#define AR04 0x04
42#define AR05 0x05
43#define AR06 0x06
44#define AR07 0x07
45#define AR08 0x08
46#define AR09 0x09
47#define AR0A 0x0A
48#define AR0B 0x0B
49#define AR0C 0x0C
50#define AR0D 0x0D
51#define AR0E 0x0E
52#define AR0F 0x0F
53#define AR10 0x10
54#define AR12 0x12
55#define AR13 0x13
56
57//
58// Sequencer Regs, SRxx, 3c4/3c5
59//
60#define SR00 0x00
61#define SR01 0x01
62#define SR02 0x02
63#define SR03 0x03
64#define SR04 0x04
65#define SR0D 0x0D
66#define SR0E 0x0E
67#define SR11 0x11
68#define SR18 0x18
69#define SR19 0x19
70
71//
72//
73//
74#define CR00 0x00
75#define CR01 0x01
76#define CR02 0x02
77#define CR03 0x03
78#define CR04 0x04
79#define CR05 0x05
80#define CR06 0x06
81#define CR07 0x07
82#define CR08 0x08
83#define CR09 0x09
84#define CR0A 0x0A
85#define CR0B 0x0B
86#define CR0C 0x0C
87#define CR0D 0x0D
88#define CR0E 0x0E
89#define CR0F 0x0F
90#define CR10 0x10
91#define CR11 0x11
92#define CR12 0x12
93#define CR13 0x13
94#define CR14 0x14
95#define CR15 0x15
96#define CR16 0x16
97#define CR17 0x17
98#define CR18 0x18
99#define CR19 0x19
100#define CR1A 0x1A
101#define CR1B 0x1B
102#define CR1C 0x1C
103#define CR1D 0x1D
104#define CR1E 0x1E
105#define CR1F 0x1F
106#define CR20 0x20
107#define CR21 0x21
108#define CR27 0x27
109#define CR29 0x29
110#define CR2A 0x2A
111#define CR2B 0x2B
112#define CR2D 0x2D
113#define CR2F 0x2F
114#define CR36 0x36
115#define CR38 0x38
116#define CR39 0x39
117#define CR3A 0x3A
118#define CR55 0x55
119#define CR56 0x56
120#define CR57 0x57
121#define CR58 0x58
122
123//
124//
125//
126
127#define GR00 0x01
128#define GR01 0x01
129#define GR02 0x02
130#define GR03 0x03
131#define GR04 0x04
132#define GR05 0x05
133#define GR06 0x06
134#define GR07 0x07
135#define GR08 0x08
136#define GR0F 0x0F
137#define GR20 0x20
138#define GR23 0x23
139#define GR2F 0x2F
140#define GR30 0x30
141#define GR31 0x31
142#define GR33 0x33
143#define GR52 0x52
144#define GR53 0x53
145#define GR5D 0x5d
146
147
148//
149// Graphics Engine
150//
151#define GEBase 0x2100 // could be mapped elsewhere if we like it
152#define GE00 (GEBase+0x00) // source 1, p 111
153#define GE04 (GEBase+0x04) // source 2, p 111
154#define GE08 (GEBase+0x08) // destination 1, p 111
155#define GE0C (GEBase+0x0C) // destination 2, p 112
156#define GE20 (GEBase+0x20) // engine status, p 113
157#define GE24 (GEBase+0x24) // reset all GE pointers
158#define GE44 (GEBase+0x44) // command register, p 126
159#define GE48 (GEBase+0x48) // raster operation, p 127
160#define GE60 (GEBase+0x60) // foreground color, p 128
161#define GE64 (GEBase+0x64) // background color, p 128
162#define GE6C (GEBase+0x6C) // Pattern and Style, p 129, ok
163#define GE9C (GEBase+0x9C) // pixel engine data port, p 125
164#define GEB8 (GEBase+0xB8) // Destination Stride / Buffer Base 0, p 133
165#define GEBC (GEBase+0xBC) // Destination Stride / Buffer Base 1, p 133
166#define GEC0 (GEBase+0xC0) // Destination Stride / Buffer Base 2, p 133
167#define GEC4 (GEBase+0xC4) // Destination Stride / Buffer Base 3, p 133
168#define GEC8 (GEBase+0xC8) // Source Stride / Buffer Base 0, p 133
169#define GECC (GEBase+0xCC) // Source Stride / Buffer Base 1, p 133
170#define GED0 (GEBase+0xD0) // Source Stride / Buffer Base 2, p 133
171#define GED4 (GEBase+0xD4) // Source Stride / Buffer Base 3, p 133
diff --git a/include/video/sisfb.h b/include/video/sisfb.h
index 136bf791643d..e402eb5b3c7a 100644
--- a/include/video/sisfb.h
+++ b/include/video/sisfb.h
@@ -1,5 +1,7 @@
1/* 1/*
2 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria. 2 * sisfb.h - definitions for the SiS framebuffer driver
3 *
4 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
3 * 5 *
4 * 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
5 * 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
@@ -16,8 +18,8 @@
16 * 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
17 */ 19 */
18 20
19#ifndef _LINUX_SISFB 21#ifndef _LINUX_SISFB_H_
20#define _LINUX_SISFB 22#define _LINUX_SISFB_H_
21 23
22#include <asm/ioctl.h> 24#include <asm/ioctl.h>
23#include <asm/types.h> 25#include <asm/types.h>
@@ -26,47 +28,35 @@
26/* PUBLIC */ 28/* PUBLIC */
27/**********************************************/ 29/**********************************************/
28 30
29/* vbflags */ 31/* vbflags, public (others in sis.h) */
30#define CRT2_DEFAULT 0x00000001 32#define CRT2_DEFAULT 0x00000001
31#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */ 33#define CRT2_LCD 0x00000002
32#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */ 34#define CRT2_TV 0x00000004
33#define CRT2_VGA 0x00000008 35#define CRT2_VGA 0x00000008
34#define TV_NTSC 0x00000010 36#define TV_NTSC 0x00000010
35#define TV_PAL 0x00000020 37#define TV_PAL 0x00000020
36#define TV_HIVISION 0x00000040 38#define TV_HIVISION 0x00000040
37#define TV_YPBPR 0x00000080 39#define TV_YPBPR 0x00000080
38#define TV_AVIDEO 0x00000100 40#define TV_AVIDEO 0x00000100
39#define TV_SVIDEO 0x00000200 41#define TV_SVIDEO 0x00000200
40#define TV_SCART 0x00000400 42#define TV_SCART 0x00000400
41#define VB_CONEXANT 0x00000800 /* 661 series only */ 43#define TV_PALM 0x00001000
42#define VB_TRUMPION VB_CONEXANT /* 300 series only */ 44#define TV_PALN 0x00002000
43#define TV_PALM 0x00001000
44#define TV_PALN 0x00002000
45#define TV_NTSCJ 0x00001000 45#define TV_NTSCJ 0x00001000
46#define VB_302ELV 0x00004000 46#define TV_CHSCART 0x00008000
47#define TV_CHSCART 0x00008000 47#define TV_CHYPBPR525I 0x00010000
48#define TV_CHYPBPR525I 0x00010000
49#define CRT1_VGA 0x00000000 48#define CRT1_VGA 0x00000000
50#define CRT1_LCDA 0x00020000 49#define CRT1_LCDA 0x00020000
51#define VGA2_CONNECTED 0x00040000 50#define VGA2_CONNECTED 0x00040000
52#define VB_DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */ 51#define VB_DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
53#define VB_301 0x00100000 /* Video bridge type */ 52#define VB_SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
54#define VB_301B 0x00200000 53#define VB_MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
55#define VB_302B 0x00400000 54#define VB_DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
56#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
57#define VB_LVDS 0x01000000
58#define VB_CHRONTEL 0x02000000
59#define VB_301LV 0x04000000
60#define VB_302LV 0x08000000
61#define VB_301C 0x10000000
62#define VB_SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
63#define VB_MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
64#define VB_DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
65 55
66/* Aliases: */ 56/* Aliases: */
67#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA) 57#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
68#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ) 58#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
69#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I) 59#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
70 60
71/* Only if TV_YPBPR is set: */ 61/* Only if TV_YPBPR is set: */
72#define TV_YPBPR525I TV_NTSC 62#define TV_YPBPR525I TV_NTSC
@@ -75,89 +65,118 @@
75#define TV_YPBPR1080I TV_PALN 65#define TV_YPBPR1080I TV_PALN
76#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I) 66#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
77 67
78#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
79#define VB_SISTVBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)
80#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
81
82#define VB_DISPTYPE_DISP2 CRT2_ENABLE 68#define VB_DISPTYPE_DISP2 CRT2_ENABLE
83#define VB_DISPTYPE_CRT2 CRT2_ENABLE 69#define VB_DISPTYPE_CRT2 CRT2_ENABLE
84#define VB_DISPTYPE_DISP1 VB_DISPTYPE_CRT1 70#define VB_DISPTYPE_DISP1 VB_DISPTYPE_CRT1
85#define VB_DISPMODE_SINGLE VB_SINGLE_MODE 71#define VB_DISPMODE_SINGLE VB_SINGLE_MODE
86#define VB_DISPMODE_MIRROR VB_MIRROR_MODE 72#define VB_DISPMODE_MIRROR VB_MIRROR_MODE
87#define VB_DISPMODE_DUAL VB_DUALVIEW_MODE 73#define VB_DISPMODE_DUAL VB_DUALVIEW_MODE
88#define VB_DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE) 74#define VB_DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
89 75
90/* Structure argument for SISFB_GET_INFO ioctl */ 76/* Structure argument for SISFB_GET_INFO ioctl */
91typedef struct _SISFB_INFO sisfb_info, *psisfb_info; 77struct sisfb_info {
92 78 __u32 sisfb_id; /* for identifying sisfb */
93struct _SISFB_INFO {
94 __u32 sisfb_id; /* for identifying sisfb */
95#ifndef SISFB_ID 79#ifndef SISFB_ID
96#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */ 80#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
97#endif 81#endif
98 __u32 chip_id; /* PCI-ID of detected chip */ 82 __u32 chip_id; /* PCI-ID of detected chip */
99 __u32 memory; /* video memory in KB which sisfb manages */ 83 __u32 memory; /* total video memory in KB */
100 __u32 heapstart; /* heap start (= sisfb "mem" argument) in KB */ 84 __u32 heapstart; /* heap start offset in KB */
101 __u8 fbvidmode; /* current sisfb mode */ 85 __u8 fbvidmode; /* current sisfb mode */
102 86
103 __u8 sisfb_version; 87 __u8 sisfb_version;
104 __u8 sisfb_revision; 88 __u8 sisfb_revision;
105 __u8 sisfb_patchlevel; 89 __u8 sisfb_patchlevel;
106 90
107 __u8 sisfb_caps; /* sisfb capabilities */ 91 __u8 sisfb_caps; /* sisfb capabilities */
108 92
109 __u32 sisfb_tqlen; /* turbo queue length (in KB) */ 93 __u32 sisfb_tqlen; /* turbo queue length (in KB) */
110 94
111 __u32 sisfb_pcibus; /* The card's PCI ID */ 95 __u32 sisfb_pcibus; /* The card's PCI ID */
112 __u32 sisfb_pcislot; 96 __u32 sisfb_pcislot;
113 __u32 sisfb_pcifunc; 97 __u32 sisfb_pcifunc;
98
99 __u8 sisfb_lcdpdc; /* PanelDelayCompensation */
100
101 __u8 sisfb_lcda; /* Detected status of LCDA for low res/text modes */
102
103 __u32 sisfb_vbflags;
104 __u32 sisfb_currentvbflags;
105
106 __u32 sisfb_scalelcd;
107 __u32 sisfb_specialtiming;
108
109 __u8 sisfb_haveemi;
110 __u8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
111 __u8 sisfb_haveemilcd;
114 112
115 __u8 sisfb_lcdpdc; /* PanelDelayCompensation */ 113 __u8 sisfb_lcdpdca; /* PanelDelayCompensation for LCD-via-CRT1 */
116 114
117 __u8 sisfb_lcda; /* Detected status of LCDA for low res/text modes */ 115 __u16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
118 116
119 __u32 sisfb_vbflags; 117 __u32 sisfb_heapsize; /* heap size (in KB) */
120 __u32 sisfb_currentvbflags; 118 __u32 sisfb_videooffset; /* Offset of viewport in video memory (in bytes) */
121 119
122 __u32 sisfb_scalelcd; 120 __u32 sisfb_curfstn; /* currently running FSTN/DSTN mode */
123 __u32 sisfb_specialtiming; 121 __u32 sisfb_curdstn;
124 122
125 __u8 sisfb_haveemi; 123 __u16 sisfb_pci_vendor; /* PCI vendor (SiS or XGI) */
126 __u8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
127 __u8 sisfb_haveemilcd;
128 124
129 __u8 sisfb_lcdpdca; /* PanelDelayCompensation for LCD-via-CRT1 */ 125 __u32 sisfb_vbflags2; /* ivideo->vbflags2 */
130 126
131 __u16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */ 127 __u8 sisfb_can_post; /* sisfb can POST this card */
128 __u8 sisfb_card_posted; /* card is POSTED */
129 __u8 sisfb_was_boot_device; /* This card was the boot video device (ie is primary) */
132 130
133 __u8 reserved[208]; /* for future use */ 131 __u8 reserved[183]; /* for future use */
132};
133
134#define SISFB_CMD_GETVBFLAGS 0x55AA0001 /* no arg; result[1] = vbflags */
135#define SISFB_CMD_SWITCHCRT1 0x55AA0010 /* arg[0]: 99 = query, 0 = off, 1 = on */
136/* more to come */
137
138#define SISFB_CMD_ERR_OK 0x80000000 /* command succeeded */
139#define SISFB_CMD_ERR_LOCKED 0x80000001 /* sisfb is locked */
140#define SISFB_CMD_ERR_EARLY 0x80000002 /* request before sisfb took over gfx system */
141#define SISFB_CMD_ERR_NOVB 0x80000003 /* No video bridge */
142#define SISFB_CMD_ERR_NOCRT2 0x80000004 /* can't change CRT1 status, CRT2 disabled */
143/* more to come */
144#define SISFB_CMD_ERR_UNKNOWN 0x8000ffff /* Unknown command */
145#define SISFB_CMD_ERR_OTHER 0x80010000 /* Other error */
146
147/* Argument for SISFB_CMD ioctl */
148struct sisfb_cmd {
149 __u32 sisfb_cmd;
150 __u32 sisfb_arg[16];
151 __u32 sisfb_result[4];
134}; 152};
135 153
136/* Addtional IOCTLs for communication sisfb <> X driver */ 154/* Addtional IOCTLs for communication sisfb <> X driver */
137/* If changing this, vgatypes.h must also be changed (for X driver) */ 155/* If changing this, vgatypes.h must also be changed (for X driver) */
138 156
139/* ioctl for identifying and giving some info (esp. memory heap start) */ 157/* ioctl for identifying and giving some info (esp. memory heap start) */
140#define SISFB_GET_INFO_SIZE _IOR(0xF3,0x00,__u32) 158#define SISFB_GET_INFO_SIZE _IOR(0xF3,0x00,__u32)
141#define SISFB_GET_INFO _IOR(0xF3,0x01,struct _SISFB_INFO) 159#define SISFB_GET_INFO _IOR(0xF3,0x01,struct sisfb_info)
142 160
143/* ioctrl to get current vertical retrace status */ 161/* ioctrl to get current vertical retrace status */
144#define SISFB_GET_VBRSTATUS _IOR(0xF3,0x02,__u32) 162#define SISFB_GET_VBRSTATUS _IOR(0xF3,0x02,__u32)
145 163
146/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */ 164/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
147#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32) 165#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32)
148#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32) 166#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32)
149 167
150/* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/ 168/* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/
151#define SISFB_GET_TVPOSOFFSET _IOR(0xF3,0x04,__u32) 169#define SISFB_GET_TVPOSOFFSET _IOR(0xF3,0x04,__u32)
152#define SISFB_SET_TVPOSOFFSET _IOW(0xF3,0x04,__u32) 170#define SISFB_SET_TVPOSOFFSET _IOW(0xF3,0x04,__u32)
171
172/* ioctl for internal sisfb commands (sisfbctrl) */
173#define SISFB_COMMAND _IOWR(0xF3,0x05,struct sisfb_cmd)
153 174
154/* ioctl for locking sisfb (no register access during lock) */ 175/* ioctl for locking sisfb (no register access during lock) */
155/* As of now, only used to avoid register access during 176/* As of now, only used to avoid register access during
156 * the ioctls listed above. 177 * the ioctls listed above.
157 */ 178 */
158#define SISFB_SET_LOCK _IOW(0xF3,0x06,__u32) 179#define SISFB_SET_LOCK _IOW(0xF3,0x06,__u32)
159
160/* more to come soon */
161 180
162/* ioctls 0xF3 up to 0x3F reserved for sisfb */ 181/* ioctls 0xF3 up to 0x3F reserved for sisfb */
163 182
@@ -165,7 +184,7 @@ struct _SISFB_INFO {
165/* The following are deprecated and should not be used anymore: */ 184/* The following are deprecated and should not be used anymore: */
166/****************************************************************/ 185/****************************************************************/
167/* ioctl for identifying and giving some info (esp. memory heap start) */ 186/* ioctl for identifying and giving some info (esp. memory heap start) */
168#define SISFB_GET_INFO_OLD _IOR('n',0xF8,__u32) 187#define SISFB_GET_INFO_OLD _IOR('n',0xF8,__u32)
169/* ioctrl to get current vertical retrace status */ 188/* ioctrl to get current vertical retrace status */
170#define SISFB_GET_VBRSTATUS_OLD _IOR('n',0xF9,__u32) 189#define SISFB_GET_VBRSTATUS_OLD _IOR('n',0xF9,__u32)
171/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */ 190/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
@@ -177,8 +196,8 @@ struct _SISFB_INFO {
177 196
178/* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */ 197/* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */
179struct sis_memreq { 198struct sis_memreq {
180 __u32 offset; 199 __u32 offset;
181 __u32 size; 200 __u32 size;
182}; 201};
183 202
184/**********************************************/ 203/**********************************************/
@@ -187,12 +206,19 @@ struct sis_memreq {
187/**********************************************/ 206/**********************************************/
188 207
189#ifdef __KERNEL__ 208#ifdef __KERNEL__
209
210#include <linux/pci.h>
211
190#define UNKNOWN_VGA 0 212#define UNKNOWN_VGA 0
191#define SIS_300_VGA 1 213#define SIS_300_VGA 1
192#define SIS_315_VGA 2 214#define SIS_315_VGA 2
193 215
216#define SISFB_HAVE_MALLOC_NEW
194extern void sis_malloc(struct sis_memreq *req); 217extern void sis_malloc(struct sis_memreq *req);
218extern void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
219
195extern void sis_free(u32 base); 220extern void sis_free(u32 base);
221extern void sis_free_new(struct pci_dev *pdev, u32 base);
196#endif 222#endif
197 223
198#endif 224#endif
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 1f06e7690106..712d02029971 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -972,6 +972,10 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
972 *s++ = '\n'; 972 *s++ = '\n';
973 *s = '\0'; 973 *s = '\0';
974 974
975 /* Do nothing if *ppos is at the eof or beyond the eof. */
976 if (s - page <= *ppos)
977 return 0;
978
975 start = page + *ppos; 979 start = page + *ppos;
976 n = s - start; 980 n = s - start;
977 retval = n - copy_to_user(buf, start, min(n, nbytes)); 981 retval = n - copy_to_user(buf, start, min(n, nbytes));
diff --git a/kernel/exit.c b/kernel/exit.c
index 5b0fb9f09f21..6d2089a1bce7 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -368,17 +368,19 @@ EXPORT_SYMBOL(daemonize);
368static inline void close_files(struct files_struct * files) 368static inline void close_files(struct files_struct * files)
369{ 369{
370 int i, j; 370 int i, j;
371 struct fdtable *fdt;
371 372
372 j = 0; 373 j = 0;
374 fdt = files_fdtable(files);
373 for (;;) { 375 for (;;) {
374 unsigned long set; 376 unsigned long set;
375 i = j * __NFDBITS; 377 i = j * __NFDBITS;
376 if (i >= files->max_fdset || i >= files->max_fds) 378 if (i >= fdt->max_fdset || i >= fdt->max_fds)
377 break; 379 break;
378 set = files->open_fds->fds_bits[j++]; 380 set = fdt->open_fds->fds_bits[j++];
379 while (set) { 381 while (set) {
380 if (set & 1) { 382 if (set & 1) {
381 struct file * file = xchg(&files->fd[i], NULL); 383 struct file * file = xchg(&fdt->fd[i], NULL);
382 if (file) 384 if (file)
383 filp_close(file, files); 385 filp_close(file, files);
384 } 386 }
@@ -403,18 +405,22 @@ struct files_struct *get_files_struct(struct task_struct *task)
403 405
404void fastcall put_files_struct(struct files_struct *files) 406void fastcall put_files_struct(struct files_struct *files)
405{ 407{
408 struct fdtable *fdt;
409
406 if (atomic_dec_and_test(&files->count)) { 410 if (atomic_dec_and_test(&files->count)) {
407 close_files(files); 411 close_files(files);
408 /* 412 /*
409 * Free the fd and fdset arrays if we expanded them. 413 * Free the fd and fdset arrays if we expanded them.
414 * If the fdtable was embedded, pass files for freeing
415 * at the end of the RCU grace period. Otherwise,
416 * you can free files immediately.
410 */ 417 */
411 if (files->fd != &files->fd_array[0]) 418 fdt = files_fdtable(files);
412 free_fd_array(files->fd, files->max_fds); 419 if (fdt == &files->fdtab)
413 if (files->max_fdset > __FD_SETSIZE) { 420 fdt->free_files = files;
414 free_fdset(files->open_fds, files->max_fdset); 421 else
415 free_fdset(files->close_on_exec, files->max_fdset); 422 kmem_cache_free(files_cachep, files);
416 } 423 free_fdtable(fdt);
417 kmem_cache_free(files_cachep, files);
418 } 424 }
419} 425}
420 426
diff --git a/kernel/fork.c b/kernel/fork.c
index 7e1ead9a6ba4..8149f3602881 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -35,6 +35,7 @@
35#include <linux/syscalls.h> 35#include <linux/syscalls.h>
36#include <linux/jiffies.h> 36#include <linux/jiffies.h>
37#include <linux/futex.h> 37#include <linux/futex.h>
38#include <linux/rcupdate.h>
38#include <linux/ptrace.h> 39#include <linux/ptrace.h>
39#include <linux/mount.h> 40#include <linux/mount.h>
40#include <linux/audit.h> 41#include <linux/audit.h>
@@ -176,6 +177,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
176 177
177 /* One for us, one for whoever does the "release_task()" (usually parent) */ 178 /* One for us, one for whoever does the "release_task()" (usually parent) */
178 atomic_set(&tsk->usage,2); 179 atomic_set(&tsk->usage,2);
180 atomic_set(&tsk->fs_excl, 0);
179 return tsk; 181 return tsk;
180} 182}
181 183
@@ -564,24 +566,53 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
564 return 0; 566 return 0;
565} 567}
566 568
567static int count_open_files(struct files_struct *files, int size) 569static int count_open_files(struct fdtable *fdt)
568{ 570{
571 int size = fdt->max_fdset;
569 int i; 572 int i;
570 573
571 /* Find the last open fd */ 574 /* Find the last open fd */
572 for (i = size/(8*sizeof(long)); i > 0; ) { 575 for (i = size/(8*sizeof(long)); i > 0; ) {
573 if (files->open_fds->fds_bits[--i]) 576 if (fdt->open_fds->fds_bits[--i])
574 break; 577 break;
575 } 578 }
576 i = (i+1) * 8 * sizeof(long); 579 i = (i+1) * 8 * sizeof(long);
577 return i; 580 return i;
578} 581}
579 582
583static struct files_struct *alloc_files(void)
584{
585 struct files_struct *newf;
586 struct fdtable *fdt;
587
588 newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
589 if (!newf)
590 goto out;
591
592 atomic_set(&newf->count, 1);
593
594 spin_lock_init(&newf->file_lock);
595 fdt = &newf->fdtab;
596 fdt->next_fd = 0;
597 fdt->max_fds = NR_OPEN_DEFAULT;
598 fdt->max_fdset = __FD_SETSIZE;
599 fdt->close_on_exec = &newf->close_on_exec_init;
600 fdt->open_fds = &newf->open_fds_init;
601 fdt->fd = &newf->fd_array[0];
602 INIT_RCU_HEAD(&fdt->rcu);
603 fdt->free_files = NULL;
604 fdt->next = NULL;
605 rcu_assign_pointer(newf->fdt, fdt);
606out:
607 return newf;
608}
609
580static int copy_files(unsigned long clone_flags, struct task_struct * tsk) 610static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
581{ 611{
582 struct files_struct *oldf, *newf; 612 struct files_struct *oldf, *newf;
583 struct file **old_fds, **new_fds; 613 struct file **old_fds, **new_fds;
584 int open_files, size, i, error = 0, expand; 614 int open_files, size, i, error = 0, expand;
615 struct fdtable *old_fdt, *new_fdt;
585 616
586 /* 617 /*
587 * A background process may not have any files ... 618 * A background process may not have any files ...
@@ -602,35 +633,27 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
602 */ 633 */
603 tsk->files = NULL; 634 tsk->files = NULL;
604 error = -ENOMEM; 635 error = -ENOMEM;
605 newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL); 636 newf = alloc_files();
606 if (!newf) 637 if (!newf)
607 goto out; 638 goto out;
608 639
609 atomic_set(&newf->count, 1);
610
611 spin_lock_init(&newf->file_lock);
612 newf->next_fd = 0;
613 newf->max_fds = NR_OPEN_DEFAULT;
614 newf->max_fdset = __FD_SETSIZE;
615 newf->close_on_exec = &newf->close_on_exec_init;
616 newf->open_fds = &newf->open_fds_init;
617 newf->fd = &newf->fd_array[0];
618
619 spin_lock(&oldf->file_lock); 640 spin_lock(&oldf->file_lock);
620 641 old_fdt = files_fdtable(oldf);
621 open_files = count_open_files(oldf, oldf->max_fdset); 642 new_fdt = files_fdtable(newf);
643 size = old_fdt->max_fdset;
644 open_files = count_open_files(old_fdt);
622 expand = 0; 645 expand = 0;
623 646
624 /* 647 /*
625 * Check whether we need to allocate a larger fd array or fd set. 648 * Check whether we need to allocate a larger fd array or fd set.
626 * Note: we're not a clone task, so the open count won't change. 649 * Note: we're not a clone task, so the open count won't change.
627 */ 650 */
628 if (open_files > newf->max_fdset) { 651 if (open_files > new_fdt->max_fdset) {
629 newf->max_fdset = 0; 652 new_fdt->max_fdset = 0;
630 expand = 1; 653 expand = 1;
631 } 654 }
632 if (open_files > newf->max_fds) { 655 if (open_files > new_fdt->max_fds) {
633 newf->max_fds = 0; 656 new_fdt->max_fds = 0;
634 expand = 1; 657 expand = 1;
635 } 658 }
636 659
@@ -642,14 +665,21 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
642 spin_unlock(&newf->file_lock); 665 spin_unlock(&newf->file_lock);
643 if (error < 0) 666 if (error < 0)
644 goto out_release; 667 goto out_release;
668 new_fdt = files_fdtable(newf);
669 /*
670 * Reacquire the oldf lock and a pointer to its fd table
671 * who knows it may have a new bigger fd table. We need
672 * the latest pointer.
673 */
645 spin_lock(&oldf->file_lock); 674 spin_lock(&oldf->file_lock);
675 old_fdt = files_fdtable(oldf);
646 } 676 }
647 677
648 old_fds = oldf->fd; 678 old_fds = old_fdt->fd;
649 new_fds = newf->fd; 679 new_fds = new_fdt->fd;
650 680
651 memcpy(newf->open_fds->fds_bits, oldf->open_fds->fds_bits, open_files/8); 681 memcpy(new_fdt->open_fds->fds_bits, old_fdt->open_fds->fds_bits, open_files/8);
652 memcpy(newf->close_on_exec->fds_bits, oldf->close_on_exec->fds_bits, open_files/8); 682 memcpy(new_fdt->close_on_exec->fds_bits, old_fdt->close_on_exec->fds_bits, open_files/8);
653 683
654 for (i = open_files; i != 0; i--) { 684 for (i = open_files; i != 0; i--) {
655 struct file *f = *old_fds++; 685 struct file *f = *old_fds++;
@@ -662,24 +692,24 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
662 * is partway through open(). So make sure that this 692 * is partway through open(). So make sure that this
663 * fd is available to the new process. 693 * fd is available to the new process.
664 */ 694 */
665 FD_CLR(open_files - i, newf->open_fds); 695 FD_CLR(open_files - i, new_fdt->open_fds);
666 } 696 }
667 *new_fds++ = f; 697 rcu_assign_pointer(*new_fds++, f);
668 } 698 }
669 spin_unlock(&oldf->file_lock); 699 spin_unlock(&oldf->file_lock);
670 700
671 /* compute the remainder to be cleared */ 701 /* compute the remainder to be cleared */
672 size = (newf->max_fds - open_files) * sizeof(struct file *); 702 size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
673 703
674 /* This is long word aligned thus could use a optimized version */ 704 /* This is long word aligned thus could use a optimized version */
675 memset(new_fds, 0, size); 705 memset(new_fds, 0, size);
676 706
677 if (newf->max_fdset > open_files) { 707 if (new_fdt->max_fdset > open_files) {
678 int left = (newf->max_fdset-open_files)/8; 708 int left = (new_fdt->max_fdset-open_files)/8;
679 int start = open_files / (8 * sizeof(unsigned long)); 709 int start = open_files / (8 * sizeof(unsigned long));
680 710
681 memset(&newf->open_fds->fds_bits[start], 0, left); 711 memset(&new_fdt->open_fds->fds_bits[start], 0, left);
682 memset(&newf->close_on_exec->fds_bits[start], 0, left); 712 memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
683 } 713 }
684 714
685 tsk->files = newf; 715 tsk->files = newf;
@@ -688,9 +718,9 @@ out:
688 return error; 718 return error;
689 719
690out_release: 720out_release:
691 free_fdset (newf->close_on_exec, newf->max_fdset); 721 free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
692 free_fdset (newf->open_fds, newf->max_fdset); 722 free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
693 free_fd_array(newf->fd, newf->max_fds); 723 free_fd_array(new_fdt->fd, new_fdt->max_fds);
694 kmem_cache_free(files_cachep, newf); 724 kmem_cache_free(files_cachep, newf);
695 goto out; 725 goto out;
696} 726}
@@ -1115,6 +1145,9 @@ static task_t *copy_process(unsigned long clone_flags,
1115 __get_cpu_var(process_counts)++; 1145 __get_cpu_var(process_counts)++;
1116 } 1146 }
1117 1147
1148 if (!current->signal->tty && p->signal->tty)
1149 p->signal->tty = NULL;
1150
1118 nr_threads++; 1151 nr_threads++;
1119 total_forks++; 1152 total_forks++;
1120 write_unlock_irq(&tasklist_lock); 1153 write_unlock_irq(&tasklist_lock);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index f436993bd590..bef3b6901b76 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -45,6 +45,7 @@
45#include <linux/percpu.h> 45#include <linux/percpu.h>
46#include <linux/notifier.h> 46#include <linux/notifier.h>
47#include <linux/rcupdate.h> 47#include <linux/rcupdate.h>
48#include <linux/rcuref.h>
48#include <linux/cpu.h> 49#include <linux/cpu.h>
49 50
50/* Definition for rcupdate control block. */ 51/* Definition for rcupdate control block. */
@@ -72,6 +73,19 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
72static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; 73static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
73static int maxbatch = 10; 74static int maxbatch = 10;
74 75
76#ifndef __HAVE_ARCH_CMPXCHG
77/*
78 * We use an array of spinlocks for the rcurefs -- similar to ones in sparc
79 * 32 bit atomic_t implementations, and a hash function similar to that
80 * for our refcounting needs.
81 * Can't help multiprocessors which donot have cmpxchg :(
82 */
83
84spinlock_t __rcuref_hash[RCUREF_HASH_SIZE] = {
85 [0 ... (RCUREF_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
86};
87#endif
88
75/** 89/**
76 * call_rcu - Queue an RCU callback for invocation after a grace period. 90 * call_rcu - Queue an RCU callback for invocation after a grace period.
77 * @head: structure to be used for queueing the RCU updates. 91 * @head: structure to be used for queueing the RCU updates.
diff --git a/kernel/sched.c b/kernel/sched.c
index 18b95520a2e2..2632b812cf24 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2888,6 +2888,7 @@ switch_tasks:
2888 if (next == rq->idle) 2888 if (next == rq->idle)
2889 schedstat_inc(rq, sched_goidle); 2889 schedstat_inc(rq, sched_goidle);
2890 prefetch(next); 2890 prefetch(next);
2891 prefetch_stack(next);
2891 clear_tsk_need_resched(prev); 2892 clear_tsk_need_resched(prev);
2892 rcu_qsctr_inc(task_cpu(prev)); 2893 rcu_qsctr_inc(task_cpu(prev));
2893 2894
diff --git a/lib/Kconfig b/lib/Kconfig
index e43197efeb9c..3de93357f5ab 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -12,6 +12,14 @@ config CRC_CCITT
12 the kernel tree does. Such modules that use library CRC-CCITT 12 the kernel tree does. Such modules that use library CRC-CCITT
13 functions require M here. 13 functions require M here.
14 14
15config CRC16
16 tristate "CRC16 functions"
17 help
18 This option is provided for the case where no in-kernel-tree
19 modules require CRC16 functions, but a module built outside
20 the kernel tree does. Such modules that use library CRC16
21 functions require M here.
22
15config CRC32 23config CRC32
16 tristate "CRC32 functions" 24 tristate "CRC32 functions"
17 default y 25 default y
diff --git a/lib/Makefile b/lib/Makefile
index 3e2bd0df23bb..d9c38ba05e7b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -23,11 +23,12 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
23obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o 23obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
24obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o 24obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
25 25
26ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 26ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
27 lib-y += dec_and_lock.o 27 lib-y += dec_and_lock.o
28endif 28endif
29 29
30obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o 30obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
31obj-$(CONFIG_CRC16) += crc16.o
31obj-$(CONFIG_CRC32) += crc32.o 32obj-$(CONFIG_CRC32) += crc32.o
32obj-$(CONFIG_LIBCRC32C) += libcrc32c.o 33obj-$(CONFIG_LIBCRC32C) += libcrc32c.o
33obj-$(CONFIG_GENERIC_IOMAP) += iomap.o 34obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
diff --git a/lib/crc16.c b/lib/crc16.c
new file mode 100644
index 000000000000..011fe573c666
--- /dev/null
+++ b/lib/crc16.c
@@ -0,0 +1,67 @@
1/*
2 * crc16.c
3 *
4 * This source code is licensed under the GNU General Public License,
5 * Version 2. See the file COPYING for more details.
6 */
7
8#include <linux/types.h>
9#include <linux/module.h>
10#include <linux/crc16.h>
11
12/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
13u16 const crc16_table[256] = {
14 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
15 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
16 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
17 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
18 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
19 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
20 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
21 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
22 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
23 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
24 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
25 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
26 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
27 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
28 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
29 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
30 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
31 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
32 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
33 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
34 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
35 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
36 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
37 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
38 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
39 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
40 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
41 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
42 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
43 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
44 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
45 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
46};
47EXPORT_SYMBOL(crc16_table);
48
49/**
50 * Compute the CRC-16 for the data buffer
51 *
52 * @param crc previous CRC value
53 * @param buffer data pointer
54 * @param len number of bytes in the buffer
55 * @return the updated CRC value
56 */
57u16 crc16(u16 crc, u8 const *buffer, size_t len)
58{
59 while (len--)
60 crc = crc16_byte(crc, *buffer++);
61 return crc;
62}
63EXPORT_SYMBOL(crc16);
64
65MODULE_DESCRIPTION("CRC16 calculations");
66MODULE_LICENSE("GPL");
67
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 13492d66b7c8..afa06e184d88 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -88,7 +88,7 @@ static kmem_cache_t *sn_cache;
88 policied. */ 88 policied. */
89static int policy_zone; 89static int policy_zone;
90 90
91static struct mempolicy default_policy = { 91struct mempolicy default_policy = {
92 .refcnt = ATOMIC_INIT(1), /* never free it */ 92 .refcnt = ATOMIC_INIT(1), /* never free it */
93 .policy = MPOL_DEFAULT, 93 .policy = MPOL_DEFAULT,
94}; 94};
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a6329fa8f862..0166ea15c9ee 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -368,10 +368,8 @@ int wakeup_pdflush(long nr_pages)
368static void wb_timer_fn(unsigned long unused); 368static void wb_timer_fn(unsigned long unused);
369static void laptop_timer_fn(unsigned long unused); 369static void laptop_timer_fn(unsigned long unused);
370 370
371static struct timer_list wb_timer = 371static DEFINE_TIMER(wb_timer, wb_timer_fn, 0, 0);
372 TIMER_INITIALIZER(wb_timer_fn, 0, 0); 372static DEFINE_TIMER(laptop_mode_wb_timer, laptop_timer_fn, 0, 0);
373static struct timer_list laptop_mode_wb_timer =
374 TIMER_INITIALIZER(laptop_timer_fn, 0, 0);
375 373
376/* 374/*
377 * Periodic writeback of "old" data. 375 * Periodic writeback of "old" data.
diff --git a/mm/shmem.c b/mm/shmem.c
index db2c9e8d9909..1f7aeb210c7b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -666,6 +666,7 @@ static void shmem_delete_inode(struct inode *inode)
666 struct shmem_inode_info *info = SHMEM_I(inode); 666 struct shmem_inode_info *info = SHMEM_I(inode);
667 667
668 if (inode->i_op->truncate == shmem_truncate) { 668 if (inode->i_op->truncate == shmem_truncate) {
669 truncate_inode_pages(inode->i_mapping, 0);
669 shmem_unacct_size(info->flags, inode->i_size); 670 shmem_unacct_size(info->flags, inode->i_size);
670 inode->i_size = 0; 671 inode->i_size = 0;
671 shmem_truncate(inode); 672 shmem_truncate(inode);
@@ -1607,6 +1608,15 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1607 int error = -ENOSPC; 1608 int error = -ENOSPC;
1608 1609
1609 if (inode) { 1610 if (inode) {
1611 error = security_inode_init_security(inode, dir, NULL, NULL,
1612 NULL);
1613 if (error) {
1614 if (error != -EOPNOTSUPP) {
1615 iput(inode);
1616 return error;
1617 }
1618 error = 0;
1619 }
1610 if (dir->i_mode & S_ISGID) { 1620 if (dir->i_mode & S_ISGID) {
1611 inode->i_gid = dir->i_gid; 1621 inode->i_gid = dir->i_gid;
1612 if (S_ISDIR(mode)) 1622 if (S_ISDIR(mode))
@@ -1616,7 +1626,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1616 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1626 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1617 d_instantiate(dentry, inode); 1627 d_instantiate(dentry, inode);
1618 dget(dentry); /* Extra count - pin the dentry in core */ 1628 dget(dentry); /* Extra count - pin the dentry in core */
1619 error = 0;
1620 } 1629 }
1621 return error; 1630 return error;
1622} 1631}
@@ -1746,6 +1755,16 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1746 if (!inode) 1755 if (!inode)
1747 return -ENOSPC; 1756 return -ENOSPC;
1748 1757
1758 error = security_inode_init_security(inode, dir, NULL, NULL,
1759 NULL);
1760 if (error) {
1761 if (error != -EOPNOTSUPP) {
1762 iput(inode);
1763 return error;
1764 }
1765 error = 0;
1766 }
1767
1749 info = SHMEM_I(inode); 1768 info = SHMEM_I(inode);
1750 inode->i_size = len-1; 1769 inode->i_size = len-1;
1751 if (len <= (char *)inode - (char *)info) { 1770 if (len <= (char *)inode - (char *)info) {
diff --git a/mm/slab.c b/mm/slab.c
index d7c4443991fe..05a391059fe1 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -75,6 +75,15 @@
75 * 75 *
76 * At present, each engine can be growing a cache. This should be blocked. 76 * At present, each engine can be growing a cache. This should be blocked.
77 * 77 *
78 * 15 March 2005. NUMA slab allocator.
79 * Shai Fultheim <shai@scalex86.org>.
80 * Shobhit Dayal <shobhit@calsoftinc.com>
81 * Alok N Kataria <alokk@calsoftinc.com>
82 * Christoph Lameter <christoph@lameter.com>
83 *
84 * Modified the slab allocator to be node aware on NUMA systems.
85 * Each node has its own list of partial, free and full slabs.
86 * All object allocations for a node occur from node specific slab lists.
78 */ 87 */
79 88
80#include <linux/config.h> 89#include <linux/config.h>
@@ -93,6 +102,7 @@
93#include <linux/module.h> 102#include <linux/module.h>
94#include <linux/rcupdate.h> 103#include <linux/rcupdate.h>
95#include <linux/string.h> 104#include <linux/string.h>
105#include <linux/nodemask.h>
96 106
97#include <asm/uaccess.h> 107#include <asm/uaccess.h>
98#include <asm/cacheflush.h> 108#include <asm/cacheflush.h>
@@ -212,6 +222,7 @@ struct slab {
212 void *s_mem; /* including colour offset */ 222 void *s_mem; /* including colour offset */
213 unsigned int inuse; /* num of objs active in slab */ 223 unsigned int inuse; /* num of objs active in slab */
214 kmem_bufctl_t free; 224 kmem_bufctl_t free;
225 unsigned short nodeid;
215}; 226};
216 227
217/* 228/*
@@ -239,7 +250,6 @@ struct slab_rcu {
239/* 250/*
240 * struct array_cache 251 * struct array_cache
241 * 252 *
242 * Per cpu structures
243 * Purpose: 253 * Purpose:
244 * - LIFO ordering, to hand out cache-warm objects from _alloc 254 * - LIFO ordering, to hand out cache-warm objects from _alloc
245 * - reduce the number of linked list operations 255 * - reduce the number of linked list operations
@@ -254,6 +264,13 @@ struct array_cache {
254 unsigned int limit; 264 unsigned int limit;
255 unsigned int batchcount; 265 unsigned int batchcount;
256 unsigned int touched; 266 unsigned int touched;
267 spinlock_t lock;
268 void *entry[0]; /*
269 * Must have this definition in here for the proper
270 * alignment of array_cache. Also simplifies accessing
271 * the entries.
272 * [0] is for gcc 2.95. It should really be [].
273 */
257}; 274};
258 275
259/* bootstrap: The caches do not work without cpuarrays anymore, 276/* bootstrap: The caches do not work without cpuarrays anymore,
@@ -266,34 +283,83 @@ struct arraycache_init {
266}; 283};
267 284
268/* 285/*
269 * The slab lists of all objects. 286 * The slab lists for all objects.
270 * Hopefully reduce the internal fragmentation
271 * NUMA: The spinlock could be moved from the kmem_cache_t
272 * into this structure, too. Figure out what causes
273 * fewer cross-node spinlock operations.
274 */ 287 */
275struct kmem_list3 { 288struct kmem_list3 {
276 struct list_head slabs_partial; /* partial list first, better asm code */ 289 struct list_head slabs_partial; /* partial list first, better asm code */
277 struct list_head slabs_full; 290 struct list_head slabs_full;
278 struct list_head slabs_free; 291 struct list_head slabs_free;
279 unsigned long free_objects; 292 unsigned long free_objects;
280 int free_touched;
281 unsigned long next_reap; 293 unsigned long next_reap;
282 struct array_cache *shared; 294 int free_touched;
295 unsigned int free_limit;
296 spinlock_t list_lock;
297 struct array_cache *shared; /* shared per node */
298 struct array_cache **alien; /* on other nodes */
283}; 299};
284 300
285#define LIST3_INIT(parent) \ 301/*
286 { \ 302 * Need this for bootstrapping a per node allocator.
287 .slabs_full = LIST_HEAD_INIT(parent.slabs_full), \ 303 */
288 .slabs_partial = LIST_HEAD_INIT(parent.slabs_partial), \ 304#define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
289 .slabs_free = LIST_HEAD_INIT(parent.slabs_free) \ 305struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
306#define CACHE_CACHE 0
307#define SIZE_AC 1
308#define SIZE_L3 (1 + MAX_NUMNODES)
309
310/*
311 * This function may be completely optimized away if
312 * a constant is passed to it. Mostly the same as
313 * what is in linux/slab.h except it returns an
314 * index.
315 */
316static inline int index_of(const size_t size)
317{
318 if (__builtin_constant_p(size)) {
319 int i = 0;
320
321#define CACHE(x) \
322 if (size <=x) \
323 return i; \
324 else \
325 i++;
326#include "linux/kmalloc_sizes.h"
327#undef CACHE
328 {
329 extern void __bad_size(void);
330 __bad_size();
331 }
290 } 332 }
291#define list3_data(cachep) \ 333 return 0;
292 (&(cachep)->lists) 334}
335
336#define INDEX_AC index_of(sizeof(struct arraycache_init))
337#define INDEX_L3 index_of(sizeof(struct kmem_list3))
338
339static inline void kmem_list3_init(struct kmem_list3 *parent)
340{
341 INIT_LIST_HEAD(&parent->slabs_full);
342 INIT_LIST_HEAD(&parent->slabs_partial);
343 INIT_LIST_HEAD(&parent->slabs_free);
344 parent->shared = NULL;
345 parent->alien = NULL;
346 spin_lock_init(&parent->list_lock);
347 parent->free_objects = 0;
348 parent->free_touched = 0;
349}
293 350
294/* NUMA: per-node */ 351#define MAKE_LIST(cachep, listp, slab, nodeid) \
295#define list3_data_ptr(cachep, ptr) \ 352 do { \
296 list3_data(cachep) 353 INIT_LIST_HEAD(listp); \
354 list_splice(&(cachep->nodelists[nodeid]->slab), listp); \
355 } while (0)
356
357#define MAKE_ALL_LISTS(cachep, ptr, nodeid) \
358 do { \
359 MAKE_LIST((cachep), (&(ptr)->slabs_full), slabs_full, nodeid); \
360 MAKE_LIST((cachep), (&(ptr)->slabs_partial), slabs_partial, nodeid); \
361 MAKE_LIST((cachep), (&(ptr)->slabs_free), slabs_free, nodeid); \
362 } while (0)
297 363
298/* 364/*
299 * kmem_cache_t 365 * kmem_cache_t
@@ -306,13 +372,12 @@ struct kmem_cache_s {
306 struct array_cache *array[NR_CPUS]; 372 struct array_cache *array[NR_CPUS];
307 unsigned int batchcount; 373 unsigned int batchcount;
308 unsigned int limit; 374 unsigned int limit;
309/* 2) touched by every alloc & free from the backend */ 375 unsigned int shared;
310 struct kmem_list3 lists;
311 /* NUMA: kmem_3list_t *nodelists[MAX_NUMNODES] */
312 unsigned int objsize; 376 unsigned int objsize;
377/* 2) touched by every alloc & free from the backend */
378 struct kmem_list3 *nodelists[MAX_NUMNODES];
313 unsigned int flags; /* constant flags */ 379 unsigned int flags; /* constant flags */
314 unsigned int num; /* # of objs per slab */ 380 unsigned int num; /* # of objs per slab */
315 unsigned int free_limit; /* upper limit of objects in the lists */
316 spinlock_t spinlock; 381 spinlock_t spinlock;
317 382
318/* 3) cache_grow/shrink */ 383/* 3) cache_grow/shrink */
@@ -349,6 +414,7 @@ struct kmem_cache_s {
349 unsigned long errors; 414 unsigned long errors;
350 unsigned long max_freeable; 415 unsigned long max_freeable;
351 unsigned long node_allocs; 416 unsigned long node_allocs;
417 unsigned long node_frees;
352 atomic_t allochit; 418 atomic_t allochit;
353 atomic_t allocmiss; 419 atomic_t allocmiss;
354 atomic_t freehit; 420 atomic_t freehit;
@@ -384,6 +450,7 @@ struct kmem_cache_s {
384 } while (0) 450 } while (0)
385#define STATS_INC_ERR(x) ((x)->errors++) 451#define STATS_INC_ERR(x) ((x)->errors++)
386#define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++) 452#define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++)
453#define STATS_INC_NODEFREES(x) ((x)->node_frees++)
387#define STATS_SET_FREEABLE(x, i) \ 454#define STATS_SET_FREEABLE(x, i) \
388 do { if ((x)->max_freeable < i) \ 455 do { if ((x)->max_freeable < i) \
389 (x)->max_freeable = i; \ 456 (x)->max_freeable = i; \
@@ -402,6 +469,7 @@ struct kmem_cache_s {
402#define STATS_SET_HIGH(x) do { } while (0) 469#define STATS_SET_HIGH(x) do { } while (0)
403#define STATS_INC_ERR(x) do { } while (0) 470#define STATS_INC_ERR(x) do { } while (0)
404#define STATS_INC_NODEALLOCS(x) do { } while (0) 471#define STATS_INC_NODEALLOCS(x) do { } while (0)
472#define STATS_INC_NODEFREES(x) do { } while (0)
405#define STATS_SET_FREEABLE(x, i) \ 473#define STATS_SET_FREEABLE(x, i) \
406 do { } while (0) 474 do { } while (0)
407 475
@@ -534,9 +602,9 @@ static struct arraycache_init initarray_generic =
534 602
535/* internal cache of cache description objs */ 603/* internal cache of cache description objs */
536static kmem_cache_t cache_cache = { 604static kmem_cache_t cache_cache = {
537 .lists = LIST3_INIT(cache_cache.lists),
538 .batchcount = 1, 605 .batchcount = 1,
539 .limit = BOOT_CPUCACHE_ENTRIES, 606 .limit = BOOT_CPUCACHE_ENTRIES,
607 .shared = 1,
540 .objsize = sizeof(kmem_cache_t), 608 .objsize = sizeof(kmem_cache_t),
541 .flags = SLAB_NO_REAP, 609 .flags = SLAB_NO_REAP,
542 .spinlock = SPIN_LOCK_UNLOCKED, 610 .spinlock = SPIN_LOCK_UNLOCKED,
@@ -557,7 +625,6 @@ static struct list_head cache_chain;
557 * SLAB_RECLAIM_ACCOUNT turns this on per-slab 625 * SLAB_RECLAIM_ACCOUNT turns this on per-slab
558 */ 626 */
559atomic_t slab_reclaim_pages; 627atomic_t slab_reclaim_pages;
560EXPORT_SYMBOL(slab_reclaim_pages);
561 628
562/* 629/*
563 * chicken and egg problem: delay the per-cpu array allocation 630 * chicken and egg problem: delay the per-cpu array allocation
@@ -565,7 +632,8 @@ EXPORT_SYMBOL(slab_reclaim_pages);
565 */ 632 */
566static enum { 633static enum {
567 NONE, 634 NONE,
568 PARTIAL, 635 PARTIAL_AC,
636 PARTIAL_L3,
569 FULL 637 FULL
570} g_cpucache_up; 638} g_cpucache_up;
571 639
@@ -574,11 +642,7 @@ static DEFINE_PER_CPU(struct work_struct, reap_work);
574static void free_block(kmem_cache_t* cachep, void** objpp, int len); 642static void free_block(kmem_cache_t* cachep, void** objpp, int len);
575static void enable_cpucache (kmem_cache_t *cachep); 643static void enable_cpucache (kmem_cache_t *cachep);
576static void cache_reap (void *unused); 644static void cache_reap (void *unused);
577 645static int __node_shrink(kmem_cache_t *cachep, int node);
578static inline void **ac_entry(struct array_cache *ac)
579{
580 return (void**)(ac+1);
581}
582 646
583static inline struct array_cache *ac_data(kmem_cache_t *cachep) 647static inline struct array_cache *ac_data(kmem_cache_t *cachep)
584{ 648{
@@ -676,48 +740,160 @@ static void __devinit start_cpu_timer(int cpu)
676 } 740 }
677} 741}
678 742
679static struct array_cache *alloc_arraycache(int cpu, int entries, 743static struct array_cache *alloc_arraycache(int node, int entries,
680 int batchcount) 744 int batchcount)
681{ 745{
682 int memsize = sizeof(void*)*entries+sizeof(struct array_cache); 746 int memsize = sizeof(void*)*entries+sizeof(struct array_cache);
683 struct array_cache *nc = NULL; 747 struct array_cache *nc = NULL;
684 748
685 if (cpu == -1) 749 nc = kmalloc_node(memsize, GFP_KERNEL, node);
686 nc = kmalloc(memsize, GFP_KERNEL);
687 else
688 nc = kmalloc_node(memsize, GFP_KERNEL, cpu_to_node(cpu));
689
690 if (nc) { 750 if (nc) {
691 nc->avail = 0; 751 nc->avail = 0;
692 nc->limit = entries; 752 nc->limit = entries;
693 nc->batchcount = batchcount; 753 nc->batchcount = batchcount;
694 nc->touched = 0; 754 nc->touched = 0;
755 spin_lock_init(&nc->lock);
695 } 756 }
696 return nc; 757 return nc;
697} 758}
698 759
760#ifdef CONFIG_NUMA
761static inline struct array_cache **alloc_alien_cache(int node, int limit)
762{
763 struct array_cache **ac_ptr;
764 int memsize = sizeof(void*)*MAX_NUMNODES;
765 int i;
766
767 if (limit > 1)
768 limit = 12;
769 ac_ptr = kmalloc_node(memsize, GFP_KERNEL, node);
770 if (ac_ptr) {
771 for_each_node(i) {
772 if (i == node || !node_online(i)) {
773 ac_ptr[i] = NULL;
774 continue;
775 }
776 ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d);
777 if (!ac_ptr[i]) {
778 for (i--; i <=0; i--)
779 kfree(ac_ptr[i]);
780 kfree(ac_ptr);
781 return NULL;
782 }
783 }
784 }
785 return ac_ptr;
786}
787
788static inline void free_alien_cache(struct array_cache **ac_ptr)
789{
790 int i;
791
792 if (!ac_ptr)
793 return;
794
795 for_each_node(i)
796 kfree(ac_ptr[i]);
797
798 kfree(ac_ptr);
799}
800
801static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache *ac, int node)
802{
803 struct kmem_list3 *rl3 = cachep->nodelists[node];
804
805 if (ac->avail) {
806 spin_lock(&rl3->list_lock);
807 free_block(cachep, ac->entry, ac->avail);
808 ac->avail = 0;
809 spin_unlock(&rl3->list_lock);
810 }
811}
812
813static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
814{
815 int i=0;
816 struct array_cache *ac;
817 unsigned long flags;
818
819 for_each_online_node(i) {
820 ac = l3->alien[i];
821 if (ac) {
822 spin_lock_irqsave(&ac->lock, flags);
823 __drain_alien_cache(cachep, ac, i);
824 spin_unlock_irqrestore(&ac->lock, flags);
825 }
826 }
827}
828#else
829#define alloc_alien_cache(node, limit) do { } while (0)
830#define free_alien_cache(ac_ptr) do { } while (0)
831#define drain_alien_cache(cachep, l3) do { } while (0)
832#endif
833
699static int __devinit cpuup_callback(struct notifier_block *nfb, 834static int __devinit cpuup_callback(struct notifier_block *nfb,
700 unsigned long action, void *hcpu) 835 unsigned long action, void *hcpu)
701{ 836{
702 long cpu = (long)hcpu; 837 long cpu = (long)hcpu;
703 kmem_cache_t* cachep; 838 kmem_cache_t* cachep;
839 struct kmem_list3 *l3 = NULL;
840 int node = cpu_to_node(cpu);
841 int memsize = sizeof(struct kmem_list3);
842 struct array_cache *nc = NULL;
704 843
705 switch (action) { 844 switch (action) {
706 case CPU_UP_PREPARE: 845 case CPU_UP_PREPARE:
707 down(&cache_chain_sem); 846 down(&cache_chain_sem);
847 /* we need to do this right in the beginning since
848 * alloc_arraycache's are going to use this list.
849 * kmalloc_node allows us to add the slab to the right
850 * kmem_list3 and not this cpu's kmem_list3
851 */
852
708 list_for_each_entry(cachep, &cache_chain, next) { 853 list_for_each_entry(cachep, &cache_chain, next) {
709 struct array_cache *nc; 854 /* setup the size64 kmemlist for cpu before we can
855 * begin anything. Make sure some other cpu on this
856 * node has not already allocated this
857 */
858 if (!cachep->nodelists[node]) {
859 if (!(l3 = kmalloc_node(memsize,
860 GFP_KERNEL, node)))
861 goto bad;
862 kmem_list3_init(l3);
863 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
864 ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
865
866 cachep->nodelists[node] = l3;
867 }
868
869 spin_lock_irq(&cachep->nodelists[node]->list_lock);
870 cachep->nodelists[node]->free_limit =
871 (1 + nr_cpus_node(node)) *
872 cachep->batchcount + cachep->num;
873 spin_unlock_irq(&cachep->nodelists[node]->list_lock);
874 }
710 875
711 nc = alloc_arraycache(cpu, cachep->limit, cachep->batchcount); 876 /* Now we can go ahead with allocating the shared array's
877 & array cache's */
878 list_for_each_entry(cachep, &cache_chain, next) {
879 nc = alloc_arraycache(node, cachep->limit,
880 cachep->batchcount);
712 if (!nc) 881 if (!nc)
713 goto bad; 882 goto bad;
714
715 spin_lock_irq(&cachep->spinlock);
716 cachep->array[cpu] = nc; 883 cachep->array[cpu] = nc;
717 cachep->free_limit = (1+num_online_cpus())*cachep->batchcount
718 + cachep->num;
719 spin_unlock_irq(&cachep->spinlock);
720 884
885 l3 = cachep->nodelists[node];
886 BUG_ON(!l3);
887 if (!l3->shared) {
888 if (!(nc = alloc_arraycache(node,
889 cachep->shared*cachep->batchcount,
890 0xbaadf00d)))
891 goto bad;
892
893 /* we are serialised from CPU_DEAD or
894 CPU_UP_CANCELLED by the cpucontrol lock */
895 l3->shared = nc;
896 }
721 } 897 }
722 up(&cache_chain_sem); 898 up(&cache_chain_sem);
723 break; 899 break;
@@ -732,13 +908,51 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
732 908
733 list_for_each_entry(cachep, &cache_chain, next) { 909 list_for_each_entry(cachep, &cache_chain, next) {
734 struct array_cache *nc; 910 struct array_cache *nc;
911 cpumask_t mask;
735 912
913 mask = node_to_cpumask(node);
736 spin_lock_irq(&cachep->spinlock); 914 spin_lock_irq(&cachep->spinlock);
737 /* cpu is dead; no one can alloc from it. */ 915 /* cpu is dead; no one can alloc from it. */
738 nc = cachep->array[cpu]; 916 nc = cachep->array[cpu];
739 cachep->array[cpu] = NULL; 917 cachep->array[cpu] = NULL;
740 cachep->free_limit -= cachep->batchcount; 918 l3 = cachep->nodelists[node];
741 free_block(cachep, ac_entry(nc), nc->avail); 919
920 if (!l3)
921 goto unlock_cache;
922
923 spin_lock(&l3->list_lock);
924
925 /* Free limit for this kmem_list3 */
926 l3->free_limit -= cachep->batchcount;
927 if (nc)
928 free_block(cachep, nc->entry, nc->avail);
929
930 if (!cpus_empty(mask)) {
931 spin_unlock(&l3->list_lock);
932 goto unlock_cache;
933 }
934
935 if (l3->shared) {
936 free_block(cachep, l3->shared->entry,
937 l3->shared->avail);
938 kfree(l3->shared);
939 l3->shared = NULL;
940 }
941 if (l3->alien) {
942 drain_alien_cache(cachep, l3);
943 free_alien_cache(l3->alien);
944 l3->alien = NULL;
945 }
946
947 /* free slabs belonging to this node */
948 if (__node_shrink(cachep, node)) {
949 cachep->nodelists[node] = NULL;
950 spin_unlock(&l3->list_lock);
951 kfree(l3);
952 } else {
953 spin_unlock(&l3->list_lock);
954 }
955unlock_cache:
742 spin_unlock_irq(&cachep->spinlock); 956 spin_unlock_irq(&cachep->spinlock);
743 kfree(nc); 957 kfree(nc);
744 } 958 }
@@ -754,6 +968,25 @@ bad:
754 968
755static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 }; 969static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 };
756 970
971/*
972 * swap the static kmem_list3 with kmalloced memory
973 */
974static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list,
975 int nodeid)
976{
977 struct kmem_list3 *ptr;
978
979 BUG_ON(cachep->nodelists[nodeid] != list);
980 ptr = kmalloc_node(sizeof(struct kmem_list3), GFP_KERNEL, nodeid);
981 BUG_ON(!ptr);
982
983 local_irq_disable();
984 memcpy(ptr, list, sizeof(struct kmem_list3));
985 MAKE_ALL_LISTS(cachep, ptr, nodeid);
986 cachep->nodelists[nodeid] = ptr;
987 local_irq_enable();
988}
989
757/* Initialisation. 990/* Initialisation.
758 * Called after the gfp() functions have been enabled, and before smp_init(). 991 * Called after the gfp() functions have been enabled, and before smp_init().
759 */ 992 */
@@ -762,6 +995,13 @@ void __init kmem_cache_init(void)
762 size_t left_over; 995 size_t left_over;
763 struct cache_sizes *sizes; 996 struct cache_sizes *sizes;
764 struct cache_names *names; 997 struct cache_names *names;
998 int i;
999
1000 for (i = 0; i < NUM_INIT_LISTS; i++) {
1001 kmem_list3_init(&initkmem_list3[i]);
1002 if (i < MAX_NUMNODES)
1003 cache_cache.nodelists[i] = NULL;
1004 }
765 1005
766 /* 1006 /*
767 * Fragmentation resistance on low memory - only use bigger 1007 * Fragmentation resistance on low memory - only use bigger
@@ -770,21 +1010,24 @@ void __init kmem_cache_init(void)
770 if (num_physpages > (32 << 20) >> PAGE_SHIFT) 1010 if (num_physpages > (32 << 20) >> PAGE_SHIFT)
771 slab_break_gfp_order = BREAK_GFP_ORDER_HI; 1011 slab_break_gfp_order = BREAK_GFP_ORDER_HI;
772 1012
773
774 /* Bootstrap is tricky, because several objects are allocated 1013 /* Bootstrap is tricky, because several objects are allocated
775 * from caches that do not exist yet: 1014 * from caches that do not exist yet:
776 * 1) initialize the cache_cache cache: it contains the kmem_cache_t 1015 * 1) initialize the cache_cache cache: it contains the kmem_cache_t
777 * structures of all caches, except cache_cache itself: cache_cache 1016 * structures of all caches, except cache_cache itself: cache_cache
778 * is statically allocated. 1017 * is statically allocated.
779 * Initially an __init data area is used for the head array, it's 1018 * Initially an __init data area is used for the head array and the
780 * replaced with a kmalloc allocated array at the end of the bootstrap. 1019 * kmem_list3 structures, it's replaced with a kmalloc allocated
1020 * array at the end of the bootstrap.
781 * 2) Create the first kmalloc cache. 1021 * 2) Create the first kmalloc cache.
782 * The kmem_cache_t for the new cache is allocated normally. An __init 1022 * The kmem_cache_t for the new cache is allocated normally.
783 * data area is used for the head array. 1023 * An __init data area is used for the head array.
784 * 3) Create the remaining kmalloc caches, with minimally sized head arrays. 1024 * 3) Create the remaining kmalloc caches, with minimally sized
1025 * head arrays.
785 * 4) Replace the __init data head arrays for cache_cache and the first 1026 * 4) Replace the __init data head arrays for cache_cache and the first
786 * kmalloc cache with kmalloc allocated arrays. 1027 * kmalloc cache with kmalloc allocated arrays.
787 * 5) Resize the head arrays of the kmalloc caches to their final sizes. 1028 * 5) Replace the __init data for kmem_list3 for cache_cache and
1029 * the other cache's with kmalloc allocated memory.
1030 * 6) Resize the head arrays of the kmalloc caches to their final sizes.
788 */ 1031 */
789 1032
790 /* 1) create the cache_cache */ 1033 /* 1) create the cache_cache */
@@ -793,6 +1036,7 @@ void __init kmem_cache_init(void)
793 list_add(&cache_cache.next, &cache_chain); 1036 list_add(&cache_cache.next, &cache_chain);
794 cache_cache.colour_off = cache_line_size(); 1037 cache_cache.colour_off = cache_line_size();
795 cache_cache.array[smp_processor_id()] = &initarray_cache.cache; 1038 cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
1039 cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE];
796 1040
797 cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size()); 1041 cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size());
798 1042
@@ -810,15 +1054,33 @@ void __init kmem_cache_init(void)
810 sizes = malloc_sizes; 1054 sizes = malloc_sizes;
811 names = cache_names; 1055 names = cache_names;
812 1056
1057 /* Initialize the caches that provide memory for the array cache
1058 * and the kmem_list3 structures first.
1059 * Without this, further allocations will bug
1060 */
1061
1062 sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
1063 sizes[INDEX_AC].cs_size, ARCH_KMALLOC_MINALIGN,
1064 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
1065
1066 if (INDEX_AC != INDEX_L3)
1067 sizes[INDEX_L3].cs_cachep =
1068 kmem_cache_create(names[INDEX_L3].name,
1069 sizes[INDEX_L3].cs_size, ARCH_KMALLOC_MINALIGN,
1070 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
1071
813 while (sizes->cs_size != ULONG_MAX) { 1072 while (sizes->cs_size != ULONG_MAX) {
814 /* For performance, all the general caches are L1 aligned. 1073 /*
1074 * For performance, all the general caches are L1 aligned.
815 * This should be particularly beneficial on SMP boxes, as it 1075 * This should be particularly beneficial on SMP boxes, as it
816 * eliminates "false sharing". 1076 * eliminates "false sharing".
817 * Note for systems short on memory removing the alignment will 1077 * Note for systems short on memory removing the alignment will
818 * allow tighter packing of the smaller caches. */ 1078 * allow tighter packing of the smaller caches.
819 sizes->cs_cachep = kmem_cache_create(names->name, 1079 */
820 sizes->cs_size, ARCH_KMALLOC_MINALIGN, 1080 if(!sizes->cs_cachep)
821 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL); 1081 sizes->cs_cachep = kmem_cache_create(names->name,
1082 sizes->cs_size, ARCH_KMALLOC_MINALIGN,
1083 (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
822 1084
823 /* Inc off-slab bufctl limit until the ceiling is hit. */ 1085 /* Inc off-slab bufctl limit until the ceiling is hit. */
824 if (!(OFF_SLAB(sizes->cs_cachep))) { 1086 if (!(OFF_SLAB(sizes->cs_cachep))) {
@@ -837,24 +1099,47 @@ void __init kmem_cache_init(void)
837 /* 4) Replace the bootstrap head arrays */ 1099 /* 4) Replace the bootstrap head arrays */
838 { 1100 {
839 void * ptr; 1101 void * ptr;
840 1102
841 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); 1103 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
1104
842 local_irq_disable(); 1105 local_irq_disable();
843 BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache); 1106 BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
844 memcpy(ptr, ac_data(&cache_cache), sizeof(struct arraycache_init)); 1107 memcpy(ptr, ac_data(&cache_cache),
1108 sizeof(struct arraycache_init));
845 cache_cache.array[smp_processor_id()] = ptr; 1109 cache_cache.array[smp_processor_id()] = ptr;
846 local_irq_enable(); 1110 local_irq_enable();
847 1111
848 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL); 1112 ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
1113
849 local_irq_disable(); 1114 local_irq_disable();
850 BUG_ON(ac_data(malloc_sizes[0].cs_cachep) != &initarray_generic.cache); 1115 BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
851 memcpy(ptr, ac_data(malloc_sizes[0].cs_cachep), 1116 != &initarray_generic.cache);
1117 memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
852 sizeof(struct arraycache_init)); 1118 sizeof(struct arraycache_init));
853 malloc_sizes[0].cs_cachep->array[smp_processor_id()] = ptr; 1119 malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
1120 ptr;
854 local_irq_enable(); 1121 local_irq_enable();
855 } 1122 }
1123 /* 5) Replace the bootstrap kmem_list3's */
1124 {
1125 int node;
1126 /* Replace the static kmem_list3 structures for the boot cpu */
1127 init_list(&cache_cache, &initkmem_list3[CACHE_CACHE],
1128 numa_node_id());
1129
1130 for_each_online_node(node) {
1131 init_list(malloc_sizes[INDEX_AC].cs_cachep,
1132 &initkmem_list3[SIZE_AC+node], node);
1133
1134 if (INDEX_AC != INDEX_L3) {
1135 init_list(malloc_sizes[INDEX_L3].cs_cachep,
1136 &initkmem_list3[SIZE_L3+node],
1137 node);
1138 }
1139 }
1140 }
856 1141
857 /* 5) resize the head arrays to their final sizes */ 1142 /* 6) resize the head arrays to their final sizes */
858 { 1143 {
859 kmem_cache_t *cachep; 1144 kmem_cache_t *cachep;
860 down(&cache_chain_sem); 1145 down(&cache_chain_sem);
@@ -870,7 +1155,6 @@ void __init kmem_cache_init(void)
870 * that initializes ac_data for all new cpus 1155 * that initializes ac_data for all new cpus
871 */ 1156 */
872 register_cpu_notifier(&cpucache_notifier); 1157 register_cpu_notifier(&cpucache_notifier);
873
874 1158
875 /* The reap timers are started later, with a module init call: 1159 /* The reap timers are started later, with a module init call:
876 * That part of the kernel is not yet operational. 1160 * That part of the kernel is not yet operational.
@@ -885,10 +1169,8 @@ static int __init cpucache_init(void)
885 * Register the timers that return unneeded 1169 * Register the timers that return unneeded
886 * pages to gfp. 1170 * pages to gfp.
887 */ 1171 */
888 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1172 for_each_online_cpu(cpu)
889 if (cpu_online(cpu)) 1173 start_cpu_timer(cpu);
890 start_cpu_timer(cpu);
891 }
892 1174
893 return 0; 1175 return 0;
894} 1176}
@@ -1167,6 +1449,20 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
1167 } 1449 }
1168} 1450}
1169 1451
1452/* For setting up all the kmem_list3s for cache whose objsize is same
1453 as size of kmem_list3. */
1454static inline void set_up_list3s(kmem_cache_t *cachep, int index)
1455{
1456 int node;
1457
1458 for_each_online_node(node) {
1459 cachep->nodelists[node] = &initkmem_list3[index+node];
1460 cachep->nodelists[node]->next_reap = jiffies +
1461 REAPTIMEOUT_LIST3 +
1462 ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
1463 }
1464}
1465
1170/** 1466/**
1171 * kmem_cache_create - Create a cache. 1467 * kmem_cache_create - Create a cache.
1172 * @name: A string which is used in /proc/slabinfo to identify this cache. 1468 * @name: A string which is used in /proc/slabinfo to identify this cache.
@@ -1320,7 +1616,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
1320 size += BYTES_PER_WORD; 1616 size += BYTES_PER_WORD;
1321 } 1617 }
1322#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) 1618#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
1323 if (size > 128 && cachep->reallen > cache_line_size() && size < PAGE_SIZE) { 1619 if (size >= malloc_sizes[INDEX_L3+1].cs_size && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
1324 cachep->dbghead += PAGE_SIZE - size; 1620 cachep->dbghead += PAGE_SIZE - size;
1325 size = PAGE_SIZE; 1621 size = PAGE_SIZE;
1326 } 1622 }
@@ -1422,10 +1718,6 @@ next:
1422 cachep->gfpflags |= GFP_DMA; 1718 cachep->gfpflags |= GFP_DMA;
1423 spin_lock_init(&cachep->spinlock); 1719 spin_lock_init(&cachep->spinlock);
1424 cachep->objsize = size; 1720 cachep->objsize = size;
1425 /* NUMA */
1426 INIT_LIST_HEAD(&cachep->lists.slabs_full);
1427 INIT_LIST_HEAD(&cachep->lists.slabs_partial);
1428 INIT_LIST_HEAD(&cachep->lists.slabs_free);
1429 1721
1430 if (flags & CFLGS_OFF_SLAB) 1722 if (flags & CFLGS_OFF_SLAB)
1431 cachep->slabp_cache = kmem_find_general_cachep(slab_size,0); 1723 cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
@@ -1444,11 +1736,43 @@ next:
1444 * the cache that's used by kmalloc(24), otherwise 1736 * the cache that's used by kmalloc(24), otherwise
1445 * the creation of further caches will BUG(). 1737 * the creation of further caches will BUG().
1446 */ 1738 */
1447 cachep->array[smp_processor_id()] = &initarray_generic.cache; 1739 cachep->array[smp_processor_id()] =
1448 g_cpucache_up = PARTIAL; 1740 &initarray_generic.cache;
1741
1742 /* If the cache that's used by
1743 * kmalloc(sizeof(kmem_list3)) is the first cache,
1744 * then we need to set up all its list3s, otherwise
1745 * the creation of further caches will BUG().
1746 */
1747 set_up_list3s(cachep, SIZE_AC);
1748 if (INDEX_AC == INDEX_L3)
1749 g_cpucache_up = PARTIAL_L3;
1750 else
1751 g_cpucache_up = PARTIAL_AC;
1449 } else { 1752 } else {
1450 cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL); 1753 cachep->array[smp_processor_id()] =
1754 kmalloc(sizeof(struct arraycache_init),
1755 GFP_KERNEL);
1756
1757 if (g_cpucache_up == PARTIAL_AC) {
1758 set_up_list3s(cachep, SIZE_L3);
1759 g_cpucache_up = PARTIAL_L3;
1760 } else {
1761 int node;
1762 for_each_online_node(node) {
1763
1764 cachep->nodelists[node] =
1765 kmalloc_node(sizeof(struct kmem_list3),
1766 GFP_KERNEL, node);
1767 BUG_ON(!cachep->nodelists[node]);
1768 kmem_list3_init(cachep->nodelists[node]);
1769 }
1770 }
1451 } 1771 }
1772 cachep->nodelists[numa_node_id()]->next_reap =
1773 jiffies + REAPTIMEOUT_LIST3 +
1774 ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
1775
1452 BUG_ON(!ac_data(cachep)); 1776 BUG_ON(!ac_data(cachep));
1453 ac_data(cachep)->avail = 0; 1777 ac_data(cachep)->avail = 0;
1454 ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES; 1778 ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
@@ -1456,13 +1780,8 @@ next:
1456 ac_data(cachep)->touched = 0; 1780 ac_data(cachep)->touched = 0;
1457 cachep->batchcount = 1; 1781 cachep->batchcount = 1;
1458 cachep->limit = BOOT_CPUCACHE_ENTRIES; 1782 cachep->limit = BOOT_CPUCACHE_ENTRIES;
1459 cachep->free_limit = (1+num_online_cpus())*cachep->batchcount
1460 + cachep->num;
1461 } 1783 }
1462 1784
1463 cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
1464 ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
1465
1466 /* Need the semaphore to access the chain. */ 1785 /* Need the semaphore to access the chain. */
1467 down(&cache_chain_sem); 1786 down(&cache_chain_sem);
1468 { 1787 {
@@ -1519,13 +1838,23 @@ static void check_spinlock_acquired(kmem_cache_t *cachep)
1519{ 1838{
1520#ifdef CONFIG_SMP 1839#ifdef CONFIG_SMP
1521 check_irq_off(); 1840 check_irq_off();
1522 BUG_ON(spin_trylock(&cachep->spinlock)); 1841 assert_spin_locked(&cachep->nodelists[numa_node_id()]->list_lock);
1523#endif 1842#endif
1524} 1843}
1844
1845static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node)
1846{
1847#ifdef CONFIG_SMP
1848 check_irq_off();
1849 assert_spin_locked(&cachep->nodelists[node]->list_lock);
1850#endif
1851}
1852
1525#else 1853#else
1526#define check_irq_off() do { } while(0) 1854#define check_irq_off() do { } while(0)
1527#define check_irq_on() do { } while(0) 1855#define check_irq_on() do { } while(0)
1528#define check_spinlock_acquired(x) do { } while(0) 1856#define check_spinlock_acquired(x) do { } while(0)
1857#define check_spinlock_acquired_node(x, y) do { } while(0)
1529#endif 1858#endif
1530 1859
1531/* 1860/*
@@ -1547,7 +1876,7 @@ static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
1547} 1876}
1548 1877
1549static void drain_array_locked(kmem_cache_t* cachep, 1878static void drain_array_locked(kmem_cache_t* cachep,
1550 struct array_cache *ac, int force); 1879 struct array_cache *ac, int force, int node);
1551 1880
1552static void do_drain(void *arg) 1881static void do_drain(void *arg)
1553{ 1882{
@@ -1556,59 +1885,82 @@ static void do_drain(void *arg)
1556 1885
1557 check_irq_off(); 1886 check_irq_off();
1558 ac = ac_data(cachep); 1887 ac = ac_data(cachep);
1559 spin_lock(&cachep->spinlock); 1888 spin_lock(&cachep->nodelists[numa_node_id()]->list_lock);
1560 free_block(cachep, &ac_entry(ac)[0], ac->avail); 1889 free_block(cachep, ac->entry, ac->avail);
1561 spin_unlock(&cachep->spinlock); 1890 spin_unlock(&cachep->nodelists[numa_node_id()]->list_lock);
1562 ac->avail = 0; 1891 ac->avail = 0;
1563} 1892}
1564 1893
1565static void drain_cpu_caches(kmem_cache_t *cachep) 1894static void drain_cpu_caches(kmem_cache_t *cachep)
1566{ 1895{
1896 struct kmem_list3 *l3;
1897 int node;
1898
1567 smp_call_function_all_cpus(do_drain, cachep); 1899 smp_call_function_all_cpus(do_drain, cachep);
1568 check_irq_on(); 1900 check_irq_on();
1569 spin_lock_irq(&cachep->spinlock); 1901 spin_lock_irq(&cachep->spinlock);
1570 if (cachep->lists.shared) 1902 for_each_online_node(node) {
1571 drain_array_locked(cachep, cachep->lists.shared, 1); 1903 l3 = cachep->nodelists[node];
1904 if (l3) {
1905 spin_lock(&l3->list_lock);
1906 drain_array_locked(cachep, l3->shared, 1, node);
1907 spin_unlock(&l3->list_lock);
1908 if (l3->alien)
1909 drain_alien_cache(cachep, l3);
1910 }
1911 }
1572 spin_unlock_irq(&cachep->spinlock); 1912 spin_unlock_irq(&cachep->spinlock);
1573} 1913}
1574 1914
1575 1915static int __node_shrink(kmem_cache_t *cachep, int node)
1576/* NUMA shrink all list3s */
1577static int __cache_shrink(kmem_cache_t *cachep)
1578{ 1916{
1579 struct slab *slabp; 1917 struct slab *slabp;
1918 struct kmem_list3 *l3 = cachep->nodelists[node];
1580 int ret; 1919 int ret;
1581 1920
1582 drain_cpu_caches(cachep); 1921 for (;;) {
1583
1584 check_irq_on();
1585 spin_lock_irq(&cachep->spinlock);
1586
1587 for(;;) {
1588 struct list_head *p; 1922 struct list_head *p;
1589 1923
1590 p = cachep->lists.slabs_free.prev; 1924 p = l3->slabs_free.prev;
1591 if (p == &cachep->lists.slabs_free) 1925 if (p == &l3->slabs_free)
1592 break; 1926 break;
1593 1927
1594 slabp = list_entry(cachep->lists.slabs_free.prev, struct slab, list); 1928 slabp = list_entry(l3->slabs_free.prev, struct slab, list);
1595#if DEBUG 1929#if DEBUG
1596 if (slabp->inuse) 1930 if (slabp->inuse)
1597 BUG(); 1931 BUG();
1598#endif 1932#endif
1599 list_del(&slabp->list); 1933 list_del(&slabp->list);
1600 1934
1601 cachep->lists.free_objects -= cachep->num; 1935 l3->free_objects -= cachep->num;
1602 spin_unlock_irq(&cachep->spinlock); 1936 spin_unlock_irq(&l3->list_lock);
1603 slab_destroy(cachep, slabp); 1937 slab_destroy(cachep, slabp);
1604 spin_lock_irq(&cachep->spinlock); 1938 spin_lock_irq(&l3->list_lock);
1605 } 1939 }
1606 ret = !list_empty(&cachep->lists.slabs_full) || 1940 ret = !list_empty(&l3->slabs_full) ||
1607 !list_empty(&cachep->lists.slabs_partial); 1941 !list_empty(&l3->slabs_partial);
1608 spin_unlock_irq(&cachep->spinlock);
1609 return ret; 1942 return ret;
1610} 1943}
1611 1944
1945static int __cache_shrink(kmem_cache_t *cachep)
1946{
1947 int ret = 0, i = 0;
1948 struct kmem_list3 *l3;
1949
1950 drain_cpu_caches(cachep);
1951
1952 check_irq_on();
1953 for_each_online_node(i) {
1954 l3 = cachep->nodelists[i];
1955 if (l3) {
1956 spin_lock_irq(&l3->list_lock);
1957 ret += __node_shrink(cachep, i);
1958 spin_unlock_irq(&l3->list_lock);
1959 }
1960 }
1961 return (ret ? 1 : 0);
1962}
1963
1612/** 1964/**
1613 * kmem_cache_shrink - Shrink a cache. 1965 * kmem_cache_shrink - Shrink a cache.
1614 * @cachep: The cache to shrink. 1966 * @cachep: The cache to shrink.
@@ -1645,6 +1997,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
1645int kmem_cache_destroy(kmem_cache_t * cachep) 1997int kmem_cache_destroy(kmem_cache_t * cachep)
1646{ 1998{
1647 int i; 1999 int i;
2000 struct kmem_list3 *l3;
1648 2001
1649 if (!cachep || in_interrupt()) 2002 if (!cachep || in_interrupt())
1650 BUG(); 2003 BUG();
@@ -1672,15 +2025,17 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
1672 if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) 2025 if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
1673 synchronize_rcu(); 2026 synchronize_rcu();
1674 2027
1675 /* no cpu_online check required here since we clear the percpu 2028 for_each_online_cpu(i)
1676 * array on cpu offline and set this to NULL.
1677 */
1678 for (i = 0; i < NR_CPUS; i++)
1679 kfree(cachep->array[i]); 2029 kfree(cachep->array[i]);
1680 2030
1681 /* NUMA: free the list3 structures */ 2031 /* NUMA: free the list3 structures */
1682 kfree(cachep->lists.shared); 2032 for_each_online_node(i) {
1683 cachep->lists.shared = NULL; 2033 if ((l3 = cachep->nodelists[i])) {
2034 kfree(l3->shared);
2035 free_alien_cache(l3->alien);
2036 kfree(l3);
2037 }
2038 }
1684 kmem_cache_free(&cache_cache, cachep); 2039 kmem_cache_free(&cache_cache, cachep);
1685 2040
1686 unlock_cpu_hotplug(); 2041 unlock_cpu_hotplug();
@@ -1690,8 +2045,8 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
1690EXPORT_SYMBOL(kmem_cache_destroy); 2045EXPORT_SYMBOL(kmem_cache_destroy);
1691 2046
1692/* Get the memory for a slab management obj. */ 2047/* Get the memory for a slab management obj. */
1693static struct slab* alloc_slabmgmt(kmem_cache_t *cachep, 2048static struct slab* alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
1694 void *objp, int colour_off, unsigned int __nocast local_flags) 2049 int colour_off, unsigned int __nocast local_flags)
1695{ 2050{
1696 struct slab *slabp; 2051 struct slab *slabp;
1697 2052
@@ -1722,7 +2077,7 @@ static void cache_init_objs(kmem_cache_t *cachep,
1722 int i; 2077 int i;
1723 2078
1724 for (i = 0; i < cachep->num; i++) { 2079 for (i = 0; i < cachep->num; i++) {
1725 void* objp = slabp->s_mem+cachep->objsize*i; 2080 void *objp = slabp->s_mem+cachep->objsize*i;
1726#if DEBUG 2081#if DEBUG
1727 /* need to poison the objs? */ 2082 /* need to poison the objs? */
1728 if (cachep->flags & SLAB_POISON) 2083 if (cachep->flags & SLAB_POISON)
@@ -1799,6 +2154,7 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
1799 size_t offset; 2154 size_t offset;
1800 unsigned int local_flags; 2155 unsigned int local_flags;
1801 unsigned long ctor_flags; 2156 unsigned long ctor_flags;
2157 struct kmem_list3 *l3;
1802 2158
1803 /* Be lazy and only check for valid flags here, 2159 /* Be lazy and only check for valid flags here,
1804 * keeping it out of the critical path in kmem_cache_alloc(). 2160 * keeping it out of the critical path in kmem_cache_alloc().
@@ -1830,6 +2186,7 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
1830 2186
1831 spin_unlock(&cachep->spinlock); 2187 spin_unlock(&cachep->spinlock);
1832 2188
2189 check_irq_off();
1833 if (local_flags & __GFP_WAIT) 2190 if (local_flags & __GFP_WAIT)
1834 local_irq_enable(); 2191 local_irq_enable();
1835 2192
@@ -1841,8 +2198,9 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
1841 */ 2198 */
1842 kmem_flagcheck(cachep, flags); 2199 kmem_flagcheck(cachep, flags);
1843 2200
1844 2201 /* Get mem for the objs.
1845 /* Get mem for the objs. */ 2202 * Attempt to allocate a physical page from 'nodeid',
2203 */
1846 if (!(objp = kmem_getpages(cachep, flags, nodeid))) 2204 if (!(objp = kmem_getpages(cachep, flags, nodeid)))
1847 goto failed; 2205 goto failed;
1848 2206
@@ -1850,6 +2208,7 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
1850 if (!(slabp = alloc_slabmgmt(cachep, objp, offset, local_flags))) 2208 if (!(slabp = alloc_slabmgmt(cachep, objp, offset, local_flags)))
1851 goto opps1; 2209 goto opps1;
1852 2210
2211 slabp->nodeid = nodeid;
1853 set_slab_attr(cachep, slabp, objp); 2212 set_slab_attr(cachep, slabp, objp);
1854 2213
1855 cache_init_objs(cachep, slabp, ctor_flags); 2214 cache_init_objs(cachep, slabp, ctor_flags);
@@ -1857,13 +2216,14 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
1857 if (local_flags & __GFP_WAIT) 2216 if (local_flags & __GFP_WAIT)
1858 local_irq_disable(); 2217 local_irq_disable();
1859 check_irq_off(); 2218 check_irq_off();
1860 spin_lock(&cachep->spinlock); 2219 l3 = cachep->nodelists[nodeid];
2220 spin_lock(&l3->list_lock);
1861 2221
1862 /* Make slab active. */ 2222 /* Make slab active. */
1863 list_add_tail(&slabp->list, &(list3_data(cachep)->slabs_free)); 2223 list_add_tail(&slabp->list, &(l3->slabs_free));
1864 STATS_INC_GROWN(cachep); 2224 STATS_INC_GROWN(cachep);
1865 list3_data(cachep)->free_objects += cachep->num; 2225 l3->free_objects += cachep->num;
1866 spin_unlock(&cachep->spinlock); 2226 spin_unlock(&l3->list_lock);
1867 return 1; 2227 return 1;
1868opps1: 2228opps1:
1869 kmem_freepages(cachep, objp); 2229 kmem_freepages(cachep, objp);
@@ -1969,7 +2329,6 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
1969 kmem_bufctl_t i; 2329 kmem_bufctl_t i;
1970 int entries = 0; 2330 int entries = 0;
1971 2331
1972 check_spinlock_acquired(cachep);
1973 /* Check slab's freelist to see if this obj is there. */ 2332 /* Check slab's freelist to see if this obj is there. */
1974 for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) { 2333 for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1975 entries++; 2334 entries++;
@@ -2012,10 +2371,11 @@ retry:
2012 */ 2371 */
2013 batchcount = BATCHREFILL_LIMIT; 2372 batchcount = BATCHREFILL_LIMIT;
2014 } 2373 }
2015 l3 = list3_data(cachep); 2374 l3 = cachep->nodelists[numa_node_id()];
2375
2376 BUG_ON(ac->avail > 0 || !l3);
2377 spin_lock(&l3->list_lock);
2016 2378
2017 BUG_ON(ac->avail > 0);
2018 spin_lock(&cachep->spinlock);
2019 if (l3->shared) { 2379 if (l3->shared) {
2020 struct array_cache *shared_array = l3->shared; 2380 struct array_cache *shared_array = l3->shared;
2021 if (shared_array->avail) { 2381 if (shared_array->avail) {
@@ -2023,8 +2383,9 @@ retry:
2023 batchcount = shared_array->avail; 2383 batchcount = shared_array->avail;
2024 shared_array->avail -= batchcount; 2384 shared_array->avail -= batchcount;
2025 ac->avail = batchcount; 2385 ac->avail = batchcount;
2026 memcpy(ac_entry(ac), &ac_entry(shared_array)[shared_array->avail], 2386 memcpy(ac->entry,
2027 sizeof(void*)*batchcount); 2387 &(shared_array->entry[shared_array->avail]),
2388 sizeof(void*)*batchcount);
2028 shared_array->touched = 1; 2389 shared_array->touched = 1;
2029 goto alloc_done; 2390 goto alloc_done;
2030 } 2391 }
@@ -2051,7 +2412,8 @@ retry:
2051 STATS_SET_HIGH(cachep); 2412 STATS_SET_HIGH(cachep);
2052 2413
2053 /* get obj pointer */ 2414 /* get obj pointer */
2054 ac_entry(ac)[ac->avail++] = slabp->s_mem + slabp->free*cachep->objsize; 2415 ac->entry[ac->avail++] = slabp->s_mem +
2416 slabp->free*cachep->objsize;
2055 2417
2056 slabp->inuse++; 2418 slabp->inuse++;
2057 next = slab_bufctl(slabp)[slabp->free]; 2419 next = slab_bufctl(slabp)[slabp->free];
@@ -2073,12 +2435,12 @@ retry:
2073must_grow: 2435must_grow:
2074 l3->free_objects -= ac->avail; 2436 l3->free_objects -= ac->avail;
2075alloc_done: 2437alloc_done:
2076 spin_unlock(&cachep->spinlock); 2438 spin_unlock(&l3->list_lock);
2077 2439
2078 if (unlikely(!ac->avail)) { 2440 if (unlikely(!ac->avail)) {
2079 int x; 2441 int x;
2080 x = cache_grow(cachep, flags, -1); 2442 x = cache_grow(cachep, flags, numa_node_id());
2081 2443
2082 // cache_grow can reenable interrupts, then ac could change. 2444 // cache_grow can reenable interrupts, then ac could change.
2083 ac = ac_data(cachep); 2445 ac = ac_data(cachep);
2084 if (!x && ac->avail == 0) // no objects in sight? abort 2446 if (!x && ac->avail == 0) // no objects in sight? abort
@@ -2088,7 +2450,7 @@ alloc_done:
2088 goto retry; 2450 goto retry;
2089 } 2451 }
2090 ac->touched = 1; 2452 ac->touched = 1;
2091 return ac_entry(ac)[--ac->avail]; 2453 return ac->entry[--ac->avail];
2092} 2454}
2093 2455
2094static inline void 2456static inline void
@@ -2160,7 +2522,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast fl
2160 if (likely(ac->avail)) { 2522 if (likely(ac->avail)) {
2161 STATS_INC_ALLOCHIT(cachep); 2523 STATS_INC_ALLOCHIT(cachep);
2162 ac->touched = 1; 2524 ac->touched = 1;
2163 objp = ac_entry(ac)[--ac->avail]; 2525 objp = ac->entry[--ac->avail];
2164 } else { 2526 } else {
2165 STATS_INC_ALLOCMISS(cachep); 2527 STATS_INC_ALLOCMISS(cachep);
2166 objp = cache_alloc_refill(cachep, flags); 2528 objp = cache_alloc_refill(cachep, flags);
@@ -2172,33 +2534,104 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast fl
2172 return objp; 2534 return objp;
2173} 2535}
2174 2536
2175/* 2537#ifdef CONFIG_NUMA
2176 * NUMA: different approach needed if the spinlock is moved into 2538/*
2177 * the l3 structure 2539 * A interface to enable slab creation on nodeid
2178 */ 2540 */
2541static void *__cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
2542{
2543 struct list_head *entry;
2544 struct slab *slabp;
2545 struct kmem_list3 *l3;
2546 void *obj;
2547 kmem_bufctl_t next;
2548 int x;
2549
2550 l3 = cachep->nodelists[nodeid];
2551 BUG_ON(!l3);
2552
2553retry:
2554 spin_lock(&l3->list_lock);
2555 entry = l3->slabs_partial.next;
2556 if (entry == &l3->slabs_partial) {
2557 l3->free_touched = 1;
2558 entry = l3->slabs_free.next;
2559 if (entry == &l3->slabs_free)
2560 goto must_grow;
2561 }
2562
2563 slabp = list_entry(entry, struct slab, list);
2564 check_spinlock_acquired_node(cachep, nodeid);
2565 check_slabp(cachep, slabp);
2566
2567 STATS_INC_NODEALLOCS(cachep);
2568 STATS_INC_ACTIVE(cachep);
2569 STATS_SET_HIGH(cachep);
2570
2571 BUG_ON(slabp->inuse == cachep->num);
2572
2573 /* get obj pointer */
2574 obj = slabp->s_mem + slabp->free*cachep->objsize;
2575 slabp->inuse++;
2576 next = slab_bufctl(slabp)[slabp->free];
2577#if DEBUG
2578 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
2579#endif
2580 slabp->free = next;
2581 check_slabp(cachep, slabp);
2582 l3->free_objects--;
2583 /* move slabp to correct slabp list: */
2584 list_del(&slabp->list);
2179 2585
2586 if (slabp->free == BUFCTL_END) {
2587 list_add(&slabp->list, &l3->slabs_full);
2588 } else {
2589 list_add(&slabp->list, &l3->slabs_partial);
2590 }
2591
2592 spin_unlock(&l3->list_lock);
2593 goto done;
2594
2595must_grow:
2596 spin_unlock(&l3->list_lock);
2597 x = cache_grow(cachep, flags, nodeid);
2598
2599 if (!x)
2600 return NULL;
2601
2602 goto retry;
2603done:
2604 return obj;
2605}
2606#endif
2607
2608/*
2609 * Caller needs to acquire correct kmem_list's list_lock
2610 */
2180static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects) 2611static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
2181{ 2612{
2182 int i; 2613 int i;
2183 2614 struct kmem_list3 *l3;
2184 check_spinlock_acquired(cachep);
2185
2186 /* NUMA: move add into loop */
2187 cachep->lists.free_objects += nr_objects;
2188 2615
2189 for (i = 0; i < nr_objects; i++) { 2616 for (i = 0; i < nr_objects; i++) {
2190 void *objp = objpp[i]; 2617 void *objp = objpp[i];
2191 struct slab *slabp; 2618 struct slab *slabp;
2192 unsigned int objnr; 2619 unsigned int objnr;
2620 int nodeid = 0;
2193 2621
2194 slabp = GET_PAGE_SLAB(virt_to_page(objp)); 2622 slabp = GET_PAGE_SLAB(virt_to_page(objp));
2623 nodeid = slabp->nodeid;
2624 l3 = cachep->nodelists[nodeid];
2195 list_del(&slabp->list); 2625 list_del(&slabp->list);
2196 objnr = (objp - slabp->s_mem) / cachep->objsize; 2626 objnr = (objp - slabp->s_mem) / cachep->objsize;
2627 check_spinlock_acquired_node(cachep, nodeid);
2197 check_slabp(cachep, slabp); 2628 check_slabp(cachep, slabp);
2629
2630
2198#if DEBUG 2631#if DEBUG
2199 if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) { 2632 if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
2200 printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n", 2633 printk(KERN_ERR "slab: double free detected in cache "
2201 cachep->name, objp); 2634 "'%s', objp %p\n", cachep->name, objp);
2202 BUG(); 2635 BUG();
2203 } 2636 }
2204#endif 2637#endif
@@ -2206,24 +2639,23 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
2206 slabp->free = objnr; 2639 slabp->free = objnr;
2207 STATS_DEC_ACTIVE(cachep); 2640 STATS_DEC_ACTIVE(cachep);
2208 slabp->inuse--; 2641 slabp->inuse--;
2642 l3->free_objects++;
2209 check_slabp(cachep, slabp); 2643 check_slabp(cachep, slabp);
2210 2644
2211 /* fixup slab chains */ 2645 /* fixup slab chains */
2212 if (slabp->inuse == 0) { 2646 if (slabp->inuse == 0) {
2213 if (cachep->lists.free_objects > cachep->free_limit) { 2647 if (l3->free_objects > l3->free_limit) {
2214 cachep->lists.free_objects -= cachep->num; 2648 l3->free_objects -= cachep->num;
2215 slab_destroy(cachep, slabp); 2649 slab_destroy(cachep, slabp);
2216 } else { 2650 } else {
2217 list_add(&slabp->list, 2651 list_add(&slabp->list, &l3->slabs_free);
2218 &list3_data_ptr(cachep, objp)->slabs_free);
2219 } 2652 }
2220 } else { 2653 } else {
2221 /* Unconditionally move a slab to the end of the 2654 /* Unconditionally move a slab to the end of the
2222 * partial list on free - maximum time for the 2655 * partial list on free - maximum time for the
2223 * other objects to be freed, too. 2656 * other objects to be freed, too.
2224 */ 2657 */
2225 list_add_tail(&slabp->list, 2658 list_add_tail(&slabp->list, &l3->slabs_partial);
2226 &list3_data_ptr(cachep, objp)->slabs_partial);
2227 } 2659 }
2228 } 2660 }
2229} 2661}
@@ -2231,36 +2663,38 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
2231static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac) 2663static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
2232{ 2664{
2233 int batchcount; 2665 int batchcount;
2666 struct kmem_list3 *l3;
2234 2667
2235 batchcount = ac->batchcount; 2668 batchcount = ac->batchcount;
2236#if DEBUG 2669#if DEBUG
2237 BUG_ON(!batchcount || batchcount > ac->avail); 2670 BUG_ON(!batchcount || batchcount > ac->avail);
2238#endif 2671#endif
2239 check_irq_off(); 2672 check_irq_off();
2240 spin_lock(&cachep->spinlock); 2673 l3 = cachep->nodelists[numa_node_id()];
2241 if (cachep->lists.shared) { 2674 spin_lock(&l3->list_lock);
2242 struct array_cache *shared_array = cachep->lists.shared; 2675 if (l3->shared) {
2676 struct array_cache *shared_array = l3->shared;
2243 int max = shared_array->limit-shared_array->avail; 2677 int max = shared_array->limit-shared_array->avail;
2244 if (max) { 2678 if (max) {
2245 if (batchcount > max) 2679 if (batchcount > max)
2246 batchcount = max; 2680 batchcount = max;
2247 memcpy(&ac_entry(shared_array)[shared_array->avail], 2681 memcpy(&(shared_array->entry[shared_array->avail]),
2248 &ac_entry(ac)[0], 2682 ac->entry,
2249 sizeof(void*)*batchcount); 2683 sizeof(void*)*batchcount);
2250 shared_array->avail += batchcount; 2684 shared_array->avail += batchcount;
2251 goto free_done; 2685 goto free_done;
2252 } 2686 }
2253 } 2687 }
2254 2688
2255 free_block(cachep, &ac_entry(ac)[0], batchcount); 2689 free_block(cachep, ac->entry, batchcount);
2256free_done: 2690free_done:
2257#if STATS 2691#if STATS
2258 { 2692 {
2259 int i = 0; 2693 int i = 0;
2260 struct list_head *p; 2694 struct list_head *p;
2261 2695
2262 p = list3_data(cachep)->slabs_free.next; 2696 p = l3->slabs_free.next;
2263 while (p != &(list3_data(cachep)->slabs_free)) { 2697 while (p != &(l3->slabs_free)) {
2264 struct slab *slabp; 2698 struct slab *slabp;
2265 2699
2266 slabp = list_entry(p, struct slab, list); 2700 slabp = list_entry(p, struct slab, list);
@@ -2272,12 +2706,13 @@ free_done:
2272 STATS_SET_FREEABLE(cachep, i); 2706 STATS_SET_FREEABLE(cachep, i);
2273 } 2707 }
2274#endif 2708#endif
2275 spin_unlock(&cachep->spinlock); 2709 spin_unlock(&l3->list_lock);
2276 ac->avail -= batchcount; 2710 ac->avail -= batchcount;
2277 memmove(&ac_entry(ac)[0], &ac_entry(ac)[batchcount], 2711 memmove(ac->entry, &(ac->entry[batchcount]),
2278 sizeof(void*)*ac->avail); 2712 sizeof(void*)*ac->avail);
2279} 2713}
2280 2714
2715
2281/* 2716/*
2282 * __cache_free 2717 * __cache_free
2283 * Release an obj back to its cache. If the obj has a constructed 2718 * Release an obj back to its cache. If the obj has a constructed
@@ -2292,14 +2727,46 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
2292 check_irq_off(); 2727 check_irq_off();
2293 objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); 2728 objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
2294 2729
2730 /* Make sure we are not freeing a object from another
2731 * node to the array cache on this cpu.
2732 */
2733#ifdef CONFIG_NUMA
2734 {
2735 struct slab *slabp;
2736 slabp = GET_PAGE_SLAB(virt_to_page(objp));
2737 if (unlikely(slabp->nodeid != numa_node_id())) {
2738 struct array_cache *alien = NULL;
2739 int nodeid = slabp->nodeid;
2740 struct kmem_list3 *l3 = cachep->nodelists[numa_node_id()];
2741
2742 STATS_INC_NODEFREES(cachep);
2743 if (l3->alien && l3->alien[nodeid]) {
2744 alien = l3->alien[nodeid];
2745 spin_lock(&alien->lock);
2746 if (unlikely(alien->avail == alien->limit))
2747 __drain_alien_cache(cachep,
2748 alien, nodeid);
2749 alien->entry[alien->avail++] = objp;
2750 spin_unlock(&alien->lock);
2751 } else {
2752 spin_lock(&(cachep->nodelists[nodeid])->
2753 list_lock);
2754 free_block(cachep, &objp, 1);
2755 spin_unlock(&(cachep->nodelists[nodeid])->
2756 list_lock);
2757 }
2758 return;
2759 }
2760 }
2761#endif
2295 if (likely(ac->avail < ac->limit)) { 2762 if (likely(ac->avail < ac->limit)) {
2296 STATS_INC_FREEHIT(cachep); 2763 STATS_INC_FREEHIT(cachep);
2297 ac_entry(ac)[ac->avail++] = objp; 2764 ac->entry[ac->avail++] = objp;
2298 return; 2765 return;
2299 } else { 2766 } else {
2300 STATS_INC_FREEMISS(cachep); 2767 STATS_INC_FREEMISS(cachep);
2301 cache_flusharray(cachep, ac); 2768 cache_flusharray(cachep, ac);
2302 ac_entry(ac)[ac->avail++] = objp; 2769 ac->entry[ac->avail++] = objp;
2303 } 2770 }
2304} 2771}
2305 2772
@@ -2369,81 +2836,30 @@ out:
2369 * Identical to kmem_cache_alloc, except that this function is slow 2836 * Identical to kmem_cache_alloc, except that this function is slow
2370 * and can sleep. And it will allocate memory on the given node, which 2837 * and can sleep. And it will allocate memory on the given node, which
2371 * can improve the performance for cpu bound structures. 2838 * can improve the performance for cpu bound structures.
2839 * New and improved: it will now make sure that the object gets
2840 * put on the correct node list so that there is no false sharing.
2372 */ 2841 */
2373void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid) 2842void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
2374{ 2843{
2375 int loop; 2844 unsigned long save_flags;
2376 void *objp; 2845 void *ptr;
2377 struct slab *slabp;
2378 kmem_bufctl_t next;
2379
2380 if (nodeid == -1)
2381 return kmem_cache_alloc(cachep, flags);
2382
2383 for (loop = 0;;loop++) {
2384 struct list_head *q;
2385
2386 objp = NULL;
2387 check_irq_on();
2388 spin_lock_irq(&cachep->spinlock);
2389 /* walk through all partial and empty slab and find one
2390 * from the right node */
2391 list_for_each(q,&cachep->lists.slabs_partial) {
2392 slabp = list_entry(q, struct slab, list);
2393
2394 if (page_to_nid(virt_to_page(slabp->s_mem)) == nodeid ||
2395 loop > 2)
2396 goto got_slabp;
2397 }
2398 list_for_each(q, &cachep->lists.slabs_free) {
2399 slabp = list_entry(q, struct slab, list);
2400 2846
2401 if (page_to_nid(virt_to_page(slabp->s_mem)) == nodeid || 2847 if (nodeid == numa_node_id() || nodeid == -1)
2402 loop > 2) 2848 return __cache_alloc(cachep, flags);
2403 goto got_slabp;
2404 }
2405 spin_unlock_irq(&cachep->spinlock);
2406 2849
2407 local_irq_disable(); 2850 if (unlikely(!cachep->nodelists[nodeid])) {
2408 if (!cache_grow(cachep, flags, nodeid)) { 2851 /* Fall back to __cache_alloc if we run into trouble */
2409 local_irq_enable(); 2852 printk(KERN_WARNING "slab: not allocating in inactive node %d for cache %s\n", nodeid, cachep->name);
2410 return NULL; 2853 return __cache_alloc(cachep,flags);
2411 }
2412 local_irq_enable();
2413 } 2854 }
2414got_slabp:
2415 /* found one: allocate object */
2416 check_slabp(cachep, slabp);
2417 check_spinlock_acquired(cachep);
2418
2419 STATS_INC_ALLOCED(cachep);
2420 STATS_INC_ACTIVE(cachep);
2421 STATS_SET_HIGH(cachep);
2422 STATS_INC_NODEALLOCS(cachep);
2423 2855
2424 objp = slabp->s_mem + slabp->free*cachep->objsize; 2856 cache_alloc_debugcheck_before(cachep, flags);
2425 2857 local_irq_save(save_flags);
2426 slabp->inuse++; 2858 ptr = __cache_alloc_node(cachep, flags, nodeid);
2427 next = slab_bufctl(slabp)[slabp->free]; 2859 local_irq_restore(save_flags);
2428#if DEBUG 2860 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0));
2429 slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
2430#endif
2431 slabp->free = next;
2432 check_slabp(cachep, slabp);
2433
2434 /* move slabp to correct slabp list: */
2435 list_del(&slabp->list);
2436 if (slabp->free == BUFCTL_END)
2437 list_add(&slabp->list, &cachep->lists.slabs_full);
2438 else
2439 list_add(&slabp->list, &cachep->lists.slabs_partial);
2440
2441 list3_data(cachep)->free_objects--;
2442 spin_unlock_irq(&cachep->spinlock);
2443 2861
2444 objp = cache_alloc_debugcheck_after(cachep, GFP_KERNEL, objp, 2862 return ptr;
2445 __builtin_return_address(0));
2446 return objp;
2447} 2863}
2448EXPORT_SYMBOL(kmem_cache_alloc_node); 2864EXPORT_SYMBOL(kmem_cache_alloc_node);
2449 2865
@@ -2513,11 +2929,18 @@ void *__alloc_percpu(size_t size, size_t align)
2513 if (!pdata) 2929 if (!pdata)
2514 return NULL; 2930 return NULL;
2515 2931
2516 for (i = 0; i < NR_CPUS; i++) { 2932 /*
2517 if (!cpu_possible(i)) 2933 * Cannot use for_each_online_cpu since a cpu may come online
2518 continue; 2934 * and we have no way of figuring out how to fix the array
2519 pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL, 2935 * that we have allocated then....
2520 cpu_to_node(i)); 2936 */
2937 for_each_cpu(i) {
2938 int node = cpu_to_node(i);
2939
2940 if (node_online(node))
2941 pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL, node);
2942 else
2943 pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
2521 2944
2522 if (!pdata->ptrs[i]) 2945 if (!pdata->ptrs[i])
2523 goto unwind_oom; 2946 goto unwind_oom;
@@ -2575,6 +2998,8 @@ EXPORT_SYMBOL(kzalloc);
2575 * kfree - free previously allocated memory 2998 * kfree - free previously allocated memory
2576 * @objp: pointer returned by kmalloc. 2999 * @objp: pointer returned by kmalloc.
2577 * 3000 *
3001 * If @objp is NULL, no operation is performed.
3002 *
2578 * Don't free memory not originally allocated by kmalloc() 3003 * Don't free memory not originally allocated by kmalloc()
2579 * or you will run into trouble. 3004 * or you will run into trouble.
2580 */ 3005 */
@@ -2607,11 +3032,11 @@ free_percpu(const void *objp)
2607 int i; 3032 int i;
2608 struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp); 3033 struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
2609 3034
2610 for (i = 0; i < NR_CPUS; i++) { 3035 /*
2611 if (!cpu_possible(i)) 3036 * We allocate for all cpus so we cannot use for online cpu here.
2612 continue; 3037 */
3038 for_each_cpu(i)
2613 kfree(p->ptrs[i]); 3039 kfree(p->ptrs[i]);
2614 }
2615 kfree(p); 3040 kfree(p);
2616} 3041}
2617EXPORT_SYMBOL(free_percpu); 3042EXPORT_SYMBOL(free_percpu);
@@ -2629,6 +3054,64 @@ const char *kmem_cache_name(kmem_cache_t *cachep)
2629} 3054}
2630EXPORT_SYMBOL_GPL(kmem_cache_name); 3055EXPORT_SYMBOL_GPL(kmem_cache_name);
2631 3056
3057/*
3058 * This initializes kmem_list3 for all nodes.
3059 */
3060static int alloc_kmemlist(kmem_cache_t *cachep)
3061{
3062 int node;
3063 struct kmem_list3 *l3;
3064 int err = 0;
3065
3066 for_each_online_node(node) {
3067 struct array_cache *nc = NULL, *new;
3068 struct array_cache **new_alien = NULL;
3069#ifdef CONFIG_NUMA
3070 if (!(new_alien = alloc_alien_cache(node, cachep->limit)))
3071 goto fail;
3072#endif
3073 if (!(new = alloc_arraycache(node, (cachep->shared*
3074 cachep->batchcount), 0xbaadf00d)))
3075 goto fail;
3076 if ((l3 = cachep->nodelists[node])) {
3077
3078 spin_lock_irq(&l3->list_lock);
3079
3080 if ((nc = cachep->nodelists[node]->shared))
3081 free_block(cachep, nc->entry,
3082 nc->avail);
3083
3084 l3->shared = new;
3085 if (!cachep->nodelists[node]->alien) {
3086 l3->alien = new_alien;
3087 new_alien = NULL;
3088 }
3089 l3->free_limit = (1 + nr_cpus_node(node))*
3090 cachep->batchcount + cachep->num;
3091 spin_unlock_irq(&l3->list_lock);
3092 kfree(nc);
3093 free_alien_cache(new_alien);
3094 continue;
3095 }
3096 if (!(l3 = kmalloc_node(sizeof(struct kmem_list3),
3097 GFP_KERNEL, node)))
3098 goto fail;
3099
3100 kmem_list3_init(l3);
3101 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
3102 ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
3103 l3->shared = new;
3104 l3->alien = new_alien;
3105 l3->free_limit = (1 + nr_cpus_node(node))*
3106 cachep->batchcount + cachep->num;
3107 cachep->nodelists[node] = l3;
3108 }
3109 return err;
3110fail:
3111 err = -ENOMEM;
3112 return err;
3113}
3114
2632struct ccupdate_struct { 3115struct ccupdate_struct {
2633 kmem_cache_t *cachep; 3116 kmem_cache_t *cachep;
2634 struct array_cache *new[NR_CPUS]; 3117 struct array_cache *new[NR_CPUS];
@@ -2641,7 +3124,7 @@ static void do_ccupdate_local(void *info)
2641 3124
2642 check_irq_off(); 3125 check_irq_off();
2643 old = ac_data(new->cachep); 3126 old = ac_data(new->cachep);
2644 3127
2645 new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()]; 3128 new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];
2646 new->new[smp_processor_id()] = old; 3129 new->new[smp_processor_id()] = old;
2647} 3130}
@@ -2651,54 +3134,43 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
2651 int shared) 3134 int shared)
2652{ 3135{
2653 struct ccupdate_struct new; 3136 struct ccupdate_struct new;
2654 struct array_cache *new_shared; 3137 int i, err;
2655 int i;
2656 3138
2657 memset(&new.new,0,sizeof(new.new)); 3139 memset(&new.new,0,sizeof(new.new));
2658 for (i = 0; i < NR_CPUS; i++) { 3140 for_each_online_cpu(i) {
2659 if (cpu_online(i)) { 3141 new.new[i] = alloc_arraycache(cpu_to_node(i), limit, batchcount);
2660 new.new[i] = alloc_arraycache(i, limit, batchcount); 3142 if (!new.new[i]) {
2661 if (!new.new[i]) { 3143 for (i--; i >= 0; i--) kfree(new.new[i]);
2662 for (i--; i >= 0; i--) kfree(new.new[i]); 3144 return -ENOMEM;
2663 return -ENOMEM;
2664 }
2665 } else {
2666 new.new[i] = NULL;
2667 } 3145 }
2668 } 3146 }
2669 new.cachep = cachep; 3147 new.cachep = cachep;
2670 3148
2671 smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); 3149 smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
2672 3150
2673 check_irq_on(); 3151 check_irq_on();
2674 spin_lock_irq(&cachep->spinlock); 3152 spin_lock_irq(&cachep->spinlock);
2675 cachep->batchcount = batchcount; 3153 cachep->batchcount = batchcount;
2676 cachep->limit = limit; 3154 cachep->limit = limit;
2677 cachep->free_limit = (1+num_online_cpus())*cachep->batchcount + cachep->num; 3155 cachep->shared = shared;
2678 spin_unlock_irq(&cachep->spinlock); 3156 spin_unlock_irq(&cachep->spinlock);
2679 3157
2680 for (i = 0; i < NR_CPUS; i++) { 3158 for_each_online_cpu(i) {
2681 struct array_cache *ccold = new.new[i]; 3159 struct array_cache *ccold = new.new[i];
2682 if (!ccold) 3160 if (!ccold)
2683 continue; 3161 continue;
2684 spin_lock_irq(&cachep->spinlock); 3162 spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
2685 free_block(cachep, ac_entry(ccold), ccold->avail); 3163 free_block(cachep, ccold->entry, ccold->avail);
2686 spin_unlock_irq(&cachep->spinlock); 3164 spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
2687 kfree(ccold); 3165 kfree(ccold);
2688 } 3166 }
2689 new_shared = alloc_arraycache(-1, batchcount*shared, 0xbaadf00d);
2690 if (new_shared) {
2691 struct array_cache *old;
2692 3167
2693 spin_lock_irq(&cachep->spinlock); 3168 err = alloc_kmemlist(cachep);
2694 old = cachep->lists.shared; 3169 if (err) {
2695 cachep->lists.shared = new_shared; 3170 printk(KERN_ERR "alloc_kmemlist failed for %s, error %d.\n",
2696 if (old) 3171 cachep->name, -err);
2697 free_block(cachep, ac_entry(old), old->avail); 3172 BUG();
2698 spin_unlock_irq(&cachep->spinlock);
2699 kfree(old);
2700 } 3173 }
2701
2702 return 0; 3174 return 0;
2703} 3175}
2704 3176
@@ -2756,11 +3228,11 @@ static void enable_cpucache(kmem_cache_t *cachep)
2756} 3228}
2757 3229
2758static void drain_array_locked(kmem_cache_t *cachep, 3230static void drain_array_locked(kmem_cache_t *cachep,
2759 struct array_cache *ac, int force) 3231 struct array_cache *ac, int force, int node)
2760{ 3232{
2761 int tofree; 3233 int tofree;
2762 3234
2763 check_spinlock_acquired(cachep); 3235 check_spinlock_acquired_node(cachep, node);
2764 if (ac->touched && !force) { 3236 if (ac->touched && !force) {
2765 ac->touched = 0; 3237 ac->touched = 0;
2766 } else if (ac->avail) { 3238 } else if (ac->avail) {
@@ -2768,9 +3240,9 @@ static void drain_array_locked(kmem_cache_t *cachep,
2768 if (tofree > ac->avail) { 3240 if (tofree > ac->avail) {
2769 tofree = (ac->avail+1)/2; 3241 tofree = (ac->avail+1)/2;
2770 } 3242 }
2771 free_block(cachep, ac_entry(ac), tofree); 3243 free_block(cachep, ac->entry, tofree);
2772 ac->avail -= tofree; 3244 ac->avail -= tofree;
2773 memmove(&ac_entry(ac)[0], &ac_entry(ac)[tofree], 3245 memmove(ac->entry, &(ac->entry[tofree]),
2774 sizeof(void*)*ac->avail); 3246 sizeof(void*)*ac->avail);
2775 } 3247 }
2776} 3248}
@@ -2789,6 +3261,7 @@ static void drain_array_locked(kmem_cache_t *cachep,
2789static void cache_reap(void *unused) 3261static void cache_reap(void *unused)
2790{ 3262{
2791 struct list_head *walk; 3263 struct list_head *walk;
3264 struct kmem_list3 *l3;
2792 3265
2793 if (down_trylock(&cache_chain_sem)) { 3266 if (down_trylock(&cache_chain_sem)) {
2794 /* Give up. Setup the next iteration. */ 3267 /* Give up. Setup the next iteration. */
@@ -2809,27 +3282,32 @@ static void cache_reap(void *unused)
2809 3282
2810 check_irq_on(); 3283 check_irq_on();
2811 3284
2812 spin_lock_irq(&searchp->spinlock); 3285 l3 = searchp->nodelists[numa_node_id()];
3286 if (l3->alien)
3287 drain_alien_cache(searchp, l3);
3288 spin_lock_irq(&l3->list_lock);
2813 3289
2814 drain_array_locked(searchp, ac_data(searchp), 0); 3290 drain_array_locked(searchp, ac_data(searchp), 0,
3291 numa_node_id());
2815 3292
2816 if(time_after(searchp->lists.next_reap, jiffies)) 3293 if (time_after(l3->next_reap, jiffies))
2817 goto next_unlock; 3294 goto next_unlock;
2818 3295
2819 searchp->lists.next_reap = jiffies + REAPTIMEOUT_LIST3; 3296 l3->next_reap = jiffies + REAPTIMEOUT_LIST3;
2820 3297
2821 if (searchp->lists.shared) 3298 if (l3->shared)
2822 drain_array_locked(searchp, searchp->lists.shared, 0); 3299 drain_array_locked(searchp, l3->shared, 0,
3300 numa_node_id());
2823 3301
2824 if (searchp->lists.free_touched) { 3302 if (l3->free_touched) {
2825 searchp->lists.free_touched = 0; 3303 l3->free_touched = 0;
2826 goto next_unlock; 3304 goto next_unlock;
2827 } 3305 }
2828 3306
2829 tofree = (searchp->free_limit+5*searchp->num-1)/(5*searchp->num); 3307 tofree = (l3->free_limit+5*searchp->num-1)/(5*searchp->num);
2830 do { 3308 do {
2831 p = list3_data(searchp)->slabs_free.next; 3309 p = l3->slabs_free.next;
2832 if (p == &(list3_data(searchp)->slabs_free)) 3310 if (p == &(l3->slabs_free))
2833 break; 3311 break;
2834 3312
2835 slabp = list_entry(p, struct slab, list); 3313 slabp = list_entry(p, struct slab, list);
@@ -2842,13 +3320,13 @@ static void cache_reap(void *unused)
2842 * searchp cannot disappear, we hold 3320 * searchp cannot disappear, we hold
2843 * cache_chain_lock 3321 * cache_chain_lock
2844 */ 3322 */
2845 searchp->lists.free_objects -= searchp->num; 3323 l3->free_objects -= searchp->num;
2846 spin_unlock_irq(&searchp->spinlock); 3324 spin_unlock_irq(&l3->list_lock);
2847 slab_destroy(searchp, slabp); 3325 slab_destroy(searchp, slabp);
2848 spin_lock_irq(&searchp->spinlock); 3326 spin_lock_irq(&l3->list_lock);
2849 } while(--tofree > 0); 3327 } while(--tofree > 0);
2850next_unlock: 3328next_unlock:
2851 spin_unlock_irq(&searchp->spinlock); 3329 spin_unlock_irq(&l3->list_lock);
2852next: 3330next:
2853 cond_resched(); 3331 cond_resched();
2854 } 3332 }
@@ -2882,7 +3360,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
2882 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); 3360 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
2883#if STATS 3361#if STATS
2884 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>" 3362 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>"
2885 " <error> <maxfreeable> <freelimit> <nodeallocs>"); 3363 " <error> <maxfreeable> <nodeallocs> <remotefrees>");
2886 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); 3364 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
2887#endif 3365#endif
2888 seq_putc(m, '\n'); 3366 seq_putc(m, '\n');
@@ -2917,39 +3395,53 @@ static int s_show(struct seq_file *m, void *p)
2917 unsigned long active_objs; 3395 unsigned long active_objs;
2918 unsigned long num_objs; 3396 unsigned long num_objs;
2919 unsigned long active_slabs = 0; 3397 unsigned long active_slabs = 0;
2920 unsigned long num_slabs; 3398 unsigned long num_slabs, free_objects = 0, shared_avail = 0;
2921 const char *name; 3399 const char *name;
2922 char *error = NULL; 3400 char *error = NULL;
3401 int node;
3402 struct kmem_list3 *l3;
2923 3403
2924 check_irq_on(); 3404 check_irq_on();
2925 spin_lock_irq(&cachep->spinlock); 3405 spin_lock_irq(&cachep->spinlock);
2926 active_objs = 0; 3406 active_objs = 0;
2927 num_slabs = 0; 3407 num_slabs = 0;
2928 list_for_each(q,&cachep->lists.slabs_full) { 3408 for_each_online_node(node) {
2929 slabp = list_entry(q, struct slab, list); 3409 l3 = cachep->nodelists[node];
2930 if (slabp->inuse != cachep->num && !error) 3410 if (!l3)
2931 error = "slabs_full accounting error"; 3411 continue;
2932 active_objs += cachep->num; 3412
2933 active_slabs++; 3413 spin_lock(&l3->list_lock);
2934 } 3414
2935 list_for_each(q,&cachep->lists.slabs_partial) { 3415 list_for_each(q,&l3->slabs_full) {
2936 slabp = list_entry(q, struct slab, list); 3416 slabp = list_entry(q, struct slab, list);
2937 if (slabp->inuse == cachep->num && !error) 3417 if (slabp->inuse != cachep->num && !error)
2938 error = "slabs_partial inuse accounting error"; 3418 error = "slabs_full accounting error";
2939 if (!slabp->inuse && !error) 3419 active_objs += cachep->num;
2940 error = "slabs_partial/inuse accounting error"; 3420 active_slabs++;
2941 active_objs += slabp->inuse; 3421 }
2942 active_slabs++; 3422 list_for_each(q,&l3->slabs_partial) {
2943 } 3423 slabp = list_entry(q, struct slab, list);
2944 list_for_each(q,&cachep->lists.slabs_free) { 3424 if (slabp->inuse == cachep->num && !error)
2945 slabp = list_entry(q, struct slab, list); 3425 error = "slabs_partial inuse accounting error";
2946 if (slabp->inuse && !error) 3426 if (!slabp->inuse && !error)
2947 error = "slabs_free/inuse accounting error"; 3427 error = "slabs_partial/inuse accounting error";
2948 num_slabs++; 3428 active_objs += slabp->inuse;
3429 active_slabs++;
3430 }
3431 list_for_each(q,&l3->slabs_free) {
3432 slabp = list_entry(q, struct slab, list);
3433 if (slabp->inuse && !error)
3434 error = "slabs_free/inuse accounting error";
3435 num_slabs++;
3436 }
3437 free_objects += l3->free_objects;
3438 shared_avail += l3->shared->avail;
3439
3440 spin_unlock(&l3->list_lock);
2949 } 3441 }
2950 num_slabs+=active_slabs; 3442 num_slabs+=active_slabs;
2951 num_objs = num_slabs*cachep->num; 3443 num_objs = num_slabs*cachep->num;
2952 if (num_objs - active_objs != cachep->lists.free_objects && !error) 3444 if (num_objs - active_objs != free_objects && !error)
2953 error = "free_objects accounting error"; 3445 error = "free_objects accounting error";
2954 3446
2955 name = cachep->name; 3447 name = cachep->name;
@@ -2961,9 +3453,9 @@ static int s_show(struct seq_file *m, void *p)
2961 cachep->num, (1<<cachep->gfporder)); 3453 cachep->num, (1<<cachep->gfporder));
2962 seq_printf(m, " : tunables %4u %4u %4u", 3454 seq_printf(m, " : tunables %4u %4u %4u",
2963 cachep->limit, cachep->batchcount, 3455 cachep->limit, cachep->batchcount,
2964 cachep->lists.shared->limit/cachep->batchcount); 3456 cachep->shared);
2965 seq_printf(m, " : slabdata %6lu %6lu %6u", 3457 seq_printf(m, " : slabdata %6lu %6lu %6lu",
2966 active_slabs, num_slabs, cachep->lists.shared->avail); 3458 active_slabs, num_slabs, shared_avail);
2967#if STATS 3459#if STATS
2968 { /* list3 stats */ 3460 { /* list3 stats */
2969 unsigned long high = cachep->high_mark; 3461 unsigned long high = cachep->high_mark;
@@ -2972,12 +3464,13 @@ static int s_show(struct seq_file *m, void *p)
2972 unsigned long reaped = cachep->reaped; 3464 unsigned long reaped = cachep->reaped;
2973 unsigned long errors = cachep->errors; 3465 unsigned long errors = cachep->errors;
2974 unsigned long max_freeable = cachep->max_freeable; 3466 unsigned long max_freeable = cachep->max_freeable;
2975 unsigned long free_limit = cachep->free_limit;
2976 unsigned long node_allocs = cachep->node_allocs; 3467 unsigned long node_allocs = cachep->node_allocs;
3468 unsigned long node_frees = cachep->node_frees;
2977 3469
2978 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu %4lu %4lu %4lu %4lu", 3470 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \
2979 allocs, high, grown, reaped, errors, 3471 %4lu %4lu %4lu %4lu",
2980 max_freeable, free_limit, node_allocs); 3472 allocs, high, grown, reaped, errors,
3473 max_freeable, node_allocs, node_frees);
2981 } 3474 }
2982 /* cpu stats */ 3475 /* cpu stats */
2983 { 3476 {
@@ -3056,9 +3549,10 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
3056 batchcount < 1 || 3549 batchcount < 1 ||
3057 batchcount > limit || 3550 batchcount > limit ||
3058 shared < 0) { 3551 shared < 0) {
3059 res = -EINVAL; 3552 res = 0;
3060 } else { 3553 } else {
3061 res = do_tune_cpucache(cachep, limit, batchcount, shared); 3554 res = do_tune_cpucache(cachep, limit,
3555 batchcount, shared);
3062 } 3556 }
3063 break; 3557 break;
3064 } 3558 }
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 67b358e57ef6..13c3d82968ae 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -332,9 +332,10 @@ void __vunmap(void *addr, int deallocate_pages)
332 * @addr: memory base address 332 * @addr: memory base address
333 * 333 *
334 * Free the virtually contiguous memory area starting at @addr, as 334 * Free the virtually contiguous memory area starting at @addr, as
335 * obtained from vmalloc(), vmalloc_32() or __vmalloc(). 335 * obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
336 * NULL, no operation is performed.
336 * 337 *
337 * May not be called in interrupt context. 338 * Must not be called in interrupt context.
338 */ 339 */
339void vfree(void *addr) 340void vfree(void *addr)
340{ 341{
@@ -352,7 +353,7 @@ EXPORT_SYMBOL(vfree);
352 * Free the virtually contiguous memory area starting at @addr, 353 * Free the virtually contiguous memory area starting at @addr,
353 * which was created from the page array passed to vmap(). 354 * which was created from the page array passed to vmap().
354 * 355 *
355 * May not be called in interrupt context. 356 * Must not be called in interrupt context.
356 */ 357 */
357void vunmap(void *addr) 358void vunmap(void *addr)
358{ 359{
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 17a81ebe7e6e..526d9531411f 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -105,7 +105,7 @@ extern void mpc_proc_clean(void);
105 105
106struct mpoa_client *mpcs = NULL; /* FIXME */ 106struct mpoa_client *mpcs = NULL; /* FIXME */
107static struct atm_mpoa_qos *qos_head = NULL; 107static struct atm_mpoa_qos *qos_head = NULL;
108static struct timer_list mpc_timer = TIMER_INITIALIZER(NULL, 0, 0); 108static DEFINE_TIMER(mpc_timer, NULL, 0, 0);
109 109
110 110
111static struct mpoa_client *find_mpc_by_itfnum(int itf) 111static struct mpoa_client *find_mpc_by_itfnum(int itf)
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index dca179daf415..0164a155b8c4 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -67,37 +67,34 @@ char *ax2asc(char *buf, ax25_address *a)
67/* 67/*
68 * ascii -> ax25 conversion 68 * ascii -> ax25 conversion
69 */ 69 */
70ax25_address *asc2ax(char *callsign) 70void asc2ax(ax25_address *addr, char *callsign)
71{ 71{
72 static ax25_address addr;
73 char *s; 72 char *s;
74 int n; 73 int n;
75 74
76 for (s = callsign, n = 0; n < 6; n++) { 75 for (s = callsign, n = 0; n < 6; n++) {
77 if (*s != '\0' && *s != '-') 76 if (*s != '\0' && *s != '-')
78 addr.ax25_call[n] = *s++; 77 addr->ax25_call[n] = *s++;
79 else 78 else
80 addr.ax25_call[n] = ' '; 79 addr->ax25_call[n] = ' ';
81 addr.ax25_call[n] <<= 1; 80 addr->ax25_call[n] <<= 1;
82 addr.ax25_call[n] &= 0xFE; 81 addr->ax25_call[n] &= 0xFE;
83 } 82 }
84 83
85 if (*s++ == '\0') { 84 if (*s++ == '\0') {
86 addr.ax25_call[6] = 0x00; 85 addr->ax25_call[6] = 0x00;
87 return &addr; 86 return;
88 } 87 }
89 88
90 addr.ax25_call[6] = *s++ - '0'; 89 addr->ax25_call[6] = *s++ - '0';
91 90
92 if (*s != '\0') { 91 if (*s != '\0') {
93 addr.ax25_call[6] *= 10; 92 addr->ax25_call[6] *= 10;
94 addr.ax25_call[6] += *s++ - '0'; 93 addr->ax25_call[6] += *s++ - '0';
95 } 94 }
96 95
97 addr.ax25_call[6] <<= 1; 96 addr->ax25_call[6] <<= 1;
98 addr.ax25_call[6] &= 0x1E; 97 addr->ax25_call[6] &= 0x1E;
99
100 return &addr;
101} 98}
102 99
103/* 100/*
diff --git a/net/core/dst.c b/net/core/dst.c
index 334790da9f16..470c05bc4cb2 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -39,8 +39,7 @@ static unsigned long dst_gc_timer_inc = DST_GC_MAX;
39static void dst_run_gc(unsigned long); 39static void dst_run_gc(unsigned long);
40static void ___dst_free(struct dst_entry * dst); 40static void ___dst_free(struct dst_entry * dst);
41 41
42static struct timer_list dst_gc_timer = 42static DEFINE_TIMER(dst_gc_timer, dst_run_gc, DST_GC_MIN, 0);
43 TIMER_INITIALIZER(dst_run_gc, DST_GC_MIN, 0);
44 43
45static void dst_run_gc(unsigned long dummy) 44static void dst_run_gc(unsigned long dummy)
46{ 45{
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a1a9a7abff50..5265dfd69928 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -645,10 +645,10 @@ int netpoll_setup(struct netpoll *np)
645 645
646 npinfo->rx_flags = 0; 646 npinfo->rx_flags = 0;
647 npinfo->rx_np = NULL; 647 npinfo->rx_np = NULL;
648 npinfo->poll_lock = SPIN_LOCK_UNLOCKED; 648 spin_lock_init(&npinfo->poll_lock);
649 npinfo->poll_owner = -1; 649 npinfo->poll_owner = -1;
650 npinfo->tries = MAX_RETRIES; 650 npinfo->tries = MAX_RETRIES;
651 npinfo->rx_lock = SPIN_LOCK_UNLOCKED; 651 spin_lock_init(&npinfo->rx_lock);
652 } else 652 } else
653 npinfo = ndev->npinfo; 653 npinfo = ndev->npinfo;
654 654
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8eb083b6041a..b3ad49fa7d78 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -503,7 +503,7 @@ static int pg_delay_d = 0;
503static int pg_clone_skb_d = 0; 503static int pg_clone_skb_d = 0;
504static int debug = 0; 504static int debug = 0;
505 505
506static spinlock_t _thread_lock = SPIN_LOCK_UNLOCKED; 506static DEFINE_SPINLOCK(_thread_lock);
507static struct pktgen_thread *pktgen_threads = NULL; 507static struct pktgen_thread *pktgen_threads = NULL;
508 508
509static char module_fname[128]; 509static char module_fname[128];
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 7bf3b3a91e97..ea30012dd195 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -43,12 +43,22 @@
43#include "ccid3.h" 43#include "ccid3.h"
44 44
45/* 45/*
46 * Reason for maths with 10 here is to avoid 32 bit overflow when a is big. 46 * Reason for maths here is to avoid 32 bit overflow when a is big.
47 * With this we get close to the limit.
47 */ 48 */
48static inline u32 usecs_div(const u32 a, const u32 b) 49static inline u32 usecs_div(const u32 a, const u32 b)
49{ 50{
50 const u32 tmp = a * (USEC_PER_SEC / 10); 51 const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 :
51 return b > 20 ? tmp / (b / 10) : tmp; 52 a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 :
53 a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 :
54 a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 :
55 a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 :
56 a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 :
57 a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
58 a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
59 100000;
60 const u32 tmp = a * (USEC_PER_SEC / div);
61 return (b >= 2 * div) ? tmp / (b / div) : tmp;
52} 62}
53 63
54static int ccid3_debug; 64static int ccid3_debug;
@@ -102,8 +112,7 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
102static inline void ccid3_hc_tx_set_state(struct sock *sk, 112static inline void ccid3_hc_tx_set_state(struct sock *sk,
103 enum ccid3_hc_tx_states state) 113 enum ccid3_hc_tx_states state)
104{ 114{
105 struct dccp_sock *dp = dccp_sk(sk); 115 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
106 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
107 enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state; 116 enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
108 117
109 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 118 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
@@ -144,8 +153,7 @@ static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
144 */ 153 */
145static void ccid3_hc_tx_update_x(struct sock *sk) 154static void ccid3_hc_tx_update_x(struct sock *sk)
146{ 155{
147 struct dccp_sock *dp = dccp_sk(sk); 156 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
148 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
149 157
150 /* To avoid large error in calcX */ 158 /* To avoid large error in calcX */
151 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) { 159 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
@@ -159,7 +167,7 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
159 } else { 167 } else {
160 struct timeval now; 168 struct timeval now;
161 169
162 do_gettimeofday(&now); 170 dccp_timestamp(sk, &now);
163 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= 171 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
164 hctx->ccid3hctx_rtt) { 172 hctx->ccid3hctx_rtt) {
165 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, 173 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv,
@@ -174,9 +182,8 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
174static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 182static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
175{ 183{
176 struct sock *sk = (struct sock *)data; 184 struct sock *sk = (struct sock *)data;
177 struct dccp_sock *dp = dccp_sk(sk);
178 unsigned long next_tmout = 0; 185 unsigned long next_tmout = 0;
179 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 186 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
180 187
181 bh_lock_sock(sk); 188 bh_lock_sock(sk);
182 if (sock_owned_by_user(sk)) { 189 if (sock_owned_by_user(sk)) {
@@ -274,7 +281,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
274 struct sk_buff *skb, int len) 281 struct sk_buff *skb, int len)
275{ 282{
276 struct dccp_sock *dp = dccp_sk(sk); 283 struct dccp_sock *dp = dccp_sk(sk);
277 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 284 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
278 struct dccp_tx_hist_entry *new_packet; 285 struct dccp_tx_hist_entry *new_packet;
279 struct timeval now; 286 struct timeval now;
280 long delay; 287 long delay;
@@ -307,7 +314,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
307 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet); 314 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
308 } 315 }
309 316
310 do_gettimeofday(&now); 317 dccp_timestamp(sk, &now);
311 318
312 switch (hctx->ccid3hctx_state) { 319 switch (hctx->ccid3hctx_state) {
313 case TFRC_SSTATE_NO_SENT: 320 case TFRC_SSTATE_NO_SENT:
@@ -348,18 +355,20 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
348 } 355 }
349 356
350 /* Can we send? if so add options and add to packet history */ 357 /* Can we send? if so add options and add to packet history */
351 if (rc == 0) 358 if (rc == 0) {
359 dp->dccps_hc_tx_insert_options = 1;
352 new_packet->dccphtx_ccval = 360 new_packet->dccphtx_ccval =
353 DCCP_SKB_CB(skb)->dccpd_ccval = 361 DCCP_SKB_CB(skb)->dccpd_ccval =
354 hctx->ccid3hctx_last_win_count; 362 hctx->ccid3hctx_last_win_count;
363 }
355out: 364out:
356 return rc; 365 return rc;
357} 366}
358 367
359static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) 368static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
360{ 369{
361 struct dccp_sock *dp = dccp_sk(sk); 370 const struct dccp_sock *dp = dccp_sk(sk);
362 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 371 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
363 struct timeval now; 372 struct timeval now;
364 373
365 BUG_ON(hctx == NULL); 374 BUG_ON(hctx == NULL);
@@ -370,7 +379,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
370 return; 379 return;
371 } 380 }
372 381
373 do_gettimeofday(&now); 382 dccp_timestamp(sk, &now);
374 383
375 /* check if we have sent a data packet */ 384 /* check if we have sent a data packet */
376 if (len > 0) { 385 if (len > 0) {
@@ -445,10 +454,11 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
445 454
446static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 455static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
447{ 456{
448 struct dccp_sock *dp = dccp_sk(sk); 457 const struct dccp_sock *dp = dccp_sk(sk);
449 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 458 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
450 struct ccid3_options_received *opt_recv; 459 struct ccid3_options_received *opt_recv;
451 struct dccp_tx_hist_entry *packet; 460 struct dccp_tx_hist_entry *packet;
461 struct timeval now;
452 unsigned long next_tmout; 462 unsigned long next_tmout;
453 u32 t_elapsed; 463 u32 t_elapsed;
454 u32 pinv; 464 u32 pinv;
@@ -471,7 +481,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
471 481
472 opt_recv = &hctx->ccid3hctx_options_received; 482 opt_recv = &hctx->ccid3hctx_options_received;
473 483
474 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time; 484 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
475 x_recv = opt_recv->ccid3or_receive_rate; 485 x_recv = opt_recv->ccid3or_receive_rate;
476 pinv = opt_recv->ccid3or_loss_event_rate; 486 pinv = opt_recv->ccid3or_loss_event_rate;
477 487
@@ -496,9 +506,14 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
496 } 506 }
497 507
498 /* Update RTT */ 508 /* Update RTT */
499 r_sample = timeval_now_delta(&packet->dccphtx_tstamp); 509 dccp_timestamp(sk, &now);
500 /* FIXME: */ 510 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
501 // r_sample -= usecs_to_jiffies(t_elapsed * 10); 511 if (unlikely(r_sample <= t_elapsed))
512 LIMIT_NETDEBUG(KERN_WARNING
513 "%s: r_sample=%uus, t_elapsed=%uus\n",
514 __FUNCTION__, r_sample, t_elapsed);
515 else
516 r_sample -= t_elapsed;
502 517
503 /* Update RTT estimate by 518 /* Update RTT estimate by
504 * If (No feedback recv) 519 * If (No feedback recv)
@@ -591,8 +606,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
591 606
592static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb) 607static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
593{ 608{
594 const struct dccp_sock *dp = dccp_sk(sk); 609 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
595 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
596 610
597 if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || 611 if (hctx == NULL || !(sk->sk_state == DCCP_OPEN ||
598 sk->sk_state == DCCP_PARTOPEN)) 612 sk->sk_state == DCCP_PARTOPEN))
@@ -606,8 +620,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
606 unsigned char *value) 620 unsigned char *value)
607{ 621{
608 int rc = 0; 622 int rc = 0;
609 struct dccp_sock *dp = dccp_sk(sk); 623 const struct dccp_sock *dp = dccp_sk(sk);
610 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 624 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
611 struct ccid3_options_received *opt_recv; 625 struct ccid3_options_received *opt_recv;
612 626
613 if (hctx == NULL) 627 if (hctx == NULL)
@@ -670,11 +684,11 @@ static int ccid3_hc_tx_init(struct sock *sk)
670 684
671 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 685 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
672 686
673 hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), 687 dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
674 gfp_any()); 688 if (dp->dccps_hc_tx_ccid_private == NULL)
675 if (hctx == NULL)
676 return -ENOMEM; 689 return -ENOMEM;
677 690
691 hctx = ccid3_hc_tx_sk(sk);
678 memset(hctx, 0, sizeof(*hctx)); 692 memset(hctx, 0, sizeof(*hctx));
679 693
680 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 694 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -696,7 +710,7 @@ static int ccid3_hc_tx_init(struct sock *sk)
696static void ccid3_hc_tx_exit(struct sock *sk) 710static void ccid3_hc_tx_exit(struct sock *sk)
697{ 711{
698 struct dccp_sock *dp = dccp_sk(sk); 712 struct dccp_sock *dp = dccp_sk(sk);
699 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 713 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
700 714
701 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 715 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
702 BUG_ON(hctx == NULL); 716 BUG_ON(hctx == NULL);
@@ -738,8 +752,7 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
738static inline void ccid3_hc_rx_set_state(struct sock *sk, 752static inline void ccid3_hc_rx_set_state(struct sock *sk,
739 enum ccid3_hc_rx_states state) 753 enum ccid3_hc_rx_states state)
740{ 754{
741 struct dccp_sock *dp = dccp_sk(sk); 755 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
742 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
743 enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state; 756 enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
744 757
745 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n", 758 ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
@@ -751,14 +764,14 @@ static inline void ccid3_hc_rx_set_state(struct sock *sk,
751 764
752static void ccid3_hc_rx_send_feedback(struct sock *sk) 765static void ccid3_hc_rx_send_feedback(struct sock *sk)
753{ 766{
767 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
754 struct dccp_sock *dp = dccp_sk(sk); 768 struct dccp_sock *dp = dccp_sk(sk);
755 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
756 struct dccp_rx_hist_entry *packet; 769 struct dccp_rx_hist_entry *packet;
757 struct timeval now; 770 struct timeval now;
758 771
759 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 772 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
760 773
761 do_gettimeofday(&now); 774 dccp_timestamp(sk, &now);
762 775
763 switch (hcrx->ccid3hcrx_state) { 776 switch (hcrx->ccid3hcrx_state) {
764 case TFRC_RSTATE_NO_DATA: 777 case TFRC_RSTATE_NO_DATA:
@@ -767,11 +780,8 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
767 case TFRC_RSTATE_DATA: { 780 case TFRC_RSTATE_DATA: {
768 const u32 delta = timeval_delta(&now, 781 const u32 delta = timeval_delta(&now,
769 &hcrx->ccid3hcrx_tstamp_last_feedback); 782 &hcrx->ccid3hcrx_tstamp_last_feedback);
770 783 hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
771 hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv * 784 delta);
772 USEC_PER_SEC);
773 if (likely(delta > 1))
774 hcrx->ccid3hcrx_x_recv /= delta;
775 } 785 }
776 break; 786 break;
777 default: 787 default:
@@ -801,14 +811,14 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
801 hcrx->ccid3hcrx_pinv = ~0; 811 hcrx->ccid3hcrx_pinv = ~0;
802 else 812 else
803 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p; 813 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
814 dp->dccps_hc_rx_insert_options = 1;
804 dccp_send_ack(sk); 815 dccp_send_ack(sk);
805} 816}
806 817
807static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) 818static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
808{ 819{
809 const struct dccp_sock *dp = dccp_sk(sk); 820 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
810 u32 x_recv, pinv; 821 u32 x_recv, pinv;
811 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
812 822
813 if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || 823 if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN ||
814 sk->sk_state == DCCP_PARTOPEN)) 824 sk->sk_state == DCCP_PARTOPEN))
@@ -837,8 +847,7 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
837 847
838static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) 848static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
839{ 849{
840 struct dccp_sock *dp = dccp_sk(sk); 850 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
841 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
842 struct dccp_rx_hist_entry *entry, *next, *tail = NULL; 851 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
843 u32 rtt, delta, x_recv, fval, p, tmp2; 852 u32 rtt, delta, x_recv, fval, p, tmp2;
844 struct timeval tstamp = { 0, }; 853 struct timeval tstamp = { 0, };
@@ -889,10 +898,9 @@ found:
889 if (rtt == 0) 898 if (rtt == 0)
890 rtt = 1; 899 rtt = 1;
891 900
892 delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback); 901 dccp_timestamp(sk, &tstamp);
893 x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC; 902 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
894 if (likely(delta > 1)) 903 x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
895 x_recv /= delta;
896 904
897 tmp1 = (u64)x_recv * (u64)rtt; 905 tmp1 = (u64)x_recv * (u64)rtt;
898 do_div(tmp1,10000000); 906 do_div(tmp1,10000000);
@@ -911,8 +919,7 @@ found:
911 919
912static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) 920static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
913{ 921{
914 struct dccp_sock *dp = dccp_sk(sk); 922 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
915 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
916 923
917 if (seq_loss != DCCP_MAX_SEQNO + 1 && 924 if (seq_loss != DCCP_MAX_SEQNO + 1 &&
918 list_empty(&hcrx->ccid3hcrx_li_hist)) { 925 list_empty(&hcrx->ccid3hcrx_li_hist)) {
@@ -930,8 +937,7 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
930 937
931static void ccid3_hc_rx_detect_loss(struct sock *sk) 938static void ccid3_hc_rx_detect_loss(struct sock *sk)
932{ 939{
933 struct dccp_sock *dp = dccp_sk(sk); 940 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
934 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
935 u8 win_loss; 941 u8 win_loss;
936 const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist, 942 const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
937 &hcrx->ccid3hcrx_li_hist, 943 &hcrx->ccid3hcrx_li_hist,
@@ -942,13 +948,12 @@ static void ccid3_hc_rx_detect_loss(struct sock *sk)
942 948
943static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 949static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
944{ 950{
945 struct dccp_sock *dp = dccp_sk(sk); 951 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
946 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
947 const struct dccp_options_received *opt_recv; 952 const struct dccp_options_received *opt_recv;
948 struct dccp_rx_hist_entry *packet; 953 struct dccp_rx_hist_entry *packet;
949 struct timeval now; 954 struct timeval now;
950 u8 win_count; 955 u8 win_count;
951 u32 p_prev; 956 u32 p_prev, r_sample, t_elapsed;
952 int ins; 957 int ins;
953 958
954 if (hcrx == NULL) 959 if (hcrx == NULL)
@@ -957,7 +962,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
957 BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA || 962 BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
958 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA)); 963 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
959 964
960 opt_recv = &dp->dccps_options_received; 965 opt_recv = &dccp_sk(sk)->dccps_options_received;
961 966
962 switch (DCCP_SKB_CB(skb)->dccpd_type) { 967 switch (DCCP_SKB_CB(skb)->dccpd_type) {
963 case DCCP_PKT_ACK: 968 case DCCP_PKT_ACK:
@@ -967,10 +972,24 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
967 if (opt_recv->dccpor_timestamp_echo == 0) 972 if (opt_recv->dccpor_timestamp_echo == 0)
968 break; 973 break;
969 p_prev = hcrx->ccid3hcrx_rtt; 974 p_prev = hcrx->ccid3hcrx_rtt;
970 do_gettimeofday(&now); 975 dccp_timestamp(sk, &now);
971 hcrx->ccid3hcrx_rtt = timeval_usecs(&now) - 976 timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
972 (opt_recv->dccpor_timestamp_echo - 977 r_sample = timeval_usecs(&now);
973 opt_recv->dccpor_elapsed_time) * 10; 978 t_elapsed = opt_recv->dccpor_elapsed_time * 10;
979
980 if (unlikely(r_sample <= t_elapsed))
981 LIMIT_NETDEBUG(KERN_WARNING
982 "%s: r_sample=%uus, t_elapsed=%uus\n",
983 __FUNCTION__, r_sample, t_elapsed);
984 else
985 r_sample -= t_elapsed;
986
987 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
988 hcrx->ccid3hcrx_rtt = r_sample;
989 else
990 hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
991 r_sample / 10;
992
974 if (p_prev != hcrx->ccid3hcrx_rtt) 993 if (p_prev != hcrx->ccid3hcrx_rtt)
975 ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n", 994 ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
976 dccp_role(sk), hcrx->ccid3hcrx_rtt, 995 dccp_role(sk), hcrx->ccid3hcrx_rtt,
@@ -985,7 +1004,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
985 return; 1004 return;
986 } 1005 }
987 1006
988 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp, 1007 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
989 skb, SLAB_ATOMIC); 1008 skb, SLAB_ATOMIC);
990 if (packet == NULL) { 1009 if (packet == NULL) {
991 ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet " 1010 ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet "
@@ -1017,7 +1036,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1017 if (ins != 0) 1036 if (ins != 0)
1018 break; 1037 break;
1019 1038
1020 do_gettimeofday(&now); 1039 dccp_timestamp(sk, &now);
1021 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >= 1040 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
1022 hcrx->ccid3hcrx_rtt) { 1041 hcrx->ccid3hcrx_rtt) {
1023 hcrx->ccid3hcrx_tstamp_last_ack = now; 1042 hcrx->ccid3hcrx_tstamp_last_ack = now;
@@ -1056,11 +1075,11 @@ static int ccid3_hc_rx_init(struct sock *sk)
1056 1075
1057 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1076 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1058 1077
1059 hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), 1078 dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
1060 gfp_any()); 1079 if (dp->dccps_hc_rx_ccid_private == NULL)
1061 if (hcrx == NULL)
1062 return -ENOMEM; 1080 return -ENOMEM;
1063 1081
1082 hcrx = ccid3_hc_rx_sk(sk);
1064 memset(hcrx, 0, sizeof(*hcrx)); 1083 memset(hcrx, 0, sizeof(*hcrx));
1065 1084
1066 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 1085 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -1072,18 +1091,16 @@ static int ccid3_hc_rx_init(struct sock *sk)
1072 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 1091 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
1073 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 1092 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1074 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 1093 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1075 /* 1094 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1076 * XXX this seems to be paranoid, need to think more about this, for 1095 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
1077 * now start with something different than zero. -acme 1096 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
1078 */
1079 hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5;
1080 return 0; 1097 return 0;
1081} 1098}
1082 1099
1083static void ccid3_hc_rx_exit(struct sock *sk) 1100static void ccid3_hc_rx_exit(struct sock *sk)
1084{ 1101{
1102 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1085 struct dccp_sock *dp = dccp_sk(sk); 1103 struct dccp_sock *dp = dccp_sk(sk);
1086 struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1087 1104
1088 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1105 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1089 1106
@@ -1104,8 +1121,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
1104 1121
1105static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 1122static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
1106{ 1123{
1107 const struct dccp_sock *dp = dccp_sk(sk); 1124 const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
1108 const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
1109 1125
1110 if (hcrx == NULL) 1126 if (hcrx == NULL)
1111 return; 1127 return;
@@ -1117,8 +1133,7 @@ static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
1117 1133
1118static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 1134static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
1119{ 1135{
1120 const struct dccp_sock *dp = dccp_sk(sk); 1136 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
1121 const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1122 1137
1123 if (hctx == NULL) 1138 if (hctx == NULL)
1124 return; 1139 return;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index ee8cbace6630..d16f00d784f3 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -115,7 +115,7 @@ struct ccid3_hc_rx_sock {
115 u64 ccid3hcrx_seqno_last_counter:48, 115 u64 ccid3hcrx_seqno_last_counter:48,
116 ccid3hcrx_state:8, 116 ccid3hcrx_state:8,
117 ccid3hcrx_last_counter:4; 117 ccid3hcrx_last_counter:4;
118 unsigned long ccid3hcrx_rtt; 118 u32 ccid3hcrx_rtt;
119 u32 ccid3hcrx_p; 119 u32 ccid3hcrx_p;
120 u32 ccid3hcrx_bytes_recv; 120 u32 ccid3hcrx_bytes_recv;
121 struct timeval ccid3hcrx_tstamp_last_feedback; 121 struct timeval ccid3hcrx_tstamp_last_feedback;
@@ -128,10 +128,14 @@ struct ccid3_hc_rx_sock {
128 u32 ccid3hcrx_x_recv; 128 u32 ccid3hcrx_x_recv;
129}; 129};
130 130
131#define ccid3_hc_tx_field(s,field) (s->dccps_hc_tx_ccid_private == NULL ? 0 : \ 131static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
132 ((struct ccid3_hc_tx_sock *)s->dccps_hc_tx_ccid_private)->ccid3hctx_##field) 132{
133 return dccp_sk(sk)->dccps_hc_tx_ccid_private;
134}
133 135
134#define ccid3_hc_rx_field(s,field) (s->dccps_hc_rx_ccid_private == NULL ? 0 : \ 136static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
135 ((struct ccid3_hc_rx_sock *)s->dccps_hc_rx_ccid_private)->ccid3hcrx_##field) 137{
138 return dccp_sk(sk)->dccps_hc_rx_ccid_private;
139}
136 140
137#endif /* _DCCP_CCID3_H_ */ 141#endif /* _DCCP_CCID3_H_ */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index fb90a91aa93d..b375ebdb7dcf 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -134,6 +134,7 @@ static inline struct dccp_tx_hist_entry *
134 134
135static inline struct dccp_rx_hist_entry * 135static inline struct dccp_rx_hist_entry *
136 dccp_rx_hist_entry_new(struct dccp_rx_hist *hist, 136 dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
137 const struct sock *sk,
137 const u32 ndp, 138 const u32 ndp,
138 const struct sk_buff *skb, 139 const struct sk_buff *skb,
139 const unsigned int __nocast prio) 140 const unsigned int __nocast prio)
@@ -148,7 +149,7 @@ static inline struct dccp_rx_hist_entry *
148 entry->dccphrx_ccval = dh->dccph_ccval; 149 entry->dccphrx_ccval = dh->dccph_ccval;
149 entry->dccphrx_type = dh->dccph_type; 150 entry->dccphrx_type = dh->dccph_type;
150 entry->dccphrx_ndp = ndp; 151 entry->dccphrx_ndp = ndp;
151 do_gettimeofday(&(entry->dccphrx_tstamp)); 152 dccp_timestamp(sk, &entry->dccphrx_tstamp);
152 } 153 }
153 154
154 return entry; 155 return entry;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 33456c0d5937..95c4630b3b18 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -426,10 +426,13 @@ extern struct dccp_ackpkts *
426 dccp_ackpkts_alloc(unsigned int len, 426 dccp_ackpkts_alloc(unsigned int len,
427 const unsigned int __nocast priority); 427 const unsigned int __nocast priority);
428extern void dccp_ackpkts_free(struct dccp_ackpkts *ap); 428extern void dccp_ackpkts_free(struct dccp_ackpkts *ap);
429extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state); 429extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
430 u64 ackno, u8 state);
430extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, 431extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
431 struct sock *sk, u64 ackno); 432 struct sock *sk, u64 ackno);
432 433
434extern void dccp_timestamp(const struct sock *sk, struct timeval *tv);
435
433static inline suseconds_t timeval_usecs(const struct timeval *tv) 436static inline suseconds_t timeval_usecs(const struct timeval *tv)
434{ 437{
435 return tv->tv_sec * USEC_PER_SEC + tv->tv_usec; 438 return tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
@@ -468,17 +471,6 @@ static inline void timeval_sub_usecs(struct timeval *tv,
468 } 471 }
469} 472}
470 473
471/*
472 * Returns the difference in usecs between timeval
473 * passed in and current time
474 */
475static inline suseconds_t timeval_now_delta(const struct timeval *tv)
476{
477 struct timeval now;
478 do_gettimeofday(&now);
479 return timeval_delta(&now, tv);
480}
481
482#ifdef CONFIG_IP_DCCP_DEBUG 474#ifdef CONFIG_IP_DCCP_DEBUG
483extern void dccp_ackvector_print(const u64 ackno, 475extern void dccp_ackvector_print(const u64 ackno,
484 const unsigned char *vector, int len); 476 const unsigned char *vector, int len);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index ef29cef1dafe..c60bc3433f5e 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -170,7 +170,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
170 if (dp->dccps_options.dccpo_send_ack_vector) { 170 if (dp->dccps_options.dccpo_send_ack_vector) {
171 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; 171 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
172 172
173 if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, 173 if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
174 DCCP_SKB_CB(skb)->dccpd_seq, 174 DCCP_SKB_CB(skb)->dccpd_seq,
175 DCCP_ACKPKTS_STATE_RECEIVED)) { 175 DCCP_ACKPKTS_STATE_RECEIVED)) {
176 LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable " 176 LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable "
@@ -498,7 +498,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
498 * DCCP_ACKPKTS_STATE_ECN_MARKED 498 * DCCP_ACKPKTS_STATE_ECN_MARKED
499 */ 499 */
500 if (dp->dccps_options.dccpo_send_ack_vector) { 500 if (dp->dccps_options.dccpo_send_ack_vector) {
501 if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, 501 if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
502 DCCP_SKB_CB(skb)->dccpd_seq, 502 DCCP_SKB_CB(skb)->dccpd_seq,
503 DCCP_ACKPKTS_STATE_RECEIVED)) 503 DCCP_ACKPKTS_STATE_RECEIVED))
504 goto discard; 504 goto discard;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3fc75dbee4b8..fee9a8c3777b 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1243,6 +1243,7 @@ static int dccp_v4_init_sock(struct sock *sk)
1243 static int dccp_ctl_socket_init = 1; 1243 static int dccp_ctl_socket_init = 1;
1244 1244
1245 dccp_options_init(&dp->dccps_options); 1245 dccp_options_init(&dp->dccps_options);
1246 do_gettimeofday(&dp->dccps_epoch);
1246 1247
1247 if (dp->dccps_options.dccpo_send_ack_vector) { 1248 if (dp->dccps_options.dccpo_send_ack_vector) {
1248 dp->dccps_hc_rx_ackpkts = 1249 dp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index ce5dff4ac22e..18461bc04cbe 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -96,6 +96,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
96 newdp->dccps_hc_rx_ackpkts = NULL; 96 newdp->dccps_hc_rx_ackpkts = NULL;
97 newdp->dccps_role = DCCP_ROLE_SERVER; 97 newdp->dccps_role = DCCP_ROLE_SERVER;
98 newicsk->icsk_rto = DCCP_TIMEOUT_INIT; 98 newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
99 do_gettimeofday(&newdp->dccps_epoch);
99 100
100 if (newdp->dccps_options.dccpo_send_ack_vector) { 101 if (newdp->dccps_options.dccpo_send_ack_vector) {
101 newdp->dccps_hc_rx_ackpkts = 102 newdp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 382c5894acb2..d4c4242d8dd7 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -72,6 +72,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
72 struct dccp_options_received *opt_recv = &dp->dccps_options_received; 72 struct dccp_options_received *opt_recv = &dp->dccps_options_received;
73 unsigned char opt, len; 73 unsigned char opt, len;
74 unsigned char *value; 74 unsigned char *value;
75 u32 elapsed_time;
75 76
76 memset(opt_recv, 0, sizeof(*opt_recv)); 77 memset(opt_recv, 0, sizeof(*opt_recv));
77 78
@@ -139,7 +140,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
139 opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); 140 opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
140 141
141 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; 142 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
142 do_gettimeofday(&dp->dccps_timestamp_time); 143 dccp_timestamp(sk, &dp->dccps_timestamp_time);
143 144
144 dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", 145 dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
145 debug_prefix, opt_recv->dccpor_timestamp, 146 debug_prefix, opt_recv->dccpor_timestamp,
@@ -159,18 +160,18 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
159 (unsigned long long) 160 (unsigned long long)
160 DCCP_SKB_CB(skb)->dccpd_ack_seq); 161 DCCP_SKB_CB(skb)->dccpd_ack_seq);
161 162
162 if (len > 4) {
163 if (len == 6)
164 opt_recv->dccpor_elapsed_time =
165 ntohs(*(u16 *)(value + 4));
166 else
167 opt_recv->dccpor_elapsed_time =
168 ntohl(*(u32 *)(value + 4));
169 163
170 dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n", 164 if (len == 4)
171 debug_prefix, 165 break;
172 opt_recv->dccpor_elapsed_time); 166
173 } 167 if (len == 6)
168 elapsed_time = ntohs(*(u16 *)(value + 4));
169 else
170 elapsed_time = ntohl(*(u32 *)(value + 4));
171
172 /* Give precedence to the biggest ELAPSED_TIME */
173 if (elapsed_time > opt_recv->dccpor_elapsed_time)
174 opt_recv->dccpor_elapsed_time = elapsed_time;
174 break; 175 break;
175 case DCCPO_ELAPSED_TIME: 176 case DCCPO_ELAPSED_TIME:
176 if (len != 2 && len != 4) 177 if (len != 2 && len != 4)
@@ -180,14 +181,15 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
180 continue; 181 continue;
181 182
182 if (len == 2) 183 if (len == 2)
183 opt_recv->dccpor_elapsed_time = 184 elapsed_time = ntohs(*(u16 *)value);
184 ntohs(*(u16 *)value);
185 else 185 else
186 opt_recv->dccpor_elapsed_time = 186 elapsed_time = ntohl(*(u32 *)value);
187 ntohl(*(u32 *)value); 187
188 if (elapsed_time > opt_recv->dccpor_elapsed_time)
189 opt_recv->dccpor_elapsed_time = elapsed_time;
188 190
189 dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix, 191 dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
190 opt_recv->dccpor_elapsed_time); 192 elapsed_time);
191 break; 193 break;
192 /* 194 /*
193 * From draft-ietf-dccp-spec-11.txt: 195 * From draft-ietf-dccp-spec-11.txt:
@@ -359,9 +361,13 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
359#endif 361#endif
360 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; 362 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
361 int len = ap->dccpap_buf_vector_len + 2; 363 int len = ap->dccpap_buf_vector_len + 2;
362 const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10; 364 struct timeval now;
365 u32 elapsed_time;
363 unsigned char *to, *from; 366 unsigned char *to, *from;
364 367
368 dccp_timestamp(sk, &now);
369 elapsed_time = timeval_delta(&now, &ap->dccpap_time) / 10;
370
365 if (elapsed_time != 0) 371 if (elapsed_time != 0)
366 dccp_insert_option_elapsed_time(sk, skb, elapsed_time); 372 dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
367 373
@@ -426,13 +432,29 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
426 (unsigned long long) ap->dccpap_ack_ackno); 432 (unsigned long long) ap->dccpap_ack_ackno);
427} 433}
428 434
435void dccp_timestamp(const struct sock *sk, struct timeval *tv)
436{
437 const struct dccp_sock *dp = dccp_sk(sk);
438
439 do_gettimeofday(tv);
440 tv->tv_sec -= dp->dccps_epoch.tv_sec;
441 tv->tv_usec -= dp->dccps_epoch.tv_usec;
442
443 while (tv->tv_usec < 0) {
444 tv->tv_sec--;
445 tv->tv_usec += USEC_PER_SEC;
446 }
447}
448
449EXPORT_SYMBOL_GPL(dccp_timestamp);
450
429void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) 451void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
430{ 452{
431 struct timeval tv; 453 struct timeval tv;
432 u32 now; 454 u32 now;
433 455
434 do_gettimeofday(&tv); 456 dccp_timestamp(sk, &tv);
435 now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10; 457 now = timeval_usecs(&tv) / 10;
436 /* yes this will overflow but that is the point as we want a 458 /* yes this will overflow but that is the point as we want a
437 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ 459 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */
438 460
@@ -450,13 +472,17 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
450 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? 472 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
451 "CLIENT TX opt: " : "server TX opt: "; 473 "CLIENT TX opt: " : "server TX opt: ";
452#endif 474#endif
475 struct timeval now;
453 u32 tstamp_echo; 476 u32 tstamp_echo;
454 const u32 elapsed_time = 477 u32 elapsed_time;
455 timeval_now_delta(&dp->dccps_timestamp_time) / 10; 478 int len, elapsed_time_len;
456 const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
457 const int len = 6 + elapsed_time_len;
458 unsigned char *to; 479 unsigned char *to;
459 480
481 dccp_timestamp(sk, &now);
482 elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10;
483 elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
484 len = 6 + elapsed_time_len;
485
460 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { 486 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
461 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " 487 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
462 "timestamp echo!\n"); 488 "timestamp echo!\n");
@@ -505,13 +531,18 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
505 (dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno != 531 (dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno !=
506 DCCP_MAX_SEQNO + 1)) 532 DCCP_MAX_SEQNO + 1))
507 dccp_insert_option_ack_vector(sk, skb); 533 dccp_insert_option_ack_vector(sk, skb);
508
509 if (dp->dccps_timestamp_echo != 0) 534 if (dp->dccps_timestamp_echo != 0)
510 dccp_insert_option_timestamp_echo(sk, skb); 535 dccp_insert_option_timestamp_echo(sk, skb);
511 } 536 }
512 537
513 ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb); 538 if (dp->dccps_hc_rx_insert_options) {
514 ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb); 539 ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
540 dp->dccps_hc_rx_insert_options = 0;
541 }
542 if (dp->dccps_hc_tx_insert_options) {
543 ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
544 dp->dccps_hc_tx_insert_options = 0;
545 }
515 546
516 /* XXX: insert other options when appropriate */ 547 /* XXX: insert other options when appropriate */
517 548
@@ -616,7 +647,8 @@ static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
616/* 647/*
617 * Implements the draft-ietf-dccp-spec-11.txt Appendix A 648 * Implements the draft-ietf-dccp-spec-11.txt Appendix A
618 */ 649 */
619int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) 650int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
651 u64 ackno, u8 state)
620{ 652{
621 /* 653 /*
622 * Check at the right places if the buffer is full, if it is, tell the 654 * Check at the right places if the buffer is full, if it is, tell the
@@ -697,7 +729,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
697 } 729 }
698 730
699 ap->dccpap_buf_ackno = ackno; 731 ap->dccpap_buf_ackno = ackno;
700 do_gettimeofday(&ap->dccpap_time); 732 dccp_timestamp(sk, &ap->dccpap_time);
701out: 733out:
702 dccp_pr_debug(""); 734 dccp_pr_debug("");
703 dccp_ackpkts_print(ap); 735 dccp_ackpkts_print(ap);
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2c915f305be3..3407f190afe8 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -117,8 +117,7 @@ static struct dn_rt_hash_bucket *dn_rt_hash_table;
117static unsigned dn_rt_hash_mask; 117static unsigned dn_rt_hash_mask;
118 118
119static struct timer_list dn_route_timer; 119static struct timer_list dn_route_timer;
120static struct timer_list dn_rt_flush_timer = 120static DEFINE_TIMER(dn_rt_flush_timer, dn_run_flush, 0, 0);
121 TIMER_INITIALIZER(dn_run_flush, 0, 0);
122int decnet_dst_gc_interval = 2; 121int decnet_dst_gc_interval = 2;
123 122
124static struct dst_ops dn_dst_ops = { 123static struct dst_ops dn_dst_ops = {
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index 58ed4319e693..91b16fbf91f0 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -1,6 +1,5 @@
1config IEEE80211 1config IEEE80211
2 tristate "Generic IEEE 802.11 Networking Stack" 2 tristate "Generic IEEE 802.11 Networking Stack"
3 select NET_RADIO
4 ---help--- 3 ---help---
5 This option enables the hardware independent IEEE 802.11 4 This option enables the hardware independent IEEE 802.11
6 networking stack. 5 networking stack.
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bf147f8db399..a9d84f93442c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1248,11 +1248,6 @@ module_init(inet_init);
1248/* ------------------------------------------------------------------------ */ 1248/* ------------------------------------------------------------------------ */
1249 1249
1250#ifdef CONFIG_PROC_FS 1250#ifdef CONFIG_PROC_FS
1251#ifdef CONFIG_IP_FIB_TRIE
1252extern int fib_stat_proc_init(void);
1253extern void fib_stat_proc_exit(void);
1254#endif
1255
1256static int __init ipv4_proc_init(void) 1251static int __init ipv4_proc_init(void)
1257{ 1252{
1258 int rc = 0; 1253 int rc = 0;
@@ -1265,19 +1260,11 @@ static int __init ipv4_proc_init(void)
1265 goto out_udp; 1260 goto out_udp;
1266 if (fib_proc_init()) 1261 if (fib_proc_init())
1267 goto out_fib; 1262 goto out_fib;
1268#ifdef CONFIG_IP_FIB_TRIE
1269 if (fib_stat_proc_init())
1270 goto out_fib_stat;
1271#endif
1272 if (ip_misc_proc_init()) 1263 if (ip_misc_proc_init())
1273 goto out_misc; 1264 goto out_misc;
1274out: 1265out:
1275 return rc; 1266 return rc;
1276out_misc: 1267out_misc:
1277#ifdef CONFIG_IP_FIB_TRIE
1278 fib_stat_proc_exit();
1279out_fib_stat:
1280#endif
1281 fib_proc_exit(); 1268 fib_proc_exit();
1282out_fib: 1269out_fib:
1283 udp4_proc_exit(); 1270 udp4_proc_exit();
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index b2dea4e5da77..1b63b4824164 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
43 * 2 of the License, or (at your option) any later version. 43 * 2 of the License, or (at your option) any later version.
44 */ 44 */
45 45
46#define VERSION "0.402" 46#define VERSION "0.403"
47 47
48#include <linux/config.h> 48#include <linux/config.h>
49#include <asm/uaccess.h> 49#include <asm/uaccess.h>
@@ -164,7 +164,6 @@ static struct node *resize(struct trie *t, struct tnode *tn);
164static struct tnode *inflate(struct trie *t, struct tnode *tn); 164static struct tnode *inflate(struct trie *t, struct tnode *tn);
165static struct tnode *halve(struct trie *t, struct tnode *tn); 165static struct tnode *halve(struct trie *t, struct tnode *tn);
166static void tnode_free(struct tnode *tn); 166static void tnode_free(struct tnode *tn);
167static void trie_dump_seq(struct seq_file *seq, struct trie *t);
168 167
169static kmem_cache_t *fn_alias_kmem __read_mostly; 168static kmem_cache_t *fn_alias_kmem __read_mostly;
170static struct trie *trie_local = NULL, *trie_main = NULL; 169static struct trie *trie_local = NULL, *trie_main = NULL;
@@ -1971,558 +1970,525 @@ struct fib_table * __init fib_hash_init(int id)
1971 return tb; 1970 return tb;
1972} 1971}
1973 1972
1974/* Trie dump functions */ 1973#ifdef CONFIG_PROC_FS
1974/* Depth first Trie walk iterator */
1975struct fib_trie_iter {
1976 struct tnode *tnode;
1977 struct trie *trie;
1978 unsigned index;
1979 unsigned depth;
1980};
1975 1981
1976static void putspace_seq(struct seq_file *seq, int n) 1982static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
1977{ 1983{
1978 while (n--) 1984 struct tnode *tn = iter->tnode;
1979 seq_printf(seq, " "); 1985 unsigned cindex = iter->index;
1980} 1986 struct tnode *p;
1981 1987
1982static void printbin_seq(struct seq_file *seq, unsigned int v, int bits) 1988 pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
1983{ 1989 iter->tnode, iter->index, iter->depth);
1984 while (bits--) 1990rescan:
1985 seq_printf(seq, "%s", (v & (1<<bits))?"1":"0"); 1991 while (cindex < (1<<tn->bits)) {
1986} 1992 struct node *n = tnode_get_child(tn, cindex);
1987 1993
1988static void printnode_seq(struct seq_file *seq, int indent, struct node *n, 1994 if (n) {
1989 int pend, int cindex, int bits) 1995 if (IS_LEAF(n)) {
1990{ 1996 iter->tnode = tn;
1991 putspace_seq(seq, indent); 1997 iter->index = cindex + 1;
1992 if (IS_LEAF(n)) 1998 } else {
1993 seq_printf(seq, "|"); 1999 /* push down one level */
1994 else 2000 iter->tnode = (struct tnode *) n;
1995 seq_printf(seq, "+"); 2001 iter->index = 0;
1996 if (bits) { 2002 ++iter->depth;
1997 seq_printf(seq, "%d/", cindex); 2003 }
1998 printbin_seq(seq, cindex, bits); 2004 return n;
1999 seq_printf(seq, ": "); 2005 }
2000 } else
2001 seq_printf(seq, "<root>: ");
2002 seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n);
2003 2006
2004 if (IS_LEAF(n)) { 2007 ++cindex;
2005 struct leaf *l = (struct leaf *)n; 2008 }
2006 struct fib_alias *fa;
2007 int i;
2008 2009
2009 seq_printf(seq, "key=%d.%d.%d.%d\n", 2010 /* Current node exhausted, pop back up */
2010 n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256); 2011 p = NODE_PARENT(tn);
2011 2012 if (p) {
2012 for (i = 32; i >= 0; i--) 2013 cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
2013 if (find_leaf_info(&l->list, i)) { 2014 tn = p;
2014 struct list_head *fa_head = get_fa_head(l, i); 2015 --iter->depth;
2015 2016 goto rescan;
2016 if (!fa_head)
2017 continue;
2018
2019 if (list_empty(fa_head))
2020 continue;
2021
2022 putspace_seq(seq, indent+2);
2023 seq_printf(seq, "{/%d...dumping}\n", i);
2024
2025 list_for_each_entry_rcu(fa, fa_head, fa_list) {
2026 putspace_seq(seq, indent+2);
2027 if (fa->fa_info == NULL) {
2028 seq_printf(seq, "Error fa_info=NULL\n");
2029 continue;
2030 }
2031 if (fa->fa_info->fib_nh == NULL) {
2032 seq_printf(seq, "Error _fib_nh=NULL\n");
2033 continue;
2034 }
2035
2036 seq_printf(seq, "{type=%d scope=%d TOS=%d}\n",
2037 fa->fa_type,
2038 fa->fa_scope,
2039 fa->fa_tos);
2040 }
2041 }
2042 } else {
2043 struct tnode *tn = (struct tnode *)n;
2044 int plen = ((struct tnode *)n)->pos;
2045 t_key prf = MASK_PFX(n->key, plen);
2046
2047 seq_printf(seq, "key=%d.%d.%d.%d/%d\n",
2048 prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen);
2049
2050 putspace_seq(seq, indent); seq_printf(seq, "| ");
2051 seq_printf(seq, "{key prefix=%08x/", tn->key & TKEY_GET_MASK(0, tn->pos));
2052 printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos);
2053 seq_printf(seq, "}\n");
2054 putspace_seq(seq, indent); seq_printf(seq, "| ");
2055 seq_printf(seq, "{pos=%d", tn->pos);
2056 seq_printf(seq, " (skip=%d bits)", tn->pos - pend);
2057 seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits));
2058 putspace_seq(seq, indent); seq_printf(seq, "| ");
2059 seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children);
2060 } 2017 }
2018
2019 /* got root? */
2020 return NULL;
2061} 2021}
2062 2022
2063static void trie_dump_seq(struct seq_file *seq, struct trie *t) 2023static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
2024 struct trie *t)
2064{ 2025{
2065 struct node *n; 2026 struct node *n = rcu_dereference(t->trie);
2066 int cindex = 0;
2067 int indent = 1;
2068 int pend = 0;
2069 int depth = 0;
2070 struct tnode *tn;
2071
2072 rcu_read_lock();
2073 n = rcu_dereference(t->trie);
2074 seq_printf(seq, "------ trie_dump of t=%p ------\n", t);
2075 2027
2076 if (!n) { 2028 if (n && IS_TNODE(n)) {
2077 seq_printf(seq, "------ trie is empty\n"); 2029 iter->tnode = (struct tnode *) n;
2078 2030 iter->trie = t;
2079 rcu_read_unlock(); 2031 iter->index = 0;
2080 return; 2032 iter->depth = 0;
2033 return n;
2081 } 2034 }
2035 return NULL;
2036}
2082 2037
2083 printnode_seq(seq, indent, n, pend, cindex, 0); 2038static void trie_collect_stats(struct trie *t, struct trie_stat *s)
2084 2039{
2085 if (!IS_TNODE(n)) { 2040 struct node *n;
2086 rcu_read_unlock(); 2041 struct fib_trie_iter iter;
2087 return;
2088 }
2089
2090 tn = (struct tnode *)n;
2091 pend = tn->pos+tn->bits;
2092 putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
2093 indent += 3;
2094 depth++;
2095
2096 while (tn && cindex < (1 << tn->bits)) {
2097 struct node *child = rcu_dereference(tn->child[cindex]);
2098 if (!child)
2099 cindex++;
2100 else {
2101 /* Got a child */
2102 printnode_seq(seq, indent, child, pend,
2103 cindex, tn->bits);
2104
2105 if (IS_LEAF(child))
2106 cindex++;
2107
2108 else {
2109 /*
2110 * New tnode. Decend one level
2111 */
2112
2113 depth++;
2114 n = child;
2115 tn = (struct tnode *)n;
2116 pend = tn->pos+tn->bits;
2117 putspace_seq(seq, indent);
2118 seq_printf(seq, "\\--\n");
2119 indent += 3;
2120 cindex = 0;
2121 }
2122 }
2123
2124 /*
2125 * Test if we are done
2126 */
2127
2128 while (cindex >= (1 << tn->bits)) {
2129 /*
2130 * Move upwards and test for root
2131 * pop off all traversed nodes
2132 */
2133 2042
2134 if (NODE_PARENT(tn) == NULL) { 2043 memset(s, 0, sizeof(*s));
2135 tn = NULL;
2136 break;
2137 }
2138 2044
2139 cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits); 2045 rcu_read_lock();
2140 cindex++; 2046 for (n = fib_trie_get_first(&iter, t); n;
2141 tn = NODE_PARENT(tn); 2047 n = fib_trie_get_next(&iter)) {
2142 pend = tn->pos + tn->bits; 2048 if (IS_LEAF(n)) {
2143 indent -= 3; 2049 s->leaves++;
2144 depth--; 2050 s->totdepth += iter.depth;
2051 if (iter.depth > s->maxdepth)
2052 s->maxdepth = iter.depth;
2053 } else {
2054 const struct tnode *tn = (const struct tnode *) n;
2055 int i;
2056
2057 s->tnodes++;
2058 s->nodesizes[tn->bits]++;
2059 for (i = 0; i < (1<<tn->bits); i++)
2060 if (!tn->child[i])
2061 s->nullpointers++;
2145 } 2062 }
2146 } 2063 }
2147 rcu_read_unlock(); 2064 rcu_read_unlock();
2148} 2065}
2149 2066
2150static struct trie_stat *trie_stat_new(void) 2067/*
2068 * This outputs /proc/net/fib_triestats
2069 */
2070static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
2151{ 2071{
2152 struct trie_stat *s; 2072 unsigned i, max, pointers, bytes, avdepth;
2153 int i;
2154 2073
2155 s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL); 2074 if (stat->leaves)
2156 if (!s) 2075 avdepth = stat->totdepth*100 / stat->leaves;
2157 return NULL; 2076 else
2077 avdepth = 0;
2158 2078
2159 s->totdepth = 0; 2079 seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
2160 s->maxdepth = 0; 2080 seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth);
2161 s->tnodes = 0;
2162 s->leaves = 0;
2163 s->nullpointers = 0;
2164 2081
2165 for (i = 0; i < MAX_CHILDS; i++) 2082 seq_printf(seq, "\tLeaves: %u\n", stat->leaves);
2166 s->nodesizes[i] = 0;
2167 2083
2168 return s; 2084 bytes = sizeof(struct leaf) * stat->leaves;
2169} 2085 seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
2086 bytes += sizeof(struct tnode) * stat->tnodes;
2170 2087
2171static struct trie_stat *trie_collect_stats(struct trie *t) 2088 max = MAX_CHILDS-1;
2172{ 2089 while (max >= 0 && stat->nodesizes[max] == 0)
2173 struct node *n; 2090 max--;
2174 struct trie_stat *s = trie_stat_new();
2175 int cindex = 0;
2176 int pend = 0;
2177 int depth = 0;
2178 2091
2179 if (!s) 2092 pointers = 0;
2180 return NULL; 2093 for (i = 1; i <= max; i++)
2094 if (stat->nodesizes[i] != 0) {
2095 seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
2096 pointers += (1<<i) * stat->nodesizes[i];
2097 }
2098 seq_putc(seq, '\n');
2099 seq_printf(seq, "\tPointers: %d\n", pointers);
2181 2100
2182 rcu_read_lock(); 2101 bytes += sizeof(struct node *) * pointers;
2183 n = rcu_dereference(t->trie); 2102 seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
2103 seq_printf(seq, "Total size: %d kB\n", (bytes + 1023) / 1024);
2184 2104
2185 if (!n) 2105#ifdef CONFIG_IP_FIB_TRIE_STATS
2186 return s; 2106 seq_printf(seq, "Counters:\n---------\n");
2107 seq_printf(seq,"gets = %d\n", t->stats.gets);
2108 seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
2109 seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
2110 seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
2111 seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
2112 seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
2113#ifdef CLEAR_STATS
2114 memset(&(t->stats), 0, sizeof(t->stats));
2115#endif
2116#endif /* CONFIG_IP_FIB_TRIE_STATS */
2117}
2187 2118
2188 if (IS_TNODE(n)) { 2119static int fib_triestat_seq_show(struct seq_file *seq, void *v)
2189 struct tnode *tn = (struct tnode *)n; 2120{
2190 pend = tn->pos+tn->bits; 2121 struct trie_stat *stat;
2191 s->nodesizes[tn->bits]++;
2192 depth++;
2193
2194 while (tn && cindex < (1 << tn->bits)) {
2195 struct node *ch = rcu_dereference(tn->child[cindex]);
2196 if (ch) {
2197
2198 /* Got a child */
2199
2200 if (IS_LEAF(tn->child[cindex])) {
2201 cindex++;
2202
2203 /* stats */
2204 if (depth > s->maxdepth)
2205 s->maxdepth = depth;
2206 s->totdepth += depth;
2207 s->leaves++;
2208 } else {
2209 /*
2210 * New tnode. Decend one level
2211 */
2212
2213 s->tnodes++;
2214 s->nodesizes[tn->bits]++;
2215 depth++;
2216
2217 n = ch;
2218 tn = (struct tnode *)n;
2219 pend = tn->pos+tn->bits;
2220
2221 cindex = 0;
2222 }
2223 } else {
2224 cindex++;
2225 s->nullpointers++;
2226 }
2227 2122
2228 /* 2123 stat = kmalloc(sizeof(*stat), GFP_KERNEL);
2229 * Test if we are done 2124 if (!stat)
2230 */ 2125 return -ENOMEM;
2231 2126
2232 while (cindex >= (1 << tn->bits)) { 2127 seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
2233 /* 2128 sizeof(struct leaf), sizeof(struct tnode));
2234 * Move upwards and test for root
2235 * pop off all traversed nodes
2236 */
2237 2129
2238 if (NODE_PARENT(tn) == NULL) { 2130 if (trie_local) {
2239 tn = NULL; 2131 seq_printf(seq, "Local:\n");
2240 n = NULL; 2132 trie_collect_stats(trie_local, stat);
2241 break; 2133 trie_show_stats(seq, stat);
2242 } 2134 }
2243 2135
2244 cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits); 2136 if (trie_main) {
2245 tn = NODE_PARENT(tn); 2137 seq_printf(seq, "Main:\n");
2246 cindex++; 2138 trie_collect_stats(trie_main, stat);
2247 n = (struct node *)tn; 2139 trie_show_stats(seq, stat);
2248 pend = tn->pos+tn->bits;
2249 depth--;
2250 }
2251 }
2252 } 2140 }
2141 kfree(stat);
2253 2142
2254 rcu_read_unlock(); 2143 return 0;
2255 return s;
2256} 2144}
2257 2145
2258#ifdef CONFIG_PROC_FS 2146static int fib_triestat_seq_open(struct inode *inode, struct file *file)
2259
2260static struct fib_alias *fib_triestat_get_first(struct seq_file *seq)
2261{ 2147{
2262 return NULL; 2148 return single_open(file, fib_triestat_seq_show, NULL);
2263} 2149}
2264 2150
2265static struct fib_alias *fib_triestat_get_next(struct seq_file *seq) 2151static struct file_operations fib_triestat_fops = {
2152 .owner = THIS_MODULE,
2153 .open = fib_triestat_seq_open,
2154 .read = seq_read,
2155 .llseek = seq_lseek,
2156 .release = single_release,
2157};
2158
2159static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
2160 loff_t pos)
2266{ 2161{
2162 loff_t idx = 0;
2163 struct node *n;
2164
2165 for (n = fib_trie_get_first(iter, trie_local);
2166 n; ++idx, n = fib_trie_get_next(iter)) {
2167 if (pos == idx)
2168 return n;
2169 }
2170
2171 for (n = fib_trie_get_first(iter, trie_main);
2172 n; ++idx, n = fib_trie_get_next(iter)) {
2173 if (pos == idx)
2174 return n;
2175 }
2267 return NULL; 2176 return NULL;
2268} 2177}
2269 2178
2270static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos) 2179static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
2271{ 2180{
2272 if (!ip_fib_main_table) 2181 rcu_read_lock();
2273 return NULL; 2182 if (*pos == 0)
2274
2275 if (*pos)
2276 return fib_triestat_get_next(seq);
2277 else
2278 return SEQ_START_TOKEN; 2183 return SEQ_START_TOKEN;
2184 return fib_trie_get_idx(seq->private, *pos - 1);
2279} 2185}
2280 2186
2281static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2187static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2282{ 2188{
2189 struct fib_trie_iter *iter = seq->private;
2190 void *l = v;
2191
2283 ++*pos; 2192 ++*pos;
2284 if (v == SEQ_START_TOKEN) 2193 if (v == SEQ_START_TOKEN)
2285 return fib_triestat_get_first(seq); 2194 return fib_trie_get_idx(iter, 0);
2286 else
2287 return fib_triestat_get_next(seq);
2288}
2289 2195
2290static void fib_triestat_seq_stop(struct seq_file *seq, void *v) 2196 v = fib_trie_get_next(iter);
2291{ 2197 BUG_ON(v == l);
2198 if (v)
2199 return v;
2292 2200
2293} 2201 /* continue scan in next trie */
2202 if (iter->trie == trie_local)
2203 return fib_trie_get_first(iter, trie_main);
2294 2204
2295/* 2205 return NULL;
2296 * This outputs /proc/net/fib_triestats 2206}
2297 *
2298 * It always works in backward compatibility mode.
2299 * The format of the file is not supposed to be changed.
2300 */
2301 2207
2302static void collect_and_show(struct trie *t, struct seq_file *seq) 2208static void fib_trie_seq_stop(struct seq_file *seq, void *v)
2303{ 2209{
2304 int bytes = 0; /* How many bytes are used, a ref is 4 bytes */ 2210 rcu_read_unlock();
2305 int i, max, pointers; 2211}
2306 struct trie_stat *stat;
2307 int avdepth;
2308
2309 stat = trie_collect_stats(t);
2310
2311 bytes = 0;
2312 seq_printf(seq, "trie=%p\n", t);
2313
2314 if (stat) {
2315 if (stat->leaves)
2316 avdepth = stat->totdepth*100 / stat->leaves;
2317 else
2318 avdepth = 0;
2319 seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100);
2320 seq_printf(seq, "Max depth: %4d\n", stat->maxdepth);
2321 2212
2322 seq_printf(seq, "Leaves: %d\n", stat->leaves); 2213static void seq_indent(struct seq_file *seq, int n)
2323 bytes += sizeof(struct leaf) * stat->leaves; 2214{
2324 seq_printf(seq, "Internal nodes: %d\n", stat->tnodes); 2215 while (n-- > 0) seq_puts(seq, " ");
2325 bytes += sizeof(struct tnode) * stat->tnodes; 2216}
2326 2217
2327 max = MAX_CHILDS-1; 2218static inline const char *rtn_scope(enum rt_scope_t s)
2219{
2220 static char buf[32];
2328 2221
2329 while (max >= 0 && stat->nodesizes[max] == 0) 2222 switch(s) {
2330 max--; 2223 case RT_SCOPE_UNIVERSE: return "universe";
2331 pointers = 0; 2224 case RT_SCOPE_SITE: return "site";
2225 case RT_SCOPE_LINK: return "link";
2226 case RT_SCOPE_HOST: return "host";
2227 case RT_SCOPE_NOWHERE: return "nowhere";
2228 default:
2229 snprintf(buf, sizeof(buf), "scope=%d", s);
2230 return buf;
2231 }
2232}
2332 2233
2333 for (i = 1; i <= max; i++) 2234static const char *rtn_type_names[__RTN_MAX] = {
2334 if (stat->nodesizes[i] != 0) { 2235 [RTN_UNSPEC] = "UNSPEC",
2335 seq_printf(seq, " %d: %d", i, stat->nodesizes[i]); 2236 [RTN_UNICAST] = "UNICAST",
2336 pointers += (1<<i) * stat->nodesizes[i]; 2237 [RTN_LOCAL] = "LOCAL",
2337 } 2238 [RTN_BROADCAST] = "BROADCAST",
2338 seq_printf(seq, "\n"); 2239 [RTN_ANYCAST] = "ANYCAST",
2339 seq_printf(seq, "Pointers: %d\n", pointers); 2240 [RTN_MULTICAST] = "MULTICAST",
2340 bytes += sizeof(struct node *) * pointers; 2241 [RTN_BLACKHOLE] = "BLACKHOLE",
2341 seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers); 2242 [RTN_UNREACHABLE] = "UNREACHABLE",
2342 seq_printf(seq, "Total size: %d kB\n", bytes / 1024); 2243 [RTN_PROHIBIT] = "PROHIBIT",
2244 [RTN_THROW] = "THROW",
2245 [RTN_NAT] = "NAT",
2246 [RTN_XRESOLVE] = "XRESOLVE",
2247};
2343 2248
2344 kfree(stat); 2249static inline const char *rtn_type(unsigned t)
2345 } 2250{
2251 static char buf[32];
2346 2252
2347#ifdef CONFIG_IP_FIB_TRIE_STATS 2253 if (t < __RTN_MAX && rtn_type_names[t])
2348 seq_printf(seq, "Counters:\n---------\n"); 2254 return rtn_type_names[t];
2349 seq_printf(seq,"gets = %d\n", t->stats.gets); 2255 snprintf(buf, sizeof(buf), "type %d", t);
2350 seq_printf(seq,"backtracks = %d\n", t->stats.backtrack); 2256 return buf;
2351 seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
2352 seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
2353 seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
2354 seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
2355#ifdef CLEAR_STATS
2356 memset(&(t->stats), 0, sizeof(t->stats));
2357#endif
2358#endif /* CONFIG_IP_FIB_TRIE_STATS */
2359} 2257}
2360 2258
2361static int fib_triestat_seq_show(struct seq_file *seq, void *v) 2259/* Pretty print the trie */
2260static int fib_trie_seq_show(struct seq_file *seq, void *v)
2362{ 2261{
2363 char bf[128]; 2262 const struct fib_trie_iter *iter = seq->private;
2263 struct node *n = v;
2364 2264
2365 if (v == SEQ_START_TOKEN) { 2265 if (v == SEQ_START_TOKEN)
2366 seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n", 2266 return 0;
2367 sizeof(struct leaf), sizeof(struct tnode));
2368 if (trie_local)
2369 collect_and_show(trie_local, seq);
2370 2267
2371 if (trie_main) 2268 if (IS_TNODE(n)) {
2372 collect_and_show(trie_main, seq); 2269 struct tnode *tn = (struct tnode *) n;
2373 } else { 2270 t_key prf = ntohl(MASK_PFX(tn->key, tn->pos));
2374 snprintf(bf, sizeof(bf), "*\t%08X\t%08X", 200, 400);
2375 2271
2376 seq_printf(seq, "%-127s\n", bf); 2272 if (!NODE_PARENT(n)) {
2273 if (iter->trie == trie_local)
2274 seq_puts(seq, "<local>:\n");
2275 else
2276 seq_puts(seq, "<main>:\n");
2277 } else {
2278 seq_indent(seq, iter->depth-1);
2279 seq_printf(seq, " +-- %d.%d.%d.%d/%d\n",
2280 NIPQUAD(prf), tn->pos);
2281 }
2282 } else {
2283 struct leaf *l = (struct leaf *) n;
2284 int i;
2285 u32 val = ntohl(l->key);
2286
2287 seq_indent(seq, iter->depth);
2288 seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));
2289 for (i = 32; i >= 0; i--) {
2290 struct leaf_info *li = find_leaf_info(&l->list, i);
2291 if (li) {
2292 struct fib_alias *fa;
2293 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2294 seq_indent(seq, iter->depth+1);
2295 seq_printf(seq, " /%d %s %s", i,
2296 rtn_scope(fa->fa_scope),
2297 rtn_type(fa->fa_type));
2298 if (fa->fa_tos)
2299 seq_printf(seq, "tos =%d\n",
2300 fa->fa_tos);
2301 seq_putc(seq, '\n');
2302 }
2303 }
2304 }
2377 } 2305 }
2306
2378 return 0; 2307 return 0;
2379} 2308}
2380 2309
2381static struct seq_operations fib_triestat_seq_ops = { 2310static struct seq_operations fib_trie_seq_ops = {
2382 .start = fib_triestat_seq_start, 2311 .start = fib_trie_seq_start,
2383 .next = fib_triestat_seq_next, 2312 .next = fib_trie_seq_next,
2384 .stop = fib_triestat_seq_stop, 2313 .stop = fib_trie_seq_stop,
2385 .show = fib_triestat_seq_show, 2314 .show = fib_trie_seq_show,
2386}; 2315};
2387 2316
2388static int fib_triestat_seq_open(struct inode *inode, struct file *file) 2317static int fib_trie_seq_open(struct inode *inode, struct file *file)
2389{ 2318{
2390 struct seq_file *seq; 2319 struct seq_file *seq;
2391 int rc = -ENOMEM; 2320 int rc = -ENOMEM;
2321 struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
2392 2322
2393 rc = seq_open(file, &fib_triestat_seq_ops); 2323 if (!s)
2324 goto out;
2325
2326 rc = seq_open(file, &fib_trie_seq_ops);
2394 if (rc) 2327 if (rc)
2395 goto out_kfree; 2328 goto out_kfree;
2396 2329
2397 seq = file->private_data; 2330 seq = file->private_data;
2331 seq->private = s;
2332 memset(s, 0, sizeof(*s));
2398out: 2333out:
2399 return rc; 2334 return rc;
2400out_kfree: 2335out_kfree:
2336 kfree(s);
2401 goto out; 2337 goto out;
2402} 2338}
2403 2339
2404static struct file_operations fib_triestat_seq_fops = { 2340static struct file_operations fib_trie_fops = {
2405 .owner = THIS_MODULE, 2341 .owner = THIS_MODULE,
2406 .open = fib_triestat_seq_open, 2342 .open = fib_trie_seq_open,
2407 .read = seq_read, 2343 .read = seq_read,
2408 .llseek = seq_lseek, 2344 .llseek = seq_lseek,
2409 .release = seq_release_private, 2345 .release = seq_release_private,
2410}; 2346};
2411 2347
2412int __init fib_stat_proc_init(void) 2348static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
2413{
2414 if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
2415 return -ENOMEM;
2416 return 0;
2417}
2418
2419void __init fib_stat_proc_exit(void)
2420{ 2349{
2421 proc_net_remove("fib_triestat"); 2350 static unsigned type2flags[RTN_MAX + 1] = {
2422} 2351 [7] = RTF_REJECT, [8] = RTF_REJECT,
2352 };
2353 unsigned flags = type2flags[type];
2423 2354
2424static struct fib_alias *fib_trie_get_first(struct seq_file *seq) 2355 if (fi && fi->fib_nh->nh_gw)
2425{ 2356 flags |= RTF_GATEWAY;
2426 return NULL; 2357 if (mask == 0xFFFFFFFF)
2358 flags |= RTF_HOST;
2359 flags |= RTF_UP;
2360 return flags;
2427} 2361}
2428 2362
2429static struct fib_alias *fib_trie_get_next(struct seq_file *seq) 2363/*
2364 * This outputs /proc/net/route.
2365 * The format of the file is not supposed to be changed
2366 * and needs to be same as fib_hash output to avoid breaking
2367 * legacy utilities
2368 */
2369static int fib_route_seq_show(struct seq_file *seq, void *v)
2430{ 2370{
2431 return NULL; 2371 struct leaf *l = v;
2432} 2372 int i;
2373 char bf[128];
2433 2374
2434static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos) 2375 if (v == SEQ_START_TOKEN) {
2435{ 2376 seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
2436 if (!ip_fib_main_table) 2377 "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
2437 return NULL; 2378 "\tWindow\tIRTT");
2379 return 0;
2380 }
2438 2381
2439 if (*pos) 2382 if (IS_TNODE(l))
2440 return fib_trie_get_next(seq); 2383 return 0;
2441 else
2442 return SEQ_START_TOKEN;
2443}
2444 2384
2445static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2385 for (i=32; i>=0; i--) {
2446{ 2386 struct leaf_info *li = find_leaf_info(&l->list, i);
2447 ++*pos; 2387 struct fib_alias *fa;
2448 if (v == SEQ_START_TOKEN) 2388 u32 mask, prefix;
2449 return fib_trie_get_first(seq);
2450 else
2451 return fib_trie_get_next(seq);
2452 2389
2453} 2390 if (!li)
2391 continue;
2454 2392
2455static void fib_trie_seq_stop(struct seq_file *seq, void *v) 2393 mask = inet_make_mask(li->plen);
2456{ 2394 prefix = htonl(l->key);
2457}
2458 2395
2459/* 2396 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2460 * This outputs /proc/net/fib_trie. 2397 const struct fib_info *fi = rcu_dereference(fa->fa_info);
2461 * 2398 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
2462 * It always works in backward compatibility mode.
2463 * The format of the file is not supposed to be changed.
2464 */
2465 2399
2466static int fib_trie_seq_show(struct seq_file *seq, void *v) 2400 if (fa->fa_type == RTN_BROADCAST
2467{ 2401 || fa->fa_type == RTN_MULTICAST)
2468 char bf[128]; 2402 continue;
2469 2403
2470 if (v == SEQ_START_TOKEN) { 2404 if (fi)
2471 if (trie_local) 2405 snprintf(bf, sizeof(bf),
2472 trie_dump_seq(seq, trie_local); 2406 "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
2407 fi->fib_dev ? fi->fib_dev->name : "*",
2408 prefix,
2409 fi->fib_nh->nh_gw, flags, 0, 0,
2410 fi->fib_priority,
2411 mask,
2412 (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
2413 fi->fib_window,
2414 fi->fib_rtt >> 3);
2415 else
2416 snprintf(bf, sizeof(bf),
2417 "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
2418 prefix, 0, flags, 0, 0, 0,
2419 mask, 0, 0, 0);
2473 2420
2474 if (trie_main) 2421 seq_printf(seq, "%-127s\n", bf);
2475 trie_dump_seq(seq, trie_main); 2422 }
2476 } else {
2477 snprintf(bf, sizeof(bf),
2478 "*\t%08X\t%08X", 200, 400);
2479 seq_printf(seq, "%-127s\n", bf);
2480 } 2423 }
2481 2424
2482 return 0; 2425 return 0;
2483} 2426}
2484 2427
2485static struct seq_operations fib_trie_seq_ops = { 2428static struct seq_operations fib_route_seq_ops = {
2486 .start = fib_trie_seq_start, 2429 .start = fib_trie_seq_start,
2487 .next = fib_trie_seq_next, 2430 .next = fib_trie_seq_next,
2488 .stop = fib_trie_seq_stop, 2431 .stop = fib_trie_seq_stop,
2489 .show = fib_trie_seq_show, 2432 .show = fib_route_seq_show,
2490}; 2433};
2491 2434
2492static int fib_trie_seq_open(struct inode *inode, struct file *file) 2435static int fib_route_seq_open(struct inode *inode, struct file *file)
2493{ 2436{
2494 struct seq_file *seq; 2437 struct seq_file *seq;
2495 int rc = -ENOMEM; 2438 int rc = -ENOMEM;
2439 struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
2496 2440
2497 rc = seq_open(file, &fib_trie_seq_ops); 2441 if (!s)
2442 goto out;
2443
2444 rc = seq_open(file, &fib_route_seq_ops);
2498 if (rc) 2445 if (rc)
2499 goto out_kfree; 2446 goto out_kfree;
2500 2447
2501 seq = file->private_data; 2448 seq = file->private_data;
2449 seq->private = s;
2450 memset(s, 0, sizeof(*s));
2502out: 2451out:
2503 return rc; 2452 return rc;
2504out_kfree: 2453out_kfree:
2454 kfree(s);
2505 goto out; 2455 goto out;
2506} 2456}
2507 2457
2508static struct file_operations fib_trie_seq_fops = { 2458static struct file_operations fib_route_fops = {
2509 .owner = THIS_MODULE, 2459 .owner = THIS_MODULE,
2510 .open = fib_trie_seq_open, 2460 .open = fib_route_seq_open,
2511 .read = seq_read, 2461 .read = seq_read,
2512 .llseek = seq_lseek, 2462 .llseek = seq_lseek,
2513 .release= seq_release_private, 2463 .release = seq_release_private,
2514}; 2464};
2515 2465
2516int __init fib_proc_init(void) 2466int __init fib_proc_init(void)
2517{ 2467{
2518 if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops)) 2468 if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops))
2519 return -ENOMEM; 2469 goto out1;
2470
2471 if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops))
2472 goto out2;
2473
2474 if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops))
2475 goto out3;
2476
2520 return 0; 2477 return 0;
2478
2479out3:
2480 proc_net_remove("fib_triestat");
2481out2:
2482 proc_net_remove("fib_trie");
2483out1:
2484 return -ENOMEM;
2521} 2485}
2522 2486
2523void __init fib_proc_exit(void) 2487void __init fib_proc_exit(void)
2524{ 2488{
2525 proc_net_remove("fib_trie"); 2489 proc_net_remove("fib_trie");
2490 proc_net_remove("fib_triestat");
2491 proc_net_remove("route");
2526} 2492}
2527 2493
2528#endif /* CONFIG_PROC_FS */ 2494#endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f84ba9c96551..2fc3fd38924f 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -100,8 +100,7 @@ DEFINE_SPINLOCK(inet_peer_unused_lock);
100#define PEER_MAX_CLEANUP_WORK 30 100#define PEER_MAX_CLEANUP_WORK 30
101 101
102static void peer_check_expire(unsigned long dummy); 102static void peer_check_expire(unsigned long dummy);
103static struct timer_list peer_periodic_timer = 103static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
104 TIMER_INITIALIZER(peer_check_expire, 0, 0);
105 104
106/* Exported for sysctl_net_ipv4. */ 105/* Exported for sysctl_net_ipv4. */
107int inet_peer_gc_mintime = 10 * HZ, 106int inet_peer_gc_mintime = 10 * HZ,
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 2b5cf9c51309..bb7246683b74 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -104,12 +104,28 @@ out:
104static struct ip_conntrack_helper helper = { 104static struct ip_conntrack_helper helper = {
105 .name = "netbios-ns", 105 .name = "netbios-ns",
106 .tuple = { 106 .tuple = {
107 .src.u.udp.port = __constant_htons(137), 107 .src = {
108 .dst.protonum = IPPROTO_UDP, 108 .u = {
109 .udp = {
110 .port = __constant_htons(137),
111 }
112 }
113 },
114 .dst = {
115 .protonum = IPPROTO_UDP,
116 },
109 }, 117 },
110 .mask = { 118 .mask = {
111 .src.u.udp.port = 0xFFFF, 119 .src = {
112 .dst.protonum = 0xFF, 120 .u = {
121 .udp = {
122 .port = 0xFFFF,
123 }
124 }
125 },
126 .dst = {
127 .protonum = 0xFF,
128 },
113 }, 129 },
114 .max_expected = 1, 130 .max_expected = 1,
115 .me = THIS_MODULE, 131 .me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f115a84a4ac6..f057025a719e 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
92 fl.fl_ip_sport = tcph->dest; 92 fl.fl_ip_sport = tcph->dest;
93 fl.fl_ip_dport = tcph->source; 93 fl.fl_ip_dport = tcph->source;
94 94
95 if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) { 95 xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
96 dst_release(&rt->u.dst);
97 rt = NULL;
98 }
99 96
100 return rt; 97 return rt;
101} 98}
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index c1889f88262b..0cee2862ed85 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/file.h> 13#include <linux/file.h>
14#include <linux/rcupdate.h>
14#include <net/sock.h> 15#include <net/sock.h>
15 16
16#include <linux/netfilter_ipv4/ipt_owner.h> 17#include <linux/netfilter_ipv4/ipt_owner.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c0b14e3beec..8549f26e2495 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1760,6 +1760,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
1760 goto cleanup; 1760 goto cleanup;
1761 } 1761 }
1762 1762
1763 atomic_set(&rth->u.dst.__refcnt, 1);
1763 rth->u.dst.flags= DST_HOST; 1764 rth->u.dst.flags= DST_HOST;
1764#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1765#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1765 if (res->fi->fib_nhs > 1) 1766 if (res->fi->fib_nhs > 1)
@@ -1820,7 +1821,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
1820 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); 1821 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
1821 if (err) 1822 if (err)
1822 return err; 1823 return err;
1823 atomic_set(&rth->u.dst.__refcnt, 1);
1824 1824
1825 /* put it into the cache */ 1825 /* put it into the cache */
1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
@@ -1834,8 +1834,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1834 u32 daddr, u32 saddr, u32 tos) 1834 u32 daddr, u32 saddr, u32 tos)
1835{ 1835{
1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1837 struct rtable* rth = NULL; 1837 struct rtable* rth = NULL, *rtres;
1838 unsigned char hop, hopcount, lasthop; 1838 unsigned char hop, hopcount;
1839 int err = -EINVAL; 1839 int err = -EINVAL;
1840 unsigned int hash; 1840 unsigned int hash;
1841 1841
@@ -1844,8 +1844,6 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1844 else 1844 else
1845 hopcount = 1; 1845 hopcount = 1;
1846 1846
1847 lasthop = hopcount - 1;
1848
1849 /* distinguish between multipath and singlepath */ 1847 /* distinguish between multipath and singlepath */
1850 if (hopcount < 2) 1848 if (hopcount < 2)
1851 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, 1849 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
@@ -1855,6 +1853,10 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1855 for (hop = 0; hop < hopcount; hop++) { 1853 for (hop = 0; hop < hopcount; hop++) {
1856 res->nh_sel = hop; 1854 res->nh_sel = hop;
1857 1855
1856 /* put reference to previous result */
1857 if (hop)
1858 ip_rt_put(rtres);
1859
1858 /* create a routing cache entry */ 1860 /* create a routing cache entry */
1859 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, 1861 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
1860 &rth); 1862 &rth);
@@ -1863,7 +1865,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1863 1865
1864 /* put it into the cache */ 1866 /* put it into the cache */
1865 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1867 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
1866 err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1868 err = rt_intern_hash(hash, rth, &rtres);
1867 if (err) 1869 if (err)
1868 return err; 1870 return err;
1869 1871
@@ -1873,13 +1875,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1873 FIB_RES_NETMASK(*res), 1875 FIB_RES_NETMASK(*res),
1874 res->prefixlen, 1876 res->prefixlen,
1875 &FIB_RES_NH(*res)); 1877 &FIB_RES_NH(*res));
1876
1877 /* only for the last hop the reference count is handled
1878 * outside
1879 */
1880 if (hop == lasthop)
1881 atomic_set(&(skb->dst->__refcnt), 1);
1882 } 1878 }
1879 skb->dst = &rtres->u.dst;
1883 return err; 1880 return err;
1884#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1881#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
1885 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos); 1882 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
@@ -2208,6 +2205,7 @@ static inline int __mkroute_output(struct rtable **result,
2208 goto cleanup; 2205 goto cleanup;
2209 } 2206 }
2210 2207
2208 atomic_set(&rth->u.dst.__refcnt, 1);
2211 rth->u.dst.flags= DST_HOST; 2209 rth->u.dst.flags= DST_HOST;
2212#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2210#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2213 if (res->fi) { 2211 if (res->fi) {
@@ -2290,8 +2288,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
2290 if (err == 0) { 2288 if (err == 0) {
2291 u32 tos = RT_FL_TOS(oldflp); 2289 u32 tos = RT_FL_TOS(oldflp);
2292 2290
2293 atomic_set(&rth->u.dst.__refcnt, 1);
2294
2295 hash = rt_hash_code(oldflp->fl4_dst, 2291 hash = rt_hash_code(oldflp->fl4_dst,
2296 oldflp->fl4_src ^ (oldflp->oif << 5), tos); 2292 oldflp->fl4_src ^ (oldflp->oif << 5), tos);
2297 err = rt_intern_hash(hash, rth, rp); 2293 err = rt_intern_hash(hash, rth, rp);
@@ -2326,6 +2322,10 @@ static inline int ip_mkroute_output(struct rtable** rp,
2326 dev2nexthop = FIB_RES_DEV(*res); 2322 dev2nexthop = FIB_RES_DEV(*res);
2327 dev_hold(dev2nexthop); 2323 dev_hold(dev2nexthop);
2328 2324
2325 /* put reference to previous result */
2326 if (hop)
2327 ip_rt_put(*rp);
2328
2329 err = __mkroute_output(&rth, res, fl, oldflp, 2329 err = __mkroute_output(&rth, res, fl, oldflp,
2330 dev2nexthop, flags); 2330 dev2nexthop, flags);
2331 2331
@@ -2350,7 +2350,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
2350 if (err != 0) 2350 if (err != 0)
2351 return err; 2351 return err;
2352 } 2352 }
2353 atomic_set(&(*rp)->u.dst.__refcnt, 1);
2354 return err; 2353 return err;
2355 } else { 2354 } else {
2356 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, 2355 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6094db5e11be..15e1134da1b2 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -499,7 +499,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
499 /* If this packet has been sent out already, we must 499 /* If this packet has been sent out already, we must
500 * adjust the various packet counters. 500 * adjust the various packet counters.
501 */ 501 */
502 if (after(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { 502 if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
503 int diff = old_factor - tcp_skb_pcount(skb) - 503 int diff = old_factor - tcp_skb_pcount(skb) -
504 tcp_skb_pcount(buff); 504 tcp_skb_pcount(buff);
505 505
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5beca7de86c..e0bd1013cb0d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
1141 if (ulen > len || ulen < sizeof(*uh)) 1141 if (ulen > len || ulen < sizeof(*uh))
1142 goto short_packet; 1142 goto short_packet;
1143 1143
1144 if (pskb_trim(skb, ulen)) 1144 if (pskb_trim_rcsum(skb, ulen))
1145 goto short_packet; 1145 goto short_packet;
1146 1146
1147 if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) 1147 if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6d6fb74f3b52..2fea3f4402a0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -123,8 +123,7 @@ DEFINE_RWLOCK(addrconf_lock);
123 123
124static void addrconf_verify(unsigned long); 124static void addrconf_verify(unsigned long);
125 125
126static struct timer_list addr_chk_timer = 126static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
127 TIMER_INITIALIZER(addrconf_verify, 0, 0);
128static DEFINE_SPINLOCK(addrconf_verify_lock); 127static DEFINE_SPINLOCK(addrconf_verify_lock);
129 128
130static void addrconf_join_anycast(struct inet6_ifaddr *ifp); 129static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 01468fab3d3d..cc518405b3e1 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,10 +175,8 @@ ipv4_connected:
175 if (final_p) 175 if (final_p)
176 ipv6_addr_copy(&fl.fl6_dst, final_p); 176 ipv6_addr_copy(&fl.fl6_dst, final_p);
177 177
178 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 178 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
179 dst_release(dst);
180 goto out; 179 goto out;
181 }
182 180
183 /* source address lookup done in ip6_dst_lookup */ 181 /* source address lookup done in ip6_dst_lookup */
184 182
@@ -390,32 +388,101 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
390 put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 388 put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
391 } 389 }
392 390
391 if (np->rxopt.bits.rxtclass) {
392 int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
393 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
394 }
395
393 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) { 396 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
394 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK; 397 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
395 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); 398 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
396 } 399 }
400
401 /* HbH is allowed only once */
397 if (np->rxopt.bits.hopopts && opt->hop) { 402 if (np->rxopt.bits.hopopts && opt->hop) {
398 u8 *ptr = skb->nh.raw + opt->hop; 403 u8 *ptr = skb->nh.raw + opt->hop;
399 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr); 404 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
400 } 405 }
401 if (np->rxopt.bits.dstopts && opt->dst0) { 406
407 if (opt->lastopt &&
408 (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
409 /*
410 * Silly enough, but we need to reparse in order to
411 * report extension headers (except for HbH)
412 * in order.
413 *
414 * Also note that IPV6_RECVRTHDRDSTOPTS is NOT
415 * (and WILL NOT be) defined because
416 * IPV6_RECVDSTOPTS is more generic. --yoshfuji
417 */
418 unsigned int off = sizeof(struct ipv6hdr);
419 u8 nexthdr = skb->nh.ipv6h->nexthdr;
420
421 while (off <= opt->lastopt) {
422 unsigned len;
423 u8 *ptr = skb->nh.raw + off;
424
425 switch(nexthdr) {
426 case IPPROTO_DSTOPTS:
427 nexthdr = ptr[0];
428 len = (ptr[1] + 1) << 3;
429 if (np->rxopt.bits.dstopts)
430 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
431 break;
432 case IPPROTO_ROUTING:
433 nexthdr = ptr[0];
434 len = (ptr[1] + 1) << 3;
435 if (np->rxopt.bits.srcrt)
436 put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
437 break;
438 case IPPROTO_AH:
439 nexthdr = ptr[0];
440 len = (ptr[1] + 1) << 2;
441 break;
442 default:
443 nexthdr = ptr[0];
444 len = (ptr[1] + 1) << 3;
445 break;
446 }
447
448 off += len;
449 }
450 }
451
452 /* socket options in old style */
453 if (np->rxopt.bits.rxoinfo) {
454 struct in6_pktinfo src_info;
455
456 src_info.ipi6_ifindex = opt->iif;
457 ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
458 put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
459 }
460 if (np->rxopt.bits.rxohlim) {
461 int hlim = skb->nh.ipv6h->hop_limit;
462 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
463 }
464 if (np->rxopt.bits.ohopopts && opt->hop) {
465 u8 *ptr = skb->nh.raw + opt->hop;
466 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
467 }
468 if (np->rxopt.bits.odstopts && opt->dst0) {
402 u8 *ptr = skb->nh.raw + opt->dst0; 469 u8 *ptr = skb->nh.raw + opt->dst0;
403 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr); 470 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
404 } 471 }
405 if (np->rxopt.bits.srcrt && opt->srcrt) { 472 if (np->rxopt.bits.osrcrt && opt->srcrt) {
406 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt); 473 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
407 put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr); 474 put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
408 } 475 }
409 if (np->rxopt.bits.dstopts && opt->dst1) { 476 if (np->rxopt.bits.odstopts && opt->dst1) {
410 u8 *ptr = skb->nh.raw + opt->dst1; 477 u8 *ptr = skb->nh.raw + opt->dst1;
411 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr); 478 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
412 } 479 }
413 return 0; 480 return 0;
414} 481}
415 482
416int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, 483int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
417 struct ipv6_txoptions *opt, 484 struct ipv6_txoptions *opt,
418 int *hlimit) 485 int *hlimit, int *tclass)
419{ 486{
420 struct in6_pktinfo *src_info; 487 struct in6_pktinfo *src_info;
421 struct cmsghdr *cmsg; 488 struct cmsghdr *cmsg;
@@ -438,6 +505,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
438 505
439 switch (cmsg->cmsg_type) { 506 switch (cmsg->cmsg_type) {
440 case IPV6_PKTINFO: 507 case IPV6_PKTINFO:
508 case IPV6_2292PKTINFO:
441 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) { 509 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
442 err = -EINVAL; 510 err = -EINVAL;
443 goto exit_f; 511 goto exit_f;
@@ -492,6 +560,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
492 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg); 560 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
493 break; 561 break;
494 562
563 case IPV6_2292HOPOPTS:
495 case IPV6_HOPOPTS: 564 case IPV6_HOPOPTS:
496 if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) { 565 if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
497 err = -EINVAL; 566 err = -EINVAL;
@@ -512,7 +581,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
512 opt->hopopt = hdr; 581 opt->hopopt = hdr;
513 break; 582 break;
514 583
515 case IPV6_DSTOPTS: 584 case IPV6_2292DSTOPTS:
516 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) { 585 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
517 err = -EINVAL; 586 err = -EINVAL;
518 goto exit_f; 587 goto exit_f;
@@ -536,6 +605,33 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
536 opt->dst1opt = hdr; 605 opt->dst1opt = hdr;
537 break; 606 break;
538 607
608 case IPV6_DSTOPTS:
609 case IPV6_RTHDRDSTOPTS:
610 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
611 err = -EINVAL;
612 goto exit_f;
613 }
614
615 hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
616 len = ((hdr->hdrlen + 1) << 3);
617 if (cmsg->cmsg_len < CMSG_LEN(len)) {
618 err = -EINVAL;
619 goto exit_f;
620 }
621 if (!capable(CAP_NET_RAW)) {
622 err = -EPERM;
623 goto exit_f;
624 }
625 if (cmsg->cmsg_type == IPV6_DSTOPTS) {
626 opt->opt_flen += len;
627 opt->dst1opt = hdr;
628 } else {
629 opt->opt_nflen += len;
630 opt->dst0opt = hdr;
631 }
632 break;
633
634 case IPV6_2292RTHDR:
539 case IPV6_RTHDR: 635 case IPV6_RTHDR:
540 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) { 636 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
541 err = -EINVAL; 637 err = -EINVAL;
@@ -568,7 +664,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
568 opt->opt_nflen += len; 664 opt->opt_nflen += len;
569 opt->srcrt = rthdr; 665 opt->srcrt = rthdr;
570 666
571 if (opt->dst1opt) { 667 if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
572 int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3); 668 int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
573 669
574 opt->opt_nflen += dsthdrlen; 670 opt->opt_nflen += dsthdrlen;
@@ -579,6 +675,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
579 675
580 break; 676 break;
581 677
678 case IPV6_2292HOPLIMIT:
582 case IPV6_HOPLIMIT: 679 case IPV6_HOPLIMIT:
583 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { 680 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
584 err = -EINVAL; 681 err = -EINVAL;
@@ -588,6 +685,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
588 *hlimit = *(int *)CMSG_DATA(cmsg); 685 *hlimit = *(int *)CMSG_DATA(cmsg);
589 break; 686 break;
590 687
688 case IPV6_TCLASS:
689 {
690 int tc;
691
692 err = -EINVAL;
693 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
694 goto exit_f;
695 }
696
697 tc = *(int *)CMSG_DATA(cmsg);
698 if (tc < 0 || tc > 0xff)
699 goto exit_f;
700
701 err = 0;
702 *tclass = tc;
703
704 break;
705 }
591 default: 706 default:
592 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", 707 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
593 cmsg->cmsg_type); 708 cmsg->cmsg_type);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5be6da2584ee..47122728212a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -164,6 +164,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
164 return -1; 164 return -1;
165 } 165 }
166 166
167 opt->lastopt = skb->h.raw - skb->nh.raw;
167 opt->dst1 = skb->h.raw - skb->nh.raw; 168 opt->dst1 = skb->h.raw - skb->nh.raw;
168 169
169 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { 170 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
@@ -243,6 +244,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
243 244
244looped_back: 245looped_back:
245 if (hdr->segments_left == 0) { 246 if (hdr->segments_left == 0) {
247 opt->lastopt = skb->h.raw - skb->nh.raw;
246 opt->srcrt = skb->h.raw - skb->nh.raw; 248 opt->srcrt = skb->h.raw - skb->nh.raw;
247 skb->h.raw += (hdr->hdrlen + 1) << 3; 249 skb->h.raw += (hdr->hdrlen + 1) << 3;
248 opt->dst0 = opt->dst1; 250 opt->dst0 = opt->dst1;
@@ -459,11 +461,10 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
459 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 461 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
460 goto drop; 462 goto drop;
461 } 463 }
462 if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { 464
463 __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr)); 465 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
464 if (skb->ip_summed == CHECKSUM_HW) 466 goto drop;
465 skb->ip_summed = CHECKSUM_NONE; 467
466 }
467 return 1; 468 return 1;
468 469
469drop: 470drop:
@@ -539,10 +540,15 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
539 u8 *proto, 540 u8 *proto,
540 struct in6_addr **daddr) 541 struct in6_addr **daddr)
541{ 542{
542 if (opt->srcrt) 543 if (opt->srcrt) {
543 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr); 544 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
544 if (opt->dst0opt) 545 /*
545 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt); 546 * IPV6_RTHDRDSTOPTS is ignored
547 * unless IPV6_RTHDR is set (RFC3542).
548 */
549 if (opt->dst0opt)
550 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
551 }
546 if (opt->hopopt) 552 if (opt->hopopt)
547 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt); 553 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
548} 554}
@@ -573,3 +579,97 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
573 } 579 }
574 return opt2; 580 return opt2;
575} 581}
582
583static int ipv6_renew_option(void *ohdr,
584 struct ipv6_opt_hdr __user *newopt, int newoptlen,
585 int inherit,
586 struct ipv6_opt_hdr **hdr,
587 char **p)
588{
589 if (inherit) {
590 if (ohdr) {
591 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
592 *hdr = (struct ipv6_opt_hdr *)*p;
593 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
594 }
595 } else {
596 if (newopt) {
597 if (copy_from_user(*p, newopt, newoptlen))
598 return -EFAULT;
599 *hdr = (struct ipv6_opt_hdr *)*p;
600 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
601 return -EINVAL;
602 *p += CMSG_ALIGN(newoptlen);
603 }
604 }
605 return 0;
606}
607
608struct ipv6_txoptions *
609ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
610 int newtype,
611 struct ipv6_opt_hdr __user *newopt, int newoptlen)
612{
613 int tot_len = 0;
614 char *p;
615 struct ipv6_txoptions *opt2;
616 int err;
617
618 if (newtype != IPV6_HOPOPTS && opt->hopopt)
619 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
620 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
621 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
622 if (newtype != IPV6_RTHDR && opt->srcrt)
623 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
624 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
625 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
626 if (newopt && newoptlen)
627 tot_len += CMSG_ALIGN(newoptlen);
628
629 if (!tot_len)
630 return NULL;
631
632 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
633 if (!opt2)
634 return ERR_PTR(-ENOBUFS);
635
636 memset(opt2, 0, tot_len);
637
638 opt2->tot_len = tot_len;
639 p = (char *)(opt2 + 1);
640
641 err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
642 newtype != IPV6_HOPOPTS,
643 &opt2->hopopt, &p);
644 if (err)
645 goto out;
646
647 err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
648 newtype != IPV6_RTHDRDSTOPTS,
649 &opt2->dst0opt, &p);
650 if (err)
651 goto out;
652
653 err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
654 newtype != IPV6_RTHDR,
655 (struct ipv6_opt_hdr **)opt2->srcrt, &p);
656 if (err)
657 goto out;
658
659 err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
660 newtype != IPV6_DSTOPTS,
661 &opt2->dst1opt, &p);
662 if (err)
663 goto out;
664
665 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
666 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
667 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
668 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
669
670 return opt2;
671out:
672 sock_kfree_s(sk, p, tot_len);
673 return ERR_PTR(err);
674}
675
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fa8f1bb0aa52..b7185fb3377c 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
287 int iif = 0; 287 int iif = 0;
288 int addr_type = 0; 288 int addr_type = 0;
289 int len; 289 int len;
290 int hlimit; 290 int hlimit, tclass;
291 int err = 0; 291 int err = 0;
292 292
293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail) 293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
374 if (err) 374 if (err)
375 goto out; 375 goto out;
376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
377 goto out_dst_release; 377 goto out;
378 378
379 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 379 if (ipv6_addr_is_multicast(&fl.fl6_dst))
380 hlimit = np->mcast_hops; 380 hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
385 if (hlimit < 0) 385 if (hlimit < 0)
386 hlimit = ipv6_get_hoplimit(dst->dev); 386 hlimit = ipv6_get_hoplimit(dst->dev);
387 387
388 tclass = np->cork.tclass;
389 if (tclass < 0)
390 tclass = 0;
391
388 msg.skb = skb; 392 msg.skb = skb;
389 msg.offset = skb->nh.raw - skb->data; 393 msg.offset = skb->nh.raw - skb->data;
390 394
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
400 err = ip6_append_data(sk, icmpv6_getfrag, &msg, 404 err = ip6_append_data(sk, icmpv6_getfrag, &msg,
401 len + sizeof(struct icmp6hdr), 405 len + sizeof(struct icmp6hdr),
402 sizeof(struct icmp6hdr), 406 sizeof(struct icmp6hdr),
403 hlimit, NULL, &fl, (struct rt6_info*)dst, 407 hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
404 MSG_DONTWAIT); 408 MSG_DONTWAIT);
405 if (err) { 409 if (err) {
406 ip6_flush_pending_frames(sk); 410 ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
434 struct dst_entry *dst; 438 struct dst_entry *dst;
435 int err = 0; 439 int err = 0;
436 int hlimit; 440 int hlimit;
441 int tclass;
437 442
438 saddr = &skb->nh.ipv6h->daddr; 443 saddr = &skb->nh.ipv6h->daddr;
439 444
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
464 if (err) 469 if (err)
465 goto out; 470 goto out;
466 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 471 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
467 goto out_dst_release; 472 goto out;
468 473
469 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 474 if (ipv6_addr_is_multicast(&fl.fl6_dst))
470 hlimit = np->mcast_hops; 475 hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
475 if (hlimit < 0) 480 if (hlimit < 0)
476 hlimit = ipv6_get_hoplimit(dst->dev); 481 hlimit = ipv6_get_hoplimit(dst->dev);
477 482
483 tclass = np->cork.tclass;
484 if (tclass < 0)
485 tclass = 0;
486
478 idev = in6_dev_get(skb->dev); 487 idev = in6_dev_get(skb->dev);
479 488
480 msg.skb = skb; 489 msg.skb = skb;
481 msg.offset = 0; 490 msg.offset = 0;
482 491
483 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 492 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
484 sizeof(struct icmp6hdr), hlimit, NULL, &fl, 493 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
485 (struct rt6_info*)dst, MSG_DONTWAIT); 494 (struct rt6_info*)dst, MSG_DONTWAIT);
486 495
487 if (err) { 496 if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
496out_put: 505out_put:
497 if (likely(idev != NULL)) 506 if (likely(idev != NULL))
498 in6_dev_put(idev); 507 in6_dev_put(idev);
499out_dst_release:
500 dst_release(dst); 508 dst_release(dst);
501out: 509out:
502 icmpv6_xmit_unlock(); 510 icmpv6_xmit_unlock();
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 16af874c9e8f..4fcc5a7acf6e 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -92,7 +92,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
92 92
93static __u32 rt_sernum; 93static __u32 rt_sernum;
94 94
95static struct timer_list ip6_fib_timer = TIMER_INITIALIZER(fib6_run_gc, 0, 0); 95static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
96 96
97struct fib6_walker_t fib6_walker_list = { 97struct fib6_walker_t fib6_walker_list = {
98 .prev = &fib6_walker_list, 98 .prev = &fib6_walker_list,
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b6c73da5ff35..f841bde30c18 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -50,7 +50,7 @@ static atomic_t fl_size = ATOMIC_INIT(0);
50static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1]; 50static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1];
51 51
52static void ip6_fl_gc(unsigned long dummy); 52static void ip6_fl_gc(unsigned long dummy);
53static struct timer_list ip6_fl_gc_timer = TIMER_INITIALIZER(ip6_fl_gc, 0, 0); 53static DEFINE_TIMER(ip6_fl_gc_timer, ip6_fl_gc, 0, 0);
54 54
55/* FL hash table lock: it protects only of GC */ 55/* FL hash table lock: it protects only of GC */
56 56
@@ -225,16 +225,20 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
225 struct ip6_flowlabel * fl, 225 struct ip6_flowlabel * fl,
226 struct ipv6_txoptions * fopt) 226 struct ipv6_txoptions * fopt)
227{ 227{
228 struct ipv6_txoptions * fl_opt = fl->opt; 228 struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
229 229
230 if (fopt == NULL || fopt->opt_flen == 0) 230 if (fopt == NULL || fopt->opt_flen == 0) {
231 return fl_opt; 231 if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
232 return fl_opt;
233 }
232 234
233 if (fl_opt != NULL) { 235 if (fl_opt != NULL) {
234 opt_space->hopopt = fl_opt->hopopt; 236 opt_space->hopopt = fl_opt->hopopt;
235 opt_space->dst0opt = fl_opt->dst0opt; 237 opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
236 opt_space->srcrt = fl_opt->srcrt; 238 opt_space->srcrt = fl_opt->srcrt;
237 opt_space->opt_nflen = fl_opt->opt_nflen; 239 opt_space->opt_nflen = fl_opt->opt_nflen;
240 if (fl_opt->dst0opt && !fl_opt->srcrt)
241 opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
238 } else { 242 } else {
239 if (fopt->opt_nflen == 0) 243 if (fopt->opt_nflen == 0)
240 return fopt; 244 return fopt;
@@ -310,7 +314,7 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
310 msg.msg_control = (void*)(fl->opt+1); 314 msg.msg_control = (void*)(fl->opt+1);
311 flowi.oif = 0; 315 flowi.oif = 0;
312 316
313 err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk); 317 err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
314 if (err) 318 if (err)
315 goto done; 319 goto done;
316 err = -EINVAL; 320 err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 01ef94f7c7f1..2f589f24c093 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -166,7 +166,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
166 struct ipv6hdr *hdr; 166 struct ipv6hdr *hdr;
167 u8 proto = fl->proto; 167 u8 proto = fl->proto;
168 int seg_len = skb->len; 168 int seg_len = skb->len;
169 int hlimit; 169 int hlimit, tclass;
170 u32 mtu; 170 u32 mtu;
171 171
172 if (opt) { 172 if (opt) {
@@ -202,7 +202,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
202 * Fill in the IPv6 header 202 * Fill in the IPv6 header
203 */ 203 */
204 204
205 *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
206 hlimit = -1; 205 hlimit = -1;
207 if (np) 206 if (np)
208 hlimit = np->hop_limit; 207 hlimit = np->hop_limit;
@@ -211,6 +210,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
211 if (hlimit < 0) 210 if (hlimit < 0)
212 hlimit = ipv6_get_hoplimit(dst->dev); 211 hlimit = ipv6_get_hoplimit(dst->dev);
213 212
213 tclass = -1;
214 if (np)
215 tclass = np->tclass;
216 if (tclass < 0)
217 tclass = 0;
218
219 *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
220
214 hdr->payload_len = htons(seg_len); 221 hdr->payload_len = htons(seg_len);
215 hdr->nexthdr = proto; 222 hdr->nexthdr = proto;
216 hdr->hop_limit = hlimit; 223 hdr->hop_limit = hlimit;
@@ -762,10 +769,11 @@ out_err_release:
762 return err; 769 return err;
763} 770}
764 771
765int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), 772int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
766 void *from, int length, int transhdrlen, 773 int offset, int len, int odd, struct sk_buff *skb),
767 int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt, 774 void *from, int length, int transhdrlen,
768 unsigned int flags) 775 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
776 struct rt6_info *rt, unsigned int flags)
769{ 777{
770 struct inet_sock *inet = inet_sk(sk); 778 struct inet_sock *inet = inet_sk(sk);
771 struct ipv6_pinfo *np = inet6_sk(sk); 779 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -803,6 +811,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
803 np->cork.rt = rt; 811 np->cork.rt = rt;
804 inet->cork.fl = *fl; 812 inet->cork.fl = *fl;
805 np->cork.hop_limit = hlimit; 813 np->cork.hop_limit = hlimit;
814 np->cork.tclass = tclass;
806 inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path); 815 inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path);
807 if (dst_allfrag(rt->u.dst.path)) 816 if (dst_allfrag(rt->u.dst.path))
808 inet->cork.flags |= IPCORK_ALLFRAG; 817 inet->cork.flags |= IPCORK_ALLFRAG;
@@ -1084,7 +1093,8 @@ int ip6_push_pending_frames(struct sock *sk)
1084 1093
1085 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); 1094 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
1086 1095
1087 *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000); 1096 *(u32*)hdr = fl->fl6_flowlabel |
1097 htonl(0x60000000 | ((int)np->cork.tclass << 20));
1088 1098
1089 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) 1099 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
1090 hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 1100 hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 09613729404c..cf94372d1af3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -673,11 +673,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
673 673
674 if ((dst = ip6_tnl_dst_check(t)) != NULL) 674 if ((dst = ip6_tnl_dst_check(t)) != NULL)
675 dst_hold(dst); 675 dst_hold(dst);
676 else 676 else {
677 dst = ip6_route_output(NULL, &fl); 677 dst = ip6_route_output(NULL, &fl);
678 678
679 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0) 679 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
680 goto tx_err_link_failure; 680 goto tx_err_link_failure;
681 }
681 682
682 tdev = dst->dev; 683 tdev = dst->dev;
683 684
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 76466af8331e..8567873d0dd8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -210,39 +210,139 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
210 retv = 0; 210 retv = 0;
211 break; 211 break;
212 212
213 case IPV6_PKTINFO: 213 case IPV6_RECVPKTINFO:
214 np->rxopt.bits.rxinfo = valbool; 214 np->rxopt.bits.rxinfo = valbool;
215 retv = 0; 215 retv = 0;
216 break; 216 break;
217
218 case IPV6_2292PKTINFO:
219 np->rxopt.bits.rxoinfo = valbool;
220 retv = 0;
221 break;
217 222
218 case IPV6_HOPLIMIT: 223 case IPV6_RECVHOPLIMIT:
219 np->rxopt.bits.rxhlim = valbool; 224 np->rxopt.bits.rxhlim = valbool;
220 retv = 0; 225 retv = 0;
221 break; 226 break;
222 227
223 case IPV6_RTHDR: 228 case IPV6_2292HOPLIMIT:
229 np->rxopt.bits.rxohlim = valbool;
230 retv = 0;
231 break;
232
233 case IPV6_RECVRTHDR:
224 if (val < 0 || val > 2) 234 if (val < 0 || val > 2)
225 goto e_inval; 235 goto e_inval;
226 np->rxopt.bits.srcrt = val; 236 np->rxopt.bits.srcrt = val;
227 retv = 0; 237 retv = 0;
228 break; 238 break;
229 239
230 case IPV6_HOPOPTS: 240 case IPV6_2292RTHDR:
241 if (val < 0 || val > 2)
242 goto e_inval;
243 np->rxopt.bits.osrcrt = val;
244 retv = 0;
245 break;
246
247 case IPV6_RECVHOPOPTS:
231 np->rxopt.bits.hopopts = valbool; 248 np->rxopt.bits.hopopts = valbool;
232 retv = 0; 249 retv = 0;
233 break; 250 break;
234 251
235 case IPV6_DSTOPTS: 252 case IPV6_2292HOPOPTS:
253 np->rxopt.bits.ohopopts = valbool;
254 retv = 0;
255 break;
256
257 case IPV6_RECVDSTOPTS:
236 np->rxopt.bits.dstopts = valbool; 258 np->rxopt.bits.dstopts = valbool;
237 retv = 0; 259 retv = 0;
238 break; 260 break;
239 261
262 case IPV6_2292DSTOPTS:
263 np->rxopt.bits.odstopts = valbool;
264 retv = 0;
265 break;
266
267 case IPV6_TCLASS:
268 if (val < 0 || val > 0xff)
269 goto e_inval;
270 np->tclass = val;
271 retv = 0;
272 break;
273
274 case IPV6_RECVTCLASS:
275 np->rxopt.bits.rxtclass = valbool;
276 retv = 0;
277 break;
278
240 case IPV6_FLOWINFO: 279 case IPV6_FLOWINFO:
241 np->rxopt.bits.rxflow = valbool; 280 np->rxopt.bits.rxflow = valbool;
242 retv = 0; 281 retv = 0;
243 break; 282 break;
244 283
245 case IPV6_PKTOPTIONS: 284 case IPV6_HOPOPTS:
285 case IPV6_RTHDRDSTOPTS:
286 case IPV6_RTHDR:
287 case IPV6_DSTOPTS:
288 {
289 struct ipv6_txoptions *opt;
290 if (optlen == 0)
291 optval = 0;
292
293 /* hop-by-hop / destination options are privileged option */
294 retv = -EPERM;
295 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
296 break;
297
298 retv = -EINVAL;
299 if (optlen & 0x7 || optlen > 8 * 255)
300 break;
301
302 opt = ipv6_renew_options(sk, np->opt, optname,
303 (struct ipv6_opt_hdr __user *)optval,
304 optlen);
305 if (IS_ERR(opt)) {
306 retv = PTR_ERR(opt);
307 break;
308 }
309
310 /* routing header option needs extra check */
311 if (optname == IPV6_RTHDR && opt->srcrt) {
312 struct ipv6_rt_hdr *rthdr = opt->srcrt;
313 if (rthdr->type)
314 goto sticky_done;
315 if ((rthdr->hdrlen & 1) ||
316 (rthdr->hdrlen >> 1) != rthdr->segments_left)
317 goto sticky_done;
318 }
319
320 retv = 0;
321 if (sk->sk_type == SOCK_STREAM) {
322 if (opt) {
323 struct tcp_sock *tp = tcp_sk(sk);
324 if (!((1 << sk->sk_state) &
325 (TCPF_LISTEN | TCPF_CLOSE))
326 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
327 tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
328 tcp_sync_mss(sk, tp->pmtu_cookie);
329 }
330 }
331 opt = xchg(&np->opt, opt);
332 sk_dst_reset(sk);
333 } else {
334 write_lock(&sk->sk_dst_lock);
335 opt = xchg(&np->opt, opt);
336 write_unlock(&sk->sk_dst_lock);
337 sk_dst_reset(sk);
338 }
339sticky_done:
340 if (opt)
341 sock_kfree_s(sk, opt, opt->tot_len);
342 break;
343 }
344
345 case IPV6_2292PKTOPTIONS:
246 { 346 {
247 struct ipv6_txoptions *opt = NULL; 347 struct ipv6_txoptions *opt = NULL;
248 struct msghdr msg; 348 struct msghdr msg;
@@ -276,7 +376,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
276 msg.msg_controllen = optlen; 376 msg.msg_controllen = optlen;
277 msg.msg_control = (void*)(opt+1); 377 msg.msg_control = (void*)(opt+1);
278 378
279 retv = datagram_send_ctl(&msg, &fl, opt, &junk); 379 retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
280 if (retv) 380 if (retv)
281 goto done; 381 goto done;
282update: 382update:
@@ -529,6 +629,17 @@ e_inval:
529 return -EINVAL; 629 return -EINVAL;
530} 630}
531 631
632int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
633 char __user *optval, int len)
634{
635 if (!hdr)
636 return 0;
637 len = min_t(int, len, ipv6_optlen(hdr));
638 if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
639 return -EFAULT;
640 return len;
641}
642
532int ipv6_getsockopt(struct sock *sk, int level, int optname, 643int ipv6_getsockopt(struct sock *sk, int level, int optname,
533 char __user *optval, int __user *optlen) 644 char __user *optval, int __user *optlen)
534{ 645{
@@ -567,7 +678,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
567 return err; 678 return err;
568 } 679 }
569 680
570 case IPV6_PKTOPTIONS: 681 case IPV6_2292PKTOPTIONS:
571 { 682 {
572 struct msghdr msg; 683 struct msghdr msg;
573 struct sk_buff *skb; 684 struct sk_buff *skb;
@@ -601,6 +712,16 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
601 int hlim = np->mcast_hops; 712 int hlim = np->mcast_hops;
602 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 713 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
603 } 714 }
715 if (np->rxopt.bits.rxoinfo) {
716 struct in6_pktinfo src_info;
717 src_info.ipi6_ifindex = np->mcast_oif;
718 ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
719 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
720 }
721 if (np->rxopt.bits.rxohlim) {
722 int hlim = np->mcast_hops;
723 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
724 }
604 } 725 }
605 len -= msg.msg_controllen; 726 len -= msg.msg_controllen;
606 return put_user(len, optlen); 727 return put_user(len, optlen);
@@ -625,26 +746,67 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
625 val = np->ipv6only; 746 val = np->ipv6only;
626 break; 747 break;
627 748
628 case IPV6_PKTINFO: 749 case IPV6_RECVPKTINFO:
629 val = np->rxopt.bits.rxinfo; 750 val = np->rxopt.bits.rxinfo;
630 break; 751 break;
631 752
632 case IPV6_HOPLIMIT: 753 case IPV6_2292PKTINFO:
754 val = np->rxopt.bits.rxoinfo;
755 break;
756
757 case IPV6_RECVHOPLIMIT:
633 val = np->rxopt.bits.rxhlim; 758 val = np->rxopt.bits.rxhlim;
634 break; 759 break;
635 760
636 case IPV6_RTHDR: 761 case IPV6_2292HOPLIMIT:
762 val = np->rxopt.bits.rxohlim;
763 break;
764
765 case IPV6_RECVRTHDR:
637 val = np->rxopt.bits.srcrt; 766 val = np->rxopt.bits.srcrt;
638 break; 767 break;
639 768
769 case IPV6_2292RTHDR:
770 val = np->rxopt.bits.osrcrt;
771 break;
772
640 case IPV6_HOPOPTS: 773 case IPV6_HOPOPTS:
774 case IPV6_RTHDRDSTOPTS:
775 case IPV6_RTHDR:
776 case IPV6_DSTOPTS:
777 {
778
779 lock_sock(sk);
780 len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
781 optval, len);
782 release_sock(sk);
783 return put_user(len, optlen);
784 }
785
786 case IPV6_RECVHOPOPTS:
641 val = np->rxopt.bits.hopopts; 787 val = np->rxopt.bits.hopopts;
642 break; 788 break;
643 789
644 case IPV6_DSTOPTS: 790 case IPV6_2292HOPOPTS:
791 val = np->rxopt.bits.ohopopts;
792 break;
793
794 case IPV6_RECVDSTOPTS:
645 val = np->rxopt.bits.dstopts; 795 val = np->rxopt.bits.dstopts;
646 break; 796 break;
647 797
798 case IPV6_2292DSTOPTS:
799 val = np->rxopt.bits.odstopts;
800 break;
801
802 case IPV6_TCLASS:
803 val = np->tclass;
804 break;
805
806 case IPV6_RECVTCLASS:
807 val = np->rxopt.bits.rxtclass;
808 break;
809
648 case IPV6_FLOWINFO: 810 case IPV6_FLOWINFO:
649 val = np->rxopt.bits.rxflow; 811 val = np->rxopt.bits.rxflow;
650 break; 812 break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a7eae30f4554..555a31347eda 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -447,10 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
447 return; 447 return;
448 448
449 err = xfrm_lookup(&dst, &fl, NULL, 0); 449 err = xfrm_lookup(&dst, &fl, NULL, 0);
450 if (err < 0) { 450 if (err < 0)
451 dst_release(dst);
452 return; 451 return;
453 }
454 452
455 if (inc_opt) { 453 if (inc_opt) {
456 if (dev->addr_len) 454 if (dev->addr_len)
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
539 return; 537 return;
540 538
541 err = xfrm_lookup(&dst, &fl, NULL, 0); 539 err = xfrm_lookup(&dst, &fl, NULL, 0);
542 if (err < 0) { 540 if (err < 0)
543 dst_release(dst);
544 return; 541 return;
545 }
546 542
547 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 543 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
548 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); 544 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
@@ -616,10 +612,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
616 return; 612 return;
617 613
618 err = xfrm_lookup(&dst, &fl, NULL, 0); 614 err = xfrm_lookup(&dst, &fl, NULL, 0);
619 if (err < 0) { 615 if (err < 0)
620 dst_release(dst);
621 return; 616 return;
622 }
623 617
624 len = sizeof(struct icmp6hdr); 618 len = sizeof(struct icmp6hdr);
625 if (dev->addr_len) 619 if (dev->addr_len)
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1353 return; 1347 return;
1354 1348
1355 err = xfrm_lookup(&dst, &fl, NULL, 0); 1349 err = xfrm_lookup(&dst, &fl, NULL, 0);
1356 if (err) { 1350 if (err)
1357 dst_release(dst);
1358 return; 1351 return;
1359 }
1360 1352
1361 rt = (struct rt6_info *) dst; 1353 rt = (struct rt6_info *) dst;
1362 1354
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 14316c3ebde4..b03e87adca93 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb)
100 dst = ip6_route_output(NULL, &fl); 100 dst = ip6_route_output(NULL, &fl);
101 if (dst == NULL) 101 if (dst == NULL)
102 return; 102 return;
103 if (dst->error || 103 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
104 xfrm_lookup(&dst, &fl, NULL, 0)) {
105 dst_release(dst);
106 return; 104 return;
107 }
108 105
109 hh_len = (dst->dev->hard_header_len + 15)&~15; 106 hh_len = (dst->dev->hard_header_len + 15)&~15;
110 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr) 107 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 9b91decbfddb..4de4cdad4b7d 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/file.h> 13#include <linux/file.h>
14#include <linux/rcupdate.h>
14#include <net/sock.h> 15#include <net/sock.h>
15 16
16#include <linux/netfilter_ipv6/ip6t_owner.h> 17#include <linux/netfilter_ipv6/ip6t_owner.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed3a76b30fd9..5aa3691c578d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -655,6 +655,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
655 struct flowi fl; 655 struct flowi fl;
656 int addr_len = msg->msg_namelen; 656 int addr_len = msg->msg_namelen;
657 int hlimit = -1; 657 int hlimit = -1;
658 int tclass = -1;
658 u16 proto; 659 u16 proto;
659 int err; 660 int err;
660 661
@@ -740,7 +741,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
740 memset(opt, 0, sizeof(struct ipv6_txoptions)); 741 memset(opt, 0, sizeof(struct ipv6_txoptions));
741 opt->tot_len = sizeof(struct ipv6_txoptions); 742 opt->tot_len = sizeof(struct ipv6_txoptions);
742 743
743 err = datagram_send_ctl(msg, &fl, opt, &hlimit); 744 err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
744 if (err < 0) { 745 if (err < 0) {
745 fl6_sock_release(flowlabel); 746 fl6_sock_release(flowlabel);
746 return err; 747 return err;
@@ -755,8 +756,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
755 } 756 }
756 if (opt == NULL) 757 if (opt == NULL)
757 opt = np->opt; 758 opt = np->opt;
758 if (flowlabel) 759 opt = fl6_merge_options(&opt_space, flowlabel, opt);
759 opt = fl6_merge_options(&opt_space, flowlabel, opt);
760 760
761 fl.proto = proto; 761 fl.proto = proto;
762 rawv6_probe_proto_opt(&fl, msg); 762 rawv6_probe_proto_opt(&fl, msg);
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
782 if (final_p) 782 if (final_p)
783 ipv6_addr_copy(&fl.fl6_dst, final_p); 783 ipv6_addr_copy(&fl.fl6_dst, final_p);
784 784
785 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 785 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
786 dst_release(dst);
787 goto out; 786 goto out;
788 }
789 787
790 if (hlimit < 0) { 788 if (hlimit < 0) {
791 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 789 if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -798,6 +796,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
798 hlimit = ipv6_get_hoplimit(dst->dev); 796 hlimit = ipv6_get_hoplimit(dst->dev);
799 } 797 }
800 798
799 if (tclass < 0) {
800 tclass = np->cork.tclass;
801 if (tclass < 0)
802 tclass = 0;
803 }
804
801 if (msg->msg_flags&MSG_CONFIRM) 805 if (msg->msg_flags&MSG_CONFIRM)
802 goto do_confirm; 806 goto do_confirm;
803 807
@@ -806,8 +810,9 @@ back_from_confirm:
806 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags); 810 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
807 } else { 811 } else {
808 lock_sock(sk); 812 lock_sock(sk);
809 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0, 813 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
810 hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags); 814 len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
815 msg->msg_flags);
811 816
812 if (err) 817 if (err)
813 ip6_flush_pending_frames(sk); 818 ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 9d9e04344c77..e4fe9ee484dd 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -479,12 +479,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
479 /* Point into the IP datagram 'data' part. */ 479 /* Point into the IP datagram 'data' part. */
480 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) 480 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
481 goto err; 481 goto err;
482 if (end-offset < skb->len) { 482
483 if (pskb_trim(skb, end - offset)) 483 if (pskb_trim_rcsum(skb, end - offset))
484 goto err; 484 goto err;
485 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
486 skb->ip_summed = CHECKSUM_NONE;
487 }
488 485
489 /* Find out which fragments are in front and at the back of us 486 /* Find out which fragments are in front and at the back of us
490 * in the chain of fragments so far. We must know where to put 487 * in the chain of fragments so far. We must know where to put
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 794734f1d230..80643e6b346b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
632 if (final_p) 632 if (final_p)
633 ipv6_addr_copy(&fl.fl6_dst, final_p); 633 ipv6_addr_copy(&fl.fl6_dst, final_p);
634 634
635 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 635 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
636 dst_release(dst);
637 goto failure; 636 goto failure;
638 }
639 637
640 if (saddr == NULL) { 638 if (saddr == NULL) {
641 saddr = &fl.fl6_src; 639 saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
849 if (dst == NULL) { 847 if (dst == NULL) {
850 opt = np->opt; 848 opt = np->opt;
851 if (opt == NULL && 849 if (opt == NULL &&
852 np->rxopt.bits.srcrt == 2 && 850 np->rxopt.bits.osrcrt == 2 &&
853 treq->pktopts) { 851 treq->pktopts) {
854 struct sk_buff *pktopts = treq->pktopts; 852 struct sk_buff *pktopts = treq->pktopts;
855 struct inet6_skb_parm *rxopt = IP6CB(pktopts); 853 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
888 } 886 }
889 887
890done: 888done:
891 dst_release(dst);
892 if (opt && opt != np->opt) 889 if (opt && opt != np->opt)
893 sock_kfree_s(sk, opt, opt->tot_len); 890 sock_kfree_s(sk, opt, opt->tot_len);
894 return err; 891 return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
915 struct inet6_skb_parm *opt = IP6CB(skb); 912 struct inet6_skb_parm *opt = IP6CB(skb);
916 913
917 if (np->rxopt.all) { 914 if (np->rxopt.all) {
918 if ((opt->hop && np->rxopt.bits.hopopts) || 915 if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
919 ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) && 916 ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
920 np->rxopt.bits.rxflow) || 917 (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
921 (opt->srcrt && np->rxopt.bits.srcrt) || 918 ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
922 ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
923 return 1; 919 return 1;
924 } 920 }
925 return 0; 921 return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
1001 /* sk = NULL, but it is safe for now. RST socket required. */ 997 /* sk = NULL, but it is safe for now. RST socket required. */
1002 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 998 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
1003 999
1004 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { 1000 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
1005 dst_release(buff->dst);
1006 return; 1001 return;
1007 }
1008 1002
1009 ip6_xmit(NULL, buff, &fl, NULL, 0); 1003 ip6_xmit(NULL, buff, &fl, NULL, 0);
1010 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1004 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
@@ -1068,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1068 fl.fl_ip_sport = t1->source; 1062 fl.fl_ip_sport = t1->source;
1069 1063
1070 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 1064 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
1071 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { 1065 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
1072 dst_release(buff->dst);
1073 return; 1066 return;
1074 }
1075 ip6_xmit(NULL, buff, &fl, NULL, 0); 1067 ip6_xmit(NULL, buff, &fl, NULL, 0);
1076 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1068 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
1077 return; 1069 return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1190 TCP_ECN_create_request(req, skb->h.th); 1182 TCP_ECN_create_request(req, skb->h.th);
1191 treq->pktopts = NULL; 1183 treq->pktopts = NULL;
1192 if (ipv6_opt_accepted(sk, skb) || 1184 if (ipv6_opt_accepted(sk, skb) ||
1193 np->rxopt.bits.rxinfo || 1185 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
1194 np->rxopt.bits.rxhlim) { 1186 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
1195 atomic_inc(&skb->users); 1187 atomic_inc(&skb->users);
1196 treq->pktopts = skb; 1188 treq->pktopts = skb;
1197 } 1189 }
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1288 if (sk_acceptq_is_full(sk)) 1280 if (sk_acceptq_is_full(sk))
1289 goto out_overflow; 1281 goto out_overflow;
1290 1282
1291 if (np->rxopt.bits.srcrt == 2 && 1283 if (np->rxopt.bits.osrcrt == 2 &&
1292 opt == NULL && treq->pktopts) { 1284 opt == NULL && treq->pktopts) {
1293 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); 1285 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
1294 if (rxopt->srcrt) 1286 if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
1544 tp = tcp_sk(sk); 1536 tp = tcp_sk(sk);
1545 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && 1537 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
1546 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { 1538 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
1547 if (np->rxopt.bits.rxinfo) 1539 if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
1548 np->mcast_oif = inet6_iif(opt_skb); 1540 np->mcast_oif = inet6_iif(opt_skb);
1549 if (np->rxopt.bits.rxhlim) 1541 if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
1550 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; 1542 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
1551 if (ipv6_opt_accepted(sk, opt_skb)) { 1543 if (ipv6_opt_accepted(sk, opt_skb)) {
1552 skb_set_owner_r(opt_skb, sk); 1544 skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
1734 1726
1735 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 1727 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
1736 sk->sk_err_soft = -err; 1728 sk->sk_err_soft = -err;
1737 dst_release(dst);
1738 return err; 1729 return err;
1739 } 1730 }
1740 1731
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
1787 1778
1788 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 1779 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
1789 sk->sk_route_caps = 0; 1780 sk->sk_route_caps = 0;
1790 dst_release(dst);
1791 return err; 1781 return err;
1792 } 1782 }
1793 1783
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 390d750449ce..69b146843a20 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -483,7 +483,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
483 } 483 }
484 484
485 if (ulen < skb->len) { 485 if (ulen < skb->len) {
486 if (__pskb_trim(skb, ulen)) 486 if (pskb_trim_rcsum(skb, ulen))
487 goto discard; 487 goto discard;
488 saddr = &skb->nh.ipv6h->saddr; 488 saddr = &skb->nh.ipv6h->saddr;
489 daddr = &skb->nh.ipv6h->daddr; 489 daddr = &skb->nh.ipv6h->daddr;
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
637 int addr_len = msg->msg_namelen; 637 int addr_len = msg->msg_namelen;
638 int ulen = len; 638 int ulen = len;
639 int hlimit = -1; 639 int hlimit = -1;
640 int tclass = -1;
640 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 641 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
641 int err; 642 int err;
642 643
@@ -758,7 +759,7 @@ do_udp_sendmsg:
758 memset(opt, 0, sizeof(struct ipv6_txoptions)); 759 memset(opt, 0, sizeof(struct ipv6_txoptions));
759 opt->tot_len = sizeof(*opt); 760 opt->tot_len = sizeof(*opt);
760 761
761 err = datagram_send_ctl(msg, fl, opt, &hlimit); 762 err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
762 if (err < 0) { 763 if (err < 0) {
763 fl6_sock_release(flowlabel); 764 fl6_sock_release(flowlabel);
764 return err; 765 return err;
@@ -773,8 +774,7 @@ do_udp_sendmsg:
773 } 774 }
774 if (opt == NULL) 775 if (opt == NULL)
775 opt = np->opt; 776 opt = np->opt;
776 if (flowlabel) 777 opt = fl6_merge_options(&opt_space, flowlabel, opt);
777 opt = fl6_merge_options(&opt_space, flowlabel, opt);
778 778
779 fl->proto = IPPROTO_UDP; 779 fl->proto = IPPROTO_UDP;
780 ipv6_addr_copy(&fl->fl6_dst, daddr); 780 ipv6_addr_copy(&fl->fl6_dst, daddr);
@@ -799,10 +799,8 @@ do_udp_sendmsg:
799 if (final_p) 799 if (final_p)
800 ipv6_addr_copy(&fl->fl6_dst, final_p); 800 ipv6_addr_copy(&fl->fl6_dst, final_p);
801 801
802 if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) { 802 if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
803 dst_release(dst);
804 goto out; 803 goto out;
805 }
806 804
807 if (hlimit < 0) { 805 if (hlimit < 0) {
808 if (ipv6_addr_is_multicast(&fl->fl6_dst)) 806 if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -815,6 +813,12 @@ do_udp_sendmsg:
815 hlimit = ipv6_get_hoplimit(dst->dev); 813 hlimit = ipv6_get_hoplimit(dst->dev);
816 } 814 }
817 815
816 if (tclass < 0) {
817 tclass = np->tclass;
818 if (tclass < 0)
819 tclass = 0;
820 }
821
818 if (msg->msg_flags&MSG_CONFIRM) 822 if (msg->msg_flags&MSG_CONFIRM)
819 goto do_confirm; 823 goto do_confirm;
820back_from_confirm: 824back_from_confirm:
@@ -834,9 +838,10 @@ back_from_confirm:
834 838
835do_append_data: 839do_append_data:
836 up->len += ulen; 840 up->len += ulen;
837 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr), 841 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
838 hlimit, opt, fl, (struct rt6_info*)dst, 842 sizeof(struct udphdr), hlimit, tclass, opt, fl,
839 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 843 (struct rt6_info*)dst,
844 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
840 if (err) 845 if (err)
841 udp_v6_flush_pending_frames(sk); 846 udp_v6_flush_pending_frames(sk);
842 else if (!corkreq) 847 else if (!corkreq)
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index 165b2abce110..e856ae1b360a 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -17,7 +17,7 @@
17static void nr_loopback_timer(unsigned long); 17static void nr_loopback_timer(unsigned long);
18 18
19static struct sk_buff_head loopback_queue; 19static struct sk_buff_head loopback_queue;
20static struct timer_list loopback_timer = TIMER_INITIALIZER(nr_loopback_timer, 0, 0); 20static DEFINE_TIMER(loopback_timer, nr_loopback_timer, 0, 0);
21 21
22void __init nr_loopback_init(void) 22void __init nr_loopback_init(void)
23{ 23{
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 02891ce2db37..36a77944622b 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -337,13 +337,13 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); 337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
338 memcpy(callsign, p + 12, l - 10); 338 memcpy(callsign, p + 12, l - 10);
339 callsign[l - 10] = '\0'; 339 callsign[l - 10] = '\0';
340 facilities->source_call = *asc2ax(callsign); 340 asc2ax(&facilities->source_call, callsign);
341 } 341 }
342 if (*p == FAC_CCITT_SRC_NSAP) { 342 if (*p == FAC_CCITT_SRC_NSAP) {
343 memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN); 343 memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
344 memcpy(callsign, p + 12, l - 10); 344 memcpy(callsign, p + 12, l - 10);
345 callsign[l - 10] = '\0'; 345 callsign[l - 10] = '\0';
346 facilities->dest_call = *asc2ax(callsign); 346 asc2ax(&facilities->dest_call, callsign);
347 } 347 }
348 p += l + 2; 348 p += l + 2;
349 n += l + 2; 349 n += l + 2;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 737681cb9a92..31570b9a6e9a 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1194,7 +1194,7 @@ EXPORT_SYMBOL(psched_time_base);
1194 * with 32-bit get_cycles(). Safe up to 4GHz CPU. 1194 * with 32-bit get_cycles(). Safe up to 4GHz CPU.
1195 */ 1195 */
1196static void psched_tick(unsigned long); 1196static void psched_tick(unsigned long);
1197static struct timer_list psched_timer = TIMER_INITIALIZER(psched_tick, 0, 0); 1197static DEFINE_TIMER(psched_timer, psched_tick, 0, 0);
1198 1198
1199static void psched_tick(unsigned long dummy) 1199static void psched_tick(unsigned long dummy)
1200{ 1200{
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 83c8135e1764..fda737d77edc 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -765,8 +765,8 @@ restart:
765 switch (policy->action) { 765 switch (policy->action) {
766 case XFRM_POLICY_BLOCK: 766 case XFRM_POLICY_BLOCK:
767 /* Prohibit the flow */ 767 /* Prohibit the flow */
768 xfrm_pol_put(policy); 768 err = -EPERM;
769 return -EPERM; 769 goto error;
770 770
771 case XFRM_POLICY_ALLOW: 771 case XFRM_POLICY_ALLOW:
772 if (policy->xfrm_nr == 0) { 772 if (policy->xfrm_nr == 0) {
@@ -782,8 +782,8 @@ restart:
782 */ 782 */
783 dst = xfrm_find_bundle(fl, policy, family); 783 dst = xfrm_find_bundle(fl, policy, family);
784 if (IS_ERR(dst)) { 784 if (IS_ERR(dst)) {
785 xfrm_pol_put(policy); 785 err = PTR_ERR(dst);
786 return PTR_ERR(dst); 786 goto error;
787 } 787 }
788 788
789 if (dst) 789 if (dst)
diff --git a/security/dummy.c b/security/dummy.c
index 6ff887586479..9623a61dfc76 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -258,16 +258,16 @@ static void dummy_inode_free_security (struct inode *inode)
258 return; 258 return;
259} 259}
260 260
261static int dummy_inode_create (struct inode *inode, struct dentry *dentry, 261static int dummy_inode_init_security (struct inode *inode, struct inode *dir,
262 int mask) 262 char **name, void **value, size_t *len)
263{ 263{
264 return 0; 264 return -EOPNOTSUPP;
265} 265}
266 266
267static void dummy_inode_post_create (struct inode *inode, struct dentry *dentry, 267static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
268 int mask) 268 int mask)
269{ 269{
270 return; 270 return 0;
271} 271}
272 272
273static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode, 273static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode,
@@ -276,13 +276,6 @@ static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode,
276 return 0; 276 return 0;
277} 277}
278 278
279static void dummy_inode_post_link (struct dentry *old_dentry,
280 struct inode *inode,
281 struct dentry *new_dentry)
282{
283 return;
284}
285
286static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry) 279static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry)
287{ 280{
288 return 0; 281 return 0;
@@ -294,24 +287,12 @@ static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry,
294 return 0; 287 return 0;
295} 288}
296 289
297static void dummy_inode_post_symlink (struct inode *inode,
298 struct dentry *dentry, const char *name)
299{
300 return;
301}
302
303static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry, 290static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry,
304 int mask) 291 int mask)
305{ 292{
306 return 0; 293 return 0;
307} 294}
308 295
309static void dummy_inode_post_mkdir (struct inode *inode, struct dentry *dentry,
310 int mask)
311{
312 return;
313}
314
315static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry) 296static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry)
316{ 297{
317 return 0; 298 return 0;
@@ -323,12 +304,6 @@ static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry,
323 return 0; 304 return 0;
324} 305}
325 306
326static void dummy_inode_post_mknod (struct inode *inode, struct dentry *dentry,
327 int mode, dev_t dev)
328{
329 return;
330}
331
332static int dummy_inode_rename (struct inode *old_inode, 307static int dummy_inode_rename (struct inode *old_inode,
333 struct dentry *old_dentry, 308 struct dentry *old_dentry,
334 struct inode *new_inode, 309 struct inode *new_inode,
@@ -337,14 +312,6 @@ static int dummy_inode_rename (struct inode *old_inode,
337 return 0; 312 return 0;
338} 313}
339 314
340static void dummy_inode_post_rename (struct inode *old_inode,
341 struct dentry *old_dentry,
342 struct inode *new_inode,
343 struct dentry *new_dentry)
344{
345 return;
346}
347
348static int dummy_inode_readlink (struct dentry *dentry) 315static int dummy_inode_readlink (struct dentry *dentry)
349{ 316{
350 return 0; 317 return 0;
@@ -886,20 +853,15 @@ void security_fixup_ops (struct security_operations *ops)
886 set_to_dummy_if_null(ops, sb_post_pivotroot); 853 set_to_dummy_if_null(ops, sb_post_pivotroot);
887 set_to_dummy_if_null(ops, inode_alloc_security); 854 set_to_dummy_if_null(ops, inode_alloc_security);
888 set_to_dummy_if_null(ops, inode_free_security); 855 set_to_dummy_if_null(ops, inode_free_security);
856 set_to_dummy_if_null(ops, inode_init_security);
889 set_to_dummy_if_null(ops, inode_create); 857 set_to_dummy_if_null(ops, inode_create);
890 set_to_dummy_if_null(ops, inode_post_create);
891 set_to_dummy_if_null(ops, inode_link); 858 set_to_dummy_if_null(ops, inode_link);
892 set_to_dummy_if_null(ops, inode_post_link);
893 set_to_dummy_if_null(ops, inode_unlink); 859 set_to_dummy_if_null(ops, inode_unlink);
894 set_to_dummy_if_null(ops, inode_symlink); 860 set_to_dummy_if_null(ops, inode_symlink);
895 set_to_dummy_if_null(ops, inode_post_symlink);
896 set_to_dummy_if_null(ops, inode_mkdir); 861 set_to_dummy_if_null(ops, inode_mkdir);
897 set_to_dummy_if_null(ops, inode_post_mkdir);
898 set_to_dummy_if_null(ops, inode_rmdir); 862 set_to_dummy_if_null(ops, inode_rmdir);
899 set_to_dummy_if_null(ops, inode_mknod); 863 set_to_dummy_if_null(ops, inode_mknod);
900 set_to_dummy_if_null(ops, inode_post_mknod);
901 set_to_dummy_if_null(ops, inode_rename); 864 set_to_dummy_if_null(ops, inode_rename);
902 set_to_dummy_if_null(ops, inode_post_rename);
903 set_to_dummy_if_null(ops, inode_readlink); 865 set_to_dummy_if_null(ops, inode_readlink);
904 set_to_dummy_if_null(ops, inode_follow_link); 866 set_to_dummy_if_null(ops, inode_follow_link);
905 set_to_dummy_if_null(ops, inode_permission); 867 set_to_dummy_if_null(ops, inode_permission);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8641f8894b4c..f40c8221ec1b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1265,85 +1265,6 @@ static int inode_security_set_sid(struct inode *inode, u32 sid)
1265 return 0; 1265 return 0;
1266} 1266}
1267 1267
1268/* Set the security attributes on a newly created file. */
1269static int post_create(struct inode *dir,
1270 struct dentry *dentry)
1271{
1272
1273 struct task_security_struct *tsec;
1274 struct inode *inode;
1275 struct inode_security_struct *dsec;
1276 struct superblock_security_struct *sbsec;
1277 u32 newsid;
1278 char *context;
1279 unsigned int len;
1280 int rc;
1281
1282 tsec = current->security;
1283 dsec = dir->i_security;
1284 sbsec = dir->i_sb->s_security;
1285
1286 inode = dentry->d_inode;
1287 if (!inode) {
1288 /* Some file system types (e.g. NFS) may not instantiate
1289 a dentry for all create operations (e.g. symlink),
1290 so we have to check to see if the inode is non-NULL. */
1291 printk(KERN_WARNING "post_create: no inode, dir (dev=%s, "
1292 "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);
1293 return 0;
1294 }
1295
1296 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1297 newsid = tsec->create_sid;
1298 } else {
1299 rc = security_transition_sid(tsec->sid, dsec->sid,
1300 inode_mode_to_security_class(inode->i_mode),
1301 &newsid);
1302 if (rc) {
1303 printk(KERN_WARNING "post_create: "
1304 "security_transition_sid failed, rc=%d (dev=%s "
1305 "ino=%ld)\n",
1306 -rc, inode->i_sb->s_id, inode->i_ino);
1307 return rc;
1308 }
1309 }
1310
1311 rc = inode_security_set_sid(inode, newsid);
1312 if (rc) {
1313 printk(KERN_WARNING "post_create: inode_security_set_sid "
1314 "failed, rc=%d (dev=%s ino=%ld)\n",
1315 -rc, inode->i_sb->s_id, inode->i_ino);
1316 return rc;
1317 }
1318
1319 if (sbsec->behavior == SECURITY_FS_USE_XATTR &&
1320 inode->i_op->setxattr) {
1321 /* Use extended attributes. */
1322 rc = security_sid_to_context(newsid, &context, &len);
1323 if (rc) {
1324 printk(KERN_WARNING "post_create: sid_to_context "
1325 "failed, rc=%d (dev=%s ino=%ld)\n",
1326 -rc, inode->i_sb->s_id, inode->i_ino);
1327 return rc;
1328 }
1329 down(&inode->i_sem);
1330 rc = inode->i_op->setxattr(dentry,
1331 XATTR_NAME_SELINUX,
1332 context, len, 0);
1333 up(&inode->i_sem);
1334 kfree(context);
1335 if (rc < 0) {
1336 printk(KERN_WARNING "post_create: setxattr failed, "
1337 "rc=%d (dev=%s ino=%ld)\n",
1338 -rc, inode->i_sb->s_id, inode->i_ino);
1339 return rc;
1340 }
1341 }
1342
1343 return 0;
1344}
1345
1346
1347/* Hook functions begin here. */ 1268/* Hook functions begin here. */
1348 1269
1349static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) 1270static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
@@ -1673,6 +1594,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1673 struct avc_audit_data ad; 1594 struct avc_audit_data ad;
1674 struct file *file, *devnull = NULL; 1595 struct file *file, *devnull = NULL;
1675 struct tty_struct *tty = current->signal->tty; 1596 struct tty_struct *tty = current->signal->tty;
1597 struct fdtable *fdt;
1676 long j = -1; 1598 long j = -1;
1677 1599
1678 if (tty) { 1600 if (tty) {
@@ -1706,9 +1628,10 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1706 1628
1707 j++; 1629 j++;
1708 i = j * __NFDBITS; 1630 i = j * __NFDBITS;
1709 if (i >= files->max_fds || i >= files->max_fdset) 1631 fdt = files_fdtable(files);
1632 if (i >= fdt->max_fds || i >= fdt->max_fdset)
1710 break; 1633 break;
1711 set = files->open_fds->fds_bits[j]; 1634 set = fdt->open_fds->fds_bits[j];
1712 if (!set) 1635 if (!set)
1713 continue; 1636 continue;
1714 spin_unlock(&files->file_lock); 1637 spin_unlock(&files->file_lock);
@@ -1729,7 +1652,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1729 continue; 1652 continue;
1730 } 1653 }
1731 if (devnull) { 1654 if (devnull) {
1732 atomic_inc(&devnull->f_count); 1655 rcuref_inc(&devnull->f_count);
1733 } else { 1656 } else {
1734 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 1657 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1735 if (!devnull) { 1658 if (!devnull) {
@@ -2018,14 +1941,64 @@ static void selinux_inode_free_security(struct inode *inode)
2018 inode_free_security(inode); 1941 inode_free_security(inode);
2019} 1942}
2020 1943
2021static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) 1944static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1945 char **name, void **value,
1946 size_t *len)
2022{ 1947{
2023 return may_create(dir, dentry, SECCLASS_FILE); 1948 struct task_security_struct *tsec;
1949 struct inode_security_struct *dsec;
1950 struct superblock_security_struct *sbsec;
1951 struct inode_security_struct *isec;
1952 u32 newsid, clen;
1953 int rc;
1954 char *namep = NULL, *context;
1955
1956 tsec = current->security;
1957 dsec = dir->i_security;
1958 sbsec = dir->i_sb->s_security;
1959 isec = inode->i_security;
1960
1961 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1962 newsid = tsec->create_sid;
1963 } else {
1964 rc = security_transition_sid(tsec->sid, dsec->sid,
1965 inode_mode_to_security_class(inode->i_mode),
1966 &newsid);
1967 if (rc) {
1968 printk(KERN_WARNING "%s: "
1969 "security_transition_sid failed, rc=%d (dev=%s "
1970 "ino=%ld)\n",
1971 __FUNCTION__,
1972 -rc, inode->i_sb->s_id, inode->i_ino);
1973 return rc;
1974 }
1975 }
1976
1977 inode_security_set_sid(inode, newsid);
1978
1979 if (name) {
1980 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
1981 if (!namep)
1982 return -ENOMEM;
1983 *name = namep;
1984 }
1985
1986 if (value && len) {
1987 rc = security_sid_to_context(newsid, &context, &clen);
1988 if (rc) {
1989 kfree(namep);
1990 return rc;
1991 }
1992 *value = context;
1993 *len = clen;
1994 }
1995
1996 return 0;
2024} 1997}
2025 1998
2026static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask) 1999static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
2027{ 2000{
2028 post_create(dir, dentry); 2001 return may_create(dir, dentry, SECCLASS_FILE);
2029} 2002}
2030 2003
2031static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) 2004static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
@@ -2038,11 +2011,6 @@ static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, stru
2038 return may_link(dir, old_dentry, MAY_LINK); 2011 return may_link(dir, old_dentry, MAY_LINK);
2039} 2012}
2040 2013
2041static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
2042{
2043 return;
2044}
2045
2046static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) 2014static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2047{ 2015{
2048 int rc; 2016 int rc;
@@ -2058,21 +2026,11 @@ static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const
2058 return may_create(dir, dentry, SECCLASS_LNK_FILE); 2026 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2059} 2027}
2060 2028
2061static void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2062{
2063 post_create(dir, dentry);
2064}
2065
2066static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask) 2029static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
2067{ 2030{
2068 return may_create(dir, dentry, SECCLASS_DIR); 2031 return may_create(dir, dentry, SECCLASS_DIR);
2069} 2032}
2070 2033
2071static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask)
2072{
2073 post_create(dir, dentry);
2074}
2075
2076static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) 2034static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2077{ 2035{
2078 return may_link(dir, dentry, MAY_RMDIR); 2036 return may_link(dir, dentry, MAY_RMDIR);
@@ -2089,23 +2047,12 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mod
2089 return may_create(dir, dentry, inode_mode_to_security_class(mode)); 2047 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2090} 2048}
2091 2049
2092static void selinux_inode_post_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2093{
2094 post_create(dir, dentry);
2095}
2096
2097static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, 2050static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
2098 struct inode *new_inode, struct dentry *new_dentry) 2051 struct inode *new_inode, struct dentry *new_dentry)
2099{ 2052{
2100 return may_rename(old_inode, old_dentry, new_inode, new_dentry); 2053 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2101} 2054}
2102 2055
2103static void selinux_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry,
2104 struct inode *new_inode, struct dentry *new_dentry)
2105{
2106 return;
2107}
2108
2109static int selinux_inode_readlink(struct dentry *dentry) 2056static int selinux_inode_readlink(struct dentry *dentry)
2110{ 2057{
2111 return dentry_has_perm(current, NULL, dentry, FILE__READ); 2058 return dentry_has_perm(current, NULL, dentry, FILE__READ);
@@ -4298,20 +4245,15 @@ static struct security_operations selinux_ops = {
4298 4245
4299 .inode_alloc_security = selinux_inode_alloc_security, 4246 .inode_alloc_security = selinux_inode_alloc_security,
4300 .inode_free_security = selinux_inode_free_security, 4247 .inode_free_security = selinux_inode_free_security,
4248 .inode_init_security = selinux_inode_init_security,
4301 .inode_create = selinux_inode_create, 4249 .inode_create = selinux_inode_create,
4302 .inode_post_create = selinux_inode_post_create,
4303 .inode_link = selinux_inode_link, 4250 .inode_link = selinux_inode_link,
4304 .inode_post_link = selinux_inode_post_link,
4305 .inode_unlink = selinux_inode_unlink, 4251 .inode_unlink = selinux_inode_unlink,
4306 .inode_symlink = selinux_inode_symlink, 4252 .inode_symlink = selinux_inode_symlink,
4307 .inode_post_symlink = selinux_inode_post_symlink,
4308 .inode_mkdir = selinux_inode_mkdir, 4253 .inode_mkdir = selinux_inode_mkdir,
4309 .inode_post_mkdir = selinux_inode_post_mkdir,
4310 .inode_rmdir = selinux_inode_rmdir, 4254 .inode_rmdir = selinux_inode_rmdir,
4311 .inode_mknod = selinux_inode_mknod, 4255 .inode_mknod = selinux_inode_mknod,
4312 .inode_post_mknod = selinux_inode_post_mknod,
4313 .inode_rename = selinux_inode_rename, 4256 .inode_rename = selinux_inode_rename,
4314 .inode_post_rename = selinux_inode_post_rename,
4315 .inode_readlink = selinux_inode_readlink, 4257 .inode_readlink = selinux_inode_readlink,
4316 .inode_follow_link = selinux_inode_follow_link, 4258 .inode_follow_link = selinux_inode_follow_link,
4317 .inode_permission = selinux_inode_permission, 4259 .inode_permission = selinux_inode_permission,
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index b2676fa34630..6982556ded56 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -50,7 +50,7 @@ static struct midi_parms parms[MAX_MIDI_DEV];
50static void midi_poll(unsigned long dummy); 50static void midi_poll(unsigned long dummy);
51 51
52 52
53static struct timer_list poll_timer = TIMER_INITIALIZER(midi_poll, 0, 0); 53static DEFINE_TIMER(poll_timer, midi_poll, 0, 0);
54 54
55static volatile int open_devs; 55static volatile int open_devs;
56static DEFINE_SPINLOCK(lock); 56static DEFINE_SPINLOCK(lock);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index a686be936aff..95fa81e26de2 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -681,8 +681,7 @@ static void do_sequencer_timer(unsigned long dummy)
681} 681}
682 682
683 683
684static struct timer_list seq_timer = 684static DEFINE_TIMER(seq_timer, do_sequencer_timer, 0, 0);
685 TIMER_INITIALIZER(do_sequencer_timer, 0, 0);
686 685
687void request_sound_timer(int count) 686void request_sound_timer(int count)
688{ 687{
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index 6afe29b763b7..c9d04518b172 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -28,8 +28,7 @@ static unsigned long prev_event_time;
28 28
29static void poll_def_tmr(unsigned long dummy); 29static void poll_def_tmr(unsigned long dummy);
30static DEFINE_SPINLOCK(lock); 30static DEFINE_SPINLOCK(lock);
31 31static DEFINE_TIMER(def_tmr, poll_def_tmr, 0, 0);
32static struct timer_list def_tmr = TIMER_INITIALIZER(poll_def_tmr, 0, 0);
33 32
34static unsigned long 33static unsigned long
35tmr2ticks(int tmr_value) 34tmr2ticks(int tmr_value)
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index be00cf128651..74ae75f9e2dc 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -78,8 +78,7 @@ static void (*midi_input_intr) (int dev, unsigned char data);
78static void poll_uart6850(unsigned long dummy); 78static void poll_uart6850(unsigned long dummy);
79 79
80 80
81static struct timer_list uart6850_timer = 81static DEFINE_TIMER(uart6850_timer, poll_uart6850, 0, 0);
82 TIMER_INITIALIZER(poll_uart6850, 0, 0);
83 82
84static void uart6850_input_loop(void) 83static void uart6850_input_loop(void)
85{ 84{
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 5aa5fe651a8a..bfbec5876659 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -735,10 +735,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
735 if (test_bit(i, &subs->active_mask)) { 735 if (test_bit(i, &subs->active_mask)) {
736 if (! test_and_set_bit(i, &subs->unlink_mask)) { 736 if (! test_and_set_bit(i, &subs->unlink_mask)) {
737 struct urb *u = subs->dataurb[i].urb; 737 struct urb *u = subs->dataurb[i].urb;
738 if (async) { 738 if (async)
739 u->transfer_flags |= URB_ASYNC_UNLINK;
740 usb_unlink_urb(u); 739 usb_unlink_urb(u);
741 } else 740 else
742 usb_kill_urb(u); 741 usb_kill_urb(u);
743 } 742 }
744 } 743 }
@@ -748,10 +747,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
748 if (test_bit(i+16, &subs->active_mask)) { 747 if (test_bit(i+16, &subs->active_mask)) {
749 if (! test_and_set_bit(i+16, &subs->unlink_mask)) { 748 if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
750 struct urb *u = subs->syncurb[i].urb; 749 struct urb *u = subs->syncurb[i].urb;
751 if (async) { 750 if (async)
752 u->transfer_flags |= URB_ASYNC_UNLINK;
753 usb_unlink_urb(u); 751 usb_unlink_urb(u);
754 } else 752 else
755 usb_kill_urb(u); 753 usb_kill_urb(u);
756 } 754 }
757 } 755 }