aboutsummaryrefslogtreecommitdiff
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 f28a24e0279..f6de52b0105 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -46,6 +46,8 @@ SubmittingPatches
- procedure to get a source patch included into the kernel tree.
VGA-softcursor.txt
- how to change your VGA cursor from a blinking underscore.
+applying-patches.txt
+ - description of various trees and how to apply their patches.
arm/
- directory with info about Linux on the ARM architecture.
basic_profiling.txt
diff --git a/Documentation/DMA-ISA-LPC.txt b/Documentation/DMA-ISA-LPC.txt
new file mode 100644
index 00000000000..705f6be92bd
--- /dev/null
+++ b/Documentation/DMA-ISA-LPC.txt
@@ -0,0 +1,151 @@
+ DMA with ISA and LPC devices
+ ============================
+
+ Pierre Ossman <drzeus@drzeus.cx>
+
+This document describes how to do DMA transfers using the old ISA DMA
+controller. Even though ISA is more or less dead today the LPC bus
+uses the same DMA system so it will be around for quite some time.
+
+Part I - Headers and dependencies
+---------------------------------
+
+To do ISA style DMA you need to include two headers:
+
+#include <linux/dma-mapping.h>
+#include <asm/dma.h>
+
+The first is the generic DMA API used to convert virtual addresses to
+physical addresses (see Documentation/DMA-API.txt for details).
+
+The second contains the routines specific to ISA DMA transfers. Since
+this is not present on all platforms make sure you construct your
+Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
+to build your driver on unsupported platforms.
+
+Part II - Buffer allocation
+---------------------------
+
+The ISA DMA controller has some very strict requirements on which
+memory it can access so extra care must be taken when allocating
+buffers.
+
+(You usually need a special buffer for DMA transfers instead of
+transferring directly to and from your normal data structures.)
+
+The DMA-able address space is the lowest 16 MB of _physical_ memory.
+Also the transfer block may not cross page boundaries (which are 64
+or 128 KiB depending on which channel you use).
+
+In order to allocate a piece of memory that satisfies all these
+requirements you pass the flag GFP_DMA to kmalloc.
+
+Unfortunately the memory available for ISA DMA is scarce so unless you
+allocate the memory during boot-up it's a good idea to also pass
+__GFP_REPEAT and __GFP_NOWARN to make the allocater try a bit harder.
+
+(This scarcity also means that you should allocate the buffer as
+early as possible and not release it until the driver is unloaded.)
+
+Part III - Address translation
+------------------------------
+
+To translate the virtual address to a physical use the normal DMA
+API. Do _not_ use isa_virt_to_phys() even though it does the same
+thing. The reason for this is that the function isa_virt_to_phys()
+will require a Kconfig dependency to ISA, not just ISA_DMA_API which
+is really all you need. Remember that even though the DMA controller
+has its origins in ISA it is used elsewhere.
+
+Note: x86_64 had a broken DMA API when it came to ISA but has since
+been fixed. If your arch has problems then fix the DMA API instead of
+reverting to the ISA functions.
+
+Part IV - Channels
+------------------
+
+A normal ISA DMA controller has 8 channels. The lower four are for
+8-bit transfers and the upper four are for 16-bit transfers.
+
+(Actually the DMA controller is really two separate controllers where
+channel 4 is used to give DMA access for the second controller (0-3).
+This means that of the four 16-bits channels only three are usable.)
+
+You allocate these in a similar fashion as all basic resources:
+
+extern int request_dma(unsigned int dmanr, const char * device_id);
+extern void free_dma(unsigned int dmanr);
+
+The ability to use 16-bit or 8-bit transfers is _not_ up to you as a
+driver author but depends on what the hardware supports. Check your
+specs or test different channels.
+
+Part V - Transfer data
+----------------------
+
+Now for the good stuff, the actual DMA transfer. :)
+
+Before you use any ISA DMA routines you need to claim the DMA lock
+using claim_dma_lock(). The reason is that some DMA operations are
+not atomic so only one driver may fiddle with the registers at a
+time.
+
+The first time you use the DMA controller you should call
+clear_dma_ff(). This clears an internal register in the DMA
+controller that is used for the non-atomic operations. As long as you
+(and everyone else) uses the locking functions then you only need to
+reset this once.
+
+Next, you tell the controller in which direction you intend to do the
+transfer using set_dma_mode(). Currently you have the options
+DMA_MODE_READ and DMA_MODE_WRITE.
+
+Set the address from where the transfer should start (this needs to
+be 16-bit aligned for 16-bit transfers) and how many bytes to
+transfer. Note that it's _bytes_. The DMA routines will do all the
+required translation to values that the DMA controller understands.
+
+The final step is enabling the DMA channel and releasing the DMA
+lock.
+
+Once the DMA transfer is finished (or timed out) you should disable
+the channel again. You should also check get_dma_residue() to make
+sure that all data has been transfered.
+
+Example:
+
+int flags, residue;
+
+flags = claim_dma_lock();
+
+clear_dma_ff();
+
+set_dma_mode(channel, DMA_MODE_WRITE);
+set_dma_addr(channel, phys_addr);
+set_dma_count(channel, num_bytes);
+
+dma_enable(channel);
+
+release_dma_lock(flags);
+
+while (!device_done());
+
+flags = claim_dma_lock();
+
+dma_disable(channel);
+
+residue = dma_get_residue(channel);
+if (residue != 0)
+ printk(KERN_ERR "driver: Incomplete DMA transfer!"
+ " %d bytes left!\n", residue);
+
+release_dma_lock(flags);
+
+Part VI - Suspend/resume
+------------------------
+
+It is the driver's responsibility to make sure that the machine isn't
+suspended while a DMA transfer is in progress. Also, all DMA settings
+are lost when the system suspends so if your driver relies on the DMA
+controller being in a certain state then you have to restore these
+registers upon resume.
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 49a9ef82d57..6367bba32d2 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -8,8 +8,7 @@
<authorgroup>
<author>
- <firstname>Paul</firstname>
- <othername>Rusty</othername>
+ <firstname>Rusty</firstname>
<surname>Russell</surname>
<affiliation>
<address>
@@ -20,7 +19,7 @@
</authorgroup>
<copyright>
- <year>2001</year>
+ <year>2005</year>
<holder>Rusty Russell</holder>
</copyright>
@@ -64,7 +63,7 @@
<chapter id="introduction">
<title>Introduction</title>
<para>
- Welcome, gentle reader, to Rusty's Unreliable Guide to Linux
+ Welcome, gentle reader, to Rusty's Remarkably Unreliable Guide to Linux
Kernel Hacking. This document describes the common routines and
general requirements for kernel code: its goal is to serve as a
primer for Linux kernel development for experienced C
@@ -96,13 +95,13 @@
<listitem>
<para>
- not associated with any process, serving a softirq, tasklet or bh;
+ not associated with any process, serving a softirq or tasklet;
</para>
</listitem>
<listitem>
<para>
- running in kernel space, associated with a process;
+ running in kernel space, associated with a process (user context);
</para>
</listitem>
@@ -114,11 +113,12 @@
</itemizedlist>
<para>
- There is a strict ordering between these: other than the last
- category (userspace) each can only be pre-empted by those above.
- For example, while a softirq is running on a CPU, no other
- softirq will pre-empt it, but a hardware interrupt can. However,
- any other CPUs in the system execute independently.
+ There is an ordering between these. The bottom two can preempt
+ each other, but above that is a strict hierarchy: each can only be
+ preempted by the ones above it. For example, while a softirq is
+ running on a CPU, no other softirq will preempt it, but a hardware
+ interrupt can. However, any other CPUs in the system execute
+ independently.
</para>
<para>
@@ -130,10 +130,10 @@
<title>User Context</title>
<para>
- User context is when you are coming in from a system call or
- other trap: you can sleep, and you own the CPU (except for
- interrupts) until you call <function>schedule()</function>.
- In other words, user context (unlike userspace) is not pre-emptable.
+ User context is when you are coming in from a system call or other
+ trap: like userspace, you can be preempted by more important tasks
+ and by interrupts. You can sleep, by calling
+ <function>schedule()</function>.
</para>
<note>
@@ -153,7 +153,7 @@
<caution>
<para>
- Beware that if you have interrupts or bottom halves disabled
+ Beware that if you have preemption or softirqs disabled
(see below), <function>in_interrupt()</function> will return a
false positive.
</para>
@@ -168,10 +168,10 @@
<hardware>keyboard</hardware> are examples of real
hardware which produce interrupts at any time. The kernel runs
interrupt handlers, which services the hardware. The kernel
- guarantees that this handler is never re-entered: if another
+ guarantees that this handler is never re-entered: if the same
interrupt arrives, it is queued (or dropped). Because it
disables interrupts, this handler has to be fast: frequently it
- simply acknowledges the interrupt, marks a `software interrupt'
+ simply acknowledges the interrupt, marks a 'software interrupt'
for execution and exits.
</para>
@@ -188,60 +188,52 @@
</sect1>
<sect1 id="basics-softirqs">
- <title>Software Interrupt Context: Bottom Halves, Tasklets, softirqs</title>
+ <title>Software Interrupt Context: Softirqs and Tasklets</title>
<para>
Whenever a system call is about to return to userspace, or a
- hardware interrupt handler exits, any `software interrupts'
+ hardware interrupt handler exits, any 'software interrupts'
which are marked pending (usually by hardware interrupts) are
run (<filename>kernel/softirq.c</filename>).
</para>
<para>
Much of the real interrupt handling work is done here. Early in
- the transition to <acronym>SMP</acronym>, there were only `bottom
+ the transition to <acronym>SMP</acronym>, there were only 'bottom
halves' (BHs), which didn't take advantage of multiple CPUs. Shortly
after we switched from wind-up computers made of match-sticks and snot,
- we abandoned this limitation.
+ we abandoned this limitation and switched to 'softirqs'.
</para>
<para>
<filename class="headerfile">include/linux/interrupt.h</filename> lists the
- different BH's. No matter how many CPUs you have, no two BHs will run at
- the same time. This made the transition to SMP simpler, but sucks hard for
- scalable performance. A very important bottom half is the timer
- BH (<filename class="headerfile">include/linux/timer.h</filename>): you
- can register to have it call functions for you in a given length of time.
+ different softirqs. A very important softirq is the
+ timer softirq (<filename
+ class="headerfile">include/linux/timer.h</filename>): you can
+ register to have it call functions for you in a given length of
+ time.
</para>
<para>
- 2.3.43 introduced softirqs, and re-implemented the (now
- deprecated) BHs underneath them. Softirqs are fully-SMP
- versions of BHs: they can run on as many CPUs at once as
- required. This means they need to deal with any races in shared
- data using their own locks. A bitmask is used to keep track of
- which are enabled, so the 32 available softirqs should not be
- used up lightly. (<emphasis>Yes</emphasis>, people will
- notice).
- </para>
-
- <para>
- tasklets (<filename class="headerfile">include/linux/interrupt.h</filename>)
- are like softirqs, except they are dynamically-registrable (meaning you
- can have as many as you want), and they also guarantee that any tasklet
- will only run on one CPU at any time, although different tasklets can
- run simultaneously (unlike different BHs).
+ Softirqs are often a pain to deal with, since the same softirq
+ will run simultaneously on more than one CPU. For this reason,
+ tasklets (<filename
+ class="headerfile">include/linux/interrupt.h</filename>) are more
+ often used: they are dynamically-registrable (meaning you can have
+ as many as you want), and they also guarantee that any tasklet
+ will only run on one CPU at any time, although different tasklets
+ can run simultaneously.
</para>
<caution>
<para>
- The name `tasklet' is misleading: they have nothing to do with `tasks',
+ The name 'tasklet' is misleading: they have nothing to do with 'tasks',
and probably more to do with some bad vodka Alexey Kuznetsov had at the
time.
</para>
</caution>
<para>
- You can tell you are in a softirq (or bottom half, or tasklet)
+ You can tell you are in a softirq (or tasklet)
using the <function>in_softirq()</function> macro
(<filename class="headerfile">include/linux/interrupt.h</filename>).
</para>
@@ -288,11 +280,10 @@
<term>A rigid stack limit</term>
<listitem>
<para>
- The kernel stack is about 6K in 2.2 (for most
- architectures: it's about 14K on the Alpha), and shared
- with interrupts so you can't use it all. Avoid deep
- recursion and huge local arrays on the stack (allocate
- them dynamically instead).
+ Depending on configuration options the kernel stack is about 3K to 6K for most 32-bit architectures: it's
+ about 14K on most 64-bit archs, and often shared with interrupts
+ so you can't use it all. Avoid deep recursion and huge local
+ arrays on the stack (allocate them dynamically instead).
</para>
</listitem>
</varlistentry>
@@ -339,7 +330,7 @@ asmlinkage long sys_mycall(int arg)
<para>
If all your routine does is read or write some parameter, consider
- implementing a <function>sysctl</function> interface instead.
+ implementing a <function>sysfs</function> interface instead.
</para>
<para>
@@ -417,7 +408,10 @@ cond_resched(); /* Will sleep */
</para>
<para>
- You will eventually lock up your box if you break these rules.
+ You should always compile your kernel
+ <symbol>CONFIG_DEBUG_SPINLOCK_SLEEP</symbol> on, and it will warn
+ you if you break these rules. If you <emphasis>do</emphasis> break
+ the rules, you will eventually lock up your box.
</para>
<para>
@@ -515,8 +509,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
success).
</para>
</caution>
- [Yes, this moronic interface makes me cringe. Please submit a
- patch and become my hero --RR.]
+ [Yes, this moronic interface makes me cringe. The flamewar comes up every year or so. --RR.]
</para>
<para>
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));
</variablelist>
<para>
- If you see a <errorname>kmem_grow: Called nonatomically from int
- </errorname> warning message you called a memory allocation function
- from interrupt context without <constant>GFP_ATOMIC</constant>.
- You should really fix that. Run, don't walk.
+ If you see a <errorname>sleeping function called from invalid
+ context</errorname> warning message, then maybe you called a
+ sleeping allocation function from interrupt context without
+ <constant>GFP_ATOMIC</constant>. You should really fix that.
+ Run, don't walk.
</para>
<para>
@@ -639,16 +633,16 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
</sect1>
<sect1 id="routines-udelay">
- <title><function>udelay()</function>/<function>mdelay()</function>
+ <title><function>mdelay()</function>/<function>udelay()</function>
<filename class="headerfile">include/asm/delay.h</filename>
<filename class="headerfile">include/linux/delay.h</filename>
</title>
<para>
- The <function>udelay()</function> function can be used for small pauses.
- Do not use large values with <function>udelay()</function> as you risk
+ The <function>udelay()</function> and <function>ndelay()</function> functions can be used for small pauses.
+ Do not use large values with them as you risk
overflow - the helper function <function>mdelay()</function> is useful
- here, or even consider <function>schedule_timeout()</function>.
+ here, or consider <function>msleep()</function>.
</para>
</sect1>
@@ -698,8 +692,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
These routines disable soft interrupts on the local CPU, and
restore them. They are reentrant; if soft interrupts were
disabled before, they will still be disabled after this pair
- of functions has been called. They prevent softirqs, tasklets
- and bottom halves from running on the current CPU.
+ of functions has been called. They prevent softirqs and tasklets
+ from running on the current CPU.
</para>
</sect1>
@@ -708,10 +702,16 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
<filename class="headerfile">include/asm/smp.h</filename></title>
<para>
- <function>smp_processor_id()</function> returns the current
- processor number, between 0 and <symbol>NR_CPUS</symbol> (the
- maximum number of CPUs supported by Linux, currently 32). These
- values are not necessarily continuous.
+ <function>get_cpu()</function> disables preemption (so you won't
+ suddenly get moved to another CPU) and returns the current
+ processor number, between 0 and <symbol>NR_CPUS</symbol>. Note
+ that the CPU numbers are not necessarily continuous. You return
+ it again with <function>put_cpu()</function> when you are done.
+ </para>
+ <para>
+ If you know you cannot be preempted by another task (ie. you are
+ in interrupt context, or have preemption disabled) you can use
+ smp_processor_id().
</para>
</sect1>
@@ -722,19 +722,14 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
<para>
After boot, the kernel frees up a special section; functions
marked with <type>__init</type> and data structures marked with
- <type>__initdata</type> are dropped after boot is complete (within
- modules this directive is currently ignored). <type>__exit</type>
+ <type>__initdata</type> are dropped after boot is complete: similarly
+ modules discard this memory after initialization. <type>__exit</type>
is used to declare a function which is only required on exit: the
function will be dropped if this file is not compiled as a module.
See the header file for use. Note that it makes no sense for a function
marked with <type>__init</type> to be exported to modules with
<function>EXPORT_SYMBOL()</function> - this will break.
</para>
- <para>
- Static data structures marked as <type>__initdata</type> must be initialised
- (as opposed to ordinary static data which is zeroed BSS) and cannot be
- <type>const</type>.
- </para>
</sect1>
@@ -762,9 +757,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
<para>
The function can return a negative error number to cause
module loading to fail (unfortunately, this has no effect if
- the module is compiled into the kernel). For modules, this is
- called in user context, with interrupts enabled, and the
- kernel lock held, so it can sleep.
+ the module is compiled into the kernel). This function is
+ called in user context with interrupts enabled, so it can sleep.
</para>
</sect1>
@@ -779,6 +773,34 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
reached zero. This function can also sleep, but cannot fail:
everything must be cleaned up by the time it returns.
</para>
+
+ <para>
+ Note that this macro is optional: if it is not present, your
+ module will not be removable (except for 'rmmod -f').
+ </para>
+ </sect1>
+
+ <sect1 id="routines-module-use-counters">
+ <title> <function>try_module_get()</function>/<function>module_put()</function>
+ <filename class="headerfile">include/linux/module.h</filename></title>
+
+ <para>
+ These manipulate the module usage count, to protect against
+ removal (a module also can't be removed if another module uses one
+ of its exported symbols: see below). Before calling into module
+ code, you should call <function>try_module_get()</function> on
+ that module: if it fails, then the module is being removed and you
+ should act as if it wasn't there. Otherwise, you can safely enter
+ the module, and call <function>module_put()</function> when you're
+ finished.
+ </para>
+
+ <para>
+ Most registerable structures have an
+ <structfield>owner</structfield> field, such as in the
+ <structname>file_operations</structname> structure. Set this field
+ to the macro <symbol>THIS_MODULE</symbol>.
+ </para>
</sect1>
<!-- add info on new-style module refcounting here -->
@@ -821,7 +843,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
There is a macro to do this:
<function>wait_event_interruptible()</function>
- <filename class="headerfile">include/linux/sched.h</filename> The
+ <filename class="headerfile">include/linux/wait.h</filename> The
first argument is the wait queue head, and the second is an
expression which is evaluated; the macro returns
<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));
<para>
Call <function>wake_up()</function>
- <filename class="headerfile">include/linux/sched.h</filename>;,
+ <filename class="headerfile">include/linux/wait.h</filename>;,
which will wake up every process in the queue. The exception is
if one has <constant>TASK_EXCLUSIVE</constant> set, in which case
- the remainder of the queue will not be woken.
+ the remainder of the queue will not be woken. There are other variants
+ of this basic function available in the same header.
</para>
</sect1>
</chapter>
@@ -863,7 +886,7 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
first class of operations work on <type>atomic_t</type>
<filename class="headerfile">include/asm/atomic.h</filename>; this
- contains a signed integer (at least 24 bits long), and you must use
+ contains a signed integer (at least 32 bits long), and you must use
these functions to manipulate or read atomic_t variables.
<function>atomic_read()</function> and
<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));
<para>
Note that these functions are slower than normal arithmetic, and
- so should not be used unnecessarily. On some platforms they
- are much slower, like 32-bit Sparc where they use a spinlock.
+ so should not be used unnecessarily.
</para>
<para>
- The second class of atomic operations is atomic bit operations on a
- <type>long</type>, defined in
+ The second class of atomic operations is atomic bit operations on an
+ <type>unsigned long</type>, defined in
<filename class="headerfile">include/linux/bitops.h</filename>. These
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));
<function>test_and_clear_bit()</function> and
<function>test_and_change_bit()</function> do the same thing,
except return true if the bit was previously set; these are
- particularly useful for very simple locking.
+ particularly useful for atomically setting flags.
</para>
<para>
@@ -907,12 +929,6 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
than BITS_PER_LONG. The resulting behavior is strange on big-endian
platforms though so it is a good idea not to do this.
</para>
-
- <para>
- Note that the order of bits depends on the architecture, and in
- particular, the bitfield passed to these operations must be at
- least as large as a <type>long</type>.
- </para>
</chapter>
<chapter id="symbols">
@@ -932,11 +948,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
<filename class="headerfile">include/linux/module.h</filename></title>
<para>
- This is the classic method of exporting a symbol, and it works
- for both modules and non-modules. In the kernel all these
- declarations are often bundled into a single file to help
- genksyms (which searches source files for these declarations).
- See the comment on genksyms and Makefiles below.
+ This is the classic method of exporting a symbol: dynamically
+ loaded modules will be able to use the symbol as normal.
</para>
</sect1>
@@ -949,7 +962,8 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can
only be seen by modules with a
<function>MODULE_LICENSE()</function> that specifies a GPL
- compatible license.
+ compatible license. It implies that the function is considered
+ an internal implementation issue, and not really an interface.
</para>
</sect1>
</chapter>
@@ -962,12 +976,13 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
<filename class="headerfile">include/linux/list.h</filename></title>
<para>
- There are three sets of linked-list routines in the kernel
- headers, but this one seems to be winning out (and Linus has
- used it). If you don't have some particular pressing need for
- a single list, it's a good choice. In fact, I don't care
- whether it's a good choice or not, just use it so we can get
- rid of the others.
+ There used to be three sets of linked-list routines in the kernel
+ headers, but this one is the winner. If you don't have some
+ particular pressing need for a single list, it's a good choice.
+ </para>
+
+ <para>
+ In particular, <function>list_for_each_entry</function> is useful.
</para>
</sect1>
@@ -979,14 +994,13 @@ printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress));
convention, and return <returnvalue>0</returnvalue> for success,
and a negative error number
(eg. <returnvalue>-EFAULT</returnvalue>) for failure. This can be
- unintuitive at first, but it's fairly widespread in the networking
- code, for example.
+ unintuitive at first, but it's fairly widespread in the kernel.
</para>
<para>
- The filesystem code uses <function>ERR_PTR()</function>
+ Using <function>ERR_PTR()</function>
- <filename class="headerfile">include/linux/fs.h</filename>; to
+ <filename class="headerfile">include/linux/err.h</filename>; to
encode a negative error number into a pointer, and
<function>IS_ERR()</function> and <function>PTR_ERR()</function>
to get it back out again: avoids a separate pointer parameter for
@@ -1040,7 +1054,7 @@ static struct block_device_operations opt_fops = {
supported, due to lack of general use, but the following are
considered standard (see the GCC info page section "C
Extensions" for more details - Yes, really the info page, the
- man page is only a short summary of the stuff in info):
+ man page is only a short summary of the stuff in info).
</para>
<itemizedlist>
<listitem>
@@ -1091,7 +1105,7 @@ static struct block_device_operations opt_fops = {
</listitem>
<listitem>
<para>
- Function names as strings (__FUNCTION__)
+ Function names as strings (__func__).
</para>
</listitem>
<listitem>
@@ -1164,63 +1178,35 @@ static struct block_device_operations opt_fops = {
<listitem>
<para>
Usually you want a configuration option for your kernel hack.
- Edit <filename>Config.in</filename> in the appropriate directory
- (but under <filename>arch/</filename> it's called
- <filename>config.in</filename>). The Config Language used is not
- bash, even though it looks like bash; the safe way is to use only
- the constructs that you already see in
- <filename>Config.in</filename> files (see
- <filename>Documentation/kbuild/kconfig-language.txt</filename>).
- It's good to run "make xconfig" at least once to test (because
- it's the only one with a static parser).
- </para>
-
- <para>
- Variables which can be Y or N use <type>bool</type> followed by a
- tagline and the config define name (which must start with
- CONFIG_). The <type>tristate</type> function is the same, but
- allows the answer M (which defines
- <symbol>CONFIG_foo_MODULE</symbol> in your source, instead of
- <symbol>CONFIG_FOO</symbol>) if <symbol>CONFIG_MODULES</symbol>
- is enabled.
+ Edit <filename>Kconfig</filename> in the appropriate directory.
+ The Config language is simple to use by cut and paste, and there's
+ complete documentation in
+ <filename>Documentation/kbuild/kconfig-language.txt</filename>.
</para>
<para>
You may well want to make your CONFIG option only visible if
<symbol>CONFIG_EXPERIMENTAL</symbol> is enabled: this serves as a
warning to users. There many other fancy things you can do: see
- the various <filename>Config.in</filename> files for ideas.
+ the various <filename>Kconfig</filename> files for ideas.
</para>
- </listitem>
- <listitem>
<para>
- Edit the <filename>Makefile</filename>: the CONFIG variables are
- exported here so you can conditionalize compilation with `ifeq'.
- If your file exports symbols then add the names to
- <varname>export-objs</varname> so that genksyms will find them.
- <caution>
- <para>
- There is a restriction on the kernel build system that objects
- which export symbols must have globally unique names.
- If your object does not have a globally unique name then the
- standard fix is to move the
- <function>EXPORT_SYMBOL()</function> statements to their own
- object with a unique name.
- This is why several systems have separate exporting objects,
- usually suffixed with ksyms.
- </para>
- </caution>
+ In your description of the option, make sure you address both the
+ expert user and the user who knows nothing about your feature. Mention
+ incompatibilities and issues here. <emphasis> Definitely
+ </emphasis> end your description with <quote> if in doubt, say N
+ </quote> (or, occasionally, `Y'); this is for people who have no
+ idea what you are talking about.
</para>
</listitem>
<listitem>
<para>
- Document your option in Documentation/Configure.help. Mention
- incompatibilities and issues here. <emphasis> Definitely
- </emphasis> end your description with <quote> if in doubt, say N
- </quote> (or, occasionally, `Y'); this is for people who have no
- idea what you are talking about.
+ Edit the <filename>Makefile</filename>: the CONFIG variables are
+ exported here so you can usually just add a "obj-$(CONFIG_xxx) +=
+ xxx.o" line. The syntax is documented in
+ <filename>Documentation/kbuild/makefiles.txt</filename>.
</para>
</listitem>
@@ -1253,20 +1239,12 @@ static struct block_device_operations opt_fops = {
</para>
<para>
- <filename>include/linux/brlock.h:</filename>
+ <filename>include/asm-i386/delay.h:</filename>
</para>
<programlisting>
-extern inline void br_read_lock (enum brlock_indices idx)
-{
- /*
- * This causes a link-time bug message if an
- * invalid index is used:
- */
- if (idx >= __BR_END)
- __br_lock_usage_bug();
-
- read_lock(&amp;__brlock_array[smp_processor_id()][idx]);
-}
+#define ndelay(n) (__builtin_constant_p(n) ? \
+ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
+ __ndelay(n))
</programlisting>
<para>
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
new file mode 100644
index 00000000000..a23fee66064
--- /dev/null
+++ b/Documentation/RCU/rcuref.txt
@@ -0,0 +1,74 @@
+Refcounter framework for elements of lists/arrays protected by
+RCU.
+
+Refcounting on elements of lists which are protected by traditional
+reader/writer spinlocks or semaphores are straight forward as in:
+
+1. 2.
+add() search_and_reference()
+{ {
+ alloc_object read_lock(&list_lock);
+ ... search_for_element
+ atomic_set(&el->rc, 1); atomic_inc(&el->rc);
+ write_lock(&list_lock); ...
+ add_element read_unlock(&list_lock);
+ ... ...
+ write_unlock(&list_lock); }
+}
+
+3. 4.
+release_referenced() delete()
+{ {
+ ... write_lock(&list_lock);
+ atomic_dec(&el->rc, relfunc) ...
+ ... delete_element
+} write_unlock(&list_lock);
+ ...
+ if (atomic_dec_and_test(&el->rc))
+ kfree(el);
+ ...
+ }
+
+If this list/array is made lock free using rcu as in changing the
+write_lock in add() and delete() to spin_lock and changing read_lock
+in search_and_reference to rcu_read_lock(), the rcuref_get in
+search_and_reference could potentially hold reference to an element which
+has already been deleted from the list/array. rcuref_lf_get_rcu takes
+care of this scenario. search_and_reference should look as;
+
+1. 2.
+add() search_and_reference()
+{ {
+ alloc_object rcu_read_lock();
+ ... search_for_element
+ atomic_set(&el->rc, 1); if (rcuref_inc_lf(&el->rc)) {
+ write_lock(&list_lock); rcu_read_unlock();
+ return FAIL;
+ add_element }
+ ... ...
+ write_unlock(&list_lock); rcu_read_unlock();
+} }
+3. 4.
+release_referenced() delete()
+{ {
+ ... write_lock(&list_lock);
+ rcuref_dec(&el->rc, relfunc) ...
+ ... delete_element
+} write_unlock(&list_lock);
+ ...
+ if (rcuref_dec_and_test(&el->rc))
+ call_rcu(&el->head, el_free);
+ ...
+ }
+
+Sometimes, reference to the element need to be obtained in the
+update (write) stream. In such cases, rcuref_inc_lf might be an overkill
+since the spinlock serialising list updates are held. rcuref_inc
+is to be used in such cases.
+For arches which do not have cmpxchg rcuref_inc_lf
+api uses a hashed spinlock implementation and the same hashed spinlock
+is acquired in all rcuref_xxx primitives to preserve atomicity.
+Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the
+refcounter atleast at one place. Mixing rcuref_inc and atomic_xxx api
+might lead to races. rcuref_inc_lf() must be used in lockfree
+RCU critical sections only.
diff --git a/Documentation/applying-patches.txt b/Documentation/applying-patches.txt
new file mode 100644
index 00000000000..681e426e248
--- /dev/null
+++ b/Documentation/applying-patches.txt
@@ -0,0 +1,439 @@
+
+ Applying Patches To The Linux Kernel
+ ------------------------------------
+
+ (Written by Jesper Juhl, August 2005)
+
+
+
+A frequently asked question on the Linux Kernel Mailing List is how to apply
+a patch to the kernel or, more specifically, what base kernel a patch for
+one of the many trees/branches should be applied to. Hopefully this document
+will explain this to you.
+
+In addition to explaining how to apply and revert patches, a brief
+description of the different kernel trees (and examples of how to apply
+their specific patches) is also provided.
+
+
+What is a patch?
+---
+ A patch is a small text document containing a delta of changes between two
+different versions of a source tree. Patches are created with the `diff'
+program.
+To correctly apply a patch you need to know what base it was generated from
+and what new version the patch will change the source tree into. These
+should both be present in the patch file metadata or be possible to deduce
+from the filename.
+
+
+How do I apply or revert a patch?
+---
+ You apply a patch with the `patch' program. The patch program reads a diff
+(or patch) file and makes the changes to the source tree described in it.
+
+Patches for the Linux kernel are generated relative to the parent directory
+holding the kernel source dir.
+
+This means that paths to files inside the patch file contain the name of the
+kernel source directories it was generated against (or some other directory
+names like "a/" and "b/").
+Since this is unlikely to match the name of the kernel source dir on your
+local machine (but is often useful info to see what version an otherwise
+unlabeled patch was generated against) you should change into your kernel
+source directory and then strip the first element of the path from filenames
+in the patch file when applying it (the -p1 argument to `patch' does this).
+
+To revert a previously applied patch, use the -R argument to patch.
+So, if you applied a patch like this:
+ patch -p1 < ../patch-x.y.z
+
+You can revert (undo) it like this:
+ patch -R -p1 < ../patch-x.y.z
+
+
+How do I feed a patch/diff file to `patch'?
+---
+ This (as usual with Linux and other UNIX like operating systems) can be
+done in several different ways.
+In all the examples below I feed the file (in uncompressed form) to patch
+via stdin using the following syntax:
+ patch -p1 < path/to/patch-x.y.z
+
+If you just want to be able to follow the examples below and don't want to
+know of more than one way to use patch, then you can stop reading this
+section here.
+
+Patch can also get the name of the file to use via the -i argument, like
+this:
+ patch -p1 -i path/to/patch-x.y.z
+
+If your patch file is compressed with gzip or bzip2 and you don't want to
+uncompress it before applying it, then you can feed it to patch like this
+instead:
+ zcat path/to/patch-x.y.z.gz | patch -p1
+ bzcat path/to/patch-x.y.z.bz2 | patch -p1
+
+If you wish to uncompress the patch file by hand first before applying it
+(what I assume you've done in the examples below), then you simply run
+gunzip or bunzip2 on the file - like this:
+ gunzip patch-x.y.z.gz
+ bunzip2 patch-x.y.z.bz2
+
+Which will leave you with a plain text patch-x.y.z file that you can feed to
+patch via stdin or the -i argument, as you prefer.
+
+A few other nice arguments for patch are -s which causes patch to be silent
+except for errors which is nice to prevent errors from scrolling out of the
+screen too fast, and --dry-run which causes patch to just print a listing of
+what would happen, but doesn't actually make any changes. Finally --verbose
+tells patch to print more information about the work being done.
+
+
+Common errors when patching
+---
+ When patch applies a patch file it attempts to verify the sanity of the
+file in different ways.
+Checking that the file looks like a valid patch file, checking the code
+around the bits being modified matches the context provided in the patch are
+just two of the basic sanity checks patch does.
+
+If patch encounters something that doesn't look quite right it has two
+options. It can either refuse to apply the changes and abort or it can try
+to find a way to make the patch apply with a few minor changes.
+
+One example of something that's not 'quite right' that patch will attempt to
+fix up is if all the context matches, the lines being changed match, but the
+line numbers are different. This can happen, for example, if the patch makes
+a change in the middle of the file but for some reasons a few lines have
+been added or removed near the beginning of the file. In that case
+everything looks good it has just moved up or down a bit, and patch will
+usually adjust the line numbers and apply the patch.
+
+Whenever patch applies a patch that it had to modify a bit to make it fit
+it'll tell you about it by saying the patch applied with 'fuzz'.
+You should be wary of such changes since even though patch probably got it
+right it doesn't /always/ get it right, and the result will sometimes be
+wrong.
+
+When patch encounters a change that it can't fix up with fuzz it rejects it
+outright and leaves a file with a .rej extension (a reject file). You can
+read this file to see exactely what change couldn't be applied, so you can
+go fix it up by hand if you wish.
+
+If you don't have any third party patches applied to your kernel source, but
+only patches from kernel.org and you apply the patches in the correct order,
+and have made no modifications yourself to the source files, then you should
+never see a fuzz or reject message from patch. If you do see such messages
+anyway, then there's a high risk that either your local source tree or the
+patch file is corrupted in some way. In that case you should probably try
+redownloading the patch and if things are still not OK then you'd be advised
+to start with a fresh tree downloaded in full from kernel.org.
+
+Let's look a bit more at some of the messages patch can produce.
+
+If patch stops and presents a "File to patch:" prompt, then patch could not
+find a file to be patched. Most likely you forgot to specify -p1 or you are
+in the wrong directory. Less often, you'll find patches that need to be
+applied with -p0 instead of -p1 (reading the patch file should reveal if
+this is the case - if so, then this is an error by the person who created
+the patch but is not fatal).
+
+If you get "Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines)." or a
+message similar to that, then it means that patch had to adjust the location
+of the change (in this example it needed to move 7 lines from where it
+expected to make the change to make it fit).
+The resulting file may or may not be OK, depending on the reason the file
+was different than expected.
+This often happens if you try to apply a patch that was generated against a
+different kernel version than the one you are trying to patch.
+
+If you get a message like "Hunk #3 FAILED at 2387.", then it means that the
+patch could not be applied correctly and the patch program was unable to
+fuzz its way through. This will generate a .rej file with the change that
+caused the patch to fail and also a .orig file showing you the original
+content that couldn't be changed.
+
+If you get "Reversed (or previously applied) patch detected! Assume -R? [n]"
+then patch detected that the change contained in the patch seems to have
+already been made.
+If you actually did apply this patch previously and you just re-applied it
+in error, then just say [n]o and abort this patch. If you applied this patch
+previously and actually intended to revert it, but forgot to specify -R,
+then you can say [y]es here to make patch revert it for you.
+This can also happen if the creator of the patch reversed the source and
+destination directories when creating the patch, and in that case reverting
+the patch will in fact apply it.
+
+A message similar to "patch: **** unexpected end of file in patch" or "patch
+unexpectedly ends in middle of line" means that patch could make no sense of
+the file you fed to it. Either your download is broken or you tried to feed
+patch a compressed patch file without uncompressing it first.
+
+As I already mentioned above, these errors should never happen if you apply
+a patch from kernel.org to the correct version of an unmodified source tree.
+So if you get these errors with kernel.org patches then you should probably
+assume that either your patch file or your tree is broken and I'd advice you
+to start over with a fresh download of a full kernel tree and the patch you
+wish to apply.
+
+
+Are there any alternatives to `patch'?
+---
+ Yes there are alternatives. You can use the `interdiff' program
+(http://cyberelk.net/tim/patchutils/) to generate a patch representing the
+differences between two patches and then apply the result.
+This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single
+step. The -z flag to interdiff will even let you feed it patches in gzip or
+bzip2 compressed form directly without the use of zcat or bzcat or manual
+decompression.
+
+Here's how you'd go from 2.6.12.2 to 2.6.12.3 in a single step:
+ interdiff -z ../patch-2.6.12.2.bz2 ../patch-2.6.12.3.gz | patch -p1
+
+Although interdiff may save you a step or two you are generally advised to
+do the additional steps since interdiff can get things wrong in some cases.
+
+ Another alternative is `ketchup', which is a python script for automatic
+downloading and applying of patches (http://www.selenic.com/ketchup/).
+
+Other nice tools are diffstat which shows a summary of changes made by a
+patch, lsdiff which displays a short listing of affected files in a patch
+file, along with (optionally) the line numbers of the start of each patch
+and grepdiff which displays a list of the files modified by a patch where
+the patch contains a given regular expression.
+
+
+Where can I download the patches?
+---
+ The patches are available at http://kernel.org/
+Most recent patches are linked from the front page, but they also have
+specific homes.
+
+The 2.6.x.y (-stable) and 2.6.x patches live at
+ ftp://ftp.kernel.org/pub/linux/kernel/v2.6/
+
+The -rc patches live at
+ ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing/
+
+The -git patches live at
+ ftp://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/
+
+The -mm kernels live at
+ ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/
+
+In place of ftp.kernel.org you can use ftp.cc.kernel.org, where cc is a
+country code. This way you'll be downloading from a mirror site that's most
+likely geographically closer to you, resulting in faster downloads for you,
+less bandwidth used globally and less load on the main kernel.org servers -
+these are good things, do use mirrors when possible.
+
+
+The 2.6.x kernels
+---
+ These are the base stable releases released by Linus. The highest numbered
+release is the most recent.
+
+If regressions or other serious flaws are found then a -stable fix patch
+will be released (see below) on top of this base. Once a new 2.6.x base
+kernel is released, a patch is made available that is a delta between the
+previous 2.6.x kernel and the new one.
+
+To apply a patch moving from 2.6.11 to 2.6.12 you'd do the following (note
+that such patches do *NOT* apply on top of 2.6.x.y kernels but on top of the
+base 2.6.x kernel - if you need to move from 2.6.x.y to 2.6.x+1 you need to
+first revert the 2.6.x.y patch).
+
+Here are some examples:
+
+# moving from 2.6.11 to 2.6.12
+$ cd ~/linux-2.6.11 # change to kernel source dir
+$ patch -p1 < ../patch-2.6.12 # apply the 2.6.12 patch
+$ cd ..
+$ mv linux-2.6.11 linux-2.6.12 # rename source dir
+
+# moving from 2.6.11.1 to 2.6.12
+$ cd ~/linux-2.6.11.1 # change to kernel source dir
+$ patch -p1 -R < ../patch-2.6.11.1 # revert the 2.6.11.1 patch
+ # source dir is now 2.6.11
+$ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch
+$ cd ..
+$ mv linux-2.6.11.1 inux-2.6.12 # rename source dir
+
+
+The 2.6.x.y kernels
+---
+ Kernels with 4 digit versions are -stable kernels. They contain small(ish)
+critical fixes for security problems or significant regressions discovered
+in a given 2.6.x kernel.
+
+This is the recommended branch for users who want the most recent stable
+kernel and are not interested in helping test development/experimental
+versions.
+
+If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is
+the current stable kernel.
+
+These patches are not incremental, meaning that for example the 2.6.12.3
+patch does not apply on top of the 2.6.12.2 kernel source, but rather on top
+of the base 2.6.12 kernel source.
+So, in order to apply the 2.6.12.3 patch to your existing 2.6.12.2 kernel
+source you have to first back out the 2.6.12.2 patch (so you are left with a
+base 2.6.12 kernel source) and then apply the new 2.6.12.3 patch.
+
+Here's a small example:
+
+$ cd ~/linux-2.6.12.2 # change into the kernel source dir
+$ patch -p1 -R < ../patch-2.6.12.2 # revert the 2.6.12.2 patch
+$ patch -p1 < ../patch-2.6.12.3 # apply the new 2.6.12.3 patch
+$ cd ..
+$ mv linux-2.6.12.2 linux-2.6.12.3 # rename the kernel source dir
+
+
+The -rc kernels
+---
+ These are release-candidate kernels. These are development kernels released
+by Linus whenever he deems the current git (the kernel's source management
+tool) tree to be in a reasonably sane state adequate for testing.
+
+These kernels are not stable and you should expect occasional breakage if
+you intend to run them. This is however the most stable of the main
+development branches and is also what will eventually turn into the next
+stable kernel, so it is important that it be tested by as many people as
+possible.
+
+This is a good branch to run for people who want to help out testing
+development kernels but do not want to run some of the really experimental
+stuff (such people should see the sections about -git and -mm kernels below).
+
+The -rc patches are not incremental, they apply to a base 2.6.x kernel, just
+like the 2.6.x.y patches described above. The kernel version before the -rcN
+suffix denotes the version of the kernel that this -rc kernel will eventually
+turn into.
+So, 2.6.13-rc5 means that this is the fifth release candidate for the 2.6.13
+kernel and the patch should be applied on top of the 2.6.12 kernel source.
+
+Here are 3 examples of how to apply these patches:
+
+# first an example of moving from 2.6.12 to 2.6.13-rc3
+$ cd ~/linux-2.6.12 # change into the 2.6.12 source dir
+$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
+$ cd ..
+$ mv linux-2.6.12 linux-2.6.13-rc3 # rename the source dir
+
+# now let's move from 2.6.13-rc3 to 2.6.13-rc5
+$ cd ~/linux-2.6.13-rc3 # change into the 2.6.13-rc3 dir
+$ patch -p1 -R < ../patch-2.6.13-rc3 # revert the 2.6.13-rc3 patch
+$ patch -p1 < ../patch-2.6.13-rc5 # apply the new 2.6.13-rc5 patch
+$ cd ..
+$ mv linux-2.6.13-rc3 linux-2.6.13-rc5 # rename the source dir
+
+# finally let's try and move from 2.6.12.3 to 2.6.13-rc5
+$ cd ~/linux-2.6.12.3 # change to the kernel source dir
+$ patch -p1 -R < ../patch-2.6.12.3 # revert the 2.6.12.3 patch
+$ patch -p1 < ../patch-2.6.13-rc5 # apply new 2.6.13-rc5 patch
+$ cd ..
+$ mv linux-2.6.12.3 linux-2.6.13-rc5 # rename the kernel source dir
+
+
+The -git kernels
+---
+ These are daily snapshots of Linus' kernel tree (managed in a git
+repository, hence the name).
+
+These patches are usually released daily and represent the current state of
+Linus' tree. They are more experimental than -rc kernels since they are
+generated automatically without even a cursory glance to see if they are
+sane.
+
+-git patches are not incremental and apply either to a base 2.6.x kernel or
+a base 2.6.x-rc kernel - you can see which from their name.
+A patch named 2.6.12-git1 applies to the 2.6.12 kernel source and a patch
+named 2.6.13-rc3-git2 applies to the source of the 2.6.13-rc3 kernel.
+
+Here are some examples of how to apply these patches:
+
+# moving from 2.6.12 to 2.6.12-git1
+$ cd ~/linux-2.6.12 # change to the kernel source dir
+$ patch -p1 < ../patch-2.6.12-git1 # apply the 2.6.12-git1 patch
+$ cd ..
+$ mv linux-2.6.12 linux-2.6.12-git1 # rename the kernel source dir
+
+# moving from 2.6.12-git1 to 2.6.13-rc2-git3
+$ cd ~/linux-2.6.12-git1 # change to the kernel source dir
+$ patch -p1 -R < ../patch-2.6.12-git1 # revert the 2.6.12-git1 patch
+ # we now have a 2.6.12 kernel
+$ patch -p1 < ../patch-2.6.13-rc2 # apply the 2.6.13-rc2 patch
+ # the kernel is now 2.6.13-rc2
+$ patch -p1 < ../patch-2.6.13-rc2-git3 # apply the 2.6.13-rc2-git3 patch
+ # the kernel is now 2.6.13-rc2-git3
+$ cd ..
+$ mv linux-2.6.12-git1 linux-2.6.13-rc2-git3 # rename source dir
+
+
+The -mm kernels
+---
+ These are experimental kernels released by Andrew Morton.
+
+The -mm tree serves as a sort of proving ground for new features and other
+experimental patches.
+Once a patch has proved its worth in -mm for a while Andrew pushes it on to
+Linus for inclusion in mainline.
+
+Although it's encouraged that patches flow to Linus via the -mm tree, this
+is not always enforced.
+Subsystem maintainers (or individuals) sometimes push their patches directly
+to Linus, even though (or after) they have been merged and tested in -mm (or
+sometimes even without prior testing in -mm).
+
+You should generally strive to get your patches into mainline via -mm to
+ensure maximum testing.
+
+This branch is in constant flux and contains many experimental features, a
+lot of debugging patches not appropriate for mainline etc and is the most
+experimental of the branches described in this document.
+
+These kernels are not appropriate for use on systems that are supposed to be
+stable and they are more risky to run than any of the other branches (make
+sure you have up-to-date backups - that goes for any experimental kernel but
+even more so for -mm kernels).
+
+These kernels in addition to all the other experimental patches they contain
+usually also contain any changes in the mainline -git kernels available at
+the time of release.
+
+Testing of -mm kernels is greatly appreciated since the whole point of the
+tree is to weed out regressions, crashes, data corruption bugs, build
+breakage (and any other bug in general) before changes are merged into the
+more stable mainline Linus tree.
+But testers of -mm should be aware that breakage in this tree is more common
+than in any other tree.
+
+The -mm kernels are not released on a fixed schedule, but usually a few -mm
+kernels are released in between each -rc kernel (1 to 3 is common).
+The -mm kernels apply to either a base 2.6.x kernel (when no -rc kernels
+have been released yet) or to a Linus -rc kernel.
+
+Here are some examples of applying the -mm patches:
+
+# moving from 2.6.12 to 2.6.12-mm1
+$ cd ~/linux-2.6.12 # change to the 2.6.12 source dir
+$ patch -p1 < ../2.6.12-mm1 # apply the 2.6.12-mm1 patch
+$ cd ..
+$ mv linux-2.6.12 linux-2.6.12-mm1 # rename the source appropriately
+
+# moving from 2.6.12-mm1 to 2.6.13-rc3-mm3
+$ cd ~/linux-2.6.12-mm1
+$ patch -p1 -R < ../2.6.12-mm1 # revert the 2.6.12-mm1 patch
+ # we now have a 2.6.12 source
+$ patch -p1 < ../patch-2.6.13-rc3 # apply the 2.6.13-rc3 patch
+ # we now have a 2.6.13-rc3 source
+$ patch -p1 < ../2.6.13-rc3-mm3 # apply the 2.6.13-rc3-mm3 patch
+$ cd ..
+$ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir
+
+
+This concludes this list of explanations of the various kernel trees and I
+hope you are now crystal clear on how to apply the various patches and help
+testing the kernel.
+
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index 4b8c326c6aa..cb63b7a93c8 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,55 +1,74 @@
-How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working
-=========================================================================================
+How to get the Nebula, PCTV and Twinhan DST cards working
+=========================================================
-1) General information
-======================
+This class of cards has a bt878a as the PCI interface, and
+require the bttv driver.
-This class of cards has a bt878a chip as the PCI interface.
-The different card drivers require the bttv driver to provide the means
-to access the i2c bus and the gpio pins of the bt8xx chipset.
+Please pay close attention to the warning about the bttv module
+options below for the DST card.
-2) Compilation rules for Kernel >= 2.6.12
-=========================================
+1) General informations
+=======================
-Enable the following options:
+These drivers require the bttv driver to provide the means to access
+the i2c bus and the gpio pins of the bt8xx chipset.
+Because of this, you need to enable
"Device drivers" => "Multimedia devices"
- => "Video For Linux" => "BT848 Video For Linux"
+ => "Video For Linux" => "BT848 Video For Linux"
+
+Furthermore you need to enable
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
- => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards"
+ => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards"
-3) Loading Modules, described by two approaches
-===============================================
+2) Loading Modules
+==================
In general you need to load the bttv driver, which will handle the gpio and
-i2c communication for us, plus the common dvb-bt8xx device driver,
-which is called the backend.
-The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110),
-TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend.
-For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt.
+i2c communication for us, plus the common dvb-bt8xx device driver.
+The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
+TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
-3a) The manual approach
------------------------
+3a) Nebula / Pinnacle PCTV
+--------------------------
-Loading modules:
-modprobe bttv
-modprobe dvb-bt8xx
+ $ modprobe bttv (normally bttv is being loaded automatically by kmod)
+ $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
-Unloading modules:
-modprobe -r dvb-bt8xx
-modprobe -r bttv
-3b) The automatic approach
+3b) TwinHan and Clones
--------------------------
-If not already done by installation, place a line either in
-/etc/modules.conf or in /etc/modprobe.conf containing this text:
-alias char-major-81 bttv
+ $ modprobe bttv i2c_hw=1 card=0x71
+ $ modprobe dvb-bt8xx
+ $ modprobe dst
+
+The value 0x71 will override the PCI type detection for dvb-bt8xx,
+which is necessary for TwinHan cards.
+
+If you're having an older card (blue color circuit) and card=0x71 locks
+your machine, try using 0x68, too. If that does not work, ask on the
+mailing list.
+
+The DST module takes a couple of useful parameters.
+
+verbose takes values 0 to 4. These values control the verbosity level,
+and can be used to debug also.
+
+verbose=0 means complete disabling of messages
+ 1 only error messages are displayed
+ 2 notifications are also displayed
+ 3 informational messages are also displayed
+ 4 debug setting
+
+dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
+0x20 means it has a Conditional Access slot.
+
+The autodected values are determined bythe cards 'response
+string' which you can see in your logs e.g.
-Then place a line in /etc/modules containing this text:
-dvb-bt8xx
+dst_get_device_id: Recognise [DSTMCI]
-Reboot your system and have fun!
--
-Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
+Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt
index 62e0701b542..95f0e73b213 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.
eg: $ szap -c channels.conf -r "TMC" -x
(b) a channels.conf containing a valid PMT PID
-
eg: TMC:11996:h:0:27500:278:512:650:321
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.
(c) after running a szap, you have to run ca_zap, for the
descrambler to function,
-
- eg: $ ca_zap patched_channels.conf "TMC"
-
- The patched means a patch to apply to scan, such that scan can
- generate a channels.conf_with pmt, which has this PMT PID info
- (NOTE: szap cannot use this channels.conf with the PMT_PID)
-
+ eg: $ ca_zap channels.conf "TMC"
(d) Hopeflly Enjoy your favourite subscribed channel as you do with
a FTA card.
diff --git a/Documentation/fb/cyblafb/bugs b/Documentation/fb/cyblafb/bugs
new file mode 100644
index 00000000000..f90cc66ea91
--- /dev/null
+++ b/Documentation/fb/cyblafb/bugs
@@ -0,0 +1,14 @@
+Bugs
+====
+
+I currently don't know of any bug. Please do send reports to:
+ - linux-fbdev-devel@lists.sourceforge.net
+ - Knut_Petersen@t-online.de.
+
+
+Untested features
+=================
+
+All LCD stuff is untested. If it worked in tridentfb, it should work in
+cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
+
diff --git a/Documentation/fb/cyblafb/credits b/Documentation/fb/cyblafb/credits
new file mode 100644
index 00000000000..0eb3b443dc2
--- /dev/null
+++ b/Documentation/fb/cyblafb/credits
@@ -0,0 +1,7 @@
+Thanks to
+=========
+ * Alan Hourihane, for writing the X trident driver
+ * Jani Monoses, for writing the tridentfb driver
+ * Antonino A. Daplas, for review of the first published
+ version of cyblafb and some code
+ * 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 00000000000..bb1aac04842
--- /dev/null
+++ b/Documentation/fb/cyblafb/documentation
@@ -0,0 +1,17 @@
+Available Documentation
+=======================
+
+Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
+2001, available from VIA:
+
+ http://www.viavpsd.com/product/6/15/DS8601A182.pdf
+
+The datasheet is incomplete, some registers that need to be programmed are not
+explained at all and important bits are listed as "reserved". But you really
+need the datasheet to understand the code. "p. xxx" comments refer to page
+numbers of this document.
+
+XFree/XOrg drivers are available and of good quality, looking at the code
+there is a good idea if the datasheet does not provide enough information
+or if the datasheet seems to be wrong.
+
diff --git a/Documentation/fb/cyblafb/fb.modes b/Documentation/fb/cyblafb/fb.modes
new file mode 100644
index 00000000000..cf4351fc32f
--- /dev/null
+++ b/Documentation/fb/cyblafb/fb.modes
@@ -0,0 +1,155 @@
+#
+# Sample fb.modes file
+#
+# Provides an incomplete list of working modes for
+# the cyberblade/i1 graphics core.
+#
+# The value 4294967256 is used instead of -40. Of course, -40 is not
+# a really reasonable value, but chip design does not always follow
+# logic. Believe me, it's ok, and it's the way the BIOS does it.
+#
+# fbset requires 4294967256 in fb.modes and -40 as an argument to
+# the -t parameter. That's also not too reasonable, and it might change
+# in the future or might even be differt for your current version.
+#
+
+mode "640x480-50"
+ geometry 640 480 640 3756 8
+ timings 47619 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-60"
+ geometry 640 480 640 3756 8
+ timings 39682 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-70"
+ geometry 640 480 640 3756 8
+ timings 34013 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-72"
+ geometry 640 480 640 3756 8
+ timings 33068 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-75"
+ geometry 640 480 640 3756 8
+ timings 31746 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-80"
+ geometry 640 480 640 3756 8
+ timings 29761 4294967256 24 17 0 216 3
+endmode
+
+mode "640x480-85"
+ geometry 640 480 640 3756 8
+ timings 28011 4294967256 24 17 0 216 3
+endmode
+
+mode "800x600-50"
+ geometry 800 600 800 3221 8
+ timings 30303 96 24 14 0 136 11
+endmode
+
+mode "800x600-60"
+ geometry 800 600 800 3221 8
+ timings 25252 96 24 14 0 136 11
+endmode
+
+mode "800x600-70"
+ geometry 800 600 800 3221 8
+ timings 21645 96 24 14 0 136 11
+endmode
+
+mode "800x600-72"
+ geometry 800 600 800 3221 8
+ timings 21043 96 24 14 0 136 11
+endmode
+
+mode "800x600-75"
+ geometry 800 600 800 3221 8
+ timings 20202 96 24 14 0 136 11
+endmode
+
+mode "800x600-80"
+ geometry 800 600 800 3221 8
+ timings 18939 96 24 14 0 136 11
+endmode
+
+mode "800x600-85"
+ geometry 800 600 800 3221 8
+ timings 17825 96 24 14 0 136 11
+endmode
+
+mode "1024x768-50"
+ geometry 1024 768 1024 2815 8
+ timings 19054 144 24 29 0 120 3
+endmode
+
+mode "1024x768-60"
+ geometry 1024 768 1024 2815 8
+ timings 15880 144 24 29 0 120 3
+endmode
+
+mode "1024x768-70"
+ geometry 1024 768 1024 2815 8
+ timings 13610 144 24 29 0 120 3
+endmode
+
+mode "1024x768-72"
+ geometry 1024 768 1024 2815 8
+ timings 13232 144 24 29 0 120 3
+endmode
+
+mode "1024x768-75"
+ geometry 1024 768 1024 2815 8
+ timings 12703 144 24 29 0 120 3
+endmode
+
+mode "1024x768-80"
+ geometry 1024 768 1024 2815 8
+ timings 11910 144 24 29 0 120 3
+endmode
+
+mode "1024x768-85"
+ geometry 1024 768 1024 2815 8
+ timings 11209 144 24 29 0 120 3
+endmode
+
+mode "1280x1024-50"
+ geometry 1280 1024 1280 2662 8
+ timings 11114 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-60"
+ geometry 1280 1024 1280 2662 8
+ timings 9262 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-70"
+ geometry 1280 1024 1280 2662 8
+ timings 7939 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-72"
+ geometry 1280 1024 1280 2662 8
+ timings 7719 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-75"
+ geometry 1280 1024 1280 2662 8
+ timings 7410 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-80"
+ geometry 1280 1024 1280 2662 8
+ timings 6946 232 16 39 0 160 3
+endmode
+
+mode "1280x1024-85"
+ geometry 1280 1024 1280 2662 8
+ timings 6538 232 16 39 0 160 3
+endmode
+
diff --git a/Documentation/fb/cyblafb/performance b/Documentation/fb/cyblafb/performance
new file mode 100644
index 00000000000..eb4e47a9cea
--- /dev/null
+++ b/Documentation/fb/cyblafb/performance
@@ -0,0 +1,80 @@
+Speed
+=====
+
+CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
+for mode 1280x1024-[8,16,32]@61 Hz.
+
+Test 1: Cat a file with 2000 lines of 0 characters.
+Test 2: Cat a file with 2000 lines of 80 characters.
+Test 3: Cat a file with 2000 lines of 160 characters.
+
+All values show system time use in seconds, kernel 2.6.12 was used for
+the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
+patch that speeds up kernel bitblitting a lot ( > 20%).
+
++-----------+-----------------------------------------------------+
+| | not accelerated |
+| TRIDENTFB +-----------------+-----------------+-----------------+
+| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
+| | noypan | ypan | noypan | ypan | noypan | ypan |
++-----------+--------+--------+--------+--------+--------+--------+
+| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- |
+| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- |
+| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- |
++-----------+--------+--------+--------+--------+--------+--------+
+| Comments | | | completely bro- |
+| | | | ken, monitor |
+| | | | switches off |
++-----------+-----------------+-----------------+-----------------+
+
+
++-----------+-----------------------------------------------------+
+| | accelerated |
+| TRIDENTFB +-----------------+-----------------+-----------------+
+| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
+| | noypan | ypan | noypan | ypan | noypan | ypan |
++-----------+--------+--------+--------+--------+--------+--------+
+| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- |
+| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- |
+| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- |
++-----------+--------+--------+--------+--------+--------+--------+
+| Comments | broken, writing | broken, ok only | completely bro- |
+| | to wrong places | if bgcolor is | ken, monitor |
+| | on screen + bug | black, bug in | switches off |
+| | in fillrect() | fillrect() | |
++-----------+-----------------+-----------------+-----------------+
+
+
++-----------+-----------------------------------------------------+
+| | not accelerated |
+| VESAFB +-----------------+-----------------+-----------------+
+| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
+| | noypan | ypan | noypan | ypan | noypan | ypan |
++-----------+--------+--------+--------+--------+--------+--------+
+| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- |
+| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- |
+| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- |
++-----------+--------+--------+--------+--------+--------+--------+
+| Comments | vga=0x307 | vga=0x31a | vga=0x31b not |
+| | fh=80kHz | fh=80kHz | supported by |
+| | fv=75kHz | fv=75kHz | video BIOS and |
+| | | | hardware |
++-----------+-----------------+-----------------+-----------------+
+
+
++-----------+-----------------------------------------------------+
+| | accelerated |
+| CYBLAFB +-----------------+-----------------+-----------------+
+| | 8 bpp | 16 bpp | 32 bpp |
+| | noypan | ypan | noypan | ypan | noypan | ypan |
++-----------+--------+--------+--------+--------+--------+--------+
+| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 |
+| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 |
+| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 |
++-----------+--------+--------+--------+--------+--------+--------+
+| Comments | | | |
+| | | | |
+| | | | |
+| | | | |
++-----------+-----------------+-----------------+-----------------+
+
diff --git a/Documentation/fb/cyblafb/todo b/Documentation/fb/cyblafb/todo
new file mode 100644
index 00000000000..80fb2f89b6c
--- /dev/null
+++ b/Documentation/fb/cyblafb/todo
@@ -0,0 +1,32 @@
+TODO / Missing features
+=======================
+
+Verify LCD stuff "stretch" and "center" options are
+ completely untested ... this code needs to be
+ verified. As I don't have access to such
+ hardware, please contact me if you are
+ willing run some tests.
+
+Interlaced video modes The reason that interleaved
+ modes are disabled is that I do not know
+ the meaning of the vertical interlace
+ parameter. Also the datasheet mentions a
+ bit d8 of a horizontal interlace parameter,
+ but nowhere the lower 8 bits. Please help
+ if you can.
+
+low-res double scan modes Who needs it?
+
+accelerated color blitting Who needs it? The console driver does use color
+ blitting for nothing but drawing the penguine,
+ everything else is done using color expanding
+ blitting of 1bpp character bitmaps.
+
+xpanning Who needs it?
+
+ioctls Who needs it?
+
+TV-out Will be done later
+
+??? Feel free to contact me if you have any
+ feature requests
diff --git a/Documentation/fb/cyblafb/usage b/Documentation/fb/cyblafb/usage
new file mode 100644
index 00000000000..e627c8f5421
--- /dev/null
+++ b/Documentation/fb/cyblafb/usage
@@ -0,0 +1,206 @@
+CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
+into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
+tested using a VIA EPIA 5000 board.
+
+Cyblafb - compiled into the kernel or as a module?
+==================================================
+
+You might compile cyblafb either as a module or compile it permanently into the
+kernel.
+
+Unless you have a real reason to do so you should not compile both vesafb and
+cyblafb permanently into the kernel. It's possible and it helps during the
+developement cycle, but it's useless and will at least block some otherwise
+usefull memory for ordinary users.
+
+Selecting Modes
+===============
+
+ Startup Mode
+ ============
+
+ First of all, you might use the "vga=???" boot parameter as it is
+ documented in vesafb.txt and svga.txt. Cyblafb will detect the video
+ mode selected and will use the geometry and timings found by
+ inspecting the hardware registers.
+
+ video=cyblafb vga=0x317
+
+ Alternatively you might use a combination of the mode, ref and bpp
+ parameters. If you compiled the driver into the kernel, add something
+ like this to the kernel command line:
+
+ video=cyblafb:1280x1024,bpp=16,ref=50 ...
+
+ If you compiled the driver as a module, the same mode would be
+ selected by the following command:
+
+ modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
+
+ None of the modes possible to select as startup modes are affected by
+ the problems described at the end of the next subsection.
+
+ Mode changes using fbset
+ ========================
+
+ You might use fbset to change the video mode, see "man fbset". Cyblafb
+ generally does assume that you know what you are doing. But it does
+ some checks, especially those that are needed to prevent you from
+ damaging your hardware.
+
+ - only 8, 16, 24 and 32 bpp video modes are accepted
+ - interlaced video modes are not accepted
+ - double scan video modes are not accepted
+ - if a flat panel is found, cyblafb does not allow you
+ to program a resolution higher than the physical
+ resolution of the flat panel monitor
+ - cyblafb does not allow xres to differ from xres_virtual
+ - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
+ and (currently) 24 bit modes use a doubled vclk internally,
+ the dotclock limit as seen by fbset is 115 MHz for those
+ modes and 230 MHz for 8 and 16 bpp modes.
+
+ Any request that violates the rules given above will be ignored and
+ fbset will return an error.
+
+ If you program a virtual y resolution higher than the hardware limit,
+ cyblafb will silently decrease that value to the highest possible
+ value.
+
+ Attempts to disable acceleration are ignored.
+
+ Some video modes that should work do not work as expected. If you use
+ the standard fb.modes, fbset 640x480-60 will program that mode, but
+ you will see a vertical area, about two characters wide, with only
+ much darker characters than the other characters on the screen.
+ Cyblafb does allow that mode to be set, as it does not violate the
+ official specifications. It would need a lot of code to reliably sort
+ out all invalid modes, playing around with the margin values will
+ give a valid mode quickly. And if cyblafb would detect such an invalid
+ mode, should it silently alter the requested values or should it
+ report an error? Both options have some pros and cons. As stated
+ above, none of the startup modes are affected, and if you set
+ verbosity to 1 or higher, cyblafb will print the fbset command that
+ would be needed to program that mode using fbset.
+
+
+Other Parameters
+================
+
+
+crt don't autodetect, assume monitor connected to
+ standard VGA connector
+
+fp don't autodetect, assume flat panel display
+ connected to flat panel monitor interface
+
+nativex inform driver about native x resolution of
+ flat panel monitor connected to special
+ interface (should be autodetected)
+
+stretch stretch image to adapt low resolution modes to
+ higer resolutions of flat panel monitors
+ connected to special interface
+
+center center image to adapt low resolution modes to
+ higer resolutions of flat panel monitors
+ connected to special interface
+
+memsize use if autodetected memsize is wrong ...
+ should never be necessary
+
+nopcirr disable PCI read retry
+nopciwr disable PCI write retry
+nopcirb disable PCI read bursts
+nopciwb disable PCI write bursts
+
+bpp bpp for specified modes
+ valid values: 8 || 16 || 24 || 32
+
+ref refresh rate for specified mode
+ valid values: 50 <= ref <= 85
+
+mode 640x480 or 800x600 or 1024x768 or 1280x1024
+ if not specified, the startup mode will be detected
+ and used, so you might also use the vga=??? parameter
+ described in vesafb.txt. If you do not specify a mode,
+ bpp and ref parameters are ignored.
+
+verbosity 0 is the default, increase to at least 2 for every
+ bug report!
+
+vesafb allows cyblafb to be loaded after vesafb has been
+ loaded. See sections "Module unloading ...".
+
+
+Development hints
+=================
+
+It's much faster do compile a module and to load the new version after
+unloading the old module than to compile a new kernel and to reboot. So if you
+try to work on cyblafb, it might be a good idea to use cyblafb as a module.
+In real life, fast often means dangerous, and that's also the case here. If
+you introduce a serious bug when cyblafb is compiled into the kernel, the
+kernel will lock or oops with a high probability before the file system is
+mounted, and the danger for your data is low. If you load a broken own version
+of cyblafb on a running system, the danger for the integrity of the file
+system is much higher as you might need a hard reset afterwards. Decide
+yourself.
+
+Module unloading, the vfb method
+================================
+
+If you want to unload/reload cyblafb using the virtual framebuffer, you need
+to enable vfb support in the kernel first. After that, load the modules as
+shown below:
+
+ modprobe vfb vfb_enable=1
+ modprobe fbcon
+ modprobe cyblafb
+ fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
+ con2fb /dev/fb1 /dev/tty1
+ ...
+
+If you now made some changes to cyblafb and want to reload it, you might do it
+as show below:
+
+ con2fb /dev/fb0 /dev/tty1
+ ...
+ rmmod cyblafb
+ modprobe cyblafb
+ con2fb /dev/fb1 /dev/tty1
+ ...
+
+Of course, you might choose another mode, and most certainly you also want to
+map some other /dev/tty* to the real framebuffer device. You might also choose
+to compile fbcon as a kernel module or place it permanently in the kernel.
+
+I do not know of any way to unload fbcon, and fbcon will prevent the
+framebuffer device loaded first from unloading. [If there is a way, then
+please add a description here!]
+
+Module unloading, the vesafb method
+===================================
+
+Configure the kernel:
+
+ <*> Support for frame buffer devices
+ [*] VESA VGA graphics support
+ <M> Cyberblade/i1 support
+
+Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
+parameter is important, choose any vga parameter you like as long as it is
+a graphics mode.
+
+After booting, load cyblafb without any mode and bpp parameter and assign
+cyblafb to individual ttys using con2fb, e.g.:
+
+ modprobe cyblafb vesafb=1
+ con2fb /dev/fb1 /dev/tty1
+
+Unloading cyblafb works without problems after you assign vesafb to all
+ttys again, e.g.:
+
+ con2fb /dev/fb0 /dev/tty1
+ rmmod cyblafb
+
diff --git a/Documentation/fb/cyblafb/whycyblafb b/Documentation/fb/cyblafb/whycyblafb
new file mode 100644
index 00000000000..a123bc11e69
--- /dev/null
+++ b/Documentation/fb/cyblafb/whycyblafb
@@ -0,0 +1,85 @@
+I tried the following framebuffer drivers:
+
+ - TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
+ graphics cores like the cyberblade/i1. It claims to support a great
+ number of devices, but documentation for most of these devices is
+ unfortunately not available. There is _no_ reason to use tridentfb
+ for cyberblade/i1 + CRT users. VESAFB is faster, and the one
+ advantage, mode switching, is broken in tridentfb.
+
+ - VESAFB is used by many distributions as a standard. Vesafb does
+ not support mode switching. VESAFB is a bit faster than the working
+ configurations of TRIDENTFB, but it is still too slow, even if you
+ use ypan.
+
+ - EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
+ graphics core, but it still has serious bugs and developement seems
+ to have stopped. This is the one driver with TV-out support. If you
+ do need this feature, try epiafb.
+
+None of these drivers was a real option for me.
+
+I believe that is unreasonable to change code that announces to support 20
+devices if I only have more or less sufficient documentation for exactly one
+of these. The risk of breaking device foo while fixing device bar is too high.
+
+So I decided to start CyBlaFB as a stripped down tridentfb.
+
+All code specific to other Trident chips has been removed. After that there
+were a lot of cosmetic changes to increase the readability of the code. All
+register names were changed to those mnemonics used in the datasheet. Function
+and macro names were changed if they hindered easy understanding of the code.
+
+After that I debugged the code and implemented some new features. I'll try to
+give a little summary of the main changes:
+
+ - calculation of vertical and horizontal timings was fixed
+
+ - video signal quality has been improved dramatically
+
+ - acceleration:
+
+ - fillrect and copyarea were fixed and reenabled
+
+ - color expanding imageblit was newly implemented, color
+ imageblit (only used to draw the penguine) still uses the
+ generic code.
+
+ - init of the acceleration engine was improved and moved to a
+ place where it really works ...
+
+ - sync function has a timeout now and tries to reset and
+ reinit the accel engine if necessary
+
+ - fewer slow copyarea calls when doing ypan scrolling by using
+ undocumented bit d21 of screen start address stored in
+ CR2B[5]. BIOS does use it also, so this should be safe.
+
+ - cyblafb rejects any attempt to set modes that would cause vclk
+ values above reasonable 230 MHz. 32bit modes use a clock
+ multiplicator of 2, so fbset does show the correct values for
+ pixclock but not for vclk in this case. The fbset limit is 115 MHz
+ for 32 bpp modes.
+
+ - cyblafb rejects modes known to be broken or unimplemented (all
+ interlaced modes, all doublescan modes for now)
+
+ - cyblafb now works independant of the video mode in effect at startup
+ time (tridentfb does not init all needed registers to reasonable
+ values)
+
+ - switching between video modes does work reliably now
+
+ - the first video mode now is the one selected on startup using the
+ vga=???? mechanism or any of
+ - 640x480, 800x600, 1024x768, 1280x1024
+ - 8, 16, 24 or 32 bpp
+ - refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
+ is limited to 63Hz)
+
+ - pci retry and pci burst mode are settable (try to disable if you
+ experience latency problems)
+
+ - built as a module cyblafb might be unloaded and reloaded using
+ the vfb module and con2vt or might be used together with vesafb
+
diff --git a/Documentation/fb/modedb.txt b/Documentation/fb/modedb.txt
index e04458b319d..4fcdb4cf4cc 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.
Valid mode specifiers (mode_option argument):
- <xres>x<yres>[-<bpp>][@<refresh>]
+ <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m]
<name>[-<bpp>][@<refresh>]
with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string.
Things between square brackets are optional.
+If 'M' is specified in the mode_option argument (after <yres> and before
+<bpp> and <refresh>, if specified) the timings will be calculated using
+VESA(TM) Coordinated Video Timings instead of looking up the mode from a table.
+If 'R' is specified, do a 'reduced blanking' calculation for digital displays.
+If 'i' is specified, calculate for an interlaced mode. And if 'm' is
+specified, add margins to the calculation (1.8% of xres rounded down to 8
+pixels and 1.8% of yres).
+
+ Sample usage: 1024x768M@60m - CVT timing with margins
+
+***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo *****
+
+What is the VESA(TM) Coordinated Video Timings (CVT)?
+
+From the VESA(TM) Website:
+
+ "The purpose of CVT is to provide a method for generating a consistent
+ and coordinated set of standard formats, display refresh rates, and
+ timing specifications for computer display products, both those
+ employing CRTs, and those using other display technologies. The
+ intention of CVT is to give both source and display manufacturers a
+ common set of tools to enable new timings to be developed in a
+ consistent manner that ensures greater compatibility."
+
+This is the third standard approved by VESA(TM) concerning video timings. The
+first was the Discrete Video Timings (DVT) which is a collection of
+pre-defined modes approved by VESA(TM). The second is the Generalized Timing
+Formula (GTF) which is an algorithm to calculate the timings, given the
+pixelclock, the horizontal sync frequency, or the vertical refresh rate.
+
+The GTF is limited by the fact that it is designed mainly for CRT displays.
+It artificially increases the pixelclock because of its high blanking
+requirement. This is inappropriate for digital display interface with its high
+data rate which requires that it conserves the pixelclock as much as possible.
+Also, GTF does not take into account the aspect ratio of the display.
+
+The CVT addresses these limitations. If used with CRT's, the formula used
+is a derivation of GTF with a few modifications. If used with digital
+displays, the "reduced blanking" calculation can be used.
+
+From the framebuffer subsystem perspective, new formats need not be added
+to the global mode database whenever a new mode is released by display
+manufacturers. Specifying for CVT will work for most, if not all, relatively
+new CRT displays and probably with most flatpanels, if 'reduced blanking'
+calculation is specified. (The CVT compatibility of the display can be
+determined from its EDID. The version 1.3 of the EDID has extra 128-byte
+blocks where additional timing information is placed. As of this time, there
+is no support yet in the layer to parse this additional blocks.)
+
+CVT also introduced a new naming convention (should be seen from dmesg output):
+
+ <pix>M<a>[-R]
+
+ where: pix = total amount of pixels in MB (xres x yres)
+ M = always present
+ a = aspect ratio (3 - 4:3; 4 - 5:4; 9 - 15:9, 16:9; A - 16:10)
+ -R = reduced blanking
+
+ example: .48M3-R - 800x600 with reduced blanking
+
+Note: VESA(TM) has restrictions on what is a standard CVT timing:
+
+ - aspect ratio can only be one of the above values
+ - acceptable refresh rates are 50, 60, 70 or 85 Hz only
+ - if reduced blanking, the refresh rate must be at 60Hz
+
+If one of the above are not satisfied, the kernel will print a warning but the
+timings will still be calculated.
+
+***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo ***** oOo *****
+
To find a suitable video mode, you just call
int __init fb_find_mode(struct fb_var_screeninfo *var,
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 2e0a01b21fe..5f95d4b3cab 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -25,15 +25,6 @@ Who: Pavel Machek <pavel@suse.cz>
---------------------------
-What: PCI Name Database (CONFIG_PCI_NAMES)
-When: July 2005
-Why: It bloats the kernel unnecessarily, and is handled by userspace better
- (pciutils supports it.) Will eliminate the need to try to keep the
- pci.ids file in sync with the sf.net database all of the time.
-Who: Greg Kroah-Hartman <gregkh@suse.de>
-
----------------------------
-
What: io_remap_page_range() (macro or function)
When: September 2005
Why: 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 00000000000..8c206f4e025
--- /dev/null
+++ b/Documentation/filesystems/files.txt
@@ -0,0 +1,123 @@
+File management in the Linux kernel
+-----------------------------------
+
+This document describes how locking for files (struct file)
+and file descriptor table (struct files) works.
+
+Up until 2.6.12, the file descriptor table has been protected
+with a lock (files->file_lock) and reference count (files->count).
+->file_lock protected accesses to all the file related fields
+of the table. ->count was used for sharing the file descriptor
+table between tasks cloned with CLONE_FILES flag. Typically
+this would be the case for posix threads. As with the common
+refcounting model in the kernel, the last task doing
+a put_files_struct() frees the file descriptor (fd) table.
+The files (struct file) themselves are protected using
+reference count (->f_count).
+
+In the new lock-free model of file descriptor management,
+the reference counting is similar, but the locking is
+based on RCU. The file descriptor table contains multiple
+elements - the fd sets (open_fds and close_on_exec, the
+array of file pointers, the sizes of the sets and the array
+etc.). In order for the updates to appear atomic to
+a lock-free reader, all the elements of the file descriptor
+table are in a separate structure - struct fdtable.
+files_struct contains a pointer to struct fdtable through
+which the actual fd table is accessed. Initially the
+fdtable is embedded in files_struct itself. On a subsequent
+expansion of fdtable, a new fdtable structure is allocated
+and files->fdtab points to the new structure. The fdtable
+structure is freed with RCU and lock-free readers either
+see the old fdtable or the new fdtable making the update
+appear atomic. Here are the locking rules for
+the fdtable structure -
+
+1. All references to the fdtable must be done through
+ the files_fdtable() macro :
+
+ struct fdtable *fdt;
+
+ rcu_read_lock();
+
+ fdt = files_fdtable(files);
+ ....
+ if (n <= fdt->max_fds)
+ ....
+ ...
+ rcu_read_unlock();
+
+ files_fdtable() uses rcu_dereference() macro which takes care of
+ the memory barrier requirements for lock-free dereference.
+ The fdtable pointer must be read within the read-side
+ critical section.
+
+2. Reading of the fdtable as described above must be protected
+ by rcu_read_lock()/rcu_read_unlock().
+
+3. For any update to the the fd table, files->file_lock must
+ be held.
+
+4. To look up the file structure given an fd, a reader
+ must use either fcheck() or fcheck_files() APIs. These
+ take care of barrier requirements due to lock-free lookup.
+ An example :
+
+ struct file *file;
+
+ rcu_read_lock();
+ file = fcheck(fd);
+ if (file) {
+ ...
+ }
+ ....
+ rcu_read_unlock();
+
+5. Handling of the file structures is special. Since the look-up
+ of the fd (fget()/fget_light()) are lock-free, it is possible
+ that look-up may race with the last put() operation on the
+ file structure. This is avoided using the rcuref APIs
+ on ->f_count :
+
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ if (rcuref_inc_lf(&file->f_count))
+ *fput_needed = 1;
+ else
+ /* Didn't get the reference, someone's freed */
+ file = NULL;
+ }
+ rcu_read_unlock();
+ ....
+ return file;
+
+ rcuref_inc_lf() detects if refcounts is already zero or
+ goes to zero during increment. If it does, we fail
+ fget()/fget_light().
+
+6. Since both fdtable and file structures can be looked up
+ lock-free, they must be installed using rcu_assign_pointer()
+ API. If they are looked up lock-free, rcu_dereference()
+ must be used. However it is advisable to use files_fdtable()
+ and fcheck()/fcheck_files() which take care of these issues.
+
+7. While updating, the fdtable pointer must be looked up while
+ holding files->file_lock. If ->file_lock is dropped, then
+ another thread expand the files thereby creating a new
+ fdtable and making the earlier fdtable pointer stale.
+ For example :
+
+ spin_lock(&files->file_lock);
+ fd = locate_fd(files, file, start);
+ if (fd >= 0) {
+ /* locate_fd() may have expanded fdtable, load the ptr */
+ fdt = files_fdtable(files);
+ FD_SET(fd, fdt->open_fds);
+ FD_CLR(fd, fdt->close_on_exec);
+ spin_unlock(&files->file_lock);
+ .....
+
+ Since locate_fd() can drop ->file_lock (and reacquire ->file_lock),
+ the fdtable pointer (fdt) must be loaded after locate_fd().
+
diff --git a/Documentation/filesystems/fuse.txt b/Documentation/filesystems/fuse.txt
new file mode 100644
index 00000000000..6b5741e651a
--- /dev/null
+++ b/Documentation/filesystems/fuse.txt
@@ -0,0 +1,315 @@
+Definitions
+~~~~~~~~~~~
+
+Userspace filesystem:
+
+ A filesystem in which data and metadata are provided by an ordinary
+ userspace process. The filesystem can be accessed normally through
+ the kernel interface.
+
+Filesystem daemon:
+
+ The process(es) providing the data and metadata of the filesystem.
+
+Non-privileged mount (or user mount):
+
+ A userspace filesystem mounted by a non-privileged (non-root) user.
+ The filesystem daemon is running with the privileges of the mounting
+ user. NOTE: this is not the same as mounts allowed with the "user"
+ option in /etc/fstab, which is not discussed here.
+
+Mount owner:
+
+ The user who does the mounting.
+
+User:
+
+ The user who is performing filesystem operations.
+
+What is FUSE?
+~~~~~~~~~~~~~
+
+FUSE is a userspace filesystem framework. It consists of a kernel
+module (fuse.ko), a userspace library (libfuse.*) and a mount utility
+(fusermount).
+
+One of the most important features of FUSE is allowing secure,
+non-privileged mounts. This opens up new possibilities for the use of
+filesystems. A good example is sshfs: a secure network filesystem
+using the sftp protocol.
+
+The userspace library and utilities are available from the FUSE
+homepage:
+
+ http://fuse.sourceforge.net/
+
+Mount options
+~~~~~~~~~~~~~
+
+'fd=N'
+
+ The file descriptor to use for communication between the userspace
+ filesystem and the kernel. The file descriptor must have been
+ obtained by opening the FUSE device ('/dev/fuse').
+
+'rootmode=M'
+
+ The file mode of the filesystem's root in octal representation.
+
+'user_id=N'
+
+ The numeric user id of the mount owner.
+
+'group_id=N'
+
+ The numeric group id of the mount owner.
+
+'default_permissions'
+
+ By default FUSE doesn't check file access permissions, the
+ filesystem is free to implement it's access policy or leave it to
+ the underlying file access mechanism (e.g. in case of network
+ filesystems). This option enables permission checking, restricting
+ access based on file mode. This is option is usually useful
+ together with the 'allow_other' mount option.
+
+'allow_other'
+
+ This option overrides the security measure restricting file access
+ to the user mounting the filesystem. This option is by default only
+ allowed to root, but this restriction can be removed with a
+ (userspace) configuration option.
+
+'max_read=N'
+
+ With this option the maximum size of read operations can be set.
+ The default is infinite. Note that the size of read requests is
+ limited anyway to 32 pages (which is 128kbyte on i386).
+
+How do non-privileged mounts work?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since the mount() system call is a privileged operation, a helper
+program (fusermount) is needed, which is installed setuid root.
+
+The implication of providing non-privileged mounts is that the mount
+owner must not be able to use this capability to compromise the
+system. Obvious requirements arising from this are:
+
+ A) mount owner should not be able to get elevated privileges with the
+ help of the mounted filesystem
+
+ B) mount owner should not get illegitimate access to information from
+ other users' and the super user's processes
+
+ C) mount owner should not be able to induce undesired behavior in
+ other users' or the super user's processes
+
+How are requirements fulfilled?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ A) The mount owner could gain elevated privileges by either:
+
+ 1) creating a filesystem containing a device file, then opening
+ this device
+
+ 2) creating a filesystem containing a suid or sgid application,
+ then executing this application
+
+ The solution is not to allow opening device files and ignore
+ setuid and setgid bits when executing programs. To ensure this
+ fusermount always adds "nosuid" and "nodev" to the mount options
+ for non-privileged mounts.
+
+ B) If another user is accessing files or directories in the
+ filesystem, the filesystem daemon serving requests can record the
+ exact sequence and timing of operations performed. This
+ information is otherwise inaccessible to the mount owner, so this
+ counts as an information leak.
+
+ The solution to this problem will be presented in point 2) of C).
+
+ C) There are several ways in which the mount owner can induce
+ undesired behavior in other users' processes, such as:
+
+ 1) mounting a filesystem over a file or directory which the mount
+ owner could otherwise not be able to modify (or could only
+ make limited modifications).
+
+ This is solved in fusermount, by checking the access
+ permissions on the mountpoint and only allowing the mount if
+ the mount owner can do unlimited modification (has write
+ access to the mountpoint, and mountpoint is not a "sticky"
+ directory)
+
+ 2) Even if 1) is solved the mount owner can change the behavior
+ of other users' processes.
+
+ i) It can slow down or indefinitely delay the execution of a
+ filesystem operation creating a DoS against the user or the
+ whole system. For example a suid application locking a
+ system file, and then accessing a file on the mount owner's
+ filesystem could be stopped, and thus causing the system
+ file to be locked forever.
+
+ ii) It can present files or directories of unlimited length, or
+ directory structures of unlimited depth, possibly causing a
+ system process to eat up diskspace, memory or other
+ resources, again causing DoS.
+
+ The solution to this as well as B) is not to allow processes
+ to access the filesystem, which could otherwise not be
+ monitored or manipulated by the mount owner. Since if the
+ mount owner can ptrace a process, it can do all of the above
+ without using a FUSE mount, the same criteria as used in
+ ptrace can be used to check if a process is allowed to access
+ the filesystem or not.
+
+ Note that the ptrace check is not strictly necessary to
+ prevent B/2/i, it is enough to check if mount owner has enough
+ privilege to send signal to the process accessing the
+ filesystem, since SIGSTOP can be used to get a similar effect.
+
+I think these limitations are unacceptable?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If a sysadmin trusts the users enough, or can ensure through other
+measures, that system processes will never enter non-privileged
+mounts, it can relax the last limitation with a "user_allow_other"
+config option. If this config option is set, the mounting user can
+add the "allow_other" mount option which disables the check for other
+users' processes.
+
+Kernel - userspace interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following diagram shows how a filesystem operation (in this
+example unlink) is performed in FUSE.
+
+NOTE: everything in this description is greatly simplified
+
+ | "rm /mnt/fuse/file" | FUSE filesystem daemon
+ | |
+ | | >sys_read()
+ | | >fuse_dev_read()
+ | | >request_wait()
+ | | [sleep on fc->waitq]
+ | |
+ | >sys_unlink() |
+ | >fuse_unlink() |
+ | [get request from |
+ | fc->unused_list] |
+ | >request_send() |
+ | [queue req on fc->pending] |
+ | [wake up fc->waitq] | [woken up]
+ | >request_wait_answer() |
+ | [sleep on req->waitq] |
+ | | <request_wait()
+ | | [remove req from fc->pending]
+ | | [copy req to read buffer]
+ | | [add req to fc->processing]
+ | | <fuse_dev_read()
+ | | <sys_read()
+ | |
+ | | [perform unlink]
+ | |
+ | | >sys_write()
+ | | >fuse_dev_write()
+ | | [look up req in fc->processing]
+ | | [remove from fc->processing]
+ | | [copy write buffer to req]
+ | [woken up] | [wake up req->waitq]
+ | | <fuse_dev_write()
+ | | <sys_write()
+ | <request_wait_answer() |
+ | <request_send() |
+ | [add request to |
+ | fc->unused_list] |
+ | <fuse_unlink() |
+ | <sys_unlink() |
+
+There are a couple of ways in which to deadlock a FUSE filesystem.
+Since we are talking about unprivileged userspace programs,
+something must be done about these.
+
+Scenario 1 - Simple deadlock
+-----------------------------
+
+ | "rm /mnt/fuse/file" | FUSE filesystem daemon
+ | |
+ | >sys_unlink("/mnt/fuse/file") |
+ | [acquire inode semaphore |
+ | for "file"] |
+ | >fuse_unlink() |
+ | [sleep on req->waitq] |
+ | | <sys_read()
+ | | >sys_unlink("/mnt/fuse/file")
+ | | [acquire inode semaphore
+ | | for "file"]
+ | | *DEADLOCK*
+
+The solution for this is to allow requests to be interrupted while
+they are in userspace:
+
+ | [interrupted by signal] |
+ | <fuse_unlink() |
+ | [release semaphore] | [semaphore acquired]
+ | <sys_unlink() |
+ | | >fuse_unlink()
+ | | [queue req on fc->pending]
+ | | [wake up fc->waitq]
+ | | [sleep on req->waitq]
+
+If the filesystem daemon was single threaded, this will stop here,
+since there's no other thread to dequeue and execute the request.
+In this case the solution is to kill the FUSE daemon as well. If
+there are multiple serving threads, you just have to kill them as
+long as any remain.
+
+Moral: a filesystem which deadlocks, can soon find itself dead.
+
+Scenario 2 - Tricky deadlock
+----------------------------
+
+This one needs a carefully crafted filesystem. It's a variation on
+the above, only the call back to the filesystem is not explicit,
+but is caused by a pagefault.
+
+ | Kamikaze filesystem thread 1 | Kamikaze filesystem thread 2
+ | |
+ | [fd = open("/mnt/fuse/file")] | [request served normally]
+ | [mmap fd to 'addr'] |
+ | [close fd] | [FLUSH triggers 'magic' flag]
+ | [read a byte from addr] |
+ | >do_page_fault() |
+ | [find or create page] |
+ | [lock page] |
+ | >fuse_readpage() |
+ | [queue READ request] |
+ | [sleep on req->waitq] |
+ | | [read request to buffer]
+ | | [create reply header before addr]
+ | | >sys_write(addr - headerlength)
+ | | >fuse_dev_write()
+ | | [look up req in fc->processing]
+ | | [remove from fc->processing]
+ | | [copy write buffer to req]
+ | | >do_page_fault()
+ | | [find or create page]
+ | | [lock page]
+ | | * DEADLOCK *
+
+Solution is again to let the the request be interrupted (not
+elaborated further).
+
+An additional problem is that while the write buffer is being
+copied to the request, the request must not be interrupted. This
+is because the destination address of the copy may not be valid
+after the request is interrupted.
+
+This is solved with doing the copy atomically, and allowing
+interruption while the page(s) belonging to the write buffer are
+faulted with get_user_pages(). The 'req->locked' flag indicates
+when the copy is taking place, and interruption is delayed until
+this flag is unset.
+
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
index eef4aca0c75..a5fbc8e897f 100644
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -439,6 +439,18 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
+2.1.24:
+ - Support journals ($LogFile) which have been modified by chkdsk. This
+ means users can boot into Windows after we marked the volume dirty.
+ The Windows boot will run chkdsk and then reboot. The user can then
+ immediately boot into Linux rather than having to do a full Windows
+ boot first before rebooting into Linux and we will recognize such a
+ journal and empty it as it is clean by definition.
+ - Support journals ($LogFile) with only one restart page as well as
+ journals with two different restart pages. We sanity check both and
+ either use the only sane one or the more recent one of the two in the
+ case that both are valid.
+ - Lots of bug fixes and enhancements across the board.
2.1.23:
- Stamp the user space journal, aka transaction log, aka $UsnJrnl, if
it is present and active thus telling Windows and applications using
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 5024ba7a592..d4773565ea2 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1241,16 +1241,38 @@ swap-intensive.
overcommit_memory
-----------------
-This file contains one value. The following algorithm is used to decide if
-there's enough memory: if the value of overcommit_memory is positive, then
-there's always enough memory. This is a useful feature, since programs often
-malloc() huge amounts of memory 'just in case', while they only use a small
-part of it. Leaving this value at 0 will lead to the failure of such a huge
-malloc(), when in fact the system has enough memory for the program to run.
-
-On the other hand, enabling this feature can cause you to run out of memory
-and thrash the system to death, so large and/or important servers will want to
-set this value to 0.
+Controls overcommit of system memory, possibly allowing processes
+to allocate (but not use) more memory than is actually available.
+
+
+0 - Heuristic overcommit handling. Obvious overcommits of
+ address space are refused. Used for a typical system. It
+ ensures a seriously wild allocation fails while allowing
+ overcommit to reduce swap usage. root is allowed to
+ allocate slighly more memory in this mode. This is the
+ default.
+
+1 - Always overcommit. Appropriate for some scientific
+ applications.
+
+2 - Don't overcommit. The total address space commit
+ for the system is not permitted to exceed swap plus a
+ configurable percentage (default is 50) of physical RAM.
+ Depending on the percentage you use, in most situations
+ this means a process will not be killed while attempting
+ to use already-allocated memory but will receive errors
+ on memory allocation as appropriate.
+
+overcommit_ratio
+----------------
+
+Percentage of physical memory size to include in overcommit calculations
+(see above.)
+
+Memory allocation limit = swapspace + physmem * (overcommit_ratio / 100)
+
+ swapspace = total size of all swap areas
+ physmem = size of physical memory in system
nr_hugepages and hugetlb_shm_group
----------------------------------
diff --git a/Documentation/filesystems/v9fs.txt b/Documentation/filesystems/v9fs.txt
new file mode 100644
index 00000000000..4e92feb6b50
--- /dev/null
+++ b/Documentation/filesystems/v9fs.txt
@@ -0,0 +1,95 @@
+ V9FS: 9P2000 for Linux
+ ======================
+
+ABOUT
+=====
+
+v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol.
+
+This software was originally developed by Ron Minnich <rminnich@lanl.gov>
+and Maya Gokhale <maya@lanl.gov>. Additional development by Greg Watson
+<gwatson@lanl.gov> and most recently Eric Van Hensbergen
+<ericvh@gmail.com> and Latchesar Ionkov <lucho@ionkov.net>.
+
+USAGE
+=====
+
+For remote file server:
+
+ mount -t 9P 10.10.1.2 /mnt/9
+
+For Plan 9 From User Space applications (http://swtch.com/plan9)
+
+ mount -t 9P `namespace`/acme /mnt/9 -o proto=unix,name=$USER
+
+OPTIONS
+=======
+
+ proto=name select an alternative transport. Valid options are
+ currently:
+ unix - specifying a named pipe mount point
+ tcp - specifying a normal TCP/IP connection
+ fd - used passed file descriptors for connection
+ (see rfdno and wfdno)
+
+ name=name user name to attempt mount as on the remote server. The
+ server may override or ignore this value. Certain user
+ names may require authentication.
+
+ aname=name aname specifies the file tree to access when the server is
+ offering several exported file systems.
+
+ debug=n specifies debug level. The debug level is a bitmask.
+ 0x01 = display verbose error messages
+ 0x02 = developer debug (DEBUG_CURRENT)
+ 0x04 = display 9P trace
+ 0x08 = display VFS trace
+ 0x10 = display Marshalling debug
+ 0x20 = display RPC debug
+ 0x40 = display transport debug
+ 0x80 = display allocation debug
+
+ rfdno=n the file descriptor for reading with proto=fd
+
+ wfdno=n the file descriptor for writing with proto=fd
+
+ maxdata=n the number of bytes to use for 9P packet payload (msize)
+
+ port=n port to connect to on the remote server
+
+ timeout=n request timeouts (in ms) (default 60000ms)
+
+ noextend force legacy mode (no 9P2000.u semantics)
+
+ uid attempt to mount as a particular uid
+
+ gid attempt to mount with a particular gid
+
+ afid security channel - used by Plan 9 authentication protocols
+
+ nodevmap do not map special files - represent them as normal files.
+ This can be used to share devices/named pipes/sockets between
+ hosts. This functionality will be expanded in later versions.
+
+RESOURCES
+=========
+
+The Linux version of the 9P server, along with some client-side utilities
+can be found at http://v9fs.sf.net (along with a CVS repository of the
+development branch of this module). There are user and developer mailing
+lists here, as well as a bug-tracker.
+
+For more information on the Plan 9 Operating System check out
+http://plan9.bell-labs.com/plan9
+
+For information on Plan 9 from User Space (Plan 9 applications and libraries
+ported to Linux/BSD/OSX/etc) check out http://swtch.com/plan9
+
+
+STATUS
+======
+
+The 2.6 kernel support is working on PPC and x86.
+
+PLEASE USE THE SOURCEFORGE BUG-TRACKER TO REPORT PROBLEMS.
+
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 3f318dd44c7..f042c12e0ed 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -1,35 +1,27 @@
-/* -*- auto-fill -*- */
- Overview of the Virtual File System
+ Overview of the Linux Virtual File System
- Richard Gooch <rgooch@atnf.csiro.au>
+ Original author: Richard Gooch <rgooch@atnf.csiro.au>
- 5-JUL-1999
+ Last updated on August 25, 2005
+ Copyright (C) 1999 Richard Gooch
+ Copyright (C) 2005 Pekka Enberg
-Conventions used in this document <section>
-=================================
+ This file is released under the GPLv2.
-Each section in this document will have the string "<section>" at the
-right-hand side of the section title. Each subsection will have
-"<subsection>" at the right-hand side. These strings are meant to make
-it easier to search through the document.
-NOTE that the master copy of this document is available online at:
-http://www.atnf.csiro.au/~rgooch/linux/docs/vfs.txt
-
-
-What is it? <section>
+What is it?
===========
The Virtual File System (otherwise known as the Virtual Filesystem
Switch) is the software layer in the kernel that provides the
filesystem interface to userspace programs. It also provides an
abstraction within the kernel which allows different filesystem
-implementations to co-exist.
+implementations to coexist.
-A Quick Look At How It Works <section>
+A Quick Look At How It Works
============================
In 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
other view which is how a filesystem is supported and subsequently
mounted.
-Opening a File <subsection>
+
+Opening a File
--------------
The VFS implements the open(2), stat(2), chmod(2) and similar system
@@ -77,7 +70,7 @@ back to userspace.
Opening a file requires another operation: allocation of a file
structure (this is the kernel-side implementation of file
-descriptors). The freshly allocated file structure is initialised with
+descriptors). The freshly allocated file structure is initialized with
a pointer to the dentry and a set of file operation member functions.
These are taken from the inode data. The open() file method is then
called 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
processors. You should ensure that access to shared resources is
protected by appropriate locks.
-Registering and Mounting a Filesystem <subsection>
+
+Registering and Mounting a Filesystem
-------------------------------------
If 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.
It's now time to look at things in more detail.
-struct file_system_type <section>
+struct file_system_type
=======================
-This describes the filesystem. As of kernel 2.1.99, the following
+This describes the filesystem. As of kernel 2.6.13, the following
members are defined:
struct file_system_type {
const char *name;
int fs_flags;
- struct super_block *(*read_super) (struct super_block *, void *, int);
- struct file_system_type * next;
+ struct super_block *(*get_sb) (struct file_system_type *, int,
+ const char *, void *);
+ void (*kill_sb) (struct super_block *);
+ struct module *owner;
+ struct file_system_type * next;
+ struct list_head fs_supers;
};
name: the name of the filesystem type, such as "ext2", "iso9660",
@@ -141,51 +139,97 @@ struct file_system_type {
fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
- read_super: the method to call when a new instance of this
+ get_sb: the method to call when a new instance of this
filesystem should be mounted
- next: for internal VFS use: you should initialise this to NULL
+ kill_sb: the method to call when an instance of this filesystem
+ should be unmounted
+
+ owner: for internal VFS use: you should initialize this to THIS_MODULE in
+ most cases.
-The read_super() method has the following arguments:
+ next: for internal VFS use: you should initialize this to NULL
+
+The get_sb() method has the following arguments:
struct super_block *sb: the superblock structure. This is partially
- initialised by the VFS and the rest must be initialised by the
- read_super() method
+ initialized by the VFS and the rest must be initialized by the
+ get_sb() method
+
+ int flags: mount flags
+
+ const char *dev_name: the device name we are mounting.
void *data: arbitrary mount options, usually comes as an ASCII
string
int silent: whether or not to be silent on error
-The read_super() method must determine if the block device specified
+The get_sb() method must determine if the block device specified
in the superblock contains a filesystem of the type the method
supports. On success the method returns the superblock pointer, on
failure it returns NULL.
The most interesting member of the superblock structure that the
-read_super() method fills in is the "s_op" field. This is a pointer to
+get_sb() method fills in is the "s_op" field. This is a pointer to
a "struct super_operations" which describes the next level of the
filesystem implementation.
+Usually, a filesystem uses generic one of the generic get_sb()
+implementations and provides a fill_super() method instead. The
+generic methods are:
+
+ get_sb_bdev: mount a filesystem residing on a block device
-struct super_operations <section>
+ get_sb_nodev: mount a filesystem that is not backed by a device
+
+ get_sb_single: mount a filesystem which shares the instance between
+ all mounts
+
+A fill_super() method implementation has the following arguments:
+
+ struct super_block *sb: the superblock structure. The method fill_super()
+ must initialize this properly.
+
+ void *data: arbitrary mount options, usually comes as an ASCII
+ string
+
+ int silent: whether or not to be silent on error
+
+
+struct super_operations
=======================
This describes how the VFS can manipulate the superblock of your
-filesystem. As of kernel 2.1.99, the following members are defined:
+filesystem. As of kernel 2.6.13, the following members are defined:
struct super_operations {
- void (*read_inode) (struct inode *);
- int (*write_inode) (struct inode *, int);
- void (*put_inode) (struct inode *);
- void (*drop_inode) (struct inode *);
- void (*delete_inode) (struct inode *);
- int (*notify_change) (struct dentry *, struct iattr *);
- void (*put_super) (struct super_block *);
- void (*write_super) (struct super_block *);
- int (*statfs) (struct super_block *, struct statfs *, int);
- int (*remount_fs) (struct super_block *, int *, char *);
- void (*clear_inode) (struct inode *);
+ struct inode *(*alloc_inode)(struct super_block *sb);
+ void (*destroy_inode)(struct inode *);
+
+ void (*read_inode) (struct inode *);
+
+ void (*dirty_inode) (struct inode *);
+ int (*write_inode) (struct inode *, int);
+ void (*put_inode) (struct inode *);
+ void (*drop_inode) (struct inode *);
+ void (*delete_inode) (struct inode *);
+ void (*put_super) (struct super_block *);
+ void (*write_super) (struct super_block *);
+ int (*sync_fs)(struct super_block *sb, int wait);
+ void (*write_super_lockfs) (struct super_block *);
+ void (*unlockfs) (struct super_block *);
+ int (*statfs) (struct super_block *, struct kstatfs *);
+ int (*remount_fs) (struct super_block *, int *, char *);
+ void (*clear_inode) (struct inode *);
+ void (*umount_begin) (struct super_block *);
+
+ void (*sync_inodes) (struct super_block *sb,
+ struct writeback_control *wbc);
+ int (*show_options)(struct seq_file *, struct vfsmount *);
+
+ ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
+ ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
};
All 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
only called from a process context (i.e. not from an interrupt handler
or bottom half).
+ alloc_inode: this method is called by inode_alloc() to allocate memory
+ for struct inode and initialize it.
+
+ destroy_inode: this method is called by destroy_inode() to release
+ resources allocated for struct inode.
+
read_inode: this method is called to read a specific inode from the
- mounted filesystem. The "i_ino" member in the "struct inode"
- will be initialised by the VFS to indicate which inode to
- read. Other members are filled in by this method
+ mounted filesystem. The i_ino member in the struct inode is
+ initialized by the VFS to indicate which inode to read. Other
+ members are filled in by this method.
+
+ You can set this to NULL and use iget5_locked() instead of iget()
+ to read inodes. This is necessary for filesystems for which the
+ inode number is not sufficient to identify an inode.
+
+ dirty_inode: this method is called by the VFS to mark an inode dirty.
write_inode: this method is called when the VFS needs to write an
inode to disc. The second parameter indicates whether the write
should be synchronous or not, not all filesystems check this flag.
put_inode: called when the VFS inode is removed from the inode
- cache. This method is optional
+ cache.
drop_inode: called when the last access to the inode is dropped,
with the inode_lock spinlock held.
- This method should be either NULL (normal unix filesystem
+ This method should be either NULL (normal UNIX filesystem
semantics) or "generic_delete_inode" (for filesystems that do not
want to cache inodes - causing "delete_inode" to always be
called regardless of the value of i_nlink)
- The "generic_delete_inode()" behaviour is equivalent to the
+ The "generic_delete_inode()" behavior is equivalent to the
old practice of using "force_delete" in the put_inode() case,
but does not have the races that the "force_delete()" approach
had.
delete_inode: called when the VFS wants to delete an inode
- notify_change: called when VFS inode attributes are changed. If this
- is NULL the VFS falls back to the write_inode() method. This
- is called with the kernel lock held
-
put_super: called when the VFS wishes to free the superblock
(i.e. unmount). This is called with the superblock lock held
write_super: called when the VFS superblock needs to be written to
disc. This method is optional
+ sync_fs: called when VFS is writing out all dirty data associated with
+ a superblock. The second parameter indicates whether the method
+ should wait until the write out has been completed. Optional.
+
+ write_super_lockfs: called when VFS is locking a filesystem and forcing
+ it into a consistent state. This function is currently used by the
+ Logical Volume Manager (LVM).
+
+ unlockfs: called when VFS is unlocking a filesystem and making it writable
+ again.
+
statfs: called when the VFS needs to get filesystem statistics. This
is called with the kernel lock held
@@ -238,21 +301,31 @@ or bottom half).
clear_inode: called then the VFS clears the inode. Optional
+ umount_begin: called when the VFS is unmounting a filesystem.
+
+ sync_inodes: called when the VFS is writing out dirty data associated with
+ a superblock.
+
+ show_options: called by the VFS to show mount options for /proc/<pid>/mounts.
+
+ quota_read: called by the VFS to read from filesystem quota file.
+
+ quota_write: called by the VFS to write to filesystem quota file.
+
The read_inode() method is responsible for filling in the "i_op"
field. This is a pointer to a "struct inode_operations" which
describes the methods that can be performed on individual inodes.
-struct inode_operations <section>
+struct inode_operations
=======================
This describes how the VFS can manipulate an inode in your
-filesystem. As of kernel 2.1.99, the following members are defined:
+filesystem. As of kernel 2.6.13, the following members are defined:
struct inode_operations {
- struct file_operations * default_file_ops;
- int (*create) (struct inode *,struct dentry *,int);
- int (*lookup) (struct inode *,struct dentry *);
+ int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
+ struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -261,25 +334,22 @@ struct inode_operations {
int (*mknod) (struct inode *,struct dentry *,int,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
- int (*readlink) (struct dentry *, char *,int);
- struct dentry * (*follow_link) (struct dentry *, struct dentry *);
- int (*readpage) (struct file *, struct page *);
- int (*writepage) (struct page *page, struct writeback_control *wbc);
- int (*bmap) (struct inode *,int);
+ int (*readlink) (struct dentry *, char __user *,int);
+ void * (*follow_link) (struct dentry *, struct nameidata *);
+ void (*put_link) (struct dentry *, struct nameidata *, void *);
void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int);
- int (*smap) (struct inode *,int);
- int (*updatepage) (struct file *, struct page *, const char *,
- unsigned long, unsigned int, int);
- int (*revalidate) (struct dentry *);
+ int (*permission) (struct inode *, int, struct nameidata *);
+ int (*setattr) (struct dentry *, struct iattr *);
+ int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
+ int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+ ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+ ssize_t (*listxattr) (struct dentry *, char *, size_t);
+ int (*removexattr) (struct dentry *, const char *);
};
Again, all methods are called without any locks being held, unless
otherwise noted.
- default_file_ops: this is a pointer to a "struct file_operations"
- which describes how to open and then manipulate open files
-
create: called by the open(2) and creat(2) system calls. Only
required if you want to support regular files. The dentry you
get should not have an inode (i.e. it should be a negative
@@ -328,31 +398,143 @@ otherwise noted.
you want to support reading symbolic links
follow_link: called by the VFS to follow a symbolic link to the
- inode it points to. Only required if you want to support
- symbolic links
+ inode it points to. Only required if you want to support
+ symbolic links. This function returns a void pointer cookie
+ that is passed to put_link().
+
+ put_link: called by the VFS to release resources allocated by
+ follow_link(). The cookie returned by follow_link() is passed to
+ to this function as the last parameter. It is used by filesystems
+ such as NFS where page cache is not stable (i.e. page that was
+ installed when the symbolic link walk started might not be in the
+ page cache at the end of the walk).
+
+ truncate: called by the VFS to change the size of a file. The i_size
+ field of the inode is set to the desired size by the VFS before
+ this function is called. This function is called by the truncate(2)
+ system call and related functionality.
+
+ permission: called by the VFS to check for access rights on a POSIX-like
+ filesystem.
+
+ setattr: called by the VFS to set attributes for a file. This function is
+ called by chmod(2) and related system calls.
+
+ getattr: called by the VFS to get attributes of a file. This function is
+ called by stat(2) and related system calls.
+
+ setxattr: called by the VFS to set an extended attribute for a file.
+ Extended attribute is a name:value pair associated with an inode. This
+ function is called by setxattr(2) system call.
+
+ getxattr: called by the VFS to retrieve the value of an extended attribute
+ name. This function is called by getxattr(2) function call.
+
+ listxattr: called by the VFS to list all extended attributes for a given
+ file. This function is called by listxattr(2) system call.
+
+ removexattr: called by the VFS to remove an extended attribute from a file.
+ This function is called by removexattr(2) system call.
+
+
+struct address_space_operations
+===============================
+
+This describes how the VFS can manipulate mapping of a file to page cache in
+your filesystem. As of kernel 2.6.13, the following members are defined:
+
+struct address_space_operations {
+ int (*writepage)(struct page *page, struct writeback_control *wbc);
+ int (*readpage)(struct file *, struct page *);
+ int (*sync_page)(struct page *);
+ int (*writepages)(struct address_space *, struct writeback_control *);
+ int (*set_page_dirty)(struct page *page);
+ int (*readpages)(struct file *filp, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages);
+ int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
+ int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
+ sector_t (*bmap)(struct address_space *, sector_t);
+ int (*invalidatepage) (struct page *, unsigned long);
+ int (*releasepage) (struct page *, int);
+ ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs);
+ struct page* (*get_xip_page)(struct address_space *, sector_t,
+ int);
+};
+
+ writepage: called by the VM write a dirty page to backing store.
+
+ readpage: called by the VM to read a page from backing store.
+
+ sync_page: called by the VM to notify the backing store to perform all
+ queued I/O operations for a page. I/O operations for other pages
+ associated with this address_space object may also be performed.
+
+ writepages: called by the VM to write out pages associated with the
+ address_space object.
+
+ set_page_dirty: called by the VM to set a page dirty.
+
+ readpages: called by the VM to read pages associated with the address_space
+ object.
+ prepare_write: called by the generic write path in VM to set up a write
+ request for a page.
-struct file_operations <section>
+ commit_write: called by the generic write path in VM to write page to
+ its backing store.
+
+ bmap: called by the VFS to map a logical block offset within object to
+ physical block number. This method is use by for the legacy FIBMAP
+ ioctl. Other uses are discouraged.
+
+ invalidatepage: called by the VM on truncate to disassociate a page from its
+ address_space mapping.
+
+ releasepage: called by the VFS to release filesystem specific metadata from
+ a page.
+
+ direct_IO: called by the VM for direct I/O writes and reads.
+
+ get_xip_page: called by the VM to translate a block number to a page.
+ The page is valid until the corresponding filesystem is unmounted.
+ Filesystems that want to use execute-in-place (XIP) need to implement
+ it. An example implementation can be found in fs/ext2/xip.c.
+
+
+struct file_operations
======================
This describes how the VFS can manipulate an open file. As of kernel
-2.1.99, the following members are defined:
+2.6.13, the following members are defined:
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
- ssize_t (*read) (struct file *, char *, size_t, loff_t *);
- ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
+ ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
+ ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
+ ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
+ ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
+ long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+ long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
+ int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
- int (*fsync) (struct file *, struct dentry *);
- int (*fasync) (struct file *, int);
- int (*check_media_change) (kdev_t dev);
- int (*revalidate) (kdev_t dev);
+ int (*fsync) (struct file *, struct dentry *, int datasync);
+ int (*aio_fsync) (struct kiocb *, int datasync);
+ int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
+ ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
+ ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
+ ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
+ ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
+ unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ int (*check_flags)(int);
+ int (*dir_notify)(struct file *filp, unsigned long arg);
+ int (*flock) (struct file *, int, struct file_lock *);
};
Again, all methods are called without any locks being held, unless
@@ -362,8 +544,12 @@ otherwise noted.
read: called by read(2) and related system calls
+ aio_read: called by io_submit(2) and other asynchronous I/O operations
+
write: called by write(2) and related system calls
+ aio_write: called by io_submit(2) and other asynchronous I/O operations
+
readdir: called when the VFS needs to read the directory contents
poll: called by the VFS when a process wants to check if there is
@@ -372,18 +558,25 @@ otherwise noted.
ioctl: called by the ioctl(2) system call
+ unlocked_ioctl: called by the ioctl(2) system call. Filesystems that do not
+ require the BKL should use this method instead of the ioctl() above.
+
+ compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
+ are used on 64 bit kernels.
+
mmap: called by the mmap(2) system call
open: called by the VFS when an inode should be opened. When the VFS
- opens a file, it creates a new "struct file" and initialises
- the "f_op" file operations member with the "default_file_ops"
- field in the inode structure. It then calls the open method
- for the newly allocated file structure. You might think that
- the open method really belongs in "struct inode_operations",
- and you may be right. I think it's done the way it is because
- it makes filesystems simpler to implement. The open() method
- is a good place to initialise the "private_data" member in the
- file structure if you want to point to a device structure
+ opens a file, it creates a new "struct file". It then calls the
+ open method for the newly allocated file structure. You might
+ think that the open method really belongs in
+ "struct inode_operations", and you may be right. I think it's
+ done the way it is because it makes filesystems simpler to
+ implement. The open() method is a good place to initialize the
+ "private_data" member in the file structure if you want to point
+ to a device structure
+
+ flush: called by the close(2) system call to flush a file
release: called when the last reference to an open file is closed
@@ -392,6 +585,23 @@ otherwise noted.
fasync: called by the fcntl(2) system call when asynchronous
(non-blocking) mode is enabled for a file
+ lock: called by the fcntl(2) system call for F_GETLK, F_SETLK, and F_SETLKW
+ commands
+
+ readv: called by the readv(2) system call
+
+ writev: called by the writev(2) system call
+
+ sendfile: called by the sendfile(2) system call
+
+ get_unmapped_area: called by the mmap(2) system call
+
+ check_flags: called by the fcntl(2) system call for F_SETFL command
+
+ dir_notify: called by the fcntl(2) system call for F_NOTIFY command
+
+ flock: called by the flock(2) system call
+
Note that the file operations are implemented by the specific
filesystem in which the inode resides. When opening a device node
(character or block special) most filesystems will call special
@@ -400,29 +610,28 @@ driver information. These support routines replace the filesystem file
operations with those for the device driver, and then proceed to call
the new open() method for the file. This is how opening a device file
in the filesystem eventually ends up calling the device driver open()
-method. Note the devfs (the Device FileSystem) has a more direct path
-from device node to device driver (this is an unofficial kernel
-patch).
+method.
-Directory Entry Cache (dcache) <section>
-------------------------------
+Directory Entry Cache (dcache)
+==============================
+
struct dentry_operations
-========================
+------------------------
This describes how a filesystem can overload the standard dentry
operations. Dentries and the dcache are the domain of the VFS and the
individual filesystem implementations. Device drivers have no business
here. These methods may be set to NULL, as they are either optional or
-the VFS uses a default. As of kernel 2.1.99, the following members are
+the VFS uses a default. As of kernel 2.6.13, the following members are
defined:
struct dentry_operations {
- int (*d_revalidate)(struct dentry *);
+ int (*d_revalidate)(struct dentry *, struct nameidata *);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
- void (*d_delete)(struct dentry *);
+ int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
};
@@ -451,6 +660,7 @@ Each dentry has a pointer to its parent dentry, as well as a hash list
of child dentries. Child dentries are basically like files in a
directory.
+
Directory Entry Cache APIs
--------------------------
@@ -471,7 +681,7 @@ manipulate dentries:
"d_delete" method is called
d_drop: this unhashes a dentry from its parents hash list. A
- subsequent call to dput() will dellocate the dentry if its
+ subsequent call to dput() will deallocate the dentry if its
usage count drops to 0
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
of the pathname and using that dentry along with the next
component to look up the next level and so on. Since it
is a frequent operation for workloads like multiuser
-environments and webservers, it is important to optimize
+environments and web servers, it is important to optimize
this path.
Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus
in every component during path look-up. Since 2.5.10 onwards,
-fastwalk algorithm changed this by holding the dcache_lock
+fast-walk algorithm changed this by holding the dcache_lock
at the beginning and walking as many cached path component
-dentries as possible. This signficantly decreases the number
+dentries as possible. This significantly decreases the number
of acquisition of dcache_lock. However it also increases the
-lock hold time signficantly and affects performance in large
+lock hold time significantly and affects performance in large
SMP machines. Since 2.5.62 kernel, dcache has been using
a new locking model that uses RCU to make dcache look-up
lock-free.
@@ -527,7 +737,7 @@ protected the hash chain, d_child, d_alias, d_lru lists as well
as d_inode and several other things like mount look-up. RCU-based
changes affect only the way the hash chain is protected. For everything
else the dcache_lock must be taken for both traversing as well as
-updating. The hash chain updations too take the dcache_lock.
+updating. The hash chain updates too take the dcache_lock.
The significant change is the way d_lookup traverses the hash chain,
it doesn't acquire the dcache_lock for this and rely on RCU to
ensure that the dentry has not been *freed*.
@@ -535,14 +745,15 @@ ensure that the dentry has not been *freed*.
Dcache locking details
----------------------
+
For many multi-user workloads, open() and stat() on files are
very frequently occurring operations. Both involve walking
of path names to find the dentry corresponding to the
concerned file. In 2.4 kernel, dcache_lock was held
during look-up of each path component. Contention and
-cacheline bouncing of this global lock caused significant
+cache-line bouncing of this global lock caused significant
scalability problems. With the introduction of RCU
-in linux kernel, this was worked around by making
+in Linux kernel, this was worked around by making
the look-up of path components during path walking lock-free.
@@ -562,7 +773,7 @@ Some of the important changes are :
2. Insertion of a dentry into the hash table is done using
hlist_add_head_rcu() which take care of ordering the writes -
the writes to the dentry must be visible before the dentry
- is inserted. This works in conjuction with hlist_for_each_rcu()
+ is inserted. This works in conjunction with hlist_for_each_rcu()
while walking the hash chain. The only requirement is that
all initialization to the dentry must be done before hlist_add_head_rcu()
since we don't have dcache_lock protection while traversing
@@ -584,7 +795,7 @@ Some of the important changes are :
the same. In some sense, dcache_rcu path walking looks like
the pre-2.5.10 version.
-5. All dentry hash chain updations must take the dcache_lock as well as
+5. All dentry hash chain updates must take the dcache_lock as well as
the per-dentry lock in that order. dput() does this to ensure
that a dentry that has just been looked up in another CPU
doesn't get deleted before dget() can be done on it.
@@ -640,10 +851,10 @@ handled as described below :
Since we redo the d_parent check and compare name while holding
d_lock, lock-free look-up will not race against d_move().
-4. There can be a theoritical race when a dentry keeps coming back
+4. There can be a theoretical race when a dentry keeps coming back
to original bucket due to double moves. Due to this look-up may
consider that it has never moved and can end up in a infinite loop.
- But this is not any worse that theoritical livelocks we already
+ But this is not any worse that theoretical livelocks we already
have in the kernel.
diff --git a/Documentation/input/yealink.txt b/Documentation/input/yealink.txt
new file mode 100644
index 00000000000..85f095a7ad0
--- /dev/null
+++ b/Documentation/input/yealink.txt
@@ -0,0 +1,203 @@
+Driver documentation for yealink usb-p1k phones
+
+0. Status
+~~~~~~~~~
+
+The p1k is a relatively cheap usb 1.1 phone with:
+ - keyboard full support, yealink.ko / input event API
+ - LCD full support, yealink.ko / sysfs API
+ - LED full support, yealink.ko / sysfs API
+ - dialtone full support, yealink.ko / sysfs API
+ - ringtone full support, yealink.ko / sysfs API
+ - audio playback full support, snd_usb_audio.ko / alsa API
+ - audio record full support, snd_usb_audio.ko / alsa API
+
+For vendor documentation see http://www.yealink.com
+
+
+1. Compilation (stand alone version)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Currently only kernel 2.6.x.y versions are supported.
+In order to build the yealink.ko module do:
+
+ make
+
+If you encounter problems please check if in the MAKE_OPTS variable in
+the Makefile is pointing to the location where your kernel sources
+are located, default /usr/src/linux.
+
+
+
+2. keyboard features
+~~~~~~~~~~~~~~~~~~~~
+The current mapping in the kernel is provided by the map_p1k_to_key
+function:
+
+ Physical USB-P1K button layout input events
+
+
+ up up
+ IN OUT left, right
+ down down
+
+ pickup C hangup enter, backspace, escape
+ 1 2 3 1, 2, 3
+ 4 5 6 4, 5, 6,
+ 7 8 9 7, 8, 9,
+ * 0 # *, 0, #,
+
+ The "up" and "down" keys, are symbolised by arrows on the button.
+ The "pickup" and "hangup" keys are symbolised by a green and red phone
+ on the button.
+
+
+3. LCD features
+~~~~~~~~~~~~~~~
+The LCD is divided and organised as a 3 line display:
+
+ |[] [][] [][] [][] in |[][]
+ |[] M [][] D [][] : [][] out |[][]
+ store
+
+ NEW REP SU MO TU WE TH FR SA
+
+ [] [] [] [] [] [] [] [] [] [] [] []
+ [] [] [] [] [] [] [] [] [] [] [] []
+
+
+Line 1 Format (see below) : 18.e8.M8.88...188
+ Icon names : M D : IN OUT STORE
+Line 2 Format : .........
+ Icon name : NEW REP SU MO TU WE TH FR SA
+Line 3 Format : 888888888888
+
+
+Format description:
+ From a user space perspective the world is seperated in "digits" and "icons".
+ A digit can have a character set, an icon can only be ON or OFF.
+
+ Format specifier
+ '8' : Generic 7 segment digit with individual addressable segments
+
+ Reduced capabillity 7 segm digit, when segments are hard wired together.
+ '1' : 2 segments digit only able to produce a 1.
+ 'e' : Most significant day of the month digit,
+ able to produce at least 1 2 3.
+ 'M' : Most significant minute digit,
+ able to produce at least 0 1 2 3 4 5.
+
+ Icons or pictograms:
+ '.' : For example like AM, PM, SU, a 'dot' .. or other single segment
+ elements.
+
+
+4. Driver usage
+~~~~~~~~~~~~~~~
+For userland the following interfaces are available using the sysfs interface:
+ /sys/.../
+ line1 Read/Write, lcd line1
+ line2 Read/Write, lcd line2
+ line3 Read/Write, lcd line3
+
+ get_icons Read, returns a set of available icons.
+ hide_icon Write, hide the element by writing the icon name.
+ show_icon Write, display the element by writing the icon name.
+
+ map_seg7 Read/Write, the 7 segments char set, common for all
+ yealink phones. (see map_to_7segment.h)
+
+ ringtone Write, upload binary representation of a ringtone,
+ see yealink.c. status EXPERIMENTAL due to potential
+ races between async. and sync usb calls.
+
+
+4.1 lineX
+~~~~~~~~~
+Reading /sys/../lineX will return the format string with its current value:
+
+ Example:
+ cat ./line3
+ 888888888888
+ Linux Rocks!
+
+Writing to /sys/../lineX will set the coresponding LCD line.
+ - Excess characters are ignored.
+ - If less characters are written than allowed, the remaining digits are
+ unchanged.
+ - The tab '\t'and '\n' char does not overwrite the original content.
+ - Writing a space to an icon will always hide its content.
+
+ Example:
+ date +"%m.%e.%k:%M" | sed 's/^0/ /' > ./line1
+
+ Will update the LCD with the current date & time.
+
+
+4.2 get_icons
+~~~~~~~~~~~~~
+Reading will return all available icon names and its current settings:
+
+ cat ./get_icons
+ on M
+ on D
+ on :
+ IN
+ OUT
+ STORE
+ NEW
+ REP
+ SU
+ MO
+ TU
+ WE
+ TH
+ FR
+ SA
+ LED
+ DIALTONE
+ RINGTONE
+
+
+4.3 show/hide icons
+~~~~~~~~~~~~~~~~~~~
+Writing to these files will update the state of the icon.
+Only one icon at a time can be updated.
+
+If an icon is also on a ./lineX the corresponding value is
+updated with the first letter of the icon.
+
+ Example - light up the store icon:
+ echo -n "STORE" > ./show_icon
+
+ cat ./line1
+ 18.e8.M8.88...188
+ S
+
+ Example - sound the ringtone for 10 seconds:
+ echo -n RINGTONE > /sys/..../show_icon
+ sleep 10
+ echo -n RINGTONE > /sys/..../hide_icon
+
+
+5. Sound features
+~~~~~~~~~~~~~~~~~
+Sound is supported by the ALSA driver: snd_usb_audio
+
+One 16-bit channel with sample and playback rates of 8000 Hz is the practical
+limit of the device.
+
+ Example - recording test:
+ arecord -v -d 10 -r 8000 -f S16_LE -t wav foobar.wav
+
+ Example - playback test:
+ aplay foobar.wav
+
+
+6. Credits & Acknowledgments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ - Olivier Vandorpe, for starting the usbb2k-api project doing much of
+ the reverse engineering.
+ - Martin Diehl, for pointing out how to handle USB memory allocation.
+ - Dmitry Torokhov, for the numerous code reviews and suggestions.
+
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 7ff213f4bec..1f5f7d28c9e 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -39,8 +39,7 @@ SETUP
and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch
and after that build the source.
-2) Download and build the appropriate (latest) kexec/kdump (-mm) kernel
- patchset and apply it to the vanilla kernel tree.
+2) Download and build the appropriate (2.6.13-rc1 onwards) vanilla kernel.
Two kernels need to be built in order to get this feature working.
@@ -84,15 +83,16 @@ SETUP
4) Load the second kernel to be booted using:
- kexec -p <second-kernel> --crash-dump --args-linux --append="root=<root-dev>
- init 1 irqpoll"
+ kexec -p <second-kernel> --args-linux --elf32-core-headers
+ --append="root=<root-dev> init 1 irqpoll"
Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work,
as of now.
- ii) By default ELF headers are stored in ELF32 format (for i386). This
- is sufficient to represent the physical memory up to 4GB. To store
- headers in ELF64 format, specifiy "--elf64-core-headers" on the
- kexec command line additionally.
+ ii) By default ELF headers are stored in ELF64 format. Option
+ --elf32-core-headers forces generation of ELF32 headers. gdb can
+ not open ELF64 headers on 32 bit systems. So creating ELF32
+ headers can come handy for users who have got non-PAE systems and
+ hence have memory less than 4GB.
iii) Specify "irqpoll" as command line parameter. This reduces driver
initialization failures in second kernel due to shared interrupts.
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index f9784147845..5df44dc894e 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -57,7 +57,7 @@ With BK, you can just get it from
and DaveJ has tar-balls at
- http://www.codemonkey.org.uk/projects/bitkeeper/sparse/
+ http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
Once you have it, just do
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 62a12a08e2a..ec785f9f15a 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -126,10 +126,12 @@ card=124 - AverMedia AverTV DVB-T 761
card=125 - MATRIX Vision Sigma-SQ
card=126 - MATRIX Vision Sigma-SLC
card=127 - APAC Viewcomp 878(AMAX)
-card=128 - DVICO FusionHDTV DVB-T Lite
+card=128 - DViCO FusionHDTV DVB-T Lite
card=129 - V-Gear MyVCD
card=130 - Super TV Tuner
card=131 - Tibet Systems 'Progress DVR' CS16
card=132 - Kodicom 4400R (master)
card=133 - Kodicom 4400R (slave)
card=134 - Adlink RTV24
+card=135 - DViCO FusionHDTV 5 Lite
+card=136 - Acorp Y878F
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 1b5a3a9ffbe..dc57225f39b 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -62,3 +62,6 @@
61 -> Philips TOUGH DVB-T reference design [1131:2004]
62 -> Compro VideoMate TV Gold+II
63 -> Kworld Xpert TV PVR7134
+ 64 -> FlyTV mini Asus Digimatrix [1043:0210,1043:0210]
+ 65 -> V-Stream Studio TV Terminator
+ 66 -> Yuan TUN-900 (saa7135)
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f3302e1b1b9..f5876be658a 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -64,3 +64,4 @@ tuner=62 - Philips TEA5767HN FM Radio
tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
tuner=64 - LG TDVS-H062F/TUA6034
tuner=65 - Ymec TVF66T5-B/DFF
+tuner=66 - LG NTSC (TALN mini series)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8e4e8292107..f038dca34ee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -116,6 +116,12 @@ M: ajk@iehk.rwth-aachen.de
L: linux-hams@vger.kernel.org
S: Maintained
+YEALINK PHONE DRIVER
+P: Henk Vergonet
+M: Henk.Vergonet@gmail.com
+L: usbb2k-api-dev@nongnu.org
+S: Maintained
+
8139CP 10/100 FAST ETHERNET DRIVER
P: Jeff Garzik
M: jgarzik@pobox.com
@@ -620,6 +626,12 @@ M: rmk@arm.linux.org.uk
W: http://www.arm.linux.org.uk/
S: Maintained
+CYBLAFB FRAMEBUFFER DRIVER
+P: Knut Petersen
+M: Knut_Petersen@t-online.de
+L: linux-fbdev-devel@lists.sourceforge.net
+S: Maintained
+
CYCLADES 2X SYNC CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
@@ -919,6 +931,13 @@ L: linux-tape@vger.kernel.org
W: http://sourceforge.net/projects/ftape
S: Orphan
+FUSE: FILESYSTEM IN USERSPACE
+P: Miklos Szeredi
+M: miklos@szeredi.hu
+L: fuse-devel@lists.sourceforge.net
+W: http://fuse.sourceforge.net/
+S: Maintained
+
FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
P: Rik Faith
M: faith@cs.unc.edu
@@ -1813,13 +1832,6 @@ M: hch@infradead.org
L: linux-abi-devel@lists.sourceforge.net
S: Maintained
-PCI ID DATABASE
-P: Martin Mares
-M: mj@ucw.cz
-L: pciids-devel@lists.sourceforge.net
-W: http://pciids.sourceforge.net/
-S: Maintained
-
PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
P: Thomas Sailer
M: sailer@ife.ee.ethz.ch
@@ -2685,6 +2697,17 @@ L: rio500-users@lists.sourceforge.net
W: http://rio500.sourceforge.net
S: Maintained
+V9FS FILE SYSTEM
+P: Eric Van Hensbergen
+M: ericvh@gmail.com
+P: Ron Minnich
+M: rminnich@lanl.gov
+P: Latchesar Ionkov
+M: lucho@ionkov.net
+L: v9fs-developer@lists.sourceforge.net
+W: http://v9fs.sf.net
+S: Maintained
+
VIDEO FOR LINUX
P: Mauro Carvalho Chehab
M: mchehab@brturbo.com.br
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index fc271e316a3..aac6d4b22f7 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)
struct got_entry {
struct got_entry *next;
- Elf64_Addr r_offset;
+ Elf64_Sxword r_addend;
int got_offset;
};
@@ -57,14 +57,14 @@ process_reloc_for_got(Elf64_Rela *rela,
{
unsigned long r_sym = ELF64_R_SYM (rela->r_info);
unsigned long r_type = ELF64_R_TYPE (rela->r_info);
- Elf64_Addr r_offset = rela->r_offset;
+ Elf64_Sxword r_addend = rela->r_addend;
struct got_entry *g;
if (r_type != R_ALPHA_LITERAL)
return;
for (g = chains + r_sym; g ; g = g->next)
- if (g->r_offset == r_offset) {
+ if (g->r_addend == r_addend) {
if (g->got_offset == 0) {
g->got_offset = *poffset;
*poffset += 8;
@@ -74,7 +74,7 @@ process_reloc_for_got(Elf64_Rela *rela,
g = kmalloc (sizeof (*g), GFP_KERNEL);
g->next = chains[r_sym].next;
- g->r_offset = r_offset;
+ g->r_addend = r_addend;
g->got_offset = *poffset;
*poffset += 8;
chains[r_sym].next = g;
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 167fd89f870..2b034182a0c 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,
size_t size;
long timeout;
int ret = -EINVAL;
+ struct fdtable *fdt;
timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
@@ -995,7 +996,8 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
}
}
- if (n < 0 || n > current->files->max_fdset)
+ fdt = files_fdtable(current->files);
+ if (n < 0 || n > fdt->max_fdset)
goto out_nofds;
/*
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 804727853d2..e32fee50522 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)
irq += 0x80; /* offset for lsi */
#if 1
- printk("PCI:%d:%d:%d (hose %d) [%s] is using MSI\n",
+ printk("PCI:%d:%d:%d (hose %d) is using MSI\n",
dev->bus->number,
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn),
- hose->index,
- pci_pretty_name (dev));
+ hose->index);
printk(" %d message(s) from 0x%04x\n",
1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
msg_dat);
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 51f430cc2fb..2786f7c34b3 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)
return ret;
}
+#ifdef CONFIG_PM
+
+struct locomo_save_data {
+ u16 LCM_GPO;
+ u16 LCM_SPICT;
+ u16 LCM_GPE;
+ u16 LCM_ASD;
+ u16 LCM_SPIMD;
+};
+
+static int locomo_suspend(struct device *dev, u32 pm_message_t, u32 level)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ struct locomo_save_data *save;
+ unsigned long flags;
+
+ if (level != SUSPEND_DISABLE)
+ return 0;
+
+ save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
+ if (!save)
+ return -ENOMEM;
+
+ dev->power.saved_state = (void *) save;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */
+ locomo_writel(0x00, lchip->base + LOCOMO_GPO);
+ save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPICT); /* SPI */
+ locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
+ save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */
+ locomo_writel(0x00, lchip->base + LOCOMO_GPE);
+ save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */
+ locomo_writel(0x00, lchip->base + LOCOMO_ASD);
+ save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPIMD); /* SPI */
+ locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD);
+
+ locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
+ locomo_writel(0x00, lchip->base + LOCOMO_DAC);
+ locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
+
+ if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) )
+ locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */
+ else
+ /* 18MHz already enabled, so no wait */
+ locomo_writel(0xc1, lchip->base + LOCOMO_C32K); /* CLK32 on */
+
+ locomo_writel(0x00, lchip->base + LOCOMO_TADC); /* 18MHz clock off*/
+ locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC); /* 22MHz/24MHz clock off */
+ locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); /* FL */
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ return 0;
+}
+
+static int locomo_resume(struct device *dev, u32 level)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ struct locomo_save_data *save;
+ unsigned long r;
+ unsigned long flags;
+
+ if (level != RESUME_ENABLE)
+ return 0;
+
+ save = (struct locomo_save_data *) dev->power.saved_state;
+ if (!save)
+ return 0;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
+ locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT);
+ locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
+ locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
+ locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD);
+
+ locomo_writel(0x00, lchip->base + LOCOMO_C32K);
+ locomo_writel(0x90, lchip->base + LOCOMO_TADC);
+
+ locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
+ r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+ r &= 0xFEFF;
+ locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+ locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ dev->power.saved_state = NULL;
+ kfree(save);
+
+ return 0;
+}
+#endif
+
/**
* locomo_probe - probe for a single LoCoMo chip.
* @phys_addr: physical address of device.
@@ -707,6 +804,10 @@ static struct device_driver locomo_device_driver = {
.bus = &platform_bus_type,
.probe = locomo_probe,
.remove = locomo_remove,
+#ifdef CONFIG_PM
+ .suspend = locomo_suspend,
+ .resume = locomo_resume,
+#endif
};
/*
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 96a794d8de8..756348bf517 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-git4
-# Wed Jun 22 15:56:42 2005
+# Linux kernel version: 2.6.13-git8
+# Thu Sep 8 19:24:02 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
# General setup
#
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -88,7 +90,9 @@ CONFIG_ARCH_S3C2410=y
#
# S3C24XX Implementations
#
+CONFIG_MACH_ANUBIS=y
CONFIG_ARCH_BAST=y
+CONFIG_BAST_PC104_IRQ=y
CONFIG_ARCH_H1940=y
CONFIG_MACH_N30=y
CONFIG_ARCH_SMDK2410=y
@@ -112,6 +116,7 @@ CONFIG_S3C2410_DMA=y
# CONFIG_S3C2410_DMA_DEBUG is not set
# CONFIG_S3C2410_PM_DEBUG is not set
# CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_PM_SIMTEC=y
CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
#
@@ -149,7 +154,15 @@ CONFIG_ISA_DMA_API=y
#
# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
-# CONFIG_DISCONTIGMEM is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_ALIGNMENT_TRAP=y
#
@@ -186,6 +199,74 @@ CONFIG_PM=y
CONFIG_APM=y
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
@@ -258,6 +339,7 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_IMPA7 is not set
CONFIG_MTD_BAST=y
CONFIG_MTD_BAST_MAXSIZE=4
+# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@@ -312,7 +394,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@@ -354,6 +435,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@@ -376,70 +458,8 @@ CONFIG_BLK_DEV_IDE_BAST=y
#
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -447,6 +467,11 @@ CONFIG_NETDEVICES=y
# CONFIG_TUN is not set
#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
@@ -480,6 +505,8 @@ CONFIG_DM9000=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -562,7 +589,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -605,7 +631,6 @@ CONFIG_S3C2410_RTC=y
#
# Ftape, the floppy tape device driver
#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
@@ -628,7 +653,7 @@ CONFIG_I2C_ALGOBIT=m
#
# I2C Hardware Bus support
#
-# CONFIG_I2C_ISA is not set
+CONFIG_I2C_ISA=m
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
CONFIG_I2C_S3C2410=y
@@ -636,14 +661,33 @@ CONFIG_I2C_S3C2410=y
# CONFIG_I2C_PCA_ISA is not set
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-CONFIG_I2C_SENSOR=m
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=m
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=m
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
# CONFIG_SENSORS_FSCPOS is not set
@@ -662,27 +706,21 @@ CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
-# Other I2C Chip support
+# Misc devices
#
-# CONFIG_SENSORS_DS1337 is not set
-CONFIG_SENSORS_EEPROM=m
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
#
-# Misc devices
+# Multimedia Capabilities Port drivers
#
#
@@ -731,7 +769,7 @@ CONFIG_DUMMY_CONSOLE=y
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB is not set
#
@@ -749,6 +787,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -758,6 +797,7 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
#
# XFS support
@@ -765,6 +805,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -791,11 +832,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -812,8 +853,7 @@ CONFIG_JFFS_FS_VERBOSE=0
# CONFIG_JFFS_PROC_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -835,6 +875,7 @@ CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -920,6 +961,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_LOG_BUF_SHIFT=16
+CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 112f1d68fb2..e216ab8b9e8 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 23c4da10101..5aeadfd7214 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 7daa021676d..44c56571d18 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
index aa3a1fef563..28846c7edaa 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 4b3199319e6..a4a7c0125d0 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 098c817a7fb..74bd2fd602d 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 = {
static struct platform_device ixp2000_serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = ixp2000_serial_port,
},
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 8b2f2532245..050c9276891 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[] = {
static struct platform_device coyote_uart = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = coyote_uart_data,
},
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 3fd92c5cbaa..29a6d02fa85 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[] = {
static struct platform_device gtwx5715_uart_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = gtwx5715_uart_platform_data,
},
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 6c14ff3c23a..ae1fa099d5f 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[] = {
static struct platform_device ixdp425_uart = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = ixdp425_uart_data,
.num_resources = 2,
.resource = ixdp425_uart_resources
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 7408ac94f77..27fc2e8e5fc 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -47,6 +47,14 @@ config MACH_OMAP_OSK
TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
if you have such a board.
+config OMAP_OSK_MISTRAL
+ bool "Mistral QVGA board Support"
+ depends on MACH_OMAP_OSK
+ help
+ The OSK supports an optional add-on board with a Quarter-VGA
+ touchscreen, PDA-ish buttons, a resume button, bicolor LED,
+ and camera connector. Say Y here if you have this board.
+
config MACH_OMAP_PERSEUS2
bool "TI Perseus2"
depends on ARCH_OMAP1 && ARCH_OMAP730
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index d386fd913f0..181a93deaae 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := io.o id.o irq.o time.o serial.o
+obj-y := io.o id.o irq.o time.o serial.o devices.o
led-y := leds.o
# Specific board support
@@ -23,6 +23,7 @@ endif
# LEDs support
led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_H3) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
led-$(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 122796ebe8f..c209c7172a9 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 = {
#if defined(CONFIG_ARCH_OMAP16XX)
static struct omap_usb_config generic1610_usb_config __initdata = {
+#ifdef CONFIG_USB_OTG
+ .otg = 1,
+#endif
.register_host = 1,
.register_dev = 1,
.hmc_mode = 16,
.pins[0] = 6,
};
+
+static struct omap_mmc_config generic_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 0,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ },
+ .mmc [1] = {
+ .enabled = 0,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1,
+ .switch_pin = -1,
+ },
+};
+
#endif
static struct omap_board_config_kernel generic_config[] = {
{ OMAP_TAG_USB, NULL },
+ { OMAP_TAG_MMC, &generic_mmc_config },
};
static void __init omap_generic_init(void)
{
+ const struct omap_uart_config *uart_conf;
+
/*
* Make sure the serial ports are muxed on at this point.
* You have to mux them off in device drivers later on
@@ -76,6 +100,18 @@ static void __init omap_generic_init(void)
generic_config[0].data = &generic1610_usb_config;
}
#endif
+
+ uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+ if (uart_conf != NULL) {
+ unsigned int enabled_ports, i;
+
+ enabled_ports = uart_conf->enabled_uarts;
+ for (i = 0; i < 3; i++) {
+ if (!(enabled_ports & (1 << i)))
+ generic_serial_ports[i] = 0;
+ }
+ }
+
omap_board_config = generic_config;
omap_board_config_size = ARRAY_SIZE(generic_config);
omap_serial_init(generic_serial_ports);
@@ -83,7 +119,7 @@ static void __init omap_generic_init(void)
static void __init omap_generic_map_io(void)
{
- omap_map_common_io()
+ omap_map_common_io();
}
MACHINE_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 f4983ee95ab..d46a70063b0 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -33,6 +33,7 @@
#include <asm/mach/map.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/arch/usb.h>
#include <asm/arch/common.h>
@@ -80,8 +81,7 @@ static struct flash_platform_data h2_flash_data = {
};
static struct resource h2_flash_resource = {
- .start = OMAP_CS2B_PHYS,
- .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+ /* This is on CS3, wherever it's mapped */
.flags = IORESOURCE_MEM,
};
@@ -126,10 +126,9 @@ static void __init h2_init_smc91x(void)
printk("Error requesting gpio 0 for smc91x irq\n");
return;
}
- omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE);
}
-void h2_init_irq(void)
+static void __init h2_init_irq(void)
{
omap_init_irq();
omap_gpio_init();
@@ -152,9 +151,13 @@ static struct omap_usb_config h2_usb_config __initdata = {
};
static struct omap_mmc_config h2_mmc_config __initdata = {
- .mmc_blocks = 1,
- .mmc1_power_pin = -1, /* tps65010 gpio3 */
- .mmc1_switch_pin = OMAP_MPUIO(1),
+ .mmc [0] = {
+ .enabled = 1,
+ .wire4 = 1,
+ .wp_pin = OMAP_MPUIO(3),
+ .power_pin = -1, /* tps65010 gpio3 */
+ .switch_pin = OMAP_MPUIO(1),
+ },
};
static struct omap_board_config_kernel h2_config[] = {
@@ -164,6 +167,16 @@ static struct omap_board_config_kernel h2_config[] = {
static void __init h2_init(void)
{
+ /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
+ * and NAND (either 16bit or 8bit) on CS3.
+ */
+ h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
+ h2_flash_resource.end += SZ_32M - 1;
+
+ /* MMC: card detect and WP */
+ // omap_cfg_reg(U19_ARMIO1); /* CD */
+ omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
+
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
omap_board_config = h2_config;
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 7cd419d61b4..2798613696f 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 = {
};
static struct resource h3_flash_resource = {
- .start = OMAP_CS2B_PHYS,
- .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+ /* This is on CS3, wherever it's mapped */
.flags = IORESOURCE_MEM,
};
@@ -161,13 +160,26 @@ static struct omap_usb_config h3_usb_config __initdata = {
.pins[1] = 3,
};
+static struct omap_mmc_config h3_mmc_config __initdata = {
+ .mmc[0] = {
+ .enabled = 1,
+ .power_pin = -1, /* tps65010 GPIO4 */
+ .switch_pin = OMAP_MPUIO(1),
+ },
+};
+
static struct omap_board_config_kernel h3_config[] = {
{ OMAP_TAG_USB, &h3_usb_config },
+ { OMAP_TAG_MMC, &h3_mmc_config },
};
static void __init h3_init(void)
{
+ h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
+ h3_flash_resource.end += OMAP_CS3_SIZE - 1;
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+ omap_board_config = h3_config;
+ omap_board_config_size = ARRAY_SIZE(h3_config);
}
static void __init h3_init_smc91x(void)
@@ -177,7 +189,6 @@ static void __init h3_init_smc91x(void)
printk("Error requesting gpio 40 for smc91x irq\n");
return;
}
- omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE);
}
void h3_init_irq(void)
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 91de60a91ef..df0312b596e 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -29,6 +29,7 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
+#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
#include <asm/arch/gpio.h>
#include <asm/arch/tc.h>
@@ -173,7 +174,6 @@ static void __init innovator_init_smc91x(void)
printk("Error requesting gpio 0 for smc91x irq\n");
return;
}
- omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
}
}
@@ -220,8 +220,19 @@ static struct omap_usb_config h2_usb_config __initdata = {
};
#endif
+static struct omap_mmc_config innovator_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 1,
+ .wire4 = 1,
+ .wp_pin = OMAP_MPUIO(3),
+ .power_pin = -1, /* FPGA F3 UIO42 */
+ .switch_pin = -1, /* FPGA F4 UIO43 */
+ },
+};
+
static struct omap_board_config_kernel innovator_config[] = {
{ OMAP_TAG_USB, NULL },
+ { OMAP_TAG_MMC, &innovator_mmc_config },
};
static void __init innovator_init(void)
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 6750b201409..d904e643f5e 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)
mdelay(50); /* 50ms until PHY ready */
/* smc91x interrupt pin */
omap_request_gpio(8);
- omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
omap_request_gpio(12);
omap_request_gpio(13);
omap_request_gpio(14);
omap_request_gpio(15);
- omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE);
- omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE);
- omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE);
- omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE);
+ set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
+ set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
+ set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
+ set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 6844e536c69..21103df5041 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -29,11 +29,16 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/interrupt.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
#include <asm/arch/gpio.h>
#include <asm/arch/usb.h>
@@ -41,12 +46,56 @@
#include <asm/arch/tc.h>
#include <asm/arch/common.h>
-static struct map_desc osk5912_io_desc[] __initdata = {
-{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
- MT_DEVICE },
+static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
+
+static struct mtd_partition osk_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
};
-static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
+static struct flash_platform_data osk_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = osk_partitions,
+ .nr_parts = ARRAY_SIZE(osk_partitions),
+};
+
+static struct resource osk_flash_resource = {
+ /* this is on CS3, wherever it's mapped */
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device osk5912_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &osk_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &osk_flash_resource,
+};
static struct resource osk5912_smc91x_resources[] = {
[0] = {
@@ -86,9 +135,16 @@ static struct platform_device osk5912_cf_device = {
.resource = osk5912_cf_resources,
};
+static struct platform_device osk5912_mcbsp1_device = {
+ .name = "omap_mcbsp",
+ .id = 1,
+};
+
static struct platform_device *osk5912_devices[] __initdata = {
+ &osk5912_flash_device,
&osk5912_smc91x_device,
&osk5912_cf_device,
+ &osk5912_mcbsp1_device,
};
static void __init osk_init_smc91x(void)
@@ -97,7 +153,6 @@ static void __init osk_init_smc91x(void)
printk("Error requesting gpio 0 for smc91x irq\n");
return;
}
- omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
EMIFS_CCS(1) |= 0x2;
@@ -110,11 +165,11 @@ static void __init osk_init_cf(void)
printk("Error requesting gpio 62 for CF irq\n");
return;
}
- /* it's really active-low */
- omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE);
+ /* the CF I/O IRQ is really active-low */
+ set_irq_type(OMAP_GPIO_IRQ(62), IRQT_FALLING);
}
-void osk_init_irq(void)
+static void __init osk_init_irq(void)
{
omap_init_irq();
omap_gpio_init();
@@ -142,18 +197,69 @@ static struct omap_board_config_kernel osk_config[] = {
{ OMAP_TAG_USB, &osk_usb_config },
};
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+#ifdef CONFIG_PM
+static irqreturn_t
+osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
+{
+ return IRQ_HANDLED;
+}
+#endif
+
+static void __init osk_mistral_init(void)
+{
+ /* FIXME here's where to feed in framebuffer, touchpad, and
+ * keyboard setup ... not in the drivers for those devices!
+ *
+ * NOTE: we could actually tell if there's a Mistral board
+ * attached, e.g. by trying to read something from the ads7846.
+ * But this is too early for that...
+ */
+
+ /* the sideways button (SW1) is for use as a "wakeup" button */
+ omap_cfg_reg(N15_1610_MPUIO2);
+ if (omap_request_gpio(OMAP_MPUIO(2)) == 0) {
+ int ret = 0;
+ omap_set_gpio_direction(OMAP_MPUIO(2), 1);
+ set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING);
+#ifdef CONFIG_PM
+ /* share the IRQ in case someone wants to use the
+ * button for more than wakeup from system sleep.
+ */
+ ret = request_irq(OMAP_GPIO_IRQ(OMAP_MPUIO(2)),
+ &osk_mistral_wake_interrupt,
+ SA_SHIRQ, "mistral_wakeup",
+ &osk_mistral_wake_interrupt);
+ if (ret != 0) {
+ omap_free_gpio(OMAP_MPUIO(2));
+ printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n",
+ ret);
+ } else
+ enable_irq_wake(OMAP_GPIO_IRQ(OMAP_MPUIO(2)));
+#endif
+ } else
+ printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
+}
+#else
+static void __init osk_mistral_init(void) { }
+#endif
+
static void __init osk_init(void)
{
+ osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
+ osk_flash_resource.end += SZ_32M - 1;
platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
omap_board_config = osk_config;
omap_board_config_size = ARRAY_SIZE(osk_config);
USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+
+ osk_mistral_init();
}
static void __init osk_map_io(void)
{
omap_map_common_io();
- iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
omap_serial_init(osk_serial_ports);
}
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 213317392d9..107c68c8ab5 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -24,6 +24,7 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
+#include <asm/arch/tc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
@@ -83,8 +84,8 @@ static struct flash_platform_data p2_flash_data = {
};
static struct resource p2_flash_resource = {
- .start = OMAP_FLASH_0_START,
- .end = OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1,
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index e4228198899..bf30b1acda0 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -25,13 +25,14 @@
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
#include <asm/mach/map.h>
+#include <asm/arch/common.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/tc.h>
#include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
#include <asm/arch/usb.h>
-#include <asm/arch/common.h>
extern void omap_init_time(void);
extern int omap_gpio_init(void);
@@ -74,7 +75,7 @@ static struct plat_serial8250_port voiceblue_ports[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 1,
+ .id = PLAT8250_DEV_PLATFORM1,
.dev = {
.platform_data = voiceblue_ports,
},
@@ -86,6 +87,27 @@ static int __init ext_uart_init(void)
}
arch_initcall(ext_uart_init);
+static struct flash_platform_data voiceblue_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource voiceblue_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device voiceblue_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &voiceblue_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &voiceblue_flash_resource,
+};
+
static struct resource voiceblue_smc91x_resources[] = {
[0] = {
.start = OMAP_CS2_PHYS + 0x300,
@@ -107,6 +129,7 @@ static struct platform_device voiceblue_smc91x_device = {
};
static struct platform_device *voiceblue_devices[] __initdata = {
+ &voiceblue_flash_device,
&voiceblue_smc91x_device,
};
@@ -119,8 +142,17 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
.pins[2] = 6,
};
+static struct omap_mmc_config voiceblue_mmc_config __initdata = {
+ .mmc[0] = {
+ .enabled = 1,
+ .power_pin = 2,
+ .switch_pin = -1,
+ },
+};
+
static struct omap_board_config_kernel voiceblue_config[] = {
{ OMAP_TAG_USB, &voiceblue_usb_config },
+ { OMAP_TAG_MMC, &voiceblue_mmc_config },
};
static void __init voiceblue_init_irq(void)
@@ -131,9 +163,6 @@ static void __init voiceblue_init_irq(void)
static void __init voiceblue_init(void)
{
- /* There is a good chance board is going up, so enable Power LED
- * (it is connected through invertor) */
- omap_writeb(0x00, OMAP_LPG1_LCR);
/* Watchdog */
omap_request_gpio(0);
/* smc91x reset */
@@ -145,7 +174,6 @@ static void __init voiceblue_init(void)
mdelay(50); /* 50ms until PHY ready */
/* smc91x interrupt pin */
omap_request_gpio(8);
- omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
/* 16C554 reset*/
omap_request_gpio(6);
omap_set_gpio_direction(6, 0);
@@ -155,14 +183,19 @@ static void __init voiceblue_init(void)
omap_request_gpio(13);
omap_request_gpio(14);
omap_request_gpio(15);
- omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE);
- omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
- omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE);
- omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE);
+ set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING);
+ set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
+ set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING);
+ set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING);
platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
omap_board_config = voiceblue_config;
omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+
+ /* There is a good chance board is going up, so enable power LED
+ * (it is connected through invertor) */
+ omap_writeb(0x00, OMAP_LPG1_LCR);
+ omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
}
static 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,
if (test_and_set_bit(MACHINE_PANICED, &machine_state))
return NOTIFY_DONE;
- /* Flash Power LED
- * (TODO: Enable clock right way (enabled in bootloader already)) */
+ /* Flash power LED */
omap_writeb(0x78, OMAP_LPG1_LCR);
+ omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
return NOTIFY_DONE;
}
@@ -195,15 +228,14 @@ static struct notifier_block panic_block = {
.notifier_call = panic_event,
};
-static int __init setup_notifier(void)
+static int __init voiceblue_setup(void)
{
/* Setup panic notifier */
notifier_chain_register(&panic_notifier_list, &panic_block);
return 0;
}
-
-postcore_initcall(setup_notifier);
+postcore_initcall(voiceblue_setup);
static int wdt_gpio_state;
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
new file mode 100644
index 00000000000..e8b3981444c
--- /dev/null
+++ b/arch/arm/mach-omap1/devices.c
@@ -0,0 +1,351 @@
+/*
+ * linux/arch/arm/mach-omap1/devices.c
+ *
+ * OMAP1 platform device setup/initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+
+static void omap_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define OMAP_I2C_BASE 0xfffb3800
+
+static struct resource i2c_resources[] = {
+ {
+ .start = OMAP_I2C_BASE,
+ .end = OMAP_I2C_BASE + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* DMA not used; works around erratum writing to non-empty i2c fifo */
+
+static struct platform_device omap_i2c_device = {
+ .name = "i2c_omap",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(i2c_resources),
+ .resource = i2c_resources,
+};
+
+static void omap_init_i2c(void)
+{
+ /* FIXME define and use a boot tag, in case of boards that
+ * either don't wire up I2C, or chips that mux it differently...
+ * it can include clocking and address info, maybe more.
+ */
+ omap_cfg_reg(I2C_SCL);
+ omap_cfg_reg(I2C_SDA);
+
+ (void) platform_device_register(&omap_i2c_device);
+}
+#else
+static inline void omap_init_i2c(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
+
+static u64 irda_dmamask = 0xffffffff;
+
+static struct platform_device omap1610ir_device = {
+ .name = "omap1610-ir",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &irda_dmamask,
+ },
+};
+
+static void omap_init_irda(void)
+{
+ /* FIXME define and use a boot tag, members something like:
+ * u8 uart; // uart1, or uart3
+ * ... but driver only handles uart3 for now
+ * s16 fir_sel; // gpio for SIR vs FIR
+ * ... may prefer a callback for SIR/MIR/FIR mode select;
+ * while h2 uses a GPIO, H3 uses a gpio expander
+ */
+ if (machine_is_omap_h2()
+ || machine_is_omap_h3())
+ (void) platform_device_register(&omap1610ir_device);
+}
+#else
+static inline void omap_init_irda(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define OMAP_MMC1_BASE 0xfffb7800
+#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+
+static struct omap_mmc_conf mmc1_conf;
+
+static u64 mmc1_dmamask = 0xffffffff;
+
+static struct resource mmc1_resources[] = {
+ {
+ .start = IO_ADDRESS(OMAP_MMC1_BASE),
+ .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MMC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mmc_omap_device1 = {
+ .name = "mmci-omap",
+ .id = 1,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &mmc1_dmamask,
+ .platform_data = &mmc1_conf,
+ },
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+ .resource = mmc1_resources,
+};
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+static struct omap_mmc_conf mmc2_conf;
+
+static u64 mmc2_dmamask = 0xffffffff;
+
+static struct resource mmc2_resources[] = {
+ {
+ .start = IO_ADDRESS(OMAP_MMC2_BASE),
+ .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_MMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mmc_omap_device2 = {
+ .name = "mmci-omap",
+ .id = 2,
+ .dev = {
+ .release = omap_nop_release,
+ .dma_mask = &mmc2_dmamask,
+ .platform_data = &mmc2_conf,
+ },
+ .num_resources = ARRAY_SIZE(mmc2_resources),
+ .resource = mmc2_resources,
+};
+#endif
+
+static void __init omap_init_mmc(void)
+{
+ const struct omap_mmc_config *mmc_conf;
+ const struct omap_mmc_conf *mmc;
+
+ /* NOTE: assumes MMC was never (wrongly) enabled */
+ mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+ if (!mmc_conf)
+ return;
+
+ /* block 1 is always available and has just one pinout option */
+ mmc = &mmc_conf->mmc[0];
+ if (mmc->enabled) {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (mmc->wire4) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc->nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ mmc1_conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device1);
+ }
+
+#ifdef CONFIG_ARCH_OMAP16XX
+ /* block 2 is on newer chips, and has many pinout options */
+ mmc = &mmc_conf->mmc[1];
+ if (mmc->enabled) {
+ if (!mmc->nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (mmc->wire4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ mmc2_conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device2);
+ }
+#endif
+ return;
+}
+#else
+static inline void omap_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
+
+#define OMAP_RTC_BASE 0xfffb4800
+
+static struct resource rtc_resources[] = {
+ {
+ .start = OMAP_RTC_BASE,
+ .end = OMAP_RTC_BASE + 0x5f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_RTC_TIMER,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap_rtc_device = {
+ .name = "omap_rtc",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+static void omap_init_rtc(void)
+{
+ (void) platform_device_register(&omap_rtc_device);
+}
+#else
+static inline void omap_init_rtc(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
+
+#define OMAP_WDT_BASE 0xfffeb000
+
+static struct resource wdt_resources[] = {
+ {
+ .start = OMAP_WDT_BASE,
+ .end = OMAP_WDT_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_wdt_device = {
+ .name = "omap1610_wdt",
+ .id = -1,
+ .dev = {
+ .release = omap_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void omap_init_wdt(void)
+{
+ (void) platform_device_register(&omap_wdt_device);
+}
+#else
+static inline void omap_init_wdt(void) {}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ * (a) Does any "standard config" pin muxing needed. Board-specific
+ * code will have muxed GPIO pins and done "nonstandard" setup;
+ * that code could live in the boot loader.
+ * (b) Populating board-specific platform_data with the data drivers
+ * rely on to handle wiring variations.
+ * (c) Creating platform devices as meaningful on this board and
+ * with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers. So is responding to probe().
+ *
+ * Board-specific knowlege like creating devices or pin setup is to be
+ * kept out of drivers as much as possible. In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_i2c();
+ omap_init_irda();
+ omap_init_mmc();
+ omap_init_rtc();
+ omap_init_wdt();
+
+ return 0;
+}
+arch_initcall(omap_init_devices);
+
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index c12a7833562..aca2a120813 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/fpga.c
+ * linux/arch/arm/mach-omap1/fpga.c
*
* Interrupt handler for OMAP-1510 Innovator FPGA
*
@@ -181,7 +181,7 @@ void omap1510_fpga_init_irq(void)
*/
omap_request_gpio(13);
omap_set_gpio_direction(13, 1);
- omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
+ set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING);
set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
}
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 207df0fe934..eb8261d7dea 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -19,6 +19,7 @@
extern int clk_init(void);
extern void omap_check_revision(void);
+extern void omap_sram_init(void);
/*
* The machine specific code may provide the extra mapping besides the
@@ -32,7 +33,6 @@ static struct map_desc omap_io_desc[] __initdata = {
static struct map_desc omap730_io_desc[] __initdata = {
{ OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE },
{ OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
- { OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE }
};
#endif
@@ -40,27 +40,13 @@ static struct map_desc omap730_io_desc[] __initdata = {
static struct map_desc omap1510_io_desc[] __initdata = {
{ OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE },
{ OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
- { OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE }
};
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
-static struct map_desc omap1610_io_desc[] __initdata = {
+static struct map_desc omap16xx_io_desc[] __initdata = {
{ OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE },
{ OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
- { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE }
-};
-
-static struct map_desc omap5912_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
-/*
- * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
- * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
- * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
- * can be used.
- */
- { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE }
};
#endif
@@ -86,14 +72,13 @@ static void __init _omap_map_io(void)
}
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
- if (cpu_is_omap1610() || cpu_is_omap1710()) {
- iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
- }
- if (cpu_is_omap5912()) {
- iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
+ if (cpu_is_omap16xx()) {
+ iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
}
#endif
+ omap_sram_init();
+
/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
* on a Posted Write in the TIPB Bridge".
*/
@@ -108,8 +93,9 @@ static void __init _omap_map_io(void)
/*
* This should only get called from board specific init
*/
-void omap_map_common_io(void)
+void __init omap_map_common_io(void)
{
if (!initialized)
_omap_map_io();
}
+
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index afd5d67e4ae..192ce6055fa 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/irq.c
+ * linux/arch/arm/mach-omap1/irq.c
*
* Interrupt handler for all OMAP boards
*
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index ec0d8285f24..be283cda63d 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/leds-h2p2-debug.c
+ * linux/arch/arm/mach-omap1/leds-h2p2-debug.c
*
* Copyright 2003 by Texas Instruments Incorporated
*
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
+#include <linux/version.h>
#include <asm/io.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
index 8043b7d0f66..c8ffd1ddcde 100644
--- a/arch/arm/mach-omap1/leds-innovator.c
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/leds-innovator.c
+ * linux/arch/arm/mach-omap1/leds-innovator.c
*/
#include <linux/config.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
index 4a0e8b9d4fc..2c8bda847c1 100644
--- a/arch/arm/mach-omap1/leds-osk.c
+++ b/arch/arm/mach-omap1/leds-osk.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/leds-osk.c
+ * linux/arch/arm/mach-omap1/leds-osk.c
*
* LED driver for OSK, and optionally Mistral QVGA, boards
*/
@@ -64,7 +64,7 @@ static void tps_work(void *unused)
static DECLARE_WORK(work, tps_work, NULL);
-#ifdef CONFIG_FB_OMAP
+#ifdef CONFIG_OMAP_OSK_MISTRAL
/* For now, all system indicators require the Mistral board, since that
* 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)
hw_led_state = 0;
break;
-#ifdef CONFIG_FB_OMAP
+#ifdef CONFIG_OMAP_OSK_MISTRAL
case led_timer:
hw_led_state ^= TIMER_LED;
@@ -144,7 +144,7 @@ void osk_leds_event(led_event_t evt)
mistral_setled();
break;
-#endif /* CONFIG_FB_OMAP */
+#endif /* CONFIG_OMAP_OSK_MISTRAL */
/* "green" == tps LED1 (leftmost, normally power-good)
* 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 8ab21fe98e1..5c6b1bb6e72 100644
--- a/arch/arm/mach-omap1/leds.c
+++ b/arch/arm/mach-omap1/leds.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-omap/leds.c
+ * linux/arch/arm/mach-omap1/leds.c
*
* OMAP LEDs dispatcher
*/
@@ -20,7 +20,9 @@ omap_leds_init(void)
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
- else if (machine_is_omap_h2() || machine_is_omap_perseus2())
+ else if (machine_is_omap_h2()
+ || machine_is_omap_h3()
+ || machine_is_omap_perseus2())
leds_event = h2p2_dbg_leds_event;
else if (machine_is_omap_osk())
@@ -30,8 +32,12 @@ omap_leds_init(void)
return -1;
if (machine_is_omap_h2()
+ || machine_is_omap_h3()
|| machine_is_omap_perseus2()
- || machine_is_omap_osk()) {
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+ || machine_is_omap_osk()
+#endif
+ ) {
/* LED1/LED2 pins can be used as GPIO (as done here), or by
* 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 214e5d17c8b..40c4f7c40e7 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -24,7 +24,11 @@
#include <asm/arch/board.h>
#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
#include <asm/arch/fpga.h>
+#ifdef CONFIG_PM
+#include <asm/arch/pm.h>
+#endif
static struct clk * uart1_ck = NULL;
static struct clk * uart2_ck = NULL;
@@ -94,7 +98,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
@@ -193,6 +197,86 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
}
}
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+
+static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ /* Need to do something with serial port right after wake-up? */
+ return IRQ_HANDLED;
+}
+
+/*
+ * Reroutes serial RX lines to GPIO lines for the duration of
+ * sleep to allow waking up the device from serial port even
+ * in deep sleep.
+ */
+void omap_serial_wake_trigger(int enable)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ if (uart1_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(V14_16XX_GPIO37);
+ else
+ omap_cfg_reg(V14_16XX_UART1_RX);
+ }
+ if (uart2_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(R9_16XX_GPIO18);
+ else
+ omap_cfg_reg(R9_16XX_UART2_RX);
+ }
+ if (uart3_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(L14_16XX_GPIO49);
+ else
+ omap_cfg_reg(L14_16XX_UART3_RX);
+ }
+}
+
+static void __init omap_serial_set_port_wakeup(int gpio_nr)
+{
+ int ret;
+
+ ret = omap_request_gpio(gpio_nr);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not request UART wake GPIO: %i\n",
+ gpio_nr);
+ return;
+ }
+ omap_set_gpio_direction(gpio_nr, 1);
+ set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING);
+ ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
+ 0, "serial wakeup", NULL);
+ if (ret) {
+ omap_free_gpio(gpio_nr);
+ printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
+ gpio_nr);
+ return;
+ }
+ enable_irq_wake(OMAP_GPIO_IRQ(gpio_nr));
+}
+
+static int __init omap_serial_wakeup_init(void)
+{
+ if (!cpu_is_omap16xx())
+ return 0;
+
+ if (uart1_ck != NULL)
+ omap_serial_set_port_wakeup(37);
+ if (uart2_ck != NULL)
+ omap_serial_set_port_wakeup(18);
+ if (uart3_ck != NULL)
+ omap_serial_set_port_wakeup(49);
+
+ return 0;
+}
+late_initcall(omap_serial_wakeup_init);
+
+#endif /* CONFIG_OMAP_SERIAL_WAKE */
+
static int __init omap_init(void)
{
return platform_device_register(&serial_device);
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index d540539c9bb..191a9b1ee9b 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)
#define OMAP_32K_TIMER_TCR 0x04
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
-#if (32768 % HZ) != 0
-/* We cannot ignore modulo.
- * Potential error can be as high as several percent.
- */
-#define OMAP_32K_TICK_MODULO (32768 % HZ)
-static unsigned modulo_count = 0; /* Counts 1/HZ units */
-#endif
/*
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
@@ -296,13 +289,22 @@ static inline void omap_32k_timer_stop(void)
}
/*
- * Rounds down to nearest usec
+ * Rounds down to nearest usec. Note that this will overflow for larger values.
*/
static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
{
return (ticks_32k * 5*5*5*5*5*5) >> 9;
}
+/*
+ * Rounds down to nearest nsec.
+ */
+static inline unsigned long long
+omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
+{
+ return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
+}
+
static unsigned long omap_32k_last_tick = 0;
/*
@@ -315,6 +317,15 @@ static unsigned long omap_32k_timer_gettimeoffset(void)
}
/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+ return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
+}
+
+/*
* Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
* function is also called from other interrupts to remove latency
* 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,
now = omap_32k_sync_timer_read();
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
-#ifdef OMAP_32K_TICK_MODULO
- /* Modulo addition may put omap_32k_last_tick ahead of now
- * and cause unwanted repetition of the while loop.
- */
- if (unlikely(now - omap_32k_last_tick == ~0))
- break;
-
- modulo_count += OMAP_32K_TICK_MODULO;
- if (modulo_count > HZ) {
- ++omap_32k_last_tick;
- modulo_count -= HZ;
- }
-#endif
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
timer_tick(regs);
}
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 8ccffba0018..366a9bde3d8 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -22,7 +22,7 @@
#include <asm/arch/corgi.h>
#include <asm/arch/pxa-regs.h>
-static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(corgi_ssp_lock);
static struct ssp_dev corgi_ssp_dev;
static struct ssp_state corgi_ssp_state;
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index a10268618f7..e3587efec4b 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 4664bd11adc..0077937a7ab 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -29,7 +29,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-
+#include <asm/arch/fb.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -103,6 +103,15 @@ struct platform_device s3c_device_lcd = {
EXPORT_SYMBOL(s3c_device_lcd);
+static struct s3c2410fb_mach_info s3c2410fb_info;
+
+void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info)
+{
+ memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info));
+ s3c_device_lcd.dev.platform_data = &s3c2410fb_info;
+}
+EXPORT_SYMBOL(set_s3c2410fb_info);
+
/* NAND Controller */
static struct resource s3c_nand_resource[] = {
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index e9182242da9..1a3367da640 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[] = {
static struct platform_device bast_sio = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = &bast_sio_data,
},
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index ea4fb1a97a5..6ff1889fbd2 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -45,6 +45,9 @@
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/fb.h>
#include <linux/serial_core.h>
@@ -88,6 +91,48 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] = {
+/**
+ * Set lcd on or off
+ **/
+static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
+ .fixed_syncs= 1,
+ .regs={
+ .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
+ S3C2410_LCDCON1_TFT | \
+ S3C2410_LCDCON1_CLKVAL(0x0C),
+
+ .lcdcon2= S3C2410_LCDCON2_VBPD(7) | \
+ S3C2410_LCDCON2_LINEVAL(319) | \
+ S3C2410_LCDCON2_VFPD(6) | \
+ S3C2410_LCDCON2_VSPW(0),
+
+ .lcdcon3= S3C2410_LCDCON3_HBPD(19) | \
+ S3C2410_LCDCON3_HOZVAL(239) | \
+ S3C2410_LCDCON3_HFPD(7),
+
+ .lcdcon4= S3C2410_LCDCON4_MVAL(0) | \
+ S3C2410_LCDCON4_HSPW(3),
+
+ .lcdcon5= S3C2410_LCDCON5_FRM565 | \
+ S3C2410_LCDCON5_INVVLINE | \
+ S3C2410_LCDCON5_HWSWP,
+ },
+ .lpcsel= 0x02,
+ .gpccon= 0xaa940659,
+ .gpccon_mask= 0xffffffff,
+ .gpcup= 0x0000ffff,
+ .gpcup_mask= 0xffffffff,
+ .gpdcon= 0xaa84aaa0,
+ .gpdcon_mask= 0xffffffff,
+ .gpdup= 0x0000faff,
+ .gpdup_mask= 0xffffffff,
+
+ .width= 240,
+ .height= 320,
+ .xres= {240,240,240},
+ .yres= {320,320,320},
+ .bpp= {16,16,16},
+};
static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_usb,
@@ -116,6 +161,11 @@ void __init h1940_init_irq(void)
}
+void __init h1940_init(void)
+{
+ set_s3c2410fb_info(&h1940_lcdcfg);
+}
+
MACHINE_START(H1940, "IPAQ-H1940")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_ram = S3C2410_SDRAM_PA,
@@ -124,5 +174,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = h1940_map_io,
.init_irq = h1940_init_irq,
+ .init_machine = h1940_init,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 924e8464c21..8f9ab2893df 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index e737eae4521..946c0d11c73 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[] = {
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 191788fb18d..b0208c99257 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -16,6 +16,58 @@
#include <asm/tlbflush.h>
#ifdef CONFIG_CPU_CACHE_VIPT
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+ if (cache_is_vivt()) {
+ if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
+ __cpuc_flush_user_all();
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ asm( "mcr p15, 0, %0, c7, c14, 0\n"
+ " mcr p15, 0, %0, c7, c5, 0\n"
+ " mcr p15, 0, %0, c7, c10, 4"
+ :
+ : "r" (0)
+ : "cc");
+ }
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ if (cache_is_vivt()) {
+ if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask))
+ __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
+ vma->vm_flags);
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ asm( "mcr p15, 0, %0, c7, c14, 0\n"
+ " mcr p15, 0, %0, c7, c5, 0\n"
+ " mcr p15, 0, %0, c7, c10, 4"
+ :
+ : "r" (0)
+ : "cc");
+ }
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+{
+ if (cache_is_vivt()) {
+ if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
+ unsigned long addr = user_addr & PAGE_MASK;
+ __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
+ }
+ return;
+ }
+
+ if (cache_is_vipt_aliasing())
+ flush_pfn_alias(pfn, user_addr);
+}
+
#define ALIAS_FLUSH_START 0xffff4000
#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 0587477c99f..92f66947014 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -97,6 +97,7 @@
#define PARAM_VESAPM_OFF 0x30
#define PARAM_LFB_PAGES 0x32
#define PARAM_VESA_ATTRIB 0x34
+#define PARAM_CAPABILITIES 0x36
/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
#ifdef CONFIG_VIDEO_RETAIN
@@ -233,6 +234,10 @@ mopar_gr:
movw 18(%di), %ax
movl %eax, %fs:(PARAM_LFB_SIZE)
+# store mode capabilities
+ movl 10(%di), %eax
+ movl %eax, %fs:(PARAM_CAPABILITIES)
+
# switching the DAC to 8-bit is for <= 8 bpp only
movw %fs:(PARAM_LFB_DEPTH), %ax
cmpw $8, %ax
@@ -1944,7 +1949,7 @@ store_edid:
movw $0x4f15, %ax # do VBE/DDC
movw $0x01, %bx
movw $0x00, %cx
- movw $0x01, %dx
+ movw $0x00, %dx
movw $0x140, %di
int $0x10
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index bf02b5026e6..8ef38544453 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)
}
if (vrmrev==0) {
- dprintk ("VRM 8.5 \n");
+ dprintk ("VRM 8.5\n");
memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
} else {
- dprintk ("Mobile VRM \n");
+ dprintk ("Mobile VRM\n");
memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 327a55d4d1c..c397b622043 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)
if (model->op_points == NULL) {
/* Matched a non-match */
- dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
+ dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n",
cpu->x86_model_id);
#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
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)
for (i=0; i<p.state_count; i++) {
if (p.states[i].control != p.states[i].status) {
- dprintk("Different control (%x) and status values (%x)\n",
+ dprintk("Different control (%llu) and status values (%llu)\n",
p.states[i].control, p.states[i].status);
result = -EINVAL;
goto err_unreg;
@@ -415,7 +415,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
}
if (p.states[i].core_frequency > p.states[0].core_frequency) {
- dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
+ dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i,
p.states[i].core_frequency, p.states[0].core_frequency);
p.states[i].core_frequency = 0;
continue;
@@ -498,13 +498,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;
- for (i = 0; i < N_IDS; i++)
- if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
- break;
-
- if (i != N_IDS)
- centrino_cpu[policy->cpu] = &cpu_ids[i];
-
if (is_const_loops_cpu(policy->cpu)) {
centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
}
@@ -513,6 +506,13 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -ENODEV;
+ for (i = 0; i < N_IDS; i++)
+ if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
+ break;
+
+ if (i != N_IDS)
+ centrino_cpu[policy->cpu] = &cpu_ids[i];
+
if (!centrino_cpu[policy->cpu]) {
dprintk(KERN_INFO PFX "found unsupported CPU with "
"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 b25fb6b635a..2718fb6f6ab 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)
u32 function = GET_SPEEDSTEP_FREQS;
if (!(ist_info.event & 0xFFFF)) {
- dprintk("bug #1422 -- can't read freqs from BIOS\n", result);
+ dprintk("bug #1422 -- can't read freqs from BIOS\n");
return -ENODEV;
}
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 889eda2d7b1..1efdc76ae96 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1634,9 +1634,9 @@ void disable_IO_APIC(void)
clear_IO_APIC();
/*
- * If the i82559 is routed through an IOAPIC
+ * If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
- * so legacy interrups can be delivered.
+ * so legacy interrupts can be delivered.
*/
pin = find_isa_irq_pin(0, mp_ExtINT);
if (pin != -1) {
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index cafaeffe381..15949fd0810 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)
static void __init MP_processor_info (struct mpc_config_processor *m)
{
- int ver, apicid, cpu, found_bsp = 0;
- physid_mask_t tmp;
+ int ver, apicid;
+ physid_mask_t phys_cpu;
if (!(m->mpc_cpuflag & CPU_ENABLED))
return;
@@ -181,7 +181,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
Dprintk(" Bootup CPU\n");
boot_cpu_physical_apicid = m->mpc_apicid;
- found_bsp = 1;
}
if (num_processors >= NR_CPUS) {
@@ -195,29 +194,26 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
" Processor ignored.\n", maxcpus);
return;
}
- num_processors++;
ver = m->mpc_apicver;
if (!MP_valid_apicid(apicid, ver)) {
printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS);
- --num_processors;
return;
}
- if (found_bsp)
- cpu = 0;
- else
- cpu = num_processors - 1;
- cpu_set(cpu, cpu_possible_map);
- tmp = apicid_to_cpu_present(apicid);
- physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
-
+ cpu_set(num_processors, cpu_possible_map);
+ num_processors++;
+ phys_cpu = apicid_to_cpu_present(apicid);
+ physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
+
/*
* Validate version
*/
if (ver == 0x0) {
- printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
+ printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! "
+ "fixing up to 0x10. (tell your hw vendor)\n",
+ m->mpc_apicid);
ver = 0x10;
}
apic_version[m->mpc_apicid] = ver;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 340980203b0..7b6368bf897 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)
__attribute__((regparm(3)))
int do_syscall_trace(struct pt_regs *regs, int entryexit)
{
- int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0;
- /* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
- * interception. */
+ int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
+ /*
+ * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
+ * interception
+ */
int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
+ int ret = 0;
/* do the secure computing check first */
- secure_computing(regs->orig_eax);
+ if (!entryexit)
+ secure_computing(regs->orig_eax);
if (unlikely(current->audit_context)) {
if (entryexit)
- audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
+ regs->eax);
/* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
* on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
* 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)
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
/* Note that the debugger could change the result of test_thread_flag!*/
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
/*
* 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)
current->exit_code = 0;
}
ret = is_sysemu;
- out:
+out:
if (unlikely(current->audit_context) && !entryexit)
audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
regs->ebx, regs->ecx, regs->edx, regs->esi);
@@ -759,6 +764,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
regs->orig_eax = -1; /* force skip of syscall restarting */
if (unlikely(current->audit_context))
- audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
+ audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
+ regs->eax);
return 1;
}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index a659d274914..f3d808451d2 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -139,6 +139,7 @@ struct sys_desc_table_struct {
unsigned char table[0];
};
struct edid_info edid_info;
+EXPORT_SYMBOL_GPL(edid_info);
struct ist_info ist_info;
#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
@@ -1299,7 +1300,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
*/
static void __init register_memory(void)
{
- unsigned long gapstart, gapsize;
+ unsigned long gapstart, gapsize, round;
unsigned long long last;
int i;
@@ -1344,14 +1345,14 @@ static void __init register_memory(void)
}
/*
- * Start allocating dynamic PCI memory a bit into the gap,
- * aligned up to the nearest megabyte.
- *
- * Question: should we try to pad it up a bit (do something
- * like " + (gapsize >> 3)" in there too?). We now have the
- * technology.
+ * See how much we want to round up: start off with
+ * rounding to the next 1MB area.
*/
- pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+ round = 0x100000;
+ while ((gapsize >> 4) > round)
+ round += round;
+ /* Fun with two's complement */
+ pci_mem_start = (gapstart + round) & -round;
printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
pci_mem_start, gapstart, gapsize);
diff --git a/arch/i386/kernel/sigframe.h b/arch/i386/kernel/sigframe.h
index d21b14f5c25..0b2221711da 100644
--- a/arch/i386/kernel/sigframe.h
+++ b/arch/i386/kernel/sigframe.h
@@ -1,6 +1,6 @@
struct sigframe
{
- char *pretcode;
+ char __user *pretcode;
int sig;
struct sigcontext sc;
struct _fpstate fpstate;
@@ -10,10 +10,10 @@ struct sigframe
struct rt_sigframe
{
- char *pretcode;
+ char __user *pretcode;
int sig;
- struct siginfo *pinfo;
- void *puc;
+ struct siginfo __user *pinfo;
+ void __user *puc;
struct siginfo info;
struct ucontext uc;
struct _fpstate fpstate;
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index eefea7c5500..2883a4d4f01 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -329,8 +329,7 @@ EXPORT_SYMBOL(get_cmos_time);
static void sync_cmos_clock(unsigned long dummy);
-static struct timer_list sync_cmos_timer =
- TIMER_INITIALIZER(sync_cmos_clock, 0, 0);
+static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
static void sync_cmos_clock(unsigned long dummy)
{
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index 3cc480998a4..6d6338500c3 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,
/* Write-combine setting is ignored, it is changed via the mtrr
* interfaces on this platform.
*/
- if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
+ if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
return -EAGAIN;
return 0;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 00151a8320d..ed25d66c8d5 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -339,12 +339,6 @@ config IA64_PALINFO
To use this option, you have to ensure that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
-config ACPI_DEALLOCATE_IRQ
- bool
- depends on ACPI
- depends on IOSAPIC && EXPERIMENTAL
- default y
-
source "drivers/firmware/Kconfig"
source "fs/Kconfig.binfmt"
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 1ca6e6e11b4..08112ab3846 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -111,7 +111,6 @@ CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 3ec94a12eac..d452e18ac49 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index d4cf73d124b..80b0e9eb7fb 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -109,7 +109,6 @@ CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index b6ec8d32c34..5da208115ea 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -99,7 +99,6 @@ CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
@@ -335,7 +334,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLOGIC_1280_1040 is not set
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 318787c84ac..28a4529fdd6 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)
EXPORT_SYMBOL(acpi_register_gsi);
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void acpi_unregister_gsi(u32 gsi)
{
iosapic_unregister_intr(gsi);
}
EXPORT_SYMBOL(acpi_unregister_gsi);
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size)
{
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 6d70fec82d0..ba0b6a1f429 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -204,9 +204,6 @@ GLOBAL_ENTRY(ia64_switch_to)
(p6) br.cond.dpnt .map
;;
.done:
-(p6) ssm psr.ic // if we had to map, reenable the psr.ic bit FIRST!!!
- ;;
-(p6) srlz.d
ld8 sp=[r21] // load kernel stack pointer of new task
mov IA64_KR(CURRENT)=in0 // update "current" application register
mov r8=r13 // return pointer to previously running task
@@ -234,6 +231,9 @@ GLOBAL_ENTRY(ia64_switch_to)
mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped...
;;
itr.d dtr[r25]=r23 // wire in new mapping...
+ ssm psr.ic // reenable the psr.ic bit
+ ;;
+ srlz.d
br.cond.sptk .done
END(ia64_switch_to)
@@ -470,6 +470,29 @@ ENTRY(load_switch_stack)
br.cond.sptk.many b7
END(load_switch_stack)
+GLOBAL_ENTRY(prefetch_stack)
+ add r14 = -IA64_SWITCH_STACK_SIZE, sp
+ add r15 = IA64_TASK_THREAD_KSP_OFFSET, in0
+ ;;
+ ld8 r16 = [r15] // load next's stack pointer
+ lfetch.fault.excl [r14], 128
+ ;;
+ lfetch.fault.excl [r14], 128
+ lfetch.fault [r16], 128
+ ;;
+ lfetch.fault.excl [r14], 128
+ lfetch.fault [r16], 128
+ ;;
+ lfetch.fault.excl [r14], 128
+ lfetch.fault [r16], 128
+ ;;
+ lfetch.fault.excl [r14], 128
+ lfetch.fault [r16], 128
+ ;;
+ lfetch.fault [r16], 128
+ br.ret.sptk.many rp
+END(prefetch_switch_stack)
+
GLOBAL_ENTRY(execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index a13df592ebf..574084f343f 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -782,7 +782,6 @@ again:
return vector;
}
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void
iosapic_unregister_intr (unsigned int gsi)
{
@@ -865,7 +864,6 @@ iosapic_unregister_intr (unsigned int gsi)
spin_unlock(&iosapic_lock);
spin_unlock_irqrestore(&idesc->lock, flags);
}
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
/*
* 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 f1201ac8a11..1650353e3f7 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -38,6 +38,7 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/bitops.h>
+#include <linux/rcupdate.h>
#include <asm/errno.h>
#include <asm/intrinsics.h>
@@ -496,7 +497,7 @@ typedef struct {
static pfm_stats_t pfm_stats[NR_CPUS];
static pfm_session_t pfm_sessions; /* global sessions information */
-static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pfm_alt_install_check);
static pfm_intr_handler_desc_t *pfm_alt_intr_handler;
static struct proc_dir_entry *perfmon_dir;
@@ -2217,15 +2218,17 @@ static void
pfm_free_fd(int fd, struct file *file)
{
struct files_struct *files = current->files;
+ struct fdtable *fdt = files_fdtable(files);
/*
* there ie no fd_uninstall(), so we do it here
*/
spin_lock(&files->file_lock);
- files->fd[fd] = NULL;
+ rcu_assign_pointer(fdt->fd[fd], NULL);
spin_unlock(&files->file_lock);
- if (file) put_filp(file);
+ if (file)
+ put_filp(file);
put_unused_fd(fd);
}
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
index 6f308e62c13..46c9331e7ab 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); \
clrrrb
;;
alloc saved_pfs_stack=ar.pfs,3,3,3,0
+ cmp.lt p8,p0=A,r0
sub B = dst0, saved_in0 // how many byte copied so far
;;
+(p8) mov A = 0; // A shouldn't be negative, cap it
+ ;;
sub C = A, B
sub D = saved_in2, A
;;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 24614869e86..3c32af910d6 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
return;
}
- if (ia64_done_with_exception(regs))
- return;
-
/*
* Since we have no vma's for region 5, we might get here even if the address is
* 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
if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
return;
+ if (ia64_done_with_exception(regs))
+ return;
+
/*
* Oops. The kernel tried to access some bad page. We'll have to terminate things
* with extreme prejudice.
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 9977c122e9f..9b5de589b82 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)
return acpi_pci_irq_enable(dev);
}
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
void
pcibios_disable_device (struct pci_dev *dev)
{
acpi_pci_irq_disable(dev);
}
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
void
pcibios_align_resource (void *data, struct resource *res,
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a594aca959e..14908ad7db8 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -56,7 +56,7 @@
DEFINE_PER_CPU(struct pda_s, pda_percpu);
-#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */
+#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */
lboard_t *root_lboard[MAX_COMPACT_NODES];
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index bb1d5cf3044..ed7c21586e9 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -885,6 +885,10 @@ xpc_init(void)
pid_t pid;
+ if (!ia64_platform_is("sn2")) {
+ return -ENODEV;
+ }
+
/*
* xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
* 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 78c13d676fa..e5c6d3c0a8e 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -130,7 +130,7 @@ struct net_device *xpnet_device;
*/
static u64 xpnet_broadcast_partitions;
/* protect above */
-static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xpnet_broadcast_lock);
/*
* Since the Block Transfer Engine (BTE) is being used for the transfer
@@ -636,6 +636,10 @@ xpnet_init(void)
int result = -ENOMEM;
+ if (!ia64_platform_is("sn2")) {
+ return -ENODEV;
+ }
+
dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
/*
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index cb5d9363046..bd5d134e9f1 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -63,7 +63,7 @@ void __init amiga_init_sound(void)
}
static void nosound( unsigned long ignored );
-static struct timer_list sound_timer = TIMER_INITIALIZER(nosound, 0, 0);
+static DEFINE_TIMER(sound_timer, nosound, 0, 0);
void amiga_mksound( unsigned int hz, unsigned int ticks )
{
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 44c5cd2ad6a..8f0640847ad 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 );
/*
* our timer to start/continue/stop the bell
*/
-static struct timer_list mac_sound_timer =
- TIMER_INITIALIZER(mac_nosound, 0, 0);
+static DEFINE_TIMER(mac_sound_timer, mac_nosound, 0, 0);
/*
* 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 00000000000..c1578b01616
--- /dev/null
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the m68knommu linux kernel.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this, which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs. You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 5cb28690f89..cf36e7d007b 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -104,11 +104,11 @@ int mcf_timerirqpending(int timer)
void config_BSP(char *commandp, int size)
{
-#if 0
- volatile unsigned long *pivrp;
+#if defined (CONFIG_MOD5272)
+ volatile unsigned char *pivrp;
/* Set base of device vectors to be 64 */
- pivrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PIVR);
+ pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR);
*pivrp = 0x40;
#endif
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 84b6b70641e..6fe5a2b8fb0 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -19,6 +19,7 @@ endif
obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
obj-$(CONFIG_M5206) += timers.o
obj-$(CONFIG_M5206e) += timers.o
+obj-$(CONFIG_M523x) += pit.o
obj-$(CONFIG_M5249) += timers.o
obj-$(CONFIG_M527x) += pit.o
obj-$(CONFIG_M5272) += timers.o
diff --git a/arch/m68knommu/platform/68328/config.c b/arch/m68knommu/platform/68328/config.c
index fd7c93f8648..bcfa5d7fe1e 100644
--- a/arch/m68knommu/platform/68328/config.c
+++ b/arch/m68knommu/platform/68328/config.c
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
/*
- * linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ * linux/arch/m68knommu/platform/68328/config.c
*
* Copyright (C) 1993 Hamish Macdonald
* Copyright (C) 1999 D. Jeff Dionne
@@ -11,6 +13,8 @@
* VZ Support/Fixes Evan Stawnyczy <e@lineo.ca>
*/
+/***************************************************************************/
+
#include <asm/dbg.h>
#include <stdarg.h>
#include <linux/config.h>
@@ -29,76 +33,16 @@
#include <asm/machdep.h>
#include <asm/MC68328.h>
+/***************************************************************************/
-void BSP_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
-{
-
-#ifdef CONFIG_XCOPILOT_BUGS
- /*
- * The only thing I know is that CLK32 is not available on Xcopilot
- * I have little idea about what frequency SYSCLK has on Xcopilot.
- * The values for prescaler and compare registers were simply
- * taken from the original source
- */
-
- /* Restart mode, Enable int, SYSCLK, Enable timer */
- TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN;
- /* Set prescaler */
- TPRER2 = 2;
- /* Set compare register */
- TCMP2 = 0xd7e4;
-#else
- /* Restart mode, Enable int, 32KHz, Enable timer */
- TCTL2 = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
- /* Set prescaler (Divide 32KHz by 32)*/
- TPRER2 = 31;
- /* Set compare register 32Khz / 32 / 10 = 100 */
- TCMP2 = 10;
-#endif
-
- request_irq(TMR2_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
- /* Reset Timer2 */
- TSTAT2 &= 0;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
-unsigned long BSP_gettimeoffset (void)
-{
- return 0;
-}
+/***************************************************************************/
-void BSP_gettod (int *yearp, int *monp, int *dayp,
- int *hourp, int *minp, int *secp)
-{
-}
-
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
- if (!op) {
- /* read */
- } else {
- /* write */
- }
- return 0;
-}
-
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
- short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-
- tod->second1 = real_seconds / 10;
- tod->second2 = real_seconds % 10;
- tod->minute1 = real_minutes / 10;
- tod->minute2 = real_minutes % 10;
-#endif
- return 0;
-}
-
-void BSP_reset (void)
+void m68328_reset (void)
{
local_irq_disable();
asm volatile ("moveal #0x10c00000, %a0;\n\t"
@@ -108,18 +52,22 @@ void BSP_reset (void)
"jmp (%a0);");
}
+/***************************************************************************/
+
void config_BSP(char *command, int len)
{
printk(KERN_INFO "\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
- mach_sched_init = BSP_sched_init;
- mach_tick = BSP_tick;
- mach_gettimeoffset = BSP_gettimeoffset;
- mach_gettod = BSP_gettod;
+ mach_sched_init = m68328_timer_init;
+ mach_tick = m68328_timer_tick;
+ mach_gettimeoffset = m68328_timer_gettimeoffset;
+ mach_gettod = m68328_timer_gettod;
mach_hwclk = NULL;
mach_set_clock_mmss = NULL;
- mach_reset = BSP_reset;
+ mach_reset = m68328_reset;
*command = '\0';
}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c
new file mode 100644
index 00000000000..68c2cd6b003
--- /dev/null
+++ b/arch/m68knommu/platform/68328/timers.c
@@ -0,0 +1,106 @@
+/***************************************************************************/
+
+/*
+ * linux/arch/m68knommu/platform/68328/timers.c
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ * Copyright (C) 1999 D. Jeff Dionne
+ * Copyright (C) 2001 Georges Menie, Ken Desmet
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/MC68VZ328.h>
+
+/***************************************************************************/
+
+#if defined(CONFIG_DRAGEN2)
+/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
+#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE 7
+#define TICKS_PER_JIFFY 41450
+
+#elif defined(CONFIG_XCOPILOT_BUGS)
+/*
+ * The only thing I know is that CLK32 is not available on Xcopilot
+ * I have little idea about what frequency SYSCLK has on Xcopilot.
+ * The values for prescaler and compare registers were simply
+ * taken from the original source
+ */
+#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
+#define CLOCK_PRE 2
+#define TICKS_PER_JIFFY 0xd7e4
+
+#else
+/* default to using the 32Khz clock */
+#define CLOCK_SOURCE TCTL_CLKSOURCE_32KHZ
+#define CLOCK_PRE 31
+#define TICKS_PER_JIFFY 10
+#endif
+
+/***************************************************************************/
+
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
+{
+ /* disable timer 1 */
+ TCTL = 0;
+
+ /* set ISR */
+ if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL))
+ panic("Unable to attach timer interrupt\n");
+
+ /* Restart mode, Enable int, Set clock source */
+ TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
+ TPRER = CLOCK_PRE;
+ TCMP = TICKS_PER_JIFFY;
+
+ /* Enable timer 1 */
+ TCTL |= TCTL_TEN;
+}
+
+/***************************************************************************/
+
+void m68328_timer_tick(void)
+{
+ /* Reset Timer1 */
+ TSTAT &= 0;
+}
+/***************************************************************************/
+
+unsigned long m68328_timer_gettimeoffset(void)
+{
+ unsigned long ticks = TCN, offset = 0;
+
+ /* check for pending interrupt */
+ if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
+ offset = 1000000 / HZ;
+ ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
+ return ticks + offset;
+}
+
+/***************************************************************************/
+
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+ long now = RTCTIME;
+
+ *year = *mon = *day = 1;
+ *hour = (now >> 24) % 24;
+ *min = (now >> 16) % 60;
+ *sec = now % 60;
+}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c
index c21971971ff..d8d56e5de31 100644
--- a/arch/m68knommu/platform/68EZ328/config.c
+++ b/arch/m68knommu/platform/68EZ328/config.c
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
/*
- * linux/arch/$(ARCH)/platform/$(PLATFORM)/config.c
+ * linux/arch/m68knommu/platform/68EZ328/config.c
*
* Copyright (C) 1993 Hamish Macdonald
* Copyright (C) 1999 D. Jeff Dionne
@@ -9,6 +11,8 @@
* for more details.
*/
+/***************************************************************************/
+
#include <stdarg.h>
#include <linux/config.h>
#include <linux/types.h>
@@ -20,68 +24,22 @@
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/pgtable.h>
-#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/MC68EZ328.h>
#ifdef CONFIG_UCSIMM
#include <asm/bootstd.h>
#endif
-#ifdef CONFIG_PILOT
-#include "PalmV/romfs.h"
-#endif
-
-void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
-{
- /* Restart mode, Enable int, 32KHz, Enable timer */
- TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
- /* Set prescaler (Divide 32KHz by 32)*/
- TPRER = 31;
- /* Set compare register 32Khz / 32 / 10 = 100 */
- TCMP = 10;
-
- request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
- /* Reset Timer1 */
- TSTAT &= 0;
-}
-
-unsigned long BSP_gettimeoffset (void)
-{
- return 0;
-}
-void BSP_gettod (int *yearp, int *monp, int *dayp,
- int *hourp, int *minp, int *secp)
-{
-}
+/***************************************************************************/
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
- if (!op) {
- /* read */
- } else {
- /* write */
- }
- return 0;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
- short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+/***************************************************************************/
- tod->second1 = real_seconds / 10;
- tod->second2 = real_seconds % 10;
- tod->minute1 = real_minutes / 10;
- tod->minute2 = real_minutes % 10;
-#endif
- return 0;
-}
-
-void BSP_reset (void)
+void m68ez328_reset(void)
{
local_irq_disable();
asm volatile ("
@@ -93,6 +51,8 @@ void BSP_reset (void)
");
}
+/***************************************************************************/
+
unsigned char *cs8900a_hwaddr;
static int errno;
@@ -119,11 +79,13 @@ void config_BSP(char *command, int len)
else command[0] = 0;
#endif
- mach_sched_init = BSP_sched_init;
- mach_tick = BSP_tick;
- mach_gettimeoffset = BSP_gettimeoffset;
- mach_gettod = BSP_gettod;
+ mach_sched_init = m68328_timer_init;
+ mach_tick = m68328_timer_tick;
+ mach_gettimeoffset = m68328_timer_gettimeoffset;
+ mach_gettod = m68328_timer_gettod;
mach_hwclk = NULL;
mach_set_clock_mmss = NULL;
- mach_reset = BSP_reset;
+ mach_reset = m68ez328_reset;
}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68VZ328/de2/config.c b/arch/m68knommu/platform/68VZ328/config.c
index d0586197f11..d926524cdf8 100644
--- a/arch/m68knommu/platform/68VZ328/de2/config.c
+++ b/arch/m68knommu/platform/68VZ328/config.c
@@ -1,5 +1,7 @@
+/***************************************************************************/
+
/*
- * linux/arch/m68knommu/platform/MC68VZ328/de2/config.c
+ * linux/arch/m68knommu/platform/68VZ328/config.c
*
* Copyright (C) 1993 Hamish Macdonald
* Copyright (C) 1999 D. Jeff Dionne
@@ -10,6 +12,8 @@
* for more details.
*/
+/***************************************************************************/
+
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -25,66 +29,25 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/MC68VZ328.h>
+#include <asm/bootstd.h>
#ifdef CONFIG_INIT_LCD
-#include "screen.h"
+#include "bootlogo.h"
#endif
-/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
-#define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
-#define CLOCK_PRE 7
-#define TICKS_PER_JIFFY 41450
-
-static void
-dragen2_sched_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *))
-{
- /* disable timer 1 */
- TCTL = 0;
-
- /* set ISR */
- if (request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL))
- panic("Unable to attach timer interrupt\n");
-
- /* Restart mode, Enable int, Set clock source */
- TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE;
- TPRER = CLOCK_PRE;
- TCMP = TICKS_PER_JIFFY;
-
- /* Enable timer 1 */
- TCTL |= TCTL_TEN;
-}
-
-static void dragen2_tick(void)
-{
- /* Reset Timer1 */
- TSTAT &= 0;
-}
-
-static unsigned long dragen2_gettimeoffset(void)
-{
- unsigned long ticks = TCN, offset = 0;
-
- /* check for pending interrupt */
- if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
- offset = 1000000 / HZ;
-
- ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
+/***************************************************************************/
- return ticks + offset;
-}
+void m68328_timer_init(irqreturn_t (*timer_routine) (int, void *, struct pt_regs *));
+void m68328_timer_tick(void);
+unsigned long m68328_timer_gettimeoffset(void);
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
-static void dragen2_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
- long now = RTCTIME;
+/***************************************************************************/
+/* Init Drangon Engine hardware */
+/***************************************************************************/
+#if defined(CONFIG_DRAGEN2)
- *year = *mon = *day = 1;
- *hour = (now >> 24) % 24;
- *min = (now >> 16) % 60;
- *sec = now % 60;
-}
-
-static void dragen2_reset(void)
+static void m68vz328_reset(void)
{
local_irq_disable();
@@ -103,7 +66,7 @@ static void dragen2_reset(void)
);
}
-static void init_hardware(void)
+static void init_hardware(char *command, int size)
{
#ifdef CONFIG_DIRECT_IO_ACCESS
SCR = 0x10; /* allow user access to internal registers */
@@ -170,6 +133,60 @@ static void init_hardware(void)
#endif
}
+/***************************************************************************/
+/* Init RT-Control uCdimm hardware */
+/***************************************************************************/
+#elif defined(CONFIG_UCDIMM)
+
+static void m68vz328_reset(void)
+{
+ local_irq_disable();
+ asm volatile ("
+ moveal #0x10c00000, %a0;
+ moveb #0, 0xFFFFF300;
+ moveal 0(%a0), %sp;
+ moveal 4(%a0), %a0;
+ jmp (%a0);
+ ");
+}
+
+unsigned char *cs8900a_hwaddr;
+static int errno;
+
+_bsc0(char *, getserialnum)
+_bsc1(unsigned char *, gethwaddr, int, a)
+_bsc1(char *, getbenv, char *, a)
+
+static void init_hardware(char *command, int size)
+{
+ char *p;
+
+ printk(KERN_INFO "uCdimm serial string [%s]\n", getserialnum());
+ p = cs8900a_hwaddr = gethwaddr(0);
+ printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ p = getbenv("APPEND");
+ if (p)
+ strcpy(p, command);
+ else
+ command[0] = 0;
+}
+
+/***************************************************************************/
+#else
+
+static void m68vz328_reset(void)
+{
+}
+
+static void init_hardware(char *command, int size)
+{
+}
+
+/***************************************************************************/
+#endif
+/***************************************************************************/
+
void config_BSP(char *command, int size)
{
printk(KERN_INFO "68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
@@ -181,11 +198,13 @@ void config_BSP(char *command, int size)
memset(command, 0, size);
#endif
- init_hardware();
+ init_hardware(command, size);
- mach_sched_init = (void *)dragen2_sched_init;
- mach_tick = dragen2_tick;
- mach_gettimeoffset = dragen2_gettimeoffset;
- mach_reset = dragen2_reset;
- mach_gettod = dragen2_gettod;
+ mach_sched_init = (void *) m68328_timer_init;
+ mach_tick = m68328_timer_tick;
+ mach_gettimeoffset = m68328_timer_gettimeoffset;
+ mach_gettod = m68328_timer_gettod;
+ mach_reset = m68vz328_reset;
}
+
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/68VZ328/ucdimm/config.c b/arch/m68knommu/platform/68VZ328/ucdimm/config.c
deleted file mode 100644
index 2deadaffd81..00000000000
--- a/arch/m68knommu/platform/68VZ328/ucdimm/config.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * linux/arch/m68knommu/platform/68VZ328/ucdimm/config.c
- *
- * Copyright (C) 1993 Hamish Macdonald
- * Copyright (C) 1999 D. Jeff Dionne
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include <stdarg.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-
-#include <asm/setup.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/machdep.h>
-#include <asm/MC68VZ328.h>
-#include <asm/bootstd.h>
-
-void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
-{
- /* Restart mode, Enable int, 32KHz, Enable timer */
- TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN;
- /* Set prescaler (Divide 32KHz by 32)*/
- TPRER = 31;
- /* Set compare register 32Khz / 32 / 10 = 100 */
- TCMP = 10;
-
- request_irq(TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
-}
-
-void BSP_tick(void)
-{
- /* Reset Timer1 */
- TSTAT &= 0;
-}
-
-unsigned long BSP_gettimeoffset (void)
-{
- return 0;
-}
-
-void BSP_gettod (int *yearp, int *monp, int *dayp,
- int *hourp, int *minp, int *secp)
-{
-}
-
-int BSP_hwclk(int op, struct hwclk_time *t)
-{
- if (!op) {
- /* read */
- } else {
- /* write */
- }
- return 0;
-}
-
-int BSP_set_clock_mmss (unsigned long nowtime)
-{
-#if 0
- short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-
- tod->second1 = real_seconds / 10;
- tod->second2 = real_seconds % 10;
- tod->minute1 = real_minutes / 10;
- tod->minute2 = real_minutes % 10;
-#endif
- return 0;
-}
-
-void BSP_reset (void)
-{
- local_irq_disable();
- asm volatile ("
- moveal #0x10c00000, %a0;
- moveb #0, 0xFFFFF300;
- moveal 0(%a0), %sp;
- moveal 4(%a0), %a0;
- jmp (%a0);
- ");
-}
-
-unsigned char *cs8900a_hwaddr;
-static int errno;
-
-_bsc0(char *, getserialnum)
-_bsc1(unsigned char *, gethwaddr, int, a)
-_bsc1(char *, getbenv, char *, a)
-
-void config_BSP(char *command, int len)
-{
- unsigned char *p;
-
- printk(KERN_INFO "\n68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
-
- printk(KERN_INFO "uCdimm serial string [%s]\n",getserialnum());
- p = cs8900a_hwaddr = gethwaddr(0);
- printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
- p[0], p[1], p[2], p[3], p[4], p[5]);
- p = getbenv("APPEND");
- if (p) strcpy(p,command);
- else command[0] = 0;
-
- mach_sched_init = BSP_sched_init;
- mach_tick = BSP_tick;
- mach_gettimeoffset = BSP_gettimeoffset;
- mach_gettod = BSP_gettod;
- mach_reset = BSP_reset;
-}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8d76eb1ff29..0eb71ac303a 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -154,6 +154,13 @@ config TANBAC_TB0226
The TANBAC Mbase(TB0226) is a MIPS-based platform manufactured by TANBAC.
Please refer to <http://www.tanbac.co.jp/> about Mbase.
+config TANBAC_TB0287
+ bool "Support for TANBAC Mini-ITX DIMM base(TB0287)"
+ depends on TANBAC_TB022X
+ help
+ The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
+
config VICTOR_MPC30X
bool "Support for Victor MP-C303/304"
depends on MACH_VR41XX
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
new file mode 100644
index 00000000000..17b9f2f65ba
--- /dev/null
+++ b/arch/mips/configs/tb0287_defconfig
@@ -0,0 +1,1041 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.13-mm1
+# Thu Sep 1 22:58:34 2005
+#
+CONFIG_MIPS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB022X=y
+# CONFIG_TANBAC_TB0226 is not set
+CONFIG_TANBAC_TB0287=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_IEEE1394_OUI_DB is not set
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+
+#
+# Texas Instruments PCILynx requires I2C
+#
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=y
+# CONFIG_R8169_NAPI is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_KGDBOE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_RTC_VR41XX is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_TANBAC_TB0219 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_GOTEMP is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISER4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+
+#
+# XFS support
+#
+CONFIG_XFS_FS=y
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+# CONFIG_XFS_SECURITY is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ASFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ISA_DMA_API=y
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
index 288bf51ad4e..71416e7bbba 100644
--- a/arch/mips/kernel/genrtc.c
+++ b/arch/mips/kernel/genrtc.c
@@ -14,7 +14,7 @@
#include <asm/rtc.h>
#include <asm/time.h>
-static spinlock_t mips_rtc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mips_rtc_lock);
unsigned int get_rtc_time(struct rtc_time *time)
{
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 7eec7568bfe..447759201d1 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -31,7 +31,7 @@ void disable_8259A_irq(unsigned int irq);
* moves to arch independent land
*/
-spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t DEFINE_SPINLOCK(i8259A_lock);
static void end_8259A_irq (unsigned int irq)
{
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index 4cd3d38a22c..3cdc22346f4 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -14,6 +14,7 @@
#include <linux/syscalls.h>
#include <linux/tty.h>
#include <linux/file.h>
+#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/ioctl.h>
@@ -33,7 +34,7 @@ static struct tty_struct *get_tty(int fd)
struct file *filp;
struct tty_struct *ttyp = NULL;
- spin_lock(&current->files->file_lock);
+ rcu_read_lock();
filp = fcheck(fd);
if(filp && filp->private_data) {
ttyp = (struct tty_struct *) filp->private_data;
@@ -41,7 +42,7 @@ static struct tty_struct *get_tty(int fd)
if(ttyp->magic != TTY_MAGIC)
ttyp =NULL;
}
- spin_unlock(&current->files->file_lock);
+ rcu_read_unlock();
return ttyp;
}
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c53e4cb359b..83d81c9cdc2 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
obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
+obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o
obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
obj-$(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 00000000000..8436d7f1fdb
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0287.c
@@ -0,0 +1,65 @@
+/*
+ * fixup-tb0287.c, The TANBAC TB0287 specific PCI fixups.
+ *
+ * Copyright (C) 2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/tb0287.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char bus;
+ int irq = -1;
+
+ bus = dev->bus->number;
+ if (bus == 0) {
+ switch (slot) {
+ case 16:
+ irq = TB0287_SM501_IRQ;
+ break;
+ case 17:
+ irq = TB0287_SIL680A_IRQ;
+ break;
+ default:
+ break;
+ }
+ } else if (bus == 1) {
+ switch (PCI_SLOT(dev->devfn)) {
+ case 0:
+ irq = TB0287_PCI_SLOT_IRQ;
+ break;
+ case 2:
+ case 3:
+ irq = TB0287_RTL8110_IRQ;
+ break;
+ default:
+ break;
+ }
+ } else if (bus > 1) {
+ irq = TB0287_PCI_SLOT_IRQ;
+ }
+
+ return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
index 89fe0ceeaa4..2ca9ec7ec3a 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)
spin_unlock_irqrestore(&cs4218_lock, flags);
}
-static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0);
+static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
};
static void cs_mksound(unsigned int hz, unsigned int ticks)
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 6ab7e5ea5fc..e3f1ce33e64 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -499,11 +499,6 @@ config WINCEPT
MPC821 PowerPC, introduced in 1998 and designed to be used in
thin-client machines. Say Y to support it directly.
- Be aware that PCI buses can only function when SYS board is plugged
- into the PIB (Platform IO Board) board from Freescale which provide
- 3 PCI slots. The PIBs PCI initialization is the bootloader's
- responsiblilty.
-
endchoice
choice
@@ -680,6 +675,11 @@ config MPC834x_SYS
help
This option enables support for the MPC 834x SYS evaluation board.
+ Be aware that PCI buses can only function when SYS board is plugged
+ into the PIB (Platform IO Board) board from Freescale which provide
+ 3 PCI slots. The PIBs PCI initialization is the bootloader's
+ responsiblilty.
+
config EV64360
bool "Marvell-EV64360BP"
help
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c
index 9017c547a6f..26818bbb6cf 100644
--- a/arch/ppc/boot/common/ns16550.c
+++ b/arch/ppc/boot/common/ns16550.c
@@ -23,7 +23,7 @@ static int shift;
unsigned long serial_init(int chan, void *ignored)
{
- unsigned long com_port;
+ unsigned long com_port, base_baud;
unsigned char lcr, dlm;
/* 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)
/* How far apart the registers are. */
shift = rs_table[chan].iomem_reg_shift;
+ /* Base baud.. */
+ base_baud = rs_table[chan].baud_base;
/* save the LCR */
lcr = inb(com_port + (UART_LCR << shift));
@@ -62,9 +64,9 @@ unsigned long serial_init(int chan, void *ignored)
else {
/* Input clock. */
outb(com_port + (UART_DLL << shift),
- (BASE_BAUD / SERIAL_BAUD) & 0xFF);
+ (base_baud / SERIAL_BAUD) & 0xFF);
outb(com_port + (UART_DLM << shift),
- (BASE_BAUD / SERIAL_BAUD) >> 8);
+ (base_baud / SERIAL_BAUD) >> 8);
/* 8 data, 1 stop, no parity */
outb(com_port + (UART_LCR << shift), 0x03);
/* RTS/DTR */
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
index 47e641455bc..c96c9f80521 100644
--- a/arch/ppc/boot/common/util.S
+++ b/arch/ppc/boot/common/util.S
@@ -252,7 +252,7 @@ _GLOBAL(flush_instruction_cache)
1: dcbf r0,r3 # Flush the data cache
icbi r0,r3 # Invalidate the instruction cache
addi r3,r3,0x10 # Increment by one cache line
- cmplwi cr0,r3,r4 # Are we at the end yet?
+ cmplw cr0,r3,r4 # Are we at the end yet?
blt 1b # No, keep flushing and invalidating
#else
/* Enable, invalidate and then disable the L1 icache/dcache. */
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index b1457a8a9c0..1fb92f16acd 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -15,8 +15,9 @@ extra-y += vmlinux.lds
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
process.o signal.o ptrace.o align.o \
semaphore.o syscalls.o setup.o \
- cputable.o ppc_htab.o perfmon.o
+ cputable.o ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
+obj-$(CONFIG_E500) += perfmon.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_POWER4) += cpu_setup_power4.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 7b3586a3bf3..854e45beb38 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -80,7 +80,6 @@ fixup_broken_pcnet32(struct pci_dev* dev)
if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
dev->vendor = PCI_VENDOR_ID_AMD;
pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
- pci_name_device(dev);
}
}
DECLARE_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 124313ce3c0..127f040de9d 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -41,10 +41,6 @@
#include <asm/ipc.h>
#include <asm/semaphore.h>
-void
-check_bugs(void)
-{
-}
/*
* 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 d87423d1003..8356d544fa6 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -849,10 +849,12 @@ void AltivecAssistException(struct pt_regs *regs)
}
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_E500
void PerformanceMonitorException(struct pt_regs *regs)
{
perf_irq(regs);
}
+#endif
#ifdef CONFIG_FSL_BOOKE
void 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 0fd3442f513..d6b2b1965dc 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -91,15 +91,10 @@ ebony_calibrate_decr(void)
* on Rev. C silicon then errata forces us to
* use the internal clock.
*/
- switch (PVR_REV(mfspr(SPRN_PVR))) {
- case PVR_REV(PVR_440GP_RB):
- freq = EBONY_440GP_RB_SYSCLK;
- break;
- case PVR_REV(PVR_440GP_RC1):
- default:
- freq = EBONY_440GP_RC_SYSCLK;
- break;
- }
+ if (strcmp(cur_cpu_spec[0]->cpu_name, "440GP Rev. B") == 0)
+ freq = EBONY_440GP_RB_SYSCLK;
+ else
+ freq = EBONY_440GP_RC_SYSCLK;
ibm44x_calibrate_decr(freq);
}
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index b659d7b3d74..ff379686012 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -58,7 +58,7 @@ static void parse_bootinfo(unsigned long r3,
static void hdpu_set_l1pe(void);
static void hdpu_cpustate_set(unsigned char new_state);
#ifdef CONFIG_SMP
-static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timebase_lock);
static unsigned int timebase_upper = 0, timebase_lower = 0;
extern int smp_tb_synchronized;
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index d4776af6a3c..0bb919859b8 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)
/* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
enable it on all other revisions
*/
- u32 pvr = mfspr(SPRN_PVR);
- if (pvr == PVR_440GX_RA || pvr == PVR_440GX_RB ||
- (pvr == PVR_440GX_RC && p->cpu > 667000000))
+ if (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. A") == 0 ||
+ strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. B") == 0
+ || (strcmp(cur_cpu_spec[0]->cpu_name, "440GX Rev. C")
+ == 0 && p->cpu > 667000000))
ibm440gx_l2c_disable();
else
ibm440gx_l2c_enable();
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
index 87065e2e4c5..3e039706bdb 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[] = {
},
[MPC10X_UART0] = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = serial_plat_uart0,
},
[MPC10X_UART1] = {
.name = "serial8250",
- .id = 1,
+ .id = PLAT8250_DEV_PLATFORM1,
.dev.platform_data = serial_plat_uart1,
},
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 5aaf0e58e1f..95b3b8a7f0b 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[] = {
},
[MPC83xx_DUART] = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = serial_platform_data,
},
[MPC83xx_SEC2] = {
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 8af322dd476..bbc5ac0de87 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[] = {
},
[MPC85xx_DUART] = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = serial_platform_data,
},
[MPC85xx_PERFMON] = {
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 6262b11f366..839f8872826 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -31,7 +31,7 @@
u8 mv64x60_pci_exclude_bridge = 1;
-spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(mv64x60_lock);
static phys_addr_t mv64x60_bridge_pbase;
static void *mv64x60_bridge_vbase;
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c
index 57f4ed5e5ae..0970b5d3039 100644
--- a/arch/ppc/syslib/qspan_pci.c
+++ b/arch/ppc/syslib/qspan_pci.c
@@ -94,7 +94,7 @@
#define mk_config_type1(bus, dev, offset) \
mk_config_addr(bus, dev, offset) | 1;
-static spinlock_t pcibios_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pcibios_lock);
int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
unsigned char offset, unsigned char *val)
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index d795775a5cd..0a23aeacba8 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -89,11 +89,12 @@ drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/
boot := arch/ppc64/boot
-boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
-boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
-boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
-boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
-$(boottarget-y): vmlinux
+boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd
+boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode
+boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd
+boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm
+boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd
+$(boottargets-y): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
@@ -124,8 +125,10 @@ include3/asm:
$(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
define archhelp
- echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
- echo ' zImage.initrd- Compressed kernel image with initrd attached,'
- echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz'
- echo ' (arch/$(ARCH)/boot/zImage.initrd)'
+ echo ' zImage.vmode - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)'
+ echo ' zImage.initrd.vmode - Compressed kernel image with initrd attached,'
+ echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz'
+ echo ' (arch/$(ARCH)/boot/zImage.initrd.vmode)'
+ echo ' zImage - zImage for pSeries machines'
+ echo ' zImage.initrd - zImage with initrd for pSeries machines'
endef
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 2c5f5e73d00..33fdc871089 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC $@
quiet_cmd_bootas = BOOTAS $@
cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
+quiet_cmd_bootld = BOOTLD $@
+ cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2)
+
$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
$(call if_changed_dep,bootcc)
$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
@@ -53,7 +56,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
hostprogs-y := addnote addRamDisk
-targets += zImage zImage.initrd imagesize.c \
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \
$(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
$(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -63,7 +66,7 @@ extra-y := initrd.o
quiet_cmd_ramdisk = RAMDISK $@
cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@
-quiet_cmd_stripvm = STRIP $@
+quiet_cmd_stripvm = STRIP $@
cmd_stripvm = $(STRIP) -s $< -o $@
vmlinux.strip: vmlinux FORCE
@@ -71,12 +74,20 @@ vmlinux.strip: vmlinux FORCE
$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE
$(call if_changed,ramdisk)
-addsection = $(CROSS32OBJCOPY) $(1) \
- --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \
- --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS)
+quiet_cmd_addsection = ADDSEC $@
+ cmd_addsection = $(CROSS32OBJCOPY) $@ \
+ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
+ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
+
+quiet_cmd_imagesize = GENSIZE $@
+ cmd_imagesize = ls -l vmlinux.strip | \
+ awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
+ > $(obj)/imagesize.c && \
+ $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
+ awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
-quiet_cmd_addnote = ADDNOTE $@
- cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@
+quiet_cmd_addnote = ADDNOTE $@
+ cmd_addnote = $(obj)/addnote $@
$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
$(call if_changed,gzip)
@@ -85,28 +96,30 @@ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
cp -f $(obj)/ramdisk.image.gz $@
$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE
- touch $@
+ @touch $@
$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE
$(call if_changed_dep,bootcc)
- $(call addsection, $@)
+ $(call cmd,addsection)
+
+$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
+$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE
+ $(call cmd,bootld,$(obj-boot))
+
+$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
+$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE
+ $(call cmd,bootld,$(obj-boot))
-$(obj)/zImage: obj-boot += $(call obj-sec, $(required))
-$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE
+ @cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd))
-$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE
+ @cp -f $< $@
$(call if_changed,addnote)
$(obj)/imagesize.c: vmlinux.strip
- @echo Generating $@
- ls -l vmlinux.strip | \
- awk '{printf "/* generated -- do not edit! */\n" \
- "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c
- $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
- awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \
- >> $(obj)/imagesize.c
+ $(call cmd,imagesize)
install: $(CONFIGURE) $(BOOTIMAGE)
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 99e68cfbe68..f7ec19a2d0b 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long);
/* Value picked to match that used by yaboot */
#define PROG_START 0x01400000
-#define RAM_END (256<<20) // Fixme: use OF */
+#define RAM_END (512<<20) // Fixme: use OF */
+#define ONE_MB 0x100000
static char *avail_ram;
static char *begin_avail, *end_avail;
@@ -32,6 +33,7 @@ static unsigned int heap_use;
static unsigned int heap_max;
extern char _start[];
+extern char _end[];
extern char _vmlinux_start[];
extern char _vmlinux_end[];
extern char _initrd_start[];
@@ -58,13 +60,13 @@ typedef void (*kernel_entry_t)( unsigned long,
#undef DEBUG
-static unsigned long claim_base = PROG_START;
+static unsigned long claim_base;
static unsigned long try_claim(unsigned long size)
{
unsigned long addr = 0;
- for(; claim_base < RAM_END; claim_base += 0x100000) {
+ for(; claim_base < RAM_END; claim_base += ONE_MB) {
#ifdef DEBUG
printf(" trying: 0x%08lx\n\r", claim_base);
#endif
@@ -95,7 +97,26 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
- printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start);
+ printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start);
+
+ /*
+ * The first available claim_base must be above the end of the
+ * the loaded kernel wrapper file (_start to _end includes the
+ * initrd image if it is present) and rounded up to a nice
+ * 1 MB boundary for good measure.
+ */
+
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+
+#if defined(PROG_START)
+ /*
+ * Maintain a "magic" minimum address. This keeps some older
+ * firmware platforms running.
+ */
+
+ if (claim_base < PROG_START)
+ claim_base = PROG_START;
+#endif
/*
* 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)
* size... In practice we add 1Mb, that is enough, but we should really
* consider fixing the Makefile to put a _raw_ kernel in there !
*/
- vmlinux_memsize += 0x100000;
+ vmlinux_memsize += ONE_MB;
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize);
vmlinux.addr = try_claim(vmlinux_memsize);
if (vmlinux.addr == 0) {
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
index c8f3dc3fad7..0aaa878e19d 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)
}
#ifdef CONFIG_SMP
+
+/* Use the highest interrupt priorities for IPI */
+static inline int iic_ipi_to_irq(int ipi)
+{
+ return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi;
+}
+
+static inline int iic_irq_to_ipi(int irq)
+{
+ return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET);
+}
+
void iic_setup_cpu(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)
void iic_cause_IPI(int cpu, int mesg)
{
- out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
+ out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
}
static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
-
- smp_message_recv(irq - IIC_IPI_OFFSET, regs);
+ smp_message_recv(iic_irq_to_ipi(irq), regs);
return IRQ_HANDLED;
}
-static void iic_request_ipi(int irq, const char *name)
+static void iic_request_ipi(int ipi, const char *name)
{
+ int irq;
+
+ irq = iic_ipi_to_irq(ipi);
/* IPIs are marked SA_INTERRUPT as they must run with irqs
* disabled */
get_irq_desc(irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, const char *name)
void iic_request_IPIs(void)
{
- iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
- iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
+ iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
+ iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
#ifdef CONFIG_DEBUGGER
- iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
+ iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
#endif /* CONFIG_DEBUGGER */
}
#endif /* CONFIG_SMP */
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
index af5272fedad..ba93fd73122 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)
while (n) {
struct pci_io_addr_range *piar;
piar = rb_entry(n, struct pci_io_addr_range, rb_node);
- printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s %s\n",
+ printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
- piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev),
- pci_pretty_name(piar->pcidev));
+ piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
cnt++;
n = rb_next(n);
}
@@ -255,22 +254,24 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
static void __pci_addr_cache_insert_device(struct pci_dev *dev)
{
struct device_node *dn;
+ struct pci_dn *pdn;
int i;
int inserted = 0;
dn = pci_device_to_OF_node(dev);
if (!dn) {
- printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n",
- pci_name(dev), pci_pretty_name(dev));
+ printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n",
+ pci_name(dev));
return;
}
/* Skip any devices for which EEH is not enabled. */
- if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
- dn->eeh_mode & EEH_MODE_NOCHECK) {
+ pdn = dn->data;
+ if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+ pdn->eeh_mode & EEH_MODE_NOCHECK) {
#ifdef DEBUG
- printk(KERN_INFO "PCI: skip building address cache for=%s %s\n",
- pci_name(dev), pci_pretty_name(dev));
+ printk(KERN_INFO "PCI: skip building address cache for=%s\n",
+ pci_name(dev));
#endif
return;
}
@@ -416,6 +417,7 @@ int eeh_unregister_notifier(struct notifier_block *nb)
static int read_slot_reset_state(struct device_node *dn, int rets[])
{
int token, outputs;
+ struct pci_dn *pdn = dn->data;
if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
token = ibm_read_slot_reset_state2;
@@ -425,8 +427,8 @@ static int read_slot_reset_state(struct device_node *dn, int rets[])
outputs = 3;
}
- return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr,
- BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+ return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
+ BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
}
/**
@@ -447,12 +449,12 @@ static void eeh_panic(struct pci_dev *dev, int reset_state)
* in light of potential corruption, we can use it here.
*/
if (panic_on_oops)
- panic("EEH: MMIO failure (%d) on device:%s %s\n", reset_state,
- pci_name(dev), pci_pretty_name(dev));
+ panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
+ pci_name(dev));
else {
__get_cpu_var(ignored_failures)++;
- printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s %s\n",
- reset_state, pci_name(dev), pci_pretty_name(dev));
+ printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
+ reset_state, pci_name(dev));
}
}
@@ -482,8 +484,8 @@ static void eeh_event_handler(void *dummy)
break;
printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device "
- "%s %s\n", event->reset_state,
- pci_name(event->dev), pci_pretty_name(event->dev));
+ "%s\n", event->reset_state,
+ pci_name(event->dev));
atomic_set(&eeh_fail_count, 0);
notifier_call_chain (&eeh_notifier_chain,
@@ -535,6 +537,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
unsigned long flags;
int rc, reset_state;
struct eeh_event *event;
+ struct pci_dn *pdn;
__get_cpu_var(total_mmio_ffs)++;
@@ -543,14 +546,15 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
if (!dn)
return 0;
+ pdn = dn->data;
/* Access to IO BARs might get this far and still not want checking. */
- if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) ||
- dn->eeh_mode & EEH_MODE_NOCHECK) {
+ if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+ pdn->eeh_mode & EEH_MODE_NOCHECK) {
return 0;
}
- if (!dn->eeh_config_addr) {
+ if (!pdn->eeh_config_addr) {
return 0;
}
@@ -558,7 +562,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* If we already have a pending isolation event for this
* slot, we know it's bad already, we don't need to check...
*/
- if (dn->eeh_mode & EEH_MODE_ISOLATED) {
+ if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
atomic_inc(&eeh_fail_count);
if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) {
/* re-read the slot reset state */
@@ -583,7 +587,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
}
/* prevent repeated reports of this failure */
- dn->eeh_mode |= EEH_MODE_ISOLATED;
+ pdn->eeh_mode |= EEH_MODE_ISOLATED;
reset_state = rets[0];
@@ -591,9 +595,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
memset(slot_errbuf, 0, eeh_error_buf_size);
rc = rtas_call(ibm_slot_error_detail,
- 8, 1, NULL, dn->eeh_config_addr,
- BUID_HI(dn->phb->buid),
- BUID_LO(dn->phb->buid), NULL, 0,
+ 8, 1, NULL, pdn->eeh_config_addr,
+ BUID_HI(pdn->phb->buid),
+ BUID_LO(pdn->phb->buid), NULL, 0,
virt_to_phys(slot_errbuf),
eeh_error_buf_size,
1 /* Temporary Error */);
@@ -680,8 +684,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
u32 *device_id = (u32 *)get_property(dn, "device-id", NULL);
u32 *regs;
int enable;
+ struct pci_dn *pdn = dn->data;
- dn->eeh_mode = 0;
+ pdn->eeh_mode = 0;
if (status && strcmp(status, "ok") != 0)
return NULL; /* ignore devices with bad status */
@@ -692,7 +697,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
/* There is nothing to check on PCI to ISA bridges */
if (dn->type && !strcmp(dn->type, "isa")) {
- dn->eeh_mode |= EEH_MODE_NOCHECK;
+ pdn->eeh_mode |= EEH_MODE_NOCHECK;
return NULL;
}
@@ -709,7 +714,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
enable = 0;
if (!enable)
- dn->eeh_mode |= EEH_MODE_NOCHECK;
+ pdn->eeh_mode |= EEH_MODE_NOCHECK;
/* Ok... see if this device supports EEH. Some do, some don't,
* 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)
EEH_ENABLE);
if (ret == 0) {
eeh_subsystem_enabled = 1;
- dn->eeh_mode |= EEH_MODE_SUPPORTED;
- dn->eeh_config_addr = regs[0];
+ pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+ pdn->eeh_config_addr = regs[0];
#ifdef DEBUG
printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
#endif
@@ -731,10 +736,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
/* This device doesn't support EEH, but it may have an
* EEH parent, in which case we mark it as supported. */
- if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
+ if (dn->parent && dn->parent->data
+ && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
/* Parent supports EEH. */
- dn->eeh_mode |= EEH_MODE_SUPPORTED;
- dn->eeh_config_addr = dn->parent->eeh_config_addr;
+ pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+ pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr;
return NULL;
}
}
@@ -791,11 +797,13 @@ void __init eeh_init(void)
for (phb = of_find_node_by_name(NULL, "pci"); phb;
phb = of_find_node_by_name(phb, "pci")) {
unsigned long buid;
+ struct pci_dn *pci;
buid = get_phb_buid(phb);
- if (buid == 0)
+ if (buid == 0 || phb->data == NULL)
continue;
+ pci = phb->data;
info.buid_lo = BUID_LO(buid);
info.buid_hi = BUID_HI(buid);
traverse_pci_devices(phb, early_enable_eeh, &info);
@@ -824,9 +832,9 @@ void eeh_add_device_early(struct device_node *dn)
struct pci_controller *phb;
struct eeh_early_enable_info info;
- if (!dn)
+ if (!dn || !dn->data)
return;
- phb = dn->phb;
+ phb = PCI_DN(dn)->phb;
if (NULL == phb || 0 == phb->buid) {
printk(KERN_WARNING "EEH: Expected buid but found none\n");
return;
@@ -851,8 +859,7 @@ void eeh_add_device_late(struct pci_dev *dev)
return;
#ifdef DEBUG
- printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev),
- pci_pretty_name(dev));
+ printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
#endif
pci_addr_cache_insert_device (dev);
@@ -873,8 +880,7 @@ void eeh_remove_device(struct pci_dev *dev)
/* Unregister the device with the EEH/PCI address search system */
#ifdef DEBUG
- printk(KERN_DEBUG "EEH: remove device %s %s\n", pci_name(dev),
- pci_pretty_name(dev));
+ printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
#endif
pci_addr_cache_remove_device(dev);
}
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
index d11c732daf8..5d921792571 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)
printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ",
count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
frame, card);
- if (pci_class_name(PciDev->class >> 8) == 0)
- printk("0x%04X\n", (int)(PciDev->class >> 8));
- else
- printk("%s\n", pci_class_name(PciDev->class >> 8));
+ printk("0x%04X\n", (int)(PciDev->class >> 8));
}
diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c
index 153cc8b0f13..6160c8dbb7c 100644
--- a/arch/ppc64/kernel/iomap.c
+++ b/arch/ppc64/kernel/iomap.c
@@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr)
{
return readw(addr);
}
+unsigned int fastcall ioread16be(void __iomem *addr)
+{
+ return in_be16(addr);
+}
unsigned int fastcall ioread32(void __iomem *addr)
{
return readl(addr);
}
+unsigned int fastcall ioread32be(void __iomem *addr)
+{
+ return in_be32(addr);
+}
EXPORT_SYMBOL(ioread8);
EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread16be);
EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread32be);
void fastcall iowrite8(u8 val, void __iomem *addr)
{
@@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr)
{
writew(val, addr);
}
+void fastcall iowrite16be(u16 val, void __iomem *addr)
+{
+ out_be16(addr, val);
+}
void fastcall iowrite32(u32 val, void __iomem *addr)
{
writel(val, addr);
}
+void fastcall iowrite32be(u32 val, void __iomem *addr)
+{
+ out_be32(addr, val);
+}
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite16be);
EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite32be);
/*
* These are the "repeat read/write" functions. Note the
@@ -56,15 +76,15 @@ EXPORT_SYMBOL(iowrite32);
*/
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
{
- _insb((u8 __force *) addr, dst, count);
+ _insb((u8 __iomem *) addr, dst, count);
}
void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
{
- _insw_ns((u16 __force *) addr, dst, count);
+ _insw_ns((u16 __iomem *) addr, dst, count);
}
void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
{
- _insl_ns((u32 __force *) addr, dst, count);
+ _insl_ns((u32 __iomem *) addr, dst, count);
}
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
@@ -72,15 +92,15 @@ EXPORT_SYMBOL(ioread32_rep);
void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
{
- _outsb((u8 __force *) addr, src, count);
+ _outsb((u8 __iomem *) addr, src, count);
}
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
{
- _outsw_ns((u16 __force *) addr, src, count);
+ _outsw_ns((u16 __iomem *) addr, src, count);
}
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
{
- _outsl_ns((u32 __force *) addr, src, count);
+ _outsl_ns((u32 __iomem *) addr, src, count);
}
EXPORT_SYMBOL(iowrite8_rep);
EXPORT_SYMBOL(iowrite16_rep);
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 845eebd1e28..9032b6bfe03 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)
void iommu_free_table(struct device_node *dn)
{
- struct iommu_table *tbl = dn->iommu_table;
+ struct pci_dn *pdn = dn->data;
+ struct iommu_table *tbl = pdn->iommu_table;
unsigned long bitmap_sz, i;
unsigned int order;
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
index 53993999b26..5a8b4d8c2dd 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)
*/
if (u3_agp) {
struct device_node *np = u3_agp->arch_data;
- np->busno = 0xf0;
+ PCI_DN(np)->busno = 0xf0;
for (np = np->child; np; np = np->sibling)
- np->busno = 0xf0;
+ PCI_DN(np)->busno = 0xf0;
}
/* 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 757903544e2..e7241ad80a0 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -1431,9 +1431,9 @@ _GLOBAL(sys_call_table)
.llong .sys_ni_syscall /* 195 - 32bit only stat64 */
.llong .sys_ni_syscall /* 32bit only lstat64 */
.llong .sys_ni_syscall /* 32bit only fstat64 */
- .llong .sys_ni_syscall /* 32bit only pciconfig_read */
- .llong .sys_ni_syscall /* 32bit only pciconfig_write */
- .llong .sys_ni_syscall /* 32bit only pciconfig_iobase */
+ .llong .sys_pciconfig_read
+ .llong .sys_pciconfig_write
+ .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */
.llong .sys_ni_syscall /* reserved for MacOnLinux */
.llong .sys_getdents64
.llong .sys_pivot_root
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 9d5e1e7fc38..f0fd7fbd653 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,
struct iommu_table *tbl,
unsigned int *dma_window)
{
- tbl->it_busno = dn->bussubno;
+ tbl->it_busno = PCI_DN(dn)->bussubno;
/* TODO: Parse field size properties properly. */
tbl->it_size = (((unsigned long)dma_window[4] << 32) |
@@ -311,6 +311,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
static void iommu_bus_setup_pSeries(struct pci_bus *bus)
{
struct device_node *dn, *pdn;
+ struct pci_dn *pci;
struct iommu_table *tbl;
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)
*/
dn = pci_bus_to_OF_node(bus);
+ pci = dn->data;
if (!bus->self) {
/* Root bus */
@@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
* alltogether. This leaves 768MB for the window.
*/
DBG("PHB has io-hole, reserving 256MB\n");
- dn->phb->dma_window_size = 3 << 28;
- dn->phb->dma_window_base_cur = 1 << 28;
+ pci->phb->dma_window_size = 3 << 28;
+ pci->phb->dma_window_base_cur = 1 << 28;
} else {
/* 1GB window by default */
- dn->phb->dma_window_size = 1 << 30;
- dn->phb->dma_window_base_cur = 0;
+ pci->phb->dma_window_size = 1 << 30;
+ pci->phb->dma_window_base_cur = 0;
}
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_setparms(dn->phb, dn, tbl);
- dn->iommu_table = iommu_init_table(tbl);
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
} else {
/* Do a 128MB table at root. This is used for the IDE
* controller on some SMP-mode POWER4 machines. It
@@ -363,16 +365,16 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
* Allocate at offset 128MB to avoid having to deal
* with ISA holes; 128MB table for IDE is plenty.
*/
- dn->phb->dma_window_size = 1 << 27;
- dn->phb->dma_window_base_cur = 1 << 27;
+ pci->phb->dma_window_size = 1 << 27;
+ pci->phb->dma_window_base_cur = 1 << 27;
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_setparms(dn->phb, dn, tbl);
- dn->iommu_table = iommu_init_table(tbl);
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
/* All child buses have 256MB tables */
- dn->phb->dma_window_size = 1 << 28;
+ pci->phb->dma_window_size = 1 << 28;
}
} else {
pdn = pci_bus_to_OF_node(bus->parent);
@@ -386,12 +388,12 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_setparms(dn->phb, dn, tbl);
+ iommu_table_setparms(pci->phb, dn, tbl);
- dn->iommu_table = iommu_init_table(tbl);
+ pci->iommu_table = iommu_init_table(tbl);
} else {
/* Lower than first child or under python, use parent table */
- dn->iommu_table = pdn->iommu_table;
+ pci->iommu_table = PCI_DN(pdn)->iommu_table;
}
}
}
@@ -401,6 +403,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
{
struct iommu_table *tbl;
struct device_node *dn, *pdn;
+ struct pci_dn *ppci;
unsigned int *dma_window = NULL;
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)
return;
}
- if (!pdn->iommu_table) {
+ ppci = pdn->data;
+ if (!ppci->iommu_table) {
/* Bussubno hasn't been copied yet.
* Do it now because iommu_table_setparms_lpar needs it.
*/
- pdn->bussubno = bus->number;
+
+ ppci->bussubno = bus->number;
tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
GFP_KERNEL);
- iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window);
+ iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
- pdn->iommu_table = iommu_init_table(tbl);
+ ppci->iommu_table = iommu_init_table(tbl);
}
if (pdn != dn)
- dn->iommu_table = pdn->iommu_table;
+ PCI_DN(dn)->iommu_table = ppci->iommu_table;
}
@@ -449,11 +454,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
*/
mydn = dn = pci_device_to_OF_node(dev);
- while (dn && dn->iommu_table == NULL)
+ while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
dn = dn->parent;
- if (dn) {
- mydn->iommu_table = dn->iommu_table;
+ if (dn && dn->data) {
+ PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
} else {
DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);
}
@@ -463,10 +468,11 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
{
int err = NOTIFY_OK;
struct device_node *np = node;
+ struct pci_dn *pci = np->data;
switch (action) {
case PSERIES_RECONFIG_REMOVE:
- if (np->iommu_table &&
+ if (pci->iommu_table &&
get_property(np, "ibm,dma-window", NULL))
iommu_free_table(np);
break;
@@ -486,6 +492,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
struct device_node *pdn, *dn;
struct iommu_table *tbl;
int *dma_window = NULL;
+ struct pci_dn *pci;
DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);
@@ -497,8 +504,10 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
*/
dn = pci_device_to_OF_node(dev);
- for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) {
- dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+ for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table;
+ pdn = pdn->parent) {
+ dma_window = (unsigned int *)
+ get_property(pdn, "ibm,dma-window", NULL);
if (dma_window)
break;
}
@@ -515,20 +524,21 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
DBG("Found DMA window, allocating table\n");
}
- if (!pdn->iommu_table) {
+ pci = pdn->data;
+ if (!pci->iommu_table) {
/* iommu_table_setparms_lpar needs bussubno. */
- pdn->bussubno = pdn->phb->bus->number;
+ pci->bussubno = pci->phb->bus->number;
tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
GFP_KERNEL);
- iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window);
+ iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
- pdn->iommu_table = iommu_init_table(tbl);
+ pci->iommu_table = iommu_init_table(tbl);
}
if (pdn != dn)
- dn->iommu_table = pdn->iommu_table;
+ PCI_DN(dn)->iommu_table = pci->iommu_table;
}
static void iommu_bus_setup_null(struct pci_bus *b) { }
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index d0d55c7908e..8447dcc2c2b 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -21,6 +21,7 @@
#include <linux/bootmem.h>
#include <linux/mm.h>
#include <linux/list.h>
+#include <linux/syscalls.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -84,7 +85,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev)
if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
dev->vendor = PCI_VENDOR_ID_AMD;
pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
- pci_name_device(dev);
}
}
DECLARE_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)
* device tree. If they are then we need to scan all the
* functions of this slot.
*/
- for (dn = busdn->child; dn; dn = dn->sibling)
- if ((dn->devfn >> 3) == (devfn >> 3))
+ for (dn = busdn->child; dn; dn = dn->sibling) {
+ struct pci_dn *pdn = dn->data;
+ if (pdn && (pdn->devfn >> 3) == (devfn >> 3))
return 1;
+ }
return 0;
}
@@ -983,3 +985,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
}
#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+
+#define IOBASE_BRIDGE_NUMBER 0
+#define IOBASE_MEMORY 1
+#define IOBASE_IO 2
+#define IOBASE_ISA_IO 3
+#define IOBASE_ISA_MEM 4
+
+long sys_pciconfig_iobase(long which, unsigned long in_bus,
+ unsigned long in_devfn)
+{
+ struct pci_controller* hose;
+ struct list_head *ln;
+ struct pci_bus *bus = NULL;
+ struct device_node *hose_node;
+
+ /* Argh ! Please forgive me for that hack, but that's the
+ * simplest way to get existing XFree to not lockup on some
+ * G5 machines... So when something asks for bus 0 io base
+ * (bus 0 is HT root), we return the AGP one instead.
+ */
+#ifdef CONFIG_PPC_PMAC
+ if (systemcfg->platform == PLATFORM_POWERMAC &&
+ machine_is_compatible("MacRISC4"))
+ if (in_bus == 0)
+ in_bus = 0xf0;
+#endif /* CONFIG_PPC_PMAC */
+
+ /* That syscall isn't quite compatible with PCI domains, but it's
+ * used on pre-domains setup. We return the first match
+ */
+
+ for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+ bus = pci_bus_b(ln);
+ if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
+ break;
+ bus = NULL;
+ }
+ if (bus == NULL || bus->sysdata == NULL)
+ return -ENODEV;
+
+ hose_node = (struct device_node *)bus->sysdata;
+ hose = PCI_DN(hose_node)->phb;
+
+ switch (which) {
+ case IOBASE_BRIDGE_NUMBER:
+ return (long)hose->first_busno;
+ case IOBASE_MEMORY:
+ return (long)hose->pci_mem_offset;
+ case IOBASE_IO:
+ return (long)hose->io_base_phys;
+ case IOBASE_ISA_IO:
+ return (long)isa_io_base;
+ case IOBASE_ISA_MEM:
+ return -EINVAL;
+ }
+
+ return -EOPNOTSUPP;
+}
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 26be78b13af..5eb2cc32056 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,
void pci_devs_phb_init(void);
void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-struct device_node *fetch_dev_dn(struct pci_dev *dev);
/* PCI address cache management routines */
void 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 ec345462afc..a86389d07d5 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -23,6 +23,8 @@
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -40,16 +42,26 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
struct pci_controller *phb = data;
int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
u32 *regs;
-
- dn->phb = phb;
+ struct pci_dn *pdn;
+
+ if (phb->is_dynamic)
+ pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
+ else
+ pdn = alloc_bootmem(sizeof(*pdn));
+ if (pdn == NULL)
+ return NULL;
+ memset(pdn, 0, sizeof(*pdn));
+ dn->data = pdn;
+ pdn->node = dn;
+ pdn->phb = phb;
regs = (u32 *)get_property(dn, "reg", NULL);
if (regs) {
/* First register entry is addr (00BBSS00) */
- dn->busno = (regs[0] >> 16) & 0xff;
- dn->devfn = (regs[0] >> 8) & 0xff;
+ pdn->busno = (regs[0] >> 16) & 0xff;
+ pdn->devfn = (regs[0] >> 8) & 0xff;
}
- dn->pci_ext_config_space = (type && *type == 1);
+ pdn->pci_ext_config_space = (type && *type == 1);
return NULL;
}
@@ -112,10 +124,15 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
{
struct device_node * dn = (struct device_node *) phb->arch_data;
+ struct pci_dn *pdn;
/* PHB nodes themselves must not match */
- dn->devfn = dn->busno = -1;
- dn->phb = phb;
+ update_dn_pci_info(dn, phb);
+ pdn = dn->data;
+ if (pdn) {
+ pdn->devfn = pdn->busno = -1;
+ pdn->phb = phb;
+ }
/* Update dn->phb ptrs for new phb and children devices */
traverse_pci_devices(dn, update_dn_pci_info, phb);
@@ -123,14 +140,17 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
/*
* Traversal func that looks for a <busno,devfcn> value.
- * If found, the device_node is returned (thus terminating the traversal).
+ * If found, the pci_dn is returned (thus terminating the traversal).
*/
static void *is_devfn_node(struct device_node *dn, void *data)
{
int busno = ((unsigned long)data >> 8) & 0xff;
int devfn = ((unsigned long)data) & 0xff;
+ struct pci_dn *pci = dn->data;
- return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL;
+ if (pci && (devfn == pci->devfn) && (busno == pci->busno))
+ return dn;
+ return NULL;
}
/*
@@ -149,13 +169,10 @@ static void *is_devfn_node(struct device_node *dn, void *data)
struct device_node *fetch_dev_dn(struct pci_dev *dev)
{
struct device_node *orig_dn = dev->sysdata;
- struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */
- struct device_node *phb_dn;
struct device_node *dn;
unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
- phb_dn = phb->arch_data;
- dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval);
+ dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
if (dn)
dev->sysdata = dn;
return dn;
@@ -165,11 +182,13 @@ EXPORT_SYMBOL(fetch_dev_dn);
static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
{
struct device_node *np = node;
+ struct pci_dn *pci;
int err = NOTIFY_OK;
switch (action) {
case PSERIES_RECONFIG_ADD:
- update_dn_pci_info(np, np->parent->phb);
+ pci = np->parent->data;
+ update_dn_pci_info(np, pci->phb);
break;
default:
err = NOTIFY_DONE;
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
index ef0a62b916b..14647e09c9c 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)
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
- return PCI_GET_DN(pdev)->iommu_table;
+ return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
#endif /* CONFIG_PPC_MULTIPLATFORM */
}
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
index 98ed2bccab1..eb4e6c3f694 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)
#if 0 /* Disabled for now */
u32 ufreq, freq, ucfg, cfg;
struct device_node *pcix_node;
+ struct pci_dn *pdn;
u8 px_bus, px_devfn;
struct pci_controller *px_hose;
@@ -687,9 +688,10 @@ void __init pmac_check_ht_link(void)
printk("No PCI-X bridge found\n");
return;
}
- px_hose = pcix_node->phb;
- px_bus = pcix_node->busno;
- px_devfn = pcix_node->devfn;
+ pdn = pcix_node->data;
+ px_hose = pdn->phb;
+ px_bus = pdn->busno;
+ px_devfn = pdn->devfn;
early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
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 71fe911ad18..d37bff2d7d4 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,
else
busdn = hose->arch_data;
for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->devfn == devfn)
+ if (dn->data && PCI_DN(dn)->devfn == devfn)
break;
if (dn == NULL)
return -1;
@@ -746,9 +746,9 @@ void __init pmac_pci_init(void)
*/
if (u3_agp) {
struct device_node *np = u3_agp->arch_data;
- np->busno = 0xf0;
+ PCI_DN(np)->busno = 0xf0;
for (np = np->child; np; np = np->sibling)
- np->busno = 0xf0;
+ PCI_DN(np)->busno = 0xf0;
}
pmac_check_ht_link();
diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c
index cdfec7438d0..63d9481c3ec 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)
mtspr(SPRN_MMCR0, mmcr0);
}
-static spinlock_t pmc_owner_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pmc_owner_lock);
static void *pmc_owner_caller; /* mostly for debugging */
perf_irq_t perf_irq = dummy_perf;
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 6ad5a8467f8..7035deb6de9 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)
kfree(node->intrs);
kfree(node->addrs);
kfree(node->full_name);
+ kfree(node->data);
kfree(node);
}
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
index 1dccadaddd1..4a9719b48ab 100644
--- a/arch/ppc64/kernel/rtas_pci.c
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -48,7 +48,7 @@ static int write_pci_config;
static int ibm_read_pci_config;
static int ibm_write_pci_config;
-static int config_access_valid(struct device_node *dn, int where)
+static int config_access_valid(struct pci_dn *dn, int where)
{
if (where < 256)
return 1;
@@ -78,15 +78,17 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
int returnval = -1;
unsigned long buid, addr;
int ret;
+ struct pci_dn *pdn;
- if (!dn)
+ if (!dn || !dn->data)
return PCIBIOS_DEVICE_NOT_FOUND;
- if (!config_access_valid(dn, where))
+ pdn = dn->data;
+ if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
- (dn->devfn << 8) | (where & 0xff);
- buid = dn->phb->buid;
+ addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+ (pdn->devfn << 8) | (where & 0xff);
+ buid = pdn->phb->buid;
if (buid) {
ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
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
if (ret)
return PCIBIOS_DEVICE_NOT_FOUND;
- if (returnval == EEH_IO_ERROR_VALUE(size)
- && eeh_dn_check_failure (dn, NULL))
+ if (returnval == EEH_IO_ERROR_VALUE(size) &&
+ eeh_dn_check_failure (dn, NULL))
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
@@ -118,24 +120,28 @@ static int rtas_pci_read_config(struct pci_bus *bus,
/* Search only direct children of the bus */
for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->devfn == devfn && of_device_available(dn))
+ if (dn->data && PCI_DN(dn)->devfn == devfn
+ && of_device_available(dn))
return rtas_read_config(dn, where, size, val);
+
return PCIBIOS_DEVICE_NOT_FOUND;
}
-static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
+int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
{
unsigned long buid, addr;
int ret;
+ struct pci_dn *pdn;
- if (!dn)
+ if (!dn || !dn->data)
return PCIBIOS_DEVICE_NOT_FOUND;
- if (!config_access_valid(dn, where))
+ pdn = dn->data;
+ if (!config_access_valid(pdn, where))
return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
- (dn->devfn << 8) | (where & 0xff);
- buid = dn->phb->buid;
+ addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
+ (pdn->devfn << 8) | (where & 0xff);
+ buid = pdn->phb->buid;
if (buid) {
ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
} else {
@@ -161,7 +167,8 @@ static int rtas_pci_write_config(struct pci_bus *bus,
/* Search only direct children of the bus */
for (dn = busdn->child; dn; dn = dn->sibling)
- if (dn->devfn == devfn && of_device_available(dn))
+ if (dn->data && PCI_DN(dn)->devfn == devfn
+ && of_device_available(dn))
return rtas_write_config(dn, where, size, val);
return PCIBIOS_DEVICE_NOT_FOUND;
}
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index d0bb68af0ea..bfa8791c980 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,
static struct platform_device serial_device = {
.name = "serial8250",
- .id = 0,
+ .id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_ports,
},
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 214914a95a5..e93c1345891 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
compat_ptr(ubuf));
}
-#define IOBASE_BRIDGE_NUMBER 0
-#define IOBASE_MEMORY 1
-#define IOBASE_IO 2
-#define IOBASE_ISA_IO 3
-#define IOBASE_ISA_MEM 4
-
asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
{
-#ifdef CONFIG_PCI
- struct pci_controller* hose;
- struct list_head *ln;
- struct pci_bus *bus = NULL;
- struct device_node *hose_node;
-
- /* Argh ! Please forgive me for that hack, but that's the
- * simplest way to get existing XFree to not lockup on some
- * G5 machines... So when something asks for bus 0 io base
- * (bus 0 is HT root), we return the AGP one instead.
- */
-#ifdef CONFIG_PPC_PMAC
- if (systemcfg->platform == PLATFORM_POWERMAC &&
- machine_is_compatible("MacRISC4"))
- if (in_bus == 0)
- in_bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
- /* That syscall isn't quite compatible with PCI domains, but it's
- * used on pre-domains setup. We return the first match
- */
-
- for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
- bus = pci_bus_b(ln);
- if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
- break;
- bus = NULL;
- }
- if (bus == NULL || bus->sysdata == NULL)
- return -ENODEV;
-
- hose_node = (struct device_node *)bus->sysdata;
- hose = hose_node->phb;
-
- switch (which) {
- case IOBASE_BRIDGE_NUMBER:
- return (long)hose->first_busno;
- case IOBASE_MEMORY:
- return (long)hose->pci_mem_offset;
- case IOBASE_IO:
- return (long)hose->io_base_phys;
- case IOBASE_ISA_IO:
- return (long)isa_io_base;
- case IOBASE_ISA_MEM:
- return -EINVAL;
- }
-#endif /* CONFIG_PCI */
- return -EOPNOTSUPP;
+ return sys_pciconfig_iobase(which, in_bus, in_devfn);
}
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c
index a8cbb202b8c..05f16633bd2 100644
--- a/arch/ppc64/kernel/syscalls.c
+++ b/arch/ppc64/kernel/syscalls.c
@@ -46,10 +46,6 @@
extern unsigned long wall_jiffies;
-void
-check_bugs(void)
-{
-}
/*
* 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 b6e3bca4102..41ea09cb9ac 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)
dn = pci_device_to_OF_node(dev);
if (dn)
- dn->iommu_table = &iommu_table_u3;
+ PCI_DN(dn)->iommu_table = &iommu_table_u3;
}
static void iommu_bus_setup_u3(struct pci_bus *bus)
@@ -291,7 +291,7 @@ static void iommu_bus_setup_u3(struct pci_bus *bus)
dn = pci_bus_to_OF_node(bus);
if (dn)
- dn->iommu_table = &iommu_table_u3;
+ PCI_DN(dn)->iommu_table = &iommu_table_u3;
}
static void iommu_dev_setup_null(struct pci_dev *dev) { }
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
index ed6766e21f5..d49c3613c8e 100644
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/ppc64/kernel/udbg.c
@@ -158,14 +158,20 @@ static struct console udbg_console = {
.index = -1,
};
+static int early_console_initialized;
+
void __init disable_early_printk(void)
{
+ if (!early_console_initialized)
+ return;
unregister_console(&udbg_console);
+ early_console_initialized = 0;
}
/* called by setup_system */
void register_early_udbg_console(void)
{
+ early_console_initialized = 1;
register_console(&udbg_console);
}
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a14ab87df49..c2157c9c3ac 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -554,12 +554,12 @@ void __init do_init_bootmem(void)
* present.
*/
for (i=0; i < lmb.memory.cnt; i++)
- free_bootmem(lmb_start_pfn(&lmb.memory, i),
+ free_bootmem(lmb.memory.region[i].base,
lmb_size_bytes(&lmb.memory, i));
/* reserve the sections we're already using */
for (i=0; i < lmb.reserved.cnt; i++)
- reserve_bootmem(lmb_start_pfn(&lmb.reserved, i),
+ reserve_bootmem(lmb.reserved.region[i].base,
lmb_size_bytes(&lmb.reserved, i));
for (i=0; i < lmb.memory.cnt; i++)
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 189c8f3a369..98db30481d9 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -19,6 +19,7 @@ CFLAGS += -m31
AFLAGS += -m31
UTS_MACHINE := s390
STACK_SIZE := 8192
+CHECKFLAGS += -D__s390__
endif
ifdef CONFIG_ARCH_S390X
@@ -28,6 +29,7 @@ CFLAGS += -m64
AFLAGS += -m64
UTS_MACHINE := s390x
STACK_SIZE := 16384
+CHECKFLAGS += -D__s390__ -D__s390x__
endif
cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5)
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 19724c5800a..2e64e8c3e8e 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -20,7 +20,7 @@ spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
#else /* SMP */
-static spinlock_t dummy = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dummy);
#define ATOMIC_HASH_SIZE 1
#define ATOMIC_HASH(a) (&dummy)
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index ec8bf4012c0..2ff7c32ab0c 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)
pbus->resource[1] = &pbm->mem_space;
}
-int pci_claim_resource(struct pci_dev *pdev, int resource)
+struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r)
{
struct pci_pbm_info *pbm = pdev->bus->sysdata;
- struct resource *res = &pdev->resource[resource];
- struct resource *root;
-
- if (!pbm)
- return -EINVAL;
+ struct resource *root = NULL;
- if (res->flags & IORESOURCE_IO)
+ if (r->flags & IORESOURCE_IO)
root = &pbm->io_space;
- else
+ if (r->flags & IORESOURCE_MEM)
root = &pbm->mem_space;
- pbm->parent->resource_adjust(pdev, res, root);
-
- return request_resource(root, res);
-}
-
-/*
- * Given the PCI bus a device resides on, try to
- * find an acceptable resource allocation for a
- * specific device resource..
- */
-static int pci_assign_bus_resource(const struct pci_bus *bus,
- struct pci_dev *dev,
- struct resource *res,
- unsigned long size,
- unsigned long min,
- int resno)
-{
- unsigned int type_mask;
- int i;
-
- type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- for (i = 0 ; i < 4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
-
- /* type_mask must match */
- if ((res->flags ^ r->flags) & type_mask)
- continue;
-
- /* Ok, try it out.. */
- if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
- continue;
-
- /* PCI config space updated by caller. */
- return 0;
- }
- return -EBUSY;
-}
-
-int pci_assign_resource(struct pci_dev *pdev, int resource)
-{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_pbm_info *pbm = pcp->pbm;
- struct resource *res = &pdev->resource[resource];
- unsigned long min, size;
- int err;
-
- if (res->flags & IORESOURCE_IO)
- min = pbm->io_space.start + 0x400UL;
- else
- min = pbm->mem_space.start;
-
- size = res->end - res->start + 1;
-
- err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
-
- if (err < 0) {
- printk("PCI: Failed to allocate resource %d for %s\n",
- resource, pci_name(pdev));
- } else {
- /* Update PCI config space. */
- pbm->parent->base_address_update(pdev, resource);
- }
-
- return err;
-}
-
-/* Sort resources by alignment */
-void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
-{
- int i;
-
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- struct resource *r;
- struct resource_list *list, *tmp;
- unsigned long r_align;
-
- r = &dev->resource[i];
- r_align = r->end - r->start;
-
- if (!(r->flags) || r->parent)
- continue;
- if (!r_align) {
- printk(KERN_WARNING "PCI: Ignore bogus resource %d "
- "[%lx:%lx] of %s\n",
- i, r->start, r->end, pci_name(dev));
- continue;
- }
- r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
- for (list = head; ; list = list->next) {
- unsigned long align = 0;
- struct resource_list *ln = list->next;
- int idx;
-
- if (ln) {
- idx = ln->res - &ln->dev->resource[0];
- align = (idx < PCI_BRIDGE_RESOURCES) ?
- ln->res->end - ln->res->start + 1 :
- ln->res->start;
- }
- if (r_align > align) {
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- if (!tmp)
- panic("pdev_sort_resources(): "
- "kmalloc() failed!\n");
- tmp->next = ln;
- tmp->res = r;
- tmp->dev = dev;
- list->next = tmp;
- break;
- }
- }
- }
+ return root;
}
void 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 91ab466d6c6..6ed1ef25e0a 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[] = {
/*0x32*/15, /* Power Management */
};
-static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -344,9 +344,9 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
return ret;
}
-static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm,
- struct pci_dev *pdev,
- unsigned int ino)
+static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
+ struct pci_dev *pdev,
+ unsigned int ino)
{
struct ino_bucket *bucket;
unsigned long imap, iclr;
@@ -1024,7 +1024,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
#define PSYCHO_CE_INO 0x2f
#define PSYCHO_PCIERR_A_INO 0x30
#define PSYCHO_PCIERR_B_INO 0x31
-static void __init psycho_register_error_handlers(struct pci_controller_info *p)
+static void psycho_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = p->pbm_A.controller_regs;
@@ -1091,15 +1091,15 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
}
/* PSYCHO boot time probing and initialization. */
-static void __init psycho_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void psycho_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
res->start += root->start;
res->end += root->start;
}
-static void __init psycho_base_address_update(struct pci_dev *pdev, int resource)
+static void psycho_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1144,7 +1144,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
@@ -1161,8 +1161,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
pci_config_write8(addr, 64);
}
-static void __init pbm_scan_bus(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
@@ -1189,7 +1189,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
pci_setup_busmastering(pbm, pbm->pci_bus);
}
-static void __init psycho_scan_bus(struct pci_controller_info *p)
+static void psycho_scan_bus(struct pci_controller_info *p)
{
pbm_config_busmastering(&p->pbm_B);
p->pbm_B.is_66mhz_capable = 0;
@@ -1204,7 +1204,7 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
psycho_register_error_handlers(p);
}
-static void __init psycho_iommu_init(struct pci_controller_info *p)
+static void psycho_iommu_init(struct pci_controller_info *p)
{
struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i;
@@ -1327,8 +1327,8 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
char *name = pbm->name;
@@ -1481,7 +1481,7 @@ static void psycho_pbm_init(struct pci_controller_info *p,
#define PSYCHO_CONFIGSPACE 0x001000000UL
-void __init psycho_init(int node, char *model_name)
+void psycho_init(int node, char *model_name)
{
struct linux_prom64_registers pr_regs[3];
struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 52bf3431a42..0ee6bd5b9ac 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[] = {
/*0x32*/15, /* Power Management */
};
-static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -612,9 +612,9 @@ static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_a
sabre_read(sync_reg);
}
-static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
- struct pci_dev *pdev,
- unsigned int ino)
+static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
+ struct pci_dev *pdev,
+ unsigned int ino)
{
struct ino_bucket *bucket;
unsigned long imap, iclr;
@@ -1009,7 +1009,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
#define SABRE_UE_INO 0x2e
#define SABRE_CE_INO 0x2f
#define SABRE_PCIERR_INO 0x30
-static void __init sabre_register_error_handlers(struct pci_controller_info *p)
+static void sabre_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = pbm->controller_regs;
@@ -1056,9 +1056,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
sabre_write(base + SABRE_PCICTRL, tmp);
}
-static void __init sabre_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void sabre_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
struct pci_pbm_info *pbm = pdev->bus->sysdata;
unsigned long base;
@@ -1072,7 +1072,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev,
res->end += base;
}
-static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
+static void sabre_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1118,7 +1118,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
+static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
{
struct pci_dev *pdev;
@@ -1181,7 +1181,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
return cookie;
}
-static void __init sabre_scan_bus(struct pci_controller_info *p)
+static void sabre_scan_bus(struct pci_controller_info *p)
{
static int once;
struct pci_bus *sabre_bus, *pbus;
@@ -1262,9 +1262,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
sabre_register_error_handlers(p);
}
-static void __init sabre_iommu_init(struct pci_controller_info *p,
- int tsbsize, unsigned long dvma_offset,
- u32 dma_mask)
+static void sabre_iommu_init(struct pci_controller_info *p,
+ int tsbsize, unsigned long dvma_offset,
+ u32 dma_mask)
{
struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i, order;
@@ -1345,8 +1345,8 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
}
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
char *name = pbm->name;
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
&pbm->mem_space);
}
-static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
{
struct pci_pbm_info *pbm;
char namebuf[128];
@@ -1552,7 +1552,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node,
}
}
-void __init sabre_init(int pnode, char *model_name)
+void sabre_init(int pnode, char *model_name)
{
struct linux_prom64_registers pr_regs[2];
struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index 6a182bb6628..331382e1a75 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[] = {
/*0x3f*/0, /* Reserved for NewLink */
};
-static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -1221,7 +1221,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
* PCI bus units of the same Tomatillo. I still have not really
* figured this out...
*/
-static void __init tomatillo_register_error_handlers(struct pci_controller_info *p)
+static void tomatillo_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm;
unsigned int irq;
@@ -1359,7 +1359,7 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info
(SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
}
-static void __init schizo_register_error_handlers(struct pci_controller_info *p)
+static void schizo_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm;
unsigned int irq;
@@ -1505,7 +1505,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
(SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
}
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
@@ -1522,8 +1522,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
pci_config_write8(addr, 64);
}
-static void __init pbm_scan_bus(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
@@ -1550,8 +1550,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
pci_setup_busmastering(pbm, pbm->pci_bus);
}
-static void __init __schizo_scan_bus(struct pci_controller_info *p,
- int chip_type)
+static void __schizo_scan_bus(struct pci_controller_info *p,
+ int chip_type)
{
if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {
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,
schizo_register_error_handlers(p);
}
-static void __init schizo_scan_bus(struct pci_controller_info *p)
+static void schizo_scan_bus(struct pci_controller_info *p)
{
__schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);
}
-static void __init tomatillo_scan_bus(struct pci_controller_info *p)
+static void tomatillo_scan_bus(struct pci_controller_info *p)
{
__schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);
}
-static void __init schizo_base_address_update(struct pci_dev *pdev, int resource)
+static void schizo_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1632,9 +1632,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init schizo_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void schizo_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
res->start += root->start;
res->end += root->start;
@@ -1702,8 +1702,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem_space.start);
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
pbm->io_space.name = pbm->mem_space.name = pbm->name;
@@ -1932,7 +1932,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
#define TOMATILLO_PCI_IOC_TDIAG (0x2250UL)
#define TOMATILLO_PCI_IOC_DDIAG (0x2290UL)
-static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
+static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
{
u64 tmp;
@@ -1986,9 +1986,9 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
}
}
-static void __init schizo_pbm_init(struct pci_controller_info *p,
- int prom_node, u32 portid,
- int chip_type)
+static void schizo_pbm_init(struct pci_controller_info *p,
+ int prom_node, u32 portid,
+ int chip_type)
{
struct linux_prom64_registers pr_regs[4];
unsigned int busrange[2];
@@ -2145,7 +2145,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
return (x == y);
}
-static void __init __schizo_init(int node, char *model_name, int chip_type)
+static void __schizo_init(int node, char *model_name, int chip_type)
{
struct pci_controller_info *p;
struct pci_iommu *iommu;
@@ -2213,17 +2213,17 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
schizo_pbm_init(p, node, portid, chip_type);
}
-void __init schizo_init(int node, char *model_name)
+void schizo_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO);
}
-void __init schizo_plus_init(int node, char *model_name)
+void schizo_plus_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
}
-void __init tomatillo_init(int node, char *model_name)
+void tomatillo_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO);
}
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d89fc24808d..7d9a0f6c437 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -403,12 +403,3 @@ EXPORT_SYMBOL(xor_vis_4);
EXPORT_SYMBOL(xor_vis_5);
EXPORT_SYMBOL(prom_palette);
-
-/* memory barriers */
-EXPORT_SYMBOL(mb);
-EXPORT_SYMBOL(rmb);
-EXPORT_SYMBOL(wmb);
-EXPORT_SYMBOL(membar_storeload);
-EXPORT_SYMBOL(membar_storeload_storestore);
-EXPORT_SYMBOL(membar_storeload_loadload);
-EXPORT_SYMBOL(membar_storestore_loadstore);
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index 6201f104098..40dbeec7e5d 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 \
U1memcpy.o U1copy_from_user.o U1copy_to_user.o \
U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
copy_in_user.o user_fixup.o memmove.o \
- mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o mb.o
+ mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
lib-$(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 4004f748619..00000000000
--- a/arch/sparc64/lib/mb.S
+++ /dev/null
@@ -1,73 +0,0 @@
-/* mb.S: Out of line memory barriers.
- *
- * Copyright (C) 2005 David S. Miller (davem@davemloft.net)
- */
-
- /* These are here in an effort to more fully work around
- * Spitfire Errata #51. Essentially, if a memory barrier
- * occurs soon after a mispredicted branch, the chip can stop
- * executing instructions until a trap occurs. Therefore, if
- * interrupts are disabled, the chip can hang forever.
- *
- * It used to be believed that the memory barrier had to be
- * right in the delay slot, but a case has been traced
- * recently wherein the memory barrier was one instruction
- * after the branch delay slot and the chip still hung. The
- * offending sequence was the following in sym_wakeup_done()
- * of the sym53c8xx_2 driver:
- *
- * call sym_ccb_from_dsa, 0
- * movge %icc, 0, %l0
- * brz,pn %o0, .LL1303
- * mov %o0, %l2
- * membar #LoadLoad
- *
- * The branch has to be mispredicted for the bug to occur.
- * Therefore, we put the memory barrier explicitly into a
- * "branch always, predicted taken" delay slot to avoid the
- * problem case.
- */
-
- .text
-
-99: retl
- nop
-
- .globl mb
-mb: ba,pt %xcc, 99b
- membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad
- .size mb, .-mb
-
- .globl rmb
-rmb: ba,pt %xcc, 99b
- membar #LoadLoad
- .size rmb, .-rmb
-
- .globl wmb
-wmb: ba,pt %xcc, 99b
- membar #StoreStore
- .size wmb, .-wmb
-
- .globl membar_storeload
-membar_storeload:
- ba,pt %xcc, 99b
- membar #StoreLoad
- .size membar_storeload, .-membar_storeload
-
- .globl membar_storeload_storestore
-membar_storeload_storestore:
- ba,pt %xcc, 99b
- membar #StoreLoad | #StoreStore
- .size membar_storeload_storestore, .-membar_storeload_storestore
-
- .globl membar_storeload_loadload
-membar_storeload_loadload:
- ba,pt %xcc, 99b
- membar #StoreLoad | #LoadLoad
- .size membar_storeload_loadload, .-membar_storeload_loadload
-
- .globl membar_storestore_loadstore
-membar_storestore_loadstore:
- ba,pt %xcc, 99b
- membar #StoreStore | #LoadStore
- .size membar_storestore_loadstore, .-membar_storestore_loadstore
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
index cac0a1cf005..be0a054e3ed 100644
--- a/arch/sparc64/solaris/ioctl.c
+++ b/arch/sparc64/solaris/ioctl.c
@@ -24,6 +24,7 @@
#include <linux/netdevice.h>
#include <linux/mtio.h>
#include <linux/time.h>
+#include <linux/rcupdate.h>
#include <linux/compat.h>
#include <net/sock.h>
@@ -293,16 +294,18 @@ static struct module_info {
static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
{
struct inode *ino;
+ struct fdtable *fdt;
/* I wonder which of these tests are superfluous... --patrik */
- spin_lock(&current->files->file_lock);
- if (! current->files->fd[fd] ||
- ! current->files->fd[fd]->f_dentry ||
- ! (ino = current->files->fd[fd]->f_dentry->d_inode) ||
+ rcu_read_lock();
+ fdt = files_fdtable(current->files);
+ if (! fdt->fd[fd] ||
+ ! fdt->fd[fd]->f_dentry ||
+ ! (ino = fdt->fd[fd]->f_dentry->d_inode) ||
! S_ISSOCK(ino->i_mode)) {
- spin_unlock(&current->files->file_lock);
+ rcu_read_unlock();
return TBADF;
}
- spin_unlock(&current->files->file_lock);
+ rcu_read_unlock();
switch (cmd & 0xff) {
case 109: /* SI_SOCKPARAMS */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 022c80f4339..aaad29c35c8 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)
static void timod_wake_socket(unsigned int fd)
{
struct socket *sock;
+ struct fdtable *fdt;
SOLD("wakeing socket");
- sock = SOCKET_I(current->files->fd[fd]->f_dentry->d_inode);
+ fdt = files_fdtable(current->files);
+ sock = SOCKET_I(fdt->fd[fd]->f_dentry->d_inode);
wake_up_interruptible(&sock->wait);
read_lock(&sock->sk->sk_callback_lock);
if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
@@ -157,9 +159,11 @@ static void timod_wake_socket(unsigned int fd)
static void timod_queue(unsigned int fd, struct T_primsg *it)
{
struct sol_socket_struct *sock;
+ struct fdtable *fdt;
SOLD("queuing primsg");
- sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
+ fdt = files_fdtable(current->files);
+ sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
it->next = sock->pfirst;
sock->pfirst = it;
if (!sock->plast)
@@ -171,9 +175,11 @@ static void timod_queue(unsigned int fd, struct T_primsg *it)
static void timod_queue_end(unsigned int fd, struct T_primsg *it)
{
struct sol_socket_struct *sock;
+ struct fdtable *fdt;
SOLD("queuing primsg at end");
- sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
+ fdt = files_fdtable(current->files);
+ sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
it->next = NULL;
if (sock->plast)
sock->plast->next = it;
@@ -344,6 +350,7 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
char *buf;
struct file *filp;
struct inode *ino;
+ struct fdtable *fdt;
struct sol_socket_struct *sock;
mm_segment_t old_fs = get_fs();
long args[6];
@@ -351,7 +358,9 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
(int (*)(int, unsigned long __user *))SYS(socketcall);
int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) =
(int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto);
- filp = current->files->fd[fd];
+
+ fdt = files_fdtable(current->files);
+ filp = fdt->fd[fd];
ino = filp->f_dentry->d_inode;
sock = (struct sol_socket_struct *)filp->private_data;
SOLD("entry");
@@ -620,6 +629,7 @@ int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __us
int oldflags;
struct file *filp;
struct inode *ino;
+ struct fdtable *fdt;
struct sol_socket_struct *sock;
struct T_unitdata_ind udi;
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
SOLD("entry");
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));
- filp = current->files->fd[fd];
+ fdt = files_fdtable(current->files);
+ filp = fdt->fd[fd];
ino = filp->f_dentry->d_inode;
sock = (struct sol_socket_struct *)filp->private_data;
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)
int __user *flgptr;
int flags;
int error = -EBADF;
+ struct fdtable *fdt;
SOLD("entry");
lock_kernel();
if(fd >= NR_OPEN) goto out;
- filp = current->files->fd[fd];
+ fdt = files_fdtable(current->files);
+ filp = fdt->fd[fd];
if(!filp) goto out;
ino = filp->f_dentry->d_inode;
@@ -910,12 +923,14 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
struct strbuf ctl, dat;
int flags = (int) arg3;
int error = -EBADF;
+ struct fdtable *fdt;
SOLD("entry");
lock_kernel();
if(fd >= NR_OPEN) goto out;
- filp = current->files->fd[fd];
+ fdt = files_fdtable(current->files);
+ filp = fdt->fd[fd];
if(!filp) goto out;
ino = filp->f_dentry->d_inode;
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index baddb5d64ca..436abbba409 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -8,6 +8,7 @@ START := 0x60000000
#it's needed for headers to work!
CFLAGS += -U__$(SUBARCH)__ -fno-builtin
USER_CFLAGS += -fno-builtin
+CHECKFLAGS += -m64
ELF_ARCH := i386:x86-64
ELF_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 cd6c280482c..6ee3f3902e6 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,18 +18,18 @@
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
-static inline int verify_area_skas(int type, const void * addr,
+static inline int verify_area_skas(int type, const void __user * addr,
unsigned long size)
{
return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
}
-extern int copy_from_user_skas(void *to, const void *from, int n);
-extern int copy_to_user_skas(void *to, const void *from, int n);
-extern int strncpy_from_user_skas(char *dst, const char *src, int count);
-extern int __clear_user_skas(void *mem, int len);
-extern int clear_user_skas(void *mem, int len);
-extern int strnlen_user_skas(const void *str, int len);
+extern int copy_from_user_skas(void *to, const void __user *from, int n);
+extern int copy_to_user_skas(void __user *to, const void *from, int n);
+extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
+extern int __clear_user_skas(void __user *mem, int len);
+extern int clear_user_skas(void __user *mem, int len);
+extern int strnlen_user_skas(const void __user *str, int len);
#endif
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index 3fbb5fe26f4..aa6db384af8 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;
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
-static inline int verify_area_tt(int type, const void * addr,
+static inline int verify_area_tt(int type, const void __user * addr,
unsigned long size)
{
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,
extern int __do_strnlen_user(const char *str, unsigned long n,
void **fault_addr, void **fault_catcher);
-extern int copy_from_user_tt(void *to, const void *from, int n);
-extern int copy_to_user_tt(void *to, const void *from, int n);
-extern int strncpy_from_user_tt(char *dst, const char *src, int count);
-extern int __clear_user_tt(void *mem, int len);
-extern int clear_user_tt(void *mem, int len);
-extern int strnlen_user_tt(const void *str, int len);
+extern int copy_from_user_tt(void *to, const void __user *from, int n);
+extern int copy_to_user_tt(void __user *to, const void *from, int n);
+extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
+extern int __clear_user_tt(void __user *mem, int len);
+extern int clear_user_tt(void __user *mem, int len);
+extern int strnlen_user_tt(const void __user *str, int len);
#endif
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 17f305b6bad..59a1291f477 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))
$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
$(CFLAGS_$(notdir $@))
+$(USER_OBJS): cmd_checksrc =
+$(USER_OBJS): quiet_cmd_checksrc =
+$(USER_OBJS): cmd_force_checksrc =
+$(USER_OBJS): quiet_cmd_force_checksrc =
+
# The stubs and unmap.o can't try to call mcount or update basic block data
define unprofile
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index d259f8a6f81..419758f19ca 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -24,17 +24,26 @@
static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr)
{
- struct file *file = fget(fd);
+ struct file *file;
struct tty_struct *real_tty;
+ int fput_needed, ret;
+ file = fget_light(fd, &fput_needed);
if (!file)
return -EBADF;
+
+ ret = -EINVAL;
if (file->f_op->ioctl != tty_ioctl)
- return -EINVAL;
+ goto out;
real_tty = (struct tty_struct *)file->private_data;
if (!real_tty)
- return -EINVAL;
- return put_user(new_encode_dev(tty_devnum(real_tty)), ptr);
+ goto out;
+
+ ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr);
+
+out:
+ fput_light(file, fput_needed);
+ return ret;
}
#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 116ac5f53dc..bb0ae18ec02 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;
*/
__init void e820_setup_gap(void)
{
- unsigned long gapstart, gapsize;
+ unsigned long gapstart, gapsize, round;
unsigned long last;
int i;
int found = 0;
@@ -604,14 +604,14 @@ __init void e820_setup_gap(void)
}
/*
- * Start allocating dynamic PCI memory a bit into the gap,
- * aligned up to the nearest megabyte.
- *
- * Question: should we try to pad it up a bit (do something
- * like " + (gapsize >> 3)" in there too?). We now have the
- * technology.
+ * See how much we want to round up: start off with
+ * rounding to the next 1MB area.
*/
- pci_mem_start = (gapstart + 0xfffff) & ~0xfffff;
+ round = 0x100000;
+ while ((gapsize >> 4) > round)
+ round += round;
+ /* Fun with two's complement */
+ pci_mem_start = (gapstart + round) & -round;
printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index adc96282a9e..6d57da96bf8 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)
static void flat_send_IPI_allbutself(int vector)
{
+#ifndef CONFIG_HOTPLUG_CPU
if (((num_online_cpus()) - 1) >= 1)
__send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL);
+#else
+ cpumask_t allbutme = cpu_online_map;
+ int me = get_cpu(); /* Ensure we are not preempted when we clear */
+ cpu_clear(me, allbutme);
+
+ if (!cpus_empty(allbutme))
+ flat_send_IPI_mask(allbutme, vector);
+ put_cpu();
+#endif
}
static 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 40e0aca088f..5f1529be123 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)
clear_IO_APIC();
/*
- * If the i82559 is routed through an IOAPIC
+ * If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
- * so legacy interrups can be delivered.
+ * so legacy interrupts can be delivered.
*/
pin = find_isa_irq_pin(0, mp_ExtINT);
if (pin != -1) {
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 90aeccd1519..4fb34b5cb1f 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)
cpu_set(0, cpu_core_map[0]);
}
-/*
- * Handle user cpus=... parameter.
- */
-static __init void enforce_max_cpus(unsigned max_cpus)
-{
- int i, k;
- k = 0;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
- if (++k > max_cpus) {
- cpu_clear(i, cpu_possible_map);
- cpu_clear(i, cpu_present_map);
- }
- }
-}
-
#ifdef CONFIG_HOTPLUG_CPU
/*
* 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)
current_cpu_data = boot_cpu_data;
current_thread_info()->cpu = 0; /* needed? */
- enforce_max_cpus(max_cpus);
-
#ifdef CONFIG_HOTPLUG_CPU
prefill_possible_map();
#endif
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index c0a37d98b4f..04854234120 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 *);
/************************* End of Prototypes **************************/
-static struct timer_list motor_off_timer =
- TIMER_INITIALIZER(fd_motor_off_timer, 0, 0);
+static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
#ifdef TRACKBUFFER
-static struct timer_list readtrack_timer =
- TIMER_INITIALIZER(fd_readtrack_check, 0, 0);
+static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
#endif
-static struct timer_list timeout_timer =
- TIMER_INITIALIZER(fd_times_out, 0, 0);
+static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
-static struct timer_list fd_timer =
- TIMER_INITIALIZER(check_change, 0, 0);
+static DEFINE_TIMER(fd_timer, check_change, 0, 0);
/* DAG: Haven't got a clue what this is? */
int stdma_islocked(void)
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 3998c9d35fe..fe1e8126fba 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -250,8 +250,7 @@ config ACPI_CUSTOM_DSDT_FILE
Enter the full path name to the file wich includes the AmlCode declaration.
config ACPI_BLACKLIST_YEAR
- int "Disable ACPI for systems before Jan 1st this year"
- depends on X86
+ int "Disable ACPI for systems before Jan 1st this year" if X86
default 0
help
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 b8c260ed4b2..0aabfc2a59d 100644
--- a/drivers/atm/idt77105.c
+++ b/drivers/atm/idt77105.c
@@ -50,10 +50,8 @@ static void idt77105_stats_timer_func(unsigned long);
static void idt77105_restart_timer_func(unsigned long);
-static struct timer_list stats_timer =
- TIMER_INITIALIZER(idt77105_stats_timer_func, 0, 0);
-static struct timer_list restart_timer =
- TIMER_INITIALIZER(idt77105_restart_timer_func, 0, 0);
+static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func, 0, 0);
+static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func, 0, 0);
static int start_timer = 1;
static struct idt77105_priv *idt77105_all = NULL;
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index a43575acb2c..2e2e50e1167 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -79,7 +79,7 @@ static IADEV *ia_dev[8];
static struct atm_dev *_ia_dev[8];
static int iadev_count;
static void ia_led_timer(unsigned long arg);
-static struct timer_list ia_timer = TIMER_INITIALIZER(ia_led_timer, 0, 0);
+static DEFINE_TIMER(ia_timer, ia_led_timer, 0, 0);
static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
static 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 ce933de4808..0e1f34fef0c 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -371,7 +371,7 @@ static int acsi_revalidate (struct gendisk *disk);
/************************* End of Prototypes **************************/
-struct timer_list acsi_timer = TIMER_INITIALIZER(acsi_times_out, 0, 0);
+DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0);
#ifdef CONFIG_ATARI_SLM
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e3be8c31a74..a5c1c8e871e 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 );
/************************* End of Prototypes **************************/
-static struct timer_list slm_timer = TIMER_INITIALIZER(slm_test_ready, 0, 0);
+static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0);
static struct file_operations slm_fops = {
.owner = THIS_MODULE,
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index db05a5a99f3..22bda05fc69 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 );
/************************* End of Prototypes **************************/
-static struct timer_list motor_off_timer =
- TIMER_INITIALIZER(fd_motor_off_timer, 0, 0);
-static struct timer_list readtrack_timer =
- TIMER_INITIALIZER(fd_readtrack_check, 0, 0);
-
-static struct timer_list timeout_timer =
- TIMER_INITIALIZER(fd_times_out, 0, 0);
-
-static struct timer_list fd_timer =
- TIMER_INITIALIZER(check_change, 0, 0);
+static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
+static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
+static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
+static DEFINE_TIMER(fd_timer, check_change, 0, 0);
static inline void start_motor_off_timer(void)
{
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 24594c57c32..52a3ae5289a 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)
/*
* batches are currently reads XOR writes
*/
- drq = dd->next_drq[WRITE] ? : dd->next_drq[READ];
+ if (dd->next_drq[WRITE])
+ drq = dd->next_drq[WRITE];
+ else
+ drq = dd->next_drq[READ];
if (drq) {
/* we have a "next request" */
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 888dad5eef3..00895477155 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -628,7 +628,7 @@ static inline void debugt(const char *message) { }
#endif /* DEBUGT */
typedef void (*timeout_fn) (unsigned long);
-static struct timer_list fd_timeout = TIMER_INITIALIZER(floppy_shutdown, 0, 0);
+static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
static const char *timeout_message;
@@ -1012,7 +1012,7 @@ static void schedule_bh(void (*handler) (void))
schedule_work(&floppy_work);
}
-static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(fd_timer, NULL, 0, 0);
static void cancel_activity(void)
{
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29548784cb7..29d1518be72 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -99,8 +99,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
static int no_int_yet;
static int ps2esdi_drives;
static u_short io_base;
-static struct timer_list esdi_timer =
- TIMER_INITIALIZER(ps2esdi_reset_timer, 0, 0);
+static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0);
static int reset_status;
static int ps2esdi_slot = -1;
static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index a026567f5d1..aa0bf7ee008 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -16,9 +16,10 @@
* -- verify the 13 conditions and do bulk resets
* -- kill last_pipe and simply do two-state clearing on both pipes
* -- verify protocol (bulk) from USB descriptors (maybe...)
- * -- highmem and sg
+ * -- highmem
* -- move top_sense and work_bcs into separate allocations (if they survive)
* for cache purists and esoteric architectures.
+ * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ?
* -- prune comments, they are too volumnous
* -- Exterminate P3 printks
* -- Resove XXX's
@@ -171,7 +172,7 @@ struct bulk_cs_wrap {
*/
struct ub_dev;
-#define UB_MAX_REQ_SG 1
+#define UB_MAX_REQ_SG 4
#define UB_MAX_SECTORS 64
/*
@@ -234,13 +235,10 @@ struct ub_scsi_cmd {
int stat_count; /* Retries getting status. */
- /*
- * We do not support transfers from highmem pages
- * because the underlying USB framework does not do what we need.
- */
- char *data; /* Requested buffer */
unsigned int len; /* Requested length */
- // struct scatterlist sgv[UB_MAX_REQ_SG];
+ unsigned int current_sg;
+ unsigned int nsg; /* sgv[nsg] */
+ struct scatterlist sgv[UB_MAX_REQ_SG];
struct ub_lun *lun;
void (*done)(struct ub_dev *, struct ub_scsi_cmd *);
@@ -389,17 +387,18 @@ struct ub_dev {
struct bulk_cs_wrap work_bcs;
struct usb_ctrlrequest work_cr;
+ int sg_stat[UB_MAX_REQ_SG+1];
struct ub_scsi_trace tr;
};
/*
*/
static void ub_cleanup(struct ub_dev *sc);
-static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq);
+static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq);
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
- struct request *rq);
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq);
static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_end_rq(struct request *rq, int uptodate);
static 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);
static void ub_scsi_action(unsigned long _dev);
static void ub_scsi_dispatch(struct ub_dev *sc);
static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
+static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static 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,
}
}
-static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page)
+static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
+ char *page)
{
struct usb_interface *intf;
struct ub_dev *sc;
@@ -523,6 +524,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, c
cnt += sprintf(page + cnt,
"qlen %d qmax %d\n",
sc->cmd_queue.qlen, sc->cmd_queue.qmax);
+ cnt += sprintf(page + cnt,
+ "sg %d %d %d %d %d\n",
+ sc->sg_stat[0],
+ sc->sg_stat[1],
+ sc->sg_stat[2],
+ sc->sg_stat[3],
+ sc->sg_stat[4]);
list_for_each (p, &sc->luns) {
lun = list_entry(p, struct ub_lun, link);
@@ -744,20 +752,20 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc)
* The request function is our main entry point
*/
-static void ub_bd_rq_fn(request_queue_t *q)
+static void ub_request_fn(request_queue_t *q)
{
struct ub_lun *lun = q->queuedata;
struct request *rq;
while ((rq = elv_next_request(q)) != NULL) {
- if (ub_bd_rq_fn_1(lun, rq) != 0) {
+ if (ub_request_fn_1(lun, rq) != 0) {
blk_stop_queue(q);
break;
}
}
}
-static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
+static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
{
struct ub_dev *sc = lun->udev;
struct ub_scsi_cmd *cmd;
@@ -774,9 +782,8 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
blkdev_dequeue_request(rq);
-
if (blk_pc_request(rq)) {
- rc = ub_cmd_build_packet(sc, cmd, rq);
+ rc = ub_cmd_build_packet(sc, lun, cmd, rq);
} else {
rc = ub_cmd_build_block(sc, lun, cmd, rq);
}
@@ -791,7 +798,7 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq)
cmd->back = rq;
cmd->tag = sc->tagcnt++;
- if ((rc = ub_submit_scsi(sc, cmd)) != 0) {
+ if (ub_submit_scsi(sc, cmd) != 0) {
ub_put_cmd(lun, cmd);
ub_end_rq(rq, 0);
return 0;
@@ -804,58 +811,31 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq)
{
int ub_dir;
-#if 0 /* We use rq->buffer for now */
- struct scatterlist *sg;
int n_elem;
-#endif
unsigned int block, nblks;
if (rq_data_dir(rq) == WRITE)
ub_dir = UB_DIR_WRITE;
else
ub_dir = UB_DIR_READ;
+ cmd->dir = ub_dir;
/*
* get scatterlist from block layer
*/
-#if 0 /* We use rq->buffer for now */
- sg = &cmd->sgv[0];
- n_elem = blk_rq_map_sg(q, rq, sg);
+ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
if (n_elem <= 0) {
- ub_put_cmd(lun, cmd);
- ub_end_rq(rq, 0);
- blk_start_queue(q);
- return 0; /* request with no s/g entries? */
+ printk(KERN_INFO "%s: failed request map (%d)\n",
+ sc->name, n_elem); /* P3 */
+ return -1; /* request with no s/g entries? */
}
-
- if (n_elem != 1) { /* Paranoia */
+ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
printk(KERN_WARNING "%s: request with %d segments\n",
sc->name, n_elem);
- ub_put_cmd(lun, cmd);
- ub_end_rq(rq, 0);
- blk_start_queue(q);
- return 0;
- }
-#endif
-
- /*
- * XXX Unfortunately, this check does not work. It is quite possible
- * to get bogus non-null rq->buffer if you allow sg by mistake.
- */
- if (rq->buffer == NULL) {
- /*
- * This must not happen if we set the queue right.
- * The block level must create bounce buffers for us.
- */
- static int do_print = 1;
- if (do_print) {
- printk(KERN_WARNING "%s: unmapped block request"
- " flags 0x%lx sectors %lu\n",
- sc->name, rq->flags, rq->nr_sectors);
- do_print = 0;
- }
return -1;
}
+ cmd->nsg = n_elem;
+ sc->sg_stat[n_elem]++;
/*
* build the command
@@ -876,30 +856,15 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
cmd->cdb[8] = nblks;
cmd->cdb_len = 10;
- cmd->dir = ub_dir;
- cmd->data = rq->buffer;
cmd->len = rq->nr_sectors * 512;
return 0;
}
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
- struct request *rq)
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq)
{
-
- if (rq->data_len != 0 && rq->data == NULL) {
- static int do_print = 1;
- if (do_print) {
- printk(KERN_WARNING "%s: unmapped packet request"
- " flags 0x%lx length %d\n",
- sc->name, rq->flags, rq->data_len);
- do_print = 0;
- }
- return -1;
- }
-
- memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
- cmd->cdb_len = rq->cmd_len;
+ int n_elem;
if (rq->data_len == 0) {
cmd->dir = UB_DIR_NONE;
@@ -908,8 +873,29 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
cmd->dir = UB_DIR_WRITE;
else
cmd->dir = UB_DIR_READ;
+
+ }
+
+ /*
+ * get scatterlist from block layer
+ */
+ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
+ if (n_elem < 0) {
+ printk(KERN_INFO "%s: failed request map (%d)\n",
+ sc->name, n_elem); /* P3 */
+ return -1;
}
- cmd->data = rq->data;
+ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
+ printk(KERN_WARNING "%s: request with %d segments\n",
+ sc->name, n_elem);
+ return -1;
+ }
+ cmd->nsg = n_elem;
+ sc->sg_stat[n_elem]++;
+
+ memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
+ cmd->cdb_len = rq->cmd_len;
+
cmd->len = rq->data_len;
return 0;
@@ -919,24 +905,34 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
struct request *rq = cmd->back;
struct ub_lun *lun = cmd->lun;
- struct gendisk *disk = lun->disk;
- request_queue_t *q = disk->queue;
int uptodate;
- if (blk_pc_request(rq)) {
- /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
- memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
- rq->sense_len = UB_SENSE_SIZE;
- }
-
- if (cmd->error == 0)
+ if (cmd->error == 0) {
uptodate = 1;
- else
+
+ if (blk_pc_request(rq)) {
+ if (cmd->act_len >= rq->data_len)
+ rq->data_len = 0;
+ else
+ rq->data_len -= cmd->act_len;
+ }
+ } else {
uptodate = 0;
+ if (blk_pc_request(rq)) {
+ /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
+ memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE);
+ rq->sense_len = UB_SENSE_SIZE;
+ if (sc->top_sense[0] != 0)
+ rq->errors = SAM_STAT_CHECK_CONDITION;
+ else
+ rq->errors = DID_ERROR << 16;
+ }
+ }
+
ub_put_cmd(lun, cmd);
ub_end_rq(rq, uptodate);
- blk_start_queue(q);
+ blk_start_queue(lun->disk->queue);
}
static 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)
sc->last_pipe = sc->send_bulk_pipe;
usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
- sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+ sc->work_urb.transfer_flags = 0;
/* Fill what we shouldn't be filling, because usb-storage did so. */
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)
{
struct urb *urb = &sc->work_urb;
struct bulk_cs_wrap *bcs;
- int pipe;
int rc;
if (atomic_read(&sc->poison)) {
@@ -1204,38 +1199,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
goto Bad_End;
}
- if (cmd->dir == UB_DIR_NONE) {
+ if (cmd->dir == UB_DIR_NONE || cmd->nsg < 1) {
ub_state_stat(sc, cmd);
return;
}
- UB_INIT_COMPLETION(sc->work_done);
-
- if (cmd->dir == UB_DIR_READ)
- pipe = sc->recv_bulk_pipe;
- else
- pipe = sc->send_bulk_pipe;
- sc->last_pipe = pipe;
- usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
- cmd->data, cmd->len, ub_urb_complete, sc);
- sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
- sc->work_urb.actual_length = 0;
- sc->work_urb.error_count = 0;
- sc->work_urb.status = 0;
-
- if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
- /* XXX Clear stalls */
- printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
- ub_complete(&sc->work_done);
- ub_state_done(sc, cmd, rc);
- return;
- }
-
- sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
- add_timer(&sc->work_timer);
-
- cmd->state = UB_CMDST_DATA;
- ub_cmdtr_state(sc, cmd);
+ // udelay(125); // usb-storage has this
+ ub_data_start(sc, cmd);
} else if (cmd->state == UB_CMDST_DATA) {
if (urb->status == -EPIPE) {
@@ -1257,16 +1227,22 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status == -EOVERFLOW) {
/*
* A babble? Failure, but we must transfer CSW now.
+ * XXX This is going to end in perpetual babble. Reset.
*/
cmd->error = -EOVERFLOW; /* A cheap trick... */
- } else {
- if (urb->status != 0)
- goto Bad_End;
+ ub_state_stat(sc, cmd);
+ return;
}
+ if (urb->status != 0)
+ goto Bad_End;
- cmd->act_len = urb->actual_length;
+ cmd->act_len += urb->actual_length;
ub_cmdtr_act_len(sc, cmd);
+ if (++cmd->current_sg < cmd->nsg) {
+ ub_data_start(sc, cmd);
+ return;
+ }
ub_state_stat(sc, cmd);
} else if (cmd->state == UB_CMDST_STAT) {
@@ -1401,6 +1377,46 @@ Bad_End: /* Little Excel is dead */
/*
* Factorization helper for the command state machine:
+ * Initiate a data segment transfer.
+ */
+static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+{
+ struct scatterlist *sg = &cmd->sgv[cmd->current_sg];
+ int pipe;
+ int rc;
+
+ UB_INIT_COMPLETION(sc->work_done);
+
+ if (cmd->dir == UB_DIR_READ)
+ pipe = sc->recv_bulk_pipe;
+ else
+ pipe = sc->send_bulk_pipe;
+ sc->last_pipe = pipe;
+ usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
+ page_address(sg->page) + sg->offset, sg->length,
+ ub_urb_complete, sc);
+ sc->work_urb.transfer_flags = 0;
+ sc->work_urb.actual_length = 0;
+ sc->work_urb.error_count = 0;
+ sc->work_urb.status = 0;
+
+ if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
+ /* XXX Clear stalls */
+ printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
+ ub_complete(&sc->work_done);
+ ub_state_done(sc, cmd, rc);
+ return;
+ }
+
+ sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
+ add_timer(&sc->work_timer);
+
+ cmd->state = UB_CMDST_DATA;
+ ub_cmdtr_state(sc, cmd);
+}
+
+/*
+ * Factorization helper for the command state machine:
* Finish the command.
*/
static 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)
sc->last_pipe = sc->recv_bulk_pipe;
usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
&sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
- sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+ sc->work_urb.transfer_flags = 0;
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -1484,6 +1500,7 @@ static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
struct ub_scsi_cmd *scmd;
+ struct scatterlist *sg;
int rc;
if (cmd->cdb[0] == REQUEST_SENSE) {
@@ -1492,12 +1509,17 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
}
scmd = &sc->top_rqs_cmd;
+ memset(scmd, 0, sizeof(struct ub_scsi_cmd));
scmd->cdb[0] = REQUEST_SENSE;
scmd->cdb[4] = UB_SENSE_SIZE;
scmd->cdb_len = 6;
scmd->dir = UB_DIR_READ;
scmd->state = UB_CMDST_INIT;
- scmd->data = sc->top_sense;
+ scmd->nsg = 1;
+ sg = &scmd->sgv[0];
+ sg->page = virt_to_page(sc->top_sense);
+ sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1);
+ sg->length = UB_SENSE_SIZE;
scmd->len = UB_SENSE_SIZE;
scmd->lun = cmd->lun;
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,
usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
(unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
- sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
+ sc->work_urb.transfer_flags = 0;
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -1560,7 +1582,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
*/
static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
{
- unsigned char *sense = scmd->data;
+ unsigned char *sense = sc->top_sense;
struct ub_scsi_cmd *cmd;
/*
@@ -1852,6 +1874,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
struct ub_capacity *ret)
{
struct ub_scsi_cmd *cmd;
+ struct scatterlist *sg;
char *p;
enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) + 8 };
unsigned long flags;
@@ -1872,7 +1895,11 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
cmd->cdb_len = 10;
cmd->dir = UB_DIR_READ;
cmd->state = UB_CMDST_INIT;
- cmd->data = p;
+ cmd->nsg = 1;
+ sg = &cmd->sgv[0];
+ sg->page = virt_to_page(p);
+ sg->offset = (unsigned int)p & (PAGE_SIZE-1);
+ sg->length = 8;
cmd->len = 8;
cmd->lun = lun;
cmd->done = ub_probe_done;
@@ -2289,7 +2316,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */
rc = -ENOMEM;
- if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL)
+ if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL)
goto err_blkqinit;
disk->queue = q;
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 43bf1e5dc38..ce4a1ce59d6 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -297,7 +297,7 @@ static char azt_auto_eject = AZT_AUTO_EJECT;
static int AztTimeout, AztTries;
static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
-static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(delay_timer, NULL, 0, 0);
static struct azt_DiskInfo DiskInfo;
static struct azt_Toc Toc[MAX_TRACKS];
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
index 7eac10e63b2..ad5464ab99b 100644
--- a/drivers/cdrom/gscd.c
+++ b/drivers/cdrom/gscd.c
@@ -146,7 +146,7 @@ static int AudioStart_f;
static int AudioEnd_m;
static int AudioEnd_f;
-static struct timer_list gscd_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(gscd_timer, NULL, 0, 0);
static DEFINE_SPINLOCK(gscd_lock);
static struct request_queue *gscd_queue;
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
index 351a01dd503..0b0eab4f40f 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)
static int sleep_timeout; /* max # of ticks to sleep */
static DECLARE_WAIT_QUEUE_HEAD(waitq);
static void sleep_timer(unsigned long data);
-static struct timer_list delay_timer = TIMER_INITIALIZER(sleep_timer, 0, 0);
+static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0);
static DEFINE_SPINLOCK(optcd_lock);
static struct request_queue *opt_queue;
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index 452d3467515..30a89775536 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -742,13 +742,10 @@ static struct sbpcd_drive *current_drive = D_S;
unsigned long cli_sti; /* for saving the processor flags */
#endif
/*==========================================================================*/
-static struct timer_list delay_timer =
- TIMER_INITIALIZER(mark_timeout_delay, 0, 0);
-static struct timer_list data_timer =
- TIMER_INITIALIZER(mark_timeout_data, 0, 0);
+static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
+static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
#if 0
-static struct timer_list audio_timer =
- TIMER_INITIALIZER(mark_timeout_audio, 0, 0);
+static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
#endif
/*==========================================================================*/
/*
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index 4e7a342ec36..74b1cadbf16 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -151,7 +151,7 @@ static struct sjcd_stat statistic;
/*
* Timer.
*/
-static struct timer_list sjcd_delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0);
#define SJCD_SET_TIMER( func, tmout ) \
( sjcd_delay_timer.expires = jiffies+tmout, \
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 2bc9d64db10..c29365d5b52 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
config COMPUTONE
tristate "Computone IntelliPort Plus serial support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32)
+ depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
---help---
This driver supports the entire family of Intelliport II/Plus
controllers with the exception of the MicroChannel controllers and
@@ -208,7 +208,7 @@ config SYNCLINK
config SYNCLINKMP
tristate "SyncLink Multiport support"
- depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32)
+ depends on SERIAL_NONSTANDARD
help
Enable support for the SyncLink Multiport (2 or 4 ports)
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 59f589d733f..0a7624a9b1c 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)
struct pci_dev *dev1;
int i;
unsigned size = amd64_fetch_size();
- printk(KERN_INFO "Setting up ULi AGP. \n");
+ printk(KERN_INFO "Setting up ULi AGP.\n");
dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0));
if (dev1 == NULL) {
printk(KERN_INFO PFX "Detected a ULi chipset, "
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index f0079e991bd..ac9da0ca36b 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)
info->mode = bridge->mode & ~AGP3_RESERVED_MASK;
else
info->mode = bridge->mode & ~AGP2_RESERVED_MASK;
- info->mode = bridge->mode;
info->aper_base = bridge->gart_bus_addr;
info->aper_size = agp_return_size();
info->max_memory = bridge->max_memory_agp;
@@ -356,7 +355,7 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
return -EINVAL;
if (curr->is_bound == TRUE) {
- printk (KERN_INFO PFX "memory %p is already bound!\n", curr);
+ printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
return -EINVAL;
}
if (curr->is_flushed == FALSE) {
@@ -391,7 +390,7 @@ int agp_unbind_memory(struct agp_memory *curr)
return -EINVAL;
if (curr->is_bound != TRUE) {
- printk (KERN_INFO PFX "memory %p was not bound!\n", curr);
+ printk(KERN_INFO PFX "memory %p was not bound!\n", curr);
return -EINVAL;
}
@@ -415,7 +414,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
u32 tmp;
if (*requested_mode & AGP2_RESERVED_MASK) {
- printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+ printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
*requested_mode &= ~AGP2_RESERVED_MASK;
}
@@ -423,7 +422,7 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
tmp = *requested_mode & 7;
switch (tmp) {
case 0:
- printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
+ printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to x1 mode.\n", current->comm);
*requested_mode |= AGPSTAT2_1X;
break;
case 1:
@@ -493,18 +492,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
u32 tmp;
if (*requested_mode & AGP3_RESERVED_MASK) {
- printk (KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
+ printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode);
*requested_mode &= ~AGP3_RESERVED_MASK;
}
/* Check the speed bits make sense. */
tmp = *requested_mode & 7;
if (tmp == 0) {
- printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
+ printk(KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
*requested_mode |= AGPSTAT3_4X;
}
if (tmp >= 3) {
- printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
+ printk(KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
*requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
}
@@ -533,7 +532,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
* AGP2.x 4x -> AGP3.0 4x.
*/
if (*requested_mode & AGPSTAT2_4X) {
- printk (KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
+ printk(KERN_INFO PFX "%s passes broken AGP3 flags (%x). Fixed.\n",
current->comm, *requested_mode);
*requested_mode &= ~AGPSTAT2_4X;
*requested_mode |= AGPSTAT3_4X;
@@ -544,7 +543,7 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
* but have been passed an AGP 2.x mode.
* Convert AGP 1x,2x,4x -> AGP 3.0 4x.
*/
- printk (KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
+ printk(KERN_INFO PFX "%s passes broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",
current->comm, *requested_mode);
*requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X);
*requested_mode |= AGPSTAT3_4X;
@@ -554,13 +553,13 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
if (!(*bridge_agpstat & AGPSTAT3_8X)) {
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
*bridge_agpstat |= AGPSTAT3_4X;
- printk ("%s requested AGPx8 but bridge not capable.\n", current->comm);
+ printk(KERN_INFO PFX "%s requested AGPx8 but bridge not capable.\n", current->comm);
return;
}
if (!(*vga_agpstat & AGPSTAT3_8X)) {
*bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
*bridge_agpstat |= AGPSTAT3_4X;
- printk ("%s requested AGPx8 but graphic card not capable.\n", current->comm);
+ printk(KERN_INFO PFX "%s requested AGPx8 but graphic card not capable.\n", current->comm);
return;
}
/* 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_
if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X))
*bridge_agpstat |= AGPSTAT3_4X;
else {
- printk (KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
+ printk(KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
"[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n",
origbridge, origvga, *bridge_agpstat, *vga_agpstat);
if (!(*bridge_agpstat & AGPSTAT3_4X))
- printk (KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
+ printk(KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
if (!(*vga_agpstat & AGPSTAT3_4X))
- printk (KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
+ printk(KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
return;
}
}
@@ -622,7 +621,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
for (;;) {
device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device);
if (!device) {
- printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
+ printk(KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
return 0;
}
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)
pci_write_config_dword(bridge->dev,
bridge->capndx+AGPCTRL, temp);
- printk (KERN_INFO PFX "Device is in legacy mode,"
+ printk(KERN_INFO PFX "Device is in legacy mode,"
" falling back to 2.x\n");
}
}
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a5337bf093..cf4c3648463 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -865,7 +865,7 @@ static void cyz_poll(unsigned long);
static long cyz_polling_cycle = CZ_DEF_POLL;
static int cyz_timeron = 0;
-static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0);
+static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
#else /* CONFIG_CYZ_INTR */
static void cyz_rx_restart(unsigned long);
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 6f98701dfe1..121cc85f347 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);
extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
+#ifndef pci_pretty_name
+#define pci_pretty_name(dev) ""
+#endif
+
#endif /* __KERNEL__ */
#endif
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 81d811edf3c..a54bc93353a 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;
static void hangcheck_fire(unsigned long);
-static struct timer_list hangcheck_ticktock =
- TIMER_INITIALIZER(hangcheck_fire, 0, 0);
+static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0);
static void hangcheck_fire(unsigned long data)
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index cf0cd58d630..9e4e26aef94 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -120,7 +120,6 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <asm/serial.h>
#include <asm/uaccess.h>
@@ -255,7 +254,7 @@ static unsigned long bh_counter = 0;
* selected, the board is serviced periodically to see if anything needs doing.
*/
#define POLL_TIMEOUT (jiffies + 1)
-static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0);
+static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
static char TimerOn;
#ifdef IP2DEBUG_TRACE
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 883ac4352be..a09ff108068 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,
case COMPAT_IPMICTL_RECEIVE_MSG:
case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
{
- struct ipmi_recv *precv64, recv64;
+ struct ipmi_recv __user *precv64;
+ struct ipmi_recv recv64;
if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
return -EFAULT;
@@ -748,7 +749,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
? IPMICTL_RECEIVE_MSG
: IPMICTL_RECEIVE_MSG_TRUNC),
- (long) precv64);
+ (unsigned long) precv64);
if (rc != 0)
return rc;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 52a073eee20..9c19e5435a1 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -780,7 +780,7 @@ static struct file_operations stli_fsiomem = {
* much cheaper on host cpu than using interrupts. It turns out to
* not increase character latency by much either...
*/
-static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0);
+static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0);
static int stli_timeron;
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 523fd3c8bba..1745065d8f7 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -233,8 +233,7 @@ static void kd_nosound(unsigned long ignored)
}
}
-static struct timer_list kd_mksound_timer =
- TIMER_INITIALIZER(kd_nosound, 0, 0);
+static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
void kd_mksound(unsigned int hz, unsigned int ticks)
{
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index da32889d22c..49f3997fd25 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -149,15 +149,14 @@ static int pty_write_room(struct tty_struct *tty)
static int pty_chars_in_buffer(struct tty_struct *tty)
{
struct tty_struct *to = tty->link;
- ssize_t (*chars_in_buffer)(struct tty_struct *);
int count;
/* We should get the line discipline lock for "tty->link" */
- if (!to || !(chars_in_buffer = to->ldisc.chars_in_buffer))
+ if (!to || !to->ldisc.chars_in_buffer)
return 0;
/* The ldisc must report 0 if no characters available to be read */
- count = chars_in_buffer(to);
+ count = to->ldisc.chars_in_buffer(to);
if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 37c8bea8e2b..ea2d54be484 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.28 2004/08/11 19:30:01 paulkf Exp $
+ * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -141,9 +141,9 @@ static MGSL_PARAMS default_params = {
typedef struct _DMABUFFERENTRY
{
u32 phys_addr; /* 32-bit flat physical address of data buffer */
- u16 count; /* buffer size/data count */
- u16 status; /* Control/status field */
- u16 rcc; /* character count field */
+ volatile u16 count; /* buffer size/data count */
+ volatile u16 status; /* Control/status field */
+ volatile u16 rcc; /* character count field */
u16 reserved; /* padding required by 16C32 */
u32 link; /* 32-bit flat link to next buffer entry */
char *virt_addr; /* virtual address of data buffer */
@@ -896,7 +896,7 @@ module_param_array(txdmabufs, int, NULL, 0);
module_param_array(txholdbufs, int, NULL, 0);
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.28 $";
+static char *driver_version = "$Revision: 4.37 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
@@ -1814,6 +1814,8 @@ static int startup(struct mgsl_struct * info)
info->pending_bh = 0;
+ memset(&info->icount, 0, sizeof(info->icount));
+
init_timer(&info->tx_timer);
info->tx_timer.data = (unsigned long)info;
info->tx_timer.function = mgsl_tx_timeout;
@@ -2470,12 +2472,12 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *
printk("%s(%d):mgsl_get_params(%s)\n",
__FILE__,__LINE__, info->device_name);
- COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));
- if (err) {
- if ( debug_level >= DEBUG_LEVEL_INFO )
- printk( "%s(%d):mgsl_get_stats(%s) user buffer copy failed\n",
- __FILE__,__LINE__,info->device_name);
- return -EFAULT;
+ if (!user_icount) {
+ memset(&info->icount, 0, sizeof(info->icount));
+ } else {
+ COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+ if (err)
+ return -EFAULT;
}
return 0;
@@ -6149,6 +6151,11 @@ static void usc_set_async_mode( struct mgsl_struct *info )
usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12));
}
+ if (info->params.loopback) {
+ info->loopback_bits = 0x300;
+ outw(0x0300, info->io_base + CCAR);
+ }
+
} /* end of usc_set_async_mode() */
/* usc_loopback_frame()
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index ec949e4c070..6fb165cf8a6 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1,5 +1,5 @@
/*
- * $Id: synclinkmp.c,v 4.34 2005/03/04 15:07:10 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
*
* Device driver for Microgate SyncLink Multiport
* high speed multiprotocol serial adapter.
@@ -55,7 +55,6 @@
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <asm/serial.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
@@ -487,7 +486,7 @@ module_param_array(maxframe, int, NULL, 0);
module_param_array(dosyncppp, int, NULL, 0);
static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.34 $";
+static char *driver_version = "$Revision: 4.38 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -556,7 +555,6 @@ static int set_txidle(SLMP_INFO *info, int idle_mode);
static int tx_enable(SLMP_INFO *info, int enable);
static int tx_abort(SLMP_INFO *info);
static int rx_enable(SLMP_INFO *info, int enable);
-static int map_status(int signals);
static int modem_input_wait(SLMP_INFO *info,int arg);
static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
static 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
static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes
static u32 misc_ctrl_value = 0x007e4040;
-static u32 lcr1_brdr_value = 0x00800029;
+static u32 lcr1_brdr_value = 0x00800028;
static u32 read_ahead_count = 8;
@@ -2750,6 +2748,8 @@ static int startup(SLMP_INFO * info)
info->pending_bh = 0;
+ memset(&info->icount, 0, sizeof(info->icount));
+
/* program hardware for current parameters */
reset_port(info);
@@ -2953,12 +2953,12 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
printk("%s(%d):%s get_params()\n",
__FILE__,__LINE__, info->device_name);
- COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));
- if (err) {
- if ( debug_level >= DEBUG_LEVEL_INFO )
- printk( "%s(%d):%s get_stats() user buffer copy failed\n",
- __FILE__,__LINE__,info->device_name);
- return -EFAULT;
+ if (!user_icount) {
+ memset(&info->icount, 0, sizeof(info->icount));
+ } else {
+ COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+ if (err)
+ return -EFAULT;
}
return 0;
@@ -3109,16 +3109,6 @@ static int rx_enable(SLMP_INFO * info, int enable)
return 0;
}
-static int map_status(int signals)
-{
- /* Map status bits to API event bits */
-
- return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) +
- ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) +
- ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) +
- ((signals & SerialSignal_RI) ? MgslEvent_RiActive : MgslEvent_RiInactive);
-}
-
/* wait for specified event to occur
*/
static 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)
/* return immediately if state matches requested events */
get_signals(info);
- s = map_status(info->serial_signals);
+ s = info->serial_signals;
events = mask &
( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
@@ -4489,11 +4479,13 @@ void async_mode(SLMP_INFO *info)
/* MD2, Mode Register 2
*
* 07..02 Reserved, must be 0
- * 01..00 CNCT<1..0> Channel connection, 0=normal
+ * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback
*
* 0000 0000
*/
RegValue = 0x00;
+ if (info->params.loopback)
+ RegValue |= (BIT1 + BIT0);
write_reg(info, MD2, RegValue);
/* RXS, Receive clock source
@@ -4574,9 +4566,6 @@ void async_mode(SLMP_INFO *info)
write_reg(info, IE2, info->ie2_value);
set_rate( info, info->params.data_rate * 16 );
-
- if (info->params.loopback)
- enable_loopback(info,1);
}
/* Program the SCA for HDLC communications.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9d657127f31..e5953f3433f 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)
static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
{
- int retval = 0;
- struct tty_ldisc o_ldisc;
+ int retval = 0;
+ struct tty_ldisc o_ldisc;
char buf[64];
int work;
unsigned long flags;
struct tty_ldisc *ld;
+ struct tty_struct *o_tty;
if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
return -EINVAL;
restart:
- if (tty->ldisc.num == ldisc)
- return 0; /* We are already in the desired discipline */
-
ld = tty_ldisc_get(ldisc);
/* Eduardo Blanco <ejbs@cs.cs.com.uy> */
/* Cyrus Durgin <cider@speakeasy.org> */
@@ -494,45 +492,74 @@ restart:
if (ld == NULL)
return -EINVAL;
- o_ldisc = tty->ldisc;
-
tty_wait_until_sent(tty, 0);
+ if (tty->ldisc.num == ldisc) {
+ tty_ldisc_put(ldisc);
+ return 0;
+ }
+
+ o_ldisc = tty->ldisc;
+ o_tty = tty->link;
+
/*
* Make sure we don't change while someone holds a
* reference to the line discipline. The TTY_LDISC bit
* prevents anyone taking a reference once it is clear.
* We need the lock to avoid racing reference takers.
*/
-
+
spin_lock_irqsave(&tty_ldisc_lock, flags);
- if(tty->ldisc.refcount)
- {
- /* Free the new ldisc we grabbed. Must drop the lock
- first. */
+ if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
+ if(tty->ldisc.refcount) {
+ /* Free the new ldisc we grabbed. Must drop the lock
+ first. */
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ tty_ldisc_put(ldisc);
+ /*
+ * There are several reasons we may be busy, including
+ * random momentary I/O traffic. We must therefore
+ * retry. We could distinguish between blocking ops
+ * and retries if we made tty_ldisc_wait() smarter. That
+ * is up for discussion.
+ */
+ if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
+ return -ERESTARTSYS;
+ goto restart;
+ }
+ if(o_tty && o_tty->ldisc.refcount) {
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ tty_ldisc_put(ldisc);
+ if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
+ return -ERESTARTSYS;
+ goto restart;
+ }
+ }
+
+ /* if the TTY_LDISC bit is set, then we are racing against another ldisc change */
+
+ if (!test_bit(TTY_LDISC, &tty->flags)) {
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
tty_ldisc_put(ldisc);
- /*
- * There are several reasons we may be busy, including
- * random momentary I/O traffic. We must therefore
- * retry. We could distinguish between blocking ops
- * and retries if we made tty_ldisc_wait() smarter. That
- * is up for discussion.
- */
- if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
- return -ERESTARTSYS;
+ ld = tty_ldisc_ref_wait(tty);
+ tty_ldisc_deref(ld);
goto restart;
}
- clear_bit(TTY_LDISC, &tty->flags);
+
+ clear_bit(TTY_LDISC, &tty->flags);
clear_bit(TTY_DONT_FLIP, &tty->flags);
+ if (o_tty) {
+ clear_bit(TTY_LDISC, &o_tty->flags);
+ clear_bit(TTY_DONT_FLIP, &o_tty->flags);
+ }
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
+
/*
* From this point on we know nobody has an ldisc
* usage reference, nor can they obtain one until
* we say so later on.
*/
-
+
work = cancel_delayed_work(&tty->flip.work);
/*
* Wait for ->hangup_work and ->flip.work handlers to terminate
@@ -583,10 +610,12 @@ restart:
*/
tty_ldisc_enable(tty);
+ if (o_tty)
+ tty_ldisc_enable(o_tty);
/* Restart it in case no characters kick it off. Safe if
already running */
- if(work)
+ if (work)
schedule_delayed_work(&tty->flip.work, 1);
return retval;
}
@@ -2425,6 +2454,7 @@ static void __do_SAK(void *arg)
int i;
struct file *filp;
struct tty_ldisc *disc;
+ struct fdtable *fdt;
if (!tty)
return;
@@ -2450,8 +2480,9 @@ static void __do_SAK(void *arg)
}
task_lock(p);
if (p->files) {
- spin_lock(&p->files->file_lock);
- for (i=0; i < p->files->max_fds; i++) {
+ rcu_read_lock();
+ fdt = files_fdtable(p->files);
+ for (i=0; i < fdt->max_fds; i++) {
filp = fcheck_files(p->files, i);
if (!filp)
continue;
@@ -2464,7 +2495,7 @@ static void __do_SAK(void *arg)
break;
}
}
- spin_unlock(&p->files->file_lock);
+ rcu_read_unlock();
}
task_unlock(p);
} while_each_task_pid(session, PIDTYPE_SID, p);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index b8d0c290b0d..1e33cb032e0 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)
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+ unsigned int end;
unsigned short *newscreen;
WARN_CONSOLE_UNLOCKED();
@@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
old_origin = vc->vc_origin;
new_origin = (long) newscreen;
new_scr_end = new_origin + new_screen_size;
- if (new_rows < old_rows)
- old_origin += (old_rows - new_rows) * old_row_size;
+
+ if (vc->vc_y > new_rows) {
+ if (old_rows - vc->vc_y < new_rows) {
+ /*
+ * Cursor near the bottom, copy contents from the
+ * bottom of buffer
+ */
+ old_origin += (old_rows - new_rows) * old_row_size;
+ end = vc->vc_scr_end;
+ } else {
+ /*
+ * Cursor is in no man's land, copy 1/2 screenful
+ * from the top and bottom of cursor position
+ */
+ old_origin += (vc->vc_y - new_rows/2) * old_row_size;
+ end = old_origin + new_screen_size;
+ }
+ } else
+ /*
+ * Cursor near the top, copy contents from the top of buffer
+ */
+ end = (old_rows > new_rows) ? old_origin + new_screen_size :
+ vc->vc_scr_end;
update_attr(vc);
- while (old_origin < vc->vc_scr_end) {
- scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth);
+ while (old_origin < end) {
+ scr_memcpyw((unsigned short *) new_origin,
+ (unsigned short *) old_origin, rlth);
if (rrem)
- scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem);
+ scr_memsetw((void *)(new_origin + rlth),
+ vc->vc_video_erase_char, rrem);
old_origin += old_row_size;
new_origin += new_row_size;
}
if (new_scr_end > new_origin)
- scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin);
+ scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
+ new_scr_end - new_origin);
if (vc->vc_kmalloced)
kfree(vc->vc_screenbuf);
vc->vc_screenbuf = newscreen;
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c9b301dccec..7fc2188386d 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 */
static int watchdog_port;
static int mixcomwd_timer_alive;
-static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0);
static char expect_close;
static int nowayout = WATCHDOG_NOWAYOUT;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 10b01498238..109d62ccf65 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)
ret = kobject_register(&policy->kobj);
if (ret)
- goto err_out;
+ goto err_out_driver_exit;
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
@@ -673,6 +673,10 @@ err_out_unregister:
kobject_unregister(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
+err_out_driver_exit:
+ if (cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
+
err_out:
kfree(policy);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6e9da137222..8334496a7e0 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -144,6 +144,22 @@ config I2C_I810
This driver can also be built as a module. If so, the module
will be called i2c-i810.
+config I2C_PXA
+ tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
+ depends on I2C && EXPERIMENTAL && ARCH_PXA
+ help
+ If you have devices in the PXA I2C bus, say yes to this option.
+ This driver can also be built as a module. If so, the module
+ will be called i2c-pxa.
+
+config I2C_PXA_SLAVE
+ bool "Intel PXA2XX I2C Slave comms support"
+ depends on I2C_PXA
+ help
+ Support I2C slave mode communications on the PXA I2C bus. This
+ is necessary for systems where the PXA may be a target on the
+ I2C bus.
+
config I2C_PIIX4
tristate "Intel PIIX4"
depends on I2C && PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 42d6d814da7..980b3e98367 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
+obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(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 00000000000..fdf53ce0424
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -0,0 +1,1022 @@
+/*
+ * i2c_adap_pxa.c
+ *
+ * I2C adapter for the PXA I2C bus access.
+ *
+ * Copyright (C) 2002 Intrinsyc Software Inc.
+ * Copyright (C) 2004-2005 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * History:
+ * Apr 2002: Initial version [CS]
+ * Jun 2002: Properly seperated algo/adap [FB]
+ * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
+ * Sep 2004: Major rework to ensure efficient bus handling [RMK]
+ * Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
+ * Feb 2005: Rework slave mode handling [RMK]
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/i2c-pxa.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/i2c.h>
+#include <asm/arch/pxa-regs.h>
+
+struct pxa_i2c {
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int msg_idx;
+ unsigned int msg_ptr;
+ unsigned int slave_addr;
+
+ struct i2c_adapter adap;
+#ifdef CONFIG_I2C_PXA_SLAVE
+ struct i2c_slave_client *slave;
+#endif
+
+ unsigned int irqlogidx;
+ u32 isrlog[32];
+ u32 icrlog[32];
+};
+
+/*
+ * I2C Slave mode address
+ */
+#define I2C_PXA_SLAVE_ADDR 0x1
+
+#ifdef DEBUG
+
+struct bits {
+ u32 mask;
+ const char *set;
+ const char *unset;
+};
+#define BIT(m, s, u) { .mask = m, .set = s, .unset = u }
+
+static inline void
+decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
+{
+ printk("%s %08x: ", prefix, val);
+ while (num--) {
+ const char *str = val & bits->mask ? bits->set : bits->unset;
+ if (str)
+ printk("%s ", str);
+ bits++;
+ }
+}
+
+static const struct bits isr_bits[] = {
+ BIT(ISR_RWM, "RX", "TX"),
+ BIT(ISR_ACKNAK, "NAK", "ACK"),
+ BIT(ISR_UB, "Bsy", "Rdy"),
+ BIT(ISR_IBB, "BusBsy", "BusRdy"),
+ BIT(ISR_SSD, "SlaveStop", NULL),
+ BIT(ISR_ALD, "ALD", NULL),
+ BIT(ISR_ITE, "TxEmpty", NULL),
+ BIT(ISR_IRF, "RxFull", NULL),
+ BIT(ISR_GCAD, "GenCall", NULL),
+ BIT(ISR_SAD, "SlaveAddr", NULL),
+ BIT(ISR_BED, "BusErr", NULL),
+};
+
+static void decode_ISR(unsigned int val)
+{
+ decode_bits(KERN_DEBUG "ISR", isr_bits, ARRAY_SIZE(isr_bits), val);
+ printk("\n");
+}
+
+static const struct bits icr_bits[] = {
+ BIT(ICR_START, "START", NULL),
+ BIT(ICR_STOP, "STOP", NULL),
+ BIT(ICR_ACKNAK, "ACKNAK", NULL),
+ BIT(ICR_TB, "TB", NULL),
+ BIT(ICR_MA, "MA", NULL),
+ BIT(ICR_SCLE, "SCLE", "scle"),
+ BIT(ICR_IUE, "IUE", "iue"),
+ BIT(ICR_GCD, "GCD", NULL),
+ BIT(ICR_ITEIE, "ITEIE", NULL),
+ BIT(ICR_IRFIE, "IRFIE", NULL),
+ BIT(ICR_BEIE, "BEIE", NULL),
+ BIT(ICR_SSDIE, "SSDIE", NULL),
+ BIT(ICR_ALDIE, "ALDIE", NULL),
+ BIT(ICR_SADIE, "SADIE", NULL),
+ BIT(ICR_UR, "UR", "ur"),
+};
+
+static void decode_ICR(unsigned int val)
+{
+ decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val);
+ printk("\n");
+}
+
+static unsigned int i2c_debug = DEBUG;
+
+static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
+{
+ dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR);
+}
+
+#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
+#else
+#define i2c_debug 0
+
+#define show_state(i2c) do { } while (0)
+#define decode_ISR(val) do { } while (0)
+#define decode_ICR(val) do { } while (0)
+#endif
+
+#define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
+
+static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
+
+static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
+{
+ unsigned int i;
+ printk("i2c: error: %s\n", why);
+ printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+ i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
+ printk("i2c: ICR: %08x ISR: %08x\n"
+ "i2c: log: ", ICR, ISR);
+ for (i = 0; i < i2c->irqlogidx; i++)
+ printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
+ printk("\n");
+}
+
+static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
+{
+ return !(ICR & ICR_SCLE);
+}
+
+static void i2c_pxa_abort(struct pxa_i2c *i2c)
+{
+ unsigned long timeout = jiffies + HZ/4;
+
+ if (i2c_pxa_is_slavemode(i2c)) {
+ dev_dbg(&i2c->adap.dev, "%s: called in slave mode\n", __func__);
+ return;
+ }
+
+ while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) {
+ unsigned long icr = ICR;
+
+ icr &= ~ICR_START;
+ icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
+
+ ICR = icr;
+
+ show_state(i2c);
+
+ msleep(1);
+ }
+
+ ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
+}
+
+static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
+{
+ int timeout = DEF_TIMEOUT;
+
+ while (timeout-- && ISR & (ISR_IBB | ISR_UB)) {
+ if ((ISR & ISR_SAD) != 0)
+ timeout += 4;
+
+ msleep(2);
+ show_state(i2c);
+ }
+
+ if (timeout <= 0)
+ show_state(i2c);
+
+ return timeout <= 0 ? I2C_RETRY : 0;
+}
+
+static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
+{
+ unsigned long timeout = jiffies + HZ*4;
+
+ while (time_before(jiffies, timeout)) {
+ if (i2c_debug > 1)
+ dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+ __func__, (long)jiffies, ISR, ICR, IBMR);
+
+ if (ISR & ISR_SAD) {
+ if (i2c_debug > 0)
+ dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
+ goto out;
+ }
+
+ /* wait for unit and bus being not busy, and we also do a
+ * quick check of the i2c lines themselves to ensure they've
+ * gone high...
+ */
+ if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) {
+ if (i2c_debug > 0)
+ dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
+ return 1;
+ }
+
+ msleep(1);
+ }
+
+ if (i2c_debug > 0)
+ dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
+ out:
+ return 0;
+}
+
+static int i2c_pxa_set_master(struct pxa_i2c *i2c)
+{
+ if (i2c_debug)
+ dev_dbg(&i2c->adap.dev, "setting to bus master\n");
+
+ if ((ISR & (ISR_UB | ISR_IBB)) != 0) {
+ dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
+ if (!i2c_pxa_wait_master(i2c)) {
+ dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
+ return I2C_RETRY;
+ }
+ }
+
+ ICR |= ICR_SCLE;
+ return 0;
+}
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
+{
+ unsigned long timeout = jiffies + HZ*1;
+
+ /* wait for stop */
+
+ show_state(i2c);
+
+ while (time_before(jiffies, timeout)) {
+ if (i2c_debug > 1)
+ dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+ __func__, (long)jiffies, ISR, ICR, IBMR);
+
+ if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD ||
+ (ICR & ICR_SCLE) == 0) {
+ if (i2c_debug > 1)
+ dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
+ return 1;
+ }
+
+ msleep(1);
+ }
+
+ if (i2c_debug > 0)
+ dev_dbg(&i2c->adap.dev, "%s: did not free\n", __func__);
+ return 0;
+}
+
+/*
+ * clear the hold on the bus, and take of anything else
+ * that has been configured
+ */
+static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
+{
+ show_state(i2c);
+
+ if (errcode < 0) {
+ udelay(100); /* simple delay */
+ } else {
+ /* we need to wait for the stop condition to end */
+
+ /* if we where in stop, then clear... */
+ if (ICR & ICR_STOP) {
+ udelay(100);
+ ICR &= ~ICR_STOP;
+ }
+
+ if (!i2c_pxa_wait_slave(i2c)) {
+ dev_err(&i2c->adap.dev, "%s: wait timedout\n",
+ __func__);
+ return;
+ }
+ }
+
+ ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA);
+ ICR &= ~ICR_SCLE;
+
+ if (i2c_debug) {
+ dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR);
+ decode_ICR(ICR);
+ }
+}
+#else
+#define i2c_pxa_set_slave(i2c, err) do { } while (0)
+#endif
+
+static void i2c_pxa_reset(struct pxa_i2c *i2c)
+{
+ pr_debug("Resetting I2C Controller Unit\n");
+
+ /* abort any transfer currently under way */
+ i2c_pxa_abort(i2c);
+
+ /* reset according to 9.8 */
+ ICR = ICR_UR;
+ ISR = I2C_ISR_INIT;
+ ICR &= ~ICR_UR;
+
+ ISAR = i2c->slave_addr;
+
+ /* set control register values */
+ ICR = I2C_ICR_INIT;
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+ dev_info(&i2c->adap.dev, "Enabling slave mode\n");
+ ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE;
+#endif
+
+ i2c_pxa_set_slave(i2c, 0);
+
+ /* enable unit */
+ ICR |= ICR_IUE;
+ udelay(100);
+}
+
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+/*
+ * I2C EEPROM emulation.
+ */
+static struct i2c_eeprom_emu eeprom = {
+ .size = I2C_EEPROM_EMU_SIZE,
+ .watch = LIST_HEAD_INIT(eeprom.watch),
+};
+
+struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void)
+{
+ return &eeprom;
+}
+
+int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *emu, void *data,
+ unsigned int addr, unsigned int size,
+ struct i2c_eeprom_emu_watcher *watcher)
+{
+ struct i2c_eeprom_emu_watch *watch;
+ unsigned long flags;
+
+ if (addr + size > emu->size)
+ return -EINVAL;
+
+ watch = kmalloc(sizeof(struct i2c_eeprom_emu_watch), GFP_KERNEL);
+ if (watch) {
+ watch->start = addr;
+ watch->end = addr + size - 1;
+ watch->ops = watcher;
+ watch->data = data;
+
+ local_irq_save(flags);
+ list_add(&watch->node, &emu->watch);
+ local_irq_restore(flags);
+ }
+
+ return watch ? 0 : -ENOMEM;
+}
+
+void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *emu, void *data,
+ struct i2c_eeprom_emu_watcher *watcher)
+{
+ struct i2c_eeprom_emu_watch *watch, *n;
+ unsigned long flags;
+
+ list_for_each_entry_safe(watch, n, &emu->watch, node) {
+ if (watch->ops == watcher && watch->data == data) {
+ local_irq_save(flags);
+ list_del(&watch->node);
+ local_irq_restore(flags);
+ kfree(watch);
+ }
+ }
+}
+
+static void i2c_eeprom_emu_event(void *ptr, i2c_slave_event_t event)
+{
+ struct i2c_eeprom_emu *emu = ptr;
+
+ eedbg(3, "i2c_eeprom_emu_event: %d\n", event);
+
+ switch (event) {
+ case I2C_SLAVE_EVENT_START_WRITE:
+ emu->seen_start = 1;
+ eedbg(2, "i2c_eeprom: write initiated\n");
+ break;
+
+ case I2C_SLAVE_EVENT_START_READ:
+ emu->seen_start = 0;
+ eedbg(2, "i2c_eeprom: read initiated\n");
+ break;
+
+ case I2C_SLAVE_EVENT_STOP:
+ emu->seen_start = 0;
+ eedbg(2, "i2c_eeprom: received stop\n");
+ break;
+
+ default:
+ eedbg(0, "i2c_eeprom: unhandled event\n");
+ break;
+ }
+}
+
+static int i2c_eeprom_emu_read(void *ptr)
+{
+ struct i2c_eeprom_emu *emu = ptr;
+ int ret;
+
+ ret = emu->bytes[emu->ptr];
+ emu->ptr = (emu->ptr + 1) % emu->size;
+
+ return ret;
+}
+
+static void i2c_eeprom_emu_write(void *ptr, unsigned int val)
+{
+ struct i2c_eeprom_emu *emu = ptr;
+ struct i2c_eeprom_emu_watch *watch;
+
+ if (emu->seen_start != 0) {
+ eedbg(2, "i2c_eeprom_emu_write: setting ptr %02x\n", val);
+ emu->ptr = val;
+ emu->seen_start = 0;
+ return;
+ }
+
+ emu->bytes[emu->ptr] = val;
+
+ eedbg(1, "i2c_eeprom_emu_write: ptr=0x%02x, val=0x%02x\n",
+ emu->ptr, val);
+
+ list_for_each_entry(watch, &emu->watch, node) {
+ if (!watch->ops || !watch->ops->write)
+ continue;
+ if (watch->start <= emu->ptr && watch->end >= emu->ptr)
+ watch->ops->write(watch->data, emu->ptr, val);
+ }
+
+ emu->ptr = (emu->ptr + 1) % emu->size;
+}
+
+struct i2c_slave_client eeprom_client = {
+ .data = &eeprom,
+ .event = i2c_eeprom_emu_event,
+ .read = i2c_eeprom_emu_read,
+ .write = i2c_eeprom_emu_write
+};
+
+/*
+ * PXA I2C Slave mode
+ */
+
+static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+ if (isr & ISR_BED) {
+ /* what should we do here? */
+ } else {
+ int ret = i2c->slave->read(i2c->slave->data);
+
+ IDBR = ret;
+ ICR |= ICR_TB; /* allow next byte */
+ }
+}
+
+static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+ unsigned int byte = IDBR;
+
+ if (i2c->slave != NULL)
+ i2c->slave->write(i2c->slave->data, byte);
+
+ ICR |= ICR_TB;
+}
+
+static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
+{
+ int timeout;
+
+ if (i2c_debug > 0)
+ dev_dbg(&i2c->adap.dev, "SAD, mode is slave-%cx\n",
+ (isr & ISR_RWM) ? 'r' : 't');
+
+ if (i2c->slave != NULL)
+ i2c->slave->event(i2c->slave->data,
+ (isr & ISR_RWM) ? I2C_SLAVE_EVENT_START_READ : I2C_SLAVE_EVENT_START_WRITE);
+
+ /*
+ * slave could interrupt in the middle of us generating a
+ * start condition... if this happens, we'd better back off
+ * and stop holding the poor thing up
+ */
+ ICR &= ~(ICR_START|ICR_STOP);
+ ICR |= ICR_TB;
+
+ timeout = 0x10000;
+
+ while (1) {
+ if ((IBMR & 2) == 2)
+ break;
+
+ timeout--;
+
+ if (timeout <= 0) {
+ dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
+ break;
+ }
+ }
+
+ ICR &= ~ICR_SCLE;
+}
+
+static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
+{
+ if (i2c_debug > 2)
+ dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop)\n");
+
+ if (i2c->slave != NULL)
+ i2c->slave->event(i2c->slave->data, I2C_SLAVE_EVENT_STOP);
+
+ if (i2c_debug > 2)
+ dev_dbg(&i2c->adap.dev, "ISR: SSD (Slave Stop) acked\n");
+
+ /*
+ * If we have a master-mode message waiting,
+ * kick it off now that the slave has completed.
+ */
+ if (i2c->msg)
+ i2c_pxa_master_complete(i2c, I2C_RETRY);
+}
+#else
+static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+ if (isr & ISR_BED) {
+ /* what should we do here? */
+ } else {
+ IDBR = 0;
+ ICR |= ICR_TB;
+ }
+}
+
+static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+ ICR |= ICR_TB | ICR_ACKNAK;
+}
+
+static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
+{
+ int timeout;
+
+ /*
+ * slave could interrupt in the middle of us generating a
+ * start condition... if this happens, we'd better back off
+ * and stop holding the poor thing up
+ */
+ ICR &= ~(ICR_START|ICR_STOP);
+ ICR |= ICR_TB | ICR_ACKNAK;
+
+ timeout = 0x10000;
+
+ while (1) {
+ if ((IBMR & 2) == 2)
+ break;
+
+ timeout--;
+
+ if (timeout <= 0) {
+ dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
+ break;
+ }
+ }
+
+ ICR &= ~ICR_SCLE;
+}
+
+static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
+{
+ if (i2c->msg)
+ i2c_pxa_master_complete(i2c, I2C_RETRY);
+}
+#endif
+
+/*
+ * PXA I2C Master mode
+ */
+
+static inline unsigned int i2c_pxa_addr_byte(struct i2c_msg *msg)
+{
+ unsigned int addr = (msg->addr & 0x7f) << 1;
+
+ if (msg->flags & I2C_M_RD)
+ addr |= 1;
+
+ return addr;
+}
+
+static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
+{
+ u32 icr;
+
+ /*
+ * Step 1: target slave address into IDBR
+ */
+ IDBR = i2c_pxa_addr_byte(i2c->msg);
+
+ /*
+ * Step 2: initiate the write.
+ */
+ icr = ICR & ~(ICR_STOP | ICR_ALDIE);
+ ICR = icr | ICR_START | ICR_TB;
+}
+
+/*
+ * We are protected by the adapter bus semaphore.
+ */
+static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
+{
+ long timeout;
+ int ret;
+
+ /*
+ * Wait for the bus to become free.
+ */
+ ret = i2c_pxa_wait_bus_not_busy(i2c);
+ if (ret) {
+ dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
+ goto out;
+ }
+
+ /*
+ * Set master mode.
+ */
+ ret = i2c_pxa_set_master(i2c);
+ if (ret) {
+ dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
+ goto out;
+ }
+
+ spin_lock_irq(&i2c->lock);
+
+ i2c->msg = msg;
+ i2c->msg_num = num;
+ i2c->msg_idx = 0;
+ i2c->msg_ptr = 0;
+ i2c->irqlogidx = 0;
+
+ i2c_pxa_start_message(i2c);
+
+ spin_unlock_irq(&i2c->lock);
+
+ /*
+ * The rest of the processing occurs in the interrupt handler.
+ */
+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+
+ /*
+ * We place the return code in i2c->msg_idx.
+ */
+ ret = i2c->msg_idx;
+
+ if (timeout == 0)
+ i2c_pxa_scream_blue_murder(i2c, "timeout");
+
+ out:
+ return ret;
+}
+
+/*
+ * i2c_pxa_master_complete - complete the message and wake up.
+ */
+static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
+{
+ i2c->msg_ptr = 0;
+ i2c->msg = NULL;
+ i2c->msg_idx ++;
+ i2c->msg_num = 0;
+ if (ret)
+ i2c->msg_idx = ret;
+ wake_up(&i2c->wait);
+}
+
+static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
+{
+ u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+
+ again:
+ /*
+ * If ISR_ALD is set, we lost arbitration.
+ */
+ if (isr & ISR_ALD) {
+ /*
+ * Do we need to do anything here? The PXA docs
+ * are vague about what happens.
+ */
+ i2c_pxa_scream_blue_murder(i2c, "ALD set");
+
+ /*
+ * We ignore this error. We seem to see spurious ALDs
+ * for seemingly no reason. If we handle them as I think
+ * they should, we end up causing an I2C error, which
+ * is painful for some systems.
+ */
+ return; /* ignore */
+ }
+
+ if (isr & ISR_BED) {
+ int ret = BUS_ERROR;
+
+ /*
+ * I2C bus error - either the device NAK'd us, or
+ * something more serious happened. If we were NAK'd
+ * on the initial address phase, we can retry.
+ */
+ if (isr & ISR_ACKNAK) {
+ if (i2c->msg_ptr == 0 && i2c->msg_idx == 0)
+ ret = I2C_RETRY;
+ else
+ ret = XFER_NAKED;
+ }
+ i2c_pxa_master_complete(i2c, ret);
+ } else if (isr & ISR_RWM) {
+ /*
+ * Read mode. We have just sent the address byte, and
+ * now we must initiate the transfer.
+ */
+ if (i2c->msg_ptr == i2c->msg->len - 1 &&
+ i2c->msg_idx == i2c->msg_num - 1)
+ icr |= ICR_STOP | ICR_ACKNAK;
+
+ icr |= ICR_ALDIE | ICR_TB;
+ } else if (i2c->msg_ptr < i2c->msg->len) {
+ /*
+ * Write mode. Write the next data byte.
+ */
+ IDBR = i2c->msg->buf[i2c->msg_ptr++];
+
+ icr |= ICR_ALDIE | ICR_TB;
+
+ /*
+ * If this is the last byte of the last message, send
+ * a STOP.
+ */
+ if (i2c->msg_ptr == i2c->msg->len &&
+ i2c->msg_idx == i2c->msg_num - 1)
+ icr |= ICR_STOP;
+ } else if (i2c->msg_idx < i2c->msg_num - 1) {
+ /*
+ * Next segment of the message.
+ */
+ i2c->msg_ptr = 0;
+ i2c->msg_idx ++;
+ i2c->msg++;
+
+ /*
+ * If we aren't doing a repeated start and address,
+ * go back and try to send the next byte. Note that
+ * we do not support switching the R/W direction here.
+ */
+ if (i2c->msg->flags & I2C_M_NOSTART)
+ goto again;
+
+ /*
+ * Write the next address.
+ */
+ IDBR = i2c_pxa_addr_byte(i2c->msg);
+
+ /*
+ * And trigger a repeated start, and send the byte.
+ */
+ icr &= ~ICR_ALDIE;
+ icr |= ICR_START | ICR_TB;
+ } else {
+ if (i2c->msg->len == 0) {
+ /*
+ * Device probes have a message length of zero
+ * and need the bus to be reset before it can
+ * be used again.
+ */
+ i2c_pxa_reset(i2c);
+ }
+ i2c_pxa_master_complete(i2c, 0);
+ }
+
+ i2c->icrlog[i2c->irqlogidx-1] = icr;
+
+ ICR = icr;
+ show_state(i2c);
+}
+
+static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
+{
+ u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+
+ /*
+ * Read the byte.
+ */
+ i2c->msg->buf[i2c->msg_ptr++] = IDBR;
+
+ if (i2c->msg_ptr < i2c->msg->len) {
+ /*
+ * If this is the last byte of the last
+ * message, send a STOP.
+ */
+ if (i2c->msg_ptr == i2c->msg->len - 1)
+ icr |= ICR_STOP | ICR_ACKNAK;
+
+ icr |= ICR_ALDIE | ICR_TB;
+ } else {
+ i2c_pxa_master_complete(i2c, 0);
+ }
+
+ i2c->icrlog[i2c->irqlogidx-1] = icr;
+
+ ICR = icr;
+}
+
+static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pxa_i2c *i2c = dev_id;
+ u32 isr = ISR;
+
+ if (i2c_debug > 2 && 0) {
+ dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
+ __func__, isr, ICR, IBMR);
+ decode_ISR(isr);
+ }
+
+ if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
+ i2c->isrlog[i2c->irqlogidx++] = isr;
+
+ show_state(i2c);
+
+ /*
+ * Always clear all pending IRQs.
+ */
+ ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED);
+
+ if (isr & ISR_SAD)
+ i2c_pxa_slave_start(i2c, isr);
+ if (isr & ISR_SSD)
+ i2c_pxa_slave_stop(i2c);
+
+ if (i2c_pxa_is_slavemode(i2c)) {
+ if (isr & ISR_ITE)
+ i2c_pxa_slave_txempty(i2c, isr);
+ if (isr & ISR_IRF)
+ i2c_pxa_slave_rxfull(i2c, isr);
+ } else if (i2c->msg) {
+ if (isr & ISR_ITE)
+ i2c_pxa_irq_txempty(i2c, isr);
+ if (isr & ISR_IRF)
+ i2c_pxa_irq_rxfull(i2c, isr);
+ } else {
+ i2c_pxa_scream_blue_murder(i2c, "spurious irq");
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ struct pxa_i2c *i2c = adap->algo_data;
+ int ret, i;
+
+ for (i = adap->retries; i >= 0; i--) {
+ ret = i2c_pxa_do_xfer(i2c, msgs, num);
+ if (ret != I2C_RETRY)
+ goto out;
+
+ if (i2c_debug)
+ dev_dbg(&adap->dev, "Retrying transmission\n");
+ udelay(100);
+ }
+ i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
+ ret = -EREMOTEIO;
+ out:
+ i2c_pxa_set_slave(i2c, ret);
+ return ret;
+}
+
+static struct i2c_algorithm i2c_pxa_algorithm = {
+ .name = "PXA-I2C-Algorithm",
+ .id = I2C_ALGO_PXA,
+ .master_xfer = i2c_pxa_xfer,
+};
+
+static struct pxa_i2c i2c_pxa = {
+ .lock = SPIN_LOCK_UNLOCKED,
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
+ .adap = {
+ .name = "pxa2xx-i2c",
+ .id = I2C_ALGO_PXA,
+ .algo = &i2c_pxa_algorithm,
+ .retries = 5,
+ },
+};
+
+static int i2c_pxa_probe(struct device *dev)
+{
+ struct pxa_i2c *i2c = &i2c_pxa;
+ struct i2c_pxa_platform_data *plat = dev->platform_data;
+ int ret;
+
+#ifdef CONFIG_PXA27x
+ pxa_gpio_mode(GPIO117_I2CSCL_MD);
+ pxa_gpio_mode(GPIO118_I2CSDA_MD);
+ udelay(100);
+#endif
+
+ i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+ i2c->slave = &eeprom_client;
+ if (plat) {
+ i2c->slave_addr = plat->slave_addr;
+ if (plat->slave)
+ i2c->slave = plat->slave;
+ }
+#endif
+
+ pxa_set_cken(CKEN14_I2C, 1);
+ ret = request_irq(IRQ_I2C, i2c_pxa_handler, SA_INTERRUPT,
+ "pxa2xx-i2c", i2c);
+ if (ret)
+ goto out;
+
+ i2c_pxa_reset(i2c);
+
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = dev;
+
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret < 0) {
+ printk(KERN_INFO "I2C: Failed to add bus\n");
+ goto err_irq;
+ }
+
+ dev_set_drvdata(dev, i2c);
+
+#ifdef CONFIG_I2C_PXA_SLAVE
+ printk(KERN_INFO "I2C: %s: PXA I2C adapter, slave address %d\n",
+ i2c->adap.dev.bus_id, i2c->slave_addr);
+#else
+ printk(KERN_INFO "I2C: %s: PXA I2C adapter\n",
+ i2c->adap.dev.bus_id);
+#endif
+ return 0;
+
+ err_irq:
+ free_irq(IRQ_I2C, i2c);
+ out:
+ return ret;
+}
+
+static int i2c_pxa_remove(struct device *dev)
+{
+ struct pxa_i2c *i2c = dev_get_drvdata(dev);
+
+ dev_set_drvdata(dev, NULL);
+
+ i2c_del_adapter(&i2c->adap);
+ free_irq(IRQ_I2C, i2c);
+ pxa_set_cken(CKEN14_I2C, 0);
+
+ return 0;
+}
+
+static struct device_driver i2c_pxa_driver = {
+ .name = "pxa2xx-i2c",
+ .bus = &platform_bus_type,
+ .probe = i2c_pxa_probe,
+ .remove = i2c_pxa_remove,
+};
+
+static int __init i2c_adap_pxa_init(void)
+{
+ return driver_register(&i2c_pxa_driver);
+}
+
+static void i2c_adap_pxa_exit(void)
+{
+ return driver_unregister(&i2c_pxa_driver);
+}
+
+module_init(i2c_adap_pxa_init);
+module_exit(i2c_adap_pxa_exit);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index f1d1ec4e967..dc0841b2721 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,
static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4),
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
+ PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
+ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
+ PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
- PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
+ PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
@@ -481,6 +484,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
+ PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e),
PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
PCMCIA_DEVICE_NULL,
};
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 06759b36afe..9d6facf2f78 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -883,7 +883,7 @@ static int __video1394_ioctl(struct file *file,
v.channel);
}
- if (copy_to_user((void *)arg, &v, sizeof(v))) {
+ if (copy_to_user(argp, &v, sizeof(v))) {
/* FIXME : free allocated dma resources */
return -EFAULT;
}
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 3241d6c9dc1..ffbcd40418d 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,
++mthca_version_printed;
}
- printk(KERN_INFO PFX "Initializing %s (%s)\n",
- pci_pretty_name(pdev), pci_name(pdev));
+ printk(KERN_INFO PFX "Initializing %s\n",
+ pci_name(pdev));
if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
- printk(KERN_ERR PFX "%s (%s) has invalid driver data %lx\n",
- pci_pretty_name(pdev), pci_name(pdev), id->driver_data);
+ printk(KERN_ERR PFX "%s has invalid driver data %lx\n",
+ pci_name(pdev), id->driver_data);
return -ENODEV;
}
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index 8ea801271a4..4f995391dd1 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)
bridge)) != NULL) {
if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
bridge->subordinate == mdev->pdev->bus) {
- mthca_dbg(mdev, "Found bridge: %s (%s)\n",
- pci_pretty_name(bridge), pci_name(bridge));
+ mthca_dbg(mdev, "Found bridge: %s\n",
+ pci_name(bridge));
break;
}
}
@@ -83,8 +83,8 @@ int mthca_reset(struct mthca_dev *mdev)
* assume we're in no-bridge mode and hope for
* the best.
*/
- mthca_warn(mdev, "No bridge found for %s (%s)\n",
- pci_pretty_name(mdev->pdev), pci_name(mdev->pdev));
+ mthca_warn(mdev, "No bridge found for %s\n",
+ pci_name(mdev->pdev));
}
}
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 19c14c4beb4..60b696e9336 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -509,7 +509,7 @@ do { \
int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
for (i = 0; i < len / sizeof(compat_long_t); i++) \
- if (copy_to_user((compat_long_t*) p + i, \
+ if (copy_to_user((compat_long_t __user *) p + i, \
(compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
sizeof(compat_long_t))) \
return -EFAULT; \
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 20ca80b7dc2..373ab92e367 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)
return 0;
}
-static int get_bitmap_file(mddev_t * mddev, void * arg)
+static int get_bitmap_file(mddev_t * mddev, void __user * arg)
{
mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */
char *ptr, *buf = NULL;
@@ -2781,7 +2781,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto done_unlock;
case GET_BITMAP_FILE:
- err = get_bitmap_file(mddev, (void *)arg);
+ err = get_bitmap_file(mddev, argp);
goto done_unlock;
case GET_DISK_INFO:
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 772d6112fb3..c578a529e7a 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,4 +2,7 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := video/ radio/ dvb/ common/
+obj-y := common/
+obj-$(CONFIG_VIDEO_DEV) += video/
+obj-$(CONFIG_VIDEO_DEV) += radio/
+obj-$(CONFIG_DVB) += dvb/
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index ab7a1fba442..a0e700d7a4a 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,4 @@
/*
- * $Id: ir-common.c,v 1.11 2005/07/07 14:44:43 mchehab Exp $
*
* some common structs and functions to handle infrared remotes via
* input layer ...
@@ -335,6 +334,72 @@ int ir_dump_samples(u32 *samples, int count)
return 0;
}
+/* decode raw samples, pulse distance coding used by NEC remotes */
+int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
+{
+ int i,last,bit,len;
+ u32 curBit;
+ u32 value;
+
+ /* find start burst */
+ for (i = len = 0; i < count * 32; i++) {
+ bit = getbit(samples,i);
+ if (bit) {
+ len++;
+ } else {
+ if (len >= 29)
+ break;
+ len = 0;
+ }
+ }
+
+ /* start burst to short */
+ if (len < 29)
+ return 0xffffffff;
+
+ /* find start silence */
+ for (len = 0; i < count * 32; i++) {
+ bit = getbit(samples,i);
+ if (bit) {
+ break;
+ } else {
+ len++;
+ }
+ }
+
+ /* silence to short */
+ if (len < 7)
+ return 0xffffffff;
+
+ /* go decoding */
+ len = 0;
+ last = 1;
+ value = 0; curBit = 1;
+ for (; i < count * 32; i++) {
+ bit = getbit(samples,i);
+ if (last) {
+ if(bit) {
+ continue;
+ } else {
+ len = 1;
+ }
+ } else {
+ if (bit) {
+ if (len > (low + high) /2)
+ value |= curBit;
+ curBit <<= 1;
+ if (curBit == 1)
+ break;
+ } else {
+ len++;
+ }
+ }
+ last = bit;
+ }
+
+ return value;
+}
+
/* decode raw samples, biphase coding, used by rc5 for example */
int ir_decode_biphase(u32 *samples, int count, int low, int high)
{
@@ -383,6 +448,7 @@ EXPORT_SYMBOL_GPL(ir_input_keydown);
EXPORT_SYMBOL_GPL(ir_extract_bits);
EXPORT_SYMBOL_GPL(ir_dump_samples);
EXPORT_SYMBOL_GPL(ir_decode_biphase);
+EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
/*
* Local variables:
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index c04fd11526e..37888989ea2 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -1,5 +1,4 @@
#include <media/saa7146_vv.h>
-#include <linux/version.h>
#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index 6284894505c..fec6beab8c2 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -1,4 +1,3 @@
-#include <linux/version.h>
#include <media/saa7146_vv.h>
static 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
saa7146_i2c_reset(dev);
if( NULL != i2c_adapter ) {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- i2c_adapter->data = dev;
-#else
BUG_ON(!i2c_adapter->class);
i2c_set_adapdata(i2c_adapter,dev);
-#endif
+ i2c_adapter->dev.parent = &dev->pci->dev;
i2c_adapter->algo = &saa7146_algo;
i2c_adapter->algo_data = NULL;
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 0410cc96a48..47e28b0ee95 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,
return 0;
}
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct flexcop_device *fc = fe->dvb->priv;
div = params->frequency / 125;
@@ -180,7 +179,7 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_fronten
if (params->frequency < 1500000) buf[3] |= 0x10;
- if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -335,8 +334,103 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
.pll_set = skystar23_samsung_tbdu18132_pll_set,
};
+
+static u8 alps_tdee4_stv0297_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x00,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0xf8,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x49,
+ 0x62, 0x0b,
+ 0x53, 0x08,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
+
static struct stv0297_config alps_tdee4_stv0297_config = {
.demod_address = 0x1c,
+ .inittab = alps_tdee4_stv0297_inittab,
// .invert = 1,
// .pll_set = alps_tdee4_stv0297_pll_set,
};
@@ -370,7 +464,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
} else
/* try the cable dvb (stv0297) */
- if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
+ if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_CABLE;
info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 3c5a8e273c4..f2957145003 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -1,7 +1,7 @@
/*
* bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
*
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
*
* large parts based on the bttv driver
* 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,
controlreg &= ~0x1f;
controlreg |= 0x1b;
- btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
+ btwrite(bt->risc_dma, BT878_ARISC_START);
/* original int mask had :
* 6 2 8 4 0
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index 837623f7fcd..a73baf00ca3 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -1,7 +1,7 @@
/*
bt878.h - Bt878 audio module (register offsets)
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 07a0b0a968a..34a837a1abf 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1,5 +1,4 @@
/*
-
Frontend/Card driver for TwinHan DST Frontend
Copyright (C) 2003 Jamie Honan
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
@@ -19,7 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -28,31 +26,45 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <asm/div64.h>
-
#include "dvb_frontend.h"
#include "dst_priv.h"
#include "dst_common.h"
-
static unsigned int verbose = 1;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-static unsigned int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
-
static unsigned int dst_addons;
module_param(dst_addons, int, 0644);
MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
-#define dprintk if (debug) printk
-
-#define HAS_LOCK 1
-#define ATTEMPT_TUNE 2
-#define HAS_POWER 4
-
-static void dst_packsize(struct dst_state* state, int psize)
+#define HAS_LOCK 1
+#define ATTEMPT_TUNE 2
+#define HAS_POWER 4
+
+#define DST_ERROR 0
+#define DST_NOTICE 1
+#define DST_INFO 2
+#define DST_DEBUG 3
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((x > DST_ERROR) && (x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_NOTICE) && (x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_INFO) && (x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_DEBUG) && (x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
+ } else { \
+ if (x > y) \
+ printk(format, ##arg); \
+ } \
+} while(0)
+
+
+static void dst_packsize(struct dst_state *state, int psize)
{
union dst_gpio_packet bits;
@@ -60,7 +72,7 @@ static void dst_packsize(struct dst_state* state, int psize)
bt878_device_control(state->bt, DST_IG_TS, &bits);
}
-int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
+int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int delay)
{
union dst_gpio_packet enb;
union dst_gpio_packet bits;
@@ -68,63 +80,55 @@ int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int
enb.enb.mask = mask;
enb.enb.enable = enbb;
- if (verbose > 4)
- dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
+ dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
- dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
+ dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
return -EREMOTEIO;
}
udelay(1000);
/* because complete disabling means no output, no need to do output packet */
if (enbb == 0)
return 0;
-
if (delay)
msleep(10);
-
bits.outp.mask = enbb;
bits.outp.highvals = outhigh;
-
if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
- dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
+ dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
return -EREMOTEIO;
}
+
return 0;
}
EXPORT_SYMBOL(dst_gpio_outb);
-int dst_gpio_inb(struct dst_state *state, u8 * result)
+int dst_gpio_inb(struct dst_state *state, u8 *result)
{
union dst_gpio_packet rd_packet;
int err;
*result = 0;
-
if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
- dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err);
return -EREMOTEIO;
}
-
*result = (u8) rd_packet.rd.value;
+
return 0;
}
EXPORT_SYMBOL(dst_gpio_inb);
int rdc_reset_state(struct dst_state *state)
{
- if (verbose > 1)
- dprintk("%s: Resetting state machine\n", __FUNCTION__);
-
+ dprintk(verbose, DST_INFO, 1, "Resetting state machine");
if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
-
msleep(10);
-
if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
msleep(10);
return -1;
}
@@ -135,16 +139,14 @@ EXPORT_SYMBOL(rdc_reset_state);
int rdc_8820_reset(struct dst_state *state)
{
- if (verbose > 1)
- dprintk("%s: Resetting DST\n", __FUNCTION__);
-
+ dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
udelay(1000);
if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
@@ -155,10 +157,11 @@ EXPORT_SYMBOL(rdc_8820_reset);
int dst_pio_enable(struct dst_state *state)
{
if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
udelay(1000);
+
return 0;
}
EXPORT_SYMBOL(dst_pio_enable);
@@ -166,7 +169,7 @@ EXPORT_SYMBOL(dst_pio_enable);
int dst_pio_disable(struct dst_state *state)
{
if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
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)
for (i = 0; i < 200; i++) {
if (dst_gpio_inb(state, &reply) < 0) {
- dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
return -1;
}
-
if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
- if (verbose > 4)
- dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
+ dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
return 1;
}
msleep(10);
}
- if (verbose > 1)
- dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
+ dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
return 0;
}
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(dst_wait_dst_ready);
int dst_error_recovery(struct dst_state *state)
{
- dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
+ dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
dst_pio_disable(state);
msleep(10);
dst_pio_enable(state);
@@ -215,7 +215,7 @@ EXPORT_SYMBOL(dst_error_recovery);
int dst_error_bailout(struct dst_state *state)
{
- dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
rdc_8820_reset(state);
dst_pio_disable(state);
msleep(10);
@@ -224,17 +224,15 @@ int dst_error_bailout(struct dst_state *state)
}
EXPORT_SYMBOL(dst_error_bailout);
-
-int dst_comm_init(struct dst_state* state)
+int dst_comm_init(struct dst_state *state)
{
- if (verbose > 1)
- dprintk ("%s: Initializing DST..\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Initializing DST.");
if ((dst_pio_enable(state)) < 0) {
- dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
return -1;
}
if ((rdc_reset_state(state)) < 0) {
- dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
return -1;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
@@ -246,36 +244,33 @@ int dst_comm_init(struct dst_state* state)
}
EXPORT_SYMBOL(dst_comm_init);
-
int write_dst(struct dst_state *state, u8 *data, u8 len)
{
struct i2c_msg msg = {
- .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = data,
+ .len = len
};
int err;
- int cnt;
- if (debug && (verbose > 4)) {
- u8 i;
- if (verbose > 4) {
- dprintk("%s writing [ ", __FUNCTION__);
- for (i = 0; i < len; i++)
- dprintk("%02x ", data[i]);
- dprintk("]\n");
- }
- }
+ u8 cnt, i;
+
+ dprintk(verbose, DST_NOTICE, 0, "writing [ ");
+ for (i = 0; i < len; i++)
+ dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
+ dprintk(verbose, DST_NOTICE, 0, "]\n");
+
for (cnt = 0; cnt < 2; cnt++) {
if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
- dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
+ dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
dst_error_recovery(state);
continue;
} else
break;
}
-
if (cnt >= 2) {
- if (verbose > 1)
- printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
dst_error_bailout(state);
return -1;
@@ -285,36 +280,37 @@ int write_dst(struct dst_state *state, u8 *data, u8 len)
}
EXPORT_SYMBOL(write_dst);
-int read_dst(struct dst_state *state, u8 * ret, u8 len)
+int read_dst(struct dst_state *state, u8 *ret, u8 len)
{
- struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = I2C_M_RD,
+ .buf = ret,
+ .len = len
+ };
+
int err;
int cnt;
for (cnt = 0; cnt < 2; cnt++) {
if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
-
- dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
+ dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
dst_error_recovery(state);
-
continue;
} else
break;
}
if (cnt >= 2) {
- if (verbose > 1)
- printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
dst_error_bailout(state);
return -1;
}
- if (debug && (verbose > 4)) {
- dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
- for (err = 1; err < len; err++)
- dprintk(" 0x%x", ret[err]);
- if (err > 1)
- dprintk("\n");
- }
+ dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
+ for (err = 1; err < len; err++)
+ dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
+ if (err > 1)
+ dprintk(verbose, DST_DEBUG, 0, "\n");
return 0;
}
@@ -323,19 +319,16 @@ EXPORT_SYMBOL(read_dst);
static int dst_set_polarization(struct dst_state *state)
{
switch (state->voltage) {
- case SEC_VOLTAGE_13: // vertical
- printk("%s: Polarization=[Vertical]\n", __FUNCTION__);
- state->tx_tuna[8] &= ~0x40; //1
- break;
-
- case SEC_VOLTAGE_18: // horizontal
- printk("%s: Polarization=[Horizontal]\n", __FUNCTION__);
- state->tx_tuna[8] |= 0x40; // 0
- break;
-
- case SEC_VOLTAGE_OFF:
-
- break;
+ case SEC_VOLTAGE_13: /* Vertical */
+ dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
+ state->tx_tuna[8] &= ~0x40;
+ break;
+ case SEC_VOLTAGE_18: /* Horizontal */
+ dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
+ state->tx_tuna[8] |= 0x40;
+ break;
+ case SEC_VOLTAGE_OFF:
+ break;
}
return 0;
@@ -344,14 +337,12 @@ static int dst_set_polarization(struct dst_state *state)
static int dst_set_freq(struct dst_state *state, u32 freq)
{
state->frequency = freq;
- if (debug > 4)
- dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
+ dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
if (state->dst_type == DST_TYPE_IS_SAT) {
freq = freq / 1000;
if (freq < 950 || freq > 2150)
return -EINVAL;
-
state->tx_tuna[2] = (freq >> 8);
state->tx_tuna[3] = (u8) freq;
state->tx_tuna[4] = 0x01;
@@ -360,27 +351,25 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
if (freq < 1531)
state->tx_tuna[8] |= 0x04;
}
-
} else if (state->dst_type == DST_TYPE_IS_TERR) {
freq = freq / 1000;
if (freq < 137000 || freq > 858000)
return -EINVAL;
-
state->tx_tuna[2] = (freq >> 16) & 0xff;
state->tx_tuna[3] = (freq >> 8) & 0xff;
state->tx_tuna[4] = (u8) freq;
-
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
+ freq = freq / 1000;
state->tx_tuna[2] = (freq >> 16) & 0xff;
state->tx_tuna[3] = (freq >> 8) & 0xff;
state->tx_tuna[4] = (u8) freq;
-
} else
return -EINVAL;
+
return 0;
}
-static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
+static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
{
state->bandwidth = bandwidth;
@@ -388,103 +377,95 @@ static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
return 0;
switch (bandwidth) {
- case BANDWIDTH_6_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x06;
- else {
- state->tx_tuna[6] = 0x06;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- case BANDWIDTH_7_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x07;
- else {
- state->tx_tuna[6] = 0x07;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- case BANDWIDTH_8_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x08;
- else {
- state->tx_tuna[6] = 0x08;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- default:
- return -EINVAL;
+ case BANDWIDTH_6_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x06;
+ else {
+ state->tx_tuna[6] = 0x06;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ case BANDWIDTH_7_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x07;
+ else {
+ state->tx_tuna[6] = 0x07;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ case BANDWIDTH_8_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x08;
+ else {
+ state->tx_tuna[6] = 0x08;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ default:
+ return -EINVAL;
}
+
return 0;
}
-static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
+static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
{
state->inversion = inversion;
switch (inversion) {
- case INVERSION_OFF: // Inversion = Normal
- state->tx_tuna[8] &= ~0x80;
- break;
-
- case INVERSION_ON:
- state->tx_tuna[8] |= 0x80;
- break;
- default:
- return -EINVAL;
+ case INVERSION_OFF: /* Inversion = Normal */
+ state->tx_tuna[8] &= ~0x80;
+ break;
+ case INVERSION_ON:
+ state->tx_tuna[8] |= 0x80;
+ break;
+ default:
+ return -EINVAL;
}
+
return 0;
}
-static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec)
+static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
{
state->fec = fec;
return 0;
}
-static fe_code_rate_t dst_get_fec(struct dst_state* state)
+static fe_code_rate_t dst_get_fec(struct dst_state *state)
{
return state->fec;
}
-static int dst_set_symbolrate(struct dst_state* state, u32 srate)
+static int dst_set_symbolrate(struct dst_state *state, u32 srate)
{
- u8 *val;
u32 symcalc;
u64 sval;
state->symbol_rate = srate;
-
if (state->dst_type == DST_TYPE_IS_TERR) {
return 0;
}
- if (debug > 4)
- dprintk("%s: set symrate %u\n", __FUNCTION__, srate);
+ dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
srate /= 1000;
- val = &state->tx_tuna[0];
-
if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
sval = srate;
sval <<= 20;
do_div(sval, 88000);
symcalc = (u32) sval;
-
- if (debug > 4)
- dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
-
- val[5] = (u8) (symcalc >> 12);
- val[6] = (u8) (symcalc >> 4);
- val[7] = (u8) (symcalc << 4);
+ dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
+ state->tx_tuna[5] = (u8) (symcalc >> 12);
+ state->tx_tuna[6] = (u8) (symcalc >> 4);
+ state->tx_tuna[7] = (u8) (symcalc << 4);
} else {
- val[5] = (u8) (srate >> 16) & 0x7f;
- val[6] = (u8) (srate >> 8);
- val[7] = (u8) srate;
+ state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
+ state->tx_tuna[6] = (u8) (srate >> 8);
+ state->tx_tuna[7] = (u8) srate;
+ }
+ state->tx_tuna[8] &= ~0x20;
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+ if (srate > 8000)
+ state->tx_tuna[8] |= 0x20;
}
- val[8] &= ~0x20;
- if (srate > 8000)
- val[8] |= 0x20;
return 0;
}
@@ -496,32 +477,27 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio
state->modulation = modulation;
switch (modulation) {
- case QAM_16:
- state->tx_tuna[8] = 0x10;
- break;
-
- case QAM_32:
- state->tx_tuna[8] = 0x20;
- break;
-
- case QAM_64:
- state->tx_tuna[8] = 0x40;
- break;
-
- case QAM_128:
- state->tx_tuna[8] = 0x80;
- break;
-
- case QAM_256:
- state->tx_tuna[8] = 0x00;
- break;
-
- case QPSK:
- case QAM_AUTO:
- case VSB_8:
- case VSB_16:
- default:
- return -EINVAL;
+ case QAM_16:
+ state->tx_tuna[8] = 0x10;
+ break;
+ case QAM_32:
+ state->tx_tuna[8] = 0x20;
+ break;
+ case QAM_64:
+ state->tx_tuna[8] = 0x40;
+ break;
+ case QAM_128:
+ state->tx_tuna[8] = 0x80;
+ break;
+ case QAM_256:
+ state->tx_tuna[8] = 0x00;
+ break;
+ case QPSK:
+ case QAM_AUTO:
+ case VSB_8:
+ case VSB_16:
+ default:
+ return -EINVAL;
}
@@ -534,7 +510,7 @@ static fe_modulation_t dst_get_modulation(struct dst_state *state)
}
-u8 dst_check_sum(u8 * buf, u32 len)
+u8 dst_check_sum(u8 *buf, u32 len)
{
u32 i;
u8 val = 0;
@@ -549,26 +525,24 @@ EXPORT_SYMBOL(dst_check_sum);
static void dst_type_flags_print(u32 type_flags)
{
- printk("DST type flags :");
+ dprintk(verbose, DST_ERROR, 0, "DST type flags :");
if (type_flags & DST_TYPE_HAS_NEWTUNE)
- printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
if (type_flags & DST_TYPE_HAS_TS204)
- printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
if (type_flags & DST_TYPE_HAS_SYMDIV)
- printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
if (type_flags & DST_TYPE_HAS_FW_1)
- printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
if (type_flags & DST_TYPE_HAS_FW_2)
- printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
if (type_flags & DST_TYPE_HAS_FW_3)
- printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
-// if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw)
-
- printk("\n");
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
+ dprintk(verbose, DST_ERROR, 0, "\n");
}
-static int dst_type_print (u8 type)
+static int dst_type_print(u8 type)
{
char *otype;
switch (type) {
@@ -585,10 +559,10 @@ static int dst_type_print (u8 type)
break;
default:
- printk("%s: invalid dst type %d\n", __FUNCTION__, type);
+ dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
return -EINVAL;
}
- printk("DST type : %s\n", otype);
+ dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
return 0;
}
@@ -700,7 +674,7 @@ struct dst_types dst_tlist[] = {
.offset = 1,
.dst_type = DST_TYPE_IS_CABLE,
.type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1
- | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+ | DST_TYPE_HAS_FW_2,
.dst_feature = DST_TYPE_HAS_CA
},
@@ -708,7 +682,7 @@ struct dst_types dst_tlist[] = {
.device_id = "DCTNEW",
.offset = 1,
.dst_type = DST_TYPE_IS_CABLE,
- .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
+ .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD,
.dst_feature = 0
},
@@ -716,7 +690,7 @@ struct dst_types dst_tlist[] = {
.device_id = "DTT-CI",
.offset = 1,
.dst_type = DST_TYPE_IS_TERR,
- .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+ .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
.dst_feature = 0
},
@@ -756,6 +730,71 @@ struct dst_types dst_tlist[] = {
};
+static int dst_get_mac(struct dst_state *state)
+{
+ u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_mac[7] = dst_check_sum(get_mac, 7);
+ if (dst_command(state, get_mac, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->mac_address, '\0', 8);
+ memcpy(&state->mac_address, &state->rxbuffer, 6);
+ dprintk(verbose, DST_ERROR, 1, "MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
+ state->mac_address[0], state->mac_address[1], state->mac_address[2],
+ state->mac_address[4], state->mac_address[5], state->mac_address[6]);
+
+ return 0;
+}
+
+static int dst_fw_ver(struct dst_state *state)
+{
+ u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_ver[7] = dst_check_sum(get_ver, 7);
+ if (dst_command(state, get_ver, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->fw_version, '\0', 8);
+ memcpy(&state->fw_version, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
+ state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
+ state->fw_version[1],
+ state->fw_version[5], state->fw_version[6],
+ state->fw_version[4], state->fw_version[3], state->fw_version[2]);
+
+ return 0;
+}
+
+static int dst_card_type(struct dst_state *state)
+{
+ u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_type[7] = dst_check_sum(get_type, 7);
+ if (dst_command(state, get_type, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->card_info, '\0', 8);
+ memcpy(&state->card_info, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
+
+ return 0;
+}
+
+static int dst_get_vendor(struct dst_state *state)
+{
+ u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_vendor[7] = dst_check_sum(get_vendor, 7);
+ if (dst_command(state, get_vendor, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->vendor, '\0', 8);
+ memcpy(&state->vendor, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
+
+ return 0;
+}
static int dst_get_device_id(struct dst_state *state)
{
@@ -772,53 +811,45 @@ static int dst_get_device_id(struct dst_state *state)
if (write_dst(state, device_type, FIXED_COMM))
return -1; /* Write failed */
-
if ((dst_pio_disable(state)) < 0)
return -1;
-
if (read_dst(state, &reply, GET_ACK))
return -1; /* Read failure */
-
if (reply != ACK) {
- dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
+ dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
return -1; /* Unack'd write */
}
-
if (!dst_wait_dst_ready(state, DEVICE_INIT))
return -1; /* DST not ready yet */
-
if (read_dst(state, state->rxbuffer, FIXED_COMM))
return -1;
dst_pio_disable(state);
-
if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
- dprintk("%s: Checksum failure! \n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Checksum failure!");
return -1; /* Checksum failure */
}
-
state->rxbuffer[7] = '\0';
- for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
+ for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
use_type_flags = p_dst_type->type_flags;
use_dst_type = p_dst_type->dst_type;
/* Card capabilities */
state->dst_hw_cap = p_dst_type->dst_feature;
- printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
+ dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id);
break;
}
}
if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
- printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
- printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
+ dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
use_dst_type = DST_TYPE_IS_SAT;
use_type_flags = DST_TYPE_HAS_SYMDIV;
}
-
dst_type_print(use_dst_type);
state->type_flags = use_type_flags;
state->dst_type = use_dst_type;
@@ -834,7 +865,7 @@ static int dst_get_device_id(struct dst_state *state)
static int dst_probe(struct dst_state *state)
{
if ((rdc_8820_reset(state)) < 0) {
- dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
return -1;
}
if (dst_addons & DST_TYPE_HAS_CA)
@@ -843,80 +874,87 @@ static int dst_probe(struct dst_state *state)
msleep(100);
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
return -1;
}
msleep(100);
if (dst_get_device_id(state) < 0) {
- dprintk("%s: unknown device.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "unknown device.");
return -1;
}
+ if (dst_get_mac(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
+ return 0;
+ }
+ if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
+ if (dst_fw_ver(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
+ return 0;
+ }
+ if (dst_card_type(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
+ return 0;
+ }
+ if (dst_get_vendor(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
+ return 0;
+ }
+ }
return 0;
}
-int dst_command(struct dst_state* state, u8 * data, u8 len)
+int dst_command(struct dst_state *state, u8 *data, u8 len)
{
u8 reply;
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
return -1;
}
-
if (write_dst(state, data, len)) {
- if (verbose > 1)
- dprintk("%s: Tring to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
return -1;
}
return -1;
}
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
return -1;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
-
if (read_dst(state, &reply, GET_ACK)) {
- if (verbose > 1)
- dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
return -1;
}
return -1;
}
-
if (reply != ACK) {
- dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
+ dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
return -1;
}
if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
return 0;
-
-// udelay(3000);
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
else
udelay(2000);
-
if (!dst_wait_dst_ready(state, NO_DELAY))
return -1;
-
if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
- if (verbose > 1)
- dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Recovery failed.");
return -1;
}
return -1;
}
-
if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
- dprintk("%s: checksum failure\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure");
return -1;
}
@@ -924,11 +962,11 @@ int dst_command(struct dst_state* state, u8 * data, u8 len)
}
EXPORT_SYMBOL(dst_command);
-static int dst_get_signal(struct dst_state* state)
+static int dst_get_signal(struct dst_state *state)
{
int retval;
u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
- dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
+ //dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
state->decode_lock = state->decode_strength = state->decode_snr = 0;
return 0;
@@ -955,13 +993,12 @@ static int dst_get_signal(struct dst_state* state)
return 0;
}
-static int dst_tone_power_cmd(struct dst_state* state)
+static int dst_tone_power_cmd(struct dst_state *state)
{
u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
if (state->dst_type == DST_TYPE_IS_TERR)
return 0;
-
paket[4] = state->tx_tuna[4];
paket[2] = state->tx_tuna[2];
paket[3] = state->tx_tuna[3];
@@ -971,61 +1008,53 @@ static int dst_tone_power_cmd(struct dst_state* state)
return 0;
}
-static int dst_get_tuna(struct dst_state* state)
+static int dst_get_tuna(struct dst_state *state)
{
int retval;
if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
return 0;
-
state->diseq_flags &= ~(HAS_LOCK);
if (!dst_wait_dst_ready(state, NO_DELAY))
return 0;
-
- if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
+ if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
/* how to get variable length reply ???? */
retval = read_dst(state, state->rx_tuna, 10);
- } else {
+ else
retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
- }
-
if (retval < 0) {
- dprintk("%s: read not successful\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "read not successful");
return 0;
}
-
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
- dprintk("%s: checksum failure?\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
return 0;
}
} else {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
- dprintk("%s: checksum failure?\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure? ");
return 0;
}
}
if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
return 0;
state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
-
state->decode_lock = 1;
state->diseq_flags |= HAS_LOCK;
return 1;
}
-static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-static int dst_write_tuna(struct dvb_frontend* fe)
+static int dst_write_tuna(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
int retval;
u8 reply;
- if (debug > 4)
- dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
-
+ dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
state->decode_freq = 0;
state->decode_lock = state->decode_strength = state->decode_snr = 0;
if (state->dst_type == DST_TYPE_IS_SAT) {
@@ -1035,35 +1064,31 @@ static int dst_write_tuna(struct dvb_frontend* fe)
state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
return -1;
}
-
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
retval = write_dst(state, &state->tx_tuna[0], 10);
-
} else {
state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
}
if (retval < 0) {
dst_pio_disable(state);
- dprintk("%s: write not successful\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "write not successful");
return retval;
}
-
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
return -1;
}
-
if ((read_dst(state, &reply, GET_ACK) < 0)) {
- dprintk("%s: read verify not successful.\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
return -1;
}
if (reply != ACK) {
- dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
+ dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
return 0;
}
state->diseq_flags |= ATTEMPT_TUNE;
@@ -1085,14 +1110,13 @@ static int dst_write_tuna(struct dvb_frontend* fe)
* Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
*/
-static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
-
if (cmd->msg_len == 0 || cmd->msg_len > 4)
return -EINVAL;
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*
return 0;
}
-static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
int need_cmd;
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
state->voltage = voltage;
-
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
need_cmd = 0;
- switch (voltage) {
- case SEC_VOLTAGE_13:
- case SEC_VOLTAGE_18:
- if ((state->diseq_flags & HAS_POWER) == 0)
- need_cmd = 1;
- state->diseq_flags |= HAS_POWER;
- state->tx_tuna[4] = 0x01;
- break;
- case SEC_VOLTAGE_OFF:
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ case SEC_VOLTAGE_18:
+ if ((state->diseq_flags & HAS_POWER) == 0)
need_cmd = 1;
- state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
- state->tx_tuna[4] = 0x00;
- break;
-
- default:
- return -EINVAL;
+ state->diseq_flags |= HAS_POWER;
+ state->tx_tuna[4] = 0x01;
+ break;
+ case SEC_VOLTAGE_OFF:
+ need_cmd = 1;
+ state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
+ state->tx_tuna[4] = 0x00;
+ break;
+ default:
+ return -EINVAL;
}
+
if (need_cmd)
dst_tone_power_cmd(state);
return 0;
}
-static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
state->tone = tone;
-
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
switch (tone) {
- case SEC_TONE_OFF:
- if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
- state->tx_tuna[2] = 0x00;
- else
- state->tx_tuna[2] = 0xff;
-
- break;
-
- case SEC_TONE_ON:
- state->tx_tuna[2] = 0x02;
- break;
+ case SEC_TONE_OFF:
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+ state->tx_tuna[2] = 0x00;
+ else
+ state->tx_tuna[2] = 0xff;
+ break;
- default:
- return -EINVAL;
+ case SEC_TONE_ON:
+ state->tx_tuna[2] = 0x02;
+ break;
+ default:
+ return -EINVAL;
}
dst_tone_power_cmd(state);
@@ -1172,16 +1192,14 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
-
state->minicmd = minicmd;
-
switch (minicmd) {
- case SEC_MINI_A:
- state->tx_tuna[3] = 0x02;
- break;
- case SEC_MINI_B:
- state->tx_tuna[3] = 0xff;
- break;
+ case SEC_MINI_A:
+ state->tx_tuna[3] = 0x02;
+ break;
+ case SEC_MINI_B:
+ state->tx_tuna[3] = 0xff;
+ break;
}
dst_tone_power_cmd(state);
@@ -1189,42 +1207,37 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
}
-static int dst_init(struct dvb_frontend* fe)
+static int dst_init(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
- static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
- static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
- static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
-// state->inversion = INVERSION_ON;
+ struct dst_state *state = fe->demodulator_priv;
+
+ static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
+ static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
+ static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+
state->inversion = INVERSION_OFF;
state->voltage = SEC_VOLTAGE_13;
state->tone = SEC_TONE_OFF;
- state->symbol_rate = 29473000;
- state->fec = FEC_AUTO;
state->diseq_flags = 0;
state->k22 = 0x02;
state->bandwidth = BANDWIDTH_7_MHZ;
state->cur_jiff = jiffies;
- if (state->dst_type == DST_TYPE_IS_SAT) {
- state->frequency = 950000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna));
- } else if (state->dst_type == DST_TYPE_IS_TERR) {
- state->frequency = 137000000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna));
- } else if (state->dst_type == DST_TYPE_IS_CABLE) {
- state->frequency = 51000000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
- }
+ if (state->dst_type == DST_TYPE_IS_SAT)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
+ else if (state->dst_type == DST_TYPE_IS_TERR)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
+ else if (state->dst_type == DST_TYPE_IS_CABLE)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
return 0;
}
-static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
*status = 0;
if (state->diseq_flags & HAS_LOCK) {
@@ -1236,9 +1249,9 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
-static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_get_signal(state);
*strength = state->decode_strength;
@@ -1246,9 +1259,9 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
return 0;
}
-static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
+static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_get_signal(state);
*snr = state->decode_snr;
@@ -1256,28 +1269,24 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
return 0;
}
-static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_set_freq(state, p->frequency);
- if (verbose > 4)
- dprintk("Set Frequency=[%d]\n", p->frequency);
+ dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
-// dst_set_inversion(state, p->inversion);
if (state->dst_type == DST_TYPE_IS_SAT) {
if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
dst_set_inversion(state, p->inversion);
-
dst_set_fec(state, p->u.qpsk.fec_inner);
dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
dst_set_polarization(state);
- if (verbose > 4)
- dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
+ dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
- } else if (state->dst_type == DST_TYPE_IS_TERR) {
+ } else if (state->dst_type == DST_TYPE_IS_TERR)
dst_set_bandwidth(state, p->u.ofdm.bandwidth);
- } else if (state->dst_type == DST_TYPE_IS_CABLE) {
+ else if (state->dst_type == DST_TYPE_IS_CABLE) {
dst_set_fec(state, p->u.qam.fec_inner);
dst_set_symbolrate(state, p->u.qam.symbol_rate);
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
return 0;
}
-static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
p->frequency = state->decode_freq;
-// p->inversion = state->inversion;
if (state->dst_type == DST_TYPE_IS_SAT) {
if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
p->inversion = state->inversion;
-
p->u.qpsk.symbol_rate = state->symbol_rate;
p->u.qpsk.fec_inner = dst_get_fec(state);
} 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
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
p->u.qam.symbol_rate = state->symbol_rate;
p->u.qam.fec_inner = dst_get_fec(state);
-// p->u.qam.modulation = QAM_AUTO;
p->u.qam.modulation = dst_get_modulation(state);
}
return 0;
}
-static void dst_release(struct dvb_frontend* fe)
+static void dst_release(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
kfree(state);
}
@@ -1321,9 +1327,8 @@ static struct dvb_frontend_ops dst_dvbt_ops;
static struct dvb_frontend_ops dst_dvbs_ops;
static struct dvb_frontend_ops dst_dvbc_ops;
-struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
+struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
{
-
/* check if the ASIC is there */
if (dst_probe(state) < 0) {
if (state)
@@ -1336,17 +1341,14 @@ struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
case DST_TYPE_IS_TERR:
memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
break;
-
case DST_TYPE_IS_CABLE:
memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
break;
-
case DST_TYPE_IS_SAT:
memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
break;
-
default:
- printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
if (state)
kfree(state);
@@ -1374,12 +1376,9 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
@@ -1401,16 +1400,12 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
-
.diseqc_send_burst = dst_send_burst,
.diseqc_send_master_cmd = dst_set_diseqc,
.set_voltage = dst_set_voltage,
@@ -1432,18 +1427,14 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
};
-
MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
MODULE_AUTHOR("Jamie Honan, Manu Abraham");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index bfaacd5fc20..6776a592045 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -18,30 +18,42 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
-
#include <linux/dvb/ca.h>
#include "dvbdev.h"
#include "dvb_frontend.h"
-
#include "dst_ca.h"
#include "dst_common.h"
+#define DST_CA_ERROR 0
+#define DST_CA_NOTICE 1
+#define DST_CA_INFO 2
+#define DST_CA_DEBUG 3
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((x > DST_CA_ERROR) && (x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_NOTICE) && (x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_INFO) && (x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_DEBUG) && (x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
+ } else { \
+ if (x > y) \
+ printk(format, ## arg); \
+ } \
+} while(0)
+
+
static unsigned int verbose = 5;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-static unsigned int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)");
-
-#define dprintk if (debug) printk
-
/* Need some more work */
static int ca_set_slot_descr(void)
{
@@ -61,27 +73,20 @@ static int put_checksum(u8 *check_string, int length)
{
u8 i = 0, checksum = 0;
- if (verbose > 3) {
- dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__);
- dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ===========================");
+ dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
- dprintk("%s: String=[", __FUNCTION__);
- }
while (i < length) {
- if (verbose > 3)
- dprintk(" %02x", check_string[i]);
+ dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
checksum += check_string[i];
i++;
}
- if (verbose > 3) {
- dprintk(" ]\n");
- dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
- }
+ dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
+ dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
check_string[length] = ~checksum + 1;
- if (verbose > 3) {
- dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]);
- dprintk("%s: ==========================================================================\n", __FUNCTION__);
- }
+ dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
return 0;
}
@@ -94,30 +99,26 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
msleep(65);
if (write_dst(state, data, len)) {
- dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
-
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: DST PIO disable failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
return -1;
}
-
if (read_dst(state, &reply, GET_ACK) < 0) {
- dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
-
if (read) {
if (! dst_wait_dst_ready(state, LONG_DELAY)) {
- dprintk("%s: 8820 not ready\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
return -1;
}
-
if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
- dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
@@ -133,8 +134,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string,
while (dst_ca_comm_err < RETRIES) {
dst_comm_init(state);
- if (verbose > 2)
- dprintk("%s: Put Command\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
if (dst_ci_command(state, data, ca_string, len, read)) { // If error
dst_error_recovery(state);
dst_ca_comm_err++; // work required here.
@@ -153,18 +153,15 @@ static int ca_get_app_info(struct dst_state *state)
put_checksum(&command[0], command[0]);
if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1) {
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
-
- dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
- dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
- __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9],
- (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
- dprintk("%s: ==================================================================================================\n", __FUNCTION__);
- }
+ dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
+ dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
+ dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
+ state->messages[7], (state->messages[8] << 8) | state->messages[9],
+ (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
+ dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
return 0;
}
@@ -177,31 +174,26 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
put_checksum(&slot_command[0], slot_command[0]);
if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1)
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
/* Will implement the rest soon */
- if (verbose > 1) {
- dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]);
- dprintk("===================================\n");
- for (i = 0; i < 8; i++)
- dprintk(" %d", slot_cap[i]);
- dprintk("\n");
- }
+ dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
+ dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+ for (i = 0; i < 8; i++)
+ dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
+ dprintk(verbose, DST_CA_INFO, 0, "\n");
p_ca_caps->slot_num = 1;
p_ca_caps->slot_type = 1;
p_ca_caps->descr_num = slot_cap[7];
p_ca_caps->descr_type = 1;
-
- if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
+ if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps)))
return -EFAULT;
- }
return 0;
}
@@ -222,46 +214,37 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
put_checksum(&slot_command[0], 7);
if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1)
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
/* Will implement the rest soon */
- if (verbose > 1) {
- dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]);
- dprintk("===================================\n");
- for (i = 0; i < 8; i++)
- dprintk(" %d", slot_info[i]);
- dprintk("\n");
- }
+ dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
+ dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+ for (i = 0; i < 8; i++)
+ dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
+ dprintk(verbose, DST_CA_INFO, 0, "\n");
if (slot_info[4] & 0x80) {
p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
p_ca_slot_info->num = 1;
p_ca_slot_info->type = CA_CI;
- }
- else if (slot_info[4] & 0x40) {
+ } else if (slot_info[4] & 0x40) {
p_ca_slot_info->flags = CA_CI_MODULE_READY;
p_ca_slot_info->num = 1;
p_ca_slot_info->type = CA_CI;
- }
- else {
+ } else
p_ca_slot_info->flags = 0;
- }
- if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) {
+ if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
return -EFAULT;
- }
return 0;
}
-
-
static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
{
u8 i = 0;
@@ -270,24 +253,21 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
return -EFAULT;
-
if (p_ca_message->msg) {
- if (verbose > 3)
- dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
+ 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]);
for (i = 0; i < 3; i++) {
command = command | p_ca_message->msg[i];
if (i < 2)
command = command << 8;
}
- if (verbose > 3)
- dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
switch (command) {
- case CA_APP_INFO:
- memcpy(p_ca_message->msg, state->messages, 128);
- if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
- return -EFAULT;
+ case CA_APP_INFO:
+ memcpy(p_ca_message->msg, state->messages, 128);
+ if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
+ return -EFAULT;
break;
}
}
@@ -298,10 +278,13 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
{
if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
- hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
- hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
- }
- else {
+ hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
+ hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
+ } else {
+ if (length > 247) {
+ dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
+ return -1;
+ }
hw_buffer->msg[0] = (length & 0xff) + 7;
hw_buffer->msg[1] = 0x40;
hw_buffer->msg[2] = 0x03;
@@ -309,6 +292,11 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
hw_buffer->msg[4] = 0x03;
hw_buffer->msg[5] = length & 0xff;
hw_buffer->msg[6] = 0x00;
+ /*
+ * Need to compute length for EN50221 section 8.3.2, for the time being
+ * assuming 8.3.2 is not applicable
+ */
+ memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
}
return 0;
}
@@ -317,13 +305,12 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
{
if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
- dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
- dprintk("%s: Resetting DST.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
+ dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
rdc_reset_state(state);
return -1;
}
- if (verbose > 2)
- dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes.");
return 0;
}
@@ -334,130 +321,47 @@ u32 asn_1_decode(u8 *asn_1_array)
u32 length = 0;
length_field = asn_1_array[0];
- dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
if (length_field < 0x80) {
length = length_field & 0x7f;
- dprintk("%s: Length=[%02x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
} else {
word_count = length_field & 0x7f;
for (count = 0; count < word_count; count++) {
length = (length | asn_1_array[count + 1]) << 8;
- dprintk("%s: Length=[%04x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
}
}
return length;
}
-static int init_buffer(u8 *buffer, u32 length)
-{
- u32 i;
- for (i = 0; i < length; i++)
- buffer[i] = 0;
-
- return 0;
-}
-
static int debug_string(u8 *msg, u32 length, u32 offset)
{
u32 i;
- dprintk(" String=[ ");
+ dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
for (i = offset; i < length; i++)
- dprintk("%02x ", msg[i]);
- dprintk("]\n");
-
- return 0;
-}
-
-static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
-{
- u32 i;
- dprintk("%s: Copying [", __FUNCTION__);
- for (i = 0; i < length; i++) {
- destination[i + dest_offset] = source[i + source_offset];
- dprintk(" %02x", source[i + source_offset]);
- }
- dprintk("]\n");
-
- return i;
-}
-
-static int modify_4_bits(u8 *message, u32 pos)
-{
- message[pos] &= 0x0f;
+ dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
+ dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
return 0;
}
-
-
static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
{
- u32 length = 0, count = 0;
- u8 asn_1_words, program_header_length;
- u16 program_info_length = 0, es_info_length = 0;
- u32 hw_offset = 0, buf_offset = 0, i;
- u8 dst_tag_length;
+ u32 length = 0;
+ u8 tag_length = 8;
length = asn_1_decode(&p_ca_message->msg[3]);
- dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
- dprintk("%s: ASN.1 ", __FUNCTION__);
- debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
+ dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
+ debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
- init_buffer(hw_buffer->msg, length);
+ memset(hw_buffer->msg, '\0', length);
handle_dst_tag(state, p_ca_message, hw_buffer, length);
+ put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
- hw_offset = 7;
- asn_1_words = 1; // just a hack to test, should compute this one
- buf_offset = 3;
- program_header_length = 6;
- dst_tag_length = 7;
-
-// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
-// dprintk("%s: Program Header(BUF)", __FUNCTION__);
-// debug_string(&p_ca_message->msg[4], program_header_length, 0);
-// dprintk("%s: Copying Program header\n", __FUNCTION__);
- copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
- buf_offset += program_header_length, hw_offset += program_header_length;
- modify_4_bits(hw_buffer->msg, (hw_offset - 2));
- if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
- dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
- debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
- hw_buffer->msg[hw_offset - 1] += 1;
- }
-
-// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
-// debug_string(hw_buffer->msg, hw_offset, 0);
-
- program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
- dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
- if (program_info_length) {
- count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
- buf_offset += count, hw_offset += count;
-// dprintk("%s: Program level ", __FUNCTION__);
-// debug_string(hw_buffer->msg, hw_offset, 0);
- }
-
- buf_offset += 1;// hw_offset += 1;
- for (i = buf_offset; i < length; i++) {
-// dprintk("%s: Stream Header ", __FUNCTION__);
- count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
- modify_4_bits(hw_buffer->msg, (hw_offset + 3));
-
- hw_offset += 5, buf_offset += 5, i += 4;
-// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
- es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
- dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
- if (es_info_length) {
- // copy descriptors @ STREAM level
- dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
- }
-
- }
- hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
-// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
- debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
- write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
+ debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
+ write_to_8820(state, hw_buffer, (length + tag_length), reply);
return 0;
}
@@ -471,26 +375,24 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
/* Do test board */
/* Not there yet but soon */
-
/* CA PMT Reply capable */
if (ca_pmt_reply_test) {
if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
- dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
return -1;
}
/* Process CA PMT Reply */
/* will implement soon */
- dprintk("%s: Not there yet\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
}
/* CA PMT Reply not capable */
if (!ca_pmt_reply_test) {
if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
- dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
return -1;
}
- if (verbose > 3)
- dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
/* put a dummy message */
}
@@ -506,11 +408,10 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer;
if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
- if (verbose > 3)
- dprintk("%s\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ");
if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
return -EFAULT;
@@ -525,51 +426,35 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
if (i < 2)
command = command << 8;
}
- if (verbose > 3)
- dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
switch (command) {
- case CA_PMT:
- if (verbose > 3)
-// dprintk("Command = SEND_CA_PMT\n");
- dprintk("Command = SEND_CA_PMT\n");
-// if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
- if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
- dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__);
-// retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0);
-
- break;
-
- case CA_PMT_REPLY:
- if (verbose > 3)
- dprintk("Command = CA_PMT_REPLY\n");
- /* Have to handle the 2 basic types of cards here */
- if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
- dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__);
-
- /* Certain boards do behave different ? */
-// retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
-
- case CA_APP_INFO_ENQUIRY: // only for debugging
- if (verbose > 3)
- dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
-
- if ((ca_get_app_info(state)) < 0) {
- dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
-
- break;
+ case CA_PMT:
+ dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
+ if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
+ break;
+ case CA_PMT_REPLY:
+ dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
+ /* Have to handle the 2 basic types of cards here */
+ if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
+ break;
+ case CA_APP_INFO_ENQUIRY: // only for debugging
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
+
+ if ((ca_get_app_info(state)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
+ break;
}
}
return 0;
@@ -584,121 +469,88 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct ca_msg *p_ca_message;
if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
/* We have now only the standard ioctl's, the driver is upposed to handle internals. */
switch (cmd) {
- case CA_SEND_MSG:
- if (verbose > 1)
- dprintk("%s: Sending message\n", __FUNCTION__);
- if ((ca_send_message(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__);
- return -1;
- }
-
- break;
-
- case CA_GET_MSG:
- if (verbose > 1)
- dprintk("%s: Getting message\n", __FUNCTION__);
- if ((ca_get_message(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__);
-
- break;
-
- case CA_RESET:
- if (verbose > 1)
- dprintk("%s: Resetting DST\n", __FUNCTION__);
- dst_error_bailout(state);
- msleep(4000);
-
- break;
-
- case CA_GET_SLOT_INFO:
- if (verbose > 1)
- dprintk("%s: Getting Slot info\n", __FUNCTION__);
- if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
- dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__);
-
- break;
-
- case CA_GET_CAP:
- if (verbose > 1)
- dprintk("%s: Getting Slot capabilities\n", __FUNCTION__);
- if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
- dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__);
-
- break;
-
- case CA_GET_DESCR_INFO:
- if (verbose > 1)
- dprintk("%s: Getting descrambler description\n", __FUNCTION__);
- if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
-
- break;
-
- case CA_SET_DESCR:
- if (verbose > 1)
- dprintk("%s: Setting descrambler\n", __FUNCTION__);
- if ((ca_set_slot_descr()) < 0) {
- dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
-
- break;
-
- case CA_SET_PID:
- if (verbose > 1)
- dprintk("%s: Setting PID\n", __FUNCTION__);
- if ((ca_set_pid()) < 0) {
- dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
-
- default:
- return -EOPNOTSUPP;
- };
+ case CA_SEND_MSG:
+ dprintk(verbose, DST_CA_INFO, 1, " Sending message");
+ if ((ca_send_message(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
+ return -1;
+ }
+ break;
+ case CA_GET_MSG:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting message");
+ if ((ca_get_message(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
+ break;
+ case CA_RESET:
+ dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
+ dst_error_bailout(state);
+ msleep(4000);
+ break;
+ case CA_GET_SLOT_INFO:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
+ if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
+ break;
+ case CA_GET_CAP:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
+ if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
+ break;
+ case CA_GET_DESCR_INFO:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
+ if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
+ break;
+ case CA_SET_DESCR:
+ dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
+ if ((ca_set_slot_descr()) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
+ break;
+ case CA_SET_PID:
+ dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
+ if ((ca_set_pid()) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
+ default:
+ return -EOPNOTSUPP;
+ };
return 0;
}
static int dst_ca_open(struct inode *inode, struct file *file)
{
- if (verbose > 4)
- dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
try_module_get(THIS_MODULE);
return 0;
@@ -706,27 +558,24 @@ static int dst_ca_open(struct inode *inode, struct file *file)
static int dst_ca_release(struct inode *inode, struct file *file)
{
- if (verbose > 4)
- dprintk("%s:Device closed.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
module_put(THIS_MODULE);
return 0;
}
-static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset)
+static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
int bytes_read = 0;
- if (verbose > 4)
- dprintk("%s:Device read.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
return bytes_read;
}
-static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset)
+static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
{
- if (verbose > 4)
- dprintk("%s:Device write.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
return 0;
}
@@ -751,8 +600,7 @@ static struct dvb_device dvbdev_ca = {
int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
{
struct dvb_device *dvbdev;
- if (verbose > 4)
- dprintk("%s:registering DST-CA device\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
return 0;
}
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index ef532a6acea..3281a6ca368 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -61,7 +61,6 @@
#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
#define DST_TYPE_HAS_SESSION 128
-
#define RDC_8820_PIO_0_DISABLE 0
#define RDC_8820_PIO_0_ENABLE 1
#define RDC_8820_INT 2
@@ -114,6 +113,10 @@ struct dst_state {
fe_sec_mini_cmd_t minicmd;
fe_modulation_t modulation;
u8 messages[256];
+ u8 mac_address[8];
+ u8 fw_version[8];
+ u8 card_info[8];
+ u8 vendor[8];
};
struct dst_types {
@@ -124,15 +127,12 @@ struct dst_types {
u32 dst_feature;
};
-
-
struct dst_config
{
/* the ASIC i2c address */
u8 demod_address;
};
-
int rdc_reset_state(struct dst_state *state);
int rdc_8820_reset(struct dst_state *state);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 6f857c6091f..c5c7672cd53 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -32,9 +32,7 @@
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
-
#include "dvb-bt8xx.h"
-
#include "bt878.h"
static int debug;
@@ -43,9 +41,11 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
#define dprintk( args... ) \
- do { \
+ do \
if (debug) printk(KERN_DEBUG args); \
- } while (0)
+ while (0)
+
+#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
static void dvb_bt8xx_task(unsigned long data)
{
@@ -119,14 +119,12 @@ static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci
unsigned int card_nr;
/* Hmm, n squared. Hope n is small */
- for (card_nr = 0; card_nr < bt878_num; card_nr++) {
+ for (card_nr = 0; card_nr < bt878_num; card_nr++)
if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
return &bt878[card_nr];
- }
return NULL;
}
-
static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
{
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_
unsigned char bs = 0;
unsigned char cp = 0;
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
- if (params->frequency < 542000000) cp = 0xb4;
- else if (params->frequency < 771000000) cp = 0xbc;
- else cp = 0xf4;
+ if (params->frequency < 542000000)
+ cp = 0xb4;
+ else if (params->frequency < 771000000)
+ cp = 0xbc;
+ else
+ cp = 0xf4;
- if (params->frequency == 0) bs = 0x03;
- else if (params->frequency < 443250000) bs = 0x02;
- else bs = 0x08;
+ if (params->frequency == 0)
+ bs = 0x03;
+ else if (params->frequency < 443250000)
+ bs = 0x02;
+ else
+ bs = 0x08;
pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
@@ -175,7 +178,6 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
}
static struct mt352_config thomson_dtt7579_config = {
-
.demod_address = 0x0f,
.demod_init = thomson_dtt7579_demod_init,
.pll_set = thomson_dtt7579_pll_set,
@@ -183,25 +185,26 @@ static struct mt352_config thomson_dtt7579_config = {
static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
- u32 freq = params->frequency;
-
- int i, a, n, pump;
- u32 band, pll;
+ u32 freq = params->frequency;
+ int i, a, n, pump;
+ u32 band, pll;
- u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
- 1576000,1718000,1856000,2036000,2150000};
- u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
- 0x00102000,0x00104000,0x00108000,0x00110000,
- 0x00120000,0x00140000};
+ u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
+ 1576000,1718000,1856000,2036000,2150000};
+ u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
+ 0x00102000,0x00104000,0x00108000,0x00110000,
+ 0x00120000,0x00140000};
-#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
+ #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
/* This is really the bit driving the tuner chip cx24108 */
- if(freq<950000) freq=950000; /* kHz */
- if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
+ if (freq<950000)
+ freq = 950000; /* kHz */
+ else if (freq>2150000)
+ freq = 2150000; /* satellite IF is 950..2150MHz */
/* decide which VCO to use for the input frequency */
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
cx24110_pll_write(fe,0x500c0000);
cx24110_pll_write(fe,0x83f1f800);
cx24110_pll_write(fe,pll);
-/* writereg(client,0x56,0x7f);*/
+ //writereg(client,0x56,0x7f);
return 0;
}
static int pinnsat_pll_init(struct dvb_frontend* fe)
{
- return 0;
+ return 0;
}
-
static struct cx24110_config pctvsat_config = {
-
.demod_address = 0x55,
.pll_init = pinnsat_pll_init,
.pll_set = cx24108_pll_set,
};
-
static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
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
div = (36000000 + params->frequency + 83333) / 166666;
cfg = 0x88;
- if (params->frequency < 175000000) cpump = 2;
- else if (params->frequency < 390000000) cpump = 1;
- else if (params->frequency < 470000000) cpump = 2;
- else if (params->frequency < 750000000) cpump = 2;
- else cpump = 3;
+ if (params->frequency < 175000000)
+ cpump = 2;
+ else if (params->frequency < 390000000)
+ cpump = 1;
+ else if (params->frequency < 470000000)
+ cpump = 2;
+ else if (params->frequency < 750000000)
+ cpump = 2;
+ else
+ cpump = 3;
- if (params->frequency < 175000000) band_select = 0x0e;
- else if (params->frequency < 470000000) band_select = 0x05;
- else band_select = 0x03;
+ if (params->frequency < 175000000)
+ band_select = 0x0e;
+ else if (params->frequency < 470000000)
+ band_select = 0x05;
+ else
+ band_select = 0x03;
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
@@ -285,14 +293,11 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s
}
static struct sp887x_config microtune_mt7202dtf_config = {
-
.demod_address = 0x70,
.pll_set = microtune_mt7202dtf_pll_set,
.request_firmware = microtune_mt7202dtf_request_firmware,
};
-
-
static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
{
static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
@@ -303,7 +308,6 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(fe, mt352_reset, sizeof(mt352_reset));
@@ -323,28 +327,45 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
unsigned char bs = 0;
unsigned char cp = 0;
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
- if (params->frequency < 150000000) cp = 0xB4;
- else if (params->frequency < 173000000) cp = 0xBC;
- else if (params->frequency < 250000000) cp = 0xB4;
- else if (params->frequency < 400000000) cp = 0xBC;
- else if (params->frequency < 420000000) cp = 0xF4;
- else if (params->frequency < 470000000) cp = 0xFC;
- else if (params->frequency < 600000000) cp = 0xBC;
- else if (params->frequency < 730000000) cp = 0xF4;
- else cp = 0xFC;
-
- if (params->frequency < 150000000) bs = 0x01;
- else if (params->frequency < 173000000) bs = 0x01;
- else if (params->frequency < 250000000) bs = 0x02;
- else if (params->frequency < 400000000) bs = 0x02;
- else if (params->frequency < 420000000) bs = 0x02;
- else if (params->frequency < 470000000) bs = 0x02;
- else if (params->frequency < 600000000) bs = 0x08;
- else if (params->frequency < 730000000) bs = 0x08;
- else bs = 0x08;
+ if (params->frequency < 150000000)
+ cp = 0xB4;
+ else if (params->frequency < 173000000)
+ cp = 0xBC;
+ else if (params->frequency < 250000000)
+ cp = 0xB4;
+ else if (params->frequency < 400000000)
+ cp = 0xBC;
+ else if (params->frequency < 420000000)
+ cp = 0xF4;
+ else if (params->frequency < 470000000)
+ cp = 0xFC;
+ else if (params->frequency < 600000000)
+ cp = 0xBC;
+ else if (params->frequency < 730000000)
+ cp = 0xF4;
+ else
+ cp = 0xFC;
+
+ if (params->frequency < 150000000)
+ bs = 0x01;
+ else if (params->frequency < 173000000)
+ bs = 0x01;
+ else if (params->frequency < 250000000)
+ bs = 0x02;
+ else if (params->frequency < 400000000)
+ bs = 0x02;
+ else if (params->frequency < 420000000)
+ bs = 0x02;
+ else if (params->frequency < 470000000)
+ bs = 0x02;
+ else if (params->frequency < 600000000)
+ bs = 0x08;
+ else if (params->frequency < 730000000)
+ bs = 0x08;
+ else
+ bs = 0x08;
pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
@@ -356,19 +377,15 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
}
static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
-
.demod_address = 0x0f,
.demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
.pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
};
-
static struct dst_config dst_config = {
-
.demod_address = 0x55,
};
-
static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
@@ -398,10 +415,8 @@ static void or51211_reset(struct dvb_frontend * fe)
*/
/* reset & PRM1,2&4 are outputs */
int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
- if (ret != 0) {
- printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
- "(%i)\n", ret);
- }
+ if (ret != 0)
+ printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
msleep(20);
/* Now set for normal operation */
@@ -417,7 +432,6 @@ static void or51211_sleep(struct dvb_frontend * fe)
}
static struct or51211_config or51211_config = {
-
.demod_address = 0x15,
.request_firmware = or51211_request_firmware,
.setmode = or51211_setmode,
@@ -425,7 +439,6 @@ static struct or51211_config or51211_config = {
.sleep = or51211_sleep,
};
-
static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
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
}
static struct nxt6000_config vp3021_alps_tded4_config = {
-
.demod_address = 0x0a,
.clock_inversion = 1,
.pll_set = vp3021_alps_tded4_pll_set,
};
+static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
+{
+ static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+ static u8 mt352_reset [] = { 0x50, 0x80 };
+ static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+ static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
+ static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+ mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+ udelay(2000);
+ mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+ mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+ mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
+ mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+ return 0;
+}
+
+static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
+{
+ u32 div;
+ struct dvb_ofdm_parameters *op = &params->u.ofdm;
+
+ div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+ pllbuf[0] = 0xc2;
+ pllbuf[1] = (div >> 8) & 0x7F;
+ pllbuf[2] = div & 0xFF;
+ pllbuf[3] = 0x85;
+
+ dprintk("frequency %u, div %u\n", params->frequency, div);
+
+ if (params->frequency < 470000000)
+ pllbuf[4] = 0x02;
+ else if (params->frequency > 823000000)
+ pllbuf[4] = 0x88;
+ else
+ pllbuf[4] = 0x08;
+
+ if (op->bandwidth == 8)
+ pllbuf[4] |= 0x04;
+
+ return 0;
+}
+
+static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
+{
+ /*
+ * Reset the frontend, must be called before trying
+ * to initialise the MT352 or mt352_attach
+ * will fail.
+ *
+ * Presumably not required for the NXT6000 frontend.
+ *
+ */
+
+ int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
+ if (ret != 0)
+ printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
+
+ /* Pulse the reset line */
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */
+ msleep(100);
+
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+}
+
+static struct mt352_config digitv_alps_tded4_config = {
+ .demod_address = 0x0a,
+ .demod_init = digitv_alps_tded4_demod_init,
+ .pll_set = digitv_alps_tded4_pll_set,
+};
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
@@ -473,7 +558,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
card->fe->ops->info.frequency_max = 862000000;
- break;
}
break;
#endif
@@ -483,17 +567,28 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
#else
case BTTV_NEBULA_DIGITV:
#endif
+ /*
+ * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
+ * this would be a cleaner solution than trying each frontend in turn.
+ */
+
+ /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) {
+ dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
break;
}
+
+ /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
+ digitv_alps_tded4_reset(card);
+ card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
+
+ if (card->fe != NULL)
+ dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
break;
case BTTV_AVDVBT_761:
card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_AVDVBT_771:
@@ -501,7 +596,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
card->fe->ops->info.frequency_max = 862000000;
- break;
}
break;
@@ -522,54 +616,41 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* Attach other DST peripherals if any */
/* Conditional Access device */
- if (state->dst_hw_cap & DST_TYPE_HAS_CA) {
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
ret = dst_ca_attach(state, &card->dvb_adapter);
- }
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_PINNACLESAT:
card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_PC_HDTV:
card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
}
- if (card->fe == NULL) {
+ if (card->fe == NULL)
printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
card->bt->dev->vendor,
card->bt->dev->device,
card->bt->dev->subsystem_vendor,
card->bt->dev->subsystem_device);
- } else {
+ else
if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
printk("dvb-bt8xx: Frontend registration failed!\n");
if (card->fe->ops->release)
card->fe->ops->release(card->fe);
card->fe = NULL;
}
- }
}
static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
{
int result;
- if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
- THIS_MODULE)) < 0) {
+ if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
return result;
-
}
card->dvb_adapter.priv = card;
@@ -664,8 +745,7 @@ static int dvb_bt8xx_probe(struct device *dev)
strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
card->i2c_adapter = &sub->core->i2c_adap;
- switch(sub->core->type)
- {
+ switch(sub->core->type) {
case BTTV_PINNACLESAT:
card->gpio_mode = 0x0400c060;
/* 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)
kfree(card);
return -EFAULT;
-
}
init_MUTEX(&card->bt->gpio_lock);
@@ -779,7 +858,8 @@ static int dvb_bt8xx_remove(struct device *dev)
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
dvb_dmxdev_release(&card->dmxdev);
dvb_dmx_release(&card->demux);
- if (card->fe) dvb_unregister_frontend(card->fe);
+ if (card->fe)
+ dvb_unregister_frontend(card->fe);
dvb_unregister_adapter(&card->dvb_adapter);
kfree(card);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 2923b3b0dd3..9ec8e5bd6c1 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -2,7 +2,7 @@
* Bt8xx based DVB adapter driver
*
* Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
* Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
* Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
*
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 226714085f5..7cf4c4a888e 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
config DVB_CINERGYT2_RC_QUERY_INTERVAL
int "Infrared Remote Controller update interval [milliseconds]"
depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
- default "100"
+ default "50"
help
If you have a very fast-repeating remote control you can try lower
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 9ea5747b121..6db0929ef53 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -25,7 +25,6 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/pci.h>
@@ -36,7 +35,6 @@
#include "dvb_demux.h"
#include "dvb_net.h"
-
#ifdef CONFIG_DVB_CINERGYT2_TUNING
#define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
#define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
@@ -49,7 +47,7 @@
#define STREAM_URB_COUNT (32)
#define STREAM_BUF_SIZE (512) /* bytes */
#define ENABLE_RC (1)
- #define RC_QUERY_INTERVAL (100) /* milliseconds */
+ #define RC_QUERY_INTERVAL (50) /* milliseconds */
#define QUERY_INTERVAL (333) /* milliseconds */
#endif
@@ -142,6 +140,8 @@ struct cinergyt2 {
struct input_dev rc_input_dev;
struct work_struct rc_query_work;
int rc_input_event;
+ u32 rc_last_code;
+ unsigned long last_event_jiffies;
#endif
};
@@ -156,7 +156,7 @@ struct cinergyt2_rc_event {
uint32_t value;
} __attribute__((packed));
-static const uint32_t rc_keys [] = {
+static const uint32_t rc_keys[] = {
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
@@ -685,52 +685,68 @@ static struct dvb_device cinergyt2_fe_template = {
#ifdef ENABLE_RC
static void cinergyt2_query_rc (void *data)
{
- struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
- char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
+ struct cinergyt2 *cinergyt2 = data;
+ char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
struct cinergyt2_rc_event rc_events[12];
- int n, len;
+ int n, len, i;
if (down_interruptible(&cinergyt2->sem))
return;
len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
- (char *) rc_events, sizeof(rc_events));
-
- for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
- int i;
+ (char *) rc_events, sizeof(rc_events));
+ if (len < 0)
+ goto out;
+ if (len == 0) {
+ if (time_after(jiffies, cinergyt2->last_event_jiffies +
+ msecs_to_jiffies(150))) {
+ /* stop key repeat */
+ if (cinergyt2->rc_input_event != KEY_MAX) {
+ dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
+ input_report_key(&cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 0);
+ cinergyt2->rc_input_event = KEY_MAX;
+ }
+ cinergyt2->rc_last_code = ~0;
+ }
+ goto out;
+ }
+ cinergyt2->last_event_jiffies = jiffies;
-/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/
+ for (n = 0; n < (len / sizeof(rc_events[0])); n++) {
+ dprintk(1, "rc_events[%d].value = %x, type=%x\n",
+ n, le32_to_cpu(rc_events[n].value), rc_events[n].type);
if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
- rc_events[n].value == ~0)
- {
- /**
- * keyrepeat bit. If we would handle this properly
- * we would need to emit down events as long the
- * keyrepeat goes, a up event if no further
- * repeat bits occur. Would need a timer to implement
- * and no other driver does this, so we simply
- * emit the last key up/down sequence again.
- */
+ rc_events[n].value == ~0) {
+ /* keyrepeat bit -> just repeat last rc_input_event */
} else {
cinergyt2->rc_input_event = KEY_MAX;
- for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
- if (rc_keys[i+0] == rc_events[n].type &&
- rc_keys[i+1] == le32_to_cpu(rc_events[n].value))
- {
- cinergyt2->rc_input_event = rc_keys[i+2];
+ for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
+ if (rc_keys[i + 0] == rc_events[n].type &&
+ rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
+ cinergyt2->rc_input_event = rc_keys[i + 2];
break;
}
}
}
if (cinergyt2->rc_input_event != KEY_MAX) {
- input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
- input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
- input_sync(&cinergyt2->rc_input_dev);
+ if (rc_events[n].value == cinergyt2->rc_last_code &&
+ cinergyt2->rc_last_code != ~0) {
+ /* emit a key-up so the double event is recognized */
+ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
+ input_report_key(&cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 0);
+ }
+ dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
+ input_report_key(&cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 1);
+ cinergyt2->rc_last_code = rc_events[n].value;
}
}
+out:
schedule_delayed_work(&cinergyt2->rc_query_work,
msecs_to_jiffies(RC_QUERY_INTERVAL));
@@ -772,7 +788,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
const struct usb_device_id *id)
{
struct cinergyt2 *cinergyt2;
- int i, err;
+ int err;
+#ifdef ENABLE_RC
+ int i;
+#endif
if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
dprintk(1, "out of memory?!?\n");
@@ -828,19 +847,18 @@ static int cinergyt2_probe (struct usb_interface *intf,
DVB_DEVICE_FRONTEND);
#ifdef ENABLE_RC
- init_input_dev(&cinergyt2->rc_input_dev);
-
- cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
- cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
- cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
+ cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ cinergyt2->rc_input_dev.keycodesize = 0;
+ cinergyt2->rc_input_dev.keycodemax = 0;
cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
- for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
- set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
+ for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
+ set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
input_register_device(&cinergyt2->rc_input_dev);
cinergyt2->rc_input_event = KEY_MAX;
+ cinergyt2->rc_last_code = ~0;
INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
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 fb55eaa5c8e..9719a3b30f7 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/time.h>
+#include <linux/dvb/dmx.h>
/*--------------------------------------------------------------------------*/
/* Common definitions */
@@ -124,9 +125,7 @@ struct dmx_ts_feed {
u16 pid,
int type,
enum dmx_ts_pes pes_type,
- size_t callback_length,
size_t circular_buffer_size,
- int descramble,
struct timespec timeout);
int (*start_filtering) (struct dmx_ts_feed* feed);
int (*stop_filtering) (struct dmx_ts_feed* feed);
@@ -159,7 +158,6 @@ struct dmx_section_feed {
int (*set) (struct dmx_section_feed* feed,
u16 pid,
size_t circular_buffer_size,
- int descramble,
int check_crc);
int (*allocate_filter) (struct dmx_section_feed* feed,
struct dmx_section_filter** filter);
@@ -207,7 +205,6 @@ struct dmx_frontend {
struct list_head connectivity_list; /* List of front-ends that can
be connected to a particular
demux */
- void* priv; /* Pointer to private data of the API client */
enum dmx_frontend_source source;
};
@@ -225,8 +222,6 @@ struct dmx_frontend {
#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
#define DMX_CRC_CHECKING 16
#define DMX_TS_DESCRAMBLING 32
-#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
-#define DMX_MAC_ADDRESS_DESCRAMBLING 128
/*
* Demux resource type identifier.
@@ -244,9 +239,7 @@ struct dmx_frontend {
struct dmx_demux {
u32 capabilities; /* Bitfield of capability flags */
struct dmx_frontend* frontend; /* Front-end connected to the demux */
- struct list_head reg_list; /* List of registered demuxes */
void* priv; /* Pointer to private data of the API client */
- int users; /* Number of users */
int (*open) (struct dmx_demux* demux);
int (*close) (struct dmx_demux* demux);
int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
@@ -260,17 +253,6 @@ struct dmx_demux {
dmx_section_cb callback);
int (*release_section_feed) (struct dmx_demux* demux,
struct dmx_section_feed* feed);
- int (*descramble_mac_address) (struct dmx_demux* demux,
- u8* buffer1,
- size_t buffer1_length,
- u8* buffer2,
- size_t buffer2_length,
- u16 pid);
- int (*descramble_section_payload) (struct dmx_demux* demux,
- u8* buffer1,
- size_t buffer1_length,
- u8* buffer2, size_t buffer2_length,
- u16 pid);
int (*add_frontend) (struct dmx_demux* demux,
struct dmx_frontend* frontend);
int (*remove_frontend) (struct dmx_demux* demux,
@@ -282,20 +264,12 @@ struct dmx_demux {
int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
+ int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
+
+ int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
+
int (*get_stc) (struct dmx_demux* demux, unsigned int num,
u64 *stc, unsigned int *base);
};
-/*--------------------------------------------------------------------------*/
-/* Demux directory */
-/*--------------------------------------------------------------------------*/
-
-/*
- * DMX_DIR_ENTRY(): Casts elements in the list of registered
- * demuxes from the generic type struct list_head* to the type struct dmx_demux
- *.
- */
-
-#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list)
-
#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 68050cd527c..8028c3a5e28 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)
return ret;
}
- ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0,
+ ret=(*secfeed)->set(*secfeed, para->pid, 32768,
(para->flags & DMX_CHECK_CRC) ? 1 : 0);
if (ret<0) {
@@ -654,7 +654,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
(*tsfeed)->priv = (void *) filter;
ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
- 188, 32768, 0, timeout);
+ 32768, timeout);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
@@ -929,6 +929,22 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
break;
+ case DMX_GET_CAPS:
+ if (!dmxdev->demux->get_caps) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
+ break;
+
+ case DMX_SET_SOURCE:
+ if (!dmxdev->demux->set_source) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = dmxdev->demux->set_source(dmxdev->demux, parg);
+ break;
+
case DMX_GET_STC:
if (!dmxdev->demux->get_stc) {
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 0eb9aa711fb..88757e2634e 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");
#define dprintk if (dvb_ca_en50221_debug) printk
-#define INIT_TIMEOUT_SECS 5
+#define INIT_TIMEOUT_SECS 10
#define HOST_LINK_BUF_SIZE 0x200
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index ac9889d2228..dc476dda2b7 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -38,82 +38,52 @@
*/
// #define DVB_DEMUX_SECTION_LOSS_LOG
-
-static LIST_HEAD(dmx_muxs);
-
-
-static int dmx_register_demux(struct dmx_demux *demux)
-{
- demux->users = 0;
- list_add(&demux->reg_list, &dmx_muxs);
- return 0;
-}
-
-static int dmx_unregister_demux(struct dmx_demux* demux)
-{
- struct list_head *pos, *n, *head=&dmx_muxs;
-
- list_for_each_safe (pos, n, head) {
- if (DMX_DIR_ENTRY(pos) == demux) {
- if (demux->users>0)
- return -EINVAL;
- list_del(pos);
- return 0;
- }
- }
-
- return -ENODEV;
-}
-
-
/******************************************************************************
* static inlined helper functions
******************************************************************************/
-
static inline u16 section_length(const u8 *buf)
{
- return 3+((buf[1]&0x0f)<<8)+buf[2];
+ return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
}
-
static inline u16 ts_pid(const u8 *buf)
{
- return ((buf[1]&0x1f)<<8)+buf[2];
+ return ((buf[1] & 0x1f) << 8) + buf[2];
}
-
static inline u8 payload(const u8 *tsp)
{
- if (!(tsp[3] & 0x10)) // no payload?
+ if (!(tsp[3] & 0x10)) // no payload?
return 0;
- if (tsp[3] & 0x20) { // adaptation field?
- if (tsp[4] > 183) // corrupted data?
+
+ if (tsp[3] & 0x20) { // adaptation field?
+ if (tsp[4] > 183) // corrupted data?
return 0;
else
- return 184-1-tsp[4];
+ return 184 - 1 - tsp[4];
}
+
return 184;
}
-
-static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
+static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len)
{
- return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len));
+ return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len));
}
-
-static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len)
+static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s,
+ size_t len)
{
- memcpy (d, s, len);
+ memcpy(d, s, len);
}
-
/******************************************************************************
* Software filter functions
******************************************************************************/
-static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf)
+static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
int count = payload(buf);
int p;
@@ -123,32 +93,31 @@ static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u
if (count == 0)
return -1;
- p = 188-count;
+ p = 188 - count;
/*
- cc=buf[3]&0x0f;
- ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
- dvbdmxfeed->cc=cc;
+ cc = buf[3] & 0x0f;
+ ccok = ((feed->cc + 1) & 0x0f) == cc;
+ feed->cc = cc;
if (!ccok)
printk("missed packet!\n");
*/
- if (buf[1] & 0x40) // PUSI ?
+ if (buf[1] & 0x40) // PUSI ?
feed->peslen = 0xfffa;
feed->peslen += count;
- return feed->cb.ts (&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
+ return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
}
-
-static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
- struct dvb_demux_filter *f)
+static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
+ struct dvb_demux_filter *f)
{
u8 neq = 0;
int i;
- for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
+ for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
if (f->maskandmode[i] & xor)
@@ -160,12 +129,11 @@ static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
if (f->doneq && !neq)
return 0;
- return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen,
- NULL, 0, &f->filter, DMX_OK);
+ return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
+ NULL, 0, &f->filter, DMX_OK);
}
-
-static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
+static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
struct dvb_demux_filter *f = feed->filter;
@@ -195,26 +163,24 @@ static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
return 0;
}
-
static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
{
struct dmx_section_feed *sec = &feed->feed.sec;
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- if(sec->secbufp < sec->tsfeedp)
- {
+ if (sec->secbufp < sec->tsfeedp) {
int i, n = sec->tsfeedp - sec->secbufp;
- /* section padding is done with 0xff bytes entirely.
- ** due to speed reasons, we won't check all of them
- ** but just first and last
- */
- if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
- {
+ /*
+ * Section padding is done with 0xff bytes entirely.
+ * Due to speed reasons, we won't check all of them
+ * but just first and last.
+ */
+ if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
printk("dvb_demux.c section ts padding loss: %d/%d\n",
n, sec->tsfeedp);
printk("dvb_demux.c pad data:");
- for(i = 0; i < n; i++)
+ for (i = 0; i < n; i++)
printk(" %02x", sec->secbuf[i]);
printk("\n");
}
@@ -226,82 +192,81 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
}
/*
-** Losless Section Demux 1.4.1 by Emard
-** Valsecchi Patrick:
-** - middle of section A (no PUSI)
-** - end of section A and start of section B
-** (with PUSI pointing to the start of the second section)
-**
-** In this case, without feed->pusi_seen you'll receive a garbage section
-** consisting of the end of section A. Basically because tsfeedp
-** is incemented and the use=0 condition is not raised
-** when the second packet arrives.
-**
-** Fix:
-** when demux is started, let feed->pusi_seen = 0 to
-** prevent initial feeding of garbage from the end of
-** previous section. When you for the first time see PUSI=1
-** then set feed->pusi_seen = 1
-*/
-static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
+ * Losless Section Demux 1.4.1 by Emard
+ * Valsecchi Patrick:
+ * - middle of section A (no PUSI)
+ * - end of section A and start of section B
+ * (with PUSI pointing to the start of the second section)
+ *
+ * In this case, without feed->pusi_seen you'll receive a garbage section
+ * consisting of the end of section A. Basically because tsfeedp
+ * is incemented and the use=0 condition is not raised
+ * when the second packet arrives.
+ *
+ * Fix:
+ * when demux is started, let feed->pusi_seen = 0 to
+ * prevent initial feeding of garbage from the end of
+ * previous section. When you for the first time see PUSI=1
+ * then set feed->pusi_seen = 1
+ */
+static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
+ const u8 *buf, u8 len)
{
struct dvb_demux *demux = feed->demux;
struct dmx_section_feed *sec = &feed->feed.sec;
u16 limit, seclen, n;
- if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
+ if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
return 0;
- if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
- {
+ if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
printk("dvb_demux.c section buffer full loss: %d/%d\n",
- sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
+ sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
+ DMX_MAX_SECFEED_SIZE);
#endif
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
}
- if(len <= 0)
+ if (len <= 0)
return 0;
demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
sec->tsfeedp += len;
- /* -----------------------------------------------------
- ** Dump all the sections we can find in the data (Emard)
- */
-
+ /*
+ * Dump all the sections we can find in the data (Emard)
+ */
limit = sec->tsfeedp;
- if(limit > DMX_MAX_SECFEED_SIZE)
- return -1; /* internal error should never happen */
+ if (limit > DMX_MAX_SECFEED_SIZE)
+ return -1; /* internal error should never happen */
/* to be sure always set secbuf */
sec->secbuf = sec->secbuf_base + sec->secbufp;
- for(n = 0; sec->secbufp + 2 < limit; n++)
- {
+ for (n = 0; sec->secbufp + 2 < limit; n++) {
seclen = section_length(sec->secbuf);
- if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
- || seclen + sec->secbufp > limit)
+ if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
+ || seclen + sec->secbufp > limit)
return 0;
sec->seclen = seclen;
sec->crc_val = ~0;
/* dump [secbuf .. secbuf+seclen) */
- if(feed->pusi_seen)
+ if (feed->pusi_seen)
dvb_dmx_swfilter_section_feed(feed);
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
else
printk("dvb_demux.c pusi not seen, discarding section data\n");
#endif
- sec->secbufp += seclen; /* secbufp and secbuf moving together is */
- sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
+ sec->secbufp += seclen; /* secbufp and secbuf moving together is */
+ sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
}
return 0;
}
-
-static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf)
+static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
u8 p, count;
int ccok, dc_i = 0;
@@ -309,10 +274,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
count = payload(buf);
- if (count == 0) /* count == 0 if no payload or out of range */
+ if (count == 0) /* count == 0 if no payload or out of range */
return -1;
- p = 188 - count; /* payload start */
+ p = 188 - count; /* payload start */
cc = buf[3] & 0x0f;
ccok = ((feed->cc + 1) & 0x0f) == cc;
@@ -326,52 +291,53 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
if (!ccok || dc_i) {
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
- /* those bytes under sume circumstances will again be reported
- ** in the following dvb_dmx_swfilter_section_new
- */
+ printk("dvb_demux.c discontinuity detected %d bytes lost\n",
+ count);
+ /*
+ * those bytes under sume circumstances will again be reported
+ * in the following dvb_dmx_swfilter_section_new
+ */
#endif
- /* Discontinuity detected. Reset pusi_seen = 0 to
- ** stop feeding of suspicious data until next PUSI=1 arrives
- */
+ /*
+ * Discontinuity detected. Reset pusi_seen = 0 to
+ * stop feeding of suspicious data until next PUSI=1 arrives
+ */
feed->pusi_seen = 0;
dvb_dmx_swfilter_section_new(feed);
- return 0;
}
if (buf[1] & 0x40) {
- // PUSI=1 (is set), section boundary is here
+ /* PUSI=1 (is set), section boundary is here */
if (count > 1 && buf[p] < count) {
- const u8 *before = buf+p+1;
+ const u8 *before = &buf[p + 1];
u8 before_len = buf[p];
- const u8 *after = before+before_len;
- u8 after_len = count-1-before_len;
+ const u8 *after = &before[before_len];
+ u8 after_len = count - 1 - before_len;
- dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
+ dvb_dmx_swfilter_section_copy_dump(feed, before,
+ before_len);
/* before start of new section, set pusi_seen = 1 */
feed->pusi_seen = 1;
dvb_dmx_swfilter_section_new(feed);
- dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
+ dvb_dmx_swfilter_section_copy_dump(feed, after,
+ after_len);
}
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- else
- if (count > 0)
- printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
+ else if (count > 0)
+ printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
#endif
} else {
- // PUSI=0 (is not set), no section boundary
- const u8 *entire = buf+p;
- u8 entire_len = count;
-
- dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
+ /* PUSI=0 (is not set), no section boundary */
+ dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
}
+
return 0;
}
-
-static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
+static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
- switch(feed->type) {
+ switch (feed->type) {
case DMX_TYPE_TS:
if (!feed->feed.ts.is_filtering)
break;
@@ -379,7 +345,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
if (feed->ts_type & TS_PAYLOAD_ONLY)
dvb_dmx_swfilter_payload(feed, buf);
else
- feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
+ feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
+ DMX_OK);
}
if (feed->ts_type & TS_DECODER)
if (feed->demux->write_to_decoder)
@@ -390,7 +357,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
if (!feed->feed.sec.is_filtering)
break;
if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
- feed->feed.sec.seclen = feed->feed.sec.secbufp=0;
+ feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
break;
default:
@@ -406,7 +373,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
{
struct dvb_demux_feed *feed;
- struct list_head *pos, *head=&demux->feed_list;
+ struct list_head *pos, *head = &demux->feed_list;
u16 pid = ts_pid(buf);
int dvr_done = 0;
@@ -432,21 +399,21 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
}
}
-void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
+void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
+ size_t count)
{
spin_lock(&demux->lock);
while (count--) {
- if(buf[0] == 0x47) {
- dvb_dmx_swfilter_packet(demux, buf);
- }
+ if (buf[0] == 0x47)
+ dvb_dmx_swfilter_packet(demux, buf);
buf += 188;
}
spin_unlock(&demux->lock);
}
-EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
+EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
@@ -454,8 +421,10 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
spin_lock(&demux->lock);
- if ((i = demux->tsbufp)) {
- if (count < (j=188-i)) {
+ if (demux->tsbufp) {
+ i = demux->tsbufp;
+ j = 188 - i;
+ if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
@@ -469,13 +438,13 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
while (p < count) {
if (buf[p] == 0x47) {
- if (count-p >= 188) {
- dvb_dmx_swfilter_packet(demux, buf+p);
+ if (count - p >= 188) {
+ dvb_dmx_swfilter_packet(demux, &buf[p]);
p += 188;
} else {
- i = count-p;
- memcpy(demux->tsbuf, buf+p, i);
- demux->tsbufp=i;
+ i = count - p;
+ memcpy(demux->tsbuf, &buf[p], i);
+ demux->tsbufp = i;
goto bailout;
}
} else
@@ -485,24 +454,29 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
bailout:
spin_unlock(&demux->lock);
}
+
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- int p = 0,i, j;
+ int p = 0, i, j;
u8 tmppack[188];
+
spin_lock(&demux->lock);
- if ((i = demux->tsbufp)) {
- if (count < (j=204-i)) {
+ if (demux->tsbufp) {
+ i = demux->tsbufp;
+ j = 204 - i;
+ if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
}
memcpy(&demux->tsbuf[i], buf, j);
- if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8)) {
+ if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) {
memcpy(tmppack, demux->tsbuf, 188);
- if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
+ if (tmppack[0] == 0xB8)
+ tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
}
demux->tsbufp = 0;
@@ -510,16 +484,17 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
}
while (p < count) {
- if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
- if (count-p >= 204) {
- memcpy(tmppack, buf+p, 188);
- if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
+ if ((buf[p] == 0x47) | (buf[p] == 0xB8)) {
+ if (count - p >= 204) {
+ memcpy(tmppack, &buf[p], 188);
+ if (tmppack[0] == 0xB8)
+ tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
p += 204;
} else {
- i = count-p;
- memcpy(demux->tsbuf, buf+p, i);
- demux->tsbufp=i;
+ i = count - p;
+ memcpy(demux->tsbuf, &buf[p], i);
+ demux->tsbufp = i;
goto bailout;
}
} else {
@@ -530,14 +505,14 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
bailout:
spin_unlock(&demux->lock);
}
-EXPORT_SYMBOL(dvb_dmx_swfilter_204);
+EXPORT_SYMBOL(dvb_dmx_swfilter_204);
-static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
+static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
{
int i;
- for (i=0; i<demux->filternum; i++)
+ for (i = 0; i < demux->filternum; i++)
if (demux->filter[i].state == DMX_STATE_FREE)
break;
@@ -549,11 +524,11 @@ static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
return &demux->filter[i];
}
-static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
+static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux)
{
int i;
- for (i=0; i<demux->feednum; i++)
+ for (i = 0; i < demux->feednum; i++)
if (demux->feed[i].state == DMX_STATE_FREE)
break;
@@ -581,7 +556,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
spin_lock_irq(&feed->demux->lock);
if (dvb_demux_feed_find(feed)) {
printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
- __FUNCTION__, feed->type, feed->state, feed->pid);
+ __FUNCTION__, feed->type, feed->state, feed->pid);
goto out;
}
@@ -595,7 +570,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
spin_lock_irq(&feed->demux->lock);
if (!(dvb_demux_feed_find(feed))) {
printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
- __FUNCTION__, feed->type, feed->state, feed->pid);
+ __FUNCTION__, feed->type, feed->state, feed->pid);
goto out;
}
@@ -604,18 +579,17 @@ out:
spin_unlock_irq(&feed->demux->lock);
}
-static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
- enum dmx_ts_pes pes_type, size_t callback_length,
- size_t circular_buffer_size, int descramble,
- struct timespec timeout)
+static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
+ enum dmx_ts_pes pes_type,
+ size_t circular_buffer_size, struct timespec timeout)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
if (pid > DMX_MAX_PID)
return -EINVAL;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
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,
feed->pid = pid;
feed->buffer_size = circular_buffer_size;
- feed->descramble = descramble;
feed->timeout = timeout;
- feed->cb_length = callback_length;
feed->ts_type = ts_type;
feed->pes_type = pes_type;
- if (feed->descramble) {
- up(&demux->mutex);
- return -ENOSYS;
- }
-
if (feed->buffer_size) {
#ifdef NOBUFS
- feed->buffer=NULL;
+ feed->buffer = NULL;
#else
feed->buffer = vmalloc(feed->buffer_size);
if (!feed->buffer) {
@@ -667,14 +634,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
return 0;
}
-
-static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
+static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
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)
return 0;
}
-static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
+static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state < DMX_STATE_GO) {
@@ -731,13 +697,14 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
return ret;
}
-static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed,
- dmx_ts_cb callback)
+static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
+ struct dmx_ts_feed **ts_feed,
+ dmx_ts_cb callback)
{
- struct dvb_demux *demux = (struct dvb_demux *) dmx;
+ struct dvb_demux *demux = (struct dvb_demux *)dmx;
struct dvb_demux_feed *feed;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
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 **
(*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
(*ts_feed)->set = dmx_ts_feed_set;
-
if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
feed->state = DMX_STATE_FREE;
up(&demux->mutex);
@@ -776,22 +742,22 @@ static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **
return 0;
}
-static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed)
+static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
+ struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux *demux = (struct dvb_demux *) dmx;
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux *demux = (struct dvb_demux *)dmx;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state == DMX_STATE_FREE) {
up(&demux->mutex);
return -EINVAL;
}
-
#ifndef NOBUFS
vfree(feed->buffer);
- feed->buffer=0;
+ feed->buffer = NULL;
#endif
feed->state = DMX_STATE_FREE;
@@ -808,19 +774,18 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_
return 0;
}
-
/******************************************************************************
* dmx_section_feed API calls
******************************************************************************/
-static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
- struct dmx_section_filter** filter)
+static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
+ struct dmx_section_filter **filter)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
struct dvb_demux_filter *dvbdmxfilter;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
@@ -844,36 +809,29 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
return 0;
}
-
-static int dmx_section_feed_set(struct dmx_section_feed* feed,
- u16 pid, size_t circular_buffer_size,
- int descramble, int check_crc)
+static int dmx_section_feed_set(struct dmx_section_feed *feed,
+ u16 pid, size_t circular_buffer_size,
+ int check_crc)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
if (pid > 0x1fff)
return -EINVAL;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
dvb_demux_feed_add(dvbdmxfeed);
dvbdmxfeed->pid = pid;
dvbdmxfeed->buffer_size = circular_buffer_size;
- dvbdmxfeed->descramble = descramble;
- if (dvbdmxfeed->descramble) {
- up(&dvbdmx->mutex);
- return -ENOSYS;
- }
-
dvbdmxfeed->feed.sec.check_crc = check_crc;
#ifdef NOBUFS
dvbdmxfeed->buffer = NULL;
#else
- dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
+ dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
if (!dvbdmxfeed->buffer) {
up(&dvbdmx->mutex);
return -ENOMEM;
@@ -885,7 +843,6 @@ static int dmx_section_feed_set(struct dmx_section_feed* feed,
return 0;
}
-
static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
{
int i;
@@ -893,12 +850,12 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
struct dmx_section_filter *sf;
u8 mask, mode, doneq;
- if (!(f=dvbdmxfeed->filter))
+ if (!(f = dvbdmxfeed->filter))
return;
do {
sf = &f->filter;
doneq = 0;
- for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
+ for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
mode = sf->filter_mode[i];
mask = sf->filter_mask[i];
f->maskandmode[i] = mask & mode;
@@ -908,14 +865,13 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
} while ((f = f->next));
}
-
static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (feed->is_filtering) {
@@ -954,14 +910,13 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
return 0;
}
-
-static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
+static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!dvbdmx->stop_feed) {
@@ -980,15 +935,14 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
return ret;
}
-
static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
- struct dmx_section_filter* filter)
+ struct dmx_section_filter *filter)
{
- struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *) filter, *f;
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (dvbdmxfilter->feed != dvbdmxfeed) {
@@ -1005,7 +959,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
if (f == dvbdmxfilter) {
dvbdmxfeed->filter = dvbdmxfilter->next;
} else {
- while(f->next != dvbdmxfilter)
+ while (f->next != dvbdmxfilter)
f = f->next;
f->next = f->next->next;
}
@@ -1020,10 +974,10 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
struct dmx_section_feed **feed,
dmx_section_cb callback)
{
- struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
struct dvb_demux_feed *dvbdmxfeed;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
@@ -1041,7 +995,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
dvbdmxfeed->filter = NULL;
dvbdmxfeed->buffer = NULL;
- (*feed)=&dvbdmxfeed->feed.sec;
+ (*feed) = &dvbdmxfeed->feed.sec;
(*feed)->is_filtering = 0;
(*feed)->parent = demux;
(*feed)->priv = NULL;
@@ -1059,21 +1013,21 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
static int dvbdmx_release_section_feed(struct dmx_demux *demux,
struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
- struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
+ struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
- if (dvbdmxfeed->state==DMX_STATE_FREE) {
+ if (dvbdmxfeed->state == DMX_STATE_FREE) {
up(&dvbdmx->mutex);
return -EINVAL;
}
#ifndef NOBUFS
vfree(dvbdmxfeed->buffer);
- dvbdmxfeed->buffer=0;
+ dvbdmxfeed->buffer = NULL;
#endif
- dvbdmxfeed->state=DMX_STATE_FREE;
+ dvbdmxfeed->state = DMX_STATE_FREE;
dvb_demux_feed_del(dvbdmxfeed);
@@ -1083,14 +1037,13 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
return 0;
}
-
/******************************************************************************
* dvb_demux kernel data API calls
******************************************************************************/
static int dvbdmx_open(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
return -EUSERS;
@@ -1099,10 +1052,9 @@ static int dvbdmx_open(struct dmx_demux *demux)
return 0;
}
-
static int dvbdmx_close(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (dvbdemux->users == 0)
return -ENODEV;
@@ -1112,15 +1064,14 @@ static int dvbdmx_close(struct dmx_demux *demux)
return 0;
}
-
static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
{
- struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
return -EINVAL;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvb_dmx_swfilter(dvbdemux, buf, count);
up(&dvbdemux->mutex);
@@ -1130,10 +1081,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
return count;
}
-
-static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_add_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
struct list_head *head = &dvbdemux->frontend_list;
list_add(&(frontend->connectivity_list), head);
@@ -1141,13 +1092,13 @@ static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *fro
return 0;
}
-
-static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_remove_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
- list_for_each_safe (pos, n, head) {
+ list_for_each_safe(pos, n, head) {
if (DMX_FE_ENTRY(pos) == frontend) {
list_del(pos);
return 0;
@@ -1157,25 +1108,25 @@ static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *
return -ENODEV;
}
-
-static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
+static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (list_empty(&dvbdemux->frontend_list))
return NULL;
+
return &dvbdemux->frontend_list;
}
-
-static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_connect_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (demux->frontend)
return -EINVAL;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = frontend;
@@ -1183,12 +1134,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend
return 0;
}
-
static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = NULL;
@@ -1196,44 +1146,42 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
return 0;
}
-
-static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
+static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
+ memcpy(pids, dvbdemux->pids, 5 * sizeof(u16));
return 0;
}
-
int dvb_dmx_init(struct dvb_demux *dvbdemux)
{
- int i, err;
+ int i;
struct dmx_demux *dmx = &dvbdemux->dmx;
dvbdemux->users = 0;
- dvbdemux->filter = vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
+ dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter));
if (!dvbdemux->filter)
return -ENOMEM;
- dvbdemux->feed = vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
+ dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed));
if (!dvbdemux->feed) {
vfree(dvbdemux->filter);
return -ENOMEM;
}
- for (i=0; i<dvbdemux->filternum; i++) {
+ for (i = 0; i < dvbdemux->filternum; i++) {
dvbdemux->filter[i].state = DMX_STATE_FREE;
dvbdemux->filter[i].index = i;
}
- for (i=0; i<dvbdemux->feednum; i++) {
+ for (i = 0; i < dvbdemux->feednum; i++) {
dvbdemux->feed[i].state = DMX_STATE_FREE;
dvbdemux->feed[i].index = i;
}
- dvbdemux->frontend_list.next=
- dvbdemux->frontend_list.prev=
- &dvbdemux->frontend_list;
- for (i=0; i<DMX_TS_PES_OTHER; i++) {
+
+ INIT_LIST_HEAD(&dvbdemux->frontend_list);
+
+ for (i = 0; i < DMX_TS_PES_OTHER; i++) {
dvbdemux->pesfilter[i] = NULL;
dvbdemux->pids[i] = 0xffff;
}
@@ -1247,12 +1195,11 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
if (!dvbdemux->check_crc32)
dvbdemux->check_crc32 = dvb_dmx_crc32;
- if (!dvbdemux->memcopy)
- dvbdemux->memcopy = dvb_dmx_memcopy;
+ if (!dvbdemux->memcopy)
+ dvbdemux->memcopy = dvb_dmx_memcopy;
dmx->frontend = NULL;
- dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;
- dmx->priv = (void *) dvbdemux;
+ dmx->priv = dvbdemux;
dmx->open = dvbdmx_open;
dmx->close = dvbdmx_close;
dmx->write = dvbdmx_write;
@@ -1261,9 +1208,6 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
dmx->release_section_feed = dvbdmx_release_section_feed;
- dmx->descramble_mac_address = NULL;
- dmx->descramble_section_payload = NULL;
-
dmx->add_frontend = dvbdmx_add_frontend;
dmx->remove_frontend = dvbdmx_remove_frontend;
dmx->get_frontends = dvbdmx_get_frontends;
@@ -1274,21 +1218,15 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
sema_init(&dvbdemux->mutex, 1);
spin_lock_init(&dvbdemux->lock);
- if ((err = dmx_register_demux(dmx)) < 0)
- return err;
-
return 0;
}
-EXPORT_SYMBOL(dvb_dmx_init);
+EXPORT_SYMBOL(dvb_dmx_init);
-int dvb_dmx_release(struct dvb_demux *dvbdemux)
+void dvb_dmx_release(struct dvb_demux *dvbdemux)
{
- struct dmx_demux *dmx = &dvbdemux->dmx;
-
- dmx_unregister_demux(dmx);
vfree(dvbdemux->filter);
vfree(dvbdemux->feed);
- return 0;
}
+
EXPORT_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 c09beb39162..0cc888339d5 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -20,7 +20,6 @@
*
*/
-
#ifndef _DVB_DEMUX_H_
#define _DVB_DEMUX_H_
@@ -44,103 +43,98 @@
#define DVB_DEMUX_MASK_MAX 18
struct dvb_demux_filter {
- struct dmx_section_filter filter;
- u8 maskandmode [DMX_MAX_FILTER_SIZE];
- u8 maskandnotmode [DMX_MAX_FILTER_SIZE];
+ struct dmx_section_filter filter;
+ u8 maskandmode[DMX_MAX_FILTER_SIZE];
+ u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
int doneq;
- struct dvb_demux_filter *next;
- struct dvb_demux_feed *feed;
- int index;
- int state;
- int type;
- int pesto;
-
- u16 handle;
- u16 hw_handle;
- struct timer_list timer;
- int ts_state;
-};
+ struct dvb_demux_filter *next;
+ struct dvb_demux_feed *feed;
+ int index;
+ int state;
+ int type;
+ u16 hw_handle;
+ struct timer_list timer;
+};
#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
struct dvb_demux_feed {
- union {
- struct dmx_ts_feed ts;
- struct dmx_section_feed sec;
+ union {
+ struct dmx_ts_feed ts;
+ struct dmx_section_feed sec;
} feed;
- union {
- dmx_ts_cb ts;
- dmx_section_cb sec;
+ union {
+ dmx_ts_cb ts;
+ dmx_section_cb sec;
} cb;
- struct dvb_demux *demux;
+ struct dvb_demux *demux;
void *priv;
- int type;
- int state;
- u16 pid;
- u8 *buffer;
- int buffer_size;
- int descramble;
+ int type;
+ int state;
+ u16 pid;
+ u8 *buffer;
+ int buffer_size;
- struct timespec timeout;
- struct dvb_demux_filter *filter;
- int cb_length;
+ struct timespec timeout;
+ struct dvb_demux_filter *filter;
- int ts_type;
- enum dmx_ts_pes pes_type;
+ int ts_type;
+ enum dmx_ts_pes pes_type;
- int cc;
- int pusi_seen; /* prevents feeding of garbage from previous section */
+ int cc;
+ int pusi_seen; /* prevents feeding of garbage from previous section */
- u16 peslen;
+ u16 peslen;
struct list_head list_head;
- int index; /* a unique index for each feed (can be used as hardware pid filter index) */
+ unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
};
struct dvb_demux {
- struct dmx_demux dmx;
- void *priv;
- int filternum;
- int feednum;
- int (*start_feed) (struct dvb_demux_feed *feed);
- int (*stop_feed) (struct dvb_demux_feed *feed);
- int (*write_to_decoder) (struct dvb_demux_feed *feed,
+ struct dmx_demux dmx;
+ void *priv;
+ int filternum;
+ int feednum;
+ int (*start_feed)(struct dvb_demux_feed *feed);
+ int (*stop_feed)(struct dvb_demux_feed *feed);
+ int (*write_to_decoder)(struct dvb_demux_feed *feed,
const u8 *buf, size_t len);
- u32 (*check_crc32) (struct dvb_demux_feed *feed,
+ u32 (*check_crc32)(struct dvb_demux_feed *feed,
const u8 *buf, size_t len);
- void (*memcopy) (struct dvb_demux_feed *feed, u8 *dst,
+ void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
const u8 *src, size_t len);
- int users;
+ int users;
#define MAX_DVB_DEMUX_USERS 10
- struct dvb_demux_filter *filter;
- struct dvb_demux_feed *feed;
+ struct dvb_demux_filter *filter;
+ struct dvb_demux_feed *feed;
- struct list_head frontend_list;
+ struct list_head frontend_list;
- struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
- u16 pids[DMX_TS_PES_OTHER];
- int playing;
- int recording;
+ struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
+ u16 pids[DMX_TS_PES_OTHER];
+ int playing;
+ int recording;
#define DMX_MAX_PID 0x2000
struct list_head feed_list;
- u8 tsbuf[204];
- int tsbufp;
+ u8 tsbuf[204];
+ int tsbufp;
struct semaphore mutex;
spinlock_t lock;
};
-
int dvb_dmx_init(struct dvb_demux *dvbdemux);
-int dvb_dmx_release(struct dvb_demux *dvbdemux);
-void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count);
+void dvb_dmx_release(struct dvb_demux *dvbdemux);
+void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
+ size_t count);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count);
+void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
+ size_t count);
#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 6a968c346a3..87935490bfb 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -62,7 +62,6 @@
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/crc32.h>
-#include <linux/version.h>
#include "dvb_demux.h"
#include "dvb_net.h"
@@ -171,11 +170,7 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
skb->mac.raw=skb->data;
skb_pull(skb,dev->hard_header_len);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
- eth = skb->mac.ethernet;
-#else
eth = eth_hdr(skb);
-#endif
if (*eth->h_dest & 1) {
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
@@ -908,7 +903,7 @@ static int dvb_net_feed_start(struct net_device *dev)
return ret;
}
- ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
+ ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
if (ret<0) {
printk("%s: could not set section feed\n", dev->name);
@@ -960,9 +955,7 @@ static int dvb_net_feed_start(struct net_device *dev)
priv->tsfeed->priv = (void *)dev;
ret = priv->tsfeed->set(priv->tsfeed, priv->pid,
TS_PACKET, DMX_TS_PES_OTHER,
- 188 * 100, /* nr. of bytes delivered per callback */
32768, /* circular buffer size */
- 0, /* descramble */
timeout);
if (ret < 0) {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 612e5b087b1..54e2b29076b 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -93,13 +93,30 @@ config DVB_USB_DIGITV
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
config DVB_USB_VP7045
- tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
+ tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
depends on DVB_USB
help
Say Y here to support the
+
TwinhanDTV Alpha (stick) (VP-7045),
- TwinhanDTV MagicBox II (VP-7046) and
- DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
+ TwinhanDTV MagicBox II (VP-7046),
+ DigitalNow TinyUSB 2 DVB-t,
+ DigitalRise USB 2.0 Ter (Beetle) and
+ TYPHOON DVB-T USB DRIVE
+
+ DVB-T USB2.0 receivers.
+
+config DVB_USB_VP702X
+ tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+
+ TwinhanDTV StarBox,
+ DigitalRise USB Starbox and
+ TYPHOON DVB-S USB 2.0 BOX
+
+ DVB-S USB2.0 receivers.
config DVB_USB_NOVA_T_USB2
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 746d87ed6f3..2dc9aad9681 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
dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
+obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
+
dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index f2fcc2f1f84..e55322ef76b 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;
static int a800_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL);
}
/* 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 9e96a188f1e..3fe383f4bb4 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,
return 0;
}
-/* I2C */
-static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
+/* GPIO */
+static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
{
struct cxusb_state *st = d->priv;
u8 o[2],i;
- if (path == st->cur_i2c_path)
+ if (st->gpio_write_state[GPIO_TUNER] == onoff)
return;
- o[0] = IOCTL_SET_I2C_PATH;
- switch (path) {
- case PATH_CX22702:
- o[1] = 0;
- break;
- case PATH_TUNER_OTHER:
- o[1] = 1;
- break;
- default:
- err("unkown i2c path");
- return;
- }
- cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
+ o[0] = GPIO_TUNER;
+ o[1] = onoff;
+ cxusb_ctrl_msg(d,CMD_GPIO_WRITE,o,2,&i,1);
if (i != 0x01)
- deb_info("i2c_path setting failed.\n");
+ deb_info("gpio_write failed.\n");
- st->cur_i2c_path = path;
+ st->gpio_write_state[GPIO_TUNER] = onoff;
}
+/* I2C */
static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
{
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)
switch (msg[i].addr) {
case 0x63:
- cxusb_set_i2c_path(d,PATH_CX22702);
+ cxusb_gpio_tuner(d,0);
break;
default:
- cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+ cxusb_gpio_tuner(d,1);
break;
}
@@ -147,16 +138,20 @@ static struct i2c_algorithm cxusb_i2c_algo = {
static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
{
- return 0;
+ u8 b = 0;
+ if (onoff)
+ return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
+ else
+ return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
}
static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 buf[2] = { 0x03, 0x00 };
if (onoff)
- cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+ cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0);
else
- cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
+ cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0);
return 0;
}
@@ -182,22 +177,11 @@ static int cxusb_tuner_attach(struct dvb_usb_device *d)
static int cxusb_frontend_attach(struct dvb_usb_device *d)
{
- u8 buf[2] = { 0x03, 0x00 };
- u8 b = 0;
-
- if (usb_set_interface(d->udev,0,0) < 0)
- err("set interface to alts=0 failed");
-
- cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
- cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
- cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
-
+ u8 b;
if (usb_set_interface(d->udev,0,6) < 0)
err("set interface failed");
- cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
- cxusb_set_i2c_path(d,PATH_CX22702);
- cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
+ cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
return 0;
@@ -211,7 +195,7 @@ static struct dvb_usb_properties cxusb_properties;
static int cxusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL);
}
static struct usb_device_id cxusb_table [] = {
@@ -237,14 +221,12 @@ static struct dvb_usb_properties cxusb_properties = {
.generic_bulk_ctrl_endpoint = 0x01,
/* parameter for the MPEG2-data transfer */
.urb = {
- .type = DVB_USB_ISOC,
+ .type = DVB_USB_BULK,
.count = 5,
.endpoint = 0x02,
.u = {
- .isoc = {
- .framesperurb = 32,
- .framesize = 940,
- .interval = 5,
+ .bulk = {
+ .buffersize = 8192,
}
}
},
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 1d79016e319..135c2a81f58 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -1,30 +1,31 @@
#ifndef _DVB_USB_CXUSB_H_
#define _DVB_USB_CXUSB_H_
-#define DVB_USB_LOG_PREFIX "digitv"
+#define DVB_USB_LOG_PREFIX "cxusb"
#include "dvb-usb.h"
extern int dvb_usb_cxusb_debug;
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
/* usb commands - some of it are guesses, don't have a reference yet */
-#define CMD_I2C_WRITE 0x08
-#define CMD_I2C_READ 0x09
+#define CMD_I2C_WRITE 0x08
+#define CMD_I2C_READ 0x09
-#define CMD_IOCTL 0x0e
-#define IOCTL_SET_I2C_PATH 0x02
+#define CMD_GPIO_READ 0x0d
+#define CMD_GPIO_WRITE 0x0e
+#define GPIO_TUNER 0x02
-#define CMD_POWER_OFF 0x50
-#define CMD_POWER_ON 0x51
+#define CMD_POWER_OFF 0xdc
+#define CMD_POWER_ON 0xde
-enum cxusb_i2c_pathes {
- PATH_UNDEF = 0x00,
- PATH_CX22702 = 0x01,
- PATH_TUNER_OTHER = 0x02,
-};
+#define CMD_STREAMING_ON 0x36
+#define CMD_STREAMING_OFF 0x37
+
+#define CMD_ANALOG 0x50
+#define CMD_DIGITAL 0x51
struct cxusb_state {
- enum cxusb_i2c_pathes cur_i2c_path;
+ u8 gpio_write_state[3];
};
#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 828b5182e16..0058505634a 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;
static int dibusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0)
return 0;
return -EINVAL;
@@ -126,10 +126,12 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
+/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
+
// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
-/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
#endif
{ } /* Terminating entry */
};
@@ -262,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
},
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
- { &dibusb_dib3000mb_table[27], NULL },
+ { &dibusb_dib3000mb_table[28], NULL },
{ NULL },
},
#endif
@@ -306,12 +308,16 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
}
},
- .num_device_descs = 1,
+ .num_device_descs = 2,
.devices = {
- { "KWorld/ADSTech Instant DVB-T USB 2.0",
+ { "KWorld/ADSTech Instant DVB-T USB2.0",
{ &dibusb_dib3000mb_table[23], NULL },
{ &dibusb_dib3000mb_table[24], NULL },
},
+ { "KWorld Xpert DVB-T USB2.0",
+ { &dibusb_dib3000mb_table[27], NULL },
+ { NULL }
+ },
}
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index e9dac430f37..6a0912eab39 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;
static int dibusb_mc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL);
}
/* 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 f70e0be0920..74545f82eff 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)
}
static struct mt352_config digitv_mt352_config = {
- .demod_address = 0x0, /* ignored by the digitv anyway */
.demod_init = digitv_mt352_demod_init,
.pll_set = dvb_usb_pll_set,
};
-static struct nxt6000_config digitv_nxt6000_config = {
- .demod_address = 0x0, /* ignored by the digitv anyway */
- .clock_inversion = 0x0,
+static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ u8 b[5];
+ dvb_usb_pll_set(fe,fep,b);
+ return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
+}
- .pll_init = NULL,
- .pll_set = NULL,
+static struct nxt6000_config digitv_nxt6000_config = {
+ .clock_inversion = 1,
+ .pll_set = digitv_nxt6000_pll_set,
};
static int digitv_frontend_attach(struct dvb_usb_device *d)
{
- if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL ||
+ (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL)
return 0;
- if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
-
- warn("nxt6000 support is not done yet, in fact you are one of the first "
- "person who wants to use this device in Linux. Please report to "
- "linux-dvb@linuxtv.org");
-
- return 0;
- }
return -EIO;
}
@@ -173,7 +170,18 @@ static struct dvb_usb_properties digitv_properties;
static int digitv_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
+ struct dvb_usb_device *d;
+ int ret;
+ if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
+ u8 b[4] = { 0 };
+
+ b[0] = 1;
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+
+ b[0] = 0;
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+ }
+ return ret;
}
static 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 b032523b07b..0a94ec22aeb 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 {
struct dvb_frontend_parameters fep;
struct dvb_frontend frontend;
+ struct dvb_frontend_ops ops;
};
static 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)
deb_info("attaching frontend dtt200u\n");
state->d = d;
+ memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
- state->frontend.ops = &dtt200u_fe_ops;
+ state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
goto success;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 47dba6e4596..5aa12ebab34 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;
static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0)
return 0;
return -ENODEV;
}
static struct usb_device_id dtt200u_usb_table [] = {
-// { USB_DEVICE(0x04b4,0x8613) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
- { 0 },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
+ { 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
@@ -189,7 +188,7 @@ static struct dvb_usb_properties wt220u_properties = {
.num_device_descs = 1,
.devices = {
- { .name = "WideView WT-220U PenType Receiver (and clones)",
+ { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
.cold_ids = { &dtt200u_usb_table[2], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
@@ -201,9 +200,9 @@ static struct dvb_usb_properties wt220u_properties = {
static struct usb_driver dtt200u_usb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dtt200u",
- .probe = dtt200u_usb_probe,
+ .probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit,
- .id_table = dtt200u_usb_table,
+ .id_table = dtt200u_usb_table,
};
/* 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 794d513a848..0818996bf15 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 @@
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KYE 0x0458
#define USB_VID_MEDION 0x1660
+#define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -52,12 +54,14 @@
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
+#define USB_PID_TWINHAN_VP7020_COLD 0x3203
+#define USB_PID_TWINHAN_VP7020_WARM 0x3204
#define USB_PID_TWINHAN_VP7045_COLD 0x3205
#define USB_PID_TWINHAN_VP7045_WARM 0x3206
-#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
-#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_TWINHAN_VP7021_COLD 0x3207
#define USB_PID_TWINHAN_VP7021_WARM 0x3208
+#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
+#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
@@ -85,5 +89,7 @@
#define USB_PID_MEDION_MD95700 0x0932
#define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f
+#define USB_PID_PCTV_200E 0x020e
+#define USB_PID_PCTV_400E 0x020f
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 65f0c095abc..a902059812a 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
/*
* USB
*/
-int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
+
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
+ *props, struct module *owner,struct dvb_usb_device **du)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct dvb_usb_device *d = NULL;
@@ -170,6 +172,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *p
usb_set_intfdata(intf, d);
+ if (du != NULL)
+ *du = d;
+
ret = dvb_usb_init(d);
}
@@ -196,19 +201,6 @@ void dvb_usb_device_exit(struct usb_interface *intf)
}
EXPORT_SYMBOL(dvb_usb_device_exit);
-/* module stuff */
-static int __init dvb_usb_module_init(void)
-{
- return 0;
-}
-
-static void __exit dvb_usb_module_exit(void)
-{
-}
-
-module_init (dvb_usb_module_init);
-module_exit (dvb_usb_module_exit);
-
MODULE_VERSION("0.3");
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_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 a80567caf50..0e4f1035b0d 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;
* helper functions.
*
* @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
- * Currently only BULK is implemented
+ * (BULK or ISOC)
*
* @num_device_descs: number of struct dvb_usb_device_description in @devices
* @devices: array of struct dvb_usb_device_description compatibles with these
@@ -310,7 +310,7 @@ struct dvb_usb_device {
void *priv;
};
-extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
extern void dvb_usb_device_exit(struct usb_interface *);
/* 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 258a92bfbcc..1841a66427b 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;
static int nova_t_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL);
}
/* 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 2112ac3cf5e..6fd67657c26 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;
static int umt_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0)
return 0;
return -EINVAL;
}
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 00000000000..f20d8dbd0be
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,339 @@
+/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
+ * DVB-S receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ * Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This file can be removed soon, after the DST-driver is rewritten to provice
+ * the frontend-controlling separately.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp702x.h"
+
+struct vp702x_fe_state {
+ struct dvb_frontend fe;
+ struct dvb_usb_device *d;
+
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone_mode;
+
+ u8 lnb_buf[8];
+
+ u8 lock;
+ u8 sig;
+ u8 snr;
+
+ unsigned long next_status_check;
+ unsigned long status_check_interval;
+};
+
+static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
+{
+ u8 buf[10];
+ if (time_after(jiffies,st->next_status_check)) {
+ vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
+
+ st->lock = buf[4];
+ vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
+ vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
+
+ st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+ }
+ return 0;
+}
+
+static u8 vp702x_chksum(u8 *buf,int f, int count)
+{
+ u8 s = 0;
+ int i;
+ for (i = f; i < f+count; i++)
+ s += buf[i];
+ return ~s+1;
+}
+
+static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ deb_fe("%s\n",__FUNCTION__);
+
+ if (st->lock == 0)
+ *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ else
+ *status = 0;
+
+ deb_fe("real state: %x\n",*status);
+ *status = 0x1f;
+
+ if (*status & FE_HAS_LOCK)
+ st->status_check_interval = 1000;
+ else
+ st->status_check_interval = 250;
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ *ber = 0;
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ *unc = 0;
+ return 0;
+}
+
+static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+
+ *strength = (st->sig << 8) | st->sig;
+ return 0;
+}
+
+static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+ u8 _snr;
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+
+ _snr = (st->snr & 0x1f) * 0xff / 0x1f;
+ *snr = (_snr << 8) | _snr;
+ return 0;
+}
+
+static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ tune->min_delay_ms = 2000;
+ return 0;
+}
+
+static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u32 freq = fep->frequency/1000;
+ /*CalFrequency*/
+/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
+ u64 sr;
+ u8 cmd[8] = { 0 },ibuf[10];
+
+ cmd[0] = (freq >> 8) & 0x7f;
+ cmd[1] = freq & 0xff;
+ cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
+
+ sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20;
+ do_div(sr,88000);
+ cmd[3] = (sr >> 12) & 0xff;
+ cmd[4] = (sr >> 4) & 0xff;
+ cmd[5] = (sr << 4) & 0xf0;
+
+ deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %Lu (%Lx)\n",
+ fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, sr, sr);
+
+/* if (fep->inversion == INVERSION_ON)
+ cmd[6] |= 0x80; */
+
+ if (st->voltage == SEC_VOLTAGE_18)
+ cmd[6] |= 0x40;
+
+/* if (fep->u.qpsk.symbol_rate > 8000000)
+ cmd[6] |= 0x20;
+
+ if (fep->frequency < 1531000)
+ cmd[6] |= 0x04;
+
+ if (st->tone_mode == SEC_TONE_ON)
+ cmd[6] |= 0x01;*/
+
+ cmd[7] = vp702x_chksum(cmd,0,7);
+
+ st->status_check_interval = 250;
+ st->next_status_check = jiffies;
+
+ vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
+ msleep(30);
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("tuning failed.\n");
+ else
+ deb_fe("tuning succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ return 0;
+}
+
+static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd *m)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 cmd[8],ibuf[10];
+ memset(cmd,0,8);
+
+ deb_fe("%s\n",__FUNCTION__);
+
+ if (m->msg_len > 4)
+ return -EINVAL;
+
+ cmd[1] = SET_DISEQC_CMD;
+ cmd[2] = m->msg_len;
+ memcpy(&cmd[3], m->msg, m->msg_len);
+ cmd[7] = vp702x_chksum(cmd,0,7);
+
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("diseqc cmd failed.\n");
+ else
+ deb_fe("diseqc cmd succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ return 0;
+}
+
+static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 ibuf[10];
+ deb_fe("%s\n",__FUNCTION__);
+
+ st->tone_mode = tone;
+
+ if (tone == SEC_TONE_ON)
+ st->lnb_buf[2] = 0x02;
+ else
+ st->lnb_buf[2] = 0x00;
+
+ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+
+ vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("set_tone cmd failed.\n");
+ else
+ deb_fe("set_tone cmd succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
+ voltage)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 ibuf[10];
+ deb_fe("%s\n",__FUNCTION__);
+
+ st->voltage = voltage;
+
+ if (voltage != SEC_VOLTAGE_OFF)
+ st->lnb_buf[4] = 0x01;
+ else
+ st->lnb_buf[4] = 0x00;
+
+ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+
+ vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("set_voltage cmd failed.\n");
+ else
+ deb_fe("set_voltage cmd succeeded.\n");
+
+ return 0;
+}
+
+static void vp702x_fe_release(struct dvb_frontend* fe)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ kfree(st);
+}
+
+static struct dvb_frontend_ops vp702x_fe_ops;
+
+struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
+{
+ struct vp702x_fe_state *s = kmalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+ memset(s,0,sizeof(struct vp702x_fe_state));
+
+ s->d = d;
+ s->fe.ops = &vp702x_fe_ops;
+ s->fe.demodulator_priv = s;
+
+ s->lnb_buf[1] = SET_LNB_POWER;
+ s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
+
+ goto success;
+error:
+ return NULL;
+success:
+ return &s->fe;
+}
+
+
+static struct dvb_frontend_ops vp702x_fe_ops = {
+ .info = {
+ .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 1000, /* kHz for QPSK frontends */
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500, /* ppm */
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+ FE_CAN_QPSK |
+ FE_CAN_FEC_AUTO
+ },
+ .release = vp702x_fe_release,
+
+ .init = NULL,
+ .sleep = NULL,
+
+ .set_frontend = vp702x_fe_set_frontend,
+ .get_frontend = vp702x_fe_get_frontend,
+ .get_tune_settings = vp702x_fe_get_tune_settings,
+
+ .read_status = vp702x_fe_read_status,
+ .read_ber = vp702x_fe_read_ber,
+ .read_signal_strength = vp702x_fe_read_signal_strength,
+ .read_snr = vp702x_fe_read_snr,
+ .read_ucblocks = vp702x_fe_read_unc_blocks,
+
+ .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
+ .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
+ .set_tone = vp702x_fe_set_tone,
+ .set_voltage = vp702x_fe_set_voltage,
+};
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
new file mode 100644
index 00000000000..de13c04e8e6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -0,0 +1,290 @@
+/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
+ * receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ * Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp702x.h"
+
+/* debug */
+int dvb_usb_vp702x_debug;
+module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+struct vp702x_state {
+ u8 pid_table[17]; /* [16] controls the pid_table state */
+};
+
+/* check for mutex FIXME */
+int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+ int ret = 0,try = 0;
+
+ while (ret >= 0 && ret != blen && try < 3) {
+ ret = usb_control_msg(d->udev,
+ usb_rcvctrlpipe(d->udev,0),
+ req,
+ USB_TYPE_VENDOR | USB_DIR_IN,
+ value,index,b,blen,
+ 2000);
+ deb_info("reading number %d (ret: %d)\n",try,ret);
+ try++;
+ }
+
+ if (ret < 0 || ret != blen) {
+ warn("usb in operation failed.");
+ ret = -EIO;
+ } else
+ ret = 0;
+
+ deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+ debug_dump(b,blen,deb_xfer);
+
+ return ret;
+}
+
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+ deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+ debug_dump(b,blen,deb_xfer);
+
+ if (usb_control_msg(d->udev,
+ usb_sndctrlpipe(d->udev,0),
+ req,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ value,index,b,blen,
+ 2000) != blen) {
+ warn("usb out operation failed.");
+ return -EIO;
+ } else
+ return 0;
+}
+
+int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
+{
+ int ret;
+
+ if ((ret = down_interruptible(&d->usb_sem)))
+ return ret;
+
+ if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
+ goto unlock;
+ msleep(msec);
+ ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
+
+unlock:
+ up(&d->usb_sem);
+
+ return ret;
+}
+
+int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
+{
+ u8 bout[olen+2];
+ u8 bin[ilen+1];
+ int ret = 0;
+
+ bout[0] = 0x00;
+ bout[1] = cmd;
+ memcpy(&bout[2],o,olen);
+
+ ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec);
+
+ if (ret == 0)
+ memcpy(i,&bin[1],ilen);
+
+ return ret;
+}
+
+static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+ struct vp702x_state *st = d->priv;
+ u8 buf[9];
+
+ if (onoff) {
+ st->pid_table[16] |= 1 << index;
+ st->pid_table[index*2] = (pid >> 8) & 0xff;
+ st->pid_table[index*2+1] = pid & 0xff;
+ } else {
+ st->pid_table[16] &= ~(1 << index);
+ st->pid_table[index*2] = st->pid_table[index*2+1] = 0;
+ }
+
+ return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10);
+}
+
+static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0);
+
+ vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+ return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+}
+
+/* keys for the enclosed remote control */
+static struct dvb_usb_rc_key vp702x_rc_keys[] = {
+ { 0x00, 0x01, KEY_1 },
+ { 0x00, 0x02, KEY_2 },
+};
+
+/* remote control stuff (does not work with my box) */
+static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[10];
+ int i;
+
+/* remove the following return to enabled remote querying */
+ return 0;
+
+ vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
+
+ deb_rc("remote query key: %x %d\n",key[1],key[1]);
+
+ if (key[1] == 0x44) {
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
+ if (vp702x_rc_keys[i].custom == key[1]) {
+ *state = REMOTE_KEY_PRESSED;
+ *event = vp702x_rc_keys[i].event;
+ break;
+ }
+ return 0;
+}
+
+static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+ u8 macb[9];
+ if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10))
+ return -EIO;
+ memcpy(mac,&macb[3],6);
+ return 0;
+}
+
+static int vp702x_frontend_attach(struct dvb_usb_device *d)
+{
+ u8 buf[9] = { 0 };
+
+ if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10))
+ return -EIO;
+
+ buf[8] = '\0';
+ info("system string: %s",&buf[1]);
+
+ d->fe = vp702x_fe_attach(d);
+ return 0;
+}
+
+static struct dvb_usb_properties vp702x_properties;
+
+static int vp702x_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ usb_clear_halt(udev,usb_sndctrlpipe(udev,0));
+ usb_clear_halt(udev,usb_rcvctrlpipe(udev,0));
+
+ return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id vp702x_usb_table [] = {
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
+
+static struct dvb_usb_properties vp702x_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 8, /* !!! */
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-vp702x-01.fw",
+
+ .pid_filter = vp702x_pid_filter,
+ .power_ctrl = vp702x_power_ctrl,
+ .frontend_attach = vp702x_frontend_attach,
+ .read_mac_address = vp702x_read_mac_addr,
+
+ .rc_key_map = vp702x_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys),
+ .rc_interval = 400,
+ .rc_query = vp702x_rc_query,
+
+ .size_of_priv = sizeof(struct vp702x_state),
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
+ .cold_ids = { &vp702x_usb_table[0], NULL },
+ .warm_ids = { &vp702x_usb_table[1], NULL },
+ },
+ { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
+ .cold_ids = { &vp702x_usb_table[2], NULL },
+ .warm_ids = { &vp702x_usb_table[3], NULL },
+ },
+ { 0 },
+ }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp702x_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "dvb-usb-vp702x",
+ .probe = vp702x_usb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = vp702x_usb_table,
+};
+
+/* module stuff */
+static int __init vp702x_usb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&vp702x_usb_driver))) {
+ err("usb_register failed. (%d)",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit vp702x_usb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&vp702x_usb_driver);
+}
+
+module_init(vp702x_usb_module_init);
+module_exit(vp702x_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
+MODULE_VERSION("1.0-alpha");
+MODULE_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 00000000000..4a3e8c7eca2
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -0,0 +1,109 @@
+#ifndef _DVB_USB_VP7021_H_
+#define _DVB_USB_VP7021_H_
+
+#define DVB_USB_LOG_PREFIX "vp702x"
+#include "dvb-usb.h"
+
+extern int dvb_usb_vp702x_debug;
+#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
+#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args)
+#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args)
+
+/* commands are read and written with USB control messages */
+
+/* consecutive read/write operation */
+#define REQUEST_OUT 0xB2
+#define REQUEST_IN 0xB3
+
+/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
+ * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
+ * the returning buffer looks as follows
+ * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
+
+#define GET_TUNER_STATUS 0x05
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
+
+#define GET_SYSTEM_STRING 0x06
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
+
+#define SET_DISEQC_CMD 0x08
+/* additional out buffer:
+ * 0 1 2 3 4
+ * len X1 X2 X3 X4
+ * additional in buffer:
+ * 0 1 2
+ * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
+
+#define SET_LNB_POWER 0x09
+/* additional out buffer:
+ * 0 1 2
+ * 0x00 0xff 1 = on, 0 = off
+ * additional in buffer:
+ * 0 1 2
+ * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
+
+#define GET_MAC_ADDRESS 0x0A
+/* #define GET_MAC_ADDRESS 0x0B */
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
+
+#define SET_PID_FILTER 0x11
+/* additional in buffer:
+ * 0 1 ... 14 15 16
+ * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
+
+/* request: 0xB2; i: 0; v: 0;
+ * b[0] != 0 -> tune and lock a channel
+ * 0 1 2 3 4 5 6 7
+ * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
+ */
+
+
+/* one direction requests */
+#define READ_REMOTE_REQ 0xB4
+/* IN i: 0; v: 0; b[0] == request, b[1] == key */
+
+#define READ_PID_NUMBER_REQ 0xB5
+/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
+
+#define WRITE_EEPROM_REQ 0xB6
+/* OUT i: offset; v: value to write; no extra buffer */
+
+#define READ_EEPROM_REQ 0xB7
+/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
+
+#define READ_STATUS 0xB8
+/* IN i: 0; v: 0; bufferlen 10 */
+
+#define READ_TUNER_REG_REQ 0xB9
+/* IN i: 0; v: register; b[0] = value */
+
+#define READ_FX2_REG_REQ 0xBA
+/* IN i: offset; v: 0; b[0] = value */
+
+#define WRITE_FX2_REG_REQ 0xBB
+/* OUT i: offset; v: value to write; 1 byte extra buffer */
+
+#define SET_TUNER_POWER_REQ 0xBC
+/* IN i: 0 = power off, 1 = power on */
+
+#define WRITE_TUNER_REG_REQ 0xBD
+/* IN i: register, v: value to write, no extra buffer */
+
+#define RESET_TUNER 0xBE
+/* IN i: 0, v: 0, no extra buffer */
+
+extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
+
+extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
+extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
+extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 9ac95f54f9f..0f57abeb6d6 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
return 0;
}
-
static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
{
return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
@@ -199,7 +198,7 @@ static struct dvb_usb_properties vp7045_properties;
static int vp7045_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL);
}
static struct usb_device_id vp7045_usb_table [] = {
@@ -256,9 +255,9 @@ static struct dvb_usb_properties vp7045_properties = {
static struct usb_driver vp7045_usb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_vp7045",
- .probe = vp7045_usb_probe,
+ .probe = vp7045_usb_probe,
.disconnect = dvb_usb_device_exit,
- .id_table = vp7045_usb_table,
+ .id_table = vp7045_usb_table,
};
/* module stuff */
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 8222b88cb48..d4b97989e3e 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,7 +1,7 @@
/*
cx24110 - Single Chip Satellite Channel Receiver driver module
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
work
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
@@ -387,8 +387,9 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
{
- int rv, bit, i;
+ int rv, bit;
struct cx24110_state *state = fe->demodulator_priv;
+ unsigned long timeout;
if (burst == SEC_MINI_A)
bit = 0x00;
@@ -398,12 +399,14 @@ static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
return -EINVAL;
rv = cx24110_readreg(state, 0x77);
- cx24110_writereg(state, 0x77, rv|0x04);
+ if (!(rv & 0x04))
+ cx24110_writereg(state, 0x77, rv | 0x04);
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
- for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
- ; /* wait for LNB ready */
+ timeout = jiffies + msecs_to_jiffies(100);
+ while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
+ ; /* wait for LNB ready */
return 0;
}
@@ -413,17 +416,22 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
{
int i, rv;
struct cx24110_state *state = fe->demodulator_priv;
+ unsigned long timeout;
for (i = 0; i < cmd->msg_len; i++)
cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
rv = cx24110_readreg(state, 0x77);
- cx24110_writereg(state, 0x77, rv|0x04);
+ if (rv & 0x04) {
+ cx24110_writereg(state, 0x77, rv & ~0x04);
+ msleep(30); /* reportedly fixes switching problems */
+ }
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
- for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);)
+ timeout = jiffies + msecs_to_jiffies(100);
+ while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
; /* wait for LNB ready */
return 0;
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 6b663f4744e..b63ecf26421 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -1,7 +1,7 @@
/*
cx24110 - Single Chip Satellite Channel Receiver driver module
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
work
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index cd434b7cf9d..21433e1831e 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -23,7 +23,6 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index cd33705a432..441de665fec 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -22,7 +22,6 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index d32dc4de9e7..cc1bc0edd65 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)
{
struct mt352_state* state = fe->demodulator_priv;
- u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
- (mt352_read_register(state, AGC_GAIN_0));
+ /* align the 12 bit AGC gain with the most significant bits */
+ u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
+ (mt352_read_register(state, AGC_GAIN_0) << 4);
+ /* inverse of gain is signal strength */
*strength = ~signal;
return 0;
}
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index 966de9853d1..88a57b79111 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
if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
return result;
+ msleep(500);
return 0;
}
@@ -525,6 +526,12 @@ static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
return 0;
}
+static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 500;
+ return 0;
+}
+
static struct dvb_frontend_ops nxt6000_ops;
struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
@@ -578,6 +585,8 @@ static struct dvb_frontend_ops nxt6000_ops = {
.init = nxt6000_init,
+ .get_tune_settings = nxt6000_fe_get_tune_settings,
+
.set_frontend = nxt6000_set_frontend,
.read_status = nxt6000_read_status,
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index cc0a77c790f..b6d0eecc59e 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,
or51132_setmode(fe);
}
- /* Change only if we are actually changing the channel */
- if (state->current_frequency != param->frequency) {
- dvb_pll_configure(state->config->pll_desc, buf,
- param->frequency, 0);
- dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
- "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
- if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
- printk(KERN_WARNING "or51132: set_parameters error "
- "writing to tuner\n");
-
- /* Set to current mode */
- or51132_setmode(fe);
-
- /* Update current frequency */
- state->current_frequency = param->frequency;
- }
+ dvb_pll_configure(state->config->pll_desc, buf,
+ param->frequency, 0);
+ dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
+ "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
+ if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
+ printk(KERN_WARNING "or51132: set_parameters error "
+ "writing to tuner\n");
+
+ /* Set to current mode */
+ or51132_setmode(fe);
+
+ /* Update current frequency */
+ state->current_frequency = param->frequency;
return 0;
}
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 4f396ac8de7..c7fe27fd530 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -48,7 +48,8 @@ struct s5h1420_state {
};
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings);
static int debug = 0;
@@ -91,7 +92,8 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
switch(voltage) {
case SEC_VOLTAGE_13:
- s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
+ s5h1420_writereg(state, 0x3c,
+ (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
break;
case SEC_VOLTAGE_18:
@@ -112,18 +114,21 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch(tone) {
case SEC_TONE_ON:
- s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
+ s5h1420_writereg(state, 0x3b,
+ (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
break;
case SEC_TONE_OFF:
- s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
+ s5h1420_writereg(state, 0x3b,
+ (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
break;
}
return 0;
}
-static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd* cmd)
{
struct s5h1420_state* state = fe->demodulator_priv;
u8 val;
@@ -131,6 +136,9 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
unsigned long timeout;
int result = 0;
+ if (cmd->msg_len > 8)
+ return -EINVAL;
+
/* setup for DISEQC */
val = s5h1420_readreg(state, 0x3b);
s5h1420_writereg(state, 0x3b, 0x02);
@@ -138,16 +146,17 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
/* write the DISEQC command bytes */
for(i=0; i< cmd->msg_len; i++) {
- s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
+ s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
}
/* kick off transmission */
- s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
+ s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
+ ((cmd->msg_len-1) << 4) | 0x08);
/* wait for transmission to complete */
timeout = jiffies + ((100*HZ) / 1000);
while(time_before(jiffies, timeout)) {
- if (s5h1420_readreg(state, 0x3b) & 0x08)
+ if (!(s5h1420_readreg(state, 0x3b) & 0x08))
break;
msleep(5);
@@ -161,7 +170,8 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
return result;
}
-static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
+static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
+ struct dvb_diseqc_slave_reply* reply)
{
struct s5h1420_state* state = fe->demodulator_priv;
u8 val;
@@ -205,7 +215,7 @@ static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_
/* extract data */
for(i=0; i< length; i++) {
- reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
+ reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
}
exit:
@@ -236,7 +246,7 @@ static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicm
s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
/* wait for transmission to complete */
- timeout = jiffies + ((20*HZ) / 1000);
+ timeout = jiffies + ((100*HZ) / 1000);
while(time_before(jiffies, timeout)) {
if (!(s5h1420_readreg(state, 0x3b) & 0x08))
break;
@@ -259,9 +269,9 @@ static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
val = s5h1420_readreg(state, 0x14);
if (val & 0x02)
- status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right
+ status |= FE_HAS_SIGNAL;
if (val & 0x01)
- status |= FE_HAS_CARRIER; // FIXME: not sure if this is right
+ status |= FE_HAS_CARRIER;
val = s5h1420_readreg(state, 0x36);
if (val & 0x01)
status |= FE_HAS_VITERBI;
@@ -284,8 +294,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* determine lock state */
*status = s5h1420_get_status_bits(state);
- /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
- wait a bit and check again */
+ /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
+ the inversion, wait a bit and check again */
if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
val = s5h1420_readreg(state, 0x32);
if ((val & 0x07) == 0x03) {
@@ -330,6 +340,10 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
tmp = (tmp * 2 * 7) / 8;
break;
}
+ if (tmp == 0) {
+ printk("s5h1420: avoided division by 0\n");
+ tmp = 1;
+ }
tmp = state->fclk / tmp;
/* 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)
s5h1420_writereg(state, 0x46, 0x1d);
mdelay(25);
- return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ return 0;
}
static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
struct s5h1420_state* state = fe->demodulator_priv;
- u8 val = 0xff - s5h1420_readreg(state, 0x15);
+ u8 val = s5h1420_readreg(state, 0x15);
- return (int) ((val << 8) | val);
+ *strength = (u16) ((val << 8) | val);
+
+ return 0;
}
static 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)
s5h1420_writereg(state, 0x46, 0x1f);
mdelay(25);
- return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ return 0;
}
static void s5h1420_reset(struct s5h1420_state* state)
@@ -396,11 +418,12 @@ static void s5h1420_reset(struct s5h1420_state* state)
udelay(10);
}
-static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+static void s5h1420_setsymbolrate(struct s5h1420_state* state,
+ struct dvb_frontend_parameters *p)
{
u64 val;
- val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
+ val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
if (p->u.qpsk.symbol_rate <= 21000000) {
val *= 2;
}
@@ -415,7 +438,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_fronte
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
{
- u64 val;
+ u64 val = 0;
int sampling = 2;
if (s5h1420_readreg(state, 0x05) & 0x2)
@@ -427,10 +450,10 @@ static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
val |= s5h1420_readreg(state, 0x13);
s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
- val *= (state->fclk / 1000);
+ val *= (state->fclk / 1000ULL);
do_div(val, ((1<<24) * sampling));
- return (u32) (val * 1000);
+ return (u32) (val * 1000ULL);
}
static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
@@ -463,46 +486,55 @@ static int s5h1420_getfreqoffset(struct s5h1420_state* state)
/* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
* divide fclk by 1000000 to get the correct value. */
- val = - ((val * (state->fclk/1000000)) / (1<<24));
+ val = (((-val) * (state->fclk/1000000)) / (1<<24));
return val;
}
-static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+static void s5h1420_setfec_inversion(struct s5h1420_state* state,
+ struct dvb_frontend_parameters *p)
{
+ u8 inversion = 0;
+
+ if (p->inversion == INVERSION_OFF) {
+ inversion = state->config->invert ? 0x08 : 0;
+ } else if (p->inversion == INVERSION_ON) {
+ inversion = state->config->invert ? 0 : 0x08;
+ }
+
if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
- s5h1420_writereg(state, 0x31, 0x00);
s5h1420_writereg(state, 0x30, 0x3f);
+ s5h1420_writereg(state, 0x31, 0x00 | inversion);
} else {
switch(p->u.qpsk.fec_inner) {
case FEC_1_2:
- s5h1420_writereg(state, 0x31, 0x10);
s5h1420_writereg(state, 0x30, 0x01);
+ s5h1420_writereg(state, 0x31, 0x10 | inversion);
break;
case FEC_2_3:
- s5h1420_writereg(state, 0x31, 0x11);
s5h1420_writereg(state, 0x30, 0x02);
+ s5h1420_writereg(state, 0x31, 0x11 | inversion);
break;
case FEC_3_4:
- s5h1420_writereg(state, 0x31, 0x12);
s5h1420_writereg(state, 0x30, 0x04);
- break;
+ s5h1420_writereg(state, 0x31, 0x12 | inversion);
+ break;
case FEC_5_6:
- s5h1420_writereg(state, 0x31, 0x13);
s5h1420_writereg(state, 0x30, 0x08);
+ s5h1420_writereg(state, 0x31, 0x13 | inversion);
break;
case FEC_6_7:
- s5h1420_writereg(state, 0x31, 0x14);
s5h1420_writereg(state, 0x30, 0x10);
+ s5h1420_writereg(state, 0x31, 0x14 | inversion);
break;
case FEC_7_8:
- s5h1420_writereg(state, 0x31, 0x15);
s5h1420_writereg(state, 0x30, 0x20);
+ s5h1420_writereg(state, 0x31, 0x15 | inversion);
break;
default:
@@ -536,22 +568,6 @@ static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
return FEC_NONE;
}
-static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
-{
- if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
- s5h1420_writereg(state, 0x31, 0x00);
- s5h1420_writereg(state, 0x30, 0x3f);
- } else {
- u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
- tmp |= 0x10;
-
- if (p->inversion == INVERSION_ON)
- tmp |= 0x80;
-
- s5h1420_writereg(state, 0x31, tmp);
- }
-}
-
static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
{
if (s5h1420_readreg(state, 0x32) & 0x08)
@@ -560,35 +576,35 @@ static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
return INVERSION_OFF;
}
-static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int s5h1420_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
{
struct s5h1420_state* state = fe->demodulator_priv;
- u32 frequency_delta;
+ int frequency_delta;
struct dvb_frontend_tune_settings fesettings;
+ u32 tmp;
/* check if we should do a fast-tune */
memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
s5h1420_get_tune_settings(fe, &fesettings);
frequency_delta = p->frequency - state->tunedfreq;
- if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
+ if ((frequency_delta > -fesettings.max_drift) &&
+ (frequency_delta < fesettings.max_drift) &&
(frequency_delta != 0) &&
(state->fec_inner == p->u.qpsk.fec_inner) &&
(state->symbol_rate == p->u.qpsk.symbol_rate)) {
- s5h1420_setfreqoffset(state, frequency_delta);
+ if (state->config->pll_set) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_set(fe, p, &tmp);
+ s5h1420_setfreqoffset(state, p->frequency - tmp);
+ }
return 0;
}
/* first of all, software reset */
s5h1420_reset(state);
- /* set tuner PLL */
- if (state->config->pll_set) {
- s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
- state->config->pll_set(fe, p, &state->tunedfreq);
- s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
- }
-
/* set s5h1420 fclk PLL according to desired symbol rate */
if (p->u.qpsk.symbol_rate > 28000000) {
state->fclk = 88000000;
@@ -609,8 +625,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
/* set misc registers */
s5h1420_writereg(state, 0x02, 0x00);
+ s5h1420_writereg(state, 0x06, 0x00);
s5h1420_writereg(state, 0x07, 0xb0);
- s5h1420_writereg(state, 0x0a, 0x67);
+ s5h1420_writereg(state, 0x0a, 0xe7);
s5h1420_writereg(state, 0x0b, 0x78);
s5h1420_writereg(state, 0x0c, 0x48);
s5h1420_writereg(state, 0x0d, 0x6b);
@@ -626,21 +643,26 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
/* start QPSK */
s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
- /* set the frequency offset to adjust for PLL inaccuracy */
- s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
+ /* set tuner PLL */
+ if (state->config->pll_set) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_set(fe, p, &tmp);
+ s5h1420_setfreqoffset(state, 0);
+ }
/* set the reset of the parameters */
s5h1420_setsymbolrate(state, p);
- s5h1420_setinversion(state, p);
- s5h1420_setfec(state, p);
+ s5h1420_setfec_inversion(state, p);
state->fec_inner = p->u.qpsk.fec_inner;
state->symbol_rate = p->u.qpsk.symbol_rate;
state->postlocked = 0;
+ state->tunedfreq = p->frequency;
return 0;
}
-static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int s5h1420_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
{
struct s5h1420_state* state = fe->demodulator_priv;
@@ -652,7 +674,8 @@ static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
return 0;
}
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings)
{
if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
fesettings->min_delay_ms = 50;
@@ -717,7 +740,8 @@ static void s5h1420_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops s5h1420_ops;
-struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
+struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
+ struct i2c_adapter* i2c)
{
struct s5h1420_state* state = NULL;
u8 identity;
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index b687fc77ceb..872028ddf2a 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -30,6 +30,9 @@ struct s5h1420_config
/* the demodulator's i2c address */
u8 demod_address;
+ /* does the inversion require inversion? */
+ u8 invert:1;
+
/* PLL maintenance */
int (*pll_init)(struct dvb_frontend* fe);
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 928aca052af..8d09afd7545 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -35,7 +35,6 @@ struct stv0297_state {
struct dvb_frontend frontend;
unsigned long base_freq;
- u8 pwm;
};
#if 1
@@ -46,94 +45,6 @@ struct stv0297_state {
#define STV0297_CLOCK_KHZ 28900
-static u8 init_tab[] = {
- 0x00, 0x09,
- 0x01, 0x69,
- 0x03, 0x00,
- 0x04, 0x00,
- 0x07, 0x00,
- 0x08, 0x00,
- 0x20, 0x00,
- 0x21, 0x40,
- 0x22, 0x00,
- 0x23, 0x00,
- 0x24, 0x40,
- 0x25, 0x88,
- 0x30, 0xff,
- 0x31, 0x00,
- 0x32, 0xff,
- 0x33, 0x00,
- 0x34, 0x50,
- 0x35, 0x7f,
- 0x36, 0x00,
- 0x37, 0x20,
- 0x38, 0x00,
- 0x40, 0x1c,
- 0x41, 0xff,
- 0x42, 0x29,
- 0x43, 0x00,
- 0x44, 0xff,
- 0x45, 0x00,
- 0x46, 0x00,
- 0x49, 0x04,
- 0x4a, 0xff,
- 0x4b, 0x7f,
- 0x52, 0x30,
- 0x55, 0xae,
- 0x56, 0x47,
- 0x57, 0xe1,
- 0x58, 0x3a,
- 0x5a, 0x1e,
- 0x5b, 0x34,
- 0x60, 0x00,
- 0x63, 0x00,
- 0x64, 0x00,
- 0x65, 0x00,
- 0x66, 0x00,
- 0x67, 0x00,
- 0x68, 0x00,
- 0x69, 0x00,
- 0x6a, 0x02,
- 0x6b, 0x00,
- 0x70, 0xff,
- 0x71, 0x00,
- 0x72, 0x00,
- 0x73, 0x00,
- 0x74, 0x0c,
- 0x80, 0x00,
- 0x81, 0x00,
- 0x82, 0x00,
- 0x83, 0x00,
- 0x84, 0x04,
- 0x85, 0x80,
- 0x86, 0x24,
- 0x87, 0x78,
- 0x88, 0x00,
- 0x89, 0x00,
- 0x90, 0x01,
- 0x91, 0x01,
- 0xa0, 0x00,
- 0xa1, 0x00,
- 0xa2, 0x00,
- 0xb0, 0x91,
- 0xb1, 0x0b,
- 0xc0, 0x53,
- 0xc1, 0x70,
- 0xc2, 0x12,
- 0xd0, 0x00,
- 0xd1, 0x00,
- 0xd2, 0x00,
- 0xd3, 0x00,
- 0xd4, 0x00,
- 0xd5, 0x00,
- 0xde, 0x00,
- 0xdf, 0x00,
- 0x61, 0x49,
- 0x62, 0x0b,
- 0x53, 0x08,
- 0x59, 0x08,
-};
-
static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
{
@@ -378,34 +289,9 @@ static int stv0297_init(struct dvb_frontend *fe)
struct stv0297_state *state = fe->demodulator_priv;
int i;
- /* soft reset */
- stv0297_writereg_mask(state, 0x80, 1, 1);
- stv0297_writereg_mask(state, 0x80, 1, 0);
-
- /* reset deinterleaver */
- stv0297_writereg_mask(state, 0x81, 1, 1);
- stv0297_writereg_mask(state, 0x81, 1, 0);
-
/* load init table */
- for (i = 0; i < sizeof(init_tab); i += 2) {
- stv0297_writereg(state, init_tab[i], init_tab[i + 1]);
- }
-
- /* set a dummy symbol rate */
- stv0297_set_symbolrate(state, 6900);
-
- /* invert AGC1 polarity */
- stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
-
- /* setup bit error counting */
- stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
-
- /* min + max PWM */
- stv0297_writereg(state, 0x4a, 0x00);
- stv0297_writereg(state, 0x4b, state->pwm);
+ for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
+ stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
msleep(200);
if (state->config->pll_init)
@@ -606,7 +492,13 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
stv0297_set_inversion(state, inversion);
/* kick off lock */
- stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+ /* Disable corner detection for higher QAMs */
+ if (p->u.qam.modulation == QAM_128 ||
+ p->u.qam.modulation == QAM_256)
+ stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
+ else
+ stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+
stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
@@ -732,7 +624,7 @@ static void stv0297_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops stv0297_ops;
struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
- struct i2c_adapter *i2c, int pwm)
+ struct i2c_adapter *i2c)
{
struct stv0297_state *state = NULL;
@@ -746,7 +638,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
state->i2c = i2c;
memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
state->base_freq = 0;
- state->pwm = pwm;
/* check if the demod is there */
if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 3be53598930..9e53f019db7 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -29,6 +29,12 @@ struct stv0297_config
/* the demodulator's i2c address */
u8 demod_address;
+ /* inittab - array of pairs of values.
+ * First of each pair is the register, second is the value.
+ * List should be terminated with an 0xff, 0xff pair.
+ */
+ u8* inittab;
+
/* does the "inversion" need inverted? */
u8 invert:1;
@@ -38,7 +44,7 @@ struct stv0297_config
};
extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
- struct i2c_adapter* i2c, int pwm);
+ struct i2c_adapter* i2c);
extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index cfa3928bb48..2d62931f20b 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -63,12 +63,8 @@ struct stv0299_state {
u32 tuner_frequency;
u32 symbol_rate;
fe_code_rate_t fec_inner;
- int errmode;
};
-#define STATUS_BER 0
-#define STATUS_UCBLOCKS 1
-
static int debug;
static int debug_legacy_dish_switch;
#define dprintk(args...) \
@@ -481,7 +477,7 @@ static int stv0299_init (struct dvb_frontend* fe)
if (state->config->pll_init) {
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_init(fe);
+ state->config->pll_init(fe, state->i2c);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
}
@@ -520,7 +516,8 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_BER) return 0;
+ stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10);
+ msleep(100);
*ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
@@ -559,8 +556,9 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
- else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+ stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30);
+ msleep(100);
+ *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
}
@@ -603,7 +601,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
} else {
/* A "normal" tune is requested */
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, p);
+ state->config->pll_set(fe, state->i2c, p);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
stv0299_writeregI(state, 0x32, 0x80);
@@ -615,7 +613,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
}
} else {
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, p);
+ state->config->pll_set(fe, state->i2c, p);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
stv0299_set_FEC (state, p->u.qpsk.fec_inner);
@@ -709,7 +707,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
state->tuner_frequency = 0;
state->symbol_rate = 0;
state->fec_inner = 0;
- state->errmode = STATUS_BER;
/* check if the demod is there */
stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 79457a80a11..d0c4484861e 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -92,8 +92,8 @@ struct stv0299_config
int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
/* PLL maintenance */
- int (*pll_init)(struct dvb_frontend* fe);
- int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+ int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c);
+ int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params);
};
extern 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 ab0c032472c..74cea9f8d72 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)
tmp = tda1004x_read_byte(state, TDA1004X_SNR);
if (tmp < 0)
return -EIO;
- if (tmp)
- tmp = 255 - tmp;
+ tmp = 255 - tmp;
*snr = ((tmp << 8) | tmp);
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 70fb44b391a..c6d276618e8 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)
{
struct ves1820_state* state = fe->demodulator_priv;
int i;
- int val;
ves1820_writereg(state, 0, 0);
- for (i = 0; i < 53; i++) {
- val = ves1820_inittab[i];
- if ((i == 2) && (state->config->selagc)) val |= 0x08;
- ves1820_writereg(state, i, val);
- }
+ for (i = 0; i < sizeof(ves1820_inittab); i++)
+ ves1820_writereg(state, i, ves1820_inittab[i]);
+ if (state->config->selagc)
+ ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
ves1820_writereg(state, 0x34, state->pwm);
- if (state->config->pll_init) state->config->pll_init(fe);
+ if (state->config->pll_init)
+ state->config->pll_init(fe);
return 0;
}
@@ -234,7 +233,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p
ves1820_writereg(state, 0x09, reg0x09[real_qam]);
ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
-
+ ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
return 0;
}
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index e4c6e87f6c5..22b203f8ff2 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)
if (ret < 0)
printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
if (rgb_on &&
- (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
+ ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
+ (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
+ (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
}
@@ -177,9 +179,6 @@ static void init_av7110_av(struct av7110 *av7110)
ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
if (ret < 0)
printk("dvb-ttpci:cannot set volume :%d\n",ret);
- ret = av7110_setup_irc_config(av7110, 0);
- if (ret < 0)
- printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
}
static void recover_arm(struct av7110 *av7110)
@@ -265,60 +264,6 @@ static int arm_thread(void *data)
}
-/**
- * Hack! we save the last av7110 ptr. This should be ok, since
- * you rarely will use more then one IR control.
- *
- * If we want to support multiple controls we would have to do much more...
- */
-int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
-{
- int ret = 0;
- static struct av7110 *last;
-
- dprintk(4, "%p\n", av7110);
-
- if (!av7110)
- av7110 = last;
- else
- last = av7110;
-
- if (av7110) {
- ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
- av7110->ir_config = ir_config;
- }
- return ret;
-}
-
-static void (*irc_handler)(u32);
-
-void av7110_register_irc_handler(void (*func)(u32))
-{
- dprintk(4, "registering %p\n", func);
- irc_handler = func;
-}
-
-void av7110_unregister_irc_handler(void (*func)(u32))
-{
- dprintk(4, "unregistering %p\n", func);
- irc_handler = NULL;
-}
-
-static void run_handlers(unsigned long ircom)
-{
- if (irc_handler != NULL)
- (*irc_handler)((u32) ircom);
-}
-
-static DECLARE_TASKLET(irtask, run_handlers, 0);
-
-static void IR_handle(struct av7110 *av7110, u32 ircom)
-{
- dprintk(4, "ircommand = %08x\n", ircom);
- irtask.data = (unsigned long) ircom;
- tasklet_schedule(&irtask);
-}
-
/****************************************************************************
* IRQ handling
****************************************************************************/
@@ -711,8 +656,9 @@ static void gpioirq(unsigned long data)
return;
case DATA_IRCOMMAND:
- IR_handle(av7110,
- swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
+ if (av7110->ir_handler)
+ av7110->ir_handler(av7110,
+ swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
break;
@@ -1668,9 +1614,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
int ret;
u8 data[4];
u32 div;
@@ -1687,7 +1632,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
if (params->frequency > 1530000) data[3] = 0xc0;
- ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
if (ret != 1)
return -EIO;
return 0;
@@ -1751,9 +1696,8 @@ static u8 alps_bsbe1_inittab[] = {
0xff, 0xff
};
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
int ret;
u8 data[4];
u32 div;
@@ -1768,7 +1712,7 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
- ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
return (ret != 1) ? -EIO : 0;
}
@@ -1936,6 +1880,98 @@ static struct sp8870_config alps_tdlb7_config = {
};
+static u8 nexusca_stv0297_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x00,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0x7b,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x49,
+ 0x62, 0x0b,
+ 0x53, 0x08,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
@@ -1984,6 +2020,7 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
static struct stv0297_config nexusca_stv0297_config = {
.demod_address = 0x1C,
+ .inittab = nexusca_stv0297_inittab,
.invert = 1,
.pll_set = nexusca_stv0297_pll_set,
};
@@ -2261,7 +2298,7 @@ static int frontend_init(struct av7110 *av7110)
case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
- av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
+ av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
if (av7110->fe) {
/* set TDA9819 into DVB mode */
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
goto err_av7110_exit_v4l_12;
#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
- av7110_ir_init();
+ av7110_ir_init(av7110);
#endif
printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
av7110_num++;
@@ -2734,6 +2771,9 @@ static int av7110_detach(struct saa7146_dev* saa)
struct av7110 *av7110 = saa->ext_priv;
dprintk(4, "%p\n", av7110);
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+ av7110_ir_exit(av7110);
+#endif
if (budgetpatch) {
/* Disable RPS1 */
saa7146_write(saa, MC1, MASK_29);
@@ -2830,7 +2870,7 @@ static struct saa7146_pci_extension_data x_var = { \
.ext_priv = x_name, \
.ext = &av7110_extension }
-MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X");
+MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
@@ -2842,16 +2882,16 @@ MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
static struct pci_device_id pci_tbl[] = {
- MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
- MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000),
- MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
- MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
- MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
- MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
- MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
- MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
- MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
- MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
+ MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
+ MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
+ MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
+ MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
+ MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
+ MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
+ MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
+ MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
+ MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
+ MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
@@ -2889,9 +2929,6 @@ static int __init av7110_init(void)
static void __exit av7110_exit(void)
{
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
- av7110_ir_exit();
-#endif
saa7146_unregister_extension(&av7110_extension);
}
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 508b7739c60..cce00ef293e 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -228,7 +228,10 @@ struct av7110 {
struct dvb_video_events video_events;
video_size_t video_size;
- u32 ir_config;
+ u32 ir_config;
+ u32 ir_command;
+ void (*ir_handler)(struct av7110 *av7110, u32 ircom);
+ struct tasklet_struct ir_tasklet;
/* firmware stuff */
unsigned char *bin_fw;
@@ -257,12 +260,10 @@ struct av7110 {
extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid);
-extern void av7110_register_irc_handler(void (*func)(u32));
-extern void av7110_unregister_irc_handler(void (*func)(u32));
extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
-extern int av7110_ir_init (void);
-extern void av7110_ir_exit (void);
+extern int av7110_ir_init(struct av7110 *av7110);
+extern void av7110_ir_exit(struct av7110 *av7110);
/* msp3400 i2c subaddresses */
#define MSP_WR_DEM 0x10
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 1220826696c..7442f56a72e 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -41,6 +41,8 @@
#include "av7110.h"
#include "av7110_hw.h"
+#define _NOHANDSHAKE
+
/****************************************************************************
* DEBI functions
****************************************************************************/
@@ -364,7 +366,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
msleep(1);
}
- wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
+ if (FW_VERSION(av7110->arm_app) <= 0x261f)
+ wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
#ifndef _NOHANDSHAKE
start = jiffies;
@@ -437,7 +440,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
- wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
+ if (FW_VERSION(av7110->arm_app) <= 0x261f)
+ wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
#ifdef COM_DEBUG
start = jiffies;
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 665cdb8a3f7..357a3728ec6 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -7,16 +7,16 @@
#include <asm/bitops.h>
#include "av7110.h"
+#include "av7110_hw.h"
-#define UP_TIMEOUT (HZ/4)
+#define UP_TIMEOUT (HZ*7/25)
/* enable ir debugging by or'ing debug with 16 */
-static int ir_initialized;
+static int av_cnt;
+static struct av7110 *av_list[4];
static struct input_dev input_dev;
-static u32 ir_config;
-
static u16 key_map [256] = {
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
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)
static struct timer_list keyup_timer = { .function = av7110_emit_keyup };
-static void av7110_emit_key(u32 ircom)
+static void av7110_emit_key(unsigned long parm)
{
+ struct av7110 *av7110 = (struct av7110 *) parm;
+ u32 ir_config = av7110->ir_config;
+ u32 ircom = av7110->ir_command;
u8 data;
u8 addr;
static u16 old_toggle = 0;
@@ -62,19 +65,33 @@ static void av7110_emit_key(u32 ircom)
u16 keycode;
/* extract device address and data */
- if (ir_config & 0x0001) {
- /* TODO RCMM: ? bits device address, 8 bits data */
+ switch (ir_config & 0x0003) {
+ case 0: /* RC5: 5 bits device address, 6 bits data */
+ data = ircom & 0x3f;
+ addr = (ircom >> 6) & 0x1f;
+ break;
+
+ case 1: /* RCMM: 8(?) bits device address, 8(?) bits data */
data = ircom & 0xff;
addr = (ircom >> 8) & 0xff;
- } else {
- /* RC5: 5 bits device address, 6 bits data */
+ break;
+
+ case 2: /* extended RC5: 5 bits device address, 7 bits data */
data = ircom & 0x3f;
addr = (ircom >> 6) & 0x1f;
+ /* invert 7th data bit for backward compatibility with RC5 keymaps */
+ if (!(ircom & 0x1000))
+ data |= 0x40;
+ break;
+
+ default:
+ printk("invalid ir_config %x\n", ir_config);
+ return;
}
keycode = key_map[data];
- dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n",
+ dprintk(16, "code %08x -> addr %i data 0x%02x -> keycode %i\n",
ircom, addr, data, keycode);
/* check device address (if selected) */
@@ -87,10 +104,10 @@ static void av7110_emit_key(u32 ircom)
return;
}
- if (ir_config & 0x0001)
+ if ((ir_config & 0x0003) == 1)
new_toggle = 0; /* RCMM */
else
- new_toggle = (ircom & 0x800); /* RC5 */
+ new_toggle = (ircom & 0x800); /* RC5, extended RC5 */
if (timer_pending(&keyup_timer)) {
del_timer(&keyup_timer);
@@ -137,6 +154,8 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
{
char *page;
int size = 4 + 256 * sizeof(u16);
+ u32 ir_config;
+ int i;
if (count < size)
return -EINVAL;
@@ -153,60 +172,95 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
memcpy(&ir_config, page, 4);
memcpy(&key_map, page + 4, 256 * sizeof(u16));
vfree(page);
- av7110_setup_irc_config(NULL, ir_config);
+ if (FW_VERSION(av_list[0]->arm_app) >= 0x2620 && !(ir_config & 0x0001))
+ ir_config |= 0x0002; /* enable extended RC5 */
+ for (i = 0; i < av_cnt; i++)
+ av7110_setup_irc_config(av_list[i], ir_config);
input_register_keys();
return count;
}
-int __init av7110_ir_init(void)
+int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
{
- static struct proc_dir_entry *e;
+ int ret = 0;
- if (ir_initialized)
- return 0;
+ dprintk(4, "%p\n", av7110);
+ if (av7110) {
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+ av7110->ir_config = ir_config;
+ }
+ return ret;
+}
- init_timer(&keyup_timer);
- keyup_timer.data = 0;
- input_dev.name = "DVB on-card IR receiver";
+static void ir_handler(struct av7110 *av7110, u32 ircom)
+{
+ dprintk(4, "ircommand = %08x\n", ircom);
+ av7110->ir_command = ircom;
+ tasklet_schedule(&av7110->ir_tasklet);
+}
- /**
- * enable keys
- */
- set_bit(EV_KEY, input_dev.evbit);
- set_bit(EV_REP, input_dev.evbit);
- input_register_keys();
+int __init av7110_ir_init(struct av7110 *av7110)
+{
+ static struct proc_dir_entry *e;
- input_register_device(&input_dev);
- input_dev.timer.function = input_repeat_key;
+ if (av_cnt >= sizeof av_list/sizeof av_list[0])
+ return -ENOSPC;
- av7110_setup_irc_config(NULL, 0x0001);
- av7110_register_irc_handler(av7110_emit_key);
+ av7110_setup_irc_config(av7110, 0x0001);
+ av_list[av_cnt++] = av7110;
- e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
- if (e) {
- e->write_proc = av7110_ir_write_proc;
- e->size = 4 + 256 * sizeof(u16);
+ if (av_cnt == 1) {
+ init_timer(&keyup_timer);
+ keyup_timer.data = 0;
+
+ input_dev.name = "DVB on-card IR receiver";
+ set_bit(EV_KEY, input_dev.evbit);
+ set_bit(EV_REP, input_dev.evbit);
+ input_register_keys();
+ input_register_device(&input_dev);
+ input_dev.timer.function = input_repeat_key;
+
+ e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ if (e) {
+ e->write_proc = av7110_ir_write_proc;
+ e->size = 4 + 256 * sizeof(u16);
+ }
}
- ir_initialized = 1;
+ tasklet_init(&av7110->ir_tasklet, av7110_emit_key, (unsigned long) av7110);
+ av7110->ir_handler = ir_handler;
+
return 0;
}
-void __exit av7110_ir_exit(void)
+void __exit av7110_ir_exit(struct av7110 *av7110)
{
- if (ir_initialized == 0)
+ int i;
+
+ if (av_cnt == 0)
return;
- del_timer_sync(&keyup_timer);
- remove_proc_entry("av7110_ir", NULL);
- av7110_unregister_irc_handler(av7110_emit_key);
- input_unregister_device(&input_dev);
- ir_initialized = 0;
+
+ av7110->ir_handler = NULL;
+ tasklet_kill(&av7110->ir_tasklet);
+ for (i = 0; i < av_cnt; i++)
+ if (av_list[i] == av7110) {
+ av_list[i] = av_list[av_cnt-1];
+ av_list[av_cnt-1] = NULL;
+ break;
+ }
+
+ if (av_cnt == 1) {
+ del_timer_sync(&keyup_timer);
+ remove_proc_entry("av7110_ir", NULL);
+ input_unregister_device(&input_dev);
+ }
+
+ av_cnt--;
}
//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
//MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index e65fc36e2ce..6af74f78b3e 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)
return 0;
}
-static struct v4l2_input inputs[2] = {
+static struct v4l2_input inputs[4] = {
{
.index = 0,
.name = "DVB",
@@ -87,6 +87,22 @@ static struct v4l2_input inputs[2] = {
.tuner = 0,
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ }, {
+ .index = 2,
+ .name = "Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .status = 0,
+ }, {
+ .index = 3,
+ .name = "Y/C",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .status = 0,
}
};
@@ -212,24 +228,44 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
}
if (0 != av7110->current_input) {
+ dprintk(1, "switching to analog TV:\n");
adswitch = 1;
source = SAA7146_HPS_SOURCE_PORT_B;
sync = SAA7146_HPS_SYNC_PORT_B;
memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
- dprintk(1, "switching to analog TV\n");
- msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
- msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
- msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
- msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
- if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
- if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
- dprintk(1, "setting band in demodulator failed.\n");
- } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
- saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
+ switch (av7110->current_input) {
+ case 1:
+ dprintk(1, "switching SAA7113 to Analog Tuner Input.\n");
+ msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
+ msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
+ msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
+ msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
+
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
+ dprintk(1, "setting band in demodulator failed.\n");
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
+ }
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ case 2:
+ dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n");
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ case 3:
+ dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n");
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ default:
+ dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n");
}
} else {
adswitch = 0;
@@ -300,7 +336,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
// FIXME: standard / stereo detection is still broken
msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
-
msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
stereo = (s8)(stereo_det >> 8);
@@ -310,7 +345,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
t->audmode = V4L2_TUNER_MODE_STEREO;
}
else if (stereo < -0x10) {
- /* bilingual*/
+ /* bilingual */
t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
t->audmode = V4L2_TUNER_MODE_LANG1;
}
@@ -344,7 +379,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
fm_matrix = 0x3000; // mono
src = 0x0010;
break;
- default: /* case V4L2_TUNER_MODE_MONO: {*/
+ default: /* case V4L2_TUNER_MODE_MONO: */
dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
fm_matrix = 0x3000; // mono
src = 0x0030;
@@ -406,7 +441,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 2)
+ if (i->index < 0 || i->index >= 4)
return -EINVAL;
} else {
if (i->index != 0)
@@ -433,10 +468,9 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
if (!av7110->analog_tuner_flags)
return 0;
- if (input < 0 || input >= 2)
+ if (input < 0 || input >= 4)
return -EINVAL;
- /* FIXME: switch inputs here */
av7110->current_input = input;
return av7110_dvb_c_switch(fh);
}
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 9746d2bb916..7692cd23f83 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)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
struct saa7146_dev *saa = budget_av->budget.dev;
- int timeout = 50; // 5 seconds (4.4.6 Ready)
+ int timeout = 500; // 5 seconds (4.4.6 Ready)
if (slot != 0)
return -EINVAL;
@@ -217,7 +217,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
- saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
return -ETIMEDOUT;
}
@@ -276,7 +275,6 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
{
printk(KERN_INFO "budget-av: cam ejected\n");
saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
- saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
budget_av->slot_status = 0;
}
}
@@ -453,9 +451,9 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra
}
static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
struct dvb_frontend_parameters *params)
{
- struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
u32 div;
u8 buf[4];
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,
else if (params->frequency < 2150000)
buf[3] |= 0xC0;
- if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -745,6 +743,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
// Enable / PowerON Frontend
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index a1267054bc0..2980db3ef22 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -40,6 +40,7 @@
#include "dvb_ca_en50221.h"
#include "stv0299.h"
+#include "stv0297.h"
#include "tda1004x.h"
#define DEBIADDR_IR 0x1234
@@ -548,9 +549,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
{
- struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
u8 buf[4];
u32 div;
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
if (params->frequency > 1530000)
buf[3] = 0xc0;
- if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -669,9 +669,9 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
}
static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
struct dvb_frontend_parameters *params)
{
- struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
u32 div;
u8 buf[4];
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,
else if (params->frequency < 2150000)
buf[3] |= 0xC0;
- if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -848,6 +848,180 @@ static struct tda1004x_config philips_tdm1316l_config = {
.request_firmware = philips_tdm1316l_request_firmware,
};
+static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+ u8 tuner_buf[5];
+ struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
+ .flags = 0,
+ .buf = tuner_buf,
+ .len = sizeof(tuner_buf) };
+ int tuner_frequency = 0;
+ u8 band, cp, filter;
+
+ // determine charge pump
+ tuner_frequency = params->frequency + 36125000;
+ if (tuner_frequency < 87000000)
+ return -EINVAL;
+ else if (tuner_frequency < 130000000) {
+ cp = 3;
+ band = 1;
+ } else if (tuner_frequency < 160000000) {
+ cp = 5;
+ band = 1;
+ } else if (tuner_frequency < 200000000) {
+ cp = 6;
+ band = 1;
+ } else if (tuner_frequency < 290000000) {
+ cp = 3;
+ band = 2;
+ } else if (tuner_frequency < 420000000) {
+ cp = 5;
+ band = 2;
+ } else if (tuner_frequency < 480000000) {
+ cp = 6;
+ band = 2;
+ } else if (tuner_frequency < 620000000) {
+ cp = 3;
+ band = 4;
+ } else if (tuner_frequency < 830000000) {
+ cp = 5;
+ band = 4;
+ } else if (tuner_frequency < 895000000) {
+ cp = 7;
+ band = 4;
+ } else
+ return -EINVAL;
+
+ // assume PLL filter should always be 8MHz for the moment.
+ filter = 1;
+
+ // calculate divisor
+ tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
+
+ // setup tuner buffer
+ tuner_buf[0] = tuner_frequency >> 8;
+ tuner_buf[1] = tuner_frequency & 0xff;
+ tuner_buf[2] = 0xc8;
+ tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+ tuner_buf[4] = 0x80;
+
+ stv0297_enable_plli2c(fe);
+ if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(50);
+
+ stv0297_enable_plli2c(fe);
+ if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(1);
+
+ return 0;
+}
+
+static u8 dvbc_philips_tdm1316l_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x20,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0x7b,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x38,
+ 0x62, 0x0a,
+ 0x53, 0x13,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
+
+static struct stv0297_config dvbc_philips_tdm1316l_config = {
+ .demod_address = 0x1c,
+ .inittab = dvbc_philips_tdm1316l_inittab,
+ .invert = 0,
+ .pll_set = dvbc_philips_tdm1316l_pll_set,
+};
+
+
static void frontend_init(struct budget_ci *budget_ci)
@@ -869,6 +1043,15 @@ static void frontend_init(struct budget_ci *budget_ci)
}
break;
+ case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
+ budget_ci->tuner_pll_address = 0x61;
+ budget_ci->budget.dvb_frontend =
+ stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ if (budget_ci->budget.dvb_frontend) {
+ break;
+ }
+ break;
+
case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
budget_ci->tuner_pll_address = 0x63;
budget_ci->budget.dvb_frontend =
@@ -878,7 +1061,7 @@ static void frontend_init(struct budget_ci *budget_ci)
}
break;
- case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+ case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
budget_ci->tuner_pll_address = 0x60;
budget_ci->budget.dvb_frontend =
tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
@@ -966,10 +1149,12 @@ static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
+ MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
{
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 8142e26b47f..b1f21ef0e3b 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
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
u8 data[4];
u32 div;
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
if (params->frequency > 1530000) data[3] = 0xc0;
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+ if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
return 0;
}
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 9961917e8a7..43d6c826864 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
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct budget* budget = (struct budget*) fe->dvb->priv;
u8 data[4];
u32 div;
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
if (params->frequency > 1530000) data[3] = 0xc0;
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+ if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
return 0;
}
@@ -481,6 +480,7 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
static struct s5h1420_config s5h1420_config = {
.demod_address = 0x53,
+ .invert = 1,
.pll_set = s5h1420_pll_set,
};
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 7daf7b1598a..d200ab0ad9e 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 @@
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/errno.h>
+#include <linux/jiffies.h>
#include <asm/semaphore.h>
#include "dvb_frontend.h"
@@ -570,7 +571,8 @@ static void ttusb_handle_sec_data(struct ttusb_channel *channel,
const u8 * data, int len);
#endif
-static int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid;
+static int numpkt = 0, numts, numstuff, numsec, numinvalid;
+static unsigned long lastj;
static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
int len)
@@ -779,7 +781,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
u8 *data;
int len;
numpkt++;
- if ((jiffies - lastj) >= HZ) {
+ if (time_after_eq(jiffies, lastj + HZ)) {
#if DEBUG > 2
printk
("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
return 0;
}
-static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
{
struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
u8 buf[4];
@@ -1322,7 +1324,7 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
if (ttusb->revision == TTUSB_REV_2_2)
buf[3] |= 0x20;
- if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 45c9a9a08e4..3d08fc83a75 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 16c85c081e6..93570355819 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -22,12 +22,21 @@ config VIDEO_BT848
the Miro, Hauppauge and STB boards. Please read the material in
<file:Documentation/video4linux/bttv/> for more information.
- If you say Y or M here, you need to say Y or M to "I2C support" and
- "I2C bit-banging interfaces" in the device drivers section.
-
To compile this driver as a module, choose M here: the
module will be called bttv.
+config VIDEO_SAA6588
+ tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
+ depends on VIDEO_DEV && I2C && VIDEO_BT848
+
+ help
+ Support for Radio Data System (RDS) decoder. This allows seeing
+ radio station identification transmitted using this standard.
+ Currentlly, it works only with bt8x8 chips.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa6588.
+
config VIDEO_PMS
tristate "Mediavision Pro Movie Studio Video For Linux"
depends on VIDEO_DEV && ISA
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3e6f5347da2..046b82de928 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,6 +5,7 @@
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
+rds-objs := saa6588.o
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
tuner-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 \
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
+obj-$(CONFIG_VIDEO_SAA6588) += rds.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
index 7f2d515d287..a48de3c0e3f 100644
--- a/drivers/media/video/btcx-risc.c
+++ b/drivers/media/video/btcx-risc.c
@@ -1,5 +1,4 @@
/*
- $Id: btcx-risc.c,v 1.6 2005/02/21 13:57:59 kraxel Exp $
btcx-risc.c
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
index 41f60395a52..503e6c6d7b6 100644
--- a/drivers/media/video/btcx-risc.h
+++ b/drivers/media/video/btcx-risc.h
@@ -1,5 +1,4 @@
/*
- * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
*/
struct btcx_riscmem {
unsigned int size;
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index a97b9b958ed..190977a1e54 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-cards.c,v 1.54 2005/07/19 18:26:46 mkrufky Exp $
bttv-cards.c
@@ -169,10 +168,10 @@ static struct CARD {
{ 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
{ 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
- // some cards ship with byteswapped IDs ...
+ /* some cards ship with byteswapped IDs ... */
{ 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
{ 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
- // this seems to happen as well ...
+ /* this seems to happen as well ... */
{ 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
{ 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
@@ -200,12 +199,12 @@ static struct CARD {
{ 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" },
{ 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" },
- // clashes with FlyVideo
- //{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" },
+ /* clashes with FlyVideo
+ *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */
{ 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" },
- { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // LR102
- { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, // ??
- { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // ??
+ { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
+ { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */
+ { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
{ 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
{ 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
@@ -287,10 +286,12 @@ static struct CARD {
{ 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
{ 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
- // likely broken, vendor id doesn't match the other magic views ...
- //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
+ { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" },
- // DVB cards (using pci function .1 for mpeg data xfer)
+ /* likely broken, vendor id doesn't match the other magic views ...
+ * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
+
+ /* DVB cards (using pci function .1 for mpeg data xfer) */
{ 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
{ 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
{ 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
@@ -298,7 +299,8 @@ static struct CARD {
{ 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" },
{ 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
{ 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
- { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" },
+ { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
+ { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0, -1, NULL }
};
@@ -316,6 +318,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.muxsel = { 2, 3, 1, 0},
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "MIRO PCTV",
.video_inputs = 4,
@@ -327,6 +330,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 2, 0, 0, 0, 10},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Hauppauge (bt848)",
.video_inputs = 4,
@@ -338,6 +342,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 1, 2, 3, 4},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "STB, Gateway P/N 6000699 (bt848)",
.video_inputs = 3,
@@ -350,6 +355,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},{
@@ -365,6 +371,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = 4,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Diamond DTV2000",
.video_inputs = 4,
@@ -376,6 +383,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 1, 0, 1, 3},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "AVerMedia TVPhone",
.video_inputs = 3,
@@ -388,6 +396,7 @@ struct tvcard bttv_tvcards[] = {
/* 0x04 for some cards ?? */
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = avermedia_tvphone_audio,
.has_remote = 1,
},{
@@ -401,6 +410,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = {0 },
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x08 ---------------------------------- */
@@ -415,6 +425,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "IMS/IXmicro TurboTV",
.video_inputs = 3,
@@ -427,6 +438,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Hauppauge (bt878)",
.video_inputs = 4,
@@ -439,6 +451,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "MIRO PCTV pro",
.video_inputs = 3,
@@ -450,6 +463,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0x20001,0x10001, 0, 0,10},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x0c ---------------------------------- */
@@ -463,6 +477,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 13, 14, 11, 7, 0, 0},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "AVerMedia TVCapture 98",
.video_inputs = 3,
@@ -476,6 +491,7 @@ struct tvcard bttv_tvcards[] = {
.msp34xx_alt = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = avermedia_tv_stereo_audio,
},{
.name = "Aimslab Video Highway Xtreme (VHX)",
@@ -489,6 +505,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Zoltrix TV-Max",
.video_inputs = 3,
@@ -500,6 +517,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = {0 , 0, 1 , 0, 10},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x10 ---------------------------------- */
@@ -510,7 +528,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x01fe00,
.muxsel = { 2, 3, 1, 1},
- // 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru>
+ /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
.audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
.needs_tvaudio = 1,
.pll = PLL_28,
@@ -526,6 +544,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = winview_audio,
.has_radio = 1,
},{
@@ -539,6 +558,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = {1, 0, 0, 0, 0},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
.video_inputs = 4,
@@ -550,6 +570,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0 },
.no_msp34xx = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x14 ---------------------------------- */
@@ -560,10 +581,11 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.muxsel = {2, 3, 1, 1},
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
.video_inputs = 4,
- .audio_inputs = 2, // tuner, line in
+ .audio_inputs = 2, /* tuner, line in */
.tuner = 0,
.svhs = 2,
.gpiomask = 0x1800,
@@ -571,6 +593,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Askey CPH050/ Phoebe Tv Master + FM",
.video_inputs = 3,
@@ -583,6 +606,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
.video_inputs = 3,
@@ -591,11 +615,12 @@ struct tvcard bttv_tvcards[] = {
.svhs = -1,
.gpiomask = 7,
.muxsel = { 2, 3, -1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .digital_mode = DIGITAL_MODE_CAMERA,
.audiomux = { 0, 0, 0, 0, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSBB5_PAL_I,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x18 ---------------------------------- */
@@ -610,6 +635,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1,
},{
.name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
@@ -622,6 +648,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = terratv_audio,
},{
.name = "Hauppauge WinCam newer (bt878)",
@@ -634,6 +661,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 1, 2, 3, 4},
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
.video_inputs = 4,
@@ -645,6 +673,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_SECAM,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x1c ---------------------------------- */
@@ -658,37 +687,38 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = terratv_audio,
/* GPIO wiring:
- External 20 pin connector (for Active Radio Upgrade board)
- gpio00: i2c-sda
- gpio01: i2c-scl
- gpio02: om5610-data
- gpio03: om5610-clk
- gpio04: om5610-wre
- gpio05: om5610-stereo
- gpio06: rds6588-davn
- gpio07: Pin 7 n.c.
- gpio08: nIOW
- gpio09+10: nIOR, nSEL ?? (bt878)
- gpio09: nIOR (bt848)
- gpio10: nSEL (bt848)
- Sound Routing:
- gpio16: u2-A0 (1st 4052bt)
- gpio17: u2-A1
- gpio18: u2-nEN
- gpio19: u4-A0 (2nd 4052)
- gpio20: u4-A1
- u4-nEN - GND
- Btspy:
- 00000 : Cdrom (internal audio input)
+ External 20 pin connector (for Active Radio Upgrade board)
+ gpio00: i2c-sda
+ gpio01: i2c-scl
+ gpio02: om5610-data
+ gpio03: om5610-clk
+ gpio04: om5610-wre
+ gpio05: om5610-stereo
+ gpio06: rds6588-davn
+ gpio07: Pin 7 n.c.
+ gpio08: nIOW
+ gpio09+10: nIOR, nSEL ?? (bt878)
+ gpio09: nIOR (bt848)
+ gpio10: nSEL (bt848)
+ Sound Routing:
+ gpio16: u2-A0 (1st 4052bt)
+ gpio17: u2-A1
+ gpio18: u2-nEN
+ gpio19: u4-A0 (2nd 4052)
+ gpio20: u4-A1
+ u4-nEN - GND
+ Btspy:
+ 00000 : Cdrom (internal audio input)
10000 : ext. Video audio input
20000 : TV Mono
a0000 : TV Mono/2
- 1a0000 : TV Stereo
+ 1a0000 : TV Stereo
30000 : Radio
40000 : Mute
- */
+*/
},{
/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
@@ -702,6 +732,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0 },
.needs_tvaudio = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.muxsel_hook = PXC200_muxsel,
},{
@@ -710,11 +741,12 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
- .gpiomask = 0x1800, //0x8dfe00
+ .gpiomask = 0x1800, /* 0x8dfe00 */
.muxsel = { 2, 3, 1, 1},
.audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Formac iProTV, Formac ProTV I (bt848)",
.video_inputs = 4,
@@ -726,6 +758,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 1, 0, 0, 0, 0 },
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x20 ---------------------------------- */
@@ -739,6 +772,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = 4,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Terratec TerraTValue Version Bt878",
.video_inputs = 3,
@@ -751,31 +785,33 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Leadtek WinFast 2000/ WinFast 2000 XP",
.video_inputs = 4,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
- .muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
+ .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
.audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
gpio23 -- hef4052:nEnable (0x800000)
gpio12 -- hef4052:A1
- gpio13 -- hef4052:A0
- 0x0000: external audio
- 0x1000: FM
- 0x2000: TV
- 0x3000: n.c.
- Note: There exists another variant "Winfast 2000" with tv stereo !?
- Note: eeprom only contains FF and pci subsystem id 107d:6606
- */
+ gpio13 -- hef4052:A0
+ 0x0000: external audio
+ 0x1000: FM
+ 0x2000: TV
+ 0x3000: n.c.
+ Note: There exists another variant "Winfast 2000" with tv stereo !?
+ Note: eeprom only contains FF and pci subsystem id 107d:6606
+ */
.needs_tvaudio = 0,
.pll = PLL_28,
.has_radio = 1,
- .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk
+ .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
+ .tuner_addr = ADDR_UNSET,
.audio_hook = winfast2000_audio,
.has_remote = 1,
},{
@@ -789,6 +825,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x24 ---------------------------------- */
@@ -802,6 +839,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 1,
},{
.name = "Prolink PixelView PlayTV pro",
@@ -815,6 +853,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Askey CPH06X TView99",
.video_inputs = 4,
@@ -827,6 +866,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1,
},{
.name = "Pinnacle PCTV Studio/Rave",
@@ -840,6 +880,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x28 ---------------------------------- */
@@ -854,6 +895,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},{
@@ -868,6 +910,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 1,
.audio_hook = avermedia_tvphone_audio,
},{
@@ -883,6 +926,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Little OnAir TV",
.video_inputs = 3,
@@ -894,6 +938,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
.no_msp34xx = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x2c ---------------------------------- */
@@ -908,6 +953,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_NONE,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "MATRIX-Vision MV-Delta 2",
.video_inputs = 5,
@@ -920,6 +966,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Zoltrix Genie TV/FM",
.video_inputs = 3,
@@ -932,6 +979,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = 21,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Terratec TV/Radio+",
.video_inputs = 3,
@@ -945,6 +993,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_35,
.tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 1,
},{
@@ -960,6 +1009,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "IODATA GV-BCTV3/PCI",
.video_inputs = 3,
@@ -972,6 +1022,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = gvbctv3pci_audio,
},{
.name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
@@ -986,6 +1037,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring: (different from Rev.4C !)
GPIO17: U4.A0 (first hef4052bt)
@@ -994,8 +1046,8 @@ struct tvcard bttv_tvcards[] = {
GPIO21: U4.nEN
GPIO22: BT832 Reset Line
GPIO23: A5,A0, U5,nEN
- Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
- */
+ Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
+ */
},{
.name = "Eagle Wireless Capricorn2 (bt878A)",
.video_inputs = 4,
@@ -1007,6 +1059,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 1, 2, 3, 4},
.pll = PLL_28,
.tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x34 ---------------------------------- */
@@ -1020,20 +1073,21 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 2, 3, 1, 1},
.audiomux = { 1, 0xd0001, 0, 0, 10},
/* sound path (5 sources):
- MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
+ MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
0= ext. Audio IN
1= from MUX2
2= Mono TV sound from Tuner
3= not connected
- MUX2 (mask 0x30000):
+ MUX2 (mask 0x30000):
0,2,3= from MSP34xx
1= FM stereo Radio from Tuner */
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Claas Langbehn <claas@bigfoot.com>,
- Sven Grothklags <sven@upb.de> */
+ Sven Grothklags <sven@upb.de> */
.name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
.video_inputs = 4,
.audio_inputs = 3,
@@ -1045,10 +1099,11 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 1,
},{
/* Tim Röstermundt <rosterm@uni-muenster.de>
- in de.comp.os.unix.linux.hardware:
+ in de.comp.os.unix.linux.hardware:
options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
options tuner type=5 */
@@ -1060,15 +1115,16 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x18e0,
.muxsel = { 2, 3, 1, 1},
.audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
- /* For cards with tda9820/tda9821:
- 0x0000: Tuner normal stereo
- 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
- 0x0880: Tuner A2 stereo */
+ /* For cards with tda9820/tda9821:
+ 0x0000: Tuner normal stereo
+ 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
+ 0x0880: Tuner A2 stereo */
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Miguel Angel Alvarez <maacruz@navegalia.com>
- old Easy TV BT848 version (model CPH031) */
+ old Easy TV BT848 version (model CPH031) */
.name = "Askey CPH031/ BESTBUY Easy TV",
.video_inputs = 4,
.audio_inputs = 1,
@@ -1080,6 +1136,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x38 ---------------------------------- */
@@ -1094,10 +1151,11 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
.pll = PLL_28,
.tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
},{
/* This is the ultimate cheapo capture card
- * just a BT848A on a small PCB!
- * Steve Hosgood <steve@equiinet.com> */
+ * just a BT848A on a small PCB!
+ * Steve Hosgood <steve@equiinet.com> */
.name = "GrandTec 'Grand Video Capture' (Bt848)",
.video_inputs = 2,
.audio_inputs = 0,
@@ -1110,19 +1168,21 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_35,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
- /* Daniel Herrington <daniel.herrington@home.com> */
- .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
+ /* Daniel Herrington <daniel.herrington@home.com> */
+ .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0xe00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
+ .tuner_addr = ADDR_UNSET,
},{
/* Matti Mottus <mottus@physic.ut.ee> */
.name = "Askey CPH03x TV Capturer",
@@ -1130,11 +1190,12 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
- .gpiomask = 0x03000F,
+ .gpiomask = 0x03000F,
.muxsel = { 2, 3, 1, 0},
- .audiomux = { 2,0,0,0,1 },
+ .audiomux = { 2,0,0,0,1 },
.pll = PLL_28,
.tuner_type = 0,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x3c ---------------------------------- */
@@ -1149,7 +1210,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 2, 0, 0, 1, 8},
.pll = PLL_35,
.tuner_type = TUNER_TEMIC_PAL,
-
+ .tuner_addr = ADDR_UNSET,
},{
/* Adrian Cox <adrian@humboldt.co.uk */
.name = "AG Electronics GMV1",
@@ -1164,10 +1225,11 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Miguel Angel Alvarez <maacruz@navegalia.com>
- new Easy TV BT878 version (model CPH061)
- special thanks to Informatica Mieres for providing the card */
+ new Easy TV BT878 version (model CPH061)
+ special thanks to Informatica Mieres for providing the card */
.name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
.video_inputs = 3,
.audio_inputs = 2,
@@ -1179,6 +1241,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder",
@@ -1191,6 +1254,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x40 ---------------------------------- */
@@ -1206,6 +1270,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
+ .tuner_addr = ADDR_UNSET,
},{
/* DeeJay <deejay@westel900.net (2000S) */
.name = "Lifeview FlyVideo 2000S LR90",
@@ -1216,7 +1281,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x18e0,
.muxsel = { 2, 3, 0, 1},
/* Radio changed from 1e80 to 0x800 to make
- FlyVideo2000S in .hu happy (gm)*/
+ FlyVideo2000S in .hu happy (gm)*/
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
.audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
.audio_hook = fv2000s_audio,
@@ -1225,6 +1290,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "Terratec TValueRadio",
.video_inputs = 3,
@@ -1237,6 +1303,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 1,
},{
/* TANAKA Kei <peg00625@nifty.com> */
@@ -1251,25 +1318,27 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = gvbctv3pci_audio,
},{
/* ---- card 0x44 ---------------------------------- */
- .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
- // try "insmod msp3400 simple=0" if you have
- // sound problems with this card.
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 0x4f8a00,
- // 0x100000: 1=MSP enabled (0=disable again)
- // 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC)
- .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
- // tvtuner, radio, external,internal, mute, stereo
- /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
- .muxsel = { 2, 3 ,0 ,1},
- .tuner_type = TUNER_MT2032,
+ .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
+ /* try "insmod msp3400 simple=0" if you have
+ * sound problems with this card. */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 0x4f8a00,
+ /* 0x100000: 1=MSP enabled (0=disable again)
+ * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
+ .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
+ /* tvtuner, radio, external,internal, mute, stereo
+ * tuner, Composit, SVid, Composit-on-Svid-adapter */
+ .muxsel = { 2, 3 ,0 ,1},
+ .tuner_type = TUNER_MT2032,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},{
@@ -1279,22 +1348,24 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
.muxsel = { 2 },
.gpiomask = 0
},{
- /* Tomasz Pyra <hellfire@sedez.iq.pl> */
- .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
- .video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 15,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = 25,
+ /* Tomasz Pyra <hellfire@sedez.iq.pl> */
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
+ .video_inputs = 3,
+ .audio_inputs = 4,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 15,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = 25,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring:
GPIO0: U4.A0 (hef4052bt)
@@ -1302,16 +1373,18 @@ struct tvcard bttv_tvcards[] = {
GPIO2: U4.A1 (second hef4052bt)
GPIO3: U4.nEN, U5.A0, A5.nEN
GPIO8-15: vrd866b ?
- */
+ */
},{
.name = "Lifeview FlyVideo 98EZ (capture only) LR51",
.video_inputs = 4,
.audio_inputs = 0,
.tuner = -1,
.svhs = 2,
- .muxsel = { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
+ .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
.pll = PLL_28,
.no_msp34xx = 1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x48 ---------------------------------- */
@@ -1329,8 +1402,9 @@ struct tvcard bttv_tvcards[] = {
.no_tda9875 = 1,
.pll = PLL_28,
.tuner_type = 5,
- .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo
- .has_radio = 1, // Note: not all cards have radio
+ .tuner_addr = ADDR_UNSET,
+ .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
+ .has_radio = 1, /* Note: not all cards have radio */
.has_remote = 1,
/* GPIO wiring:
GPIO0: A0 hef4052
@@ -1338,7 +1412,7 @@ struct tvcard bttv_tvcards[] = {
GPIO3: nEN hef4052
GPIO8-15: vrd866b
GPIO20,22,23: R30,R29,R28
- */
+ */
},{
/* Clay Kunz <ckunz@mail.arc.nasa.gov> */
/* you must jumper JP5 for the card to work */
@@ -1352,6 +1426,7 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
.name = "RemoteVision MX (RV605)",
@@ -1362,71 +1437,78 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x00,
.gpiomask2 = 0x07ff,
.muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
- 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+ 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
.no_msp34xx = 1,
.no_tda9875 = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.muxsel_hook = rv605_muxsel,
},{
- .name = "Powercolor MTV878/ MTV878R/ MTV878F",
- .video_inputs = 3,
- .audio_inputs = 2,
+ .name = "Powercolor MTV878/ MTV878R/ MTV878F",
+ .video_inputs = 3,
+ .audio_inputs = 2,
.tuner = 0,
- .svhs = 2,
- .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
- .muxsel = { 2, 1, 1, },
- .audiomux = { 0, 1, 2, 2, 4 },
- .needs_tvaudio = 0,
- .tuner_type = TUNER_PHILIPS_PAL,
+ .svhs = 2,
+ .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
+ .muxsel = { 2, 1, 1, },
+ .audiomux = { 0, 1, 2, 2, 4 },
+ .needs_tvaudio = 0,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},{
/* ---- card 0x4c ---------------------------------- */
- /* Masaki Suzuki <masaki@btree.org> */
- .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x140007,
- .muxsel = { 2, 3, 1, 1 },
- .audiomux = { 0, 1, 2, 3, 4, 0 },
- .tuner_type = TUNER_PHILIPS_NTSC,
- .audio_hook = windvr_audio,
-},{
- .name = "GrandTec Multi Capture Card (Bt878)",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
-},{
- .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
- .video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector
- .audiomux = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio!
- // This card lacks external Audio In, so we mute it on Ext. & Int.
- // The PCB can take a sbx1637/sbx1673, wiring unknown.
- // This card lacks PCI subsystem ID, sigh.
- // audiomux=1: lower volume, 2+3: mute
- // btwincap uses 0x80000/0x80003
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
- // radio signal strength indicators work fine.
- .has_radio = 1,
+ /* Masaki Suzuki <masaki@btree.org> */
+ .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x140007,
+ .muxsel = { 2, 3, 1, 1 },
+ .audiomux = { 0, 1, 2, 3, 4, 0 },
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .audio_hook = windvr_audio,
+},{
+ .name = "GrandTec Multi Capture Card (Bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+},{
+ .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
+ .video_inputs = 4,
+ .audio_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
+ * This card lacks external Audio In, so we mute it on Ext. & Int.
+ * The PCB can take a sbx1637/sbx1673, wiring unknown.
+ * This card lacks PCI subsystem ID, sigh.
+ * audiomux=1: lower volume, 2+3: mute
+ * btwincap uses 0x80000/0x80003
+ */
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
+ /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
+ radio signal strength indicators work fine. */
+ .has_radio = 1,
/* GPIO Info:
GPIO0,1: HEF4052 A0,A1
GPIO2: HEF4052 nENABLE
@@ -1437,25 +1519,27 @@ struct tvcard bttv_tvcards[] = {
GPIO22,23: ??
?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
},{
- /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
- .name = "DSP Design TCVIDEO",
- .video_inputs = 4,
- .svhs = -1,
- .muxsel = { 2, 3, 1, 0},
- .pll = PLL_28,
- .tuner_type = -1,
+ /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
+ .name = "DSP Design TCVIDEO",
+ .video_inputs = 4,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0},
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
- /* ---- card 0x50 ---------------------------------- */
+ /* ---- card 0x50 ---------------------------------- */
.name = "Hauppauge WinTV PVR",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 0, 1, 1},
- .needs_tvaudio = 1,
- .pll = PLL_28,
- .tuner_type = -1,
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 0, 1, 1},
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.gpiomask = 7,
.audiomux = {7},
@@ -1471,6 +1555,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = gvbctv5pci_audio,
.has_radio = 1,
},{
@@ -1482,9 +1567,10 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 3, 2, 0, 1 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
.video_inputs = 3,
@@ -1494,9 +1580,10 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 2, 3, 1 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
/* ---- card 0x54 ---------------------------------- */
@@ -1508,9 +1595,10 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 3, 1 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
.video_inputs = 1,
@@ -1520,9 +1608,10 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 0 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
.video_inputs = 2,
@@ -1532,9 +1621,10 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 0, 1 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
.video_inputs = 1,
@@ -1543,10 +1633,11 @@ struct tvcard bttv_tvcards[] = {
.svhs = -1,
.muxsel = { 0 },
.pll = PLL_28,
- .tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
/* ---- card 0x58 ---------------------------------- */
@@ -1557,10 +1648,11 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1,
.muxsel = { 0, 1 },
.pll = PLL_28,
- .tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
.video_inputs = 2,
@@ -1569,10 +1661,11 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1,
.muxsel = { 2, 3 },
.pll = PLL_28,
- .tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
.name = "Osprey 500", /* 500 */
.video_inputs = 2,
@@ -1582,19 +1675,21 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 2, 3 },
.pll = PLL_28,
.tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
- .name = "Osprey 540", /* 540 */
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = -1,
- .pll = PLL_28,
- .tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
+ .name = "Osprey 540", /* 540 */
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = -1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
},{
/* ---- card 0x5C ---------------------------------- */
@@ -1605,10 +1700,11 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1,
.muxsel = { 2, 3 },
.pll = PLL_28,
- .tuner_type = -1,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
},{
/* M G Berberich <berberic@forwiss.uni-passau.de> */
.name = "IDS Eagle",
@@ -1616,6 +1712,7 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.svhs = -1,
.gpiomask = 0,
.muxsel = { 0, 1, 2, 3 },
@@ -1630,6 +1727,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1,
.tuner = -1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1641,38 +1739,40 @@ struct tvcard bttv_tvcards[] = {
.no_gpioirq = 1,
.has_dvb = 1,
},{
- .name = "Formac ProTV II (bt878)",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 2,
- // TV, Comp1, Composite over SVID con, SVID
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 2, 2, 0, 0, 0 },
- .pll = PLL_28,
+ .name = "Formac ProTV II (bt878)",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 3,
+ .gpiomask = 2,
+ /* TV, Comp1, Composite over SVID con, SVID */
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 2, 2, 0, 0, 0 },
+ .pll = PLL_28,
.has_radio = 1,
- .tuner_type = TUNER_PHILIPS_PAL,
- /* sound routing:
- GPIO=0x00,0x01,0x03: mute (?)
- 0x02: both TV and radio (tuner: FM1216/I)
- The card has onboard audio connectors labeled "cdrom" and "board",
- not soldered here, though unknown wiring.
- Card lacks: external audio in, pci subsystem id.
- */
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+/* sound routing:
+ GPIO=0x00,0x01,0x03: mute (?)
+ 0x02: both TV and radio (tuner: FM1216/I)
+ The card has onboard audio connectors labeled "cdrom" and "board",
+ not soldered here, though unknown wiring.
+ Card lacks: external audio in, pci subsystem id.
+*/
},{
/* ---- card 0x60 ---------------------------------- */
.name = "MachTV",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = -1,
- .gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 0, 1, 2, 3, 4},
- .needs_tvaudio = 1,
- .tuner_type = 5,
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = -1,
+ .gpiomask = 7,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0, 1, 2, 3, 4},
+ .needs_tvaudio = 1,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
.pll = 1,
},{
.name = "Euresys Picolo",
@@ -1686,6 +1786,8 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.muxsel = { 2, 0, 1},
.pll = PLL_28,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},{
/* Luc Van Hoeylandt <luc@e-magic.be> */
.name = "ProVideo PV150", /* 0x4f */
@@ -1699,7 +1801,8 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = -1,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},{
/* Hiroshi Takekawa <sian@big.or.jp> */
/* This card lacks subsystem ID */
@@ -1716,78 +1819,85 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = 2,
+ .tuner_addr = ADDR_UNSET,
.audio_hook = adtvk503_audio,
},{
/* ---- card 0x64 ---------------------------------- */
- .name = "Hercules Smart TV Stereo",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
- .needs_tvaudio = 1,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = 5,
+ .name = "Hercules Smart TV Stereo",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x00,
+ .muxsel = { 2, 3, 1, 1 },
+ .needs_tvaudio = 1,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = 5,
+ .tuner_addr = ADDR_UNSET,
/* Notes:
- - card lacks subsystem ID
- - stereo variant w/ daughter board with tda9874a @0xb0
- - Audio Routing:
+ - card lacks subsystem ID
+ - stereo variant w/ daughter board with tda9874a @0xb0
+ - Audio Routing:
always from tda9874 independent of GPIO (?)
external line in: unknown
- - Other chips: em78p156elp @ 0x96 (probably IR remote control)
- hef4053 (instead 4052) for unknown function
+ - Other chips: em78p156elp @ 0x96 (probably IR remote control)
+ hef4053 (instead 4052) for unknown function
+ */
+},{
+ .name = "Pace TV & Radio Card",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
+ .gpiomask = 0,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = 1,
+ .tuner_addr = ADDR_UNSET,
+ .has_radio = 1,
+ .pll = PLL_28,
+ /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
+ only internal line out: (4pin header) RGGL
+ Radio must be decoded by msp3410d (not routed through)*/
+ /*
+ .digital_mode = DIGITAL_MODE_CAMERA, todo!
*/
},{
- .name = "Pace TV & Radio Card",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector
- .gpiomask = 0,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = 1,
- .has_radio = 1,
- .pll = PLL_28,
- /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
- only internal line out: (4pin header) RGGL
- Radio must be decoded by msp3410d (not routed through)*/
- // .digital_mode = DIGITAL_MODE_CAMERA, // todo!
-},{
- /* Chris Willing <chris@vislab.usyd.edu.au> */
- .name = "IVC-200",
- .video_inputs = 1,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .svhs = -1,
- .gpiomask = 0xdf,
- .muxsel = { 2 },
- .pll = PLL_28,
+ /* Chris Willing <chris@vislab.usyd.edu.au> */
+ .name = "IVC-200",
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0xdf,
+ .muxsel = { 2 },
+ .pll = PLL_28,
},{
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
.tuner_type = 4,
- .gpiomask2 = 0xff,
+ .tuner_addr = ADDR_UNSET,
+ .gpiomask2 = 0xff,
.muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
- .no_tda7432 = 1,
+ .no_tda7432 = 1,
.pll = PLL_28,
},{
/* ---- card 0x68 ---------------------------------- */
.name = "Nebula Electronics DigiTV",
.video_inputs = 1,
- .tuner = -1,
+ .tuner = -1,
.svhs = -1,
.muxsel = { 2, 3, 1, 0},
.no_msp34xx = 1,
@@ -1795,22 +1905,24 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.has_dvb = 1,
.no_gpioirq = 1,
},{
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
.name = "ProVideo PV143",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
- .audiomux = { 0 },
- .needs_tvaudio = 0,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = -1,
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .gpiomask = 0,
+ .muxsel = { 2, 3, 1, 0 },
+ .audiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* M.Klahr@phytec.de */
.name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
@@ -1824,6 +1936,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "PHYTEC VD-009-X1 Combi (bt878)",
.video_inputs = 4,
@@ -1836,6 +1949,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* ---- card 0x6c ---------------------------------- */
@@ -1846,13 +1960,14 @@ struct tvcard bttv_tvcards[] = {
.svhs = 9,
.gpiomask = 0x00,
.gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
+ via the upper nibble of muxsel. here: used for
+ xternal video-mux */
.muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
.name = "PHYTEC VD-009 Combi (bt878)",
.video_inputs = 10,
@@ -1861,23 +1976,25 @@ struct tvcard bttv_tvcards[] = {
.svhs = 9,
.gpiomask = 0x00,
.gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
+ via the upper nibble of muxsel. here: used for
+ xternal video-mux */
.muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
- .name = "IVC-100",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .tuner_type = -1,
- .svhs = -1,
- .gpiomask = 0xdf,
- .muxsel = { 2, 3, 1, 0 },
- .pll = PLL_28,
+ .name = "IVC-100",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = -1,
+ .gpiomask = 0xdf,
+ .muxsel = { 2, 3, 1, 0 },
+ .pll = PLL_28,
},{
/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
.name = "IVC-120G",
@@ -1885,6 +2002,7 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 0, /* card has no audio */
.tuner = -1, /* card has no tuner */
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.svhs = -1, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
@@ -1892,7 +2010,7 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.gpiomask = 0x00,
.muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
.muxsel_hook = ivc120_muxsel,
.pll = PLL_28,
},{
@@ -1905,6 +2023,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.muxsel = { 2, 3, 1, 0},
.tuner_type = TUNER_PHILIPS_ATSC,
+ .tuner_addr = ADDR_UNSET,
.has_dvb = 1,
},{
.name = "Twinhan DST + clones",
@@ -1912,19 +2031,21 @@ struct tvcard bttv_tvcards[] = {
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
.no_video = 1,
.has_dvb = 1,
},{
- .name = "Winfast VC100",
+ .name = "Winfast VC100",
.video_inputs = 3,
.audio_inputs = 0,
.svhs = 1,
- .tuner = -1, // no tuner
- .muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = TUNER_ABSENT,
+ .tuner = -1,
+ .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_28,
},{
.name = "Teppro TEV-560/InterVision IV-560",
@@ -1937,44 +2058,49 @@ struct tvcard bttv_tvcards[] = {
.audiomux = { 1, 1, 1, 1, 0},
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.pll = PLL_35,
},{
/* ---- card 0x74 ---------------------------------- */
- .name = "SIMUS GVC1100",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .tuner_type = -1,
- .pll = PLL_28,
- .muxsel = { 2, 2, 2, 2},
- .gpiomask = 0x3F,
+ .name = "SIMUS GVC1100",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ .muxsel = { 2, 2, 2, 2},
+ .gpiomask = 0x3F,
.muxsel_hook = gvc1100_muxsel,
},{
- /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
- .name = "NGS NGSTV+",
- .video_inputs = 3,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x008007,
- .muxsel = {2, 3, 0, 0},
- .audiomux = {0, 0, 0, 0, 0x000003, 0},
- .pll = PLL_28,
- .tuner_type = TUNER_PHILIPS_PAL,
- .has_remote = 1,
-},{
- /* http://linuxmedialabs.com */
- .name = "LMLBT4",
- .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 2, 3, 1, 0 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .needs_tvaudio = 0,
+ /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
+ .name = "NGS NGSTV+",
+ .video_inputs = 3,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x008007,
+ .muxsel = {2, 3, 0, 0},
+ .audiomux = {0, 0, 0, 0, 0x000003, 0},
+ .pll = PLL_28,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
+ .has_remote = 1,
+},{
+ /* http://linuxmedialabs.com */
+ .name = "LMLBT4",
+ .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 2, 3, 1, 0 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .needs_tvaudio = 0,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Helmroos Harri <harri.helmroos@pp.inet.fi> */
.name = "Tekram M205 PRO",
@@ -1982,6 +2108,7 @@ struct tvcard bttv_tvcards[] = {
.audio_inputs = 1,
.tuner = 0,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.svhs = 2,
.needs_tvaudio = 0,
.gpiomask = 0x68,
@@ -2004,6 +2131,7 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},{
@@ -2026,6 +2154,8 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.needs_tvaudio = 0,
.muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Spirit TV Tuner from http://spiritmodems.com.au */
/* Stafford Goodsell <surge@goliath.homeunix.org> */
@@ -2038,23 +2168,25 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 2, 1, 1 },
.audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
.tuner_type = TUNER_TEMIC_PAL,
+ .tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
},{
/* Wolfram Joost <wojo@frokaschwei.de> */
- .name = "AVerMedia AVerTV DVB-T 771",
- .video_inputs = 2,
- .svhs = 1,
- .tuner = -1,
- .tuner_type = TUNER_ABSENT,
- .muxsel = { 3 , 3 },
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .has_dvb = 1,
- .no_gpioirq = 1,
- .has_remote = 1,
+ .name = "AVerMedia AVerTV DVB-T 771",
+ .video_inputs = 2,
+ .svhs = 1,
+ .tuner = -1,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .muxsel = { 3 , 3 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .pll = PLL_28,
+ .has_dvb = 1,
+ .no_gpioirq = 1,
+ .has_remote = 1,
},{
/* ---- card 0x7c ---------------------------------- */
/* Matt Jesson <dvb@jesson.eclipse.co.uk> */
@@ -2069,6 +2201,7 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.has_dvb = 1,
.no_gpioirq = 1,
.has_remote = 1,
@@ -2081,12 +2214,13 @@ struct tvcard bttv_tvcards[] = {
.svhs = -1,
.gpiomask = 0x0,
.muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3 },
+ 3, 3, 3, 3, 3, 3, 3, 3 },
.muxsel_hook = sigmaSQ_muxsel,
.audiomux = { 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* andre.schwarz@matrix-vision.de */
.name = "MATRIX Vision Sigma-SLC",
@@ -2101,6 +2235,7 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* BTTV_APAC_VIEWCOMP */
/* Attila Kondoros <attila.kondoros@chello.hu> */
@@ -2116,13 +2251,14 @@ struct tvcard bttv_tvcards[] = {
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
+ .tuner_addr = ADDR_UNSET,
.has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
.has_radio = 1, /* not every card has radio */
},{
/* ---- card 0x80 ---------------------------------- */
/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
- .name = "DVICO FusionHDTV DVB-T Lite",
+ .name = "DViCO FusionHDTV DVB-T Lite",
.tuner = -1,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2131,6 +2267,7 @@ struct tvcard bttv_tvcards[] = {
.no_video = 1,
.has_dvb = 1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
},{
/* Steven <photon38@pchome.com.tw> */
.name = "V-Gear MyVCD",
@@ -2144,62 +2281,65 @@ struct tvcard bttv_tvcards[] = {
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
+ .tuner_addr = ADDR_UNSET,
.has_radio = 0,
- // .has_remote = 1,
},{
/* Rick C <cryptdragoon@gmail.com> */
- .name = "Super TV Tuner",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = TUNER_PHILIPS_NTSC,
- .gpiomask = 0x008007,
- .audiomux = { 0, 0x000001,0,0, 0},
- .needs_tvaudio = 1,
- .has_radio = 1,
-},{
- /* Chris Fanning <video4linux@haydon.net> */
- .name = "Tibet Systems 'Progress DVR' CS16",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = -1,
- .svhs = -1,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
- .pll = PLL_28,
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .tuner_type = -1,
- .muxsel_hook = tibetCS16_muxsel,
+ .name = "Super TV Tuner",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = TUNER_PHILIPS_NTSC,
+ .tuner_addr = ADDR_UNSET,
+ .gpiomask = 0x008007,
+ .audiomux = { 0, 0x000001,0,0, 0},
+ .needs_tvaudio = 1,
+ .has_radio = 1,
+},{
+ /* Chris Fanning <video4linux@haydon.net> */
+ .name = "Tibet Systems 'Progress DVR' CS16",
+ .video_inputs = 16,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .muxsel_hook = tibetCS16_muxsel,
},
{
/* Bill Brack <wbrack@mmm.com.hk> */
/*
- * Note that, because of the card's wiring, the "master"
- * BT878A chip (i.e. the one which controls the analog switch
- * and must use this card type) is the 2nd one detected. The
- * other 3 chips should use card type 0x85, whose description
- * follows this one. There is a EEPROM on the card (which is
- * connected to the I2C of one of those other chips), but is
- * not currently handled. There is also a facility for a
- * "monitor", which is also not currently implemented.
- */
- .name = "Kodicom 4400R (master)",
+ * Note that, because of the card's wiring, the "master"
+ * BT878A chip (i.e. the one which controls the analog switch
+ * and must use this card type) is the 2nd one detected. The
+ * other 3 chips should use card type 0x85, whose description
+ * follows this one. There is a EEPROM on the card (which is
+ * connected to the I2C of one of those other chips), but is
+ * not currently handled. There is also a facility for a
+ * "monitor", which is also not currently implemented.
+ */
+ .name = "Kodicom 4400R (master)",
.video_inputs = 16,
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.svhs = -1,
/* GPIO bits 0-9 used for analog switch:
- * 00 - 03: camera selector
- * 04 - 06: channel (controller) selector
- * 07: data (1->on, 0->off)
- * 08: strobe
- * 09: reset
- * bit 16 is input from sync separator for the channel
- */
+ * 00 - 03: camera selector
+ * 04 - 06: channel (controller) selector
+ * 07: data (1->on, 0->off)
+ * 08: strobe
+ * 09: reset
+ * bit 16 is input from sync separator for the channel
+ */
.gpiomask = 0x0003ff,
.no_gpioirq = 1,
.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[] = {
{
/* Bill Brack <wbrack@mmm.com.hk> */
/* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
- * one which controls the analog switch, and must use the card type)
- * is the 2nd one detected. The other 3 chips should use this card
- * type
- */
+ * one which controls the analog switch, and must use the card type)
+ * is the 2nd one detected. The other 3 chips should use this card
+ * type
+ */
.name = "Kodicom 4400R (slave)",
.video_inputs = 16,
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
.svhs = -1,
.gpiomask = 0x010000,
.no_gpioirq = 1,
@@ -2232,18 +2373,51 @@ struct tvcard bttv_tvcards[] = {
.muxsel_hook = kodicom4400r_muxsel,
},
{
- /* ---- card 0x85---------------------------------- */
- /* Michael Henson <mhenson@clarityvi.com> */
- /* Adlink RTV24 with special unlock codes */
- .name = "Adlink RTV24",
- .video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .muxsel = { 2, 3, 1, 0},
- .tuner_type = -1,
- .pll = PLL_28,
-
+ /* ---- card 0x86---------------------------------- */
+ /* Michael Henson <mhenson@clarityvi.com> */
+ /* Adlink RTV24 with special unlock codes */
+ .name = "Adlink RTV24",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .pll = PLL_28,
+},
+{
+ /* ---- card 0x87---------------------------------- */
+ /* Michael Krufky <mkrufky@m1k.net> */
+ .name = "DViCO FusionHDTV 5 Lite",
+ .tuner = 0,
+ .tuner_type = TUNER_LG_TDVS_H062F,
+ .tuner_addr = ADDR_UNSET,
+ .video_inputs = 2,
+ .audio_inputs = 1,
+ .svhs = 2,
+ .muxsel = { 2, 3 },
+ .gpiomask = 0x00e00007,
+ .audiomux = { 0x00400005, 0, 0, 0, 0, 0 },
+ .no_msp34xx = 1,
+ .no_tda9875 = 1,
+ .no_tda7432 = 1,
+},{
+ /* ---- card 0x88---------------------------------- */
+ /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
+ .name = "Acorp Y878F",
+ .video_inputs = 3,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .gpiomask = 0x01fe00,
+ .muxsel = { 2, 3, 1, 1},
+ .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
+ .needs_tvaudio = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
+ .tuner_addr = 0xc1 >>1,
+ .has_radio = 1,
}};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2355,32 +2529,32 @@ static void flyvideo_gpio(struct bttv *btv)
int tuner=-1,ttype;
gpio_inout(0xffffff, 0);
- udelay(8); // without this we would see the 0x1800 mask
+ udelay(8); /* without this we would see the 0x1800 mask */
gpio = gpio_read();
/* FIXME: must restore OUR_EN ??? */
- // all cards provide GPIO info, some have an additional eeprom
- // LR50: GPIO coding can be found lower right CP1 .. CP9
- // CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
- // GPIO14-12: n.c.
- // LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
-
- // lowest 3 bytes are remote control codes (no handshake needed)
- // xxxFFF: No remote control chip soldered
- // xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
- // Note: Some bits are Audio_Mask !
+ /* all cards provide GPIO info, some have an additional eeprom
+ * LR50: GPIO coding can be found lower right CP1 .. CP9
+ * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
+ * GPIO14-12: n.c.
+ * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
+ * lowest 3 bytes are remote control codes (no handshake needed)
+ * xxxFFF: No remote control chip soldered
+ * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
+ * Note: Some bits are Audio_Mask !
+ */
ttype=(gpio&0x0f0000)>>16;
switch(ttype) {
- case 0x0: tuner=2; // NTSC, e.g. TPI8NSR11P
+ case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
break;
- case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P
+ case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
break;
- case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216
+ case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
break;
- case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P
+ case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */
break;
- case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF
+ case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
break;
default:
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)
has_remote = gpio & 0x800000;
has_radio = gpio & 0x400000;
- // unknown 0x200000;
- // unknown2 0x100000;
- is_capture_only = !(gpio & 0x008000); //GPIO15
+ /* unknown 0x200000;
+ * unknown2 0x100000; */
+ is_capture_only = !(gpio & 0x008000); /* GPIO15 */
has_tda9820_tda9821 = !(gpio & 0x004000);
- is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only)
- // gpio & 0x001000 // output bit for audio routing
+ is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
+ /*
+ * gpio & 0x001000 output bit for audio routing */
if(is_capture_only)
- tuner=4; // No tuner present
+ tuner=4; /* No tuner present */
printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
@@ -2404,15 +2579,15 @@ static void flyvideo_gpio(struct bttv *btv)
btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
is_capture_only?"yes":"no ");
- if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through
+ if(tuner!= -1) /* only set if known tuner autodetected, else let insmod option through */
btv->tuner_type = tuner;
btv->has_radio = has_radio;
- // LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
- // LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
- // Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute
+ /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
+ * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
+ * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
- //todo: if(has_tda9874) btv->audio_hook = fv2000s_audio;
+ /* todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; */
}
static 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)
void __devinit bttv_init_card2(struct bttv *btv)
{
int tda9887;
+ int addr=ADDR_UNSET;
+
btv->tuner_type = -1;
if (BTTV_UNKNOWN == btv->c.type) {
@@ -2773,9 +2950,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->pll.pll_current = -1;
/* tuner configuration (from card list / autodetect / insmod option) */
- if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
+ if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
+ addr = bttv_tvcards[btv->c.type].tuner_addr;
+
+ if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
if(UNSET == btv->tuner_type)
- btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
+ btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
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)
tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
- tun_setup.addr = ADDR_UNSET;
+ tun_setup.addr = addr;
bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
}
@@ -2880,7 +3060,7 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
{
struct tveeprom tv;
- tveeprom_hauppauge_analog(&tv, eeprom_data);
+ tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
btv->tuner_type = tv.tuner_type;
btv->has_radio = tv.has_radio;
}
@@ -2902,7 +3082,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
btv->mbox_csel = 1 << 10;
freq=88000/62.5;
- tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8
+ tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */
if (0x1ed8 == tea5757_read(btv)) {
printk("bttv%d: Terratec Active Radio Upgrade found.\n",
btv->c.nr);
@@ -3073,7 +3253,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
case 0x0060:
case 0x0070:
btv->c.type = BTTV_OSPREY2x0;
- //enable output on select control lines
+ /* enable output on select control lines */
gpio_inout(0xffffff,0x000303);
break;
default:
@@ -3105,7 +3285,7 @@ static int tuner_1_table[] = {
TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
- TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM
+ TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
static void __devinit avermedia_eeprom(struct bttv *btv)
@@ -3126,7 +3306,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
if (tuner_make == 4)
if(tuner_format == 0x09)
- tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P
+ tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
@@ -3143,7 +3323,7 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
void bttv_tda9880_setnorm(struct bttv *btv, int norm)
{
- // fix up our card entry
+ /* fix up our card entry */
if(norm==VIDEO_MODE_NTSC) {
bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
@@ -3154,7 +3334,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
dprintk("bttv_tda9880_setnorm to PAL\n");
}
- // set GPIO according
+ /* set GPIO according */
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
bttv_tvcards[btv->c.type].audiomux[btv->audio]);
}
@@ -3447,7 +3627,7 @@ static int tea5757_read(struct bttv *btv)
udelay(10);
timeout= jiffies + HZ;
- // wait for DATA line to go low; error if it doesn't
+ /* wait for DATA line to go low; error if it doesn't */
while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
schedule();
if (bus_in(btv,btv->mbox_data)) {
@@ -3574,8 +3754,8 @@ gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
con = 0x300;
if (v->mode & VIDEO_SOUND_STEREO)
con = 0x200;
-// if (v->mode & VIDEO_SOUND_MONO)
-// con = 0x100;
+/* if (v->mode & VIDEO_SOUND_MONO)
+ * con = 0x100; */
gpio_bits(0x300, con);
} else {
v->mode = VIDEO_SOUND_STEREO |
@@ -3718,7 +3898,7 @@ lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
}
}
-// TDA9821 on TerraTV+ Bt848, Bt878
+/* TDA9821 on TerraTV+ Bt848, Bt878 */
static void
terratv_audio(struct bttv *btv, struct video_audio *v, int set)
{
@@ -3818,7 +3998,7 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
}
if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
|| (v->mode & VIDEO_SOUND_STEREO)) {
- val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ...
+ val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
}
if (val != 0xffff) {
gpio_bits(0x1800, val);
@@ -3869,10 +4049,10 @@ adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
{
unsigned int con = 0xffffff;
- //btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN);
+ /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
if (set) {
- //btor(***, BT848_GPIO_OUT_EN);
+ /* btor(***, BT848_GPIO_OUT_EN); */
if (v->mode & VIDEO_SOUND_LANG1)
con = 0x00000000;
if (v->mode & VIDEO_SOUND_LANG2)
@@ -4079,14 +4259,14 @@ static void kodicom4400r_init(struct bttv *btv)
master[btv->c.nr+2] = btv;
}
-// The Grandtec X-Guard framegrabber card uses two Dual 4-channel
-// video multiplexers to provide up to 16 video inputs. These
-// multiplexers are controlled by the lower 8 GPIO pins of the
-// bt878. The multiplexers probably Pericom PI5V331Q or similar.
-
-// xxx0 is pin xxx of multiplexer U5,
-// yyy1 is pin yyy of multiplexer U2
+/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel
+ * video multiplexers to provide up to 16 video inputs. These
+ * multiplexers are controlled by the lower 8 GPIO pins of the
+ * bt878. The multiplexers probably Pericom PI5V331Q or similar.
+ * xxx0 is pin xxx of multiplexer U5,
+ * yyy1 is pin yyy of multiplexer U2
+ */
#define ENA0 0x01
#define ENB0 0x02
#define ENA1 0x04
@@ -4157,14 +4337,14 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
static void ivc120_muxsel(struct bttv *btv, unsigned int input)
{
- // Simple maths
+ /* Simple maths */
int key = input % 4;
int matrix = input / 4;
dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
btv->c.nr, input, matrix, key);
- // Handles the input selection on the TDA8540's
+ /* Handles the input selection on the TDA8540's */
bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
((matrix == 3) ? (key | key << 2) : 0x00), 1);
bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
@@ -4174,17 +4354,17 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
((matrix == 2) ? (key | key << 2) : 0x00), 1);
- // Handles the output enables on the TDA8540's
+ /* Handles the output enables on the TDA8540's */
bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
- ((matrix == 3) ? 0x03 : 0x00), 1); // 13 - 16
+ ((matrix == 3) ? 0x03 : 0x00), 1); /* 13 - 16 */
bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
- ((matrix == 0) ? 0x03 : 0x00), 1); // 1-4
+ ((matrix == 0) ? 0x03 : 0x00), 1); /* 1-4 */
bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
- ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8
+ ((matrix == 1) ? 0x03 : 0x00), 1); /* 5-8 */
bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
- ((matrix == 2) ? 0x03 : 0x00), 1); // 9-12
+ ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
- // Selects MUX0 for input on the 878
+ /* Selects MUX0 for input on the 878 */
btaor((0)<<5, ~(3<<5), BT848_IFORM);
}
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 087efb4dea0..a564321db2f 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $
bttv - Bt848 frame grabber driver
@@ -42,6 +41,9 @@
#include "bttvp.h"
+#include "rds.h"
+
+
unsigned int bttv_num; /* number of Bt848s in use */
struct bttv bttvs[BTTV_MAX];
@@ -3128,15 +3130,12 @@ static int radio_open(struct inode *inode, struct file *file)
dprintk("bttv%d: open called (radio)\n",btv->c.nr);
down(&btv->lock);
- if (btv->radio_user) {
- up(&btv->lock);
- return -EBUSY;
- }
+
btv->radio_user++;
+
file->private_data = btv;
- i2c_vidiocschan(btv);
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
+ bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
audio_mux(btv,AUDIO_RADIO);
up(&btv->lock);
@@ -3145,9 +3144,13 @@ static int radio_open(struct inode *inode, struct file *file)
static int radio_release(struct inode *inode, struct file *file)
{
- struct bttv *btv = file->private_data;
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
btv->radio_user--;
+
+ bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+
return 0;
}
@@ -3203,13 +3206,42 @@ static int radio_ioctl(struct inode *inode, struct file *file,
return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
}
+static ssize_t radio_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
+ cmd.block_count = count/3;
+ cmd.buffer = data;
+ cmd.instance = file;
+ cmd.result = -ENODEV;
+
+ bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+
+ return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
+ cmd.instance = file;
+ cmd.event_list = wait;
+ cmd.result = -ENODEV;
+ bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+
+ return cmd.result;
+}
+
static struct file_operations radio_fops =
{
.owner = THIS_MODULE,
.open = radio_open,
+ .read = radio_read,
.release = radio_release,
.ioctl = radio_ioctl,
.llseek = no_llseek,
+ .poll = radio_poll,
};
static struct video_device radio_template =
@@ -4047,6 +4079,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
struct bttv_buffer_set idle;
unsigned long flags;
+ dprintk("bttv%d: suspend %d\n", btv->c.nr, state.event);
/* stop dma + irqs */
spin_lock_irqsave(&btv->s_lock,flags);
@@ -4079,15 +4112,29 @@ static int bttv_resume(struct pci_dev *pci_dev)
{
struct bttv *btv = pci_get_drvdata(pci_dev);
unsigned long flags;
+ int err;
dprintk("bttv%d: resume\n", btv->c.nr);
/* restore pci state */
if (btv->state.disabled) {
- pci_enable_device(pci_dev);
+ err=pci_enable_device(pci_dev);
+ if (err) {
+ printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+ btv->c.nr);
+ return err;
+ }
btv->state.disabled = 0;
}
- pci_set_power_state(pci_dev, PCI_D0);
+ err=pci_set_power_state(pci_dev, PCI_D0);
+ if (err) {
+ pci_disable_device(pci_dev);
+ printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+ btv->c.nr);
+ btv->state.disabled = 1;
+ return err;
+ }
+
pci_restore_state(pci_dev);
/* restore bt878 state */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 77320cdf205..6b280c03e39 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-gpio.c,v 1.7 2005/02/16 12:14:10 kraxel Exp $
bttv-gpio.c -- gpio sub drivers
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index 706dc48df96..e684df37eb0 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-i2c.c,v 1.25 2005/07/05 17:37:35 nsh Exp $
bttv-i2c.c -- all the i2c code is here
@@ -381,6 +380,7 @@ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
}
static char *i2c_devs[128] = {
+ [ 0x1c >> 1 ] = "lgdt330x",
[ 0x30 >> 1 ] = "IR (hauppauge)",
[ 0x80 >> 1 ] = "msp34xx",
[ 0x86 >> 1 ] = "tda9887",
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index f7b5543a96a..e8aada772b8 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-if.c,v 1.4 2004/11/17 18:47:47 kraxel Exp $
bttv-if.c -- old gpio interface to other kernel modules
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 9ed21fd190c..a5ed99b8944 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
bttv-risc.c -- interfaces to other kernel modules
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
index 06f3e62b3e8..f4f58c60f15 100644
--- a/drivers/media/video/bttv-vbi.c
+++ b/drivers/media/video/bttv-vbi.c
@@ -1,5 +1,4 @@
/*
- $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $
bttv - Bt848 frame grabber driver
vbi interface
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index f2af9e1454f..d254e90e3bb 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -1,5 +1,4 @@
/*
- * $Id: bttv.h,v 1.22 2005/07/28 18:41:21 mchehab Exp $
*
* bttv - Bt848 frame grabber driver
*
@@ -218,6 +217,8 @@ struct tvcard
#define PLL_35 2
unsigned int tuner_type;
+ unsigned int tuner_addr;
+
unsigned int has_radio;
void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
void (*muxsel_hook)(struct bttv *btv, unsigned int input);
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index aab094bc243..9b0b7ca035f 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -1,5 +1,4 @@
/*
- $Id: bttvp.h,v 1.21 2005/07/15 21:44:14 mchehab Exp $
bttv - Bt848 frame grabber driver
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 4f39688f780..0c0c59e9477 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
*
* Support for a cx23416 mpeg encoder via cx2388x host port.
* "blackbird" reference design.
@@ -62,7 +61,6 @@ static LIST_HEAD(cx8802_devlist);
#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
/* Firmware API commands */
-/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
#define IVTV_API_STD_TIMEOUT 500
#define BLACKBIRD_API_PING 0x80
@@ -696,7 +694,6 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
/* assign stream type */
blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
- /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
/* assign output port */
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)
BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */
+ /* initialize the video input */
+ blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0);
msleep(1);
@@ -833,11 +831,12 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
msleep(1);
- /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */
+ /* start capturing to the host interface */
+ /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */
blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
BLACKBIRD_MPEG_CAPTURE,
BLACKBIRD_RAW_BITS_NONE
- ); /* start capturing to the host interface */
+ );
msleep(10);
blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
@@ -851,8 +850,8 @@ static int bb_buf_setup(struct videobuf_queue *q,
{
struct cx8802_fh *fh = q->priv_data;
- fh->dev->ts_packet_size = 512;
- fh->dev->ts_packet_count = 100;
+ fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
+ fh->dev->ts_packet_count = 32; /* was: 100 */
*size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
if (0 == *count)
@@ -900,12 +899,36 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
{
struct cx8802_fh *fh = file->private_data;
struct cx8802_dev *dev = fh->dev;
+ struct cx88_core *core = dev->core;
if (debug > 1)
- cx88_print_ioctl(dev->core->name,cmd);
+ cx88_print_ioctl(core->name,cmd);
switch (cmd) {
+ /* --- capabilities ------------------------------------------ */
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *cap = arg;
+
+ memset(cap,0,sizeof(*cap));
+ strcpy(cap->driver, "cx88_blackbird");
+ strlcpy(cap->card, cx88_boards[core->board].name,sizeof(cap->card));
+ sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
+ cap->version = CX88_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_VBI_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
+ 0;
+ if (UNSET != core->tuner_type)
+ cap->capabilities |= V4L2_CAP_TUNER;
+
+ return 0;
+ }
+
/* --- capture ioctls ---------------------------------------- */
case VIDIOC_ENUM_FMT:
{
@@ -935,7 +958,11 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */;
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */;
+ f->fmt.pix.colorspace = 0;
+ return 0;
}
/* --- streaming capture ------------------------------------- */
@@ -959,15 +986,25 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
return videobuf_streamoff(&fh->mpegq);
default:
- return -EINVAL;
+ return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
}
return 0;
}
+int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg);
+unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
+
+static unsigned int mpeg_translate_ioctl(unsigned int cmd)
+{
+ return cmd;
+}
+
static int mpeg_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
- return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl);
+ cmd = cx88_ioctl_translator( cmd );
+ return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook);
}
static int mpeg_open(struct inode *inode, struct file *file)
@@ -1135,7 +1172,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
dev->pci = pci_dev;
dev->core = core;
dev->width = 720;
- dev->height = 480;
+ dev->height = 576;
err = cx8802_init_common(dev);
if (0 != err)
@@ -1148,6 +1185,9 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
list_add_tail(&dev->devlist,&cx8802_devlist);
blackbird_register_video(dev);
+
+ /* initial device configuration: needed ? */
+
return 0;
fail_free:
@@ -1202,6 +1242,8 @@ static int blackbird_init(void)
printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
+ cx88_ioctl_hook = mpeg_do_ioctl;
+ cx88_ioctl_translator = mpeg_translate_ioctl;
return pci_register_driver(&blackbird_pci_driver);
}
@@ -1213,6 +1255,9 @@ static void blackbird_fini(void)
module_init(blackbird_init);
module_exit(blackbird_fini);
+EXPORT_SYMBOL(cx88_ioctl_hook);
+EXPORT_SYMBOL(cx88_ioctl_translator);
+
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index ebf02a7f81e..4da91d535a5 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-cards.c,v 1.90 2005/07/28 02:47:42 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* card-specific stuff.
@@ -499,9 +498,6 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
}},
.dvb = 1,
},
@@ -614,12 +610,12 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- .gpio0 = 0xed12, // internal decoder
+ .gpio0 = 0xed12, /* internal decoder */
.gpio2 = 0x00ff,
},{
.type = CX88_VMUX_DEBUG,
.vmux = 0,
- .gpio0 = 0xff01, // mono from tuner chip
+ .gpio0 = 0xff01, /* mono from tuner chip */
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -715,19 +711,18 @@ struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- .gpio0 = 0x0f0d,
+ .gpio0 = 0x97ed,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- .gpio0 = 0x0f00,
+ .gpio0 = 0x97e9,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- .gpio0 = 0x0f00,
+ .gpio0 = 0x97e9,
}},
.dvb = 1,
},
@@ -765,20 +760,21 @@ struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
+ .tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- .gpio0 = 0x0f0d,
+ .gpio0 = 0x87fd,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- .gpio0 = 0x0f00,
+ .gpio0 = 0x87f9,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- .gpio0 = 0x0f00,
+ .gpio0 = 0x87f9,
}},
+ .dvb = 1,
},
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -949,7 +945,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
{
struct tveeprom tv;
- tveeprom_hauppauge_analog(&tv, eeprom_data);
+ tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
core->tuner_type = tv.tuner_type;
core->has_radio = tv.has_radio;
}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 5e868f5cd0c..dc5c5c1f346 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* driver core
@@ -876,7 +875,7 @@ static int set_tvaudio(struct cx88_core *core)
cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
cx88_set_tvaudio(core);
- // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
+ /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
@@ -1087,10 +1086,17 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
core->pci_bus = pci->bus->number;
core->pci_slot = PCI_SLOT(pci->devfn);
core->pci_irqmask = 0x00fc00;
+ init_MUTEX(&core->lock);
core->nr = cx88_devcount++;
sprintf(core->name,"cx88[%d]",core->nr);
if (0 != get_ressources(core,pci)) {
+ printk(KERN_ERR "CORE %s No more PCI ressources for "
+ "subsystem: %04x:%04x, board: %s\n",
+ core->name,pci->subsystem_vendor,
+ pci->subsystem_device,
+ cx88_boards[core->board].name);
+
cx88_devcount--;
goto fail_free;
}
@@ -1114,11 +1120,11 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
core->board = CX88_BOARD_UNKNOWN;
cx88_card_list(core,pci);
}
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
- core->name,pci->subsystem_vendor,
- pci->subsystem_device,cx88_boards[core->board].name,
- core->board, card[core->nr] == core->board ?
- "insmod option" : "autodetected");
+ printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ core->name,pci->subsystem_vendor,
+ pci->subsystem_device,cx88_boards[core->board].name,
+ core->board, card[core->nr] == core->board ?
+ "insmod option" : "autodetected");
core->tuner_type = tuner[core->nr];
core->radio_type = radio[core->nr];
@@ -1202,4 +1208,5 @@ EXPORT_SYMBOL(cx88_core_put);
* Local variables:
* c-basic-offset: 8
* End:
+ * 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
*/
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 78d223257a6..c9106b1d79d 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-dvb.c,v 1.58 2005/08/07 09:24:08 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines
@@ -29,7 +28,7 @@
#include <linux/kthread.h>
#include <linux/file.h>
#include <linux/suspend.h>
-#include <linux/config.h>
+
#include "cx88.h"
#include "dvb-pll.h"
@@ -210,16 +209,26 @@ static struct or51132_config pchdtv_hd3000 = {
static int lgdt330x_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
+ /* FIXME make this routine use the tuner-simple code.
+ * It could probably be shared with a number of ATSC
+ * frontends. Many share the same tuner with analog TV. */
+
struct cx8802_dev *dev= fe->dvb->priv;
+ struct cx88_core *core = dev->core;
u8 buf[4];
struct i2c_msg msg =
{ .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
int err;
- dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, 0);
+ /* Put the analog decoder in standby to keep it quiet */
+ if (core->tda9887_conf) {
+ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ }
+
+ dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
__FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
- if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
+ if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
printk(KERN_WARNING "cx88-dvb: %s error "
"(addr %02x <- %02x, err = %i)\n",
__FUNCTION__, buf[0], buf[1], err);
@@ -228,6 +237,13 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe,
else
return -EREMOTEIO;
}
+ if (core->tuner_type == TUNER_LG_TDVS_H062F) {
+ /* Set the Auxiliary Byte. */
+ buf[2] &= ~0x20;
+ buf[2] |= 0x18;
+ buf[3] = 0x50;
+ i2c_transfer(&core->i2c_adap, &msg, 1);
+ }
return 0;
}
@@ -261,6 +277,14 @@ static struct lgdt330x_config fusionhdtv_3_gold = {
.pll_set = lgdt330x_pll_set,
.set_ts_params = lgdt330x_set_ts_param,
};
+
+static struct lgdt330x_config fusionhdtv_5_gold = {
+ .demod_address = 0x0e,
+ .demod_chip = LGDT3303,
+ .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
+ .pll_set = lgdt330x_pll_set,
+ .set_ts_params = lgdt330x_set_ts_param,
+};
#endif
static int dvb_register(struct cx8802_dev *dev)
@@ -346,6 +370,22 @@ static int dvb_register(struct cx8802_dev *dev)
&dev->core->i2c_adap);
}
break;
+ case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
+ dev->ts_gen_cntrl = 0x08;
+ {
+ /* Do a hardware reset of chip before using it. */
+ struct cx88_core *core = dev->core;
+
+ cx_clear(MO_GP0_IO, 1);
+ mdelay(100);
+ cx_set(MO_GP0_IO, 1);
+ mdelay(200);
+ dev->core->pll_addr = 0x61;
+ dev->core->pll_desc = &dvb_pll_tdvs_tua6034;
+ dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
+ &dev->core->i2c_adap);
+ }
+ break;
#endif
default:
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)
dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
}
- /* Copy the board name into the DVB structure */
- strlcpy(dev->dvb.frontend->ops->info.name,
- cx88_boards[dev->core->board].name,
- sizeof(dev->dvb.frontend->ops->info.name));
-
/* register everything */
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 7f598039e02..761cebd40db 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,4 @@
/*
- $Id: cx88-i2c.c,v 1.30 2005/07/25 05:10:13 mkrufky Exp $
cx88-i2c.c -- all the i2c code is here
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 21488779819..d81b21d6e05 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-input.c,v 1.15 2005/07/07 13:58:38 mchehab Exp $
*
* Device driver for GPIO attached remote control interfaces
* on Conexant 2388x based TV/DVB cards.
@@ -212,6 +211,53 @@ static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
/* ---------------------------------------------------------------------- */
+/* Cinergy 1400 DVB-T */
+static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
+ [0x01] = KEY_POWER,
+ [0x02] = KEY_1,
+ [0x03] = KEY_2,
+ [0x04] = KEY_3,
+ [0x05] = KEY_4,
+ [0x06] = KEY_5,
+ [0x07] = KEY_6,
+ [0x08] = KEY_7,
+ [0x09] = KEY_8,
+ [0x0a] = KEY_9,
+ [0x0c] = KEY_0,
+
+ [0x0b] = KEY_VIDEO,
+ [0x0d] = KEY_REFRESH,
+ [0x0e] = KEY_SELECT,
+ [0x0f] = KEY_EPG,
+ [0x10] = KEY_UP,
+ [0x11] = KEY_LEFT,
+ [0x12] = KEY_OK,
+ [0x13] = KEY_RIGHT,
+ [0x14] = KEY_DOWN,
+ [0x15] = KEY_TEXT,
+ [0x16] = KEY_INFO,
+
+ [0x17] = KEY_RED,
+ [0x18] = KEY_GREEN,
+ [0x19] = KEY_YELLOW,
+ [0x1a] = KEY_BLUE,
+
+ [0x1b] = KEY_CHANNELUP,
+ [0x1c] = KEY_VOLUMEUP,
+ [0x1d] = KEY_MUTE,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x1f] = KEY_CHANNELDOWN,
+
+ [0x40] = KEY_PAUSE,
+ [0x4c] = KEY_PLAY,
+ [0x58] = KEY_RECORD,
+ [0x54] = KEY_PREVIOUS,
+ [0x48] = KEY_STOP,
+ [0x5c] = KEY_NEXT,
+};
+
+/* ---------------------------------------------------------------------- */
+
struct cx88_IR {
struct cx88_core *core;
struct input_dev input;
@@ -241,7 +287,7 @@ module_param(ir_debug, int, 0644); /* debug level [IR] */
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define ir_dprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg)
+ printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
/* ---------------------------------------------------------------------- */
@@ -329,6 +375,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir->mask_keyup = 0x60;
ir->polling = 50; /* ms */
break;
+ case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
+ ir_codes = ir_codes_cinergy_1400;
+ ir_type = IR_TYPE_PD;
+ ir->sampling = 1;
+ break;
case CX88_BOARD_HAUPPAUGE:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
ir_codes = ir_codes_hauppauge_new;
@@ -394,6 +445,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir->input.id.vendor = pci->vendor;
ir->input.id.product = pci->device;
}
+ ir->input.dev = &pci->dev;
/* record handles to ourself */
ir->core = core;
@@ -445,7 +497,7 @@ int cx88_ir_fini(struct cx88_core *core)
void cx88_ir_irq(struct cx88_core *core)
{
struct cx88_IR *ir = core->ir;
- u32 samples, rc5;
+ u32 samples, ircode;
int i;
if (NULL == ir)
@@ -477,13 +529,44 @@ void cx88_ir_irq(struct cx88_core *core)
/* decode it */
switch (core->board) {
+ case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
+ ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
+
+ if (ircode == 0xffffffff) { /* decoding error */
+ ir_dprintk("pulse distance decoding error\n");
+ break;
+ }
+
+ ir_dprintk("pulse distance decoded: %x\n", ircode);
+
+ if (ircode == 0) { /* key still pressed */
+ ir_dprintk("pulse distance decoded repeat code\n");
+ ir->release = jiffies + msecs_to_jiffies(120);
+ break;
+ }
+
+ if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
+ ir_dprintk("pulse distance decoded wrong address\n");
+ break;
+ }
+
+ if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
+ ir_dprintk("pulse distance decoded wrong check sum\n");
+ break;
+ }
+
+ ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
+
+ ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+ ir->release = jiffies + msecs_to_jiffies(120);
+ break;
case CX88_BOARD_HAUPPAUGE:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- rc5 = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
- ir_dprintk("biphase decoded: %x\n", rc5);
- if ((rc5 & 0xfffff000) != 0x3000)
+ ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
+ ir_dprintk("biphase decoded: %x\n", ircode);
+ if ((ircode & 0xfffff000) != 0x3000)
break;
- ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5);
+ ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
ir->release = jiffies + msecs_to_jiffies(120);
break;
}
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index fe2767c0ff9..ee2300e1ae0 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-mpeg.c,v 1.31 2005/07/07 14:17:47 mchehab Exp $
*
* Support for the mpeg transport stream transfers
* PCI function #2 of the cx2388x.
@@ -73,11 +72,15 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
udelay(100);
cx_write(MO_PINMUX_IO, 0x00);
cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
- if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) ||
- (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) {
+ switch (core->board) {
+ case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
+ case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
+ case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
cx_write(TS_SOP_STAT, 1<<13);
- } else {
+ break;
+ default:
cx_write(TS_SOP_STAT, 0x00);
+ break;
}
cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
udelay(100);
@@ -86,12 +89,10 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
if (cx88_boards[core->board].blackbird) {
cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
- // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */
cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
udelay(100);
cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
- //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */
cx_write(TS_VALERR_CNTRL, 0x2000);
cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
@@ -106,7 +107,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
dprintk( 0, "setting the interrupt mask\n" );
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
cx_set(MO_TS_INTMSK, 0x1f0011);
- //cx_write(MO_TS_INTMSK, 0x0f0011);
/* start dma */
cx_set(MO_DEV_CNTRL2, (1<<5));
@@ -206,7 +206,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
dprintk(0,"[%p/%d] %s - first active\n",
buf, buf->vb.i, __FUNCTION__);
- //udelay(100);
} else {
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)
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk( 1, "[%p/%d] %s - append to active\n",
buf, buf->vb.i, __FUNCTION__);
- //udelay(100);
}
}
@@ -387,7 +385,6 @@ int cx8802_init_common(struct cx8802_dev *dev)
dev->pci_lat,pci_resource_start(dev->pci,0));
/* initialize driver struct */
- init_MUTEX(&dev->lock);
spin_lock_init(&dev->slock);
/* init dma queue */
@@ -458,14 +455,28 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
int cx8802_resume_common(struct pci_dev *pci_dev)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+ int err;
if (dev->state.disabled) {
- pci_enable_device(pci_dev);
+ err=pci_enable_device(pci_dev);
+ if (err) {
+ printk(KERN_ERR "%s: can't enable device\n",
+ dev->core->name);
+ return err;
+ }
dev->state.disabled = 0;
}
- pci_set_power_state(pci_dev, PCI_D0);
+ err=pci_set_power_state(pci_dev, PCI_D0);
+ if (err) {
+ printk(KERN_ERR "%s: can't enable device\n",
+ dev->core->name);
+ pci_disable_device(pci_dev);
+ dev->state.disabled = 1;
+
+ return err;
+ }
pci_restore_state(pci_dev);
/* FIXME: re-initialize hardware */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 37f82662d26..0a3a62fc9bb 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,4 @@
/*
- $Id: cx88-reg.h,v 1.8 2005/07/07 13:58:38 mchehab Exp $
cx88x-hw.h - CX2388x register offsets
@@ -40,6 +39,29 @@
#define CX88X_EN_TBFX 0x02
#define CX88X_EN_VSFX 0x04
+/* ---------------------------------------------------------------------- */
+/* PCI controller registers */
+
+/* Command and Status Register */
+#define F0_CMD_STAT_MM 0x2f0004
+#define F1_CMD_STAT_MM 0x2f0104
+#define F2_CMD_STAT_MM 0x2f0204
+#define F3_CMD_STAT_MM 0x2f0304
+#define F4_CMD_STAT_MM 0x2f0404
+
+/* Device Control #1 */
+#define F0_DEV_CNTRL1_MM 0x2f0040
+#define F1_DEV_CNTRL1_MM 0x2f0140
+#define F2_DEV_CNTRL1_MM 0x2f0240
+#define F3_DEV_CNTRL1_MM 0x2f0340
+#define F4_DEV_CNTRL1_MM 0x2f0440
+
+/* Device Control #1 */
+#define F0_BAR0_MM 0x2f0010
+#define F1_BAR0_MM 0x2f0110
+#define F2_BAR0_MM 0x2f0210
+#define F3_BAR0_MM 0x2f0310
+#define F4_BAR0_MM 0x2f0410
/* ---------------------------------------------------------------------- */
/* DMA Controller registers */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 91207f10bae..2765acee028 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,4 @@
/*
- $Id: cx88-tvaudio.c,v 1.37 2005/07/07 13:58:38 mchehab Exp $
cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
@@ -121,25 +120,19 @@ static void set_audio_registers(struct cx88_core *core,
}
static void set_audio_start(struct cx88_core *core,
- u32 mode, u32 ctl)
+ u32 mode)
{
// mute
cx_write(AUD_VOL_CTL, (1 << 6));
- // increase level of input by 12dB
-// cx_write(AUD_AFE_12DB_EN, 0x0001);
- cx_write(AUD_AFE_12DB_EN, 0x0000);
-
// start programming
cx_write(AUD_CTL, 0x0000);
cx_write(AUD_INIT, mode);
cx_write(AUD_INIT_LD, 0x0001);
cx_write(AUD_SOFT_RESET, 0x0001);
-
- cx_write(AUD_CTL, ctl);
}
-static void set_audio_finish(struct cx88_core *core)
+static void set_audio_finish(struct cx88_core *core, u32 ctl)
{
u32 volume;
@@ -154,25 +147,25 @@ static void set_audio_finish(struct cx88_core *core)
cx_write(AUD_I2SOUTPUTCNTL, 1);
cx_write(AUD_I2SCNTL, 0);
//cx_write(AUD_APB_IN_RATE_ADJ, 0);
+ } else {
+ ctl |= EN_DAC_ENABLE;
+ cx_write(AUD_CTL, ctl);
}
- // finish programming
+ /* finish programming */
cx_write(AUD_SOFT_RESET, 0x0000);
- // start audio processing
- cx_set(AUD_CTL, EN_DAC_ENABLE);
-
- // unmute
+ /* unmute */
volume = cx_sread(SHADOW_AUD_VOL_CTL);
cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
}
/* ----------------------------------------------------------- */
-static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
+static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode)
{
static const struct rlist btsc[] = {
- /* from dscaler */
+ { AUD_AFE_12DB_EN, 0x00000001 },
{ AUD_OUT1_SEL, 0x00000013 },
{ AUD_OUT1_SHIFT, 0x00000000 },
{ AUD_POLY0_DDS_CONSTANT, 0x0012010c },
@@ -206,9 +199,10 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
{ AUD_RDSI_SHIFT, 0x00000000 },
{ AUD_RDSQ_SHIFT, 0x00000000 },
{ AUD_POLYPH80SCALEFAC, 0x00000003 },
- { /* end of list */ },
+ { /* end of list */ },
};
static const struct rlist btsc_sap[] = {
+ { AUD_AFE_12DB_EN, 0x00000001 },
{ AUD_DBX_IN_GAIN, 0x00007200 },
{ AUD_DBX_WBE_GAIN, 0x00006200 },
{ AUD_DBX_SE_GAIN, 0x00006200 },
@@ -259,371 +253,400 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
{ AUD_RDSI_SHIFT, 0x00000000 },
{ AUD_RDSQ_SHIFT, 0x00000000 },
{ AUD_POLYPH80SCALEFAC, 0x00000003 },
- { /* end of list */ },
+ { /* end of list */ },
};
- // dscaler: exactly taken from driver,
- // dscaler: don't know why to set EN_FMRADIO_EN_RDS
+ mode |= EN_FMRADIO_EN_RDS;
+
if (sap) {
dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
- set_audio_start(core, 0x0001,
- EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
+ set_audio_start(core, SEL_SAP);
set_audio_registers(core, btsc_sap);
+ set_audio_finish(core, mode);
} else {
dprintk("%s (status: known-good)\n",__FUNCTION__);
- set_audio_start(core, 0x0001,
- EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
+ set_audio_start(core, SEL_BTSC);
set_audio_registers(core, btsc);
+ set_audio_finish(core, mode);
}
- set_audio_finish(core);
}
static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
{
- /* This is probably weird..
- * Let's operate and find out. */
-
- static const struct rlist nicam_l_mono[] = {
- { AUD_ERRLOGPERIOD_R, 0x00000064 },
- { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
- { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
-
- { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
- { AUD_QAM_MODE, 0x00 },
- { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
- { AUD_PHACC_FREQ_8MSB, 0x3a },
- { AUD_PHACC_FREQ_8LSB, 0x4a },
-
- { AUD_DEEMPHGAIN_R, 0x6680 },
- { AUD_DEEMPHNUMER1_R, 0x353DE },
- { AUD_DEEMPHNUMER2_R, 0x1B1 },
- { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
- { AUD_DEEMPHDENOM2_R, 0x0 },
- { AUD_FM_MODE_ENABLE, 0x7 },
- { AUD_POLYPH80SCALEFAC, 0x3 },
- { AUD_AFE_12DB_EN, 0x1 },
- { AAGC_GAIN, 0x0 },
- { AAGC_HYST, 0x18 },
- { AAGC_DEF, 0x20 },
- { AUD_DN0_FREQ, 0x0 },
- { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
- { AUD_DCOC_0_SRC, 0x21 },
- { AUD_IIR1_0_SEL, 0x0 },
- { AUD_IIR1_0_SHIFT, 0x7 },
- { AUD_IIR1_1_SEL, 0x2 },
- { AUD_IIR1_1_SHIFT, 0x0 },
- { AUD_DCOC_1_SRC, 0x3 },
- { AUD_DCOC1_SHIFT, 0x0 },
- { AUD_DCOC_PASS_IN, 0x0 },
- { AUD_IIR1_2_SEL, 0x23 },
- { AUD_IIR1_2_SHIFT, 0x0 },
- { AUD_IIR1_3_SEL, 0x4 },
- { AUD_IIR1_3_SHIFT, 0x7 },
- { AUD_IIR1_4_SEL, 0x5 },
- { AUD_IIR1_4_SHIFT, 0x7 },
- { AUD_IIR3_0_SEL, 0x7 },
- { AUD_IIR3_0_SHIFT, 0x0 },
- { AUD_DEEMPH0_SRC_SEL, 0x11 },
- { AUD_DEEMPH0_SHIFT, 0x0 },
- { AUD_DEEMPH0_G0, 0x7000 },
- { AUD_DEEMPH0_A0, 0x0 },
- { AUD_DEEMPH0_B0, 0x0 },
- { AUD_DEEMPH0_A1, 0x0 },
- { AUD_DEEMPH0_B1, 0x0 },
- { AUD_DEEMPH1_SRC_SEL, 0x11 },
- { AUD_DEEMPH1_SHIFT, 0x0 },
- { AUD_DEEMPH1_G0, 0x7000 },
- { AUD_DEEMPH1_A0, 0x0 },
- { AUD_DEEMPH1_B0, 0x0 },
- { AUD_DEEMPH1_A1, 0x0 },
- { AUD_DEEMPH1_B1, 0x0 },
- { AUD_OUT0_SEL, 0x3F },
- { AUD_OUT1_SEL, 0x3F },
- { AUD_DMD_RA_DDS, 0x0F5C285 },
- { AUD_PLL_INT, 0x1E },
- { AUD_PLL_DDS, 0x0 },
- { AUD_PLL_FRAC, 0x0E542 },
-
- // setup QAM registers
- { AUD_RATE_ADJ1, 0x00000100 },
- { AUD_RATE_ADJ2, 0x00000200 },
- { AUD_RATE_ADJ3, 0x00000300 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00000500 },
- { AUD_RATE_THRES_DMD, 0x000000C0 },
- { /* end of list */ },
- };
-
- static const struct rlist nicam_l[] = {
- // setup QAM registers
- { AUD_RATE_ADJ1, 0x00000060 },
- { AUD_RATE_ADJ2, 0x000000F9 },
- { AUD_RATE_ADJ3, 0x000001CC },
- { AUD_RATE_ADJ4, 0x000002B3 },
- { AUD_RATE_ADJ5, 0x00000726 },
- { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_ERRLOGPERIOD_R, 0x00000064 },
- { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
- { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
- { AUD_DMD_RA_DDS, 0x00C00000 },
- { AUD_PLL_INT, 0x0000001E },
- { AUD_PLL_DDS, 0x00000000 },
- { AUD_PLL_FRAC, 0x0000E542 },
- { AUD_START_TIMER, 0x00000000 },
- { AUD_DEEMPHNUMER1_R, 0x000353DE },
- { AUD_DEEMPHNUMER2_R, 0x000001B1 },
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_QAM_MODE, 0x05 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_PHACC_FREQ_8MSB, 0x34 },
- { AUD_PHACC_FREQ_8LSB, 0x4C },
- { AUD_DEEMPHGAIN_R, 0x00006680 },
- { AUD_RATE_THRES_DMD, 0x000000C0 },
- { /* end of list */ },
- } ;
- dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
-
- if (!stereo) {
- /* AM mono sound */
- set_audio_start(core, 0x0004,
- 0x100c /* FIXME again */);
- set_audio_registers(core, nicam_l_mono);
- } else {
- set_audio_start(core, 0x0010,
- 0x1924 /* FIXME again */);
- set_audio_registers(core, nicam_l);
- }
- set_audio_finish(core);
+ /* This is probably weird..
+ * Let's operate and find out. */
+
+ static const struct rlist nicam_l_mono[] = {
+ { AUD_ERRLOGPERIOD_R, 0x00000064 },
+ { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
+ { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
+ { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
+
+ { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
+ { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
+ { AUD_QAM_MODE, 0x00 },
+ { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
+ { AUD_PHACC_FREQ_8MSB, 0x3a },
+ { AUD_PHACC_FREQ_8LSB, 0x4a },
+
+ { AUD_DEEMPHGAIN_R, 0x6680 },
+ { AUD_DEEMPHNUMER1_R, 0x353DE },
+ { AUD_DEEMPHNUMER2_R, 0x1B1 },
+ { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
+ { AUD_DEEMPHDENOM2_R, 0x0 },
+ { AUD_FM_MODE_ENABLE, 0x7 },
+ { AUD_POLYPH80SCALEFAC, 0x3 },
+ { AUD_AFE_12DB_EN, 0x1 },
+ { AAGC_GAIN, 0x0 },
+ { AAGC_HYST, 0x18 },
+ { AAGC_DEF, 0x20 },
+ { AUD_DN0_FREQ, 0x0 },
+ { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
+ { AUD_DCOC_0_SRC, 0x21 },
+ { AUD_IIR1_0_SEL, 0x0 },
+ { AUD_IIR1_0_SHIFT, 0x7 },
+ { AUD_IIR1_1_SEL, 0x2 },
+ { AUD_IIR1_1_SHIFT, 0x0 },
+ { AUD_DCOC_1_SRC, 0x3 },
+ { AUD_DCOC1_SHIFT, 0x0 },
+ { AUD_DCOC_PASS_IN, 0x0 },
+ { AUD_IIR1_2_SEL, 0x23 },
+ { AUD_IIR1_2_SHIFT, 0x0 },
+ { AUD_IIR1_3_SEL, 0x4 },
+ { AUD_IIR1_3_SHIFT, 0x7 },
+ { AUD_IIR1_4_SEL, 0x5 },
+ { AUD_IIR1_4_SHIFT, 0x7 },
+ { AUD_IIR3_0_SEL, 0x7 },
+ { AUD_IIR3_0_SHIFT, 0x0 },
+ { AUD_DEEMPH0_SRC_SEL, 0x11 },
+ { AUD_DEEMPH0_SHIFT, 0x0 },
+ { AUD_DEEMPH0_G0, 0x7000 },
+ { AUD_DEEMPH0_A0, 0x0 },
+ { AUD_DEEMPH0_B0, 0x0 },
+ { AUD_DEEMPH0_A1, 0x0 },
+ { AUD_DEEMPH0_B1, 0x0 },
+ { AUD_DEEMPH1_SRC_SEL, 0x11 },
+ { AUD_DEEMPH1_SHIFT, 0x0 },
+ { AUD_DEEMPH1_G0, 0x7000 },
+ { AUD_DEEMPH1_A0, 0x0 },
+ { AUD_DEEMPH1_B0, 0x0 },
+ { AUD_DEEMPH1_A1, 0x0 },
+ { AUD_DEEMPH1_B1, 0x0 },
+ { AUD_OUT0_SEL, 0x3F },
+ { AUD_OUT1_SEL, 0x3F },
+ { AUD_DMD_RA_DDS, 0x0F5C285 },
+ { AUD_PLL_INT, 0x1E },
+ { AUD_PLL_DDS, 0x0 },
+ { AUD_PLL_FRAC, 0x0E542 },
+
+ // setup QAM registers
+ { AUD_RATE_ADJ1, 0x00000100 },
+ { AUD_RATE_ADJ2, 0x00000200 },
+ { AUD_RATE_ADJ3, 0x00000300 },
+ { AUD_RATE_ADJ4, 0x00000400 },
+ { AUD_RATE_ADJ5, 0x00000500 },
+ { AUD_RATE_THRES_DMD, 0x000000C0 },
+ { /* end of list */ },
+ };
+ static const struct rlist nicam_l[] = {
+ // setup QAM registers
+ { AUD_RATE_ADJ1, 0x00000060 },
+ { AUD_RATE_ADJ2, 0x000000F9 },
+ { AUD_RATE_ADJ3, 0x000001CC },
+ { AUD_RATE_ADJ4, 0x000002B3 },
+ { AUD_RATE_ADJ5, 0x00000726 },
+ { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
+ { AUD_DEEMPHDENOM2_R, 0x00000000 },
+ { AUD_ERRLOGPERIOD_R, 0x00000064 },
+ { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
+ { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
+ { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
+ { AUD_POLYPH80SCALEFAC, 0x00000003 },
+ { AUD_DMD_RA_DDS, 0x00C00000 },
+ { AUD_PLL_INT, 0x0000001E },
+ { AUD_PLL_DDS, 0x00000000 },
+ { AUD_PLL_FRAC, 0x0000E542 },
+ { AUD_START_TIMER, 0x00000000 },
+ { AUD_DEEMPHNUMER1_R, 0x000353DE },
+ { AUD_DEEMPHNUMER2_R, 0x000001B1 },
+ { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
+ { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
+ { AUD_QAM_MODE, 0x05 },
+ { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
+ { AUD_PHACC_FREQ_8MSB, 0x34 },
+ { AUD_PHACC_FREQ_8LSB, 0x4C },
+ { AUD_DEEMPHGAIN_R, 0x00006680 },
+ { AUD_RATE_THRES_DMD, 0x000000C0 },
+ { /* end of list */ },
+ } ;
+ dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
+
+ if (!stereo) {
+ /* AM Mono */
+ set_audio_start(core, SEL_A2);
+ set_audio_registers(core, nicam_l_mono);
+ set_audio_finish(core, EN_A2_FORCE_MONO1);
+ } else {
+ /* Nicam Stereo */
+ set_audio_start(core, SEL_NICAM);
+ set_audio_registers(core, nicam_l);
+ set_audio_finish(core, 0x1924); /* FIXME */
+ }
}
static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
{
static const struct rlist pal_i_fm_mono[] = {
- {AUD_ERRLOGPERIOD_R, 0x00000064},
- {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
- {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
- {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
- {AUD_PDF_DDS_CNST_BYTE2, 0x06},
- {AUD_PDF_DDS_CNST_BYTE1, 0x82},
- {AUD_PDF_DDS_CNST_BYTE0, 0x12},
- {AUD_QAM_MODE, 0x05},
- {AUD_PHACC_FREQ_8MSB, 0x3a},
- {AUD_PHACC_FREQ_8LSB, 0x93},
- {AUD_DMD_RA_DDS, 0x002a4f2f},
- {AUD_PLL_INT, 0x0000001e},
- {AUD_PLL_DDS, 0x00000004},
- {AUD_PLL_FRAC, 0x0000e542},
- {AUD_RATE_ADJ1, 0x00000100},
- {AUD_RATE_ADJ2, 0x00000200},
- {AUD_RATE_ADJ3, 0x00000300},
- {AUD_RATE_ADJ4, 0x00000400},
- {AUD_RATE_ADJ5, 0x00000500},
- {AUD_THR_FR, 0x00000000},
- {AUD_PILOT_BQD_1_K0, 0x0000755b},
- {AUD_PILOT_BQD_1_K1, 0x00551340},
- {AUD_PILOT_BQD_1_K2, 0x006d30be},
- {AUD_PILOT_BQD_1_K3, 0xffd394af},
- {AUD_PILOT_BQD_1_K4, 0x00400000},
- {AUD_PILOT_BQD_2_K0, 0x00040000},
- {AUD_PILOT_BQD_2_K1, 0x002a4841},
- {AUD_PILOT_BQD_2_K2, 0x00400000},
- {AUD_PILOT_BQD_2_K3, 0x00000000},
- {AUD_PILOT_BQD_2_K4, 0x00000000},
- {AUD_MODE_CHG_TIMER, 0x00000060},
- {AUD_AFE_12DB_EN, 0x00000001},
- {AAGC_HYST, 0x0000000a},
- {AUD_CORDIC_SHIFT_0, 0x00000007},
- {AUD_CORDIC_SHIFT_1, 0x00000007},
- {AUD_C1_UP_THR, 0x00007000},
- {AUD_C1_LO_THR, 0x00005400},
- {AUD_C2_UP_THR, 0x00005400},
- {AUD_C2_LO_THR, 0x00003000},
- {AUD_DCOC_0_SRC, 0x0000001a},
- {AUD_DCOC0_SHIFT, 0x00000000},
- {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
- {AUD_DCOC_PASS_IN, 0x00000003},
- {AUD_IIR3_0_SEL, 0x00000021},
- {AUD_DN2_AFC, 0x00000002},
- {AUD_DCOC_1_SRC, 0x0000001b},
- {AUD_DCOC1_SHIFT, 0x00000000},
- {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
- {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
- {AUD_IIR3_1_SEL, 0x00000023},
- {AUD_DN0_FREQ, 0x000035a3},
- {AUD_DN2_FREQ, 0x000029c7},
- {AUD_CRDC0_SRC_SEL, 0x00000511},
- {AUD_IIR1_0_SEL, 0x00000001},
- {AUD_IIR1_1_SEL, 0x00000000},
- {AUD_IIR3_2_SEL, 0x00000003},
- {AUD_IIR3_2_SHIFT, 0x00000000},
- {AUD_IIR3_0_SEL, 0x00000002},
- {AUD_IIR2_0_SEL, 0x00000021},
- {AUD_IIR2_0_SHIFT, 0x00000002},
- {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
- {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
- {AUD_POLYPH80SCALEFAC, 0x00000001},
- {AUD_START_TIMER, 0x00000000},
- { /* end of list */ },
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_QAM_MODE, 0x05},
+ {AUD_PHACC_FREQ_8MSB, 0x3a},
+ {AUD_PHACC_FREQ_8LSB, 0x93},
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_PLL_INT, 0x0000001e},
+ {AUD_PLL_DDS, 0x00000004},
+ {AUD_PLL_FRAC, 0x0000e542},
+ {AUD_RATE_ADJ1, 0x00000100},
+ {AUD_RATE_ADJ2, 0x00000200},
+ {AUD_RATE_ADJ3, 0x00000300},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00000500},
+ {AUD_THR_FR, 0x00000000},
+ {AUD_PILOT_BQD_1_K0, 0x0000755b},
+ {AUD_PILOT_BQD_1_K1, 0x00551340},
+ {AUD_PILOT_BQD_1_K2, 0x006d30be},
+ {AUD_PILOT_BQD_1_K3, 0xffd394af},
+ {AUD_PILOT_BQD_1_K4, 0x00400000},
+ {AUD_PILOT_BQD_2_K0, 0x00040000},
+ {AUD_PILOT_BQD_2_K1, 0x002a4841},
+ {AUD_PILOT_BQD_2_K2, 0x00400000},
+ {AUD_PILOT_BQD_2_K3, 0x00000000},
+ {AUD_PILOT_BQD_2_K4, 0x00000000},
+ {AUD_MODE_CHG_TIMER, 0x00000060},
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AAGC_HYST, 0x0000000a},
+ {AUD_CORDIC_SHIFT_0, 0x00000007},
+ {AUD_CORDIC_SHIFT_1, 0x00000007},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_DCOC0_SHIFT, 0x00000000},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_IIR3_0_SEL, 0x00000021},
+ {AUD_DN2_AFC, 0x00000002},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_IIR3_1_SEL, 0x00000023},
+ {AUD_DN0_FREQ, 0x000035a3},
+ {AUD_DN2_FREQ, 0x000029c7},
+ {AUD_CRDC0_SRC_SEL, 0x00000511},
+ {AUD_IIR1_0_SEL, 0x00000001},
+ {AUD_IIR1_1_SEL, 0x00000000},
+ {AUD_IIR3_2_SEL, 0x00000003},
+ {AUD_IIR3_2_SHIFT, 0x00000000},
+ {AUD_IIR3_0_SEL, 0x00000002},
+ {AUD_IIR2_0_SEL, 0x00000021},
+ {AUD_IIR2_0_SHIFT, 0x00000002},
+ {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
+ {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
+ {AUD_POLYPH80SCALEFAC, 0x00000001},
+ {AUD_START_TIMER, 0x00000000},
+ { /* end of list */ },
};
static const struct rlist pal_i_nicam[] = {
- { AUD_RATE_ADJ1, 0x00000010 },
- { AUD_RATE_ADJ2, 0x00000040 },
- { AUD_RATE_ADJ3, 0x00000100 },
- { AUD_RATE_ADJ4, 0x00000400 },
- { AUD_RATE_ADJ5, 0x00001000 },
- // { AUD_DMD_RA_DDS, 0x00c0d5ce },
- { AUD_DEEMPHGAIN_R, 0x000023c2 },
- { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
- { AUD_DEEMPHNUMER2_R, 0x0003023e },
- { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_DEEMPHDENOM2_R, 0x00000000 },
- { AUD_ERRLOGPERIOD_R, 0x00000fff },
- { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
- { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
- { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
- { AUD_POLYPH80SCALEFAC, 0x00000003 },
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
- { AUD_QAM_MODE, 0x05 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_PHACC_FREQ_8MSB, 0x3a },
- { AUD_PHACC_FREQ_8LSB, 0x93 },
- { /* end of list */ },
- };
-
- dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
-
- if (!stereo) {
- // FM mono
- set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
+ { AUD_RATE_ADJ1, 0x00000010 },
+ { AUD_RATE_ADJ2, 0x00000040 },
+ { AUD_RATE_ADJ3, 0x00000100 },
+ { AUD_RATE_ADJ4, 0x00000400 },
+ { AUD_RATE_ADJ5, 0x00001000 },
+ // { AUD_DMD_RA_DDS, 0x00c0d5ce },
+ { AUD_DEEMPHGAIN_R, 0x000023c2 },
+ { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
+ { AUD_DEEMPHNUMER2_R, 0x0003023e },
+ { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
+ { AUD_DEEMPHDENOM2_R, 0x00000000 },
+ { AUD_DEEMPHDENOM2_R, 0x00000000 },
+ { AUD_ERRLOGPERIOD_R, 0x00000fff },
+ { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
+ { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
+ { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
+ { AUD_POLYPH80SCALEFAC, 0x00000003 },
+ { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
+ { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
+ { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
+ { AUD_QAM_MODE, 0x05 },
+ { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
+ { AUD_PHACC_FREQ_8MSB, 0x3a },
+ { AUD_PHACC_FREQ_8LSB, 0x93 },
+ { /* end of list */ },
+ };
+
+ dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
+
+ if (!stereo) {
+ /* FM Mono */
+ set_audio_start(core, SEL_A2);
set_audio_registers(core, pal_i_fm_mono);
- } else {
- // Nicam Stereo
- set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
+ set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
+ } else {
+ /* Nicam Stereo */
+ set_audio_start(core, SEL_NICAM);
set_audio_registers(core, pal_i_nicam);
- }
- set_audio_finish(core);
+ set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
+ }
}
-static void set_audio_standard_A2(struct cx88_core *core)
+static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
{
- /* from dscaler cvs */
static const struct rlist a2_common[] = {
- { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
- { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
- { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
- { AUD_QAM_MODE, 0x05 },
- { AUD_PHACC_FREQ_8MSB, 0x34 },
- { AUD_PHACC_FREQ_8LSB, 0x4c },
-
- { AUD_RATE_ADJ1, 0x00001000 },
- { AUD_RATE_ADJ2, 0x00002000 },
- { AUD_RATE_ADJ3, 0x00003000 },
- { AUD_RATE_ADJ4, 0x00004000 },
- { AUD_RATE_ADJ5, 0x00005000 },
- { AUD_THR_FR, 0x00000000 },
- { AAGC_HYST, 0x0000001a },
- { AUD_PILOT_BQD_1_K0, 0x0000755b },
- { AUD_PILOT_BQD_1_K1, 0x00551340 },
- { AUD_PILOT_BQD_1_K2, 0x006d30be },
- { AUD_PILOT_BQD_1_K3, 0xffd394af },
- { AUD_PILOT_BQD_1_K4, 0x00400000 },
- { AUD_PILOT_BQD_2_K0, 0x00040000 },
- { AUD_PILOT_BQD_2_K1, 0x002a4841 },
- { AUD_PILOT_BQD_2_K2, 0x00400000 },
- { AUD_PILOT_BQD_2_K3, 0x00000000 },
- { AUD_PILOT_BQD_2_K4, 0x00000000 },
- { AUD_MODE_CHG_TIMER, 0x00000040 },
- { AUD_START_TIMER, 0x00000200 },
- { AUD_AFE_12DB_EN, 0x00000000 },
- { AUD_CORDIC_SHIFT_0, 0x00000007 },
- { AUD_CORDIC_SHIFT_1, 0x00000007 },
- { AUD_DEEMPH0_G0, 0x00000380 },
- { AUD_DEEMPH1_G0, 0x00000380 },
- { AUD_DCOC_0_SRC, 0x0000001a },
- { AUD_DCOC0_SHIFT, 0x00000000 },
- { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
- { AUD_DCOC_PASS_IN, 0x00000003 },
- { AUD_IIR3_0_SEL, 0x00000021 },
- { AUD_DN2_AFC, 0x00000002 },
- { AUD_DCOC_1_SRC, 0x0000001b },
- { AUD_DCOC1_SHIFT, 0x00000000 },
- { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
- { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
- { AUD_IIR3_1_SEL, 0x00000023 },
- { AUD_RDSI_SEL, 0x00000017 },
- { AUD_RDSI_SHIFT, 0x00000000 },
- { AUD_RDSQ_SEL, 0x00000017 },
- { AUD_RDSQ_SHIFT, 0x00000000 },
- { AUD_POLYPH80SCALEFAC, 0x00000001 },
+ {AUD_ERRLOGPERIOD_R, 0x00000064},
+ {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
+ {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
+ {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
+ {AUD_PDF_DDS_CNST_BYTE2, 0x06},
+ {AUD_PDF_DDS_CNST_BYTE1, 0x82},
+ {AUD_PDF_DDS_CNST_BYTE0, 0x12},
+ {AUD_QAM_MODE, 0x05},
+ {AUD_PHACC_FREQ_8MSB, 0x34},
+ {AUD_PHACC_FREQ_8LSB, 0x4c},
+ {AUD_RATE_ADJ1, 0x00000100},
+ {AUD_RATE_ADJ2, 0x00000200},
+ {AUD_RATE_ADJ3, 0x00000300},
+ {AUD_RATE_ADJ4, 0x00000400},
+ {AUD_RATE_ADJ5, 0x00000500},
+ {AUD_THR_FR, 0x00000000},
+ {AAGC_HYST, 0x0000001a},
+ {AUD_PILOT_BQD_1_K0, 0x0000755b},
+ {AUD_PILOT_BQD_1_K1, 0x00551340},
+ {AUD_PILOT_BQD_1_K2, 0x006d30be},
+ {AUD_PILOT_BQD_1_K3, 0xffd394af},
+ {AUD_PILOT_BQD_1_K4, 0x00400000},
+ {AUD_PILOT_BQD_2_K0, 0x00040000},
+ {AUD_PILOT_BQD_2_K1, 0x002a4841},
+ {AUD_PILOT_BQD_2_K2, 0x00400000},
+ {AUD_PILOT_BQD_2_K3, 0x00000000},
+ {AUD_PILOT_BQD_2_K4, 0x00000000},
+ {AUD_MODE_CHG_TIMER, 0x00000040},
+ {AUD_AFE_12DB_EN, 0x00000001},
+ {AUD_CORDIC_SHIFT_0, 0x00000007},
+ {AUD_CORDIC_SHIFT_1, 0x00000007},
+ {AUD_DEEMPH0_G0, 0x00000380},
+ {AUD_DEEMPH1_G0, 0x00000380},
+ {AUD_DCOC_0_SRC, 0x0000001a},
+ {AUD_DCOC0_SHIFT, 0x00000000},
+ {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
+ {AUD_DCOC_PASS_IN, 0x00000003},
+ {AUD_IIR3_0_SEL, 0x00000021},
+ {AUD_DN2_AFC, 0x00000002},
+ {AUD_DCOC_1_SRC, 0x0000001b},
+ {AUD_DCOC1_SHIFT, 0x00000000},
+ {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
+ {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
+ {AUD_IIR3_1_SEL, 0x00000023},
+ {AUD_RDSI_SEL, 0x00000017},
+ {AUD_RDSI_SHIFT, 0x00000000},
+ {AUD_RDSQ_SEL, 0x00000017},
+ {AUD_RDSQ_SHIFT, 0x00000000},
+ {AUD_PLL_INT, 0x0000001e},
+ {AUD_PLL_DDS, 0x00000000},
+ {AUD_PLL_FRAC, 0x0000e542},
+ {AUD_POLYPH80SCALEFAC, 0x00000001},
+ {AUD_START_TIMER, 0x00000000},
+ { /* end of list */ },
+ };
+ static const struct rlist a2_bg[] = {
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
{ /* end of list */ },
};
- static const struct rlist a2_table1[] = {
- // PAL-BG
- { AUD_DMD_RA_DDS, 0x002a73bd },
- { AUD_C1_UP_THR, 0x00007000 },
- { AUD_C1_LO_THR, 0x00005400 },
- { AUD_C2_UP_THR, 0x00005400 },
- { AUD_C2_LO_THR, 0x00003000 },
+ static const struct rlist a2_dk[] = {
+ {AUD_DMD_RA_DDS, 0x002a4f2f},
+ {AUD_C1_UP_THR, 0x00007000},
+ {AUD_C1_LO_THR, 0x00005400},
+ {AUD_C2_UP_THR, 0x00005400},
+ {AUD_C2_LO_THR, 0x00003000},
+ {AUD_DN0_FREQ, 0x00003a1c},
+ {AUD_DN2_FREQ, 0x0000d2e0},
{ /* end of list */ },
};
- static const struct rlist a2_table2[] = {
- // PAL-DK
- { AUD_DMD_RA_DDS, 0x002a73bd },
- { AUD_C1_UP_THR, 0x00007000 },
- { AUD_C1_LO_THR, 0x00005400 },
- { AUD_C2_UP_THR, 0x00005400 },
- { AUD_C2_LO_THR, 0x00003000 },
- { AUD_DN0_FREQ, 0x00003a1c },
- { AUD_DN2_FREQ, 0x0000d2e0 },
+/* unknown, probably NTSC-M */
+ static const struct rlist a2_m[] = {
+ {AUD_DMD_RA_DDS, 0x002a0425},
+ {AUD_C1_UP_THR, 0x00003c00},
+ {AUD_C1_LO_THR, 0x00003000},
+ {AUD_C2_UP_THR, 0x00006000},
+ {AUD_C2_LO_THR, 0x00003c00},
+ {AUD_DEEMPH0_A0, 0x00007a80},
+ {AUD_DEEMPH1_A0, 0x00007a80},
+ {AUD_DEEMPH0_G0, 0x00001200},
+ {AUD_DEEMPH1_G0, 0x00001200},
+ {AUD_DN0_FREQ, 0x0000283b},
+ {AUD_DN1_FREQ, 0x00003418},
+ {AUD_DN2_FREQ, 0x000029c7},
+ {AUD_POLY0_DDS_CONSTANT, 0x000a7540},
{ /* end of list */ },
};
- static const struct rlist a2_table3[] = {
- // unknown, probably NTSC-M
- { AUD_DMD_RA_DDS, 0x002a2873 },
- { AUD_C1_UP_THR, 0x00003c00 },
- { AUD_C1_LO_THR, 0x00003000 },
- { AUD_C2_UP_THR, 0x00006000 },
- { AUD_C2_LO_THR, 0x00003c00 },
- { AUD_DN0_FREQ, 0x00002836 },
- { AUD_DN1_FREQ, 0x00003418 },
- { AUD_DN2_FREQ, 0x000029c7 },
- { AUD_POLY0_DDS_CONSTANT, 0x000a7540 },
+
+ static const struct rlist a2_deemph50[] = {
+ {AUD_DEEMPH0_G0, 0x00000380},
+ {AUD_DEEMPH1_G0, 0x00000380},
+ {AUD_DEEMPHGAIN_R, 0x000011e1},
+ {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
+ {AUD_DEEMPHNUMER2_R, 0x0003023c},
+ { /* end of list */ },
+ };
+
+ static const struct rlist a2_deemph75[] = {
+ {AUD_DEEMPH0_G0, 0x00000480},
+ {AUD_DEEMPH1_G0, 0x00000480},
+ {AUD_DEEMPHGAIN_R, 0x00009000},
+ {AUD_DEEMPHNUMER1_R, 0x000353de},
+ {AUD_DEEMPHNUMER2_R, 0x000001b1},
{ /* end of list */ },
};
- set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
+ set_audio_start(core, SEL_A2);
set_audio_registers(core, a2_common);
switch (core->tvaudio) {
case WW_A2_BG:
dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
- set_audio_registers(core, a2_table1);
+ set_audio_registers(core, a2_bg);
+ set_audio_registers(core, a2_deemph50);
break;
case WW_A2_DK:
dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
- set_audio_registers(core, a2_table2);
+ set_audio_registers(core, a2_dk);
+ set_audio_registers(core, a2_deemph50);
break;
case WW_A2_M:
dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
- set_audio_registers(core, a2_table3);
+ set_audio_registers(core, a2_m);
+ set_audio_registers(core, a2_deemph75);
break;
};
- set_audio_finish(core);
+
+ mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF;
+ set_audio_finish(core, mode);
}
static void set_audio_standard_EIAJ(struct cx88_core *core)
@@ -635,9 +658,9 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
};
dprintk("%s (status: unknown)\n",__FUNCTION__);
- set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO);
+ set_audio_start(core, SEL_EIAJ);
set_audio_registers(core, eiaj);
- set_audio_finish(core);
+ set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
}
static 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
};
dprintk("%s (status: unknown)\n",__FUNCTION__);
- set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
+ set_audio_start(core, SEL_FMRADIO);
switch (deemph)
{
@@ -700,7 +723,7 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
break;
}
- set_audio_finish(core);
+ set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
}
/* ----------------------------------------------------------- */
@@ -709,7 +732,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
{
switch (core->tvaudio) {
case WW_BTSC:
- set_audio_standard_BTSC(core,0);
+ set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
break;
case WW_NICAM_BGDKL:
set_audio_standard_NICAM_L(core,0);
@@ -720,7 +743,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
case WW_A2_BG:
case WW_A2_DK:
case WW_A2_M:
- set_audio_standard_A2(core);
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
break;
case WW_EIAJ:
set_audio_standard_EIAJ(core);
@@ -734,7 +757,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
case WW_NONE:
default:
printk("%s/0: unknown tv audio mode [%d]\n",
- core->name, core->tvaudio);
+ core->name, core->tvaudio);
break;
}
return;
@@ -769,6 +792,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
aud_ctl_names[cx_read(AUD_CTL) & 63]);
core->astat = reg;
+/* TODO
+ Reading from AUD_STATUS is not enough
+ for auto-detecting sap/dual-fm/nicam.
+ Add some code here later.
+*/
+
+# if 0
t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
t->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -779,7 +809,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
t->capability = V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_SAP;
t->rxsubchans = V4L2_TUNER_SUB_STEREO;
- if (1 == pilot) {
+ if (1 == pilot) {
/* SAP */
t->rxsubchans |= V4L2_TUNER_SUB_SAP;
}
@@ -787,13 +817,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
case WW_A2_BG:
case WW_A2_DK:
case WW_A2_M:
- if (1 == pilot) {
+ if (1 == pilot) {
/* stereo */
t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
if (0 == mode)
t->audmode = V4L2_TUNER_MODE_STEREO;
}
- if (2 == pilot) {
+ if (2 == pilot) {
/* dual language -- FIXME */
t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
t->audmode = V4L2_TUNER_MODE_LANG1;
@@ -805,16 +835,17 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
}
break;
- case WW_SYSTEM_L_AM:
- if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
- t->audmode = V4L2_TUNER_MODE_STEREO;
+ case WW_SYSTEM_L_AM:
+ if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
+ t->audmode = V4L2_TUNER_MODE_STEREO;
t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
}
- break ;
+ break ;
default:
/* nothing */
break;
}
+# endif
return;
}
@@ -835,16 +866,16 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
case WW_BTSC:
switch (mode) {
case V4L2_TUNER_MODE_MONO:
- ctl = EN_BTSC_FORCE_MONO;
- mask = 0x3f;
+ set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_MONO);
break;
- case V4L2_TUNER_MODE_SAP:
- ctl = EN_BTSC_FORCE_SAP;
- mask = 0x3f;
+ case V4L2_TUNER_MODE_LANG1:
+ set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
break;
case V4L2_TUNER_MODE_STEREO:
- ctl = EN_BTSC_AUTO_STEREO;
- mask = 0x3f;
+ set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
break;
}
break;
@@ -854,16 +885,13 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
switch (mode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_LANG1:
- ctl = EN_A2_FORCE_MONO1;
- mask = 0x3f;
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
break;
case V4L2_TUNER_MODE_LANG2:
- ctl = EN_A2_AUTO_MONO2;
- mask = 0x3f;
+ set_audio_standard_A2(core, EN_A2_FORCE_MONO2);
break;
case V4L2_TUNER_MODE_STEREO:
- ctl = EN_A2_AUTO_STEREO | EN_DMTRX_SUMR;
- mask = 0x8bf;
+ set_audio_standard_A2(core, EN_A2_FORCE_STEREO);
break;
}
break;
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 320d57888bb..9bc6c899558 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
*/
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 5f58c103198..3dbc074fb51 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,4 @@
/*
- * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* video4linux video interface
@@ -66,7 +65,7 @@ module_param(vid_limit,int,0644);
MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
#define dprintk(level,fmt, arg...) if (video_debug >= level) \
- printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg)
+ printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
/* ------------------------------------------------------------------ */
@@ -326,22 +325,23 @@ static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
{
+ struct cx88_core *core = dev->core;
if (fh->resources & bit)
/* have it already allocated */
return 1;
/* is it free? */
- down(&dev->lock);
+ down(&core->lock);
if (dev->resources & bit) {
/* no, someone else uses it */
- up(&dev->lock);
+ up(&core->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->resources |= bit;
dprintk(1,"res: get %d\n",bit);
- up(&dev->lock);
+ up(&core->lock);
return 1;
}
@@ -360,27 +360,29 @@ int res_locked(struct cx8800_dev *dev, unsigned int bit)
static
void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
{
+ struct cx88_core *core = dev->core;
if ((fh->resources & bits) != bits)
BUG();
- down(&dev->lock);
+ down(&core->lock);
fh->resources &= ~bits;
dev->resources &= ~bits;
dprintk(1,"res: put %d\n",bits);
- up(&dev->lock);
+ up(&core->lock);
}
/* ------------------------------------------------------------------ */
-static int video_mux(struct cx8800_dev *dev, unsigned int input)
+/* static int video_mux(struct cx8800_dev *dev, unsigned int input) */
+static int video_mux(struct cx88_core *core, unsigned int input)
{
- struct cx88_core *core = dev->core;
+ /* struct cx88_core *core = dev->core; */
dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
input, INPUT(input)->vmux,
INPUT(input)->gpio0,INPUT(input)->gpio1,
INPUT(input)->gpio2,INPUT(input)->gpio3);
- dev->core->input = input;
+ core->input = input;
cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
cx_write(MO_GP3_IO, INPUT(input)->gpio3);
cx_write(MO_GP0_IO, INPUT(input)->gpio0);
@@ -413,9 +415,9 @@ static int start_video_dma(struct cx8800_dev *dev,
struct cx88_core *core = dev->core;
/* setup fifo + format */
- cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21],
+ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
buf->bpl, buf->risc.dma);
- cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field);
+ cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field);
cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
/* reset counter */
@@ -424,6 +426,14 @@ static int start_video_dma(struct cx8800_dev *dev,
/* enable irqs */
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
+
+ /* Enables corresponding bits at PCI_INT_STAT:
+ bits 0 to 4: video, audio, transport stream, VIP, Host
+ bit 7: timer
+ bits 8 and 9: DMA complete for: SRC, DST
+ bits 10 and 11: BERR signal asserted for RISC: RD, WR
+ bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB
+ */
cx_set(MO_VID_INTMSK, 0x0f0011);
/* enable capture */
@@ -431,7 +441,7 @@ static int start_video_dma(struct cx8800_dev *dev,
/* start dma */
cx_set(MO_DEV_CNTRL2, (1<<5));
- cx_set(MO_VID_DMACNTRL, 0x11);
+ cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */
return 0;
}
@@ -455,6 +465,7 @@ static int stop_video_dma(struct cx8800_dev *dev)
static int restart_video_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q)
{
+ struct cx88_core *core = dev->core;
struct cx88_buffer *buf, *prev;
struct list_head *item;
@@ -524,12 +535,13 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
{
struct cx8800_fh *fh = q->priv_data;
struct cx8800_dev *dev = fh->dev;
+ struct cx88_core *core = dev->core;
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
int rc, init_buffer = 0;
BUG_ON(NULL == fh->fmt);
- if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) ||
- fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm))
+ if (fh->width < 48 || fh->width > norm_maxw(core->tvnorm) ||
+ fh->height < 32 || fh->height > norm_maxh(core->tvnorm))
return -EINVAL;
buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
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)
struct cx88_buffer *prev;
struct cx8800_fh *fh = vq->priv_data;
struct cx8800_dev *dev = fh->dev;
+ struct cx88_core *core = dev->core;
struct cx88_dmaqueue *q = &dev->vidq;
/* add jump to stopper */
@@ -701,6 +714,7 @@ static int video_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
struct cx8800_dev *h,*dev = NULL;
+ struct cx88_core *core;
struct cx8800_fh *fh;
struct list_head *list;
enum v4l2_buf_type type = 0;
@@ -725,6 +739,8 @@ static int video_open(struct inode *inode, struct file *file)
if (NULL == dev)
return -ENODEV;
+ core = dev->core;
+
dprintk(1,"open minor=%d radio=%d type=%s\n",
minor,radio,v4l2_type_names[type]);
@@ -755,17 +771,16 @@ static int video_open(struct inode *inode, struct file *file)
fh);
if (fh->radio) {
- struct cx88_core *core = dev->core;
int board = core->board;
dprintk(1,"video_open: setting radio device\n");
cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
- dev->core->tvaudio = WW_FM;
+ core->tvaudio = WW_FM;
cx88_set_tvaudio(core);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
- cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL);
+ cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
}
return 0;
@@ -857,6 +872,9 @@ static int video_release(struct inode *inode, struct file *file)
videobuf_mmap_free(&fh->vbiq);
file->private_data = NULL;
kfree(fh);
+
+ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+
return 0;
}
@@ -870,9 +888,10 @@ video_mmap(struct file *file, struct vm_area_struct * vma)
/* ------------------------------------------------------------------ */
-static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
+/* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
+static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
{
- struct cx88_core *core = dev->core;
+ /* struct cx88_core *core = dev->core; */
struct cx88_ctrl *c = NULL;
u32 value;
int i;
@@ -898,9 +917,10 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
return 0;
}
-static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
+/* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
+static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
{
- struct cx88_core *core = dev->core;
+ /* struct cx88_core *core = dev->core; */
struct cx88_ctrl *c = NULL;
u32 v_sat_value;
u32 value;
@@ -913,9 +933,9 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
return -EINVAL;
if (ctl->value < c->v.minimum)
- return -ERANGE;
+ ctl->value = c->v.minimum;
if (ctl->value > c->v.maximum)
- return -ERANGE;
+ ctl->value = c->v.maximum;
switch (ctl->id) {
case V4L2_CID_AUDIO_BALANCE:
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)
return 0;
}
-static void init_controls(struct cx8800_dev *dev)
+/* static void init_controls(struct cx8800_dev *dev) */
+static void init_controls(struct cx88_core *core)
{
static struct v4l2_control mute = {
.id = V4L2_CID_AUDIO_MUTE,
@@ -969,11 +990,11 @@ static void init_controls(struct cx8800_dev *dev)
.value = 0x80,
};
- set_control(dev,&mute);
- set_control(dev,&volume);
- set_control(dev,&hue);
- set_control(dev,&contrast);
- set_control(dev,&brightness);
+ set_control(core,&mute);
+ set_control(core,&volume);
+ set_control(core,&hue);
+ set_control(core,&contrast);
+ set_control(core,&brightness);
}
/* ------------------------------------------------------------------ */
@@ -1004,6 +1025,8 @@ static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
struct v4l2_format *f)
{
+ struct cx88_core *core = dev->core;
+
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
{
@@ -1016,8 +1039,8 @@ static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
return -EINVAL;
field = f->fmt.pix.field;
- maxw = norm_maxw(dev->core->tvnorm);
- maxh = norm_maxh(dev->core->tvnorm);
+ maxw = norm_maxw(core->tvnorm);
+ maxh = norm_maxh(core->tvnorm);
if (V4L2_FIELD_ANY == field) {
field = (f->fmt.pix.height > maxh/2)
@@ -1101,12 +1124,14 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (video_debug > 1)
cx88_print_ioctl(core->name,cmd);
switch (cmd) {
+
+ /* --- capabilities ------------------------------------------ */
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
- strcpy(cap->driver, "cx8800");
+ strcpy(cap->driver, "cx8800");
strlcpy(cap->card, cx88_boards[core->board].name,
sizeof(cap->card));
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,
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
0;
if (UNSET != core->tuner_type)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
+ /* --- capture ioctls ---------------------------------------- */
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc *f = arg;
+ enum v4l2_buf_type type;
+ unsigned int index;
+
+ index = f->index;
+ type = f->type;
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+ memset(f,0,sizeof(*f));
+ f->index = index;
+ f->type = type;
+ strlcpy(f->description,formats[index].name,sizeof(f->description));
+ f->pixelformat = formats[index].fourcc;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+ }
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *f = arg;
+ return cx8800_g_fmt(dev,fh,f);
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *f = arg;
+ return cx8800_s_fmt(dev,fh,f);
+ }
+ case VIDIOC_TRY_FMT:
+ {
+ struct v4l2_format *f = arg;
+ return cx8800_try_fmt(dev,fh,f);
+ }
+
+ /* --- streaming capture ------------------------------------- */
+ case VIDIOCGMBUF:
+ {
+ struct video_mbuf *mbuf = arg;
+ struct videobuf_queue *q;
+ struct v4l2_requestbuffers req;
+ unsigned int i;
+
+ q = get_queue(fh);
+ memset(&req,0,sizeof(req));
+ req.type = q->type;
+ req.count = 8;
+ req.memory = V4L2_MEMORY_MMAP;
+ err = videobuf_reqbufs(q,&req);
+ if (err < 0)
+ return err;
+ memset(mbuf,0,sizeof(*mbuf));
+ mbuf->frames = req.count;
+ mbuf->size = 0;
+ for (i = 0; i < mbuf->frames; i++) {
+ mbuf->offsets[i] = q->bufs[i]->boff;
+ mbuf->size += q->bufs[i]->bsize;
+ }
+ return 0;
+ }
+ case VIDIOC_REQBUFS:
+ return videobuf_reqbufs(get_queue(fh), arg);
+
+ case VIDIOC_QUERYBUF:
+ return videobuf_querybuf(get_queue(fh), arg);
+
+ case VIDIOC_QBUF:
+ return videobuf_qbuf(get_queue(fh), arg);
+
+ case VIDIOC_DQBUF:
+ return videobuf_dqbuf(get_queue(fh), arg,
+ file->f_flags & O_NONBLOCK);
+
+ case VIDIOC_STREAMON:
+ {
+ int res = get_ressource(fh);
+
+ if (!res_get(dev,fh,res))
+ return -EBUSY;
+ return videobuf_streamon(get_queue(fh));
+ }
+ case VIDIOC_STREAMOFF:
+ {
+ int res = get_ressource(fh);
+
+ err = videobuf_streamoff(get_queue(fh));
+ if (err < 0)
+ return err;
+ res_free(dev,fh,res);
+ return 0;
+ }
+
+ default:
+ return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
+ }
+ return 0;
+}
+
+int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
+ struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
+{
+ int err;
+
+ if (video_debug > 1)
+ cx88_print_ioctl(core->name,cmd);
+ printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
+ cx88_print_ioctl(core->name,cmd);
+ dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
+
+ switch (cmd) {
/* ---------- tv norms ---------- */
case VIDIOC_ENUMSTD:
{
@@ -1156,9 +1297,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (i == ARRAY_SIZE(tvnorms))
return -EINVAL;
- down(&dev->lock);
- cx88_set_tvnorm(dev->core,&tvnorms[i]);
- up(&dev->lock);
+ down(&core->lock);
+ cx88_set_tvnorm(core,&tvnorms[i]);
+ up(&core->lock);
return 0;
}
@@ -1199,7 +1340,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
{
unsigned int *i = arg;
- *i = dev->core->input;
+ *i = core->input;
return 0;
}
case VIDIOC_S_INPUT:
@@ -1208,55 +1349,15 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (*i >= 4)
return -EINVAL;
- down(&dev->lock);
+ down(&core->lock);
cx88_newstation(core);
- video_mux(dev,*i);
- up(&dev->lock);
+ video_mux(core,*i);
+ up(&core->lock);
return 0;
}
- /* --- capture ioctls ---------------------------------------- */
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
- enum v4l2_buf_type type;
- unsigned int index;
-
- index = f->index;
- type = f->type;
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (index >= ARRAY_SIZE(formats))
- return -EINVAL;
- memset(f,0,sizeof(*f));
- f->index = index;
- f->type = type;
- strlcpy(f->description,formats[index].name,sizeof(f->description));
- f->pixelformat = formats[index].fourcc;
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- return cx8800_g_fmt(dev,fh,f);
- }
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- return cx8800_s_fmt(dev,fh,f);
- }
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
- return cx8800_try_fmt(dev,fh,f);
- }
-
/* --- controls ---------------------------------------------- */
case VIDIOC_QUERYCTRL:
{
@@ -1277,9 +1378,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
case VIDIOC_G_CTRL:
- return get_control(dev,arg);
+ return get_control(core,arg);
case VIDIOC_S_CTRL:
- return set_control(dev,arg);
+ return set_control(core,arg);
/* --- tuner ioctls ------------------------------------------ */
case VIDIOC_G_TUNER:
@@ -1323,10 +1424,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (UNSET == core->tuner_type)
return -EINVAL;
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
+ /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
+ f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ f->frequency = core->freq;
- cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f);
+ cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
return 0;
}
@@ -1338,83 +1440,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
if (f->tuner != 0)
return -EINVAL;
- if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)
+ if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV)
return -EINVAL;
- if (1 == fh->radio && f->type != V4L2_TUNER_RADIO)
+ if (1 == radio && f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- down(&dev->lock);
- dev->freq = f->frequency;
+ down(&core->lock);
+ core->freq = f->frequency;
cx88_newstation(core);
- cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
+ cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
/* When changing channels it is required to reset TVAUDIO */
msleep (10);
cx88_set_tvaudio(core);
- up(&dev->lock);
- return 0;
- }
-
- /* --- streaming capture ------------------------------------- */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *mbuf = arg;
- struct videobuf_queue *q;
- struct v4l2_requestbuffers req;
- unsigned int i;
-
- q = get_queue(fh);
- memset(&req,0,sizeof(req));
- req.type = q->type;
- req.count = 8;
- req.memory = V4L2_MEMORY_MMAP;
- err = videobuf_reqbufs(q,&req);
- if (err < 0)
- return err;
- memset(mbuf,0,sizeof(*mbuf));
- mbuf->frames = req.count;
- mbuf->size = 0;
- for (i = 0; i < mbuf->frames; i++) {
- mbuf->offsets[i] = q->bufs[i]->boff;
- mbuf->size += q->bufs[i]->bsize;
- }
- return 0;
- }
- case VIDIOC_REQBUFS:
- return videobuf_reqbufs(get_queue(fh), arg);
-
- case VIDIOC_QUERYBUF:
- return videobuf_querybuf(get_queue(fh), arg);
-
- case VIDIOC_QBUF:
- return videobuf_qbuf(get_queue(fh), arg);
-
- case VIDIOC_DQBUF:
- return videobuf_dqbuf(get_queue(fh), arg,
- file->f_flags & O_NONBLOCK);
-
- case VIDIOC_STREAMON:
- {
- int res = get_ressource(fh);
-
- if (!res_get(dev,fh,res))
- return -EBUSY;
- return videobuf_streamon(get_queue(fh));
- }
- case VIDIOC_STREAMOFF:
- {
- int res = get_ressource(fh);
-
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- res_free(dev,fh,res);
+ up(&core->lock);
return 0;
}
default:
return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- video_do_ioctl);
+ driver_ioctl);
}
return 0;
}
@@ -1461,7 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
memset(t,0,sizeof(*t));
strcpy(t->name, "Radio");
- cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
+ cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
return 0;
}
case VIDIOC_ENUMINPUT:
@@ -1501,8 +1546,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
if (v->tuner) /* Only tuner 0 */
return -EINVAL;
- cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v);
- return 0;
+ cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
+ return 0;
}
case VIDIOC_S_TUNER:
{
@@ -1511,7 +1556,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
if (0 != t->index)
return -EINVAL;
- cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t);
+ cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
return 0;
}
@@ -1569,7 +1614,7 @@ static void cx8800_vid_timeout(unsigned long data)
struct cx88_buffer *buf;
unsigned long flags;
- cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
+ cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
cx_clear(MO_VID_DMACNTRL, 0x11);
cx_clear(VID_CAPTURE_CONTROL, 0x06);
@@ -1614,14 +1659,14 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
cx_clear(MO_VID_DMACNTRL, 0x11);
cx_clear(VID_CAPTURE_CONTROL, 0x06);
- cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
+ cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
}
/* risc1 y */
if (status & 0x01) {
spin_lock(&dev->slock);
count = cx_read(MO_VIDY_GPCNT);
- cx88_wakeup(dev->core, &dev->vidq, count);
+ cx88_wakeup(core, &dev->vidq, count);
spin_unlock(&dev->slock);
}
@@ -1629,7 +1674,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
if (status & 0x08) {
spin_lock(&dev->slock);
count = cx_read(MO_VBI_GPCNT);
- cx88_wakeup(dev->core, &dev->vbiq, count);
+ cx88_wakeup(core, &dev->vbiq, count);
spin_unlock(&dev->slock);
}
@@ -1798,7 +1843,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
}
/* initialize driver struct */
- init_MUTEX(&dev->lock);
spin_lock_init(&dev->slock);
core->tvnorm = tvnorms;
@@ -1835,6 +1879,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
request_module("tuner");
if (core->tda9887_conf)
request_module("tda9887");
+
/* register v4l devices */
dev->video_dev = cx88_vdev_init(core,dev->pci,
&cx8800_video_template,"video");
@@ -1878,11 +1923,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
pci_set_drvdata(pci_dev,dev);
/* initial device configuration */
- down(&dev->lock);
- init_controls(dev);
- cx88_set_tvnorm(dev->core,tvnorms);
- video_mux(dev,0);
- up(&dev->lock);
+ down(&core->lock);
+ init_controls(core);
+ cx88_set_tvnorm(core,tvnorms);
+ video_mux(core,0);
+ up(&core->lock);
/* start tvaudio thread */
if (core->tuner_type != TUNER_ABSENT)
@@ -1902,14 +1947,15 @@ fail_free:
static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
{
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx88_core *core = dev->core;
/* stop thread */
- if (dev->core->kthread) {
- kthread_stop(dev->core->kthread);
- dev->core->kthread = NULL;
+ if (core->kthread) {
+ kthread_stop(core->kthread);
+ core->kthread = NULL;
}
- cx88_shutdown(dev->core); /* FIXME */
+ cx88_shutdown(core); /* FIXME */
pci_disable_device(pci_dev);
/* unregister stuff */
@@ -1921,7 +1967,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
/* free memory */
btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
list_del(&dev->devlist);
- cx88_core_put(dev->core,dev->pci);
+ cx88_core_put(core,dev->pci);
kfree(dev);
}
@@ -1945,7 +1991,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
spin_unlock(&dev->slock);
/* FIXME -- shutdown device */
- cx88_shutdown(dev->core);
+ cx88_shutdown(core);
pci_save_state(pci_dev);
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)
{
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
+ int err;
if (dev->state.disabled) {
- pci_enable_device(pci_dev);
+ err=pci_enable_device(pci_dev);
+ if (err) {
+ printk(KERN_ERR "%s: can't enable device\n",
+ core->name);
+ return err;
+ }
+
dev->state.disabled = 0;
}
- pci_set_power_state(pci_dev, PCI_D0);
+ err= pci_set_power_state(pci_dev, PCI_D0);
+ if (err) {
+ printk(KERN_ERR "%s: can't enable device\n",
+ core->name);
+
+ pci_disable_device(pci_dev);
+ dev->state.disabled = 1;
+
+ return err;
+ }
pci_restore_state(pci_dev);
/* FIXME: re-initialize hardware */
- cx88_reset(dev->core);
+ cx88_reset(core);
/* restart video+vbi capture */
spin_lock(&dev->slock);
@@ -2030,6 +2092,8 @@ static void cx8800_fini(void)
module_init(cx8800_init);
module_exit(cx8800_fini);
+EXPORT_SYMBOL(cx88_do_ioctl);
+
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index da65dc92787..f48dd435356 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,4 @@
/*
- * $Id: cx88.h,v 1.70 2005/07/24 17:44:09 mkrufky Exp $
*
* v4l2 device driver for cx2388x based TV cards
*
@@ -35,7 +34,7 @@
#include "btcx-risc.h"
#include "cx88-reg.h"
-#include <linux/utsname.h>
+#include <linux/version.h>
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
#ifndef TRUE
@@ -48,6 +47,9 @@
#define CX88_MAXBOARDS 8
+/* Max number of inputs by card */
+#define MAX_CX88_INPUT 8
+
/* ----------------------------------------------------------- */
/* defines and enums */
@@ -199,7 +201,7 @@ struct cx88_board {
unsigned char tuner_addr;
unsigned char radio_addr;
int tda9887_conf;
- struct cx88_input input[8];
+ struct cx88_input input[MAX_CX88_INPUT];
struct cx88_input radio;
int blackbird:1;
int dvb:1;
@@ -288,6 +290,11 @@ struct cx88_core {
/* IR remote control state */
struct cx88_IR *ir;
+
+ struct semaphore lock;
+
+ /* various v4l controls */
+ u32 freq;
};
struct cx8800_dev;
@@ -323,8 +330,7 @@ struct cx8800_suspend_state {
struct cx8800_dev {
struct cx88_core *core;
struct list_head devlist;
- struct semaphore lock;
- spinlock_t slock;
+ spinlock_t slock;
/* various device info */
unsigned int resources;
@@ -342,7 +348,6 @@ struct cx8800_dev {
struct cx88_dmaqueue vbiq;
/* various v4l controls */
- u32 freq;
/* other global state info */
struct cx8800_suspend_state state;
@@ -350,14 +355,8 @@ struct cx8800_dev {
/* ----------------------------------------------------------- */
/* function 1: audio/alsa stuff */
+/* =============> moved to cx88-alsa.c <====================== */
-struct cx8801_dev {
- struct cx88_core *core;
-
- /* pci i/o */
- struct pci_dev *pci;
- unsigned char pci_rev,pci_lat;
-};
/* ----------------------------------------------------------- */
/* function 2: mpeg stuff */
@@ -373,8 +372,7 @@ struct cx8802_suspend_state {
struct cx8802_dev {
struct cx88_core *core;
- struct semaphore lock;
- spinlock_t slock;
+ spinlock_t slock;
/* pci i/o */
struct pci_dev *pci;
@@ -553,8 +551,21 @@ void cx8802_fini_common(struct cx8802_dev *dev);
int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
int cx8802_resume_common(struct pci_dev *pci_dev);
+/* ----------------------------------------------------------- */
+/* cx88-video.c */
+extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
+ struct cx88_core *core, unsigned int cmd,
+ void *arg, v4l2_kioctl driver_ioctl);
+
+/* ----------------------------------------------------------- */
+/* cx88-blackbird.c */
+extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg);
+extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
+
/*
* Local variables:
* c-basic-offset: 8
* End:
+ * 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
*/
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index a565823330a..cf292da8fdd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -1,5 +1,4 @@
/*
- * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
*
* Copyright (c) 2003 Gerd Knorr
* Copyright (c) 2003 Pavel Machek
@@ -354,6 +353,7 @@ static int ir_probe(struct device *dev)
ir->input.id.vendor = sub->core->pci->vendor;
ir->input.id.product = sub->core->pci->device;
}
+ ir->input.dev = &sub->core->pci->dev;
if (ir->polling) {
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 1e273ff3f95..67105b9804a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -1,5 +1,4 @@
/*
- * $Id: ir-kbd-i2c.c,v 1.11 2005/07/07 16:42:11 mchehab Exp $
*
* keyboard input driver for i2c IR remote controls
*
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index ca02f6f14b0..f0d43fc2632 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -124,10 +124,14 @@ module_param(standard, int, 0644);
module_param(amsound, int, 0644);
module_param(dolby, int, 0644);
+MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler");
MODULE_PARM_DESC(once, "No continuous stereo monitoring");
MODULE_PARM_DESC(debug, "Enable debug messages");
+MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
+MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
+
MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
MODULE_AUTHOR("Gerd Knorr");
@@ -1452,7 +1456,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
if (-1 == msp3400c_reset(&client_template)) {
- dprintk("msp3400: no chip found\n");
+ dprintk("msp34xx: no chip found\n");
return -1;
}
@@ -1478,7 +1482,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
if (-1 == msp3400c_reset(c)) {
kfree(msp);
kfree(c);
- dprintk("msp3400: no chip found\n");
+ dprintk("msp34xx: no chip found\n");
return -1;
}
@@ -1488,7 +1492,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
kfree(msp);
kfree(c);
- printk("msp3400: error while reading chip version\n");
+ dprintk("msp34xx: error while reading chip version\n");
return -1;
}
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index 023f33056a4..2d9ff40f0b0 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -1,5 +1,4 @@
/*
- * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
*/
#ifndef MSP3400_H
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 2fb7c2d1787..972aa5e0aee 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -1,5 +1,4 @@
/*
- * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
*
* i2c tv tuner chip device driver
* controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -494,6 +493,7 @@ int microtune_init(struct i2c_client *c)
memset(buf,0,sizeof(buf));
t->tv_freq = NULL;
t->radio_freq = NULL;
+ t->standby = NULL;
name = "unknown";
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 00000000000..30337d0f1a8
--- /dev/null
+++ b/drivers/media/video/rds.h
@@ -0,0 +1,48 @@
+/*
+
+ Types and defines needed for RDS. This is included by
+ saa6588.c and every driver (e.g. bttv-driver.c) that wants
+ to use the saa6588 module.
+
+ Instead of having a seperate rds.h, I'd prefer to include
+ this stuff in one of the already existing files like tuner.h
+
+ (c) 2005 by Hans J. Koch
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _RDS_H
+#define _RDS_H
+
+struct rds_command {
+ unsigned int block_count;
+ int result;
+ unsigned char *buffer;
+ struct file *instance;
+ poll_table *event_list;
+};
+
+#define RDS_CMD_OPEN _IOW('R',1,int)
+#define RDS_CMD_CLOSE _IOW('R',2,int)
+#define RDS_CMD_READ _IOR('R',3,int)
+#define RDS_CMD_POLL _IOR('R',4,int)
+
+#endif
+
+
+
+
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
new file mode 100644
index 00000000000..1a657a70ff4
--- /dev/null
+++ b/drivers/media/video/saa6588.c
@@ -0,0 +1,534 @@
+/*
+ Driver for SAA6588 RDS decoder
+
+ (c) 2005 Hans J. Koch
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/videodev.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <asm/uaccess.h>
+
+#include <media/id.h>
+
+#include "rds.h"
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {
+ 0x20 >> 1,
+ 0x22 >> 1,
+ I2C_CLIENT_END,
+};
+
+I2C_CLIENT_INSMOD;
+
+/* insmod options */
+static unsigned int debug = 0;
+static unsigned int xtal = 0;
+static unsigned int rbds = 0;
+static unsigned int plvl = 0;
+static unsigned int bufblocks = 100;
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "enable debug messages");
+MODULE_PARM(xtal, "i");
+MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
+MODULE_PARM(rbds, "i");
+MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0");
+MODULE_PARM(plvl, "i");
+MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
+MODULE_PARM(bufblocks, "i");
+MODULE_PARM_DESC(bufblocks, "number of buffered blocks, default 100");
+
+MODULE_DESCRIPTION("v4l2 driver module for SAA6588 RDS decoder");
+MODULE_AUTHOR("Hans J. Koch <koch@hjk-az.de>");
+
+MODULE_LICENSE("GPL");
+
+/* ---------------------------------------------------------------------- */
+
+#define UNSET (-1U)
+#define PREFIX "saa6588: "
+#define dprintk if (debug) printk
+
+struct saa6588 {
+ struct i2c_client client;
+ struct work_struct work;
+ struct timer_list timer;
+ spinlock_t lock;
+ unsigned char *buffer;
+ unsigned int buf_size;
+ unsigned int rd_index;
+ unsigned int wr_index;
+ unsigned int block_count;
+ unsigned char last_blocknum;
+ wait_queue_head_t read_queue;
+ int data_available_for_read;
+};
+
+static struct i2c_driver driver;
+static struct i2c_client client_template;
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * SAA6588 defines
+ */
+
+/* Initialization and mode control byte (0w) */
+
+/* bit 0+1 (DAC0/DAC1) */
+#define cModeStandard 0x00
+#define cModeFastPI 0x01
+#define cModeReducedRequest 0x02
+#define cModeInvalid 0x03
+
+/* bit 2 (RBDS) */
+#define cProcessingModeRDS 0x00
+#define cProcessingModeRBDS 0x04
+
+/* bit 3+4 (SYM0/SYM1) */
+#define cErrCorrectionNone 0x00
+#define cErrCorrection2Bits 0x08
+#define cErrCorrection5Bits 0x10
+#define cErrCorrectionNoneRBDS 0x18
+
+/* bit 5 (NWSY) */
+#define cSyncNormal 0x00
+#define cSyncRestart 0x20
+
+/* bit 6 (TSQD) */
+#define cSigQualityDetectOFF 0x00
+#define cSigQualityDetectON 0x40
+
+/* bit 7 (SQCM) */
+#define cSigQualityTriggered 0x00
+#define cSigQualityContinous 0x80
+
+/* Pause level and flywheel control byte (1w) */
+
+/* bits 0..5 (FEB0..FEB5) */
+#define cFlywheelMaxBlocksMask 0x3F
+#define cFlywheelDefault 0x20
+
+/* bits 6+7 (PL0/PL1) */
+#define cPauseLevel_11mV 0x00
+#define cPauseLevel_17mV 0x40
+#define cPauseLevel_27mV 0x80
+#define cPauseLevel_43mV 0xC0
+
+/* Pause time/oscillator frequency/quality detector control byte (1w) */
+
+/* bits 0..4 (SQS0..SQS4) */
+#define cQualityDetectSensMask 0x1F
+#define cQualityDetectDefault 0x0F
+
+/* bit 5 (SOSC) */
+#define cSelectOscFreqOFF 0x00
+#define cSelectOscFreqON 0x20
+
+/* bit 6+7 (PTF0/PTF1) */
+#define cOscFreq_4332kHz 0x00
+#define cOscFreq_8664kHz 0x40
+#define cOscFreq_12996kHz 0x80
+#define cOscFreq_17328kHz 0xC0
+
+/* ---------------------------------------------------------------------- */
+
+static int block_to_user_buf(struct saa6588 *s, unsigned char *user_buf)
+{
+ int i;
+
+ if (s->rd_index == s->wr_index) {
+ if (debug > 2)
+ dprintk(PREFIX "Read: buffer empty.\n");
+ return 0;
+ }
+
+ if (debug > 2) {
+ dprintk(PREFIX "Read: ");
+ for (i = s->rd_index; i < s->rd_index + 3; i++)
+ dprintk("0x%02x ", s->buffer[i]);
+ }
+
+ if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3))
+ return -EFAULT;
+
+ s->rd_index += 3;
+ if (s->rd_index >= s->buf_size)
+ s->rd_index = 0;
+ s->block_count--;
+
+ if (debug > 2)
+ dprintk("%d blocks total.\n", s->block_count);
+
+ return 1;
+}
+
+static void read_from_buf(struct saa6588 *s, struct rds_command *a)
+{
+ unsigned long flags;
+
+ unsigned char *buf_ptr = a->buffer; /* This is a user space buffer! */
+ unsigned int i;
+ unsigned int rd_blocks;
+
+ a->result = 0;
+ if (!a->buffer)
+ return;
+
+ while (!s->data_available_for_read) {
+ int ret = wait_event_interruptible(s->read_queue,
+ s->data_available_for_read);
+ if (ret == -ERESTARTSYS) {
+ a->result = -EINTR;
+ return;
+ }
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ rd_blocks = a->block_count;
+ if (rd_blocks > s->block_count)
+ rd_blocks = s->block_count;
+
+ if (!rd_blocks)
+ return;
+
+ for (i = 0; i < rd_blocks; i++) {
+ if (block_to_user_buf(s, buf_ptr)) {
+ buf_ptr += 3;
+ a->result++;
+ } else
+ break;
+ }
+ a->result *= 3;
+ s->data_available_for_read = (s->block_count > 0);
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
+{
+ unsigned int i;
+
+ if (debug > 3)
+ dprintk(PREFIX "New block: ");
+
+ for (i = 0; i < 3; ++i) {
+ if (debug > 3)
+ dprintk("0x%02x ", blockbuf[i]);
+ s->buffer[s->wr_index] = blockbuf[i];
+ s->wr_index++;
+ }
+
+ if (s->wr_index >= s->buf_size)
+ s->wr_index = 0;
+
+ if (s->wr_index == s->rd_index) {
+ s->rd_index++;
+ if (s->rd_index >= s->buf_size)
+ s->rd_index = 0;
+ } else
+ s->block_count++;
+
+ if (debug > 3)
+ dprintk("%d blocks total.\n", s->block_count);
+}
+
+static void saa6588_i2c_poll(struct saa6588 *s)
+{
+ unsigned long flags;
+ unsigned char tmpbuf[6];
+ unsigned char blocknum;
+ unsigned char tmp;
+
+ /* Although we only need 3 bytes, we have to read at least 6.
+ SAA6588 returns garbage otherwise */
+ if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
+ if (debug > 1)
+ dprintk(PREFIX "read error!\n");
+ return;
+ }
+
+ blocknum = tmpbuf[0] >> 5;
+ if (blocknum == s->last_blocknum) {
+ if (debug > 3)
+ dprintk("Saw block %d again.\n", blocknum);
+ return;
+ }
+
+ s->last_blocknum = blocknum;
+
+ /*
+ Byte order according to v4l2 specification:
+
+ Byte 0: Least Significant Byte of RDS Block
+ Byte 1: Most Significant Byte of RDS Block
+ Byte 2 Bit 7: Error bit. Indicates that an uncorrectable error
+ occurred during reception of this block.
+ Bit 6: Corrected bit. Indicates that an error was
+ corrected for this data block.
+ Bits 5-3: Received Offset. Indicates the offset received
+ by the sync system.
+ Bits 2-0: Offset Name. Indicates the offset applied to this data.
+
+ SAA6588 byte order is Status-MSB-LSB, so we have to swap the
+ first and the last of the 3 bytes block.
+ */
+
+ tmp = tmpbuf[2];
+ tmpbuf[2] = tmpbuf[0];
+ tmpbuf[0] = tmp;
+
+ tmp = blocknum;
+ tmp |= blocknum << 3; /* Received offset == Offset Name (OK ?) */
+ if ((tmpbuf[2] & 0x03) == 0x03)
+ tmp |= 0x80; /* uncorrectable error */
+ else if ((tmpbuf[2] & 0x03) != 0x00)
+ tmp |= 0x40; /* corrected error */
+ tmpbuf[2] = tmp; /* Is this enough ? Should we also check other bits ? */
+
+ spin_lock_irqsave(&s->lock, flags);
+ block_to_buf(s, tmpbuf);
+ spin_unlock_irqrestore(&s->lock, flags);
+ s->data_available_for_read = 1;
+ wake_up_interruptible(&s->read_queue);
+}
+
+static void saa6588_timer(unsigned long data)
+{
+ struct saa6588 *s = (struct saa6588 *)data;
+
+ schedule_work(&s->work);
+}
+
+static void saa6588_work(void *data)
+{
+ struct saa6588 *s = (struct saa6588 *)data;
+
+ saa6588_i2c_poll(s);
+ mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */
+}
+
+static int saa6588_configure(struct saa6588 *s)
+{
+ unsigned char buf[3];
+ int rc;
+
+ buf[0] = cSyncRestart;
+ if (rbds)
+ buf[0] |= cProcessingModeRBDS;
+
+ buf[1] = cFlywheelDefault;
+ switch (plvl) {
+ case 0:
+ buf[1] |= cPauseLevel_11mV;
+ break;
+ case 1:
+ buf[1] |= cPauseLevel_17mV;
+ break;
+ case 2:
+ buf[1] |= cPauseLevel_27mV;
+ break;
+ case 3:
+ buf[1] |= cPauseLevel_43mV;
+ break;
+ default: /* nothing */
+ break;
+ }
+
+ buf[2] = cQualityDetectDefault | cSelectOscFreqON;
+
+ switch (xtal) {
+ case 0:
+ buf[2] |= cOscFreq_4332kHz;
+ break;
+ case 1:
+ buf[2] |= cOscFreq_8664kHz;
+ break;
+ case 2:
+ buf[2] |= cOscFreq_12996kHz;
+ break;
+ case 3:
+ buf[2] |= cOscFreq_17328kHz;
+ break;
+ default: /* nothing */
+ break;
+ }
+
+ dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
+ buf[0], buf[1], buf[2]);
+
+ if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
+ printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+ struct saa6588 *s;
+ client_template.adapter = adap;
+ client_template.addr = addr;
+
+ printk(PREFIX "chip found @ 0x%x\n", addr << 1);
+
+ if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
+ return -ENOMEM;
+
+ s->buf_size = bufblocks * 3;
+
+ if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
+ kfree(s);
+ return -ENOMEM;
+ }
+ s->client = client_template;
+ s->block_count = 0;
+ s->wr_index = 0;
+ s->rd_index = 0;
+ s->last_blocknum = 0xff;
+ init_waitqueue_head(&s->read_queue);
+ s->data_available_for_read = 0;
+ i2c_set_clientdata(&s->client, s);
+ i2c_attach_client(&s->client);
+
+ saa6588_configure(s);
+
+ /* start polling via eventd */
+ INIT_WORK(&s->work, saa6588_work, s);
+ init_timer(&s->timer);
+ s->timer.function = saa6588_timer;
+ s->timer.data = (unsigned long)s;
+ schedule_work(&s->work);
+
+ return 0;
+}
+
+static int saa6588_probe(struct i2c_adapter *adap)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adap->class & I2C_CLASS_TV_ANALOG)
+ return i2c_probe(adap, &addr_data, saa6588_attach);
+#else
+ switch (adap->id) {
+ case I2C_ALGO_BIT | I2C_HW_B_BT848:
+ case I2C_ALGO_BIT | I2C_HW_B_RIVA:
+ case I2C_ALGO_SAA7134:
+ return i2c_probe(adap, &addr_data, saa6588_attach);
+ break;
+ }
+#endif
+ return 0;
+}
+
+static int saa6588_detach(struct i2c_client *client)
+{
+ struct saa6588 *s = i2c_get_clientdata(client);
+
+ del_timer_sync(&s->timer);
+ flush_scheduled_work();
+
+ i2c_detach_client(client);
+ kfree(s->buffer);
+ kfree(s);
+ return 0;
+}
+
+static int saa6588_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ struct saa6588 *s = i2c_get_clientdata(client);
+ struct rds_command *a = (struct rds_command *)arg;
+
+ switch (cmd) {
+ /* --- open() for /dev/radio --- */
+ case RDS_CMD_OPEN:
+ a->result = 0; /* return error if chip doesn't work ??? */
+ break;
+ /* --- close() for /dev/radio --- */
+ case RDS_CMD_CLOSE:
+ s->data_available_for_read = 1;
+ wake_up_interruptible(&s->read_queue);
+ a->result = 0;
+ break;
+ /* --- read() for /dev/radio --- */
+ case RDS_CMD_READ:
+ read_from_buf(s, a);
+ break;
+ /* --- poll() for /dev/radio --- */
+ case RDS_CMD_POLL:
+ a->result = 0;
+ if (s->data_available_for_read) {
+ a->result |= POLLIN | POLLRDNORM;
+ }
+ poll_wait(a->instance, &s->read_queue, a->event_list);
+ break;
+
+ default:
+ /* nothing */
+ break;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver driver = {
+ .owner = THIS_MODULE,
+ .name = "i2c saa6588 driver",
+ .id = -1, /* FIXME */
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = saa6588_probe,
+ .detach_client = saa6588_detach,
+ .command = saa6588_command,
+};
+
+static struct i2c_client client_template = {
+ .name = "saa6588",
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
+};
+
+static int __init saa6588_init_module(void)
+{
+ return i2c_add_driver(&driver);
+}
+
+static void __exit saa6588_cleanup_module(void)
+{
+ i2c_del_driver(&driver);
+}
+
+module_init(saa6588_init_module);
+module_exit(saa6588_cleanup_module);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 88b71a20b60..acc7a4335e2 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-cards.c,v 1.80 2005/07/07 01:49:30 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* card-specific stuff.
@@ -1373,7 +1372,7 @@ struct saa7134_board saa7134_boards[] = {
.inputs = {{
.name = name_comp1,
.vmux = 1,
- .amux = LINE2,
+ .amux = LINE1,
},{
.name = name_tv,
.vmux = 3,
@@ -1382,7 +1381,7 @@ struct saa7134_board saa7134_boards[] = {
},{
.name = name_svideo,
.vmux = 8,
- .amux = LINE2,
+ .amux = LINE1,
}},
.radio = {
.name = name_radio,
@@ -2001,6 +2000,115 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x000,
},
},
+ [SAA7134_BOARD_FLYTV_DIGIMATRIX] = {
+ .name = "FlyTV mini Asus Digimatrix",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_LG_NTSC_TALN_MINI,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ },{
+ .name = name_comp2,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ .radio = {
+ .name = name_radio, /* radio unconfirmed */
+ .amux = LINE2,
+ },
+ },
+ [SAA7134_BOARD_KWORLD_TERMINATOR] = {
+ /* Kworld V-Stream Studio TV Terminator */
+ /* "James Webb <jrwebb@qwest.net> */
+ .name = "V-Stream Studio TV Terminator",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 1 << 21,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .gpio = 0x0000000,
+ .tv = 1,
+ },{
+ .name = name_comp1, /* Composite input */
+ .vmux = 3,
+ .amux = LINE2,
+ .gpio = 0x0000000,
+ },{
+ .name = name_svideo, /* S-Video input */
+ .vmux = 8,
+ .amux = LINE2,
+ .gpio = 0x0000000,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
+ [SAA7134_BOARD_YUAN_TUN900] = {
+ /* FIXME:
+ * S-Video and composite sources untested.
+ * Radio not working.
+ * Remote control not yet implemented.
+ * From : codemaster@webgeeks.be */
+ .name = "Yuan TUN-900 (saa7135)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr= ADDR_UNSET,
+ .radio_addr= ADDR_UNSET,
+ .gpiomask = 0x00010003,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x01,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ .gpio = 0x02,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE2,
+ .gpio = 0x02,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x00010003,
+ },
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ .gpio = 0x01,
+ },
+ },
};
@@ -2272,12 +2380,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0,
- .driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0x9715,
@@ -2346,6 +2448,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = 0x4e42,
.subdevice = 0x0502,
.driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1043,
+ .subdevice = 0x0210, /* mini pci NTSC version */
+ .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1043,
+ .subdevice = 0x0210, /* mini pci PAL/SECAM version */
+ .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
},{
/* --- boards without eeprom + subsystem ID --- */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 1dbe61755e9..e5e36f3c625 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-core.c,v 1.39 2005/07/05 17:37:35 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* driver core
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 8be6a90358c..639ae51a052 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-dvb.c,v 1.23 2005/07/24 22:12:47 mkrufky Exp $
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
@@ -29,7 +28,6 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/suspend.h>
-#include <linux/config.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c85348d0239..77b627eb648 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index eae6b529713..711aa8e85fa 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-i2c.c,v 1.22 2005/07/22 04:09:41 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* i2c interface support
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 213740122fe..1f456c4d76f 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-input.c,v 1.21 2005/06/22 23:37:34 nsh Exp $
*
* handle saa7134 IR remotes via linux kernel input layer.
*
@@ -565,6 +564,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
ir->dev.id.vendor = dev->pci->vendor;
ir->dev.id.product = dev->pci->device;
}
+ ir->dev.dev = &dev->pci->dev;
/* all done */
dev->remote = ir;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index b5bede95dbf..c20630c82f1 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-oss.c,v 1.17 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* oss dsp interface
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index 87734f22af7..ae0c7a16539 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-reg.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
*
* philips saa7134 registers
*/
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 4dd9f1b2392..463885601ab 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-ts.c,v 1.15 2005/06/14 22:48:18 hhackmann Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index eeafa5a71d2..badf2f9e307 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-tvaudio.c,v 1.30 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* 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 29e51cad2aa..f4aee0af80e 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a4c2f751d09..35e5e85f669 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134-video.c,v 1.36 2005/06/28 23:41:47 mkrufky Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
@@ -1368,29 +1367,7 @@ static int video_release(struct inode *inode, struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
- if (dev->tuner_type == TUNER_PHILIPS_TDA8290) {
- u8 data[2];
- int ret;
- struct i2c_msg msg = {.addr=I2C_ADDR_TDA8290, .flags=0, .buf=data, .len = 2};
- data[0] = 0x21;
- data[1] = 0xc0;
- ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
- if (ret != 1)
- printk(KERN_ERR "TDA8290 access failure\n");
- msg.addr = I2C_ADDR_TDA8275;
- data[0] = 0x30;
- data[1] = 0xd0;
- ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
- if (ret != 1)
- printk(KERN_ERR "TDA8275 access failure\n");
- msg.addr = I2C_ADDR_TDA8290;
- data[0] = 0x21;
- data[1] = 0x80;
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- data[0] = 0x00;
- data[1] = 0x02;
- i2c_transfer(&dev->i2c_adap, &msg, 1);
- }
+ saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
/* free stuff */
videobuf_mmap_free(&fh->cap);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 2af0cb2a731..3ea09142ec9 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,4 @@
/*
- * $Id: saa7134.h,v 1.49 2005/07/13 17:25:25 mchehab Exp $
*
* v4l2 device driver for philips saa7134 based TV cards
*
@@ -185,6 +184,9 @@ struct saa7134_format {
#define SAA7134_BOARD_PHILIPS_TOUGH 61
#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
#define SAA7134_BOARD_KWORLD_XPERT 63
+#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
+#define SAA7134_BOARD_KWORLD_TERMINATOR 65
+#define SAA7134_BOARD_YUAN_TUN900 66
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index a8b6a8df510..c65f0c7680a 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,4 @@
/*
- * $Id: tda8290.c,v 1.15 2005/07/08 20:21:33 mchehab Exp $
*
* i2c tv tuner chip device driver
* controls the philips tda8290+75 tuner chip combo.
@@ -9,6 +8,9 @@
#include <linux/delay.h>
#include <media/tuner.h>
+#define I2C_ADDR_TDA8290 0x4b
+#define I2C_ADDR_TDA8275 0x61
+
/* ---------------------------------------------------------------------- */
struct freq_entry {
@@ -75,10 +77,12 @@ static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
+static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
+static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
@@ -117,6 +121,13 @@ static struct i2c_msg i2c_msg_epilog[] = {
{ I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on },
};
+static struct i2c_msg i2c_msg_standby[] = {
+ { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
+ { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 },
+ { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
+ { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby },
+};
+
static int tda8290_tune(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
@@ -205,6 +216,11 @@ static int has_signal(struct i2c_client *c)
return (afc & 0x80)? 65535:0;
}
+static void standby(struct i2c_client *c)
+{
+ i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby));
+}
+
int tda8290_init(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
@@ -214,6 +230,7 @@ int tda8290_init(struct i2c_client *c)
t->tv_freq = set_tv_freq;
t->radio_freq = set_radio_freq;
t->has_signal = has_signal;
+ t->standby = standby;
i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge));
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 d60fc562aec..0456dda2624 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -23,6 +23,7 @@
TDA9887 (world), TDA9885 (USA)
Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
- KNC One TV-Station RDS (saa7134)
+ - Hauppauge PVR-150/500 (possibly more)
*/
@@ -49,7 +50,7 @@ MODULE_LICENSE("GPL");
struct tda9887 {
struct i2c_client client;
v4l2_std_id std;
- unsigned int radio;
+ enum tuner_mode mode;
unsigned int config;
unsigned int pinnacle_id;
unsigned int using_v4l2;
@@ -196,7 +197,7 @@ static struct tvnorm tvnorms[] = {
.b = ( cNegativeFmTV |
cQSS ),
.c = ( cDeemphasisON |
- cDeemphasis50 ),
+ cDeemphasis75 ),
.e = ( cGating_36 |
cAudioIF_4_5 |
cVideoIF_45_75 ),
@@ -364,7 +365,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
struct tvnorm *norm = NULL;
int i;
- if (t->radio) {
+ if (t->mode == T_RADIO) {
if (t->radio_mode == V4L2_TUNER_MODE_MONO)
norm = &radio_mono;
else
@@ -378,7 +379,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
}
}
if (NULL == norm) {
- dprintk(PREFIX "Oops: no tvnorm entry found\n");
+ dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n");
return -1;
}
@@ -519,6 +520,12 @@ static int tda9887_fixup_std(struct tda9887 *t)
dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
t->std = V4L2_STD_PAL_DK;
break;
+ case '-':
+ /* default parameter, do nothing */
+ break;
+ default:
+ printk(PREFIX "pal= argument not recognised\n");
+ break;
}
}
if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
@@ -535,6 +542,12 @@ static int tda9887_fixup_std(struct tda9887 *t)
dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
t->std = V4L2_STD_SECAM_L;
break;
+ case '-':
+ /* default parameter, do nothing */
+ break;
+ default:
+ printk(PREFIX "secam= argument not recognised\n");
+ break;
}
}
return 0;
@@ -569,6 +582,10 @@ static int tda9887_configure(struct tda9887 *t)
tda9887_set_config(t,buf);
tda9887_set_insmod(t,buf);
+ if (t->mode == T_STANDBY) {
+ buf[1] |= cForcedMuteAudioON;
+ }
+
dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
buf[1],buf[2],buf[3]);
@@ -653,10 +670,17 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
/* --- configuration --- */
case AUDC_SET_RADIO:
- t->radio = 1;
+ {
+ t->mode = T_RADIO;
tda9887_configure(t);
break;
-
+ }
+ case TUNER_SET_STANDBY:
+ {
+ t->mode = T_STANDBY;
+ tda9887_configure(t);
+ break;
+ }
case AUDC_CONFIG_PINNACLE:
{
int *i = arg;
@@ -689,7 +713,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
struct video_channel *vc = arg;
CHECK_V4L2;
- t->radio = 0;
+ t->mode = T_ANALOG_TV;
if (vc->norm < ARRAY_SIZE(map))
t->std = map[vc->norm];
tda9887_fixup_std(t);
@@ -701,7 +725,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
v4l2_std_id *id = arg;
SWITCH_V4L2;
- t->radio = 0;
+ t->mode = T_ANALOG_TV;
t->std = *id;
tda9887_fixup_std(t);
tda9887_configure(t);
@@ -713,14 +737,14 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
SWITCH_V4L2;
if (V4L2_TUNER_ANALOG_TV == f->type) {
- if (t->radio == 0)
+ if (t->mode == T_ANALOG_TV)
return 0;
- t->radio = 0;
+ t->mode = T_ANALOG_TV;
}
if (V4L2_TUNER_RADIO == f->type) {
- if (t->radio == 1)
+ if (t->mode == T_RADIO)
return 0;
- t->radio = 1;
+ t->mode = T_RADIO;
}
tda9887_configure(t);
break;
@@ -735,7 +759,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
};
struct v4l2_tuner* tuner = arg;
- if (t->radio) {
+ if (t->mode == T_RADIO) {
__u8 reg = 0;
tuner->afc=0;
if (1 == i2c_master_recv(&t->client,&reg,1))
@@ -747,7 +771,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct v4l2_tuner* tuner = arg;
- if (t->radio) {
+ if (t->mode == T_RADIO) {
t->radio_mode = tuner->audmode;
tda9887_configure (t);
}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index cebcc1fa68d..38bf5094379 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -2,7 +2,6 @@
* For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
* I2C address is allways 0xC0.
*
- * $Id: tea5767.c,v 1.27 2005/07/31 12:10:56 mchehab Exp $
*
* Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
* 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)
TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
buffer[4] = 0;
- if (t->mode == T_STANDBY) {
- tuner_dbg("TEA5767 set to standby mode\n");
- buffer[3] |= TEA5767_STDBY;
- }
-
if (t->audmode == V4L2_TUNER_MODE_MONO) {
tuner_dbg("TEA5767 set to mono\n");
buffer[2] |= TEA5767_MONO;
@@ -290,13 +284,31 @@ static int tea5767_stereo(struct i2c_client *c)
return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
}
+static void tea5767_standby(struct i2c_client *c)
+{
+ unsigned char buffer[5];
+ struct tuner *t = i2c_get_clientdata(c);
+ unsigned div, rc;
+
+ div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
+ buffer[0] = (div >> 8) & 0x3f;
+ buffer[1] = div & 0xff;
+ buffer[2] = TEA5767_PORT1_HIGH;
+ buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
+ TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
+ buffer[4] = 0;
+
+ if (5 != (rc = i2c_master_send(c, buffer, 5)))
+ tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+}
+
int tea5767_autodetection(struct i2c_client *c)
{
unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
int rc;
struct tuner *t = i2c_get_clientdata(c);
- if (7 != (rc = i2c_master_recv(c, buffer, 7))) {
+ if ((rc = i2c_master_recv(c, buffer, 7))< 5) {
tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
return EINVAL;
}
@@ -313,15 +325,10 @@ int tea5767_autodetection(struct i2c_client *c)
* bit 0 : internally set to 0
* Byte 5: bit 7:0 : == 0
*/
- if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
+ if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
return EINVAL;
}
- /* It seems that tea5767 returns 0xff after the 5th byte */
- if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
- tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n");
- return EINVAL;
- }
/* It seems that tea5767 returns 0xff after the 5th byte */
if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
@@ -337,14 +344,14 @@ int tea5767_tuner_init(struct i2c_client *c)
{
struct tuner *t = i2c_get_clientdata(c);
- tuner_info("type set to %d (%s)\n", t->type,
- "Philips TEA5767HN FM Radio");
+ tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
strlcpy(c->name, "tea5767", sizeof(c->name));
t->tv_freq = set_tv_freq;
t->radio_freq = set_radio_freq;
t->has_signal = tea5767_signal;
t->is_stereo = tea5767_stereo;
+ t->standby = tea5767_standby;
return (0);
}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 3b1893c2ae3..05572020af4 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,4 @@
/*
- * $Id: tuner-core.c,v 1.63 2005/07/28 18:19:55 mchehab Exp $
*
* i2c tv tuner chip device driver
* 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,
i2c_master_send(c, buffer, 4);
default_tuner_init(c);
break;
+ case TUNER_LG_TDVS_H062F:
+ /* Set the Auxiliary Byte. */
+ buffer[2] &= ~0x20;
+ buffer[2] |= 0x18;
+ buffer[3] = 0x20;
+ i2c_master_send(c, buffer, 4);
+ default_tuner_init(c);
+ break;
default:
default_tuner_init(c);
break;
@@ -208,31 +215,31 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
{
struct tuner *t = i2c_get_clientdata(c);
- if (tun_setup->addr == ADDR_UNSET) {
- if (t->mode_mask & tun_setup->mode_mask)
+ if ((tun_setup->addr == ADDR_UNSET &&
+ (t->mode_mask & tun_setup->mode_mask)) ||
+ tun_setup->addr == c->addr) {
set_type(c, tun_setup->type, tun_setup->mode_mask);
- } else if (tun_setup->addr == c->addr) {
- set_type(c, tun_setup->type, tun_setup->mode_mask);
}
}
static inline int check_mode(struct tuner *t, char *cmd)
{
- if (1 << t->mode & t->mode_mask) {
- switch (t->mode) {
- case V4L2_TUNER_RADIO:
- tuner_dbg("Cmd %s accepted for radio\n", cmd);
- break;
- case V4L2_TUNER_ANALOG_TV:
- tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
- break;
- case V4L2_TUNER_DIGITAL_TV:
- tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
- break;
- }
- return 0;
+ if ((1 << t->mode & t->mode_mask) == 0) {
+ return EINVAL;
+ }
+
+ switch (t->mode) {
+ case V4L2_TUNER_RADIO:
+ tuner_dbg("Cmd %s accepted for radio\n", cmd);
+ break;
+ case V4L2_TUNER_ANALOG_TV:
+ tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
+ break;
+ case V4L2_TUNER_DIGITAL_TV:
+ tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
+ break;
}
- return EINVAL;
+ return 0;
}
static char pal[] = "-";
@@ -274,6 +281,12 @@ static int tuner_fixup_std(struct tuner *t)
tuner_dbg ("insmod fixup: PAL => PAL-N\n");
t->std = V4L2_STD_PAL_N;
break;
+ case '-':
+ /* default parameter, do nothing */
+ break;
+ default:
+ tuner_warn ("pal= argument not recognised\n");
+ break;
}
}
if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
@@ -290,6 +303,12 @@ static int tuner_fixup_std(struct tuner *t)
tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
t->std = V4L2_STD_SECAM_L;
break;
+ case '-':
+ /* default parameter, do nothing */
+ break;
+ default:
+ tuner_warn ("secam= argument not recognised\n");
+ break;
}
}
@@ -406,20 +425,18 @@ static int tuner_detach(struct i2c_client *client)
static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
{
- if (mode != t->mode) {
-
- t->mode = mode;
- if (check_mode(t, cmd) == EINVAL) {
- t->mode = T_STANDBY;
- if (V4L2_TUNER_RADIO == mode) {
- set_tv_freq(client, 400 * 16);
- } else {
- set_radio_freq(client, 87.5 * 16000);
- }
- return EINVAL;
- }
- }
- return 0;
+ if (mode == t->mode)
+ return 0;
+
+ t->mode = mode;
+
+ if (check_mode(t, cmd) == EINVAL) {
+ t->mode = T_STANDBY;
+ if (t->standby)
+ t->standby (client);
+ return EINVAL;
+ }
+ return 0;
}
#define switch_v4l2() if (!t->using_v4l2) \
@@ -453,6 +470,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
case AUDC_SET_RADIO:
set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO");
break;
+ case TUNER_SET_STANDBY:
+ {
+ if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
+ return 0;
+ if (t->standby)
+ t->standby (client);
+ break;
+ }
case AUDC_CONFIG_PINNACLE:
if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
return 0;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index de0c93aeb75..8edd73abe1d 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,4 @@
/*
- * $Id: tuner-simple.c,v 1.43 2005/07/28 18:41:21 mchehab Exp $
*
* i2c tv tuner chip device driver
* controls all those simple 4-control-bytes style tuners.
@@ -102,6 +101,7 @@ struct tunertype
* "no float in kernel" rule.
*/
static struct tunertype tuners[] = {
+ /* 0-9 */
{ "Temic PAL (4002 FH5)", TEMIC, PAL,
16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
{ "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
@@ -110,7 +110,6 @@ static struct tunertype tuners[] = {
16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
{ "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
-
{ "NoTuner", NoTuner, NOTUNER,
0,0,0x00,0x00,0x00,0x00,0x00},
{ "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
@@ -119,34 +118,34 @@ static struct tunertype tuners[] = {
16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
{ "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
-
{ "Temic NTSC (4036 FY5)", TEMIC, NTSC,
16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
{ "Alps HSBH1", TEMIC, NTSC,
16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
- { "Alps TSBE1",TEMIC,PAL,
+
+ /* 10-19 */
+ { "Alps TSBE1", TEMIC, PAL,
16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
{ "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
-
{ "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
{ "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
{ "Temic PAL_BG (4006FH5)", TEMIC, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
- { "Alps TSCH6",Alps,NTSC,
+ { "Alps TSCH6", Alps, NTSC,
16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
-
- { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
+ { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
- { "Philips NTSC_M (MK2)",Philips,NTSC,
+ { "Philips NTSC_M (MK2)", Philips, NTSC,
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
{ "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
{ "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
+ /* 20-29 */
{ "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
{ "Temic NTSC (4039 FR5)", TEMIC, NTSC,
@@ -155,7 +154,6 @@ static struct tunertype tuners[] = {
16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
{ "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-
{ "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
{ "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
@@ -164,25 +162,24 @@ static struct tunertype tuners[] = {
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
{ "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
-
{ "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
{ "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
+
+ /* 30-39 */
{ "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
{ "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
-
- { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
+ { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
16*169,16*464,0xA0,0x90,0x30,0x8e,623},
- { "MT20xx universal", Microtune,PAL|NTSC,
+ { "MT20xx universal", Microtune, PAL|NTSC,
/* see mt20xx.c for details */ },
{ "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
{ "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
-
{ "Temic NTSC (4136 FY5)", TEMIC, NTSC,
16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
{ "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
@@ -192,42 +189,41 @@ static struct tunertype tuners[] = {
{ "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
+ /* 40-49 */
{ "HITACHI V7-J180AT", HITACHI, NTSC,
16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 },
{ "Philips PAL_MK (FI1216 MK)", Philips, PAL,
16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
- { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC,
+ { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
{ "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
-
{ "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
- { "Microtune 4049 FM5",Microtune,PAL,
+ { "Microtune 4049 FM5", Microtune, PAL,
16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
{ "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
{ "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
-
{ "Tenna TNF 8831 BGFF)", Philips, PAL,
16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
{ "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
+
+ /* 50-59 */
{ "TCL 2002N", TCL, NTSC,
16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
{ "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
-
{ "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
{ "Philips FQ1286", Philips, NTSC,
- 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested
- { "tda8290+75", Philips,PAL|NTSC,
+ 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
+ { "tda8290+75", Philips, PAL|NTSC,
/* see tda8290.c for details */ },
{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
-
{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
{ "Philips FQ1236A MK4", Philips, NTSC,
@@ -237,6 +233,7 @@ static struct tunertype tuners[] = {
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+ /* 60-66 */
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
@@ -245,12 +242,12 @@ static struct tunertype tuners[] = {
/* see tea5767.c for details */},
{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
-
- { "LG TDVS-H062F/TUA6034", LGINNOTEK, NTSC,
+ { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
-
{ "Ymec TVF66T5-B/DFF", Philips, PAL,
16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
+ { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
+ 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -471,6 +468,10 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
case TUNER_LG_PAL_FM:
buffer[3] = 0xa5;
break;
+ case TUNER_MICROTUNE_4049FM5:
+ div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
+ buffer[3] = 0xa4;
+ break;
default:
buffer[3] = 0xa4;
break;
@@ -497,6 +498,7 @@ int default_tuner_init(struct i2c_client *c)
t->radio_freq = default_set_radio_freq;
t->has_signal = tuner_signal;
t->is_stereo = tuner_stereo;
+ t->standby = NULL;
return 0;
}
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 258724b2d6d..1c31ef52f86 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");
MODULE_LICENSE("GPL");
#define UNSET (-1U)
-#define dprintk if (debug) printk
+
+#define tvaudio_info(fmt, arg...) do {\
+ printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
+ chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
+#define tvaudio_warn(fmt, arg...) do {\
+ printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \
+ chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
+#define tvaudio_dbg(fmt, arg...) do {\
+ if (debug) \
+ printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
+ chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
/* ---------------------------------------------------------------------- */
/* our structs */
@@ -162,23 +172,24 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
unsigned char buffer[2];
if (-1 == subaddr) {
- dprintk("%s: chip_write: 0x%x\n", chip->c.name, val);
+ tvaudio_dbg("%s: chip_write: 0x%x\n",
+ chip->c.name, val);
chip->shadow.bytes[1] = val;
buffer[0] = val;
if (1 != i2c_master_send(&chip->c,buffer,1)) {
- printk(KERN_WARNING "%s: I/O error (write 0x%x)\n",
- chip->c.name, val);
+ tvaudio_warn("%s: I/O error (write 0x%x)\n",
+ chip->c.name, val);
return -1;
}
} else {
- dprintk("%s: chip_write: reg%d=0x%x\n",
+ tvaudio_dbg("%s: chip_write: reg%d=0x%x\n",
chip->c.name, subaddr, val);
chip->shadow.bytes[subaddr+1] = val;
buffer[0] = subaddr;
buffer[1] = val;
if (2 != i2c_master_send(&chip->c,buffer,2)) {
- printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n",
- chip->c.name, subaddr, val);
+ tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n",
+ chip->c.name, subaddr, val);
return -1;
}
}
@@ -202,29 +213,30 @@ static int chip_read(struct CHIPSTATE *chip)
unsigned char buffer;
if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
- printk(KERN_WARNING "%s: I/O error (read)\n", chip->c.name);
+ tvaudio_warn("%s: I/O error (read)\n",
+ chip->c.name);
return -1;
}
- dprintk("%s: chip_read: 0x%x\n", chip->c.name, buffer);
+ tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name,buffer);
return buffer;
}
static int chip_read2(struct CHIPSTATE *chip, int subaddr)
{
- unsigned char write[1];
- unsigned char read[1];
- struct i2c_msg msgs[2] = {
- { chip->c.addr, 0, 1, write },
- { chip->c.addr, I2C_M_RD, 1, read }
- };
- write[0] = subaddr;
+ unsigned char write[1];
+ unsigned char read[1];
+ struct i2c_msg msgs[2] = {
+ { chip->c.addr, 0, 1, write },
+ { chip->c.addr, I2C_M_RD, 1, read }
+ };
+ write[0] = subaddr;
if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
- printk(KERN_WARNING "%s: I/O error (read2)\n", chip->c.name);
+ tvaudio_warn("%s: I/O error (read2)\n", chip->c.name);
return -1;
}
- dprintk("%s: chip_read2: reg%d=0x%x\n",
- chip->c.name, subaddr, read[0]);
+ tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n",
+ chip->c.name,subaddr,read[0]);
return read[0];
}
@@ -236,17 +248,19 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
return 0;
/* update our shadow register set; print bytes if (debug > 0) */
- dprintk("%s: chip_cmd(%s): reg=%d, data:",
- chip->c.name, name, cmd->bytes[0]);
+ tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:",
+ chip->c.name,name,cmd->bytes[0]);
for (i = 1; i < cmd->count; i++) {
- dprintk(" 0x%x",cmd->bytes[i]);
+ if (debug)
+ printk(" 0x%x",cmd->bytes[i]);
chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
}
- dprintk("\n");
+ if (debug)
+ printk("\n");
/* send data to the chip */
if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
- printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.name, name);
+ tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name);
return -1;
}
return 0;
@@ -261,19 +275,19 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
static void chip_thread_wake(unsigned long data)
{
- struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
+ struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
wake_up_interruptible(&chip->wq);
}
static int chip_thread(void *data)
{
DECLARE_WAITQUEUE(wait, current);
- struct CHIPSTATE *chip = data;
+ struct CHIPSTATE *chip = data;
struct CHIPDESC *desc = chiplist + chip->type;
daemonize("%s", chip->c.name);
allow_signal(SIGTERM);
- dprintk("%s: thread started\n", chip->c.name);
+ tvaudio_dbg("%s: thread started\n", chip->c.name);
for (;;) {
add_wait_queue(&chip->wq, &wait);
@@ -285,7 +299,7 @@ static int chip_thread(void *data)
try_to_freeze();
if (chip->done || signal_pending(current))
break;
- dprintk("%s: thread wakeup\n", chip->c.name);
+ tvaudio_dbg("%s: thread wakeup\n", chip->c.name);
/* don't do anything for radio or if mode != auto */
if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
@@ -298,8 +312,8 @@ static int chip_thread(void *data)
mod_timer(&chip->wt, jiffies+2*HZ);
}
- dprintk("%s: thread exiting\n", chip->c.name);
- complete_and_exit(&chip->texit, 0);
+ tvaudio_dbg("%s: thread exiting\n", chip->c.name);
+ complete_and_exit(&chip->texit, 0);
return 0;
}
@@ -309,9 +323,9 @@ static void generic_checkmode(struct CHIPSTATE *chip)
int mode = desc->getmode(chip);
if (mode == chip->prevmode)
- return;
+ return;
- dprintk("%s: thread checkmode\n", chip->c.name);
+ tvaudio_dbg("%s: thread checkmode\n", chip->c.name);
chip->prevmode = mode;
if (mode & VIDEO_SOUND_STEREO)
@@ -358,8 +372,8 @@ static int tda9840_getmode(struct CHIPSTATE *chip)
if (val & TDA9840_ST_STEREO)
mode |= VIDEO_SOUND_STEREO;
- dprintk ("tda9840_getmode(): raw chip read: %d, return: %d\n",
- val, mode);
+ tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n",
+ val, mode);
return mode;
}
@@ -654,8 +668,8 @@ static int tda9873_getmode(struct CHIPSTATE *chip)
mode |= VIDEO_SOUND_STEREO;
if (val & TDA9873_DUAL)
mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
- dprintk ("tda9873_getmode(): raw chip read: %d, return: %d\n",
- val, mode);
+ tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n",
+ val, mode);
return mode;
}
@@ -665,12 +679,12 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
/* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
- dprintk("tda9873_setmode(): external input\n");
+ tvaudio_dbg("tda9873_setmode(): external input\n");
return;
}
- dprintk("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
- dprintk("tda9873_setmode(): sw_data = %d\n", sw_data);
+ tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
+ tvaudio_dbg("tda9873_setmode(): sw_data = %d\n", sw_data);
switch (mode) {
case VIDEO_SOUND_MONO:
@@ -691,7 +705,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
}
chip_write(chip, TDA9873_SW, sw_data);
- dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
+ tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n",
mode, sw_data);
}
@@ -828,9 +842,9 @@ static int tda9874a_setup(struct CHIPSTATE *chip)
} else { /* dic == 0x07 */
chip_write(chip, TDA9874A_AMCONR, 0xfb);
chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
- chip_write(chip, TDA9874A_AOSR, 0x00); // or 0x10
+ chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
}
- dprintk("tda9874a_setup(): %s [0x%02X].\n",
+ tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n",
tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
return 1;
}
@@ -873,7 +887,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip)
mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
}
- dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
+ tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
dsr, nsr, necr, mode);
return mode;
}
@@ -919,7 +933,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
chip_write(chip, TDA9874A_AOSR, aosr);
chip_write(chip, TDA9874A_MDACOSR, mdacosr);
- dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
+ tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
mode, aosr, mdacosr);
} else { /* dic == 0x07 */
@@ -954,7 +968,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
chip_write(chip, TDA9874A_FMMR, fmmr);
chip_write(chip, TDA9874A_AOSR, aosr);
- dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
+ tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
mode, fmmr, aosr);
}
}
@@ -968,10 +982,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip)
if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
return 0;
- dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
+ tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
if((dic == 0x11)||(dic == 0x07)) {
- printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h");
+ tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h");
tda9874a_dic = dic; /* remember device id. */
return 1;
}
@@ -1146,7 +1160,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for TA8874Z */
-// write 1st byte
+/* write 1st byte */
#define TA8874Z_LED_STE 0x80
#define TA8874Z_LED_BIL 0x40
#define TA8874Z_LED_EXT 0x20
@@ -1156,21 +1170,22 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
#define TA8874Z_MODE_SUB 0x02
#define TA8874Z_MODE_MAIN 0x01
-// write 2nd byte
-//#define TA8874Z_TI 0x80 // test mode
+/* write 2nd byte */
+/*#define TA8874Z_TI 0x80 */ /* test mode */
#define TA8874Z_SEPARATION 0x3f
#define TA8874Z_SEPARATION_DEFAULT 0x10
-// read
+/* read */
#define TA8874Z_B1 0x80
#define TA8874Z_B0 0x40
#define TA8874Z_CHAG_FLAG 0x20
-// B1 B0
-// mono L H
-// stereo L L
-// BIL H L
-
+/*
+ * B1 B0
+ * mono L H
+ * stereo L L
+ * BIL H L
+ */
static int ta8874z_getmode(struct CHIPSTATE *chip)
{
int val, mode;
@@ -1182,7 +1197,7 @@ static int ta8874z_getmode(struct CHIPSTATE *chip)
}else if (!(val & TA8874Z_B0)){
mode |= VIDEO_SOUND_STEREO;
}
- //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode);
+ /* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */
return mode;
}
@@ -1195,7 +1210,7 @@ static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
{
int update = 1;
audiocmd *t = NULL;
- dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode);
+ tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode);
switch(mode){
case VIDEO_SOUND_MONO:
@@ -1235,11 +1250,11 @@ static int tda9850 = 1;
static int tda9855 = 1;
static int tda9873 = 1;
static int tda9874a = 1;
-static int tea6300 = 0; // address clash with msp34xx
-static int tea6320 = 0; // address clash with msp34xx
+static int tea6300 = 0; /* address clash with msp34xx */
+static int tea6320 = 0; /* address clash with msp34xx */
static int tea6420 = 1;
static int pic16c54 = 1;
-static int ta8874z = 0; // address clash with tda9840
+static int ta8874z = 0; /* address clash with tda9840 */
module_param(tda8425, int, 0444);
module_param(tda9840, int, 0444);
@@ -1441,7 +1456,7 @@ static struct CHIPDESC chiplist[] = {
{
.name = "ta8874z",
.id = -1,
- //.id = I2C_DRIVERID_TA8874Z,
+ /*.id = I2C_DRIVERID_TA8874Z, */
.checkit = ta8874z_checkit,
.insmodopt = &ta8874z,
.addr_lo = I2C_TDA9840 >> 1,
@@ -1476,7 +1491,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
i2c_set_clientdata(&chip->c, chip);
/* find description for the chip */
- dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1);
+ tvaudio_dbg("chip found @ 0x%x\n", addr<<1);
for (desc = chiplist; desc->name != NULL; desc++) {
if (0 == *(desc->insmodopt))
continue;
@@ -1488,17 +1503,19 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
break;
}
if (desc->name == NULL) {
- dprintk("tvaudio: no matching chip description found\n");
+ tvaudio_dbg("no matching chip description found\n");
return -EIO;
}
- printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1);
- dprintk("tvaudio: matches:%s%s%s.\n",
- (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
- (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
- (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
+ tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
+ if (desc->flags) {
+ tvaudio_dbg("matches:%s%s%s.\n",
+ (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
+ (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
+ (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
+ }
/* fill required data structures */
- strcpy(chip->c.name, desc->name);
+ strcpy(chip->c.name,desc->name);
chip->type = desc-chiplist;
chip->shadow.count = desc->registers+1;
chip->prevmode = -1;
@@ -1534,7 +1551,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
init_completion(&chip->texit);
chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
if (chip->tpid < 0)
- printk(KERN_WARNING "%s: kernel_thread() failed\n",
+ tvaudio_warn("%s: kernel_thread() failed\n",
chip->c.name);
wake_up_interruptible(&chip->wq);
}
@@ -1545,7 +1562,7 @@ static int chip_probe(struct i2c_adapter *adap)
{
/* don't attach on saa7146 based cards,
because dedicated drivers are used */
- if (adap->id == I2C_HW_SAA7146)
+ if ((adap->id == I2C_HW_SAA7146))
return 0;
#ifdef I2C_CLASS_TV_ANALOG
if (adap->class & I2C_CLASS_TV_ANALOG)
@@ -1584,11 +1601,11 @@ static int chip_detach(struct i2c_client *client)
static int chip_command(struct i2c_client *client,
unsigned int cmd, void *arg)
{
- __u16 *sarg = arg;
+ __u16 *sarg = arg;
struct CHIPSTATE *chip = i2c_get_clientdata(client);
struct CHIPDESC *desc = chiplist + chip->type;
- dprintk("%s: chip_command 0x%x\n", chip->c.name, cmd);
+ tvaudio_dbg("%s: chip_command 0x%x\n",chip->c.name,cmd);
switch (cmd) {
case AUDC_SET_INPUT:
@@ -1601,7 +1618,6 @@ static int chip_command(struct i2c_client *client,
break;
case AUDC_SET_RADIO:
- dprintk(KERN_DEBUG "tvaudio: AUDC_SET_RADIO\n");
chip->norm = VIDEO_MODE_RADIO;
chip->watch_stereo = 0;
/* del_timer(&chip->wt); */
@@ -1609,7 +1625,7 @@ static int chip_command(struct i2c_client *client,
/* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
+ kernel pointer here... */
case VIDIOCGAUDIO:
{
struct video_audio *va = arg;
@@ -1643,9 +1659,9 @@ static int chip_command(struct i2c_client *client,
if (desc->flags & CHIP_HAS_VOLUME) {
chip->left = (min(65536 - va->balance,32768) *
- va->volume) / 32768;
+ va->volume) / 32768;
chip->right = (min(va->balance,(__u16)32768) *
- va->volume) / 32768;
+ va->volume) / 32768;
chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
}
@@ -1667,17 +1683,16 @@ static int chip_command(struct i2c_client *client,
{
struct video_channel *vc = arg;
- dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n");
chip->norm = vc->norm;
break;
}
case VIDIOCSFREQ:
{
- chip->mode = 0; /* automatic */
+ chip->mode = 0; /* automatic */
if (desc->checkmode) {
desc->setmode(chip,VIDEO_SOUND_MONO);
- if (chip->prevmode != VIDEO_SOUND_MONO)
- chip->prevmode = -1; /* reset previous mode */
+ if (chip->prevmode != VIDEO_SOUND_MONO)
+ chip->prevmode = -1; /* reset previous mode */
mod_timer(&chip->wt, jiffies+2*HZ);
/* the thread will call checkmode() later */
}
@@ -1689,29 +1704,32 @@ static int chip_command(struct i2c_client *client,
static struct i2c_driver driver = {
.owner = THIS_MODULE,
- .name = "generic i2c audio driver",
- .id = I2C_DRIVERID_TVAUDIO,
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = chip_probe,
- .detach_client = chip_detach,
- .command = chip_command,
+ .name = "generic i2c audio driver",
+ .id = I2C_DRIVERID_TVAUDIO,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = chip_probe,
+ .detach_client = chip_detach,
+ .command = chip_command,
};
static struct i2c_client client_template =
{
.name = "(unset)",
.flags = I2C_CLIENT_ALLOW_USE,
- .driver = &driver,
+ .driver = &driver,
};
static int __init audiochip_init_module(void)
{
struct CHIPDESC *desc;
- printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
- printk(KERN_INFO "tvaudio: known chips: ");
- for (desc = chiplist; desc->name != NULL; desc++)
- printk("%s%s", (desc == chiplist) ? "" : ",",desc->name);
- printk("\n");
+
+ if (debug) {
+ printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
+ printk(KERN_INFO "tvaudio: known chips: ");
+ for (desc = chiplist; desc->name != NULL; desc++)
+ printk("%s%s", (desc == chiplist) ? "" : ", ", desc->name);
+ printk("\n");
+ }
return i2c_add_driver(&driver);
}
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3c3356a01cc..5344d559219 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -47,18 +47,21 @@ MODULE_LICENSE("GPL");
static int debug = 0;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-2)");
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
-#define dprintk(num, args...) \
- do { \
- if (debug >= num) \
- printk(KERN_INFO "tveeprom: " args); \
- } while (0)
+#define tveeprom_info(fmt, arg...) do {\
+ printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
+ c->adapter->nr, c->addr , ##arg); } while (0)
+#define tveeprom_warn(fmt, arg...) do {\
+ printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
+ c->adapter->nr, c->addr , ##arg); } while (0)
+#define tveeprom_dbg(fmt, arg...) do {\
+ if (debug) \
+ printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
+ c->adapter->nr, c->addr , ##arg); } while (0)
-#define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
-#define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
/* ----------------------------------------------------------------------- */
/* some hauppauge specific stuff */
@@ -70,14 +73,14 @@ static struct HAUPPAUGE_TUNER_FMT
}
hauppauge_tuner_fmt[] =
{
- { 0x00000000, "unknown1" },
- { 0x00000000, "unknown2" },
- { 0x00000007, "PAL(B/G)" },
- { 0x00001000, "NTSC(M)" },
- { 0x00000010, "PAL(I)" },
- { 0x00400000, "SECAM(L/L´)" },
- { 0x00000e00, "PAL(D/K)" },
- { 0x03000000, "ATSC Digital" },
+ { 0x00000000, " unknown1" },
+ { 0x00000000, " unknown2" },
+ { 0x00000007, " PAL(B/G)" },
+ { 0x00001000, " NTSC(M)" },
+ { 0x00000010, " PAL(I)" },
+ { 0x00400000, " SECAM(L/L')" },
+ { 0x00000e00, " PAL(D/K)" },
+ { 0x03000000, " ATSC Digital" },
};
/* This is the full list of possible tuners. Many thanks to Hauppauge for
@@ -152,13 +155,13 @@ hauppauge_tuner[] =
{ TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
{ TUNER_ABSENT, "LG TPI8NSR11F"},
{ TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
- { TUNER_ABSENT, "Philips FQ1216ME MK3"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
{ TUNER_ABSENT, "Philips FI1236 MK3"},
{ TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
- { TUNER_ABSENT, "Philips FM1236 MK3"},
+ { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
{ TUNER_ABSENT, "Philips FM1216MP MK3"},
/* 60-69 */
- { TUNER_ABSENT, "LG S001D MK3"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
{ TUNER_ABSENT, "LG M001D MK3"},
{ TUNER_ABSENT, "LG S701D MK3"},
{ TUNER_ABSENT, "LG M701D MK3"},
@@ -167,7 +170,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Temic 4106FH5"},
{ TUNER_ABSENT, "Philips FQ1216LMP MK3"},
{ TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
- { TUNER_ABSENT, "LG TAPE H701F MK3"},
+ { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"},
/* 70-79 */
{ TUNER_ABSENT, "LG TALN H200T"},
{ TUNER_ABSENT, "LG TALN H250T"},
@@ -183,8 +186,8 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Philips FQ1216LME MK3"},
{ TUNER_ABSENT, "LG TAPC G701D"},
{ TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
- { TUNER_ABSENT, "TCL 2002MB 3"},
- { TUNER_ABSENT, "TCL 2002MI 3"},
+ { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
+ { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
{ TUNER_TCL_2002N, "TCL 2002N 6A"},
{ TUNER_ABSENT, "Philips FQ1236 MK3"},
{ TUNER_ABSENT, "Samsung TCPN 2121P30A"},
@@ -199,17 +202,51 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Philips FQ1236 MK5"},
{ TUNER_ABSENT, "Unspecified"},
{ TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"},
+ { TUNER_ABSENT, "Unspecified"},
+ { TUNER_TCL_2002N, "TCL 2002N 5H"},
+ /* 100-103 */
+ { TUNER_ABSENT, "Unspecified"},
+ { TUNER_TEA5767, "Philips TEA5767HN FM Radio"},
+ { TUNER_ABSENT, "Unspecified"},
+ { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"},
};
-static char *sndtype[] = {
- "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D",
- "MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440",
- "MSP3445", "MSP3411", "MSP3416", "MSP3425",
+/* This list is supplied by Hauppauge. Thanks! */
+static const char *audioIC[] = {
+ /* 0-4 */
+ "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C",
+ /* 5-9 */
+ "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331",
+ /* 10-14 */
+ "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416",
+ /* 15-19 */
+ "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716",
+ /* 20-24 */
+ "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408",
+ /* 25-29 */
+ "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d",
+ /* 30-34 */
+ "CX880", "CX881", "CX883", "CX882", "CX25840",
+ /* 35-38 */
+ "CX25841", "CX25842", "CX25843", "CX23418",
+};
- "Type 0x10","Type 0x11","Type 0x12","Type 0x13",
- "Type 0x14","Type 0x15","Type 0x16","Type 0x17",
- "Type 0x18","MSP4418","Type 0x1a","MSP4448",
- "Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f",
+/* This list is supplied by Hauppauge. Thanks! */
+static const char *decoderIC[] = {
+ /* 0-4 */
+ "None", "BT815", "BT817", "BT819", "BT815A",
+ /* 5-9 */
+ "BT817A", "BT819A", "BT827", "BT829", "BT848",
+ /* 10-14 */
+ "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
+ /* 15-19 */
+ "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
+ /* 20-24 */
+ "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
+ /* 25-29 */
+ "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
+ /* 30-31 */
+ "CX25843", "CX23418",
};
static int hasRadioTuner(int tunerType)
@@ -250,7 +287,8 @@ static int hasRadioTuner(int tunerType)
return 0;
}
-void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data)
+void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
+ unsigned char *eeprom_data)
{
/* ----------------------------------------------
** The hauppauge eeprom format is tagged
@@ -260,10 +298,11 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
**
** In our (ivtv) case we're interested in the following:
- ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
- ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
- ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
- ** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?)
+ ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
+ ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
+ ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
+ ** audio proc: tag [02].01 or [05].00 (mask with 0x7f)
+ ** decoder proc: tag [09].01)
** Fun info:
** model: tag [00].07-08 or [06].00-01
@@ -273,20 +312,24 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
** # of inputs/outputs ???
*/
- int i, j, len, done, beenhere, tag, tuner = 0, t_format = 0;
- char *t_name = NULL, *t_fmt_name = NULL;
+ int i, j, len, done, beenhere, tag;
- dprintk(1, "%s\n",__FUNCTION__);
- tvee->revision = done = len = beenhere = 0;
- for (i = 0; !done && i < 256; i += len) {
- dprintk(2, "processing pos = %02x (%02x, %02x)\n",
- i, eeprom_data[i], eeprom_data[i + 1]);
+ int tuner1 = 0, t_format1 = 0;
+ char *t_name1 = NULL;
+ const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
+ int tuner2 = 0, t_format2 = 0;
+ char *t_name2 = NULL;
+ const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
+
+ memset(tvee, 0, sizeof(*tvee));
+ done = len = beenhere = 0;
+ for (i = 0; !done && i < 256; i += len) {
if (eeprom_data[i] == 0x84) {
len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
- i+=3;
+ i += 3;
} else if ((eeprom_data[i] & 0xf0) == 0x70) {
- if ((eeprom_data[i] & 0x08)) {
+ if (eeprom_data[i] & 0x08) {
/* verify checksum! */
done = 1;
break;
@@ -294,24 +337,30 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
len = eeprom_data[i] & 0x07;
++i;
} else {
- TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "
+ tveeprom_warn("Encountered bad packet header [%02x]. "
"Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
return;
}
- dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);
- for(j = 1; j < len; j++) {
- dprintk(1, "%02x ", eeprom_data[i + j]);
- }
- dprintk(1, "\n");
+ if (debug) {
+ tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
+ for(j = 1; j < len; j++) {
+ printk(" %02x", eeprom_data[i + j]);
+ }
+ printk("\n");
+ }
/* process by tag */
tag = eeprom_data[i];
switch (tag) {
case 0x00:
- tuner = eeprom_data[i+6];
- t_format = eeprom_data[i+5];
+ /* tag: 'Comprehensive' */
+ tuner1 = eeprom_data[i+6];
+ t_format1 = eeprom_data[i+5];
tvee->has_radio = eeprom_data[i+len-1];
+ /* old style tag, don't know how to detect
+ IR presence, mark as unknown. */
+ tvee->has_ir = 2;
tvee->model =
eeprom_data[i+8] +
(eeprom_data[i+9] << 8);
@@ -319,25 +368,43 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
(eeprom_data[i+11] << 8) +
(eeprom_data[i+12] << 16);
break;
+
case 0x01:
+ /* tag: 'SerialID' */
tvee->serial_number =
eeprom_data[i+6] +
(eeprom_data[i+7] << 8) +
(eeprom_data[i+8] << 16);
break;
+
case 0x02:
- tvee->audio_processor = eeprom_data[i+2] & 0x0f;
+ /* tag 'AudioInfo'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ tvee->audio_processor = eeprom_data[i+2] & 0x7f;
break;
+
+ /* case 0x03: tag 'EEInfo' */
+
case 0x04:
+ /* tag 'SerialID2' */
tvee->serial_number =
eeprom_data[i+5] +
(eeprom_data[i+6] << 8) +
(eeprom_data[i+7] << 16);
break;
+
case 0x05:
- tvee->audio_processor = eeprom_data[i+1] & 0x0f;
+ /* tag 'Audio2'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ tvee->audio_processor = eeprom_data[i+1] & 0x7f;
break;
+
case 0x06:
+ /* tag 'ModelRev' */
tvee->model =
eeprom_data[i+1] +
(eeprom_data[i+2] << 8);
@@ -345,27 +412,66 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
(eeprom_data[i+6] << 8) +
(eeprom_data[i+7] << 16);
break;
+
+ case 0x07:
+ /* tag 'Details': according to Hauppauge not interesting
+ on any PCI-era or later boards. */
+ break;
+
+ /* there is no tag 0x08 defined */
+
+ case 0x09:
+ /* tag 'Video' */
+ tvee->decoder_processor = eeprom_data[i + 1];
+ break;
+
case 0x0a:
- if(beenhere == 0) {
- tuner = eeprom_data[i+2];
- t_format = eeprom_data[i+1];
+ /* tag 'Tuner' */
+ if (beenhere == 0) {
+ tuner1 = eeprom_data[i+2];
+ t_format1 = eeprom_data[i+1];
beenhere = 1;
- break;
} else {
- break;
- }
+ /* a second (radio) tuner may be present */
+ tuner2 = eeprom_data[i+2];
+ t_format2 = eeprom_data[i+1];
+ if (t_format2 == 0) { /* not a TV tuner? */
+ tvee->has_radio = 1; /* must be radio */
+ }
+ }
+ break;
+
+ case 0x0b:
+ /* tag 'Inputs': according to Hauppauge this is specific
+ to each driver family, so no good assumptions can be
+ made. */
+ break;
+
+ /* case 0x0c: tag 'Balun' */
+ /* case 0x0d: tag 'Teletext' */
+
case 0x0e:
+ /* tag: 'Radio' */
tvee->has_radio = eeprom_data[i+1];
break;
+
+ case 0x0f:
+ /* tag 'IRInfo' */
+ tvee->has_ir = eeprom_data[i+1];
+ break;
+
+ /* case 0x10: tag 'VBIInfo' */
+ /* case 0x11: tag 'QCInfo' */
+ /* case 0x12: tag 'InfoBits' */
+
default:
- dprintk(1, "Not sure what to do with tag [%02x]\n", tag);
+ tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
/* dump the rest of the packet? */
}
-
}
if (!done) {
- TVEEPROM_KERN_ERR("Ran out of data!\n");
+ tveeprom_warn("Ran out of data!\n");
return;
}
@@ -377,47 +483,72 @@ void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data
tvee->rev_str[4] = 0;
}
- if (hasRadioTuner(tuner) && !tvee->has_radio) {
- TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");
- TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");
+ if (hasRadioTuner(tuner1) && !tvee->has_radio) {
+ tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
+ tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
tvee->has_radio = 1;
}
- if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
- tvee->tuner_type = hauppauge_tuner[tuner].id;
- t_name = hauppauge_tuner[tuner].name;
+ if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
+ tvee->tuner_type = hauppauge_tuner[tuner1].id;
+ t_name1 = hauppauge_tuner[tuner1].name;
} else {
- t_name = "<unknown>";
+ t_name1 = "unknown";
+ }
+
+ if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
+ tvee->tuner2_type = hauppauge_tuner[tuner2].id;
+ t_name2 = hauppauge_tuner[tuner2].name;
+ } else {
+ t_name2 = "unknown";
}
tvee->tuner_formats = 0;
- t_fmt_name = "<none>";
- for (i = 0; i < 8; i++) {
- if (t_format & (1<<i)) {
+ tvee->tuner2_formats = 0;
+ for (i = j = 0; i < 8; i++) {
+ if (t_format1 & (1 << i)) {
tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
- /* yuck */
- t_fmt_name = hauppauge_tuner_fmt[i].name;
+ t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
}
+ if (t_format2 & (1 << i)) {
+ tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
+ t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
+ }
}
-
- TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
- tvee->model,
- tvee->rev_str,
- tvee->serial_number);
- TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",
- t_name,
- tuner,
- tvee->tuner_type);
- TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",
- t_fmt_name,
- t_format,
- tvee->tuner_formats);
-
- TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",
- STRM(sndtype,tvee->audio_processor),
+ tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
+ tvee->model, tvee->rev_str, tvee->serial_number);
+ tveeprom_info("tuner model is %s (idx %d, type %d)\n",
+ t_name1, tuner1, tvee->tuner_type);
+ tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
+ t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
+ t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
+ t_format1);
+ if (tuner2) {
+ tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
+ t_name2, tuner2, tvee->tuner2_type);
+ }
+ if (t_format2) {
+ tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
+ t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
+ t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
+ t_format2);
+ }
+ tveeprom_info("audio processor is %s (idx %d)\n",
+ STRM(audioIC, tvee->audio_processor),
tvee->audio_processor);
-
+ if (tvee->decoder_processor) {
+ tveeprom_info("decoder processor is %s (idx %d)\n",
+ STRM(decoderIC, tvee->decoder_processor),
+ tvee->decoder_processor);
+ }
+ if (tvee->has_ir == 2)
+ tveeprom_info("has %sradio\n",
+ tvee->has_radio ? "" : "no ");
+ else
+ tveeprom_info("has %sradio, has %sIR remote\n",
+ tvee->has_radio ? "" : "no ",
+ tvee->has_ir ? "" : "no ");
}
EXPORT_SYMBOL(tveeprom_hauppauge_analog);
@@ -429,40 +560,31 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
unsigned char buf;
int err;
- dprintk(1, "%s\n",__FUNCTION__);
buf = 0;
- if (1 != (err = i2c_master_send(c,&buf,1))) {
- printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",
- c->name,err);
+ if (1 != (err = i2c_master_send(c, &buf, 1))) {
+ tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
return -1;
}
- if (len != (err = i2c_master_recv(c,eedata,len))) {
- printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",
- c->name,err);
+ if (len != (err = i2c_master_recv(c, eedata, len))) {
+ tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
return -1;
}
+ if (debug) {
+ int i;
+
+ tveeprom_info("full 256-byte eeprom dump:\n");
+ for (i = 0; i < len; i++) {
+ if (0 == (i % 16))
+ tveeprom_info("%02x:", i);
+ printk(" %02x", eedata[i]);
+ if (15 == (i % 16))
+ printk("\n");
+ }
+ }
return 0;
}
EXPORT_SYMBOL(tveeprom_read);
-#if 0
-int tveeprom_dump(unsigned char *eedata, int len)
-{
- int i;
-
- dprintk(1, "%s\n",__FUNCTION__);
- for (i = 0; i < len; i++) {
- if (0 == (i % 16))
- printk(KERN_INFO "tveeprom: %02x:",i);
- printk(" %02x",eedata[i]);
- if (15 == (i % 16))
- printk("\n");
- }
- return 0;
-}
-EXPORT_SYMBOL(tveeprom_dump);
-#endif /* 0 */
-
/* ----------------------------------------------------------------------- */
/* needed for ivtv.sf.net at the moment. Should go away in the long */
/* run, just call the exported tveeprom_* directly, there is no point in */
@@ -495,12 +617,13 @@ tveeprom_command(struct i2c_client *client,
buf = kmalloc(256,GFP_KERNEL);
memset(buf,0,256);
tveeprom_read(client,buf,256);
- tveeprom_hauppauge_analog(&eeprom,buf);
+ tveeprom_hauppauge_analog(client, &eeprom,buf);
kfree(buf);
eeprom_props[0] = eeprom.tuner_type;
eeprom_props[1] = eeprom.tuner_formats;
eeprom_props[2] = eeprom.model;
eeprom_props[3] = eeprom.revision;
+ eeprom_props[4] = eeprom.has_radio;
break;
default:
return -EINVAL;
@@ -515,8 +638,6 @@ tveeprom_detect_client(struct i2c_adapter *adapter,
{
struct i2c_client *client;
- dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
- adapter->id, address << 1);
client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (NULL == client)
return -ENOMEM;
@@ -533,7 +654,6 @@ tveeprom_detect_client(struct i2c_adapter *adapter,
static int
tveeprom_attach_adapter (struct i2c_adapter *adapter)
{
- dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
if (adapter->id != I2C_HW_B_BT848)
return 0;
return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index a43301a154a..d86e08ebddf 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -1,5 +1,4 @@
/*
- * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $
*/
#include <linux/module.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 70ecbdb8027..59bb71381a1 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1,5 +1,4 @@
/*
- * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $
*
* Video for Linux Two
* Backward Compatibility Layer
@@ -604,9 +603,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
break;
}
-#if 0 /* FIXME */
- pict->depth = fmt2->fmt.pix.depth;
-#endif
pict->palette = pixelformat_to_palette(
fmt2->fmt.pix.pixelformat);
break;
@@ -707,13 +703,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
}
case VIDIOCSTUNER: /* select a tuner input */
{
-#if 0 /* FIXME */
- err = drv(inode, file, VIDIOC_S_INPUT, &i);
- if (err < 0)
- dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
-#else
err = 0;
-#endif
break;
}
case VIDIOCGFREQ: /* get frequency */
@@ -852,12 +842,6 @@ v4l_compat_translate_ioctl(struct inode *inode,
err = 0;
break;
}
-#if 0
- case VIDIOCGMBUF:
- /* v4l2 drivers must implement that themself. The
- mmap() differences can't be translated fully
- transparent, thus there is no point to try that */
-#endif
case VIDIOCMCAPTURE: /* capture a frame */
{
struct video_mmap *mm = arg;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b5e0cf3448f..597b8db35a1 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -84,20 +84,6 @@ MODULE_LICENSE("GPL");
* Video Standard Operations (contributed by Michael Schimek)
*/
-#if 0 /* seems to have no users */
-/* This is the recommended method to deal with the framerate fields. More
- sophisticated drivers will access the fields directly. */
-unsigned int
-v4l2_video_std_fps(struct v4l2_standard *vs)
-{
- if (vs->frameperiod.numerator > 0)
- return (((vs->frameperiod.denominator << 8) /
- vs->frameperiod.numerator) +
- (1 << 7)) / (1 << 8);
- return 0;
-}
-EXPORT_SYMBOL(v4l2_video_std_fps);
-#endif
/* Fill in the fields of a v4l2_standard structure according to the
'id' and 'transmission' parameters. Returns negative on error. */
@@ -213,10 +199,6 @@ char *v4l2_ioctl_names[256] = {
[_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
[_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
[_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
-#if 0
- [_IOC_NR(VIDIOC_G_COMP)] = "VIDIOC_G_COMP",
- [_IOC_NR(VIDIOC_S_COMP)] = "VIDIOC_S_COMP",
-#endif
[_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
[_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
[_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 15f5bb48696..55f129e964e 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -1,5 +1,4 @@
/*
- * $Id: video-buf-dvb.c,v 1.7 2004/12/09 12:51:35 kraxel Exp $
*
* some helper function for simple DVB cards which simply DMA the
* 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 5afdc785261..97354f253a8 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -1,5 +1,4 @@
/*
- * $Id: video-buf.c,v 1.18 2005/02/24 13:32:30 kraxel Exp $
*
* generic helper functions for video4linux capture buffers, to handle
* memory management and PCI DMA. Right now bttv + saa7134 use it.
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0a117c61cd1..ceae379a4d4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1079,13 +1079,17 @@ static void mmc_setup(struct mmc_host *host)
/**
* mmc_detect_change - process change of state on a MMC socket
* @host: host which changed state.
+ * @delay: optional delay to wait before detection (jiffies)
*
* All we know is that card(s) have been inserted or removed
* from the socket(s). We don't know which socket or cards.
*/
-void mmc_detect_change(struct mmc_host *host)
+void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
- schedule_work(&host->detect);
+ if (delay)
+ schedule_delayed_work(&host->detect, delay);
+ else
+ schedule_work(&host->detect);
}
EXPORT_SYMBOL(mmc_detect_change);
@@ -1189,7 +1193,7 @@ int mmc_add_host(struct mmc_host *host)
ret = mmc_add_host_sysfs(host);
if (ret == 0) {
mmc_power_off(host);
- mmc_detect_change(host);
+ mmc_detect_change(host, 0);
}
return ret;
@@ -1259,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
*/
int mmc_resume_host(struct mmc_host *host)
{
- mmc_detect_change(host);
+ mmc_detect_change(host, 0);
return 0;
}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 716c4ef4faf..91c74843dc0 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -442,7 +442,7 @@ static void mmci_check_status(unsigned long data)
status = host->plat->status(mmc_dev(host->mmc));
if (status ^ host->oldstat)
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
host->oldstat = status;
mod_timer(&host->timer, jiffies + HZ);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index e99a53b09e3..b53af57074e 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)
static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
{
- mmc_detect_change(devid);
+ struct pxamci_host *host = mmc_priv(devid);
+
+ mmc_detect_change(devid, host->pdata->detect_delay);
return IRQ_HANDLED;
}
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index dec01d38c78..a62c86fef5c 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1122,7 +1122,7 @@ static void wbsd_detect_card(unsigned long data)
DBG("Executing card detection\n");
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
}
/*
@@ -1198,7 +1198,7 @@ static void wbsd_tasklet_card(unsigned long param)
*/
spin_unlock(&host->lock);
- mmc_detect_change(host->mmc);
+ mmc_detect_change(host->mmc, 0);
}
else
spin_unlock(&host->lock);
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index 1798ce7262c..0095384ff45 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);
static struct net_device_stats *net_get_stats(struct net_device *dev);
static void bionet_tick(unsigned long);
-static struct timer_list bionet_timer = TIMER_INITIALIZER(bionet_tick, 0, 0);
+static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0);
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 81c362c8cb9..8b997809f9d 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -165,7 +165,7 @@ static void pamsnet_tick(unsigned long);
static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp);
-static struct timer_list pamsnet_timer = TIMER_INITIALIZER(pamsnet_tick, 0, 0);
+static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0);
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 55a72c7ad00..83598e32179 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.2.20"
-#define DRV_MODULE_RELDATE "August 22, 2005"
+#define DRV_MODULE_VERSION "1.2.21"
+#define DRV_MODULE_RELDATE "September 7, 2005"
#define RUN_AT(x) (jiffies + (x))
@@ -1533,6 +1533,7 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
struct net_device *dev = dev_instance;
struct bnx2 *bp = dev->priv;
+ prefetch(bp->status_blk);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -1558,7 +1559,7 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
* When using MSI, the MSI message will always complete after
* the status block write.
*/
- if ((bp->status_blk->status_idx == bp->last_status_idx) ||
+ if ((bp->status_blk->status_idx == bp->last_status_idx) &&
(REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
return IRQ_NONE;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 9ad3f5740cd..62857b6a6ee 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -50,6 +50,7 @@
#endif
#include <linux/workqueue.h>
#include <linux/crc32.h>
+#include <linux/prefetch.h>
/* Hardware data structures and register definitions automatically
* generated from RTL code. Do not modify.
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 442670860fc..b68b9cad76e 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 */
static unsigned int network_tr_ctrl_shadow = 0;
/* Network speed indication. */
-static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0);
-static struct timer_list clear_led_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(speed_timer, NULL, 0, 0);
+static DEFINE_TIMER(clear_led_timer, NULL, 0, 0);
static int current_speed; /* Speed read from transceiver */
static int current_speed_selection; /* Speed selected by user */
static unsigned long led_next_time;
@@ -393,7 +393,7 @@ static int led_active;
static int rx_queue_len;
/* Duplex */
-static struct timer_list duplex_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(duplex_timer, NULL, 0, 0);
static int full_duplex;
static enum duplex current_duplex;
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index b780307093e..cdc07ccd733 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
static int get_eeprom_cksum(int off, int len, int *buffer);
static int set_mac_address(struct net_device *dev, void *addr);
static void count_rx_errors(int status, struct net_local *lp);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void net_poll_controller(struct net_device *dev);
+#endif
#if ALLOW_DMA
static void get_dma_channel(struct net_device *dev);
static void release_dma_buff(struct net_local *lp);
@@ -405,6 +408,19 @@ get_eeprom_cksum(int off, int len, int *buffer)
return -1;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void net_poll_controller(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ net_interrupt(dev->irq, dev, NULL);
+ enable_irq(dev->irq);
+}
+#endif
+
/* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probes avoids doing writes, and
verifies that the correct device exists and functions.
@@ -760,6 +776,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
dev->get_stats = net_get_stats;
dev->set_multicast_list = set_multicast_list;
dev->set_mac_address = set_mac_address;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = net_poll_controller;
+#endif
printk("\n");
if (net_debug)
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 41213ef602d..f52ee3162c5 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -170,7 +170,7 @@ static char ax25_bcast[7] =
static char ax25_test[7] =
{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
-static struct timer_list yam_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(yam_timer, NULL, 0, 0);
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 46e0022d325..6c766fdc51a 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)
frame, IRDA_USB_SPEED_MTU,
speed_bulk_callback, self);
urb->transfer_buffer_length = USB_IRDA_HEADER;
- urb->transfer_flags = URB_ASYNC_UNLINK;
+ urb->transfer_flags = 0;
/* Irq disabled -> GFP_ATOMIC */
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)
skb->data, IRDA_SKB_MAX_MTU,
write_bulk_callback, skb);
urb->transfer_buffer_length = skb->len;
- /* Note : unlink *must* be Asynchronous because of the code in
- * irda_usb_net_timeout() -> call in irq - Jean II */
- urb->transfer_flags = URB_ASYNC_UNLINK;
/* This flag (URB_ZERO_PACKET) indicates that what we send is not
* a continuous stream of data but separate packets.
* In this case, the USB layer will insert an empty USB frame (TD)
* after each of our packets that is exact multiple of the frame size.
* This is how the dongle will detect the end of packet - Jean II */
- urb->transfer_flags |= URB_ZERO_PACKET;
+ urb->transfer_flags = URB_ZERO_PACKET;
/* Generate min turn time. FIXME: can we do better than this? */
/* 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)
* in completion handler, because urb->status will
* be -ENOENT. We will fix that at the next watchdog,
* leaving more time to USB to recover...
- * Also, we are in interrupt, so we need to have
- * URB_ASYNC_UNLINK to work properly...
* Jean II */
done = 1;
break;
@@ -1008,9 +1003,7 @@ static int irda_usb_net_close(struct net_device *netdev)
}
}
/* Cancel Tx and speed URB - need to be synchronous to avoid races */
- self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
usb_kill_urb(self->tx_urb);
- self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
usb_kill_urb(self->speed_urb);
/* Stop and remove instance of IrLAP */
@@ -1521,9 +1514,7 @@ static void irda_usb_disconnect(struct usb_interface *intf)
usb_kill_urb(self->rx_urb[i]);
/* Cancel Tx and speed URB.
* Toggle flags to make sure it's synchronous. */
- self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
usb_kill_urb(self->tx_urb);
- self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
usb_kill_urb(self->speed_urb);
}
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 414694abf58..741aecc655d 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -69,14 +69,8 @@ typedef void irqreturn_t;
#else /* 2.5 or later */
-/* recent 2.5/2.6 stores pci device names at varying places ;-) */
-#ifdef CONFIG_PCI_NAMES
-/* human readable name */
-#define PCIDEV_NAME(pdev) ((pdev)->pretty_name)
-#else
/* whatever we get from the associated struct device - bus:slot:dev.fn id */
#define PCIDEV_NAME(pdev) (pci_name(pdev))
-#endif
#endif
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7c9dbc8c942..25c9a99c377 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -94,7 +94,7 @@ static char mv643xx_driver_version[] = "1.0";
static void __iomem *mv643xx_eth_shared_base;
/* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */
-static spinlock_t mv643xx_eth_phy_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
static inline u32 mv_read(int offset)
{
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 91df0bf181d..7a57c1b8373 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
#define IOSAPIC_IRDT_ID_EID_SHIFT 0x10
-static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iosapic_lock);
static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
{
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 97f723179f6..1b938bb9be3 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)
struct pci_dev *pdev = NULL;
int ret = 0;
- while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+ for_each_pci_dev(pdev) {
id = pci_match_id(parport_pc_pci_tbl, pdev);
if (id == NULL || id->driver_data >= last_sio)
continue;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7f31991772e..f187fd8aeed 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -30,23 +30,6 @@ config PCI_LEGACY_PROC
When in doubt, say N.
-config PCI_NAMES
- bool "PCI device name database"
- depends on PCI
- ---help---
- By default, the kernel contains a database of all known PCI device
- names to make the information in /proc/pci, /proc/ioports and
- similar files comprehensible to the user.
-
- This database increases size of the kernel image by about 80KB. This
- memory is freed after the system boots up if CONFIG_HOTPLUG is not set.
-
- Anyway, if you are building an installation floppy or kernel for an
- embedded system where kernel image size really matters, you can disable
- this feature and you'll get device ID numbers instead of names.
-
- When in doubt, say Y.
-
config PCI_DEBUG
bool "PCI Debugging"
depends on PCI && DEBUG_KERNEL
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3657f6199c4..716df015f8d 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -3,14 +3,9 @@
#
obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
- names.o pci-driver.o search.o pci-sysfs.o \
- rom.o
+ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
obj-$(CONFIG_PROC_FS) += proc.o
-ifndef CONFIG_SPARC64
-obj-y += setup-res.o
-endif
-
obj-$(CONFIG_HOTPLUG) += hotplug.o
# Build the PCI Hotplug drivers if we were asked to
@@ -46,21 +41,6 @@ ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
-hostprogs-y := gen-devlist
-
-# Dependencies on generated files need to be listed explicitly
-$(obj)/names.o: $(obj)/devlist.h $(obj)/classlist.h
-$(obj)/classlist.h: $(obj)/devlist.h
-
-# And that's how to generate them
-quiet_cmd_devlist = DEVLIST $@
- cmd_devlist = ( cd $(obj); ./gen-devlist ) < $<
-$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
- $(call cmd,devlist)
-
-# Files generated that shall be removed upon make clean
-clean-files := devlist.h classlist.h
-
# Build PCI Express stuff if needed
obj-$(CONFIG_PCIEPORTBUS) += pcie/
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index fb9a11243d2..eed67d9e73b 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)
void pci_enable_bridges(struct pci_bus *bus)
{
struct pci_dev *dev;
+ int retval;
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
- pci_enable_device(dev);
+ retval = pci_enable_device(dev);
pci_set_master(dev);
pci_enable_bridges(dev->subordinate);
}
}
}
+/** pci_walk_bus - walk devices on/under bus, calling callback.
+ * @top bus whose devices should be walked
+ * @cb callback to be called for each device found
+ * @userdata arbitrary pointer to be passed to callback.
+ *
+ * Walk the given bus, including any bridged devices
+ * on buses under this bus. Call the provided callback
+ * on each device found.
+ */
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+ void *userdata)
+{
+ struct pci_dev *dev;
+ struct pci_bus *bus;
+ struct list_head *next;
+
+ bus = top;
+ spin_lock(&pci_bus_lock);
+ next = top->devices.next;
+ for (;;) {
+ if (next == &bus->devices) {
+ /* end of this bus, go up or finish */
+ if (bus == top)
+ break;
+ next = bus->self->bus_list.next;
+ bus = bus->self->bus;
+ continue;
+ }
+ dev = list_entry(next, struct pci_dev, bus_list);
+ pci_dev_get(dev);
+ if (dev->subordinate) {
+ /* this is a pci-pci bridge, do its devices next */
+ next = dev->subordinate->devices.next;
+ bus = dev->subordinate;
+ } else
+ next = dev->bus_list.next;
+ spin_unlock(&pci_bus_lock);
+
+ /* Run device routines with the bus unlocked */
+ cb(dev, userdata);
+
+ spin_lock(&pci_bus_lock);
+ pci_dev_put(dev);
+ }
+ spin_unlock(&pci_bus_lock);
+}
+EXPORT_SYMBOL_GPL(pci_walk_bus);
+
EXPORT_SYMBOL(pci_bus_alloc_resource);
EXPORT_SYMBOL_GPL(pci_bus_add_device);
EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c
deleted file mode 100644
index 8abfc499fde..00000000000
--- a/drivers/pci/gen-devlist.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Generate devlist.h and classlist.h from the PCI ID file.
- *
- * (c) 1999--2002 Martin Mares <mj@ucw.cz>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#define MAX_NAME_SIZE 200
-
-static void
-pq(FILE *f, const char *c, int len)
-{
- int i = 1;
- while (*c && i != len) {
- if (*c == '"')
- fprintf(f, "\\\"");
- else {
- fputc(*c, f);
- if (*c == '?' && c[1] == '?') {
- /* Avoid trigraphs */
- fprintf(f, "\" \"");
- }
- }
- c++;
- i++;
- }
-}
-
-int
-main(void)
-{
- char line[1024], *c, *bra, vend[8];
- int vendors = 0;
- int mode = 0;
- int lino = 0;
- int vendor_len = 0;
- FILE *devf, *clsf;
-
- devf = fopen("devlist.h", "w");
- clsf = fopen("classlist.h", "w");
- if (!devf || !clsf) {
- fprintf(stderr, "Cannot create output file!\n");
- return 1;
- }
-
- while (fgets(line, sizeof(line)-1, stdin)) {
- lino++;
- if ((c = strchr(line, '\n')))
- *c = 0;
- if (!line[0] || line[0] == '#')
- continue;
- if (line[1] == ' ') {
- if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
- vend[0] = line[2];
- vend[1] = line[3];
- vend[2] = 0;
- mode = 2;
- } else goto err;
- }
- else if (line[0] == '\t') {
- if (line[1] == '\t')
- continue;
- switch (mode) {
- case 1:
- if (strlen(line) > 5 && line[5] == ' ') {
- c = line + 5;
- while (*c == ' ')
- *c++ = 0;
- if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
- /* Too long, try cutting off long description */
- bra = strchr(c, '[');
- if (bra && bra > c && bra[-1] == ' ')
- bra[-1] = 0;
- if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
- fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino);
- fprintf(stderr, "%s\n", c);
- /*return 1;*/
- }
- }
- fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
- pq(devf, c, MAX_NAME_SIZE - vendor_len - 1);
- fputs("\")\n", devf);
- } else goto err;
- break;
- case 2:
- if (strlen(line) > 3 && line[3] == ' ') {
- c = line + 3;
- while (*c == ' ')
- *c++ = 0;
- fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
- } else goto err;
- break;
- default:
- goto err;
- }
- } else if (strlen(line) > 4 && line[4] == ' ') {
- c = line + 4;
- while (*c == ' ')
- *c++ = 0;
- if (vendors)
- fputs("ENDVENDOR()\n\n", devf);
- vendors++;
- strcpy(vend, line);
- vendor_len = strlen(c);
- if (vendor_len + 24 > MAX_NAME_SIZE) {
- fprintf(stderr, "Line %d: Vendor name too long\n", lino);
- return 1;
- }
- fprintf(devf, "VENDOR(%s,\"", vend);
- pq(devf, c, 0);
- fputs("\")\n", devf);
- mode = 1;
- } else {
- err:
- fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line);
- return 1;
- }
- }
- fputs("ENDVENDOR()\n\
-\n\
-#undef VENDOR\n\
-#undef DEVICE\n\
-#undef ENDVENDOR\n", devf);
- fputs("\n#undef CLASS\n", clsf);
-
- fclose(devf);
- fclose(clsf);
-
- return 0;
-}
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index b844bc97232..10444988a10 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,
scratch = buffer;
- /* stuff we want to pass to /sbin/hotplug */
- envp[i++] = scratch;
- length += scnprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
- pdev->class);
- if ((buffer_size - length <= 0) || (i >= num_envp))
+
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PCI_CLASS=%04X", pdev->class))
return -ENOMEM;
- ++length;
- scratch += length;
- envp[i++] = scratch;
- length += scnprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
- pdev->vendor, pdev->device);
- if ((buffer_size - length <= 0) || (i >= num_envp))
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
return -ENOMEM;
- ++length;
- scratch += length;
- envp[i++] = scratch;
- length += scnprintf (scratch, buffer_size - length,
- "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
- pdev->subsystem_device);
- if ((buffer_size - length <= 0) || (i >= num_envp))
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
+ pdev->subsystem_device))
return -ENOMEM;
- ++length;
- scratch += length;
- envp[i++] = scratch;
- length += scnprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
- pci_name(pdev));
- if ((buffer_size - length <= 0) || (i >= num_envp))
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PCI_SLOT_NAME=%s", pci_name(pdev)))
return -ENOMEM;
- envp[i++] = scratch;
- length += scnprintf (scratch, buffer_size - length,
- "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
- pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device,
- (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
- (u8)(pdev->class));
- if ((buffer_size - length <= 0) || (i >= num_envp))
+ if (add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
+ pdev->vendor, pdev->device,
+ pdev->subsystem_vendor, pdev->subsystem_device,
+ (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+ (u8)(pdev->class)))
return -ENOMEM;
envp[i] = NULL;
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 246586a3d91..3c71e3077ff 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -41,8 +41,7 @@ acpiphp-objs := acpiphp_core.o \
rpaphp-objs := rpaphp_core.o \
rpaphp_pci.o \
- rpaphp_slot.o \
- rpaphp_vio.o
+ rpaphp_slot.o
rpadlpar_io-objs := rpadlpar_core.o \
rpadlpar_sysfs.o
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 2b92b9e8c91..061ead21ef1 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
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
{
- snprintf(buffer, buffer_size, "%d", slot->number);
+ snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
}
enum php_ctlr_type {
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 305b47ec2f2..1406db35b08 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -1696,15 +1696,15 @@ void pciehprm_enable_card(
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
+ rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
if (card_type == PCI_HEADER_TYPE_BRIDGE) {
- rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
+ rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
}
- cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
+ command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
| PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
- bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
+ bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
if (ab) {
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 86b384e4271..ad1017da865 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -19,33 +19,36 @@
#include <asm/pci-bridge.h>
#include <asm/semaphore.h>
#include <asm/rtas.h>
+#include <asm/vio.h>
#include "../pci.h"
#include "rpaphp.h"
#include "rpadlpar.h"
static DECLARE_MUTEX(rpadlpar_sem);
+#define DLPAR_MODULE_NAME "rpadlpar_io"
+
#define NODE_TYPE_VIO 1
#define NODE_TYPE_SLOT 2
#define NODE_TYPE_PHB 3
-static struct device_node *find_php_slot_vio_node(char *drc_name)
+static struct device_node *find_vio_slot_node(char *drc_name)
{
- struct device_node *child;
struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
- char *loc_code;
+ struct device_node *dn = NULL;
+ char *name;
+ int rc;
if (!parent)
return NULL;
- for (child = of_get_next_child(parent, NULL);
- child; child = of_get_next_child(parent, child)) {
- loc_code = get_property(child, "ibm,loc-code", NULL);
- if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
- return child;
+ while ((dn = of_get_next_child(parent, dn))) {
+ rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
+ if ((rc == 0) && (!strcmp(drc_name, name)))
+ break;
}
- return NULL;
+ return dn;
}
/* 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,
return np;
}
-static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
+static struct device_node *find_dlpar_node(char *drc_name, int *node_type)
{
struct device_node *dn;
@@ -83,7 +86,7 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
return dn;
}
- dn = find_php_slot_vio_node(drc_name);
+ dn = find_vio_slot_node(drc_name);
if (dn) {
*node_type = NODE_TYPE_VIO;
return dn;
@@ -92,14 +95,14 @@ static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
return NULL;
}
-static struct slot *find_slot(char *drc_name)
+static struct slot *find_slot(struct device_node *dn)
{
struct list_head *tmp, *n;
struct slot *slot;
list_for_each_safe(tmp, n, &rpaphp_slot_head) {
slot = list_entry(tmp, struct slot, rpaphp_slot_list);
- if (strcmp(slot->location, drc_name) == 0)
+ if (slot->dn == dn)
return slot;
}
@@ -131,7 +134,8 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
static int pci_add_secondary_bus(struct device_node *dn,
struct pci_dev *bridge_dev)
{
- struct pci_controller *hose = dn->phb;
+ struct pci_dn *pdn = dn->data;
+ struct pci_controller *hose = pdn->phb;
struct pci_bus *child;
u8 sec_busno;
@@ -156,7 +160,7 @@ static int pci_add_secondary_bus(struct device_node *dn,
if (hose->last_busno < child->number)
hose->last_busno = child->number;
- dn->bussubno = child->number;
+ pdn->bussubno = child->number;
/* ioremap() for child bus, which may or may not succeed */
remap_bus_range(child);
@@ -164,13 +168,28 @@ static int pci_add_secondary_bus(struct device_node *dn,
return 0;
}
+static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
+ struct device_node *dev_dn)
+{
+ struct pci_dev *tmp = NULL;
+ struct device_node *child_dn;
+
+ list_for_each_entry(tmp, &parent->devices, bus_list) {
+ child_dn = pci_device_to_OF_node(tmp);
+ if (child_dn == dev_dn)
+ return tmp;
+ }
+ return NULL;
+}
+
static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
{
- struct pci_controller *hose = dn->phb;
+ struct pci_dn *pdn = dn->data;
+ struct pci_controller *hose = pdn->phb;
struct pci_dev *dev = NULL;
/* Scan phb bus for EADS device, adding new one to bus->devices */
- if (!pci_scan_single_device(hose->bus, dn->devfn)) {
+ if (!pci_scan_single_device(hose->bus, pdn->devfn)) {
printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
return NULL;
}
@@ -179,49 +198,28 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
pci_bus_add_devices(hose->bus);
/* Confirm new bridge dev was created */
- dev = rpaphp_find_pci_dev(dn);
- if (!dev) {
- printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__);
- return NULL;
- }
+ dev = dlpar_find_new_dev(hose->bus, dn);
+ if (dev) {
+ if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+ printk(KERN_ERR "%s: unexpected header type %d\n",
+ __FUNCTION__, dev->hdr_type);
+ return NULL;
+ }
- if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
- printk(KERN_ERR "%s: unexpected header type %d\n",
- __FUNCTION__, dev->hdr_type);
- return NULL;
+ if (pci_add_secondary_bus(dn, dev))
+ return NULL;
}
- if (pci_add_secondary_bus(dn, dev))
- return NULL;
-
return dev;
}
-static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev)
+static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
{
- struct pci_bus *secondary_bus;
+ struct pci_dev *dev;
+ int rc;
- if (!bridge_dev) {
- printk(KERN_ERR "%s: unexpected null device\n",
- __FUNCTION__);
+ if (rpaphp_find_pci_bus(dn))
return -EINVAL;
- }
-
- secondary_bus = bridge_dev->subordinate;
-
- if (unmap_bus_range(secondary_bus)) {
- printk(KERN_ERR "%s: failed to unmap bus range\n",
- __FUNCTION__);
- return -ERANGE;
- }
-
- pci_remove_bus_device(bridge_dev);
- return 0;
-}
-
-static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
-{
- struct pci_dev *dev;
/* Add pci bus */
dev = dlpar_pci_add_bus(dn);
@@ -231,6 +229,21 @@ static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
return -EIO;
}
+ if (dn->child) {
+ rc = rpaphp_config_pci_adapter(dev->subordinate);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: unable to enable slot %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
+ }
+
+ /* Add hotplug slot */
+ if (rpaphp_add_slot(dn)) {
+ printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
return 0;
}
@@ -255,47 +268,69 @@ static int dlpar_remove_root_bus(struct pci_controller *phb)
return 0;
}
-static int dlpar_remove_phb(struct slot *slot)
+static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
{
- struct pci_controller *phb;
- struct device_node *dn;
+ struct slot *slot;
+ struct pci_dn *pdn;
int rc = 0;
- dn = slot->dn;
- if (!dn) {
- printk(KERN_ERR "%s: unexpected NULL slot device node\n",
- __FUNCTION__);
- return -EIO;
- }
-
- phb = dn->phb;
- if (!phb) {
- printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
- __FUNCTION__);
- return -EIO;
- }
+ if (!rpaphp_find_pci_bus(dn))
+ return -EINVAL;
- if (rpaphp_remove_slot(slot)) {
- printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
- __FUNCTION__, slot->location);
- return -EIO;
+ slot = find_slot(dn);
+ if (slot) {
+ /* Remove hotplug slot */
+ if (rpaphp_remove_slot(slot)) {
+ printk(KERN_ERR
+ "%s: unable to remove hotplug slot %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
}
- rc = dlpar_remove_root_bus(phb);
+ pdn = dn->data;
+ BUG_ON(!pdn || !pdn->phb);
+ rc = dlpar_remove_root_bus(pdn->phb);
if (rc < 0)
return rc;
+ pdn->phb = NULL;
+
return 0;
}
-static int dlpar_add_phb(struct device_node *dn)
+static int dlpar_add_phb(char *drc_name, struct device_node *dn)
{
struct pci_controller *phb;
+ if (PCI_DN(dn)->phb) {
+ /* PHB already exists */
+ return -EINVAL;
+ }
+
phb = init_phb_dynamic(dn);
if (!phb)
+ return -EIO;
+
+ if (rpaphp_add_slot(dn)) {
+ printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
+{
+ if (vio_find_node(dn))
return -EINVAL;
+ if (!vio_register_device_node(dn)) {
+ printk(KERN_ERR
+ "%s: failed to register vio node %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
return 0;
}
@@ -316,18 +351,13 @@ int dlpar_add_slot(char *drc_name)
{
struct device_node *dn = NULL;
int node_type;
- int rc = 0;
+ int rc = -EIO;
if (down_interruptible(&rpadlpar_sem))
return -ERESTARTSYS;
- /* Check for existing hotplug slot */
- if (find_slot(drc_name)) {
- rc = -EINVAL;
- goto exit;
- }
-
- dn = find_newly_added_node(drc_name, &node_type);
+ /* Find newly added node */
+ dn = find_dlpar_node(drc_name, &node_type);
if (!dn) {
rc = -ENODEV;
goto exit;
@@ -335,24 +365,17 @@ int dlpar_add_slot(char *drc_name)
switch (node_type) {
case NODE_TYPE_VIO:
- /* Just add hotplug slot */
+ rc = dlpar_add_vio_slot(drc_name, dn);
break;
case NODE_TYPE_SLOT:
rc = dlpar_add_pci_slot(drc_name, dn);
break;
case NODE_TYPE_PHB:
- rc = dlpar_add_phb(dn);
+ rc = dlpar_add_phb(drc_name, dn);
break;
- default:
- printk("%s: unexpected node type\n", __FUNCTION__);
- return -EIO;
}
- if (!rc && rpaphp_add_slot(dn)) {
- printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
- __FUNCTION__, drc_name);
- rc = -EIO;
- }
+ printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name);
exit:
up(&rpadlpar_sem);
return rc;
@@ -366,17 +389,17 @@ exit:
* of an I/O Slot.
* Return Codes:
* 0 Success
- * -EIO Internal Error
+ * -EINVAL Vio dev doesn't exist
*/
-int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
+static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
{
- /* Remove hotplug slot */
+ struct vio_dev *vio_dev;
- if (rpaphp_remove_slot(slot)) {
- printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
- __FUNCTION__, drc_name);
- return -EIO;
- }
+ vio_dev = vio_find_node(dn);
+ if (!vio_dev)
+ return -EINVAL;
+
+ vio_unregister_device(vio_dev);
return 0;
}
@@ -391,31 +414,34 @@ int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
* -ENODEV Not a valid drc_name
* -EIO Internal PCI Error
*/
-int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
+int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
{
- struct pci_dev *bridge_dev;
+ struct pci_bus *bus;
+ struct slot *slot;
- bridge_dev = slot->bridge;
- if (!bridge_dev) {
- printk(KERN_ERR "%s: unexpected null bridge device\n",
- __FUNCTION__);
- return -EIO;
- }
+ bus = rpaphp_find_pci_bus(dn);
+ if (!bus)
+ return -EINVAL;
- /* Remove hotplug slot */
- if (rpaphp_remove_slot(slot)) {
- printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
- __FUNCTION__, drc_name);
- return -EIO;
+ slot = find_slot(dn);
+ if (slot) {
+ /* Remove hotplug slot */
+ if (rpaphp_remove_slot(slot)) {
+ printk(KERN_ERR
+ "%s: unable to remove hotplug slot %s\n",
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
}
- /* Remove pci bus */
-
- if (dlpar_pci_remove_bus(bridge_dev)) {
- printk(KERN_ERR "%s: unable to remove pci bus %s\n",
- __FUNCTION__, drc_name);
- return -EIO;
+ if (unmap_bus_range(bus)) {
+ printk(KERN_ERR "%s: failed to unmap bus range\n",
+ __FUNCTION__);
+ return -ERANGE;
}
+
+ BUG_ON(!bus->self);
+ pci_remove_bus_device(bus->self);
return 0;
}
@@ -434,38 +460,31 @@ int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
*/
int dlpar_remove_slot(char *drc_name)
{
- struct slot *slot;
+ struct device_node *dn;
+ int node_type;
int rc = 0;
if (down_interruptible(&rpadlpar_sem))
return -ERESTARTSYS;
- if (!find_php_slot_vio_node(drc_name) &&
- !find_php_slot_pci_node(drc_name, "SLOT") &&
- !find_php_slot_pci_node(drc_name, "PHB")) {
+ dn = find_dlpar_node(drc_name, &node_type);
+ if (!dn) {
rc = -ENODEV;
goto exit;
}
- slot = find_slot(drc_name);
- if (!slot) {
- rc = -EINVAL;
- goto exit;
- }
-
- if (slot->type == PHB) {
- rc = dlpar_remove_phb(slot);
- } else {
- switch (slot->dev_type) {
- case PCI_DEV:
- rc = dlpar_remove_pci_slot(slot, drc_name);
- break;
-
- case VIO_DEV:
- rc = dlpar_remove_vio_slot(slot, drc_name);
- break;
- }
+ switch (node_type) {
+ case NODE_TYPE_VIO:
+ rc = dlpar_remove_vio_slot(drc_name, dn);
+ break;
+ case NODE_TYPE_PHB:
+ rc = dlpar_remove_phb(drc_name, dn);
+ break;
+ case NODE_TYPE_SLOT:
+ rc = dlpar_remove_pci_slot(drc_name, dn);
+ break;
}
+ printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
exit:
up(&rpadlpar_sem);
return rc;
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 81746e6e0e0..61d94d1e29c 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -30,10 +30,6 @@
#include <linux/pci.h>
#include "pci_hotplug.h"
-#define PHB 2
-#define HOTPLUG 1
-#define EMBEDDED 0
-
#define DR_INDICATOR 9002
#define DR_ENTITY_SENSE 9003
@@ -61,10 +57,6 @@ extern int debug;
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-/* slot types */
-#define VIO_DEV 1
-#define PCI_DEV 2
-
/* slot states */
#define NOT_VALID 3
@@ -72,11 +64,6 @@ extern int debug;
#define CONFIGURED 1
#define EMPTY 0
-struct rpaphp_pci_func {
- struct pci_dev *pci_dev;
- struct list_head sibling;
-};
-
/*
* struct slot - slot information for each *physical* slot
*/
@@ -88,15 +75,9 @@ struct slot {
u32 power_domain;
char *name;
char *location;
- u8 removable;
- u8 dev_type; /* VIO or PCI */
- struct device_node *dn; /* slot's device_node in OFDT */
- /* dn has phb info */
- struct pci_dev *bridge; /* slot's pci_dev in pci_devices */
- union {
- struct list_head *pci_devs; /* pci_devs in PCI slot */
- struct vio_dev *vio_dev; /* vio_dev in VIO slot */
- } dev;
+ struct device_node *dn;
+ struct pci_bus *bus;
+ struct list_head *pci_devs;
struct hotplug_slot *hotplug_slot;
};
@@ -107,13 +88,13 @@ extern int num_slots;
/* function prototypes */
/* rpaphp_pci.c */
-extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn);
+extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
extern int rpaphp_enable_pci_slot(struct slot *slot);
extern int register_pci_slot(struct slot *slot);
extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
-extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev);
+extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
/* rpaphp_core.c */
extern int rpaphp_add_slot(struct device_node *dn);
@@ -121,12 +102,6 @@ extern int rpaphp_remove_slot(struct slot *slot);
extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
char **drc_name, char **drc_type, int *drc_power_domain);
-/* rpaphp_vio.c */
-extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
-extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
-extern int register_vio_slot(struct device_node *dn);
-extern int rpaphp_enable_vio_slot(struct slot *slot);
-
/* rpaphp_slot.c */
extern void dealloc_slot_struct(struct slot *slot);
extern 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 29117a3a328..c830ff0acdc 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)
int retval = 0;
down(&rpaphp_sem);
- /* have to go through this */
- switch (slot->dev_type) {
- case PCI_DEV:
- retval = rpaphp_get_pci_adapter_status(slot, 0, value);
- break;
- case VIO_DEV:
- retval = rpaphp_get_vio_adapter_status(slot, 0, value);
- break;
- default:
- retval = -EINVAL;
- }
+ retval = rpaphp_get_pci_adapter_status(slot, 0, value);
up(&rpaphp_sem);
return retval;
}
@@ -317,34 +307,6 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names,
return 0;
}
-static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
- int **types, int **power_domains, int **my_drc_index)
-{
- int rc;
-
- *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
- if(!*my_drc_index)
- return (0);
-
- if (!dn->parent)
- return (0);
-
- rc = get_children_props(dn->parent, indexes, names, types,
- power_domains);
- return (rc >= 0);
-}
-
-static inline int is_vdevice_root(struct device_node *dn)
-{
- return !strcmp(dn->name, "vdevice");
-}
-
-int is_dlpar_type(const char *type_str)
-{
- /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
- return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
-}
-
/****************************************************************
* rpaphp not only registers PCI hotplug slots(HOTPLUG),
* but also logical DR slots(EMBEDDED).
@@ -356,54 +318,33 @@ int rpaphp_add_slot(struct device_node *dn)
{
struct slot *slot;
int retval = 0;
- int i, *my_drc_index, slot_type;
+ int i;
int *indexes, *names, *types, *power_domains;
char *name, *type;
dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
- if (dn->parent && is_vdevice_root(dn->parent)) {
- /* register a VIO device */
- retval = register_vio_slot(dn);
- goto exit;
- }
-
/* register PCI devices */
if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
- if (is_php_dn(dn, &indexes, &names, &types, &power_domains))
- slot_type = HOTPLUG;
- else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index))
- slot_type = EMBEDDED;
- else goto exit;
+ if (!is_php_dn(dn, &indexes, &names, &types, &power_domains))
+ goto exit;
name = (char *) &names[1];
type = (char *) &types[1];
for (i = 0; i < indexes[0]; i++,
- name += (strlen(name) + 1), type += (strlen(type) + 1)) {
-
- if (slot_type == HOTPLUG ||
- (slot_type == EMBEDDED &&
- indexes[i + 1] == my_drc_index[0] &&
- is_dlpar_type(type))) {
- if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
- power_domains[i + 1]))) {
- retval = -ENOMEM;
- goto exit;
- }
- if (!strcmp(type, "PHB"))
- slot->type = PHB;
- else if (slot_type == EMBEDDED)
- slot->type = EMBEDDED;
- else
- slot->type = simple_strtoul(type, NULL, 10);
+ name += (strlen(name) + 1), type += (strlen(type) + 1)) {
+
+ if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
+ power_domains[i + 1]))) {
+ retval = -ENOMEM;
+ goto exit;
+ }
+ slot->type = simple_strtoul(type, NULL, 10);
- dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n",
+ dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
indexes[i + 1], name, type);
- retval = register_pci_slot(slot);
- if (slot_type == EMBEDDED)
- goto exit;
- }
+ retval = register_pci_slot(slot);
}
}
exit:
@@ -412,31 +353,6 @@ exit:
return retval;
}
-/*
- * init_slots - initialize 'struct slot' structures for each slot
- *
- */
-static void init_slots(void)
-{
- struct device_node *dn;
-
- for (dn = find_all_nodes(); dn; dn = dn->next)
- rpaphp_add_slot(dn);
-}
-
-static int __init init_rpa(void)
-{
-
- init_MUTEX(&rpaphp_sem);
-
- /* initialize internal data structure etc. */
- init_slots();
- if (!num_slots)
- return -ENODEV;
-
- return 0;
-}
-
static void __exit cleanup_slots(void)
{
struct list_head *tmp, *n;
@@ -458,10 +374,18 @@ static void __exit cleanup_slots(void)
static int __init rpaphp_init(void)
{
+ struct device_node *dn = NULL;
+
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ init_MUTEX(&rpaphp_sem);
- /* read all the PRA info from the system */
- return init_rpa();
+ while ((dn = of_find_node_by_type(dn, "pci")))
+ rpaphp_add_slot(dn);
+
+ if (!num_slots)
+ return -ENODEV;
+
+ return 0;
}
static void __exit rpaphp_exit(void)
@@ -481,16 +405,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
dbg("ENABLING SLOT %s\n", slot->name);
down(&rpaphp_sem);
- switch (slot->dev_type) {
- case PCI_DEV:
- retval = rpaphp_enable_pci_slot(slot);
- break;
- case VIO_DEV:
- retval = rpaphp_enable_vio_slot(slot);
- break;
- default:
- retval = -EINVAL;
- }
+ retval = rpaphp_enable_pci_slot(slot);
up(&rpaphp_sem);
exit:
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
@@ -511,16 +426,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
dbg("DISABLING SLOT %s\n", slot->name);
down(&rpaphp_sem);
- switch (slot->dev_type) {
- case PCI_DEV:
- retval = rpaphp_unconfig_pci_adapter(slot);
- break;
- case VIO_DEV:
- retval = rpaphp_unconfig_vio_adapter(slot);
- break;
- default:
- retval = -ENODEV;
- }
+ retval = rpaphp_unconfig_pci_adapter(slot);
up(&rpaphp_sem);
exit:
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 d8305a935aa..49e4d10a648 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -30,22 +30,35 @@
#include "rpaphp.h"
-struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn)
+static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
+ struct device_node *dn)
{
- struct pci_dev *dev = NULL;
- char bus_id[BUS_ID_SIZE];
+ struct pci_bus *child = NULL;
+ struct list_head *tmp;
+ struct device_node *busdn;
+
+ busdn = pci_bus_to_OF_node(bus);
+ if (busdn == dn)
+ return bus;
- sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number,
- dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn));
- for_each_pci_dev(dev) {
- if (!strcmp(pci_name(dev), bus_id)) {
+ list_for_each(tmp, &bus->children) {
+ child = find_bus_among_children(pci_bus_b(tmp), dn);
+ if (child)
break;
- }
}
- return dev;
+ return child;
}
-EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev);
+struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn)
+{
+ struct pci_dn *pdn = dn->data;
+
+ if (!pdn || !pdn->phb || !pdn->phb->bus)
+ return NULL;
+
+ return find_bus_among_children(pdn->phb->bus, dn);
+}
+EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
int rpaphp_claim_resource(struct pci_dev *dev, int resource)
{
@@ -69,11 +82,6 @@ int rpaphp_claim_resource(struct pci_dev *dev, int resource)
EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
-static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot)
-{
- return rpaphp_find_pci_dev(slot->dn);
-}
-
static int rpaphp_get_sensor_state(struct slot *slot, int *state)
{
int rc;
@@ -116,39 +124,27 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state)
*/
int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
{
+ struct pci_bus *bus;
int state, rc;
- struct device_node *child_dn;
- struct pci_dev *child_dev = NULL;
*value = NOT_VALID;
rc = rpaphp_get_sensor_state(slot, &state);
if (rc)
goto exit;
- if ((state == EMPTY) || (slot->type == PHB)) {
- dbg("slot is empty\n");
+ if (state == EMPTY)
*value = EMPTY;
- }
else if (state == PRESENT) {
if (!is_init) {
/* at run-time slot->state can be changed by */
/* config/unconfig adapter */
*value = slot->state;
} else {
- child_dn = slot->dn->child;
- if (child_dn)
- child_dev = rpaphp_find_pci_dev(child_dn);
-
- if (child_dev)
- *value = CONFIGURED;
- else if (!child_dn)
- dbg("%s: %s is not valid OFDT node\n",
- __FUNCTION__, slot->dn->full_name);
- else {
- err("%s: can't find pdev of adapter in slot[%s]\n",
- __FUNCTION__, slot->dn->full_name);
+ bus = rpaphp_find_pci_bus(slot->dn);
+ if (bus && !list_empty(&bus->devices))
+ *value = CONFIGURED;
+ else
*value = NOT_CONFIGURED;
- }
}
}
exit:
@@ -186,39 +182,6 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
}
}
-static int rpaphp_pci_config_bridge(struct pci_dev *dev);
-
-/*****************************************************************************
- rpaphp_pci_config_slot() will configure all devices under the
- given slot->dn and return the the first pci_dev.
- *****************************************************************************/
-static struct pci_dev *
-rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus)
-{
- struct device_node *eads_first_child = dn->child;
- struct pci_dev *dev = NULL;
- int num;
-
- dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
-
- if (eads_first_child) {
- /* pci_scan_slot should find all children of EADs */
- num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0));
- if (num) {
- rpaphp_fixup_new_pci_devices(bus, 1);
- pci_bus_add_devices(bus);
- }
- dev = rpaphp_find_pci_dev(eads_first_child);
- if (!dev) {
- err("No new device found\n");
- return NULL;
- }
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- rpaphp_pci_config_bridge(dev);
- }
- return dev;
-}
-
static int rpaphp_pci_config_bridge(struct pci_dev *dev)
{
u8 sec_busno;
@@ -252,6 +215,42 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
return 0;
}
+/*****************************************************************************
+ rpaphp_pci_config_slot() will configure all devices under the
+ given slot->dn and return the the first pci_dev.
+ *****************************************************************************/
+static struct pci_dev *
+rpaphp_pci_config_slot(struct pci_bus *bus)
+{
+ struct device_node *dn = pci_bus_to_OF_node(bus);
+ struct pci_dev *dev = NULL;
+ int slotno;
+ int num;
+
+ dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
+ if (!dn || !dn->child)
+ return NULL;
+
+ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+
+ /* pci_scan_slot should find all children */
+ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+ if (num) {
+ rpaphp_fixup_new_pci_devices(bus, 1);
+ pci_bus_add_devices(bus);
+ }
+ if (list_empty(&bus->devices)) {
+ err("%s: No new device found\n", __FUNCTION__);
+ return NULL;
+ }
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ rpaphp_pci_config_bridge(dev);
+ }
+
+ return dev;
+}
+
static void enable_eeh(struct device_node *dn)
{
struct device_node *sib;
@@ -263,49 +262,44 @@ static void enable_eeh(struct device_node *dn)
}
-static void print_slot_pci_funcs(struct slot *slot)
+static void print_slot_pci_funcs(struct pci_bus *bus)
{
+ struct device_node *dn;
struct pci_dev *dev;
- if (slot->dev_type == PCI_DEV) {
- dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name);
- list_for_each_entry (dev, slot->dev.pci_devs, bus_list)
- dbg("\t%s\n", pci_name(dev));
- }
+ dn = pci_bus_to_OF_node(bus);
+ if (!dn)
+ return;
+
+ dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name);
+ list_for_each_entry (dev, &bus->devices, bus_list)
+ dbg("\t%s\n", pci_name(dev));
return;
}
-static int rpaphp_config_pci_adapter(struct slot *slot)
+int rpaphp_config_pci_adapter(struct pci_bus *bus)
{
- struct pci_bus *pci_bus;
+ struct device_node *dn = pci_bus_to_OF_node(bus);
struct pci_dev *dev;
int rc = -ENODEV;
- dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
-
- if (slot->bridge) {
+ dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name);
+ if (!dn)
+ goto exit;
- pci_bus = slot->bridge->subordinate;
- if (!pci_bus) {
- err("%s: can't find bus structure\n", __FUNCTION__);
- goto exit;
- }
- enable_eeh(slot->dn);
- dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
- if (!dev) {
- err("%s: can't find any devices.\n", __FUNCTION__);
- goto exit;
- }
- print_slot_pci_funcs(slot);
- rc = 0;
- } else {
- /* slot is not enabled */
- err("slot doesn't have pci_dev structure\n");
+ enable_eeh(dn);
+ dev = rpaphp_pci_config_slot(bus);
+ if (!dev) {
+ err("%s: can't find any devices.\n", __FUNCTION__);
+ goto exit;
}
+ print_slot_pci_funcs(bus);
+ rc = 0;
exit:
dbg("Exit %s: rc=%d\n", __FUNCTION__, rc);
return rc;
}
+EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter);
static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
{
@@ -327,13 +321,14 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
int rpaphp_unconfig_pci_adapter(struct slot *slot)
{
- struct pci_dev *dev;
+ struct pci_dev *dev, *tmp;
int retval = 0;
- list_for_each_entry(dev, slot->dev.pci_devs, bus_list)
+ list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
rpaphp_eeh_remove_bus_device(dev);
+ pci_remove_bus_device(dev);
+ }
- pci_remove_behind_bridge(slot->bridge);
slot->state = NOT_CONFIGURED;
info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
slot->name);
@@ -356,66 +351,41 @@ static int setup_pci_hotplug_slot_info(struct slot *slot)
return 0;
}
-static int set_phb_slot_name(struct slot *slot)
+static void set_slot_name(struct slot *slot)
{
- struct device_node *dn;
- struct pci_controller *phb;
- struct pci_bus *bus;
-
- dn = slot->dn;
- if (!dn) {
- return -EINVAL;
- }
- phb = dn->phb;
- if (!phb) {
- return -EINVAL;
- }
- bus = phb->bus;
- if (!bus) {
- return -EINVAL;
- }
+ struct pci_bus *bus = slot->bus;
+ struct pci_dev *bridge;
- sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
- bus->number, 0, 0);
- return 0;
+ bridge = bus->self;
+ if (bridge)
+ strcpy(slot->name, pci_name(bridge));
+ else
+ sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
+ bus->number);
}
static int setup_pci_slot(struct slot *slot)
{
+ struct device_node *dn = slot->dn;
struct pci_bus *bus;
- int rc;
- if (slot->type == PHB) {
- rc = set_phb_slot_name(slot);
- if (rc < 0) {
- err("%s: failed to set phb slot name\n", __FUNCTION__);
- goto exit_rc;
- }
- } else {
- slot->bridge = rpaphp_find_bridge_pdev(slot);
- if (!slot->bridge) {
- /* slot being added doesn't have pci_dev yet */
- err("%s: no pci_dev for bridge dn %s\n",
- __FUNCTION__, slot->name);
- goto exit_rc;
- }
-
- bus = slot->bridge->subordinate;
- if (!bus)
- goto exit_rc;
- slot->dev.pci_devs = &bus->devices;
-
- dbg("%s set slot->name to %s\n", __FUNCTION__,
- pci_name(slot->bridge));
- strcpy(slot->name, pci_name(slot->bridge));
+ BUG_ON(!dn);
+ bus = rpaphp_find_pci_bus(dn);
+ if (!bus) {
+ err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name);
+ goto exit_rc;
}
+ slot->bus = bus;
+ slot->pci_devs = &bus->devices;
+ set_slot_name(slot);
+
/* find slot's pci_dev if it's not empty */
if (slot->hotplug_slot->info->adapter_status == EMPTY) {
slot->state = EMPTY; /* slot is empty */
} else {
/* slot is occupied */
- if (!(slot->dn->child)) {
+ if (!dn->child) {
/* non-empty slot has to have child */
err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
__FUNCTION__, slot->name);
@@ -425,7 +395,7 @@ static int setup_pci_slot(struct slot *slot)
if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
dbg("%s CONFIGURING pci adapter in slot[%s]\n",
__FUNCTION__, slot->name);
- if (rpaphp_config_pci_adapter(slot)) {
+ if (rpaphp_config_pci_adapter(slot->bus)) {
err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
goto exit_rc;
}
@@ -435,8 +405,8 @@ static int setup_pci_slot(struct slot *slot)
__FUNCTION__, slot->name);
goto exit_rc;
}
- print_slot_pci_funcs(slot);
- if (!list_empty(slot->dev.pci_devs)) {
+ print_slot_pci_funcs(slot->bus);
+ if (!list_empty(slot->pci_devs)) {
slot->state = CONFIGURED;
} else {
/* DLPAR add as opposed to
@@ -454,11 +424,6 @@ int register_pci_slot(struct slot *slot)
{
int rc = -EINVAL;
- slot->dev_type = PCI_DEV;
- if ((slot->type == EMBEDDED) || (slot->type == PHB))
- slot->removable = 0;
- else
- slot->removable = 1;
if (setup_pci_hotplug_slot_info(slot))
goto exit_rc;
if (setup_pci_slot(slot))
@@ -479,7 +444,7 @@ int rpaphp_enable_pci_slot(struct slot *slot)
/* if slot is not empty, enable the adapter */
if (state == PRESENT) {
dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
- retval = rpaphp_config_pci_adapter(slot);
+ retval = rpaphp_config_pci_adapter(slot->bus);
if (!retval) {
slot->state = CONFIGURED;
dbg("%s: PCI devices in slot[%s] has been configured\n",
@@ -502,37 +467,3 @@ exit:
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
return retval;
}
-
-struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev)
-{
- struct list_head *tmp, *n;
- struct slot *slot;
-
- list_for_each_safe(tmp, n, &rpaphp_slot_head) {
- struct pci_bus *bus;
- struct list_head *ln;
-
- slot = list_entry(tmp, struct slot, rpaphp_slot_list);
- if (slot->bridge == NULL) {
- if (slot->dev_type == PCI_DEV) {
- printk(KERN_WARNING "PCI slot missing bridge %s %s \n",
- slot->name, slot->location);
- }
- continue;
- }
-
- bus = slot->bridge->subordinate;
- if (!bus) {
- continue; /* should never happen? */
- }
- for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
- struct pci_dev *pdev = pci_dev_b(ln);
- if (pdev == dev)
- return slot->hotplug_slot;
- }
- }
-
- return NULL;
-}
-
-EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot);
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index ff2cbf0652d..0e881549508 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -30,35 +30,6 @@
#include <asm/rtas.h>
#include "rpaphp.h"
-static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf)
-{
- u8 value;
- int retval = -ENOENT;
- struct slot *slot = (struct slot *)php_slot->private;
-
- if (!slot)
- return retval;
-
- value = slot->removable;
- retval = sprintf (buf, "%d\n", value);
- return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_removable = {
- .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO},
- .show = removable_read_file,
-};
-
-static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot)
-{
- sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
-}
-
-static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot)
-{
- sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
-}
-
static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
{
char *value;
@@ -176,9 +147,6 @@ int deregister_slot(struct slot *slot)
/* remove "phy_location" file */
rpaphp_sysfs_remove_attr_location(php_slot);
- /* remove "phy_removable" file */
- rpaphp_sysfs_remove_attr_removable(php_slot);
-
retval = pci_hp_deregister(php_slot);
if (retval)
err("Problem unregistering a slot %s\n", slot->name);
@@ -212,21 +180,13 @@ int register_slot(struct slot *slot)
/* create "phy_locatoin" file */
rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
- /* create "phy_removable" file */
- rpaphp_sysfs_add_attr_removable(slot->hotplug_slot);
-
/* add slot to our internal list */
dbg("%s adding slot[%s] to rpaphp_slot_list\n",
__FUNCTION__, slot->name);
list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
-
- if (slot->dev_type == VIO_DEV)
- info("Slot [%s](VIO location=%s) registered\n",
- slot->name, slot->location);
- else
- info("Slot [%s](PCI location=%s) registered\n",
- slot->name, slot->location);
+ info("Slot [%s](PCI location=%s) registered\n", slot->name,
+ slot->location);
num_slots++;
return 0;
}
@@ -235,21 +195,17 @@ int rpaphp_get_power_status(struct slot *slot, u8 * value)
{
int rc = 0, level;
- if (slot->type == HOTPLUG) {
- rc = rtas_get_power_level(slot->power_domain, &level);
- if (!rc) {
- dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
- __FUNCTION__, slot->name, slot->power_domain, level);
- *value = level;
- } else
- err("failed to get power-level for slot(%s), rc=0x%x\n",
- slot->location, rc);
- } else {
- dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
- __FUNCTION__, slot->location);
- *value = (u8) POWER_ON;
+ rc = rtas_get_power_level(slot->power_domain, &level);
+ if (rc < 0) {
+ err("failed to get power-level for slot(%s), rc=0x%x\n",
+ slot->location, rc);
+ return rc;
}
+ dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
+ __FUNCTION__, slot->name, slot->power_domain, level);
+ *value = level;
+
return rc;
}
diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
deleted file mode 100644
index 74df6a305e6..00000000000
--- a/drivers/pci/hotplug/rpaphp_vio.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * RPA Hot Plug Virtual I/O device functions
- * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <lxie@us.ibm.com>
- *
- */
-#include <asm/vio.h>
-#include "rpaphp.h"
-
-/*
- * get_vio_adapter_status - get the status of a slot
- *
- * status:
- *
- * 1-- adapter is configured
- * 2-- adapter is not configured
- * 3-- not valid
- */
-inline int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 *value)
-{
- *value = slot->state;
- return 0;
-}
-
-int rpaphp_unconfig_vio_adapter(struct slot *slot)
-{
- int retval = 0;
-
- dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
- if (!slot->dev.vio_dev) {
- info("%s: no VIOA in slot[%s]\n", __FUNCTION__, slot->name);
- retval = -EINVAL;
- goto exit;
- }
- /* remove the device from the vio core */
- vio_unregister_device(slot->dev.vio_dev);
- slot->state = NOT_CONFIGURED;
- info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, slot->name);
-exit:
- dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
- return retval;
-}
-
-static int setup_vio_hotplug_slot_info(struct slot *slot)
-{
- slot->hotplug_slot->info->power_status = 1;
- rpaphp_get_vio_adapter_status(slot, 1,
- &slot->hotplug_slot->info->adapter_status);
- return 0;
-}
-
-int register_vio_slot(struct device_node *dn)
-{
- u32 *index;
- char *name;
- int rc = -EINVAL;
- struct slot *slot = NULL;
-
- rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
- if (rc < 0)
- goto exit_rc;
- index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
- if (!index)
- goto exit_rc;
- if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
- rc = -ENOMEM;
- goto exit_rc;
- }
- slot->dev_type = VIO_DEV;
- slot->dev.vio_dev = vio_find_node(dn);
- if (slot->dev.vio_dev) {
- /*
- * rpaphp is the only owner of vio devices and
- * does not need extra reference taken by
- * vio_find_node
- */
- put_device(&slot->dev.vio_dev->dev);
- } else
- slot->dev.vio_dev = vio_register_device_node(dn);
- if (slot->dev.vio_dev)
- slot->state = CONFIGURED;
- else
- slot->state = NOT_CONFIGURED;
- if (setup_vio_hotplug_slot_info(slot))
- goto exit_rc;
- strcpy(slot->name, slot->dev.vio_dev->dev.bus_id);
- info("%s: registered VIO device[name=%s vio_dev=%p]\n",
- __FUNCTION__, slot->name, slot->dev.vio_dev);
- rc = register_slot(slot);
-exit_rc:
- if (rc && slot)
- dealloc_slot_struct(slot);
- return (rc);
-}
-
-int rpaphp_enable_vio_slot(struct slot *slot)
-{
- int retval = 0;
-
- if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) {
- info("%s: VIO adapter %s in slot[%s] has been configured\n",
- __FUNCTION__, slot->dn->name, slot->name);
- slot->state = CONFIGURED;
- } else {
- info("%s: no vio_dev struct for adapter in slot[%s]\n",
- __FUNCTION__, slot->name);
- slot->state = NOT_CONFIGURED;
- }
-
- return retval;
-}
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 323041fd41d..b1409441c1c 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -32,14 +32,15 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
-#define PCIIO_ASIC_TYPE_TIOCA 4
-#define PCI_SLOT_ALREADY_UP 2 /* slot already up */
-#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */
-#define PCI_L1_ERR 7 /* L1 console command error */
-#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */
-#define PCI_L1_QSIZE 128 /* our L1 message buffer size */
-#define SN_MAX_HP_SLOTS 32 /* max number of hotplug slots */
-#define SGI_HOTPLUG_PROM_REV 0x0420 /* Min. required PROM version */
+#define PCIIO_ASIC_TYPE_TIOCA 4
+#define PCI_SLOT_ALREADY_UP 2 /* slot already up */
+#define PCI_SLOT_ALREADY_DOWN 3 /* slot already down */
+#define PCI_L1_ERR 7 /* L1 console command error */
+#define PCI_EMPTY_33MHZ 15 /* empty 33 MHz bus */
+#define PCI_L1_QSIZE 128 /* our L1 message buffer size */
+#define SN_MAX_HP_SLOTS 32 /* max hotplug slots */
+#define SGI_HOTPLUG_PROM_REV 0x0430 /* Min. required PROM version */
+#define SN_SLOT_NAME_SIZE 33 /* size of name string */
/* internal list head */
static struct list_head sn_hp_list;
@@ -51,6 +52,7 @@ struct slot {
/* this struct for glue internal only */
struct hotplug_slot *hotplug_slot;
struct list_head hp_list;
+ char physical_path[SN_SLOT_NAME_SIZE];
};
struct pcibr_slot_enable_resp {
@@ -70,7 +72,7 @@ enum sn_pci_req_e {
static int enable_slot(struct hotplug_slot *slot);
static int disable_slot(struct hotplug_slot *slot);
-static int get_power_status(struct hotplug_slot *slot, u8 *value);
+static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
static struct hotplug_slot_ops sn_hotplug_slot_ops = {
.owner = THIS_MODULE,
@@ -81,6 +83,21 @@ static struct hotplug_slot_ops sn_hotplug_slot_ops = {
static DECLARE_MUTEX(sn_hotplug_sem);
+static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot,
+ char *buf)
+{
+ int retval = -ENOENT;
+ struct slot *slot = bss_hotplug_slot->private;
+
+ if (!slot)
+ return retval;
+
+ retval = sprintf (buf, "%s\n", slot->physical_path);
+ return retval;
+}
+
+static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
+
static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
{
struct pcibus_info *pcibus_info;
@@ -120,15 +137,15 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
/* Only register slots in I/O Bricks that support hotplug */
bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
switch (bricktype) {
- case L1_BRICKTYPE_IX:
- case L1_BRICKTYPE_PX:
- case L1_BRICKTYPE_IA:
- case L1_BRICKTYPE_PA:
- return 1;
- break;
- default:
- return -EPERM;
- break;
+ case L1_BRICKTYPE_IX:
+ case L1_BRICKTYPE_PX:
+ case L1_BRICKTYPE_IA:
+ case L1_BRICKTYPE_PA:
+ return 1;
+ break;
+ default:
+ return -EPERM;
+ break;
}
return -EIO;
@@ -142,13 +159,12 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
- bss_hotplug_slot->private = kcalloc(1, sizeof(struct slot),
- GFP_KERNEL);
- if (!bss_hotplug_slot->private)
+ slot = kcalloc(1, sizeof(*slot), GFP_KERNEL);
+ if (!slot)
return -ENOMEM;
- slot = (struct slot *)bss_hotplug_slot->private;
+ bss_hotplug_slot->private = slot;
- bss_hotplug_slot->name = kmalloc(33, GFP_KERNEL);
+ bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
if (!bss_hotplug_slot->name) {
kfree(bss_hotplug_slot->private);
return -ENOMEM;
@@ -156,16 +172,16 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
slot->device_num = device;
slot->pci_bus = pci_bus;
-
- sprintf(bss_hotplug_slot->name, "module_%c%c%c%c%.2d_b_%d_s_%d",
+ sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
+ pci_domain_nr(pci_bus),
+ ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
+ device + 1);
+ sprintf(slot->physical_path, "module_%c%c%c%c%.2d",
'0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
'0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
'0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
- MODULE_GET_BPOS(pcibus_info->pbi_moduleid),
- ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
- device + 1);
-
+ MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
slot->hotplug_slot = bss_hotplug_slot;
list_add(&slot->hp_list, &sn_hp_list);
@@ -175,14 +191,14 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
static struct hotplug_slot * sn_hp_destroy(void)
{
struct slot *slot;
- struct list_head *list;
struct hotplug_slot *bss_hotplug_slot = NULL;
- list_for_each(list, &sn_hp_list) {
- slot = list_entry(list, struct slot, hp_list);
+ list_for_each_entry(slot, &sn_hp_list, hp_list) {
bss_hotplug_slot = slot->hotplug_slot;
list_del(&((struct slot *)bss_hotplug_slot->private)->
hp_list);
+ sysfs_remove_file(&bss_hotplug_slot->kobj,
+ &sn_slot_path_attr.attr);
break;
}
return bss_hotplug_slot;
@@ -190,7 +206,6 @@ static struct hotplug_slot * sn_hp_destroy(void)
static void sn_bus_alloc_data(struct pci_dev *dev)
{
- struct list_head *node;
struct pci_bus *subordinate_bus;
struct pci_dev *child;
@@ -199,66 +214,29 @@ static void sn_bus_alloc_data(struct pci_dev *dev)
/* Recursively sets up the sn_irq_info structs */
if (dev->subordinate) {
subordinate_bus = dev->subordinate;
- list_for_each(node, &subordinate_bus->devices) {
- child = list_entry(node, struct pci_dev, bus_list);
+ list_for_each_entry(child, &subordinate_bus->devices, bus_list)
sn_bus_alloc_data(child);
- }
}
}
static void sn_bus_free_data(struct pci_dev *dev)
{
- struct list_head *node;
struct pci_bus *subordinate_bus;
struct pci_dev *child;
/* Recursively clean up sn_irq_info structs */
if (dev->subordinate) {
subordinate_bus = dev->subordinate;
- list_for_each(node, &subordinate_bus->devices) {
- child = list_entry(node, struct pci_dev, bus_list);
+ list_for_each_entry(child, &subordinate_bus->devices, bus_list)
sn_bus_free_data(child);
- }
}
sn_pci_unfixup_slot(dev);
}
-static u8 sn_power_status_get(struct hotplug_slot *bss_hotplug_slot)
-{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
- struct pcibus_info *pcibus_info;
- u8 retval;
-
- pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
- retval = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
-
- return retval ? 1 : 0;
-}
-
-static void sn_slot_mark_enable(struct hotplug_slot *bss_hotplug_slot,
- int device_num)
-{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
- struct pcibus_info *pcibus_info;
-
- pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
- pcibus_info->pbi_enabled_devices |= (1 << device_num);
-}
-
-static void sn_slot_mark_disable(struct hotplug_slot *bss_hotplug_slot,
- int device_num)
-{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
- struct pcibus_info *pcibus_info;
-
- pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
- pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
-}
-
static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
int device_num)
{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct slot *slot = bss_hotplug_slot->private;
struct pcibus_info *pcibus_info;
struct pcibr_slot_enable_resp resp;
int rc;
@@ -273,7 +251,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
if (rc == PCI_SLOT_ALREADY_UP) {
dev_dbg(slot->pci_bus->self, "is already active\n");
- return -EPERM;
+ return 1; /* return 1 to user */
}
if (rc == PCI_L1_ERR) {
@@ -290,7 +268,8 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
return -EIO;
}
- sn_slot_mark_enable(bss_hotplug_slot, device_num);
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+ pcibus_info->pbi_enabled_devices |= (1 << device_num);
return 0;
}
@@ -298,7 +277,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
int device_num, int action)
{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct slot *slot = bss_hotplug_slot->private;
struct pcibus_info *pcibus_info;
struct pcibr_slot_disable_resp resp;
int rc;
@@ -307,43 +286,44 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
- if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_SLOT_ALREADY_DOWN) {
+ if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
+ (rc == PCI_SLOT_ALREADY_DOWN)) {
dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
- return -ENODEV;
+ return 1; /* return 1 to user */
}
- if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_EMPTY_33MHZ) {
+ if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
dev_dbg(slot->pci_bus->self,
"Cannot remove last 33MHz card\n");
return -EPERM;
}
- if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_L1_ERR) {
+ if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
dev_dbg(slot->pci_bus->self,
"L1 failure %d with message \n%s\n",
resp.resp_sub_errno, resp.resp_l1_msg);
return -EPERM;
}
- if (action == PCI_REQ_SLOT_ELIGIBLE && rc) {
+ if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
dev_dbg(slot->pci_bus->self,
"remove failed with error %d sub-error %d\n",
rc, resp.resp_sub_errno);
return -EIO;
}
- if (action == PCI_REQ_SLOT_ELIGIBLE && !rc)
+ if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
return 0;
- if (action == PCI_REQ_SLOT_DISABLE && !rc) {
- sn_slot_mark_disable(bss_hotplug_slot, device_num);
+ if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+ pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
dev_dbg(slot->pci_bus->self, "remove successful\n");
return 0;
}
- if (action == PCI_REQ_SLOT_DISABLE && rc) {
+ if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
- return rc;
}
return rc;
@@ -351,7 +331,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct slot *slot = bss_hotplug_slot->private;
struct pci_bus *new_bus = NULL;
struct pci_dev *dev;
int func, num_funcs;
@@ -371,8 +351,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
return rc;
}
- num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num+1,
- PCI_FUNC(0)));
+ num_funcs = pci_scan_slot(slot->pci_bus,
+ PCI_DEVFN(slot->device_num + 1, 0));
if (!num_funcs) {
dev_dbg(slot->pci_bus->self, "no device in slot\n");
up(&sn_hotplug_sem);
@@ -391,8 +371,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
dev = pci_get_slot(slot->pci_bus,
PCI_DEVFN(slot->device_num + 1,
PCI_FUNC(func)));
-
-
if (dev) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
unsigned char sec_bus;
@@ -431,7 +409,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
{
- struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+ struct slot *slot = bss_hotplug_slot->private;
struct pci_dev *dev;
int func;
int rc;
@@ -448,7 +426,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
/* Free the SN resources assigned to the Linux device.*/
for (func = 0; func < 8; func++) {
dev = pci_get_slot(slot->pci_bus,
- PCI_DEVFN(slot->device_num+1,
+ PCI_DEVFN(slot->device_num + 1,
PCI_FUNC(func)));
if (dev) {
/*
@@ -477,10 +455,15 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
return rc;
}
-static int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value)
+static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
+ u8 *value)
{
+ struct slot *slot = bss_hotplug_slot->private;
+ struct pcibus_info *pcibus_info;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
down(&sn_hotplug_sem);
- *value = sn_power_status_get(bss_hotplug_slot);
+ *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
up(&sn_hotplug_sem);
return 0;
}
@@ -508,7 +491,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
if (sn_pci_slot_valid(pci_bus, device) != 1)
continue;
- bss_hotplug_slot = kcalloc(1,sizeof(struct hotplug_slot),
+ bss_hotplug_slot = kcalloc(1, sizeof(*bss_hotplug_slot),
GFP_KERNEL);
if (!bss_hotplug_slot) {
rc = -ENOMEM;
@@ -516,7 +499,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
}
bss_hotplug_slot->info =
- kcalloc(1,sizeof(struct hotplug_slot_info),
+ kcalloc(1, sizeof(struct hotplug_slot_info),
GFP_KERNEL);
if (!bss_hotplug_slot->info) {
rc = -ENOMEM;
@@ -535,6 +518,11 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
rc = pci_hp_register(bss_hotplug_slot);
if (rc)
goto register_err;
+
+ rc = sysfs_create_file(&bss_hotplug_slot->kobj,
+ &sn_slot_path_attr.attr);
+ if (rc)
+ goto register_err;
}
dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
return rc;
@@ -564,14 +552,14 @@ static int sn_pci_hotplug_init(void)
int rc;
int registered = 0;
- INIT_LIST_HEAD(&sn_hp_list);
-
if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
- printk(KERN_ERR "%s: PROM version must be greater than 4.05\n",
+ printk(KERN_ERR "%s: PROM version must be greater than 4.30\n",
__FUNCTION__);
return -EPERM;
}
+ INIT_LIST_HEAD(&sn_hp_list);
+
while ((pci_bus = pci_find_next_bus(pci_bus))) {
if (!pci_bus->sysdata)
continue;
@@ -584,9 +572,9 @@ static int sn_pci_hotplug_init(void)
dev_dbg(pci_bus->self, "valid hotplug bus\n");
rc = sn_hotplug_slot_register(pci_bus);
- if (!rc)
+ if (!rc) {
registered = 1;
- else {
+ } else {
registered = 0;
break;
}
@@ -599,9 +587,8 @@ static void sn_pci_hotplug_exit(void)
{
struct hotplug_slot *bss_hotplug_slot;
- while ((bss_hotplug_slot = sn_hp_destroy())) {
+ while ((bss_hotplug_slot = sn_hp_destroy()))
pci_hp_deregister(bss_hotplug_slot);
- }
if (!list_empty(&sn_hp_list))
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 fe4d653da18..b7d1c61d6bb 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
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
{
- snprintf(buffer, buffer_size, "%d", slot->number);
+ snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
}
enum php_ctlr_type {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 532f73bb222..ee8677bda95 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)
}
if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
/* PCI Express Endpoint device detected */
- u16 cmd;
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_intx(dev, 0); /* disable intx */
}
}
@@ -461,10 +458,7 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
}
if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
/* PCI Express Endpoint device detected */
- u16 cmd;
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_intx(dev, 1); /* enable intx */
}
}
diff --git a/drivers/pci/names.c b/drivers/pci/names.c
deleted file mode 100644
index ad224aada7c..00000000000
--- a/drivers/pci/names.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * PCI Class and Device Name Tables
- *
- * Copyright 1993--1999 Drew Eckhardt, Frederic Potter,
- * David Mosberger-Tang, Martin Mares
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_PCI_NAMES
-
-struct pci_device_info {
- unsigned short device;
- unsigned short seen;
- const char *name;
-};
-
-struct pci_vendor_info {
- unsigned short vendor;
- unsigned short nr;
- const char *name;
- struct pci_device_info *devices;
-};
-
-/*
- * This is ridiculous, but we want the strings in
- * the .init section so that they don't take up
- * real memory.. Parse the same file multiple times
- * to get all the info.
- */
-#define VENDOR( vendor, name ) static char __vendorstr_##vendor[] __devinitdata = name;
-#define ENDVENDOR()
-#define DEVICE( vendor, device, name ) static char __devicestr_##vendor##device[] __devinitdata = name;
-#include "devlist.h"
-
-
-#define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __devinitdata = {
-#define ENDVENDOR() };
-#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device },
-#include "devlist.h"
-
-static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
-#define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
-#define ENDVENDOR()
-#define DEVICE( vendor, device, name )
-#include "devlist.h"
-};
-
-#define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info))
-
-void __devinit pci_name_device(struct pci_dev *dev)
-{
- const struct pci_vendor_info *vendor_p = pci_vendor_list;
- int i = VENDORS;
- char *name = dev->pretty_name;
-
- do {
- if (vendor_p->vendor == dev->vendor)
- goto match_vendor;
- vendor_p++;
- } while (--i);
-
- /* Couldn't find either the vendor nor the device */
- sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device);
- return;
-
- match_vendor: {
- struct pci_device_info *device_p = vendor_p->devices;
- int i = vendor_p->nr;
-
- while (i > 0) {
- if (device_p->device == dev->device)
- goto match_device;
- device_p++;
- i--;
- }
-
- /* Ok, found the vendor, but unknown device */
- sprintf(name, "PCI device %04x:%04x (%." PCI_NAME_HALF "s)",
- dev->vendor, dev->device, vendor_p->name);
- return;
-
- /* Full match */
- match_device: {
- char *n = name + sprintf(name, "%s %s",
- vendor_p->name, device_p->name);
- int nr = device_p->seen + 1;
- device_p->seen = nr;
- if (nr > 1)
- sprintf(n, " (#%d)", nr);
- }
- }
-}
-
-/*
- * Class names. Not in .init section as they are needed in runtime.
- */
-
-static u16 pci_class_numbers[] = {
-#define CLASS(x,y) 0x##x,
-#include "classlist.h"
-};
-
-static char *pci_class_names[] = {
-#define CLASS(x,y) y,
-#include "classlist.h"
-};
-
-char *
-pci_class_name(u32 class)
-{
- int i;
-
- for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++)
- if (pci_class_numbers[i] == class)
- return pci_class_names[i];
- return NULL;
-}
-
-#else
-
-void __devinit pci_name_device(struct pci_dev *dev)
-{
-}
-
-char *
-pci_class_name(u32 class)
-{
- return NULL;
-}
-
-#endif /* CONFIG_PCI_NAMES */
-
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e4115a0d5ba..0d0d533894e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/mempolicy.h>
#include "pci.h"
/*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
return NULL;
}
+static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ int error;
+#ifdef CONFIG_NUMA
+ /* Execute driver initialization on node where the
+ device's bus is attached to. This way the driver likely
+ allocates its local memory on the right node without
+ any need to change it. */
+ struct mempolicy *oldpol;
+ cpumask_t oldmask = current->cpus_allowed;
+ int node = pcibus_to_node(dev->bus);
+ if (node >= 0 && node_online(node))
+ set_cpus_allowed(current, node_to_cpumask(node));
+ /* And set default memory allocation policy */
+ oldpol = current->mempolicy;
+ current->mempolicy = &default_policy;
+ mpol_get(current->mempolicy);
+#endif
+ error = drv->probe(dev, id);
+#ifdef CONFIG_NUMA
+ set_cpus_allowed(current, oldmask);
+ mpol_free(current->mempolicy);
+ current->mempolicy = oldpol;
+#endif
+ return error;
+}
+
/**
* __pci_device_probe()
*
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
id = pci_match_device(drv, pci_dev);
if (id)
- error = drv->probe(pci_dev, id);
+ error = pci_call_probe(drv, pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
error = 0;
@@ -243,17 +272,19 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
}
-/*
+/*
* Default resume method for devices that have no driver provided resume,
* or not even a driver at all.
*/
static void pci_default_resume(struct pci_dev *pci_dev)
{
+ int retval;
+
/* restore the PCI config space */
pci_restore_state(pci_dev);
/* if the device was enabled before suspend, reenable */
if (pci_dev->is_enabled)
- pci_enable_device(pci_dev);
+ retval = pci_enable_device(pci_dev);
/* if the device was busmaster before the suspend, make it busmaster again */
if (pci_dev->is_busmaster)
pci_set_master(pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c62d2f04339..992db89adce 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)
}
/**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+void
+pci_restore_bars(struct pci_dev *dev)
+{
+ int i, numres;
+
+ switch (dev->hdr_type) {
+ case PCI_HEADER_TYPE_NORMAL:
+ numres = 6;
+ break;
+ case PCI_HEADER_TYPE_BRIDGE:
+ numres = 2;
+ break;
+ case PCI_HEADER_TYPE_CARDBUS:
+ numres = 1;
+ break;
+ default:
+ /* Should never get here, but just in case... */
+ return;
+ }
+
+ for (i = 0; i < numres; i ++)
+ pci_update_resource(dev, &dev->resource[i], i);
+}
+
+/**
* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to be suspended
* @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);
int
pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
- int pm;
+ int pm, need_restore = 0;
u16 pmcsr, pmc;
/* bound the state we're entering */
@@ -263,7 +294,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return -EIO;
pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
- if ((pmc & PCI_PM_CAP_VER_MASK) > 2) {
+ if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
printk(KERN_DEBUG
"PCI: %s has unsupported PM cap regs version (%u)\n",
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)
}
/* check if this device supports the desired state */
- if (state == PCI_D1 || state == PCI_D2) {
- if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
- return -EIO;
- else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
- return -EIO;
- }
+ if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
+ return -EIO;
+ else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
+ return -EIO;
+
+ pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
/* If we're in D3, force entire word to 0.
* This doesn't affect PME_Status, disables PME_En, and
* sets PowerState to 0.
*/
- if (dev->current_state >= PCI_D3hot)
+ if (dev->current_state >= PCI_D3hot) {
+ if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+ need_restore = 1;
pmcsr = 0;
- else {
- pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+ } else {
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
pmcsr |= state;
}
@@ -308,6 +340,22 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
platform_pci_set_power_state(dev, state);
dev->current_state = state;
+
+ /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
+ * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
+ * from D3hot to D0 _may_ perform an internal reset, thereby
+ * going to "D0 Uninitialized" rather than "D0 Initialized".
+ * For example, at least some versions of the 3c905B and the
+ * 3c556B exhibit this behaviour.
+ *
+ * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
+ * devices in a D3hot state at boot. Consequently, we need to
+ * restore at least the BARs so that the device will be
+ * accessible to its driver.
+ */
+ if (need_restore)
+ pci_restore_bars(dev);
+
return 0;
}
@@ -394,8 +442,11 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
{
int err;
- pci_set_power_state(dev, PCI_D0);
- if ((err = pcibios_enable_device(dev, bars)) < 0)
+ err = pci_set_power_state(dev, PCI_D0);
+ if (err < 0 && err != -EIO)
+ return err;
+ err = pcibios_enable_device(dev, bars);
+ if (err < 0)
return err;
return 0;
}
@@ -747,6 +798,31 @@ pci_clear_mwi(struct pci_dev *dev)
}
}
+/**
+ * pci_intx - enables/disables PCI INTx for device dev
+ * @dev: the PCI device to operate on
+ * @enable: boolean
+ *
+ * Enables/disables PCI INTx for device dev
+ */
+void
+pci_intx(struct pci_dev *pdev, int enable)
+{
+ u16 pci_command, new;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+
+ if (enable) {
+ new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+ } else {
+ new = pci_command | PCI_COMMAND_INTX_DISABLE;
+ }
+
+ if (new != pci_command) {
+ pci_write_config_word(pdev, PCI_COMMAND, new);
+ }
+}
+
#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
/*
* These can be overridden by arch-specific implementations
@@ -809,6 +885,7 @@ struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);
#endif
+EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(pci_enable_device_bars);
EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pci_disable_device);
@@ -823,6 +900,7 @@ EXPORT_SYMBOL(pci_request_region);
EXPORT_SYMBOL(pci_set_master);
EXPORT_SYMBOL(pci_set_mwi);
EXPORT_SYMBOL(pci_clear_mwi);
+EXPORT_SYMBOL_GPL(pci_intx);
EXPORT_SYMBOL(pci_set_dma_mask);
EXPORT_SYMBOL(pci_set_consistent_dma_mask);
EXPORT_SYMBOL(pci_assign_resource);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d00168b1f66..d3f3dd42240 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; }
#endif
/* Functions for PCI Hotplug drivers to use */
-extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
extern int pci_remove_device_safe(struct pci_dev *dev);
extern unsigned char pci_max_busnr(void);
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
deleted file mode 100644
index 1d2ef1e2ffc..00000000000
--- a/drivers/pci/pci.ids
+++ /dev/null
@@ -1,10180 +0,0 @@
-#
-# List of PCI ID's
-#
-# Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
-# Linux PCI ID's Project at http://pciids.sf.net/. New data are always
-# welcome (if they are accurate), we're eagerly expecting new entries,
-# so if you have anything to contribute, please visit the home page or
-# send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
-#
-# Daily snapshot on Tue 2005-03-08 10:11:48
-#
-
-# Vendors, devices and subsystems. Please keep sorted.
-
-# Syntax:
-# vendor vendor_name
-# device device_name <-- single tab
-# subvendor subdevice subsystem_name <-- two tabs
-
-0000 Gammagraphx, Inc.
-001a Ascend Communications, Inc.
-0033 Paradyne corp.
-003d Lockheed Martin-Marietta Corp
-# Real TJN ID is e159, but they got it wrong several times --mj
-0059 Tiger Jet Network Inc. (Wrong ID)
-0070 Hauppauge computer works Inc.
- 4000 WinTV PVR-350
- 4001 WinTV PVR-250 (v1)
- 4009 WinTV PVR-250
- 4801 WinTV PVR-250 MCE
-0071 Nebula Electronics Ltd.
-0095 Silicon Image, Inc. (Wrong ID)
- 0680 Ultra ATA/133 IDE RAID CONTROLLER CARD
-0100 Ncipher Corp Ltd
-# 018a is not LevelOne but there is a board misprogrammed
-018a LevelOne
- 0106 FPC-0106TX misprogrammed [RTL81xx]
-# 021b is not Compaq but there is a board misprogrammed
-021b Compaq Computer Corporation
- 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking]
-# http://www.davicom.com.tw/
-0291 Davicom Semiconductor, Inc.
- 8212 DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
-# SpeedStream is Efficient Networks, Inc, a Siemens Company
-02ac SpeedStream
- 1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
-0357 TTTech AG
- 000a TTP-Monitoring Card V2.0
-0432 SCM Microsystems, Inc.
- 0001 Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
-05e3 CyberDoor
- 0701 CBD516
-0675 Dynalink
- 1700 IS64PH ISDN Adapter
- 1702 IS64PH ISDN Adapter
-# Wrong ID used in subsystem ID of VIA USB controllers.
-0925 VIA Technologies, Inc. (Wrong ID)
-09c1 Arris
- 0704 CM 200E Cable Modem
-0a89 BREA Technologies Inc
-0b49 ASCII Corporation
-# see http://homepage1.nifty.com/mcn/lab/machines/trance_vibrator/usbview.vib.txt
- 064f Trance Vibrator
-0e11 Compaq Computer Corporation
- 0001 PCI to EISA Bridge
- 0002 PCI to ISA Bridge
- 0046 Smart Array 64xx
- 0e11 409a Smart Array 641
- 0e11 409b Smart Array 642
- 0e11 409c Smart Array 6400
- 0e11 409d Smart Array 6400 EM
- 0049 NC7132 Gigabit Upgrade Module
- 004a NC6136 Gigabit Server Adapter
- 007c NC7770 1000BaseTX
- 007d NC6770 1000BaseTX
- 0085 NC7780 1000BaseTX
- 00bb NC7760
- 00ca NC7771
- 00cb NC7781
- 00cf NC7772
- 00d0 NC7782
- 00d1 NC7783
- 00e3 NC7761
- 0508 Netelligent 4/16 Token Ring
- 1000 Triflex/Pentium Bridge, Model 1000
- 2000 Triflex/Pentium Bridge, Model 2000
- 3032 QVision 1280/p
- 3033 QVision 1280/p
- 3034 QVision 1280/p
- 4000 4000 [Triflex]
- 4030 SMART-2/P
- 4031 SMART-2SL
- 4032 Smart Array 3200
- 4033 Smart Array 3100ES
- 4034 Smart Array 221
- 4040 Integrated Array
- 4048 Compaq Raid LC2
- 4050 Smart Array 4200
- 4051 Smart Array 4250ES
- 4058 Smart Array 431
- 4070 Smart Array 5300
- 4080 Smart Array 5i
- 4082 Smart Array 532
- 4083 Smart Array 5312
- 4091 Smart Array 6i
- 409a Smart Array 641
- 409b Smart Array 642
- 409c Smart Array 6400
- 409d Smart Array 6400 EM
- 6010 HotPlug PCI Bridge 6010
- 7020 USB Controller
- a0ec Fibre Channel Host Controller
- a0f0 Advanced System Management Controller
- a0f3 Triflex PCI to ISA Bridge
- a0f7 PCI Hotplug Controller
- 8086 002a PCI Hotplug Controller A
- 8086 002b PCI Hotplug Controller B
- a0f8 ZFMicro Chipset USB
- a0fc FibreChannel HBA Tachyon
- ae10 Smart-2/P RAID Controller
- 0e11 4030 Smart-2/P Array Controller
- 0e11 4031 Smart-2SL Array Controller
- 0e11 4032 Smart Array Controller
- 0e11 4033 Smart 3100ES Array Controller
- ae29 MIS-L
- ae2a MPC
- ae2b MIS-E
- ae31 System Management Controller
- ae32 Netelligent 10/100 TX PCI UTP
- ae33 Triflex Dual EIDE Controller
- ae34 Netelligent 10 T PCI UTP
- ae35 Integrated NetFlex-3/P
- ae40 Netelligent Dual 10/100 TX PCI UTP
- ae43 Netelligent Integrated 10/100 TX UTP
- ae69 CETUS-L
- ae6c Northstar
- ae6d NorthStar CPU to PCI Bridge
- b011 Netelligent 10/100 TX Embedded UTP
- b012 Netelligent 10 T/2 PCI UTP/Coax
- b01e NC3120 Fast Ethernet NIC
- b01f NC3122 Fast Ethernet NIC
- b02f NC1120 Ethernet NIC
- b030 Netelligent 10/100 TX UTP
- b04a 10/100 TX PCI Intel WOL UTP Controller
- b060 Smart Array 5300 Controller
- b0c6 NC3161 Fast Ethernet NIC
- b0c7 NC3160 Fast Ethernet NIC
- b0d7 NC3121 Fast Ethernet NIC
- b0dd NC3131 Fast Ethernet NIC
- b0de NC3132 Fast Ethernet Module
- b0df NC6132 Gigabit Module
- b0e0 NC6133 Gigabit Module
- b0e1 NC3133 Fast Ethernet Module
- b123 NC6134 Gigabit NIC
- b134 NC3163 Fast Ethernet NIC
- b13c NC3162 Fast Ethernet NIC
- b144 NC3123 Fast Ethernet NIC
- b163 NC3134 Fast Ethernet NIC
- b164 NC3165 Fast Ethernet Upgrade Module
- b178 Smart Array 5i/532
- 0e11 4080 Smart Array 5i
- 0e11 4082 Smart Array 532
- 0e11 4083 Smart Array 5312
- b1a4 NC7131 Gigabit Server Adapter
-# HP Memory Hot-Plug Controller
- b200 Memory Hot-Plug Controller
- b203 Integrated Lights Out Controller
- b204 Integrated Lights Out Processor
- f130 NetFlex-3/P ThunderLAN 1.0
- f150 NetFlex-3/P ThunderLAN 2.3
-0e55 HaSoTec GmbH
-# Formerly NCR
-1000 LSI Logic / Symbios Logic
- 0001 53c810
- 1000 1000 LSI53C810AE PCI to SCSI I/O Processor
- 0002 53c820
- 0003 53c825
- 1000 1000 LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
- 0004 53c815
- 0005 53c810AP
- 0006 53c860
- 1000 1000 LSI53C860E PCI to Ultra SCSI I/O Processor
- 000a 53c1510
- 1000 1000 LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
- 000b 53C896/897
- 0e11 6004 EOB003 Series SCSI host adapter
- 1000 1000 LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
- 1000 1010 LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
- 1000 1020 LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
-# multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics
- 13e9 1000 6221L-4U
- 000c 53c895
- 1000 1010 LSI8951U PCI to Ultra2 SCSI host adapter
- 1000 1020 LSI8952U PCI to Ultra2 SCSI host adapter
- 1de1 3906 DC-390U2B SCSI adapter
- 1de1 3907 DC-390U2W
- 000d 53c885
- 000f 53c875
- 0e11 7004 Embedded Ultra Wide SCSI Controller
- 1000 1000 LSI53C876/E PCI to Dual Channel SCSI Controller
- 1000 1010 LSI22801 PCI to Dual Channel Ultra SCSI host adapter
- 1000 1020 LSI22802 PCI to Dual Channel Ultra SCSI host adapter
- 1092 8760 FirePort 40 Dual SCSI Controller
- 1de1 3904 DC390F/U Ultra Wide SCSI Adapter
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 4c53 1050 CT7 mainboard
- 0010 53C1510
- 0e11 4040 Integrated Array Controller
- 0e11 4048 RAID LC2 Controller
- 1000 1000 53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
- 0012 53c895a
- 1000 1000 LSI53C895A PCI to Ultra2 SCSI Controller
- 0013 53c875a
- 1000 1000 LSI53C875A PCI to Ultra SCSI Controller
- 0020 53c1010 Ultra3 SCSI Adapter
- 1000 1000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
- 1de1 1020 DC-390U3W
- 0021 53c1010 66MHz Ultra3 SCSI Adapter
- 1000 1000 LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
- 1000 1010 Asus TR-DLS onboard 53C1010-66
- 124b 1070 PMC-USCSI3
- 4c53 1080 CT8 mainboard
- 4c53 1300 P017 mezzanine (32-bit PMC)
- 4c53 1310 P017 mezzanine (64-bit PMC)
- 0030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
- 1028 0123 PowerEdge 2600
- 1028 014a PowerEdge 1750
- 1028 016c PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
- 1028 0183 PowerEdge 1800
- 1028 1010 LSI U320 SCSI Controller
- 0031 53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
- 0032 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
- 1000 1000 LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
- 0033 1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
- 0040 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
- 1000 0033 MegaRAID SCSI 320-2XR
- 1000 0066 MegaRAID SCSI 320-2XRWS
- 0041 53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
- 008f 53c875J
- 1092 8000 FirePort 40 SCSI Controller
- 1092 8760 FirePort 40 Dual SCSI Host Adapter
- 0407 MegaRAID
- 1000 0530 MegaRAID 530 SCSI 320-0X RAID Controller
- 1000 0531 MegaRAID 531 SCSI 320-4X RAID Controller
- 1000 0532 MegaRAID 532 SCSI 320-2X RAID Controller
- 1028 0531 PowerEdge Expandable RAID Controller 4/QC
- 1028 0533 PowerEdge Expandable RAID Controller 4/QC
- 8086 0530 MegaRAID Intel RAID Controller SRCZCRX
- 8086 0532 MegaRAID Intel RAID Controller SRCU42X
- 0408 MegaRAID
- 1000 0001 MegaRAID SCSI 320-1E RAID Controller
- 1000 0002 MegaRAID SCSI 320-2E RAID Controller
- 1025 004d MegaRAID ACER ROMB-2E RAID Controller
- 1028 0001 PowerEdge RAID Controller PERC4e/SC
- 1028 0002 PowerEdge RAID Controller PERC4e/DC
- 1734 1065 FSC MegaRAID PCI Express ROMB
- 8086 0002 MegaRAID Intel RAID Controller SRCU42E
- 0409 MegaRAID
- 1000 3004 MegaRAID SATA 300-4X RAID Controller
- 1000 3008 MegaRAID SATA 300-8X RAID Controller
- 8086 3008 MegaRAID RAID Controller SRCS28X
- 8086 3431 MegaRAID RAID Controller Alief SROMBU42E
- 8086 3499 MegaRAID RAID Controller Harwich SROMBU42E
- 0621 FC909 Fibre Channel Adapter
- 0622 FC929 Fibre Channel Adapter
- 1000 1020 44929 O Dual Fibre Channel card
- 0623 FC929 LAN
- 0624 FC919 Fibre Channel Adapter
- 0625 FC919 LAN
- 0626 FC929X Fibre Channel Adapter
- 1000 1010 7202-XP-LC Dual Fibre Channel card
- 0627 FC929X LAN
- 0628 FC919X Fibre Channel Adapter
- 0629 FC919X LAN
- 0701 83C885 NT50 DigitalScape Fast Ethernet
- 0702 Yellowfin G-NIC gigabit ethernet
- 1318 0000 PEI100X
- 0804 SA2010
- 0805 SA2010ZC
- 0806 SA2020
- 0807 SA2020ZC
- 0901 61C102
- 1000 63C815
- 1960 MegaRAID
- 1000 0518 MegaRAID 518 SCSI 320-2 Controller
- 1000 0520 MegaRAID 520 SCSI 320-1 Controller
- 1000 0522 MegaRAID 522 i4 133 RAID Controller
- 1000 0523 MegaRAID SATA 150-6 RAID Controller
- 1000 4523 MegaRAID SATA 150-4 RAID Controller
- 1000 a520 MegaRAID ZCR SCSI 320-0 Controller
- 1028 0518 MegaRAID 518 DELL PERC 4/DC RAID Controller
- 1028 0520 MegaRAID 520 DELL PERC 4/SC RAID Controller
- 1028 0531 PowerEdge Expandable RAID Controller 4/QC
- 1028 0533 PowerEdge Expandable RAID Controller 4/QC
- 8086 0520 MegaRAIDRAID Controller SRCU41L
- 8086 0523 MegaRAID RAID Controller SRCS16
-1001 Kolter Electronic
- 0010 PCI 1616 Measurement card with 32 digital I/O lines
- 0011 OPTO-PCI Opto-Isolated digital I/O board
- 0012 PCI-AD/DA Analogue I/O board
- 0013 PCI-OPTO-RELAIS Digital I/O board with relay outputs
- 0014 PCI-Counter/Timer Counter Timer board
- 0015 PCI-DAC416 Analogue output board
- 0016 PCI-MFB Analogue I/O board
- 0017 PROTO-3 PCI Prototyping board
- 9100 INI-9100/9100W SCSI Host
-1002 ATI Technologies Inc
- 3150 M24 1P [Radeon Mobility X600]
- 3154 M24 1T [FireGL M24 GL]
- 3e50 RV380 0x3e50 [Radeon X600]
- 3e54 RV380 0x3e54 [FireGL V3200]
- 3e70 RV380 [Radeon X600] Secondary
- 4136 Radeon IGP 320 M
- 4137 Radeon IGP330/340/350
- 4144 R300 AD [Radeon 9500 Pro]
-# New PCI ID provided by ATI developer relations (correction to above)
- 4145 R300 AE [Radeon 9700 Pro]
-# New PCI ID provided by ATI developer relations (oops, correction to above)
- 4146 R300 AF [Radeon 9700 Pro]
- 4147 R300 AG [FireGL Z1/X1]
- 4148 R350 AH [Radeon 9800]
- 4149 R350 AI [Radeon 9800]
- 414a R350 AJ [Radeon 9800]
- 414b R350 AK [Fire GL X2]
-# New PCI ID provided by ATI developer relations
- 4150 RV350 AP [Radeon 9600]
- 1002 0002 R9600 Pro primary (Asus OEM for HP)
- 1002 0003 R9600 Pro secondary (Asus OEM for HP)
- 1458 4024 Giga-Byte GV-R96128D Primary
- 148c 2064 PowerColor R96A-C3N
- 148c 2066 PowerColor R96A-C3N
- 174b 7c19 Sapphire Atlantis Radeon 9600 Pro
- 174b 7c29 GC-R9600PRO Primary [Sapphire]
- 17ee 2002 Radeon 9600 256Mb Primary
- 18bc 0101 GC-R9600PRO Primary
-# New PCI ID provided by ATI developer relations
- 4151 RV350 AQ [Radeon 9600]
- 1043 c004 A9600SE
-# New PCI ID provided by ATI developer relations
- 4152 RV350 AR [Radeon 9600]
- 1002 0002 Radeon 9600XT
- 1043 c002 Radeon 9600 XT TVD
- 174b 7c29 Sapphire Radeon 9600XT
- 1787 4002 Radeon 9600 XT
- 4153 RV350 AS [Radeon 9600 AS]
- 4154 RV350 AT [Fire GL T2]
- 4155 RV350 AU [Fire GL T2]
- 4156 RV350 AV [Fire GL T2]
- 4157 RV350 AW [Fire GL T2]
- 4158 68800AX [Mach32]
-# The PCI ID is unrelated to any DVI output.
- 4164 R300 AD [Radeon 9500 Pro] (Secondary)
-# New PCI ID info provided by ATI developer relations
- 4165 R300 AE [Radeon 9700 Pro] (Secondary)
-# New PCI ID info provided by ATI developer relations
- 4166 R300 AF [Radeon 9700 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations
- 4168 Radeon R350 [Radeon 9800] (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
- 4170 RV350 AP [Radeon 9600] (Secondary)
- 1458 4025 Giga-Byte GV-R96128D Secondary
- 148c 2067 PowerColor R96A-C3N (Secondary)
- 174b 7c28 GC-R9600PRO Secondary [Sapphire]
- 17ee 2003 Radeon 9600 256Mb Secondary
- 18bc 0100 GC-R9600PRO Secondary
-# New PCI ID provided by ATI developer relations (correction to above)
- 4171 RV350 AQ [Radeon 9600] (Secondary)
- 1043 c005 A9600SE (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
- 4172 RV350 AR [Radeon 9600] (Secondary)
- 1002 0003 Radeon 9600XT (Secondary)
- 1043 c003 A9600XT (Secondary)
- 174b 7c28 Sapphire Radeon 9600XT (Secondary)
- 1787 4003 Radeon 9600 XT (Secondary)
- 4173 RV350 ?? [Radeon 9550] (Secondary)
- 4237 Radeon 7000 IGP
- 4242 R200 BB [Radeon All in Wonder 8500DV]
- 1002 02aa Radeon 8500 AIW DV Edition
- 4243 R200 BC [Radeon All in Wonder 8500]
- 4336 Radeon Mobility U1
- 103c 0024 Pavilion ze4400 builtin Video
- 4337 Radeon IGP 330M/340M/350M
- 1014 053a ThinkPad R40e (2684-HVG) builtin VGA controller
- 103c 0850 Radeon IGP 345M
- 4341 IXP150 AC'97 Audio Controller
- 4345 EHCI USB Controller
- 4347 OHCI USB Controller #1
- 4348 OHCI USB Controller #2
- 4349 ATI Dual Channel Bus Master PCI IDE Controller
- 434d IXP AC'97 Modem
- 4353 ATI SMBus
- 4354 215CT [Mach64 CT]
- 4358 210888CX [Mach64 CX]
- 4363 ATI SMBus
- 436e ATI 436E Serial ATA Controller
- 4372 ATI SMBus
- 4376 Standard Dual Channel PCI IDE Controller ATI
- 4379 ATI 4379 Serial ATA Controller
- 437a ATI 437A Serial ATA Controller
- 4437 Radeon Mobility 7000 IGP
- 4554 210888ET [Mach64 ET]
- 4654 Mach64 VT
- 4742 3D Rage Pro AGP 1X/2X
- 1002 0040 Rage Pro Turbo AGP 2X
- 1002 0044 Rage Pro Turbo AGP 2X
- 1002 0061 Rage Pro AIW AGP 2X
- 1002 0062 Rage Pro AIW AGP 2X
- 1002 0063 Rage Pro AIW AGP 2X
- 1002 0080 Rage Pro Turbo AGP 2X
- 1002 0084 Rage Pro Turbo AGP 2X
- 1002 4742 Rage Pro Turbo AGP 2X
- 1002 8001 Rage Pro Turbo AGP 2X
- 1028 0082 Rage Pro Turbo AGP 2X
- 1028 4082 Optiplex GX1 Onboard Display Adapter
- 1028 8082 Rage Pro Turbo AGP 2X
- 1028 c082 Rage Pro Turbo AGP 2X
- 8086 4152 Xpert 98D AGP 2X
- 8086 464a Rage Pro Turbo AGP 2X
- 4744 3D Rage Pro AGP 1X
- 1002 4744 Rage Pro Turbo AGP
- 4747 3D Rage Pro
- 4749 3D Rage Pro
- 1002 0061 Rage Pro AIW
- 1002 0062 Rage Pro AIW
- 474c Rage XC
- 474d Rage XL AGP 2X
- 1002 0004 Xpert 98 RXL AGP 2X
- 1002 0008 Xpert 98 RXL AGP 2X
- 1002 0080 Rage XL AGP 2X
- 1002 0084 Xpert 98 AGP 2X
- 1002 474d Rage XL AGP
- 1033 806a Rage XL AGP
- 474e Rage XC AGP
- 1002 474e Rage XC AGP
- 474f Rage XL
- 1002 0008 Rage XL
- 1002 474f Rage XL
- 4750 3D Rage Pro 215GP
- 1002 0040 Rage Pro Turbo
- 1002 0044 Rage Pro Turbo
- 1002 0080 Rage Pro Turbo
- 1002 0084 Rage Pro Turbo
- 1002 4750 Rage Pro Turbo
- 4751 3D Rage Pro 215GQ
- 4752 Rage XL
- 1002 0008 Rage XL
- 1002 4752 Rage XL
- 1002 8008 Rage XL
- 1028 00ce PowerEdge 1400
- 1028 00d1 PowerEdge 2550
- 1028 00d9 PowerEdge 2500
- 8086 3411 SDS2 Mainboard
- 8086 3427 S875WP1-E mainboard
- 4753 Rage XC
- 1002 4753 Rage XC
- 4754 3D Rage I/II 215GT [Mach64 GT]
- 4755 3D Rage II+ 215GTB [Mach64 GTB]
- 4756 3D Rage IIC 215IIC [Mach64 GT IIC]
- 1002 4756 Rage IIC
- 4757 3D Rage IIC AGP
- 1002 4757 Rage IIC AGP
- 1028 0089 Rage 3D IIC
- 1028 4082 Rage 3D IIC
- 1028 8082 Rage 3D IIC
- 1028 c082 Rage 3D IIC
- 4758 210888GX [Mach64 GX]
- 4759 3D Rage IIC
- 475a 3D Rage IIC AGP
- 1002 0084 Rage 3D Pro AGP 2x XPERT 98
- 1002 0087 Rage 3D IIC
- 1002 475a Rage IIC AGP
- 4964 Radeon RV250 Id [Radeon 9000]
- 4965 Radeon RV250 Ie [Radeon 9000]
- 4966 Radeon RV250 If [Radeon 9000]
- 10f1 0002 RV250 If [Tachyon G9000 PRO]
- 148c 2039 RV250 If [Radeon 9000 Pro "Evil Commando"]
- 1509 9a00 RV250 If [Radeon 9000 "AT009"]
-# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified.
- 1681 0040 RV250 If [3D prophet 9000]
- 174b 7176 RV250 If [Sapphire Radeon 9000 Pro]
- 174b 7192 RV250 If [Radeon 9000 "Atlantis"]
- 17af 2005 RV250 If [Excalibur Radeon 9000 Pro]
- 17af 2006 RV250 If [Excalibur Radeon 9000]
- 4967 Radeon RV250 Ig [Radeon 9000]
- 496e Radeon RV250 [Radeon 9000] (Secondary)
- 4a48 R420 JH [Radeon X800]
- 4a49 R420 JI [Radeon X800PRO]
- 4a4a R420 JJ [Radeon X800SE]
- 4a4b R420 JK [Radeon X800]
- 4a4c R420 JL [Radeon X800]
- 4a4d R420 JM [FireGL X3]
- 4a4e M18 JN [Radeon Mobility 9800]
- 4a50 R420 JP [Radeon X800XT]
- 4a70 R420 [X800XT-PE] (Secondary)
- 4c42 3D Rage LT Pro AGP-133
- 0e11 b0e7 Rage LT Pro (Compaq Presario 5240)
- 0e11 b0e8 Rage 3D LT Pro
- 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750)
- 1002 0040 Rage LT Pro AGP 2X
- 1002 0044 Rage LT Pro AGP 2X
- 1002 4c42 Rage LT Pro AGP 2X
- 1002 8001 Rage LT Pro AGP 2X
- 1028 0085 Rage 3D LT Pro
- 4c44 3D Rage LT Pro AGP-66
- 4c45 Rage Mobility M3 AGP
- 4c46 Rage Mobility M3 AGP 2x
- 1028 00b1 Latitude C600
- 4c47 3D Rage LT-G 215LG
- 4c49 3D Rage LT Pro
- 1002 0004 Rage LT Pro
- 1002 0040 Rage LT Pro
- 1002 0044 Rage LT Pro
- 1002 4c49 Rage LT Pro
- 4c4d Rage Mobility P/M AGP 2x
- 0e11 b111 Armada M700
- 0e11 b160 Armada E500
- 1002 0084 Xpert 98 AGP 2X (Mobility)
- 1014 0154 ThinkPad A20m
- 1028 00aa Latitude CPt
- 1028 00bb Latitude CPx
- 4c4e Rage Mobility L AGP 2x
- 4c50 3D Rage LT Pro
- 1002 4c50 Rage LT Pro
- 4c51 3D Rage LT Pro
- 4c52 Rage Mobility P/M
- 1033 8112 Versa Note VXi
- 4c53 Rage Mobility L
- 4c54 264LT [Mach64 LT]
- 4c57 Radeon Mobility M7 LW [Radeon Mobility 7500]
- 1014 0517 ThinkPad T30
- 1028 00e6 Radeon Mobility M7 LW (Dell Inspiron 8100)
- 1028 012a Latitude C640
- 144d c006 Radeon Mobility M7 LW in vpr Matrix 170B4
- 4c58 Radeon RV200 LX [Mobility FireGL 7800 M7]
- 4c59 Radeon Mobility M6 LY
- 1014 0235 ThinkPad A30/A30p (2652/2653)
- 1014 0239 ThinkPad X22/X23/X24
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 4c5a Radeon Mobility M6 LZ
- 4c64 Radeon R250 Ld [Radeon Mobility 9000 M9]
- 4c65 Radeon R250 Le [Radeon Mobility 9000 M9]
- 4c66 Radeon R250 Lf [FireGL 9000]
- 4c67 Radeon R250 Lg [Radeon Mobility 9000 M9]
-# Secondary chip to the Lf
- 4c6e Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary]
- 4d46 Rage Mobility M4 AGP
- 4d4c Rage Mobility M4 AGP
- 4e44 Radeon R300 ND [Radeon 9700 Pro]
- 4e45 Radeon R300 NE [Radeon 9500 Pro]
- 1002 0002 Radeon R300 NE [Radeon 9500 Pro]
- 1681 0002 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
-# New PCI ID provided by ATI developer relations (correction to above)
- 4e46 RV350 NF [Radeon 9600]
- 4e47 Radeon R300 NG [FireGL X1]
-# (added pro)
- 4e48 Radeon R350 [Radeon 9800 Pro]
-# New PCI ID provided by ATI developer relations
- 4e49 Radeon R350 [Radeon 9800]
- 4e4a RV350 NJ [Radeon 9800 XT]
- 4e4b R350 NK [Fire GL X2]
-# New PCI ID provided by ATI developer relations
- 4e50 RV350 [Mobility Radeon 9600 M10]
- 1025 005a TravelMate 290
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1734 1055 Amilo M1420W
- 4e51 M10 NQ [Radeon Mobility 9600]
- 4e52 RV350 [Mobility Radeon 9600 M10]
- 4e53 M10 NS [Radeon Mobility 9600]
- 4e54 M10 NT [FireGL Mobility T2]
- 4e56 M11 NV [FireGL Mobility T2e]
- 4e64 Radeon R300 [Radeon 9700 Pro] (Secondary)
- 4e65 Radeon R300 [Radeon 9500 Pro] (Secondary)
- 1002 0003 Radeon R300 NE [Radeon 9500 Pro]
- 1681 0003 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations (correction to above)
- 4e66 RV350 NF [Radeon 9600] (Secondary)
- 4e67 Radeon R300 [FireGL X1] (Secondary)
-# (added pro)
- 4e68 Radeon R350 [Radeon 9800 Pro] (Secondary)
-# New PCI ID provided by ATI developer relations
- 4e69 Radeon R350 [Radeon 9800] (Secondary)
- 4e6a RV350 NJ [Radeon 9800 XT] (Secondary)
- 1002 4e71 ATI Technologies Inc M10 NQ [Radeon Mobility 9600]
- 5041 Rage 128 PA/PRO
- 5042 Rage 128 PB/PRO AGP 2x
- 5043 Rage 128 PC/PRO AGP 4x
- 5044 Rage 128 PD/PRO TMDS
- 1002 0028 Rage 128 AIW
- 1002 0029 Rage 128 AIW
- 5045 Rage 128 PE/PRO AGP 2x TMDS
- 5046 Rage 128 PF/PRO AGP 4x TMDS
- 1002 0004 Rage Fury Pro
- 1002 0008 Rage Fury Pro/Xpert 2000 Pro
- 1002 0014 Rage Fury Pro
- 1002 0018 Rage Fury Pro/Xpert 2000 Pro
- 1002 0028 Rage 128 Pro AIW AGP
- 1002 002a Rage 128 Pro AIW AGP
- 1002 0048 Rage Fury Pro
- 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)
- 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
- 5047 Rage 128 PG/PRO
- 5048 Rage 128 PH/PRO AGP 2x
- 5049 Rage 128 PI/PRO AGP 4x
- 504a Rage 128 PJ/PRO TMDS
- 504b Rage 128 PK/PRO AGP 2x TMDS
- 504c Rage 128 PL/PRO AGP 4x TMDS
- 504d Rage 128 PM/PRO
- 504e Rage 128 PN/PRO AGP 2x
- 504f Rage 128 PO/PRO AGP 4x
- 5050 Rage 128 PP/PRO TMDS [Xpert 128]
- 1002 0008 Xpert 128
- 5051 Rage 128 PQ/PRO AGP 2x TMDS
- 5052 Rage 128 PR/PRO AGP 4x TMDS
- 5053 Rage 128 PS/PRO
- 5054 Rage 128 PT/PRO AGP 2x
- 5055 Rage 128 PU/PRO AGP 4x
- 5056 Rage 128 PV/PRO TMDS
- 5057 Rage 128 PW/PRO AGP 2x TMDS
- 5058 Rage 128 PX/PRO AGP 4x TMDS
- 5144 Radeon R100 QD [Radeon 7200]
- 1002 0008 Radeon 7000/Radeon VE
- 1002 0009 Radeon 7000/Radeon
- 1002 000a Radeon 7000/Radeon
- 1002 001a Radeon 7000/Radeon
- 1002 0029 Radeon AIW
- 1002 0038 Radeon 7000/Radeon
- 1002 0039 Radeon 7000/Radeon
- 1002 008a Radeon 7000/Radeon
- 1002 00ba Radeon 7000/Radeon
- 1002 0139 Radeon 7000/Radeon
- 1002 028a Radeon 7000/Radeon
- 1002 02aa Radeon AIW
- 1002 053a Radeon 7000/Radeon
- 5145 Radeon R100 QE
- 5146 Radeon R100 QF
- 5147 Radeon R100 QG
- 5148 Radeon R200 QH [Radeon 8500]
- 1002 010a FireGL 8800 64Mb
- 1002 0152 FireGL 8800 128Mb
- 1002 0162 FireGL 8700 32Mb
- 1002 0172 FireGL 8700 64Mb
- 5149 Radeon R200 QI
- 514a Radeon R200 QJ
- 514b Radeon R200 QK
- 514c Radeon R200 QL [Radeon 8500 LE]
- 1002 003a Radeon R200 QL [Radeon 8500 LE]
- 1002 013a Radeon 8500
- 148c 2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
- 1681 0010 Radeon 8500 [3D Prophet 8500 128Mb]
- 174b 7149 Radeon R200 QL [Sapphire Radeon 8500 LE]
- 514d Radeon R200 QM [Radeon 9100]
- 514e Radeon R200 QN [Radeon 8500LE]
- 514f Radeon R200 QO [Radeon 8500LE]
- 5154 R200 QT [Radeon 8500]
- 5155 R200 QU [Radeon 9100]
- 5157 Radeon RV200 QW [Radeon 7500]
- 1002 013a Radeon 7500
- 1002 103a Dell Optiplex GX260
- 1458 4000 RV200 QW [RADEON 7500 PRO MAYA AR]
- 148c 2024 RV200 QW [Radeon 7500LE Dual Display]
- 148c 2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
- 148c 2036 RV200 QW [Radeon 7500 PCI Dual Display]
- 174b 7146 RV200 QW [Radeon 7500 LE]
- 174b 7147 RV200 QW [Sapphire Radeon 7500LE]
- 174b 7161 Radeon RV200 QW [Radeon 7500 LE]
- 17af 0202 RV200 QW [Excalibur Radeon 7500LE]
- 5158 Radeon RV200 QX [Radeon 7500]
- 5159 Radeon RV100 QY [Radeon 7000/VE]
- 1002 000a Radeon 7000/Radeon VE
- 1002 000b Radeon 7000
- 1002 0038 Radeon 7000/Radeon VE
- 1002 003a Radeon 7000/Radeon VE
- 1002 00ba Radeon 7000/Radeon VE
- 1002 013a Radeon 7000/Radeon VE
- 1458 4002 RV100 QY [RADEON 7000 PRO MAYA AV Series]
- 148c 2003 RV100 QY [Radeon 7000 Multi-Display Edition]
- 148c 2023 RV100 QY [Radeon 7000 Evil Master Multi-Display]
- 174b 7112 RV100 QY [Sapphire Radeon VE 7000]
- 174b 7c28 Sapphire Radeon VE 7000 DDR
- 1787 0202 RV100 QY [Excalibur Radeon 7000]
- 515a Radeon RV100 QZ [Radeon 7000/VE]
- 5168 Radeon R200 Qh
- 5169 Radeon R200 Qi
- 516a Radeon R200 Qj
- 516b Radeon R200 Qk
-# This one is not in ATI documentation, but is in XFree86 source code
- 516c Radeon R200 Ql
- 5245 Rage 128 RE/SG
- 1002 0008 Xpert 128
- 1002 0028 Rage 128 AIW
- 1002 0029 Rage 128 AIW
- 1002 0068 Rage 128 AIW
- 5246 Rage 128 RF/SG AGP
- 1002 0004 Magnum/Xpert 128/Xpert 99
- 1002 0008 Magnum/Xpert128/X99/Xpert2000
- 1002 0028 Rage 128 AIW AGP
- 1002 0044 Rage Fury/Xpert 128/Xpert 2000
- 1002 0068 Rage 128 AIW AGP
- 1002 0448 Rage Fury
- 5247 Rage 128 RG
- 524b Rage 128 RK/VR
- 524c Rage 128 RL/VR AGP
- 1002 0008 Xpert 99/Xpert 2000
- 1002 0088 Xpert 99
- 5345 Rage 128 SE/4x
- 5346 Rage 128 SF/4x AGP 2x
- 1002 0048 RAGE 128 16MB VGA TVOUT AMC PAL
- 5347 Rage 128 SG/4x AGP 4x
- 5348 Rage 128 SH
- 534b Rage 128 SK/4x
- 534c Rage 128 SL/4x AGP 2x
- 534d Rage 128 SM/4x AGP 4x
- 1002 0008 Xpert 99/Xpert 2000
- 1002 0018 Xpert 2000
- 534e Rage 128 4x
- 5354 Mach 64 VT
- 1002 5654 Mach 64 reference
- 5446 Rage 128 Pro Ultra TF
- 1002 0004 Rage Fury Pro
- 1002 0008 Rage Fury Pro/Xpert 2000 Pro
- 1002 0018 Rage Fury Pro/Xpert 2000 Pro
- 1002 0028 Rage 128 AIW Pro AGP
- 1002 0029 Rage 128 AIW
- 1002 002a Rage 128 AIW Pro AGP
- 1002 002b Rage 128 AIW
- 1002 0048 Xpert 2000 Pro
- 544c Rage 128 Pro Ultra TL
- 5452 Rage 128 Pro Ultra TR
- 1002 001c Rage 128 Pro 4XL
- 103c 1279 Rage 128 Pro 4XL
- 5453 Rage 128 Pro Ultra TS
- 5454 Rage 128 Pro Ultra TT
- 5455 Rage 128 Pro Ultra TU
- 5460 M22 [Radeon Mobility M300]
- 5464 M22 [FireGL GL]
- 5548 R423 UH [Radeon X800 (PCIE)]
- 5549 R423 UI [Radeon X800PRO (PCIE)]
- 554a R423 UJ [Radeon X800LE (PCIE)]
- 554b R423 UK [Radeon X800SE (PCIE)]
- 5551 R423 UQ [FireGL V7200 (PCIE)]
- 5552 R423 UR [FireGL V5100 (PCIE)]
- 5554 R423 UT [FireGL V7100 (PCIE)]
- 556b Radeon R423 UK (PCIE) [X800 SE] (Secondary)
- 5654 264VT [Mach64 VT]
- 1002 5654 Mach64VT Reference
- 5655 264VT3 [Mach64 VT3]
- 5656 264VT4 [Mach64 VT4]
- 5830 RS300 Host Bridge
- 5831 RS300 Host Bridge
- 5832 RS300 Host Bridge
- 5833 Radeon 9100 IGP Host Bridge
- 5834 Radeon 9100 IGP
- 5835 RS300M AGP [Radeon Mobility 9100IGP]
- 5838 Radeon 9100 IGP AGP Bridge
- 5941 RV280 [Radeon 9200] (Secondary)
- 1458 4019 Gigabyte Radeon 9200
- 174b 7c12 Sapphire Radeon 9200
-# http://www.hightech.com.hk/html/9200.htm
- 17af 200d Excalibur Radeon 9200
- 18bc 0050 GeXcube GC-R9200-C3 (Secondary)
- 5944 RV280 [Radeon 9200 SE (PCI)]
- 5960 RV280 [Radeon 9200 PRO]
- 5961 RV280 [Radeon 9200]
- 1002 2f72 All-in-Wonder 9200 Series
- 1019 4c30 Radeon 9200 VIVO
- 12ab 5961 YUAN SMARTVGA Radeon 9200
- 1458 4018 Gigabyte Radeon 9200
- 174b 7c13 Sapphire Radeon 9200
-# http://www.hightech.com.hk/html/9200.htm
- 17af 200c Excalibur Radeon 9200
- 18bc 0050 Radeon 9200 Game Buster
- 18bc 0051 GeXcube GC-R9200-C3
- 18bc 0053 Radeon 9200 Game Buster VIVO
- 5962 RV280 [Radeon 9200]
- 5964 RV280 [Radeon 9200 SE]
- 1043 c006 ASUS Radeon 9200 SE / TD / 128M
- 1458 4018 Radeon 9200 SE
- 148c 2073 CN-AG92E
- 174b 7c13 Sapphire Radeon 9200 SE
- 1787 5964 Excalibur 9200SE VIVO 128M
- 17af 2012 Radeon 9200 SE Excalibur
- 18bc 0170 Sapphire Radeon 9200 SE 128MB Game Buster
-# 128MB DDR, DVI/VGA/TV out
- 18bc 0173 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
- 5b60 RV370 5B60 [Radeon X300 (PCIE)]
- 1043 002a Extreme AX300SE-X
- 1043 032e Extreme AX300/TD
- 5b62 RV370 5B62 [Radeon X600 (PCIE)]
- 5b64 RV370 5B64 [FireGL V3100 (PCIE)]
- 5b65 RV370 5B65 [FireGL D1100 (PCIE)]
- 5c61 M9+ 5C61 [Radeon Mobility 9200 (AGP)]
- 5c63 M9+ 5C63 [Radeon Mobility 9200 (AGP)]
- 5d44 RV280 [Radeon 9200 SE] (Secondary)
- 1458 4019 Radeon 9200 SE (Secondary)
- 174b 7c12 Sapphire Radeon 9200 SE (Secondary)
- 1787 5965 Excalibur 9200SE VIVO 128M (Secondary)
- 17af 2013 Radeon 9200 SE Excalibur (Secondary)
- 18bc 0171 Radeon 9200 SE 128MB Game Buster (Secondary)
- 18bc 0172 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
- 5d4d R480 [Radeon X850XT Platinum]
- 5d57 R423 5F57 [Radeon X800XT (PCIE)]
- 700f PCI Bridge [IGP 320M]
- 7010 PCI Bridge [IGP 340M]
- 7834 Radeon 9100 PRO IGP
- 7835 Radeon Mobility 9200 IGP
- 7c37 RV350 AQ [Radeon 9600 SE]
- cab0 AGP Bridge [IGP 320M]
- cab2 RS200/RS200M AGP Bridge [IGP 340M]
- cbb2 RS200/RS200M AGP Bridge [IGP 340M]
-1003 ULSI Systems
- 0201 US201
-1004 VLSI Technology Inc
- 0005 82C592-FC1
- 0006 82C593-FC1
- 0007 82C594-AFC2
- 0008 82C596/7 [Wildcat]
- 0009 82C597-AFC2
- 000c 82C541 [Lynx]
- 000d 82C543 [Lynx]
- 0101 82C532
- 0102 82C534 [Eagle]
- 0103 82C538
- 0104 82C535
- 0105 82C147
- 0200 82C975
- 0280 82C925
- 0304 QSound ThunderBird PCI Audio
- 1004 0304 QSound ThunderBird PCI Audio
- 122d 1206 DSP368 Audio
- 1483 5020 XWave Thunder 3D Audio
- 0305 QSound ThunderBird PCI Audio Gameport
- 1004 0305 QSound ThunderBird PCI Audio Gameport
- 122d 1207 DSP368 Audio Gameport
- 1483 5021 XWave Thunder 3D Audio Gameport
- 0306 QSound ThunderBird PCI Audio Support Registers
- 1004 0306 QSound ThunderBird PCI Audio Support Registers
- 122d 1208 DSP368 Audio Support Registers
- 1483 5022 XWave Thunder 3D Audio Support Registers
- 0307 Thunderbird
- 0308 Thunderbird
- 0702 VAS96011 [Golden Gate II]
- 0703 Tollgate
-1005 Avance Logic Inc. [ALI]
- 2064 ALG2032/2064
- 2128 ALG2364A
- 2301 ALG2301
- 2302 ALG2302
- 2364 ALG2364
- 2464 ALG2364A
- 2501 ALG2564A/25128A
-1006 Reply Group
-1007 NetFrame Systems Inc
-1008 Epson
-100a Phoenix Technologies
-100b National Semiconductor Corporation
- 0001 DP83810
- 0002 87415/87560 IDE
- 000e 87560 Legacy I/O
- 000f FireWire Controller
- 0011 NS87560 National PCI System I/O
- 0012 USB Controller
- 0020 DP83815 (MacPhyter) Ethernet Controller
- 103c 0024 Pavilion ze4400 builtin Network
- 1385 f311 FA311 / FA312 (FA311 with WoL HW)
- 0022 DP83820 10/100/1000 Ethernet Controller
- 0028 Geode GX2 Host Bridge
- 002a CS5535 South Bridge
- 002b CS5535 ISA bridge
- 002d CS5535 IDE
- 002e CS5535 Audio
- 002f CS5535 USB
- 0030 Geode GX2 Graphics Processor
- 0035 DP83065 [Saturn] 10/100/1000 Ethernet Controller
- 0500 SCx200 Bridge
- 0501 SCx200 SMI
- 0502 SCx200 IDE
- 0503 SCx200 Audio
- 0504 SCx200 Video
- 0505 SCx200 XBus
- 0510 SC1100 Bridge
- 0511 SC1100 SMI
- 0515 SC1100 XBus
- d001 87410 IDE
-100c Tseng Labs Inc
- 3202 ET4000/W32p rev A
- 3205 ET4000/W32p rev B
- 3206 ET4000/W32p rev C
- 3207 ET4000/W32p rev D
- 3208 ET6000
- 4702 ET6300
-100d AST Research Inc
-100e Weitek
- 9000 P9000 Viper
- 9001 P9000 Viper
- 9002 P9000 Viper
- 9100 P9100 Viper Pro/SE
-1010 Video Logic, Ltd.
-1011 Digital Equipment Corporation
- 0001 DECchip 21050
- 0002 DECchip 21040 [Tulip]
- 0004 DECchip 21030 [TGA]
- 0007 NVRAM [Zephyr NVRAM]
- 0008 KZPSA [KZPSA]
- 0009 DECchip 21140 [FasterNet]
- 1025 0310 21140 Fast Ethernet
- 10b8 2001 SMC9332BDT EtherPower 10/100
- 10b8 2002 SMC9332BVT EtherPower T4 10/100
- 10b8 2003 SMC9334BDT EtherPower 10/100 (1-port)
- 1109 2400 ANA-6944A/TX Fast Ethernet
- 1112 2300 RNS2300 Fast Ethernet
- 1112 2320 RNS2320 Fast Ethernet
- 1112 2340 RNS2340 Fast Ethernet
- 1113 1207 EN-1207-TX Fast Ethernet
- 1186 1100 DFE-500TX Fast Ethernet
- 1186 1112 DFE-570TX Fast Ethernet
- 1186 1140 DFE-660 Cardbus Ethernet 10/100
- 1186 1142 DFE-660 Cardbus Ethernet 10/100
- 11f6 0503 Freedomline Fast Ethernet
- 1282 9100 AEF-380TXD Fast Ethernet
- 1385 1100 FA310TX Fast Ethernet
- 2646 0001 KNE100TX Fast Ethernet
- 000a 21230 Video Codec
- 000d PBXGB [TGA2]
- 000f DEFPA
- 0014 DECchip 21041 [Tulip Pass 3]
- 1186 0100 DE-530+
- 0016 DGLPB [OPPO]
- 0017 PV-PCI Graphics Controller (ZLXp-L)
- 0019 DECchip 21142/43
- 1011 500a DE500A Fast Ethernet
- 1011 500b DE500B Fast Ethernet
- 1014 0001 10/100 EtherJet Cardbus
- 1025 0315 ALN315 Fast Ethernet
- 1033 800c PC-9821-CS01 100BASE-TX Interface Card
- 1033 800d PC-9821NR-B06 100BASE-TX Interface Card
- 108d 0016 Rapidfire 2327 10/100 Ethernet
- 108d 0017 GoCard 2250 Ethernet 10/100 Cardbus
- 10b8 2005 SMC8032DT Extreme Ethernet 10/100
- 10b8 8034 SMC8034 Extreme Ethernet 10/100
- 10ef 8169 Cardbus Fast Ethernet
- 1109 2a00 ANA-6911A/TX Fast Ethernet
- 1109 2b00 ANA-6911A/TXC Fast Ethernet
- 1109 3000 ANA-6922/TX Fast Ethernet
- 1113 1207 Cheetah Fast Ethernet
- 1113 2220 Cardbus Fast Ethernet
- 115d 0002 Cardbus Ethernet 10/100
- 1179 0203 Fast Ethernet
- 1179 0204 Cardbus Fast Ethernet
- 1186 1100 DFE-500TX Fast Ethernet
- 1186 1101 DFE-500TX Fast Ethernet
- 1186 1102 DFE-500TX Fast Ethernet
- 1186 1112 DFE-570TX Quad Fast Ethernet
- 1259 2800 AT-2800Tx Fast Ethernet
- 1266 0004 Eagle Fast EtherMAX
- 12af 0019 NetFlyer Cardbus Fast Ethernet
- 1374 0001 Cardbus Ethernet Card 10/100
- 1374 0002 Cardbus Ethernet Card 10/100
- 1374 0007 Cardbus Ethernet Card 10/100
- 1374 0008 Cardbus Ethernet Card 10/100
- 1385 2100 FA510
- 1395 0001 10/100 Ethernet CardBus PC Card
- 13d1 ab01 EtherFast 10/100 Cardbus (PCMPC200)
- 14cb 0100 LNDL-100N 100Base-TX Ethernet PC Card
- 8086 0001 EtherExpress PRO/100 Mobile CardBus 32
- 001a Farallon PN9000SX Gigabit Ethernet
- 0021 DECchip 21052
- 0022 DECchip 21150
- 0023 DECchip 21150
- 0024 DECchip 21152
- 0025 DECchip 21153
- 0026 DECchip 21154
- 0034 56k Modem Cardbus
- 1374 0003 56k Modem Cardbus
- 0045 DECchip 21553
- 0046 DECchip 21554
- 0e11 4050 Integrated Smart Array
- 0e11 4051 Integrated Smart Array
- 0e11 4058 Integrated Smart Array
- 103c 10c2 Hewlett-Packard NetRAID-4M
- 12d9 000a IP Telephony card
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- 9005 0364 5400S (Mustang)
- 9005 0365 5400S (Mustang)
- 9005 1364 Dell PowerEdge RAID Controller 2
- 9005 1365 Dell PowerEdge RAID Controller 2
- e4bf 1000 CC8-1-BLUES
- 1065 StrongARM DC21285
- 1069 0020 DAC960P / DAC1164P
-1012 Micronics Computers Inc
-1013 Cirrus Logic
- 0038 GD 7548
- 0040 GD 7555 Flat Panel GUI Accelerator
- 004c GD 7556 Video/Graphics LCD/CRT Ctrlr
- 00a0 GD 5430/40 [Alpine]
- 00a2 GD 5432 [Alpine]
- 00a4 GD 5434-4 [Alpine]
- 00a8 GD 5434-8 [Alpine]
- 00ac GD 5436 [Alpine]
- 00b0 GD 5440
- 00b8 GD 5446
- 00bc GD 5480
- 1013 00bc CL-GD5480
- 00d0 GD 5462
- 00d2 GD 5462 [Laguna I]
- 00d4 GD 5464 [Laguna]
- 00d5 GD 5464 BD [Laguna]
- 00d6 GD 5465 [Laguna]
- 13ce 8031 Barco Metheus 2 Megapixel, Dual Head
- 13cf 8031 Barco Metheus 2 Megapixel, Dual Head
- 00e8 GD 5436U
- 1100 CL 6729
- 1110 PD 6832 PCMCIA/CardBus Ctrlr
- 1112 PD 6834 PCMCIA/CardBus Ctrlr
- 1113 PD 6833 PCMCIA/CardBus Ctrlr
- 1200 GD 7542 [Nordic]
- 1202 GD 7543 [Viking]
- 1204 GD 7541 [Nordic Light]
- 4000 MD 5620 [CLM Data Fax Voice]
- 4400 CD 4400
- 6001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
- 1014 1010 CS4610 SoundFusion Audio Accelerator
- 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
- 1013 4280 Crystal SoundFusion PCI Audio Accelerator
- 153b 1136 SiXPack 5.1+
- 1681 0050 Game Theater XP
- 1681 a011 Fortissimo III 7.1
- 6004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
- 6005 Crystal CS4281 PCI Audio
- 1013 4281 Crystal CS4281 PCI Audio
- 10cf 10a8 Crystal CS4281 PCI Audio
- 10cf 10a9 Crystal CS4281 PCI Audio
- 10cf 10aa Crystal CS4281 PCI Audio
- 10cf 10ab Crystal CS4281 PCI Audio
- 10cf 10ac Crystal CS4281 PCI Audio
- 10cf 10ad Crystal CS4281 PCI Audio
- 10cf 10b4 Crystal CS4281 PCI Audio
- 1179 0001 Crystal CS4281 PCI Audio
- 14c0 000c Crystal CS4281 PCI Audio
-1014 IBM
- 0002 PCI to MCA Bridge
- 0005 Alta Lite
- 0007 Alta MP
- 000a Fire Coral
- 0017 CPU to PCI Bridge
- 0018 TR Auto LANstreamer
- 001b GXT-150P
- 001c Carrera
- 001d 82G2675
- 0020 GXT1000 Graphics Adapter
- 0022 IBM27-82351
- 002d Python
-# [official name in AIX 5]
- 002e SCSI RAID Adapter [ServeRAID]
- 1014 002e ServeRAID-3x
- 1014 022e ServeRAID-4H
- 0031 2 Port Serial Adapter
-# AS400 iSeries PCI sync serial card
- 1014 0031 2721 WAN IOA - 2 Port Sync Serial Adapter
- 0036 Miami
- 0037 82660 CPU to PCI Bridge
- 003a CPU to PCI Bridge
- 003c GXT250P/GXT255P Graphics Adapter
- 003e 16/4 Token ring UTP/STP controller
- 1014 003e Token-Ring Adapter
- 1014 00cd Token-Ring Adapter + Wake-On-LAN
- 1014 00ce 16/4 Token-Ring Adapter 2
- 1014 00cf 16/4 Token-Ring Adapter Special
- 1014 00e4 High-Speed 100/16/4 Token-Ring Adapter
- 1014 00e5 16/4 Token-Ring Adapter 2 + Wake-On-LAN
- 1014 016d iSeries 2744 Card
- 0045 SSA Adapter
- 0046 MPIC interrupt controller
- 0047 PCI to PCI Bridge
- 0048 PCI to PCI Bridge
- 0049 Warhead SCSI Controller
- 004e ATM Controller (14104e00)
- 004f ATM Controller (14104f00)
- 0050 ATM Controller (14105000)
- 0053 25 MBit ATM Controller
- 0054 GXT500P/GXT550P Graphics Adapter
- 0057 MPEG PCI Bridge
- 005c i82557B 10/100
- 005e GXT800P Graphics Adapter
- 007c ATM Controller (14107c00)
- 007d 3780IDSP [MWave]
- 008b EADS PCI to PCI Bridge
- 008e GXT3000P Graphics Adapter
- 0090 GXT 3000P
- 1014 008e GXT-3000P
- 0091 SSA Adapter
- 0095 20H2999 PCI Docking Bridge
- 0096 Chukar chipset SCSI controller
- 1014 0097 iSeries 2778 DASD IOA
- 1014 0098 iSeries 2763 DASD IOA
- 1014 0099 iSeries 2748 DASD IOA
- 009f PCI 4758 Cryptographic Accelerator
- 00a5 ATM Controller (1410a500)
- 00a6 ATM 155MBPS MM Controller (1410a600)
- 00b7 256-bit Graphics Rasterizer [Fire GL1]
- 1092 00b8 FireGL1 AGP 32Mb
- 00b8 GXT2000P Graphics Adapter
- 00be ATM 622MBPS Controller (1410be00)
- 00dc Advanced Systems Management Adapter (ASMA)
- 00fc CPC710 Dual Bridge and Memory Controller (PCI-64)
- 0104 Gigabit Ethernet-SX Adapter
- 0105 CPC710 Dual Bridge and Memory Controller (PCI-32)
- 010f Remote Supervisor Adapter (RSA)
- 0142 Yotta Video Compositor Input
- 1014 0143 Yotta Input Controller (ytin)
- 0144 Yotta Video Compositor Output
- 1014 0145 Yotta Output Controller (ytout)
- 0156 405GP PLB to PCI Bridge
- 015e 622Mbps ATM PCI Adapter
- 0160 64bit/66MHz PCI ATM 155 MMF
- 016e GXT4000P Graphics Adapter
- 0170 GXT6000P Graphics Adapter
- 017d GXT300P Graphics Adapter
- 0180 Snipe chipset SCSI controller
- 1014 0241 iSeries 2757 DASD IOA
- 1014 0264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
- 0188 EADS-X PCI-X to PCI-X Bridge
- 01a7 PCI-X to PCI-X Bridge
- 01bd ServeRAID Controller
- 1014 01be ServeRAID-4M
- 1014 01bf ServeRAID-4L
- 1014 0208 ServeRAID-4Mx
- 1014 020e ServeRAID-4Lx
- 1014 022e ServeRAID-4H
- 1014 0258 ServeRAID-5i
- 1014 0259 ServeRAID-5i
- 01c1 64bit/66MHz PCI ATM 155 UTP
- 01e6 Cryptographic Accelerator
- 01ff 10/100 Mbps Ethernet
- 0219 Multiport Serial Adapter
- 1014 021a Dual RVX
- 1014 0251 Internal Modem/RVX
- 1014 0252 Quad Internal Modem
- 021b GXT6500P Graphics Adapter
- 021c GXT4500P Graphics Adapter
- 0233 GXT135P Graphics Adapter
- 0266 PCI-X Dual Channel SCSI
- 0268 Gigabit Ethernet-SX Adapter (PCI-X)
- 0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
- 028c Citrine chipset SCSI controller
- 1014 028D Dual Channel PCI-X DDR SAS RAID Adapter (572E)
- 1014 02BE Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
- 1014 02C0 Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
- 0302 X-Architecture Bridge [Summit]
- 0314 ZISC 036 Neural accelerator card
- ffff MPIC-2 interrupt controller
-1015 LSI Logic Corp of Canada
-1016 ICL Personal Systems
-1017 SPEA Software AG
- 5343 SPEA 3D Accelerator
-1018 Unisys Systems
-1019 Elitegroup Computer Systems
-101a AT&T GIS (NCR)
- 0005 100VG ethernet
-101b Vitesse Semiconductor
-101c Western Digital
- 0193 33C193A
- 0196 33C196A
- 0197 33C197A
- 0296 33C296A
- 3193 7193
- 3197 7197
- 3296 33C296A
- 4296 34C296
- 9710 Pipeline 9710
- 9712 Pipeline 9712
- c24a 90C
-101e American Megatrends Inc.
- 1960 MegaRAID
- 101e 0471 MegaRAID 471 Enterprise 1600 RAID Controller
- 101e 0475 MegaRAID 475 Express 500/500LC RAID Controller
- 101e 0477 MegaRAID 477 Elite 3100 RAID Controller
- 101e 0493 MegaRAID 493 Elite 1600 RAID Controller
- 101e 0494 MegaRAID 494 Elite 1650 RAID Controller
- 101e 0503 MegaRAID 503 Enterprise 1650 RAID Controller
- 101e 0511 MegaRAID 511 i4 IDE RAID Controller
- 101e 0522 MegaRAID 522 i4133 RAID Controller
- 1028 0471 PowerEdge RAID Controller 3/QC
- 1028 0475 PowerEdge RAID Controller 3/SC
- 1028 0493 PowerEdge RAID Controller 3/DC
- 1028 0511 PowerEdge Cost Effective RAID Controller ATA100/4Ch
- 9010 MegaRAID 428 Ultra RAID Controller
- 9030 EIDE Controller
- 9031 EIDE Controller
- 9032 EIDE & SCSI Controller
- 9033 SCSI Controller
- 9040 Multimedia card
- 9060 MegaRAID 434 Ultra GT RAID Controller
- 9063 MegaRAC
- 101e 0767 Dell Remote Assistant Card 2
-101f PictureTel
-1020 Hitachi Computer Products
-1021 OKI Electric Industry Co. Ltd.
-1022 Advanced Micro Devices [AMD]
- 1100 K8 [Athlon64/Opteron] HyperTransport Technology Configuration
- 1101 K8 [Athlon64/Opteron] Address Map
- 1102 K8 [Athlon64/Opteron] DRAM Controller
- 1103 K8 [Athlon64/Opteron] Miscellaneous Control
- 2000 79c970 [PCnet32 LANCE]
- 1014 2000 NetFinity 10/100 Fast Ethernet
- 1022 2000 PCnet - Fast 79C971
- 103c 104c Ethernet with LAN remote power Adapter
- 103c 1064 Ethernet with LAN remote power Adapter
- 103c 1065 Ethernet with LAN remote power Adapter
- 103c 106c Ethernet with LAN remote power Adapter
- 103c 106e Ethernet with LAN remote power Adapter
- 103c 10ea Ethernet with LAN remote power Adapter
- 1113 1220 EN1220 10/100 Fast Ethernet
- 1259 2450 AT-2450 10/100 Fast Ethernet
- 1259 2454 AT-2450v4 10Mb Ethernet Adapter
- 1259 2700 AT-2700TX 10/100 Fast Ethernet
- 1259 2701 AT-2700FX 100Mb Ethernet
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 4c53 1010 CP5/CR6 mainboard
- 4c53 1020 VR6 mainboard
- 4c53 1030 PC5 mainboard
- 4c53 1040 CL7 mainboard
- 4c53 1060 PC7 mainboard
- 2001 79c978 [HomePNA]
- 1092 0a78 Multimedia Home Network Adapter
- 1668 0299 ActionLink Home Network Adapter
- 2003 Am 1771 MBW [Alchemy]
- 2020 53c974 [PCscsi]
- 2040 79c974
- 3000 ELanSC520 Microcontroller
- 7006 AMD-751 [Irongate] System Controller
- 7007 AMD-751 [Irongate] AGP Bridge
- 700a AMD-IGR4 AGP Host to PCI Bridge
- 700b AMD-IGR4 PCI to PCI Bridge
- 700c AMD-760 MP [IGD4-2P] System Controller
- 700d AMD-760 MP [IGD4-2P] AGP Bridge
- 700e AMD-760 [IGD4-1P] System Controller
- 700f AMD-760 [IGD4-1P] AGP Bridge
- 7400 AMD-755 [Cobra] ISA
- 7401 AMD-755 [Cobra] IDE
- 7403 AMD-755 [Cobra] ACPI
- 7404 AMD-755 [Cobra] USB
- 7408 AMD-756 [Viper] ISA
- 7409 AMD-756 [Viper] IDE
- 740b AMD-756 [Viper] ACPI
- 740c AMD-756 [Viper] USB
- 7410 AMD-766 [ViperPlus] ISA
- 7411 AMD-766 [ViperPlus] IDE
- 7413 AMD-766 [ViperPlus] ACPI
- 7414 AMD-766 [ViperPlus] USB
- 7440 AMD-768 [Opus] ISA
- 1043 8044 A7M-D Mainboard
- 7441 AMD-768 [Opus] IDE
- 7443 AMD-768 [Opus] ACPI
- 1043 8044 A7M-D Mainboard
- 7445 AMD-768 [Opus] Audio
- 7446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
- 7448 AMD-768 [Opus] PCI
- 7449 AMD-768 [Opus] USB
- 7450 AMD-8131 PCI-X Bridge
- 7451 AMD-8131 PCI-X APIC
- 7454 AMD-8151 System Controller
- 7455 AMD-8151 AGP Bridge
- 7460 AMD-8111 PCI
- 161f 3017 HDAMB
- 7461 AMD-8111 USB
- 7462 AMD-8111 Ethernet
- 7464 AMD-8111 USB
- 161f 3017 HDAMB
- 7468 AMD-8111 LPC
- 161f 3017 HDAMB
- 7469 AMD-8111 IDE
- 161f 3017 HDAMB
- 746a AMD-8111 SMBus 2.0
- 746b AMD-8111 ACPI
- 161f 3017 HDAMB
- 746d AMD-8111 AC97 Audio
- 161f 3017 HDAMB
- 746e AMD-8111 MC97 Modem
- 756b AMD-8111 ACPI
-1023 Trident Microsystems
- 0194 82C194
- 2000 4DWave DX
- 2001 4DWave NX
- 122d 1400 Trident PCI288-Q3DII (NX)
- 2100 CyberBlade XP4m32
- 2200 XGI Volari XP5
- 8400 CyberBlade/i7
- 1023 8400 CyberBlade i7 AGP
- 8420 CyberBlade/i7d
- 0e11 b15a CyberBlade i7 AGP
- 8500 CyberBlade/i1
- 8520 CyberBlade i1
- 0e11 b16e CyberBlade i1 AGP
- 1023 8520 CyberBlade i1 AGP
- 8620 CyberBlade/i1
- 1014 0502 ThinkPad R30/T30
- 8820 CyberBlade XPAi1
- 9320 TGUI 9320
- 9350 GUI Accelerator
- 9360 Flat panel GUI Accelerator
- 9382 Cyber 9382 [Reference design]
- 9383 Cyber 9383 [Reference design]
- 9385 Cyber 9385 [Reference design]
- 9386 Cyber 9386
- 9388 Cyber 9388
- 9397 Cyber 9397
- 939a Cyber 9397DVD
- 9420 TGUI 9420
- 9430 TGUI 9430
- 9440 TGUI 9440
- 9460 TGUI 9460
- 9470 TGUI 9470
- 9520 Cyber 9520
- 9525 Cyber 9525
- 10cf 1094 Lifebook C6155
- 9540 Cyber 9540
- 9660 TGUI 9660/938x/968x
- 9680 TGUI 9680
- 9682 TGUI 9682
- 9683 TGUI 9683
- 9685 ProVIDIA 9685
- 9750 3DImage 9750
- 1014 9750 3DImage 9750
- 1023 9750 3DImage 9750
- 9753 TGUI 9753
- 9754 TGUI 9754
- 9759 TGUI 975
- 9783 TGUI 9783
- 9785 TGUI 9785
- 9850 3DImage 9850
- 9880 Blade 3D PCI/AGP
- 1023 9880 Blade 3D
- 9910 CyberBlade/XP
- 9930 CyberBlade/XPm
-1024 Zenith Data Systems
-1025 Acer Incorporated [ALI]
- 1435 M1435
- 1445 M1445
- 1449 M1449
- 1451 M1451
- 1461 M1461
- 1489 M1489
- 1511 M1511
- 1512 ALI M1512 Aladdin
- 1513 M1513
- 1521 ALI M1521 Aladdin III CPU Bridge
- 10b9 1521 ALI M1521 Aladdin III CPU Bridge
- 1523 ALI M1523 ISA Bridge
- 10b9 1523 ALI M1523 ISA Bridge
- 1531 M1531 Northbridge [Aladdin IV/IV+]
- 1533 M1533 PCI-to-ISA Bridge
- 10b9 1533 ALI M1533 Aladdin IV/V ISA South Bridge
- 1535 M1535 PCI Bridge + Super I/O + FIR
- 1541 M1541 Northbridge [Aladdin V]
- 10b9 1541 ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
- 1542 M1542 Northbridge [Aladdin V]
- 1543 M1543 PCI-to-ISA Bridge + Super I/O + FIR
- 1561 M1561 Northbridge [Aladdin 7]
- 1621 M1621 Northbridge [Aladdin-Pro II]
- 1631 M1631 Northbridge+3D Graphics [Aladdin TNT2]
- 1641 M1641 Northbridge [Aladdin-Pro IV]
- 1647 M1647 [MaGiK1] PCI North Bridge
- 1671 M1671 Northbridge [ALADDiN-P4]
- 1672 Northbridge [CyberALADDiN-P4]
- 3141 M3141
- 3143 M3143
- 3145 M3145
- 3147 M3147
- 3149 M3149
- 3151 M3151
- 3307 M3307 MPEG-I Video Controller
- 3309 M3309 MPEG-II Video w/ Software Audio Decoder
- 3321 M3321 MPEG-II Audio/Video Decoder
- 5212 M4803
- 5215 ALI PCI EIDE Controller
- 5217 M5217H
- 5219 M5219
- 5225 M5225
- 5229 M5229
- 5235 M5235
- 5237 M5237 PCI USB Host Controller
- 5240 EIDE Controller
- 5241 PCMCIA Bridge
- 5242 General Purpose Controller
- 5243 PCI to PCI Bridge Controller
- 5244 Floppy Disk Controller
- 5247 M1541 PCI to PCI Bridge
- 5251 M5251 P1394 Controller
- 5427 PCI to AGP Bridge
- 5451 M5451 PCI AC-Link Controller Audio Device
- 5453 M5453 PCI AC-Link Controller Modem Device
- 7101 M7101 PCI PMU Power Management Controller
- 10b9 7101 M7101 PCI PMU Power Management Controller
-1028 Dell
- 0001 PowerEdge Expandable RAID Controller 2/Si
- 1028 0001 PowerEdge 2400
- 0002 PowerEdge Expandable RAID Controller 3/Di
- 1028 0002 PowerEdge 4400
- 0003 PowerEdge Expandable RAID Controller 3/Si
- 1028 0003 PowerEdge 2450
- 0006 PowerEdge Expandable RAID Controller 3/Di
- 0007 Remote Access Card III
- 0008 Remote Access Card III
- 0009 Remote Access Card III: BMC/SMIC device not present
- 000a PowerEdge Expandable RAID Controller 3/Di
- 000c Embedded Remote Access or ERA/O
- 000d Embedded Remote Access: BMC/SMIC device
- 000e PowerEdge Expandable RAID controller 4/Di
- 000f PowerEdge Expandable RAID controller 4/Di
- 0010 Remote Access Card 4
- 0011 Remote Access Card 4 Daughter Card
- 0012 Remote Access Card 4 Daughter Card Virtual UART
- 0013 PowerEdge Expandable RAID controller 4
- 1028 016c PowerEdge Expandable RAID Controller 4e/Si
- 1028 016d PowerEdge Expandable RAID Controller 4e/Di
- 1028 016e PowerEdge Expandable RAID Controller 4e/Di
- 1028 016f PowerEdge Expandable RAID Controller 4e/Di
- 1028 0170 PowerEdge Expandable RAID Controller 4e/Di
- 0014 Remote Access Card 4 Daughter Card SMIC interface
-1029 Siemens Nixdorf IS
-102a LSI Logic
- 0000 HYDRA
- 0010 ASPEN
- 001f AHA-2940U2/U2W /7890/7891 SCSI Controllers
- 9005 000f 2940U2W SCSI Controller
- 9005 0106 2940U2W SCSI Controller
- 9005 a180 2940U2W SCSI Controller
- 00c5 AIC-7899 U160/m SCSI Controller
- 1028 00c5 PowerEdge 2550/2650/4600
- 00cf AIC-7899P U160/m
- 1028 0106 PowerEdge 4600
- 1028 0121 PowerEdge 2650
-102b Matrox Graphics, Inc.
-# DJ: I've a suspicion that 0010 is a duplicate of 0d10.
- 0010 MGA-I [Impression?]
- 0100 MGA 1064SG [Mystique]
- 0518 MGA-II [Athena]
- 0519 MGA 2064W [Millennium]
- 051a MGA 1064SG [Mystique]
- 102b 0100 MGA-1064SG Mystique
- 102b 1100 MGA-1084SG Mystique
- 102b 1200 MGA-1084SG Mystique
- 1100 102b MGA-1084SG Mystique
- 110a 0018 Scenic Pro C5 (D1025)
- 051b MGA 2164W [Millennium II]
- 102b 051b MGA-2164W Millennium II
- 102b 1100 MGA-2164W Millennium II
- 102b 1200 MGA-2164W Millennium II
- 051e MGA 1064SG [Mystique] AGP
- 051f MGA 2164W [Millennium II] AGP
- 0520 MGA G200
- 102b dbc2 G200 Multi-Monitor
- 102b dbc8 G200 Multi-Monitor
- 102b dbe2 G200 Multi-Monitor
- 102b dbe8 G200 Multi-Monitor
- 102b ff03 Millennium G200 SD
- 102b ff04 Marvel G200
- 0521 MGA G200 AGP
- 1014 ff03 Millennium G200 AGP
- 102b 48e9 Mystique G200 AGP
- 102b 48f8 Millennium G200 SD AGP
- 102b 4a60 Millennium G200 LE AGP
- 102b 4a64 Millennium G200 AGP
- 102b c93c Millennium G200 AGP
- 102b c9b0 Millennium G200 AGP
- 102b c9bc Millennium G200 AGP
- 102b ca60 Millennium G250 LE AGP
- 102b ca6c Millennium G250 AGP
- 102b dbbc Millennium G200 AGP
- 102b dbc2 Millennium G200 MMS (Dual G200)
- 102b dbc3 G200 Multi-Monitor
- 102b dbc8 Millennium G200 MMS (Dual G200)
- 102b dbd2 G200 Multi-Monitor
- 102b dbd3 G200 Multi-Monitor
- 102b dbd4 G200 Multi-Monitor
- 102b dbd5 G200 Multi-Monitor
- 102b dbd8 G200 Multi-Monitor
- 102b dbd9 G200 Multi-Monitor
- 102b dbe2 Millennium G200 MMS (Quad G200)
- 102b dbe3 G200 Multi-Monitor
- 102b dbe8 Millennium G200 MMS (Quad G200)
- 102b dbf2 G200 Multi-Monitor
- 102b dbf3 G200 Multi-Monitor
- 102b dbf4 G200 Multi-Monitor
- 102b dbf5 G200 Multi-Monitor
- 102b dbf8 G200 Multi-Monitor
- 102b dbf9 G200 Multi-Monitor
- 102b f806 Mystique G200 Video AGP
- 102b ff00 MGA-G200 AGP
- 102b ff02 Mystique G200 AGP
- 102b ff03 Millennium G200 AGP
- 102b ff04 Marvel G200 AGP
- 110a 0032 MGA-G200 AGP
- 0525 MGA G400 AGP
- 0e11 b16f MGA-G400 AGP
- 102b 0328 Millennium G400 16Mb SDRAM
- 102b 0338 Millennium G400 16Mb SDRAM
- 102b 0378 Millennium G400 32Mb SDRAM
- 102b 0541 Millennium G450 Dual Head
- 102b 0542 Millennium G450 Dual Head LX
- 102b 0543 Millennium G450 Single Head LX
- 102b 0641 Millennium G450 32Mb SDRAM Dual Head
- 102b 0642 Millennium G450 32Mb SDRAM Dual Head LX
- 102b 0643 Millennium G450 32Mb SDRAM Single Head LX
- 102b 07c0 Millennium G450 Dual Head LE
- 102b 07c1 Millennium G450 SDR Dual Head LE
- 102b 0d41 Millennium G450 Dual Head PCI
- 102b 0d42 Millennium G450 Dual Head LX PCI
- 102b 0d43 Millennium G450 32Mb Dual Head PCI
- 102b 0e00 Marvel G450 eTV
- 102b 0e01 Marvel G450 eTV
- 102b 0e02 Marvel G450 eTV
- 102b 0e03 Marvel G450 eTV
- 102b 0f80 Millennium G450 Low Profile
- 102b 0f81 Millennium G450 Low Profile
- 102b 0f82 Millennium G450 Low Profile DVI
- 102b 0f83 Millennium G450 Low Profile DVI
- 102b 19d8 Millennium G400 16Mb SGRAM
- 102b 19f8 Millennium G400 32Mb SGRAM
- 102b 2159 Millennium G400 Dual Head 16Mb
- 102b 2179 Millennium G400 MAX/Dual Head 32Mb
- 102b 217d Millennium G400 Dual Head Max
- 102b 23c0 Millennium G450
- 102b 23c1 Millennium G450
- 102b 23c2 Millennium G450 DVI
- 102b 23c3 Millennium G450 DVI
- 102b 2f58 Millennium G400
- 102b 2f78 Millennium G400
- 102b 3693 Marvel G400 AGP
- 102b 5dd0 4Sight II
- 102b 5f50 4Sight II
- 102b 5f51 4Sight II
- 102b 5f52 4Sight II
- 102b 9010 Millennium G400 Dual Head
- 1458 0400 GA-G400
- 1705 0001 Millennium G450 32MB SGRAM
- 1705 0002 Millennium G450 16MB SGRAM
- 1705 0003 Millennium G450 32MB
- 1705 0004 Millennium G450 16MB
- 0527 MGA Parhelia AGP
- 102b 0840 Parhelia 128Mb
- 0d10 MGA Ultima/Impression
- 1000 MGA G100 [Productiva]
- 102b ff01 Productiva G100
- 102b ff05 Productiva G100 Multi-Monitor
- 1001 MGA G100 [Productiva] AGP
- 102b 1001 MGA-G100 AGP
- 102b ff00 MGA-G100 AGP
- 102b ff01 MGA-G100 Productiva AGP
- 102b ff03 Millennium G100 AGP
- 102b ff04 MGA-G100 AGP
- 102b ff05 MGA-G100 Productiva AGP Multi-Monitor
- 110a 001e MGA-G100 AGP
- 2007 MGA Mistral
- 2527 MGA G550 AGP
- 102b 0f83 Millennium G550
- 102b 0f84 Millennium G550 Dual Head DDR 32Mb
- 102b 1e41 Millennium G550
- 2537 MGA G650 AGP
- 4536 VIA Framegrabber
- 6573 Shark 10/100 Multiport SwitchNIC
-102c Chips and Technologies
- 00b8 F64310
- 00c0 F69000 HiQVideo
- 102c 00c0 F69000 HiQVideo
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 4c53 1010 CP5/CR6 mainboard
- 4c53 1020 VR6 mainboard
- 4c53 1030 PC5 mainboard
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- 00d0 F65545
- 00d8 F65545
- 00dc F65548
- 00e0 F65550
- 00e4 F65554
- 00e5 F65555 HiQVPro
- 0e11 b049 Armada 1700 Laptop Display Controller
- 00f0 F68554
- 00f4 F68554 HiQVision
- 00f5 F68555
- 0c30 F69030
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
-# C5C project cancelled
- 4c53 1080 CT8 mainboard
-102d Wyse Technology Inc.
- 50dc 3328 Audio
-102e Olivetti Advanced Technology
-102f Toshiba America
- 0009 r4x00
- 000a TX3927 MIPS RISC PCI Controller
- 0020 ATM Meteor 155
- 102f 00f8 ATM Meteor 155
- 0030 TC35815CF PCI 10/100 Mbit Ethernet Controller
- 0031 TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
- 0105 TC86C001 [goku-s] IDE
- 0106 TC86C001 [goku-s] USB 1.1 Host
- 0107 TC86C001 [goku-s] USB Device Controller
- 0108 TC86C001 [goku-s] I2C/SIO/GPIO Controller
- 0180 TX4927/38 MIPS RISC PCI Controller
- 0181 TX4925 MIPS RISC PCI Controller
- 0182 TX4937 MIPS RISC PCI Controller
-1030 TMC Research
-1031 Miro Computer Products AG
- 5601 DC20 ASIC
- 5607 Video I/O & motion JPEG compressor
- 5631 Media 3D
- 6057 MiroVideo DC10/DC30+
-1032 Compaq
-1033 NEC Corporation
- 0000 Vr4181A USB Host or Function Control Unit
- 0001 PCI to 486-like bus Bridge
- 0002 PCI to VL98 Bridge
- 0003 ATM Controller
- 0004 R4000 PCI Bridge
- 0005 PCI to 486-like bus Bridge
- 0006 PC-9800 Graphic Accelerator
- 0007 PCI to UX-Bus Bridge
- 0008 PC-9800 Graphic Accelerator
- 0009 PCI to PC9800 Core-Graph Bridge
- 0016 PCI to VL Bridge
- 001a [Nile II]
- 0021 Vrc4373 [Nile I]
- 0029 PowerVR PCX1
- 002a PowerVR 3D
- 002c Star Alpha 2
- 002d PCI to C-bus Bridge
- 0035 USB
- 1179 0001 USB
- 12ee 7000 Root Hub
- 1799 0001 Root Hub
- 807d 0035 PCI-USB2 (OHCI subsystem)
- 003b PCI to C-bus Bridge
- 003e NAPCCARD Cardbus Controller
- 0046 PowerVR PCX2 [midas]
- 005a Vrc5074 [Nile 4]
- 0063 Firewarden
- 0067 PowerVR Neon 250 Chipset
- 1010 0020 PowerVR Neon 250 AGP 32Mb
- 1010 0080 PowerVR Neon 250 AGP 16Mb
- 1010 0088 PowerVR Neon 250 16Mb
- 1010 0090 PowerVR Neon 250 AGP 16Mb
- 1010 0098 PowerVR Neon 250 16Mb
- 1010 00a0 PowerVR Neon 250 AGP 32Mb
- 1010 00a8 PowerVR Neon 250 32Mb
- 1010 0120 PowerVR Neon 250 AGP 32Mb
- 0072 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
- 0074 56k Voice Modem
- 1033 8014 RCV56ACF 56k Voice Modem
- 009b Vrc5476
- 00a5 VRC4173
- 00a6 VRC5477 AC97
- 00cd IEEE 1394 [OrangeLink] Host Controller
- 12ee 8011 Root hub
- 00ce IEEE 1394 Host Controller
- 00df Vr4131
- 00e0 USB 2.0
- 0ee4 3383 Sitecom IEEE 1394 / USB2.0 Combo Card
- 12ee 7001 Root hub
- 1799 0002 Root Hub
- 807d 1043 PCI-USB2 (EHCI subsystem)
- 00e7 IEEE 1394 Host Controller
- 00f2 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
- 00f3 uPD6113x Multimedia Decoder/Processor [EMMA2]
- 010c VR7701
-1034 Framatome Connectors USA Inc.
-1035 Comp. & Comm. Research Lab
-1036 Future Domain Corp.
- 0000 TMC-18C30 [36C70]
-1037 Hitachi Micro Systems
-1038 AMP, Inc
-1039 Silicon Integrated Systems [SiS]
- 0001 Virtual PCI-to-PCI bridge (AGP)
- 0002 SG86C202
- 0006 85C501/2/3
- 0008 SiS85C503/5513 (LPC Bridge)
- 0009 ACPI
-# source: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
- 0016 SiS961/2 SMBus Controller
- 0018 SiS85C503/5513 (LPC Bridge)
-# Controller for 2 PATA and 2 SATA channels
- 0180 RAID bus controller 180 SATA/PATA [SiS]
- 0181 SiS SATA
- 0200 5597/5598/6326 VGA
- 1039 0000 SiS5597 SVGA (Shared RAM)
- 0204 82C204
- 0205 SG86C205
- 0300 300/305 PCI/AGP VGA Display Adapter
- 107d 2720 Leadtek WinFast VR300
- 0310 315H PCI/AGP VGA Display Adapter
- 0315 315 PCI/AGP VGA Display Adapter
- 0325 315PRO PCI/AGP VGA Display Adapter
- 0330 330 [Xabre] PCI/AGP VGA Display Adapter
- 0406 85C501/2
- 0496 85C496
- 0530 530 Host
- 0540 540 Host
- 0550 550 Host
- 0597 5513C
- 0601 85C601
- 0620 620 Host
- 0630 630 Host
- 0633 633 Host
- 0635 635 Host
- 0645 SiS645 Host & Memory & AGP Controller
- 0646 SiS645DX Host & Memory & AGP Controller
- 0648 SiS 645xx
- 0650 650/M650 Host
- 0651 651 Host
- 0655 655 Host
- 0660 660 Host
- 0661 661FX/M661FX/M661MX Host
- 0730 730 Host
- 0733 733 Host
- 0735 735 Host
- 0740 740 Host
- 0741 741/741GX/M741 Host
- 0745 745 Host
- 0746 746 Host
- 0755 755 Host
- 0760 760/M760 Host
- 0900 SiS900 PCI Fast Ethernet
- 1019 0a14 K7S5A motherboard
- 1039 0900 SiS900 10/100 Ethernet Adapter
- 1043 8035 CUSI-FX motherboard
- 0961 SiS961 [MuTIOL Media IO]
- 0962 SiS962 [MuTIOL Media IO]
- 0963 SiS963 [MuTIOL Media IO]
- 0964 SiS964 [MuTIOL Media IO]
- 0965 SiS965 [MuTIOL Media IO]
- 3602 83C602
- 5107 5107
- 5300 SiS540 PCI Display Adapter
- 5315 550 PCI/AGP VGA Display Adapter
- 5401 486 PCI Chipset
- 5511 5511/5512
- 5513 5513 [IDE]
- 1019 0970 P6STP-FL motherboard
- 1039 5513 SiS5513 EIDE Controller (A,B step)
- 1043 8035 CUSI-FX motherboard
- 5517 5517
- 5571 5571
- 5581 5581 Pentium Chipset
- 5582 5582
- 5591 5591/5592 Host
- 5596 5596 Pentium Chipset
- 5597 5597 [SiS5582]
- 5600 5600 Host
- 6204 Video decoder & MPEG interface
- 6205 VGA Controller
- 6236 6236 3D-AGP
- 6300 630/730 PCI/AGP VGA Display Adapter
- 1019 0970 P6STP-FL motherboard
- 1043 8035 CUSI-FX motherboard
- 6306 530/620 PCI/AGP VGA Display Adapter
- 1039 6306 SiS530,620 GUI Accelerator+3D
- 6325 65x/M650/740 PCI/AGP VGA Display Adapter
- 6326 86C326 5598/6326
- 1039 6326 SiS6326 GUI Accelerator
- 1092 0a50 SpeedStar A50
- 1092 0a70 SpeedStar A70
- 1092 4910 SpeedStar A70
- 1092 4920 SpeedStar A70
- 1569 6326 SiS6326 GUI Accelerator
- 6330 661/741/760 PCI/AGP VGA Display Adapter
- 1039 6330 [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
- 7001 USB 1.0 Controller
- 1019 0a14 K7S5A motherboard
- 1039 7000 Onboard USB Controller
- 7002 USB 2.0 Controller
- 1509 7002 Onboard USB Controller
- 7007 FireWire Controller
- 7012 Sound Controller
-# There are may be different modem codecs here (Intel537 compatible and incompatible)
- 7013 AC'97 Modem Controller
- 7016 SiS7016 PCI Fast Ethernet Adapter
- 1039 7016 SiS7016 10/100 Ethernet Adapter
- 7018 SiS PCI Audio Accelerator
- 1014 01b6 SiS PCI Audio Accelerator
- 1014 01b7 SiS PCI Audio Accelerator
- 1019 7018 SiS PCI Audio Accelerator
- 1025 000e SiS PCI Audio Accelerator
- 1025 0018 SiS PCI Audio Accelerator
- 1039 7018 SiS PCI Audio Accelerator
- 1043 800b SiS PCI Audio Accelerator
- 1054 7018 SiS PCI Audio Accelerator
- 107d 5330 SiS PCI Audio Accelerator
- 107d 5350 SiS PCI Audio Accelerator
- 1170 3209 SiS PCI Audio Accelerator
- 1462 400a SiS PCI Audio Accelerator
- 14a4 2089 SiS PCI Audio Accelerator
- 14cd 2194 SiS PCI Audio Accelerator
- 14ff 1100 SiS PCI Audio Accelerator
- 152d 8808 SiS PCI Audio Accelerator
- 1558 1103 SiS PCI Audio Accelerator
- 1558 2200 SiS PCI Audio Accelerator
- 1563 7018 SiS PCI Audio Accelerator
- 15c5 0111 SiS PCI Audio Accelerator
- 270f a171 SiS PCI Audio Accelerator
- a0a0 0022 SiS PCI Audio Accelerator
- 7019 SiS7019 Audio Accelerator
-103a Seiko Epson Corporation
-103b Tatung Co. of America
-103c Hewlett-Packard Company
- 1005 A4977A Visualize EG
- 1006 Visualize FX6
- 1008 Visualize FX4
- 100a Visualize FX2
- 1028 Tach TL Fibre Channel Host Adapter
- 1029 Tach XL2 Fibre Channel Host Adapter
- 107e 000f Interphase 5560 Fibre Channel Adapter
- 9004 9210 1Gb/2Gb Family Fibre Channel Controller
- 9004 9211 1Gb/2Gb Family Fibre Channel Controller
- 102a Tach TS Fibre Channel Host Adapter
- 107e 000e Interphase 5540/5541 Fibre Channel Adapter
- 9004 9110 1Gb/2Gb Family Fibre Channel Controller
- 9004 9111 1Gb/2Gb Family Fibre Channel Controller
- 1030 J2585A DeskDirect 10/100VG NIC
- 1031 J2585B HP 10/100VG PCI LAN Adapter
- 103c 1040 J2973A DeskDirect 10BaseT NIC
- 103c 1041 J2585B DeskDirect 10/100VG NIC
- 103c 1042 J2970A DeskDirect 10BaseT/2 NIC
- 1040 J2973A DeskDirect 10BaseT NIC
- 1041 J2585B DeskDirect 10/100 NIC
- 1042 J2970A DeskDirect 10BaseT/2 NIC
- 1048 Diva Serial [GSP] Multiport UART
- 103c 1049 Tosca Console
- 103c 104a Tosca Secondary
- 103c 104b Maestro SP2
- 103c 1223 Superdome Console
- 103c 1226 Keystone SP2
- 103c 1227 Powerbar SP2
- 103c 1282 Everest SP2
- 103c 1301 Diva RMP3
- 1054 PCI Local Bus Adapter
- 1064 79C970 PCnet Ethernet Controller
- 108b Visualize FXe
- 10c1 NetServer Smart IRQ Router
- 10ed TopTools Remote Control
- 10f0 rio System Bus Adapter
- 10f1 rio I/O Controller
- 1200 82557B 10/100 NIC
- 1219 NetServer PCI Hot-Plug Controller
- 121a NetServer SMIC Controller
- 121b NetServer Legacy COM Port Decoder
- 121c NetServer PCI COM Port Decoder
- 1229 zx1 System Bus Adapter
- 122a zx1 I/O Controller
- 122e zx1 Local Bus Adapter
- 127c sx1000 I/O Controller
- 1290 Auxiliary Diva Serial Port
- 12b4 zx1 QuickSilver AGP8x Local Bus Adapter
- 2910 E2910A PCIBus Exerciser
- 2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
-103e Solliday Engineering
-103f Synopsys/Logic Modeling Group
-1040 Accelgraphics Inc.
-1041 Computrend
-1042 Micron
- 1000 PC Tech RZ1000
- 1001 PC Tech RZ1001
- 3000 Samurai_0
- 3010 Samurai_1
- 3020 Samurai_IDE
-1043 ASUSTeK Computer Inc.
- 0675 ISDNLink P-IN100-ST-D
- 4015 v7100 SDRAM [GeForce2 MX]
- 4021 v7100 Combo Deluxe [GeForce2 MX + TV tuner]
- 4057 v8200 GeForce 3
- 8043 v8240 PAL 128M [P4T] Motherboard
- 807b v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI]
- 80bb v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
- 80c5 nForce3 chipset motherboard [SK8N]
- 80df v9520 Magic/T
-1044 Adaptec (formerly DPT)
- 1012 Domino RAID Engine
- a400 SmartCache/Raid I-IV Controller
- a500 PCI Bridge
- a501 SmartRAID V Controller
- 1044 c001 PM1554U2 Ultra2 Single Channel
- 1044 c002 PM1654U2 Ultra2 Single Channel
- 1044 c003 PM1564U3 Ultra3 Single Channel
- 1044 c004 PM1564U3 Ultra3 Dual Channel
- 1044 c005 PM1554U2 Ultra2 Single Channel (NON ACPI)
- 1044 c00a PM2554U2 Ultra2 Single Channel
- 1044 c00b PM2654U2 Ultra2 Single Channel
- 1044 c00c PM2664U3 Ultra3 Single Channel
- 1044 c00d PM2664U3 Ultra3 Dual Channel
- 1044 c00e PM2554U2 Ultra2 Single Channel (NON ACPI)
- 1044 c00f PM2654U2 Ultra2 Single Channel (NON ACPI)
- 1044 c014 PM3754U2 Ultra2 Single Channel (NON ACPI)
- 1044 c015 PM3755U2B Ultra2 Single Channel (NON ACPI)
- 1044 c016 PM3755F Fibre Channel (NON ACPI)
- 1044 c01e PM3757U2 Ultra2 Single Channel
- 1044 c01f PM3757U2 Ultra2 Dual Channel
- 1044 c020 PM3767U3 Ultra3 Dual Channel
- 1044 c021 PM3767U3 Ultra3 Quad Channel
- 1044 c028 PM2865U3 Ultra3 Single Channel
- 1044 c029 PM2865U3 Ultra3 Dual Channel
- 1044 c02a PM2865F Fibre Channel
- 1044 c03c 2000S Ultra3 Single Channel
- 1044 c03d 2000S Ultra3 Dual Channel
- 1044 c03e 2000F Fibre Channel
- 1044 c046 3000S Ultra3 Single Channel
- 1044 c047 3000S Ultra3 Dual Channel
- 1044 c048 3000F Fibre Channel
- 1044 c050 5000S Ultra3 Single Channel
- 1044 c051 5000S Ultra3 Dual Channel
- 1044 c052 5000F Fibre Channel
- 1044 c05a 2400A UDMA Four Channel
- 1044 c05b 2400A UDMA Four Channel DAC
- 1044 c064 3010S Ultra3 Dual Channel
- 1044 c065 3410S Ultra160 Four Channel
- 1044 c066 3010S Fibre Channel
- a511 SmartRAID V Controller
- 1044 c032 ASR-2005S I2O Zero Channel
-1045 OPTi Inc.
- a0f8 82C750 [Vendetta] USB Controller
- c101 92C264
- c178 92C178
- c556 82X556 [Viper]
- c557 82C557 [Viper-M]
- c558 82C558 [Viper-M ISA+IDE]
- c567 82C750 [Vendetta], device 0
- c568 82C750 [Vendetta], device 1
- c569 82C579 [Viper XPress+ Chipset]
- c621 82C621 [Viper-M/N+]
- c700 82C700 [FireStar]
- c701 82C701 [FireStar Plus]
- c814 82C814 [Firebridge 1]
- c822 82C822
- c824 82C824
- c825 82C825 [Firebridge 2]
- c832 82C832
- c861 82C861
- c895 82C895
- c935 EV1935 ECTIVA MachOne PCIAudio
- d568 82C825 [Firebridge 2]
- d721 IDE [FireStar]
-1046 IPC Corporation, Ltd.
-1047 Genoa Systems Corp
-1048 Elsa AG
- 0c60 Gladiac MX
- 0d22 Quadro4 900XGL [ELSA GLoria4 900XGL]
- 1000 QuickStep 1000
- 3000 QuickStep 3000
- 8901 Gloria XL
-1049 Fountain Technologies, Inc.
-# # nee SGS Thomson Microelectronics
-104a STMicroelectronics
- 0008 STG 2000X
- 0009 STG 1764X
- 0010 STG4000 [3D Prophet Kyro Series]
- 0209 STPC Consumer/Industrial North- and Southbridge
- 020a STPC Atlas/ConsumerS/Consumer IIA Northbridge
-# From <http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/share/misc/pci_vendors>
- 0210 STPC Atlas ISA Bridge
- 021a STPC Consumer S Southbridge
- 021b STPC Consumer IIA Southbridge
- 0500 ST70137 [Unicorn] ADSL DMT Transceiver
- 0564 STPC Client Northbridge
- 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
- 1746 STG 1764X
- 2774 21x4x DEC-Tulip compatible 10/100 Ethernet
- 3520 MPEG-II decoder card
- 55cc STPC Client Southbridge
-104b BusLogic
- 0140 BT-946C (old) [multimaster 01]
- 1040 BT-946C (BA80C30) [MultiMaster 10]
- 8130 Flashpoint LT
-104c Texas Instruments
- 0500 100 MBit LAN Controller
- 0508 TMS380C2X Compressor Interface
- 1000 Eagle i/f AS
- 104c PCI1510 PC card Cardbus Controller
- 3d04 TVP4010 [Permedia]
- 3d07 TVP4020 [Permedia 2]
- 1011 4d10 Comet
- 1040 000f AccelStar II
- 1040 0011 AccelStar II
- 1048 0a31 WINNER 2000
- 1048 0a32 GLoria Synergy
- 1048 0a35 GLoria Synergy
- 107d 2633 WinFast 3D L2300
- 1092 0127 FIRE GL 1000 PRO
- 1092 0136 FIRE GL 1000 PRO
- 1092 0141 FIRE GL 1000 PRO
- 1092 0146 FIRE GL 1000 PRO
- 1092 0148 FIRE GL 1000 PRO
- 1092 0149 FIRE GL 1000 PRO
- 1092 0152 FIRE GL 1000 PRO
- 1092 0154 FIRE GL 1000 PRO
- 1092 0155 FIRE GL 1000 PRO
- 1092 0156 FIRE GL 1000 PRO
- 1092 0157 FIRE GL 1000 PRO
- 1097 3d01 Jeronimo Pro
- 1102 100f Graphics Blaster Extreme
- 3d3d 0100 Reference Permedia 2 3D
- 8000 PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
- e4bf 1010 CF1-1-SNARE
- e4bf 1020 CF1-2-SNARE
- 8009 FireWire Controller
- 104d 8032 8032 OHCI i.LINK (IEEE 1394) Controller
- 8017 PCI4410 FireWire Controller
- 8019 TSB12LV23 IEEE-1394 Controller
- 11bd 000a Studio DV500-1394
- 11bd 000e Studio DV
- e4bf 1010 CF2-1-CYMBAL
- 8020 TSB12LV26 IEEE-1394 Controller (Link)
- 11bd 000f Studio DV500-1394
- 8021 TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
- 104d 80df Vaio PCG-FX403
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 8022 TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link)
- 8023 TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
- 103c 088c nc8000 laptop
- 8024 TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
- 8025 TSB82AA2 IEEE-1394b Link Layer Controller
- 55aa 55aa FireWire 800 PCI Card
- 8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
- 8027 PCI4451 IEEE-1394 Controller
- 1028 00e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
- 8029 PCI4510 IEEE-1394 Controller
- 1028 0163 Latitude D505
- 1071 8160 MIM2900
- 802b PCI7410,7510,7610 OHCI-Lynx Controller
- 1028 014e PCI7410,7510,7610 OHCI-Lynx Controller (Dell Latitude D800)
- 802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
- 8031 Texas Instruments PCIxx21/x515 Cardbus Controller
- 8032 Texas Instruments OHCI Compliant IEEE 1394 Host Controller
- 8033 Texas Instruments PCIxx21 Integrated FlashMedia Controller
- 8034 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Secure Digital (SD) Controller
- 8035 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Smart Card Controller (SMC)
- 8201 PCI1620 Firmware Loading Function
- 8204 PCI7410,7510,7610 PCI Firmware Loading Function
- 1028 014e Latitude D800
- 8400 ACX 100 22Mbps Wireless Interface
- 00fc 16ec U.S. Robotics 22 Mbps Wireless PC Card (model 2210)
- 00fd 16ec U.S. Robotics 22Mbps Wireless PCI Adapter (model 2216)
- 1186 3b00 DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
- 1186 3b01 DWL-520+ 22Mbps PCI Wireless Adapter
- 8401 ACX 100 22Mbps Wireless Interface
-# 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
- 9000 Wireless Interface (of unknown type)
- 9066 ACX 111 54Mbps Wireless Interface
- a001 TDC1570
- a100 TDC1561
- a102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
- a106 TMS320C6205 Fixed Point DSP
- 175c 5000 ASI50xx Audio Adapter
- 175c 8700 ASI87xx Radio Tuner card
- ac10 PCI1050
- ac11 PCI1053
- ac12 PCI1130
- ac13 PCI1031
- ac15 PCI1131
- ac16 PCI1250
- 1014 0092 ThinkPad 600
- ac17 PCI1220
- ac18 PCI1260
- ac19 PCI1221
- ac1a PCI1210
- ac1b PCI1450
- 0e11 b113 Armada M700
- ac1c PCI1225
- 0e11 b121 Armada E500
- 1028 0088 Dell Computer Corporation Latitude CPi A400XT
- ac1d PCI1251A
- ac1e PCI1211
- ac1f PCI1251B
- ac20 TI 2030
- ac21 PCI2031
- ac22 PCI2032 PCI Docking Bridge
- ac23 PCI2250 PCI-to-PCI Bridge
- ac28 PCI2050 PCI-to-PCI Bridge
- ac30 PCI1260 PC card Cardbus Controller
- ac40 PCI4450 PC card Cardbus Controller
- ac41 PCI4410 PC card Cardbus Controller
- ac42 PCI4451 PC card Cardbus Controller
- 1028 00e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
- ac44 PCI4510 PC card Cardbus Controller
- 1028 0163 Latitude D505
- 1071 8160 MIM2000
- ac46 PCI4520 PC card Cardbus Controller
- ac47 PCI7510 PC card Cardbus Controller
- 1028 014e Latitude D800
- ac4a PCI7510,7610 PC card Cardbus Controller
- 1028 014e Latitude D800
- ac50 PCI1410 PC card Cardbus Controller
- ac51 PCI1420
- 1014 023b ThinkPad T23 (2647-4MG)
- 1028 00b1 Latitude C600
- 1028 012a Latitude C640
- 1033 80cd Versa Note VXi
- 10cf 1095 Lifebook C6155
- e4bf 1000 CP2-2-HIPHOP
- ac52 PCI1451 PC card Cardbus Controller
- ac53 PCI1421 PC card Cardbus Controller
- ac54 PCI1620 PC Card Controller
- ac55 PCI1520 PC card Cardbus Controller
- 1014 0512 ThinkPad T30/T40
- ac56 PCI1510 PC card Cardbus Controller
- 1014 0528 ThinkPad R40e (2684-HVG) Cardbus Controller
- ac60 PCI2040 PCI to DSP Bridge Controller
- 175c 5100 ASI51xx Audio Adapter
- 175c 6100 ASI61xx Audio Adapter
- 175c 6200 ASI62xx Audio Adapter
- ac8d PCI 7620
- ac8e PCI7420 CardBus Controller
- 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
- fe00 FireWire Host Controller
- fe03 12C01A FireWire Host Controller
-104d Sony Corporation
- 8004 DTL-H2500 [Playstation development board]
- 8009 CXD1947Q i.LINK Controller
- 8039 CXD3222 i.LINK Controller
- 8056 Rockwell HCF 56K modem
- 808a Memory Stick Controller
-104e Oak Technology, Inc
- 0017 OTI-64017
- 0107 OTI-107 [Spitfire]
- 0109 Video Adapter
- 0111 OTI-64111 [Spitfire]
- 0217 OTI-64217
- 0317 OTI-64317
-104f Co-time Computer Ltd
-1050 Winbond Electronics Corp
- 0000 NE2000
- 0001 W83769F
- 0105 W82C105
- 0840 W89C840
- 1050 0001 W89C840 Ethernet Adapter
- 1050 0840 W89C840 Ethernet Adapter
- 0940 W89C940
- 5a5a W89C940F
- 6692 W6692
- 9921 W99200F MPEG-1 Video Encoder
- 9922 W99200F/W9922PF MPEG-1/2 Video Encoder
- 9970 W9970CF
-1051 Anigma, Inc.
-1052 ?Young Micro Systems
-1053 Young Micro Systems
-1054 Hitachi, Ltd
-1055 Efar Microsystems
- 9130 SLC90E66 [Victory66] IDE
- 9460 SLC90E66 [Victory66] ISA
- 9462 SLC90E66 [Victory66] USB
- 9463 SLC90E66 [Victory66] ACPI
-1056 ICL
-# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
-1057 Motorola
- 0001 MPC105 [Eagle]
- 0002 MPC106 [Grackle]
- 0003 MPC8240 [Kahlua]
- 0004 MPC107
- 0006 MPC8245 [Unity]
- 0008 MPC8540
- 0009 MPC8560
- 0100 MC145575 [HFC-PCI]
- 0431 KTI829c 100VG
- 1801 DSP56301 Digital Signal Processor
- 14fb 0101 Transas Radar Imitator Board [RIM]
- 14fb 0102 Transas Radar Imitator Board [RIM-2]
- 14fb 0202 Transas Radar Integrator Board [RIB-2]
- 14fb 0611 1 channel CAN bus Controller [CanPci-1]
- 14fb 0612 2 channels CAN bus Controller [CanPci-2]
- 14fb 0613 3 channels CAN bus Controller [CanPci-3]
- 14fb 0614 4 channels CAN bus Controller [CanPci-4]
- 14fb 0621 1 channel CAN bus Controller [CanPci2-1]
- 14fb 0622 2 channels CAN bus Controller [CanPci2-2]
- 14fb 0810 Transas VTS Radar Integrator Board [RIB-4]
- 175c 4200 ASI4215 Audio Adapter
- 175c 4300 ASI43xx Audio Adapter
- 175c 4400 ASI4401 Audio Adapter
- ecc0 0010 Darla
- ecc0 0020 Gina
- ecc0 0030 Layla rev.0
- ecc0 0031 Layla rev.1
- ecc0 0040 Darla24 rev.0
- ecc0 0041 Darla24 rev.1
- ecc0 0050 Gina24 rev.0
- ecc0 0051 Gina24 rev.1
- ecc0 0070 Mona rev.0
- ecc0 0071 Mona rev.1
- ecc0 0072 Mona rev.2
- 18c0 MPC8265A/MPC8266
- 18c1 MPC8271/MPC8272
- 3410 DSP56361 Digital Signal Processor
- ecc0 0050 Gina24 rev.0
- ecc0 0051 Gina24 rev.1
- ecc0 0060 Layla24
- ecc0 0070 Mona rev.0
- ecc0 0071 Mona rev.1
- ecc0 0072 Mona rev.2
- ecc0 0080 Mia rev.0
- ecc0 0081 Mia rev.1
- ecc0 0090 Indigo
- ecc0 00a0 Indigo IO
- ecc0 00b0 Indigo DJ
- ecc0 0100 3G
- 4801 Raven
- 4802 Falcon
- 4803 Hawk
- 4806 CPX8216
- 4d68 20268
- 5600 SM56 PCI Modem
- 1057 0300 SM56 PCI Speakerphone Modem
- 1057 0301 SM56 PCI Voice Modem
- 1057 0302 SM56 PCI Fax Modem
- 1057 5600 SM56 PCI Voice modem
- 13d2 0300 SM56 PCI Speakerphone Modem
- 13d2 0301 SM56 PCI Voice modem
- 13d2 0302 SM56 PCI Fax Modem
- 1436 0300 SM56 PCI Speakerphone Modem
- 1436 0301 SM56 PCI Voice modem
- 1436 0302 SM56 PCI Fax Modem
- 144f 100c SM56 PCI Fax Modem
- 1494 0300 SM56 PCI Speakerphone Modem
- 1494 0301 SM56 PCI Voice modem
- 14c8 0300 SM56 PCI Speakerphone Modem
- 14c8 0302 SM56 PCI Fax Modem
- 1668 0300 SM56 PCI Speakerphone Modem
- 1668 0302 SM56 PCI Fax Modem
- 5803 MPC5200
- 6400 MPC190 Security Processor (S1 family, encryption)
- 6405 MPC184 Security Processor (S1 family)
-1058 Electronics & Telecommunications RSH
-1059 Teknor Industrial Computers Inc
-105a Promise Technology, Inc.
-# more correct description from promise linux sources
- 0d30 PDC20265 (FastTrak100 Lite/Ultra100)
- 105a 4d33 Ultra100
- 0d38 20263
- 105a 4d39 Fasttrak66
- 1275 20275
- 3318 PDC20318 (SATA150 TX4)
- 3319 PDC20319 (FastTrak S150 TX4)
- 8086 3427 S875WP1-E mainboard
- 3371 PDC20371 (FastTrak S150 TX2plus)
- 3373 PDC20378 (FastTrak 378/SATA 378)
- 1043 80f5 K8V Deluxe/PC-DL Deluxe motherboard
- 1462 702e K8T NEO FIS2R motherboard
- 3375 PDC20375 (SATA150 TX2plus)
- 3376 PDC20376 (FastTrak 376)
- 1043 809e A7V8X motherboard
- 3574 PDC20579 SATAII 150 IDE Controller
- 3d18 PDC20518/PDC40518 (SATAII 150 TX4)
- 3d75 PDC20575 (SATAII150 TX2plus)
- 4d30 PDC20267 (FastTrak100/Ultra100)
- 105a 4d33 Ultra100
- 105a 4d39 FastTrak100
- 4d33 20246
- 105a 4d33 20246 IDE Controller
- 4d38 PDC20262 (FastTrak66/Ultra66)
- 105a 4d30 Ultra Device on SuperTrak
- 105a 4d33 Ultra66
- 105a 4d39 FastTrak66
- 4d68 PDC20268 (Ultra100 TX2)
- 105a 4d68 Ultra100TX2
- 4d69 20269
- 105a 4d68 Ultra133TX2
- 5275 PDC20276 (MBFastTrak133 Lite)
- 105a 0275 SuperTrak SX6000 IDE
- 105a 1275 MBFastTrak133 Lite (tm) Controller (RAID mode)
- 1458 b001 MBUltra 133
- 5300 DC5300
- 6268 PDC20270 (FastTrak100 LP/TX2/TX4)
- 105a 4d68 FastTrak100 TX2
- 6269 PDC20271 (FastTrak TX2000)
- 105a 6269 FastTrak TX2/TX2000
- 6621 PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
- 6622 PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
- 6626 PDC20618 (Ultra 618)
- 6629 PDC20619 (FastTrak TX4000)
- 7275 PDC20277 (SBFastTrak133 Lite)
-105b Foxconn International, Inc.
-105c Wipro Infotech Limited
-105d Number 9 Computer Company
- 2309 Imagine 128
- 2339 Imagine 128-II
- 105d 0000 Imagine 128 series 2 4Mb VRAM
- 105d 0001 Imagine 128 series 2 4Mb VRAM
- 105d 0002 Imagine 128 series 2 4Mb VRAM
- 105d 0003 Imagine 128 series 2 4Mb VRAM
- 105d 0004 Imagine 128 series 2 4Mb VRAM
- 105d 0005 Imagine 128 series 2 4Mb VRAM
- 105d 0006 Imagine 128 series 2 4Mb VRAM
- 105d 0007 Imagine 128 series 2 4Mb VRAM
- 105d 0008 Imagine 128 series 2e 4Mb DRAM
- 105d 0009 Imagine 128 series 2e 4Mb DRAM
- 105d 000a Imagine 128 series 2 8Mb VRAM
- 105d 000b Imagine 128 series 2 8Mb H-VRAM
- 11a4 000a Barco Metheus 5 Megapixel
- 13cc 0000 Barco Metheus 5 Megapixel
- 13cc 0004 Barco Metheus 5 Megapixel
- 13cc 0005 Barco Metheus 5 Megapixel
- 13cc 0006 Barco Metheus 5 Megapixel
- 13cc 0008 Barco Metheus 5 Megapixel
- 13cc 0009 Barco Metheus 5 Megapixel
- 13cc 000a Barco Metheus 5 Megapixel
- 13cc 000c Barco Metheus 5 Megapixel
- 493d Imagine 128 T2R [Ticket to Ride]
- 11a4 000a Barco Metheus 5 Megapixel, Dual Head
- 11a4 000b Barco Metheus 5 Megapixel, Dual Head
- 13cc 0002 Barco Metheus 4 Megapixel, Dual Head
- 13cc 0003 Barco Metheus 5 Megapixel, Dual Head
- 13cc 0007 Barco Metheus 5 Megapixel, Dual Head
- 13cc 0008 Barco Metheus 5 Megapixel, Dual Head
- 13cc 0009 Barco Metheus 5 Megapixel, Dual Head
- 13cc 000a Barco Metheus 5 Megapixel, Dual Head
- 5348 Revolution 4
- 105d 0037 Revolution IV-FP AGP (For SGI 1600SW)
-105e Vtech Computers Ltd
-105f Infotronic America Inc
-1060 United Microelectronics [UMC]
- 0001 UM82C881
- 0002 UM82C886
- 0101 UM8673F
- 0881 UM8881
- 0886 UM8886F
- 0891 UM8891A
- 1001 UM886A
- 673a UM8886BF
- 673b EIDE Master/DMA
- 8710 UM8710
- 886a UM8886A
- 8881 UM8881F
- 8886 UM8886F
- 888a UM8886A
- 8891 UM8891A
- 9017 UM9017F
- 9018 UM9018
- 9026 UM9026
- e881 UM8881N
- e886 UM8886N
- e88a UM8886N
- e891 UM8891N
-1061 I.I.T.
- 0001 AGX016
- 0002 IIT3204/3501
-1062 Maspar Computer Corp
-1063 Ocean Office Automation
-1064 Alcatel
-1065 Texas Microsystems
-1066 PicoPower Technology
- 0000 PT80C826
- 0001 PT86C521 [Vesuvius v1] Host Bridge
- 0002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
- 0003 PT86C524 [Nile] PCI-to-PCI Bridge
- 0004 PT86C525 [Nile-II] PCI-to-PCI Bridge
- 0005 National PC87550 System Controller
- 8002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
-1067 Mitsubishi Electric
- 0301 AccelGraphics AccelECLIPSE
- 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
- 0308 Tornado 3000 [OEM Evans & Sutherland]
- 1002 VG500 [VolumePro Volume Rendering Accelerator]
-1068 Diversified Technology
-1069 Mylex Corporation
- 0001 DAC960P
- 0002 DAC960PD
- 0010 DAC960PG
- 0020 DAC960LA
- 0050 AcceleRAID 352/170/160 support Device
- b166 Gemstone chipset SCSI controller
- 1014 0242 iSeries 2872 DASD IOA
- 1014 0266 Dual Channel PCI-X U320 SCSI Adapter
- 1014 0278 Dual Channel PCI-X U320 SCSI RAID Adapter
- 1014 02d3 Dual Channel PCI-X U320 SCSI Adapter
- 1014 02d4 Dual Channel PCI-X U320 SCSI RAID Adapter
- ba55 eXtremeRAID 1100 support Device
- ba56 eXtremeRAID 2000/3000 support Device
-106a Aten Research Inc
-106b Apple Computer Inc.
- 0001 Bandit PowerPC host bridge
- 0002 Grand Central I/O
- 0003 Control Video
- 0004 PlanB Video-In
- 0007 O'Hare I/O
- 000c DOS on Mac
- 000e Hydra Mac I/O
- 0010 Heathrow Mac I/O
- 0017 Paddington Mac I/O
- 0018 UniNorth FireWire
- 0019 KeyLargo USB
- 001e UniNorth Internal PCI
- 001f UniNorth PCI
- 0020 UniNorth AGP
- 0021 UniNorth GMAC (Sun GEM)
- 0022 KeyLargo Mac I/O
- 0024 UniNorth/Pangea GMAC (Sun GEM)
- 0025 KeyLargo/Pangea Mac I/O
- 0026 KeyLargo/Pangea USB
- 0027 UniNorth/Pangea AGP
- 0028 UniNorth/Pangea PCI
- 0029 UniNorth/Pangea Internal PCI
- 002d UniNorth 1.5 AGP
- 002e UniNorth 1.5 PCI
- 002f UniNorth 1.5 Internal PCI
- 0030 UniNorth/Pangea FireWire
- 0031 UniNorth 2 FireWire
- 0032 UniNorth 2 GMAC (Sun GEM)
- 0033 UniNorth 2 ATA/100
- 0034 UniNorth 2 AGP
- 0035 UniNorth 2 PCI
- 0036 UniNorth 2 Internal PCI
- 003b UniNorth/Intrepid ATA/100
- 003e KeyLargo/Intrepid Mac I/O
- 003f KeyLargo/Intrepid USB
- 0040 K2 KeyLargo USB
- 0041 K2 KeyLargo Mac/IO
- 0042 K2 FireWire
- 0043 K2 ATA/100
- 0045 K2 HT-PCI Bridge
- 0046 K2 HT-PCI Bridge
- 0047 K2 HT-PCI Bridge
- 0048 K2 HT-PCI Bridge
- 0049 K2 HT-PCI Bridge
- 004b U3 AGP
- 004c K2 GMAC (Sun GEM)
- 004f Shasta Mac I/O
- 0050 Shasta IDE
- 0051 Shasta (Sun GEM)
- 0052 Shasta Firewire
- 0053 Shasta PCI Bridge
- 0054 Shasta PCI Bridge
- 0055 Shasta PCI Bridge
- 0058 U3L AGP Bridge
- 1645 Tigon3 Gigabit Ethernet NIC (BCM5701)
-106c Hynix Semiconductor
- 8801 Dual Pentium ISA/PCI Motherboard
- 8802 PowerPC ISA/PCI Motherboard
- 8803 Dual Window Graphics Accelerator
- 8804 LAN Controller
- 8805 100-BaseT LAN
-106d Sequent Computer Systems
-106e DFI, Inc
-106f City Gate Development Ltd
-1070 Daewoo Telecom Ltd
-1071 Mitac
- 8160 Mitac 8060B Mobile Platform
-1072 GIT Co Ltd
-1073 Yamaha Corporation
- 0001 3D GUI Accelerator
- 0002 YGV615 [RPA3 3D-Graphics Controller]
- 0003 YMF-740
- 0004 YMF-724
- 1073 0004 YMF724-Based PCI Audio Adapter
- 0005 DS1 Audio
- 1073 0005 DS-XG PCI Audio CODEC
- 0006 DS1 Audio
- 0008 DS1 Audio
- 1073 0008 DS-XG PCI Audio CODEC
- 000a DS1L Audio
- 1073 0004 DS-XG PCI Audio CODEC
- 1073 000a DS-XG PCI Audio CODEC
- 000c YMF-740C [DS-1L Audio Controller]
- 107a 000c DS-XG PCI Audio CODEC
- 000d YMF-724F [DS-1 Audio Controller]
- 1073 000d DS-XG PCI Audio CODEC
- 0010 YMF-744B [DS-1S Audio Controller]
- 1073 0006 DS-XG PCI Audio CODEC
- 1073 0010 DS-XG PCI Audio CODEC
- 0012 YMF-754 [DS-1E Audio Controller]
- 1073 0012 DS-XG PCI Audio Codec
- 0020 DS-1 Audio
- 2000 DS2416 Digital Mixing Card
- 1073 2000 DS2416 Digital Mixing Card
-1074 NexGen Microsystems
- 4e78 82c500/1
-1075 Advanced Integrations Research
-1076 Chaintech Computer Co. Ltd
-1077 QLogic Corp.
- 1016 ISP10160 Single Channel Ultra3 SCSI Processor
- 1020 ISP1020 Fast-wide SCSI
- 1022 ISP1022 Fast-wide SCSI
- 1080 ISP1080 SCSI Host Adapter
- 1216 ISP12160 Dual Channel Ultra3 SCSI Processor
- 101e 8471 QLA12160 on AMI MegaRAID
- 101e 8493 QLA12160 on AMI MegaRAID
- 1240 ISP1240 SCSI Host Adapter
- 1280 ISP1280 SCSI Host Adapter
- 2020 ISP2020A Fast!SCSI Basic Adapter
- 2100 QLA2100 64-bit Fibre Channel Adapter
- 1077 0001 QLA2100 64-bit Fibre Channel Adapter
- 2200 QLA2200 64-bit Fibre Channel Adapter
- 1077 0002 QLA2200
- 2300 QLA2300 64-bit Fibre Channel Adapter
- 2312 QLA2312 Fibre Channel Adapter
-1078 Cyrix Corporation
- 0000 5510 [Grappa]
- 0001 PCI Master
- 0002 5520 [Cognac]
- 0100 5530 Legacy [Kahlua]
- 0101 5530 SMI [Kahlua]
- 0102 5530 IDE [Kahlua]
- 0103 5530 Audio [Kahlua]
- 0104 5530 Video [Kahlua]
- 0400 ZFMicro PCI Bridge
- 0401 ZFMicro Chipset SMI
- 0402 ZFMicro Chipset IDE
- 0403 ZFMicro Expansion Bus
-1079 I-Bus
-107a NetWorth
-107b Gateway 2000
-107c LG Electronics [Lucky Goldstar Co. Ltd]
-107d LeadTek Research Inc.
- 0000 P86C850
- 2134 WinFast 3D S320 II
- 2971 [GeForce FX 5900] WinFast A350 TDH MyViVo
-107e Interphase Corporation
- 0001 5515 ATM Adapter [Flipper]
- 0002 100 VG AnyLan Controller
- 0004 5526 Fibre Channel Host Adapter
- 0005 x526 Fibre Channel Host Adapter
- 0008 5525/5575 ATM Adapter (155 Mbit) [Atlantic]
- 9003 5535-4P-BRI-ST
- 9007 5535-4P-BRI-U
- 9008 5535-1P-SR
- 900c 5535-1P-SR-ST
- 900e 5535-1P-SR-U
- 9011 5535-1P-PRI
- 9013 5535-2P-PRI
- 9023 5536-4P-BRI-ST
- 9027 5536-4P-BRI-U
- 9031 5536-1P-PRI
- 9033 5536-2P-PRI
-107f Data Technology Corporation
- 0802 SL82C105
-1080 Contaq Microsystems
- 0600 82C599
- c691 Cypress CY82C691
- c693 82c693
-1081 Supermac Technology
- 0d47 Radius PCI to NuBUS Bridge
-1082 EFA Corporation of America
-1083 Forex Computer Corporation
- 0001 FR710
-1084 Parador
-1085 Tulip Computers Int.B.V.
-1086 J. Bond Computer Systems
-1087 Cache Computer
-1088 Microcomputer Systems (M) Son
-1089 Data General Corporation
-# Formerly Bit3 Computer Corp.
-108a SBS Technologies
- 0001 VME Bridge Model 617
- 0010 VME Bridge Model 618
- 0040 dataBLIZZARD
- 3000 VME Bridge Model 2706
-108c Oakleigh Systems Inc.
-108d Olicom
- 0001 Token-Ring 16/4 PCI Adapter (3136/3137)
- 0002 16/4 Token Ring
- 0004 RapidFire 3139 Token-Ring 16/4 PCI Adapter
- 108d 0004 OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
- 0005 GoCard 3250 Token-Ring 16/4 CardBus PC Card
- 0006 OC-3530 RapidFire Token-Ring 100
- 0007 RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
- 108d 0007 OC-3141 RapidFire Token-Ring 16/4 Adapter
- 0008 RapidFire 3540 HSTR 100/16/4 PCI Adapter
- 108d 0008 OC-3540 RapidFire HSTR 100/16/4 Adapter
- 0011 OC-2315
- 0012 OC-2325
- 0013 OC-2183/2185
- 0014 OC-2326
- 0019 OC-2327/2250 10/100 Ethernet Adapter
- 108d 0016 OC-2327 Rapidfire 10/100 Ethernet Adapter
- 108d 0017 OC-2250 GoCard 10/100 Ethernet Adapter
- 0021 OC-6151/6152 [RapidFire ATM 155]
- 0022 ATM Adapter
-108e Sun Microsystems Computer Corp.
- 0001 EBUS
- 1000 EBUS
- 1001 Happy Meal
- 1100 RIO EBUS
- 1101 RIO GEM
- 1102 RIO 1394
- 1103 RIO USB
- 1648 [bge] Gigabit Ethernet
- 2bad GEM
- 5000 Simba Advanced PCI Bridge
- 5043 SunPCI Co-processor
- 8000 Psycho PCI Bus Module
- 8001 Schizo PCI Bus Module
- 8002 Schizo+ PCI Bus Module
- a000 Ultra IIi
- a001 Ultra IIe
- a801 Tomatillo PCI Bus Module
- abba Cassini 10/100/1000
-108f Systemsoft
-1090 Encore Computer Corporation
-1091 Intergraph Corporation
- 0020 3D graphics processor
- 0021 3D graphics processor w/Texturing
- 0040 3D graphics frame buffer
- 0041 3D graphics frame buffer
- 0060 Proprietary bus bridge
- 00e4 Powerstorm 4D50T
- 0720 Motion JPEG codec
- 07a0 Sun Expert3D-Lite Graphics Accelerator
- 1091 Sun Expert3D Graphics Accelerator
-1092 Diamond Multimedia Systems
- 00a0 Speedstar Pro SE
- 00a8 Speedstar 64
- 0550 Viper V550
- 08d4 Supra 2260 Modem
- 094c SupraExpress 56i Pro
- 1092 Viper V330
- 6120 Maximum DVD
- 8810 Stealth SE
- 8811 Stealth 64/SE
- 8880 Stealth
- 8881 Stealth
- 88b0 Stealth 64
- 88b1 Stealth 64
- 88c0 Stealth 64
- 88c1 Stealth 64
- 88d0 Stealth 64
- 88d1 Stealth 64
- 88f0 Stealth 64
- 88f1 Stealth 64
- 9999 DMD-I0928-1 "Monster sound" sound chip
-1093 National Instruments
- 0160 PCI-DIO-96
- 0162 PCI-MIO-16XE-50
- 1170 PCI-MIO-16XE-10
- 1180 PCI-MIO-16E-1
- 1190 PCI-MIO-16E-4
- 1310 PCI-6602
- 1330 PCI-6031E
- 1350 PCI-6071E
- 14e0 PCI-6110
- 14f0 PCI-6111
- 17d0 PCI-6503
- 1870 PCI-6713
- 1880 PCI-6711
- 18b0 PCI-6052E
- 2410 PCI-6733
- 2890 PCI-6036E
- 2a60 PCI-6023E
- 2a70 PCI-6024E
- 2a80 PCI-6025E
- 2c80 PCI-6035E
- 2ca0 PCI-6034E
- 70b8 PCI-6251 [M Series - High Speed Multifunction DAQ]
- b001 IMAQ-PCI-1408
- b011 IMAQ-PXI-1408
- b021 IMAQ-PCI-1424
- b031 IMAQ-PCI-1413
- b041 IMAQ-PCI-1407
- b051 IMAQ-PXI-1407
- b061 IMAQ-PCI-1411
- b071 IMAQ-PCI-1422
- b081 IMAQ-PXI-1422
- b091 IMAQ-PXI-1411
- c801 PCI-GPIB
- c831 PCI-GPIB bridge
-1094 First International Computers [FIC]
-1095 Silicon Image, Inc. (formerly CMD Technology Inc)
- 0240 Adaptec AAR-1210SA SATA HostRAID Controller
- 0640 PCI0640
- 0643 PCI0643
- 0646 PCI0646
- 0647 PCI0647
- 0648 PCI0648
- 0649 SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
- 0e11 005d Integrated Ultra ATA-100 Dual Channel Controller
- 0e11 007e Integrated Ultra ATA-100 IDE RAID Controller
- 101e 0649 AMI MegaRAID IDE 100 Controller
- 0650 PBC0650A
- 0670 USB0670
- 1095 0670 USB0670
- 0673 USB0673
- 0680 PCI0680 Ultra ATA-133 Host Controller
- 1095 3680 Winic W-680 (Silicon Image 680 based)
- 3112 SiI 3112 [SATALink/SATARaid] Serial ATA Controller
- 1095 3112 SiI 3112 SATALink Controller
- 1095 6112 SiI 3112 SATARaid Controller
- 3114 SiI 3114 [SATALink/SATARaid] Serial ATA Controller
- 1095 3114 SiI 3114 SATALink Controller
- 1095 6114 SiI 3114 SATARaid Controller
- 3124 SiI 3124 PCI-X Serial ATA Controller
- 1095 3124 SiI 3124 PCI-X Serial ATA Controller
- 3512 SiI 3512 [SATALink/SATARaid] Serial ATA Controller
- 1095 3512 SiI 3512 SATALink Controller
- 1095 6512 SiI 3512 SATARaid Controller
-1096 Alacron
-1097 Appian Technology
-1098 Quantum Designs (H.K.) Ltd
- 0001 QD-8500
- 0002 QD-8580
-1099 Samsung Electronics Co., Ltd
-109a Packard Bell
-109b Gemlight Computer Ltd.
-109c Megachips Corporation
-109d Zida Technologies Ltd.
-109e Brooktree Corporation
- 0350 Bt848 Video Capture
- 0351 Bt849A Video capture
- 0369 Bt878 Video Capture
- 1002 0001 TV-Wonder
- 1002 0003 TV-Wonder/VE
- 036c Bt879(??) Video Capture
- 13e9 0070 Win/TV (Video Section)
- 036e Bt878 Video Capture
- 0070 13eb WinTV Series
- 0070 ff01 Viewcast Osprey 200
- 0071 0101 DigiTV PCI
- 107d 6606 WinFast TV 2000
- 11bd 0012 PCTV pro (TV + FM stereo receiver)
- 11bd 001c PCTV Sat (DBC receiver)
- 127a 0001 Bt878 Mediastream Controller NTSC
- 127a 0002 Bt878 Mediastream Controller PAL BG
- 127a 0003 Bt878a Mediastream Controller PAL BG
- 127a 0048 Bt878/832 Mediastream Controller
- 144f 3000 MagicTView CPH060 - Video
- 1461 0002 TV98 Series (TV/No FM/Remote)
- 1461 0003 AverMedia UltraTV PCI 350
- 1461 0004 AVerTV WDM Video Capture
- 1461 0761 AverTV DVB-T
- 14f1 0001 Bt878 Mediastream Controller NTSC
- 14f1 0002 Bt878 Mediastream Controller PAL BG
- 14f1 0003 Bt878a Mediastream Controller PAL BG
- 14f1 0048 Bt878/832 Mediastream Controller
- 1822 0001 VisionPlus DVB card
- 1851 1850 FlyVideo'98 - Video
- 1851 1851 FlyVideo II
- 1852 1852 FlyVideo'98 - Video (with FM Tuner)
- 270f fc00 Digitop DTT-1000
- bd11 1200 PCTV pro (TV + FM stereo receiver)
- 036f Bt879 Video Capture
- 127a 0044 Bt879 Video Capture NTSC
- 127a 0122 Bt879 Video Capture PAL I
- 127a 0144 Bt879 Video Capture NTSC
- 127a 0222 Bt879 Video Capture PAL BG
- 127a 0244 Bt879a Video Capture NTSC
- 127a 0322 Bt879 Video Capture NTSC
- 127a 0422 Bt879 Video Capture NTSC
- 127a 1122 Bt879 Video Capture PAL I
- 127a 1222 Bt879 Video Capture PAL BG
- 127a 1322 Bt879 Video Capture NTSC
- 127a 1522 Bt879a Video Capture PAL I
- 127a 1622 Bt879a Video Capture PAL BG
- 127a 1722 Bt879a Video Capture NTSC
- 14f1 0044 Bt879 Video Capture NTSC
- 14f1 0122 Bt879 Video Capture PAL I
- 14f1 0144 Bt879 Video Capture NTSC
- 14f1 0222 Bt879 Video Capture PAL BG
- 14f1 0244 Bt879a Video Capture NTSC
- 14f1 0322 Bt879 Video Capture NTSC
- 14f1 0422 Bt879 Video Capture NTSC
- 14f1 1122 Bt879 Video Capture PAL I
- 14f1 1222 Bt879 Video Capture PAL BG
- 14f1 1322 Bt879 Video Capture NTSC
- 14f1 1522 Bt879a Video Capture PAL I
- 14f1 1622 Bt879a Video Capture PAL BG
- 14f1 1722 Bt879a Video Capture NTSC
- 1851 1850 FlyVideo'98 - Video
- 1851 1851 FlyVideo II
- 1852 1852 FlyVideo'98 - Video (with FM Tuner)
- 0370 Bt880 Video Capture
- 1851 1850 FlyVideo'98
- 1851 1851 FlyVideo'98 EZ - video
- 1852 1852 FlyVideo'98 (with FM Tuner)
- 0878 Bt878 Audio Capture
- 0070 13eb WinTV Series
- 0070 ff01 Viewcast Osprey 200
- 0071 0101 DigiTV PCI
- 1002 0001 TV-Wonder
- 1002 0003 TV-Wonder/VE
- 11bd 0012 PCTV pro (TV + FM stereo receiver, audio section)
- 11bd 001c PCTV Sat (DBC receiver)
- 127a 0001 Bt878 Video Capture (Audio Section)
- 127a 0002 Bt878 Video Capture (Audio Section)
- 127a 0003 Bt878 Video Capture (Audio Section)
- 127a 0048 Bt878 Video Capture (Audio Section)
- 13e9 0070 Win/TV (Audio Section)
- 144f 3000 MagicTView CPH060 - Audio
- 1461 0004 AVerTV WDM Audio Capture
- 1461 0761 AVerTV DVB-T
- 14f1 0001 Bt878 Video Capture (Audio Section)
- 14f1 0002 Bt878 Video Capture (Audio Section)
- 14f1 0003 Bt878 Video Capture (Audio Section)
- 14f1 0048 Bt878 Video Capture (Audio Section)
- 1822 0001 VisionPlus DVB Card
- 270f fc00 Digitop DTT-1000
- bd11 1200 PCTV pro (TV + FM stereo receiver, audio section)
- 0879 Bt879 Audio Capture
- 127a 0044 Bt879 Video Capture (Audio Section)
- 127a 0122 Bt879 Video Capture (Audio Section)
- 127a 0144 Bt879 Video Capture (Audio Section)
- 127a 0222 Bt879 Video Capture (Audio Section)
- 127a 0244 Bt879 Video Capture (Audio Section)
- 127a 0322 Bt879 Video Capture (Audio Section)
- 127a 0422 Bt879 Video Capture (Audio Section)
- 127a 1122 Bt879 Video Capture (Audio Section)
- 127a 1222 Bt879 Video Capture (Audio Section)
- 127a 1322 Bt879 Video Capture (Audio Section)
- 127a 1522 Bt879 Video Capture (Audio Section)
- 127a 1622 Bt879 Video Capture (Audio Section)
- 127a 1722 Bt879 Video Capture (Audio Section)
- 14f1 0044 Bt879 Video Capture (Audio Section)
- 14f1 0122 Bt879 Video Capture (Audio Section)
- 14f1 0144 Bt879 Video Capture (Audio Section)
- 14f1 0222 Bt879 Video Capture (Audio Section)
- 14f1 0244 Bt879 Video Capture (Audio Section)
- 14f1 0322 Bt879 Video Capture (Audio Section)
- 14f1 0422 Bt879 Video Capture (Audio Section)
- 14f1 1122 Bt879 Video Capture (Audio Section)
- 14f1 1222 Bt879 Video Capture (Audio Section)
- 14f1 1322 Bt879 Video Capture (Audio Section)
- 14f1 1522 Bt879 Video Capture (Audio Section)
- 14f1 1622 Bt879 Video Capture (Audio Section)
- 14f1 1722 Bt879 Video Capture (Audio Section)
- 0880 Bt880 Audio Capture
- 2115 BtV 2115 Mediastream controller
- 2125 BtV 2125 Mediastream controller
- 2164 BtV 2164
- 2165 BtV 2165
- 8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
- 8472 Bt8472
- 8474 Bt8474
-109f Trigem Computer Inc.
-10a0 Meidensha Corporation
-10a1 Juko Electronics Ind. Co. Ltd
-10a2 Quantum Corporation
-10a3 Everex Systems Inc
-10a4 Globe Manufacturing Sales
-10a5 Smart Link Ltd.
- 3052 SmartPCI562 56K Modem
- 5449 SmartPCI561 modem
-10a6 Informtech Industrial Ltd.
-10a7 Benchmarq Microelectronics
-10a8 Sierra Semiconductor
- 0000 STB Horizon 64
-10a9 Silicon Graphics, Inc.
- 0001 Crosstalk to PCI Bridge
- 0002 Linc I/O controller
- 0003 IOC3 I/O controller
- 0004 O2 MACE
- 0005 RAD Audio
- 0006 HPCEX
- 0007 RPCEX
- 0008 DiVO VIP
- 0009 AceNIC Gigabit Ethernet
- 10a9 8002 AceNIC Gigabit Ethernet
- 0010 AMP Video I/O
- 0011 GRIP
- 0012 SGH PSHAC GSN
- 1001 Magic Carpet
- 1002 Lithium
- 1003 Dual JPEG 1
- 1004 Dual JPEG 2
- 1005 Dual JPEG 3
- 1006 Dual JPEG 4
- 1007 Dual JPEG 5
- 1008 Cesium
- 100a IOC4 I/O controller
- 2001 Fibre Channel
- 2002 ASDE
- 8001 O2 1394
- 8002 G-net NT
-10aa ACC Microelectronics
- 0000 ACCM 2188
-10ab Digicom
-10ac Honeywell IAC
-10ad Symphony Labs
- 0001 W83769F
- 0003 SL82C103
- 0005 SL82C105
- 0103 SL82c103
- 0105 SL82c105
- 0565 W83C553
-10ae Cornerstone Technology
-10af Micro Computer Systems Inc
-10b0 CardExpert Technology
-10b1 Cabletron Systems Inc
-10b2 Raytheon Company
-10b3 Databook Inc
- 3106 DB87144
- b106 DB87144
-10b4 STB Systems Inc
- 1b1d Velocity 128 3D
- 10b4 237e Velocity 4400
-10b5 PLX Technology, Inc.
- 0001 i960 PCI bus interface
- 1076 VScom 800 8 port serial adaptor
- 1077 VScom 400 4 port serial adaptor
- 1078 VScom 210 2 port serial and 1 port parallel adaptor
- 1103 VScom 200 2 port serial adaptor
- 1146 VScom 010 1 port parallel adaptor
- 1147 VScom 020 2 port parallel adaptor
- 2724 Thales PCSM Security Card
- 8516 PEX 8516 Versatile PCI Express Switch
- 8532 PEX 8532 Versatile PCI Express Switch
- 9030 PCI <-> IOBus Bridge Hot Swap
- 10b5 2862 Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
- 10b5 2906 Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
- 10b5 2940 Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
- 10b5 3025 Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
- 10b5 3068 Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
- 15ed 1002 MCCS 8-port Serial Hot Swap
- 15ed 1003 MCCS 16-port Serial Hot Swap
- 9036 9036
- 9050 PCI <-> IOBus Bridge
- 10b5 1067 IXXAT CAN i165
- 10b5 1172 IK220 (Heidenhain)
- 10b5 2036 SatPak GPS
- 10b5 2221 Alpermann+Velte PCL PCI LV: Timecode Reader Board
- 10b5 2273 SH-ARC SoHard ARCnet card
- 10b5 2431 Alpermann+Velte PCL PCI D: Timecode Reader Board
- 10b5 2905 Alpermann+Velte PCI TS: Time Synchronisation Board
- 10b5 9050 MP9050
- 1498 0362 TPMC866 8 Channel Serial Card
- 1522 0001 RockForce 4 Port V.90 Data/Fax/Voice Modem
- 1522 0002 RockForce 2 Port V.90 Data/Fax/Voice Modem
- 1522 0003 RockForce 6 Port V.90 Data/Fax/Voice Modem
- 1522 0004 RockForce 8 Port V.90 Data/Fax/Voice Modem
- 1522 0010 RockForce2000 4 Port V.90 Data/Fax/Voice Modem
- 1522 0020 RockForce2000 2 Port V.90 Data/Fax/Voice Modem
- 15ed 1000 Macrolink MCCS 8-port Serial
- 15ed 1001 Macrolink MCCS 16-port Serial
- 15ed 1002 Macrolink MCCS 8-port Serial Hot Swap
- 15ed 1003 Macrolink MCCS 16-port Serial Hot Swap
-# Sorry, there was a typo
- 5654 2036 OpenSwitch 6 Telephony card
-# Sorry, there was a typo
- 5654 3132 OpenSwitch 12 Telephony card
- 5654 5634 OpenLine4 Telephony Card
- d531 c002 PCIntelliCAN 2xSJA1000 CAN bus
- d84d 4006 EX-4006 1P
- d84d 4008 EX-4008 1P EPP/ECP
- d84d 4014 EX-4014 2P
- d84d 4018 EX-4018 3P EPP/ECP
- d84d 4025 EX-4025 1S(16C550) RS-232
- d84d 4027 EX-4027 1S(16C650) RS-232
- d84d 4028 EX-4028 1S(16C850) RS-232
- d84d 4036 EX-4036 2S(16C650) RS-232
- d84d 4037 EX-4037 2S(16C650) RS-232
- d84d 4038 EX-4038 2S(16C850) RS-232
- d84d 4052 EX-4052 1S(16C550) RS-422/485
- d84d 4053 EX-4053 2S(16C550) RS-422/485
- d84d 4055 EX-4055 4S(16C550) RS-232
- d84d 4058 EX-4055 4S(16C650) RS-232
- d84d 4065 EX-4065 8S(16C550) RS-232
- d84d 4068 EX-4068 8S(16C650) RS-232
- d84d 4078 EX-4078 2S(16C552) RS-232+1P
- 9054 PCI <-> IOBus Bridge
- 10b5 2455 Wessex Techology PHIL-PCI
- 10b5 2696 Innes Corp AM Radcap card
- 10b5 2717 Innes Corp Auricon card
- 10b5 2844 Innes Corp TVS Encoder card
- 12d9 0002 PCI Prosody Card rev 1.5
- 16df 0011 PIKA PrimeNet MM PCI
- 16df 0012 PIKA PrimeNet MM cPCI 8
- 16df 0013 PIKA PrimeNet MM cPCI 8 (without CAS Signaling Option)
- 16df 0014 PIKA PrimeNet MM cPCI 4
- 16df 0015 PIKA Daytona MM
- 16df 0016 PIKA InLine MM
- 9056 Francois
- 10b5 2979 CellinkBlade 11 - CPCI board VoATM AAL1
- 9060 9060
- 906d 9060SD
- 125c 0640 Aries 16000P
- 906e 9060ES
- 9080 9080
- 103c 10eb (Agilent) E2777B 83K Series PCI based Optical Communication Interface
- 103c 10ec (Agilent) E6978-66442 PCI CIC
- 10b5 9080 9080 [real subsystem ID not set]
- 129d 0002 Aculab PCI Prosidy card
- 12d9 0002 PCI Prosody Card
- 12df 4422 4422PCI ["Do-All" Telemetry Data Aquisition System]
- bb04 B&B 3PCIOSD1A Isolated PCI Serial
-10b6 Madge Networks
- 0001 Smart 16/4 PCI Ringnode
- 0002 Smart 16/4 PCI Ringnode Mk2
- 10b6 0002 Smart 16/4 PCI Ringnode Mk2
- 10b6 0006 16/4 CardBus Adapter
- 0003 Smart 16/4 PCI Ringnode Mk3
- 0e11 b0fd Compaq NC4621 PCI, 4/16, WOL
- 10b6 0003 Smart 16/4 PCI Ringnode Mk3
- 10b6 0007 Presto PCI Plus Adapter
- 0004 Smart 16/4 PCI Ringnode Mk1
- 0006 16/4 Cardbus Adapter
- 10b6 0006 16/4 CardBus Adapter
- 0007 Presto PCI Adapter
- 10b6 0007 Presto PCI
- 0009 Smart 100/16/4 PCI-HS Ringnode
- 10b6 0009 Smart 100/16/4 PCI-HS Ringnode
- 000a Smart 100/16/4 PCI Ringnode
- 10b6 000a Smart 100/16/4 PCI Ringnode
- 000b 16/4 CardBus Adapter Mk2
- 10b6 0008 16/4 CardBus Adapter Mk2
- 10b6 000b 16/4 Cardbus Adapter Mk2
- 000c RapidFire 3140V2 16/4 TR Adapter
- 10b6 000c RapidFire 3140V2 16/4 TR Adapter
- 1000 Collage 25/155 ATM Client Adapter
- 1001 Collage 155 ATM Server Adapter
-10b7 3Com Corporation
- 0001 3c985 1000BaseSX (SX/TX)
- 0013 AR5212 802.11abg NIC (3CRDAG675)
- 10b7 2031 3CRDAG675 11a/b/g Wireless PCI Adapter
- 0910 3C910-A01
- 1006 MINI PCI type 3B Data Fax Modem
- 1007 Mini PCI 56k Winmodem
- 10b7 615c Mini PCI 56K Modem
- 1201 3c982-TXM 10/100baseTX Dual Port A [Hydra]
- 1202 3c982-TXM 10/100baseTX Dual Port B [Hydra]
- 1700 3c940 10/100/1000Base-T [Marvell]
- 1043 80eb P4P800/K8V Deluxe motherboard
- 10b7 0010 3C940 Gigabit LOM Ethernet Adapter
- 10b7 0020 3C941 Gigabit LOM Ethernet Adapter
- 147b 1407 KV8-MAX3 motherboard
- 3390 3c339 TokenLink Velocity
- 3590 3c359 TokenLink Velocity XL
- 10b7 3590 TokenLink Velocity XL Adapter (3C359/359B)
- 4500 3c450 HomePNA [Tornado]
- 5055 3c555 Laptop Hurricane
- 5057 3c575 Megahertz 10/100 LAN CardBus [Boomerang]
- 10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5157 3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
- 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5257 3cCFE575CT CardBus [Cyclone]
- 10b7 5c57 FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
- 5900 3c590 10BaseT [Vortex]
- 5920 3c592 EISA 10mbps Demon/Vortex
- 5950 3c595 100BaseTX [Vortex]
- 5951 3c595 100BaseT4 [Vortex]
- 5952 3c595 100Base-MII [Vortex]
- 5970 3c597 EISA Fast Demon/Vortex
- 5b57 3c595 Megahertz 10/100 LAN CardBus [Boomerang]
- 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 6000 3CRSHPW796 [OfficeConnect Wireless CardBus]
- 6001 3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
- 6055 3c556 Hurricane CardBus [Cyclone]
- 6056 3c556B CardBus [Tornado]
- 10b7 6556 10/100 Mini PCI Ethernet Adapter
- 6560 3cCFE656 CardBus [Cyclone]
- 10b7 656a 3CCFEM656 10/100 LAN+56K Modem CardBus
- 6561 3cCFEM656 10/100 LAN+56K Modem CardBus
- 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
- 6562 3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
- 10b7 656b 3CCFEM656B 10/100 LAN+56K Modem CardBus
- 6563 3cCFEM656B 10/100 LAN+56K Modem CardBus
- 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
- 6564 3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
- 7646 3cSOHO100-TX Hurricane
- 7770 3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
- 7940 3c803 FDDILink UTP Controller
- 7980 3c804 FDDILink SAS Controller
- 7990 3c805 FDDILink DAS Controller
- 80eb 3c940B 10/100/1000Base-T
- 8811 Token ring
- 9000 3c900 10BaseT [Boomerang]
- 9001 3c900 10Mbps Combo [Boomerang]
- 9004 3c900B-TPO Etherlink XL [Cyclone]
- 10b7 9004 3C900B-TPO Etherlink XL TPO 10Mb
- 9005 3c900B-Combo Etherlink XL [Cyclone]
- 10b7 9005 3C900B-Combo Etherlink XL Combo
- 9006 3c900B-TPC Etherlink XL [Cyclone]
- 900a 3c900B-FL 10base-FL [Cyclone]
- 9050 3c905 100BaseTX [Boomerang]
- 9051 3c905 100BaseT4 [Boomerang]
- 9055 3c905B 100BaseTX [Cyclone]
- 1028 0080 3C905B Fast Etherlink XL 10/100
- 1028 0081 3C905B Fast Etherlink XL 10/100
- 1028 0082 3C905B Fast Etherlink XL 10/100
- 1028 0083 3C905B Fast Etherlink XL 10/100
- 1028 0084 3C905B Fast Etherlink XL 10/100
- 1028 0085 3C905B Fast Etherlink XL 10/100
- 1028 0086 3C905B Fast Etherlink XL 10/100
- 1028 0087 3C905B Fast Etherlink XL 10/100
- 1028 0088 3C905B Fast Etherlink XL 10/100
- 1028 0089 3C905B Fast Etherlink XL 10/100
- 1028 0090 3C905B Fast Etherlink XL 10/100
- 1028 0091 3C905B Fast Etherlink XL 10/100
- 1028 0092 3C905B Fast Etherlink XL 10/100
- 1028 0093 3C905B Fast Etherlink XL 10/100
- 1028 0094 3C905B Fast Etherlink XL 10/100
- 1028 0095 3C905B Fast Etherlink XL 10/100
- 1028 0096 3C905B Fast Etherlink XL 10/100
- 1028 0097 3C905B Fast Etherlink XL 10/100
- 1028 0098 3C905B Fast Etherlink XL 10/100
- 1028 0099 3C905B Fast Etherlink XL 10/100
- 10b7 9055 3C905B Fast Etherlink XL 10/100
- 9056 3c905B-T4 Fast EtherLink XL [Cyclone]
- 9058 3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
- 905a 3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
- 9200 3c905C-TX/TX-M [Tornado]
- 1028 0095 3C920 Integrated Fast Ethernet Controller
- 1028 0097 3C920 Integrated Fast Ethernet Controller
- 1028 00fe Optiplex GX240
- 1028 012a 3C920 Integrated Fast Ethernet Controller [Latitude C640]
- 10b7 1000 3C905C-TX Fast Etherlink for PC Management NIC
- 10b7 7000 10/100 Mini PCI Ethernet Adapter
- 10f1 2466 Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
- 9201 3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
- 1043 80ab A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
- 9202 3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
- 9210 3C920B-EMB-WNM Integrated Fast Ethernet Controller
- 9300 3CSOHO100B-TX 910-A01 [tulip]
- 9800 3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
- 10b7 9800 3c980-TX Fast Etherlink XL Server Adapter
- 9805 3c980-C 10/100baseTX NIC [Python-T]
- 10b7 1201 EtherLink Server 10/100 Dual Port A
- 10b7 1202 EtherLink Server 10/100 Dual Port B
- 10b7 9805 3c980 10/100baseTX NIC [Python-T]
- 10f1 2462 Thunder K7 S2462
- 9900 3C990-TX [Typhoon]
- 9902 3CR990-TX-95 [Typhoon 56-bit]
- 9903 3CR990-TX-97 [Typhoon 168-bit]
- 9904 3C990B-TX-M/3C990BSVR [Typhoon2]
- 10b7 1000 3CR990B-TX-M [Typhoon2]
- 10b7 2000 3CR990BSVR [Typhoon2 Server]
- 9905 3CR990-FX-95/97/95 [Typhon Fiber]
- 10b7 1101 3CR990-FX-95 [Typhoon Fiber 56-bit]
- 10b7 1102 3CR990-FX-97 [Typhoon Fiber 168-bit]
- 10b7 2101 3CR990-FX-95 Server [Typhoon Fiber 56-bit]
- 10b7 2102 3CR990-FX-97 Server [Typhoon Fiber 168-bit]
- 9908 3CR990SVR95 [Typhoon Server 56-bit]
- 9909 3CR990SVR97 [Typhoon Server 168-bit]
- 990a 3C990SVR [Typhoon Server]
- 990b 3C990SVR [Typhoon Server]
-10b8 Standard Microsystems Corp [SMC]
- 0005 83c170 EPIC/100 Fast Ethernet Adapter
- 1055 e000 LANEPIC 10/100 [EVB171Q-PCI]
- 1055 e002 LANEPIC 10/100 [EVB171G-PCI]
- 10b8 a011 EtherPower II 10/100
- 10b8 a014 EtherPower II 10/100
- 10b8 a015 EtherPower II 10/100
- 10b8 a016 EtherPower II 10/100
- 10b8 a017 EtherPower II 10/100
- 0006 83c175 EPIC/100 Fast Ethernet Adapter
- 1055 e100 LANEPIC Cardbus Fast Ethernet Adapter
- 1055 e102 LANEPIC Cardbus Fast Ethernet Adapter
- 1055 e300 LANEPIC Cardbus Fast Ethernet Adapter
- 1055 e302 LANEPIC Cardbus Fast Ethernet Adapter
- 10b8 a012 LANEPIC Cardbus Fast Ethernet Adapter
- 13a2 8002 LANEPIC Cardbus Fast Ethernet Adapter
- 13a2 8006 LANEPIC Cardbus Fast Ethernet Adapter
- 1000 FDC 37c665
- 1001 FDC 37C922
-# 802.11g card
- 2802 SMC2802W [EZ Connect g]
- a011 83C170QF
- b106 SMC34C90
-10b9 ALi Corporation
- 0101 CMI8338/C3DX PCI Audio Device
- 0111 C-Media CMI8738/C3DX Audio Device (OEM)
- 10b9 0111 C-Media CMI8738/C3DX Audio Device (OEM)
- 0780 Multi-IO Card
- 0782 Multi-IO Card
- 1435 M1435
- 1445 M1445
- 1449 M1449
- 1451 M1451
- 1461 M1461
- 1489 M1489
- 1511 M1511 [Aladdin]
- 1512 M1512 [Aladdin]
- 1513 M1513 [Aladdin]
- 1521 M1521 [Aladdin III]
- 10b9 1521 ALI M1521 Aladdin III CPU Bridge
- 1523 M1523
- 10b9 1523 ALI M1523 ISA Bridge
- 1531 M1531 [Aladdin IV]
- 1533 M1533 PCI to ISA Bridge [Aladdin IV]
- 1014 053b ThinkPad R40e (2684-HVG) PCI to ISA Bridge
- 10b9 1533 ALI M1533 Aladdin IV ISA Bridge
- 1541 M1541
- 10b9 1541 ALI M1541 Aladdin V/V+ AGP System Controller
- 1543 M1543
- 1563 M1563 HyperTransport South Bridge
- 1621 M1621
- 1631 ALI M1631 PCI North Bridge Aladdin Pro III
- 1632 M1632M Northbridge+Trident
- 1641 ALI M1641 PCI North Bridge Aladdin Pro IV
- 1644 M1644/M1644T Northbridge+Trident
- 1646 M1646 Northbridge+Trident
- 1647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
- 1651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
- 1671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
- 1672 M1672 Northbridge [CyberALADDiN-P4]
- 1681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
- 1687 M1687 K8 Northbridge [AGP8X and HyperTransport]
- 1689 M1689 K8 Northbridge [Super K8 Single Chip]
- 3141 M3141
- 3143 M3143
- 3145 M3145
- 3147 M3147
- 3149 M3149
- 3151 M3151
- 3307 M3307
- 3309 M3309
- 3323 M3325 Video/Audio Decoder
- 5212 M4803
- 5215 MS4803
- 5217 M5217H
- 5219 M5219
- 5225 M5225
- 5228 M5228 ALi ATA/RAID Controller
- 5229 M5229 IDE
- 1014 050f ThinkPad R30
- 1014 053d ThinkPad R40e (2684-HVG) builtin IDE
- 103c 0024 Pavilion ze4400 builtin IDE
- 1043 8053 A7A266 Motherboard IDE
- 5235 M5225
- 5237 USB 1.1 Controller
- 1014 0540 ThinkPad R40e (2684-HVG) builtin USB
- 103c 0024 Pavilion ze4400 builtin USB
- 5239 USB 2.0 Controller
- 5243 M1541 PCI to AGP Controller
- 5246 AGP8X Controller
- 5247 PCI to AGP Controller
- 5249 M5249 HTT to PCI Bridge
- 5251 M5251 P1394 OHCI 1.0 Controller
- 5253 M5253 P1394 OHCI 1.1 Controller
- 5261 M5261 Ethernet Controller
- 5263 M5263 Ethernet Controller
- 5281 ALi M5281 Serial ATA / RAID Host Controller
- 5287 ULi 5287 SATA
- 5289 ULi 5289 SATA
- 5450 Lucent Technologies Soft Modem AMR
- 5451 M5451 PCI AC-Link Controller Audio Device
- 1014 0506 ThinkPad R30
- 1014 053e ThinkPad R40e (2684-HVG) builtin Audio
- 103c 0024 Pavilion ze4400 builtin Audio
- 10b9 5451 HP Compaq nc4010 (DY885AA#ABN)
- 5453 M5453 PCI AC-Link Controller Modem Device
- 5455 M5455 PCI AC-Link Controller Audio Device
- 5457 M5457 AC'97 Modem Controller
- 1014 0535 ThinkPad R40e (2684-HVG) builtin modem
- 103c 0024 Pavilion ze4400 builtin Modem Device
-# Same but more usefull for driver's lookup
- 5459 SmartLink SmartPCI561 56K Modem
-# SmartLink PCI SoftModem
- 545a SmartLink SmartPCI563 56K Modem
- 5471 M5471 Memory Stick Controller
- 5473 M5473 SD-MMC Controller
- 7101 M7101 Power Management Controller [PMU]
- 1014 0510 ThinkPad R30
- 1014 053c ThinkPad R40e (2684-HVG) Power Management Controller
- 103c 0024 Pavilion ze4400
-10ba Mitsubishi Electric Corp.
- 0301 AccelGraphics AccelECLIPSE
- 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
- 0308 Tornado 3000 [OEM Evans & Sutherland]
- 1002 VG500 [VolumePro Volume Rendering Accelerator]
-10bb Dapha Electronics Corporation
-10bc Advanced Logic Research
-10bd Surecom Technology
- 0e34 NE-34
-10be Tseng Labs International Co.
-10bf Most Inc
-10c0 Boca Research Inc.
-10c1 ICM Co., Ltd.
-10c2 Auspex Systems Inc.
-10c3 Samsung Semiconductors, Inc.
- 1100 Smartether100 SC1100 LAN Adapter (i82557B)
-10c4 Award Software International Inc.
-10c5 Xerox Corporation
-10c6 Rambus Inc.
-10c7 Media Vision
-10c8 Neomagic Corporation
- 0001 NM2070 [MagicGraph 128]
- 0002 NM2090 [MagicGraph 128V]
- 0003 NM2093 [MagicGraph 128ZV]
- 0004 NM2160 [MagicGraph 128XD]
- 1014 00ba MagicGraph 128XD
- 1025 1007 MagicGraph 128XD
- 1028 0074 MagicGraph 128XD
- 1028 0075 MagicGraph 128XD
- 1028 007d MagicGraph 128XD
- 1028 007e MagicGraph 128XD
- 1033 802f MagicGraph 128XD
- 104d 801b MagicGraph 128XD
- 104d 802f MagicGraph 128XD
- 104d 830b MagicGraph 128XD
- 10ba 0e00 MagicGraph 128XD
- 10c8 0004 MagicGraph 128XD
- 10cf 1029 MagicGraph 128XD
- 10f7 8308 MagicGraph 128XD
- 10f7 8309 MagicGraph 128XD
- 10f7 830b MagicGraph 128XD
- 10f7 830d MagicGraph 128XD
- 10f7 8312 MagicGraph 128XD
- 0005 NM2200 [MagicGraph 256AV]
- 1014 00dd ThinkPad 570
- 1028 0088 Latitude CPi A
- 0006 NM2360 [MagicMedia 256ZX]
- 0016 NM2380 [MagicMedia 256XL+]
- 10c8 0016 MagicMedia 256XL+
- 0025 NM2230 [MagicGraph 256AV+]
- 0083 NM2093 [MagicGraph 128ZV+]
- 8005 NM2200 [MagicMedia 256AV Audio]
- 0e11 b0d1 MagicMedia 256AV Audio Device on Discovery
- 0e11 b126 MagicMedia 256AV Audio Device on Durango
- 1014 00dd MagicMedia 256AV Audio Device on BlackTip Thinkpad
- 1025 1003 MagicMedia 256AV Audio Device on TravelMate 720
- 1028 0088 Latitude CPi A
- 1028 008f MagicMedia 256AV Audio Device on Colorado Inspiron
- 103c 0007 MagicMedia 256AV Audio Device on Voyager II
- 103c 0008 MagicMedia 256AV Audio Device on Voyager III
- 103c 000d MagicMedia 256AV Audio Device on Omnibook 900
- 10c8 8005 MagicMedia 256AV Audio Device on FireAnt
- 110a 8005 MagicMedia 256AV Audio Device
- 14c0 0004 MagicMedia 256AV Audio Device
- 8006 NM2360 [MagicMedia 256ZX Audio]
- 8016 NM2380 [MagicMedia 256XL+ Audio]
-10c9 Dataexpert Corporation
-10ca Fujitsu Microelectr., Inc.
-10cb Omron Corporation
-# nee Mentor ARC Inc
-10cc Mai Logic Incorporated
- 0660 Articia S Host Bridge
- 0661 Articia S PCI Bridge
-10cd Advanced System Products, Inc
- 1100 ASC1100
- 1200 ASC1200 [(abp940) Fast SCSI-II]
- 1300 ABP940-U / ABP960-U
- 10cd 1310 ASC1300 SCSI Adapter
- 2300 ABP940-UW
- 2500 ABP940-U2W
-10ce Radius
-# nee Citicorp TTI
-10cf Fujitsu Limited.
- 2001 mb86605
-10d1 FuturePlus Systems Corp.
-10d2 Molex Incorporated
-10d3 Jabil Circuit Inc
-10d4 Hualon Microelectronics
-10d5 Autologic Inc.
-10d6 Cetia
-10d7 BCM Advanced Research
-10d8 Advanced Peripherals Labs
-10d9 Macronix, Inc. [MXIC]
- 0431 MX98715
- 0512 MX98713
- 0531 MX987x5
- 1186 1200 DFE-540TX ProFAST 10/100 Adapter
- 8625 MX86250
- 8888 MX86200
-10da Compaq IPG-Austin
- 0508 TC4048 Token Ring 4/16
- 3390 Tl3c3x9
-10db Rohm LSI Systems, Inc.
-10dc CERN/ECP/EDU
- 0001 STAR/RD24 SCI-PCI (PMC)
- 0002 TAR/RD24 SCI-PCI (PMC)
- 0021 HIPPI destination
- 0022 HIPPI source
- 10dc ATT2C15-3 FPGA
-10dd Evans & Sutherland
-10de nVidia Corporation
- 0008 NV1 [EDGE 3D]
- 0009 NV1 [EDGE 3D]
- 0010 NV2 [Mutara V08]
- 0020 NV4 [RIVA TNT]
- 1043 0200 V3400 TNT
- 1048 0c18 Erazor II SGRAM
- 1048 0c1b Erazor II
- 1092 0550 Viper V550
- 1092 0552 Viper V550
- 1092 4804 Viper V550
- 1092 4808 Viper V550
- 1092 4810 Viper V550
- 1092 4812 Viper V550
- 1092 4815 Viper V550
- 1092 4820 Viper V550 with TV out
- 1092 4822 Viper V550
- 1092 4904 Viper V550
- 1092 4914 Viper V550
- 1092 8225 Viper V550
- 10b4 273d Velocity 4400
- 10b4 273e Velocity 4400
- 10b4 2740 Velocity 4400
- 10de 0020 Riva TNT
- 1102 1015 Graphics Blaster CT6710
- 1102 1016 Graphics Blaster RIVA TNT
- 0028 NV5 [RIVA TNT2/TNT2 Pro]
- 1043 0200 AGP-V3800 SGRAM
- 1043 0201 AGP-V3800 SDRAM
- 1043 0205 PCI-V3800
- 1043 4000 AGP-V3800PRO
- 1048 0c21 Synergy II
- 1048 0c31 Erazor III
- 107d 2134 WinFast 3D S320 II + TV-Out
- 1092 4804 Viper V770
- 1092 4a00 Viper V770
- 1092 4a02 Viper V770 Ultra
- 1092 5a00 RIVA TNT2/TNT2 Pro
- 1092 6a02 Viper V770 Ultra
- 1092 7a02 Viper V770 Ultra
- 10de 0005 RIVA TNT2 Pro
- 10de 000f Compaq NVIDIA TNT2 Pro
- 1102 1020 3D Blaster RIVA TNT2
- 1102 1026 3D Blaster RIVA TNT2 Digital
- 14af 5810 Maxi Gamer Xentor
- 0029 NV5 [RIVA TNT2 Ultra]
- 1043 0200 AGP-V3800 Deluxe
- 1043 0201 AGP-V3800 Ultra SDRAM
- 1043 0205 PCI-V3800 Ultra
- 1102 1021 3D Blaster RIVA TNT2 Ultra
- 1102 1029 3D Blaster RIVA TNT2 Ultra
- 1102 102f 3D Blaster RIVA TNT2 Ultra
- 14af 5820 Maxi Gamer Xentor 32
- 002a NV5 [Riva TnT2]
- 002b NV5 [Riva TnT2]
- 002c NV6 [Vanta/Vanta LT]
- 1043 0200 AGP-V3800 Combat SDRAM
- 1043 0201 AGP-V3800 Combat
- 1092 6820 Viper V730
- 1102 1031 CT6938 VANTA 8MB
- 1102 1034 CT6894 VANTA 16MB
- 14af 5008 Maxi Gamer Phoenix 2
- 002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
- 1043 0200 AGP-V3800M
- 1043 0201 AGP-V3800M
- 1048 0c3a Erazor III LT
- 10de 001e M64 AGP4x
- 1102 1023 CT6892 RIVA TNT2 Value
- 1102 1024 CT6932 RIVA TNT2 Value 32Mb
- 1102 102c CT6931 RIVA TNT2 Value [Jumper]
- 1462 8808 MSI-8808
- 1554 1041 Pixelview RIVA TNT2 M64
- 1569 002d Palit Microsystems Daytona TNT2 M64
- 002e NV6 [Vanta]
- 002f NV6 [Vanta]
- 0034 MCP04 SMBus
- 0035 MCP04 IDE
- 0036 MCP04 Serial ATA Controller
- 0037 MCP04 Ethernet Controller
- 0038 MCP04 Ethernet Controller
- 003a MCP04 AC'97 Audio Controller
- 003b MCP04 USB Controller
- 003c MCP04 USB Controller
- 003d MCP04 PCI Bridge
- 003e MCP04 Serial ATA Controller
- 0040 nv40 [GeForce 6800 Ultra]
- 0041 NV40 [GeForce 6800]
- 0042 NV40.2
- 0043 NV40.3
- 0045 NV40 [GeForce 6800 GT]
- 0049 NV40GL
- 004e NV40GL [Quadro FX 4000]
- 0051 CK804 ISA Bridge
- 0052 CK804 SMBus
- 0053 CK804 IDE
- 0054 CK804 Serial ATA Controller
- 0055 CK804 Serial ATA Controller
- 0056 CK804 Ethernet Controller
- 0057 CK804 Ethernet Controller
- 0059 CK804 AC'97 Audio Controller
- 005a CK804 USB Controller
- 005b CK804 USB Controller
- 005c CK804 PCI Bridge
- 005d CK804 PCIE Bridge
- 005e CK804 Memory Controller
- 0060 nForce2 ISA Bridge
- 1043 80ad A7N8X Mainboard
- 0064 nForce2 SMBus (MCP)
- 0065 nForce2 IDE
- 0066 nForce2 Ethernet Controller
- 1043 80a7 A7N8X Mainboard onboard nForce2 Ethernet
- 0067 nForce2 USB Controller
- 1043 0c11 A7N8X Mainboard
- 0068 nForce2 USB Controller
- 1043 0c11 A7N8X Mainboard
- 006a nForce2 AC97 Audio Controler (MCP)
- 006b nForce Audio Processing Unit
- 10de 006b nForce2 MCP Audio Processing Unit
- 006c nForce2 External PCI Bridge
- 006d nForce2 PCI Bridge
- 006e nForce2 FireWire (IEEE 1394) Controller
- 0084 MCP2A SMBus
- 0085 MCP2A IDE
- 0086 MCP2A Ethernet Controller
- 0087 MCP2A USB Controller
- 0088 MCP2A USB Controller
- 008a MCP2S AC'97 Audio Controller
- 008b MCP2A PCI Bridge
- 008c MCP2A Ethernet Controller
- 008e nForce2 Serial ATA Controller
- 00a0 NV5 [Aladdin TNT2]
- 14af 5810 Maxi Gamer Xentor
- 00c0 NV41.0
- 00c1 NV41.1
- 00c2 NV41.2
- 00c8 NV41.8
- 00ce NV41GL
- 00d0 nForce3 LPC Bridge
- 00d1 nForce3 Host Bridge
- 00d2 nForce3 AGP Bridge
- 00d3 CK804 Memory Controller
- 00d4 nForce3 SMBus
- 00d5 nForce3 IDE
- 00d6 nForce3 Ethernet
- 00d7 nForce3 USB 1.1
- 00d8 nForce3 USB 2.0
- 00da nForce3 Audio
- 00dd nForce3 PCI Bridge
- 00df CK8S Ethernet Controller
- 00e0 nForce3 250Gb LPC Bridge
- 00e1 nForce3 250Gb Host Bridge
- 00e2 nForce3 250Gb AGP Host to PCI Bridge
- 00e3 CK8S Serial ATA Controller (v2.5)
- 00e4 nForce 250Gb PCI System Management
- 00e5 CK8S Parallel ATA Controller (v2.5)
- 00e6 CK8S Ethernet Controller
- 00e7 CK8S USB Controller
- 00e8 nForce3 EHCI USB 2.0 Controller
- 00ea nForce3 250Gb AC'97 Audio Controller
- 00ed nForce3 250Gb PCI-to-PCI Bridge
- 00ee CK8S Serial ATA Controller (v2.5)
- 00f0 NV40 [GeForce 6800/GeForce 6800 Ultra]
- 00f1 NV43 [GeForce 6600/GeForce 6600 GT]
- 00f2 NV43 [GeForce 6600 GT]
- 00f8 NV45GL [Quadro FX 3400]
- 00f9 NV40 [GeForce 6800 Ultra/GeForce 6800 GT]
- 1682 2120 GEFORCE 6800 GT PCI-E
- 00fa NV36 [GeForce PCX 5750]
- 00fb NV35 [GeForce PCX 5900]
- 00fc NV37GL [Quadro FX 330/GeForce PCX 5300]
- 00fd NV37GL [Quadro FX 330]
- 00fe NV38GL [Quadro FX 1300]
- 00ff NV18 [GeForce PCX 4300]
- 0100 NV10 [GeForce 256 SDR]
- 1043 0200 AGP-V6600 SGRAM
- 1043 0201 AGP-V6600 SDRAM
- 1043 4008 AGP-V6600 SGRAM
- 1043 4009 AGP-V6600 SDRAM
- 1102 102d CT6941 GeForce 256
- 14af 5022 3D Prophet SE
- 0101 NV10DDR [GeForce 256 DDR]
- 1043 0202 AGP-V6800 DDR
- 1043 400a AGP-V6800 DDR SGRAM
- 1043 400b AGP-V6800 DDR SDRAM
- 107d 2822 WinFast GeForce 256
- 1102 102e CT6971 GeForce 256 DDR
- 14af 5021 3D Prophet DDR-DVI
- 0103 NV10GL [Quadro]
- 0110 NV11 [GeForce2 MX/MX 400]
- 1043 4015 AGP-V7100 Pro
- 1043 4031 V7100 Pro with TV output
- 10de 0091 Dell OEM GeForce 2 MX 400
- 1462 8817 MSI GeForce2 MX400 Pro32S [MS-8817]
- 14af 7102 3D Prophet II MX
- 14af 7103 3D Prophet II MX Dual-Display
- 0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR]
- 0112 NV11 [GeForce2 Go]
- 0113 NV11GL [Quadro2 MXR/EX]
- 0140 NV43 [MSI NX6600GT-TD128E]
- 014f NV43 [GeForce 6200]
- 0150 NV15 [GeForce2 GTS/Pro]
- 1043 4016 V7700 AGP Video Card
- 107d 2840 WinFast GeForce2 GTS with TV output
- 107d 2842 WinFast GeForce 2 Pro
- 1462 8831 Creative GeForce2 Pro
- 0151 NV15DDR [GeForce2 Ti]
- 1043 405f V7700Ti
- 1462 5506 Creative 3D Blaster Geforce2 Titanium
- 0152 NV15BR [GeForce2 Ultra, Bladerunner]
- 1048 0c56 GLADIAC Ultra
- 0153 NV15GL [Quadro2 Pro]
- 0170 NV17 [GeForce4 MX 460]
- 0171 NV17 [GeForce4 MX 440]
- 10b0 0002 Gainward Pro/600 TV
- 1462 8661 G4MX440-VTP
- 1462 8730 MX440SES-T (MS-8873)
- 147b 8f00 Abit Siluro GeForce4MX440
- 0172 NV17 [GeForce4 MX 420]
- 0173 NV17 [GeForce4 MX 440-SE]
- 0174 NV17 [GeForce4 440 Go]
- 0175 NV17 [GeForce4 420 Go]
- 0176 NV17 [GeForce4 420 Go 32M]
- 4c53 1090 Cx9 / Vx9 mainboard
- 0177 NV17 [GeForce4 460 Go]
- 0178 NV17GL [Quadro4 550 XGL]
- 0179 NV17 [GeForce4 440 Go 64M]
- 10de 0179 GeForce4 MX (Mac)
- 017a NV17GL [Quadro4 200/400 NVS]
- 017b NV17GL [Quadro4 550 XGL]
- 017c NV17GL [Quadro4 550 GoGL]
- 017d NV17 [GeForce4 410 Go 16M]
- 0181 NV18 [GeForce4 MX 440 AGP 8x]
- 1043 806f V9180 Magic
- 1462 8880 MS-StarForce GeForce4 MX 440 with AGP8X
- 1462 8900 MS-8890 GeForce 4 MX440 AGP8X
- 1462 9350 MSI Geforce4 MX T8X with AGP8X
- 147b 8f0d Siluro GF4 MX-8X
- 0182 NV18 [GeForce4 MX 440SE AGP 8x]
- 0183 NV18 [GeForce4 MX 420 AGP 8x]
- 0185 NV18 [GeForce4 MX 4000 AGP 8x]
- 0186 NV18M [GeForce4 448 Go]
- 0187 NV18M [GeForce4 488 Go]
- 0188 NV18GL [Quadro4 580 XGL]
- 018a NV18GL [Quadro4 NVS AGP 8x]
- 018b NV18GL [Quadro4 380 XGL]
- 018d NV18M [GeForce4 448 Go]
- 01a0 NVCrush11 [GeForce2 MX Integrated Graphics]
- 01a4 nForce CPU bridge
- 01ab nForce 420 Memory Controller (DDR)
- 01ac nForce 220/420 Memory Controller
- 01ad nForce 220/420 Memory Controller
- 01b0 nForce Audio
- 01b1 nForce Audio
- 01b2 nForce ISA Bridge
- 01b4 nForce PCI System Management
- 01b7 nForce AGP to PCI Bridge
- 01b8 nForce PCI-to-PCI bridge
- 01bc nForce IDE
- 01c1 nForce AC'97 Modem Controller
- 01c2 nForce USB Controller
- 01c3 nForce Ethernet Controller
- 01e0 nForce2 AGP (different version?)
- 01e8 nForce2 AGP
- 01ea nForce2 Memory Controller 0
- 01eb nForce2 Memory Controller 1
- 01ec nForce2 Memory Controller 2
- 01ed nForce2 Memory Controller 3
- 01ee nForce2 Memory Controller 4
- 01ef nForce2 Memory Controller 5
- 01f0 NV18 [GeForce4 MX - nForce GPU]
- 0200 NV20 [GeForce3]
- 1043 402f AGP-V8200 DDR
- 0201 NV20 [GeForce3 Ti 200]
- 0202 NV20 [GeForce3 Ti 500]
- 1043 405b V8200 T5
- 1545 002f Xtasy 6964
- 0203 NV20DCC [Quadro DCC]
- 0240 C51 PCI Express Bridge
- 0241 C51 PCI Express Bridge
- 0242 C51 PCI Express Bridge
- 0243 C51 PCI Express Bridge
- 0244 C51 PCI Express Bridge
- 0245 C51 PCI Express Bridge
- 0246 C51 PCI Express Bridge
- 0247 C51 PCI Express Bridge
- 0248 C51 PCI Express Bridge
- 0249 C51 PCI Express Bridge
- 024a C51 PCI Express Bridge
- 024b C51 PCI Express Bridge
- 024c C51 PCI Express Bridge
- 024d C51 PCI Express Bridge
- 024e C51 PCI Express Bridge
- 024f C51 PCI Express Bridge
- 0250 NV25 [GeForce4 Ti 4600]
- 0251 NV25 [GeForce4 Ti 4400]
- 1043 8023 v8440 GeForce 4 Ti4400
- 0252 NV25 [GeForce4 Ti]
- 0253 NV25 [GeForce4 Ti 4200]
- 107d 2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI)
- 147b 8f09 Siluro (Dual VGA/TV-out/DVI)
- 0258 NV25GL [Quadro4 900 XGL]
- 0259 NV25GL [Quadro4 750 XGL]
- 025b NV25GL [Quadro4 700 XGL]
- 0260 MCP51 LPC Bridge
- 0261 MCP51 LPC Bridge
- 0262 MCP51 LPC Bridge
- 0263 MCP51 LPC Bridge
- 0264 MCP51 SMBus
- 0265 MCP51 IDE
- 0266 MCP51 Serial ATA Controller
- 0267 MCP51 Serial ATA Controller
- 0268 MCP51 Ethernet Controller
- 0269 MCP51 Ethernet Controller
- 026a MCP51 MCI
- 026b MCP51 AC97 Audio Controller
- 026c MCP51 High Definition Audio
- 026d MCP51 USB Controller
- 026e MCP51 USB Controller
- 026f MCP51 PCI Bridge
- 0270 MCP51 Host Bridge
- 0271 MCP51 PMU
- 0272 MCP51 Memory Controller 0
- 027e C51 Memory Controller 2
- 027f C51 Memory Controller 3
- 0280 NV28 [GeForce4 Ti 4800]
- 0281 NV28 [GeForce4 Ti 4200 AGP 8x]
- 0282 NV28 [GeForce4 Ti 4800 SE]
- 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x]
- 0288 NV28GL [Quadro4 980 XGL]
- 0289 NV28GL [Quadro4 780 XGL]
- 028c NV28GLM [Quadro4 700 GoGL]
- 02f0 C51 Host Bridge
- 02f1 C51 Host Bridge
- 02f2 C51 Host Bridge
- 02f3 C51 Host Bridge
- 02f4 C51 Host Bridge
- 02f5 C51 Host Bridge
- 02f6 C51 Host Bridge
- 02f7 C51 Host Bridge
- 02f8 C51 Memory Controller 5
- 02f9 C51 Memory Controller 4
- 02fa C51 Memory Controller 0
- 02fb C51 PCI Express Bridge
- 02fc C51 PCI Express Bridge
- 02fd C51 PCI Express Bridge
- 02fe C51 Memory Controller 1
- 02ff C51 Host Bridge
- 0300 NV30 [GeForce FX]
- 0301 NV30 [GeForce FX 5800 Ultra]
- 0302 NV30 [GeForce FX 5800]
- 0308 NV30GL [Quadro FX 2000]
- 0309 NV30GL [Quadro FX 1000]
- 0311 NV31 [GeForce FX 5600 Ultra]
- 0312 NV31 [GeForce FX 5600]
- 0313 NV31
- 0314 NV31 [GeForce FX 5600XT]
- 1043 814a V9560XT/TD
- 0316 NV31
- 0317 NV31
- 031a NV31M [GeForce FX Go 5600]
- 031b NV31M [GeForce FX Go5650]
- 031c NVIDIA Quadro FX 700 Go
- 031d NV31
- 031e NV31
- 031f NV31
- 0320 NV34 [GeForce FX 5200]
- 0321 NV34 [GeForce FX 5200 Ultra]
- 0322 NV34 [GeForce FX 5200]
- 1462 9171 MS-8917 (FX5200-T128)
- 0323 NV34 [GeForce FX 5200LE]
- 0324 NV34M [GeForce FX Go 5200]
- 1071 8160 MIM2000
- 0325 NV34M [GeForce FX Go5250]
- 0326 NV34 [GeForce FX 5500]
- 0327 NV34 [GeForce FX 5100]
- 0328 NV34M [GeForce FX Go 5200]
- 0329 NV34M [GeForce FX Go5200]
- 032a NV34GL [Quadro NVS 280 PCI]
- 032b NV34GL [Quadro FX 500/600 PCI]
- 032c NV34GLM [GeForce FX Go 5300]
- 032d NV34 [GeForce FX Go5100]
- 032f NV34
- 0330 NV35 [GeForce FX 5900 Ultra]
- 0331 NV35 [GeForce FX 5900]
- 1043 8145 V9950GE
- 0332 NV35 [GeForce FX 5900XT]
- 0333 NV38 [GeForce FX 5950 Ultra]
- 0334 NV35 [GeForce FX 5900ZT]
- 0338 NV35GL [Quadro FX 3000]
- 033f NV35GL [Quadro FX 700]
- 0341 NV36.1 [GeForce FX 5700 Ultra]
- 0342 NV36.2 [GeForce FX 5700]
- 0343 NV36 [GeForce FX 5700LE]
- 0344 NV36.4 [GeForce FX 5700VE]
- 0345 NV36.5
- 0347 NV36 [GeForce FX Go5700]
- 0348 NV36 [GeForce FX Go5700]
- 0349 NV36
- 034b NV36
- 034c NV36 [Quadro FX Go1000]
- 034e NV36GL [Quadro FX 1100]
- 034f NV36GL
-10df Emulex Corporation
- 1ae5 LP6000 Fibre Channel Host Adapter
- 1ae6 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
- 1ae7 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:2-3)
- f005 LP1150e Fibre Channel Host Adapter
- f085 LP850 Fibre Channel Host Adapter
- f095 LP952 Fibre Channel Host Adapter
- f098 LP982 Fibre Channel Host Adapter
- f0a5 LP1050 Fibre Channel Host Adapter
- f0d5 LP1150 Fibre Channel Host Adapter
- f100 LP11000e Fibre Channel Host Adapter
- f700 LP7000 Fibre Channel Host Adapter
- f701 LP 7000EFibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
- f800 LP8000 Fibre Channel Host Adapter
- f801 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
- f900 LP9000 Fibre Channel Host Adapter
- f901 LP 9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
- f980 LP9802 Fibre Channel Host Adapter
- f981 LP 9802 Fibre Channel Host Adapter Alternate ID
- f982 LP 9802 Fibre Channel Host Adapter Alternate ID
- fa00 LP10000 Fibre Channel Host Adapter
- fa01 LP101 Fibre Channel Host Adapter
- fd00 LP11000 Fibre Channel Host Adapter
-10e0 Integrated Micro Solutions Inc.
- 5026 IMS5026/27/28
- 5027 IMS5027
- 5028 IMS5028
- 8849 IMS8849
- 8853 IMS8853
- 9128 IMS9128 [Twin turbo 128]
-10e1 Tekram Technology Co.,Ltd.
- 0391 TRM-S1040
- 10e1 0391 DC-315U SCSI-3 Host Adapter
- 690c DC-690c
- dc29 DC-290
-10e2 Aptix Corporation
-10e3 Tundra Semiconductor Corp.
- 0000 CA91C042 [Universe]
- 0860 CA91C860 [QSpan]
- 0862 CA91C862A [QSpan-II]
- 8260 CA91L8200B [Dual PCI PowerSpan II]
- 8261 CA91L8260B [Single PCI PowerSpan II]
-10e4 Tandem Computers
-10e5 Micro Industries Corporation
-10e6 Gainbery Computer Products Inc.
-10e7 Vadem
-10e8 Applied Micro Circuits Corp.
- 1072 INES GPIB-PCI (AMCC5920 based)
- 2011 Q-Motion Video Capture/Edit board
- 4750 S5930 [Matchmaker]
- 5920 S5920
- 8043 LANai4.x [Myrinet LANai interface chip]
- 8062 S5933_PARASTATION
- 807d S5933 [Matchmaker]
- 8088 Kongsberg Spacetec Format Synchronizer
- 8089 Kongsberg Spacetec Serial Output Board
- 809c S5933_HEPC3
- 80d7 PCI-9112
- 80d9 PCI-9118
- 80da PCI-9812
- 811a PCI-IEEE1355-DS-DE Interface
- 814c Fastcom ESCC-PCI (Commtech, Inc.)
- 8170 S5933 [Matchmaker] (Chipset Development Tool)
-# sold with Roper Scientifc(Photometrics) CoolSnap HQ camera
- 81e6 Multimedia video controller
- 8291 Fastcom 232/8-PCI (Commtech, Inc.)
- 82c4 Fastcom 422/4-PCI (Commtech, Inc.)
- 82c5 Fastcom 422/2-PCI (Commtech, Inc.)
- 82c6 Fastcom IG422/1-PCI (Commtech, Inc.)
- 82c7 Fastcom IG232/2-PCI (Commtech, Inc.)
- 82ca Fastcom 232/4-PCI (Commtech, Inc.)
- 82db AJA HDNTV HD SDI Framestore
- 82e2 Fastcom DIO24H-PCI (Commtech, Inc.)
- 8851 S5933 on Innes Corp FM Radio Capture card
-10e9 Alps Electric Co., Ltd.
-10ea Intergraphics Systems
- 1680 IGA-1680
- 1682 IGA-1682
- 1683 IGA-1683
- 2000 CyberPro 2000
- 2010 CyberPro 2000A
- 5000 CyberPro 5000
- 5050 CyberPro 5050
- 5202 CyberPro 5202
-# CyberPro5202 Audio Function
- 5252 CyberPro5252
-10eb Artists Graphics
- 0101 3GA
- 8111 Twist3 Frame Grabber
-10ec Realtek Semiconductor Co., Ltd.
- 8029 RTL-8029(AS)
- 10b8 2011 EZ-Card (SMC1208)
- 10ec 8029 RTL-8029(AS)
- 1113 1208 EN1208
- 1186 0300 DE-528
- 1259 2400 AT-2400
- 8129 RTL-8129
- 10ec 8129 RT8129 Fast Ethernet Adapter
- 8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter
- 10ec 8138 RT8139 (B/C) Fast Ethernet Adapter
- 8139 RTL-8139/8139C/8139C+
- 0357 000a TTP-Monitoring Card V2.0
- 1025 005a TravelMate 290
- 1025 8920 ALN-325
- 1025 8921 ALN-325
- 1071 8160 MIM2000
- 10bd 0320 EP-320X-R
- 10ec 8139 RT8139
- 1113 ec01 FNC-0107TX
- 1186 1300 DFE-538TX
- 1186 1320 SN5200
- 1186 8139 DRN-32TX
- 11f6 8139 FN22-3(A) LinxPRO Ethernet Adapter
- 1259 2500 AT-2500TX
- 1259 2503 AT-2500TX/ACPI
- 1429 d010 ND010
- 1432 9130 EN-9130TX
- 1436 8139 RT8139
- 1458 e000 GA-7VM400M/7VT600 Motherboard
- 146c 1439 FE-1439TX
- 1489 6001 GF100TXRII
- 1489 6002 GF100TXRA
- 149c 139a LFE-8139ATX
- 149c 8139 LFE-8139TX
- 14cb 0200 LNR-100 Family 10/100 Base-TX Ethernet
- 1799 5000 F5D5000 PCI Card/Desktop Network PCI Card
- 2646 0001 EtheRx
- 8e2e 7000 KF-230TX
- 8e2e 7100 KF-230TX/2
- a0a0 0007 ALN-325C
- 8169 RTL-8169 Gigabit Ethernet
- 1259 c107 CG-LAPCIGT
- 1371 434e ProG-2000L
- 1458 e000 GA-K8VT800 Pro Motherboard
- 1462 702c K8T NEO 2 motherboard
- 8180 RTL8180L 802.11b MAC
- 8197 SmartLAN56 56K Modem
-10ed Ascii Corporation
- 7310 V7310
-10ee Xilinx Corporation
- 3fc0 RME Digi96
- 3fc1 RME Digi96/8
- 3fc2 RME Digi96/8 Pro
- 3fc3 RME Digi96/8 Pad
- 3fc4 RME Digi9652 (Hammerfall)
- 3fc5 RME Hammerfall DSP
- 3fc6 RME Hammerfall DSP MADI
- 8381 Ellips Santos Frame Grabber
-10ef Racore Computer Products, Inc.
- 8154 M815x Token Ring Adapter
-10f0 Peritek Corporation
-10f1 Tyan Computer
-10f2 Achme Computer, Inc.
-10f3 Alaris, Inc.
-10f4 S-MOS Systems, Inc.
-10f5 NKK Corporation
- a001 NDR4000 [NR4600 Bridge]
-10f6 Creative Electronic Systems SA
-10f7 Matsushita Electric Industrial Co., Ltd.
-10f8 Altos India Ltd
-10f9 PC Direct
-10fa Truevision
- 000c TARGA 1000
-10fb Thesys Gesellschaft für Mikroelektronik mbH
- 186f TH 6255
-10fc I-O Data Device, Inc.
-# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
- 0003 Cardbus IDE Controller
- 0005 Cardbus SCSI CBSC II
-10fd Soyo Computer, Inc
-10fe Fast Multimedia AG
-10ff NCube
-1100 Jazz Multimedia
-1101 Initio Corporation
- 1060 INI-A100U2W
- 9100 INI-9100/9100W
- 9400 INI-940
- 9401 INI-950
- 9500 360P
- 9502 Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip
-1102 Creative Labs
- 0002 SB Live! EMU10k1
- 1102 0020 CT4850 SBLive! Value
- 1102 0021 CT4620 SBLive!
- 1102 002f SBLive! mainboard implementation
- 1102 4001 E-mu APS
- 1102 8022 CT4780 SBLive! Value
- 1102 8023 CT4790 SoundBlaster PCI512
- 1102 8024 CT4760 SBLive!
- 1102 8025 SBLive! Mainboard Implementation
- 1102 8026 CT4830 SBLive! Value
- 1102 8027 CT4832 SBLive! Value
- 1102 8028 CT4760 SBLive! OEM version
- 1102 8031 CT4831 SBLive! Value
- 1102 8040 CT4760 SBLive!
- 1102 8051 CT4850 SBLive! Value
- 1102 8061 SBLive! Player 5.1
- 1102 8064 SB Live! 5.1 Model SB0100
- 1102 8065 SBLive! 5.1 Digital Model SB0220
- 1102 8067 SBLive! 5.1 eMicro 28028
- 0004 SB Audigy
- 1102 0051 SB0090 Audigy Player
- 1102 0053 SB0090 Audigy Player/OEM
- 1102 0058 SB0090 Audigy Player/OEM
- 1102 1007 SB0240 Audigy 2 Platinum 6.1
- 1102 2002 SB Audigy 2 ZS (SB0350)
- 0006 [SB Live! Value] EMU10k1X
- 0007 SB Audigy LS
- 1102 1001 SB0310 Audigy LS
- 1102 1002 SB0312 Audigy LS
- 1102 1006 SB0410 SBLive! 24-bit
- 0008 SB0400 Audigy2 Value
- 4001 SB Audigy FireWire Port
- 1102 0010 SB Audigy FireWire Port
- 7002 SB Live! MIDI/Game Port
- 1102 0020 Gameport Joystick
- 7003 SB Audigy MIDI/Game port
- 1102 0040 SB Audigy MIDI/Game Port
- 7004 [SB Live! Value] Input device controller
- 7005 SB Audigy LS MIDI/Game port
- 1102 1001 SB0310 Audigy LS MIDI/Game port
- 1102 1002 SB0312 Audigy LS MIDI/Game port
- 8064 SB0100 [SBLive! 5.1 OEM]
- 8938 Ectiva EV1938
- 1033 80e5 SlimTower-Jim (NEC)
- 1071 7150 Mitac 7150
- 110a 5938 Siemens Scenic Mobile 510PIII
- 13bd 100c Ceres-C (Sharp, Intel BX)
- 13bd 100d Sharp, Intel Banister
- 13bd 100e TwinHead P09S/P09S3 (Sharp)
- 13bd f6f1 Marlin (Sharp)
- 14ff 0e70 P88TE (TWINHEAD INTERNATIONAL Corp)
- 14ff c401 Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
- 156d b400 G400 - Geo (AlphaTop (Taiwan))
- 156d b550 G560 (AlphaTop (Taiwan))
- 156d b560 G560 (AlphaTop (Taiwan))
- 156d b700 G700/U700 (AlphaTop (Taiwan))
- 156d b795 G795 (AlphaTop (Taiwan))
- 156d b797 G797 (AlphaTop (Taiwan))
-1103 Triones Technologies, Inc.
- 0003 HPT343
- 0004 HPT366/368/370/370A/372/372N
- 1103 0001 HPT370A
- 1103 0003 HPT343 / HPT345 / HPT363 UDMA33
- 1103 0004 HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
- 1103 0005 HPT370 UDMA100
- 1103 0006 HPT302
- 1103 0007 HPT371 UDMA133
- 1103 0008 HPT374 UDMA/ATA133 RAID Controller
- 0005 HPT372A/372N
- 0006 HPT302
- 0007 HPT371/371N
- 0008 HPT374
- 0009 HPT372N
-1104 RasterOps Corp.
-1105 Sigma Designs, Inc.
- 1105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
- 8300 REALmagic Hollywood Plus DVD Decoder
- 8400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
- 8401 EM8401 REALmagic DVD/MPEG-2 A/V Decoder
- 8470 EM8470 REALmagic DVD/MPEG-4 A/V Decoder
- 8471 EM8471 REALmagic DVD/MPEG-4 A/V Decoder
- 8475 EM8475 REALmagic DVD/MPEG-4 A/V Decoder
- 8476 EM8476 REALmagic DVD/MPEG-4 A/V Decoder
- 8485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder
- 8486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder
-1106 VIA Technologies, Inc.
- 0102 Embedded VIA Ethernet Controller
- 0130 VT6305 1394.A Controller
- 0305 VT8363/8365 [KT133/KM133]
- 1043 8033 A7V Mainboard
- 1043 803e A7V-E Mainboard
- 1043 8042 A7V133/A7V133-C Mainboard
- 147b a401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
- 0391 VT8371 [KX133]
- 0501 VT8501 [Apollo MVP4]
- 0505 VT82C505
-# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
- 0561 VT82C576MV
- 0571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
- 1019 0985 P6VXA Motherboard
- 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
- 1043 8052 VT8233A Bus Master ATA100/66/33 IDE
- 1043 808c A7V8X motherboard
- 1043 80a1 A7V8X-X motherboard rev. 1.01
- 1043 80ed A7V600 motherboard
- 1106 0571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
- 1179 0001 Magnia Z310
- 1297 f641 FX41 motherboard
- 1458 5002 GA-7VAX Mainboard
- 1462 7020 K8T NEO 2 motherboard
- 147b 1407 KV8-MAX3 motherboard
- 1849 0571 K7VT2 motherboard
- 0576 VT82C576 3V [Apollo Master]
- 0585 VT82C585VP [Apollo VP1/VPX]
- 0586 VT82C586/A/B PCI-to-ISA [Apollo VP]
- 1106 0000 MVP3 ISA Bridge
- 0595 VT82C595 [Apollo VP2]
- 0596 VT82C596 ISA [Mobile South]
- 1106 0000 VT82C596/A/B PCI to ISA Bridge
- 1458 0596 VT82C596/A/B PCI to ISA Bridge
- 0597 VT82C597 [Apollo VP3]
- 0598 VT82C598 [Apollo MVP3]
- 0601 VT8601 [Apollo ProMedia]
- 0605 VT8605 [ProSavage PM133]
- 1043 802c CUV4X mainboard
- 0680 VT82C680 [Apollo P6]
- 0686 VT82C686 [Apollo Super South]
- 1019 0985 P6VXA Motherboard
- 1043 802c CUV4X mainboard
- 1043 8033 A7V Mainboard
- 1043 803e A7V-E Mainboard
- 1043 8040 A7M266 Mainboard
- 1043 8042 A7V133/A7V133-C Mainboard
- 1106 0000 VT82C686/A PCI to ISA Bridge
- 1106 0686 VT82C686/A PCI to ISA Bridge
- 1179 0001 Magnia Z310
- 147b a702 KG7-Lite Mainboard
- 0691 VT82C693A/694x [Apollo PRO133x]
- 1019 0985 P6VXA Motherboard
- 1179 0001 Magnia Z310
- 1458 0691 VT82C691 Apollo Pro System Controller
- 0693 VT82C693 [Apollo Pro Plus]
- 0698 VT82C693A [Apollo Pro133 AGP]
- 0926 VT82C926 [Amazon]
- 1000 VT82C570MV
- 1106 VT82C570MV
- 1571 VT82C576M/VT82C586
- 1595 VT82C595/97 [Apollo VP2/97]
- 3022 CLE266
-# This is *not* USB 2.0 as the existing entry suggests
- 3038 VT82xxxxx UHCI USB 1.1 Controller
- 0925 1234 USB Controller
- 1019 0985 P6VXA Motherboard
- 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
- 1043 808c VT6202 USB2.0 4 port controller
- 1043 80a1 A7V8X-X motherboard
- 1043 80ed A7V600 motherboard
- 1179 0001 Magnia Z310
- 1458 5004 GA-7VAX Mainboard
- 1462 7020 K8T NEO 2 motherboard
- 147b 1407 KV8-MAX3 motherboard
- 182d 201d CN-029 USB2.0 4 port PCI Card
- 3040 VT82C586B ACPI
- 3043 VT86C100A [Rhine]
- 10bd 0000 VT86C100A Fast Ethernet Adapter
- 1106 0100 VT86C100A Fast Ethernet Adapter
- 1186 1400 DFE-530TX rev A
- 3044 IEEE 1394 Host Controller
- 1025 005a TravelMate 290
- 1458 1000 GA-7VT600-1394 Motherboard
- 1462 702d K8T NEO 2 motherboard
- 3050 VT82C596 Power Management
- 3051 VT82C596 Power Management
- 3053 VT6105M [Rhine-III]
- 3057 VT82C686 [Apollo Super ACPI]
- 1019 0985 P6VXA Motherboard
- 1043 8033 A7V Mainboard
- 1043 803e A7V-E Mainboard
- 1043 8040 A7M266 Mainboard
- 1043 8042 A7V133/A7V133-C Mainboard
- 1179 0001 Magnia Z310
- 3058 VT82C686 AC97 Audio Controller
- 0e11 0097 SoundMax Digital Integrated Audio
- 0e11 b194 Soundmax integrated digital audio
- 1019 0985 P6VXA Motherboard
- 1043 1106 A7V133/A7V133-C Mainboard
- 1106 4511 Onboard Audio on EP7KXA
- 1458 7600 Onboard Audio
- 1462 3091 MS-6309 Onboard Audio
- 1462 3300 MS-6330 Onboard Audio
- 15dd 7609 Onboard Audio
- 3059 VT8233/A/8235/8237 AC97 Audio Controller
- 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
- 1043 8095 A7V8X Motherboard (Realtek ALC650 codec)
- 1043 80a1 A7V8X-X Motherboard
- 1043 80b0 A7V600/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
- 1106 3059 L7VMM2 Motherboard
- 1106 4161 K7VT2 motherboard
- 1297 c160 FX41 motherboard (Realtek ALC650 codec)
- 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650)
- 1462 0080 K8T NEO 2 motherboard
- 1462 3800 KT266 onboard audio
- 147b 1407 KV8-MAX3 motherboard
- 3065 VT6102 [Rhine-II]
- 1043 80a1 A7V8X-X Motherboard
- 1106 0102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
- 1186 1400 DFE-530TX rev A
- 1186 1401 DFE-530TX rev B
- 13b9 1421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
-# This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs
- 3068 AC'97 Modem Controller
- 1462 309e MS-6309 Saturn Motherboard
- 3074 VT8233 PCI to ISA Bridge
- 1043 8052 VT8233A
- 3091 VT8633 [Apollo Pro266]
- 3099 VT8366/A/7 [Apollo KT266/A/333]
- 1043 8064 A7V266-E Mainboard
- 1043 807f A7V333 Mainboard
- 1849 3099 K7VT2 motherboard
- 3101 VT8653 Host Bridge
- 3102 VT8662 Host Bridge
- 3103 VT8615 Host Bridge
- 3104 USB 2.0
- 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
- 1043 808c A7V8X motherboard
- 1043 80a1 A7V8X-X motherboard rev 1.01
- 1043 80ed A7V600 motherboard
- 1297 f641 FX41 motherboard
- 1458 5004 GA-7VAX Mainboard
- 1462 7020 K8T NEO 2 motherboard
- 147b 1407 KV8-MAX3 motherboard
- 182d 201d CN-029 USB 2.0 4 port PCI Card
- 3106 VT6105 [Rhine-III]
- 1186 1403 DFE-530TX rev C
- 3108 S3 Unichrome Pro VGA Adapter
- 3109 VT8233C PCI to ISA Bridge
- 3112 VT8361 [KLE133] Host Bridge
- 3116 VT8375 [KM266/KL266] Host Bridge
- 1297 f641 FX41 motherboard
- 3118 S3 Unichrome Pro VGA Adapter
- 3119 VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
-# found on EPIA M6000/9000 mainboard
- 3122 VT8623 [Apollo CLE266] integrated CastleRock graphics
-# found on EPIA M6000/9000 mainboard
- 3123 VT8623 [Apollo CLE266]
- 3128 VT8753 [P4X266 AGP]
- 3133 VT3133 Host Bridge
- 3147 VT8233A ISA Bridge
- 3148 P4M266 Host Bridge
- 3149 VIA VT6420 SATA RAID Controller
- 1043 80ed A7V600/K8V Deluxe motherboard
- 1458 b003 GA-7VM400AM(F) Motherboard
- 1462 7020 K8T Neo 2 Motherboard
- 147b 1407 KV8-MAX3 motherboard
- 3156 P/KN266 Host Bridge
-# on ASUS P4P800
- 3164 VT6410 ATA133 RAID controller
- 3168 VT8374 P4X400 Host Controller/AGP Bridge
- 3177 VT8235 ISA Bridge
- 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
- 1043 808c A7V8X motherboard
- 1043 80a1 A7V8X-X motherboard
- 1297 f641 FX41 motherboard
- 1458 5001 GA-7VAX Mainboard
- 1849 3177 K7VT2 motherboard
- 3178 ProSavageDDR P4N333 Host Bridge
- 3188 VT8385 [K8T800 AGP] Host Bridge
- 1043 80a3 K8V Deluxe motherboard
- 147b 1407 KV8-MAX3 motherboard
- 3189 VT8377 [KT400/KT600 AGP] Host Bridge
- 1043 807f A7V8X motherboard
- 1458 5000 GA-7VAX Mainboard
- 3204 K8M800
- 3205 VT8378 [KM400/A] Chipset Host Bridge
- 1458 5000 GA-7VM400M Motherboard
- 3218 K8T800M Host Bridge
- 3227 VT8237 ISA bridge [KT600/K8T800 South]
- 1043 80ed A7V600 motherboard
- 1106 3227 DFI KT600-AL Motherboard
- 1458 5001 GA-7VT600 Motherboard
- 147b 1407 KV8-MAX3 motherboard
- 3249 VT6421 IDE RAID Controller
- 4149 VIA VT6420 (ATA133) Controller
- 5030 VT82C596 ACPI [Apollo PRO]
- 6100 VT85C100A [Rhine II]
- 7204 K8M800
-# S3 Graphics UniChromeâ„¢ 2D/3D Graphics with motion compensation
- 7205 VT8378 [S3 UniChrome] Integrated Video
- 1458 d000 Gigabyte GA-7VM400(A)M(F) Motherboard
- 8231 VT8231 [PCI-to-ISA Bridge]
- 8235 VT8235 ACPI
- 8305 VT8363/8365 [KT133/KM133 AGP]
- 8391 VT8371 [KX133 AGP]
- 8501 VT8501 [Apollo MVP4 AGP]
- 8596 VT82C596 [Apollo PRO AGP]
- 8597 VT82C597 [Apollo VP3 AGP]
- 8598 VT82C598/694x [Apollo MVP3/Pro133x AGP]
- 1019 0985 P6VXA Motherboard
- 8601 VT8601 [Apollo ProMedia AGP]
- 8605 VT8605 [PM133 AGP]
- 8691 VT82C691 [Apollo Pro]
- 8693 VT82C693 [Apollo Pro Plus] PCI Bridge
- b091 VT8633 [Apollo Pro266 AGP]
- b099 VT8366/A/7 [Apollo KT266/A/333 AGP]
- b101 VT8653 AGP Bridge
- b102 VT8362 AGP Bridge
- b103 VT8615 AGP Bridge
- b112 VT8361 [KLE133] AGP Bridge
- b168 VT8235 PCI Bridge
- b188 VT8237 PCI bridge [K8T800 South]
- 147b 1407 KV8-MAX3 motherboard
- b198 VT8237 PCI Bridge
-# 32-Bit PCI bus master Ethernet MAC with standard MII interface
- d104 VT8237 Integrated Fast Ethernet Controller
-1107 Stratus Computers
- 0576 VIA VT82C570MV [Apollo] (Wrong vendor ID!)
-1108 Proteon, Inc.
- 0100 p1690plus_AA
- 0101 p1690plus_AB
- 0105 P1690Plus
- 0108 P1690Plus
- 0138 P1690Plus
- 0139 P1690Plus
- 013c P1690Plus
- 013d P1690Plus
-1109 Cogent Data Technologies, Inc.
- 1400 EM110TX [EX110TX]
-110a Siemens Nixdorf AG
- 0002 Pirahna 2-port
- 0005 Tulip controller, power management, switch extender
- 0006 FSC PINC (I/O-APIC)
- 0015 FSC Multiprocessor Interrupt Controller
- 001d FSC Copernicus Management Controller
- 007b FSC Remote Service Controller, mailbox device
- 007c FSC Remote Service Controller, shared memory device
- 007d FSC Remote Service Controller, SMIC device
-# Superfastcom-PCI (Commtech, Inc.) or DSCC4 WAN Adapter
- 2102 DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
- 2104 Eicon Diva 2.02 compatible passive ISDN card
- 3142 SIMATIC NET CP 5613A1 (Profibus Adapter)
- 4021 SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
- 4029 SIMATIC NET CP 5613A2 (Profibus Adapter)
- 4942 FPGA I-Bus Tracer for MBD
- 6120 SZB6120
-110b Chromatic Research Inc.
- 0001 Mpact Media Processor
- 0004 Mpact 2
-110c Mini-Max Technology, Inc.
-110d Znyx Advanced Systems
-110e CPU Technology
-110f Ross Technology
-1110 Powerhouse Systems
- 6037 Firepower Powerized SMP I/O ASIC
- 6073 Firepower Powerized SMP I/O ASIC
-1111 Santa Cruz Operation
-# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
-1112 Osicom Technologies Inc
- 2200 FDDI Adapter
- 2300 Fast Ethernet Adapter
- 2340 4 Port Fast Ethernet Adapter
- 2400 ATM Adapter
-1113 Accton Technology Corporation
- 1211 SMC2-1211TX
- 103c 1207 EN-1207D Fast Ethernet Adapter
- 1113 1211 EN-1207D Fast Ethernet Adapter
- 1216 EN-1216 Ethernet Adapter
- 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card
- 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
- 1217 EN-1217 Ethernet Adapter
- 5105 10Mbps Network card
- 9211 EN-1207D Fast Ethernet Adapter
- 1113 9211 EN-1207D Fast Ethernet Adapter
- 9511 21x4x DEC-Tulip compatible Fast Ethernet
- d301 CPWNA100 (Philips wireless PCMCIA)
- ec02 SMC 1244TX v3
-1114 Atmel Corporation
- 0506 802.11b Wireless Network Adaptor (at76c506)
-1115 3D Labs
-1116 Data Translation
- 0022 DT3001
- 0023 DT3002
- 0024 DT3003
- 0025 DT3004
- 0026 DT3005
- 0027 DT3001-PGL
- 0028 DT3003-PGL
-1117 Datacube, Inc
- 9500 Max-1C SVGA card
- 9501 Max-1C image processing
-1118 Berg Electronics
-1119 ICP Vortex Computersysteme GmbH
- 0000 GDT 6000/6020/6050
- 0001 GDT 6000B/6010
- 0002 GDT 6110/6510
- 0003 GDT 6120/6520
- 0004 GDT 6530
- 0005 GDT 6550
- 0006 GDT 6117/6517
- 0007 GDT 6127/6527
- 0008 GDT 6537
- 0009 GDT 6557/6557-ECC
- 000a GDT 6115/6515
- 000b GDT 6125/6525
- 000c GDT 6535
- 000d GDT 6555
- 0010 GDT 6115/6515
- 0011 GDT 6125/6525
- 0012 GDT 6535
- 0013 GDT 6555/6555-ECC
- 0100 GDT 6117RP/6517RP
- 0101 GDT 6127RP/6527RP
- 0102 GDT 6537RP
- 0103 GDT 6557RP
- 0104 GDT 6111RP/6511RP
- 0105 GDT 6121RP/6521RP
- 0110 GDT 6117RD/6517RD
- 0111 GDT 6127RD/6527RD
- 0112 GDT 6537RD
- 0113 GDT 6557RD
- 0114 GDT 6111RD/6511RD
- 0115 GDT 6121RD/6521RD
- 0118 GDT 6118RD/6518RD/6618RD
- 0119 GDT 6128RD/6528RD/6628RD
- 011a GDT 6538RD/6638RD
- 011b GDT 6558RD/6658RD
- 0120 GDT 6117RP2/6517RP2
- 0121 GDT 6127RP2/6527RP2
- 0122 GDT 6537RP2
- 0123 GDT 6557RP2
- 0124 GDT 6111RP2/6511RP2
- 0125 GDT 6121RP2/6521RP2
- 0136 GDT 6113RS/6513RS
- 0137 GDT 6123RS/6523RS
- 0138 GDT 6118RS/6518RS/6618RS
- 0139 GDT 6128RS/6528RS/6628RS
- 013a GDT 6538RS/6638RS
- 013b GDT 6558RS/6658RS
- 013c GDT 6533RS/6633RS
- 013d GDT 6543RS/6643RS
- 013e GDT 6553RS/6653RS
- 013f GDT 6563RS/6663RS
- 0166 GDT 7113RN/7513RN/7613RN
- 0167 GDT 7123RN/7523RN/7623RN
- 0168 GDT 7118RN/7518RN/7518RN
- 0169 GDT 7128RN/7528RN/7628RN
- 016a GDT 7538RN/7638RN
- 016b GDT 7558RN/7658RN
- 016c GDT 7533RN/7633RN
- 016d GDT 7543RN/7643RN
- 016e GDT 7553RN/7653RN
- 016f GDT 7563RN/7663RN
- 01d6 GDT 4x13RZ
- 01d7 GDT 4x23RZ
- 01f6 GDT 8x13RZ
- 01f7 GDT 8x23RZ
- 01fc GDT 8x33RZ
- 01fd GDT 8x43RZ
- 01fe GDT 8x53RZ
- 01ff GDT 8x63RZ
- 0210 GDT 6519RD/6619RD
- 0211 GDT 6529RD/6629RD
- 0260 GDT 7519RN/7619RN
- 0261 GDT 7529RN/7629RN
- 02ff GDT MAXRP
- 0300 GDT NEWRX
-111a Efficient Networks, Inc
- 0000 155P-MF1 (FPGA)
- 0002 155P-MF1 (ASIC)
- 0003 ENI-25P ATM
- 111a 0000 ENI-25p Miniport ATM Adapter
- 0005 SpeedStream (LANAI)
- 111a 0001 ENI-3010 ATM
- 111a 0009 ENI-3060 ADSL (VPI=0)
- 111a 0101 ENI-3010 ATM
- 111a 0109 ENI-3060CO ADSL (VPI=0)
- 111a 0809 ENI-3060 ADSL (VPI=0 or 8)
- 111a 0909 ENI-3060CO ADSL (VPI=0 or 8)
- 111a 0a09 ENI-3060 ADSL (VPI=<0..15>)
- 0007 SpeedStream ADSL
- 111a 1001 ENI-3061 ADSL [ASIC]
- 1203 SpeedStream 1023 Wireless PCI Adapter
-111b Teledyne Electronic Systems
-111c Tricord Systems Inc.
- 0001 Powerbis Bridge
-111d Integrated Device Technology, Inc.
- 0001 IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
- 0003 IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
- 0004 IDT77V252 155Mbps ATM MICRO ABR SAR Controller
- 0005 IDT77V222 155Mbps ATM MICRO ABR SAR Controller
-111e Eldec
-111f Precision Digital Images
- 4a47 Precision MX Video engine interface
- 5243 Frame capture bus interface
-1120 EMC Corporation
-1121 Zilog
-1122 Multi-tech Systems, Inc.
-1123 Excellent Design, Inc.
-1124 Leutron Vision AG
-1125 Eurocore
-1126 Vigra
-1127 FORE Systems Inc
- 0200 ForeRunner PCA-200 ATM
- 0210 PCA-200PC
- 0250 ATM
- 0300 ForeRunner PCA-200EPC ATM
- 0310 ATM
- 0400 ForeRunnerHE ATM Adapter
- 1127 0400 ForeRunnerHE ATM
-1129 Firmworks
-112a Hermes Electronics Company, Ltd.
-112b Linotype - Hell AG
-112c Zenith Data Systems
-112d Ravicad
-112e Infomedia Microelectronics Inc.
-112f Imaging Technology Inc
- 0000 MVC IC-PCI
- 0001 MVC IM-PCI Video frame grabber/processor
-1130 Computervision
-1131 Philips Semiconductors
- 1561 USB 1.1 Host Controller
- 1562 USB 2.0 Host Controller
- 3400 SmartPCI56(UCB1500) 56K Modem
- 5400 TriMedia TM1000/1100
- 5402 TriMedia TM-1300
- 1244 0f00 Fritz!Card DSL
- 7130 SAA7130 Video Broadcast Decoder
- 5168 0138 LiveView FlyVideo 2000
- 7133 SAA713X Audio+video broadcast decoder
- 5168 0138 LifeView FlyVideo 3000
- 5168 0212 LifeView FlyTV Platinum mini
- 5168 0502 LifeView FlyDVB-T Duo CardBus
-# PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl)
- 7134 SAA7134
- 1043 4842 TV-FM Card 7134
- 7135 SAA7135 Audio+video broadcast decoder
- 7145 SAA7145
- 7146 SAA7146
- 110a 0000 Fujitsu/Siemens DVB-C card rev1.5
- 110a ffff Fujitsu/Siemens DVB-C card rev1.5
- 1131 4f56 KNC1 DVB-S Budget
- 1131 4f61 Fujitsu-Siemens Activy DVB-S Budget
- 114b 2003 DVRaptor Video Edit/Capture Card
- 11bd 0006 DV500 Overlay
- 11bd 000a DV500 Overlay
- 11bd 000f DV500 Overlay
- 13c2 0000 Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
- 13c2 0001 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
- 13c2 0002 Technotrend/Hauppauge DVB card rev2.1
- 13c2 0003 Technotrend/Hauppauge DVB card rev2.1
- 13c2 0004 Technotrend/Hauppauge DVB card rev2.1
- 13c2 0006 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
- 13c2 0008 Technotrend/Hauppauge DVB-T
- 13c2 000a Octal/Technotrend DVB-C for iTV
- 13c2 1003 Technotrend-Budget / Hauppauge WinTV-NOVA-S DVB card
- 13c2 1004 Technotrend-Budget / Hauppauge WinTV-NOVA-C DVB card
- 13c2 1005 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
- 13c2 100c Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
- 13c2 100f Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
- 13c2 1011 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
- 13c2 1013 SATELCO Multimedia DVB
- 13c2 1102 Technotrend/Hauppauge DVB card rev2.1
-1132 Mitel Corp.
-# This is the new official company name. See disclaimer on www.eicon.com for details!
-1133 Eicon Networks Corporation
- 7901 EiconCard S90
- 7902 EiconCard S90
- 7911 EiconCard S91
- 7912 EiconCard S91
- 7941 EiconCard S94
- 7942 EiconCard S94
- 7943 EiconCard S94
- 7944 EiconCard S94
- b921 EiconCard P92
- b922 EiconCard P92
- b923 EiconCard P92
- e001 Diva Pro 2.0 S/T
- e002 Diva 2.0 S/T PCI
- e003 Diva Pro 2.0 U
- e004 Diva 2.0 U PCI
- e005 Diva 2.01 S/T PCI
- e006 Diva CT S/T PCI
- e007 Diva CT U PCI
- e008 Diva CT Lite S/T PCI
- e009 Diva CT Lite U PCI
- e00a Diva ISDN+V.90 PCI
- e00b Diva 2.02 PCI S/T
- e00c Diva 2.02 PCI U
- e00d Diva ISDN Pro 3.0 PCI
- e00e Diva ISDN+CT S/T PCI Rev 2
- e010 Diva Server BRI-2M PCI
- 110a 0021 Fujitsu Siemens ISDN S0
- 8001 0014 Diva Server BRI-2M PCI Cornet NQ
- e011 Diva Server BRI S/T Rev 2
- e012 Diva Server 4BRI-8M PCI
- 8001 0014 Diva Server 4BRI-8M PCI Cornet NQ
- e013 Diva Server 4BRI Rev 2
- 1133 1300 Diva Server V-4BRI-8
- 1133 e013 Diva Server 4BRI-8M 2.0 PCI
- 8001 0014 Diva Server 4BRI-8M 2.0 PCI Cornet NQ
- e014 Diva Server PRI-30M PCI
- 0008 0100 Diva Server PRI-30M PCI
- 8001 0014 Diva Server PRI-30M PCI Cornet NQ
- e015 DIVA Server PRI Rev 2
- 1133 e015 Diva Server PRI 2.0 PCI
- 8001 0014 Diva Server PRI 2.0 PCI Cornet NQ
- e016 Diva Server Voice 4BRI PCI
- 8001 0014 Diva Server PRI Cornet NQ
- e017 Diva Server Voice 4BRI Rev 2
- 1133 e017 Diva Server Voice 4BRI-8M 2.0 PCI
- 8001 0014 Diva Server Voice 4BRI-8M 2.0 PCI Cornet NQ
- e018 Diva Server BRI-2M 2.0 PCI
- 1133 1800 Diva Server V-BRI-2
- 1133 e018 Diva Server BRI-2M 2.0 PCI
- 8001 0014 Diva Server BRI-2M 2.0 PCI Cornet NQ
- e019 Diva Server Voice PRI Rev 2
- 1133 e019 Diva Server Voice PRI 2.0 PCI
- 8001 0014 Diva Server Voice PRI 2.0 PCI Cornet NQ
- e01a Diva Server 2FX
- e01b Diva Server Voice BRI-2M 2.0 PCI
- 1133 e01b Diva Server Voice BRI-2M 2.0 PCI
- 8001 0014 Diva Server Voice BRI-2M 2.0 PCI Cornet NQ
- e01c Diva Server PRI Rev 3
- 1133 1c01 Diva Server PRI/E1/T1-8
- 1133 1c02 Diva Server PRI/T1-24
- 1133 1c03 Diva Server PRI/E1-30
- 1133 1c04 Diva Server PRI/E1/T1
- 1133 1c05 Diva Server V-PRI/T1-24
- 1133 1c06 Diva Server V-PRI/E1-30
- 1133 1c07 Diva Server PRI/E1/T1-8 Cornet NQ
- 1133 1c08 Diva Server PRI/T1-24 Cornet NQ
- 1133 1c09 Diva Server PRI/E1-30 Cornet NQ
- 1133 1c0a Diva Server PRI/E1/T1 Cornet NQ
- 1133 1c0b Diva Server V-PRI/T1-24 Cornet NQ
- 1133 1c0c Diva Server V-PRI/E1-30 Cornet NQ
- e01e Diva Server 2PRI
- 1133 1e00 Diva Server V-2PRI/E1-60
- 1133 1e01 Diva Server V-2PRI/T1-48
- 1133 1e02 Diva Server 2PRI/E1-60
- 1133 1e03 Diva Server 2PRI/T1-48
- e020 Diva Server 4PRI
- 1133 2000 Diva Server V-4PRI/E1-120
- 1133 2001 Diva Server V-4PRI/T1-96
- 1133 2002 Diva Server 4PRI/E1-120
- 1133 2003 Diva Server 4PRI/T1-96
- e024 Diva Server Analog-4P
- 1133 2400 Diva Server V-Analog-4P
- 1133 e024 Diva Server Analog-4P
- e028 Diva Server Analog-8P
- 1133 2800 Diva Server V-Analog-8P
- 1133 e028 Diva Server Analog-8P
-1134 Mercury Computer Systems
- 0001 Raceway Bridge
- 0002 Dual PCI to RapidIO Bridge
-1135 Fuji Xerox Co Ltd
- 0001 Printer controller
-1136 Momentum Data Systems
-1137 Cisco Systems Inc
-1138 Ziatech Corporation
- 8905 8905 [STD 32 Bridge]
-1139 Dynamic Pictures, Inc
- 0001 VGA Compatable 3D Graphics
-113a FWB Inc
-113b Network Computing Devices
-113c Cyclone Microsystems, Inc.
- 0000 PCI-9060 i960 Bridge
- 0001 PCI-SDK [PCI i960 Evaluation Platform]
- 0911 PCI-911 [i960Jx-based Intelligent I/O Controller]
- 0912 PCI-912 [i960CF-based Intelligent I/O Controller]
- 0913 PCI-913
- 0914 PCI-914 [I/O Controller w/ secondary PCI bus]
-113d Leading Edge Products Inc
-113e Sanyo Electric Co - Computer Engineering Dept
-113f Equinox Systems, Inc.
- 0808 SST-64P Adapter
- 1010 SST-128P Adapter
- 80c0 SST-16P DB Adapter
- 80c4 SST-16P RJ Adapter
- 80c8 SST-16P Adapter
- 8888 SST-4P Adapter
- 9090 SST-8P Adapter
-1140 Intervoice Inc
-1141 Crest Microsystem Inc
-1142 Alliance Semiconductor Corporation
- 3210 AP6410
- 6422 ProVideo 6422
- 6424 ProVideo 6424
- 6425 ProMotion AT25
- 643d ProMotion AT3D
-1143 NetPower, Inc
-1144 Cincinnati Milacron
- 0001 Noservo controller
-1145 Workbit Corporation
- 8007 NinjaSCSI-32 Workbit
- f007 NinjaSCSI-32 KME
- f010 NinjaSCSI-32 Workbit
- f012 NinjaSCSI-32 Logitec
- f013 NinjaSCSI-32 Logitec
- f015 NinjaSCSI-32 Melco
-1146 Force Computers
-1147 Interface Corp
-# Formerly (Schneider & Koch)
-1148 SysKonnect
- 4000 FDDI Adapter
- 0e11 b03b Netelligent 100 FDDI DAS Fibre SC
- 0e11 b03c Netelligent 100 FDDI SAS Fibre SC
- 0e11 b03d Netelligent 100 FDDI DAS UTP
- 0e11 b03e Netelligent 100 FDDI SAS UTP
- 0e11 b03f Netelligent 100 FDDI SAS Fibre MIC
- 1148 5521 FDDI SK-5521 (SK-NET FDDI-UP)
- 1148 5522 FDDI SK-5522 (SK-NET FDDI-UP DAS)
- 1148 5541 FDDI SK-5541 (SK-NET FDDI-FP)
- 1148 5543 FDDI SK-5543 (SK-NET FDDI-LP)
- 1148 5544 FDDI SK-5544 (SK-NET FDDI-LP DAS)
- 1148 5821 FDDI SK-5821 (SK-NET FDDI-UP64)
- 1148 5822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
- 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64)
- 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64)
- 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
- 4200 Token Ring adapter
- 4300 SK-98xx Gigabit Ethernet Server Adapter
- 1148 9821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
- 1148 9822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
- 1148 9841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
- 1148 9842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
- 1148 9843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
- 1148 9844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
- 1148 9861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
- 1148 9862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
- 1148 9871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
- 1148 9872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
- 1259 2970 AT-2970SX Gigabit Ethernet Adapter
- 1259 2971 AT-2970LX Gigabit Ethernet Adapter
- 1259 2972 AT-2970TX Gigabit Ethernet Adapter
- 1259 2973 AT-2971SX Gigabit Ethernet Adapter
- 1259 2974 AT-2971T Gigabit Ethernet Adapter
- 1259 2975 AT-2970SX/2SC Gigabit Ethernet Adapter
- 1259 2976 AT-2970LX/2SC Gigabit Ethernet Adapter
- 1259 2977 AT-2970TX/2TX Gigabit Ethernet Adapter
- 4320 SK-98xx V2.0 Gigabit Ethernet Adapter
- 1148 0121 Marvell RDK-8001 Adapter
- 1148 0221 Marvell RDK-8002 Adapter
- 1148 0321 Marvell RDK-8003 Adapter
- 1148 0421 Marvell RDK-8004 Adapter
- 1148 0621 Marvell RDK-8006 Adapter
- 1148 0721 Marvell RDK-8007 Adapter
- 1148 0821 Marvell RDK-8008 Adapter
- 1148 0921 Marvell RDK-8009 Adapter
- 1148 1121 Marvell RDK-8011 Adapter
- 1148 1221 Marvell RDK-8012 Adapter
- 1148 3221 SK-9521 V2.0 10/100/1000Base-T Adapter
- 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
- 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
- 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
- 1148 9521 SK-9521 10/100/1000Base-T Adapter
- 4400 SK-9Dxx Gigabit Ethernet Adapter
- 4500 SK-9Mxx Gigabit Ethernet Adapter
- 9000 SK-9Sxx Gigabit Ethernet Server Adapter PCI-X
- 9843 [Fujitsu] Gigabit Ethernet
- 9e00 SK-9Exx 10/100/1000Base-T Adapter
- 1148 2100 SK-9E21 Server Adapter
- 1148 21d0 SK-9E21D 10/100/1000Base-T Adapter
- 1148 2200 SK-9E22 Server Adapter
- 1148 8100 SK-9E81 Server Adapter
- 1148 8200 SK-9E82 Server Adapter
- 1148 9100 SK-9E91 Server Adapter
- 1148 9200 SK-9E92 Server Adapter
-1149 Win System Corporation
-114a VMIC
- 5579 VMIPCI-5579 (Reflective Memory Card)
- 5587 VMIPCI-5587 (Reflective Memory Card)
- 6504 VMIC PCI 7755 FPGA
- 7587 VMIVME-7587
-114b Canopus Co., Ltd
-114c Annabooks
-114d IC Corporation
-114e Nikon Systems Inc
-114f Digi International
- 0002 AccelePort EPC
- 0003 RightSwitch SE-6
- 0004 AccelePort Xem
- 0005 AccelePort Xr
- 0006 AccelePort Xr,C/X
- 0009 AccelePort Xr/J
- 000a AccelePort EPC/J
- 000c DataFirePRIme T1 (1-port)
- 000d SyncPort 2-Port (x.25/FR)
- 0011 AccelePort 8r EIA-232 (IBM)
- 0012 AccelePort 8r EIA-422
- 0013 AccelePort Xr
- 0014 AccelePort 8r EIA-422
- 0015 AccelePort Xem
- 0016 AccelePort EPC/X
- 0017 AccelePort C/X
- 001a DataFirePRIme E1 (1-port)
- 001b AccelePort C/X (IBM)
- 001d DataFire RAS T1/E1/PRI
- 114f 0050 DataFire RAS E1 Adapter
- 114f 0051 DataFire RAS Dual E1 Adapter
- 114f 0052 DataFire RAS T1 Adapter
- 114f 0053 DataFire RAS Dual T1 Adapter
- 0023 AccelePort RAS
- 0024 DataFire RAS B4 ST/U
- 114f 0030 DataFire RAS BRI U Adapter
- 114f 0031 DataFire RAS BRI S/T Adapter
- 0026 AccelePort 4r 920
- 0027 AccelePort Xr 920
- 0028 ClassicBoard 4
- 0029 ClassicBoard 8
- 0034 AccelePort 2r 920
- 0035 DataFire DSP T1/E1/PRI cPCI
- 0040 AccelePort Xp
- 0042 AccelePort 2p
- 0043 AccelePort 4p
- 0044 AccelePort 8p
- 0045 AccelePort 16p
- 004e AccelePort 32p
- 0070 Datafire Micro V IOM2 (Europe)
- 0071 Datafire Micro V (Europe)
- 0072 Datafire Micro V IOM2 (North America)
- 0073 Datafire Micro V (North America)
- 00b0 Digi Neo 4
- 00b1 Digi Neo 8
- 00c8 Digi Neo 2 DB9
- 00c9 Digi Neo 2 DB9 PRI
- 00ca Digi Neo 2 RJ45
- 00cb Digi Neo 2 RJ45 PRI
- 00d0 ClassicBoard 4 422
- 00d1 ClassicBoard 8 422
- 6001 Avanstar
-1150 Thinking Machines Corp
-1151 JAE Electronics Inc.
-1152 Megatek
-1153 Land Win Electronic Corp
-1154 Melco Inc
-1155 Pine Technology Ltd
-1156 Periscope Engineering
-1157 Avsys Corporation
-1158 Voarx R & D Inc
- 3011 Tokenet/vg 1001/10m anylan
- 9050 Lanfleet/Truevalue
- 9051 Lanfleet/Truevalue
-1159 Mutech Corp
- 0001 MV-1000
-115a Harlequin Ltd
-115b Parallax Graphics
-115c Photron Ltd.
-115d Xircom
- 0003 Cardbus Ethernet 10/100
- 1014 0181 10/100 EtherJet Cardbus Adapter
- 1014 1181 10/100 EtherJet Cardbus Adapter
- 1014 8181 10/100 EtherJet Cardbus Adapter
- 1014 9181 10/100 EtherJet Cardbus Adapter
- 115d 0181 Cardbus Ethernet 10/100
- 115d 1181 Cardbus Ethernet 10/100
- 1179 0181 Cardbus Ethernet 10/100
- 8086 8181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
- 8086 9181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
- 0005 Cardbus Ethernet 10/100
- 1014 0182 10/100 EtherJet Cardbus Adapter
- 1014 1182 10/100 EtherJet Cardbus Adapter
- 115d 0182 Cardbus Ethernet 10/100
- 115d 1182 Cardbus Ethernet 10/100
- 0007 Cardbus Ethernet 10/100
- 1014 0182 10/100 EtherJet Cardbus Adapter
- 1014 1182 10/100 EtherJet Cardbus Adapter
- 115d 0182 Cardbus Ethernet 10/100
- 115d 1182 Cardbus Ethernet 10/100
- 000b Cardbus Ethernet 10/100
- 1014 0183 10/100 EtherJet Cardbus Adapter
- 115d 0183 Cardbus Ethernet 10/100
- 000c Mini-PCI V.90 56k Modem
- 000f Cardbus Ethernet 10/100
- 1014 0183 10/100 EtherJet Cardbus Adapter
- 115d 0183 Cardbus Ethernet 10/100
- 00d4 Mini-PCI K56Flex Modem
- 0101 Cardbus 56k modem
- 115d 1081 Cardbus 56k Modem
- 0103 Cardbus Ethernet + 56k Modem
- 1014 9181 Cardbus 56k Modem
- 1115 1181 Cardbus Ethernet 100 + 56k Modem
- 115d 1181 CBEM56G-100 Ethernet + 56k Modem
- 8086 9181 PRO/100 LAN + Modem56 CardBus
-115e Peer Protocols Inc
-115f Maxtor Corporation
-1160 Megasoft Inc
-1161 PFU Limited
-1162 OA Laboratory Co Ltd
-1163 Rendition
- 0001 Verite 1000
- 2000 Verite V2000/V2100/V2200
- 1092 2000 Stealth II S220
-1164 Advanced Peripherals Technologies
-1165 Imagraph Corporation
- 0001 Motion TPEG Recorder/Player with audio
-1166 ServerWorks
- 0000 CMIC-LE
- 0005 CNB20-LE Host Bridge
- 0006 CNB20HE Host Bridge
- 0007 CNB20-LE Host Bridge
- 0008 CNB20HE Host Bridge
- 0009 CNB20LE Host Bridge
- 0010 CIOB30
- 0011 CMIC-HE
- 0012 CMIC-WS Host Bridge (GC-LE chipset)
- 0013 CNB20-HE Host Bridge
- 0014 CMIC-LE Host Bridge (GC-LE chipset)
- 0015 CMIC-GC Host Bridge
- 0016 CMIC-GC Host Bridge
- 0017 GCNB-LE Host Bridge
- 0101 CIOB-X2 PCI-X I/O Bridge
- 0110 CIOB-E I/O Bridge with Gigabit Ethernet
- 0200 OSB4 South Bridge
- 0201 CSB5 South Bridge
- 4c53 1080 CT8 mainboard
- 0203 CSB6 South Bridge
- 0211 OSB4 IDE Controller
- 0212 CSB5 IDE Controller
- 4c53 1080 CT8 mainboard
- 0213 CSB6 RAID/IDE Controller
- 0217 CSB6 IDE Controller
- 0220 OSB4/CSB5 OHCI USB Controller
- 4c53 1080 CT8 mainboard
- 0221 CSB6 OHCI USB Controller
- 0225 CSB5 LPC bridge
-# cancelled
- 4c53 1080 CT8 mainboard
- 0227 GCLE-2 Host Bridge
- 0230 CSB5 LPC bridge
- 4c53 1080 CT8 mainboard
- 0240 K2 SATA
- 0241 K2 SATA
- 0242 K2 SATA
-1167 Mutoh Industries Inc
-1168 Thine Electronics Inc
-1169 Centre for Development of Advanced Computing
-116a Polaris Communications
- 6100 Bus/Tag Channel
- 6800 Escon Channel
- 7100 Bus/Tag Channel
- 7800 Escon Channel
-116b Connectware Inc
-116c Intelligent Resources Integrated Systems
-116d Martin-Marietta
-116e Electronics for Imaging
-116f Workstation Technology
-1170 Inventec Corporation
-1171 Loughborough Sound Images Plc
-1172 Altera Corporation
-1173 Adobe Systems, Inc
-1174 Bridgeport Machines
-1175 Mitron Computer Inc.
-1176 SBE Incorporated
-1177 Silicon Engineering
-1178 Alfa, Inc.
- afa1 Fast Ethernet Adapter
-1179 Toshiba America Info Systems
- 0103 EX-IDE Type-B
- 0404 DVD Decoder card
- 0406 Tecra Video Capture device
- 0407 DVD Decoder card (Version 2)
- 0601 CPU to PCI bridge
- 0603 ToPIC95 PCI to CardBus Bridge for Notebooks
- 060a ToPIC95
- 060f ToPIC97
- 0617 ToPIC100 PCI to Cardbus Bridge with ZV Support
- 0618 CPU to PCI and PCI to ISA bridge
-# Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID?
- 0701 FIR Port
- 0804 TC6371AF SmartMedia Controller
- 0805 SD TypA Controller
- 0d01 FIR Port Type-DO
- 1179 0001 FIR Port Type-DO
-117a A-Trend Technology
-117b L G Electronics, Inc.
-117c Atto Technology
-117d Becton & Dickinson
-117e T/R Systems
-117f Integrated Circuit Systems
-1180 Ricoh Co Ltd
- 0465 RL5c465
- 0466 RL5c466
- 0475 RL5c475
- 144d c006 vpr Matrix 170B4 CardBus bridge
- 0476 RL5c476 II
- 1014 0185 ThinkPad A/T/X Series
- 104d 80df Vaio PCG-FX403
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 14ef 0220 PCD-RP-220S
- 0477 RL5c477
- 0478 RL5c478
- 1014 0184 ThinkPad A30p (2653-64G)
- 0522 R5C522 IEEE 1394 Controller
- 1014 01cf ThinkPad A30p (2653-64G)
- 0551 R5C551 IEEE 1394 Controller
- 144d c006 vpr Matrix 170B4
- 0552 R5C552 IEEE 1394 Controller
- 1014 0511 ThinkPad A/T/X Series
- 0576 R5C576 SD Bus Host Adapter
- 0592 R5C592 Memory Stick Bus Host Adapter
-1181 Telmatics International
-1183 Fujikura Ltd
-1184 Forks Inc
-1185 Dataworld International Ltd
-1186 D-Link System Inc
- 0100 DC21041
- 1002 DL10050 Sundance Ethernet
- 1186 1002 DFE-550TX
- 1186 1012 DFE-580TX
- 1025 AirPlus Xtreme G DWL-G650 Adapter
- 1026 AirXpert DWL-AG650 Wireless Cardbus Adapter
- 1043 AirXpert DWL-AG650 Wireless Cardbus Adapter
- 1300 RTL8139 Ethernet
- 1186 1300 DFE-538TX 10/100 Ethernet Adapter
- 1186 1301 DFE-530TX+ 10/100 Ethernet Adapter
- 1340 DFE-690TXD CardBus PC Card
- 1541 DFE-680TXD CardBus PC Card
- 1561 DRP-32TXD Cardbus PC Card
- 2027 AirPlus Xtreme G DWL-G520 Adapter
- 3203 AirPlus Xtreme G DWL-G520 Adapter
- 3300 DWL-510 2.4GHz Wireless PCI Adapter
- 3a03 AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
- 3a04 AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
- 3a05 AirPro DWL-AB520 Multimode Wireless PCI Adapter
- 3a07 AirXpert DWL-AG650 Wireless Cardbus Adapter
- 3a08 AirXpert DWL-AG520 Wireless PCI Adapter
- 3a10 AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
- 3a11 AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
- 3a12 AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
- 3a13 AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
- 3a14 AirPremier DWL-AG530 Wireless PCI Adapter
- 3a63 AirXpert DWL-AG660 Wireless Cardbus Adapter
- 3b05 DWL-G650+ CardBus PC Card
- 4000 DL2000-based Gigabit Ethernet
- 4300 DGE-528T Gigabit Ethernet Adapter
- 4c00 Gigabit Ethernet Adapter
- 1186 4c00 DGE-530T Gigabit Ethernet Adapter
- 8400 D-Link DWL-650+ CardBus PC Card
-1187 Advanced Technology Laboratories, Inc.
-1188 Shima Seiki Manufacturing Ltd.
-1189 Matsushita Electronics Co Ltd
-118a Hilevel Technology
-118b Hypertec Pty Limited
-118c Corollary, Inc
- 0014 PCIB [C-bus II to PCI bus host bridge chip]
- 1117 Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
-118d BitFlow Inc
- 0001 Raptor-PCI framegrabber
- 0012 Model 12 Road Runner Frame Grabber
- 0014 Model 14 Road Runner Frame Grabber
- 0024 Model 24 Road Runner Frame Grabber
- 0044 Model 44 Road Runner Frame Grabber
- 0112 Model 12 Road Runner Frame Grabber
- 0114 Model 14 Road Runner Frame Grabber
- 0124 Model 24 Road Runner Frame Grabber
- 0144 Model 44 Road Runner Frame Grabber
- 0212 Model 12 Road Runner Frame Grabber
- 0214 Model 14 Road Runner Frame Grabber
- 0224 Model 24 Road Runner Frame Grabber
- 0244 Model 44 Road Runner Frame Grabber
- 0312 Model 12 Road Runner Frame Grabber
- 0314 Model 14 Road Runner Frame Grabber
- 0324 Model 24 Road Runner Frame Grabber
- 0344 Model 44 Road Runner Frame Grabber
-118e Hermstedt GmbH
-118f Green Logic
-1190 Tripace
- c731 TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
-1191 Artop Electronic Corp
- 0003 SCSI Cache Host Adapter
- 0004 ATP8400
- 0005 ATP850UF
- 0006 ATP860 NO-BIOS
- 0007 ATP860
- 0008 ATP865 NO-ROM
- 0009 ATP865
- 8002 AEC6710 SCSI-2 Host Adapter
- 8010 AEC6712UW SCSI
- 8020 AEC6712U SCSI
- 8030 AEC6712S SCSI
- 8040 AEC6712D SCSI
- 8050 AEC6712SUW SCSI
- 8060 AEC6712 SCSI
- 8080 AEC67160 SCSI
- 8081 AEC67160S SCSI
- 808a AEC67162 2-ch. LVD SCSI
-1192 Densan Company Ltd
-1193 Zeitnet Inc.
- 0001 1221
- 0002 1225
-1194 Toucan Technology
-1195 Ratoc System Inc
-1196 Hytec Electronics Ltd
-1197 Gage Applied Sciences, Inc.
- 010c CompuScope 82G 8bit 2GS/s Analog Input Card
-1198 Lambda Systems Inc
-1199 Attachmate Corporation
-119a Mind Share, Inc.
-119b Omega Micro Inc.
- 1221 82C092G
-119c Information Technology Inst.
-119d Bug, Inc. Sapporo Japan
-119e Fujitsu Microelectronics Ltd.
- 0001 FireStream 155
- 0003 FireStream 50
-119f Bull HN Information Systems
-11a0 Convex Computer Corporation
-11a1 Hamamatsu Photonics K.K.
-11a2 Sierra Research and Technology
-11a3 Deuretzbacher GmbH & Co. Eng. KG
-11a4 Barco Graphics NV
-11a5 Microunity Systems Eng. Inc
-11a6 Pure Data Ltd.
-11a7 Power Computing Corp.
-11a8 Systech Corp.
-11a9 InnoSys Inc.
- 4240 AMCC S933Q Intelligent Serial Card
-11aa Actel
-# Formerly Galileo Technology, Inc.
-11ab Marvell Technology Group Ltd.
- 0146 GT-64010/64010A System Controller
- 138f W8300 802.11 Adapter (rev 07)
- 1fa6 Marvell W8300 802.11 Adapter
- 1fa7 88W8310 and 88W8000G [Libertas] 802.11g client chipset
- 4320 Gigabit Ethernet Controller
- 1019 0f38 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
- 1019 8001 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
- 1043 173c Marvell 88E8001 Gigabit Ethernet Controller (Asus)
- 1043 811a Marvell 88E8001 Gigabit Ethernet Controller (Asus)
- 105b 0c19 Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
- 10b8 b452 SMC EZ Card 1000 (SMC9452TXV.2)
- 11ab 0121 Marvell RDK-8001
- 11ab 0321 Marvell RDK-8003
- 11ab 1021 Marvell RDK-8010
- 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
- 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
- 1458 e000 Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
- 147b 1406 Marvell 88E8001 Gigabit Ethernet Controller (Abit)
- 15d4 0047 Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
- 1695 9025 Marvell 88E8001 Gigabit Ethernet Controller (Epox)
- 17f2 1c03 Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
- 270f 2803 Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
- 4350 Fast Ethernet Controller
- 1179 0001 Marvell 88E8035 Fast Ethernet Controller (Toshiba)
- 11ab 3521 Marvell RDK-8035
- 1854 000d Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 000e Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 000f Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0011 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0012 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0016 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0017 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0018 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0019 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 001c Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 001e Marvell 88E8035 Fast Ethernet Controller (LGE)
- 1854 0020 Marvell 88E8035 Fast Ethernet Controller (LGE)
- 4351 Fast Ethernet Controller
- 107b 4009 Marvell 88E8036 Fast Ethernet Controller (Wistron)
- 10f7 8338 Marvell 88E8036 Fast Ethernet Controller (Panasonic)
- 1179 0001 Marvell 88E8036 Fast Ethernet Controller (Toshiba)
- 1179 ff00 Marvell 88E8036 Fast Ethernet Controller (Compal)
- 1179 ff10 Marvell 88E8036 Fast Ethernet Controller (Inventec)
- 11ab 3621 Marvell RDK-8036
- 13d1 ac12 Abocom EFE3K - 10/100 Ethernet Expresscard
- 161f 203d Marvell 88E8036 Fast Ethernet Controller (Arima)
- 1854 000d Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 000e Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 000f Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0011 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0012 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0016 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0017 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0018 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0019 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 001c Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 001e Marvell 88E8036 Fast Ethernet Controller (LGE)
- 1854 0020 Marvell 88E8036 Fast Ethernet Controller (LGE)
- 4360 Gigabit Ethernet Controller
- 1043 8134 Marvell 88E8052 Gigabit Ethernet Controller (Asus)
- 107b 4009 Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
- 11ab 5221 Marvell RDK-8052
- 1458 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
- 1462 052c Marvell 88E8052 Gigabit Ethernet Controller (MSI)
- 1849 8052 Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
- 1940 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
- a0a0 0509 Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
- 4361 Gigabit Ethernet Controller
- 107b 3015 Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
- 11ab 5021 Marvell 88E8050 Gigabit Ethernet Controller (Intel)
- 8086 3063 D925XCVLK mainboard
- 4362 Gigabit Ethernet Controller
- 103c 2a0d Marvell 88E8053 Gigabit Ethernet Controller (Asus)
- 1043 8142 Marvell 88E8053 Gigabit Ethernet Controller (Asus)
- 109f 3197 Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
- 10f7 8338 Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
- 10fd a430 Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
- 1179 0001 Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
- 1179 ff00 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
- 1179 ff10 Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
- 11ab 5321 Marvell RDK-8053
- 1297 c240 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
- 1297 c241 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
- 1297 c242 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
- 1297 c243 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
- 1297 c244 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
- 13d1 ac11 Abocom EGE5K - Giga Ethernet Expresscard
- 1458 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
- 1462 058c Marvell 88E8053 Gigabit Ethernet Controller (MSI)
- 14c0 0012 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
- 1558 04a0 Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
- 15bd 1003 Marvell 88E8053 Gigabit Ethernet Controller (DFI)
- 161f 203c Marvell 88E8053 Gigabit Ethernet Controller (Arima)
- 161f 203d Marvell 88E8053 Gigabit Ethernet Controller (Arima)
- 1695 9029 Marvell 88E8053 Gigabit Ethernet Controller (Epox)
- 17f2 2c08 Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
- 17ff 0585 Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
- 1849 8053 Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
- 1854 000b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 000c Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0010 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0013 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0014 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0015 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 001a Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 001b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 001d Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 001f Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0021 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1854 0022 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
- 1940 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
- 270f 2801 Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
- a0a0 0506 Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
- 4611 GT-64115 System Controller
- 4620 GT-64120/64120A/64121A System Controller
- 4801 GT-48001
- 5005 Belkin F5D5005 Gigabit Desktop Network PCI Card
- 5040 MV88SX5040 4-port SATA I PCI-X Controller
- 5041 MV88SX5041 4-port SATA I PCI-X Controller
- 5080 MV88SX5080 8-port SATA I PCI-X Controller
- 5081 MV88SX5081 8-port SATA I PCI-X Controller
- 6041 MV88SX6041 4-port SATA II PCI-X Controller
- 6081 MV88SX6081 8-port SATA II PCI-X Controller
- 6460 MV64360/64361/64362 System Controller
- f003 GT-64010 Primary Image Piranha Image Generator
-11ac Canon Information Systems Research Aust.
-11ad Lite-On Communications Inc
- 0002 LNE100TX
- 11ad 0002 LNE100TX
- 11ad 0003 LNE100TX
- 11ad f003 LNE100TX
- 11ad ffff LNE100TX
- 1385 f004 FA310TX
- c115 LNE100TX [Linksys EtherFast 10/100]
- 11ad c001 LNE100TX [ver 2.0]
-11ae Aztech System Ltd
-11af Avid Technology Inc.
- 0001 [Cinema]
-11b0 V3 Semiconductor Inc.
- 0002 V300PSC
- 0292 V292PBC [Am29030/40 Bridge]
- 0960 V96xPBC
- c960 V96DPC
-11b1 Apricot Computers
-11b2 Eastman Kodak
-11b3 Barr Systems Inc.
-11b4 Leitch Technology International
-11b5 Radstone Technology Plc
-11b6 United Video Corp
-11b7 Motorola
-11b8 XPoint Technologies, Inc
- 0001 Quad PeerMaster
-11b9 Pathlight Technology Inc.
- c0ed SSA Controller
-11ba Videotron Corp
-11bb Pyramid Technology
-11bc Network Peripherals Inc
- 0001 NP-PCI
-11bd Pinnacle Systems Inc.
-11be International Microcircuits Inc
-11bf Astrodesign, Inc.
-11c0 Hewlett Packard
-11c1 Agere Systems (former Lucent Microelectronics)
- 0440 56k WinModem
- 1033 8015 LT WinModem 56k Data+Fax+Voice+Dsvd
- 1033 8047 LT WinModem 56k Data+Fax+Voice+Dsvd
- 1033 804f LT WinModem 56k Data+Fax+Voice+Dsvd
- 10cf 102c LB LT Modem V.90 56k
- 10cf 104a BIBLO LT Modem 56k
- 10cf 105f LB2 LT Modem V.90 56k
- 1179 0001 Internal V.90 Modem
- 11c1 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
- 122d 4101 MDP7800-U Modem
- 122d 4102 MDP7800SP-U Modem
- 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 0441 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 0450 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 f100 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 f101 LT WinModem 56k Data+Fax+Voice+Dsvd
- 144d 2101 LT56PV Modem
- 149f 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
- 0441 56k WinModem
- 1033 804d LT WinModem 56k Data+Fax
- 1033 8065 LT WinModem 56k Data+Fax
- 1092 0440 Supra 56i
- 1179 0001 Internal V.90 Modem
- 11c1 0440 LT WinModem 56k Data+Fax
- 11c1 0441 LT WinModem 56k Data+Fax
- 122d 4100 MDP7800-U Modem
- 13e0 0040 LT WinModem 56k Data+Fax
- 13e0 0100 LT WinModem 56k Data+Fax
- 13e0 0410 LT WinModem 56k Data+Fax
- 13e0 0420 TelePath Internet 56k WinModem
- 13e0 0440 LT WinModem 56k Data+Fax
- 13e0 0443 LT WinModem 56k Data+Fax
- 13e0 f102 LT WinModem 56k Data+Fax
- 1416 9804 CommWave 56k Modem
- 141d 0440 LT WinModem 56k Data+Fax
- 144f 0441 Lucent 56k V.90 DF Modem
- 144f 0449 Lucent 56k V.90 DF Modem
- 144f 110d Lucent Win Modem
- 1468 0441 Presario 56k V.90 DF Modem
- 1668 0440 Lucent Win Modem
- 0442 56k WinModem
- 11c1 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 11c1 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 13e0 0412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 13e0 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 13fc 2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 144d 2104 LT56PT Modem
- 144f 1104 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 149f 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 1668 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 0443 LT WinModem
- 0444 LT WinModem
- 0445 LT WinModem
- 8086 2203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
- 8086 2204 PRO/100+ MiniPCI on Armada E500
- 0446 LT WinModem
- 0447 LT WinModem
- 0448 WinModem 56k
- 1014 0131 Lucent Win Modem
- 1033 8066 LT WinModem 56k Data+Fax+Voice+Dsvd
- 13e0 0030 56k Voice Modem
- 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
-# Actiontech eth+modem card as used by Dell &c.
- 1668 2400 LT WinModem 56k (MiniPCI Ethernet+Modem)
- 0449 WinModem 56k
- 0e11 b14d 56k V.90 Modem
- 13e0 0020 LT WinModem 56k Data+Fax
- 13e0 0041 TelePath Internet 56k WinModem
- 1436 0440 Lucent Win Modem
- 144f 0449 Lucent 56k V.90 DFi Modem
- 1468 0410 IBM ThinkPad T23 (2647-4MG)
- 1468 0440 Lucent Win Modem
- 1468 0449 Presario 56k V.90 DFi Modem
- 044a F-1156IV WinModem (V90, 56KFlex)
- 10cf 1072 LB Global LT Modem
- 13e0 0012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 13e0 0042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 144f 1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
- 044b LT WinModem
- 044c LT WinModem
- 044d LT WinModem
- 044e LT WinModem
- 044f V90 WildWire Modem
- 0450 LT WinModem
- 1033 80a8 Versa Note Vxi
- 144f 4005 Magnia SG20
- 0451 LT WinModem
- 0452 LT WinModem
- 0453 LT WinModem
- 0454 LT WinModem
- 0455 LT WinModem
- 0456 LT WinModem
- 0457 LT WinModem
- 0458 LT WinModem
- 0459 LT WinModem
- 045a LT WinModem
- 045c LT WinModem
- 0461 V90 WildWire Modem
- 0462 V90 WildWire Modem
- 0480 Venus Modem (V90, 56KFlex)
- 048c V.92 56K WinModem
-# InPorte Home Internal 56k Modem/fax/answering machine/SMS Features
- 048f V.92 56k WinModem
- 5801 USB
- 5802 USS-312 USB Controller
-# 4 port PCI USB Controller made by Agere (formely Lucent)
- 5803 USS-344S USB Controller
- 5811 FW323
- 8086 524c D865PERL mainboard
- dead 0800 FireWire Host Bus Adapter
- ab10 WL60010 Wireless LAN MAC
- ab11 WL60040 Multimode Wireles LAN MAC
- 11c1 ab12 WaveLAN 11abg Cardbus card (Model 1102)
- 11c1 ab13 WaveLAN 11abg MiniPCI card (Model 0512)
- 11c1 ab15 WaveLAN 11abg Cardbus card (Model 1106)
- 11c1 ab16 WaveLAN 11abg MiniPCI card (Model 0516)
- ab20 ORiNOCO PCI Adapter
- ab21 Agere Wireless PCI Adapter
- ab30 Hermes2 Mini-PCI WaveLAN a/b/g
- 14cd 2012 Hermes2 Mini-PCI WaveLAN a/b/g
-11c2 Sand Microelectronics
-11c3 NEC Corporation
-11c4 Document Technologies, Inc
-11c5 Shiva Corporation
-11c6 Dainippon Screen Mfg. Co. Ltd
-11c7 D.C.M. Data Systems
-11c8 Dolphin Interconnect Solutions AS
- 0658 PSB32 SCI-Adapter D31x
- d665 PSB64 SCI-Adapter D32x
- d667 PSB66 SCI-Adapter D33x
-11c9 Magma
- 0010 16-line serial port w/- DMA
- 0011 4-line serial port w/- DMA
-11ca LSI Systems, Inc
-11cb Specialix Research Ltd.
- 2000 PCI_9050
- 11cb 0200 SX
- 11cb b008 I/O8+
- 4000 SUPI_1
- 8000 T225
-11cc Michels & Kleberhoff Computer GmbH
-11cd HAL Computer Systems, Inc.
-11ce Netaccess
-11cf Pioneer Electronic Corporation
-11d0 Lockheed Martin Federal Systems-Manassas
-11d1 Auravision
- 01f7 VxP524
-11d2 Intercom Inc.
-11d3 Trancell Systems Inc
-11d4 Analog Devices
- 1535 Blackfin BF535 processor
- 1805 SM56 PCI modem
- 1889 AD1889 sound chip
-11d5 Ikon Corporation
- 0115 10115
- 0117 10117
-11d6 Tekelec Telecom
-11d7 Trenton Technology, Inc.
-11d8 Image Technologies Development
-11d9 TEC Corporation
-11da Novell
-11db Sega Enterprises Ltd
-11dc Questra Corporation
-11dd Crosfield Electronics Limited
-11de Zoran Corporation
- 6057 ZR36057PQC Video cutting chipset
- 1031 7efe DC10 Plus
- 1031 fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
- 13ca 4231 JPEG/TV Card
- 6120 ZR36120
- 1328 f001 Cinemaster C DVD Decoder
-11df New Wave PDG
-11e0 Cray Communications A/S
-11e1 GEC Plessey Semi Inc.
-11e2 Samsung Information Systems America
-11e3 Quicklogic Corporation
- 5030 PC Watchdog
-11e4 Second Wave Inc
-11e5 IIX Consulting
-11e6 Mitsui-Zosen System Research
-11e7 Toshiba America, Elec. Company
-11e8 Digital Processing Systems Inc.
-11e9 Highwater Designs Ltd.
-11ea Elsag Bailey
-11eb Formation Inc.
-11ec Coreco Inc
-11ed Mediamatics
-11ee Dome Imaging Systems Inc
-11ef Nicolet Technologies B.V.
-11f0 Compu-Shack
- 4231 FDDI
- 4232 FASTline UTP Quattro
- 4233 FASTline FO
- 4234 FASTline UTP
- 4235 FASTline-II UTP
- 4236 FASTline-II FO
- 4731 GIGAline
-11f1 Symbios Logic Inc
-11f2 Picture Tel Japan K.K.
-11f3 Keithley Metrabyte
-11f4 Kinetic Systems Corporation
- 2915 CAMAC controller
-11f5 Computing Devices International
-11f6 Compex
- 0112 ENet100VG4
- 0113 FreedomLine 100
- 1401 ReadyLink 2000
- 2011 RL100-ATX 10/100
- 11f6 2011 RL100-ATX
- 2201 ReadyLink 100TX (Winbond W89C840)
- 11f6 2011 ReadyLink 100TX
- 9881 RL100TX Fast Ethernet
-11f7 Scientific Atlanta
-11f8 PMC-Sierra Inc.
- 7375 PM7375 [LASAR-155 ATM SAR]
-11f9 I-Cube Inc
-11fa Kasan Electronics Company, Ltd.
-11fb Datel Inc
-11fc Silicon Magic
-11fd High Street Consultants
-11fe Comtrol Corporation
- 0001 RocketPort 32 port w/external I/F
- 0002 RocketPort 8 port w/external I/F
- 0003 RocketPort 16 port w/external I/F
- 0004 RocketPort 4 port w/quad cable
- 0005 RocketPort 8 port w/octa cable
- 0006 RocketPort 8 port w/RJ11 connectors
- 0007 RocketPort 4 port w/RJ11 connectors
- 0008 RocketPort 8 port w/ DB78 SNI (Siemens) connector
- 0009 RocketPort 16 port w/ DB78 SNI (Siemens) connector
- 000a RocketPort Plus 4 port
- 000b RocketPort Plus 8 port
- 000c RocketModem 6 port
- 000d RocketModem 4-port
- 000e RocketPort Plus 2 port RS232
- 000f RocketPort Plus 2 port RS422
- 0801 RocketPort UPCI 32 port w/external I/F
- 0802 RocketPort UPCI 8 port w/external I/F
- 0803 RocketPort UPCI 16 port w/external I/F
- 0805 RocketPort UPCI 8 port w/octa cable
- 080c RocketModem III 8 port
- 080d RocketModem III 4 port
- 0903 RocketPort Compact PCI 16 port w/external I/F
- 8015 RocketPort 4-port UART 16954
-11ff Scion Corporation
- 0003 AG-5
-1200 CSS Corporation
-1201 Vista Controls Corp
-1202 Network General Corp.
- 4300 Gigabit Ethernet Adapter
- 1202 9841 SK-9841 LX
- 1202 9842 SK-9841 LX dual link
- 1202 9843 SK-9843 SX
- 1202 9844 SK-9843 SX dual link
-1203 Bayer Corporation, Agfa Division
-1204 Lattice Semiconductor Corporation
-1205 Array Corporation
-1206 Amdahl Corporation
-1208 Parsytec GmbH
- 4853 HS-Link Device
-1209 SCI Systems Inc
-120a Synaptel
-120b Adaptive Solutions
-120c Technical Corp.
-120d Compression Labs, Inc.
-120e Cyclades Corporation
- 0100 Cyclom-Y below first megabyte
- 0101 Cyclom-Y above first megabyte
- 0102 Cyclom-4Y below first megabyte
- 0103 Cyclom-4Y above first megabyte
- 0104 Cyclom-8Y below first megabyte
- 0105 Cyclom-8Y above first megabyte
- 0200 Cyclades-Z below first megabyte
- 0201 Cyclades-Z above first megabyte
- 0300 PC300/RSV or /X21 (2 ports)
- 0301 PC300/RSV or /X21 (1 port)
- 0310 PC300/TE (2 ports)
- 0311 PC300/TE (1 port)
- 0320 PC300/TE-M (2 ports)
- 0321 PC300/TE-M (1 port)
- 0400 PC400
-120f Essential Communications
- 0001 Roadrunner serial HIPPI
-1210 Hyperparallel Technologies
-1211 Braintech Inc
-1212 Kingston Technology Corp.
-1213 Applied Intelligent Systems, Inc.
-1214 Performance Technologies, Inc.
-1215 Interware Co., Ltd
-1216 Purup Prepress A/S
-1217 O2 Micro, Inc.
- 6729 OZ6729
- 673a OZ6730
- 6832 OZ6832/6833 CardBus Controller
- 6836 OZ6836/6860 CardBus Controller
- 6872 OZ6812 CardBus Controller
- 6925 OZ6922 CardBus Controller
- 6933 OZ6933/711E1 CardBus/SmartCardBus Controller
- 1025 1016 Travelmate 612 TX
- 6972 OZ601/6912/711E0 CardBus/SmartCardBus Controller
- 1014 020c ThinkPad R30
- 1179 0001 Magnia Z310
- 7110 OZ711Mx 4-in-1 MemoryCardBus Accelerator
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 7112 OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
- 7113 OZ711EC1 SmartCardBus Controller
- 7114 OZ711M1/MC1 4-in-1 MemoryCardBus Controller
- 7134 OZ711MP1/MS1 MemoryCardBus Controller
- 71e2 OZ711E2 SmartCardBus Controller
- 7212 OZ711M2 4-in-1 MemoryCardBus Controller
- 7213 OZ6933E CardBus Controller
- 7223 OZ711M3/MC3 4-in-1 MemoryCardBus Controller
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 7233 OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
-1218 Hybricon Corp.
-1219 First Virtual Corporation
-121a 3Dfx Interactive, Inc.
- 0001 Voodoo
- 0002 Voodoo 2
- 0003 Voodoo Banshee
- 1092 0003 Monster Fusion
- 1092 4000 Monster Fusion
- 1092 4002 Monster Fusion
- 1092 4801 Monster Fusion AGP
- 1092 4803 Monster Fusion AGP
- 1092 8030 Monster Fusion
- 1092 8035 Monster Fusion AGP
- 10b0 0001 Dragon 4000
- 1102 1018 3D Blaster Banshee VE
- 121a 0001 Voodoo Banshee AGP
- 121a 0003 Voodoo Banshee AGP SGRAM
- 121a 0004 Voodoo Banshee
- 139c 0016 Raven
- 139c 0017 Raven
- 14af 0002 Maxi Gamer Phoenix
- 0004 Voodoo Banshee [Velocity 100]
- 0005 Voodoo 3
- 121a 0004 Voodoo3 AGP
- 121a 0030 Voodoo3 AGP
- 121a 0031 Voodoo3 AGP
- 121a 0034 Voodoo3 AGP
- 121a 0036 Voodoo3 2000 PCI
- 121a 0037 Voodoo3 AGP
- 121a 0038 Voodoo3 AGP
- 121a 003a Voodoo3 AGP
- 121a 0044 Voodoo3
- 121a 004b Velocity 100
- 121a 004c Velocity 200
- 121a 004d Voodoo3 AGP
- 121a 004e Voodoo3 AGP
- 121a 0051 Voodoo3 AGP
- 121a 0052 Voodoo3 AGP
- 121a 0060 Voodoo3 3500 TV (NTSC)
- 121a 0061 Voodoo3 3500 TV (PAL)
- 121a 0062 Voodoo3 3500 TV (SECAM)
- 0009 Voodoo 4 / Voodoo 5
- 121a 0003 Voodoo5 PCI 5500
- 121a 0009 Voodoo5 AGP 5500/6000
- 0057 Voodoo 3/3000 [Avenger]
-121b Advanced Telecommunications Modules
-121c Nippon Texaco., Ltd
-121d Lippert Automationstechnik GmbH
-121e CSPI
-121f Arcus Technology, Inc.
-1220 Ariel Corporation
- 1220 AMCC 5933 TMS320C80 DSP/Imaging board
-1221 Contec Co., Ltd
-1222 Ancor Communications, Inc.
-1223 Artesyn Communication Products
- 0003 PM/Link
- 0004 PM/T1
- 0005 PM/E1
- 0008 PM/SLS
- 0009 BajaSpan Resource Target
- 000a BajaSpan Section 0
- 000b BajaSpan Section 1
- 000c BajaSpan Section 2
- 000d BajaSpan Section 3
- 000e PM/PPC
-1224 Interactive Images
-1225 Power I/O, Inc.
-1227 Tech-Source
- 0006 Raptor GFX 8P
-1228 Norsk Elektro Optikk A/S
-1229 Data Kinesis Inc.
-122a Integrated Telecom
-122b LG Industrial Systems Co., Ltd
-122c Sican GmbH
-122d Aztech System Ltd
- 1206 368DSP
- 1400 Trident PCI288-Q3DII (NX)
- 50dc 3328 Audio
- 122d 0001 3328 Audio
- 80da 3328 Audio
- 122d 0001 3328 Audio
-122e Xyratex
-122f Andrew Corporation
-1230 Fishcamp Engineering
-1231 Woodward McCoach, Inc.
-1232 GPT Limited
-1233 Bus-Tech, Inc.
-1234 Technical Corp.
-1235 Risq Modular Systems, Inc.
-1236 Sigma Designs Corporation
- 0000 RealMagic64/GX
- 6401 REALmagic 64/GX (SD 6425)
-1237 Alta Technology Corporation
-1238 Adtran
-1239 3DO Company
-123a Visicom Laboratories, Inc.
-123b Seeq Technology, Inc.
-123c Century Systems, Inc.
-123d Engineering Design Team, Inc.
- 0000 EasyConnect 8/32
- 0002 EasyConnect 8/64
- 0003 EasyIO
-123e Simutech, Inc.
-123f C-Cube Microsystems
- 00e4 MPEG
- 8120 E4?
- 11bd 0006 DV500 E4
- 11bd 000a DV500 E4
- 11bd 000f DV500 E4
- 8888 Cinemaster C 3.0 DVD Decoder
- 1002 0001 Cinemaster C 3.0 DVD Decoder
- 1002 0002 Cinemaster C 3.0 DVD Decoder
- 1328 0001 Cinemaster C 3.0 DVD Decoder
-1240 Marathon Technologies Corp.
-1241 DSC Communications
-# Formerly Jaycor Networks, Inc.
-1242 JNI Corporation
- 1560 JNIC-1560 PCI-X Fibre Channel Controller
- 1242 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
- 1242 656a FCX-6562 PCI-X Fibre Channel Adapter
- 4643 FCI-1063 Fibre Channel Adapter
- 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
- 656a FCX-6562 PCI-X Fibre Channel Adapter
-1243 Delphax
-1244 AVM Audiovisuelles MKTG & Computer System GmbH
- 0700 B1 ISDN
- 0800 C4 ISDN
- 0a00 A1 ISDN [Fritz]
- 1244 0a00 FRITZ!Card ISDN Controller
- 0e00 Fritz!PCI v2.0 ISDN
- 1100 C2 ISDN
- 1200 T1 ISDN
- 2700 Fritz!Card DSL SL
- 2900 Fritz!Card DSL v2.0
-1245 A.P.D., S.A.
-1246 Dipix Technologies, Inc.
-1247 Xylon Research, Inc.
-1248 Central Data Corporation
-1249 Samsung Electronics Co., Ltd.
-124a AEG Electrocom GmbH
-124b SBS/Greenspring Modular I/O
- 0040 PCI-40A or cPCI-200 Quad IndustryPack carrier
- 124b 9080 PCI9080 Bridge
-124c Solitron Technologies, Inc.
-124d Stallion Technologies, Inc.
- 0000 EasyConnection 8/32
- 0002 EasyConnection 8/64
- 0003 EasyIO
- 0004 EasyConnection/RA
-124e Cylink
-124f Infortrend Technology, Inc.
- 0041 IFT-2000 Series RAID Controller
-1250 Hitachi Microcomputer System Ltd
-1251 VLSI Solutions Oy
-1253 Guzik Technical Enterprises
-1254 Linear Systems Ltd.
-1255 Optibase Ltd
- 1110 MPEG Forge
- 1210 MPEG Fusion
- 2110 VideoPlex
- 2120 VideoPlex CC
- 2130 VideoQuest
-1256 Perceptive Solutions, Inc.
- 4201 PCI-2220I
- 4401 PCI-2240I
- 5201 PCI-2000
-1257 Vertex Networks, Inc.
-1258 Gilbarco, Inc.
-1259 Allied Telesyn International
- 2560 AT-2560 Fast Ethernet Adapter (i82557B)
- a117 RTL81xx Fast Ethernet
- a120 21x4x DEC-Tulip compatible 10/100 Ethernet
-125a ABB Power Systems
-125b Asix Electronics Corporation
- 1400 ALFA GFC2204 Fast Ethernet
-125c Aurora Technologies, Inc.
- 0101 Saturn 4520P
- 0640 Aries 16000P
-125d ESS Technology
- 0000 ES336H Fax Modem (Early Model)
- 1948 Solo?
- 1968 ES1968 Maestro 2
- 1028 0085 ES1968 Maestro-2 PCI
- 1033 8051 ES1968 Maestro-2 Audiodrive
- 1969 ES1969 Solo-1 Audiodrive
- 1014 0166 ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
- 125d 8888 Solo-1 Audio Adapter
- 153b 111b Terratec 128i PCI
- 1978 ES1978 Maestro 2E
- 0e11 b112 Armada M700/E500
- 1033 803c ES1978 Maestro-2E Audiodrive
- 1033 8058 ES1978 Maestro-2E Audiodrive
- 1092 4000 Monster Sound MX400
- 1179 0001 ES1978 Maestro-2E Audiodrive
- 1988 ES1988 Allegro-1
- 1092 4100 Sonic Impact S100
- 125d 1988 ESS Allegro-1 Audiodrive
- 1989 ESS Modem
- 125d 1989 ESS Modem
- 1998 ES1983S Maestro-3i PCI Audio Accelerator
- 1028 00b1 Latitude C600
- 1028 00e6 ES1983S Maestro-3i (Dell Inspiron 8100)
- 1999 ES1983S Maestro-3i PCI Modem Accelerator
- 199a ES1983S Maestro-3i PCI Audio Accelerator
- 199b ES1983S Maestro-3i PCI Modem Accelerator
- 2808 ES336H Fax Modem (Later Model)
- 2838 ES2838/2839 SuperLink Modem
- 2898 ES2898 Modem
- 125d 0424 ES56-PI Data Fax Modem
- 125d 0425 ES56T-PI Data Fax Modem
- 125d 0426 ES56V-PI Data Fax Modem
- 125d 0427 VW-PI Data Fax Modem
- 125d 0428 ES56ST-PI Data Fax Modem
- 125d 0429 ES56SV-PI Data Fax Modem
- 147a c001 ES56-PI Data Fax Modem
- 14fe 0428 ES56-PI Data Fax Modem
- 14fe 0429 ES56-PI Data Fax Modem
-125e Specialvideo Engineering SRL
-125f Concurrent Technologies, Inc.
-1260 Intersil Corporation
- 3872 Prism 2.5 Wavelan chipset
- 1468 0202 LAN-Express IEEE 802.11b Wireless LAN
- 3873 Prism 2.5 Wavelan chipset
- 1186 3501 DWL-520 Wireless PCI Adapter
- 1186 3700 DWL-520 Wireless PCI Adapter, Rev E1
- 1385 4105 MA311 802.11b wireless adapter
- 1668 0414 HWP01170-01 802.11b PCI Wireless Adapter
- 16a5 1601 AIR.mate PC-400 PCI Wireless LAN Adapter
- 1737 3874 WMP11 Wireless 802.11b PCI Adapter
- 8086 2513 Wireless 802.11b MiniPCI Adapter
- 3886 ISL3886 [Prism Javelin/Prism Xbow]
- 17cf 0037 Z-Com XG-901 and clones Wireless Adapter
- 3890 Intersil ISL3890 [Prism GT/Prism Duette]
- 10b8 2802 SMC2802W Wireless PCI Adapter
- 10b8 2835 SMC2835W Wireless Cardbus Adapter
- 10b8 a835 SMC2835W V2 Wireless Cardbus Adapter
- 1113 ee03 SMC2802W V2 Wireless PCI Adapter
- 1113 ee08 SMC2835W V3 EU Wireless Cardbus Adapter
- 1186 3202 DWL-G650 A1 Wireless Adapter
- 1259 c104 CG-WLCB54GT Wireless Adapter
- 1385 4800 WG511 Wireless Adapter
- 16a5 1605 ALLNET ALL0271 Wireless PCI Adapter
- 17cf 0014 Z-Com XG-600 and clones Wireless Adapter
- 17cf 0020 Z-Com XG-900 and clones Wireless Adapter
- 8130 HMP8130 NTSC/PAL Video Decoder
- 8131 HMP8131 NTSC/PAL Video Decoder
-1261 Matsushita-Kotobuki Electronics Industries, Ltd.
-1262 ES Computer Company, Ltd.
-1263 Sonic Solutions
-1264 Aval Nagasaki Corporation
-1265 Casio Computer Co., Ltd.
-1266 Microdyne Corporation
- 0001 NE10/100 Adapter (i82557B)
- 1910 NE2000Plus (RT8029) Ethernet Adapter
- 1266 1910 NE2000Plus Ethernet Adapter
-1267 S. A. Telecommunications
- 5352 PCR2101
- 5a4b Telsat Turbo
-1268 Tektronix
-1269 Thomson-CSF/TTM
-126a Lexmark International, Inc.
-126b Adax, Inc.
-126c Northern Telecom
- 1211 10/100BaseTX [RTL81xx]
- 126c 802.11b Wireless Ethernet Adapter
-126d Splash Technology, Inc.
-126e Sumitomo Metal Industries, Ltd.
-126f Silicon Motion, Inc.
- 0501 SM501 VoyagerGX
- 0710 SM710 LynxEM
- 0712 SM712 LynxEM+
- 0720 SM720 Lynx3DM
- 0730 SM731 Cougar3DR
- 0810 SM810 LynxE
- 0811 SM811 LynxE
- 0820 SM820 Lynx3D
- 0910 SM910
-1270 Olympus Optical Co., Ltd.
-1271 GW Instruments
-1272 Telematics International
-1273 Hughes Network Systems
- 0002 DirecPC
-1274 Ensoniq
- 1171 ES1373 [AudioPCI] (also Creative Labs CT5803)
- 1371 ES1371 [AudioPCI-97]
- 0e11 0024 AudioPCI on Motherboard Compaq Deskpro
- 0e11 b1a7 ES1371, ES1373 AudioPCI
- 1033 80ac ES1371, ES1373 AudioPCI
- 1042 1854 Tazer
- 107b 8054 Tabor2
- 1274 1371 Creative Sound Blaster AudioPCI64V, AudioPCI128
- 1462 6470 ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
- 1462 6560 ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
- 1462 6630 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
- 1462 6631 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
- 1462 6632 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
- 1462 6633 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
- 1462 6820 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
- 1462 6822 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
- 1462 6830 ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
- 1462 6880 ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
- 1462 6900 ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
- 1462 6910 ES1371, ES1373 AudioPCI On Motherboard MS-6191
- 1462 6930 ES1371, ES1373 AudioPCI On Motherboard MS-6193
- 1462 6990 ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
- 1462 6991 ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
- 14a4 2077 ES1371, ES1373 AudioPCI On Motherboard KR639
- 14a4 2105 ES1371, ES1373 AudioPCI On Motherboard MR800
- 14a4 2107 ES1371, ES1373 AudioPCI On Motherboard MR801
- 14a4 2172 ES1371, ES1373 AudioPCI On Motherboard DR739
- 1509 9902 ES1371, ES1373 AudioPCI On Motherboard KW11
- 1509 9903 ES1371, ES1373 AudioPCI On Motherboard KW31
- 1509 9904 ES1371, ES1373 AudioPCI On Motherboard KA11
- 1509 9905 ES1371, ES1373 AudioPCI On Motherboard KC13
- 152d 8801 ES1371, ES1373 AudioPCI On Motherboard CP810E
- 152d 8802 ES1371, ES1373 AudioPCI On Motherboard CP810
- 152d 8803 ES1371, ES1373 AudioPCI On Motherboard P3810E
- 152d 8804 ES1371, ES1373 AudioPCI On Motherboard P3810-S
- 152d 8805 ES1371, ES1373 AudioPCI On Motherboard P3820-S
- 270f 2001 ES1371, ES1373 AudioPCI On Motherboard 6CTR
- 270f 2200 ES1371, ES1373 AudioPCI On Motherboard 6WTX
- 270f 3000 ES1371, ES1373 AudioPCI On Motherboard 6WSV
- 270f 3100 ES1371, ES1373 AudioPCI On Motherboard 6WIV2
- 270f 3102 ES1371, ES1373 AudioPCI On Motherboard 6WIV
- 270f 7060 ES1371, ES1373 AudioPCI On Motherboard 6ASA2
- 8086 4249 ES1371, ES1373 AudioPCI On Motherboard BI440ZX
- 8086 424c ES1371, ES1373 AudioPCI On Motherboard BL440ZX
- 8086 425a ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
- 8086 4341 ES1371, ES1373 AudioPCI On Motherboard Cayman
- 8086 4343 ES1371, ES1373 AudioPCI On Motherboard Cape Cod
- 8086 4649 ES1371, ES1373 AudioPCI On Motherboard Fire Island
- 8086 464a ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
- 8086 4d4f ES1371, ES1373 AudioPCI On Motherboard Montreal
- 8086 4f43 ES1371, ES1373 AudioPCI On Motherboard OC440LX
- 8086 5243 ES1371, ES1373 AudioPCI On Motherboard RC440BX
- 8086 5352 ES1371, ES1373 AudioPCI On Motherboard SunRiver
- 8086 5643 ES1371, ES1373 AudioPCI On Motherboard Vancouver
- 8086 5753 ES1371, ES1373 AudioPCI On Motherboard WS440BX
- 5000 ES1370 [AudioPCI]
- 5880 5880 AudioPCI
- 1274 2000 Creative Sound Blaster AudioPCI128
- 1274 2003 Creative SoundBlaster AudioPCI 128
- 1274 5880 Creative Sound Blaster AudioPCI128
- 1274 8001 Sound Blaster 16PCI 4.1ch
- 1458 a000 5880 AudioPCI On Motherboard 6OXET
- 1462 6880 5880 AudioPCI On Motherboard MS-6188 1.00
- 270f 2001 5880 AudioPCI On Motherboard 6CTR
- 270f 2200 5880 AudioPCI On Motherboard 6WTX
- 270f 7040 5880 AudioPCI On Motherboard 6ATA4
-1275 Network Appliance Corporation
-1276 Switched Network Technologies, Inc.
-1277 Comstream
-1278 Transtech Parallel Systems Ltd.
- 0701 TPE3/TM3 PowerPC Node
- 0710 TPE5 PowerPC PCI board
-1279 Transmeta Corporation
- 0295 Northbridge
- 0395 LongRun Northbridge
- 0396 SDRAM controller
- 0397 BIOS scratchpad
-127a Rockwell International
- 1002 HCF 56k Data/Fax Modem
- 1092 094c SupraExpress 56i PRO [Diamond SUP2380]
- 122d 4002 HPG / MDP3858-U
- 122d 4005 MDP3858-E
- 122d 4007 MDP3858-A/-NZ
- 122d 4012 MDP3858-SA
- 122d 4017 MDP3858-W
- 122d 4018 MDP3858-W
- 127a 1002 Rockwell 56K D/F HCF Modem
- 1003 HCF 56k Data/Fax Modem
- 0e11 b0bc 229-DF Zephyr
- 0e11 b114 229-DF Cheetah
- 1033 802b 229-DF
- 13df 1003 PCI56RX Modem
- 13e0 0117 IBM
- 13e0 0147 IBM F-1156IV+/R3 Spain V.90 Modem
- 13e0 0197 IBM
- 13e0 01c7 IBM F-1156IV+/R3 WW V.90 Modem
- 13e0 01f7 IBM
- 1436 1003 IBM
- 1436 1103 IBM 5614PM3G V.90 Modem
- 1436 1602 Compaq 229-DF Ducati
- 1004 HCF 56k Data/Fax/Voice Modem
- 1048 1500 MicroLink 56k Modem
- 10cf 1059 Fujitsu 229-DFRT
- 1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 1005 127a AOpen FM56-P
- 1033 8029 229-DFSV
- 1033 8054 Modem
- 10cf 103c Fujitsu
- 10cf 1055 Fujitsu 229-DFSV
- 10cf 1056 Fujitsu 229-DFSV
- 122d 4003 MDP3858SP-U
- 122d 4006 Packard Bell MDP3858V-E
- 122d 4008 MDP3858SP-A/SP-NZ
- 122d 4009 MDP3858SP-E
- 122d 4010 MDP3858V-U
- 122d 4011 MDP3858SP-SA
- 122d 4013 MDP3858V-A/V-NZ
- 122d 4015 MDP3858SP-W
- 122d 4016 MDP3858V-W
- 122d 4019 MDP3858V-SA
- 13df 1005 PCI56RVP Modem
- 13e0 0187 IBM
- 13e0 01a7 IBM
- 13e0 01b7 IBM DF-1156IV+/R3 Spain V.90 Modem
- 13e0 01d7 IBM DF-1156IV+/R3 WW V.90 Modem
- 1436 1005 IBM
- 1436 1105 IBM
- 1437 1105 IBM 5614PS3G V.90 Modem
- 1022 HCF 56k Modem
- 1436 1303 M3-5614PM3G V.90 Modem
- 1023 HCF 56k Data/Fax Modem
- 122d 4020 Packard Bell MDP3858-WE
- 122d 4023 MDP3858-UE
- 13e0 0247 IBM F-1156IV+/R6 Spain V.90 Modem
- 13e0 0297 IBM
- 13e0 02c7 IBM F-1156IV+/R6 WW V.90 Modem
- 1436 1203 IBM
- 1436 1303 IBM
- 1024 HCF 56k Data/Fax/Voice Modem
- 1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 10cf 106a Fujitsu 235-DFSV
- 122d 4021 Packard Bell MDP3858V-WE
- 122d 4022 MDP3858SP-WE
- 122d 4024 MDP3858V-UE
- 122d 4025 MDP3858SP-UE
- 1026 HCF 56k PCI Speakerphone Modem
- 1032 HCF 56k Modem
- 1033 HCF 56k Modem
- 1034 HCF 56k Modem
- 1035 HCF 56k PCI Speakerphone Modem
- 1036 HCF 56k Modem
- 1085 HCF 56k Volcano PCI Modem
- 2005 HCF 56k Data/Fax Modem
- 104d 8044 229-DFSV
- 104d 8045 229-DFSV
- 104d 8055 PBE/Aztech 235W-DFSV
- 104d 8056 235-DFSV
- 104d 805a Modem
- 104d 805f Modem
- 104d 8074 Modem
- 2013 HSF 56k Data/Fax Modem
- 1179 0001 Modem
- 1179 ff00 Modem
- 2014 HSF 56k Data/Fax/Voice Modem
- 10cf 1057 Fujitsu Citicorp III
- 122d 4050 MSP3880-U
- 122d 4055 MSP3880-W
- 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 10cf 1063 Fujitsu
- 10cf 1064 Fujitsu
- 1468 2015 Fujitsu
- 2016 HSF 56k Data/Fax/Voice/Spkp Modem
- 122d 4051 MSP3880V-W
- 122d 4052 MSP3880SP-W
- 122d 4054 MSP3880V-U
- 122d 4056 MSP3880SP-U
- 122d 4057 MSP3880SP-A
- 4311 Riptide HSF 56k PCI Modem
- 127a 4311 Ring Modular? Riptide HSF RT HP Dom
- 13e0 0210 HP-GVC
- 4320 Riptide PCI Audio Controller
- 1235 4320 Riptide PCI Audio Controller
- 4321 Riptide HCF 56k PCI Modem
- 1235 4321 Hewlett Packard DF
- 1235 4324 Hewlett Packard DF
- 13e0 0210 Hewlett Packard DF
- 144d 2321 Riptide
- 4322 Riptide PCI Game Controller
- 1235 4322 Riptide PCI Game Controller
- 8234 RapidFire 616X ATM155 Adapter
- 108d 0022 RapidFire 616X ATM155 Adapter
- 108d 0027 RapidFire 616X ATM155 Adapter
-127b Pixera Corporation
-127c Crosspoint Solutions, Inc.
-127d Vela Research
-127e Winnov, L.P.
-127f Fujifilm
-1280 Photoscript Group Ltd.
-1281 Yokogawa Electric Corporation
-1282 Davicom Semiconductor, Inc.
- 9009 Ethernet 100/10 MBit
- 9100 21x4x DEC-Tulip compatible 10/100 Ethernet
- 9102 21x4x DEC-Tulip compatible 10/100 Ethernet
- 9132 Ethernet 100/10 MBit
-1283 Integrated Technology Express, Inc.
- 673a IT8330G
- 8212 IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212)
- 1283 0001 IT/ITE8212 Dual channel ATA RAID controller
- 8330 IT8330G
- 8872 IT8874F PCI Dual Serial Port Controller
- 8888 IT8888F PCI to ISA Bridge with SMB
- 8889 IT8889F PCI to ISA Bridge
- e886 IT8330G
-1284 Sahara Networks, Inc.
-1285 Platform Technologies, Inc.
- 0100 AGOGO sound chip (aka ESS Maestro 1)
-1286 Mazet GmbH
-1287 M-Pact, Inc.
- 001e LS220D DVD Decoder
- 001f LS220C DVD Decoder
-1288 Timestep Corporation
-1289 AVC Technology, Inc.
-128a Asante Technologies, Inc.
-128b Transwitch Corporation
-128c Retix Corporation
-128d G2 Networks, Inc.
- 0021 ATM155 Adapter
-128e Hoontech Corporation/Samho Multi Tech Ltd.
- 0008 ST128 WSS/SB
- 0009 ST128 SAM9407
- 000a ST128 Game Port
- 000b ST128 MPU Port
- 000c ST128 Ctrl Port
-128f Tateno Dennou, Inc.
-1290 Sord Computer Corporation
-1291 NCS Computer Italia
-1292 Tritech Microelectronics Inc
-1293 Media Reality Technology
-1294 Rhetorex, Inc.
-1295 Imagenation Corporation
-1296 Kofax Image Products
-1297 Holco Enterprise Co, Ltd/Shuttle Computer
-1298 Spellcaster Telecommunications Inc.
-1299 Knowledge Technology Lab.
-129a VMetro, inc.
- 0615 PBT-615 PCI-X Bus Analyzer
-129b Image Access
-129c Jaycor
-129d Compcore Multimedia, Inc.
-129e Victor Company of Japan, Ltd.
-129f OEC Medical Systems, Inc.
-12a0 Allen-Bradley Company
-12a1 Simpact Associates, Inc.
-12a2 Newgen Systems Corporation
-12a3 Lucent Technologies
- 8105 T8105 H100 Digital Switch
-12a4 NTT Electronics Technology Company
-12a5 Vision Dynamics Ltd.
-12a6 Scalable Networks, Inc.
-12a7 AMO GmbH
-12a8 News Datacom
-12a9 Xiotech Corporation
-12aa SDL Communications, Inc.
-12ab Yuan Yuan Enterprise Co., Ltd.
- 0002 AU8830 [Vortex2] Based Sound Card With A3D Support
- 3000 MPG-200C PCI DVD Decoder Card
-12ac Measurex Corporation
-12ad Multidata GmbH
-12ae Alteon Networks Inc.
- 0001 AceNIC Gigabit Ethernet
- 1014 0104 Gigabit Ethernet-SX PCI Adapter
- 12ae 0001 Gigabit Ethernet-SX (Universal)
- 1410 0104 Gigabit Ethernet-SX PCI Adapter
- 0002 AceNIC Gigabit Ethernet (Copper)
- 10a9 8002 Acenic Gigabit Ethernet
- 12ae 0002 Gigabit Ethernet-T (3C986-T)
- 00fa Farallon PN9100-T Gigabit Ethernet
-12af TDK USA Corp
-12b0 Jorge Scientific Corp
-12b1 GammaLink
-12b2 General Signal Networks
-12b3 Inter-Face Co Ltd
-12b4 FutureTel Inc
-12b5 Granite Systems Inc.
-12b6 Natural Microsystems
-12b7 Cognex Modular Vision Systems Div. - Acumen Inc.
-12b8 Korg
-12b9 3Com Corp, Modem Division (formerly US Robotics)
- 1006 WinModem
- 12b9 005c USR 56k Internal Voice WinModem (Model 3472)
- 12b9 005e USR 56k Internal WinModem (Models 662975)
- 12b9 0062 USR 56k Internal Voice WinModem (Model 662978)
- 12b9 0068 USR 56k Internal Voice WinModem (Model 5690)
- 12b9 007a USR 56k Internal Voice WinModem (Model 662974)
- 12b9 007f USR 56k Internal WinModem (Models 5698, 5699)
- 12b9 0080 USR 56k Internal WinModem (Models 2975, 3528)
- 12b9 0081 USR 56k Internal Voice WinModem (Models 2974, 3529)
- 12b9 0091 USR 56k Internal Voice WinModem (Model 2978)
- 1007 USR 56k Internal WinModem
- 12b9 00a3 USR 56k Internal WinModem (Model 3595)
- 1008 56K FaxModem Model 5610
- 12b9 00a2 USR 56k Internal FAX Modem (Model 2977)
- 12b9 00aa USR 56k Internal Voice Modem (Model 2976)
- 12b9 00ab USR 56k Internal Voice Modem (Model 5609)
- 12b9 00ac USR 56k Internal Voice Modem (Model 3298)
- 12b9 00ad USR 56k Internal FAX Modem (Model 5610)
-12ba BittWare, Inc.
-12bb Nippon Unisoft Corporation
-12bc Array Microsystems
-12bd Computerm Corp.
-12be Anchor Chips Inc.
- 3041 AN3041Q CO-MEM
- 3042 AN3042Q CO-MEM Lite
- 12be 3042 Anchor Chips Lite Evaluation Board
-12bf Fujifilm Microdevices
-12c0 Infimed
-12c1 GMM Research Corp
-12c2 Mentec Limited
-12c3 Holtek Microelectronics Inc
- 0058 PCI NE2K Ethernet
- 5598 PCI NE2K Ethernet
-12c4 Connect Tech Inc
- 0001 Blue HEAT/PCI 8 (RS232/CL/RJ11)
- 0002 Blue HEAT/PCI 4 (RS232)
- 0003 Blue HEAT/PCI 2 (RS232)
- 0004 Blue HEAT/PCI 8 (UNIV, RS485)
- 0005 Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
- 0006 Blue HEAT/PCI 4 (OPTO, RS485)
- 0007 Blue HEAT/PCI 2+2 (RS232/485)
- 0008 Blue HEAT/PCI 2 (OPTO, Tx, RS485)
- 0009 Blue HEAT/PCI 2+6 (RS232/485)
- 000a Blue HEAT/PCI 8 (Tx, RS485)
- 000b Blue HEAT/PCI 4 (Tx, RS485)
- 000c Blue HEAT/PCI 2 (20 MHz, RS485)
- 000d Blue HEAT/PCI 2 PTM
- 0100 NT960/PCI
- 0201 cPCI Titan - 2 Port
- 0202 cPCI Titan - 4 Port
- 0300 CTI PCI UART 2 (RS232)
- 0301 CTI PCI UART 4 (RS232)
- 0302 CTI PCI UART 8 (RS232)
- 0310 CTI PCI UART 1+1 (RS232/485)
- 0311 CTI PCI UART 2+2 (RS232/485)
- 0312 CTI PCI UART 4+4 (RS232/485)
- 0320 CTI PCI UART 2
- 0321 CTI PCI UART 4
- 0322 CTI PCI UART 8
- 0330 CTI PCI UART 2 (RS485)
- 0331 CTI PCI UART 4 (RS485)
- 0332 CTI PCI UART 8 (RS485)
-12c5 Picture Elements Incorporated
- 007e Imaging/Scanning Subsystem Engine
- 007f Imaging/Scanning Subsystem Engine
- 0081 PCIVST [Grayscale Thresholding Engine]
- 0085 Video Simulator/Sender
- 0086 THR2 Multi-scale Thresholder
-12c6 Mitani Corporation
-12c7 Dialogic Corp
-12c8 G Force Co, Ltd
-12c9 Gigi Operations
-12ca Integrated Computing Engines
-12cb Antex Electronics Corporation
-12cc Pluto Technologies International
-12cd Aims Lab
-12ce Netspeed Inc.
-12cf Prophet Systems, Inc.
-12d0 GDE Systems, Inc.
-12d1 PSITech
-12d2 NVidia / SGS Thomson (Joint Venture)
- 0008 NV1
- 0009 DAC64
- 0018 Riva128
- 1048 0c10 VICTORY Erazor
- 107b 8030 STB Velocity 128
- 1092 0350 Viper V330
- 1092 1092 Viper V330
- 10b4 1b1b STB Velocity 128
- 10b4 1b1d STB Velocity 128
- 10b4 1b1e STB Velocity 128, PAL TV-Out
- 10b4 1b20 STB Velocity 128 Sapphire
- 10b4 1b21 STB Velocity 128
- 10b4 1b22 STB Velocity 128 AGP, NTSC TV-Out
- 10b4 1b23 STB Velocity 128 AGP, PAL TV-Out
- 10b4 1b27 STB Velocity 128 DVD
- 10b4 1b88 MVP Pro 128
- 10b4 222a STB Velocity 128 AGP
- 10b4 2230 STB Velocity 128
- 10b4 2232 STB Velocity 128
- 10b4 2235 STB Velocity 128 AGP
- 2a15 54a3 3DVision-SAGP / 3DexPlorer 3000
- 0019 Riva128ZX
- 0020 TNT
- 0028 TNT2
- 0029 UTNT2
- 002c VTNT2
- 00a0 ITNT2
-12d3 Vingmed Sound A/S
-12d4 Ulticom (Formerly DGM&S)
- 0200 T1 Card
-12d5 Equator Technologies Inc
- 0003 BSP16
- 1000 BSP15
-12d6 Analogic Corp
-12d7 Biotronic SRL
-12d8 Pericom Semiconductor
-12d9 Aculab PLC
- 0002 PCI Prosody
- 0004 cPCI Prosody
- 0005 Aculab E1/T1 PCI card
-12da True Time Inc.
-12db Annapolis Micro Systems, Inc
-12dc Symicron Computer Communication Ltd.
-12dd Management Graphics
-12de Rainbow Technologies
- 0200 CryptoSwift CS200
-12df SBS Technologies Inc
-12e0 Chase Research
- 0010 ST16C654 Quad UART
- 0020 ST16C654 Quad UART
- 0030 ST16C654 Quad UART
-12e1 Nintendo Co, Ltd
-12e2 Datum Inc. Bancomm-Timing Division
-12e3 Imation Corp - Medical Imaging Systems
-12e4 Brooktrout Technology Inc
-12e5 Apex Semiconductor Inc
-12e6 Cirel Systems
-12e7 Sunsgroup Corporation
-12e8 Crisc Corp
-12e9 GE Spacenet
-12ea Zuken
-12eb Aureal Semiconductor
- 0001 Vortex 1
- 104d 8036 AU8820 Vortex Digital Audio Processor
- 1092 2000 Sonic Impact A3D
- 1092 2100 Sonic Impact A3D
- 1092 2110 Sonic Impact A3D
- 1092 2200 Sonic Impact A3D
- 122d 1002 AU8820 Vortex Digital Audio Processor
- 12eb 0001 AU8820 Vortex Digital Audio Processor
- 5053 3355 Montego
- 0002 Vortex 2
- 104d 8049 AU8830 Vortex 3D Digital Audio Processor
- 104d 807b AU8830 Vortex 3D Digital Audio Processor
- 1092 3000 Monster Sound II
- 1092 3001 Monster Sound II
- 1092 3002 Monster Sound II
- 1092 3003 Monster Sound II
- 1092 3004 Monster Sound II
- 12eb 0001 AU8830 Vortex 3D Digital Audio Processor
- 12eb 0002 AU8830 Vortex 3D Digital Audio Processor
- 12eb 0088 AU8830 Vortex 3D Digital Audio Processor
- 144d 3510 AU8830 Vortex 3D Digital Audio Processor
- 5053 3356 Montego II
- 0003 AU8810 Vortex Digital Audio Processor
- 104d 8049 AU8810 Vortex Digital Audio Processor
- 104d 8077 AU8810 Vortex Digital Audio Processor
- 109f 1000 AU8810 Vortex Digital Audio Processor
- 12eb 0003 AU8810 Vortex Digital Audio Processor
- 1462 6780 AU8810 Vortex Digital Audio Processor
- 14a4 2073 AU8810 Vortex Digital Audio Processor
- 14a4 2091 AU8810 Vortex Digital Audio Processor
- 14a4 2104 AU8810 Vortex Digital Audio Processor
- 14a4 2106 AU8810 Vortex Digital Audio Processor
- 8803 Vortex 56k Software Modem
- 12eb 8803 Vortex 56k Software Modem
-12ec 3A International, Inc.
-12ed Optivision Inc.
-12ee Orange Micro
-12ef Vienna Systems
-12f0 Pentek
-12f1 Sorenson Vision Inc
-12f2 Gammagraphx, Inc.
-12f3 Radstone Technology
-12f4 Megatel
-12f5 Forks
-12f6 Dawson France
-12f7 Cognex
-12f8 Electronic Design GmbH
- 0002 VideoMaker
-12f9 Four Fold Ltd
-12fb Spectrum Signal Processing
-12fc Capital Equipment Corp
-12fd I2S
-12fe ESD Electronic System Design GmbH
-12ff Lexicon
-1300 Harman International Industries Inc
-1302 Computer Sciences Corp
-1303 Innovative Integration
-1304 Juniper Networks
-1305 Netphone, Inc
-1306 Duet Technologies
-# Formerly ComputerBoards
-1307 Measurement Computing
- 0001 PCI-DAS1602/16
- 000b PCI-DIO48H
- 000c PCI-PDISO8
- 000d PCI-PDISO16
- 000f PCI-DAS1200
- 0010 PCI-DAS1602/12
- 0014 PCI-DIO24H
- 0015 PCI-DIO24H/CTR3
- 0016 PCI-DIO48H/CTR15
- 0017 PCI-DIO96H
- 0018 PCI-CTR05
- 0019 PCI-DAS1200/JR
- 001a PCI-DAS1001
- 001b PCI-DAS1002
- 001c PCI-DAS1602JR/16
- 001d PCI-DAS6402/16
- 001e PCI-DAS6402/12
- 001f PCI-DAS16/M1
- 0020 PCI-DDA02/12
- 0021 PCI-DDA04/12
- 0022 PCI-DDA08/12
- 0023 PCI-DDA02/16
- 0024 PCI-DDA04/16
- 0025 PCI-DDA08/16
- 0026 PCI-DAC04/12-HS
- 0027 PCI-DAC04/16-HS
- 0028 PCI-DIO24
- 0029 PCI-DAS08
- 002c PCI-INT32
- 0033 PCI-DUAL-AC5
- 0034 PCI-DAS-TC
- 0035 PCI-DAS64/M1/16
- 0036 PCI-DAS64/M2/16
- 0037 PCI-DAS64/M3/16
- 004c PCI-DAS1000
- 004d PCI-QUAD04
- 0052 PCI-DAS4020/12
- 005e PCI-DAS6025
-1308 Jato Technologies Inc.
- 0001 NetCelerator Adapter
- 1308 0001 NetCelerator Adapter
-1309 AB Semiconductor Ltd
-130a Mitsubishi Electric Microcomputer
-130b Colorgraphic Communications Corp
-130c Ambex Technologies, Inc
-130d Accelerix Inc
-130e Yamatake-Honeywell Co. Ltd
-130f Advanet Inc
-1310 Gespac
-1311 Videoserver, Inc
-1312 Acuity Imaging, Inc
-1313 Yaskawa Electric Co.
-1316 Teradyne Inc
-1317 Linksys
- 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
- 0985 NC100 Network Everywhere Fast Ethernet 10/100
- 1985 21x4x DEC-Tulip compatible 10/100 Ethernet
- 2850 HSP MicroModem 56
- 8201 ADMtek ADM8211 802.11b Wireless Interface
- 10b8 2635 SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card
- 1317 8201 SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card
- 8211 ADMtek ADM8211 802.11b Wireless Interface
- 9511 21x4x DEC-Tulip compatible 10/100 Ethernet
-1318 Packet Engines Inc.
- 0911 GNIC-II PCI Gigabit Ethernet [Hamachi]
-1319 Fortemedia, Inc
- 0801 Xwave QS3000A [FM801]
- 0802 Xwave QS3000A [FM801 game port]
- 1000 FM801 PCI Audio
- 1001 FM801 PCI Joystick
-131a Finisar Corp.
-131c Nippon Electro-Sensory Devices Corp
-131d Sysmic, Inc.
-131e Xinex Networks Inc
-131f Siig Inc
- 1000 CyberSerial (1-port) 16550
- 1001 CyberSerial (1-port) 16650
- 1002 CyberSerial (1-port) 16850
- 1010 Duet 1S(16550)+1P
- 1011 Duet 1S(16650)+1P
- 1012 Duet 1S(16850)+1P
- 1020 CyberParallel (1-port)
- 1021 CyberParallel (2-port)
- 1030 CyberSerial (2-port) 16550
- 1031 CyberSerial (2-port) 16650
- 1032 CyberSerial (2-port) 16850
- 1034 Trio 2S(16550)+1P
- 1035 Trio 2S(16650)+1P
- 1036 Trio 2S(16850)+1P
- 1050 CyberSerial (4-port) 16550
- 1051 CyberSerial (4-port) 16650
- 1052 CyberSerial (4-port) 16850
- 2000 CyberSerial (1-port) 16550
- 2001 CyberSerial (1-port) 16650
- 2002 CyberSerial (1-port) 16850
- 2010 Duet 1S(16550)+1P
- 2011 Duet 1S(16650)+1P
- 2012 Duet 1S(16850)+1P
- 2020 CyberParallel (1-port)
- 2021 CyberParallel (2-port)
- 2030 CyberSerial (2-port) 16550
- 131f 2030 PCI Serial Card
- 2031 CyberSerial (2-port) 16650
- 2032 CyberSerial (2-port) 16850
- 2040 Trio 1S(16550)+2P
- 2041 Trio 1S(16650)+2P
- 2042 Trio 1S(16850)+2P
- 2050 CyberSerial (4-port) 16550
- 2051 CyberSerial (4-port) 16650
- 2052 CyberSerial (4-port) 16850
- 2060 Trio 2S(16550)+1P
- 2061 Trio 2S(16650)+1P
- 2062 Trio 2S(16850)+1P
- 2081 CyberSerial (8-port) ST16654
-1320 Crypto AG
-1321 Arcobel Graphics BV
-1322 MTT Co., Ltd
-1323 Dome Inc
-1324 Sphere Communications
-1325 Salix Technologies, Inc
-1326 Seachange international
-1327 Voss scientific
-1328 quadrant international
-1329 Productivity Enhancement
-132a Microcom Inc.
-132b Broadband Technologies
-132c Micrel Inc
-132d Integrated Silicon Solution, Inc.
-1330 MMC Networks
-1331 Radisys Corp.
- 0030 ENP-2611
- 8200 82600 Host Bridge
- 8201 82600 IDE
- 8202 82600 USB
- 8210 82600 PCI Bridge
-1332 Micro Memory
- 5415 MM-5415CN PCI Memory Module with Battery Backup
- 5425 MM-5425CN PCI 64/66 Memory Module with Battery Backup
-1334 Redcreek Communications, Inc
-1335 Videomail, Inc
-1337 Third Planet Publishing
-1338 BT Electronics
-133a Vtel Corp
-133b Softcom Microsystems
-133c Holontech Corp
-133d SS Technologies
-133e Virtual Computer Corp
-133f SCM Microsystems
-1340 Atalla Corp
-1341 Kyoto Microcomputer Co
-1342 Promax Systems Inc
-1343 Phylon Communications Inc
-1344 Crucial Technology
-1345 Arescom Inc
-1347 Odetics
-1349 Sumitomo Electric Industries, Ltd.
-134a DTC Technology Corp.
- 0001 Domex 536
- 0002 Domex DMX3194UP SCSI Adapter
-134b ARK Research Corp.
-134c Chori Joho System Co. Ltd
-134d PCTel Inc
- 2189 HSP56 MicroModem
- 2486 2304WT V.92 MDC Modem
- 7890 HSP MicroModem 56
- 134d 0001 PCT789 adapter
- 7891 HSP MicroModem 56
- 134d 0001 HSP MicroModem 56
- 7892 HSP MicroModem 56
- 7893 HSP MicroModem 56
- 7894 HSP MicroModem 56
- 7895 HSP MicroModem 56
- 7896 HSP MicroModem 56
- 7897 HSP MicroModem 56
-134e CSTI
-134f Algo System Co Ltd
-1350 Systec Co. Ltd
-1351 Sonix Inc
-1353 Thales Idatys
- 0002 Proserver
- 0003 PCI-FUT
- 0004 PCI-S0
- 0005 PCI-FUT-S0
-1354 Dwave System Inc
-1355 Kratos Analytical Ltd
-1356 The Logical Co
-1359 Prisa Networks
-135a Brain Boxes
-135b Giganet Inc
-135c Quatech Inc
- 0010 QSC-100
- 0020 DSC-100
- 0030 DSC-200/300
- 0040 QSC-200/300
- 0050 ESC-100D
- 0060 ESC-100M
- 00f0 MPAC-100 Syncronous Serial Card (Zilog 85230)
- 0170 QSCLP-100
- 0180 DSCLP-100
- 0190 SSCLP-100
- 01a0 QSCLP-200/300
- 01b0 DSCLP-200/300
- 01c0 SSCLP-200/300
-135d ABB Network Partner AB
-135e Sealevel Systems Inc
- 5101 Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
- 7101 Single Port RS-232/422/485/530
- 7201 Dual Port RS-232/422/485 Interface
- 7202 Dual Port RS-232 Interface
- 7401 Four Port RS-232 Interface
- 7402 Four Port RS-422/485 Interface
- 7801 Eight Port RS-232 Interface
- 7804 Eight Port RS-232/422/485 Interface
- 8001 8001 Digital I/O Adapter
-135f I-Data International A-S
-1360 Meinberg Funkuhren
- 0101 PCI32 DCF77 Radio Clock
- 0102 PCI509 DCF77 Radio Clock
- 0103 PCI510 DCF77 Radio Clock
- 0201 GPS167PCI GPS Receiver
- 0202 GPS168PCI GPS Receiver
- 0203 GPS169PCI GPS Receiver
- 0301 TCR510PCI IRIG Receiver
-1361 Soliton Systems K.K.
-1362 Fujifacom Corporation
-1363 Phoenix Technology Ltd
-1364 ATM Communications Inc
-1365 Hypercope GmbH
-1366 Teijin Seiki Co. Ltd
-1367 Hitachi Zosen Corporation
-1368 Skyware Corporation
-1369 Digigram
-136a High Soft Tech
-136b Kawasaki Steel Corporation
- ff01 KL5A72002 Motion JPEG
-136c Adtek System Science Co Ltd
-136d Gigalabs Inc
-136f Applied Magic Inc
-1370 ATL Products
-1371 CNet Technology Inc
- 434e GigaCard Network Adapter
- 1371 434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-1373 Silicon Vision Inc
-1374 Silicom Ltd
-1375 Argosystems Inc
-1376 LMC
-1377 Electronic Equipment Production & Distribution GmbH
-1378 Telemann Co. Ltd
-1379 Asahi Kasei Microsystems Co Ltd
-137a Mark of the Unicorn Inc
- 0001 PCI-324 Audiowire Interface
-137b PPT Vision
-137c Iwatsu Electric Co Ltd
-137d Dynachip Corporation
-137e Patriot Scientific Corporation
-137f Japan Satellite Systems Inc
-1380 Sanritz Automation Co Ltd
-1381 Brains Co. Ltd
-1382 Marian - Electronic & Software
- 0001 ARC88 audio recording card
- 2008 Prodif 96 Pro sound system
- 2088 Marc 8 Midi sound system
- 20c8 Marc A sound system
- 4008 Marc 2 sound system
- 4010 Marc 2 Pro sound system
- 4048 Marc 4 MIDI sound system
- 4088 Marc 4 Digi sound system
- 4248 Marc X sound system
-1383 Controlnet Inc
-1384 Reality Simulation Systems Inc
-1385 Netgear
-# Note: This lists as Atheros Communications, Inc. AR5212 802.11abg NIC because of Madwifi
- 0013 WG311T
- 311a GA511 Gigabit Ethernet
- 4100 802.11b Wireless Adapter (MA301)
- 4105 MA311 802.11b wireless adapter
- 4400 WAG511 802.11a/b/g Dual Band Wireless PC Card
- 4600 WAG511 802.11a/b/g Dual Band Wireless PC Card
- 4601 WAG511 802.11a/b/g Dual Band Wireless PC Card
- 4610 WAG511 802.11a/b/g Dual Band Wireless PC Card
- 4a00 WAG311 802.11a/g Wireless PCI Adapter
- 4c00 WG311v2 54 Mbps Wireless PCI Adapter
- 620a GA620 Gigabit Ethernet
- 622a GA622
- 630a GA630 Gigabit Ethernet
- f004 FA310TX
-1386 Video Domain Technologies
-1387 Systran Corp
-1388 Hitachi Information Technology Co Ltd
-1389 Applicom International
- 0001 PCI1500PFB [Intelligent fieldbus adaptor]
-138a Fusion Micromedia Corp
-138b Tokimec Inc
-138c Silicon Reality
-138d Future Techno Designs pte Ltd
-138e Basler GmbH
-138f Patapsco Designs Inc
-1390 Concept Development Inc
-1391 Development Concepts Inc
-1392 Medialight Inc
-1393 Moxa Technologies Co Ltd
- 1040 Smartio C104H/PCI
- 1141 Industrio CP-114
- 1680 Smartio C168H/PCI
- 2040 Intellio CP-204J
- 2180 Intellio C218 Turbo PCI
- 3200 Intellio C320 Turbo PCI
-1394 Level One Communications
- 0001 LXT1001 Gigabit Ethernet
- 1394 0001 NetCelerator Adapter
-1395 Ambicom Inc
-1396 Cipher Systems Inc
-1397 Cologne Chip Designs GmbH
- 2bd0 ISDN network controller [HFC-PCI]
- 1397 2bd0 ISDN Board
- e4bf 1000 CI1-1-Harp
-1398 Clarion co. Ltd
-1399 Rios systems Co Ltd
-139a Alacritech Inc
- 0001 Quad Port 10/100 Server Accelerator
- 0003 Single Port 10/100 Server Accelerator
- 0005 Single Port Gigabit Server Accelerator
-139b Mediasonic Multimedia Systems Ltd
-139c Quantum 3d Inc
-139d EPL limited
-139e Media4
-139f Aethra s.r.l.
-13a0 Crystal Group Inc
-13a1 Kawasaki Heavy Industries Ltd
-13a2 Ositech Communications Inc
-13a3 Hifn Inc.
- 0005 7751 Security Processor
- 0006 6500 Public Key Processor
- 0007 7811 Security Processor
- 0012 7951 Security Processor
- 0014 78XX Security Processor
- 0016 8065 Security Processor
- 0017 8165 Security Processor
- 0018 8154 Security Processor
- 001d 7956 Security Processor
- 0020 7955 Security Processor
-13a4 Rascom Inc
-13a5 Audio Digital Imaging Inc
-13a6 Videonics Inc
-13a7 Teles AG
-13a8 Exar Corp.
- 0154 XR17C154 Quad UART
- 0158 XR17C158 Octal UART
-13a9 Siemens Medical Systems, Ultrasound Group
-13aa Broadband Networks Inc
-13ab Arcom Control Systems Ltd
-13ac Motion Media Technology Ltd
-13ad Nexus Inc
-13ae ALD Technology Ltd
-13af T.Sqware
-13b0 Maxspeed Corp
-13b1 Tamura corporation
-13b2 Techno Chips Co. Ltd
-13b3 Lanart Corporation
-13b4 Wellbean Co Inc
-13b5 ARM
-13b6 Dlog GmbH
-13b7 Logic Devices Inc
-13b8 Nokia Telecommunications oy
-13b9 Elecom Co Ltd
-13ba Oxford Instruments
-13bb Sanyo Technosound Co Ltd
-13bc Bitran Corporation
-13bd Sharp corporation
-13be Miroku Jyoho Service Co. Ltd
-13bf Sharewave Inc
-13c0 Microgate Corporation
- 0010 SyncLink Adapter v1
- 0020 SyncLink SCC Adapter
- 0030 SyncLink Multiport Adapter
- 0210 SyncLink Adapter v2
-13c1 3ware Inc
- 1000 3ware Inc 3ware 5xxx/6xxx-series PATA-RAID
- 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
- 13c1 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
- 1002 3ware Inc 3ware 9xxx-series SATA-RAID
-13c2 Technotrend Systemtechnik GmbH
-13c3 Janz Computer AG
-13c4 Phase Metrics
-13c5 Alphi Technology Corp
-13c6 Condor Engineering Inc
- 0520 CEI-520 A429 Card
- 0620 CEI-620 A429 Card
- 0820 CEI-820 A429 Card
-13c7 Blue Chip Technology Ltd
-13c8 Apptech Inc
-13c9 Eaton Corporation
-13ca Iomega Corporation
-13cb Yano Electric Co Ltd
-13cc Metheus Corporation
-13cd Compatible Systems Corporation
-13ce Cocom A/S
-13cf Studio Audio & Video Ltd
-13d0 Techsan Electronics Co Ltd
- 2103 B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
- 2200 B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
-13d1 Abocom Systems Inc
- ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
- ab03 21x4x DEC-Tulip compatible 10/100 Ethernet
- ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
- ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
-13d2 Shark Multimedia Inc
-13d3 IMC Networks
-13d4 Graphics Microsystems Inc
-13d5 Media 100 Inc
-13d6 K.I. Technology Co Ltd
-13d7 Toshiba Engineering Corporation
-13d8 Phobos corporation
-13d9 Apex PC Solutions Inc
-13da Intresource Systems pte Ltd
-13db Janich & Klass Computertechnik GmbH
-13dc Netboost Corporation
-13dd Multimedia Bundle Inc
-13de ABB Robotics Products AB
-13df E-Tech Inc
- 0001 PCI56RVP Modem
- 13df 0001 PCI56RVP Modem
-13e0 GVC Corporation
-13e1 Silicom Multimedia Systems Inc
-13e2 Dynamics Research Corporation
-13e3 Nest Inc
-13e4 Calculex Inc
-13e5 Telesoft Design Ltd
-13e6 Argosy research Inc
-13e7 NAC Incorporated
-13e8 Chip Express Corporation
-13e9 Intraserver Technology Inc
-13ea Dallas Semiconductor
-13eb Hauppauge Computer Works Inc
-13ec Zydacron Inc
-13ed Raytheion E-Systems
-13ee Hayes Microcomputer Products Inc
-13ef Coppercom Inc
-13f0 Sundance Technology Inc
- 0201 ST201 Sundance Ethernet
-13f1 Oce' - Technologies B.V.
-13f2 Ford Microelectronics Inc
-13f3 Mcdata Corporation
-13f4 Troika Networks, Inc.
- 1401 Zentai Fibre Channel Adapter
-13f5 Kansai Electric Co. Ltd
-13f6 C-Media Electronics Inc
- 0011 CMI8738
- 0100 CM8338A
- 13f6 ffff CMI8338/C3DX PCI Audio Device
- 0101 CM8338B
- 13f6 0101 CMI8338-031 PCI Audio Device
- 0111 CM8738
- 1019 0970 P6STP-FL motherboard
- 1043 8035 CUSI-FX motherboard
- 1043 8077 CMI8738 6-channel audio controller
- 1043 80e2 CMI8738 6ch-MX
- 13f6 0111 CMI8738/C3DX PCI Audio Device
- 1681 a000 Gamesurround MUSE XL
- 0211 CM8738
-13f7 Wildfire Communications
-13f8 Ad Lib Multimedia Inc
-13f9 NTT Advanced Technology Corp.
-13fa Pentland Systems Ltd
-13fb Aydin Corp
-13fc Computer Peripherals International
-13fd Micro Science Inc
-13fe Advantech Co. Ltd
- 1240 PCI-1240 4-channel stepper motor controller card w. Nova Electronics MCX314
- 1600 PCI-1612 4-port RS-232/422/485 PCI Communication Card
- 1752 PCI-1752
- 1754 PCI-1754
- 1756 PCI-1756
-13ff Silicon Spice Inc
-1400 Artx Inc
- 1401 9432 TX
-1401 CR-Systems A/S
-1402 Meilhaus Electronic GmbH
-1403 Ascor Inc
-1404 Fundamental Software Inc
-1405 Excalibur Systems Inc
-1406 Oce' Printing Systems GmbH
-1407 Lava Computer mfg Inc
- 0100 Lava Dual Serial
- 0101 Lava Quatro A
- 0102 Lava Quatro B
- 0110 Lava DSerial-PCI Port A
- 0111 Lava DSerial-PCI Port B
- 0120 Quattro-PCI A
- 0121 Quattro-PCI B
- 0180 Lava Octo A
- 0181 Lava Octo B
- 0200 Lava Port Plus
- 0201 Lava Quad A
- 0202 Lava Quad B
- 0220 Lava Quattro PCI Ports A/B
- 0221 Lava Quattro PCI Ports C/D
- 0500 Lava Single Serial
- 0600 Lava Port 650
- 8000 Lava Parallel
- 8001 Dual parallel port controller A
- 8002 Lava Dual Parallel port A
- 8003 Lava Dual Parallel port B
- 8800 BOCA Research IOPPAR
-1408 Aloka Co. Ltd
-1409 Timedia Technology Co Ltd
- 7168 PCI2S550 (Dual 16550 UART)
-140a DSP Research Inc
-140b Ramix Inc
-140c Elmic Systems Inc
-140d Matsushita Electric Works Ltd
-140e Goepel Electronic GmbH
-140f Salient Systems Corp
-1410 Midas lab Inc
-1411 Ikos Systems Inc
-# formerly IC Ensemble Inc.
-1412 VIA Technologies Inc.
- 1712 ICE1712 [Envy24] PCI Multi-Channel I/O Controller
- 1412 1712 Hoontech ST Audio DSP 24
- 1412 d630 M-Audio Delta 1010
- 1412 d631 M-Audio Delta DiO
- 1412 d632 M-Audio Delta 66
- 1412 d633 M-Audio Delta 44
- 1412 d634 M-Audio Delta Audiophile
- 1412 d635 M-Audio Delta TDIF
- 1412 d637 M-Audio Delta RBUS
- 1412 d638 M-Audio Delta 410
- 1412 d63b M-Audio Delta 1010LT
- 1412 d63c Digigram VX442
- 1416 1712 Hoontech ST Audio DSP 24 Media 7.1
- 153b 1115 EWS88 MT
- 153b 1125 EWS88 MT (Master)
- 153b 112b EWS88 D
- 153b 112c EWS88 D (Master)
- 153b 1130 EWX 24/96
- 153b 1138 DMX 6fire 24/96
- 153b 1151 PHASE88
- 16ce 1040 Edirol DA-2496
- 1724 VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
- 1412 1724 AMP Ltd AUDIO2000
- 1412 3630 M-Audio Revolution 7.1
- 153b 1145 Aureon 7.1 Space
- 153b 1147 Aureon 5.1 Sky
- 153b 1153 Aureon 7.1 Universe
- 270f f641 ZNF3-150
- 270f f645 ZNF3-250
-1413 Addonics
-1414 Microsoft Corporation
-1415 Oxford Semiconductor Ltd
- 8403 VScom 011H-EP1 1 port parallel adaptor
- 9501 OX16PCI954 (Quad 16950 UART) function 0
- 131f 2050 CyberPro (4-port)
-# Model IO1085, Part No: JJ-P46012
- 131f 2051 CyberSerial 4S Plus
- 15ed 2000 MCCR Serial p0-3 of 8
- 15ed 2001 MCCR Serial p0-3 of 16
- 950a EXSYS EX-41092 Dual 16950 Serial adapter
- 950b OXCB950 Cardbus 16950 UART
- 9510 OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
- 9511 OX16PCI954 (Quad 16950 UART) function 1
- 15ed 2000 MCCR Serial p4-7 of 8
- 15ed 2001 MCCR Serial p4-15 of 16
- 9521 OX16PCI952 (Dual 16950 UART)
-1416 Multiwave Innovation pte Ltd
-1417 Convergenet Technologies Inc
-1418 Kyushu electronics systems Inc
-1419 Excel Switching Corp
-141a Apache Micro Peripherals Inc
-141b Zoom Telephonics Inc
-141d Digitan Systems Inc
-141e Fanuc Ltd
-141f Visiontech Ltd
-1420 Psion Dacom plc
- 8002 Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
- 8003 Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
-1421 Ads Technologies Inc
-1422 Ygrec Systems Co Ltd
-1423 Custom Technology Corp.
-1424 Videoserver Connections
-1425 Chelsio Communications Inc
-1426 Storage Technology Corp.
-1427 Better On-Line Solutions
-1428 Edec Co Ltd
-1429 Unex Technology Corp.
-142a Kingmax Technology Inc
-142b Radiolan
-142c Minton Optic Industry Co Ltd
-142d Pix stream Inc
-142e Vitec Multimedia
- 4020 VM2-2 [Video Maker 2] MPEG1/2 Encoder
-142f Radicom Research Inc
-1430 ITT Aerospace/Communications Division
-1431 Gilat Satellite Networks
-1432 Edimax Computer Co.
- 9130 RTL81xx Fast Ethernet
-1433 Eltec Elektronik GmbH
-1435 Real Time Devices US Inc.
-1436 CIS Technology Inc
-1437 Nissin Inc Co
-1438 Atmel-dream
-1439 Outsource Engineering & Mfg. Inc
-143a Stargate Solutions Inc
-143b Canon Research Center, America
-143c Amlogic Inc
-143d Tamarack Microelectronics Inc
-143e Jones Futurex Inc
-143f Lightwell Co Ltd - Zax Division
-1440 ALGOL Corp.
-1441 AGIE Ltd
-1442 Phoenix Contact GmbH & Co.
-1443 Unibrain S.A.
-1444 TRW
-1445 Logical DO Ltd
-1446 Graphin Co Ltd
-1447 AIM GmBH
-1448 Alesis Studio Electronics
-1449 TUT Systems Inc
-144a Adlink Technology
- 7296 PCI-7296
- 7432 PCI-7432
- 7433 PCI-7433
- 7434 PCI-7434
- 7841 PCI-7841
- 8133 PCI-8133
- 8164 PCI-8164
- 8554 PCI-8554
- 9111 PCI-9111
- 9113 PCI-9113
- 9114 PCI-9114
-144b Loronix Information Systems Inc
-144c Catalina Research Inc
-144d Samsung Electronics Co Ltd
-144e OLITEC
-144f Askey Computer Corp.
-1450 Octave Communications Ind.
-1451 SP3D Chip Design GmBH
-1453 MYCOM Inc
-1454 Altiga Networks
-1455 Logic Plus Plus Inc
-1456 Advanced Hardware Architectures
-1457 Nuera Communications Inc
-1458 Giga-byte Technology
- 0c11 K8NS Pro Mainboard
-1459 DOOIN Electronics
-145a Escalate Networks Inc
-145b PRAIM SRL
-145c Cryptek
-145d Gallant Computer Inc
-145e Aashima Technology B.V.
-145f Baldor Electric Company
- 0001 NextMove PCI
-1460 DYNARC INC
-1461 Avermedia Technologies Inc
-1462 Micro-Star International Co., Ltd.
-# MSI CB54G Wireless PC Card that seems to use the Broadcom 4306 Chipset
- 6819 Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
- 6825 PCI Card wireless 11g [PC54G]
- 8725 NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
-# MSI G4Ti4800, 128MB DDR SDRAM, TV-Out, DVI-I
- 9000 NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
- 9110 GeFORCE FX5200
- 9119 NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
- 9591 nVidia Corporation NV36 [GeForce FX 5700LE]
-1463 Fast Corporation
-1464 Interactive Circuits & Systems Ltd
-1465 GN NETTEST Telecom DIV.
-1466 Designpro Inc.
-1467 DIGICOM SPA
-1468 AMBIT Microsystem Corp.
-1469 Cleveland Motion Controls
-146a IFR
-146b Parascan Technologies Ltd
-146c Ruby Tech Corp.
- 1430 FE-1430TX Fast Ethernet PCI Adapter
-146d Tachyon, INC.
-146e Williams Electronics Games, Inc.
-146f Multi Dimensional Consulting Inc
-1470 Bay Networks
-1471 Integrated Telecom Express Inc
-1472 DAIKIN Industries, Ltd
-1473 ZAPEX Technologies Inc
-1474 Doug Carson & Associates
-1475 PICAZO Communications
-1476 MORTARA Instrument Inc
-1477 Net Insight
-1478 DIATREND Corporation
-1479 TORAY Industries Inc
-147a FORMOSA Industrial Computing
-147b ABIT Computer Corp.
-147c AWARE, Inc.
-147d Interworks Computer Products
-147e Matsushita Graphic Communication Systems, Inc.
-147f NIHON UNISYS, Ltd.
-1480 SCII Telecom
-1481 BIOPAC Systems Inc
-1482 ISYTEC - Integrierte Systemtechnik GmBH
-1483 LABWAY Corporation
-1484 Logic Corporation
-1485 ERMA - Electronic GmBH
-1486 L3 Communications Telemetry & Instrumentation
-1487 MARQUETTE Medical Systems
-1488 KONTRON Electronik GmBH
-1489 KYE Systems Corporation
-148a OPTO
-148b INNOMEDIALOGIC Inc.
-148c C.P. Technology Co. Ltd
-148d DIGICOM Systems, Inc.
- 1003 HCF 56k Data/Fax Modem
-148e OSI Plus Corporation
-148f Plant Equipment, Inc.
-1490 Stone Microsystems PTY Ltd.
-1491 ZEAL Corporation
-1492 Time Logic Corporation
-1493 MAKER Communications
-1494 WINTOP Technology, Inc.
-1495 TOKAI Communications Industry Co. Ltd
-1496 JOYTECH Computer Co., Ltd.
-1497 SMA Regelsysteme GmBH
-1498 TEWS Datentechnik GmBH
- 30c8 TPCI200
-1499 EMTEC CO., Ltd
-149a ANDOR Technology Ltd
-149b SEIKO Instruments Inc
-149c OVISLINK Corp.
-149d NEWTEK Inc
- 0001 Video Toaster for PC
-149e Mapletree Networks Inc.
-149f LECTRON Co Ltd
-14a0 SOFTING GmBH
-14a1 Systembase Co Ltd
-14a2 Millennium Engineering Inc
-14a3 Maverick Networks
-14a4 GVC/BCM Advanced Research
-14a5 XIONICS Document Technologies Inc
-14a6 INOVA Computers GmBH & Co KG
-14a7 MYTHOS Systems Inc
-14a8 FEATRON Technologies Corporation
-14a9 HIVERTEC Inc
-14aa Advanced MOS Technology Inc
-14ab Mentor Graphics Corp.
-14ac Novaweb Technologies Inc
-14ad Time Space Radio AB
-14ae CTI, Inc
-14af Guillemot Corporation
- 7102 3D Prophet II MX
-14b0 BST Communication Technology Ltd
-14b1 Nextcom K.K.
-14b2 ENNOVATE Networks Inc
-14b3 XPEED Inc
- 0000 DSL NIC
-14b4 PHILIPS Business Electronics B.V.
-14b5 Creamware GmBH
- 0200 Scope
- 0300 Pulsar
- 0400 PulsarSRB
- 0600 Pulsar2
- 0800 DSP-Board
- 0900 DSP-Board
- 0a00 DSP-Board
- 0b00 DSP-Board
-14b6 Quantum Data Corp.
-14b7 PROXIM Inc
- 0001 Symphony 4110
-14b8 Techsoft Technology Co Ltd
-14b9 AIRONET Wireless Communications
- 0001 PC4800
- 0340 PC4800
- 0350 PC4800
- 4500 PC4500
- 4800 Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
- a504 Cisco Aironet Wireless 802.11b
- a505 Cisco Aironet CB20a 802.11a Wireless LAN Adapter
- a506 Cisco Aironet Mini PCI b/g
-14ba INTERNIX Inc.
-14bb SEMTECH Corporation
-14bc Globespan Semiconductor Inc.
-14bd CARDIO Control N.V.
-14be L3 Communications
-14bf SPIDER Communications Inc.
-14c0 COMPAL Electronics Inc
-14c1 MYRICOM Inc.
- 8043 Myrinet 2000 Scalable Cluster Interconnect
-14c2 DTK Computer
-14c3 MEDIATEK Corp.
-14c4 IWASAKI Information Systems Co Ltd
-14c5 Automation Products AB
-14c6 Data Race Inc
-14c7 Modular Technology Holdings Ltd
-14c8 Turbocomm Tech. Inc.
-14c9 ODIN Telesystems Inc
-14ca PE Logic Corp.
-14cb Billionton Systems Inc
-14cc NAKAYO Telecommunications Inc
-14cd Universal Scientific Ind.
-14ce Whistle Communications
-14cf TEK Microsystems Inc.
-14d0 Ericsson Axe R & D
-14d1 Computer Hi-Tech Co Ltd
-14d2 Titan Electronics Inc
- 8001 VScom 010L 1 port parallel adaptor
- 8002 VScom 020L 2 port parallel adaptor
- 8010 VScom 100L 1 port serial adaptor
- 8011 VScom 110L 1 port serial and 1 port parallel adaptor
- 8020 VScom 200L 1 port serial adaptor
- 8021 VScom 210L 2 port serial and 1 port parallel adaptor
- 8040 VScom 400L 4 port serial adaptor
- 8080 VScom 800L 8 port serial adaptor
- a000 VScom 010H 1 port parallel adaptor
- a001 VScom 100H 1 port serial adaptor
- a003 VScom 400H 4 port serial adaptor
- a004 VScom 400HF1 4 port serial adaptor
- a005 VScom 200H 2 port serial adaptor
- e001 VScom 010HV2 1 port parallel adaptor
- e010 VScom 100HV2 1 port serial adaptor
- e020 VScom 200HV2 2 port serial adaptor
-14d3 CIRTECH (UK) Ltd
-14d4 Panacom Technology Corp
-14d5 Nitsuko Corporation
-14d6 Accusys Inc
-14d7 Hirakawa Hewtech Corp
-14d8 HOPF Elektronik GmBH
-# Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
-14d9 Alliance Semiconductor Corporation
- 0010 AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
- 9000 AS90L10204/10208 HyperTransport to PCI-X Bridge
-14da National Aerospace Laboratories
-14db AFAVLAB Technology Inc
- 2120 TK9902
-14dc Amplicon Liveline Ltd
- 0000 PCI230
- 0001 PCI242
- 0002 PCI244
- 0003 PCI247
- 0004 PCI248
- 0005 PCI249
- 0006 PCI260
- 0007 PCI224
- 0008 PCI234
- 0009 PCI236
- 000a PCI272
- 000b PCI215
-14dd Boulder Design Labs Inc
-14de Applied Integration Corporation
-14df ASIC Communications Corp
-14e1 INVERTEX
-14e2 INFOLIBRIA
-14e3 AMTELCO
-14e4 Broadcom Corporation
- 0800 Sentry5 Chipcommon I/O Controller
- 0804 Sentry5 PCI Bridge
- 0805 Sentry5 MIPS32 CPU
- 0806 Sentry5 Ethernet Controller
- 080b Sentry5 Crypto Accelerator
- 080f Sentry5 DDR/SDR RAM Controller
- 0811 Sentry5 External Interface Core
- 0816 BCM3302 Sentry5 MIPS32 CPU
- 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express
- 1644 NetXtreme BCM5700 Gigabit Ethernet
- 1014 0277 Broadcom Vigil B5700 1000Base-T
- 1028 00d1 Broadcom BCM5700
- 1028 0106 Broadcom BCM5700
- 1028 0109 Broadcom BCM5700 1000Base-T
- 1028 010a Broadcom BCM5700 1000BaseTX
- 10b7 1000 3C996-T 1000Base-T
- 10b7 1001 3C996B-T 1000Base-T
- 10b7 1002 3C996C-T 1000Base-T
- 10b7 1003 3C997-T 1000Base-T Dual Port
- 10b7 1004 3C996-SX 1000Base-SX
- 10b7 1005 3C997-SX 1000Base-SX Dual Port
- 10b7 1008 3C942 Gigabit LOM (31X31)
- 14e4 0002 NetXtreme 1000Base-SX
- 14e4 0003 NetXtreme 1000Base-SX
- 14e4 0004 NetXtreme 1000Base-T
- 14e4 1028 NetXtreme 1000BaseTX
- 14e4 1644 BCM5700 1000Base-T
- 1645 NetXtreme BCM5701 Gigabit Ethernet
- 0e11 007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
- 0e11 007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
- 0e11 0085 NC7780 Gigabit Server Adapter (embedded, WOL)
- 0e11 0099 NC7780 Gigabit Server Adapter (embedded, WOL)
- 0e11 009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
- 0e11 00c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
- 1028 0121 Broadcom BCM5701 1000Base-T
- 103c 128a HP 1000Base-T (PCI) [A7061A]
- 103c 128b HP 1000Base-SX (PCI) [A7073A]
- 103c 12a4 HP Core Lan 1000Base-T
- 103c 12c1 HP IOX Core Lan 1000Base-T [A7109AX]
- 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
- 10a9 8011 SGI Gigabit Ethernet (Copper)
- 10a9 8012 SGI Gigabit Ethernet (Fiber)
- 10b7 1004 3C996-SX 1000Base-SX
- 10b7 1006 3C996B-T 1000Base-T
- 10b7 1007 3C1000-T 1000Base-T
- 10b7 1008 3C940-BR01 1000Base-T
- 14e4 0001 BCM5701 1000Base-T
- 14e4 0005 BCM5701 1000Base-T
- 14e4 0006 BCM5701 1000Base-T
- 14e4 0007 BCM5701 1000Base-SX
- 14e4 0008 BCM5701 1000Base-T
- 14e4 8008 BCM5701 1000Base-T
- 1646 NetXtreme BCM5702 Gigabit Ethernet
- 0e11 00bb NC7760 1000BaseTX
- 1028 0126 Broadcom BCM5702 1000BaseTX
- 14e4 8009 BCM5702 1000BaseTX
- 1647 NetXtreme BCM5703 Gigabit Ethernet
- 0e11 0099 NC7780 1000BaseTX
- 0e11 009a NC7770 1000BaseTX
- 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
- 14e4 0009 BCM5703 1000BaseTX
- 14e4 000a BCM5703 1000BaseSX
- 14e4 000b BCM5703 1000BaseTX
- 14e4 8009 BCM5703 1000BaseTX
- 14e4 800a BCM5703 1000BaseTX
- 1648 NetXtreme BCM5704 Gigabit Ethernet
- 0e11 00cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 0e11 00d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 0e11 00d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X
- 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X
- 1166 1648 NetXtreme CIOB-E 1000Base-T
- 164a NetXtreme II BCM5706 Gigabit Ethernet
- 164d NetXtreme BCM5702FE Gigabit Ethernet
- 1653 NetXtreme BCM5705 Gigabit Ethernet
- 0e11 00e3 NC7761 Gigabit Server Adapter
- 1654 NetXtreme BCM5705_2 Gigabit Ethernet
- 0e11 00e3 NC7761 Gigabit Server Adapter
- 103c 3100 NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
- 1659 NetXtreme BCM5721 Gigabit Ethernet PCI Express
- 165d NetXtreme BCM5705M Gigabit Ethernet
- 165e NetXtreme BCM5705M_2 Gigabit Ethernet
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 166e 570x 10/100 Integrated Controller
- 1677 NetXtreme BCM5751 Gigabit Ethernet PCI Express
- 1028 0179 Optiplex GX280
- 167d NetXtreme BCM5751M Gigabit Ethernet PCI Express
- 167e NetXtreme BCM5751F Fast Ethernet PCI Express
- 1696 NetXtreme BCM5782 Gigabit Ethernet
- 103c 12bc HP d530 CMT (DG746A)
- 14e4 000d NetXtreme BCM5782 1000Base-T
- 169c NetXtreme BCM5788 Gigabit Ethernet
- 169d NetLink BCM5789 Gigabit Ethernet PCI Express
- 16a6 NetXtreme BCM5702X Gigabit Ethernet
- 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
- 1028 0126 BCM5702 1000Base-T
- 14e4 000c BCM5702 1000Base-T
- 14e4 8009 BCM5702 1000Base-T
- 16a7 NetXtreme BCM5703X Gigabit Ethernet
- 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 14e4 0009 NetXtreme BCM5703 1000Base-T
- 14e4 000a NetXtreme BCM5703 1000Base-SX
- 14e4 000b NetXtreme BCM5703 1000Base-T
- 14e4 800a NetXtreme BCM5703 1000Base-T
- 16a8 NetXtreme BCM5704S Gigabit Ethernet
- 10b7 2001 3C998-SX Dual Port 1000-SX PCI-X
- 16aa NetXtreme II BCM5706S Gigabit Ethernet
- 16c6 NetXtreme BCM5702A3 Gigabit Ethernet
- 10b7 1100 3C1000B-T 10/100/1000 PCI
- 14e4 000c BCM5702 1000Base-T
- 14e4 8009 BCM5702 1000Base-T
- 16c7 NetXtreme BCM5703 Gigabit Ethernet
- 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
- 103c 12c3 HP Combo FC/GigE-SX [A9782A]
- 103c 12ca HP Combo FC/GigE-T [A9784A]
- 14e4 0009 NetXtreme BCM5703 1000Base-T
- 14e4 000a NetXtreme BCM5703 1000Base-SX
- 16dd NetLink BCM5781 Gigabit Ethernet PCI Express
- 16f7 NetXtreme BCM5753 Gigabit Ethernet PCI Express
- 16fd NetXtreme BCM5753M Gigabit Ethernet PCI Express
- 16fe NetXtreme BCM5753F Fast Ethernet PCI Express
- 170c BCM4401-B0 100Base-TX
- 170d NetXtreme BCM5901 100Base-TX
- 1014 0545 ThinkPad R40e (2684-HVG) builtin ethernet controller
- 170e NetXtreme BCM5901 100Base-TX
- 3352 BCM3352
- 3360 BCM3360
- 4210 BCM4210 iLine10 HomePNA 2.0
- 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
- 4212 BCM4212 v.90 56k modem
- 4301 BCM4303 802.11b Wireless LAN Controller
- 1028 0407 TrueMobile 1180 Onboard WLAN
- 1043 0120 WL-103b Wireless LAN PC Card
- 4305 BCM4307 V.90 56k Modem
- 4306 BCM4307 Ethernet Controller
- 4307 BCM4307 802.11b Wireless LAN Controller
- 4310 BCM4310 Chipcommon I/OController
- 4312 BCM4310 UART
- 4313 BCM4310 Ethernet Controller
- 4315 BCM4310 USB Controller
- 4320 BCM4306 802.11b/g Wireless LAN Controller
- 1028 0001 TrueMobile 1300 WLAN Mini-PCI Card
- 1028 0003 Wireless 1350 WLAN Mini-PCI Card
- 1043 100f WL-100G
- 14e4 4320 Linksys WMP54G PCI
- 1737 4320 WPC54G
- 1799 7010 Belkin F5D7010 54g Wireless Network card
- 4321 BCM4306 802.11a Wireless LAN Controller
- 4322 BCM4306 UART
- 4324 BCM4309 802.11a/b/g
- 1028 0001 Truemobile 1400
- 1028 0003 Truemobile 1450 MiniPCI
- 4325 BCM43xG 802.11b/g
- 1414 0003 Wireless Notebook Adapter MN-720
- 1414 0004 Wireless PCI Adapter MN-730
-# probably this is a correct ID...
- 4326 BCM4307 Chipcommon I/O Controller?
- 4401 BCM4401 100Base-T
- 1043 80a8 A7V8X motherboard
- 4402 BCM4402 Integrated 10/100BaseT
- 4403 BCM4402 V.90 56k Modem
- 4410 BCM4413 iLine32 HomePNA 2.0
- 4411 BCM4413 V.90 56k modem
- 4412 BCM4412 10/100BaseT
- 4430 BCM44xx CardBus iLine32 HomePNA 2.0
- 4432 BCM4432 CardBus 10/100BaseT
- 4610 BCM4610 Sentry5 PCI to SB Bridge
- 4611 BCM4610 Sentry5 iLine32 HomePNA 1.0
- 4612 BCM4610 Sentry5 V.90 56k Modem
- 4613 BCM4610 Sentry5 Ethernet Controller
- 4614 BCM4610 Sentry5 External Interface
- 4615 BCM4610 Sentry5 USB Controller
- 4704 BCM4704 PCI to SB Bridge
- 4705 BCM4704 Sentry5 802.11b Wireless LAN Controller
- 4706 BCM4704 Sentry5 Ethernet Controller
- 4707 BCM4704 Sentry5 USB Controller
- 4708 BCM4704 Crypto Accelerator
- 4710 BCM4710 Sentry5 PCI to SB Bridge
- 4711 BCM47xx Sentry5 iLine32 HomePNA 2.0
- 4712 BCM47xx V.92 56k modem
- 4713 Sentry5 Ethernet Controller
- 4714 BCM47xx Sentry5 External Interface
- 4715 Sentry5 USB Controller
- 4716 BCM47xx Sentry5 USB Host Controller
- 4717 BCM47xx Sentry5 USB Device Controller
- 4718 Sentry5 Crypto Accelerator
- 4720 BCM4712 MIPS CPU
- 5365 BCM5365P Sentry5 Host Bridge
- 5600 BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
- 5605 BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
- 5615 BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
- 5625 BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
- 5645 BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
- 5670 BCM5670 8-Port 10GE Ethernet Switch Fabric
- 5680 BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
- 5690 BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
- 5691 BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
- 5820 BCM5820 Crypto Accelerator
- 5821 BCM5821 Crypto Accelerator
- 5822 BCM5822 Crypto Accelerator
- 5823 BCM5823 Crypto Accelerator
- 5824 BCM5824 Crypto Accelerator
- 5840 BCM5840 Crypto Accelerator
- 5841 BCM5841 Crypto Accelerator
- 5850 BCM5850 Crypto Accelerator
-14e5 Pixelfusion Ltd
-14e6 SHINING Technology Inc
-14e7 3CX
-14e8 RAYCER Inc
-14e9 GARNETS System CO Ltd
-14ea Planex Communications, Inc
- ab06 FNW-3603-TX CardBus Fast Ethernet
- ab07 RTL81xx RealTek Ethernet
-14eb SEIKO EPSON Corp
-14ec ACQIRIS
-14ed DATAKINETICS Ltd
-14ee MASPRO KENKOH Corp
-14ef CARRY Computer ENG. CO Ltd
-14f0 CANON RESEACH CENTRE FRANCE
-14f1 Conexant
- 1002 HCF 56k Modem
- 1003 HCF 56k Modem
- 1004 HCF 56k Modem
- 1005 HCF 56k Modem
- 1006 HCF 56k Modem
- 1022 HCF 56k Modem
- 1023 HCF 56k Modem
- 1024 HCF 56k Modem
- 1025 HCF 56k Modem
- 1026 HCF 56k Modem
- 1032 HCF 56k Modem
- 1033 HCF 56k Data/Fax Modem
- 1033 8077 NEC
- 122d 4027 Dell Zeus - MDP3880-W(B) Data Fax Modem
- 122d 4030 Dell Mercury - MDP3880-U(B) Data Fax Modem
- 122d 4034 Dell Thor - MDP3880-W(U) Data Fax Modem
- 13e0 020d Dell Copper
- 13e0 020e Dell Silver
- 13e0 0261 IBM
- 13e0 0290 Compaq Goldwing
- 13e0 02a0 IBM
- 13e0 02b0 IBM
- 13e0 02c0 Compaq Scooter
- 13e0 02d0 IBM
- 144f 1500 IBM P85-DF (1)
- 144f 1501 IBM P85-DF (2)
- 144f 150a IBM P85-DF (3)
- 144f 150b IBM P85-DF Low Profile (1)
- 144f 1510 IBM P85-DF Low Profile (2)
- 1034 HCF 56k Data/Fax/Voice Modem
- 1035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 10cf 1098 Fujitsu P85-DFSV
- 1036 HCF 56k Data/Fax/Voice/Spkp Modem
- 104d 8067 HCF 56k Modem
- 122d 4029 MDP3880SP-W
- 122d 4031 MDP3880SP-U
- 13e0 0209 Dell Titanium
- 13e0 020a Dell Graphite
- 13e0 0260 Gateway Red Owl
- 13e0 0270 Gateway White Horse
- 1052 HCF 56k Data/Fax Modem (Worldwide)
- 1053 HCF 56k Data/Fax Modem (Worldwide)
- 1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
- 1055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
- 1056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
- 1057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
- 1059 HCF 56k Data/Fax/Voice Modem (Worldwide)
- 1063 HCF 56k Data/Fax Modem
- 1064 HCF 56k Data/Fax/Voice Modem
- 1065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 1066 HCF 56k Data/Fax/Voice/Spkp Modem
- 122d 4033 Dell Athena - MDP3900V-U
- 1433 HCF 56k Data/Fax Modem
- 1434 HCF 56k Data/Fax/Voice Modem
- 1435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 1436 HCF 56k Data/Fax Modem
- 1453 HCF 56k Data/Fax Modem
- 13e0 0240 IBM
- 13e0 0250 IBM
- 144f 1502 IBM P95-DF (1)
- 144f 1503 IBM P95-DF (2)
- 1454 HCF 56k Data/Fax/Voice Modem
- 1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 1456 HCF 56k Data/Fax/Voice/Spkp Modem
- 122d 4035 Dell Europa - MDP3900V-W
- 122d 4302 Dell MP3930V-W(C) MiniPCI
- 1610 ADSL AccessRunner PCI Arbitration Device
- 1611 AccessRunner PCI ADSL Interface Device
- 1620 ADSL AccessRunner V2 PCI Arbitration Device
- 1621 AccessRunner V2 PCI ADSL Interface Device
- 1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter
- 1803 HCF 56k Modem
- 0e11 0023 623-LAN Grizzly
- 0e11 0043 623-LAN Yogi
- 1815 HCF 56k Modem
- 0e11 0022 Grizzly
- 0e11 0042 Yogi
- 2003 HSF 56k Data/Fax Modem
- 2004 HSF 56k Data/Fax/Voice Modem
- 2005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 2006 HSF 56k Data/Fax/Voice/Spkp Modem
- 2013 HSF 56k Data/Fax Modem
- 0e11 b195 Bear
- 0e11 b196 Seminole 1
- 0e11 b1be Seminole 2
- 1025 8013 Acer
- 1033 809d NEC
- 1033 80bc NEC
- 155d 6793 HP
- 155d 8850 E Machines
- 2014 HSF 56k Data/Fax/Voice Modem
- 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
- 2016 HSF 56k Data/Fax/Voice/Spkp Modem
- 2043 HSF 56k Data/Fax Modem (WorldW SmartDAA)
- 2044 HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
- 2045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
- 2046 HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
- 2063 HSF 56k Data/Fax Modem (SmartDAA)
- 2064 HSF 56k Data/Fax/Voice Modem (SmartDAA)
- 2065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
- 2066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
- 2093 HSF 56k Modem
- 155d 2f07 Legend
- 2143 HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
- 2144 HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
- 2145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
- 2146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
- 2163 HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
- 2164 HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
- 2165 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
- 2166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
- 2343 HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
- 2344 HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
- 2345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
- 2346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
- 2363 HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
- 2364 HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
- 2365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
- 2366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
- 2443 HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
- 104d 8075 Modem
- 104d 8083 Modem
- 104d 8097 Modem
- 2444 HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
- 2445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
- 2446 HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
- 2463 HSF 56k Data/Fax Modem (Mob SmartDAA)
- 2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
- 2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
- 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
- 2f00 HSF 56k HSFi Modem
- 13e0 8d84 IBM HSFi V.90
- 13e0 8d85 Compaq Stinger
- 14f1 2004 Dynalink 56PMi
- 2f02 HSF 56k HSFi Data/Fax
- 2f11 HSF 56k HSFi Modem
- 8234 RS8234 ATM SAR Controller [ServiceSAR Plus]
- 8800 CX22702 DVB-T 2k/8k
- 17de 08a1 XPert DVB-T PCI BDA DVBT 23880 Video Capture
- 8802 CX23883 Broadcast Decoder
- 17de 08a1 Xpert DVB-T PCI 2388x Transport Stream Capture
-14f2 MOBILITY Electronics
- 0120 EV1000 bridge
- 0121 EV1000 Parallel port
- 0122 EV1000 Serial port
- 0123 EV1000 Keyboard controller
- 0124 EV1000 Mouse controller
-14f3 BroadLogic
- 2030 2030 DVB-S Satellite Reciever
- 2050 2050 DVB-T Terrestrial (Cable) Reciever
- 2060 2060 ATSC Terrestrial (Cable) Reciever
-14f4 TOKYO Electronic Industry CO Ltd
-14f5 SOPAC Ltd
-14f6 COYOTE Technologies LLC
-14f7 WOLF Technology Inc
-14f8 AUDIOCODES Inc
- 2077 TP-240 dual span E1 VoIP PCI card
-14f9 AG COMMUNICATIONS
-14fa WANDEL & GOCHERMANN
-14fb TRANSAS MARINE (UK) Ltd
-14fc Quadrics Ltd
- 0000 QsNet Elan3 Network Adapter
- 0001 QsNetII Elan4 Network Adapter
-14fd JAPAN Computer Industry Inc
-14fe ARCHTEK TELECOM Corp
-14ff TWINHEAD INTERNATIONAL Corp
-1500 DELTA Electronics, Inc
- 1360 RTL81xx RealTek Ethernet
-1501 BANKSOFT CANADA Ltd
-1502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
-1503 KAWASAKI LSI USA Inc
-1504 KAISER Electronics
-1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
-1506 CHAMELEON Systems Inc
-# Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057).
-1507 Motorola ?? / HTEC
- 0001 MPC105 [Eagle]
- 0002 MPC106 [Grackle]
- 0003 MPC8240 [Kahlua]
- 0100 MC145575 [HFC-PCI]
- 0431 KTI829c 100VG
- 4801 Raven
- 4802 Falcon
- 4803 Hawk
- 4806 CPX8216
-1508 HONDA CONNECTORS/MHOTRONICS Inc
-1509 FIRST INTERNATIONAL Computer Inc
-150a FORVUS RESEARCH Inc
-150b YAMASHITA Systems Corp
-150c KYOPAL CO Ltd
-150d WARPSPPED Inc
-150e C-PORT Corp
-150f INTEC GmbH
-1510 BEHAVIOR TECH Computer Corp
-1511 CENTILLIUM Technology Corp
-1512 ROSUN Technologies Inc
-1513 Raychem
-1514 TFL LAN Inc
-1515 Advent design
-1516 MYSON Technology Inc
- 0800 MTD-8xx 100/10M Ethernet PCI Adapter
- 0803 SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
- 1320 10bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
- 0891 MTD-8xx 100/10M Ethernet PCI Adapter
-1517 ECHOTEK Corp
-1518 PEP MODULAR Computers GmbH
-1519 TELEFON AKTIEBOLAGET LM Ericsson
-151a Globetek
- 1002 PCI-1002
- 1004 PCI-1004
- 1008 PCI-1008
-151b COMBOX Ltd
-151c DIGITAL AUDIO LABS Inc
- 0003 Prodif T 2496
- 4000 Prodif 88
-151d Fujitsu Computer Products Of America
-151e MATRIX Corp
-151f TOPIC SEMICONDUCTOR Corp
- 0000 TP560 Data/Fax/Voice 56k modem
-1520 CHAPLET System Inc
-1521 BELL Corp
-1522 MainPine Ltd
- 0100 PCI <-> IOBus Bridge
- 1522 0200 RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
- 1522 0300 RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
- 1522 0400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
- 1522 0500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
- 1522 0600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem
- 1522 0700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem
- 1522 0800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
- 1522 0c00 RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
- 1522 0d00 RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
-# this is a correction to a recent entry. 1522:0E00 should be 1522:1D00
- 1522 1d00 RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
-1523 MUSIC Semiconductors
-1524 ENE Technology Inc
- 0510 CB710 Memory Card Reader Controller
- 0610 PCI Smart Card Reader Controller
- 1211 CB1211 Cardbus Controller
- 1225 CB1225 Cardbus Controller
- 1410 CB1410 Cardbus Controller
- 1025 005a TravelMate 290
- 1411 CB-710/2/4 Cardbus Controller
- 1412 CB-712/4 Cardbus Controller
- 1420 CB1420 Cardbus Controller
- 1421 CB-720/2/4 Cardbus Controller
- 1422 CB-722/4 Cardbus Controller
-1525 IMPACT Technologies
-1526 ISS, Inc
-1527 SOLECTRON
-1528 ACKSYS
-1529 AMERICAN MICROSystems Inc
-152a QUICKTURN DESIGN Systems
-152b FLYTECH Technology CO Ltd
-152c MACRAIGOR Systems LLC
-152d QUANTA Computer Inc
-152e MELEC Inc
-152f PHILIPS - CRYPTO
-1530 ACQIS Technology Inc
-1531 CHRYON Corp
-1532 ECHELON Corp
-1533 BALTIMORE
-1534 ROAD Corp
-1535 EVERGREEN Technologies Inc
-1537 DATALEX COMMUNCATIONS
-1538 ARALION Inc
- 0303 ARS106S Ultra ATA 133/100/66 Host Controller
-1539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
-153a ONO SOKKI
-153b TERRATEC Electronic GmbH
- 1144 Aureon 5.1
-# Terratec seems to use several IDs for the same card.
- 1147 Aureon 5.1 Sky
- 1158 Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
-153c ANTAL Electronic
-153d FILANET Corp
-153e TECHWELL Inc
-153f MIPS DENMARK
-1540 PROVIDEO MULTIMEDIA Co Ltd
-1541 MACHONE Communications
-1542 VIVID Technology Inc
-1543 SILICON Laboratories
- 3052 Intel 537 [Winmodem]
- 4c22 Si3036 MC'97 DAA
-1544 DCM DATA Systems
-1545 VISIONTEK
-1546 IOI Technology Corp
-1547 MITUTOYO Corp
-1548 JET PROPULSION Laboratory
-1549 INTERCONNECT Systems Solutions
-154a MAX Technologies Inc
-154b COMPUTEX Co Ltd
-154c VISUAL Technology Inc
-154d PAN INTERNATIONAL Industrial Corp
-154e SERVOTEST Ltd
-154f STRATABEAM Technology
-1550 OPEN NETWORK Co Ltd
-1551 SMART Electronic DEVELOPMENT GmBH
-1552 RACAL AIRTECH Ltd
-1553 CHICONY Electronics Co Ltd
-1554 PROLINK Microsystems Corp
-1555 GESYTEC GmBH
-1556 PLD APPLICATIONS
-1557 MEDIASTAR Co Ltd
-1558 CLEVO/KAPOK Computer
-1559 SI LOGIC Ltd
-155a INNOMEDIA Inc
-155b PROTAC INTERNATIONAL Corp
-155c Cemax-Icon Inc
-155d Mac System Co Ltd
-155e LP Elektronik GmbH
-155f Perle Systems Ltd
-1560 Terayon Communications Systems
-1561 Viewgraphics Inc
-1562 Symbol Technologies
-1563 A-Trend Technology Co Ltd
-1564 Yamakatsu Electronics Industry Co Ltd
-1565 Biostar Microtech Int'l Corp
-1566 Ardent Technologies Inc
-1567 Jungsoft
-1568 DDK Electronics Inc
-1569 Palit Microsystems Inc.
-156a Avtec Systems
-156b 2wire Inc
-156c Vidac Electronics GmbH
-156d Alpha-Top Corp
-156e Alfa Inc
-156f M-Systems Flash Disk Pioneers Ltd
-1570 Lecroy Corp
-1571 Contemporary Controls
- a001 CCSI PCI20-485 ARCnet
- a002 CCSI PCI20-485D ARCnet
- a003 CCSI PCI20-485X ARCnet
- a004 CCSI PCI20-CXB ARCnet
- a005 CCSI PCI20-CXS ARCnet
- a006 CCSI PCI20-FOG-SMA ARCnet
- a007 CCSI PCI20-FOG-ST ARCnet
- a008 CCSI PCI20-TB5 ARCnet
- a009 CCSI PCI20-5-485 5Mbit ARCnet
- a00a CCSI PCI20-5-485D 5Mbit ARCnet
- a00b CCSI PCI20-5-485X 5Mbit ARCnet
- a00c CCSI PCI20-5-FOG-ST 5Mbit ARCnet
- a00d CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
- a201 CCSI PCI22-485 10Mbit ARCnet
- a202 CCSI PCI22-485D 10Mbit ARCnet
- a203 CCSI PCI22-485X 10Mbit ARCnet
- a204 CCSI PCI22-CHB 10Mbit ARCnet
- a205 CCSI PCI22-FOG_ST 10Mbit ARCnet
- a206 CCSI PCI22-THB 10Mbit ARCnet
-1572 Otis Elevator Company
-1573 Lattice - Vantis
-1574 Fairchild Semiconductor
-1575 Voltaire Advanced Data Security Ltd
-1576 Viewcast COM
-1578 HITT
- 5615 VPMK3 [Video Processor Mk III]
-1579 Dual Technology Corp
-157a Japan Elecronics Ind Inc
-157b Star Multimedia Corp
-157c Eurosoft (UK)
- 8001 Fix2000 PCI Y2K Compliance Card
-157d Gemflex Networks
-157e Transition Networks
-157f PX Instruments Technology Ltd
-1580 Primex Aerospace Co
-1581 SEH Computertechnik GmbH
-1582 Cytec Corp
-1583 Inet Technologies Inc
-1584 Uniwill Computer Corp
-1585 Logitron
-1586 Lancast Inc
-1587 Konica Corp
-1588 Solidum Systems Corp
-1589 Atlantek Microsystems Pty Ltd
-158a Digalog Systems Inc
-158b Allied Data Technologies
-158c Hitachi Semiconductor & Devices Sales Co Ltd
-158d Point Multimedia Systems
-158e Lara Technology Inc
-158f Ditect Coop
-1590 3pardata Inc
-1591 ARN
-1592 Syba Tech Ltd
- 0781 Multi-IO Card
- 0782 Parallel Port Card 2xEPP
- 0783 Multi-IO Card
- 0785 Multi-IO Card
- 0786 Multi-IO Card
- 0787 Multi-IO Card
- 0788 Multi-IO Card
- 078a Multi-IO Card
-1593 Bops Inc
-1594 Netgame Ltd
-1595 Diva Systems Corp
-1596 Folsom Research Inc
-1597 Memec Design Services
-1598 Granite Microsystems
-1599 Delta Electronics Inc
-159a General Instrument
-159b Faraday Technology Corp
-159c Stratus Computer Systems
-159d Ningbo Harrison Electronics Co Ltd
-159e A-Max Technology Co Ltd
-159f Galea Network Security
-15a0 Compumaster SRL
-15a1 Geocast Network Systems
-15a2 Catalyst Enterprises Inc
- 0001 TA700 PCI Bus Analyzer/Exerciser
-15a3 Italtel
-15a4 X-Net OY
-15a5 Toyota Macs Inc
-15a6 Sunlight Ultrasound Technologies Ltd
-15a7 SSE Telecom Inc
-15a8 Shanghai Communications Technologies Center
-15aa Moreton Bay
-15ab Bluesteel Networks Inc
-15ac North Atlantic Instruments
-15ad VMware Inc
- 0405 [VMware SVGA II] PCI Display Adapter
- 0710 Virtual SVGA
- 0720 VMware High-Speed Virtual NIC [vmxnet]
-15ae Amersham Pharmacia Biotech
-15b0 Zoltrix International Ltd
-15b1 Source Technology Inc
-15b2 Mosaid Technologies Inc
-15b3 Mellanox Technologies
- 5274 MT21108 InfiniBridge
- 5a44 MT23108 InfiniHost
- 5a45 MT23108 [Infinihost HCA Flash Recovery]
- 5a46 MT23108 PCI Bridge
- 5e8c MT24204 [InfiniHost III Lx HCA]
- 5e8d MT24204 [InfiniHost III Lx HCA Flash Recovery]
- 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
- 6279 MT25208 [InfiniHost III Ex HCA Flash Recovery]
- 6282 MT25208 InfiniHost III Ex
-15b4 CCI/TRIAD
-15b5 Cimetrics Inc
-15b6 Texas Memory Systems Inc
-15b7 Sandisk Corp
-15b8 ADDI-DATA GmbH
-15b9 Maestro Digital Communications
-15ba Impacct Technology Corp
-15bb Portwell Inc
-15bc Agilent Technologies
- 2922 64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
- 2928 64 Bit, 66MHz PCI Exerciser & Analyzer
- 2929 64 Bit, 133MHz PCI-X Analyzer & Exerciser
-15bd DFI Inc
-15be Sola Electronics
-15bf High Tech Computer Corp (HTC)
-15c0 BVM Ltd
-15c1 Quantel
-15c2 Newer Technology Inc
-15c3 Taiwan Mycomp Co Ltd
-15c4 EVSX Inc
-15c5 Procomp Informatics Ltd
- 8010 1394b - 1394 Firewire 3-Port Host Adapter Card
-15c6 Technical University of Budapest
-15c7 Tateyama System Laboratory Co Ltd
- 0349 Tateyama C-PCI PLC/NC card Rev.01A
-15c8 Penta Media Co Ltd
-15c9 Serome Technology Inc
-15ca Bitboys OY
-15cb AG Electronics Ltd
-15cc Hotrail Inc
-15cd Dreamtech Co Ltd
-15ce Genrad Inc
-15cf Hilscher GmbH
-15d1 Infineon Technologies AG
-15d2 FIC (First International Computer Inc)
-15d3 NDS Technologies Israel Ltd
-15d4 Iwill Corp
-15d5 Tatung Co
-15d6 Entridia Corp
-15d7 Rockwell-Collins Inc
-15d8 Cybernetics Technology Co Ltd
-15d9 Super Micro Computer Inc
-15da Cyberfirm Inc
-15db Applied Computing Systems Inc
-15dc Litronic Inc
- 0001 Argus 300 PCI Cryptography Module
-15dd Sigmatel Inc
-15de Malleable Technologies Inc
-15df Infinilink Corp
-15e0 Cacheflow Inc
-15e1 Voice Technologies Group Inc
-15e2 Quicknet Technologies Inc
-15e3 Networth Technologies Inc
-15e4 VSN Systemen BV
-15e5 Valley technologies Inc
-15e6 Agere Inc
-15e7 Get Engineering Corp
-15e8 National Datacomm Corp
- 0130 Wireless PCI Card
-15e9 Pacific Digital Corp
- 1841 ADMA-100 DiscStaQ ATA Controller
-15ea Tokyo Denshi Sekei K.K.
-15eb Drsearch GmbH
-15ec Beckhoff GmbH
- 3101 FC3101 Profibus DP 1 Channel PCI
- 5102 FC5102
-15ed Macrolink Inc
-15ee In Win Development Inc
-15ef Intelligent Paradigm Inc
-15f0 B-Tree Systems Inc
-15f1 Times N Systems Inc
-15f2 Diagnostic Instruments Inc
-15f3 Digitmedia Corp
-15f4 Valuesoft
-15f5 Power Micro Research
-15f6 Extreme Packet Device Inc
-15f7 Banctec
-15f8 Koga Electronics Co
-15f9 Zenith Electronics Corp
-15fa J.P. Axzam Corp
-15fb Zilog Inc
-15fc Techsan Electronics Co Ltd
-15fd N-CUBED.NET
-15fe Kinpo Electronics Inc
-15ff Fastpoint Technologies Inc
-1600 Northrop Grumman - Canada Ltd
-1601 Tenta Technology
-1602 Prosys-tec Inc
-1603 Nokia Wireless Communications
-1604 Central System Research Co Ltd
-1605 Pairgain Technologies
-1606 Europop AG
-1607 Lava Semiconductor Manufacturing Inc
-1608 Automated Wagering International
-1609 Scimetric Instruments Inc
-1612 Telesynergy Research Inc.
-1619 FarSite Communications Ltd
- 0400 FarSync T2P (2 port X.21/V.35/V.24)
- 0440 FarSync T4P (4 port X.21/V.35/V.24)
-# www.rioworks.com
-161f Rioworks
-1626 TDK Semiconductor Corp.
- 8410 RTL81xx Fast Ethernet
-1629 Kongsberg Spacetec AS
- 1003 Format synchronizer v3.0
- 2002 Fast Universal Data Output
-# This seems to occur on their 802.11b Wireless card WMP-11
-1637 Linksys
- 3874 Linksys 802.11b WMP11 PCI Wireless card
-1638 Standard Microsystems Corp [SMC]
- 1100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
-163c Smart Link Ltd.
- 3052 SmartLink SmartPCI562 56K Modem
- 5449 SmartPCI561 Modem
-1657 Brocade Communications Systems, Inc.
-165a Epix Inc
- c100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
- d200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
- d300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
-165d Hsing Tech. Enterprise Co., Ltd.
-1661 Worldspace Corp.
-1668 Actiontec Electronics Inc
- 0100 Mini-PCI bridge
-# Formerly SiByte, Inc.
-166d Broadcom Corporation
- 0001 SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
- 0002 SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
-1677 Bernecker + Rainer
- 104e 5LS172.6 B&R Dual CAN Interface Card
- 12d7 5LS172.61 B&R Dual CAN Interface Card
-167b ZyDAS Technology Corp.
- 2102 ZyDAS ZD1202
- 187e 3406 ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
-1681 Hercules
-# More specs, more accurate desc.
- 0010 Hercules 3d Prophet II Ultra 64MB [ 350 MHz NV15BR core, 128-bit DDR @ 460 MHz, 1.5v AGP4x ]
-1682 XFX Pine Group Inc.
-1688 CastleNet Technology Inc.
- 1170 WLAN 802.11b card
-168c Atheros Communications, Inc.
- 0007 AR5000 802.11a Wireless Adapter
- 0011 AR5210 802.11a NIC
- 0012 AR5211 802.11ab NIC
- 0013 AR5212 802.11abg NIC
- 1113 d301 Philips CPWNA100 Wireless CardBus adapter
- 1186 3202 D-link DWL-G650 B3 Wireless cardbus adapter
- 1186 3203 DWL-G520 Wireless PCI Adapter
- 1186 3a13 DWL-G520 Wireless PCI Adapter rev. B
- 1186 3a94 C54C Wireless 801.11g cardbus
- 1385 4d00 Netgear WG311T Wireless PCI Adapter
- 14b7 0a60 8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
- 168c 0013 WG511T Wireless CardBus Adapter
- 168c 1025 DWL-G650B2 Wireless CardBus Adapter
- 168c 1027 Netgate NL-3054CB ARIES b/g CardBus Adapter
- 168c 2026 Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
- 168c 2041 Netgate 5354MP Plus ARIES2 b/g MiniPCI Adapter
- 168c 2042 Netgate 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
- 1014 AR5212 802.11abg NIC
-169c Netcell Corporation
- 0044 SyncRAID SR3000/5000 Series SATA RAID Controllers
-16a5 Tekram Technology Co.,Ltd.
-16ab Global Sun Technology Inc
- 1100 GL24110P
- 1101 PLX9052 PCMCIA-to-PCI Wireless LAN
- 1102 PCMCIA-to-PCI Wireless Network Bridge
- 8501 WL-8305 Wireless LAN PCI Adapter
-16ae Safenet Inc
- 1141 SafeXcel-1141
-16b4 Aspex Semiconductor Ltd
-16be Creatix Polymedia GmbH
-16ca CENATEK Inc
- 0001 Rocket Drive DL
-16cd Densitron Technologies
-16ce Roland Corp.
-# www.pikatechnologies.com
-16df PIKA Technologies Inc.
-16e3 European Space Agency
- 1e0f LEON2FT Processor
-16ec U.S. Robotics
- 00ff USR997900 10/100 Mbps PCI Network Card
- 0116 USR997902 10/100/1000 Mbps PCI Network Card
- 3685 Wireless Access PCI Adapter Model 022415
-16ed Sycron N. V.
- 1001 UMIO communication card
-16f3 Jetway Information Co., Ltd.
-16f4 Vweb Corp
- 8000 VW2010
-16f6 VideoTele.com, Inc.
-# www.internetmachines.com
-1702 Internet Machines Corporation (IMC)
-1705 Digital First, Inc.
-170b NetOctave
- 0100 NSP2000-SSL crypto accelerator
-170c YottaYotta Inc.
-# Seems to be a 2nd ID for Vitesse Semiconductor
-1725 Vitesse Semiconductor
- 7174 VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
-172a Accelerated Encryption
-1734 Fujitsu Siemens Computer GmbH
-1737 Linksys
- 0013 WMP54G Wireless Pci Card
- 0015 WMP54GS Wireless Pci Card
- 1032 Gigabit Network Adapter
- 1737 0015 EG1032 v2 Instant Gigabit Network Adapter
- 1064 Gigabit Network Adapter
- 1737 0016 EG1064 v2 Instant Gigabit Network Adapter
- ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
- ab09 21x4x DEC-Tulip compatible 10/100 Ethernet
-173b Altima (nee Broadcom)
- 03e8 AC1000 Gigabit Ethernet
- 03e9 AC1001 Gigabit Ethernet
- 03ea AC9100 Gigabit Ethernet
- 173b 0001 AC1002
- 03eb AC1003 Gigabit Ethernet
-1743 Peppercon AG
- 8139 ROL/F-100 Fast Ethernet Adapter with ROL
-1749 RLX Technologies
-174b PC Partner Limited
-174d WellX Telecom SA
-175c AudioScience Inc
-175e Sanera Systems, Inc.
-1787 Hightech Information System Ltd.
-# also used by Struck Innovative Systeme for joint developments
-1796 Research Centre Juelich
- 0001 SIS1100 [Gigabit link]
- 0002 HOTlink
- 0003 Counter Timer
- 0004 CAMAC Controller
- 0005 PROFIBUS
- 0006 AMCC HOTlink
-1797 JumpTec h, GMBH
-1799 Belkin
- 6001 Wireless PCI Card - F5D6001
- 6020 Wireless PCMCIA Card - F5D6020
- 6060 Wireless PDA Card - F5D6060
- 7000 Wireless PCI Card - F5D7000
-17a0 Genesys Logic, Inc
- 8033 GL880S USB 1.1 controller
- 8034 GL880S USB 2.0 controller
-17af Hightech Information System Ltd.
-17b3 Hawking Technologies
- ab08 PN672TX 10/100 Ethernet
-17b4 Indra Networks, Inc.
- 0011 WebEnhance 100 GZIP Compression Card
-17c0 Wistron Corp.
-17c2 Newisys, Inc.
-17cc NetChip Technology, Inc
- 2280 USB 2.0
-17d3 Areca Technology Corp.
- 1110 ARC-1110 4-Port PCI-X to SATA RAID Controller
- 1120 ARC-1120 8-Port PCI-X to SATA RAID Controller
- 1130 ARC-1130 12-Port PCI-X to SATA RAID Controller
- 1160 ARC-1160 16-Port PCI-X to SATA RAID Controller
- 1210 ARC-1210 4-Port PCI-Express to SATA RAID Controller
- 1220 ARC-1220 8-Port PCI-Express to SATA RAID Controller
- 1230 ARC-1230 12-Port PCI-Express to SATA RAID Controller
- 1260 ARC-1260 16-Port PCI-Express to SATA RAID Controller
-# S2io ships 10Gb PCI-X Ethernet adapters www.s2io.com
-17d5 S2io Inc.
- 5831 Xframe 10 Gigabit Ethernet PCI-X
- 103c 12d5 HP PCI-X 133MHz 10GbE SR Fiber [AB287A]
-17de KWorld Computer Co. Ltd.
-# http://www.connect3d.com
-17ee Connect Components Ltd
-17fe Linksys, A Division of Cisco Systems
- 2120 WMP11v4 802.11b PCI card
- 2220 [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01)
-1813 Ambient Technologies Inc
- 4000 HaM controllerless modem
- 16be 0001 V9x HAM Data Fax Modem
- 4100 HaM plus Data Fax Modem
- 16be 0002 V9x HAM 1394
-1814 RaLink
- 0101 Wireless PCI Adpator RT2400 / RT2460
- 3306 1113 Quidway WL100M
- 0201 Ralink RT2500 802.11 Cardbus Reference Card
- 1371 001e CWC-854 Wireless-G CardBus Adapter
- 1371 001f CWM-854 Wireless-G Mini PCI Adapter
- 1371 0020 CWP-854 Wireless-G PCI Adapter
- 1458 e381 GN-WMKG 802.11b/g Wireless CardBus Adapter
-1820 InfiniCon Systems Inc.
-1822 Twinhan Technology Co. Ltd
-182d SiteCom Europe BV
-# HFC-based ISDN card
- 3069 ISDN PCI DC-105V2
- 9790 WL-121 Wireless Network Adapter 100g+ [Ver.3]
-1830 Credence Systems Corporation
-183b MikroM GmbH
- 08a7 MVC100 DVI
- 08a8 MVC101 SDI
- 08a9 MVC102 DVI+Audio
-1849 ASRock Incorporation
-1851 Microtune, Inc.
-1852 Anritsu Corp.
-185f Wistron NeWeb Corp.
-1867 Topspin Communications
- 5a44 MT23108 PCI-X HCA
- 5a45 MT23108 PCI-X HCA flash recovery
- 5a46 MT23108 PCI-X HCA bridge
- 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
- 6282 MT25208 InfiniHost III Ex
-187e ZyXEL Communication Corporation
-1888 Varisys Ltd
- 0301 VMFX1 FPGA PMC module
- 0601 VSM2 dual PMC carrier
- 0710 VS14x series PowerPC PCI board
- 0720 VS24x series PowerPC PCI board
-# found e.g. on KNC DVB-S card
-1894 KNC One
-1896 B&B Electronics Manufacturing Company, Inc.
-18a1 Astute Networks Inc.
-18ac DViCO Corporation
- d810 FusionHDTV 3 Gold
-18b8 Ammasso
- b001 AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
-18bc Info-Tek Corp.
-# assigned to Octigabay System, which has been acquired by Cray
-18c8 Cray Inc
-18c9 ARVOO Engineering BV
-18ca XGI - Xabre Graphics Inc
- 0040 Volari V8
-18e6 MPL AG
- 0001 OSCI [Octal Serial Communication Interface]
-18f7 Commtech, Inc.
- 0001 Fastcom ESCC-PCI-335
- 0002 Fastcom 422/4-PCI-335
- 0004 Fastcom 422/2-PCI-335
- 0005 Fastcom IGESCC-PCI-ISO/1
- 000a Fastcom 232/4-PCI-335
-18fb Resilience Corporation
-1924 Level 5 Networks Inc.
-1966 Orad Hi-Tec Systems
- 1975 DVG64 family
-1993 Innominate Security Technologies AG
-# http://www.progeny.net
-19ae Progeny Systems Corporation
-1a08 Sierra semiconductor
- 0000 SC15064
-1b13 Jaton Corp
-1c1c Symphony
- 0001 82C101
-1d44 DPT
- a400 PM2x24/PM3224
-1de1 Tekram Technology Co.,Ltd.
- 0391 TRM-S1040
- 2020 DC-390
- 690c 690c
- dc29 DC290
-1fc0 Tumsan Oy
- 0300 E2200 Dual E1/Rawpipe Card
-2000 Smart Link Ltd.
-2001 Temporal Research Ltd
-2003 Smart Link Ltd.
-2004 Smart Link Ltd.
-21c3 21st Century Computer Corp.
-2348 Racore
- 2010 8142 100VG/AnyLAN
-2646 Kingston Technologies
-270b Xantel Corporation
-270f Chaintech Computer Co. Ltd
-2711 AVID Technology Inc.
-2a15 3D Vision(???)
-3000 Hansol Electronics Inc.
-3142 Post Impression Systems.
-3388 Hint Corp
- 0013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
- 0014 HiNT HC4 PCI to ISDN bridge, Network controller
- 0020 HB6 Universal PCI-PCI bridge (transparent mode)
- 0021 HB6 Universal PCI-PCI bridge (non-transparent mode)
- 4c53 1050 CT7 mainboard
- 4c53 1080 CT8 mainboard
- 4c53 10a0 CA3/CR3 mainboard
- 4c53 3010 PPCI mezzanine (32-bit PMC)
- 4c53 3011 PPCI mezzanine (64-bit PMC)
- 0022 HiNT HB4 PCI-PCI Bridge (PCI6150)
- 0026 HB2 PCI-PCI Bridge
- 101a E.Band [AudioTrak Inca88]
- 101b E.Band [AudioTrak Inca88]
- 8011 VXPro II Chipset
- 3388 8011 VXPro II Chipset CPU to PCI Bridge
- 8012 VXPro II Chipset
- 3388 8012 VXPro II Chipset PCI to ISA Bridge
- 8013 VXPro II IDE
- 3388 8013 VXPro II Chipset EIDE Controller
-3411 Quantum Designs (H.K.) Inc
-3513 ARCOM Control Systems Ltd
-3842 eVga.com. Corp.
-38ef 4Links
-3d3d 3DLabs
- 0001 GLINT 300SX
- 0002 GLINT 500TX
- 0003 GLINT Delta
- 0004 Permedia
- 0005 Permedia
- 0006 GLINT MX
- 0007 3D Extreme
- 0008 GLINT Gamma G1
- 0009 Permedia II 2D+3D
- 1040 0011 AccelStar II
- 13e9 1000 6221L-4U
- 3d3d 0100 AccelStar II 3D Accelerator
- 3d3d 0111 Permedia 3:16
- 3d3d 0114 Santa Ana
- 3d3d 0116 Oxygen GVX1
- 3d3d 0119 Scirocco
- 3d3d 0120 Santa Ana PCL
- 3d3d 0125 Oxygen VX1
- 3d3d 0127 Permedia3 Create!
- 000a GLINT R3
- 3d3d 0121 Oxygen VX1
- 000c GLINT R3 [Oxygen VX1]
- 3d3d 0144 Oxygen VX1-4X AGP [Permedia 4]
- 000d GLint R4 rev A
- 0011 GLint R4 rev B
- 0012 GLint R5 rev A
- 0013 GLint R5 rev B
- 0020 VP10 visual processor
-# P10 generic II
- 0022 VP10 visual processor
- 0024 VP9 visual processor
- 0100 Permedia II 2D+3D
- 07a1 Wildcat III 6210
- 07a2 Sun XVR-500 Graphics Accelerator
- 07a3 Wildcat IV 7210
- 1004 Permedia
- 3d04 Permedia
- ffff Glint VGA
-4005 Avance Logic Inc.
- 0300 ALS300 PCI Audio Device
- 0308 ALS300+ PCI Audio Device
- 0309 PCI Input Controller
- 1064 ALG-2064
- 2064 ALG-2064i
- 2128 ALG-2364A GUI Accelerator
- 2301 ALG-2301
- 2302 ALG-2302
- 2303 AVG-2302 GUI Accelerator
- 2364 ALG-2364A
- 2464 ALG-2464
- 2501 ALG-2564A/25128A
- 4000 ALS4000 Audio Chipset
- 4005 4000 ALS4000 Audio Chipset
- 4710 ALC200/200P
-4033 Addtron Technology Co, Inc.
- 1360 RTL8139 Ethernet
-4143 Digital Equipment Corp
-4144 Alpha Data
- 0044 ADM-XRCIIPro
-416c Aladdin Knowledge Systems
- 0100 AladdinCARD
- 0200 CPC
-4444 Internext Compression Inc
- 0016 iTVC16 (CX23416) MPEG-2 Encoder
- 0070 4009 WinTV PVR 250
- 0070 8003 WinTV PVR 150
- 0803 iTVC15 MPEG-2 Encoder
- 0070 4000 WinTV PVR-350
- 0070 4001 WinTV PVR-250
-# video capture card
- 1461 a3cf M179
-4468 Bridgeport machines
-4594 Cogetec Informatique Inc
-45fb Baldor Electric Company
-4680 Umax Computer Corp
-4843 Hercules Computer Technology Inc
-4916 RedCreek Communications Inc
- 1960 RedCreek PCI adapter
-4943 Growth Networks
-494f ACCES I/O Products, Inc.
- 10e8 LPCI-COM-8SM
-4978 Axil Computer Inc
-4a14 NetVin
- 5000 NV5000SC
- 4a14 5000 RT8029-Based Ethernet Adapter
-4b10 Buslogic Inc.
-4c48 LUNG HWA Electronics
-4c53 SBS Technologies
- 0000 PLUSTEST device
- 4c53 3000 PLUSTEST card (PC104+)
- 4c53 3001 PLUSTEST card (PMC)
- 0001 PLUSTEST-MM device
- 4c53 3002 PLUSTEST-MM card (PMC)
-4ca1 Seanix Technology Inc
-4d51 MediaQ Inc.
- 0200 MQ-200
-4d54 Microtechnica Co Ltd
-4ddc ILC Data Device Corp
- 0100 DD-42924I5-300 (ARINC 429 Data Bus)
- 0801 BU-65570I1 MIL-STD-1553 Test and Simulation
- 0802 BU-65570I2 MIL-STD-1553 Test and Simulation
- 0811 BU-65572I1 MIL-STD-1553 Test and Simulation
- 0812 BU-65572I2 MIL-STD-1553 Test and Simulation
- 0881 BU-65570T1 MIL-STD-1553 Test and Simulation
- 0882 BU-65570T2 MIL-STD-1553 Test and Simulation
- 0891 BU-65572T1 MIL-STD-1553 Test and Simulation
- 0892 BU-65572T2 MIL-STD-1553 Test and Simulation
- 0901 BU-65565C1 MIL-STD-1553 Data Bus
- 0902 BU-65565C2 MIL-STD-1553 Data Bus
- 0903 BU-65565C3 MIL-STD-1553 Data Bus
- 0904 BU-65565C4 MIL-STD-1553 Data Bus
- 0b01 BU-65569I1 MIL-STD-1553 Data Bus
- 0b02 BU-65569I2 MIL-STD-1553 Data Bus
- 0b03 BU-65569I3 MIL-STD-1553 Data Bus
- 0b04 BU-65569I4 MIL-STD-1553 Data Bus
-5046 GemTek Technology Corporation
- 1001 PCI Radio
-5053 Voyetra Technologies
- 2010 Daytona Audio Adapter
-5136 S S Technologies
-5143 Qualcomm Inc
-5145 Ensoniq (Old)
- 3031 Concert AudioPCI
-5168 Animation Technologies Inc.
-5301 Alliance Semiconductor Corp.
- 0001 ProMotion aT3D
-5333 S3 Inc.
- 0551 Plato/PX (system)
- 5631 86c325 [ViRGE]
- 8800 86c866 [Vision 866]
- 8801 86c964 [Vision 964]
- 8810 86c764_0 [Trio 32 vers 0]
- 8811 86c764/765 [Trio32/64/64V+]
- 8812 86cM65 [Aurora64V+]
- 8813 86c764_3 [Trio 32/64 vers 3]
- 8814 86c767 [Trio 64UV+]
- 8815 86cM65 [Aurora 128]
- 883d 86c988 [ViRGE/VX]
- 8870 FireGL
- 8880 86c868 [Vision 868 VRAM] vers 0
- 8881 86c868 [Vision 868 VRAM] vers 1
- 8882 86c868 [Vision 868 VRAM] vers 2
- 8883 86c868 [Vision 868 VRAM] vers 3
- 88b0 86c928 [Vision 928 VRAM] vers 0
- 88b1 86c928 [Vision 928 VRAM] vers 1
- 88b2 86c928 [Vision 928 VRAM] vers 2
- 88b3 86c928 [Vision 928 VRAM] vers 3
- 88c0 86c864 [Vision 864 DRAM] vers 0
- 88c1 86c864 [Vision 864 DRAM] vers 1
- 88c2 86c864 [Vision 864-P DRAM] vers 2
- 88c3 86c864 [Vision 864-P DRAM] vers 3
- 88d0 86c964 [Vision 964 VRAM] vers 0
- 88d1 86c964 [Vision 964 VRAM] vers 1
- 88d2 86c964 [Vision 964-P VRAM] vers 2
- 88d3 86c964 [Vision 964-P VRAM] vers 3
- 88f0 86c968 [Vision 968 VRAM] rev 0
- 88f1 86c968 [Vision 968 VRAM] rev 1
- 88f2 86c968 [Vision 968 VRAM] rev 2
- 88f3 86c968 [Vision 968 VRAM] rev 3
- 8900 86c755 [Trio 64V2/DX]
- 5333 8900 86C775 Trio64V2/DX
- 8901 86c775/86c785 [Trio 64V2/DX or /GX]
- 5333 8901 86C775 Trio64V2/DX, 86C785 Trio64V2/GX
- 8902 Plato/PX
- 8903 Trio 3D business multimedia
- 8904 Trio 64 3D
- 1014 00db Integrated Trio3D
- 5333 8904 86C365 Trio3D AGP
- 8905 Trio 64V+ family
- 8906 Trio 64V+ family
- 8907 Trio 64V+ family
- 8908 Trio 64V+ family
- 8909 Trio 64V+ family
- 890a Trio 64V+ family
- 890b Trio 64V+ family
- 890c Trio 64V+ family
- 890d Trio 64V+ family
- 890e Trio 64V+ family
- 890f Trio 64V+ family
- 8a01 ViRGE/DX or /GX
- 0e11 b032 ViRGE/GX
- 10b4 1617 Nitro 3D
- 10b4 1717 Nitro 3D
- 5333 8a01 ViRGE/DX
- 8a10 ViRGE/GX2
- 1092 8a10 Stealth 3D 4000
- 8a13 86c368 [Trio 3D/2X]
- 5333 8a13 Trio3D/2X
- 8a20 86c794 [Savage 3D]
- 5333 8a20 86C391 Savage3D
- 8a21 86c390 [Savage 3D/MV]
- 5333 8a21 86C390 Savage3D/MV
- 8a22 Savage 4
- 1033 8068 Savage 4
- 1033 8069 Savage 4
- 1033 8110 Savage4 LT
- 105d 0018 SR9 8Mb SDRAM
- 105d 002a SR9 Pro 16Mb SDRAM
- 105d 003a SR9 Pro 32Mb SDRAM
- 105d 092f SR9 Pro+ 16Mb SGRAM
- 1092 4207 Stealth III S540
- 1092 4800 Stealth III S540
- 1092 4807 SpeedStar A90
- 1092 4808 Stealth III S540
- 1092 4809 Stealth III S540
- 1092 480e Stealth III S540
- 1092 4904 Stealth III S520
- 1092 4905 SpeedStar A200
- 1092 4a09 Stealth III S540
- 1092 4a0b Stealth III S540 Xtreme
- 1092 4a0f Stealth III S540
- 1092 4e01 Stealth III S540
- 1102 101d 3d Blaster Savage 4
- 1102 101e 3d Blaster Savage 4
- 5333 8100 86C394-397 Savage4 SDRAM 100
- 5333 8110 86C394-397 Savage4 SDRAM 110
- 5333 8125 86C394-397 Savage4 SDRAM 125
- 5333 8143 86C394-397 Savage4 SDRAM 143
- 5333 8a22 86C394-397 Savage4
- 5333 8a2e 86C394-397 Savage4 32bit
- 5333 9125 86C394-397 Savage4 SGRAM 125
- 5333 9143 86C394-397 Savage4 SGRAM 143
- 8a23 Savage 4
- 8a25 ProSavage PM133
- 8a26 ProSavage KM133
- 8c00 ViRGE/M3
- 8c01 ViRGE/MX
- 1179 0001 ViRGE/MX
- 8c02 ViRGE/MX+
- 8c03 ViRGE/MX+MV
- 8c10 86C270-294 Savage/MX-MV
- 8c11 82C270-294 Savage/MX
- 8c12 86C270-294 Savage/IX-MV
- 1014 017f ThinkPad T20
- 1179 0001 86C584 SuperSavage/IXC Toshiba
- 8c13 86C270-294 Savage/IX
- 1179 0001 Magnia Z310
- 8c22 SuperSavage MX/128
- 8c24 SuperSavage MX/64
- 8c26 SuperSavage MX/64C
- 8c2a SuperSavage IX/128 SDR
- 8c2b SuperSavage IX/128 DDR
- 8c2c SuperSavage IX/64 SDR
- 8c2d SuperSavage IX/64 DDR
- 8c2e SuperSavage IX/C SDR
- 1014 01fc ThinkPad T23 (2647-4MG)
- 8c2f SuperSavage IX/C DDR
- 8d01 86C380 [ProSavageDDR K4M266]
- 8d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
- 8d03 VT8751 [ProSavageDDR P4M266]
- 8d04 VT8375 [ProSavage8 KM266/KL266]
- 9102 86C410 Savage 2000
- 1092 5932 Viper II Z200
- 1092 5934 Viper II Z200
- 1092 5952 Viper II Z200
- 1092 5954 Viper II Z200
- 1092 5a35 Viper II Z200
- 1092 5a37 Viper II Z200
- 1092 5a55 Viper II Z200
- 1092 5a57 Viper II Z200
- ca00 SonicVibes
-544c Teralogic Inc
- 0350 TL880-based HDTV/ATSC tuner
-5455 Technische University Berlin
- 4458 S5933
-5519 Cnet Technologies, Inc.
-5544 Dunord Technologies
- 0001 I-30xx Scanner Interface
-5555 Genroco, Inc
- 0003 TURBOstor HFP-832 [HiPPI NIC]
-5654 VoiceTronix Pty Ltd
- 3132 OpenSwitch12
-5700 Netpower
-5851 Exacq Technologies
-6356 UltraStor
-6374 c't Magazin für Computertechnik
- 6773 GPPCI
-6409 Logitec Corp.
-6666 Decision Computer International Co.
- 0001 PCCOM4
- 0002 PCCOM8
-7604 O.N. Electronic Co Ltd.
-7bde MIDAC Corporation
-7fed PowerTV
-8008 Quancom Electronic GmbH
- 0010 WDOG1 [PCI-Watchdog 1]
- 0011 PWDOG2 [PCI-Watchdog 2]
-# Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card.
-807d Asustek Computer, Inc.
-8086 Intel Corporation
- 0007 82379AB
- 0008 Extended Express System Support Controller
- 0008 1000 WorldMark 4300 INCA ASIC
- 0039 21145 Fast Ethernet
- 0122 82437FX
- 0309 80303 I/O Processor PCI-to-PCI Bridge
- 030d 80312 I/O Companion Chip PCI-to-PCI Bridge
- 0326 6700/6702PXH I/OxAPIC Interrupt Controller A
- 0327 6700PXH I/OxAPIC Interrupt Controller B
- 0329 6700PXH PCI Express-to-PCI Bridge A
- 032a 6700PXH PCI Express-to-PCI Bridge B
- 032c 6702PXH PCI Express-to-PCI Bridge A
-# A-segment bridge
- 0330 80332 [Dobson] I/O processor
-# A-segment IOAPIC
- 0331 80332 [Dobson] I/O processor
-# B-segment bridge
- 0332 80332 [Dobson] I/O processor
-# B-segment IOAPIC
- 0333 80332 [Dobson] I/O processor
-# Address Translation Unit (ATU)
- 0334 80332 [Dobson] I/O processor
-# PCI-X bridge
- 0335 80331 [Lindsay] I/O processor
-# Address Translation Unit (ATU)
- 0336 80331 [Lindsay] I/O processor
-# A-segment bridge
- 0340 41210 [Lanai] Serial to Parallel PCI Bridge
-# B-segment bridge
- 0341 41210 [Lanai] Serial to Parallel PCI Bridge
- 0482 82375EB/SB PCI to EISA Bridge
- 0483 82424TX/ZX [Saturn] CPU to PCI bridge
- 0484 82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
- 0486 82425EX/ZX [Aries] PCIset with ISA bridge
- 04a3 82434LX/NX [Mercury/Neptune] Processor to PCI bridge
- 04d0 82437FX [Triton FX]
- 0500 E8870 Processor bus control
- 0501 E8870 Memory controller
-# and registers common to both SPs
- 0502 E8870 Scalability Port 0
-# and global performance monitoring
- 0503 E8870 Scalability Port 1
- 0510 E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
- 0511 E8870IO Hub Interface Port 1 registers
- 0512 E8870IO Hub Interface Port 2 registers
- 0513 E8870IO Hub Interface Port 3 registers
- 0514 E8870IO Hub Interface Port 4 registers
- 0515 E8870IO General SIOH registers
- 0516 E8870IO RAS registers
- 0530 E8870SP Scalability Port 0 registers
- 0531 E8870SP Scalability Port 1 registers
- 0532 E8870SP Scalability Port 2 registers
- 0533 E8870SP Scalability Port 3 registers
- 0534 E8870SP Scalability Port 4 registers
- 0535 E8870SP Scalability Port 5 registers
-# (bi-interleave 0) and global registers that are neither per-port nor per-interleave
- 0536 E8870SP Interleave registers 0 and 1
-# (bi-interleave 1)
- 0537 E8870SP Interleave registers 2 and 3
- 0600 RAID Controller
- 8086 01c1 ICP Vortex GDT8546RZ
- 8086 01f7 SCRU32
-# uninitialized SRCU32 RAID Controller
- 061f 80303 I/O Processor
- 0960 80960RP [i960 RP Microprocessor/Bridge]
- 0962 80960RM [i960RM Bridge]
- 0964 80960RP [i960 RP Microprocessor/Bridge]
- 1000 82542 Gigabit Ethernet Controller
- 0e11 b0df NC1632 Gigabit Ethernet Adapter (1000-SX)
- 0e11 b0e0 NC1633 Gigabit Ethernet Adapter (1000-LX)
- 0e11 b123 NC1634 Gigabit Ethernet Adapter (1000-SX)
- 1014 0119 Netfinity Gigabit Ethernet SX Adapter
- 8086 1000 PRO/1000 Gigabit Server Adapter
- 1001 82543GC Gigabit Ethernet Controller (Fiber)
- 0e11 004a NC6136 Gigabit Server Adapter
- 1014 01ea Netfinity Gigabit Ethernet SX Adapter
- 8086 1002 PRO/1000 F Server Adapter
- 8086 1003 PRO/1000 F Server Adapter
- 1002 Pro 100 LAN+Modem 56 Cardbus II
- 8086 200e Pro 100 LAN+Modem 56 Cardbus II
- 8086 2013 Pro 100 SR Mobile Combo Adapter
- 8086 2017 Pro 100 S Combo Mobile Adapter
- 1004 82543GC Gigabit Ethernet Controller (Copper)
- 0e11 0049 NC7132 Gigabit Upgrade Module
- 0e11 b1a4 NC7131 Gigabit Server Adapter
- 1014 10f2 Gigabit Ethernet Server Adapter
- 8086 1004 PRO/1000 T Server Adapter
- 8086 2004 PRO/1000 T Server Adapter
- 1008 82544EI Gigabit Ethernet Controller (Copper)
- 1014 0269 iSeries 1000/100/10 Ethernet Adapter
- 1028 011c PRO/1000 XT Network Connection
- 8086 1107 PRO/1000 XT Server Adapter
- 8086 2107 PRO/1000 XT Server Adapter
- 8086 2110 PRO/1000 XT Server Adapter
- 8086 3108 PRO/1000 XT Network Connection
- 1009 82544EI Gigabit Ethernet Controller (Fiber)
- 1014 0268 iSeries Gigabit Ethernet Adapter
- 8086 1109 PRO/1000 XF Server Adapter
- 8086 2109 PRO/1000 XF Server Adapter
- 100c 82544GC Gigabit Ethernet Controller (Copper)
- 8086 1112 PRO/1000 T Desktop Adapter
- 8086 2112 PRO/1000 T Desktop Adapter
- 100d 82544GC Gigabit Ethernet Controller (LOM)
- 1028 0123 PRO/1000 XT Network Connection
- 1079 891f 82544GC Based Network Connection
- 4c53 1080 CT8 mainboard
- 8086 110d 82544GC Based Network Connection
- 100e 82540EM Gigabit Ethernet Controller
- 1014 0265 PRO/1000 MT Network Connection
- 1014 0267 PRO/1000 MT Network Connection
- 1014 026a PRO/1000 MT Network Connection
- 1028 002e Optiplex GX260
- 1028 0151 PRO/1000 MT Network Connection
- 107b 8920 PRO/1000 MT Desktop Adapter
- 8086 001e PRO/1000 MT Desktop Adapter
- 8086 002e PRO/1000 MT Desktop Adapter
- 100f 82545EM Gigabit Ethernet Controller (Copper)
- 1014 0269 iSeries 1000/100/10 Ethernet Adapter
- 1014 028e PRO/1000 MT Network Connection
- 8086 1000 PRO/1000 MT Network Connection
- 8086 1001 PRO/1000 MT Server Adapter
- 1010 82546EB Gigabit Ethernet Controller (Copper)
- 1014 027c PRO/1000 MT Dual Port Network Adapter
- 18fb 7872 RESlink-X
- 4c53 1080 CT8 mainboard
- 4c53 10a0 CA3/CR3 mainboard
- 8086 1011 PRO/1000 MT Dual Port Server Adapter
- 8086 101a PRO/1000 MT Dual Port Network Adapter
- 8086 3424 SE7501HG2 Mainboard
- 1011 82545EM Gigabit Ethernet Controller (Fiber)
- 1014 0268 iSeries Gigabit Ethernet Adapter
- 8086 1002 PRO/1000 MF Server Adapter
- 8086 1003 PRO/1000 MF Server Adapter (LX)
- 1012 82546EB Gigabit Ethernet Controller (Fiber)
- 8086 1012 PRO/1000 MF Dual Port Server Adapter
- 1013 82541EI Gigabit Ethernet Controller (Copper)
- 8086 0013 PRO/1000 MT Network Connection
- 8086 1013 IBM ThinkCentre Network Card
- 8086 1113 PRO/1000 MT Desktop Adapter
- 1014 82541ER Gigabit Ethernet Controller
- 1015 82540EM Gigabit Ethernet Controller (LOM)
- 1016 82540EP Gigabit Ethernet Controller (LOM)
- 1014 052c PRO/1000 MT Mobile Connection
- 1179 0001 PRO/1000 MT Mobile Connection
- 8086 1016 PRO/1000 MT Mobile Connection
- 1017 82540EP Gigabit Ethernet Controller (LOM)
- 8086 1017 PR0/1000 MT Desktop Connection
-# Update controller name from 82541EP to 82541EI
- 1018 82541EI Gigabit Ethernet Controller
- 8086 1018 PRO/1000 MT Desktop Adapter
- 1019 82547EI Gigabit Ethernet Controller (LOM)
- 1458 1019 GA-8IPE1000 Pro2 motherboard (865PE)
- 1458 e000 Intel Gigabit Ethernet (Kenai II)
- 8086 1019 PRO/1000 CT Desktop Connection
- 8086 301f D865PERL mainboard
- 8086 3427 S875WP1-E mainboard
- 101d 82546EB Gigabit Ethernet Controller
- 8086 1000 PRO/1000 MT Quad Port Server Adapter
- 101e 82540EP Gigabit Ethernet Controller (Mobile)
- 1014 0549 PRO/1000 MT Mobile Connection
- 1179 0001 PRO/1000 MT Mobile Connection
- 8086 101e PRO/1000 MT Mobile Connection
- 1026 82545GM Gigabit Ethernet Controller
- 8086 1000 PRO/1000 MT Server Connection
- 8086 1001 PRO/1000 MT Server Adapter
- 8086 1002 PRO/1000 MT Server Adapter
- 8086 1026 PRO/1000 MT Server Connection
- 1027 82545GM Gigabit Ethernet Controller
- 8086 1001 PRO/1000 MF Server Adapter(LX)
- 8086 1002 PRO/1000 MF Server Adapter(LX)
- 8086 1003 PRO/1000 MF Server Adapter(LX)
- 8086 1027 PRO/1000 MF Server Adapter
- 1028 82545GM Gigabit Ethernet Controller
- 8086 1028 PRO/1000 MB Server Adapter
- 1029 82559 Ethernet Controller
- 1030 82559 InBusiness 10/100
- 1031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
- 1014 0209 ThinkPad A/T/X Series
- 104d 80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 107b 5350 EtherExpress PRO/100 VE
- 1179 0001 EtherExpress PRO/100 VE
- 144d c000 EtherExpress PRO/100 VE
- 144d c001 EtherExpress PRO/100 VE
- 144d c003 EtherExpress PRO/100 VE
- 144d c006 vpr Matrix 170B4
- 1032 82801CAM (ICH3) PRO/100 VE Ethernet Controller
- 1033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
- 1034 82801CAM (ICH3) PRO/100 VM Ethernet Controller
- 1035 82801CAM (ICH3)/82562EH (LOM) Ethernet Controller
- 1036 82801CAM (ICH3) 82562EH Ethernet Controller
- 1037 82801CAM (ICH3) Chipset Ethernet Controller
- 1038 82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
- 1039 82801DB PRO/100 VE (LOM) Ethernet Controller
- 1014 0267 NetVista A30p
- 103a 82801DB PRO/100 VE (CNR) Ethernet Controller
- 103b 82801DB PRO/100 VM (LOM) Ethernet Controller
- 103c 82801DB PRO/100 VM (CNR) Ethernet Controller
- 103d 82801DB PRO/100 VE (MOB) Ethernet Controller
- 103e 82801DB PRO/100 VM (MOB) Ethernet Controller
- 1040 536EP Data Fax Modem
- 16be 1040 V.9X DSP Data Fax Modem
- 1043 PRO/Wireless LAN 2100 3B Mini PCI Adapter
- 8086 2527 MIM2000/Centrino
- 1048 PRO/10GbE LR Server Adapter
- 8086 a01f PRO/10GbE LR Server Adapter
- 8086 a11f PRO/10GbE LR Server Adapter
- 1050 82562EZ 10/100 Ethernet Controller
- 1462 728c 865PE Neo2 (MS-6728)
- 1462 758c MS-6758 (875P Neo)
- 8086 3020 D865PERL mainboard
- 8086 3427 S875WP1-E mainboard
- 1051 82801EB/ER (ICH5/ICH5R) integrated LAN Controller
- 1059 82551QM Ethernet Controller
-# ICH-6 Component
- 1064 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
-# ICH-6 Component
- 1065 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
-# ICH-6 Component
- 1066 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
-# ICH-6 Component
- 1067 82562 EM/EX/GX - PRO/100 VM Ethernet Controller
-# ICH-6 Component
- 1068 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
-# ICH-6 Component
- 1069 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
-# ICH-6 Component
- 106a 82562G \t- PRO/100 VE (LOM) Ethernet Controller
-# ICH-6 Component
- 106b 82562G \t- PRO/100 VE Ethernet Controller Mobile
- 1075 82547GI Gigabit Ethernet Controller
- 1028 0165 PowerEdge 750
- 8086 0075 PRO/1000 CT Network Connection
- 8086 1075 PRO/1000 CT Network Connection
- 1076 82541GI/PI Gigabit Ethernet Controller
- 1028 0165 PowerEdge 750
- 8086 0076 PRO/1000 MT Network Connection
- 8086 1076 PRO/1000 MT Network Connection
- 8086 1176 PRO/1000 MT Desktop Adapter
- 8086 1276 PRO/1000 MT Desktop Adapter
- 1077 82541GI Gigabit Ethernet Controller
- 1179 0001 PRO/1000 MT Mobile Connection
- 8086 0077 PRO/1000 MT Mobile Connection
- 8086 1077 PRO/1000 MT Mobile Connection
- 1078 82541EI Gigabit Ethernet Controller
- 8086 1078 PRO/1000 MT Network Connection
- 1079 82546GB Gigabit Ethernet Controller
- 103c 12a6 HP Dual Port 1000Base-T [A9900A]
- 103c 12cf HP Core Dual Port 1000Base-T [AB352A]
- 4c53 1090 Cx9 / Vx9 mainboard
- 4c53 10b0 CL9 mainboard
- 8086 0079 PRO/1000 MT Dual Port Network Connection
- 8086 1079 PRO/1000 MT Dual Port Network Connection
- 8086 1179 PRO/1000 MT Dual Port Network Connection
- 8086 117a PRO/1000 MT Dual Port Server Adapter
- 107a 82546GB Gigabit Ethernet Controller
- 103c 12a8 HP Dual Port 1000base-SX [A9899A]
- 8086 107a PRO/1000 MF Dual Port Server Adapter
- 8086 127a PRO/1000 MF Dual Port Server Adapter
- 107b 82546GB Gigabit Ethernet Controller
- 8086 007b PRO/1000 MB Dual Port Server Connection
- 8086 107b PRO/1000 MB Dual Port Server Connection
- 1107 PRO/1000 MF Server Adapter (LX)
- 1130 82815 815 Chipset Host Bridge and Memory Controller Hub
- 1025 1016 Travelmate 612 TX
- 1043 8027 TUSL2-C Mainboard
- 104d 80df Vaio PCG-FX403
- 8086 4532 D815EEA2 mainboard
- 8086 4557 D815EGEW Mainboard
- 1131 82815 815 Chipset AGP Bridge
- 1132 82815 CGC [Chipset Graphics Controller]
- 1025 1016 Travelmate 612 TX
- 104d 80df Vaio PCG-FX403
- 8086 4532 D815EEA2 Mainboard
- 8086 4557 D815EGEW Mainboard
- 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller
- 8086 1161 82806AA PCI64 Hub APIC
- 1162 Xscale 80200 Big Endian Companion Chip
- 1200 Intel IXP1200 Network Processor
- 172a 0000 AEP SSL Accelerator
- 1209 8255xER/82551IT Fast Ethernet Controller
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- 4c53 1070 PC6 mainboard
- 1221 82092AA PCI to PCMCIA Bridge
- 1222 82092AA IDE Controller
- 1223 SAA7116
- 1225 82452KX/GX [Orion]
- 1226 82596 PRO/10 PCI
- 1227 82865 EtherExpress PRO/100A
- 1228 82556 EtherExpress PRO/100 Smart
-# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
- 1229 82557/8/9 [Ethernet Pro 100]
- 0e11 3001 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3002 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3003 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3004 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3005 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3006 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 3007 82559 Fast Ethernet LOM with Alert on LAN*
- 0e11 b01e NC3120 Fast Ethernet NIC
- 0e11 b01f NC3122 Fast Ethernet NIC (dual port)
- 0e11 b02f NC1120 Ethernet NIC
- 0e11 b04a Netelligent 10/100TX NIC with Wake on LAN
- 0e11 b0c6 NC3161 Fast Ethernet NIC (embedded, WOL)
- 0e11 b0c7 NC3160 Fast Ethernet NIC (embedded)
- 0e11 b0d7 NC3121 Fast Ethernet NIC (WOL)
- 0e11 b0dd NC3131 Fast Ethernet NIC (dual port)
- 0e11 b0de NC3132 Fast Ethernet Module (dual port)
- 0e11 b0e1 NC3133 Fast Ethernet Module (100-FX)
- 0e11 b134 NC3163 Fast Ethernet NIC (embedded, WOL)
- 0e11 b13c NC3162 Fast Ethernet NIC (embedded)
- 0e11 b144 NC3123 Fast Ethernet NIC (WOL)
- 0e11 b163 NC3134 Fast Ethernet NIC (dual port)
- 0e11 b164 NC3135 Fast Ethernet Upgrade Module (dual port)
- 0e11 b1a4 NC7131 Gigabit Server Adapter
- 1014 005c 82558B Ethernet Pro 10/100
- 1014 01bc 82559 Fast Ethernet LAN On Motherboard
- 1014 01f1 10/100 Ethernet Server Adapter
- 1014 01f2 10/100 Ethernet Server Adapter
- 1014 0207 Ethernet Pro/100 S
- 1014 0232 10/100 Dual Port Server Adapter
- 1014 023a ThinkPad R30
- 1014 105c Netfinity 10/100
- 1014 2205 ThinkPad A22p
- 1014 305c 10/100 EtherJet Management Adapter
- 1014 405c 10/100 EtherJet Adapter with Alert on LAN
- 1014 505c 10/100 EtherJet Secure Management Adapter
- 1014 605c 10/100 EtherJet Secure Management Adapter
- 1014 705c 10/100 Netfinity 10/100 Ethernet Security Adapter
- 1014 805c 10/100 Netfinity 10/100 Ethernet Security Adapter
- 1028 009b PowerEdge 2500/2550
- 1028 00ce PowerEdge 1400
- 1033 8000 PC-9821X-B06
- 1033 8016 PK-UG-X006
- 1033 801f PK-UG-X006
- 1033 8026 PK-UG-X006
- 1033 8063 82559-based Fast Ethernet Adapter
- 1033 8064 82559-based Fast Ethernet Adapter
- 103c 10c0 NetServer 10/100TX
- 103c 10c3 NetServer 10/100TX
- 103c 10ca NetServer 10/100TX
- 103c 10cb NetServer 10/100TX
- 103c 10e3 NetServer 10/100TX
- 103c 10e4 NetServer 10/100TX
- 103c 1200 NetServer 10/100TX
- 10c3 1100 SmartEther100 SC1100
- 10cf 1115 8255x-based Ethernet Adapter (10/100)
- 10cf 1143 8255x-based Ethernet Adapter (10/100)
- 1179 0001 8255x-based Ethernet Adapter (10/100)
- 1179 0002 PCI FastEther LAN on Docker
- 1179 0003 8255x-based Fast Ethernet
- 1259 2560 AT-2560 100
- 1259 2561 AT-2560 100 FX Ethernet Adapter
- 1266 0001 NE10/100 Adapter
- 13e9 1000 6221L-4U
- 144d 2501 SEM-2000 MiniPCI LAN Adapter
- 144d 2502 SEM-2100IL MiniPCI LAN Adapter
- 1668 1100 EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
- 4c53 1080 CT8 mainboard
- 8086 0001 EtherExpress PRO/100B (TX)
- 8086 0002 EtherExpress PRO/100B (T4)
- 8086 0003 EtherExpress PRO/10+
- 8086 0004 EtherExpress PRO/100 WfM
- 8086 0005 82557 10/100
- 8086 0006 82557 10/100 with Wake on LAN
- 8086 0007 82558 10/100 Adapter
- 8086 0008 82558 10/100 with Wake on LAN
- 8086 0009 EtherExpress PRO/100+
- 8086 000a EtherExpress PRO/100+ Management Adapter
- 8086 000b EtherExpress PRO/100+
- 8086 000c EtherExpress PRO/100+ Management Adapter
- 8086 000d EtherExpress PRO/100+ Alert On LAN II* Adapter
- 8086 000e EtherExpress PRO/100+ Management Adapter with Alert On LAN*
- 8086 000f EtherExpress PRO/100 Desktop Adapter
- 8086 0010 EtherExpress PRO/100 S Management Adapter
- 8086 0011 EtherExpress PRO/100 S Management Adapter
- 8086 0012 EtherExpress PRO/100 S Advanced Management Adapter (D)
- 8086 0013 EtherExpress PRO/100 S Advanced Management Adapter (E)
- 8086 0030 EtherExpress PRO/100 Management Adapter with Alert On LAN* GC
- 8086 0031 EtherExpress PRO/100 Desktop Adapter
- 8086 0040 EtherExpress PRO/100 S Desktop Adapter
- 8086 0041 EtherExpress PRO/100 S Desktop Adapter
- 8086 0042 EtherExpress PRO/100 Desktop Adapter
- 8086 0050 EtherExpress PRO/100 S Desktop Adapter
- 8086 1009 EtherExpress PRO/100+ Server Adapter
- 8086 100c EtherExpress PRO/100+ Server Adapter (PILA8470B)
- 8086 1012 EtherExpress PRO/100 S Server Adapter (D)
- 8086 1013 EtherExpress PRO/100 S Server Adapter (E)
- 8086 1015 EtherExpress PRO/100 S Dual Port Server Adapter
- 8086 1017 EtherExpress PRO/100+ Dual Port Server Adapter
- 8086 1030 EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
- 8086 1040 EtherExpress PRO/100 S Server Adapter
- 8086 1041 EtherExpress PRO/100 S Server Adapter
- 8086 1042 EtherExpress PRO/100 Server Adapter
- 8086 1050 EtherExpress PRO/100 S Server Adapter
- 8086 1051 EtherExpress PRO/100 Server Adapter
- 8086 1052 EtherExpress PRO/100 Server Adapter
- 8086 10f0 EtherExpress PRO/100+ Dual Port Adapter
- 8086 2009 EtherExpress PRO/100 S Mobile Adapter
- 8086 200d EtherExpress PRO/100 Cardbus
- 8086 200e EtherExpress PRO/100 LAN+V90 Cardbus Modem
- 8086 200f EtherExpress PRO/100 SR Mobile Adapter
- 8086 2010 EtherExpress PRO/100 S Mobile Combo Adapter
- 8086 2013 EtherExpress PRO/100 SR Mobile Combo Adapter
- 8086 2016 EtherExpress PRO/100 S Mobile Adapter
- 8086 2017 EtherExpress PRO/100 S Combo Mobile Adapter
- 8086 2018 EtherExpress PRO/100 SR Mobile Adapter
- 8086 2019 EtherExpress PRO/100 SR Combo Mobile Adapter
- 8086 2101 EtherExpress PRO/100 P Mobile Adapter
- 8086 2102 EtherExpress PRO/100 SP Mobile Adapter
- 8086 2103 EtherExpress PRO/100 SP Mobile Adapter
- 8086 2104 EtherExpress PRO/100 SP Mobile Adapter
- 8086 2105 EtherExpress PRO/100 SP Mobile Adapter
- 8086 2106 EtherExpress PRO/100 P Mobile Adapter
- 8086 2107 EtherExpress PRO/100 Network Connection
- 8086 2108 EtherExpress PRO/100 Network Connection
- 8086 2200 EtherExpress PRO/100 P Mobile Combo Adapter
- 8086 2201 EtherExpress PRO/100 P Mobile Combo Adapter
- 8086 2202 EtherExpress PRO/100 SP Mobile Combo Adapter
- 8086 2203 EtherExpress PRO/100+ MiniPCI
- 8086 2204 EtherExpress PRO/100+ MiniPCI
- 8086 2205 EtherExpress PRO/100 SP Mobile Combo Adapter
- 8086 2206 EtherExpress PRO/100 SP Mobile Combo Adapter
- 8086 2207 EtherExpress PRO/100 SP Mobile Combo Adapter
- 8086 2208 EtherExpress PRO/100 P Mobile Combo Adapter
- 8086 2402 EtherExpress PRO/100+ MiniPCI
- 8086 2407 EtherExpress PRO/100+ MiniPCI
- 8086 2408 EtherExpress PRO/100+ MiniPCI
- 8086 2409 EtherExpress PRO/100+ MiniPCI
- 8086 240f EtherExpress PRO/100+ MiniPCI
- 8086 2410 EtherExpress PRO/100+ MiniPCI
- 8086 2411 EtherExpress PRO/100+ MiniPCI
- 8086 2412 EtherExpress PRO/100+ MiniPCI
- 8086 2413 EtherExpress PRO/100+ MiniPCI
- 8086 3000 82559 Fast Ethernet LAN on Motherboard
- 8086 3001 82559 Fast Ethernet LOM with Basic Alert on LAN*
- 8086 3002 82559 Fast Ethernet LOM with Alert on LAN II*
- 8086 3006 EtherExpress PRO/100 S Network Connection
- 8086 3007 EtherExpress PRO/100 S Network Connection
- 8086 3008 EtherExpress PRO/100 Network Connection
- 8086 3010 EtherExpress PRO/100 S Network Connection
- 8086 3011 EtherExpress PRO/100 S Network Connection
- 8086 3012 EtherExpress PRO/100 Network Connection
- 8086 3411 SDS2 Mainboard
- 122d 430FX - 82437FX TSC [Triton I]
- 122e 82371FB PIIX ISA [Triton I]
- 1230 82371FB PIIX IDE [Triton I]
- 1231 DSVD Modem
- 1234 430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
- 1235 430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
- 1237 440FX - 82441FX PMC [Natoma]
- 1239 82371FB PIIX IDE Interface
- 123b 82380PB PCI to PCI Docking Bridge
- 123c 82380AB (MISA) Mobile PCI-to-ISA Bridge
- 123d 683053 Programmable Interrupt Device
-# in" hidden" mode
- 123e 82466GX (IHPC) Integrated Hot-Plug Controller
- 123f 82466GX Integrated Hot-Plug Controller (IHPC)
- 1240 82752 (752) AGP Graphics Accelerator
- 124b 82380FB (MPCI2) Mobile Docking Controller
- 1250 430HX - 82439HX TXC [Triton II]
- 1360 82806AA PCI64 Hub PCI Bridge
- 1361 82806AA PCI64 Hub Controller (HRes)
- 8086 1361 82806AA PCI64 Hub Controller (HRes)
- 8086 8000 82806AA PCI64 Hub Controller (HRes)
- 1460 82870P2 P64H2 Hub PCI Bridge
- 1461 82870P2 P64H2 I/OxAPIC
- 15d9 3480 P4DP6
- 4c53 1090 Cx9 / Vx9 mainboard
- 1462 82870P2 P64H2 Hot Plug Controller
- 1960 80960RP [i960RP Microprocessor]
- 101e 0431 MegaRAID 431 RAID Controller
- 101e 0438 MegaRAID 438 Ultra2 LVD RAID Controller
- 101e 0466 MegaRAID 466 Express Plus RAID Controller
- 101e 0467 MegaRAID 467 Enterprise 1500 RAID Controller
- 101e 0490 MegaRAID 490 Express 300 RAID Controller
- 101e 0762 MegaRAID 762 Express RAID Controller
- 101e 09a0 PowerEdge Expandable RAID Controller 2/SC
- 1028 0467 PowerEdge Expandable RAID Controller 2/DC
- 1028 1111 PowerEdge Expandable RAID Controller 2/SC
- 103c 03a2 MegaRAID
- 103c 10c6 MegaRAID 438, HP NetRAID-3Si
- 103c 10c7 MegaRAID T5, Integrated HP NetRAID
- 103c 10cc MegaRAID, Integrated HP NetRAID
- 103c 10cd HP NetRAID-1Si
- 105a 0000 SuperTrak
- 105a 2168 SuperTrak Pro
- 105a 5168 SuperTrak66/100
- 1111 1111 MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
- 1111 1112 PowerEdge Expandable RAID Controller 2/SC
- 113c 03a2 MegaRAID
- e4bf 1010 CG1-RADIO
- e4bf 1020 CU2-QUARTET
- e4bf 1040 CU1-CHORUS
- e4bf 3100 CX1-BAND
- 1962 80960RM [i960RM Microprocessor]
- 105a 0000 SuperTrak SX6000 I2O CPU
- 1a21 82840 840 (Carmel) Chipset Host Bridge (Hub A)
- 1a23 82840 840 (Carmel) Chipset AGP Bridge
- 1a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B)
- 1a30 82845 845 (Brookdale) Chipset Host Bridge
- 1028 010e Optiplex GX240
- 1a31 82845 845 (Brookdale) Chipset AGP Bridge
- 2410 82801AA ISA Bridge (LPC)
- 2411 82801AA IDE
- 2412 82801AA USB
- 2413 82801AA SMBus
- 2415 82801AA AC'97 Audio
- 1028 0095 Precision Workstation 220 Integrated Digital Audio
- 11d4 0040 SoundMAX Integrated Digital Audio
- 11d4 0048 SoundMAX Integrated Digital Audio
- 11d4 5340 SoundMAX Integrated Digital Audio
- 2416 82801AA AC'97 Modem
- 2418 82801AA PCI Bridge
- 2420 82801AB ISA Bridge (LPC)
- 2421 82801AB IDE
- 2422 82801AB USB
- 2423 82801AB SMBus
- 2425 82801AB AC'97 Audio
- 11d4 0040 SoundMAX Integrated Digital Audio
- 11d4 0048 SoundMAX Integrated Digital Audio
- 2426 82801AB AC'97 Modem
- 2428 82801AB PCI Bridge
- 2440 82801BA ISA Bridge (LPC)
- 2442 82801BA/BAM USB (Hub #1)
- 1014 01c6 Netvista A40/A40p
- 1025 1016 Travelmate 612 TX
- 1028 010e Optiplex GX240
- 1043 8027 TUSL2-C Mainboard
- 104d 80df Vaio PCG-FX403
- 147b 0507 TH7II-RAID
- 8086 4532 D815EEA2 mainboard
- 8086 4557 D815EGEW Mainboard
- 2443 82801BA/BAM SMBus
- 1014 01c6 Netvista A40/A40p
- 1025 1016 Travelmate 612 TX
- 1028 010e Optiplex GX240
- 1043 8027 TUSL2-C Mainboard
- 104d 80df Vaio PCG-FX403
- 147b 0507 TH7II-RAID
- 8086 4532 D815EEA2 mainboard
- 8086 4557 D815EGEW Mainboard
- 2444 82801BA/BAM USB (Hub #2)
- 1025 1016 Travelmate 612 TX
- 1028 010e Optiplex GX240
- 1043 8027 TUSL2-C Mainboard
- 104d 80df Vaio PCG-FX403
- 147b 0507 TH7II-RAID
- 8086 4532 D815EEA2 mainboard
- 2445 82801BA/BAM AC'97 Audio
- 1014 01c6 Netvista A40/A40p
- 1025 1016 Travelmate 612 TX
- 104d 80df Vaio PCG-FX403
- 1462 3370 STAC9721 AC
- 147b 0507 TH7II-RAID
- 8086 4557 D815EGEW Mainboard
- 2446 82801BA/BAM AC'97 Modem
- 1025 1016 Travelmate 612 TX
- 104d 80df Vaio PCG-FX403
- 2448 82801 Mobile PCI Bridge
- 2449 82801BA/BAM/CA/CAM Ethernet Controller
- 0e11 0012 EtherExpress PRO/100 VM
- 0e11 0091 EtherExpress PRO/100 VE
- 1014 01ce EtherExpress PRO/100 VE
- 1014 01dc EtherExpress PRO/100 VE
- 1014 01eb EtherExpress PRO/100 VE
- 1014 01ec EtherExpress PRO/100 VE
- 1014 0202 EtherExpress PRO/100 VE
- 1014 0205 EtherExpress PRO/100 VE
- 1014 0217 EtherExpress PRO/100 VE
- 1014 0234 EtherExpress PRO/100 VE
- 1014 023d EtherExpress PRO/100 VE
- 1014 0244 EtherExpress PRO/100 VE
- 1014 0245 EtherExpress PRO/100 VE
- 1014 0265 PRO/100 VE Desktop Connection
- 1014 0267 PRO/100 VE Desktop Connection
- 1014 026a PRO/100 VE Desktop Connection
- 109f 315d EtherExpress PRO/100 VE
- 109f 3181 EtherExpress PRO/100 VE
- 1179 ff01 PRO/100 VE Network Connection
- 1186 7801 EtherExpress PRO/100 VE
- 144d 2602 HomePNA 1M CNR
- 8086 3010 EtherExpress PRO/100 VE
- 8086 3011 EtherExpress PRO/100 VM
- 8086 3012 82562EH based Phoneline
- 8086 3013 EtherExpress PRO/100 VE
- 8086 3014 EtherExpress PRO/100 VM
- 8086 3015 82562EH based Phoneline
- 8086 3016 EtherExpress PRO/100 P Mobile Combo
- 8086 3017 EtherExpress PRO/100 P Mobile
- 8086 3018 EtherExpress PRO/100
- 244a 82801BAM IDE U100
- 1025 1016 Travelmate 612TX
- 104d 80df Vaio PCG-FX403
- 244b 82801BA IDE U100
- 1014 01c6 Netvista A40/A40p
- 1028 010e Optiplex GX240
- 1043 8027 TUSL2-C Mainboard
- 147b 0507 TH7II-RAID
- 8086 4532 D815EEA2 mainboard
- 8086 4557 D815EGEW Mainboard
- 244c 82801BAM ISA Bridge (LPC)
- 244e 82801 PCI Bridge
- 1014 0267 NetVista A30p
- 2450 82801E ISA Bridge (LPC)
- 2452 82801E USB
- 2453 82801E SMBus
- 2459 82801E Ethernet Controller 0
- 245b 82801E IDE U100
- 245d 82801E Ethernet Controller 1
- 245e 82801E PCI Bridge
- 2480 82801CA LPC Interface Controller
- 2482 82801CA/CAM USB (Hub #1)
- 1014 0220 ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 15d9 3480 P4DP6
- 8086 1958 vpr Matrix 170B4
- 8086 3424 SE7501HG2 Mainboard
- 8086 4541 Latitude C640
- 2483 82801CA/CAM SMBus Controller
- 1014 0220 ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 15d9 3480 P4DP6
- 8086 1958 vpr Matrix 170B4
- 2484 82801CA/CAM USB (Hub #2)
- 1014 0220 ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 15d9 3480 P4DP6
- 8086 1958 vpr Matrix 170B4
- 2485 82801CA/CAM AC'97 Audio Controller
- 1013 5959 Crystal WMD Audio Codec
- 1014 0222 ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653)
- 1014 0508 ThinkPad T30
- 1014 051c ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 144d c006 vpr Matrix 170B4
- 2486 82801CA/CAM AC'97 Modem Controller
- 1014 0223 ThinkPad A/T/X Series
- 1014 0503 ThinkPad R31 2656BBG
- 1014 051a ThinkPad A/T/X Series
- 101f 1025 Acer 620 Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 1179 0001 Toshiba Satellite 1110 Z15 internal Modem
- 134d 4c21 Dell Inspiron 2100 internal modem
- 144d 2115 vpr Matrix 170B4 internal modem
- 14f1 5421 MD56ORD V.92 MDC Modem
- 2487 82801CA/CAM USB (Hub #3)
- 1014 0220 ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 15d9 3480 P4DP6
- 8086 1958 vpr Matrix 170B4
- 248a 82801CAM IDE U100
- 1014 0220 ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 8086 1958 vpr Matrix 170B4
- 8086 4541 Latitude C640
- 248b 82801CA Ultra ATA Storage Controller
- 15d9 3480 P4DP6
- 248c 82801CAM ISA Bridge (LPC)
- 24c0 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
- 1014 0267 NetVista A30p
- 1462 5800 845PE Max (MS-6580)
- 24c1 82801DBL (ICH4-L) IDE Controller
- 24c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0126 Optiplex GX260
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1462 5800 845PE Max (MS-6580)
- 1509 2990 Averatec 5110H laptop
- 4c53 1090 Cx9 / Vx9 mainboard
- 24c3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0126 Optiplex GX260
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1458 24c2 GA-8PE667 Ultra
- 1462 5800 845PE Max (MS-6580)
- 4c53 1090 Cx9 / Vx9 mainboard
- 24c4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0126 Optiplex GX260
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1462 5800 845PE Max (MS-6580)
- 1509 2990 Averatec 5110H
- 4c53 1090 Cx9 / Vx9 mainboard
- 24c5 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
- 0e11 00b8 Analog Devices Inc. codec [SoundMAX]
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1458 a002 GA-8PE667 Ultra
- 1462 5800 845PE Max (MS-6580)
- 24c6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
- 1025 005a TravelMate 290
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 24c7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0126 Optiplex GX260
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1462 5800 845PE Max (MS-6580)
- 1509 2990 Averatec 5110H
- 4c53 1090 Cx9 / Vx9 mainboard
- 24ca 82801DBM (ICH4-M) IDE Controller
- 1025 005a TravelMate 290
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 24cb 82801DB (ICH4) IDE Controller
- 1014 0267 NetVista A30p
- 1028 0126 Optiplex GX260
- 1458 24c2 GA-8PE667 Ultra
- 1462 5800 845PE Max (MS-6580)
- 4c53 1090 Cx9 / Vx9 mainboard
- 24cc 82801DBM (ICH4-M) LPC Interface Bridge
- 24cd 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
- 1014 0267 NetVista A30p
- 1025 005a TravelMate 290
- 1028 0126 Optiplex GX260
- 1028 0163 Latitude D505
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 1071 8160 MIM2000
- 1462 3981 845PE Max (MS-6580)
- 1509 1968 Averatec 5110H
- 4c53 1090 Cx9 / Vx9 mainboard
- 24d0 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
- 24d1 82801EB (ICH5) SATA Controller
- 103c 12bc d530 CMT (DG746A)
- 1458 24d1 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
- 1028 0183 PowerEdge 1800
- 103c 12bc d530 CMT (DG746A)
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000/8KNXP motherboard
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24d3 82801EB/ER (ICH5/ICH5R) SMBus Controller
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
- 1028 0183 PowerEdge 1800
- 103c 12bc d530 CMT (DG746A)
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
- 103c 12bc Analog Devices codec [SoundMAX Integrated Digital Audio]
- 1043 80f3 P4P800 Mainboard
-# Again, I suppose they use the same in different subsystems
- 1458 a002 GA-8IPE1000/8KNXP motherboard
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 a000 D865PERL mainboard
- 8086 e000 D865PERL mainboard
- 24d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
- 24d7 82801EB/ER (ICH5/ICH5R) USB UHCI #3
- 1028 0183 PowerEdge 1800
- 103c 12bc d530 CMT (DG746A)
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24db 82801EB/ER (ICH5/ICH5R) IDE Controller
- 103c 12bc d530 CMT (DG746A)
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 1462 7580 MSI 875P
- 8086 24db P4C800 Mainboard
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24dc 82801EB (ICH5) LPC Interface Bridge
- 24dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
- 1028 0183 PowerEdge 1800
- 103c 12bc d530 CMT (DG746A)
- 1043 80a6 P4P800 Mainboard
- 1458 5006 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
- 1043 80a6 P4P800 Mainboard
- 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
- 1462 7280 865PE Neo2 (MS-6728)
- 8086 3427 S875WP1-E mainboard
- 8086 524c D865PERL mainboard
- 24df 82801ER (ICH5R) SATA Controller
- 2500 82820 820 (Camino) Chipset Host Bridge (MCH)
- 1028 0095 Precision Workstation 220 Chipset
- 1043 801c P3C-2000 system chipset
- 2501 82820 820 (Camino) Chipset Host Bridge (MCH)
- 1043 801c P3C-2000 system chipset
- 250b 82820 820 (Camino) Chipset Host Bridge
- 250f 82820 820 (Camino) Chipset AGP Bridge
- 2520 82805AA MTH Memory Translator Hub
- 2521 82804AA MRH-S Memory Repeater Hub for SDRAM
- 2530 82850 850 (Tehama) Chipset Host Bridge (MCH)
- 147b 0507 TH7II-RAID
- 2531 82860 860 (Wombat) Chipset Host Bridge (MCH)
- 2532 82850 850 (Tehama) Chipset AGP Bridge
- 2533 82860 860 (Wombat) Chipset AGP Bridge
- 2534 82860 860 (Wombat) Chipset PCI Bridge
- 2540 E7500 Memory Controller Hub
- 15d9 3480 P4DP6
- 2541 E7500/E7501 Host RASUM Controller
- 15d9 3480 P4DP6
- 4c53 1090 Cx9 / Vx9 mainboard
- 8086 3424 SE7501HG2 Mainboard
- 2543 E7500/E7501 Hub Interface B PCI-to-PCI Bridge
- 2544 E7500/E7501 Hub Interface B RASUM Controller
- 4c53 1090 Cx9 / Vx9 mainboard
- 2545 E7500/E7501 Hub Interface C PCI-to-PCI Bridge
- 2546 E7500/E7501 Hub Interface C RASUM Controller
- 2547 E7500/E7501 Hub Interface D PCI-to-PCI Bridge
- 2548 E7500/E7501 Hub Interface D RASUM Controller
- 254c E7501 Memory Controller Hub
- 4c53 1090 Cx9 / Vx9 mainboard
- 8086 3424 SE7501HG2 Mainboard
- 2550 E7505 Memory Controller Hub
- 2551 E7505/E7205 Series RAS Controller
- 2552 E7505/E7205 PCI-to-AGP Bridge
- 2553 E7505 Hub Interface B PCI-to-PCI Bridge
- 2554 E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
- 255d E7205 Memory Controller Hub
- 2560 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
- 1028 0126 Optiplex GX260
- 1458 2560 GA-8PE667 Ultra
- 1462 5800 845PE Max (MS-6580)
- 2561 82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
- 2562 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
- 1014 0267 NetVista A30p
- 2570 82865G/PE/P DRAM Controller/Host-Hub Interface
- 1043 80f2 P4P800 Mainboard
- 1458 2570 GA-8IPE1000 Pro2 motherboard (865PE)
- 2571 82865G/PE/P PCI to AGP Controller
- 2572 82865G Integrated Graphics Controller
- 2573 82865G/PE/P PCI to CSA Bridge
- 2576 82865G/PE/P Processor to I/O Memory Interface
- 2578 82875P/E7210 Memory Controller Hub
- 1458 2578 GA-8KNXP motherboard (875P)
- 1462 7580 MS-6758 (875P Neo)
-# Motherboard P4SCE
- 15d9 4580 Super Micro Computer Inc. P4SCE
- 2579 82875P Processor to AGP Controller
- 257b 82875P/E7210 Processor to PCI to CSA Bridge
- 257e 82875P/E7210 Processor to I/O Memory Interface
- 2580 915G/P/GV/GL/PL/910GL Processor to I/O Controller
- 2581 915G/P/GV/GL/PL/910GL PCI Express Root Port
- 2582 82915G/GV/910GL Express Chipset Family Graphics Controller
- 1028 1079 Optiplex GX280
- 2584 925X/XE Memory Controller Hub
- 2585 925X/XE PCI Express Root Port
- 2588 E7220/E7221 Memory Controller Hub
- 2589 E7220/E7221 PCI Express Root Port
- 258a E7221 Integrated Graphics Controller
- 2590 Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
- 2591 Mobile 915GM/PM Express PCI Express Root Port
- 2592 Mobile 915GM/GMS/910GML Express Graphics Controller
- 25a1 6300ESB LPC Interface Controller
- 25a2 6300ESB PATA Storage Controller
- 4c53 10b0 CL9 mainboard
- 25a3 6300ESB SATA Storage Controller
- 4c53 10b0 CL9 mainboard
- 25a4 6300ESB SMBus Controller
- 4c53 10b0 CL9 mainboard
- 25a6 6300ESB AC'97 Audio Controller
- 4c53 10b0 CL9 mainboard
- 25a7 6300ESB AC'97 Modem Controller
- 25a9 6300ESB USB Universal Host Controller
- 4c53 10b0 CL9 mainboard
- 25aa 6300ESB USB Universal Host Controller
- 4c53 10b0 CL9 mainboard
- 25ab 6300ESB Watchdog Timer
- 4c53 10b0 CL9 mainboard
- 25ac 6300ESB I/O Advanced Programmable Interrupt Controller
- 4c53 10b0 CL9 mainboard
- 25ad 6300ESB USB2 Enhanced Host Controller
- 25ae 6300ESB 64-bit PCI-X Bridge
- 25b0 6300ESB SATA RAID Controller
- 2600 E8500 Hub Interface
- 2601 E8500 PCI Express x4 Port D
- 2602 E8500 PCI Express x4 Port C0
- 2603 E8500 PCI Express x4 Port C1
- 2604 E8500 PCI Express x4 Port B0
- 2605 E8500 PCI Express x4 Port B1
- 2606 E8500 PCI Express x4 Port A0
- 2607 E8500 PCI Express x4 Port A1
- 2608 E8500 PCI Express x8 Port C
- 2609 E8500 PCI Express x8 Port B
- 260a E8500 PCI Express x8 Port A
- 260c E8500 IMI Registers
- 2610 E8500 System Bus, Boot, and Interrupt Registers
- 2611 E8500 Address Mapping Registers
- 2612 E8500 RAS Registers
- 2613 E8500 Reserved Registers
- 2614 E8500 Reserved Registers
- 2615 E8500 Miscellaneous Registers
- 2617 E8500 Reserved Registers
- 2618 E8500 Reserved Registers
- 2619 E8500 Reserved Registers
- 261a E8500 Reserved Registers
- 261b E8500 Reserved Registers
- 261c E8500 Reserved Registers
- 261d E8500 Reserved Registers
- 261e E8500 Reserved Registers
- 2620 E8500 eXternal Memory Bridge
- 2621 E8500 XMB Miscellaneous Registers
- 2622 E8500 XMB Memory Interleaving Registers
- 2623 E8500 XMB DDR Initialization and Calibration
- 2624 E8500 XMB Reserved Registers
- 2625 E8500 XMB Reserved Registers
- 2626 E8500 XMB Reserved Registers
- 2627 E8500 XMB Reserved Registers
- 2640 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
- 2641 82801FBM (ICH6M) LPC Interface Bridge
- 2642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
- 2651 82801FB/FW (ICH6/ICH6W) SATA Controller
- 1028 0179 Optiplex GX280
- 2652 82801FR/FRW (ICH6R/ICH6RW) SATA Controller
- 2653 82801FBM (ICH6M) SATA Controller
- 2658 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
- 1028 0179 Optiplex GX280
- 2659 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
- 1028 0179 Optiplex GX280
- 265a 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
- 1028 0179 Optiplex GX280
- 265b 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
- 1028 0179 Optiplex GX280
- 265c 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
- 1028 0179 Optiplex GX280
- 2660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
- 2662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
- 2664 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
- 2666 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
- 2668 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
- 266a 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
- 1028 0179 Optiplex GX280
- 266c 82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
- 266d 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
- 266e 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
- 1028 0179 Optiplex GX280
- 266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
- 2770 Memory Controller Hub
- 2771 PCI Express Graphics Port
- 2772 Integrated Graphics Controller
- 2774 Workstation Memory Controller Hub
- 2775 PCI Express Graphics Port
- 2776 Integrated Graphics Controller
- 2778 Server Memory Controller Hub
- 2779 PCI Express Root Port
- 2782 82915G Express Chipset Family Graphics Controller
- 2792 Mobile 915GM/GMS/910GML Express Graphics Controller
- 27b8 I/O Controller Hub LPC
- 27b9 Mobile I/O Controller Hub LPC
- 27c0 I/O Controller Hub SATA cc=IDE
- 27c1 I/O Controller Hub SATA cc=AHCI
- 27c3 I/O Controller Hub SATA cc=RAID
- 27c4 Mobile I/O Controller Hub SATA cc=IDE
- 27c5 Mobile I/O Controller Hub SATA cc=AHCI
- 27c8 I/O Controller Hub UHCI USB #1
- 27c9 I/O Controller Hub UHCI USB #2
- 27ca I/O Controller Hub UHCI USB #3
- 27cb I/O Controller Hub UHCI USB #4
- 27cc I/O Controller Hub EHCI USB
- 27d0 I/O Controller Hub PCI Express Port 1
- 27d2 I/O Controller Hub PCI Express Port 2
- 27d4 I/O Controller Hub PCI Express Port 3
- 27d6 I/O Controller Hub PCI Express Port 4
- 27d8 I/O Controller Hub High Definition Audio
- 27da I/O Controller Hub SMBus
- 27dc I/O Controller Hub LAN
- 27dd I/O Controller Hub AC'97 Modem
- 27de I/O Controller Hub AC'97 Audio
- 27df I/O Controller Hub PATA
- 27e0 I/O Controller Hub PCI Express Port 5
- 27e2 I/O Controller Hub PCI Express Port 6
- 3092 Integrated RAID
- 3200 GD31244 PCI-X SATA HBA
- 3340 82855PM Processor to I/O Controller
- 1025 005a TravelMate 290
- 103c 088c nc8000 laptop
- 103c 0890 nc6000 laptop
- 3341 82855PM Processor to AGP Controller
- 3575 82830 830 Chipset Host Bridge
- 1014 021d ThinkPad A/T/X Series
- 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
- 3576 82830 830 Chipset AGP Bridge
- 3577 82830 CGC [Chipset Graphics Controller]
- 1014 0513 ThinkPad A/T/X Series
- 3578 82830 830 Chipset Host Bridge
- 3580 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
- 1028 0163 Latitude D505
- 4c53 10b0 CL9 mainboard
- 3581 82852/82855 GM/GME/PM/GMV Processor to AGP Controller
- 3582 82852/855GM Integrated Graphics Device
- 1028 0163 Latitude D505
- 4c53 10b0 CL9 mainboard
- 3584 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
- 1028 0163 Latitude D505
- 4c53 10b0 CL9 mainboard
- 3585 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
- 1028 0163 Latitude D505
- 4c53 10b0 CL9 mainboard
- 3590 E7520 Memory Controller Hub
- 3591 E7525/E7520 Error Reporting Registers
- 3592 E7320 Memory Controller Hub
- 3593 E7320 Error Reporting Registers
- 3594 E7520 DMA Controller
- 3595 E7525/E7520/E7320 PCI Express Port A
- 3596 E7525/E7520/E7320 PCI Express Port A1
- 3597 E7525/E7520 PCI Express Port B
- 3598 E7520 PCI Express Port B1
- 3599 E7520 PCI Express Port C
- 359a E7520 PCI Express Port C1
- 359b E7525/E7520/E7320 Extended Configuration Registers
- 359e E7525 Memory Controller Hub
- 4220 PRO/Wireless 2200BG
- 4223 PRO/Wireless 2915ABG MiniPCI Adapter
- 5200 EtherExpress PRO/100 Intelligent Server
- 5201 EtherExpress PRO/100 Intelligent Server
- 8086 0001 EtherExpress PRO/100 Server Ethernet Adapter
- 530d 80310 IOP [IO Processor]
- 7000 82371SB PIIX3 ISA [Natoma/Triton II]
- 7010 82371SB PIIX3 IDE [Natoma/Triton II]
- 7020 82371SB PIIX3 USB [Natoma/Triton II]
- 7030 430VX - 82437VX TVX [Triton VX]
- 7050 Intel Intercast Video Capture Card
- 7100 430TX - 82439TX MTXC
- 7110 82371AB/EB/MB PIIX4 ISA
- 15ad 1976 virtualHW v3
- 7111 82371AB/EB/MB PIIX4 IDE
- 15ad 1976 virtualHW v3
- 7112 82371AB/EB/MB PIIX4 USB
- 15ad 1976 virtualHW v3
- 7113 82371AB/EB/MB PIIX4 ACPI
- 15ad 1976 virtualHW v3
- 7120 82810 GMCH [Graphics Memory Controller Hub]
- 4c53 1040 CL7 mainboard
- 4c53 1060 PC7 mainboard
- 7121 82810 CGC [Chipset Graphics Controller]
- 4c53 1040 CL7 mainboard
- 4c53 1060 PC7 mainboard
- 8086 4341 Cayman (CA810) Mainboard
- 7122 82810 DC-100 GMCH [Graphics Memory Controller Hub]
- 7123 82810 DC-100 CGC [Chipset Graphics Controller]
- 7124 82810E DC-133 GMCH [Graphics Memory Controller Hub]
- 7125 82810E DC-133 CGC [Chipset Graphics Controller]
- 7126 82810 DC-133 System and Graphics Controller
- 7128 82810-M DC-100 System and Graphics Controller
- 712a 82810-M DC-133 System and Graphics Controller
- 7180 440LX/EX - 82443LX/EX Host bridge
- 7181 440LX/EX - 82443LX/EX AGP bridge
- 7190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge
- 0e11 0500 Armada 1750 Laptop System Chipset
- 0e11 b110 Armada M700/E500
- 1179 0001 Toshiba Tecra 8100 Laptop System Chipset
- 15ad 1976 virtualHW v3
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- 7191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
- 7192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
- 0e11 0460 Armada 1700 Laptop System Chipset
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 7194 82440MX Host Bridge
- 1033 0000 Versa Note Vxi
- 4c53 10a0 CA3/CR3 mainboard
- 7195 82440MX AC'97 Audio Controller
- 1033 80cc Versa Note VXi
- 10cf 1099 QSound_SigmaTel Stac97 PCI Audio
- 11d4 0040 SoundMAX Integrated Digital Audio
- 11d4 0048 SoundMAX Integrated Digital Audio
- 7196 82440MX AC'97 Modem Controller
- 7198 82440MX ISA Bridge
- 7199 82440MX EIDE Controller
- 719a 82440MX USB Universal Host Controller
- 719b 82440MX Power Management Controller
- 71a0 440GX - 82443GX Host bridge
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- 71a1 440GX - 82443GX AGP bridge
- 71a2 440GX - 82443GX Host bridge (AGP disabled)
- 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
- 7600 82372FB PIIX5 ISA
- 7601 82372FB PIIX5 IDE
- 7602 82372FB PIIX5 USB
- 7603 82372FB PIIX5 SMBus
- 7800 82740 (i740) AGP Graphics Accelerator
- 003d 0008 Starfighter AGP
- 003d 000b Starfighter AGP
- 1092 0100 Stealth II G460
- 10b4 201a Lightspeed 740
- 10b4 202f Lightspeed 740
- 8086 0000 Terminator 2x/i
- 8086 0100 Intel740 Graphics Accelerator
- 84c4 450KX/GX [Orion] - 82454KX/GX PCI bridge
- 84c5 450KX/GX [Orion] - 82453KX/GX Memory controller
- 84ca 450NX - 82451NX Memory & I/O Controller
- 84cb 450NX - 82454NX/84460GX PCI Expander Bridge
- 84e0 460GX - 84460GX System Address Controller (SAC)
- 84e1 460GX - 84460GX System Data Controller (SDC)
- 84e2 460GX - 84460GX AGP Bridge (GXB function 2)
- 84e3 460GX - 84460GX Memory Address Controller (MAC)
- 84e4 460GX - 84460GX Memory Data Controller (MDC)
- 84e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
- 84ea 460GX - 84460GX AGP Bridge (GXB function 1)
- 8500 IXP4XX - Intel Network Processor family. IXP420, IXP421, IXP422, IXP425 and IXC1100
- 1993 0dee mGuard-PCI AV#1
- 1993 0def mGuard-PCI AV#0
- 9000 IXP2000 Family Network Processor
- 9001 IXP2400 Network Processor
- 9004 IXP2800 Network Processor
- 9621 Integrated RAID
- 9622 Integrated RAID
- 9641 Integrated RAID
- 96a1 Integrated RAID
-# retail verson
- a01f PRO/10GbE LR Server Adapter
-# OEM version
- a11f PRO/10GbE LR Server Adapter
- b152 21152 PCI-to-PCI Bridge
-# observed, and documented in Intel revision note; new mask of 1011:0026
- b154 21154 PCI-to-PCI Bridge
- b555 21555 Non transparent PCI-to-PCI Bridge
- 12d9 000a PCI VoIP Gateway
- 4c53 1050 CT7 mainboard
- 4c53 1051 CE7 mainboard
- e4bf 1000 CC8-1-BLUES
- ffff 450NX/GX [Orion] - 82453KX/GX Memory controller [BUG]
-8401 TRENDware International Inc.
-8800 Trigem Computer Inc.
- 2008 Video assistent component
-8866 T-Square Design Inc.
-8888 Silicon Magic
-# 8c4a is not Winbond but there is a board misprogrammed
-8c4a Winbond
- 1980 W89C940 misprogrammed [ne2k]
-8e0e Computone Corporation
-8e2e KTI
- 3000 ET32P2
-9004 Adaptec
- 0078 AHA-2940U_CN
- 1078 AIC-7810
- 1160 AIC-1160 [Family Fibre Channel Adapter]
- 2178 AIC-7821
- 3860 AHA-2930CU
- 3b78 AHA-4844W/4844UW
- 5075 AIC-755x
- 5078 AHA-7850
- 9004 7850 AHA-2904/Integrated AIC-7850
- 5175 AIC-755x
- 5178 AIC-7851
- 5275 AIC-755x
- 5278 AIC-7852
- 5375 AIC-755x
- 5378 AIC-7850
- 5475 AIC-755x
- 5478 AIC-7850
- 5575 AVA-2930
- 5578 AIC-7855
- 5647 ANA-7711 TCP Offload Engine
- 9004 7710 ANA-7711F TCP Offload Engine - Optical
- 9004 7711 ANA-7711LP TCP Offload Engine - Copper
- 5675 AIC-755x
- 5678 AIC-7856
- 5775 AIC-755x
- 5778 AIC-7850
- 5800 AIC-5800
- 5900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
- 5905 ANA-5910A/5930A/5940A ATM Adapter
- 6038 AIC-3860
- 6075 AIC-1480 / APA-1480
- 9004 7560 AIC-1480 / APA-1480 Cardbus
- 6078 AIC-7860
- 6178 AIC-7861
- 9004 7861 AHA-2940AU Single
- 6278 AIC-7860
- 6378 AIC-7860
- 6478 AIC-786x
- 6578 AIC-786x
- 6678 AIC-786x
- 6778 AIC-786x
- 6915 ANA620xx/ANA69011A
- 9004 0008 ANA69011A/TX 10/100
- 9004 0009 ANA69011A/TX 10/100
- 9004 0010 ANA62022 2-port 10/100
- 9004 0018 ANA62044 4-port 10/100
- 9004 0019 ANA62044 4-port 10/100
- 9004 0020 ANA62022 2-port 10/100
- 9004 0028 ANA69011A/TX 10/100
- 9004 8008 ANA69011A/TX 64 bit 10/100
- 9004 8009 ANA69011A/TX 64 bit 10/100
- 9004 8010 ANA62022 2-port 64 bit 10/100
- 9004 8018 ANA62044 4-port 64 bit 10/100
- 9004 8019 ANA62044 4-port 64 bit 10/100
- 9004 8020 ANA62022 2-port 64 bit 10/100
- 9004 8028 ANA69011A/TX 64 bit 10/100
- 7078 AHA-294x / AIC-7870
- 7178 AHA-2940/2940W / AIC-7871
- 7278 AHA-3940/3940W / AIC-7872
- 7378 AHA-3985 / AIC-7873
- 7478 AHA-2944/2944W / AIC-7874
- 7578 AHA-3944/3944W / AIC-7875
- 7678 AHA-4944W/UW / AIC-7876
- 7710 ANA-7711F Network Accelerator Card (NAC) - Optical
- 7711 ANA-7711C Network Accelerator Card (NAC) - Copper
- 7778 AIC-787x
- 7810 AIC-7810
- 7815 AIC-7815 RAID+Memory Controller IC
- 9004 7815 ARO-1130U2 RAID Controller
- 9004 7840 AIC-7815 RAID+Memory Controller IC
- 7850 AIC-7850
- 7855 AHA-2930
- 7860 AIC-7860
- 7870 AIC-7870
- 7871 AHA-2940
- 7872 AHA-3940
- 7873 AHA-3980
- 7874 AHA-2944
- 7880 AIC-7880P
- 7890 AIC-7890
- 7891 AIC-789x
- 7892 AIC-789x
- 7893 AIC-789x
- 7894 AIC-789x
- 7895 AHA-2940U/UW / AHA-39xx / AIC-7895
- 9004 7890 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
- 9004 7891 AHA-2940U/2940UW Dual
- 9004 7892 AHA-3940AU/AUW/AUWD/UWD
- 9004 7894 AHA-3944AUWD
- 9004 7895 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
- 9004 7896 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
- 9004 7897 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
- 7896 AIC-789x
- 7897 AIC-789x
- 8078 AIC-7880U
- 9004 7880 AIC-7880P Ultra/Ultra Wide SCSI Chipset
- 8178 AHA-2940U/UW/D / AIC-7881U
- 9004 7881 AHA-2940UW SCSI Host Adapter
- 8278 AHA-3940U/UW/UWD / AIC-7882U
- 8378 AHA-3940U/UW / AIC-7883U
- 8478 AHA-2944UW / AIC-7884U
- 8578 AHA-3944U/UWD / AIC-7885
- 8678 AHA-4944UW / AIC-7886
- 8778 AHA-2940UW Pro / AIC-788x
- 9004 7887 2940UW Pro Ultra-Wide SCSI Controller
- 8878 AHA-2930UW / AIC-7888
- 9004 7888 AHA-2930UW SCSI Controller
- 8b78 ABA-1030
- ec78 AHA-4944W/UW
-9005 Adaptec
- 0010 AHA-2940U2/U2W
- 9005 2180 AHA-2940U2 SCSI Controller
- 9005 8100 AHA-2940U2B SCSI Controller
- 9005 a100 AHA-2940U2B SCSI Controller
- 9005 a180 AHA-2940U2W SCSI Controller
- 9005 e100 AHA-2950U2B SCSI Controller
- 0011 AHA-2930U2
- 0013 78902
- 9005 0003 AAA-131U2 Array1000 1 Channel RAID Controller
- 9005 000f AIC7890_ARO
- 001f AHA-2940U2/U2W / 7890/7891
- 9005 000f 2940U2W SCSI Controller
- 9005 a180 2940U2W SCSI Controller
- 0020 AIC-7890
- 002f AIC-7890
- 0030 AIC-7890
- 003f AIC-7890
- 0050 AHA-3940U2x/395U2x
- 9005 f500 AHA-3950U2B
- 9005 ffff AHA-3950U2B
- 0051 AHA-3950U2D
- 9005 b500 AHA-3950U2D
- 0053 AIC-7896 SCSI Controller
- 9005 ffff AIC-7896 SCSI Controller mainboard implementation
- 005f AIC-7896U2/7897U2
- 0080 AIC-7892A U160/m
- 0e11 e2a0 Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
- 9005 6220 AHA-29160C
- 9005 62a0 29160N Ultra160 SCSI Controller
- 9005 e220 29160LP Low Profile Ultra160 SCSI Controller
- 9005 e2a0 29160 Ultra160 SCSI Controller
- 0081 AIC-7892B U160/m
- 9005 62a1 19160 Ultra160 SCSI Controller
- 0083 AIC-7892D U160/m
- 008f AIC-7892P U160/m
- 1179 0001 Magnia Z310
- 15d9 9005 Onboard SCSI Host Adapter
- 00c0 AHA-3960D / AIC-7899A U160/m
- 0e11 f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
- 9005 f620 AHA-3960D U160/m
- 00c1 AIC-7899B U160/m
- 00c3 AIC-7899D U160/m
- 00c5 RAID subsystem HBA
- 1028 00c5 PowerEdge 2400,2500,2550,4400
- 00cf AIC-7899P U160/m
- 1028 00ce PowerEdge 1400
- 1028 00d1 PowerEdge 2550
- 1028 00d9 PowerEdge 2500
- 10f1 2462 Thunder K7 S2462
- 15d9 9005 Onboard SCSI Host Adapter
- 8086 3411 SDS2 Mainboard
- 0250 ServeRAID Controller
- 1014 0279 ServeRAID-xx
- 1014 028c ServeRAID-xx
-# from kernel sources
- 0279 ServeRAID 6M
- 0283 AAC-RAID
- 9005 0283 Catapult
- 0284 AAC-RAID
- 9005 0284 Tomcat
- 0285 AAC-RAID
- 0e11 0295 SATA 6Ch (Bearcat)
- 1014 02f2 ServeRAID 8i
- 1028 0287 PowerEdge Expandable RAID Controller 320/DC
- 1028 0291 CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
- 103c 3227 AAR-2610SA
- 17aa 0286 Legend S220 (Legend Crusader)
- 17aa 0287 Legend S230 (Legend Vulcan)
- 9005 0285 2200S (Vulcan)
- 9005 0286 2120S (Crusader)
- 9005 0287 2200S (Vulcan-2m)
- 9005 0288 3230S (Harrier)
- 9005 0289 3240S (Tornado)
- 9005 028a ASR-2020S PCI-X ZCR (Skyhawk)
- 9005 028b ASR-2020S SO-DIMM PCI-X ZCR (Terminator)
- 9005 0290 AAR-2410SA PCI SATA 4ch (Jaguar II)
- 9005 0292 AAR-2810SA PCI SATA 8ch (Corsair-8)
- 9005 0293 AAR-21610SA PCI SATA 16ch (Corsair-16)
- 9005 0294 ESD SO-DIMM PCI-X SATA ZCR (Prowler)
- 0286 AAC-RAID (Rocket)
- 9005 028c ASR-2230S + ASR-2230SLP PCI-X (Lancer)
- 0503 Scamp chipset SCSI controller
- 1014 02BF Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
- 8000 ASC-29320A U320
- 800f AIC-7901 U320
- 8010 ASC-39320 U320
- 8011 ASC-32320D U320
- 0e11 00ac ASC-39320D U320
- 9005 0041 ASC-39320D U320
- 8012 ASC-29320 U320
- 8013 ASC-29320B U320
- 8014 ASC-29320LP U320
- 8015 ASC-39320B U320
- 8016 ASC-39320A U320
- 8017 ASC-29320ALP U320
- 801c ASC-39320D U320
- 801d AIC-7902B U320
- 801e AIC-7901A U320
- 801f AIC-7902 U320
- 8080 ASC-29320A U320 w/HostRAID
- 808f AIC-7901 U320 w/HostRAID
- 8090 ASC-39320 U320 w/HostRAID
- 8091 ASC-39320D U320 w/HostRAID
- 8092 ASC-29320 U320 w/HostRAID
- 8093 ASC-29320B U320 w/HostRAID
- 8094 ASC-29320LP U320 w/HostRAID
- 8095 ASC-39320(B) U320 w/HostRAID
- 8096 ASC-39320A U320 w/HostRAID
- 8097 ASC-29320ALP U320 w/HostRAID
- 809c ASC-39320D(B) U320 w/HostRAID
- 809d AIC-7902(B) U320 w/HostRAID
- 809e AIC-7901A U320 w/HostRAID
- 809f AIC-7902 U320 w/HostRAID
-907f Atronics
- 2015 IDE-2015PL
-919a Gigapixel Corp
-9412 Holtek
- 6565 6565
-9699 Omni Media Technology Inc
- 6565 6565
-9710 NetMos Technology
- 7780 USB IRDA-port
- 9705 PCI 9705 Parallel Port
- 9715 PCI 9715 Dual Parallel Port
- 9735 PCI 9735 Multi-I/O Controller
- 1000 0002 0P2S (2 serial)
- 1000 0012 1P2S (1 parallel + 2 serial)
- 9745 PCI 9745 Multi-I/O Controller
- 1000 0002 0P2S (2 serial)
- 1000 0012 1P2S (1 parallel + 2 serial)
- 9755 PCI 9755 Parallel Port and ISA Bridge
- 9805 PCI 9805 Parallel Port
- 9815 PCI 9815 Dual Parallel Port
- 1000 0020 2P0S (2 port parallel adaptor)
- 9835 PCI 9835 Multi-I/O Controller
- 1000 0002 0P2S (16C550 UART)
- 1000 0012 1P2S
- 9845 PCI 9845 Multi-I/O Controller
- 1000 0004 0P4S (4 port 16550A serial card)
- 1000 0006 0P6S (6 port 16550A serial card)
- 1000 0014 1P4S (4 port 16550A serial card + parallel)
- 9855 PCI 9855 Multi-I/O Controller
- 1000 0014 1P4S
-9902 Stargen Inc.
- 0001 SG2010 PCI over Starfabric Bridge
- 0002 SG2010 PCI to Starfabric Gateway
- 0003 SG1010 Starfabric Switch and PCI Bridge
-a0a0 AOPEN Inc.
-a0f1 UNISYS Corporation
-a200 NEC Corporation
-a259 Hewlett Packard
-a25b Hewlett Packard GmbH PL24-MKT
-a304 Sony
-a727 3Com Corporation
- 0013 3CRPAG175 Wireless PC Card
-aa42 Scitex Digital Video
-ac1e Digital Receiver Technology Inc
-ac3d Actuality Systems
-aecb Adrienne Electronics Corporation
-b1b3 Shiva Europe Limited
-# Pinnacle should be 11bd, but they got it wrong several times --mj
-bd11 Pinnacle Systems, Inc. (Wrong ID)
-c001 TSI Telsys
-c0a9 Micron/Crucial Technology
-c0de Motorola
-c0fe Motion Engineering, Inc.
-ca50 Varian Australia Pty Ltd
-cafe Chrysalis-ITS
-cccc Catapult Communications
-cddd Tyzx, Inc.
- 0101 DeepSea 1 High Speed Stereo Vision Frame Grabber
- 0200 DeepSea 2 High Speed Stereo Vision Frame Grabber
-d4d4 Dy4 Systems Inc
- 0601 PCI Mezzanine Card
-d531 I+ME ACTIA GmbH
-d84d Exsys
-dead Indigita Corporation
-deaf Middle Digital Inc.
- 9050 PC Weasel Virtual VGA
- 9051 PC Weasel Serial Port
- 9052 PC Weasel Watchdog Timer
-e000 Winbond
- e000 W89C940
-# 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
-e159 Tiger Jet Network Inc.
- 0001 Tiger3XX Modem/ISDN interface
- 0059 0001 128k ISDN-S/T Adapter
- 0059 0003 128k ISDN-U Adapter
- 0002 Tiger100APC ISDN chipset
-e4bf EKF Elektronik GmbH
-# Innovative and scalable network IC vendor
-e55e Essence Technology, Inc.
-ea01 Eagle Technology
-# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
-ea60 RME
- 9896 Digi32
- 9897 Digi32 Pro
- 9898 Digi32/8
-eabb Aashima Technology B.V.
-eace Endace Measurement Systems, Ltd
- 3100 DAG 3.10 OC-3/OC-12
- 3200 DAG 3.2x OC-3/OC-12
- 320e DAG 3.2E Fast Ethernet
- 340e DAG 3.4E Fast Ethernet
- 341e DAG 3.41E Fast Ethernet
- 3500 DAG 3.5 OC-3/OC-12
- 351c DAG 3.5ECM Fast Ethernet
- 4100 DAG 4.10 OC-48
- 4110 DAG 4.11 OC-48
- 4220 DAG 4.2 OC-48
- 422e DAG 4.2E Dual Gigabit Ethernet
-ec80 Belkin Corporation
- ec00 F5D6000
-ecc0 Echo Digital Audio Corporation
-edd8 ARK Logic Inc
- a091 1000PV [Stingray]
- a099 2000PV [Stingray]
- a0a1 2000MT
- a0a9 2000MI
-f1d0 AJA Video
-# All boards I have seen have this ID not efac, though all docs say efac...
- cafe KONA SD SMPTE 259M I/O
- efac KONA SD SMPTE 259M I/O
- facd KONA HD SMPTE 292M I/O
-fa57 Interagon AS
- 0001 PMC [Pattern Matching Chip]
-febd Ultraview Corp.
-feda Broadcom Inc (nee Epigram)
- a0fa BCM4210 iLine10 HomePNA 2.0
- a10e BCM4230 iLine10 HomePNA 2.0
-# IT & Telecom company, develops PCI Trunk cards <www.fedetec.es>
-fede Fedetec Inc.
- 0003 TABIC PCI v3
-fffe VMWare Inc
- 0405 Virtual SVGA 4.0
- 0710 Virtual SVGA
-ffff Illegal Vendor ID
-
-
-# List of known device classes, subclasses and programming interfaces
-
-# Syntax:
-# C class class_name
-# subclass subclass_name <-- single tab
-# prog-if prog-if_name <-- two tabs
-
-C 00 Unclassified device
- 00 Non-VGA unclassified device
- 01 VGA compatible unclassified device
-C 01 Mass storage controller
- 00 SCSI storage controller
- 01 IDE interface
- 02 Floppy disk controller
- 03 IPI bus controller
- 04 RAID bus controller
- 80 Unknown mass storage controller
-C 02 Network controller
- 00 Ethernet controller
- 01 Token ring network controller
- 02 FDDI network controller
- 03 ATM network controller
- 04 ISDN controller
- 80 Network controller
-C 03 Display controller
- 00 VGA compatible controller
- 00 VGA
- 01 8514
- 01 XGA compatible controller
- 02 3D controller
- 80 Display controller
-C 04 Multimedia controller
- 00 Multimedia video controller
- 01 Multimedia audio controller
- 02 Computer telephony device
- 80 Multimedia controller
-C 05 Memory controller
- 00 RAM memory
- 01 FLASH memory
- 80 Memory controller
-C 06 Bridge
- 00 Host bridge
- 01 ISA bridge
- 02 EISA bridge
- 03 MicroChannel bridge
- 04 PCI bridge
- 00 Normal decode
- 01 Subtractive decode
- 05 PCMCIA bridge
- 06 NuBus bridge
- 07 CardBus bridge
- 08 RACEway bridge
- 00 Transparent mode
- 01 Endpoint mode
- 09 Semi-transparent PCI-to-PCI bridge
- 40 Primary bus towards host CPU
- 80 Secondary bus towards host CPU
- 0a InfiniBand to PCI host bridge
- 80 Bridge
-C 07 Communication controller
- 00 Serial controller
- 00 8250
- 01 16450
- 02 16550
- 03 16650
- 04 16750
- 05 16850
- 06 16950
- 01 Parallel controller
- 00 SPP
- 01 BiDir
- 02 ECP
- 03 IEEE1284
- fe IEEE1284 Target
- 02 Multiport serial controller
- 03 Modem
- 00 Generic
- 01 Hayes/16450
- 02 Hayes/16550
- 03 Hayes/16650
- 04 Hayes/16750
- 80 Communication controller
-C 08 Generic system peripheral
- 00 PIC
- 00 8259
- 01 ISA PIC
- 02 EISA PIC
- 10 IO-APIC
- 20 IO(X)-APIC
- 01 DMA controller
- 00 8237
- 01 ISA DMA
- 02 EISA DMA
- 02 Timer
- 00 8254
- 01 ISA Timer
- 02 EISA Timers
- 03 RTC
- 00 Generic
- 01 ISA RTC
- 04 PCI Hot-plug controller
- 80 System peripheral
-C 09 Input device controller
- 00 Keyboard controller
- 01 Digitizer Pen
- 02 Mouse controller
- 03 Scanner controller
- 04 Gameport controller
- 00 Generic
- 10 Extended
- 80 Input device controller
-C 0a Docking station
- 00 Generic Docking Station
- 80 Docking Station
-C 0b Processor
- 00 386
- 01 486
- 02 Pentium
- 10 Alpha
- 20 Power PC
- 30 MIPS
- 40 Co-processor
-C 0c Serial bus controller
- 00 FireWire (IEEE 1394)
- 00 Generic
- 10 OHCI
- 01 ACCESS Bus
- 02 SSA
- 03 USB Controller
- 00 UHCI
- 10 OHCI
- 20 EHCI
- 80 Unspecified
- fe USB Device
- 04 Fibre Channel
- 05 SMBus
- 06 InfiniBand
-C 0d Wireless controller
- 00 IRDA controller
- 01 Consumer IR controller
- 10 RF controller
- 80 Wireless controller
-C 0e Intelligent controller
- 00 I2O
-C 0f Satellite communications controller
- 00 Satellite TV controller
- 01 Satellite audio communication controller
- 03 Satellite voice communication controller
- 04 Satellite data communication controller
-C 10 Encryption controller
- 00 Network and computing encryption device
- 10 Entertainment encryption device
- 80 Encryption controller
-C 11 Signal processing controller
- 00 DPIO module
- 01 Performance counters
- 10 Communication synchronizer
- 80 Signal processing controller
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 30bac7ed7c1..3c565ce7f77 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)
pci_save_msi_state(dev);
}
-static void pcie_portdrv_restore_config(struct pci_dev *dev)
+static int pcie_portdrv_restore_config(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+ int retval;
pci_restore_state(dev);
if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
pci_restore_msi_state(dev);
- pci_enable_device(dev);
+ retval = pci_enable_device(dev);
+ if (retval)
+ return retval;
pci_set_master(dev);
+ return 0;
}
/*
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 93e8a878ea9..35caec13023 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -584,7 +584,7 @@ static int pci_setup_device(struct pci_dev * dev)
dev->vendor, dev->device, class, dev->hdr_type);
/* "Unknown power state" */
- dev->current_state = 4;
+ dev->current_state = PCI_UNKNOWN;
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
@@ -753,29 +753,19 @@ pci_scan_device(struct pci_bus *bus, int devfn)
kfree(dev);
return NULL;
}
- device_initialize(&dev->dev);
- dev->dev.release = pci_release_dev;
- pci_dev_get(dev);
-
- pci_name_device(dev);
-
- dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.coherent_dma_mask = 0xffffffffull;
return dev;
}
-struct pci_dev * __devinit
-pci_scan_single_device(struct pci_bus *bus, int devfn)
+void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
{
- struct pci_dev *dev;
+ device_initialize(&dev->dev);
+ dev->dev.release = pci_release_dev;
+ pci_dev_get(dev);
- dev = pci_scan_device(bus, devfn);
- pci_scan_msi_device(dev);
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.coherent_dma_mask = 0xffffffffull;
- if (!dev)
- return NULL;
-
/* Fix up broken headers */
pci_fixup_device(pci_fixup_header, dev);
@@ -787,6 +777,19 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
spin_lock(&pci_bus_lock);
list_add_tail(&dev->bus_list, &bus->devices);
spin_unlock(&pci_bus_lock);
+}
+
+struct pci_dev * __devinit
+pci_scan_single_device(struct pci_bus *bus, int devfn)
+{
+ struct pci_dev *dev;
+
+ dev = pci_scan_device(bus, devfn);
+ if (!dev)
+ return NULL;
+
+ pci_device_add(dev, bus);
+ pci_scan_msi_device(dev);
return dev;
}
@@ -883,7 +886,8 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
return max;
}
-struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
+struct pci_bus * __devinit pci_create_bus(struct device *parent,
+ int bus, struct pci_ops *ops, void *sysdata)
{
int error;
struct pci_bus *b;
@@ -940,8 +944,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
b->resource[0] = &ioport_resource;
b->resource[1] = &iomem_resource;
- b->subordinate = pci_scan_child_bus(b);
-
return b;
sys_create_link_err:
@@ -959,6 +961,18 @@ err_out:
kfree(b);
return NULL;
}
+EXPORT_SYMBOL_GPL(pci_create_bus);
+
+struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
+ int bus, struct pci_ops *ops, void *sysdata)
+{
+ struct pci_bus *b;
+
+ b = pci_create_bus(parent, bus, ops, sysdata);
+ if (b)
+ b->subordinate = pci_scan_child_bus(b);
+ return b;
+}
EXPORT_SYMBOL(pci_scan_bus_parented);
#ifdef CONFIG_HOTPLUG
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 7988fc8df3f..9613f666c11 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)
struct pci_dev *first_dev;
struct pci_driver *drv;
u32 class_rev;
- unsigned char latency, min_gnt, max_lat, *class;
+ unsigned char latency, min_gnt, max_lat;
int reg;
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)
pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
seq_printf(m, " Bus %2d, device %3d, function %2d:\n",
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
- class = pci_class_name(class_rev >> 16);
- if (class)
- seq_printf(m, " %s", class);
- else
- seq_printf(m, " Class %04x", class_rev >> 16);
-#ifdef CONFIG_PCI_NAMES
- seq_printf(m, ": %s", dev->pretty_name);
-#else
+ seq_printf(m, " Class %04x", class_rev >> 16);
seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device);
-#endif
seq_printf(m, " (rev %d).\n", class_rev & 0xff);
if (dev->irq)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 140354a2aa7..11ca44387cb 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
{
region &= ~(size-1);
if (region) {
+ struct pci_bus_region bus_region;
struct resource *res = dev->resource + nr;
res->name = pci_name(dev);
res->start = region;
res->end = region + size - 1;
res->flags = IORESOURCE_IO;
+
+ /* Convert from PCI bus to resource space. */
+ bus_region.start = res->start;
+ bus_region.end = res->end;
+ pcibios_bus_to_resource(dev, res, &bus_region);
+
pci_claim_resource(dev, nr);
}
}
@@ -869,6 +876,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
case 0xC00C: /* Samsung P35 notebook */
asus_hides_smbus = 1;
}
+ } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ)) {
+ if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+ switch(dev->subsystem_device) {
+ case 0x0058: /* Compaq Evo N620c */
+ asus_hides_smbus = 1;
+ }
}
}
DECLARE_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 6b0e6464eb3..657be948baf 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)
}
}
-static void __devinit
-pci_setup_cardbus(struct pci_bus *bus)
+void pci_setup_cardbus(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
struct pci_bus_region region;
@@ -130,6 +129,7 @@ pci_setup_cardbus(struct pci_bus *bus)
region.end);
}
}
+EXPORT_SYMBOL(pci_setup_cardbus);
/* Initialize bridges with base/limit values we have collected.
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 5598b4714f7..50d6685dcbc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -26,7 +26,7 @@
#include "pci.h"
-static void
+void
pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
{
struct pci_bus_region region;
@@ -97,10 +97,7 @@ pci_claim_resource(struct pci_dev *dev, int resource)
char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
int err;
- if (res->flags & IORESOURCE_IO)
- root = &ioport_resource;
- if (res->flags & IORESOURCE_MEM)
- root = &iomem_resource;
+ root = pcibios_select_root(dev, res);
err = -EINVAL;
if (root != NULL)
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 6485f75d2fb..ddc741e6ecb 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -221,6 +221,13 @@ config PCMCIA_VRC4173
tristate "NEC VRC4173 CARDU support"
depends on CPU_VR41XX && PCI && PCMCIA
+config OMAP_CF
+ tristate "OMAP CompactFlash Controller"
+ depends on PCMCIA && ARCH_OMAP16XX
+ help
+ Say Y here to support the CompactFlash controller on OMAP.
+ Note that this doesn't support "True IDE" mode.
+
config PCCARD_NONSTATIC
tristate
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index ef694c74dfb..a41fbb38fdc 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
+obj-$(CONFIG_OMAP_CF) += omap_cf.o
sa11xx_core-y += soc_common.o sa11xx_base.o
pxa2xx_core-y += soc_common.o pxa2xx_base.o
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e39178fc59d..fabd3529ceb 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -654,9 +654,10 @@ static int pccardd(void *__skt)
skt->thread = NULL;
complete_and_exit(&skt->thread_done, 0);
}
- complete(&skt->thread_done);
add_wait_queue(&skt->thread_wait, &wait);
+ complete(&skt->thread_done);
+
for (;;) {
unsigned long flags;
unsigned int events;
@@ -682,11 +683,11 @@ static int pccardd(void *__skt)
continue;
}
- schedule();
- try_to_freeze();
-
if (!skt->thread)
break;
+
+ schedule();
+ try_to_freeze();
}
remove_wait_queue(&skt->thread_wait, &wait);
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 6bbfbd0e02a..55867bc7f19 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -17,9 +17,6 @@
#include <linux/config.h>
-#define CLIENT_MAGIC 0x51E6
-typedef struct client_t client_t;
-
/* Flags in client state */
#define CLIENT_CONFIG_LOCKED 0x0001
#define CLIENT_IRQ_REQ 0x0002
@@ -45,7 +42,6 @@ typedef struct region_t {
typedef struct config_t {
u_int state;
u_int Attributes;
- u_int Vcc, Vpp1, Vpp2;
u_int IntType;
u_int ConfigBase;
u_char Status, Pin, Copy, Option, ExtStatus;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 43da2e92d50..080608c7381 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -354,6 +354,7 @@ static void pcmcia_release_dev(struct device *dev)
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
ds_dbg(1, "releasing dev %p\n", p_dev);
pcmcia_put_socket(p_dev->socket);
+ kfree(p_dev->devname);
kfree(p_dev);
}
@@ -424,9 +425,13 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
{
cistpl_manfid_t manf_id;
cistpl_funcid_t func_id;
- cistpl_vers_1_t vers1;
+ cistpl_vers_1_t *vers1;
unsigned int i;
+ vers1 = kmalloc(sizeof(*vers1), GFP_KERNEL);
+ if (!vers1)
+ return -ENOMEM;
+
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
CISTPL_MANFID, &manf_id)) {
p_dev->manf_id = manf_id.manf;
@@ -443,23 +448,30 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
/* rule of thumb: cards with no FUNCID, but with
* common memory device geometry information, are
* probably memory cards (from pcmcia-cs) */
- cistpl_device_geo_t devgeo;
+ cistpl_device_geo_t *devgeo;
+
+ devgeo = kmalloc(sizeof(*devgeo), GFP_KERNEL);
+ if (!devgeo) {
+ kfree(vers1);
+ return -ENOMEM;
+ }
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
- CISTPL_DEVICE_GEO, &devgeo)) {
+ CISTPL_DEVICE_GEO, devgeo)) {
ds_dbg(0, "mem device geometry probably means "
"FUNCID_MEMORY\n");
p_dev->func_id = CISTPL_FUNCID_MEMORY;
p_dev->has_func_id = 1;
}
+ kfree(devgeo);
}
if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1,
- &vers1)) {
- for (i=0; i < vers1.ns; i++) {
+ vers1)) {
+ for (i=0; i < vers1->ns; i++) {
char *tmp;
unsigned int length;
- tmp = vers1.str + vers1.ofs[i];
+ tmp = vers1->str + vers1->ofs[i];
length = strlen(tmp) + 1;
if ((length < 3) || (length > 255))
@@ -475,6 +487,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
}
}
+ kfree(vers1);
return 0;
}
@@ -492,6 +505,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
{
struct pcmcia_device *p_dev;
unsigned long flags;
+ int bus_id_len;
s = pcmcia_get_socket(s);
if (!s)
@@ -515,7 +529,12 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
p_dev->dev.bus = &pcmcia_bus_type;
p_dev->dev.parent = s->dev.dev;
p_dev->dev.release = pcmcia_release_dev;
- sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
+ bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
+
+ p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
+ if (!p_dev->devname)
+ goto err_free;
+ sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
/* compat */
p_dev->state = CLIENT_UNBOUND;
@@ -540,6 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
return p_dev;
err_free:
+ kfree(p_dev->devname);
kfree(p_dev);
s->device_count--;
err_put:
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
new file mode 100644
index 00000000000..08d1c928826
--- /dev/null
+++ b/drivers/pcmcia/omap_cf.c
@@ -0,0 +1,373 @@
+/*
+ * omap_cf.c -- OMAP 16xx CompactFlash controller driver
+ *
+ * Copyright (c) 2005 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <pcmcia/ss.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+
+#include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
+
+
+/* NOTE: don't expect this to support many I/O cards. The 16xx chips have
+ * hard-wired timings to support Compact Flash memory cards; they won't work
+ * with various other devices (like WLAN adapters) without some external
+ * logic to help out.
+ *
+ * NOTE: CF controller docs disagree with address space docs as to where
+ * CF_BASE really lives; this is a doc erratum.
+ */
+#define CF_BASE 0xfffe2800
+
+/* status; read after IRQ */
+#define CF_STATUS_REG __REG16(CF_BASE + 0x00)
+# define CF_STATUS_BAD_READ (1 << 2)
+# define CF_STATUS_BAD_WRITE (1 << 1)
+# define CF_STATUS_CARD_DETECT (1 << 0)
+
+/* which chipselect (CS0..CS3) is used for CF (active low) */
+#define CF_CFG_REG __REG16(CF_BASE + 0x02)
+
+/* card reset */
+#define CF_CONTROL_REG __REG16(CF_BASE + 0x04)
+# define CF_CONTROL_RESET (1 << 0)
+
+#define omap_cf_present() (!(CF_STATUS_REG & CF_STATUS_CARD_DETECT))
+
+/*--------------------------------------------------------------------------*/
+
+static const char driver_name[] = "omap_cf";
+
+struct omap_cf_socket {
+ struct pcmcia_socket socket;
+
+ struct timer_list timer;
+ unsigned present:1;
+ unsigned active:1;
+
+ struct platform_device *pdev;
+ unsigned long phys_cf;
+ u_int irq;
+};
+
+#define POLL_INTERVAL (2 * HZ)
+
+#define SZ_2K (2 * SZ_1K)
+
+/*--------------------------------------------------------------------------*/
+
+static int omap_cf_ss_init(struct pcmcia_socket *s)
+{
+ return 0;
+}
+
+/* the timer is primarily to kick this socket's pccardd */
+static void omap_cf_timer(unsigned long _cf)
+{
+ struct omap_cf_socket *cf = (void *) _cf;
+ unsigned present = omap_cf_present();
+
+ if (present != cf->present) {
+ cf->present = present;
+ pr_debug("%s: card %s\n", driver_name,
+ present ? "present" : "gone");
+ pcmcia_parse_events(&cf->socket, SS_DETECT);
+ }
+
+ if (cf->active)
+ mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
+}
+
+/* This irq handler prevents "irqNNN: nobody cared" messages as drivers
+ * claim the card's IRQ. It may also detect some card insertions, but
+ * not removals; it can't always eliminate timer irqs.
+ */
+static irqreturn_t omap_cf_irq(int irq, void *_cf, struct pt_regs *r)
+{
+ omap_cf_timer((unsigned long)_cf);
+ return IRQ_HANDLED;
+}
+
+static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp)
+{
+ if (!sp)
+ return -EINVAL;
+
+ /* FIXME power management should probably be board-specific:
+ * - 3VCARD vs XVCARD (OSK only handles 3VCARD)
+ * - POWERON (switched on/off by set_socket)
+ */
+ if (omap_cf_present()) {
+ struct omap_cf_socket *cf;
+
+ *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
+ cf = container_of(s, struct omap_cf_socket, socket);
+ s->irq.AssignedIRQ = cf->irq;
+ } else
+ *sp = 0;
+ return 0;
+}
+
+static int
+omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
+{
+ u16 control;
+
+ /* FIXME some non-OSK boards will support power switching */
+ switch (s->Vcc) {
+ case 0:
+ case 33:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ control = CF_CONTROL_REG;
+ if (s->flags & SS_RESET)
+ CF_CONTROL_REG = CF_CONTROL_RESET;
+ else
+ CF_CONTROL_REG = 0;
+
+ pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
+ driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
+
+ return 0;
+}
+
+static int omap_cf_ss_suspend(struct pcmcia_socket *s)
+{
+ pr_debug("%s: %s\n", driver_name, __FUNCTION__);
+ return omap_cf_set_socket(s, &dead_socket);
+}
+
+/* regions are 2K each: mem, attrib, io (and reserved-for-ide) */
+
+static int
+omap_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
+{
+ struct omap_cf_socket *cf;
+
+ cf = container_of(s, struct omap_cf_socket, socket);
+ io->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
+ io->start = cf->phys_cf + SZ_4K;
+ io->stop = io->start + SZ_2K - 1;
+ return 0;
+}
+
+static int
+omap_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
+{
+ struct omap_cf_socket *cf;
+
+ if (map->card_start)
+ return -EINVAL;
+ cf = container_of(s, struct omap_cf_socket, socket);
+ map->static_start = cf->phys_cf;
+ map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
+ if (map->flags & MAP_ATTRIB)
+ map->static_start += SZ_2K;
+ return 0;
+}
+
+static struct pccard_operations omap_cf_ops = {
+ .init = omap_cf_ss_init,
+ .suspend = omap_cf_ss_suspend,
+ .get_status = omap_cf_get_status,
+ .set_socket = omap_cf_set_socket,
+ .set_io_map = omap_cf_set_io_map,
+ .set_mem_map = omap_cf_set_mem_map,
+};
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * NOTE: right now the only board-specific platform_data is
+ * "what chipselect is used". Boards could want more.
+ */
+
+static int __init omap_cf_probe(struct device *dev)
+{
+ unsigned seg;
+ struct omap_cf_socket *cf;
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq;
+ int status;
+
+ seg = (int) dev->platform_data;
+ if (seg == 0 || seg > 3)
+ return -ENODEV;
+
+ /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */
+ irq = platform_get_irq(pdev, 0);
+ if (!irq)
+ return -EINVAL;
+
+ cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+ if (!cf)
+ return -ENOMEM;
+ init_timer(&cf->timer);
+ cf->timer.function = omap_cf_timer;
+ cf->timer.data = (unsigned long) cf;
+
+ cf->pdev = pdev;
+ dev_set_drvdata(dev, cf);
+
+ /* this primarily just shuts up irq handling noise */
+ status = request_irq(irq, omap_cf_irq, SA_SHIRQ,
+ driver_name, cf);
+ if (status < 0)
+ goto fail0;
+ cf->irq = irq;
+ cf->socket.pci_irq = irq;
+
+ switch (seg) {
+ /* NOTE: CS0 could be configured too ... */
+ case 1:
+ cf->phys_cf = OMAP_CS1_PHYS;
+ break;
+ case 2:
+ cf->phys_cf = OMAP_CS2_PHYS;
+ break;
+ case 3:
+ cf->phys_cf = omap_cs3_phys();
+ break;
+ default:
+ goto fail1;
+ }
+
+ /* pcmcia layer only remaps "real" memory */
+ cf->socket.io_offset = (unsigned long)
+ ioremap(cf->phys_cf + SZ_4K, SZ_2K);
+ if (!cf->socket.io_offset)
+ goto fail1;
+
+ if (!request_mem_region(cf->phys_cf, SZ_8K, driver_name))
+ goto fail1;
+
+ /* NOTE: CF conflicts with MMC1 */
+ omap_cfg_reg(W11_1610_CF_CD1);
+ omap_cfg_reg(P11_1610_CF_CD2);
+ omap_cfg_reg(R11_1610_CF_IOIS16);
+ omap_cfg_reg(V10_1610_CF_IREQ);
+ omap_cfg_reg(W10_1610_CF_RESET);
+
+ CF_CFG_REG = ~(1 << seg);
+
+ pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq);
+
+ /* NOTE: better EMIFS setup might support more cards; but the
+ * TRM only shows how to affect regular flash signals, not their
+ * CF/PCMCIA variants...
+ */
+ pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name,
+ seg, EMIFS_CCS(seg), EMIFS_ACS(seg));
+ EMIFS_CCS(seg) = 0x0004a1b3; /* synch mode 4 etc */
+ EMIFS_ACS(seg) = 0x00000000; /* OE hold/setup */
+
+ /* CF uses armxor_ck, which is "always" available */
+
+ pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name,
+ CF_STATUS_REG, CF_CFG_REG, CF_CONTROL_REG,
+ omap_cf_present() ? "present" : "(not present)");
+
+ cf->socket.owner = THIS_MODULE;
+ cf->socket.dev.dev = dev;
+ cf->socket.ops = &omap_cf_ops;
+ cf->socket.resource_ops = &pccard_static_ops;
+ cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
+ | SS_CAP_MEM_ALIGN;
+ cf->socket.map_size = SZ_2K;
+
+ status = pcmcia_register_socket(&cf->socket);
+ if (status < 0)
+ goto fail2;
+
+ cf->active = 1;
+ mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
+ return 0;
+
+fail2:
+ iounmap((void __iomem *) cf->socket.io_offset);
+ release_mem_region(cf->phys_cf, SZ_8K);
+fail1:
+ free_irq(irq, cf);
+fail0:
+ kfree(cf);
+ return status;
+}
+
+static int __devexit omap_cf_remove(struct device *dev)
+{
+ struct omap_cf_socket *cf = dev_get_drvdata(dev);
+
+ cf->active = 0;
+ pcmcia_unregister_socket(&cf->socket);
+ del_timer_sync(&cf->timer);
+ iounmap((void __iomem *) cf->socket.io_offset);
+ release_mem_region(cf->phys_cf, SZ_8K);
+ free_irq(cf->irq, cf);
+ kfree(cf);
+ return 0;
+}
+
+static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level)
+{
+ if (level != SUSPEND_SAVE_STATE)
+ return 0;
+ return pcmcia_socket_dev_suspend(dev, mesg);
+}
+
+static int omap_cf_resume(struct device *dev, u32 level)
+{
+ if (level != RESUME_RESTORE_STATE)
+ return 0;
+ return pcmcia_socket_dev_resume(dev);
+}
+
+static struct device_driver omap_cf_driver = {
+ .name = (char *) driver_name,
+ .bus = &platform_bus_type,
+ .probe = omap_cf_probe,
+ .remove = __devexit_p(omap_cf_remove),
+ .suspend = omap_cf_suspend,
+ .resume = omap_cf_resume,
+};
+
+static int __init omap_cf_init(void)
+{
+ if (cpu_is_omap16xx())
+ driver_register(&omap_cf_driver);
+ return 0;
+}
+
+static void __exit omap_cf_exit(void)
+{
+ if (cpu_is_omap16xx())
+ driver_unregister(&omap_cf_driver);
+}
+
+module_init(omap_cf_init);
+module_exit(omap_cf_exit);
+
+MODULE_DESCRIPTION("OMAP CF Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 599b116d974..89022ad5b52 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,
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2)
return CS_BAD_VPP;
- c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;
+ s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket))
return CS_BAD_VPP;
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
@@ -623,8 +623,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
if (s->ops->set_socket(s, &s->socket))
return CS_BAD_VPP;
- c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
-
/* Pick memory or I/O card, DMA mode, interrupt */
c->IntType = req->IntType;
c->Attributes = req->Attributes;
@@ -822,7 +820,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
(s->functions > 1) ||
(irq == s->pci_irq)) ? SA_SHIRQ : 0,
- p_dev->dev.bus_id,
+ p_dev->devname,
(req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
if (!ret) {
if (!(req->Attributes & IRQ_HANDLE_PRESENT))
@@ -832,7 +830,8 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
}
}
#endif
- if (ret) {
+ /* only assign PCI irq if no IRQ already assigned */
+ if (ret && !s->irq.AssignedIRQ) {
if (!s->pci_irq)
return ret;
irq = s->pci_irq;
@@ -843,7 +842,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
(s->functions > 1) ||
(irq == s->pci_irq)) ? SA_SHIRQ : 0,
- p_dev->dev.bus_id, req->Instance))
+ p_dev->devname, req->Instance))
return CS_IN_USE;
}
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0347a29f297..f0997c36c9b 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)
{
debug("%p %04x %08x\n", socket, reg, val);
writel(val, socket->base + reg);
+ readl(socket->base + reg); /* avoid problems with PCI write posting */
}
static 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
{
debug("%p %04x %02x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
+ readb(socket->base + 0x800 + reg); /* PCI write posting... */
}
static 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)
debug("%p %04x %04x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
writeb(val >> 8, socket->base + 0x800 + reg + 1);
+
+ /* PCI write posting... */
+ readb(socket->base + 0x800 + reg);
+ readb(socket->base + 0x800 + reg + 1);
}
/*
@@ -667,7 +673,7 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
return 0;
}
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
+static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
{
struct resource *root, *res;
struct pci_bus_region region;
@@ -676,7 +682,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
/* Already allocated? */
if (res->parent)
- return;
+ return 0;
/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
mask = ~0xfff;
@@ -692,7 +698,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
pcibios_bus_to_resource(socket->dev, res, &region);
root = pci_find_parent_resource(socket->dev, res);
if (root && (request_resource(root, res) == 0))
- return;
+ return 0;
printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
pci_name(socket->dev), nr);
}
@@ -700,35 +706,27 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
if (type & IORESOURCE_IO) {
if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
(yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
- (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
- config_writel(socket, addr_start, res->start);
- config_writel(socket, addr_end, res->end);
- return;
- }
+ (yenta_search_res(socket, res, BRIDGE_IO_MIN)))
+ return 1;
} else {
if (type & IORESOURCE_PREFETCH) {
if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
(yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
- (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
- config_writel(socket, addr_start, res->start);
- config_writel(socket, addr_end, res->end);
- return;
- }
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
+ return 1;
/* Approximating prefetchable by non-prefetchable */
res->flags = IORESOURCE_MEM;
}
if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
(yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
- (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
- config_writel(socket, addr_start, res->start);
- config_writel(socket, addr_end, res->end);
- return;
- }
+ (yenta_search_res(socket, res, BRIDGE_MEM_MIN)))
+ return 1;
}
printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
pci_name(socket->dev), type);
res->start = res->end = res->flags = 0;
+ return 0;
}
/*
@@ -736,14 +734,17 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ
*/
static void yenta_allocate_resources(struct yenta_socket *socket)
{
- yenta_allocate_res(socket, 0, IORESOURCE_IO,
+ int program = 0;
+ program += yenta_allocate_res(socket, 0, IORESOURCE_IO,
PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
- yenta_allocate_res(socket, 1, IORESOURCE_IO,
+ program += yenta_allocate_res(socket, 1, IORESOURCE_IO,
PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
- yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+ program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
- yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+ program += yenta_allocate_res(socket, 3, IORESOURCE_MEM,
PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
+ if (program)
+ pci_setup_cardbus(socket->dev->subordinate);
}
@@ -758,7 +759,7 @@ static void yenta_free_resources(struct yenta_socket *socket)
res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
if (res->start != 0 && res->end != 0)
release_resource(res);
- res->start = res->end = 0;
+ res->start = res->end = res->flags = 0;
}
}
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index d96cc47de56..672f9f2b216 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
#ifdef AURORA_INT_DEBUG
static void aurora_timer (unsigned long ignored);
-static struct timer_list aurora_poll_timer =
- TIMER_INITIALIZER(aurora_timer, 0, 0);
+static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);
static void
aurora_timer (unsigned long ignored)
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 320df6cd3de..c2c8fa828e2 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)
return 0;
}
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_intx(struct pci_dev *pdev, int enable)
-{
- u16 pci_command, new;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
- if (enable)
- new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
- else
- new = pci_command | PCI_COMMAND_INTX_DISABLE;
-
- if (new != pci_command)
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-}
-
static void ahci_print_info(struct ata_probe_ent *probe_ent)
{
struct ahci_host_priv *hpriv = probe_ent->private_data;
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index deec0cef88d..87e0c36f155 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -68,8 +68,8 @@ enum {
PIIX_COMB_PATA_P0 = (1 << 1),
PIIX_COMB = (1 << 2), /* combined mode enabled? */
- PIIX_PORT_PRESENT = (1 << 0),
- PIIX_PORT_ENABLED = (1 << 4),
+ PIIX_PORT_ENABLED = (1 << 0),
+ PIIX_PORT_PRESENT = (1 << 4),
PIIX_80C_PRI = (1 << 5) | (1 << 4),
PIIX_80C_SEC = (1 << 7) | (1 << 6),
@@ -377,7 +377,9 @@ static void piix_pata_phy_reset(struct ata_port *ap)
* None (inherited from caller).
*
* RETURNS:
- * Non-zero if device detected, zero otherwise.
+ * Non-zero if port is enabled, it may or may not have a device
+ * attached in that case (PRESENT bit would only be set if BIOS probe
+ * was done). Zero is returned if port is disabled.
*/
static int piix_sata_probe (struct ata_port *ap)
{
@@ -401,7 +403,7 @@ static int piix_sata_probe (struct ata_port *ap)
*/
for (i = 0; i < 4; i++) {
- mask = (PIIX_PORT_PRESENT << i) | (PIIX_PORT_ENABLED << i);
+ mask = (PIIX_PORT_ENABLED << i);
if ((orig_mask & mask) == mask)
if (combined || (i == ap->hard_port_no))
@@ -566,18 +568,6 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
}
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
- u16 pci_command;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_INTX_DISABLE) {
- pci_command &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
- }
-}
-
#define AHCI_PCI_BAR 5
#define AHCI_GLOBAL_CTL 0x04
#define AHCI_ENABLE (1 << 31)
@@ -675,7 +665,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
* message-signalled interrupts currently).
*/
if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
- pci_enable_intx(pdev);
+ pci_intx(pdev, 1);
if (combined) {
port_info[sata_chan] = &piix_port_info[ent->driver_data];
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index bd0e1b6be1e..13ecd0c4740 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -116,7 +116,7 @@ typedef struct {
} scsi_changer;
static LIST_HEAD(ch_devlist);
-static spinlock_t ch_devlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ch_devlist_lock);
static int ch_devcount;
static struct scsi_driver ch_template =
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 623082d3a83..c89da7d5b6d 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -95,8 +95,7 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
int i, retry, nplutos;
fc_channel *fc;
Scsi_Device dev;
- struct timer_list fc_timer =
- TIMER_INITIALIZER(pluto_detect_timeout, 0, 0);
+ DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
tpnt->proc_name = "pluto";
fcscount = 0;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 72bbaa91dc7..9791496fa78 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)
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
WRT_REG_DWORD(dmp_reg, 0xB0200000);
- dmp_reg = (uint32_t *)((uint8_t *)reg + 0xFC);
+ dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
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 f97e3afa97d..ea76fe44585 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)
return rc;
}
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_intx(struct pci_dev *pdev, int enable)
-{
- u16 pci_command, new;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
- if (enable)
- new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
- else
- new = pci_command | PCI_COMMAND_INTX_DISABLE;
-
- if (new != pci_command)
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-}
-
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 43af445b3ad..a63f93186e4 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -52,7 +52,10 @@ enum {
/* PCI configuration registers */
SIS_GENCTL = 0x54, /* IDE General Control register */
SIS_SCR_BASE = 0xc0, /* sata0 phy SCR registers */
- SIS_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */
+ SIS180_SATA1_OFS = 0x10, /* offset from sata0->sata1 phy regs */
+ SIS182_SATA1_OFS = 0x20, /* offset from sata0->sata1 phy regs */
+ SIS_PMR = 0x90, /* port mapping register */
+ SIS_PMR_COMBINED = 0x30,
/* random bits */
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);
static struct pci_device_id sis_pci_tbl[] = {
{ PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
+ { PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ } /* terminate list */
};
@@ -139,67 +143,95 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
{
unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
- if (port_no)
- addr += SIS_SATA1_OFS;
+ if (port_no) {
+ if (device == 0x182)
+ addr += SIS182_SATA1_OFS;
+ else
+ addr += SIS180_SATA1_OFS;
+ }
+
return addr;
}
static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
{
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
- u32 val;
+ unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
+ u32 val, val2;
+ u8 pmr;
if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
return 0xffffffff;
+
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+
pci_read_config_dword(pdev, cfg_addr, &val);
- return val;
+
+ if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
+
+ return val|val2;
}
static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
{
struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+ u8 pmr;
if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
return;
+
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+
pci_write_config_dword(pdev, cfg_addr, val);
+
+ if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ pci_write_config_dword(pdev, cfg_addr+0x10, val);
}
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ u32 val, val2 = 0;
+ u8 pmr;
+
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
if (ap->flags & SIS_FLAG_CFGSCR)
return sis_scr_cfg_read(ap, sc_reg);
- return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+
+ val = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+
+ if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
+
+ return val | val2;
}
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
+ struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+ u8 pmr;
+
if (sc_reg > SCR_CONTROL)
return;
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+
if (ap->flags & SIS_FLAG_CFGSCR)
sis_scr_cfg_write(ap, sc_reg, val);
- else
+ else {
outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
-}
-
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
- u16 pci_command;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_INTX_DISABLE) {
- pci_command &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+ if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
}
}
@@ -210,6 +242,8 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
u32 genctl;
struct ata_port_info *ppi;
int pci_dev_busy = 0;
+ u8 pmr;
+ u8 port2_start;
rc = pci_enable_device(pdev);
if (rc)
@@ -251,15 +285,31 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->host_flags |= SIS_FLAG_CFGSCR;
}
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+ if (ent->device != 0x182) {
+ if ((pmr & SIS_PMR_COMBINED) == 0) {
+ printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
+ port2_start=0x64;
+ }
+ else {
+ printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
+ port2_start=0;
+ }
+ }
+ else {
+ printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
+ port2_start = 0x20;
+ }
+
if (!(probe_ent->host_flags & SIS_FLAG_CFGSCR)) {
probe_ent->port[0].scr_addr =
pci_resource_start(pdev, SIS_SCR_PCI_BAR);
probe_ent->port[1].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR) + 64;
+ pci_resource_start(pdev, SIS_SCR_PCI_BAR) + port2_start;
}
pci_set_master(pdev);
- pci_enable_intx(pdev);
+ pci_intx(pdev, 1);
/* FIXME: check ata_device_add return value */
ata_device_add(probe_ent);
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 42e13ed8eb5..4c9fb8b71be 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)
uli_scr_cfg_write(ap, sc_reg, val);
}
-/* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
-{
- u16 pci_command;
-
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
- if (pci_command & PCI_COMMAND_INTX_DISABLE) {
- pci_command &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(pdev, PCI_COMMAND, pci_command);
- }
-}
-
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
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)
}
pci_set_master(pdev);
- pci_enable_intx(pdev);
+ pci_intx(pdev, 1);
/* FIXME: check ata_device_add return value */
ata_device_add(probe_ent);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30a0a3d1014..5b65e208893 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2536,7 +2536,7 @@ static int __init serial8250_init(void)
goto out;
serial8250_isa_devs = platform_device_register_simple("serial8250",
- -1, NULL, 0);
+ PLAT8250_DEV_LEGACY, NULL, 0);
if (IS_ERR(serial8250_isa_devs)) {
ret = PTR_ERR(serial8250_isa_devs);
goto unreg;
diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c
index 1f2c276063e..9c10262f246 100644
--- a/drivers/serial/8250_accent.c
+++ b/drivers/serial/8250_accent.c
@@ -29,7 +29,7 @@ static struct plat_serial8250_port accent_data[] = {
static struct platform_device accent_device = {
.name = "serial8250",
- .id = 2,
+ .id = PLAT8250_DEV_ACCENT,
.dev = {
.platform_data = accent_data,
},
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c
index 465c9ea1e7a..3bfe0f7b26f 100644
--- a/drivers/serial/8250_boca.c
+++ b/drivers/serial/8250_boca.c
@@ -43,7 +43,7 @@ static struct plat_serial8250_port boca_data[] = {
static struct platform_device boca_device = {
.name = "serial8250",
- .id = 3,
+ .id = PLAT8250_DEV_BOCA,
.dev = {
.platform_data = boca_data,
},
diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c
index e9b4d908ef4..6375d68b791 100644
--- a/drivers/serial/8250_fourport.c
+++ b/drivers/serial/8250_fourport.c
@@ -35,7 +35,7 @@ static struct plat_serial8250_port fourport_data[] = {
static struct platform_device fourport_device = {
.name = "serial8250",
- .id = 1,
+ .id = PLAT8250_DEV_FOURPORT,
.dev = {
.platform_data = fourport_data,
},
diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c
index 77f396f84b4..daf569cd3c8 100644
--- a/drivers/serial/8250_hub6.c
+++ b/drivers/serial/8250_hub6.c
@@ -40,7 +40,7 @@ static struct plat_serial8250_port hub6_data[] = {
static struct platform_device hub6_device = {
.name = "serial8250",
- .id = 4,
+ .id = PLAT8250_DEV_HUB6,
.dev = {
.platform_data = hub6_data,
},
diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c
index f0c40d68b8c..ac205256d5f 100644
--- a/drivers/serial/8250_mca.c
+++ b/drivers/serial/8250_mca.c
@@ -44,7 +44,7 @@ static struct plat_serial8250_port mca_data[] = {
static struct platform_device mca_device = {
.name = "serial8250",
- .id = 5,
+ .id = PLAT8250_DEV_MCA,
.dev = {
.platform_data = mca_data,
},
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 49afadbe461..f10c86d60b6 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -31,6 +31,8 @@
* 1.01 Set fifosize to make tx_empry called properly.
* Use standard uart_get_divisor.
* 1.02 Cleanup. (import 8250.c changes)
+ * 1.03 Fix low-latency mode. (import 8250.c changes)
+ * 1.04 Remove usage of deprecated functions, cleanup.
*/
#include <linux/config.h>
@@ -54,7 +56,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-static char *serial_version = "1.02";
+static char *serial_version = "1.04";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -86,9 +88,9 @@ static char *serial_name = "TX39/49 Serial driver";
*/
#ifdef ENABLE_SERIAL_TXX9_PCI
#define NR_PCI_BOARDS 4
-#define UART_NR (2 + NR_PCI_BOARDS)
+#define UART_NR (4 + NR_PCI_BOARDS)
#else
-#define UART_NR 2
+#define UART_NR 4
#endif
struct uart_txx9_port {
@@ -304,8 +306,11 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
/* The following is not allowed by the tty layer and
unsafe. It should be fixed ASAP */
if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
- if(tty->low_latency)
+ if (tty->low_latency) {
+ spin_unlock(&up->port.lock);
tty_flip_buffer_push(tty);
+ spin_lock(&up->port.lock);
+ }
/* If this failed then we will throw away the
bytes but must do so to clear interrupts */
}
@@ -356,7 +361,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
ignore_char:
disr = sio_in(up, TXX9_SIDISR);
} while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
+ spin_unlock(&up->port.lock);
tty_flip_buffer_push(tty);
+ spin_lock(&up->port.lock);
*status = disr;
}
@@ -667,17 +674,8 @@ serial_txx9_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- if (state) {
- /* sleep */
-
- if (up->pm)
- up->pm(port, state, oldstate);
- } else {
- /* wake */
-
- if (up->pm)
- up->pm(port, state, oldstate);
- }
+ if (up->pm)
+ up->pm(port, state, oldstate);
}
static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -979,14 +977,6 @@ static int __init serial_txx9_console_init(void)
}
console_initcall(serial_txx9_console_init);
-static int __init serial_txx9_late_console_init(void)
-{
- if (!(serial_txx9_console.flags & CON_ENABLED))
- register_console(&serial_txx9_console);
- return 0;
-}
-late_initcall(serial_txx9_late_console_init);
-
#define SERIAL_TXX9_CONSOLE &serial_txx9_console
#else
#define SERIAL_TXX9_CONSOLE NULL
@@ -1039,6 +1029,73 @@ static void serial_txx9_resume_port(int line)
uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
}
+static DECLARE_MUTEX(serial_txx9_sem);
+
+/**
+ * serial_txx9_register_port - register a serial port
+ * @port: serial port template
+ *
+ * Configure the serial port specified by the request.
+ *
+ * The port is then probed and if necessary the IRQ is autodetected
+ * If this fails an error is returned.
+ *
+ * On success the port is ready to use and the line number is returned.
+ */
+static int __devinit serial_txx9_register_port(struct uart_port *port)
+{
+ int i;
+ struct uart_txx9_port *uart;
+ int ret = -ENOSPC;
+
+ down(&serial_txx9_sem);
+ for (i = 0; i < UART_NR; i++) {
+ uart = &serial_txx9_ports[i];
+ if (uart->port.type == PORT_UNKNOWN)
+ break;
+ }
+ if (i < UART_NR) {
+ uart_remove_one_port(&serial_txx9_reg, &uart->port);
+ uart->port.iobase = port->iobase;
+ uart->port.membase = port->membase;
+ uart->port.irq = port->irq;
+ uart->port.uartclk = port->uartclk;
+ uart->port.iotype = port->iotype;
+ uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
+ uart->port.mapbase = port->mapbase;
+ if (port->dev)
+ uart->port.dev = port->dev;
+ ret = uart_add_one_port(&serial_txx9_reg, &uart->port);
+ if (ret == 0)
+ ret = uart->port.line;
+ }
+ up(&serial_txx9_sem);
+ return ret;
+}
+
+/**
+ * serial_txx9_unregister_port - remove a txx9 serial port at runtime
+ * @line: serial line number
+ *
+ * Remove one serial port. This may not be called from interrupt
+ * context. We hand the port back to the our control.
+ */
+static void __devexit serial_txx9_unregister_port(int line)
+{
+ struct uart_txx9_port *uart = &serial_txx9_ports[line];
+
+ down(&serial_txx9_sem);
+ uart_remove_one_port(&serial_txx9_reg, &uart->port);
+ uart->port.flags = 0;
+ uart->port.type = PORT_UNKNOWN;
+ uart->port.iobase = 0;
+ uart->port.mapbase = 0;
+ uart->port.membase = 0;
+ uart->port.dev = NULL;
+ uart_add_one_port(&serial_txx9_reg, &uart->port);
+ up(&serial_txx9_sem);
+}
+
/*
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* 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)
memset(&port, 0, sizeof(port));
port.ops = &serial_txx9_pops;
- port.flags |= UPF_BOOT_AUTOCONF; /* uart_ops.config_port will be called */
port.flags |= UPF_TXX9_HAVE_CTS_LINE;
port.uartclk = 66670000;
port.irq = dev->irq;
port.iotype = UPIO_PORT;
port.iobase = pci_resource_start(dev, 1);
- line = uart_register_port(&serial_txx9_reg, &port);
+ port.dev = &dev->dev;
+ line = serial_txx9_register_port(&port);
if (line < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
}
@@ -1078,7 +1135,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
pci_set_drvdata(dev, NULL);
if (line) {
- uart_unregister_port(&serial_txx9_reg, line);
+ serial_txx9_unregister_port(line);
pci_disable_device(dev);
}
}
@@ -1089,6 +1146,8 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
if (line)
serial_txx9_suspend_port(line);
+ pci_save_state(dev);
+ pci_set_power_state(dev, pci_choose_state(dev, state));
return 0;
}
@@ -1096,8 +1155,13 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev)
{
int line = (int)(long)pci_get_drvdata(dev);
- if (line)
+ pci_set_power_state(dev, PCI_D0);
+ pci_restore_state(dev);
+
+ if (line) {
+ pci_enable_device(dev);
serial_txx9_resume_port(line);
+ }
return 0;
}
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 8e184e2641c..79861ee12a2 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,
usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
instance->rcv_buf, PAGE_SIZE,
cxacru_blocking_completion, &instance->rcv_done, 1);
- instance->rcv_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_fill_int_urb(instance->snd_urb,
usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
instance->snd_buf, PAGE_SIZE,
cxacru_blocking_completion, &instance->snd_done, 4);
- instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
init_MUTEX(&instance->cm_serialize);
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 0561d0234f2..333e39bb105 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -4,9 +4,22 @@
comment "USB Device Class drivers"
depends on USB
+config OBSOLETE_OSS_USB_DRIVER
+ bool "Obsolete OSS USB drivers"
+ depends on USB && SOUND
+ help
+ This option enables support for the obsolete USB Audio and Midi
+ drivers that are scheduled for removal in the near future since
+ there are ALSA drivers for the same hardware.
+
+ Please contact Adrian Bunk <bunk@stusta.de> if you had to
+ say Y here because of missing support in the ALSA drivers.
+
+ If unsure, say N.
+
config USB_AUDIO
tristate "USB Audio support"
- depends on USB && SOUND
+ depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
help
Say Y here if you want to connect USB audio equipment such as
speakers to your computer's USB port. You only need this if you use
@@ -40,10 +53,12 @@ config USB_BLUETOOTH_TTY
config USB_MIDI
tristate "USB MIDI support"
- depends on USB && SOUND
+ depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER
---help---
Say Y here if you want to connect a USB MIDI device to your
- computer's USB port. This driver is for devices that comply with
+ computer's USB port. You only need this if you use the OSS
+ sound system; USB MIDI devices are supported by ALSA's USB
+ audio driver. This driver is for devices that comply with
'Universal Serial Bus Device Class Definition for MIDI Device'.
The following devices are known to work:
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 7ce43fb8118..e195709c9c7 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)
error = usblp_read_status (usblp, usblp->statusbuf);
if (error < 0) {
- err("usblp%d: error %d reading printer status",
- usblp->minor, error);
+ if (printk_ratelimit())
+ err("usblp%d: error %d reading printer status",
+ usblp->minor, error);
return 0;
}
@@ -604,7 +605,9 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case LPGETSTATUS:
if (usblp_read_status(usblp, usblp->statusbuf)) {
- err("usblp%d: failed reading printer status", usblp->minor);
+ if (printk_ratelimit())
+ err("usblp%d: failed reading printer status",
+ usblp->minor);
retval = -EIO;
goto done;
}
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 9e8c377b816..d5503cf0bf7 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -3,14 +3,14 @@
#
usbcore-objs := usb.o hub.o hcd.o urb.o message.o \
- config.o file.o buffer.o sysfs.o
+ config.o file.o buffer.o sysfs.o devio.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
endif
ifeq ($(CONFIG_USB_DEVICEFS),y)
- usbcore-objs += devio.o inode.o devices.o
+ usbcore-objs += inode.o devices.o
endif
obj-$(CONFIG_USB) += usbcore.o
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index f86bf1454e2..b4265aa7d45 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -43,6 +43,7 @@
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
+#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/moduleparam.h>
@@ -50,6 +51,10 @@
#include "hcd.h" /* for usbcore internals */
#include "usb.h"
+#define USB_MAXBUS 64
+#define USB_DEVICE_MAX USB_MAXBUS * 128
+static struct class *usb_device_class;
+
struct async {
struct list_head asynclist;
struct dev_state *ps;
@@ -71,6 +76,8 @@ MODULE_PARM_DESC (usbfs_snoop, "true to log all usbfs traffic");
dev_info( dev , format , ## arg); \
} while (0)
+#define USB_DEVICE_DEV MKDEV(USB_DEVICE_MAJOR, 0)
+
#define MAX_USBFS_BUFFER_SIZE 16384
@@ -487,7 +494,7 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
*/
static int usbdev_open(struct inode *inode, struct file *file)
{
- struct usb_device *dev;
+ struct usb_device *dev = NULL;
struct dev_state *ps;
int ret;
@@ -501,11 +508,16 @@ static int usbdev_open(struct inode *inode, struct file *file)
lock_kernel();
ret = -ENOENT;
- dev = usb_get_dev(inode->u.generic_ip);
+ /* check if we are called from a real node or usbfs */
+ if (imajor(inode) == USB_DEVICE_MAJOR)
+ dev = usbdev_lookup_minor(iminor(inode));
+ if (!dev)
+ dev = inode->u.generic_ip;
if (!dev) {
kfree(ps);
goto out;
}
+ usb_get_dev(dev);
ret = 0;
ps->dev = dev;
ps->file = file;
@@ -1226,7 +1238,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
int retval = 0;
struct usb_interface *intf = NULL;
struct usb_driver *driver = NULL;
- int i;
/* get input parameters and alloc buffer */
if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
@@ -1258,15 +1269,6 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg)
/* disconnect kernel driver from interface */
case USBDEVFS_DISCONNECT:
- /* don't allow the user to unbind the hub driver from
- * a hub with children to manage */
- for (i = 0; i < ps->dev->maxchild; ++i) {
- if (ps->dev->children[i])
- retval = -EBUSY;
- }
- if (retval)
- break;
-
down_write(&usb_bus_type.subsys.rwsem);
if (intf->dev.driver) {
driver = to_usb_driver(intf->dev.driver);
@@ -1477,3 +1479,79 @@ struct file_operations usbfs_device_file_operations = {
.open = usbdev_open,
.release = usbdev_release,
};
+
+struct usb_device *usbdev_lookup_minor(int minor)
+{
+ struct class_device *class_dev;
+ struct usb_device *dev = NULL;
+
+ down(&usb_device_class->sem);
+ list_for_each_entry(class_dev, &usb_device_class->children, node) {
+ if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
+ dev = class_dev->class_data;
+ break;
+ }
+ }
+ up(&usb_device_class->sem);
+
+ return dev;
+};
+
+void usbdev_add(struct usb_device *dev)
+{
+ int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
+
+ dev->class_dev = class_device_create(usb_device_class,
+ MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
+ "usbdev%d.%d", dev->bus->busnum, dev->devnum);
+
+ dev->class_dev->class_data = dev;
+}
+
+void usbdev_remove(struct usb_device *dev)
+{
+ class_device_unregister(dev->class_dev);
+}
+
+static struct cdev usb_device_cdev = {
+ .kobj = {.name = "usb_device", },
+ .owner = THIS_MODULE,
+};
+
+int __init usbdev_init(void)
+{
+ int retval;
+
+ retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
+ "usb_device");
+ if (retval) {
+ err("unable to register minors for usb_device");
+ goto out;
+ }
+ cdev_init(&usb_device_cdev, &usbfs_device_file_operations);
+ retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
+ if (retval) {
+ err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
+ unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ goto out;
+ }
+ usb_device_class = class_create(THIS_MODULE, "usb_device");
+ if (IS_ERR(usb_device_class)) {
+ err("unable to register usb_device class");
+ retval = PTR_ERR(usb_device_class);
+ usb_device_class = NULL;
+ cdev_del(&usb_device_cdev);
+ unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+ }
+
+out:
+ return retval;
+}
+
+void usbdev_cleanup(void)
+{
+ class_destroy(usb_device_class);
+ cdev_del(&usb_device_cdev);
+ unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
+}
+
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index fc056062c96..cbb451d227d 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)
}
}
-#ifdef CONFIG_PCI_NAMES
- hcd->product_desc = dev->pretty_name;
-#endif
-
pci_set_master (dev);
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)
retval = pci_set_power_state (dev, PCI_D3hot);
if (retval == 0) {
dev_dbg (hcd->self.controller, "--> PCI D3\n");
- pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
- pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
+ retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup);
+ if (retval)
+ break;
+ retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup);
} else if (retval < 0) {
dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n",
retval);
@@ -339,8 +337,20 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
dev->current_state);
}
#endif
- pci_enable_wake (dev, dev->current_state, 0);
- pci_enable_wake (dev, PCI_D3cold, 0);
+ retval = pci_enable_wake (dev, dev->current_state, 0);
+ if (retval) {
+ dev_err(hcd->self.controller,
+ "can't enable_wake to %d, %d!\n",
+ dev->current_state, retval);
+ return retval;
+ }
+ retval = pci_enable_wake (dev, PCI_D3cold, 0);
+ if (retval) {
+ dev_err(hcd->self.controller,
+ "can't enable_wake to %d, %d!\n",
+ PCI_D3cold, retval);
+ return retval;
+ }
} else {
/* Same basic cases: clean (powered/not), dirty */
dev_dbg(hcd->self.controller, "PCI legacy resume\n");
@@ -380,7 +390,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
usb_hc_died (hcd);
}
- pci_enable_device(dev);
+ retval = pci_enable_device(dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 28055f95645..ac451fa7e4d 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);
* to preallocate bandwidth)
*/
#define USB2_HOST_DELAY 5 /* nsec, guess */
-#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \
- + ((2083UL * (3167 + BitTime (bytes)))/1000) \
+#define HS_NSECS(bytes) ( ((55 * 8 * 2083) \
+ + (2083UL * (3 + BitTime(bytes))))/1000 \
+ USB2_HOST_DELAY)
-#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \
- + ((2083UL * (3167 + BitTime (bytes)))/1000) \
+#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \
+ + (2083UL * (3 + BitTime(bytes))))/1000 \
+ USB2_HOST_DELAY)
#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
#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 c9412daff68..758c7f0ed15 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,
return ret;
}
+static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+{
+ struct usb_device *hdev = hub->hdev;
+ int ret;
+
+ if (hdev->children[port1-1] && set_state) {
+ usb_set_device_state(hdev->children[port1-1],
+ USB_STATE_NOTATTACHED);
+ }
+ ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
+ if (ret)
+ dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
+ port1, ret);
+
+ return ret;
+}
+
static int hub_configure(struct usb_hub *hub,
struct usb_endpoint_descriptor *endpoint)
{
@@ -610,19 +627,33 @@ static int hub_configure(struct usb_hub *hub,
break;
}
+ /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
- case 0x00:
- if (hdev->descriptor.bDeviceProtocol != 0)
- dev_dbg(hub_dev, "TT requires at most 8 FS bit times\n");
+ case HUB_TTTT_8_BITS:
+ if (hdev->descriptor.bDeviceProtocol != 0) {
+ hub->tt.think_time = 666;
+ dev_dbg(hub_dev, "TT requires at most %d "
+ "FS bit times (%d ns)\n",
+ 8, hub->tt.think_time);
+ }
break;
- case 0x20:
- dev_dbg(hub_dev, "TT requires at most 16 FS bit times\n");
+ case HUB_TTTT_16_BITS:
+ hub->tt.think_time = 666 * 2;
+ dev_dbg(hub_dev, "TT requires at most %d "
+ "FS bit times (%d ns)\n",
+ 16, hub->tt.think_time);
break;
- case 0x40:
- dev_dbg(hub_dev, "TT requires at most 24 FS bit times\n");
+ case HUB_TTTT_24_BITS:
+ hub->tt.think_time = 666 * 3;
+ dev_dbg(hub_dev, "TT requires at most %d "
+ "FS bit times (%d ns)\n",
+ 24, hub->tt.think_time);
break;
- case 0x60:
- dev_dbg(hub_dev, "TT requires at most 32 FS bit times\n");
+ case HUB_TTTT_32_BITS:
+ hub->tt.think_time = 666 * 4;
+ dev_dbg(hub_dev, "TT requires at most %d "
+ "FS bit times (%d ns)\n",
+ 32, hub->tt.think_time);
break;
}
@@ -712,20 +743,36 @@ fail:
static unsigned highspeed_hubs;
+/* Called after the hub driver is unbound from a hub with children */
+static void hub_remove_children_work(void *__hub)
+{
+ struct usb_hub *hub = __hub;
+ struct usb_device *hdev = hub->hdev;
+ int i;
+
+ kfree(hub);
+
+ usb_lock_device(hdev);
+ for (i = 0; i < hdev->maxchild; ++i) {
+ if (hdev->children[i])
+ usb_disconnect(&hdev->children[i]);
+ }
+ usb_unlock_device(hdev);
+ usb_put_dev(hdev);
+}
+
static void hub_disconnect(struct usb_interface *intf)
{
struct usb_hub *hub = usb_get_intfdata (intf);
struct usb_device *hdev;
+ int n, port1;
- if (!hub)
- return;
+ usb_set_intfdata (intf, NULL);
hdev = hub->hdev;
if (hdev->speed == USB_SPEED_HIGH)
highspeed_hubs--;
- usb_set_intfdata (intf, NULL);
-
hub_quiesce(hub);
usb_free_urb(hub->urb);
hub->urb = NULL;
@@ -746,8 +793,27 @@ static void hub_disconnect(struct usb_interface *intf)
hub->buffer = NULL;
}
- /* Free the memory */
- kfree(hub);
+ /* If there are any children then this is an unbind only, not a
+ * physical disconnection. The active ports must be disabled
+ * and later on we must call usb_disconnect(). We can't call
+ * it now because we may not hold the hub's device lock.
+ */
+ n = 0;
+ for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+ if (hdev->children[port1 - 1]) {
+ ++n;
+ hub_port_disable(hub, port1, 1);
+ }
+ }
+
+ if (n == 0)
+ kfree(hub);
+ else {
+ /* Reuse the hub->leds work_struct for our own purposes */
+ INIT_WORK(&hub->leds, hub_remove_children_work, hub);
+ schedule_work(&hub->leds);
+ usb_get_dev(hdev);
+ }
}
static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1051,6 +1117,7 @@ void usb_disconnect(struct usb_device **pdev)
dev_dbg (&udev->dev, "unregistering device\n");
release_address(udev);
usbfs_remove_device(udev);
+ usbdev_remove(udev);
usb_remove_sysfs_dev_files(udev);
/* Avoid races with recursively_mark_NOTATTACHED() */
@@ -1290,6 +1357,7 @@ int usb_new_device(struct usb_device *udev)
/* USB device state == configured ... usable */
/* add a /proc/bus/usb entry */
+ usbdev_add(udev);
usbfs_add_device(udev);
return 0;
@@ -1428,23 +1496,6 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
return status;
}
-static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
-{
- struct usb_device *hdev = hub->hdev;
- int ret;
-
- if (hdev->children[port1-1] && set_state) {
- usb_set_device_state(hdev->children[port1-1],
- USB_STATE_NOTATTACHED);
- }
- ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
- if (ret)
- dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
- port1, ret);
-
- return ret;
-}
-
/*
* Disable a port and mark a logical connnect-change event, so that some
* 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 53bf5649621..e7fa9b5a521 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -157,6 +157,12 @@ enum hub_led_mode {
struct usb_device;
+/* Transaction Translator Think Times, in bits */
+#define HUB_TTTT_8_BITS 0x00
+#define HUB_TTTT_16_BITS 0x20
+#define HUB_TTTT_24_BITS 0x40
+#define HUB_TTTT_32_BITS 0x60
+
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
@@ -170,6 +176,7 @@ struct usb_device;
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
+ unsigned think_time; /* think time in ns */
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
spinlock_t lock;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index c3e3a95d380..640f41e4702 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -728,15 +728,9 @@ int __init usbfs_init(void)
{
int retval;
- retval = usb_register(&usbfs_driver);
- if (retval)
- return retval;
-
retval = register_filesystem(&usb_fs_type);
- if (retval) {
- usb_deregister(&usbfs_driver);
+ if (retval)
return retval;
- }
/* create mount point for usbfs */
usbdir = proc_mkdir("usb", proc_bus);
@@ -746,7 +740,6 @@ int __init usbfs_init(void)
void usbfs_cleanup(void)
{
- usb_deregister(&usbfs_driver);
unregister_filesystem(&usb_fs_type);
if (usbdir)
remove_proc_entry("usb", proc_bus);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 88d1b376f67..c47c8052b48 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)
init_completion(&done);
urb->context = &done;
- urb->transfer_flags |= URB_ASYNC_UNLINK;
urb->actual_length = 0;
status = usb_submit_urb(urb, GFP_NOIO);
@@ -266,7 +265,9 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
continue;
if (found) {
status = usb_unlink_urb (io->urbs [i]);
- if (status != -EINPROGRESS && status != -EBUSY)
+ if (status != -EINPROGRESS
+ && status != -ENODEV
+ && status != -EBUSY)
dev_err (&io->dev->dev,
"%s, unlink --> %d\n",
__FUNCTION__, status);
@@ -357,8 +358,7 @@ int usb_sg_init (
if (!io->urbs)
goto nomem;
- urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP
- | URB_NO_INTERRUPT;
+ urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
if (usb_pipein (pipe))
urb_flags |= URB_SHORT_NOT_OK;
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c0feee25ff0..c846fefb738 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)
unsigned int allowed;
/* enforce simple/standard policy */
- allowed = URB_ASYNC_UNLINK; // affects later unlinks
- allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
- allowed |= URB_NO_INTERRUPT;
+ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
+ URB_NO_INTERRUPT);
switch (temp) {
case PIPE_BULK:
if (is_out)
@@ -400,14 +399,8 @@ int usb_submit_urb(struct urb *urb, unsigned mem_flags)
* canceled (rather than any other code) and will quickly be removed
* from host controller data structures.
*
- * In the past, clearing the URB_ASYNC_UNLINK transfer flag for the
- * URB indicated that the request was synchronous. This usage is now
- * deprecated; if the flag is clear the call will be forwarded to
- * usb_kill_urb() and the return value will be 0. In the future, drivers
- * should call usb_kill_urb() directly for synchronous unlinking.
- *
- * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
- * request is asynchronous. Success is indicated by returning -EINPROGRESS,
+ * This request is always asynchronous.
+ * Success is indicated by returning -EINPROGRESS,
* at which time the URB will normally have been unlinked but not yet
* given back to the device driver. When it is called, the completion
* function will see urb->status == -ECONNRESET. Failure is indicated
@@ -453,17 +446,6 @@ int usb_unlink_urb(struct urb *urb)
{
if (!urb)
return -EINVAL;
- if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) {
-#ifdef CONFIG_DEBUG_KERNEL
- if (printk_ratelimit()) {
- printk(KERN_NOTICE "usb_unlink_urb() is deprecated for "
- "synchronous unlinks. Use usb_kill_urb() instead.\n");
- WARN_ON(1);
- }
-#endif
- usb_kill_urb(urb);
- return 0;
- }
if (!(urb->dev && urb->dev->bus && urb->dev->bus->op))
return -ENODEV;
return urb->dev->bus->op->unlink_urb(urb, -ECONNRESET);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 2cddd8a0043..087af73a59d 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -65,6 +65,16 @@ static int generic_probe (struct device *dev)
}
static int generic_remove (struct device *dev)
{
+ struct usb_device *udev = to_usb_device(dev);
+
+ /* if this is only an unbind, not a physical disconnect, then
+ * unconfigure the device */
+ if (udev->state == USB_STATE_CONFIGURED)
+ usb_set_configuration(udev, 0);
+
+ /* in case the call failed or the device was suspended */
+ if (udev->state >= USB_STATE_CONFIGURED)
+ usb_disable_device(udev, 0);
return 0;
}
@@ -912,7 +922,7 @@ int usb_trylock_device(struct usb_device *udev)
* is neither BINDING nor BOUND. Rather than sleeping to wait for the
* lock, the routine polls repeatedly. This is to prevent deadlock with
* disconnect; in some drivers (such as usb-storage) the disconnect()
- * callback will block waiting for a device reset to complete.
+ * or suspend() method will block waiting for a device reset to complete.
*
* Returns a negative error code for failure, otherwise 1 or 0 to indicate
* 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)
int usb_lock_device_for_reset(struct usb_device *udev,
struct usb_interface *iface)
{
+ unsigned long jiffies_expire = jiffies + HZ;
+
if (udev->state == USB_STATE_NOTATTACHED)
return -ENODEV;
if (udev->state == USB_STATE_SUSPENDED)
@@ -938,6 +950,12 @@ int usb_lock_device_for_reset(struct usb_device *udev,
}
while (!usb_trylock_device(udev)) {
+
+ /* If we can't acquire the lock after waiting one second,
+ * we're probably deadlocked */
+ if (time_after(jiffies, jiffies_expire))
+ return -EBUSY;
+
msleep(15);
if (udev->state == USB_STATE_NOTATTACHED)
return -ENODEV;
@@ -1478,13 +1496,18 @@ static int __init usb_init(void)
retval = usb_major_init();
if (retval)
goto major_init_failed;
+ retval = usb_register(&usbfs_driver);
+ if (retval)
+ goto driver_register_failed;
+ retval = usbdev_init();
+ if (retval)
+ goto usbdevice_init_failed;
retval = usbfs_init();
if (retval)
goto fs_init_failed;
retval = usb_hub_init();
if (retval)
goto hub_init_failed;
-
retval = driver_register(&usb_generic_driver);
if (!retval)
goto out;
@@ -1493,7 +1516,11 @@ static int __init usb_init(void)
hub_init_failed:
usbfs_cleanup();
fs_init_failed:
- usb_major_cleanup();
+ usbdev_cleanup();
+usbdevice_init_failed:
+ usb_deregister(&usbfs_driver);
+driver_register_failed:
+ usb_major_cleanup();
major_init_failed:
usb_host_cleanup();
host_init_failed:
@@ -1514,6 +1541,8 @@ static void __exit usb_exit(void)
driver_unregister(&usb_generic_driver);
usb_major_cleanup();
usbfs_cleanup();
+ usb_deregister(&usbfs_driver);
+ usbdev_cleanup();
usb_hub_cleanup();
usb_host_cleanup();
bus_unregister(&usb_bus_type);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 2c690f6d4c1..83d48c8133a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -37,6 +37,11 @@ extern struct file_operations usbfs_devices_fops;
extern struct file_operations usbfs_device_file_operations;
extern void usbfs_conn_disc_event(void);
+extern int usbdev_init(void);
+extern void usbdev_cleanup(void);
+extern void usbdev_add(struct usb_device *dev);
+extern void usbdev_remove(struct usb_device *dev);
+extern struct usb_device *usbdev_lookup_minor(int minor);
struct dev_state {
struct list_head list; /* state list */
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8509e955007..49459e33e95 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2181,6 +2181,7 @@ eth_bind (struct usb_gadget *gadget)
u8 cdc = 1, zlp = 1, rndis = 1;
struct usb_ep *in_ep, *out_ep, *status_ep = NULL;
int status = -ENOMEM;
+ int gcnum;
/* these flags are only ever cleared; compiler take note */
#ifndef DEV_CONFIG_CDC
@@ -2194,44 +2195,26 @@ eth_bind (struct usb_gadget *gadget)
* standard protocol is _strongly_ preferred for interop purposes.
* (By everyone except Microsoft.)
*/
- if (gadget_is_net2280 (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
- } else if (gadget_is_dummy (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0202);
- } else if (gadget_is_pxa (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
+ if (gadget_is_pxa (gadget)) {
/* pxa doesn't support altsettings */
cdc = 0;
} else if (gadget_is_sh(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
/* sh doesn't support multiple interfaces or configs */
cdc = 0;
rndis = 0;
} else if (gadget_is_sa1100 (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
/* hardware can't write zlps */
zlp = 0;
/* sa1100 CAN do CDC, without status endpoint ... we use
* non-CDC to be compatible with ARM Linux-2.4 "usb-eth".
*/
cdc = 0;
- } else if (gadget_is_goku (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
- } else if (gadget_is_mq11xx (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
- } else if (gadget_is_omap (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
- } else if (gadget_is_lh7a40x(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
- } else if (gadget_is_n9604(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
- } else if (gadget_is_pxa27x(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
- } else if (gadget_is_s3c2410(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
- } else if (gadget_is_at91(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
- } else {
+ }
+
+ gcnum = usb_gadget_controller_number (gadget);
+ if (gcnum >= 0)
+ device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+ else {
/* can't assume CDC works. don't want to default to
* anything less functional on CDC-capable hardware,
* so we fail in this case.
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 4f57085619b..a41d9d4baee 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)
static int __init check_parameters(struct fsg_dev *fsg)
{
int prot;
+ int gcnum;
/* Store the default values */
mod_data.transport_type = USB_PR_BULK;
@@ -3724,33 +3725,13 @@ static int __init check_parameters(struct fsg_dev *fsg)
mod_data.can_stall = 0;
if (mod_data.release == 0xffff) { // Parameter wasn't set
- if (gadget_is_net2280(fsg->gadget))
- mod_data.release = 0x0301;
- else if (gadget_is_dummy(fsg->gadget))
- mod_data.release = 0x0302;
- else if (gadget_is_pxa(fsg->gadget))
- mod_data.release = 0x0303;
- else if (gadget_is_sh(fsg->gadget))
- mod_data.release = 0x0304;
-
/* The sa1100 controller is not supported */
-
- else if (gadget_is_goku(fsg->gadget))
- mod_data.release = 0x0306;
- else if (gadget_is_mq11xx(fsg->gadget))
- mod_data.release = 0x0307;
- else if (gadget_is_omap(fsg->gadget))
- mod_data.release = 0x0308;
- else if (gadget_is_lh7a40x(fsg->gadget))
- mod_data.release = 0x0309;
- else if (gadget_is_n9604(fsg->gadget))
- mod_data.release = 0x0310;
- else if (gadget_is_pxa27x(fsg->gadget))
- mod_data.release = 0x0311;
- else if (gadget_is_s3c2410(gadget))
- mod_data.release = 0x0312;
- else if (gadget_is_at91(fsg->gadget))
- mod_data.release = 0x0313;
+ if (gadget_is_sa1100(fsg->gadget))
+ gcnum = -1;
+ else
+ gcnum = usb_gadget_controller_number(fsg->gadget);
+ if (gcnum >= 0)
+ mod_data.release = 0x0300 + gcnum;
else {
WARN(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index ea2eb52c766..8cbae21d84b 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -5,6 +5,7 @@
*
* This could eventually work like the ARM mach_is_*() stuff, driven by
* some config file that gets updated as new hardware is supported.
+ * (And avoiding the runtime comparisons in typical one-choice cases.)
*
* NOTE: some of these controller drivers may not be available yet.
*/
@@ -86,7 +87,61 @@
#define gadget_is_at91(g) 0
#endif
+#ifdef CONFIG_USB_GADGET_IMX
+#define gadget_is_imx(g) !strcmp("imx_udc", (g)->name)
+#else
+#define gadget_is_imx(g) 0
+#endif
+
// CONFIG_USB_GADGET_SX2
// CONFIG_USB_GADGET_AU1X00
// ...
+
+/**
+ * usb_gadget_controller_number - support bcdDevice id convention
+ * @gadget: the controller being driven
+ *
+ * Return a 2-digit BCD value associated with the peripheral controller,
+ * suitable for use as part of a bcdDevice value, or a negative error code.
+ *
+ * NOTE: this convention is purely optional, and has no meaning in terms of
+ * any USB specification. If you want to use a different convention in your
+ * gadget driver firmware -- maybe a more formal revision ID -- feel free.
+ *
+ * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
+ * to change their behavior accordingly. For example it might help avoiding
+ * some chip bug.
+ */
+static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
+{
+ if (gadget_is_net2280(gadget))
+ return 0x01;
+ else if (gadget_is_dummy(gadget))
+ return 0x02;
+ else if (gadget_is_pxa(gadget))
+ return 0x03;
+ else if (gadget_is_sh(gadget))
+ return 0x04;
+ else if (gadget_is_sa1100(gadget))
+ return 0x05;
+ else if (gadget_is_goku(gadget))
+ return 0x06;
+ else if (gadget_is_mq11xx(gadget))
+ return 0x07;
+ else if (gadget_is_omap(gadget))
+ return 0x08;
+ else if (gadget_is_lh7a40x(gadget))
+ return 0x09;
+ else if (gadget_is_n9604(gadget))
+ return 0x10;
+ else if (gadget_is_pxa27x(gadget))
+ return 0x11;
+ else if (gadget_is_s3c2410(gadget))
+ return 0x12;
+ else if (gadget_is_at91(gadget))
+ return 0x13;
+ else if (gadget_is_imx(gadget))
+ return 0x14;
+ return -ENOENT;
+}
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 9e4f1c6935a..c925d9222f5 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)
int ret;
struct usb_ep *ep;
struct gs_dev *dev;
+ int gcnum;
- /* device specific */
- if (gadget_is_net2280(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0001);
- } else if (gadget_is_pxa(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0002);
- } else if (gadget_is_sh(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0003);
- /* sh doesn't support multiple interfaces or configs */
+ /* Some controllers can't support CDC ACM:
+ * - sh doesn't support multiple interfaces or configs;
+ * - sa1100 doesn't have a third interrupt endpoint
+ */
+ if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
use_acm = 0;
- } else if (gadget_is_sa1100(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0004);
- /* sa1100 doesn't support necessary endpoints */
- use_acm = 0;
- } else if (gadget_is_goku(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0005);
- } else if (gadget_is_mq11xx(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0006);
- } else if (gadget_is_omap(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0007);
- } else if (gadget_is_lh7a40x(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0008);
- } else if (gadget_is_n9604(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0009);
- } else if (gadget_is_pxa27x(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0011);
- } else if (gadget_is_s3c2410(gadget)) {
- gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0012);
- } else if (gadget_is_at91(gadget)) {
+
+ gcnum = usb_gadget_controller_number(gadget);
+ if (gcnum >= 0)
gs_device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM|0x0013);
- } else {
+ cpu_to_le16(GS_VERSION_NUM | gcnum);
+ else {
printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index bb9b2d94eed..6890e773b2a 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1139,6 +1139,13 @@ zero_bind (struct usb_gadget *gadget)
{
struct zero_dev *dev;
struct usb_ep *ep;
+ int gcnum;
+
+ /* FIXME this can't yet work right with SH ... it has only
+ * one configuration, numbered one.
+ */
+ if (gadget_is_sh(gadget))
+ return -ENODEV;
/* Bulk-only drivers like this one SHOULD be able to
* autoconfigure on any sane usb controller driver,
@@ -1161,43 +1168,10 @@ autoconf_fail:
EP_OUT_NAME = ep->name;
ep->driver_data = ep; /* claim */
-
- /*
- * DRIVER POLICY CHOICE: you may want to do this differently.
- * One thing to avoid is reusing a bcdDevice revision code
- * with different host-visible configurations or behavior
- * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc
- */
- if (gadget_is_net2280 (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
- } else if (gadget_is_pxa (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0203);
-#if 0
- } else if (gadget_is_sh(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0204);
- /* SH has only one configuration; see "loopdefault" */
- device_desc.bNumConfigurations = 1;
- /* FIXME make 1 == default.bConfigurationValue */
-#endif
- } else if (gadget_is_sa1100 (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0205);
- } else if (gadget_is_goku (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0206);
- } else if (gadget_is_mq11xx (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
- } else if (gadget_is_omap (gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
- } else if (gadget_is_lh7a40x(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
- } else if (gadget_is_n9604(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
- } else if (gadget_is_pxa27x(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
- } else if (gadget_is_s3c2410(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212);
- } else if (gadget_is_at91(gadget)) {
- device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213);
- } else {
+ gcnum = usb_gadget_controller_number (gadget);
+ if (gcnum >= 0)
+ device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
+ else {
/* gadget zero is so simple (for now, no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
* 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 149b13fc0a7..2507e898af0 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)
hcd->can_wakeup = (port_wake & 1) != 0;
/* help hc dma work well with cachelines */
- pci_set_mwi (pdev);
+ retval = pci_set_mwi(pdev);
+ if (retval)
+ ehci_dbg(ehci, "unable to enable MWI - not fatal.\n");
}
#endif
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 20df01a79b2..940d38ca7d9 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -677,6 +677,9 @@ qh_make (
goto done;
}
} else {
+ struct usb_tt *tt = urb->dev->tt;
+ int think_time;
+
/* gap is f(FS/LS transfer times) */
qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
is_input, 0, maxp) / (125 * 1000);
@@ -690,6 +693,10 @@ qh_make (
qh->c_usecs = HS_USECS (0);
}
+ think_time = tt ? tt->think_time : 0;
+ qh->tt_usecs = NS_TO_US (think_time +
+ usb_calc_bus_time (urb->dev->speed,
+ is_input, 0, max_packet (maxp)));
qh->period = urb->interval;
}
}
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 4c972b57c7c..ccc7300baa6 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -700,6 +700,7 @@ iso_stream_init (
} else {
u32 addr;
+ int think_time;
addr = dev->ttport << 24;
if (!ehci_is_TDI(ehci)
@@ -709,6 +710,9 @@ iso_stream_init (
addr |= epnum << 8;
addr |= dev->devnum;
stream->usecs = HS_USECS_ISO (maxp);
+ think_time = dev->tt ? dev->tt->think_time : 0;
+ stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
+ dev->speed, is_input, 1, maxp));
if (is_input) {
u32 tmp;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index a7542157534..20c9b550097 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -421,6 +421,7 @@ struct ehci_qh {
u8 usecs; /* intr bandwidth */
u8 gap_uf; /* uframes split/csplit gap */
u8 c_usecs; /* ... split completion bw */
+ u16 tt_usecs; /* tt downstream bandwidth */
unsigned short period; /* polling interval */
unsigned short start; /* where polling starts */
#define NO_FRAME ((unsigned short)~0) /* pick new start */
@@ -479,6 +480,7 @@ struct ehci_iso_stream {
*/
u8 interval;
u8 usecs, c_usecs;
+ u16 tt_usecs;
u16 maxp;
u16 raw_mask;
unsigned bandwidth;
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 81f8f6b7fdc..a8267cf17db 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[] =
0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
};
-static struct timer_list bulk_start_timer = TIMER_INITIALIZER(NULL, 0, 0);
-static struct timer_list bulk_eot_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(bulk_start_timer, NULL, 0, 0);
+static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0);
/* We want the start timer to expire before the eot timer, because the former might start
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 75128c37180..41bbae83fc7 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -83,7 +83,7 @@
#include "../core/hcd.h"
#include "isp116x.h"
-#define DRIVER_VERSION "08 Apr 2005"
+#define DRIVER_VERSION "05 Aug 2005"
#define DRIVER_DESC "ISP116x USB Host Controller Driver"
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -629,14 +629,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
ERR("Unrecoverable error\n");
/* What should we do here? Reset? */
}
- if (intstat & HCINT_RHSC) {
- isp116x->rhstatus =
- isp116x_read_reg32(isp116x, HCRHSTATUS);
- isp116x->rhport[0] =
- isp116x_read_reg32(isp116x, HCRHPORT1);
- isp116x->rhport[1] =
- isp116x_read_reg32(isp116x, HCRHPORT2);
- }
+ if (intstat & HCINT_RHSC)
+ /* When root hub or any of its ports is going
+ to come out of suspend, it may take more
+ than 10ms for status bits to stabilize. */
+ mod_timer(&hcd->rh_timer, jiffies
+ + msecs_to_jiffies(20) + 1);
if (intstat & HCINT_RD) {
DBG("---- remote wakeup\n");
schedule_work(&isp116x->rh_resume);
@@ -925,20 +923,27 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
int ports, i, changed = 0;
+ unsigned long flags;
if (!HC_IS_RUNNING(hcd->state))
return -ESHUTDOWN;
- ports = isp116x->rhdesca & RH_A_NDP;
+ /* Report no status change now, if we are scheduled to be
+ called later */
+ if (timer_pending(&hcd->rh_timer))
+ return 0;
- /* init status */
+ ports = isp116x->rhdesca & RH_A_NDP;
+ spin_lock_irqsave(&isp116x->lock, flags);
+ isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
buf[0] = changed = 1;
else
buf[0] = 0;
for (i = 0; i < ports; i++) {
- u32 status = isp116x->rhport[i];
+ u32 status = isp116x->rhport[i] =
+ isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC)) {
@@ -947,6 +952,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
continue;
}
}
+ spin_unlock_irqrestore(&isp116x->lock, flags);
return changed;
}
@@ -1463,10 +1469,6 @@ static int isp116x_sw_reset(struct isp116x *isp116x)
return ret;
}
-/*
- Reset. Tries to perform platform-specific hardware
- reset first; falls back to software reset.
-*/
static int isp116x_reset(struct usb_hcd *hcd)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
@@ -1474,17 +1476,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
u16 clkrdy = 0;
int ret = 0, timeout = 15 /* ms */ ;
- if (isp116x->board && isp116x->board->reset) {
- /* Hardware reset */
- isp116x->board->reset(hcd->self.controller, 1);
- msleep(10);
- if (isp116x->board->clock)
- isp116x->board->clock(hcd->self.controller, 1);
- msleep(1);
- isp116x->board->reset(hcd->self.controller, 0);
- } else
- ret = isp116x_sw_reset(isp116x);
-
+ ret = isp116x_sw_reset(isp116x);
if (ret)
return ret;
@@ -1501,10 +1493,7 @@ static int isp116x_reset(struct usb_hcd *hcd)
ERR("Clock not ready after 20ms\n");
/* After sw_reset the clock won't report to be ready, if
H_WAKEUP pin is high. */
- if (!isp116x->board || !isp116x->board->reset)
- ERR("The driver does not support hardware wakeup.\n");
- ERR("Please make sure that the H_WAKEUP pin "
- "is pulled low!\n");
+ ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
ret = -ENODEV;
}
return ret;
@@ -1527,15 +1516,7 @@ static void isp116x_stop(struct usb_hcd *hcd)
isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
spin_unlock_irqrestore(&isp116x->lock, flags);
- /* Put the chip into reset state */
- if (isp116x->board && isp116x->board->reset)
- isp116x->board->reset(hcd->self.controller, 0);
- else
- isp116x_sw_reset(isp116x);
-
- /* Stop the clock */
- if (isp116x->board && isp116x->board->clock)
- isp116x->board->clock(hcd->self.controller, 0);
+ isp116x_sw_reset(isp116x);
}
/*
@@ -1561,6 +1542,9 @@ static int isp116x_start(struct usb_hcd *hcd)
return -ENODEV;
}
+ /* To be removed in future */
+ hcd->uses_new_polling = 1;
+
isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
@@ -1569,7 +1553,7 @@ static int isp116x_start(struct usb_hcd *hcd)
if (board->sel15Kres)
val |= HCHWCFG_15KRSEL;
/* Remote wakeup won't work without working clock */
- if (board->clknotstop || board->remote_wakeup_enable)
+ if (board->remote_wakeup_enable)
val |= HCHWCFG_CLKNOTSTOP;
if (board->oc_enable)
val |= HCHWCFG_ANALOG_OC;
@@ -1580,16 +1564,13 @@ static int isp116x_start(struct usb_hcd *hcd)
isp116x_write_reg16(isp116x, HCHWCFG, val);
/* ----- Root hub conf */
- val = 0;
- /* AN10003_1.pdf recommends NPS to be always 1 */
- if (board->no_power_switching)
- val |= RH_A_NPS;
- if (board->power_switching_mode)
- val |= RH_A_PSM;
- if (board->potpg)
- val |= (board->potpg << 24) & RH_A_POTPGT;
- else
- val |= (25 << 24) & RH_A_POTPGT;
+ val = (25 << 24) & RH_A_POTPGT;
+ /* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
+ be always set. Yet, instead, we request individual port
+ power switching. */
+ val |= RH_A_PSM;
+ /* Report overcurrent per port */
+ val |= RH_A_OCPM;
isp116x_write_reg32(isp116x, HCRHDESCA, val);
isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
@@ -1619,9 +1600,6 @@ static int isp116x_start(struct usb_hcd *hcd)
/* Go operational */
val = HCCONTROL_USB_OPER;
- /* Remote wakeup connected - NOT SUPPORTED */
- /* if (board->remote_wakeup_connected)
- val |= HCCONTROL_RWC; */
if (board->remote_wakeup_enable)
val |= HCCONTROL_RWE;
isp116x_write_reg32(isp116x, HCCONTROL, val);
@@ -1670,7 +1648,7 @@ static int __init_or_module isp116x_remove(struct device *dev)
struct platform_device *pdev;
struct resource *res;
- if(!hcd)
+ if (!hcd)
return 0;
isp116x = hcd_to_isp116x(hcd);
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 17964c39d06..25153336302 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -14,8 +14,6 @@
* This file is licenced under the GPL.
*/
-#include <asm/usb.h>
-
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
@@ -23,9 +21,7 @@
* usb_hcd_ppc_soc_probe - initialize On-Chip HCDs
* Context: !in_interrupt()
*
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
+ * Allocates basic resources for this USB host controller.
*
* Store this function in the HCD's struct pci_driver as probe().
*/
@@ -37,7 +33,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
struct ohci_hcd *ohci;
struct resource *res;
int irq;
- struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
pr_debug("initializing PPC-SOC USB Controller\n");
@@ -73,9 +68,6 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
goto err2;
}
- if (pd->start && (retval = pd->start(pdev)))
- goto err3;
-
ohci = hcd_to_ohci(hcd);
ohci->flags |= OHCI_BIG_ENDIAN;
ohci_hcd_init(ohci);
@@ -85,9 +77,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver,
return retval;
pr_debug("Removing PPC-SOC USB Controller\n");
- if (pd && pd->stop)
- pd->stop(pdev);
- err3:
+
iounmap(hcd->regs);
err2:
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,
* @pdev: USB Host Controller being removed
* Context: !in_interrupt()
*
- * Reverses the effect of usb_hcd_ppc_soc_probe(), first invoking
- * the HCD's stop() method. It is always called from a thread
+ * Reverses the effect of usb_hcd_ppc_soc_probe().
+ * It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*
*/
static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd,
struct platform_device *pdev)
{
- struct usb_hcd_platform_data *pd = pdev->dev.platform_data;
-
usb_remove_hcd(hcd);
pr_debug("stopping PPC-SOC USB Controller\n");
- if (pd && pd->stop)
- pd->stop(pdev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_hcd_put(hcd);
+ usb_put_hcd(hcd);
}
static int __devinit
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e9401662503..3d9bcf78a9a 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,
if (info->power_control != NULL) {
info->port[port-1].power = to;
- (info->power_control)(port, to);
+ (info->power_control)(port-1, to);
}
}
@@ -339,8 +339,8 @@ int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
struct usb_hcd *hcd = NULL;
int retval;
- s3c2410_usb_set_power(dev->dev.platform_data, 0, 1);
s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
+ s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);
hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
if (hcd == NULL)
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 298e4a25e3d..482c4be521f 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -230,6 +230,20 @@ config USB_EGALAX
To compile this driver as a module, choose M here: the
module will be called touchkitusb.
+config USB_YEALINK
+ tristate "Yealink usb-p1k voip phone"
+ depends on USB && INPUT && EXPERIMENTAL
+ ---help---
+ Say Y here if you want to enable keyboard and LCD functions of the
+ Yealink usb-p1k usb phones. The audio part is enabled by the generic
+ usb sound driver, so you might want to enable that as well.
+
+ For information about how to use these additional functions, see
+ <file:Documentation/input/yealink.txt>.
+
+ To compile this driver as a module, choose M here: the module will be
+ called yealink.
+
config USB_XPAD
tristate "X-Box gamepad support"
depends on USB && INPUT
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index f1547be632d..43b2f999edf 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -39,4 +39,5 @@ obj-$(CONFIG_USB_EGALAX) += touchkitusb.o
obj-$(CONFIG_USB_POWERMATE) += powermate.o
obj-$(CONFIG_USB_WACOM) += wacom.o
obj-$(CONFIG_USB_ACECAD) += acecad.o
+obj-$(CONFIG_USB_YEALINK) += yealink.o
obj-$(CONFIG_USB_XPAD) += xpad.o
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index b2cb2b35892..1ab95d24c5e 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)
#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
#define USB_DEVICE_ID_POWERCONTROL 0x2030
+#define USB_VENDOR_ID_APPLE 0x05ac
+#define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000
/*
* Alphabetically sorted blacklist by quirk type.
@@ -1462,6 +1464,7 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_BLUETOOTH, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
{ 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)
usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
hid_irq_in, hid, interval);
hid->urbin->transfer_dma = hid->inbuf_dma;
- hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
+ hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
} else {
if (hid->urbout)
continue;
@@ -1695,7 +1698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
hid_irq_out, hid, interval);
hid->urbout->transfer_dma = hid->outbuf_dma;
- hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
+ hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
}
}
@@ -1747,7 +1750,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid->ctrlbuf, 1, hid_ctrl, hid);
hid->urbctrl->setup_dma = hid->cr_dma;
hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
- hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK);
+ hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
return hid;
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 67dc9368520..99de1b33c07 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
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
- /* See if the offered device matches what we can accept */
- if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
- (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
- return -ENODEV;
-
/* allocate memory for our device state and initialize it */
remote = kmalloc(sizeof(*remote), GFP_KERNEL);
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 00000000000..52ff27f1512
--- /dev/null
+++ b/drivers/usb/input/map_to_7segment.h
@@ -0,0 +1,189 @@
+/*
+ * drivers/usb/input/map_to_7segment.h
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MAP_TO_7SEGMENT_H
+#define MAP_TO_7SEGMENT_H
+
+/* This file provides translation primitives and tables for the conversion
+ * of (ASCII) characters to a 7-segments notation.
+ *
+ * The 7 segment's wikipedia notation below is used as standard.
+ * See: http://en.wikipedia.org/wiki/Seven_segment_display
+ *
+ * Notation: +-a-+
+ * f b
+ * +-g-+
+ * e c
+ * +-d-+
+ *
+ * Usage:
+ *
+ * Register a map variable, and fill it with a character set:
+ * static SEG7_DEFAULT_MAP(map_seg7);
+ *
+ *
+ * Then use for conversion:
+ * seg7 = map_to_seg7(&map_seg7, some_char);
+ * ...
+ *
+ * In device drivers it is recommended, if required, to make the char map
+ * accessible via the sysfs interface using the following scheme:
+ *
+ * static ssize_t show_map(struct device *dev, char *buf) {
+ * memcpy(buf, &map_seg7, sizeof(map_seg7));
+ * return sizeof(map_seg7);
+ * }
+ * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) {
+ * if(cnt != sizeof(map_seg7))
+ * return -EINVAL;
+ * memcpy(&map_seg7, buf, cnt);
+ * return cnt;
+ * }
+ * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map);
+ *
+ * History:
+ * 2005-05-31 RFC linux-kernel@vger.kernel.org
+ */
+#include <linux/errno.h>
+
+
+#define BIT_SEG7_A 0
+#define BIT_SEG7_B 1
+#define BIT_SEG7_C 2
+#define BIT_SEG7_D 3
+#define BIT_SEG7_E 4
+#define BIT_SEG7_F 5
+#define BIT_SEG7_G 6
+#define BIT_SEG7_RESERVED 7
+
+struct seg7_conversion_map {
+ unsigned char table[128];
+};
+
+static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
+{
+ return c & 0x7f ? map->table[c] : -EINVAL;
+}
+
+#define SEG7_CONVERSION_MAP(_name, _map) \
+ struct seg7_conversion_map _name = { .table = { _map } }
+
+/*
+ * It is recommended to use a facility that allows user space to redefine
+ * custom character sets for LCD devices. Please use a sysfs interface
+ * as described above.
+ */
+#define MAP_TO_SEG7_SYSFS_FILE "map_seg7"
+
+/*******************************************************************************
+ * ASCII conversion table
+ ******************************************************************************/
+
+#define _SEG7(l,a,b,c,d,e,f,g) \
+ ( a<<BIT_SEG7_A | b<<BIT_SEG7_B | c<<BIT_SEG7_C | d<<BIT_SEG7_D | \
+ e<<BIT_SEG7_E | f<<BIT_SEG7_F | g<<BIT_SEG7_G )
+
+#define _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
+ 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,
+
+#define _MAP_33_47_ASCII_SEG7_SYMBOL \
+ _SEG7('!',0,0,0,0,1,1,0), _SEG7('"',0,1,0,0,0,1,0), _SEG7('#',0,1,1,0,1,1,0),\
+ _SEG7('$',1,0,1,1,0,1,1), _SEG7('%',0,0,1,0,0,1,0), _SEG7('&',1,0,1,1,1,1,1),\
+ _SEG7('\'',0,0,0,0,0,1,0),_SEG7('(',1,0,0,1,1,1,0), _SEG7(')',1,1,1,1,0,0,0),\
+ _SEG7('*',0,1,1,0,1,1,1), _SEG7('+',0,1,1,0,0,0,1), _SEG7(',',0,0,0,0,1,0,0),\
+ _SEG7('-',0,0,0,0,0,0,1), _SEG7('.',0,0,0,0,1,0,0), _SEG7('/',0,1,0,0,1,0,1),
+
+#define _MAP_48_57_ASCII_SEG7_NUMERIC \
+ _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),\
+ _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),\
+ _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),\
+ _SEG7('9',1,1,1,1,0,1,1),
+
+#define _MAP_58_64_ASCII_SEG7_SYMBOL \
+ _SEG7(':',0,0,0,1,0,0,1), _SEG7(';',0,0,0,1,0,0,1), _SEG7('<',1,0,0,0,0,1,1),\
+ _SEG7('=',0,0,0,1,0,0,1), _SEG7('>',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\
+ _SEG7('@',1,1,0,1,1,1,1),
+
+#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
+
+#define _MAP_91_96_ASCII_SEG7_SYMBOL \
+ _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\
+ _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0),
+
+#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _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),\
+ _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
+
+#define _MAP_123_126_ASCII_SEG7_SYMBOL \
+ _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\
+ _SEG7('~',1,0,0,0,0,0,0),
+
+/* Maps */
+
+/* This set tries to map as close as possible to the visible characteristics
+ * of the ASCII symbol, lowercase and uppercase letters may differ in
+ * presentation on the display.
+ */
+#define MAP_ASCII7SEG_ALPHANUM \
+ _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
+ _MAP_33_47_ASCII_SEG7_SYMBOL \
+ _MAP_48_57_ASCII_SEG7_NUMERIC \
+ _MAP_58_64_ASCII_SEG7_SYMBOL \
+ _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
+ _MAP_91_96_ASCII_SEG7_SYMBOL \
+ _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
+ _MAP_123_126_ASCII_SEG7_SYMBOL
+
+/* This set tries to map as close as possible to the symbolic characteristics
+ * of the ASCII character for maximum discrimination.
+ * For now this means all alpha chars are in lower case representations.
+ * (This for example facilitates the use of hex numbers with uppercase input.)
+ */
+#define MAP_ASCII7SEG_ALPHANUM_LC \
+ _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
+ _MAP_33_47_ASCII_SEG7_SYMBOL \
+ _MAP_48_57_ASCII_SEG7_NUMERIC \
+ _MAP_58_64_ASCII_SEG7_SYMBOL \
+ _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
+ _MAP_91_96_ASCII_SEG7_SYMBOL \
+ _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
+ _MAP_123_126_ASCII_SEG7_SYMBOL
+
+#define SEG7_DEFAULT_MAP(_name) \
+ SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM)
+
+#endif /* MAP_TO_7SEGMENT_H */
+
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
new file mode 100644
index 00000000000..58a176ef96a
--- /dev/null
+++ b/drivers/usb/input/yealink.c
@@ -0,0 +1,1013 @@
+/*
+ * drivers/usb/input/yealink.c
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Description:
+ * Driver for the USB-P1K voip usb phone.
+ * This device is produced by Yealink Network Technology Co Ltd
+ * but may be branded under several names:
+ * - Yealink usb-p1k
+ * - Tiptel 115
+ * - ...
+ *
+ * This driver is based on:
+ * - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/
+ * - information from http://memeteau.free.fr/usbb2k
+ * - the xpad-driver drivers/usb/input/xpad.c
+ *
+ * Thanks to:
+ * - Olivier Vandorpe, for providing the usbb2k-api.
+ * - Martin Diehl, for spotting my memory allocation bug.
+ *
+ * History:
+ * 20050527 henk First version, functional keyboard. Keyboard events
+ * will pop-up on the ../input/eventX bus.
+ * 20050531 henk Added led, LCD, dialtone and sysfs interface.
+ * 20050610 henk Cleanups, make it ready for public consumption.
+ * 20050630 henk Cleanups, fixes in response to comments.
+ * 20050701 henk sysfs write serialisation, fix potential unload races
+ * 20050801 henk Added ringtone, restructure USB
+ * 20050816 henk Merge 2.6.13-rc6
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/rwsem.h>
+#include <linux/usb.h>
+
+#include "map_to_7segment.h"
+#include "yealink.h"
+
+#define DRIVER_VERSION "yld-20050816"
+#define DRIVER_AUTHOR "Henk Vergonet"
+#define DRIVER_DESC "Yealink phone driver"
+
+#define YEALINK_POLLING_FREQUENCY 10 /* in [Hz] */
+
+struct yld_status {
+ u8 lcd[24];
+ u8 led;
+ u8 dialtone;
+ u8 ringtone;
+ u8 keynum;
+} __attribute__ ((packed));
+
+/*
+ * Register the LCD segment and icon map
+ */
+#define _LOC(k,l) { .a = (k), .m = (l) }
+#define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm) \
+ { .type = (t), \
+ .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm), \
+ _LOC(d, dm), _LOC(e, em), _LOC(g, gm), \
+ _LOC(f, fm) } } }
+#define _PIC(t, h, hm, n) \
+ { .type = (t), \
+ .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
+
+static const struct lcd_segment_map {
+ char type;
+ union {
+ struct pictogram_map {
+ u8 a,m;
+ char name[10];
+ } p;
+ struct segment_map {
+ u8 a,m;
+ } s[7];
+ } u;
+} lcdMap[] = {
+#include "yealink.h"
+};
+
+struct yealink_dev {
+ struct input_dev idev; /* input device */
+ struct usb_device *udev; /* usb device */
+
+ /* irq input channel */
+ struct yld_ctl_packet *irq_data;
+ dma_addr_t irq_dma;
+ struct urb *urb_irq;
+
+ /* control output channel */
+ struct yld_ctl_packet *ctl_data;
+ dma_addr_t ctl_dma;
+ struct usb_ctrlrequest *ctl_req;
+ dma_addr_t ctl_req_dma;
+ struct urb *urb_ctl;
+
+ char phys[64]; /* physical device path */
+
+ u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */
+ int key_code; /* last reported key */
+
+ int stat_ix;
+ union {
+ struct yld_status s;
+ u8 b[sizeof(struct yld_status)];
+ } master, copy;
+};
+
+
+/*******************************************************************************
+ * Yealink lcd interface
+ ******************************************************************************/
+
+/*
+ * Register a default 7 segment character set
+ */
+static SEG7_DEFAULT_MAP(map_seg7);
+
+ /* Display a char,
+ * char '\9' and '\n' are placeholders and do not overwrite the original text.
+ * A space will always hide an icon.
+ */
+static int setChar(struct yealink_dev *yld, int el, int chr)
+{
+ int i, a, m, val;
+
+ if (el >= ARRAY_SIZE(lcdMap))
+ return -EINVAL;
+
+ if (chr == '\t' || chr == '\n')
+ return 0;
+
+ yld->lcdMap[el] = chr;
+
+ if (lcdMap[el].type == '.') {
+ a = lcdMap[el].u.p.a;
+ m = lcdMap[el].u.p.m;
+ if (chr != ' ')
+ yld->master.b[a] |= m;
+ else
+ yld->master.b[a] &= ~m;
+ return 0;
+ }
+
+ val = map_to_seg7(&map_seg7, chr);
+ for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
+ m = lcdMap[el].u.s[i].m;
+
+ if (m == 0)
+ continue;
+
+ a = lcdMap[el].u.s[i].a;
+ if (val & 1)
+ yld->master.b[a] |= m;
+ else
+ yld->master.b[a] &= ~m;
+ val = val >> 1;
+ }
+ return 0;
+};
+
+/*******************************************************************************
+ * Yealink key interface
+ ******************************************************************************/
+
+/* Map device buttons to internal key events.
+ *
+ * USB-P1K button layout:
+ *
+ * up
+ * IN OUT
+ * down
+ *
+ * pickup C hangup
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ * * 0 #
+ *
+ * The "up" and "down" keys, are symbolised by arrows on the button.
+ * The "pickup" and "hangup" keys are symbolised by a green and red phone
+ * on the button.
+ */
+static int map_p1k_to_key(int scancode)
+{
+ switch(scancode) { /* phone key: */
+ case 0x23: return KEY_LEFT; /* IN */
+ case 0x33: return KEY_UP; /* up */
+ case 0x04: return KEY_RIGHT; /* OUT */
+ case 0x24: return KEY_DOWN; /* down */
+ case 0x03: return KEY_ENTER; /* pickup */
+ case 0x14: return KEY_BACKSPACE; /* C */
+ case 0x13: return KEY_ESC; /* hangup */
+ case 0x00: return KEY_1; /* 1 */
+ case 0x01: return KEY_2; /* 2 */
+ case 0x02: return KEY_3; /* 3 */
+ case 0x10: return KEY_4; /* 4 */
+ case 0x11: return KEY_5; /* 5 */
+ case 0x12: return KEY_6; /* 6 */
+ case 0x20: return KEY_7; /* 7 */
+ case 0x21: return KEY_8; /* 8 */
+ case 0x22: return KEY_9; /* 9 */
+ case 0x30: return KEY_KPASTERISK; /* * */
+ case 0x31: return KEY_0; /* 0 */
+ case 0x32: return KEY_LEFTSHIFT |
+ KEY_3 << 8; /* # */
+ }
+ return -EINVAL;
+}
+
+/* Completes a request by converting the data into events for the
+ * input subsystem.
+ *
+ * The key parameter can be cascaded: key2 << 8 | key1
+ */
+static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
+{
+ struct input_dev *idev = &yld->idev;
+
+ input_regs(idev, regs);
+ if (yld->key_code >= 0) {
+ /* old key up */
+ input_report_key(idev, yld->key_code & 0xff, 0);
+ if (yld->key_code >> 8)
+ input_report_key(idev, yld->key_code >> 8, 0);
+ }
+
+ yld->key_code = key;
+ if (key >= 0) {
+ /* new valid key */
+ input_report_key(idev, key & 0xff, 1);
+ if (key >> 8)
+ input_report_key(idev, key >> 8, 1);
+ }
+ input_sync(idev);
+}
+
+/*******************************************************************************
+ * Yealink usb communication interface
+ ******************************************************************************/
+
+static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
+{
+ u8 *buf = (u8 *)p;
+ int i;
+ u8 sum = 0;
+
+ for(i=0; i<USB_PKT_LEN-1; i++)
+ sum -= buf[i];
+ p->sum = sum;
+ return usb_control_msg(yld->udev,
+ usb_sndctrlpipe(yld->udev, 0),
+ USB_REQ_SET_CONFIGURATION,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+ 0x200, 3,
+ p, sizeof(*p),
+ USB_CTRL_SET_TIMEOUT);
+}
+
+static u8 default_ringtone[] = {
+ 0xEF, /* volume [0-255] */
+ 0xFB, 0x1E, 0x00, 0x0C, /* 1250 [hz], 12/100 [s] */
+ 0xFC, 0x18, 0x00, 0x0C, /* 1000 [hz], 12/100 [s] */
+ 0xFB, 0x1E, 0x00, 0x0C,
+ 0xFC, 0x18, 0x00, 0x0C,
+ 0xFB, 0x1E, 0x00, 0x0C,
+ 0xFC, 0x18, 0x00, 0x0C,
+ 0xFB, 0x1E, 0x00, 0x0C,
+ 0xFC, 0x18, 0x00, 0x0C,
+ 0xFF, 0xFF, 0x01, 0x90, /* silent, 400/100 [s] */
+ 0x00, 0x00 /* end of sequence */
+};
+
+static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
+{
+ struct yld_ctl_packet *p = yld->ctl_data;
+ int ix, len;
+
+ if (size <= 0)
+ return -EINVAL;
+
+ /* Set the ringtone volume */
+ memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+ yld->ctl_data->cmd = CMD_RING_VOLUME;
+ yld->ctl_data->size = 1;
+ yld->ctl_data->data[0] = buf[0];
+ yealink_cmd(yld, p);
+
+ buf++;
+ size--;
+
+ p->cmd = CMD_RING_NOTE;
+ ix = 0;
+ while (size != ix) {
+ len = size - ix;
+ if (len > sizeof(p->data))
+ len = sizeof(p->data);
+ p->size = len;
+ p->offset = cpu_to_be16(ix);
+ memcpy(p->data, &buf[ix], len);
+ yealink_cmd(yld, p);
+ ix += len;
+ }
+ return 0;
+}
+
+/* keep stat_master & stat_copy in sync.
+ */
+static int yealink_do_idle_tasks(struct yealink_dev *yld)
+{
+ u8 val;
+ int i, ix, len;
+
+ ix = yld->stat_ix;
+
+ memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+ yld->ctl_data->cmd = CMD_KEYPRESS;
+ yld->ctl_data->size = 1;
+ yld->ctl_data->sum = 0xff - CMD_KEYPRESS;
+
+ /* If state update pointer wraps do a KEYPRESS first. */
+ if (ix >= sizeof(yld->master)) {
+ yld->stat_ix = 0;
+ return 0;
+ }
+
+ /* find update candidates: copy != master */
+ do {
+ val = yld->master.b[ix];
+ if (val != yld->copy.b[ix])
+ goto send_update;
+ } while (++ix < sizeof(yld->master));
+
+ /* nothing todo, wait a bit and poll for a KEYPRESS */
+ yld->stat_ix = 0;
+ /* TODO how can we wait abit. ??
+ * msleep_interruptible(1000 / YEALINK_POLLING_FREQUENCY);
+ */
+ return 0;
+
+send_update:
+
+ /* Setup an appropriate update request */
+ yld->copy.b[ix] = val;
+ yld->ctl_data->data[0] = val;
+
+ switch(ix) {
+ case offsetof(struct yld_status, led):
+ yld->ctl_data->cmd = CMD_LED;
+ yld->ctl_data->sum = -1 - CMD_LED - val;
+ break;
+ case offsetof(struct yld_status, dialtone):
+ yld->ctl_data->cmd = CMD_DIALTONE;
+ yld->ctl_data->sum = -1 - CMD_DIALTONE - val;
+ break;
+ case offsetof(struct yld_status, ringtone):
+ yld->ctl_data->cmd = CMD_RINGTONE;
+ yld->ctl_data->sum = -1 - CMD_RINGTONE - val;
+ break;
+ case offsetof(struct yld_status, keynum):
+ val--;
+ val &= 0x1f;
+ yld->ctl_data->cmd = CMD_SCANCODE;
+ yld->ctl_data->offset = cpu_to_be16(val);
+ yld->ctl_data->data[0] = 0;
+ yld->ctl_data->sum = -1 - CMD_SCANCODE - val;
+ break;
+ default:
+ len = sizeof(yld->master.s.lcd) - ix;
+ if (len > sizeof(yld->ctl_data->data))
+ len = sizeof(yld->ctl_data->data);
+
+ /* Combine up to <len> consecutive LCD bytes in a singe request
+ */
+ yld->ctl_data->cmd = CMD_LCD;
+ yld->ctl_data->offset = cpu_to_be16(ix);
+ yld->ctl_data->size = len;
+ yld->ctl_data->sum = -CMD_LCD - ix - val - len;
+ for(i=1; i<len; i++) {
+ ix++;
+ val = yld->master.b[ix];
+ yld->copy.b[ix] = val;
+ yld->ctl_data->data[i] = val;
+ yld->ctl_data->sum -= val;
+ }
+ }
+ yld->stat_ix = ix + 1;
+ return 1;
+}
+
+/* Decide on how to handle responses
+ *
+ * The state transition diagram is somethhing like:
+ *
+ * syncState<--+
+ * | |
+ * | idle
+ * \|/ |
+ * init --ok--> waitForKey --ok--> getKey
+ * ^ ^ |
+ * | +-------ok-------+
+ * error,start
+ *
+ */
+static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct yealink_dev *yld = urb->context;
+ int ret;
+
+ if (urb->status)
+ err("%s - urb status %d", __FUNCTION__, urb->status);
+
+ switch (yld->irq_data->cmd) {
+ case CMD_KEYPRESS:
+
+ yld->master.s.keynum = yld->irq_data->data[0];
+ break;
+
+ case CMD_SCANCODE:
+ dbg("get scancode %x", yld->irq_data->data[0]);
+
+ report_key(yld, map_p1k_to_key(yld->irq_data->data[0]), regs);
+ break;
+
+ default:
+ err("unexpected response %x", yld->irq_data->cmd);
+ }
+
+ yealink_do_idle_tasks(yld);
+
+ ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+ if (ret)
+ err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+}
+
+static void urb_ctl_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct yealink_dev *yld = urb->context;
+ int ret;
+
+ if (urb->status)
+ err("%s - urb status %d", __FUNCTION__, urb->status);
+
+ switch (yld->ctl_data->cmd) {
+ case CMD_KEYPRESS:
+ case CMD_SCANCODE:
+ /* ask for a response */
+ ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
+ break;
+ default:
+ /* send new command */
+ yealink_do_idle_tasks(yld);
+ ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+ }
+
+ if (ret)
+ err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+}
+
+/*******************************************************************************
+ * input event interface
+ ******************************************************************************/
+
+/* TODO should we issue a ringtone on a SND_BELL event?
+static int input_ev(struct input_dev *dev, unsigned int type,
+ unsigned int code, int value)
+{
+
+ if (type != EV_SND)
+ return -EINVAL;
+
+ switch (code) {
+ case SND_BELL:
+ case SND_TONE:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+*/
+
+static int input_open(struct input_dev *dev)
+{
+ struct yealink_dev *yld = dev->private;
+ int i, ret;
+
+ dbg("%s", __FUNCTION__);
+
+ /* force updates to device */
+ for (i = 0; i<sizeof(yld->master); i++)
+ yld->copy.b[i] = ~yld->master.b[i];
+ yld->key_code = -1; /* no keys pressed */
+
+ yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
+
+ /* issue INIT */
+ memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
+ yld->ctl_data->cmd = CMD_INIT;
+ yld->ctl_data->size = 10;
+ yld->ctl_data->sum = 0x100-CMD_INIT-10;
+ if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
+ dbg("%s - usb_submit_urb failed with result %d",
+ __FUNCTION__, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static void input_close(struct input_dev *dev)
+{
+ struct yealink_dev *yld = dev->private;
+
+ usb_kill_urb(yld->urb_ctl);
+ usb_kill_urb(yld->urb_irq);
+}
+
+/*******************************************************************************
+ * sysfs interface
+ ******************************************************************************/
+
+static DECLARE_RWSEM(sysfs_rwsema);
+
+/* Interface to the 7-segments translation table aka. char set.
+ */
+static ssize_t show_map(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ memcpy(buf, &map_seg7, sizeof(map_seg7));
+ return sizeof(map_seg7);
+}
+
+static ssize_t store_map(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t cnt)
+{
+ if (cnt != sizeof(map_seg7))
+ return -EINVAL;
+ memcpy(&map_seg7, buf, sizeof(map_seg7));
+ return sizeof(map_seg7);
+}
+
+/* Interface to the LCD.
+ */
+
+/* Reading /sys/../lineX will return the format string with its settings:
+ *
+ * Example:
+ * cat ./line3
+ * 888888888888
+ * Linux Rocks!
+ */
+static ssize_t show_line(struct device *dev, char *buf, int a, int b)
+{
+ struct yealink_dev *yld;
+ int i;
+
+ down_read(&sysfs_rwsema);
+ yld = dev_get_drvdata(dev);
+ if (yld == NULL) {
+ up_read(&sysfs_rwsema);
+ return -ENODEV;
+ }
+
+ for (i = a; i < b; i++)
+ *buf++ = lcdMap[i].type;
+ *buf++ = '\n';
+ for (i = a; i < b; i++)
+ *buf++ = yld->lcdMap[i];
+ *buf++ = '\n';
+ *buf = 0;
+
+ up_read(&sysfs_rwsema);
+ return 3 + ((b - a) << 1);
+}
+
+static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
+}
+
+static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
+}
+
+static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
+}
+
+/* Writing to /sys/../lineX will set the coresponding LCD line.
+ * - Excess characters are ignored.
+ * - If less characters are written than allowed, the remaining digits are
+ * unchanged.
+ * - The '\n' or '\t' char is a placeholder, it does not overwrite the
+ * original content.
+ */
+static ssize_t store_line(struct device *dev, const char *buf, size_t count,
+ int el, size_t len)
+{
+ struct yealink_dev *yld;
+ int i;
+
+ down_write(&sysfs_rwsema);
+ yld = dev_get_drvdata(dev);
+ if (yld == NULL) {
+ up_write(&sysfs_rwsema);
+ return -ENODEV;
+ }
+
+ if (len > count)
+ len = count;
+ for (i = 0; i < len; i++)
+ setChar(yld, el++, buf[i]);
+
+ up_write(&sysfs_rwsema);
+ return count;
+}
+
+static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
+}
+
+static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
+}
+
+static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
+}
+
+/* Interface to visible and audible "icons", these include:
+ * pictures on the LCD, the LED, and the dialtone signal.
+ */
+
+/* Get a list of "switchable elements" with their current state. */
+static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct yealink_dev *yld;
+ int i, ret = 1;
+
+ down_read(&sysfs_rwsema);
+ yld = dev_get_drvdata(dev);
+ if (yld == NULL) {
+ up_read(&sysfs_rwsema);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
+ if (lcdMap[i].type != '.')
+ continue;
+ ret += sprintf(&buf[ret], "%s %s\n",
+ yld->lcdMap[i] == ' ' ? " " : "on",
+ lcdMap[i].u.p.name);
+ }
+ up_read(&sysfs_rwsema);
+ return ret;
+}
+
+/* Change the visibility of a particular element. */
+static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
+ int chr)
+{
+ struct yealink_dev *yld;
+ int i;
+
+ down_write(&sysfs_rwsema);
+ yld = dev_get_drvdata(dev);
+ if (yld == NULL) {
+ up_write(&sysfs_rwsema);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
+ if (lcdMap[i].type != '.')
+ continue;
+ if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
+ setChar(yld, i, chr);
+ break;
+ }
+ }
+
+ up_write(&sysfs_rwsema);
+ return count;
+}
+
+static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return set_icon(dev, buf, count, buf[0]);
+}
+
+static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return set_icon(dev, buf, count, ' ');
+}
+
+/* Upload a ringtone to the device.
+ */
+
+/* Stores raw ringtone data in the phone */
+static ssize_t store_ringtone(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct yealink_dev *yld;
+
+ down_write(&sysfs_rwsema);
+ yld = dev_get_drvdata(dev);
+ if (yld == NULL) {
+ up_write(&sysfs_rwsema);
+ return -ENODEV;
+ }
+
+ /* TODO locking with async usb control interface??? */
+ yealink_set_ringtone(yld, (char *)buf, count);
+ up_write(&sysfs_rwsema);
+ return count;
+}
+
+#define _M444 S_IRUGO
+#define _M664 S_IRUGO|S_IWUSR|S_IWGRP
+#define _M220 S_IWUSR|S_IWGRP
+
+static DEVICE_ATTR(map_seg7 , _M664, show_map , store_map );
+static DEVICE_ATTR(line1 , _M664, show_line1 , store_line1 );
+static DEVICE_ATTR(line2 , _M664, show_line2 , store_line2 );
+static DEVICE_ATTR(line3 , _M664, show_line3 , store_line3 );
+static DEVICE_ATTR(get_icons , _M444, get_icons , NULL );
+static DEVICE_ATTR(show_icon , _M220, NULL , show_icon );
+static DEVICE_ATTR(hide_icon , _M220, NULL , hide_icon );
+static DEVICE_ATTR(ringtone , _M220, NULL , store_ringtone);
+
+static struct attribute *yld_attributes[] = {
+ &dev_attr_line1.attr,
+ &dev_attr_line2.attr,
+ &dev_attr_line3.attr,
+ &dev_attr_get_icons.attr,
+ &dev_attr_show_icon.attr,
+ &dev_attr_hide_icon.attr,
+ &dev_attr_map_seg7.attr,
+ &dev_attr_ringtone.attr,
+ NULL
+};
+
+static struct attribute_group yld_attr_group = {
+ .attrs = yld_attributes
+};
+
+/*******************************************************************************
+ * Linux interface and usb initialisation
+ ******************************************************************************/
+
+static const struct yld_device {
+ u16 idVendor;
+ u16 idProduct;
+ char *name;
+} yld_device[] = {
+ { 0x6993, 0xb001, "Yealink usb-p1k" },
+};
+
+static struct usb_device_id usb_table [] = {
+ { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) },
+ { }
+};
+
+static int usb_cleanup(struct yealink_dev *yld, int err)
+{
+ if (yld == NULL)
+ return err;
+
+ if (yld->urb_irq) {
+ usb_kill_urb(yld->urb_irq);
+ usb_free_urb(yld->urb_irq);
+ }
+ if (yld->urb_ctl)
+ usb_free_urb(yld->urb_ctl);
+ if (yld->idev.dev)
+ input_unregister_device(&yld->idev);
+ if (yld->ctl_req)
+ usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
+ yld->ctl_req, yld->ctl_req_dma);
+ if (yld->ctl_data)
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->ctl_data, yld->ctl_dma);
+ if (yld->irq_data)
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->irq_data, yld->irq_dma);
+ kfree(yld);
+ return err;
+}
+
+static void usb_disconnect(struct usb_interface *intf)
+{
+ struct yealink_dev *yld;
+
+ down_write(&sysfs_rwsema);
+ yld = usb_get_intfdata(intf);
+ sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
+ usb_set_intfdata(intf, NULL);
+ up_write(&sysfs_rwsema);
+
+ usb_cleanup(yld, 0);
+}
+
+static int usb_match(struct usb_device *udev)
+{
+ int i;
+ u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
+ u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
+
+ for (i = 0; i < ARRAY_SIZE(yld_device); i++) {
+ if ((idVendor == yld_device[i].idVendor) &&
+ (idProduct == yld_device[i].idProduct))
+ return i;
+ }
+ return -ENODEV;
+}
+
+static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev (intf);
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct yealink_dev *yld;
+ char path[64];
+ int ret, pipe, i;
+
+ i = usb_match(udev);
+ if (i < 0)
+ return -ENODEV;
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+ if (!(endpoint->bEndpointAddress & 0x80))
+ return -EIO;
+ if ((endpoint->bmAttributes & 3) != 3)
+ return -EIO;
+
+ if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
+ memset(yld, 0, sizeof(*yld));
+ yld->udev = udev;
+
+ /* allocate usb buffers */
+ yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+ SLAB_ATOMIC, &yld->irq_dma);
+ if (yld->irq_data == NULL)
+ return usb_cleanup(yld, -ENOMEM);
+
+ yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+ SLAB_ATOMIC, &yld->ctl_dma);
+ if (!yld->ctl_data)
+ return usb_cleanup(yld, -ENOMEM);
+
+ yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
+ SLAB_ATOMIC, &yld->ctl_req_dma);
+ if (yld->ctl_req == NULL)
+ return usb_cleanup(yld, -ENOMEM);
+
+ /* allocate urb structures */
+ yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (yld->urb_irq == NULL)
+ return usb_cleanup(yld, -ENOMEM);
+
+ yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
+ if (yld->urb_ctl == NULL)
+ return usb_cleanup(yld, -ENOMEM);
+
+ /* get a handle to the interrupt data pipe */
+ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+ ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+ if (ret != USB_PKT_LEN)
+ err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+
+ /* initialise irq urb */
+ usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
+ USB_PKT_LEN,
+ urb_irq_callback,
+ yld, endpoint->bInterval);
+ yld->urb_irq->transfer_dma = yld->irq_dma;
+ yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ yld->urb_irq->dev = udev;
+
+ /* initialise ctl urb */
+ yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+ USB_DIR_OUT;
+ yld->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
+ yld->ctl_req->wValue = cpu_to_le16(0x200);
+ yld->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
+ yld->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
+
+ usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
+ (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
+ urb_ctl_callback, yld);
+ yld->urb_ctl->setup_dma = yld->ctl_req_dma;
+ yld->urb_ctl->transfer_dma = yld->ctl_dma;
+ yld->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
+ URB_NO_TRANSFER_DMA_MAP;
+ yld->urb_ctl->dev = udev;
+
+ /* find out the physical bus location */
+ if (usb_make_path(udev, path, sizeof(path)) > 0)
+ snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path);
+
+ /* register settings for the input device */
+ init_input_dev(&yld->idev);
+ yld->idev.private = yld;
+ yld->idev.id.bustype = BUS_USB;
+ yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+ yld->idev.dev = &intf->dev;
+ yld->idev.name = yld_device[i].name;
+ yld->idev.phys = yld->phys;
+ /* yld->idev.event = input_ev; TODO */
+ yld->idev.open = input_open;
+ yld->idev.close = input_close;
+
+ /* register available key events */
+ yld->idev.evbit[0] = BIT(EV_KEY);
+ for (i = 0; i < 256; i++) {
+ int k = map_p1k_to_key(i);
+ if (k >= 0) {
+ set_bit(k & 0xff, yld->idev.keybit);
+ if (k >> 8)
+ set_bit(k >> 8, yld->idev.keybit);
+ }
+ }
+
+ printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
+
+ input_register_device(&yld->idev);
+
+ usb_set_intfdata(intf, yld);
+
+ /* clear visible elements */
+ for (i=0; i<ARRAY_SIZE(lcdMap); i++)
+ setChar(yld, i, ' ');
+
+ /* display driver version on LCD line 3 */
+ store_line3(&intf->dev, NULL,
+ DRIVER_VERSION, sizeof(DRIVER_VERSION));
+
+ /* Register sysfs hooks (don't care about failure) */
+ sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
+ return 0;
+}
+
+static struct usb_driver yealink_driver = {
+ .owner = THIS_MODULE,
+ .name = "yealink",
+ .probe = usb_probe,
+ .disconnect = usb_disconnect,
+ .id_table = usb_table,
+};
+
+static int __init yealink_dev_init(void)
+{
+ int ret = usb_register(&yealink_driver);
+ if (ret == 0)
+ info(DRIVER_DESC ":" DRIVER_VERSION);
+ return ret;
+}
+
+static void __exit yealink_dev_exit(void)
+{
+ usb_deregister(&yealink_driver);
+}
+
+module_init(yealink_dev_init);
+module_exit(yealink_dev_exit);
+
+MODULE_DEVICE_TABLE (usb, usb_table);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/yealink.h b/drivers/usb/input/yealink.h
new file mode 100644
index 00000000000..48af0be9cbd
--- /dev/null
+++ b/drivers/usb/input/yealink.h
@@ -0,0 +1,220 @@
+/*
+ * drivers/usb/input/yealink.h
+ *
+ * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef INPUT_YEALINK_H
+#define INPUT_YEALINK_H
+
+/* Using the control channel on interface 3 various aspects of the phone
+ * can be controlled like LCD, LED, dialtone and the ringtone.
+ */
+
+struct yld_ctl_packet {
+ u8 cmd; /* command code, see below */
+ u8 size; /* 1-11, size of used data bytes. */
+ u16 offset; /* internal packet offset */
+ u8 data[11];
+ s8 sum; /* negative sum of 15 preceding bytes */
+} __attribute__ ((packed));
+
+#define USB_PKT_LEN sizeof(struct yld_ctl_packet)
+
+/* The following yld_ctl_packet's are available: */
+
+/* Init registers
+ *
+ * cmd 0x8e
+ * size 10
+ * offset 0
+ * data 0,0,0,0....
+ */
+#define CMD_INIT 0x8e
+
+/* Request key scan
+ *
+ * cmd 0x80
+ * size 1
+ * offset 0
+ * data[0] on return returns the key number, if it changes there's a new
+ * key pressed.
+ */
+#define CMD_KEYPRESS 0x80
+
+/* Request scancode
+ *
+ * cmd 0x81
+ * size 1
+ * offset key number [0-1f]
+ * data[0] on return returns the scancode
+ */
+#define CMD_SCANCODE 0x81
+
+/* Set LCD
+ *
+ * cmd 0x04
+ * size 1-11
+ * offset 0-23
+ * data segment bits
+ */
+#define CMD_LCD 0x04
+
+/* Set led
+ *
+ * cmd 0x05
+ * size 1
+ * offset 0
+ * data[0] 0 OFF / 1 ON
+ */
+#define CMD_LED 0x05
+
+/* Set ringtone volume
+ *
+ * cmd 0x11
+ * size 1
+ * offset 0
+ * data[0] 0-0xff volume
+ */
+#define CMD_RING_VOLUME 0x11
+
+/* Set ringtone notes
+ *
+ * cmd 0x02
+ * size 1-11
+ * offset 0->
+ * data binary representation LE16(-freq), LE16(duration) ....
+ */
+#define CMD_RING_NOTE 0x02
+
+/* Sound ringtone via the speaker on the back
+ *
+ * cmd 0x03
+ * size 1
+ * offset 0
+ * data[0] 0 OFF / 0x24 ON
+ */
+#define CMD_RINGTONE 0x03
+
+/* Sound dial tone via the ear speaker
+ *
+ * cmd 0x09
+ * size 1
+ * offset 0
+ * data[0] 0 OFF / 1 ON
+ */
+#define CMD_DIALTONE 0x09
+
+#endif /* INPUT_YEALINK_H */
+
+
+#if defined(_SEG) && defined(_PIC)
+/* This table maps the LCD segments onto individual bit positions in the
+ * yld_status struct.
+ */
+
+/* LCD, each segment must be driven seperately.
+ *
+ * Layout:
+ *
+ * |[] [][] [][] [][] in |[][]
+ * |[] M [][] D [][] : [][] out |[][]
+ * store
+ *
+ * NEW REP SU MO TU WE TH FR SA
+ *
+ * [] [] [] [] [] [] [] [] [] [] [] []
+ * [] [] [] [] [] [] [] [] [] [] [] []
+ */
+
+/* Line 1
+ * Format : 18.e8.M8.88...188
+ * Icon names : M D : IN OUT STORE
+ */
+#define LCD_LINE1_OFFSET 0
+#define LCD_LINE1_SIZE 17
+
+/* Note: first g then f => ! ! */
+/* _SEG( type a b c d e g f ) */
+ _SEG('1', 0,0 , 22,2 , 22,2 , 0,0 , 0,0 , 0,0 , 0,0 ),
+ _SEG('8', 20,1 , 20,2 , 20,4 , 20,8 , 21,4 , 21,2 , 21,1 ),
+ _PIC('.', 22,1 , "M" ),
+ _SEG('e', 18,1 , 18,2 , 18,4 , 18,1 , 19,2 , 18,1 , 19,1 ),
+ _SEG('8', 16,1 , 16,2 , 16,4 , 16,8 , 17,4 , 17,2 , 17,1 ),
+ _PIC('.', 15,8 , "D" ),
+ _SEG('M', 14,1 , 14,2 , 14,4 , 14,1 , 15,4 , 15,2 , 15,1 ),
+ _SEG('8', 12,1 , 12,2 , 12,4 , 12,8 , 13,4 , 13,2 , 13,1 ),
+ _PIC('.', 11,8 , ":" ),
+ _SEG('8', 10,1 , 10,2 , 10,4 , 10,8 , 11,4 , 11,2 , 11,1 ),
+ _SEG('8', 8,1 , 8,2 , 8,4 , 8,8 , 9,4 , 9,2 , 9,1 ),
+ _PIC('.', 7,1 , "IN" ),
+ _PIC('.', 7,2 , "OUT" ),
+ _PIC('.', 7,4 , "STORE" ),
+ _SEG('1', 0,0 , 5,1 , 5,1 , 0,0 , 0,0 , 0,0 , 0,0 ),
+ _SEG('8', 4,1 , 4,2 , 4,4 , 4,8 , 5,8 , 5,4 , 5,2 ),
+ _SEG('8', 2,1 , 2,2 , 2,4 , 2,8 , 3,4 , 3,2 , 3,1 ),
+
+/* Line 2
+ * Format : .........
+ * Pict. name : NEW REP SU MO TU WE TH FR SA
+ */
+#define LCD_LINE2_OFFSET LCD_LINE1_OFFSET + LCD_LINE1_SIZE
+#define LCD_LINE2_SIZE 9
+
+ _PIC('.', 23,2 , "NEW" ),
+ _PIC('.', 23,4 , "REP" ),
+ _PIC('.', 1,8 , "SU" ),
+ _PIC('.', 1,4 , "MO" ),
+ _PIC('.', 1,2 , "TU" ),
+ _PIC('.', 1,1 , "WE" ),
+ _PIC('.', 0,1 , "TH" ),
+ _PIC('.', 0,2 , "FR" ),
+ _PIC('.', 0,4 , "SA" ),
+
+/* Line 3
+ * Format : 888888888888
+ */
+#define LCD_LINE3_OFFSET LCD_LINE2_OFFSET + LCD_LINE2_SIZE
+#define LCD_LINE3_SIZE 12
+
+ _SEG('8', 22,16, 22,32, 22,64, 22,128, 23,128, 23,64, 23,32 ),
+ _SEG('8', 20,16, 20,32, 20,64, 20,128, 21,128, 21,64, 21,32 ),
+ _SEG('8', 18,16, 18,32, 18,64, 18,128, 19,128, 19,64, 19,32 ),
+ _SEG('8', 16,16, 16,32, 16,64, 16,128, 17,128, 17,64, 17,32 ),
+ _SEG('8', 14,16, 14,32, 14,64, 14,128, 15,128, 15,64, 15,32 ),
+ _SEG('8', 12,16, 12,32, 12,64, 12,128, 13,128, 13,64, 13,32 ),
+ _SEG('8', 10,16, 10,32, 10,64, 10,128, 11,128, 11,64, 11,32 ),
+ _SEG('8', 8,16, 8,32, 8,64, 8,128, 9,128, 9,64, 9,32 ),
+ _SEG('8', 6,16, 6,32, 6,64, 6,128, 7,128, 7,64, 7,32 ),
+ _SEG('8', 4,16, 4,32, 4,64, 4,128, 5,128, 5,64, 5,32 ),
+ _SEG('8', 2,16, 2,32, 2,64, 2,128, 3,128, 3,64, 3,32 ),
+ _SEG('8', 0,16, 0,32, 0,64, 0,128, 1,128, 1,64, 1,32 ),
+
+/* Line 4
+ *
+ * The LED, DIALTONE and RINGTONE are implemented as icons and use the same
+ * sysfs interface.
+ */
+#define LCD_LINE4_OFFSET LCD_LINE3_OFFSET + LCD_LINE3_SIZE
+
+ _PIC('.', offsetof(struct yld_status, led) , 0x01, "LED" ),
+ _PIC('.', offsetof(struct yld_status, dialtone) , 0x01, "DIALTONE" ),
+ _PIC('.', offsetof(struct yld_status, ringtone) , 0x24, "RINGTONE" ),
+
+#undef _SEG
+#undef _PIC
+#endif /* _SEG && _PIC */
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 6f7994f5a71..ae4681f9f0e 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)
/* cancel an urb which is submitted to the chain
the result is 0 if the urb is cancelled, or -EINPROGRESS if
- URB_ASYNC_UNLINK is set and the function is successfully started.
+ the function is successfully started.
*/
static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
{
@@ -515,7 +515,6 @@ static void auerchain_unlink_all (pauerchain_t acp)
acep = acp->active;
if (acep) {
urbp = acep->urbp;
- urbp->transfer_flags &= ~URB_ASYNC_UNLINK;
dbg ("unlink active urb");
usb_kill_urb (urbp);
}
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index ad17892aac9..7e93ac96490 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,
actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
bytes_to_read = min(count, *actual_buffer);
if (bytes_to_read < *actual_buffer)
- dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n",
+ dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n",
*actual_buffer-bytes_to_read);
/* 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,
/* write the data into interrupt_out_buffer from userspace */
bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
if (bytes_to_write < count)
- dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write);
- dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write);
+ dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+ dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 2fd12264fd5..d63ce6c030f 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,
usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
sisusb_bulk_completeout, &sisusb->urbout_context[index]);
- urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK);
+ urb->transfer_flags |= tflags;
urb->actual_length = 0;
if ((urb->transfer_dma = transfer_dma))
@@ -295,7 +295,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data,
usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
sisusb_bulk_completein, sisusb);
- urb->transfer_flags |= (tflags | URB_ASYNC_UNLINK);
+ urb->transfer_flags |= tflags;
urb->actual_length = 0;
if ((urb->transfer_dma = transfer_dma))
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index fd7fb98e4b2..54799eb0bc6 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)
u->context = &context;
u->complete = ctrl_complete;
- u->transfer_flags |= URB_ASYNC_UNLINK;
}
/* queue the urbs */
@@ -1052,7 +1051,6 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async)
urb = simple_alloc_urb (testdev_to_usbdev (dev), pipe, size);
if (!urb)
return -ENOMEM;
- urb->transfer_flags |= URB_ASYNC_UNLINK;
urb->context = &completion;
urb->complete = unlink1_callback;
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
index b0015b8a1d1..3cf3ea3a88e 100644
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -2,7 +2,7 @@
# Makefile for USB Core files and filesystem
#
-usbmon-objs := mon_main.o mon_stat.o mon_text.o
+usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_dma.o
# This does not use CONFIG_USB_MON because we want this to use a tristate.
obj-$(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 00000000000..0a1367b760a
--- /dev/null
+++ b/drivers/usb/mon/mon_dma.c
@@ -0,0 +1,55 @@
+/*
+ * The USB Monitor, inspired by Dave Harding's USBMon.
+ *
+ * mon_dma.c: Library which snoops on DMA areas.
+ *
+ * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
+ */
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <asm/page.h>
+
+#include <linux/usb.h> /* Only needed for declarations in usb_mon.h */
+#include "usb_mon.h"
+
+#ifdef __i386__ /* CONFIG_ARCH_I386 does not exit */
+#define MON_HAS_UNMAP 1
+
+#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT)
+
+char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
+{
+ struct page *pg;
+ unsigned long flags;
+ unsigned char *map;
+ unsigned char *ptr;
+
+ /*
+ * On i386, a DMA handle is the "physical" address of a page.
+ * In other words, the bus address is equal to physical address.
+ * There is no IOMMU.
+ */
+ pg = phys_to_page(dma_addr);
+
+ /*
+ * We are called from hardware IRQs in case of callbacks.
+ * But we can be called from softirq or process context in case
+ * of submissions. In such case, we need to protect KM_IRQ0.
+ */
+ local_irq_save(flags);
+ map = kmap_atomic(pg, KM_IRQ0);
+ ptr = map + (dma_addr & (PAGE_SIZE-1));
+ memcpy(dst, ptr, len);
+ kunmap_atomic(map, KM_IRQ0);
+ local_irq_restore(flags);
+ return 0;
+}
+#endif /* __i386__ */
+
+#ifndef MON_HAS_UNMAP
+char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len)
+{
+ return 'D';
+}
+#endif
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 26266b30028..417464dea9f 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,
int len, char ev_type)
{
int pipe = urb->pipe;
- unsigned char *data;
-
- /*
- * The check to see if it's safe to poke at data has an enormous
- * number of corner cases, but it seems that the following is
- * more or less safe.
- *
- * We do not even try to look transfer_buffer, because it can
- * contain non-NULL garbage in case the upper level promised to
- * set DMA for the HCD.
- */
- if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
- return 'D';
if (len <= 0)
return 'L';
-
- if ((data = urb->transfer_buffer) == NULL)
- return 'Z'; /* '0' would be not as pretty. */
+ if (len >= DATA_MAX)
+ len = DATA_MAX;
/*
* 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,
}
}
- if (len >= DATA_MAX)
- len = DATA_MAX;
+ /*
+ * The check to see if it's safe to poke at data has an enormous
+ * number of corner cases, but it seems that the following is
+ * more or less safe.
+ *
+ * We do not even try to look transfer_buffer, because it can
+ * contain non-NULL garbage in case the upper level promised to
+ * set DMA for the HCD.
+ */
+ if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
+ return mon_dmapeek(ep->data, urb->transfer_dma, len);
+
+ if (urb->transfer_buffer == NULL)
+ return 'Z'; /* '0' would be not as pretty. */
+
memcpy(ep->data, urb->transfer_buffer, len);
return 0;
}
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index 9b06784d2c4..4be0f934607 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -45,6 +45,10 @@ struct mon_reader {
void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r);
void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
+/*
+ */
+extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len);
+
extern struct semaphore mon_lock;
extern struct file_operations mon_fops_text;
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index b104430e2c6..8c010bb44eb 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -99,7 +99,7 @@ config USB_USBNET
with "minidrivers" built around a common network driver core
that supports deep queues for efficient transfers. (This gives
better performance with small packets and at high speeds).
-
+
The USB host runs "usbnet", and the other end of the link might be:
- Another USB host, when using USB "network" or "data transfer"
@@ -125,38 +125,63 @@ config USB_USBNET
To compile this driver as a module, choose M here: the
module will be called usbnet.
-comment "USB Host-to-Host Cables"
- depends on USB_USBNET
-
-config USB_ALI_M5632
- boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
- depends on USB_USBNET
+config USB_NET_AX8817X
+ tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
+ depends on USB_USBNET && NET_ETHERNET
+ select CRC32
+ select MII
default y
help
- Choose this option if you're using a host-to-host cable
- based on this design, which supports USB 2.0 high speed.
+ This option adds support for ASIX AX88xxx based USB 2.0
+ 10/100 Ethernet adapters.
-config USB_AN2720
- boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
- depends on USB_USBNET
- default y
- help
- Choose this option if you're using a host-to-host cable
- based on this design. Note that AnchorChips is now a
- Cypress brand.
+ This driver should work with at least the following devices:
+ * Aten UC210T
+ * ASIX AX88172
+ * Billionton Systems, USB2AR
+ * Buffalo LUA-U2-KTX
+ * Corega FEther USB2-TX
+ * D-Link DUB-E100
+ * Hawking UF200
+ * Linksys USB200M
+ * Netgear FA120
+ * Sitecom LN-029
+ * Intellinet USB 2.0 Ethernet
+ * ST Lab USB 2.0 Ethernet
+ * TrendNet TU2-ET100
-config USB_BELKIN
- boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
+ This driver creates an interface named "ethX", where X depends on
+ what other networking devices you have in use.
+
+
+config USB_NET_CDCETHER
+ tristate "CDC Ethernet support (smart devices such as cable modems)"
depends on USB_USBNET
default y
help
- Choose this option if you're using a host-to-host cable
- based on this design: two NetChip 2890 chips and an Atmel
- microcontroller, with LEDs that indicate traffic.
+ This option supports devices conforming to the Communication Device
+ Class (CDC) Ethernet Control Model, a specification that's easy to
+ implement in device firmware. The CDC specifications are available
+ from <http://www.usb.org/>.
-config USB_GENESYS
- boolean "GeneSys GL620USB-A based cables"
- default y
+ CDC Ethernet is an implementation option for DOCSIS cable modems
+ that support USB connectivity, used for non-Microsoft USB hosts.
+ The Linux-USB CDC Ethernet Gadget driver is an open implementation.
+ This driver should work with at least the following devices:
+
+ * Ericsson PipeRider (all variants)
+ * Motorola (DM100 and SB4100)
+ * Broadcom Cable Modem (reference design)
+ * Toshiba PCX1100U
+ * ...
+
+ This driver creates an interface named "ethX", where X depends on
+ what other networking devices you have in use. However, if the
+ IEEE 802 "local assignment" bit is set in the address, a "usbX"
+ name is used instead.
+
+config USB_NET_GL620A
+ tristate "GeneSys GL620USB-A based cables"
depends on USB_USBNET
help
Choose this option if you're using a host-to-host cable,
@@ -164,38 +189,78 @@ config USB_GENESYS
Note that the half-duplex "GL620USB" is not supported.
-config USB_NET1080
- boolean "NetChip 1080 based cables (Laplink, ...)"
+config USB_NET_NET1080
+ tristate "NetChip 1080 based cables (Laplink, ...)"
default y
depends on USB_USBNET
help
Choose this option if you're using a host-to-host cable based
- on this design: one NetChip 1080 chips and supporting logic,
- supporting LEDs that indicate traffic
+ on this design: one NetChip 1080 chip and supporting logic,
+ optionally with LEDs that indicate traffic
-config USB_PL2301
- boolean "Prolific PL-2301/2302 based cables"
- default y
- # handshake/init/reset problems, from original 'plusb' driver
+config USB_NET_PLUSB
+ tristate "Prolific PL-2301/2302 based cables"
+ # if the handshake/init/reset problems, from original 'plusb',
+ # are ever resolved ... then remove "experimental"
depends on USB_USBNET && EXPERIMENTAL
help
Choose this option if you're using a host-to-host cable
with one of these chips.
-config USB_KC2190
- boolean "KT Technology KC2190 based cables (InstaNet)"
- default y
+config USB_NET_RNDIS_HOST
+ tristate "Host for RNDIS devices (EXPERIMENTAL)"
depends on USB_USBNET && EXPERIMENTAL
+ select USB_NET_CDCETHER
help
- Choose this option if you're using a host-to-host cable
- with one of these chips.
+ This option enables hosting "Remote NDIS" USB networking links,
+ as encouraged by Microsoft (instead of CDC Ethernet!) for use in
+ various devices that may only support this protocol.
-comment "Intelligent USB Devices/Gadgets"
+ Avoid using this protocol unless you have no better options.
+ The protocol specification is incomplete, and is controlled by
+ (and for) Microsoft; it isn't an "Open" ecosystem or market.
+
+config USB_NET_CDC_SUBSET
+ tristate "Simple USB Network Links (CDC Ethernet subset)"
depends on USB_USBNET
+ help
+ This driver module supports USB network devices that can work
+ without any device-specific information. Select it if you have
+ one of these drivers.
+
+ Note that while many USB host-to-host cables can work in this mode,
+ that may mean not being able to talk to Win32 systems or more
+ commonly not being able to handle certain events (like replugging
+ the host on the other end) very well. Also, these devices will
+ not generally have permanently assigned Ethernet addresses.
+
+config USB_ALI_M5632
+ boolean "ALi M5632 based 'USB 2.0 Data Link' cables"
+ depends on USB_NET_CDC_SUBSET
+ help
+ Choose this option if you're using a host-to-host cable
+ based on this design, which supports USB 2.0 high speed.
+
+config USB_AN2720
+ boolean "AnchorChips 2720 based cables (Xircom PGUNET, ...)"
+ depends on USB_NET_CDC_SUBSET
+ help
+ Choose this option if you're using a host-to-host cable
+ based on this design. Note that AnchorChips is now a
+ Cypress brand.
+
+config USB_BELKIN
+ boolean "eTEK based host-to-host cables (Advance, Belkin, ...)"
+ depends on USB_NET_CDC_SUBSET
+ default y
+ help
+ Choose this option if you're using a host-to-host cable
+ based on this design: two NetChip 2890 chips and an Atmel
+ microcontroller, with LEDs that indicate traffic.
config USB_ARMLINUX
boolean "Embedded ARM Linux links (iPaq, ...)"
- depends on USB_USBNET
+ depends on USB_NET_CDC_SUBSET
default y
help
Choose this option to support the "usb-eth" networking driver
@@ -212,15 +277,15 @@ config USB_ARMLINUX
config USB_EPSON2888
boolean "Epson 2888 based firmware (DEVELOPMENT)"
- depends on USB_USBNET
- default y
+ depends on USB_NET_CDC_SUBSET
help
Choose this option to support the usb networking links used
by some sample firmware from Epson.
-config USB_ZAURUS
- boolean "Sharp Zaurus (stock ROMs) and compatible"
+config USB_NET_ZAURUS
+ tristate "Sharp Zaurus (stock ROMs) and compatible"
depends on USB_USBNET
+ select USB_NET_CDCETHER
select CRC32
default y
help
@@ -235,61 +300,6 @@ config USB_ZAURUS
really need this non-conformant variant of CDC Ethernet (or in
some cases CDC MDLM) protocol, not "g_ether".
-config USB_CDCETHER
- boolean "CDC Ethernet support (smart devices such as cable modems)"
- depends on USB_USBNET
- default y
- help
- This option supports devices conforming to the Communication Device
- Class (CDC) Ethernet Control Model, a specification that's easy to
- implement in device firmware. The CDC specifications are available
- from <http://www.usb.org/>.
-
- CDC Ethernet is an implementation option for DOCSIS cable modems
- that support USB connectivity, used for non-Microsoft USB hosts.
- This driver should work with at least the following devices:
-
- * Ericsson PipeRider (all variants)
- * Motorola (DM100 and SB4100)
- * Broadcom Cable Modem (reference design)
- * Toshiba PCX1100U
- * ...
-
- This driver creates an interface named "ethX", where X depends on
- what other networking devices you have in use. However, if the
- IEEE 802 "local assignment" bit is set in the address, a "usbX"
- name is used instead.
-
-comment "USB Network Adapters"
- depends on USB_USBNET
-
-config USB_AX8817X
- boolean "ASIX AX88xxx Based USB 2.0 Ethernet Devices"
- depends on USB_USBNET && NET_ETHERNET
- select CRC32
- select MII
- default y
- help
- This option adds support for ASIX AX88xxx based USB 2.0
- 10/100 Ethernet devices.
-
- This driver should work with at least the following devices:
- * Aten UC210T
- * ASIX AX88172
- * Billionton Systems, USB2AR
- * Buffalo LUA-U2-KTX
- * Corega FEther USB2-TX
- * D-Link DUB-E100
- * Hawking UF200
- * Linksys USB200M
- * Netgear FA120
- * Sitecom LN-029
- * Intellinet USB 2.0 Ethernet
- * ST Lab USB 2.0 Ethernet
- * TrendNet TU2-ET100
-
- This driver creates an interface named "ethX", where X depends on
- what other networking devices you have in use.
config USB_ZD1201
tristate "USB ZD1201 based Wireless device support"
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index fe3fd4115e1..222c0495f79 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -6,5 +6,13 @@ obj-$(CONFIG_USB_CATC) += catc.o
obj-$(CONFIG_USB_KAWETH) += kaweth.o
obj-$(CONFIG_USB_PEGASUS) += pegasus.o
obj-$(CONFIG_USB_RTL8150) += rtl8150.o
+obj-$(CONFIG_USB_NET_AX8817X) += asix.o
+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
+obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
+obj-$(CONFIG_USB_NET_NET1080) += net1080.o
+obj-$(CONFIG_USB_NET_PLUSB) += plusb.o
+obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
+obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
+obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_ZD1201) += zd1201.o
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
new file mode 100644
index 00000000000..861f00a4375
--- /dev/null
+++ b/drivers/usb/net/asix.c
@@ -0,0 +1,948 @@
+/*
+ * ASIX AX8817X based USB 2.0 Ethernet Devices
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
+ * Copyright (c) 2002-2003 TiVo Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+
+#include "usbnet.h"
+
+
+/* ASIX AX8817X based USB 2.0 Ethernet Devices */
+
+#define AX_CMD_SET_SW_MII 0x06
+#define AX_CMD_READ_MII_REG 0x07
+#define AX_CMD_WRITE_MII_REG 0x08
+#define AX_CMD_SET_HW_MII 0x0a
+#define AX_CMD_READ_EEPROM 0x0b
+#define AX_CMD_WRITE_EEPROM 0x0c
+#define AX_CMD_WRITE_ENABLE 0x0d
+#define AX_CMD_WRITE_DISABLE 0x0e
+#define AX_CMD_WRITE_RX_CTL 0x10
+#define AX_CMD_READ_IPG012 0x11
+#define AX_CMD_WRITE_IPG0 0x12
+#define AX_CMD_WRITE_IPG1 0x13
+#define AX_CMD_WRITE_IPG2 0x14
+#define AX_CMD_WRITE_MULTI_FILTER 0x16
+#define AX_CMD_READ_NODE_ID 0x17
+#define AX_CMD_READ_PHY_ID 0x19
+#define AX_CMD_READ_MEDIUM_STATUS 0x1a
+#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
+#define AX_CMD_READ_MONITOR_MODE 0x1c
+#define AX_CMD_WRITE_MONITOR_MODE 0x1d
+#define AX_CMD_WRITE_GPIOS 0x1f
+#define AX_CMD_SW_RESET 0x20
+#define AX_CMD_SW_PHY_STATUS 0x21
+#define AX_CMD_SW_PHY_SELECT 0x22
+#define AX88772_CMD_READ_NODE_ID 0x13
+
+#define AX_MONITOR_MODE 0x01
+#define AX_MONITOR_LINK 0x02
+#define AX_MONITOR_MAGIC 0x04
+#define AX_MONITOR_HSFS 0x10
+
+/* AX88172 Medium Status Register values */
+#define AX_MEDIUM_FULL_DUPLEX 0x02
+#define AX_MEDIUM_TX_ABORT_ALLOW 0x04
+#define AX_MEDIUM_FLOW_CONTROL_EN 0x10
+
+#define AX_MCAST_FILTER_SIZE 8
+#define AX_MAX_MCAST 64
+
+#define AX_EEPROM_LEN 0x40
+
+#define AX_SWRESET_CLEAR 0x00
+#define AX_SWRESET_RR 0x01
+#define AX_SWRESET_RT 0x02
+#define AX_SWRESET_PRTE 0x04
+#define AX_SWRESET_PRL 0x08
+#define AX_SWRESET_BZ 0x10
+#define AX_SWRESET_IPRL 0x20
+#define AX_SWRESET_IPPD 0x40
+
+#define AX88772_IPG0_DEFAULT 0x15
+#define AX88772_IPG1_DEFAULT 0x0c
+#define AX88772_IPG2_DEFAULT 0x12
+
+#define AX88772_MEDIUM_FULL_DUPLEX 0x0002
+#define AX88772_MEDIUM_RESERVED 0x0004
+#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010
+#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020
+#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080
+#define AX88772_MEDIUM_RX_ENABLE 0x0100
+#define AX88772_MEDIUM_100MB 0x0200
+#define AX88772_MEDIUM_DEFAULT \
+ (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
+ AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
+ AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
+
+#define AX_EEPROM_MAGIC 0xdeadbeef
+
+/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
+struct ax8817x_data {
+ u8 multi_filter[AX_MCAST_FILTER_SIZE];
+};
+
+struct ax88172_int_data {
+ u16 res1;
+ u8 link;
+ u16 res2;
+ u8 status;
+ u16 res3;
+} __attribute__ ((packed));
+
+static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+ u16 size, void *data)
+{
+ return usb_control_msg(
+ dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ cmd,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ data,
+ size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+ u16 size, void *data)
+{
+ return usb_control_msg(
+ dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ cmd,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ data,
+ size,
+ USB_CTRL_SET_TIMEOUT);
+}
+
+static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+ if (urb->status < 0)
+ printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
+ urb->status);
+
+ kfree(req);
+ usb_free_urb(urb);
+}
+
+static void ax8817x_status(struct usbnet *dev, struct urb *urb)
+{
+ struct ax88172_int_data *event;
+ int link;
+
+ if (urb->actual_length < 8)
+ return;
+
+ event = urb->transfer_buffer;
+ link = event->link & 0x01;
+ if (netif_carrier_ok(dev->net) != link) {
+ if (link) {
+ netif_carrier_on(dev->net);
+ usbnet_defer_kevent (dev, EVENT_LINK_RESET );
+ } else
+ netif_carrier_off(dev->net);
+ devdbg(dev, "ax8817x - Link Status is: %d", link);
+ }
+}
+
+static void
+ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+ u16 size, void *data)
+{
+ struct usb_ctrlrequest *req;
+ int status;
+ struct urb *urb;
+
+ if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
+ devdbg(dev, "Error allocating URB in write_cmd_async!");
+ return;
+ }
+
+ if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+ deverr(dev, "Failed to allocate memory for control request");
+ usb_free_urb(urb);
+ return;
+ }
+
+ req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+ req->bRequest = cmd;
+ req->wValue = cpu_to_le16(value);
+ req->wIndex = cpu_to_le16(index);
+ req->wLength = cpu_to_le16(size);
+
+ usb_fill_control_urb(urb, dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, data, size,
+ ax8817x_async_cmd_callback, req);
+
+ if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+ deverr(dev, "Error submitting the control message: status=%d",
+ status);
+ kfree(req);
+ usb_free_urb(urb);
+ }
+}
+
+static void ax8817x_set_multicast(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+ struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
+ u8 rx_ctl = 0x8c;
+
+ if (net->flags & IFF_PROMISC) {
+ rx_ctl |= 0x01;
+ } else if (net->flags & IFF_ALLMULTI
+ || net->mc_count > AX_MAX_MCAST) {
+ rx_ctl |= 0x02;
+ } else if (net->mc_count == 0) {
+ /* just broadcast and directed */
+ } else {
+ /* We use the 20 byte dev->data
+ * for our 8 byte filter buffer
+ * to avoid allocating memory that
+ * is tricky to free later */
+ struct dev_mc_list *mc_list = net->mc_list;
+ u32 crc_bits;
+ int i;
+
+ memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
+
+ /* Build the multicast hash filter. */
+ for (i = 0; i < net->mc_count; i++) {
+ crc_bits =
+ ether_crc(ETH_ALEN,
+ mc_list->dmi_addr) >> 26;
+ data->multi_filter[crc_bits >> 3] |=
+ 1 << (crc_bits & 7);
+ mc_list = mc_list->next;
+ }
+
+ ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+ AX_MCAST_FILTER_SIZE, data->multi_filter);
+
+ rx_ctl |= 0x10;
+ }
+
+ ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
+}
+
+static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 res;
+ u8 buf[1];
+
+ ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+ ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
+ (__u16)loc, 2, (u16 *)&res);
+ ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+
+ return res & 0xffff;
+}
+
+/* same as above, but converts resulting value to cpu byte order */
+static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc)
+{
+ return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc));
+}
+
+static void
+ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 res = val;
+ u8 buf[1];
+
+ ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
+ (__u16)loc, 2, (u16 *)&res);
+ ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+}
+
+/* same as above, but converts new value to le16 byte order before writing */
+static void
+ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val)
+{
+ ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) );
+}
+
+static int ax88172_link_reset(struct usbnet *dev)
+{
+ u16 lpa;
+ u16 adv;
+ u16 res;
+ u8 mode;
+
+ mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
+ lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
+ adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+ res = mii_nway_result(lpa|adv);
+ if (res & LPA_DUPLEX)
+ mode |= AX_MEDIUM_FULL_DUPLEX;
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+ return 0;
+}
+
+static void
+ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+ struct usbnet *dev = netdev_priv(net);
+ u8 opt;
+
+ if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
+ wolinfo->supported = 0;
+ wolinfo->wolopts = 0;
+ return;
+ }
+ wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+ wolinfo->wolopts = 0;
+ if (opt & AX_MONITOR_MODE) {
+ if (opt & AX_MONITOR_LINK)
+ wolinfo->wolopts |= WAKE_PHY;
+ if (opt & AX_MONITOR_MAGIC)
+ wolinfo->wolopts |= WAKE_MAGIC;
+ }
+}
+
+static int
+ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+ struct usbnet *dev = netdev_priv(net);
+ u8 opt = 0;
+ u8 buf[1];
+
+ if (wolinfo->wolopts & WAKE_PHY)
+ opt |= AX_MONITOR_LINK;
+ if (wolinfo->wolopts & WAKE_MAGIC)
+ opt |= AX_MONITOR_MAGIC;
+ if (opt != 0)
+ opt |= AX_MONITOR_MODE;
+
+ if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
+ opt, 0, 0, &buf) < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ax8817x_get_eeprom_len(struct net_device *net)
+{
+ return AX_EEPROM_LEN;
+}
+
+static int ax8817x_get_eeprom(struct net_device *net,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ struct usbnet *dev = netdev_priv(net);
+ u16 *ebuf = (u16 *)data;
+ int i;
+
+ /* Crude hack to ensure that we don't overwrite memory
+ * if an odd length is supplied
+ */
+ if (eeprom->len % 2)
+ return -EINVAL;
+
+ eeprom->magic = AX_EEPROM_MAGIC;
+
+ /* ax8817x returns 2 bytes from eeprom on read */
+ for (i=0; i < eeprom->len / 2; i++) {
+ if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
+ eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void ax8817x_get_drvinfo (struct net_device *net,
+ struct ethtool_drvinfo *info)
+{
+ /* Inherit standard device info */
+ usbnet_get_drvinfo(net, info);
+ info->eedump_len = 0x3e;
+}
+
+static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ return mii_ethtool_gset(&dev->mii,cmd);
+}
+
+static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ return mii_ethtool_sset(&dev->mii,cmd);
+}
+
+/* We need to override some ethtool_ops so we require our
+ own structure so we don't interfere with other usbnet
+ devices that may be connected at the same time. */
+static struct ethtool_ops ax8817x_ethtool_ops = {
+ .get_drvinfo = ax8817x_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_wol = ax8817x_get_wol,
+ .set_wol = ax8817x_set_wol,
+ .get_eeprom_len = ax8817x_get_eeprom_len,
+ .get_eeprom = ax8817x_get_eeprom,
+ .get_settings = ax8817x_get_settings,
+ .set_settings = ax8817x_set_settings,
+};
+
+static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret = 0;
+ void *buf;
+ int i;
+ unsigned long gpio_bits = dev->driver_info->data;
+
+ usbnet_get_endpoints(dev,intf);
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf) {
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ /* Toggle the GPIOs in a manufacturer/model specific way */
+ for (i = 2; i >= 0; i--) {
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
+ (gpio_bits >> (i * 8)) & 0xff, 0, 0,
+ buf)) < 0)
+ goto out2;
+ msleep(5);
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
+ 0x80, 0, 0, buf)) < 0) {
+ dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+ goto out2;
+ }
+
+ /* Get the MAC address */
+ memset(buf, 0, ETH_ALEN);
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID,
+ 0, 0, 6, buf)) < 0) {
+ dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
+ goto out2;
+ }
+ memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+
+ /* Get the PHY id */
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
+ 0, 0, 2, buf)) < 0) {
+ dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
+ goto out2;
+ } else if (ret < 2) {
+ /* this should always return 2 bytes */
+ dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
+ ret);
+ ret = -EIO;
+ goto out2;
+ }
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = ax8817x_mdio_read;
+ dev->mii.mdio_write = ax8817x_mdio_write;
+ dev->mii.phy_id_mask = 0x3f;
+ dev->mii.reg_num_mask = 0x1f;
+ dev->mii.phy_id = *((u8 *)buf + 1);
+ dev->net->do_ioctl = ax8817x_ioctl;
+
+ dev->net->set_multicast_list = ax8817x_set_multicast;
+ dev->net->ethtool_ops = &ax8817x_ethtool_ops;
+
+ ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+ ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+ mii_nway_restart(&dev->mii);
+
+ return 0;
+out2:
+ kfree(buf);
+out1:
+ return ret;
+}
+
+static struct ethtool_ops ax88772_ethtool_ops = {
+ .get_drvinfo = ax8817x_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_wol = ax8817x_get_wol,
+ .set_wol = ax8817x_set_wol,
+ .get_eeprom_len = ax8817x_get_eeprom_len,
+ .get_eeprom = ax8817x_get_eeprom,
+ .get_settings = ax8817x_get_settings,
+ .set_settings = ax8817x_set_settings,
+};
+
+static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+ void *buf;
+
+ usbnet_get_endpoints(dev,intf);
+
+ buf = kmalloc(6, GFP_KERNEL);
+ if(!buf) {
+ dbg ("Cannot allocate memory for buffer");
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
+ 0x00B0, 0, 0, buf)) < 0)
+ goto out2;
+
+ msleep(5);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT,
+ 0x0001, 0, 0, buf)) < 0) {
+ dbg("Select PHY #1 failed: %d", ret);
+ goto out2;
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD,
+ 0, 0, buf)) < 0) {
+ dbg("Failed to power down internal PHY: %d", ret);
+ goto out2;
+ }
+
+ msleep(150);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR,
+ 0, 0, buf)) < 0) {
+ dbg("Failed to perform software reset: %d", ret);
+ goto out2;
+ }
+
+ msleep(150);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
+ AX_SWRESET_IPRL | AX_SWRESET_PRL,
+ 0, 0, buf)) < 0) {
+ dbg("Failed to set Internal/External PHY reset control: %d",
+ ret);
+ goto out2;
+ }
+
+ msleep(150);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
+ 0x0000, 0, 0, buf)) < 0) {
+ dbg("Failed to reset RX_CTL: %d", ret);
+ goto out2;
+ }
+
+ /* Get the MAC address */
+ memset(buf, 0, ETH_ALEN);
+ if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID,
+ 0, 0, ETH_ALEN, buf)) < 0) {
+ dbg("Failed to read MAC address: %d", ret);
+ goto out2;
+ }
+ memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII,
+ 0, 0, 0, buf)) < 0) {
+ dbg("Enabling software MII failed: %d", ret);
+ goto out2;
+ }
+
+ if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG,
+ 0x0010, 2, 2, buf)) < 0)
+ || (*((u16 *)buf) != 0x003b)) {
+ dbg("Read PHY register 2 must be 0x3b00: %d", ret);
+ goto out2;
+ }
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = ax8817x_mdio_read;
+ dev->mii.mdio_write = ax8817x_mdio_write;
+ dev->mii.phy_id_mask = 0xff;
+ dev->mii.reg_num_mask = 0xff;
+ dev->net->do_ioctl = ax8817x_ioctl;
+
+ /* Get the PHY id */
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,
+ 0, 0, 2, buf)) < 0) {
+ dbg("Error reading PHY ID: %02x", ret);
+ goto out2;
+ } else if (ret < 2) {
+ /* this should always return 2 bytes */
+ dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
+ ret);
+ ret = -EIO;
+ goto out2;
+ }
+ dev->mii.phy_id = *((u8 *)buf + 1);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL,
+ 0, 0, buf)) < 0) {
+ dbg("Set external PHY reset pin level: %d", ret);
+ goto out2;
+ }
+ msleep(150);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,
+ AX_SWRESET_IPRL | AX_SWRESET_PRL,
+ 0, 0, buf)) < 0) {
+ dbg("Set Internal/External PHY reset control: %d", ret);
+ goto out2;
+ }
+ msleep(150);
+
+
+ dev->net->set_multicast_list = ax8817x_set_multicast;
+ dev->net->ethtool_ops = &ax88772_ethtool_ops;
+
+ ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+ ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_CSMA);
+ mii_nway_restart(&dev->mii);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
+ AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
+ dbg("Write medium mode register: %d", ret);
+ goto out2;
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,
+ AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
+ AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
+ dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
+ goto out2;
+ }
+ if ((ret =
+ ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
+ dbg("Failed to set hardware MII: %02x", ret);
+ goto out2;
+ }
+
+ /* Set RX_CTL to default values with 2k buffer, and enable cactus */
+ if ((ret =
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
+ buf)) < 0) {
+ dbg("Reset RX_CTL failed: %d", ret);
+ goto out2;
+ }
+
+ kfree(buf);
+
+ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
+ if (dev->driver_info->flags & FLAG_FRAMING_AX) {
+ /* hard_mtu is still the default - the device does not support
+ jumbo eth frames */
+ dev->rx_urb_size = 2048;
+ }
+
+ return 0;
+
+out2:
+ kfree(buf);
+out1:
+ return ret;
+}
+
+static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ u8 *head;
+ u32 header;
+ char *packet;
+ struct sk_buff *ax_skb;
+ u16 size;
+
+ head = (u8 *) skb->data;
+ memcpy(&header, head, sizeof(header));
+ le32_to_cpus(&header);
+ packet = head + sizeof(header);
+
+ skb_pull(skb, 4);
+
+ while (skb->len > 0) {
+ if ((short)(header & 0x0000ffff) !=
+ ~((short)((header & 0xffff0000) >> 16))) {
+ devdbg(dev,"header length data is error");
+ }
+ /* get the packet length */
+ size = (u16) (header & 0x0000ffff);
+
+ if ((skb->len) - ((size + 1) & 0xfffe) == 0)
+ return 2;
+ if (size > ETH_FRAME_LEN) {
+ devdbg(dev,"invalid rx length %d", size);
+ return 0;
+ }
+ ax_skb = skb_clone(skb, GFP_ATOMIC);
+ if (ax_skb) {
+ ax_skb->len = size;
+ ax_skb->data = packet;
+ ax_skb->tail = packet + size;
+ usbnet_skb_return(dev, ax_skb);
+ } else {
+ return 0;
+ }
+
+ skb_pull(skb, (size + 1) & 0xfffe);
+
+ if (skb->len == 0)
+ break;
+
+ head = (u8 *) skb->data;
+ memcpy(&header, head, sizeof(header));
+ le32_to_cpus(&header);
+ packet = head + sizeof(header);
+ skb_pull(skb, 4);
+ }
+
+ if (skb->len < 0) {
+ devdbg(dev,"invalid rx length %d", skb->len);
+ return 0;
+ }
+ return 1;
+}
+
+static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ unsigned flags)
+{
+ int padlen;
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+ u32 packet_len;
+ u32 padbytes = 0xffff0000;
+
+ padlen = ((skb->len + 4) % 512) ? 0 : 4;
+
+ if ((!skb_cloned(skb))
+ && ((headroom + tailroom) >= (4 + padlen))) {
+ if ((headroom < 4) || (tailroom < padlen)) {
+ skb->data = memmove(skb->head + 4, skb->data, skb->len);
+ skb->tail = skb->data + skb->len;
+ }
+ } else {
+ struct sk_buff *skb2;
+ skb2 = skb_copy_expand(skb, 4, padlen, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+
+ skb_push(skb, 4);
+ packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
+ memcpy(skb->data, &packet_len, sizeof(packet_len));
+
+ if ((skb->len % 512) == 0) {
+ memcpy( skb->tail, &padbytes, sizeof(padbytes));
+ skb_put(skb, sizeof(padbytes));
+ }
+ return skb;
+}
+
+static int ax88772_link_reset(struct usbnet *dev)
+{
+ u16 lpa;
+ u16 adv;
+ u16 res;
+ u16 mode;
+
+ mode = AX88772_MEDIUM_DEFAULT;
+ lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);
+ adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+ res = mii_nway_result(lpa|adv);
+
+ if ((res & LPA_DUPLEX) == 0)
+ mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
+ if ((res & LPA_100) == 0)
+ mode &= ~AX88772_MEDIUM_100MB;
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+ return 0;
+}
+
+static const struct driver_info ax8817x_info = {
+ .description = "ASIX AX8817x USB 2.0 Ethernet",
+ .bind = ax8817x_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
+ .flags = FLAG_ETHER,
+ .data = 0x00130103,
+};
+
+static const struct driver_info dlink_dub_e100_info = {
+ .description = "DLink DUB-E100 USB Ethernet",
+ .bind = ax8817x_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
+ .flags = FLAG_ETHER,
+ .data = 0x009f9d9f,
+};
+
+static const struct driver_info netgear_fa120_info = {
+ .description = "Netgear FA-120 USB Ethernet",
+ .bind = ax8817x_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
+ .flags = FLAG_ETHER,
+ .data = 0x00130103,
+};
+
+static const struct driver_info hawking_uf200_info = {
+ .description = "Hawking UF200 USB Ethernet",
+ .bind = ax8817x_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88172_link_reset,
+ .reset = ax88172_link_reset,
+ .flags = FLAG_ETHER,
+ .data = 0x001f1d1f,
+};
+
+static const struct driver_info ax88772_info = {
+ .description = "ASIX AX88772 USB 2.0 Ethernet",
+ .bind = ax88772_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88772_link_reset,
+ .reset = ax88772_link_reset,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .rx_fixup = ax88772_rx_fixup,
+ .tx_fixup = ax88772_tx_fixup,
+ .data = 0x00130103,
+};
+
+static const struct usb_device_id products [] = {
+{
+ // Linksys USB200M
+ USB_DEVICE (0x077b, 0x2226),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Netgear FA120
+ USB_DEVICE (0x0846, 0x1040),
+ .driver_info = (unsigned long) &netgear_fa120_info,
+}, {
+ // DLink DUB-E100
+ USB_DEVICE (0x2001, 0x1a00),
+ .driver_info = (unsigned long) &dlink_dub_e100_info,
+}, {
+ // Intellinet, ST Lab USB Ethernet
+ USB_DEVICE (0x0b95, 0x1720),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Hawking UF200, TrendNet TU2-ET100
+ USB_DEVICE (0x07b8, 0x420a),
+ .driver_info = (unsigned long) &hawking_uf200_info,
+}, {
+ // Billionton Systems, USB2AR
+ USB_DEVICE (0x08dd, 0x90ff),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // ATEN UC210T
+ USB_DEVICE (0x0557, 0x2009),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Buffalo LUA-U2-KTX
+ USB_DEVICE (0x0411, 0x003d),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
+ USB_DEVICE (0x6189, 0x182d),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // corega FEther USB2-TX
+ USB_DEVICE (0x07aa, 0x0017),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Surecom EP-1427X-2
+ USB_DEVICE (0x1189, 0x0893),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // goodway corp usb gwusb2e
+ USB_DEVICE (0x1631, 0x6200),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // ASIX AX88772 10/100
+ USB_DEVICE (0x0b95, 0x7720),
+ .driver_info = (unsigned long) &ax88772_info,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver asix_driver = {
+ .owner = THIS_MODULE,
+ .name = "asix",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .disconnect = usbnet_disconnect,
+};
+
+static int __init asix_init(void)
+{
+ return usb_register(&asix_driver);
+}
+module_init(asix_init);
+
+static void __exit asix_exit(void)
+{
+ usb_deregister(&asix_driver);
+}
+module_exit(asix_exit);
+
+MODULE_AUTHOR("David Hollis");
+MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index c8be912f24e..37ef365a247 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)
if (urb->status == -ECONNRESET) {
dbg("Tx Reset.");
- urb->transfer_flags &= ~URB_ASYNC_UNLINK;
urb->status = 0;
catc->netdev->trans_start = jiffies;
catc->stats.tx_errors++;
@@ -445,7 +444,6 @@ static void catc_tx_timeout(struct net_device *netdev)
struct catc *catc = netdev_priv(netdev);
warn("Transmit timed out.");
- catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(catc->tx_urb);
}
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
new file mode 100644
index 00000000000..652b04bbf6a
--- /dev/null
+++ b/drivers/usb/net/cdc_ether.c
@@ -0,0 +1,509 @@
+/*
+ * CDC Ethernet based networking peripherals
+ * Copyright (C) 2003-2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * probes control interface, claims data interface, collects the bulk
+ * endpoints, activates data interface (if needed), maybe sets MTU.
+ * all pure cdc, except for certain firmware workarounds, and knowing
+ * that rndis uses one different rule.
+ */
+int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 *buf = intf->cur_altsetting->extra;
+ int len = intf->cur_altsetting->extralen;
+ struct usb_interface_descriptor *d;
+ struct cdc_state *info = (void *) &dev->data;
+ int status;
+ int rndis;
+ struct usb_driver *driver = driver_of(intf);
+
+ if (sizeof dev->data < sizeof *info)
+ return -EDOM;
+
+ /* expect strict spec conformance for the descriptors, but
+ * cope with firmware which stores them in the wrong place
+ */
+ if (len == 0 && dev->udev->actconfig->extralen) {
+ /* Motorola SB4100 (and others: Brad Hards says it's
+ * from a Broadcom design) put CDC descriptors here
+ */
+ buf = dev->udev->actconfig->extra;
+ len = dev->udev->actconfig->extralen;
+ if (len)
+ dev_dbg(&intf->dev,
+ "CDC descriptors on config\n");
+ }
+
+ /* this assumes that if there's a non-RNDIS vendor variant
+ * of cdc-acm, it'll fail RNDIS requests cleanly.
+ */
+ rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
+
+ memset(info, 0, sizeof *info);
+ info->control = intf;
+ while (len > 3) {
+ if (buf [1] != USB_DT_CS_INTERFACE)
+ goto next_desc;
+
+ /* use bDescriptorSubType to identify the CDC descriptors.
+ * We expect devices with CDC header and union descriptors.
+ * For CDC Ethernet we need the ethernet descriptor.
+ * For RNDIS, ignore two (pointless) CDC modem descriptors
+ * in favor of a complicated OID-based RPC scheme doing what
+ * CDC Ethernet achieves with a simple descriptor.
+ */
+ switch (buf [2]) {
+ case USB_CDC_HEADER_TYPE:
+ if (info->header) {
+ dev_dbg(&intf->dev, "extra CDC header\n");
+ goto bad_desc;
+ }
+ info->header = (void *) buf;
+ if (info->header->bLength != sizeof *info->header) {
+ dev_dbg(&intf->dev, "CDC header len %u\n",
+ info->header->bLength);
+ goto bad_desc;
+ }
+ break;
+ case USB_CDC_UNION_TYPE:
+ if (info->u) {
+ dev_dbg(&intf->dev, "extra CDC union\n");
+ goto bad_desc;
+ }
+ info->u = (void *) buf;
+ if (info->u->bLength != sizeof *info->u) {
+ dev_dbg(&intf->dev, "CDC union len %u\n",
+ info->u->bLength);
+ goto bad_desc;
+ }
+
+ /* we need a master/control interface (what we're
+ * probed with) and a slave/data interface; union
+ * descriptors sort this all out.
+ */
+ info->control = usb_ifnum_to_if(dev->udev,
+ info->u->bMasterInterface0);
+ info->data = usb_ifnum_to_if(dev->udev,
+ info->u->bSlaveInterface0);
+ if (!info->control || !info->data) {
+ dev_dbg(&intf->dev,
+ "master #%u/%p slave #%u/%p\n",
+ info->u->bMasterInterface0,
+ info->control,
+ info->u->bSlaveInterface0,
+ info->data);
+ goto bad_desc;
+ }
+ if (info->control != intf) {
+ dev_dbg(&intf->dev, "bogus CDC Union\n");
+ /* Ambit USB Cable Modem (and maybe others)
+ * interchanges master and slave interface.
+ */
+ if (info->data == intf) {
+ info->data = info->control;
+ info->control = intf;
+ } else
+ goto bad_desc;
+ }
+
+ /* a data interface altsetting does the real i/o */
+ d = &info->data->cur_altsetting->desc;
+ if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
+ dev_dbg(&intf->dev, "slave class %u\n",
+ d->bInterfaceClass);
+ goto bad_desc;
+ }
+ break;
+ case USB_CDC_ETHERNET_TYPE:
+ if (info->ether) {
+ dev_dbg(&intf->dev, "extra CDC ether\n");
+ goto bad_desc;
+ }
+ info->ether = (void *) buf;
+ if (info->ether->bLength != sizeof *info->ether) {
+ dev_dbg(&intf->dev, "CDC ether len %u\n",
+ info->ether->bLength);
+ goto bad_desc;
+ }
+ dev->hard_mtu = le16_to_cpu(
+ info->ether->wMaxSegmentSize);
+ /* because of Zaurus, we may be ignoring the host
+ * side link address we were given.
+ */
+ break;
+ }
+next_desc:
+ len -= buf [0]; /* bLength */
+ buf += buf [0];
+ }
+
+ if (!info->header || !info->u || (!rndis && !info->ether)) {
+ dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n",
+ info->header ? "" : "header ",
+ info->u ? "" : "union ",
+ info->ether ? "" : "ether ");
+ goto bad_desc;
+ }
+
+ /* claim data interface and set it up ... with side effects.
+ * network traffic can't flow until an altsetting is enabled.
+ */
+ status = usb_driver_claim_interface(driver, info->data, dev);
+ if (status < 0)
+ return status;
+ status = usbnet_get_endpoints(dev, info->data);
+ if (status < 0) {
+ /* ensure immediate exit from usbnet_disconnect */
+ usb_set_intfdata(info->data, NULL);
+ usb_driver_release_interface(driver, info->data);
+ return status;
+ }
+
+ /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
+ dev->status = NULL;
+ if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
+ struct usb_endpoint_descriptor *desc;
+
+ dev->status = &info->control->cur_altsetting->endpoint [0];
+ desc = &dev->status->desc;
+ if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
+ || !(desc->bEndpointAddress & USB_DIR_IN)
+ || (le16_to_cpu(desc->wMaxPacketSize)
+ < sizeof(struct usb_cdc_notification))
+ || !desc->bInterval) {
+ dev_dbg(&intf->dev, "bad notification endpoint\n");
+ dev->status = NULL;
+ }
+ }
+ if (rndis && !dev->status) {
+ dev_dbg(&intf->dev, "missing RNDIS status endpoint\n");
+ usb_set_intfdata(info->data, NULL);
+ usb_driver_release_interface(driver, info->data);
+ return -ENODEV;
+ }
+ return 0;
+
+bad_desc:
+ dev_info(&dev->udev->dev, "bad CDC descriptors\n");
+ return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind);
+
+void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct cdc_state *info = (void *) &dev->data;
+ struct usb_driver *driver = driver_of(intf);
+
+ /* disconnect master --> disconnect slave */
+ if (intf == info->control && info->data) {
+ /* ensure immediate exit from usbnet_disconnect */
+ usb_set_intfdata(info->data, NULL);
+ usb_driver_release_interface(driver, info->data);
+ info->data = NULL;
+ }
+
+ /* and vice versa (just in case) */
+ else if (intf == info->data && info->control) {
+ /* ensure immediate exit from usbnet_disconnect */
+ usb_set_intfdata(info->control, NULL);
+ usb_driver_release_interface(driver, info->control);
+ info->control = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Communications Device Class, Ethernet Control model
+ *
+ * Takes two interfaces. The DATA interface is inactive till an altsetting
+ * is selected. Configuration data includes class descriptors. There's
+ * an optional status endpoint on the control interface.
+ *
+ * This should interop with whatever the 2.4 "CDCEther.c" driver
+ * (by Brad Hards) talked with, with more functionality.
+ *
+ *-------------------------------------------------------------------------*/
+
+static void dumpspeed(struct usbnet *dev, __le32 *speeds)
+{
+ if (netif_msg_timer(dev))
+ devinfo(dev, "link speeds: %u kbps up, %u kbps down",
+ __le32_to_cpu(speeds[0]) / 1000,
+ __le32_to_cpu(speeds[1]) / 1000);
+}
+
+static void cdc_status(struct usbnet *dev, struct urb *urb)
+{
+ struct usb_cdc_notification *event;
+
+ if (urb->actual_length < sizeof *event)
+ return;
+
+ /* SPEED_CHANGE can get split into two 8-byte packets */
+ if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) {
+ dumpspeed(dev, (__le32 *) urb->transfer_buffer);
+ return;
+ }
+
+ event = urb->transfer_buffer;
+ switch (event->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ if (netif_msg_timer(dev))
+ devdbg(dev, "CDC: carrier %s",
+ event->wValue ? "on" : "off");
+ if (event->wValue)
+ netif_carrier_on(dev->net);
+ else
+ netif_carrier_off(dev->net);
+ break;
+ case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
+ if (netif_msg_timer(dev))
+ devdbg(dev, "CDC: speed change (len %d)",
+ urb->actual_length);
+ if (urb->actual_length != (sizeof *event + 8))
+ set_bit(EVENT_STS_SPLIT, &dev->flags);
+ else
+ dumpspeed(dev, (__le32 *) &event[1]);
+ break;
+ /* USB_CDC_NOTIFY_RESPONSE_AVAILABLE can happen too (e.g. RNDIS),
+ * but there are no standard formats for the response data.
+ */
+ default:
+ deverr(dev, "CDC: unexpected notification %02x!",
+ event->bNotificationType);
+ break;
+ }
+}
+
+static u8 nibble(unsigned char c)
+{
+ if (likely(isdigit(c)))
+ return c - '0';
+ c = toupper(c);
+ if (likely(isxdigit(c)))
+ return 10 + c - 'A';
+ return 0;
+}
+
+static inline int
+get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
+{
+ int tmp, i;
+ unsigned char buf [13];
+
+ tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
+ if (tmp != 12) {
+ dev_dbg(&dev->udev->dev,
+ "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
+ if (tmp >= 0)
+ tmp = -EINVAL;
+ return tmp;
+ }
+ for (i = tmp = 0; i < 6; i++, tmp += 2)
+ dev->net->dev_addr [i] =
+ (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
+ return 0;
+}
+
+static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int status;
+ struct cdc_state *info = (void *) &dev->data;
+
+ status = usbnet_generic_cdc_bind(dev, intf);
+ if (status < 0)
+ return status;
+
+ status = get_ethernet_addr(dev, info->ether);
+ if (status < 0) {
+ usb_set_intfdata(info->data, NULL);
+ usb_driver_release_interface(driver_of(intf), info->data);
+ return status;
+ }
+
+ /* FIXME cdc-ether has some multicast code too, though it complains
+ * in routine cases. info->ether describes the multicast support.
+ * Implement that here, manipulating the cdc filter as needed.
+ */
+ return 0;
+}
+
+static const struct driver_info cdc_info = {
+ .description = "CDC Ethernet Device",
+ .flags = FLAG_ETHER,
+ // .check_connect = cdc_check_connect,
+ .bind = cdc_bind,
+ .unbind = usbnet_cdc_unbind,
+ .status = cdc_status,
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+static const struct usb_device_id products [] = {
+/*
+ * BLACKLIST !!
+ *
+ * First blacklist any products that are egregiously nonconformant
+ * with the CDC Ethernet specs. Minor braindamage we cope with; when
+ * they're not even trying, needing a separate driver is only the first
+ * of the differences to show up.
+ */
+
+#define ZAURUS_MASTER_INTERFACE \
+ .bInterfaceClass = USB_CLASS_COMM, \
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE
+
+/* SA-1100 based Sharp Zaurus ("collie"), or compatible;
+ * wire-incompatible with true CDC Ethernet implementations.
+ * (And, it seems, needlessly so...)
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8004,
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+},
+
+/* PXA-25x based Sharp Zaurii. Note that it seems some of these
+ * (later models especially) may have shipped only with firmware
+ * advertising false "CDC MDLM" compatibility ... but we're not
+ * clear which models did that, so for now let's assume the worst.
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8005, /* A-300 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8006, /* B-500/SL-5600 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8007, /* C-700 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x9031, /* C-750 C-760 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x9032, /* SL-6000 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ /* reported with some C860 units */
+ .idProduct = 0x9050, /* C-860 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = 0,
+},
+
+/*
+ * WHITELIST!!!
+ *
+ * CDC Ether uses two interfaces, not necessarily consecutive.
+ * We match the main interface, ignoring the optional device
+ * class so we could handle devices that aren't exclusively
+ * CDC ether.
+ *
+ * NOTE: this match must come AFTER entries blacklisting devices
+ * because of bugs/quirks in a given product (like Zaurus, above).
+ */
+{
+ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &cdc_info,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver cdc_driver = {
+ .owner = THIS_MODULE,
+ .name = "cdc_ether",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+
+static int __init cdc_init(void)
+{
+ BUG_ON((sizeof(((struct usbnet *)0)->data)
+ < sizeof(struct cdc_state)));
+
+ return usb_register(&cdc_driver);
+}
+module_init(cdc_init);
+
+static void __exit cdc_exit(void)
+{
+ usb_deregister(&cdc_driver);
+}
+module_exit(cdc_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB CDC Ethernet devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
new file mode 100644
index 00000000000..f1730b685fd
--- /dev/null
+++ b/drivers/usb/net/cdc_subset.c
@@ -0,0 +1,335 @@
+/*
+ * Simple "CDC Subset" USB Networking Links
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * This supports simple USB network links that don't require any special
+ * framing or hardware control operations. The protocol used here is a
+ * strict subset of CDC Ethernet, with three basic differences reflecting
+ * the goal that almost any hardware should run it:
+ *
+ * - Minimal runtime control: one interface, no altsettings, and
+ * no vendor or class specific control requests. If a device is
+ * configured, it is allowed to exchange packets with the host.
+ * Fancier models would mean not working on some hardware.
+ *
+ * - Minimal manufacturing control: no IEEE "Organizationally
+ * Unique ID" required, or an EEPROMs to store one. Each host uses
+ * one random "locally assigned" Ethernet address instead, which can
+ * of course be overridden using standard tools like "ifconfig".
+ * (With 2^46 such addresses, same-net collisions are quite rare.)
+ *
+ * - There is no additional framing data for USB. Packets are written
+ * exactly as in CDC Ethernet, starting with an Ethernet header and
+ * terminated by a short packet. However, the host will never send a
+ * zero length packet; some systems can't handle those robustly.
+ *
+ * Anything that can transmit and receive USB bulk packets can implement
+ * this protocol. That includes both smart peripherals and quite a lot
+ * of "host-to-host" USB cables (which embed two devices back-to-back).
+ *
+ * Note that although Linux may use many of those host-to-host links
+ * with this "cdc_subset" framing, that doesn't mean there may not be a
+ * better approach. Handling the "other end unplugs/replugs" scenario
+ * well tends to require chip-specific vendor requests. Also, Windows
+ * peers at the other end of host-to-host cables may expect their own
+ * framing to be used rather than this "cdc_subset" model.
+ */
+
+#if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX)
+/* PDA style devices are always connected if present */
+static int always_connected (struct usbnet *dev)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_USB_ALI_M5632
+#define HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * ALi M5632 driver ... does high speed
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info ali_m5632_info = {
+ .description = "ALi M5632",
+};
+
+
+#endif
+
+
+#ifdef CONFIG_USB_AN2720
+#define HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * AnchorChips 2720 driver ... http://www.cypress.com
+ *
+ * This doesn't seem to have a way to detect whether the peer is
+ * connected, or need any reset handshaking. It's got pretty big
+ * internal buffers (handles most of a frame's worth of data).
+ * Chip data sheets don't describe any vendor control messages.
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info an2720_info = {
+ .description = "AnchorChips/Cypress 2720",
+ // no reset available!
+ // no check_connect available!
+
+ .in = 2, .out = 2, // direction distinguishes these
+};
+
+#endif /* CONFIG_USB_AN2720 */
+
+
+#ifdef CONFIG_USB_BELKIN
+#define HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller
+ *
+ * ... also two eTEK designs, including one sold as "Advance USBNET"
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info belkin_info = {
+ .description = "Belkin, eTEK, or compatible",
+};
+
+#endif /* CONFIG_USB_BELKIN */
+
+
+
+#ifdef CONFIG_USB_EPSON2888
+#define HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * EPSON USB clients
+ *
+ * This is the same idea as Linux PDAs (below) except the firmware in the
+ * device might not be Tux-powered. Epson provides reference firmware that
+ * implements this interface. Product developers can reuse or modify that
+ * code, such as by using their own product and vendor codes.
+ *
+ * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info epson2888_info = {
+ .description = "Epson USB Device",
+ .check_connect = always_connected,
+
+ .in = 4, .out = 3,
+};
+
+#endif /* CONFIG_USB_EPSON2888 */
+
+
+#ifdef CONFIG_USB_KC2190
+#define HAVE_HARDWARE
+static const struct driver_info kc2190_info = {
+ .description = "KC Technology KC-190",
+};
+#endif /* CONFIG_USB_KC2190 */
+
+
+#ifdef CONFIG_USB_ARMLINUX
+#define HAVE_HARDWARE
+
+/*-------------------------------------------------------------------------
+ *
+ * Intel's SA-1100 chip integrates basic USB support, and is used
+ * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
+ * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
+ * network using minimal USB framing data.
+ *
+ * This describes the driver currently in standard ARM Linux kernels.
+ * The Zaurus uses a different driver (see later).
+ *
+ * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
+ * and different USB endpoint numbering than the SA1100 devices. The
+ * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
+ * so we rely on the endpoint descriptors.
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info linuxdev_info = {
+ .description = "Linux Device",
+ .check_connect = always_connected,
+};
+
+static const struct driver_info yopy_info = {
+ .description = "Yopy",
+ .check_connect = always_connected,
+};
+
+static const struct driver_info blob_info = {
+ .description = "Boot Loader OBject",
+ .check_connect = always_connected,
+};
+
+#endif /* CONFIG_USB_ARMLINUX */
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef HAVE_HARDWARE
+#error You need to configure some hardware for this driver
+#endif
+
+/*
+ * chip vendor names won't normally be on the cables, and
+ * may not be on the device.
+ */
+
+static const struct usb_device_id products [] = {
+
+#ifdef CONFIG_USB_ALI_M5632
+{
+ USB_DEVICE (0x0402, 0x5632), // ALi defaults
+ .driver_info = (unsigned long) &ali_m5632_info,
+},
+#endif
+
+#ifdef CONFIG_USB_AN2720
+{
+ USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
+ .driver_info = (unsigned long) &an2720_info,
+}, {
+ USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
+ .driver_info = (unsigned long) &an2720_info,
+},
+#endif
+
+#ifdef CONFIG_USB_BELKIN
+{
+ USB_DEVICE (0x050d, 0x0004), // Belkin
+ .driver_info = (unsigned long) &belkin_info,
+}, {
+ USB_DEVICE (0x056c, 0x8100), // eTEK
+ .driver_info = (unsigned long) &belkin_info,
+}, {
+ USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
+ .driver_info = (unsigned long) &belkin_info,
+},
+#endif
+
+#ifdef CONFIG_USB_EPSON2888
+{
+ USB_DEVICE (0x0525, 0x2888), // EPSON USB client
+ .driver_info = (unsigned long) &epson2888_info,
+},
+#endif
+
+#ifdef CONFIG_USB_KC2190
+{
+ USB_DEVICE (0x050f, 0x0190), // KC-190
+ .driver_info = (unsigned long) &kc2190_info,
+},
+#endif
+
+#ifdef CONFIG_USB_ARMLINUX
+/*
+ * SA-1100 using standard ARM Linux kernels, or compatible.
+ * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
+ * The sa-1100 "usb-eth" driver handles the basic framing.
+ *
+ * PXA25x or PXA210 ... these use a "usb-eth" driver much like
+ * the sa1100 one, but hardware uses different endpoint numbers.
+ *
+ * Or the Linux "Ethernet" gadget on hardware that can't talk
+ * CDC Ethernet (e.g., no altsettings), in either of two modes:
+ * - acting just like the old "usb-eth" firmware, though
+ * the implementation is different
+ * - supporting RNDIS as the first/default configuration for
+ * MS-Windows interop; Linux needs to use the other config
+ */
+{
+ // 1183 = 0x049F, both used as hex values?
+ // Compaq "Itsy" vendor/product id
+ USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
+ .driver_info = (unsigned long) &linuxdev_info,
+}, {
+ USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
+ .driver_info = (unsigned long) &yopy_info,
+}, {
+ USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
+ .driver_info = (unsigned long) &blob_info,
+}, {
+ // Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
+ // e.g. Gumstix, current OpenZaurus, ...
+ USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
+ .driver_info = (unsigned long) &linuxdev_info,
+},
+#endif
+
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_driver cdc_subset_driver = {
+ .owner = THIS_MODULE,
+ .name = "cdc_subset",
+ .probe = usbnet_probe,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .disconnect = usbnet_disconnect,
+ .id_table = products,
+};
+
+static int __init cdc_subset_init(void)
+{
+ return usb_register(&cdc_subset_driver);
+}
+module_init(cdc_subset_init);
+
+static void __exit cdc_subset_exit(void)
+{
+ usb_deregister(&cdc_subset_driver);
+}
+module_exit(cdc_subset_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
new file mode 100644
index 00000000000..c8763ae33c7
--- /dev/null
+++ b/drivers/usb/net/gl620a.c
@@ -0,0 +1,407 @@
+/*
+ * GeneSys GL620USB-A based links
+ * Copyright (C) 2001 by Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
+ * Copyright (C) 2001 by Stanislav Brabec <utx@penguin.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * GeneSys GL620USB-A (www.genesyslogic.com.tw)
+ *
+ * ... should partially interop with the Win32 driver for this hardware.
+ * The GeneSys docs imply there's some NDIS issue motivating this framing.
+ *
+ * Some info from GeneSys:
+ * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
+ * (Some cables, like the BAFO-100c, use the half duplex version.)
+ * - For the full duplex model, the low bit of the version code says
+ * which side is which ("left/right").
+ * - For the half duplex type, a control/interrupt handshake settles
+ * the transfer direction. (That's disabled here, partially coded.)
+ * A control URB would block until other side writes an interrupt.
+ *
+ * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
+ * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
+ */
+
+// control msg write command
+#define GENELINK_CONNECT_WRITE 0xF0
+// interrupt pipe index
+#define GENELINK_INTERRUPT_PIPE 0x03
+// interrupt read buffer size
+#define INTERRUPT_BUFSIZE 0x08
+// interrupt pipe interval value
+#define GENELINK_INTERRUPT_INTERVAL 0x10
+// max transmit packet number per transmit
+#define GL_MAX_TRANSMIT_PACKETS 32
+// max packet length
+#define GL_MAX_PACKET_LEN 1514
+// max receive buffer size
+#define GL_RCV_BUF_SIZE \
+ (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
+
+struct gl_packet {
+ u32 packet_length;
+ char packet_data [1];
+};
+
+struct gl_header {
+ u32 packet_count;
+ struct gl_packet packets;
+};
+
+#ifdef GENELINK_ACK
+
+// FIXME: this code is incomplete, not debugged; it doesn't
+// handle interrupts correctly; it should use the generic
+// status IRQ code (which didn't exist back in 2001).
+
+struct gl_priv {
+ struct urb *irq_urb;
+ char irq_buf [INTERRUPT_BUFSIZE];
+};
+
+static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
+{
+ int retval;
+
+ retval = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ request,
+ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ value,
+ 0, // index
+ 0, // data buffer
+ 0, // size
+ USB_CTRL_SET_TIMEOUT);
+ return retval;
+}
+
+static void gl_interrupt_complete(struct urb *urb, struct pt_regs *regs)
+{
+ int status = urb->status;
+
+ switch (status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
+ }
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status)
+ err("%s - usb_submit_urb failed with result %d",
+ __FUNCTION__, status);
+}
+
+static int gl_interrupt_read(struct usbnet *dev)
+{
+ struct gl_priv *priv = dev->priv_data;
+ int retval;
+
+ // issue usb interrupt read
+ if (priv && priv->irq_urb) {
+ // submit urb
+ if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0)
+ dbg("gl_interrupt_read: submit fail - %X...", retval);
+ else
+ dbg("gl_interrupt_read: submit success...");
+ }
+
+ return 0;
+}
+
+// check whether another side is connected
+static int genelink_check_connect(struct usbnet *dev)
+{
+ int retval;
+
+ dbg("genelink_check_connect...");
+
+ // detect whether another side is connected
+ if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
+ dbg("%s: genelink_check_connect write fail - %X",
+ dev->net->name, retval);
+ return retval;
+ }
+
+ // usb interrupt read to ack another side
+ if ((retval = gl_interrupt_read(dev)) != 0) {
+ dbg("%s: genelink_check_connect read fail - %X",
+ dev->net->name, retval);
+ return retval;
+ }
+
+ dbg("%s: genelink_check_connect read success", dev->net->name);
+ return 0;
+}
+
+// allocate and initialize the private data for genelink
+static int genelink_init(struct usbnet *dev)
+{
+ struct gl_priv *priv;
+
+ // allocate the private data structure
+ if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) {
+ dbg("%s: cannot allocate private data per device",
+ dev->net->name);
+ return -ENOMEM;
+ }
+
+ // allocate irq urb
+ if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) {
+ dbg("%s: cannot allocate private irq urb per device",
+ dev->net->name);
+ kfree(priv);
+ return -ENOMEM;
+ }
+
+ // fill irq urb
+ usb_fill_int_urb(priv->irq_urb, dev->udev,
+ usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE),
+ priv->irq_buf, INTERRUPT_BUFSIZE,
+ gl_interrupt_complete, 0,
+ GENELINK_INTERRUPT_INTERVAL);
+
+ // set private data pointer
+ dev->priv_data = priv;
+
+ return 0;
+}
+
+// release the private data
+static int genelink_free(struct usbnet *dev)
+{
+ struct gl_priv *priv = dev->priv_data;
+
+ if (!priv)
+ return 0;
+
+// FIXME: can't cancel here; it's synchronous, and
+// should have happened earlier in any case (interrupt
+// handling needs to be generic)
+
+ // cancel irq urb first
+ usb_kill_urb(priv->irq_urb);
+
+ // free irq urb
+ usb_free_urb(priv->irq_urb);
+
+ // free the private data structure
+ kfree(priv);
+
+ return 0;
+}
+
+#endif
+
+static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ struct gl_header *header;
+ struct gl_packet *packet;
+ struct sk_buff *gl_skb;
+ u32 size;
+
+ header = (struct gl_header *) skb->data;
+
+ // get the packet count of the received skb
+ le32_to_cpus(&header->packet_count);
+ if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
+ || (header->packet_count < 0)) {
+ dbg("genelink: invalid received packet count %d",
+ header->packet_count);
+ return 0;
+ }
+
+ // set the current packet pointer to the first packet
+ packet = &header->packets;
+
+ // decrement the length for the packet count size 4 bytes
+ skb_pull(skb, 4);
+
+ while (header->packet_count > 1) {
+ // get the packet length
+ size = le32_to_cpu(packet->packet_length);
+
+ // this may be a broken packet
+ if (size > GL_MAX_PACKET_LEN) {
+ dbg("genelink: invalid rx length %d", size);
+ return 0;
+ }
+
+ // allocate the skb for the individual packet
+ gl_skb = alloc_skb(size, GFP_ATOMIC);
+ if (gl_skb) {
+
+ // copy the packet data to the new skb
+ memcpy(skb_put(gl_skb, size),
+ packet->packet_data, size);
+ usbnet_skb_return(dev, gl_skb);
+ }
+
+ // advance to the next packet
+ packet = (struct gl_packet *)
+ &packet->packet_data [size];
+ header->packet_count--;
+
+ // shift the data pointer to the next gl_packet
+ skb_pull(skb, size + 4);
+ }
+
+ // skip the packet length field 4 bytes
+ skb_pull(skb, 4);
+
+ if (skb->len > GL_MAX_PACKET_LEN) {
+ dbg("genelink: invalid rx length %d", skb->len);
+ return 0;
+ }
+ return 1;
+}
+
+static struct sk_buff *
+genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+ int padlen;
+ int length = skb->len;
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+ u32 *packet_count;
+ u32 *packet_len;
+
+ // FIXME: magic numbers, bleech
+ padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
+
+ if ((!skb_cloned(skb))
+ && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
+ if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
+ skb->data = memmove(skb->head + (4 + 4*1),
+ skb->data, skb->len);
+ skb->tail = skb->data + skb->len;
+ }
+ } else {
+ struct sk_buff *skb2;
+ skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+
+ // attach the packet count to the header
+ packet_count = (u32 *) skb_push(skb, (4 + 4*1));
+ packet_len = packet_count + 1;
+
+ *packet_count = cpu_to_le32(1);
+ *packet_len = cpu_to_le32(length);
+
+ // add padding byte
+ if ((skb->len % dev->maxpacket) == 0)
+ skb_put(skb, 1);
+
+ return skb;
+}
+
+static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ dev->hard_mtu = GL_RCV_BUF_SIZE;
+ dev->net->hard_header_len += 4;
+ dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
+ dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
+ return 0;
+}
+
+static const struct driver_info genelink_info = {
+ .description = "Genesys GeneLink",
+ .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT,
+ .bind = genelink_bind,
+ .rx_fixup = genelink_rx_fixup,
+ .tx_fixup = genelink_tx_fixup,
+
+ .in = 1, .out = 2,
+
+#ifdef GENELINK_ACK
+ .check_connect =genelink_check_connect,
+#endif
+};
+
+static const struct usb_device_id products [] = {
+
+{
+ USB_DEVICE(0x05e3, 0x0502), // GL620USB-A
+ .driver_info = (unsigned long) &genelink_info,
+},
+ /* NOT: USB_DEVICE(0x05e3, 0x0501), // GL620USB
+ * that's half duplex, not currently supported
+ */
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver gl620a_driver = {
+ .owner = THIS_MODULE,
+ .name = "gl620a",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init usbnet_init(void)
+{
+ return usb_register(&gl620a_driver);
+}
+module_init(usbnet_init);
+
+static void __exit usbnet_exit(void)
+{
+ usb_deregister(&gl620a_driver);
+}
+module_exit(usbnet_exit);
+
+MODULE_AUTHOR("Jiun-Jie Huang");
+MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 7ffa99b9760..e04b0ce3611 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)
kaweth_usb_transmit_complete,
kaweth);
kaweth->end = 0;
- kaweth->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
{
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
new file mode 100644
index 00000000000..a4309c4a491
--- /dev/null
+++ b/drivers/usb/net/net1080.c
@@ -0,0 +1,622 @@
+/*
+ * Net1080 based USB host-to-host cables
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include <asm/unaligned.h>
+
+#include "usbnet.h"
+
+
+/*
+ * Netchip 1080 driver ... http://www.netchip.com
+ * (Sept 2004: End-of-life announcement has been sent.)
+ * Used in (some) LapLink cables
+ */
+
+#define frame_errors data[1]
+
+/*
+ * NetChip framing of ethernet packets, supporting additional error
+ * checks for links that may drop bulk packets from inside messages.
+ * Odd USB length == always short read for last usb packet.
+ * - nc_header
+ * - Ethernet header (14 bytes)
+ * - payload
+ * - (optional padding byte, if needed so length becomes odd)
+ * - nc_trailer
+ *
+ * This framing is to be avoided for non-NetChip devices.
+ */
+
+struct nc_header { // packed:
+ __le16 hdr_len; // sizeof nc_header (LE, all)
+ __le16 packet_len; // payload size (including ethhdr)
+ __le16 packet_id; // detects dropped packets
+#define MIN_HEADER 6
+
+ // all else is optional, and must start with:
+ // __le16 vendorId; // from usb-if
+ // __le16 productId;
+} __attribute__((__packed__));
+
+#define PAD_BYTE ((unsigned char)0xAC)
+
+struct nc_trailer {
+ __le16 packet_id;
+} __attribute__((__packed__));
+
+// packets may use FLAG_FRAMING_NC and optional pad
+#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
+ + sizeof (struct ethhdr) \
+ + (mtu) \
+ + 1 \
+ + sizeof (struct nc_trailer))
+
+#define MIN_FRAMED FRAMED_SIZE(0)
+
+/* packets _could_ be up to 64KB... */
+#define NC_MAX_PACKET 32767
+
+
+/*
+ * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
+ * before the hardware drops it. If that's done, the driver will need to
+ * frame network packets to guard against the dropped USB packets. The win32
+ * driver sets this for both sides of the link.
+ */
+#define NC_READ_TTL_MS ((u8)255) // ms
+
+/*
+ * We ignore most registers and EEPROM contents.
+ */
+#define REG_USBCTL ((u8)0x04)
+#define REG_TTL ((u8)0x10)
+#define REG_STATUS ((u8)0x11)
+
+/*
+ * Vendor specific requests to read/write data
+ */
+#define REQUEST_REGISTER ((u8)0x10)
+#define REQUEST_EEPROM ((u8)0x11)
+
+static int
+nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
+{
+ int status = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, regnum,
+ retval_ptr, sizeof *retval_ptr,
+ USB_CTRL_GET_TIMEOUT);
+ if (status > 0)
+ status = 0;
+ if (!status)
+ le16_to_cpus(retval_ptr);
+ return status;
+}
+
+static inline int
+nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr)
+{
+ return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr);
+}
+
+// no retval ... can become async, usable in_interrupt()
+static void
+nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value)
+{
+ usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, regnum,
+ NULL, 0, // data is in setup packet
+ USB_CTRL_SET_TIMEOUT);
+}
+
+static inline void
+nc_register_write(struct usbnet *dev, u8 regnum, u16 value)
+{
+ nc_vendor_write(dev, REQUEST_REGISTER, regnum, value);
+}
+
+
+#if 0
+static void nc_dump_registers(struct usbnet *dev)
+{
+ u8 reg;
+ u16 *vp = kmalloc(sizeof (u16));
+
+ if (!vp) {
+ dbg("no memory?");
+ return;
+ }
+
+ dbg("%s registers:", dev->net->name);
+ for (reg = 0; reg < 0x20; reg++) {
+ int retval;
+
+ // reading some registers is trouble
+ if (reg >= 0x08 && reg <= 0xf)
+ continue;
+ if (reg >= 0x12 && reg <= 0x1e)
+ continue;
+
+ retval = nc_register_read(dev, reg, vp);
+ if (retval < 0)
+ dbg("%s reg [0x%x] ==> error %d",
+ dev->net->name, reg, retval);
+ else
+ dbg("%s reg [0x%x] = 0x%x",
+ dev->net->name, reg, *vp);
+ }
+ kfree(vp);
+}
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Control register
+ */
+
+#define USBCTL_WRITABLE_MASK 0x1f0f
+// bits 15-13 reserved, r/o
+#define USBCTL_ENABLE_LANG (1 << 12)
+#define USBCTL_ENABLE_MFGR (1 << 11)
+#define USBCTL_ENABLE_PROD (1 << 10)
+#define USBCTL_ENABLE_SERIAL (1 << 9)
+#define USBCTL_ENABLE_DEFAULTS (1 << 8)
+// bits 7-4 reserved, r/o
+#define USBCTL_FLUSH_OTHER (1 << 3)
+#define USBCTL_FLUSH_THIS (1 << 2)
+#define USBCTL_DISCONN_OTHER (1 << 1)
+#define USBCTL_DISCONN_THIS (1 << 0)
+
+static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl)
+{
+ if (!netif_msg_link(dev))
+ return;
+ devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
+ " this%s%s;"
+ " other%s%s; r/o 0x%x",
+ dev->udev->bus->bus_name, dev->udev->devpath,
+ usbctl,
+ (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
+ (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
+ (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
+ (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
+ (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
+
+ (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
+ (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
+ (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
+ (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
+ usbctl & ~USBCTL_WRITABLE_MASK
+ );
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Status register
+ */
+
+#define STATUS_PORT_A (1 << 15)
+
+#define STATUS_CONN_OTHER (1 << 14)
+#define STATUS_SUSPEND_OTHER (1 << 13)
+#define STATUS_MAILBOX_OTHER (1 << 12)
+#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
+
+#define STATUS_CONN_THIS (1 << 6)
+#define STATUS_SUSPEND_THIS (1 << 5)
+#define STATUS_MAILBOX_THIS (1 << 4)
+#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
+
+#define STATUS_UNSPEC_MASK 0x0c8c
+#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
+
+
+static inline void nc_dump_status(struct usbnet *dev, u16 status)
+{
+ if (!netif_msg_link(dev))
+ return;
+ devdbg(dev, "net1080 %s-%s status 0x%x:"
+ " this (%c) PKT=%d%s%s%s;"
+ " other PKT=%d%s%s%s; unspec 0x%x",
+ dev->udev->bus->bus_name, dev->udev->devpath,
+ status,
+
+ // XXX the packet counts don't seem right
+ // (1 at reset, not 0); maybe UNSPEC too
+
+ (status & STATUS_PORT_A) ? 'A' : 'B',
+ STATUS_PACKETS_THIS(status),
+ (status & STATUS_CONN_THIS) ? " CON" : "",
+ (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
+ (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
+
+ STATUS_PACKETS_OTHER(status),
+ (status & STATUS_CONN_OTHER) ? " CON" : "",
+ (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
+ (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
+
+ status & STATUS_UNSPEC_MASK
+ );
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * TTL register
+ */
+
+#define TTL_THIS(ttl) (0x00ff & ttl)
+#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
+#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
+
+static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl)
+{
+ if (netif_msg_link(dev))
+ devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
+ dev->udev->bus->bus_name, dev->udev->devpath,
+ ttl, TTL_THIS(ttl), TTL_OTHER(ttl));
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int net1080_reset(struct usbnet *dev)
+{
+ u16 usbctl, status, ttl;
+ u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
+ int retval;
+
+ if (!vp)
+ return -ENOMEM;
+
+ // nc_dump_registers(dev);
+
+ if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) {
+ dbg("can't read %s-%s status: %d",
+ dev->udev->bus->bus_name, dev->udev->devpath, retval);
+ goto done;
+ }
+ status = *vp;
+ nc_dump_status(dev, status);
+
+ if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) {
+ dbg("can't read USBCTL, %d", retval);
+ goto done;
+ }
+ usbctl = *vp;
+ nc_dump_usbctl(dev, usbctl);
+
+ nc_register_write(dev, REG_USBCTL,
+ USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
+
+ if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) {
+ dbg("can't read TTL, %d", retval);
+ goto done;
+ }
+ ttl = *vp;
+ // nc_dump_ttl(dev, ttl);
+
+ nc_register_write(dev, REG_TTL,
+ MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) );
+ dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
+
+ if (netif_msg_link(dev))
+ devinfo(dev, "port %c, peer %sconnected",
+ (status & STATUS_PORT_A) ? 'A' : 'B',
+ (status & STATUS_CONN_OTHER) ? "" : "dis"
+ );
+ retval = 0;
+
+done:
+ kfree(vp);
+ return retval;
+}
+
+static int net1080_check_connect(struct usbnet *dev)
+{
+ int retval;
+ u16 status;
+ u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL);
+
+ if (!vp)
+ return -ENOMEM;
+ retval = nc_register_read(dev, REG_STATUS, vp);
+ status = *vp;
+ kfree(vp);
+ if (retval != 0) {
+ dbg("%s net1080_check_conn read - %d", dev->net->name, retval);
+ return retval;
+ }
+ if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
+ return -ENOLINK;
+ return 0;
+}
+
+static void nc_flush_complete(struct urb *urb, struct pt_regs *regs)
+{
+ kfree(urb->context);
+ usb_free_urb(urb);
+}
+
+static void nc_ensure_sync(struct usbnet *dev)
+{
+ dev->frame_errors++;
+ if (dev->frame_errors > 5) {
+ struct urb *urb;
+ struct usb_ctrlrequest *req;
+ int status;
+
+ /* Send a flush */
+ urb = usb_alloc_urb(0, SLAB_ATOMIC);
+ if (!urb)
+ return;
+
+ req = kmalloc(sizeof *req, GFP_ATOMIC);
+ if (!req) {
+ usb_free_urb(urb);
+ return;
+ }
+
+ req->bRequestType = USB_DIR_OUT
+ | USB_TYPE_VENDOR
+ | USB_RECIP_DEVICE;
+ req->bRequest = REQUEST_REGISTER;
+ req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS
+ | USBCTL_FLUSH_OTHER);
+ req->wIndex = cpu_to_le16(REG_USBCTL);
+ req->wLength = cpu_to_le16(0);
+
+ /* queue an async control request, we don't need
+ * to do anything when it finishes except clean up.
+ */
+ usb_fill_control_urb(urb, dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ (unsigned char *) req,
+ NULL, 0,
+ nc_flush_complete, req);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status) {
+ kfree(req);
+ usb_free_urb(urb);
+ return;
+ }
+
+ if (netif_msg_rx_err(dev))
+ devdbg(dev, "flush net1080; too many framing errors");
+ dev->frame_errors = 0;
+ }
+}
+
+static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ struct nc_header *header;
+ struct nc_trailer *trailer;
+ u16 hdr_len, packet_len;
+
+ if (!(skb->len & 0x01)) {
+#ifdef DEBUG
+ struct net_device *net = dev->net;
+ dbg("rx framesize %d range %d..%d mtu %d", skb->len,
+ net->hard_header_len, dev->hard_mtu, net->mtu);
+#endif
+ dev->stats.rx_frame_errors++;
+ nc_ensure_sync(dev);
+ return 0;
+ }
+
+ header = (struct nc_header *) skb->data;
+ hdr_len = le16_to_cpup(&header->hdr_len);
+ packet_len = le16_to_cpup(&header->packet_len);
+ if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
+ dev->stats.rx_frame_errors++;
+ dbg("packet too big, %d", packet_len);
+ nc_ensure_sync(dev);
+ return 0;
+ } else if (hdr_len < MIN_HEADER) {
+ dev->stats.rx_frame_errors++;
+ dbg("header too short, %d", hdr_len);
+ nc_ensure_sync(dev);
+ return 0;
+ } else if (hdr_len > MIN_HEADER) {
+ // out of band data for us?
+ dbg("header OOB, %d bytes", hdr_len - MIN_HEADER);
+ nc_ensure_sync(dev);
+ // switch (vendor/product ids) { ... }
+ }
+ skb_pull(skb, hdr_len);
+
+ trailer = (struct nc_trailer *)
+ (skb->data + skb->len - sizeof *trailer);
+ skb_trim(skb, skb->len - sizeof *trailer);
+
+ if ((packet_len & 0x01) == 0) {
+ if (skb->data [packet_len] != PAD_BYTE) {
+ dev->stats.rx_frame_errors++;
+ dbg("bad pad");
+ return 0;
+ }
+ skb_trim(skb, skb->len - 1);
+ }
+ if (skb->len != packet_len) {
+ dev->stats.rx_frame_errors++;
+ dbg("bad packet len %d (expected %d)",
+ skb->len, packet_len);
+ nc_ensure_sync(dev);
+ return 0;
+ }
+ if (header->packet_id != get_unaligned(&trailer->packet_id)) {
+ dev->stats.rx_fifo_errors++;
+ dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
+ le16_to_cpu(header->packet_id),
+ le16_to_cpu(trailer->packet_id));
+ return 0;
+ }
+#if 0
+ devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len,
+ header->packet_len, header->packet_id);
+#endif
+ dev->frame_errors = 0;
+ return 1;
+}
+
+static struct sk_buff *
+net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+ int padlen;
+ struct sk_buff *skb2;
+ struct nc_header *header = NULL;
+ struct nc_trailer *trailer = NULL;
+ int len = skb->len;
+
+ padlen = ((len + sizeof (struct nc_header)
+ + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
+ if (!skb_cloned(skb)) {
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+
+ if ((padlen + sizeof (struct nc_trailer)) <= tailroom
+ && sizeof (struct nc_header) <= headroom)
+ /* There's enough head and tail room */
+ goto encapsulate;
+
+ if ((sizeof (struct nc_header) + padlen
+ + sizeof (struct nc_trailer)) <
+ (headroom + tailroom)) {
+ /* There's enough total room, so just readjust */
+ skb->data = memmove(skb->head
+ + sizeof (struct nc_header),
+ skb->data, skb->len);
+ skb->tail = skb->data + len;
+ goto encapsulate;
+ }
+ }
+
+ /* Create a new skb to use with the correct size */
+ skb2 = skb_copy_expand(skb,
+ sizeof (struct nc_header),
+ sizeof (struct nc_trailer) + padlen,
+ flags);
+ dev_kfree_skb_any(skb);
+ if (!skb2)
+ return skb2;
+ skb = skb2;
+
+encapsulate:
+ /* header first */
+ header = (struct nc_header *) skb_push(skb, sizeof *header);
+ header->hdr_len = cpu_to_le16(sizeof (*header));
+ header->packet_len = cpu_to_le16(len);
+ header->packet_id = cpu_to_le16((u16)dev->xid++);
+
+ /* maybe pad; then trailer */
+ if (!((skb->len + sizeof *trailer) & 0x01))
+ *skb_put(skb, 1) = PAD_BYTE;
+ trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer);
+ put_unaligned(header->packet_id, &trailer->packet_id);
+#if 0
+ devdbg(dev, "frame >tx h %d p %d id %d",
+ header->hdr_len, header->packet_len,
+ header->packet_id);
+#endif
+ return skb;
+}
+
+static int net1080_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ unsigned extra = sizeof (struct nc_header)
+ + 1
+ + sizeof (struct nc_trailer);
+
+ dev->net->hard_header_len += extra;
+ dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
+ dev->hard_mtu = NC_MAX_PACKET;
+ return usbnet_get_endpoints (dev, intf);
+}
+
+static const struct driver_info net1080_info = {
+ .description = "NetChip TurboCONNECT",
+ .flags = FLAG_FRAMING_NC,
+ .bind = net1080_bind,
+ .reset = net1080_reset,
+ .check_connect = net1080_check_connect,
+ .rx_fixup = net1080_rx_fixup,
+ .tx_fixup = net1080_tx_fixup,
+};
+
+static const struct usb_device_id products [] = {
+{
+ USB_DEVICE(0x0525, 0x1080), // NetChip ref design
+ .driver_info = (unsigned long) &net1080_info,
+}, {
+ USB_DEVICE(0x06D0, 0x0622), // Laplink Gold
+ .driver_info = (unsigned long) &net1080_info,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver net1080_driver = {
+ .owner = THIS_MODULE,
+ .name = "net1080",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init net1080_init(void)
+{
+ return usb_register(&net1080_driver);
+}
+module_init(net1080_init);
+
+static void __exit net1080_exit(void)
+{
+ usb_deregister(&net1080_driver);
+}
+module_exit(net1080_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index fcd6d3ccef4..7484d34780f 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)
pegasus_t *pegasus = netdev_priv(net);
if (netif_msg_timer(pegasus))
printk(KERN_WARNING "%s: tx timeout\n", net->name);
- pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(pegasus->tx_urb);
pegasus->stats.tx_errors++;
}
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
new file mode 100644
index 00000000000..74c2b3581c7
--- /dev/null
+++ b/drivers/usb/net/plusb.c
@@ -0,0 +1,156 @@
+/*
+ * PL-2301/2302 USB host-to-host link cables
+ * Copyright (C) 2000-2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+
+/*
+ * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
+ *
+ * The protocol and handshaking used here should be bug-compatible
+ * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
+ *
+ * HEADS UP: this handshaking isn't all that robust. This driver
+ * gets confused easily if you unplug one end of the cable then
+ * try to connect it again; you'll need to restart both ends. The
+ * "naplink" software (used by some PlayStation/2 deveopers) does
+ * the handshaking much better! Also, sometimes this hardware
+ * seems to get wedged under load. Prolific docs are weak, and
+ * don't identify differences between PL2301 and PL2302, much less
+ * anything to explain the different PL2302 versions observed.
+ */
+
+/*
+ * Bits 0-4 can be used for software handshaking; they're set from
+ * one end, cleared from the other, "read" with the interrupt byte.
+ */
+#define PL_S_EN (1<<7) /* (feature only) suspend enable */
+/* reserved bit -- rx ready (6) ? */
+#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
+#define PL_RESET_OUT (1<<4) /* reset output pipe */
+#define PL_RESET_IN (1<<3) /* reset input pipe */
+#define PL_TX_C (1<<2) /* transmission complete */
+#define PL_TX_REQ (1<<1) /* transmission received */
+#define PL_PEER_E (1<<0) /* peer exists */
+
+static inline int
+pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
+{
+ return usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ val, index,
+ NULL, 0,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int
+pl_clear_QuickLink_features(struct usbnet *dev, int val)
+{
+ return pl_vendor_req(dev, 1, (u8) val, 0);
+}
+
+static inline int
+pl_set_QuickLink_features(struct usbnet *dev, int val)
+{
+ return pl_vendor_req(dev, 3, (u8) val, 0);
+}
+
+static int pl_reset(struct usbnet *dev)
+{
+ /* some units seem to need this reset, others reject it utterly.
+ * FIXME be more like "naplink" or windows drivers.
+ */
+ (void) pl_set_QuickLink_features(dev,
+ PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
+ return 0;
+}
+
+static const struct driver_info prolific_info = {
+ .description = "Prolific PL-2301/PL-2302",
+ .flags = FLAG_NO_SETINT,
+ /* some PL-2302 versions seem to fail usb_set_interface() */
+ .reset = pl_reset,
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Proilific's name won't normally be on the cables, and
+ * may not be on the device.
+ */
+
+static const struct usb_device_id products [] = {
+
+{
+ USB_DEVICE(0x067b, 0x0000), // PL-2301
+ .driver_info = (unsigned long) &prolific_info,
+}, {
+ USB_DEVICE(0x067b, 0x0001), // PL-2302
+ .driver_info = (unsigned long) &prolific_info,
+},
+
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver plusb_driver = {
+ .owner = THIS_MODULE,
+ .name = "plusb",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init plusb_init(void)
+{
+ return usb_register(&plusb_driver);
+}
+module_init(plusb_init);
+
+static void __exit plusb_exit(void)
+{
+ usb_deregister(&plusb_driver);
+}
+module_exit(plusb_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
new file mode 100644
index 00000000000..2ed2e5fb777
--- /dev/null
+++ b/drivers/usb/net/rndis_host.c
@@ -0,0 +1,615 @@
+/*
+ * Host Side support for RNDIS Networking Links
+ * Copyright (C) 2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of
+ * course ACM was intended for modems, not Ethernet links! USB's standard
+ * for Ethernet links is "CDC Ethernet", which is significantly simpler.
+ */
+
+/*
+ * CONTROL uses CDC "encapsulated commands" with funky notifications.
+ * - control-out: SEND_ENCAPSULATED
+ * - interrupt-in: RESPONSE_AVAILABLE
+ * - control-in: GET_ENCAPSULATED
+ *
+ * We'll try to ignore the RESPONSE_AVAILABLE notifications.
+ */
+struct rndis_msg_hdr {
+ __le32 msg_type; /* RNDIS_MSG_* */
+ __le32 msg_len;
+ // followed by data that varies between messages
+ __le32 request_id;
+ __le32 status;
+ // ... and more
+} __attribute__ ((packed));
+
+/* RNDIS defines this (absurdly huge) control timeout */
+#define RNDIS_CONTROL_TIMEOUT_MS (10 * 1000)
+
+
+#define ccpu2 __constant_cpu_to_le32
+
+#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
+
+/* codes for "msg_type" field of rndis messages;
+ * only the data channel uses packet messages (maybe batched);
+ * everything else goes on the control channel.
+ */
+#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
+#define RNDIS_MSG_INIT ccpu2(0x00000002)
+#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_HALT ccpu2(0x00000003)
+#define RNDIS_MSG_QUERY ccpu2(0x00000004)
+#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_SET ccpu2(0x00000005)
+#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_RESET ccpu2(0x00000006)
+#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
+#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
+#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
+#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
+
+/* codes for "status" field of completion messages */
+#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
+#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
+#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
+#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
+#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
+#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
+
+
+struct rndis_data_hdr {
+ __le32 msg_type; /* RNDIS_MSG_PACKET */
+ __le32 msg_len; // rndis_data_hdr + data_len + pad
+ __le32 data_offset; // 36 -- right after header
+ __le32 data_len; // ... real packet size
+
+ __le32 oob_data_offset; // zero
+ __le32 oob_data_len; // zero
+ __le32 num_oob; // zero
+ __le32 packet_data_offset; // zero
+
+ __le32 packet_data_len; // zero
+ __le32 vc_handle; // zero
+ __le32 reserved; // zero
+} __attribute__ ((packed));
+
+struct rndis_init { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INIT */
+ __le32 msg_len; // 24
+ __le32 request_id;
+ __le32 major_version; // of rndis (1.0)
+ __le32 minor_version;
+ __le32 max_transfer_size;
+} __attribute__ ((packed));
+
+struct rndis_init_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INIT_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+ __le32 major_version; // of rndis (1.0)
+ __le32 minor_version;
+ __le32 device_flags;
+ __le32 medium; // zero == 802.3
+ __le32 max_packets_per_message;
+ __le32 max_transfer_size;
+ __le32 packet_alignment; // max 7; (1<<n) bytes
+ __le32 af_list_offset; // zero
+ __le32 af_list_size; // zero
+} __attribute__ ((packed));
+
+struct rndis_halt { /* OUT (no reply) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_HALT */
+ __le32 msg_len;
+ __le32 request_id;
+} __attribute__ ((packed));
+
+struct rndis_query { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_QUERY */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 oid;
+ __le32 len;
+ __le32 offset;
+/*?*/ __le32 handle; // zero
+} __attribute__ ((packed));
+
+struct rndis_query_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_QUERY_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+ __le32 len;
+ __le32 offset;
+} __attribute__ ((packed));
+
+struct rndis_set { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_SET */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 oid;
+ __le32 len;
+ __le32 offset;
+/*?*/ __le32 handle; // zero
+} __attribute__ ((packed));
+
+struct rndis_set_c { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_SET_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+} __attribute__ ((packed));
+
+struct rndis_reset { /* IN */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_RESET */
+ __le32 msg_len;
+ __le32 reserved;
+} __attribute__ ((packed));
+
+struct rndis_reset_c { /* OUT */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_RESET_C */
+ __le32 msg_len;
+ __le32 status;
+ __le32 addressing_lost;
+} __attribute__ ((packed));
+
+struct rndis_indicate { /* IN (unrequested) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_INDICATE */
+ __le32 msg_len;
+ __le32 status;
+ __le32 length;
+ __le32 offset;
+/**/ __le32 diag_status;
+ __le32 error_offset;
+/**/ __le32 message;
+} __attribute__ ((packed));
+
+struct rndis_keepalive { /* OUT (optionally IN) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
+ __le32 msg_len;
+ __le32 request_id;
+} __attribute__ ((packed));
+
+struct rndis_keepalive_c { /* IN (optionally OUT) */
+ // header and:
+ __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
+ __le32 msg_len;
+ __le32 request_id;
+ __le32 status;
+} __attribute__ ((packed));
+
+/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
+ * there are gobs more that may optionally be supported. We'll avoid as much
+ * of that mess as possible.
+ */
+#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
+#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
+
+/*
+ * RNDIS notifications from device: command completion; "reverse"
+ * keepalives; etc
+ */
+static void rndis_status(struct usbnet *dev, struct urb *urb)
+{
+ devdbg(dev, "rndis status urb, len %d stat %d",
+ urb->actual_length, urb->status);
+ // FIXME for keepalives, respond immediately (asynchronously)
+ // if not an RNDIS status, do like cdc_status(dev,urb) does
+}
+
+/*
+ * RPC done RNDIS-style. Caller guarantees:
+ * - message is properly byteswapped
+ * - there's no other request pending
+ * - buf can hold up to 1KB response (required by RNDIS spec)
+ * On return, the first few entries are already byteswapped.
+ *
+ * Call context is likely probe(), before interface name is known,
+ * which is why we won't try to use it in the diagnostics.
+ */
+static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
+{
+ struct cdc_state *info = (void *) &dev->data;
+ int retval;
+ unsigned count;
+ __le32 rsp;
+ u32 xid = 0, msg_len, request_id;
+
+ /* REVISIT when this gets called from contexts other than probe() or
+ * disconnect(): either serialize, or dispatch responses on xid
+ */
+
+ /* Issue the request; don't bother byteswapping our xid */
+ if (likely(buf->msg_type != RNDIS_MSG_HALT
+ && buf->msg_type != RNDIS_MSG_RESET)) {
+ xid = dev->xid++;
+ if (!xid)
+ xid = dev->xid++;
+ buf->request_id = (__force __le32) xid;
+ }
+ retval = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SEND_ENCAPSULATED_COMMAND,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, info->u->bMasterInterface0,
+ buf, le32_to_cpu(buf->msg_len),
+ RNDIS_CONTROL_TIMEOUT_MS);
+ if (unlikely(retval < 0 || xid == 0))
+ return retval;
+
+ // FIXME Seems like some devices discard responses when
+ // we time out and cancel our "get response" requests...
+ // so, this is fragile. Probably need to poll for status.
+
+ /* ignore status endpoint, just poll the control channel;
+ * the request probably completed immediately
+ */
+ rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
+ for (count = 0; count < 10; count++) {
+ memset(buf, 0, 1024);
+ retval = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ USB_CDC_GET_ENCAPSULATED_RESPONSE,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, info->u->bMasterInterface0,
+ buf, 1024,
+ RNDIS_CONTROL_TIMEOUT_MS);
+ if (likely(retval >= 8)) {
+ msg_len = le32_to_cpu(buf->msg_len);
+ request_id = (__force u32) buf->request_id;
+ if (likely(buf->msg_type == rsp)) {
+ if (likely(request_id == xid)) {
+ if (unlikely(rsp == RNDIS_MSG_RESET_C))
+ return 0;
+ if (likely(RNDIS_STATUS_SUCCESS
+ == buf->status))
+ return 0;
+ dev_dbg(&info->control->dev,
+ "rndis reply status %08x\n",
+ le32_to_cpu(buf->status));
+ return -EL3RST;
+ }
+ dev_dbg(&info->control->dev,
+ "rndis reply id %d expected %d\n",
+ request_id, xid);
+ /* then likely retry */
+ } else switch (buf->msg_type) {
+ case RNDIS_MSG_INDICATE: { /* fault */
+ // struct rndis_indicate *msg = (void *)buf;
+ dev_info(&info->control->dev,
+ "rndis fault indication\n");
+ }
+ break;
+ case RNDIS_MSG_KEEPALIVE: { /* ping */
+ struct rndis_keepalive_c *msg = (void *)buf;
+
+ msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
+ msg->msg_len = ccpu2(sizeof *msg);
+ msg->status = RNDIS_STATUS_SUCCESS;
+ retval = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SEND_ENCAPSULATED_COMMAND,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, info->u->bMasterInterface0,
+ msg, sizeof *msg,
+ RNDIS_CONTROL_TIMEOUT_MS);
+ if (unlikely(retval < 0))
+ dev_dbg(&info->control->dev,
+ "rndis keepalive err %d\n",
+ retval);
+ }
+ break;
+ default:
+ dev_dbg(&info->control->dev,
+ "unexpected rndis msg %08x len %d\n",
+ le32_to_cpu(buf->msg_type), msg_len);
+ }
+ } else {
+ /* device probably issued a protocol stall; ignore */
+ dev_dbg(&info->control->dev,
+ "rndis response error, code %d\n", retval);
+ }
+ msleep(2);
+ }
+ dev_dbg(&info->control->dev, "rndis response timeout\n");
+ return -ETIMEDOUT;
+}
+
+static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int retval;
+ struct net_device *net = dev->net;
+ union {
+ void *buf;
+ struct rndis_msg_hdr *header;
+ struct rndis_init *init;
+ struct rndis_init_c *init_c;
+ struct rndis_query *get;
+ struct rndis_query_c *get_c;
+ struct rndis_set *set;
+ struct rndis_set_c *set_c;
+ } u;
+ u32 tmp;
+
+ /* we can't rely on i/o from stack working, or stack allocation */
+ u.buf = kmalloc(1024, GFP_KERNEL);
+ if (!u.buf)
+ return -ENOMEM;
+ retval = usbnet_generic_cdc_bind(dev, intf);
+ if (retval < 0)
+ goto done;
+
+ net->hard_header_len += sizeof (struct rndis_data_hdr);
+
+ /* initialize; max transfer is 16KB at full speed */
+ u.init->msg_type = RNDIS_MSG_INIT;
+ u.init->msg_len = ccpu2(sizeof *u.init);
+ u.init->major_version = ccpu2(1);
+ u.init->minor_version = ccpu2(0);
+ u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len);
+
+ retval = rndis_command(dev, u.header);
+ if (unlikely(retval < 0)) {
+ /* it might not even be an RNDIS device!! */
+ dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
+fail:
+ usb_driver_release_interface(driver_of(intf),
+ ((struct cdc_state *)&(dev->data))->data);
+ goto done;
+ }
+ dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size);
+ /* REVISIT: peripheral "alignment" request is ignored ... */
+ dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu,
+ 1 << le32_to_cpu(u.init_c->packet_alignment));
+
+ /* get designated host ethernet address */
+ memset(u.get, 0, sizeof *u.get);
+ u.get->msg_type = RNDIS_MSG_QUERY;
+ u.get->msg_len = ccpu2(sizeof *u.get);
+ u.get->oid = OID_802_3_PERMANENT_ADDRESS;
+
+ retval = rndis_command(dev, u.header);
+ if (unlikely(retval < 0)) {
+ dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
+ goto fail;
+ }
+ tmp = le32_to_cpu(u.get_c->offset);
+ if (unlikely((tmp + 8) > (1024 - ETH_ALEN)
+ || u.get_c->len != ccpu2(ETH_ALEN))) {
+ dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n",
+ tmp, le32_to_cpu(u.get_c->len));
+ retval = -EDOM;
+ goto fail;
+ }
+ memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN);
+
+ /* set a nonzero filter to enable data transfers */
+ memset(u.set, 0, sizeof *u.set);
+ u.set->msg_type = RNDIS_MSG_SET;
+ u.set->msg_len = ccpu2(4 + sizeof *u.set);
+ u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
+ u.set->len = ccpu2(4);
+ u.set->offset = ccpu2((sizeof *u.set) - 8);
+ *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
+
+ retval = rndis_command(dev, u.header);
+ if (unlikely(retval < 0)) {
+ dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
+ goto fail;
+ }
+
+ retval = 0;
+done:
+ kfree(u.buf);
+ return retval;
+}
+
+static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct rndis_halt *halt;
+
+ /* try to clear any rndis state/activity (no i/o from stack!) */
+ halt = kcalloc(1, sizeof *halt, SLAB_KERNEL);
+ if (halt) {
+ halt->msg_type = RNDIS_MSG_HALT;
+ halt->msg_len = ccpu2(sizeof *halt);
+ (void) rndis_command(dev, (void *)halt);
+ kfree(halt);
+ }
+
+ return usbnet_cdc_unbind(dev, intf);
+}
+
+/*
+ * DATA -- host must not write zlps
+ */
+static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ /* peripheral may have batched packets to us... */
+ while (likely(skb->len)) {
+ struct rndis_data_hdr *hdr = (void *)skb->data;
+ struct sk_buff *skb2;
+ u32 msg_len, data_offset, data_len;
+
+ msg_len = le32_to_cpu(hdr->msg_len);
+ data_offset = le32_to_cpu(hdr->data_offset);
+ data_len = le32_to_cpu(hdr->data_len);
+
+ /* don't choke if we see oob, per-packet data, etc */
+ if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
+ || skb->len < msg_len
+ || (data_offset + data_len + 8) > msg_len)) {
+ dev->stats.rx_frame_errors++;
+ devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
+ le32_to_cpu(hdr->msg_type),
+ msg_len, data_offset, data_len, skb->len);
+ return 0;
+ }
+ skb_pull(skb, 8 + data_offset);
+
+ /* at most one packet left? */
+ if (likely((data_len - skb->len) <= sizeof *hdr)) {
+ skb_trim(skb, data_len);
+ break;
+ }
+
+ /* try to return all the packets in the batch */
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (unlikely(!skb2))
+ break;
+ skb_pull(skb, msg_len - sizeof *hdr);
+ skb_trim(skb2, data_len);
+ usbnet_skb_return(dev, skb2);
+ }
+
+ /* caller will usbnet_skb_return the remaining packet */
+ return 1;
+}
+
+static struct sk_buff *
+rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+ struct rndis_data_hdr *hdr;
+ struct sk_buff *skb2;
+ unsigned len = skb->len;
+
+ if (likely(!skb_cloned(skb))) {
+ int room = skb_headroom(skb);
+
+ /* enough head room as-is? */
+ if (unlikely((sizeof *hdr) <= room))
+ goto fill;
+
+ /* enough room, but needs to be readjusted? */
+ room += skb_tailroom(skb);
+ if (likely((sizeof *hdr) <= room)) {
+ skb->data = memmove(skb->head + sizeof *hdr,
+ skb->data, len);
+ skb->tail = skb->data + len;
+ goto fill;
+ }
+ }
+
+ /* create a new skb, with the correct size (and tailpad) */
+ skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
+ dev_kfree_skb_any(skb);
+ if (unlikely(!skb2))
+ return skb2;
+ skb = skb2;
+
+ /* fill out the RNDIS header. we won't bother trying to batch
+ * packets; Linux minimizes wasted bandwidth through tx queues.
+ */
+fill:
+ hdr = (void *) __skb_push(skb, sizeof *hdr);
+ memset(hdr, 0, sizeof *hdr);
+ hdr->msg_type = RNDIS_MSG_PACKET;
+ hdr->msg_len = cpu_to_le32(skb->len);
+ hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
+ hdr->data_len = cpu_to_le32(len);
+
+ /* FIXME make the last packet always be short ... */
+ return skb;
+}
+
+
+static const struct driver_info rndis_info = {
+ .description = "RNDIS device",
+ .flags = FLAG_ETHER | FLAG_FRAMING_RN,
+ .bind = rndis_bind,
+ .unbind = rndis_unbind,
+ .status = rndis_status,
+ .rx_fixup = rndis_rx_fixup,
+ .tx_fixup = rndis_tx_fixup,
+};
+
+#undef ccpu2
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products [] = {
+{
+ /* RNDIS is MSFT's un-official variant of CDC ACM */
+ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+ .driver_info = (unsigned long) &rndis_info,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver rndis_driver = {
+ .owner = THIS_MODULE,
+ .name = "rndis_host",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init rndis_init(void)
+{
+ return usb_register(&rndis_driver);
+}
+module_init(rndis_init);
+
+static void __exit rndis_exit(void)
+{
+ usb_deregister(&rndis_driver);
+}
+module_exit(rndis_exit);
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB Host side RNDIS driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 59ab40ebb39..c3d4e3589e3 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)
{
rtl8150_t *dev = netdev_priv(netdev);
warn("%s: Tx timeout.", netdev->name);
- dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(dev->tx_urb);
dev->stats.tx_errors++;
}
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index a2f67245f6d..6c460918d54 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1,10 +1,7 @@
/*
- * USB Networking Links
- * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
- * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
+ * USB Network driver infrastructure
+ * Copyright (C) 2000-2005 by David Brownell
* Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
- * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
- * Copyright (c) 2002-2003 TiVo Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,95 +20,15 @@
/*
* This is a generic "USB networking" framework that works with several
- * kinds of full and high speed networking devices:
- *
- * + USB host-to-host "network cables", used for IP-over-USB links.
- * These are often used for Laplink style connectivity products.
- * - AnchorChip 2720
- * - Belkin, eTEK (interops with Win32 drivers)
- * - GeneSys GL620USB-A
- * - NetChip 1080 (interoperates with NetChip Win32 drivers)
- * - Prolific PL-2301/2302 (replaces "plusb" driver)
- * - KC Technology KC2190
- *
- * + Smart USB devices can support such links directly, using Internet
- * standard protocols instead of proprietary host-to-device links.
- * - Linux PDAs like iPaq, Yopy, and Zaurus
- * - The BLOB boot loader (for diskless booting)
- * - Linux "gadgets", perhaps using PXA-2xx or Net2280 controllers
- * - Devices using EPSON's sample USB firmware
- * - CDC-Ethernet class devices, such as many cable modems
- *
- * + Adapters to networks such as Ethernet.
- * - AX8817X based USB 2.0 products
- *
- * Links to these devices can be bridged using Linux Ethernet bridging.
- * With minor exceptions, these all use similar USB framing for network
- * traffic, but need different protocols for control traffic.
- *
- * USB devices can implement their side of this protocol at the cost
- * of two bulk endpoints; it's not restricted to "cable" applications.
- * See the SA1110, Zaurus, or EPSON device/client support in this driver;
- * slave/target drivers such as "usb-eth" (on most SA-1100 PDAs) or
- * "g_ether" (in the Linux "gadget" framework) implement that behavior
- * within devices.
- *
- *
- * CHANGELOG:
- *
- * 13-sep-2000 experimental, new
- * 10-oct-2000 usb_device_id table created.
- * 28-oct-2000 misc fixes; mostly, discard more TTL-mangled rx packets.
- * 01-nov-2000 usb_device_id table and probing api update by
- * Adam J. Richter <adam@yggdrasil.com>.
- * 18-dec-2000 (db) tx watchdog, "net1080" renaming to "usbnet", device_info
- * and prolific support, isolate net1080-specific bits, cleanup.
- * fix unlink_urbs oops in D3 PM resume code path.
- *
- * 02-feb-2001 (db) fix tx skb sharing, packet length, match_flags, ...
- * 08-feb-2001 stubbed in "linuxdev", maybe the SA-1100 folk can use it;
- * AnchorChips 2720 support (from spec) for testing;
- * fix bit-ordering problem with ethernet multicast addr
- * 19-feb-2001 Support for clearing halt conditions. SA1100 UDC support
- * updates. Oleg Drokin (green@iXcelerator.com)
- * 25-mar-2001 More SA-1100 updates, including workaround for ip problem
- * expecting cleared skb->cb and framing change to match latest
- * handhelds.org version (Oleg). Enable device IDs from the
- * Win32 Belkin driver; other cleanups (db).
- * 16-jul-2001 Bugfixes for uhci oops-on-unplug, Belkin support, various
- * cleanups for problems not yet seen in the field. (db)
- * 17-oct-2001 Handle "Advance USBNET" product, like Belkin/eTEK devices,
- * from Ioannis Mavroukakis <i.mavroukakis@btinternet.com>;
- * rx unlinks somehow weren't async; minor cleanup.
- * 03-nov-2001 Merged GeneSys driver; original code from Jiun-Jie Huang
- * <huangjj@genesyslogic.com.tw>, updated by Stanislav Brabec
- * <utx@penguin.cz>. Made framing options (NetChip/GeneSys)
- * tie mostly to (sub)driver info. Workaround some PL-2302
- * chips that seem to reject SET_INTERFACE requests.
- *
- * 06-apr-2002 Added ethtool support, based on a patch from Brad Hards.
- * Level of diagnostics is more configurable; they use device
- * location (usb_device->devpath) instead of address (2.5).
- * For tx_fixup, memflags can't be NOIO.
- * 07-may-2002 Generalize/cleanup keventd support, handling rx stalls (mostly
- * for USB 2.0 TTs) and memory shortages (potential) too. (db)
- * Use "locally assigned" IEEE802 address space. (Brad Hards)
- * 18-oct-2002 Support for Zaurus (Pavel Machek), related cleanup (db).
- * 14-dec-2002 Remove Zaurus-private crc32 code (Pavel); 2.5 oops fix,
- * cleanups and stubbed PXA-250 support (db), fix for framing
- * issues on Z, net1080, and gl620a (Toby Milne)
- *
- * 31-mar-2003 Use endpoint descriptors: high speed support, simpler sa1100
- * vs pxa25x, and CDC Ethernet. Throttle down log floods on
- * disconnect; other cleanups. (db) Flush net1080 fifos
- * after several sequential framing errors. (Johannes Erdfelt)
- * 22-aug-2003 AX8817X support (Dave Hollis).
- * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
- * (Neil Bortnak)
- * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell)
- *
- * 01-feb-2005 AX88772 support (Phil Chang & Dave Hollis)
- *-------------------------------------------------------------------------*/
+ * kinds of full and high speed networking devices: host-to-host cables,
+ * smart usb peripherals, and actual Ethernet adapters.
+ *
+ * These devices usually differ in terms of control protocols (if they
+ * even have one!) and sometimes they define new framing to wrap or batch
+ * Ethernet packets. Otherwise, they talk to USB pretty much the same,
+ * so interface (un)binding, endpoint I/O queues, fault handling, and other
+ * issues can usefully be addressed by this framework.
+ */
// #define DEBUG // error path messages, extra info
// #define VERBOSE // more; success messages
@@ -121,24 +38,18 @@
# define DEBUG
#endif
#include <linux/module.h>
-#include <linux/kmod.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/random.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
#include <linux/usb.h>
-#include <asm/io.h>
-#include <asm/scatterlist.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
-#define DRIVER_VERSION "03-Nov-2004"
+#include "usbnet.h"
+
+#define DRIVER_VERSION "22-Aug-2005"
/*-------------------------------------------------------------------------*/
@@ -149,15 +60,14 @@
* One maximum size Ethernet packet takes twenty four of them.
* For high speed, each frame comfortably fits almost 36 max size
* Ethernet packets (so queues should be bigger).
+ *
+ * REVISIT qlens should be members of 'struct usbnet'; the goal is to
+ * let the USB host controller be busy for 5msec or more before an irq
+ * is required, under load. Jumbograms change the equation.
*/
#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
-// packets are always ethernet inside
-// ... except they can be bigger (limit of 64K with NetChip framing)
-#define MIN_PACKET sizeof(struct ethhdr)
-#define MAX_PACKET 32768
-
// reawaken network queue this soon after stopping; else watchdog barks
#define TX_TIMEOUT_JIFFIES (5*HZ)
@@ -165,9 +75,6 @@
// us (it polls at HZ/4 usually) before we report too many false errors.
#define THROTTLE_JIFFIES (HZ/8)
-// for vendor-specific control operations
-#define CONTROL_TIMEOUT_MS 500
-
// between wakeups
#define UNLINK_TIMEOUT_MS 3
@@ -176,109 +83,6 @@
// randomly generated ethernet address
static u8 node_id [ETH_ALEN];
-// state we keep for each device we handle
-struct usbnet {
- // housekeeping
- struct usb_device *udev;
- struct driver_info *driver_info;
- wait_queue_head_t *wait;
-
- // i/o info: pipes etc
- unsigned in, out;
- struct usb_host_endpoint *status;
- unsigned maxpacket;
- struct timer_list delay;
-
- // protocol/interface state
- struct net_device *net;
- struct net_device_stats stats;
- int msg_enable;
- unsigned long data [5];
-
- struct mii_if_info mii;
-
- // various kinds of pending driver work
- struct sk_buff_head rxq;
- struct sk_buff_head txq;
- struct sk_buff_head done;
- struct urb *interrupt;
- struct tasklet_struct bh;
-
- struct work_struct kevent;
- unsigned long flags;
-# define EVENT_TX_HALT 0
-# define EVENT_RX_HALT 1
-# define EVENT_RX_MEMORY 2
-# define EVENT_STS_SPLIT 3
-# define EVENT_LINK_RESET 4
-};
-
-// device-specific info used by the driver
-struct driver_info {
- char *description;
-
- int flags;
-/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
-#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
-#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */
-#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */
-#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */
-
-#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
-#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
-
-#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
-
- /* init device ... can sleep, or cause probe() failure */
- int (*bind)(struct usbnet *, struct usb_interface *);
-
- /* cleanup device ... can sleep, but can't fail */
- void (*unbind)(struct usbnet *, struct usb_interface *);
-
- /* reset device ... can sleep */
- int (*reset)(struct usbnet *);
-
- /* see if peer is connected ... can sleep */
- int (*check_connect)(struct usbnet *);
-
- /* for status polling */
- void (*status)(struct usbnet *, struct urb *);
-
- /* link reset handling, called from defer_kevent */
- int (*link_reset)(struct usbnet *);
-
- /* fixup rx packet (strip framing) */
- int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
-
- /* fixup tx packet (add framing) */
- struct sk_buff *(*tx_fixup)(struct usbnet *dev,
- struct sk_buff *skb, int flags);
-
- // FIXME -- also an interrupt mechanism
- // useful for at least PL2301/2302 and GL620USB-A
- // and CDC use them to report 'is it connected' changes
-
- /* for new devices, use the descriptor-reading code instead */
- int in; /* rx endpoint */
- int out; /* tx endpoint */
-
- unsigned long data; /* Misc driver specific data */
-};
-
-// we record the state for each of our queued skbs
-enum skb_state {
- illegal = 0,
- tx_start, tx_done,
- rx_start, rx_done, rx_cleanup
-};
-
-struct skb_data { // skb->cb is one of these
- struct urb *urb;
- struct usbnet *dev;
- enum skb_state state;
- size_t length;
-};
-
static const char driver_name [] = "usbnet";
/* use ethtool to change the level for any given device */
@@ -286,39 +90,10 @@ static int msg_level = -1;
module_param (msg_level, int, 0);
MODULE_PARM_DESC (msg_level, "Override default message level");
-
-#ifdef DEBUG
-#define devdbg(usbnet, fmt, arg...) \
- printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#else
-#define devdbg(usbnet, fmt, arg...) do {} while(0)
-#endif
-
-#define deverr(usbnet, fmt, arg...) \
- printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-#define devwarn(usbnet, fmt, arg...) \
- printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
-
-#define devinfo(usbnet, fmt, arg...) \
- printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
-
/*-------------------------------------------------------------------------*/
-static void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
-static u32 usbnet_get_link (struct net_device *);
-static u32 usbnet_get_msglevel (struct net_device *);
-static void usbnet_set_msglevel (struct net_device *, u32);
-static void defer_kevent (struct usbnet *, int);
-
-/* mostly for PDA style devices, which are always connected if present */
-static int always_connected (struct usbnet *dev)
-{
- return 0;
-}
-
/* handles CDC Ethernet and many other network "bulk data" interfaces */
-static int
-get_endpoints (struct usbnet *dev, struct usb_interface *intf)
+int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
{
int tmp;
struct usb_host_interface *alt = NULL;
@@ -382,6 +157,7 @@ get_endpoints (struct usbnet *dev, struct usb_interface *intf)
dev->status = status;
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
static void intr_complete (struct urb *urb, struct pt_regs *regs);
@@ -421,7 +197,11 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
return 0;
}
-static void skb_return (struct usbnet *dev, struct sk_buff *skb)
+/* Passes this packet up the stack, updating its accounting.
+ * Some link protocols batch packets, so their rx_fixup paths
+ * can return clones as well as just modify the original skb.
+ */
+void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
{
int status;
@@ -438,2425 +218,7 @@ static void skb_return (struct usbnet *dev, struct sk_buff *skb)
if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev))
devdbg (dev, "netif_rx status %d", status);
}
-
-
-#ifdef CONFIG_USB_ALI_M5632
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * ALi M5632 driver ... does high speed
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info ali_m5632_info = {
- .description = "ALi M5632",
-};
-
-
-#endif
-
-
-#ifdef CONFIG_USB_AN2720
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * AnchorChips 2720 driver ... http://www.cypress.com
- *
- * This doesn't seem to have a way to detect whether the peer is
- * connected, or need any reset handshaking. It's got pretty big
- * internal buffers (handles most of a frame's worth of data).
- * Chip data sheets don't describe any vendor control messages.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info an2720_info = {
- .description = "AnchorChips/Cypress 2720",
- // no reset available!
- // no check_connect available!
-
- .in = 2, .out = 2, // direction distinguishes these
-};
-
-#endif /* CONFIG_USB_AN2720 */
-
-
-#ifdef CONFIG_USB_AX8817X
-/* ASIX AX8817X based USB 2.0 Ethernet Devices */
-
-#define HAVE_HARDWARE
-#define NEED_MII
-
-#include <linux/crc32.h>
-
-#define AX_CMD_SET_SW_MII 0x06
-#define AX_CMD_READ_MII_REG 0x07
-#define AX_CMD_WRITE_MII_REG 0x08
-#define AX_CMD_SET_HW_MII 0x0a
-#define AX_CMD_READ_EEPROM 0x0b
-#define AX_CMD_WRITE_EEPROM 0x0c
-#define AX_CMD_WRITE_ENABLE 0x0d
-#define AX_CMD_WRITE_DISABLE 0x0e
-#define AX_CMD_WRITE_RX_CTL 0x10
-#define AX_CMD_READ_IPG012 0x11
-#define AX_CMD_WRITE_IPG0 0x12
-#define AX_CMD_WRITE_IPG1 0x13
-#define AX_CMD_WRITE_IPG2 0x14
-#define AX_CMD_WRITE_MULTI_FILTER 0x16
-#define AX_CMD_READ_NODE_ID 0x17
-#define AX_CMD_READ_PHY_ID 0x19
-#define AX_CMD_READ_MEDIUM_STATUS 0x1a
-#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
-#define AX_CMD_READ_MONITOR_MODE 0x1c
-#define AX_CMD_WRITE_MONITOR_MODE 0x1d
-#define AX_CMD_WRITE_GPIOS 0x1f
-#define AX_CMD_SW_RESET 0x20
-#define AX_CMD_SW_PHY_STATUS 0x21
-#define AX_CMD_SW_PHY_SELECT 0x22
-#define AX88772_CMD_READ_NODE_ID 0x13
-
-#define AX_MONITOR_MODE 0x01
-#define AX_MONITOR_LINK 0x02
-#define AX_MONITOR_MAGIC 0x04
-#define AX_MONITOR_HSFS 0x10
-
-/* AX88172 Medium Status Register values */
-#define AX_MEDIUM_FULL_DUPLEX 0x02
-#define AX_MEDIUM_TX_ABORT_ALLOW 0x04
-#define AX_MEDIUM_FLOW_CONTROL_EN 0x10
-
-#define AX_MCAST_FILTER_SIZE 8
-#define AX_MAX_MCAST 64
-
-#define AX_EEPROM_LEN 0x40
-
-#define AX_SWRESET_CLEAR 0x00
-#define AX_SWRESET_RR 0x01
-#define AX_SWRESET_RT 0x02
-#define AX_SWRESET_PRTE 0x04
-#define AX_SWRESET_PRL 0x08
-#define AX_SWRESET_BZ 0x10
-#define AX_SWRESET_IPRL 0x20
-#define AX_SWRESET_IPPD 0x40
-
-#define AX88772_IPG0_DEFAULT 0x15
-#define AX88772_IPG1_DEFAULT 0x0c
-#define AX88772_IPG2_DEFAULT 0x12
-
-#define AX88772_MEDIUM_FULL_DUPLEX 0x0002
-#define AX88772_MEDIUM_RESERVED 0x0004
-#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010
-#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020
-#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080
-#define AX88772_MEDIUM_RX_ENABLE 0x0100
-#define AX88772_MEDIUM_100MB 0x0200
-#define AX88772_MEDIUM_DEFAULT \
- (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \
- AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \
- AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE )
-
-#define AX_EEPROM_MAGIC 0xdeadbeef
-
-/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
-struct ax8817x_data {
- u8 multi_filter[AX_MCAST_FILTER_SIZE];
-};
-
-struct ax88172_int_data {
- u16 res1;
- u8 link;
- u16 res2;
- u8 status;
- u16 res3;
-} __attribute__ ((packed));
-
-static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- return usb_control_msg(
- dev->udev,
- usb_rcvctrlpipe(dev->udev, 0),
- cmd,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- data,
- size,
- CONTROL_TIMEOUT_MS);
-}
-
-static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- return usb_control_msg(
- dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- cmd,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value,
- index,
- data,
- size,
- CONTROL_TIMEOUT_MS);
-}
-
-static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
-
- if (urb->status < 0)
- printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
- urb->status);
-
- kfree(req);
- usb_free_urb(urb);
-}
-
-static void ax8817x_status(struct usbnet *dev, struct urb *urb)
-{
- struct ax88172_int_data *event;
- int link;
-
- if (urb->actual_length < 8)
- return;
-
- event = urb->transfer_buffer;
- link = event->link & 0x01;
- if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- defer_kevent (dev, EVENT_LINK_RESET );
- } else
- netif_carrier_off(dev->net);
- devdbg(dev, "ax8817x - Link Status is: %d", link);
- }
-}
-
-static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
- u16 size, void *data)
-{
- struct usb_ctrlrequest *req;
- int status;
- struct urb *urb;
-
- if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) {
- devdbg(dev, "Error allocating URB in write_cmd_async!");
- return;
- }
-
- if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
- deverr(dev, "Failed to allocate memory for control request");
- usb_free_urb(urb);
- return;
- }
-
- req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- req->bRequest = cmd;
- req->wValue = cpu_to_le16(value);
- req->wIndex = cpu_to_le16(index);
- req->wLength = cpu_to_le16(size);
-
- usb_fill_control_urb(urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- (void *)req, data, size,
- ax8817x_async_cmd_callback, req);
-
- if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- deverr(dev, "Error submitting the control message: status=%d", status);
- kfree(req);
- usb_free_urb(urb);
- }
-}
-
-static void ax8817x_set_multicast(struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
- u8 rx_ctl = 0x8c;
-
- if (net->flags & IFF_PROMISC) {
- rx_ctl |= 0x01;
- } else if (net->flags & IFF_ALLMULTI
- || net->mc_count > AX_MAX_MCAST) {
- rx_ctl |= 0x02;
- } else if (net->mc_count == 0) {
- /* just broadcast and directed */
- } else {
- /* We use the 20 byte dev->data
- * for our 8 byte filter buffer
- * to avoid allocating memory that
- * is tricky to free later */
- struct dev_mc_list *mc_list = net->mc_list;
- u32 crc_bits;
- int i;
-
- memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
-
- /* Build the multicast hash filter. */
- for (i = 0; i < net->mc_count; i++) {
- crc_bits =
- ether_crc(ETH_ALEN,
- mc_list->dmi_addr) >> 26;
- data->multi_filter[crc_bits >> 3] |=
- 1 << (crc_bits & 7);
- mc_list = mc_list->next;
- }
-
- ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
- AX_MCAST_FILTER_SIZE, data->multi_filter);
-
- rx_ctl |= 0x10;
- }
-
- ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
-}
-
-static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u16 res;
- u8 buf[1];
-
- ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
- ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
- ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
-
- return res & 0xffff;
-}
-
-static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
-{
- struct usbnet *dev = netdev_priv(netdev);
- u16 res = val;
- u8 buf[1];
-
- ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
- ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
- ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
-}
-
-static int ax88172_link_reset(struct usbnet *dev)
-{
- u16 lpa;
- u8 mode;
-
- mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
- lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
- if (lpa & LPA_DUPLEX)
- mode |= AX_MEDIUM_FULL_DUPLEX;
- ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
-
- return 0;
-}
-
-static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
- struct usbnet *dev = netdev_priv(net);
- u8 opt;
-
- if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
- wolinfo->supported = 0;
- wolinfo->wolopts = 0;
- return;
- }
- wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
- wolinfo->wolopts = 0;
- if (opt & AX_MONITOR_MODE) {
- if (opt & AX_MONITOR_LINK)
- wolinfo->wolopts |= WAKE_PHY;
- if (opt & AX_MONITOR_MAGIC)
- wolinfo->wolopts |= WAKE_MAGIC;
- }
-}
-
-static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
-{
- struct usbnet *dev = netdev_priv(net);
- u8 opt = 0;
- u8 buf[1];
-
- if (wolinfo->wolopts & WAKE_PHY)
- opt |= AX_MONITOR_LINK;
- if (wolinfo->wolopts & WAKE_MAGIC)
- opt |= AX_MONITOR_MAGIC;
- if (opt != 0)
- opt |= AX_MONITOR_MODE;
-
- if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
- opt, 0, 0, &buf) < 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int ax8817x_get_eeprom_len(struct net_device *net)
-{
- return AX_EEPROM_LEN;
-}
-
-static int ax8817x_get_eeprom(struct net_device *net,
- struct ethtool_eeprom *eeprom, u8 *data)
-{
- struct usbnet *dev = netdev_priv(net);
- u16 *ebuf = (u16 *)data;
- int i;
-
- /* Crude hack to ensure that we don't overwrite memory
- * if an odd length is supplied
- */
- if (eeprom->len % 2)
- return -EINVAL;
-
- eeprom->magic = AX_EEPROM_MAGIC;
-
- /* ax8817x returns 2 bytes from eeprom on read */
- for (i=0; i < eeprom->len / 2; i++) {
- if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
- eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
- return -EINVAL;
- }
- return 0;
-}
-
-static void ax8817x_get_drvinfo (struct net_device *net,
- struct ethtool_drvinfo *info)
-{
- /* Inherit standard device info */
- usbnet_get_drvinfo(net, info);
- info->eedump_len = 0x3e;
-}
-
-static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return mii_ethtool_gset(&dev->mii,cmd);
-}
-
-static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
- struct usbnet *dev = netdev_priv(net);
-
- return mii_ethtool_sset(&dev->mii,cmd);
-}
-
-/* We need to override some ethtool_ops so we require our
- own structure so we don't interfere with other usbnet
- devices that may be connected at the same time. */
-static struct ethtool_ops ax8817x_ethtool_ops = {
- .get_drvinfo = ax8817x_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_wol = ax8817x_get_wol,
- .set_wol = ax8817x_set_wol,
- .get_eeprom_len = ax8817x_get_eeprom_len,
- .get_eeprom = ax8817x_get_eeprom,
- .get_settings = ax8817x_get_settings,
- .set_settings = ax8817x_set_settings,
-};
-
-static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret = 0;
- void *buf;
- int i;
- unsigned long gpio_bits = dev->driver_info->data;
-
- get_endpoints(dev,intf);
-
- buf = kmalloc(ETH_ALEN, GFP_KERNEL);
- if(!buf) {
- ret = -ENOMEM;
- goto out1;
- }
-
- /* Toggle the GPIOs in a manufacturer/model specific way */
- for (i = 2; i >= 0; i--) {
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
- (gpio_bits >> (i * 8)) & 0xff, 0, 0,
- buf)) < 0)
- goto out2;
- msleep(5);
- }
-
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
- dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
- goto out2;
- }
-
- /* Get the MAC address */
- memset(buf, 0, ETH_ALEN);
- if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) {
- dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
- goto out2;
- }
- memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
- /* Get the PHY id */
- if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
- dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
- goto out2;
- } else if (ret < 2) {
- /* this should always return 2 bytes */
- dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
- ret = -EIO;
- goto out2;
- }
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = ax8817x_mdio_read;
- dev->mii.mdio_write = ax8817x_mdio_write;
- dev->mii.phy_id_mask = 0x3f;
- dev->mii.reg_num_mask = 0x1f;
- dev->mii.phy_id = *((u8 *)buf + 1);
-
- dev->net->set_multicast_list = ax8817x_set_multicast;
- dev->net->ethtool_ops = &ax8817x_ethtool_ops;
-
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
- mii_nway_restart(&dev->mii);
-
- return 0;
-out2:
- kfree(buf);
-out1:
- return ret;
-}
-
-static struct ethtool_ops ax88772_ethtool_ops = {
- .get_drvinfo = ax8817x_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
- .get_wol = ax8817x_get_wol,
- .set_wol = ax8817x_set_wol,
- .get_eeprom_len = ax8817x_get_eeprom_len,
- .get_eeprom = ax8817x_get_eeprom,
- .get_settings = ax8817x_get_settings,
- .set_settings = ax8817x_set_settings,
-};
-
-static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
-{
- int ret;
- void *buf;
-
- get_endpoints(dev,intf);
-
- buf = kmalloc(6, GFP_KERNEL);
- if(!buf) {
- dbg ("Cannot allocate memory for buffer");
- ret = -ENOMEM;
- goto out1;
- }
-
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
- 0x00B0, 0, 0, buf)) < 0)
- goto out2;
-
- msleep(5);
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) {
- dbg("Select PHY #1 failed: %d", ret);
- goto out2;
- }
-
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, 0, 0, buf)) < 0) {
- dbg("Failed to power down internal PHY: %d", ret);
- goto out2;
- }
-
- msleep(150);
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, 0, 0, buf)) < 0) {
- dbg("Failed to perform software reset: %d", ret);
- goto out2;
- }
-
- msleep(150);
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
- dbg("Failed to set Internal/External PHY reset control: %d", ret);
- goto out2;
- }
-
- msleep(150);
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0000, 0, 0,
- buf)) < 0) {
- dbg("Failed to reset RX_CTL: %d", ret);
- goto out2;
- }
-
- /* Get the MAC address */
- memset(buf, 0, ETH_ALEN);
- if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) {
- dbg("Failed to read MAC address: %d", ret);
- goto out2;
- }
- memcpy(dev->net->dev_addr, buf, ETH_ALEN);
-
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, buf)) < 0) {
- dbg("Enabling software MII failed: %d", ret);
- goto out2;
- }
-
- if (((ret =
- ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0)
- || (*((u16 *)buf) != 0x003b)) {
- dbg("Read PHY register 2 must be 0x3b00: %d", ret);
- goto out2;
- }
-
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = ax8817x_mdio_read;
- dev->mii.mdio_write = ax8817x_mdio_write;
- dev->mii.phy_id_mask = 0xff;
- dev->mii.reg_num_mask = 0xff;
-
- /* Get the PHY id */
- if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
- dbg("Error reading PHY ID: %02x", ret);
- goto out2;
- } else if (ret < 2) {
- /* this should always return 2 bytes */
- dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
- ret);
- ret = -EIO;
- goto out2;
- }
- dev->mii.phy_id = *((u8 *)buf + 1);
-
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 0, 0, buf)) < 0) {
- dbg("Set external PHY reset pin level: %d", ret);
- goto out2;
- }
- msleep(150);
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPRL | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
- dbg("Set Internal/External PHY reset control: %d", ret);
- goto out2;
- }
- msleep(150);
-
-
- dev->net->set_multicast_list = ax8817x_set_multicast;
- dev->net->ethtool_ops = &ax88772_ethtool_ops;
-
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
- ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA);
- mii_nway_restart(&dev->mii);
-
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
- dbg("Write medium mode register: %d", ret);
- goto out2;
- }
-
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
- dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
- goto out2;
- }
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
- dbg("Failed to set hardware MII: %02x", ret);
- goto out2;
- }
-
- /* Set RX_CTL to default values with 2k buffer, and enable cactus */
- if ((ret =
- ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,
- buf)) < 0) {
- dbg("Reset RX_CTL failed: %d", ret);
- goto out2;
- }
-
- kfree(buf);
-
- return 0;
-
-out2:
- kfree(buf);
-out1:
- return ret;
-}
-
-static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
-{
- u32 *header;
- char *packet;
- struct sk_buff *ax_skb;
- u16 size;
-
- header = (u32 *) skb->data;
- le32_to_cpus(header);
- packet = (char *)(header + 1);
-
- skb_pull(skb, 4);
-
- while (skb->len > 0) {
- if ((short)(*header & 0x0000ffff) !=
- ~((short)((*header & 0xffff0000) >> 16))) {
- devdbg(dev,"header length data is error");
- }
- /* get the packet length */
- size = (u16) (*header & 0x0000ffff);
-
- if ((skb->len) - ((size + 1) & 0xfffe) == 0)
- return 2;
- if (size > ETH_FRAME_LEN) {
- devdbg(dev,"invalid rx length %d", size);
- return 0;
- }
- ax_skb = skb_clone(skb, GFP_ATOMIC);
- if (ax_skb) {
- ax_skb->len = size;
- ax_skb->data = packet;
- ax_skb->tail = packet + size;
- skb_return(dev, ax_skb);
- } else {
- return 0;
- }
-
- skb_pull(skb, (size + 1) & 0xfffe);
-
- if (skb->len == 0)
- break;
-
- header = (u32 *) skb->data;
- le32_to_cpus(header);
- packet = (char *)(header + 1);
- skb_pull(skb, 4);
- }
-
- if (skb->len < 0) {
- devdbg(dev,"invalid rx length %d", skb->len);
- return 0;
- }
- return 1;
-}
-
-static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
- int flags)
-{
- int padlen;
- int headroom = skb_headroom(skb);
- int tailroom = skb_tailroom(skb);
- u32 *packet_len;
- u32 *padbytes_ptr;
-
- padlen = ((skb->len + 4) % 512) ? 0 : 4;
-
- if ((!skb_cloned(skb))
- && ((headroom + tailroom) >= (4 + padlen))) {
- if ((headroom < 4) || (tailroom < padlen)) {
- skb->data = memmove(skb->head + 4, skb->data, skb->len);
- skb->tail = skb->data + skb->len;
- }
- } else {
- struct sk_buff *skb2;
- skb2 = skb_copy_expand(skb, 4, padlen, flags);
- dev_kfree_skb_any(skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- packet_len = (u32 *) skb_push(skb, 4);
-
- packet_len = (u32 *) skb->data;
- *packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
-
- if ((skb->len % 512) == 0) {
- padbytes_ptr = (u32 *) skb->tail;
- *padbytes_ptr = 0xffff0000;
- skb_put(skb, padlen);
- }
- return skb;
-}
-
-static int ax88772_link_reset(struct usbnet *dev)
-{
- u16 lpa;
- u16 mode;
-
- mode = AX88772_MEDIUM_DEFAULT;
- lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
-
- if ((lpa & LPA_DUPLEX) == 0)
- mode &= ~AX88772_MEDIUM_FULL_DUPLEX;
- if ((lpa & LPA_100) == 0)
- mode &= ~AX88772_MEDIUM_100MB;
- ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
-
- return 0;
-}
-
-static const struct driver_info ax8817x_info = {
- .description = "ASIX AX8817x USB 2.0 Ethernet",
- .bind = ax8817x_bind,
- .status = ax8817x_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
- .data = 0x00130103,
-};
-
-static const struct driver_info dlink_dub_e100_info = {
- .description = "DLink DUB-E100 USB Ethernet",
- .bind = ax8817x_bind,
- .status = ax8817x_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
- .data = 0x009f9d9f,
-};
-
-static const struct driver_info netgear_fa120_info = {
- .description = "Netgear FA-120 USB Ethernet",
- .bind = ax8817x_bind,
- .status = ax8817x_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
- .data = 0x00130103,
-};
-
-static const struct driver_info hawking_uf200_info = {
- .description = "Hawking UF200 USB Ethernet",
- .bind = ax8817x_bind,
- .status = ax8817x_status,
- .link_reset = ax88172_link_reset,
- .reset = ax88172_link_reset,
- .flags = FLAG_ETHER,
- .data = 0x001f1d1f,
-};
-
-static const struct driver_info ax88772_info = {
- .description = "ASIX AX88772 USB 2.0 Ethernet",
- .bind = ax88772_bind,
- .status = ax8817x_status,
- .link_reset = ax88772_link_reset,
- .reset = ax88772_link_reset,
- .flags = FLAG_ETHER | FLAG_FRAMING_AX,
- .rx_fixup = ax88772_rx_fixup,
- .tx_fixup = ax88772_tx_fixup,
- .data = 0x00130103,
-};
-
-#endif /* CONFIG_USB_AX8817X */
-
-
-
-#ifdef CONFIG_USB_BELKIN
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Belkin F5U104 ... two NetChip 2280 devices + Atmel microcontroller
- *
- * ... also two eTEK designs, including one sold as "Advance USBNET"
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info belkin_info = {
- .description = "Belkin, eTEK, or compatible",
-};
-
-#endif /* CONFIG_USB_BELKIN */
-
-
-
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class declarations.
- * Used by CDC Ethernet, and some CDC variants
- *
- *-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_USB_CDCETHER
-#define NEED_GENERIC_CDC
-#endif
-
-#ifdef CONFIG_USB_ZAURUS
-/* Ethernet variant uses funky framing, broken ethernet addressing */
-#define NEED_GENERIC_CDC
-#endif
-
-#ifdef CONFIG_USB_RNDIS
-/* ACM variant uses even funkier framing, complex control RPC scheme */
-#define NEED_GENERIC_CDC
-#endif
-
-
-#ifdef NEED_GENERIC_CDC
-
-#include <linux/usb_cdc.h>
-
-struct cdc_state {
- struct usb_cdc_header_desc *header;
- struct usb_cdc_union_desc *u;
- struct usb_cdc_ether_desc *ether;
- struct usb_interface *control;
- struct usb_interface *data;
-};
-
-static struct usb_driver usbnet_driver;
-
-/*
- * probes control interface, claims data interface, collects the bulk
- * endpoints, activates data interface (if needed), maybe sets MTU.
- * all pure cdc, except for certain firmware workarounds.
- */
-static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
-{
- u8 *buf = intf->cur_altsetting->extra;
- int len = intf->cur_altsetting->extralen;
- struct usb_interface_descriptor *d;
- struct cdc_state *info = (void *) &dev->data;
- int status;
- int rndis;
-
- if (sizeof dev->data < sizeof *info)
- return -EDOM;
-
- /* expect strict spec conformance for the descriptors, but
- * cope with firmware which stores them in the wrong place
- */
- if (len == 0 && dev->udev->actconfig->extralen) {
- /* Motorola SB4100 (and others: Brad Hards says it's
- * from a Broadcom design) put CDC descriptors here
- */
- buf = dev->udev->actconfig->extra;
- len = dev->udev->actconfig->extralen;
- if (len)
- dev_dbg (&intf->dev,
- "CDC descriptors on config\n");
- }
-
- /* this assumes that if there's a non-RNDIS vendor variant
- * of cdc-acm, it'll fail RNDIS requests cleanly.
- */
- rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
-
- memset (info, 0, sizeof *info);
- info->control = intf;
- while (len > 3) {
- if (buf [1] != USB_DT_CS_INTERFACE)
- goto next_desc;
-
- /* use bDescriptorSubType to identify the CDC descriptors.
- * We expect devices with CDC header and union descriptors.
- * For CDC Ethernet we need the ethernet descriptor.
- * For RNDIS, ignore two (pointless) CDC modem descriptors
- * in favor of a complicated OID-based RPC scheme doing what
- * CDC Ethernet achieves with a simple descriptor.
- */
- switch (buf [2]) {
- case USB_CDC_HEADER_TYPE:
- if (info->header) {
- dev_dbg (&intf->dev, "extra CDC header\n");
- goto bad_desc;
- }
- info->header = (void *) buf;
- if (info->header->bLength != sizeof *info->header) {
- dev_dbg (&intf->dev, "CDC header len %u\n",
- info->header->bLength);
- goto bad_desc;
- }
- break;
- case USB_CDC_UNION_TYPE:
- if (info->u) {
- dev_dbg (&intf->dev, "extra CDC union\n");
- goto bad_desc;
- }
- info->u = (void *) buf;
- if (info->u->bLength != sizeof *info->u) {
- dev_dbg (&intf->dev, "CDC union len %u\n",
- info->u->bLength);
- goto bad_desc;
- }
-
- /* we need a master/control interface (what we're
- * probed with) and a slave/data interface; union
- * descriptors sort this all out.
- */
- info->control = usb_ifnum_to_if(dev->udev,
- info->u->bMasterInterface0);
- info->data = usb_ifnum_to_if(dev->udev,
- info->u->bSlaveInterface0);
- if (!info->control || !info->data) {
- dev_dbg (&intf->dev,
- "master #%u/%p slave #%u/%p\n",
- info->u->bMasterInterface0,
- info->control,
- info->u->bSlaveInterface0,
- info->data);
- goto bad_desc;
- }
- if (info->control != intf) {
- dev_dbg (&intf->dev, "bogus CDC Union\n");
- /* Ambit USB Cable Modem (and maybe others)
- * interchanges master and slave interface.
- */
- if (info->data == intf) {
- info->data = info->control;
- info->control = intf;
- } else
- goto bad_desc;
- }
-
- /* a data interface altsetting does the real i/o */
- d = &info->data->cur_altsetting->desc;
- if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
- dev_dbg (&intf->dev, "slave class %u\n",
- d->bInterfaceClass);
- goto bad_desc;
- }
- break;
- case USB_CDC_ETHERNET_TYPE:
- if (info->ether) {
- dev_dbg (&intf->dev, "extra CDC ether\n");
- goto bad_desc;
- }
- info->ether = (void *) buf;
- if (info->ether->bLength != sizeof *info->ether) {
- dev_dbg (&intf->dev, "CDC ether len %u\n",
- info->ether->bLength);
- goto bad_desc;
- }
- dev->net->mtu = le16_to_cpup (
- &info->ether->wMaxSegmentSize)
- - ETH_HLEN;
- /* because of Zaurus, we may be ignoring the host
- * side link address we were given.
- */
- break;
- }
-next_desc:
- len -= buf [0]; /* bLength */
- buf += buf [0];
- }
-
- if (!info->header || !info->u || (!rndis && !info->ether)) {
- dev_dbg (&intf->dev, "missing cdc %s%s%sdescriptor\n",
- info->header ? "" : "header ",
- info->u ? "" : "union ",
- info->ether ? "" : "ether ");
- goto bad_desc;
- }
-
- /* claim data interface and set it up ... with side effects.
- * network traffic can't flow until an altsetting is enabled.
- */
- status = usb_driver_claim_interface (&usbnet_driver, info->data, dev);
- if (status < 0)
- return status;
- status = get_endpoints (dev, info->data);
- if (status < 0) {
- /* ensure immediate exit from usbnet_disconnect */
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface (&usbnet_driver, info->data);
- return status;
- }
-
- /* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
- dev->status = NULL;
- if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
- struct usb_endpoint_descriptor *desc;
-
- dev->status = &info->control->cur_altsetting->endpoint [0];
- desc = &dev->status->desc;
- if (desc->bmAttributes != USB_ENDPOINT_XFER_INT
- || !(desc->bEndpointAddress & USB_DIR_IN)
- || (le16_to_cpu(desc->wMaxPacketSize)
- < sizeof (struct usb_cdc_notification))
- || !desc->bInterval) {
- dev_dbg (&intf->dev, "bad notification endpoint\n");
- dev->status = NULL;
- }
- }
- if (rndis && !dev->status) {
- dev_dbg (&intf->dev, "missing RNDIS status endpoint\n");
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface (&usbnet_driver, info->data);
- return -ENODEV;
- }
- return 0;
-
-bad_desc:
- dev_info (&dev->udev->dev, "bad CDC descriptors\n");
- return -ENODEV;
-}
-
-static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
-{
- struct cdc_state *info = (void *) &dev->data;
-
- /* disconnect master --> disconnect slave */
- if (intf == info->control && info->data) {
- /* ensure immediate exit from usbnet_disconnect */
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface (&usbnet_driver, info->data);
- info->data = NULL;
- }
-
- /* and vice versa (just in case) */
- else if (intf == info->data && info->control) {
- /* ensure immediate exit from usbnet_disconnect */
- usb_set_intfdata(info->control, NULL);
- usb_driver_release_interface (&usbnet_driver, info->control);
- info->control = NULL;
- }
-}
-
-#endif /* NEED_GENERIC_CDC */
-
-
-#ifdef CONFIG_USB_CDCETHER
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Communications Device Class, Ethernet Control model
- *
- * Takes two interfaces. The DATA interface is inactive till an altsetting
- * is selected. Configuration data includes class descriptors.
- *
- * This should interop with whatever the 2.4 "CDCEther.c" driver
- * (by Brad Hards) talked with.
- *
- *-------------------------------------------------------------------------*/
-
-#include <linux/ctype.h>
-
-
-static void dumpspeed (struct usbnet *dev, __le32 *speeds)
-{
- if (netif_msg_timer (dev))
- devinfo (dev, "link speeds: %u kbps up, %u kbps down",
- __le32_to_cpu(speeds[0]) / 1000,
- __le32_to_cpu(speeds[1]) / 1000);
-}
-
-static void cdc_status (struct usbnet *dev, struct urb *urb)
-{
- struct usb_cdc_notification *event;
-
- if (urb->actual_length < sizeof *event)
- return;
-
- /* SPEED_CHANGE can get split into two 8-byte packets */
- if (test_and_clear_bit (EVENT_STS_SPLIT, &dev->flags)) {
- dumpspeed (dev, (__le32 *) urb->transfer_buffer);
- return;
- }
-
- event = urb->transfer_buffer;
- switch (event->bNotificationType) {
- case USB_CDC_NOTIFY_NETWORK_CONNECTION:
- if (netif_msg_timer (dev))
- devdbg (dev, "CDC: carrier %s",
- event->wValue ? "on" : "off");
- if (event->wValue)
- netif_carrier_on(dev->net);
- else
- netif_carrier_off(dev->net);
- break;
- case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */
- if (netif_msg_timer (dev))
- devdbg (dev, "CDC: speed change (len %d)",
- urb->actual_length);
- if (urb->actual_length != (sizeof *event + 8))
- set_bit (EVENT_STS_SPLIT, &dev->flags);
- else
- dumpspeed (dev, (__le32 *) &event[1]);
- break;
- // case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: /* RNDIS; or unsolicited */
- default:
- deverr (dev, "CDC: unexpected notification %02x!",
- event->bNotificationType);
- break;
- }
-}
-
-static u8 nibble (unsigned char c)
-{
- if (likely (isdigit (c)))
- return c - '0';
- c = toupper (c);
- if (likely (isxdigit (c)))
- return 10 + c - 'A';
- return 0;
-}
-
-static inline int
-get_ethernet_addr (struct usbnet *dev, struct usb_cdc_ether_desc *e)
-{
- int tmp, i;
- unsigned char buf [13];
-
- tmp = usb_string (dev->udev, e->iMACAddress, buf, sizeof buf);
- if (tmp != 12) {
- dev_dbg (&dev->udev->dev,
- "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
- if (tmp >= 0)
- tmp = -EINVAL;
- return tmp;
- }
- for (i = tmp = 0; i < 6; i++, tmp += 2)
- dev->net->dev_addr [i] =
- (nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]);
- return 0;
-}
-
-static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
-{
- int status;
- struct cdc_state *info = (void *) &dev->data;
-
- status = generic_cdc_bind (dev, intf);
- if (status < 0)
- return status;
-
- status = get_ethernet_addr (dev, info->ether);
- if (status < 0) {
- usb_set_intfdata(info->data, NULL);
- usb_driver_release_interface (&usbnet_driver, info->data);
- return status;
- }
-
- /* FIXME cdc-ether has some multicast code too, though it complains
- * in routine cases. info->ether describes the multicast support.
- */
- return 0;
-}
-
-static const struct driver_info cdc_info = {
- .description = "CDC Ethernet Device",
- .flags = FLAG_ETHER,
- // .check_connect = cdc_check_connect,
- .bind = cdc_bind,
- .unbind = cdc_unbind,
- .status = cdc_status,
-};
-
-#endif /* CONFIG_USB_CDCETHER */
-
-
-
-#ifdef CONFIG_USB_EPSON2888
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * EPSON USB clients
- *
- * This is the same idea as Linux PDAs (below) except the firmware in the
- * device might not be Tux-powered. Epson provides reference firmware that
- * implements this interface. Product developers can reuse or modify that
- * code, such as by using their own product and vendor codes.
- *
- * Support was from Juro Bystricky <bystricky.juro@erd.epson.com>
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info epson2888_info = {
- .description = "Epson USB Device",
- .check_connect = always_connected,
-
- .in = 4, .out = 3,
-};
-
-#endif /* CONFIG_USB_EPSON2888 */
-
-
-#ifdef CONFIG_USB_GENESYS
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * GeneSys GL620USB-A (www.genesyslogic.com.tw)
- *
- * ... should partially interop with the Win32 driver for this hardware
- * The GeneSys docs imply there's some NDIS issue motivating this framing.
- *
- * Some info from GeneSys:
- * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
- * (Some cables, like the BAFO-100c, use the half duplex version.)
- * - For the full duplex model, the low bit of the version code says
- * which side is which ("left/right").
- * - For the half duplex type, a control/interrupt handshake settles
- * the transfer direction. (That's disabled here, partially coded.)
- * A control URB would block until other side writes an interrupt.
- *
- * Original code from Jiun-Jie Huang <huangjj@genesyslogic.com.tw>
- * and merged into "usbnet" by Stanislav Brabec <utx@penguin.cz>.
- *
- *-------------------------------------------------------------------------*/
-
-// control msg write command
-#define GENELINK_CONNECT_WRITE 0xF0
-// interrupt pipe index
-#define GENELINK_INTERRUPT_PIPE 0x03
-// interrupt read buffer size
-#define INTERRUPT_BUFSIZE 0x08
-// interrupt pipe interval value
-#define GENELINK_INTERRUPT_INTERVAL 0x10
-// max transmit packet number per transmit
-#define GL_MAX_TRANSMIT_PACKETS 32
-// max packet length
-#define GL_MAX_PACKET_LEN 1514
-// max receive buffer size
-#define GL_RCV_BUF_SIZE \
- (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
-
-struct gl_packet {
- u32 packet_length;
- char packet_data [1];
-};
-
-struct gl_header {
- u32 packet_count;
- struct gl_packet packets;
-};
-
-#ifdef GENELINK_ACK
-
-// FIXME: this code is incomplete, not debugged; it doesn't
-// handle interrupts correctly. interrupts should be generic
-// code like all other device I/O, anyway.
-
-struct gl_priv {
- struct urb *irq_urb;
- char irq_buf [INTERRUPT_BUFSIZE];
-};
-
-static inline int gl_control_write (struct usbnet *dev, u8 request, u16 value)
-{
- int retval;
-
- retval = usb_control_msg (dev->udev,
- usb_sndctrlpipe (dev->udev, 0),
- request,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- value,
- 0, // index
- 0, // data buffer
- 0, // size
- CONTROL_TIMEOUT_MS);
- return retval;
-}
-
-static void gl_interrupt_complete (struct urb *urb, struct pt_regs *regs)
-{
- int status = urb->status;
-
- switch (status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- }
-
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, status);
-}
-
-static int gl_interrupt_read (struct usbnet *dev)
-{
- struct gl_priv *priv = dev->priv_data;
- int retval;
-
- // issue usb interrupt read
- if (priv && priv->irq_urb) {
- // submit urb
- if ((retval = usb_submit_urb (priv->irq_urb, GFP_KERNEL)) != 0)
- dbg ("gl_interrupt_read: submit fail - %X...", retval);
- else
- dbg ("gl_interrupt_read: submit success...");
- }
-
- return 0;
-}
-
-// check whether another side is connected
-static int genelink_check_connect (struct usbnet *dev)
-{
- int retval;
-
- dbg ("genelink_check_connect...");
-
- // detect whether another side is connected
- if ((retval = gl_control_write (dev, GENELINK_CONNECT_WRITE, 0)) != 0) {
- dbg ("%s: genelink_check_connect write fail - %X",
- dev->net->name, retval);
- return retval;
- }
-
- // usb interrupt read to ack another side
- if ((retval = gl_interrupt_read (dev)) != 0) {
- dbg ("%s: genelink_check_connect read fail - %X",
- dev->net->name, retval);
- return retval;
- }
-
- dbg ("%s: genelink_check_connect read success", dev->net->name);
- return 0;
-}
-
-// allocate and initialize the private data for genelink
-static int genelink_init (struct usbnet *dev)
-{
- struct gl_priv *priv;
-
- // allocate the private data structure
- if ((priv = kmalloc (sizeof *priv, GFP_KERNEL)) == 0) {
- dbg ("%s: cannot allocate private data per device",
- dev->net->name);
- return -ENOMEM;
- }
-
- // allocate irq urb
- if ((priv->irq_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
- dbg ("%s: cannot allocate private irq urb per device",
- dev->net->name);
- kfree (priv);
- return -ENOMEM;
- }
-
- // fill irq urb
- usb_fill_int_urb (priv->irq_urb, dev->udev,
- usb_rcvintpipe (dev->udev, GENELINK_INTERRUPT_PIPE),
- priv->irq_buf, INTERRUPT_BUFSIZE,
- gl_interrupt_complete, 0,
- GENELINK_INTERRUPT_INTERVAL);
-
- // set private data pointer
- dev->priv_data = priv;
-
- return 0;
-}
-
-// release the private data
-static int genelink_free (struct usbnet *dev)
-{
- struct gl_priv *priv = dev->priv_data;
-
- if (!priv)
- return 0;
-
-// FIXME: can't cancel here; it's synchronous, and
-// should have happened earlier in any case (interrupt
-// handling needs to be generic)
-
- // cancel irq urb first
- usb_kill_urb (priv->irq_urb);
-
- // free irq urb
- usb_free_urb (priv->irq_urb);
-
- // free the private data structure
- kfree (priv);
-
- return 0;
-}
-
-#endif
-
-static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
-{
- struct gl_header *header;
- struct gl_packet *packet;
- struct sk_buff *gl_skb;
- u32 size;
-
- header = (struct gl_header *) skb->data;
-
- // get the packet count of the received skb
- le32_to_cpus (&header->packet_count);
- if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS)
- || (header->packet_count < 0)) {
- dbg ("genelink: invalid received packet count %d",
- header->packet_count);
- return 0;
- }
-
- // set the current packet pointer to the first packet
- packet = &header->packets;
-
- // decrement the length for the packet count size 4 bytes
- skb_pull (skb, 4);
-
- while (header->packet_count > 1) {
- // get the packet length
- size = packet->packet_length;
-
- // this may be a broken packet
- if (size > GL_MAX_PACKET_LEN) {
- dbg ("genelink: invalid rx length %d", size);
- return 0;
- }
-
- // allocate the skb for the individual packet
- gl_skb = alloc_skb (size, GFP_ATOMIC);
- if (gl_skb) {
-
- // copy the packet data to the new skb
- memcpy(skb_put(gl_skb, size), packet->packet_data, size);
- skb_return (dev, gl_skb);
- }
-
- // advance to the next packet
- packet = (struct gl_packet *)
- &packet->packet_data [size];
- header->packet_count--;
-
- // shift the data pointer to the next gl_packet
- skb_pull (skb, size + 4);
- }
-
- // skip the packet length field 4 bytes
- skb_pull (skb, 4);
-
- if (skb->len > GL_MAX_PACKET_LEN) {
- dbg ("genelink: invalid rx length %d", skb->len);
- return 0;
- }
- return 1;
-}
-
-static struct sk_buff *
-genelink_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
- int padlen;
- int length = skb->len;
- int headroom = skb_headroom (skb);
- int tailroom = skb_tailroom (skb);
- u32 *packet_count;
- u32 *packet_len;
-
- // FIXME: magic numbers, bleech
- padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
-
- if ((!skb_cloned (skb))
- && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
- if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
- skb->data = memmove (skb->head + (4 + 4*1),
- skb->data, skb->len);
- skb->tail = skb->data + skb->len;
- }
- } else {
- struct sk_buff *skb2;
- skb2 = skb_copy_expand (skb, (4 + 4*1) , padlen, flags);
- dev_kfree_skb_any (skb);
- skb = skb2;
- if (!skb)
- return NULL;
- }
-
- // attach the packet count to the header
- packet_count = (u32 *) skb_push (skb, (4 + 4*1));
- packet_len = packet_count + 1;
-
- // FIXME little endian?
- *packet_count = 1;
- *packet_len = length;
-
- // add padding byte
- if ((skb->len % dev->maxpacket) == 0)
- skb_put (skb, 1);
-
- return skb;
-}
-
-static const struct driver_info genelink_info = {
- .description = "Genesys GeneLink",
- .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT,
- .rx_fixup = genelink_rx_fixup,
- .tx_fixup = genelink_tx_fixup,
-
- .in = 1, .out = 2,
-
-#ifdef GENELINK_ACK
- .check_connect =genelink_check_connect,
-#endif
-};
-
-#endif /* CONFIG_USB_GENESYS */
-
-
-
-#ifdef CONFIG_USB_NET1080
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Netchip 1080 driver ... http://www.netchip.com
- * Used in LapLink cables
- *
- *-------------------------------------------------------------------------*/
-
-#define dev_packet_id data[0]
-#define frame_errors data[1]
-
-/*
- * NetChip framing of ethernet packets, supporting additional error
- * checks for links that may drop bulk packets from inside messages.
- * Odd USB length == always short read for last usb packet.
- * - nc_header
- * - Ethernet header (14 bytes)
- * - payload
- * - (optional padding byte, if needed so length becomes odd)
- * - nc_trailer
- *
- * This framing is to be avoided for non-NetChip devices.
- */
-
-struct nc_header { // packed:
- __le16 hdr_len; // sizeof nc_header (LE, all)
- __le16 packet_len; // payload size (including ethhdr)
- __le16 packet_id; // detects dropped packets
-#define MIN_HEADER 6
-
- // all else is optional, and must start with:
- // u16 vendorId; // from usb-if
- // u16 productId;
-} __attribute__((__packed__));
-
-#define PAD_BYTE ((unsigned char)0xAC)
-
-struct nc_trailer {
- __le16 packet_id;
-} __attribute__((__packed__));
-
-// packets may use FLAG_FRAMING_NC and optional pad
-#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \
- + sizeof (struct ethhdr) \
- + (mtu) \
- + 1 \
- + sizeof (struct nc_trailer))
-
-#define MIN_FRAMED FRAMED_SIZE(0)
-
-
-/*
- * Zero means no timeout; else, how long a 64 byte bulk packet may be queued
- * before the hardware drops it. If that's done, the driver will need to
- * frame network packets to guard against the dropped USB packets. The win32
- * driver sets this for both sides of the link.
- */
-#define NC_READ_TTL_MS ((u8)255) // ms
-
-/*
- * We ignore most registers and EEPROM contents.
- */
-#define REG_USBCTL ((u8)0x04)
-#define REG_TTL ((u8)0x10)
-#define REG_STATUS ((u8)0x11)
-
-/*
- * Vendor specific requests to read/write data
- */
-#define REQUEST_REGISTER ((u8)0x10)
-#define REQUEST_EEPROM ((u8)0x11)
-
-static int
-nc_vendor_read (struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr)
-{
- int status = usb_control_msg (dev->udev,
- usb_rcvctrlpipe (dev->udev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, regnum,
- retval_ptr, sizeof *retval_ptr,
- CONTROL_TIMEOUT_MS);
- if (status > 0)
- status = 0;
- if (!status)
- le16_to_cpus (retval_ptr);
- return status;
-}
-
-static inline int
-nc_register_read (struct usbnet *dev, u8 regnum, u16 *retval_ptr)
-{
- return nc_vendor_read (dev, REQUEST_REGISTER, regnum, retval_ptr);
-}
-
-// no retval ... can become async, usable in_interrupt()
-static void
-nc_vendor_write (struct usbnet *dev, u8 req, u8 regnum, u16 value)
-{
- usb_control_msg (dev->udev,
- usb_sndctrlpipe (dev->udev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, regnum,
- NULL, 0, // data is in setup packet
- CONTROL_TIMEOUT_MS);
-}
-
-static inline void
-nc_register_write (struct usbnet *dev, u8 regnum, u16 value)
-{
- nc_vendor_write (dev, REQUEST_REGISTER, regnum, value);
-}
-
-
-#if 0
-static void nc_dump_registers (struct usbnet *dev)
-{
- u8 reg;
- u16 *vp = kmalloc (sizeof (u16));
-
- if (!vp) {
- dbg ("no memory?");
- return;
- }
-
- dbg ("%s registers:", dev->net->name);
- for (reg = 0; reg < 0x20; reg++) {
- int retval;
-
- // reading some registers is trouble
- if (reg >= 0x08 && reg <= 0xf)
- continue;
- if (reg >= 0x12 && reg <= 0x1e)
- continue;
-
- retval = nc_register_read (dev, reg, vp);
- if (retval < 0)
- dbg ("%s reg [0x%x] ==> error %d",
- dev->net->name, reg, retval);
- else
- dbg ("%s reg [0x%x] = 0x%x",
- dev->net->name, reg, *vp);
- }
- kfree (vp);
-}
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Control register
- */
-
-#define USBCTL_WRITABLE_MASK 0x1f0f
-// bits 15-13 reserved, r/o
-#define USBCTL_ENABLE_LANG (1 << 12)
-#define USBCTL_ENABLE_MFGR (1 << 11)
-#define USBCTL_ENABLE_PROD (1 << 10)
-#define USBCTL_ENABLE_SERIAL (1 << 9)
-#define USBCTL_ENABLE_DEFAULTS (1 << 8)
-// bits 7-4 reserved, r/o
-#define USBCTL_FLUSH_OTHER (1 << 3)
-#define USBCTL_FLUSH_THIS (1 << 2)
-#define USBCTL_DISCONN_OTHER (1 << 1)
-#define USBCTL_DISCONN_THIS (1 << 0)
-
-static inline void nc_dump_usbctl (struct usbnet *dev, u16 usbctl)
-{
- if (!netif_msg_link (dev))
- return;
- devdbg (dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
- " this%s%s;"
- " other%s%s; r/o 0x%x",
- dev->udev->bus->bus_name, dev->udev->devpath,
- usbctl,
- (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
- (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
- (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
- (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
- (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
-
- (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
- (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
- (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
- (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
- usbctl & ~USBCTL_WRITABLE_MASK
- );
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Status register
- */
-
-#define STATUS_PORT_A (1 << 15)
-
-#define STATUS_CONN_OTHER (1 << 14)
-#define STATUS_SUSPEND_OTHER (1 << 13)
-#define STATUS_MAILBOX_OTHER (1 << 12)
-#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
-
-#define STATUS_CONN_THIS (1 << 6)
-#define STATUS_SUSPEND_THIS (1 << 5)
-#define STATUS_MAILBOX_THIS (1 << 4)
-#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
-
-#define STATUS_UNSPEC_MASK 0x0c8c
-#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
-
-
-static inline void nc_dump_status (struct usbnet *dev, u16 status)
-{
- if (!netif_msg_link (dev))
- return;
- devdbg (dev, "net1080 %s-%s status 0x%x:"
- " this (%c) PKT=%d%s%s%s;"
- " other PKT=%d%s%s%s; unspec 0x%x",
- dev->udev->bus->bus_name, dev->udev->devpath,
- status,
-
- // XXX the packet counts don't seem right
- // (1 at reset, not 0); maybe UNSPEC too
-
- (status & STATUS_PORT_A) ? 'A' : 'B',
- STATUS_PACKETS_THIS (status),
- (status & STATUS_CONN_THIS) ? " CON" : "",
- (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
- (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
-
- STATUS_PACKETS_OTHER (status),
- (status & STATUS_CONN_OTHER) ? " CON" : "",
- (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
- (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
-
- status & STATUS_UNSPEC_MASK
- );
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * TTL register
- */
-
-#define TTL_THIS(ttl) (0x00ff & ttl)
-#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
-#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
-
-static inline void nc_dump_ttl (struct usbnet *dev, u16 ttl)
-{
- if (netif_msg_link (dev))
- devdbg (dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
- dev->udev->bus->bus_name, dev->udev->devpath,
- ttl, TTL_THIS (ttl), TTL_OTHER (ttl));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int net1080_reset (struct usbnet *dev)
-{
- u16 usbctl, status, ttl;
- u16 *vp = kmalloc (sizeof (u16), GFP_KERNEL);
- int retval;
-
- if (!vp)
- return -ENOMEM;
-
- // nc_dump_registers (dev);
-
- if ((retval = nc_register_read (dev, REG_STATUS, vp)) < 0) {
- dbg ("can't read %s-%s status: %d",
- dev->udev->bus->bus_name, dev->udev->devpath, retval);
- goto done;
- }
- status = *vp;
- nc_dump_status (dev, status);
-
- if ((retval = nc_register_read (dev, REG_USBCTL, vp)) < 0) {
- dbg ("can't read USBCTL, %d", retval);
- goto done;
- }
- usbctl = *vp;
- nc_dump_usbctl (dev, usbctl);
-
- nc_register_write (dev, REG_USBCTL,
- USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
-
- if ((retval = nc_register_read (dev, REG_TTL, vp)) < 0) {
- dbg ("can't read TTL, %d", retval);
- goto done;
- }
- ttl = *vp;
- // nc_dump_ttl (dev, ttl);
-
- nc_register_write (dev, REG_TTL,
- MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) );
- dbg ("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS);
-
- if (netif_msg_link (dev))
- devinfo (dev, "port %c, peer %sconnected",
- (status & STATUS_PORT_A) ? 'A' : 'B',
- (status & STATUS_CONN_OTHER) ? "" : "dis"
- );
- retval = 0;
-
-done:
- kfree (vp);
- return retval;
-}
-
-static int net1080_check_connect (struct usbnet *dev)
-{
- int retval;
- u16 status;
- u16 *vp = kmalloc (sizeof (u16), GFP_KERNEL);
-
- if (!vp)
- return -ENOMEM;
- retval = nc_register_read (dev, REG_STATUS, vp);
- status = *vp;
- kfree (vp);
- if (retval != 0) {
- dbg ("%s net1080_check_conn read - %d", dev->net->name, retval);
- return retval;
- }
- if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER)
- return -ENOLINK;
- return 0;
-}
-
-static void nc_flush_complete (struct urb *urb, struct pt_regs *regs)
-{
- kfree (urb->context);
- usb_free_urb(urb);
-}
-
-static void nc_ensure_sync (struct usbnet *dev)
-{
- dev->frame_errors++;
- if (dev->frame_errors > 5) {
- struct urb *urb;
- struct usb_ctrlrequest *req;
- int status;
-
- /* Send a flush */
- urb = usb_alloc_urb (0, SLAB_ATOMIC);
- if (!urb)
- return;
-
- req = kmalloc (sizeof *req, GFP_ATOMIC);
- if (!req) {
- usb_free_urb (urb);
- return;
- }
-
- req->bRequestType = USB_DIR_OUT
- | USB_TYPE_VENDOR
- | USB_RECIP_DEVICE;
- req->bRequest = REQUEST_REGISTER;
- req->wValue = cpu_to_le16 (USBCTL_FLUSH_THIS
- | USBCTL_FLUSH_OTHER);
- req->wIndex = cpu_to_le16 (REG_USBCTL);
- req->wLength = cpu_to_le16 (0);
-
- /* queue an async control request, we don't need
- * to do anything when it finishes except clean up.
- */
- usb_fill_control_urb (urb, dev->udev,
- usb_sndctrlpipe (dev->udev, 0),
- (unsigned char *) req,
- NULL, 0,
- nc_flush_complete, req);
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status) {
- kfree (req);
- usb_free_urb (urb);
- return;
- }
-
- if (netif_msg_rx_err (dev))
- devdbg (dev, "flush net1080; too many framing errors");
- dev->frame_errors = 0;
- }
-}
-
-static int net1080_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
-{
- struct nc_header *header;
- struct nc_trailer *trailer;
- u16 hdr_len, packet_len;
-
- if (!(skb->len & 0x01)
- || MIN_FRAMED > skb->len
- || skb->len > FRAMED_SIZE (dev->net->mtu)) {
- dev->stats.rx_frame_errors++;
- dbg ("rx framesize %d range %d..%d mtu %d", skb->len,
- (int)MIN_FRAMED, (int)FRAMED_SIZE (dev->net->mtu),
- dev->net->mtu);
- nc_ensure_sync (dev);
- return 0;
- }
-
- header = (struct nc_header *) skb->data;
- hdr_len = le16_to_cpup (&header->hdr_len);
- packet_len = le16_to_cpup (&header->packet_len);
- if (FRAMED_SIZE (packet_len) > MAX_PACKET) {
- dev->stats.rx_frame_errors++;
- dbg ("packet too big, %d", packet_len);
- nc_ensure_sync (dev);
- return 0;
- } else if (hdr_len < MIN_HEADER) {
- dev->stats.rx_frame_errors++;
- dbg ("header too short, %d", hdr_len);
- nc_ensure_sync (dev);
- return 0;
- } else if (hdr_len > MIN_HEADER) {
- // out of band data for us?
- dbg ("header OOB, %d bytes", hdr_len - MIN_HEADER);
- nc_ensure_sync (dev);
- // switch (vendor/product ids) { ... }
- }
- skb_pull (skb, hdr_len);
-
- trailer = (struct nc_trailer *)
- (skb->data + skb->len - sizeof *trailer);
- skb_trim (skb, skb->len - sizeof *trailer);
-
- if ((packet_len & 0x01) == 0) {
- if (skb->data [packet_len] != PAD_BYTE) {
- dev->stats.rx_frame_errors++;
- dbg ("bad pad");
- return 0;
- }
- skb_trim (skb, skb->len - 1);
- }
- if (skb->len != packet_len) {
- dev->stats.rx_frame_errors++;
- dbg ("bad packet len %d (expected %d)",
- skb->len, packet_len);
- nc_ensure_sync (dev);
- return 0;
- }
- if (header->packet_id != get_unaligned (&trailer->packet_id)) {
- dev->stats.rx_fifo_errors++;
- dbg ("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
- le16_to_cpu (header->packet_id),
- le16_to_cpu (trailer->packet_id));
- return 0;
- }
-#if 0
- devdbg (dev, "frame <rx h %d p %d id %d", header->hdr_len,
- header->packet_len, header->packet_id);
-#endif
- dev->frame_errors = 0;
- return 1;
-}
-
-static struct sk_buff *
-net1080_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
- int padlen;
- struct sk_buff *skb2;
-
- padlen = ((skb->len + sizeof (struct nc_header)
- + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
- if (!skb_cloned (skb)) {
- int headroom = skb_headroom (skb);
- int tailroom = skb_tailroom (skb);
-
- if ((padlen + sizeof (struct nc_trailer)) <= tailroom
- && sizeof (struct nc_header) <= headroom)
- /* There's enough head and tail room */
- return skb;
-
- if ((sizeof (struct nc_header) + padlen
- + sizeof (struct nc_trailer)) <
- (headroom + tailroom)) {
- /* There's enough total room, so just readjust */
- skb->data = memmove (skb->head
- + sizeof (struct nc_header),
- skb->data, skb->len);
- skb->tail = skb->data + skb->len;
- return skb;
- }
- }
-
- /* Create a new skb to use with the correct size */
- skb2 = skb_copy_expand (skb,
- sizeof (struct nc_header),
- sizeof (struct nc_trailer) + padlen,
- flags);
- dev_kfree_skb_any (skb);
- return skb2;
-}
-
-static const struct driver_info net1080_info = {
- .description = "NetChip TurboCONNECT",
- .flags = FLAG_FRAMING_NC,
- .reset = net1080_reset,
- .check_connect =net1080_check_connect,
- .rx_fixup = net1080_rx_fixup,
- .tx_fixup = net1080_tx_fixup,
-};
-
-#endif /* CONFIG_USB_NET1080 */
-
-
-
-#ifdef CONFIG_USB_PL2301
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Prolific PL-2301/PL-2302 driver ... http://www.prolifictech.com
- *
- * The protocol and handshaking used here should be bug-compatible
- * with the Linux 2.2 "plusb" driver, by Deti Fliegl.
- *
- *-------------------------------------------------------------------------*/
-
-/*
- * Bits 0-4 can be used for software handshaking; they're set from
- * one end, cleared from the other, "read" with the interrupt byte.
- */
-#define PL_S_EN (1<<7) /* (feature only) suspend enable */
-/* reserved bit -- rx ready (6) ? */
-#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
-#define PL_RESET_OUT (1<<4) /* reset output pipe */
-#define PL_RESET_IN (1<<3) /* reset input pipe */
-#define PL_TX_C (1<<2) /* transmission complete */
-#define PL_TX_REQ (1<<1) /* transmission received */
-#define PL_PEER_E (1<<0) /* peer exists */
-
-static inline int
-pl_vendor_req (struct usbnet *dev, u8 req, u8 val, u8 index)
-{
- return usb_control_msg (dev->udev,
- usb_rcvctrlpipe (dev->udev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- val, index,
- NULL, 0,
- CONTROL_TIMEOUT_MS);
-}
-
-static inline int
-pl_clear_QuickLink_features (struct usbnet *dev, int val)
-{
- return pl_vendor_req (dev, 1, (u8) val, 0);
-}
-
-static inline int
-pl_set_QuickLink_features (struct usbnet *dev, int val)
-{
- return pl_vendor_req (dev, 3, (u8) val, 0);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int pl_reset (struct usbnet *dev)
-{
- /* some units seem to need this reset, others reject it utterly.
- * FIXME be more like "naplink" or windows drivers.
- */
- (void) pl_set_QuickLink_features (dev,
- PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
- return 0;
-}
-
-static const struct driver_info prolific_info = {
- .description = "Prolific PL-2301/PL-2302",
- .flags = FLAG_NO_SETINT,
- /* some PL-2302 versions seem to fail usb_set_interface() */
- .reset = pl_reset,
-};
-
-#endif /* CONFIG_USB_PL2301 */
-
-
-#ifdef CONFIG_USB_KC2190
-#define HAVE_HARDWARE
-static const struct driver_info kc2190_info = {
- .description = "KC Technology KC-190",
-};
-#endif /* CONFIG_USB_KC2190 */
-
-
-#ifdef CONFIG_USB_ARMLINUX
-#define HAVE_HARDWARE
-
-/*-------------------------------------------------------------------------
- *
- * Intel's SA-1100 chip integrates basic USB support, and is used
- * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more.
- * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to
- * network using minimal USB framing data.
- *
- * This describes the driver currently in standard ARM Linux kernels.
- * The Zaurus uses a different driver (see later).
- *
- * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support
- * and different USB endpoint numbering than the SA1100 devices. The
- * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100
- * so we rely on the endpoint descriptors.
- *
- *-------------------------------------------------------------------------*/
-
-static const struct driver_info linuxdev_info = {
- .description = "Linux Device",
- .check_connect = always_connected,
-};
-
-static const struct driver_info yopy_info = {
- .description = "Yopy",
- .check_connect = always_connected,
-};
-
-static const struct driver_info blob_info = {
- .description = "Boot Loader OBject",
- .check_connect = always_connected,
-};
-
-#endif /* CONFIG_USB_ARMLINUX */
-
-
-#ifdef CONFIG_USB_ZAURUS
-#define HAVE_HARDWARE
-
-#include <linux/crc32.h>
-
-/*-------------------------------------------------------------------------
- *
- * Zaurus is also a SA-1110 based PDA, but one using a different driver
- * (and framing) for its USB slave/gadget controller than the case above.
- *
- * For the current version of that driver, the main way that framing is
- * nonstandard (also from perspective of the CDC ethernet model!) is a
- * crc32, added to help detect when some sa1100 usb-to-memory DMA errata
- * haven't been fully worked around. Also, all Zaurii use the same
- * default Ethernet address.
- *
- * PXA based models use the same framing, and also can't implement
- * set_interface properly.
- *
- * All known Zaurii lie about their standards conformance. Most lie by
- * saying they support CDC Ethernet. Some lie and say they support CDC
- * MDLM (as if for access to cell phone modems). Someone, please beat
- * on Sharp (and other such vendors) for a while with a cluestick.
- *
- *-------------------------------------------------------------------------*/
-
-static struct sk_buff *
-zaurus_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags)
-{
- int padlen;
- struct sk_buff *skb2;
-
- padlen = 2;
- if (!skb_cloned (skb)) {
- int tailroom = skb_tailroom (skb);
- if ((padlen + 4) <= tailroom)
- goto done;
- }
- skb2 = skb_copy_expand (skb, 0, 4 + padlen, flags);
- dev_kfree_skb_any (skb);
- skb = skb2;
- if (skb) {
- u32 fcs;
-done:
- fcs = crc32_le (~0, skb->data, skb->len);
- fcs = ~fcs;
-
- *skb_put (skb, 1) = fcs & 0xff;
- *skb_put (skb, 1) = (fcs>> 8) & 0xff;
- *skb_put (skb, 1) = (fcs>>16) & 0xff;
- *skb_put (skb, 1) = (fcs>>24) & 0xff;
- }
- return skb;
-}
-
-static const struct driver_info zaurus_sl5x00_info = {
- .description = "Sharp Zaurus SL-5x00",
- .flags = FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = generic_cdc_bind,
- .unbind = cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
-
-static const struct driver_info zaurus_pxa_info = {
- .description = "Sharp Zaurus, PXA-2xx based",
- .flags = FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = generic_cdc_bind,
- .unbind = cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
-
-static const struct driver_info olympus_mxl_info = {
- .description = "Olympus R1000",
- .flags = FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .bind = generic_cdc_bind,
- .unbind = cdc_unbind,
- .tx_fixup = zaurus_tx_fixup,
-};
-#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
-
-
-/* Some more recent products using Lineo/Belcarra code will wrongly claim
- * CDC MDLM conformance. They aren't conformant: data endpoints live
- * in the control interface, there's no data interface, and it's not used
- * to talk to a cell phone radio. But at least we can detect these two
- * pseudo-classes, rather than growing this product list with entries for
- * each new nonconformant product (sigh).
- */
-static const u8 safe_guid[16] = {
- 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
- 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
-};
-static const u8 blan_guid[16] = {
- 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
- 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
-};
-
-static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf)
-{
- u8 *buf = intf->cur_altsetting->extra;
- int len = intf->cur_altsetting->extralen;
- struct usb_cdc_mdlm_desc *desc = NULL;
- struct usb_cdc_mdlm_detail_desc *detail = NULL;
-
- while (len > 3) {
- if (buf [1] != USB_DT_CS_INTERFACE)
- goto next_desc;
-
- /* use bDescriptorSubType, and just verify that we get a
- * "BLAN" (or "SAFE") descriptor.
- */
- switch (buf [2]) {
- case USB_CDC_MDLM_TYPE:
- if (desc) {
- dev_dbg (&intf->dev, "extra MDLM\n");
- goto bad_desc;
- }
- desc = (void *) buf;
- if (desc->bLength != sizeof *desc) {
- dev_dbg (&intf->dev, "MDLM len %u\n",
- desc->bLength);
- goto bad_desc;
- }
- /* expect bcdVersion 1.0, ignore */
- if (memcmp(&desc->bGUID, blan_guid, 16)
- && memcmp(&desc->bGUID, safe_guid, 16) ) {
- /* hey, this one might _really_ be MDLM! */
- dev_dbg (&intf->dev, "MDLM guid\n");
- goto bad_desc;
- }
- break;
- case USB_CDC_MDLM_DETAIL_TYPE:
- if (detail) {
- dev_dbg (&intf->dev, "extra MDLM detail\n");
- goto bad_desc;
- }
- detail = (void *) buf;
- switch (detail->bGuidDescriptorType) {
- case 0: /* "SAFE" */
- if (detail->bLength != (sizeof *detail + 2))
- goto bad_detail;
- break;
- case 1: /* "BLAN" */
- if (detail->bLength != (sizeof *detail + 3))
- goto bad_detail;
- break;
- default:
- goto bad_detail;
- }
-
- /* assuming we either noticed BLAN already, or will
- * find it soon, there are some data bytes here:
- * - bmNetworkCapabilities (unused)
- * - bmDataCapabilities (bits, see below)
- * - bPad (ignored, for PADAFTER -- BLAN-only)
- * bits are:
- * - 0x01 -- Zaurus framing (add CRC)
- * - 0x02 -- PADBEFORE (CRC includes some padding)
- * - 0x04 -- PADAFTER (some padding after CRC)
- * - 0x08 -- "fermat" packet mangling (for hw bugs)
- * the PADBEFORE appears not to matter; we interop
- * with devices that use it and those that don't.
- */
- if ((detail->bDetailData[1] & ~02) != 0x01) {
- /* bmDataCapabilites == 0 would be fine too,
- * but framing is minidriver-coupled for now.
- */
-bad_detail:
- dev_dbg (&intf->dev,
- "bad MDLM detail, %d %d %d\n",
- detail->bLength,
- detail->bDetailData[0],
- detail->bDetailData[2]);
- goto bad_desc;
- }
- break;
- }
-next_desc:
- len -= buf [0]; /* bLength */
- buf += buf [0];
- }
-
- if (!desc || !detail) {
- dev_dbg (&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
- desc ? "" : "func ",
- detail ? "" : "detail ");
- goto bad_desc;
- }
-
- /* There's probably a CDC Ethernet descriptor there, but we can't
- * rely on the Ethernet address it provides since not all vendors
- * bother to make it unique. Likewise there's no point in tracking
- * of the CDC event notifications.
- */
- return get_endpoints (dev, intf);
-
-bad_desc:
- dev_info (&dev->udev->dev, "unsupported MDLM descriptors\n");
- return -ENODEV;
-}
-
-static const struct driver_info bogus_mdlm_info = {
- .description = "pseudo-MDLM (BLAN) device",
- .flags = FLAG_FRAMING_Z,
- .check_connect = always_connected,
- .tx_fixup = zaurus_tx_fixup,
- .bind = blan_mdlm_bind,
-};
-
-#else
-
-/* blacklist all those devices */
-#define ZAURUS_STRONGARM_INFO 0
-#define ZAURUS_PXA_INFO 0
-#define OLYMPUS_MXL_INFO 0
-
-#endif
+EXPORT_SYMBOL_GPL(usbnet_skb_return);
/*-------------------------------------------------------------------------
@@ -2868,22 +230,12 @@ static const struct driver_info bogus_mdlm_info = {
static int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
struct usbnet *dev = netdev_priv(net);
+ int ll_mtu = new_mtu + net->hard_header_len;
- if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
+ if (new_mtu <= 0 || ll_mtu > dev->hard_mtu)
return -EINVAL;
-#ifdef CONFIG_USB_NET1080
- if (((dev->driver_info->flags) & FLAG_FRAMING_NC)) {
- if (FRAMED_SIZE (new_mtu) > MAX_PACKET)
- return -EINVAL;
- }
-#endif
-#ifdef CONFIG_USB_GENESYS
- if (((dev->driver_info->flags) & FLAG_FRAMING_GL)
- && new_mtu > GL_MAX_PACKET_LEN)
- return -EINVAL;
-#endif
// no second zero-length packet read wanted after mtu-sized packets
- if (((new_mtu + sizeof (struct ethhdr)) % dev->maxpacket) == 0)
+ if ((ll_mtu % dev->maxpacket) == 0)
return -EDOM;
net->mtu = new_mtu;
return 0;
@@ -2922,7 +274,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea
* NOTE: annoying asymmetry: if it's active, schedule_work() fails,
* but tasklet_schedule() doesn't. hope the failure is rare.
*/
-static void defer_kevent (struct usbnet *dev, int work)
+void usbnet_defer_kevent (struct usbnet *dev, int work)
{
set_bit (work, &dev->flags);
if (!schedule_work (&dev->kevent))
@@ -2930,50 +282,24 @@ static void defer_kevent (struct usbnet *dev, int work)
else
devdbg (dev, "kevent %d scheduled", work);
}
+EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
/*-------------------------------------------------------------------------*/
static void rx_complete (struct urb *urb, struct pt_regs *regs);
-static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
+static void rx_submit (struct usbnet *dev, struct urb *urb, unsigned flags)
{
struct sk_buff *skb;
struct skb_data *entry;
int retval = 0;
unsigned long lockflags;
- size_t size;
-
-#ifdef CONFIG_USB_NET1080
- if (dev->driver_info->flags & FLAG_FRAMING_NC)
- size = FRAMED_SIZE (dev->net->mtu);
- else
-#endif
-#ifdef CONFIG_USB_GENESYS
- if (dev->driver_info->flags & FLAG_FRAMING_GL)
- size = GL_RCV_BUF_SIZE;
- else
-#endif
-#ifdef CONFIG_USB_ZAURUS
- if (dev->driver_info->flags & FLAG_FRAMING_Z)
- size = 6 + (sizeof (struct ethhdr) + dev->net->mtu);
- else
-#endif
-#ifdef CONFIG_USB_RNDIS
- if (dev->driver_info->flags & FLAG_FRAMING_RN)
- size = RNDIS_MAX_TRANSFER;
- else
-#endif
-#ifdef CONFIG_USB_AX8817X
- if (dev->driver_info->flags & FLAG_FRAMING_AX)
- size = 2048;
- else
-#endif
- size = (sizeof (struct ethhdr) + dev->net->mtu);
+ size_t size = dev->rx_urb_size;
if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) {
if (netif_msg_rx_err (dev))
devdbg (dev, "no rx skb");
- defer_kevent (dev, EVENT_RX_MEMORY);
+ usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
usb_free_urb (urb);
return;
}
@@ -2987,7 +313,6 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
usb_fill_bulk_urb (urb, dev->udev, dev->in,
skb->data, size, rx_complete, skb);
- urb->transfer_flags |= URB_ASYNC_UNLINK;
spin_lock_irqsave (&dev->rxq.lock, lockflags);
@@ -2996,10 +321,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
case -EPIPE:
- defer_kevent (dev, EVENT_RX_HALT);
+ usbnet_defer_kevent (dev, EVENT_RX_HALT);
break;
case -ENOMEM:
- defer_kevent (dev, EVENT_RX_MEMORY);
+ usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
break;
case -ENODEV:
if (netif_msg_ifdown (dev))
@@ -3037,7 +362,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
// else network stack removes extra byte if we forced a short packet
if (skb->len)
- skb_return (dev, skb);
+ usbnet_skb_return (dev, skb);
else {
if (netif_msg_rx_err (dev))
devdbg (dev, "drop");
@@ -3063,7 +388,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
switch (urb_status) {
// success
case 0:
- if (MIN_PACKET > skb->len || skb->len > MAX_PACKET) {
+ if (skb->len < dev->net->hard_header_len) {
entry->state = rx_cleanup;
dev->stats.rx_errors++;
dev->stats.rx_length_errors++;
@@ -3078,7 +403,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
// storm, recovering as needed.
case -EPIPE:
dev->stats.rx_errors++;
- defer_kevent (dev, EVENT_RX_HALT);
+ usbnet_defer_kevent (dev, EVENT_RX_HALT);
// FALLTHROUGH
// software-driven interface shutdown
@@ -3320,55 +645,58 @@ done:
/*-------------------------------------------------------------------------*/
-static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+/* ethtool methods; minidrivers may need to add some more, but
+ * they'll probably want to use this base set.
+ */
+
+void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
{
struct usbnet *dev = netdev_priv(net);
+ /* REVISIT don't always return "usbnet" */
strncpy (info->driver, driver_name, sizeof info->driver);
strncpy (info->version, DRIVER_VERSION, sizeof info->version);
strncpy (info->fw_version, dev->driver_info->description,
sizeof info->fw_version);
usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
}
+EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
static u32 usbnet_get_link (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- /* If a check_connect is defined, return it's results */
+ /* If a check_connect is defined, return its result */
if (dev->driver_info->check_connect)
return dev->driver_info->check_connect (dev) == 0;
- /* Otherwise, we're up to avoid breaking scripts */
+ /* Otherwise, say we're up (to avoid breaking scripts) */
return 1;
}
-static u32 usbnet_get_msglevel (struct net_device *net)
+u32 usbnet_get_msglevel (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
return dev->msg_enable;
}
+EXPORT_SYMBOL_GPL(usbnet_get_msglevel);
-static void usbnet_set_msglevel (struct net_device *net, u32 level)
+void usbnet_set_msglevel (struct net_device *net, u32 level)
{
struct usbnet *dev = netdev_priv(net);
dev->msg_enable = level;
}
+EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
-static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
-{
-#ifdef NEED_MII
- {
- struct usbnet *dev = netdev_priv(net);
-
- if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
- return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
- }
-#endif
- return -EOPNOTSUPP;
-}
+/* drivers may override default ethtool_ops in their bind() routine */
+static struct ethtool_ops usbnet_ethtool_ops = {
+ .get_drvinfo = usbnet_get_drvinfo,
+ .get_link = usbnet_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+};
/*-------------------------------------------------------------------------*/
@@ -3387,19 +715,24 @@ kevent (void *data)
if (test_bit (EVENT_TX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->txq);
status = usb_clear_halt (dev->udev, dev->out);
- if (status < 0 && status != -EPIPE) {
+ if (status < 0
+ && status != -EPIPE
+ && status != -ESHUTDOWN) {
if (netif_msg_tx_err (dev))
deverr (dev, "can't clear tx halt, status %d",
status);
} else {
clear_bit (EVENT_TX_HALT, &dev->flags);
- netif_wake_queue (dev->net);
+ if (status != -ESHUTDOWN)
+ netif_wake_queue (dev->net);
}
}
if (test_bit (EVENT_RX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->rxq);
status = usb_clear_halt (dev->udev, dev->in);
- if (status < 0 && status != -EPIPE) {
+ if (status < 0
+ && status != -EPIPE
+ && status != -ESHUTDOWN) {
if (netif_msg_rx_err (dev))
deverr (dev, "can't clear rx halt, status %d",
status);
@@ -3458,7 +791,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
switch (urb->status) {
case -EPIPE:
- defer_kevent (dev, EVENT_TX_HALT);
+ usbnet_defer_kevent (dev, EVENT_TX_HALT);
break;
/* software-driven interface shutdown */
@@ -3515,10 +848,6 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
struct skb_data *entry;
struct driver_info *info = dev->driver_info;
unsigned long flags;
-#ifdef CONFIG_USB_NET1080
- struct nc_header *header = NULL;
- struct nc_trailer *trailer = NULL;
-#endif /* CONFIG_USB_NET1080 */
// some devices want funky USB-level framing, for
// win32 driver (usually) and/or hardware quirks
@@ -3544,24 +873,8 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
entry->state = tx_start;
entry->length = length;
- // FIXME: reorganize a bit, so that fixup() fills out NetChip
- // framing too. (Packet ID update needs the spinlock...)
- // [ BETTER: we already own net->xmit_lock, that's enough ]
-
-#ifdef CONFIG_USB_NET1080
- if (info->flags & FLAG_FRAMING_NC) {
- header = (struct nc_header *) skb_push (skb, sizeof *header);
- header->hdr_len = cpu_to_le16 (sizeof (*header));
- header->packet_len = cpu_to_le16 (length);
- if (!((skb->len + sizeof *trailer) & 0x01))
- *skb_put (skb, 1) = PAD_BYTE;
- trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
- }
-#endif /* CONFIG_USB_NET1080 */
-
usb_fill_bulk_urb (urb, dev->udev, dev->out,
skb->data, skb->len, tx_complete, skb);
- urb->transfer_flags |= URB_ASYNC_UNLINK;
/* don't assume the hardware handles USB_ZERO_PACKET
* 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)
spin_lock_irqsave (&dev->txq.lock, flags);
-#ifdef CONFIG_USB_NET1080
- if (info->flags & FLAG_FRAMING_NC) {
- header->packet_id = cpu_to_le16 ((u16)dev->dev_packet_id++);
- put_unaligned (header->packet_id, &trailer->packet_id);
-#if 0
- devdbg (dev, "frame >tx h %d p %d id %d",
- header->hdr_len, header->packet_len,
- header->packet_id);
-#endif
- }
-#endif /* CONFIG_USB_NET1080 */
-
switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
case -EPIPE:
netif_stop_queue (net);
- defer_kevent (dev, EVENT_TX_HALT);
+ usbnet_defer_kevent (dev, EVENT_TX_HALT);
break;
default:
if (netif_msg_tx_err (dev))
@@ -3692,7 +993,7 @@ static void usbnet_bh (unsigned long param)
// precondition: never called in_interrupt
-static void usbnet_disconnect (struct usb_interface *intf)
+void usbnet_disconnect (struct usb_interface *intf)
{
struct usbnet *dev;
struct usb_device *xdev;
@@ -3706,7 +1007,8 @@ static void usbnet_disconnect (struct usb_interface *intf)
xdev = interface_to_usbdev (intf);
if (netif_msg_probe (dev))
- devinfo (dev, "unregister usbnet usb-%s-%s, %s",
+ devinfo (dev, "unregister '%s' usb-%s-%s, %s",
+ intf->dev.driver->name,
xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description);
@@ -3722,15 +1024,14 @@ static void usbnet_disconnect (struct usb_interface *intf)
free_netdev(net);
usb_put_dev (xdev);
}
+EXPORT_SYMBOL_GPL(usbnet_disconnect);
/*-------------------------------------------------------------------------*/
-static struct ethtool_ops usbnet_ethtool_ops;
-
// precondition: never called in_interrupt
-static int
+int
usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
{
struct usbnet *dev;
@@ -3779,6 +1080,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
strcpy (net->name, "usb%d");
memcpy (net->dev_addr, node_id, sizeof node_id);
+ /* rx and tx sides can use different message sizes;
+ * bind() should set rx_urb_size in that case.
+ */
+ dev->hard_mtu = net->mtu + net->hard_header_len;
#if 0
// dma_supported() is deeply broken on almost all architectures
// possible with some EHCI controllers
@@ -3793,7 +1098,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
net->stop = usbnet_stop;
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->tx_timeout = usbnet_tx_timeout;
- net->do_ioctl = usbnet_ioctl;
net->ethtool_ops = &usbnet_ethtool_ops;
// allow device-specific bind/init procedures
@@ -3806,8 +1110,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if ((dev->driver_info->flags & FLAG_ETHER) != 0
&& (net->dev_addr [0] & 0x02) == 0)
strcpy (net->name, "eth%d");
- } else if (!info->in || info->out)
- status = get_endpoints (dev, udev);
+
+ /* maybe the remote can't receive an Ethernet MTU */
+ if (net->mtu > (dev->hard_mtu - net->hard_header_len))
+ net->mtu = dev->hard_mtu - net->hard_header_len;
+ } else if (!info->in || !info->out)
+ status = usbnet_get_endpoints (dev, udev);
else {
dev->in = usb_rcvbulkpipe (xdev, info->in);
dev->out = usb_sndbulkpipe (xdev, info->out);
@@ -3819,12 +1127,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
status = 0;
}
-
if (status == 0 && dev->status)
status = init_status (dev, udev);
if (status < 0)
goto out1;
+ if (!dev->rx_urb_size)
+ dev->rx_urb_size = dev->hard_mtu;
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
SET_NETDEV_DEV(net, &udev->dev);
@@ -3832,8 +1141,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if (status)
goto out3;
if (netif_msg_probe (dev))
- devinfo (dev, "register usbnet at usb-%s-%s, %s, "
+ devinfo (dev, "register '%s' at usb-%s-%s, %s, "
"%02x:%02x:%02x:%02x:%02x:%02x",
+ udev->dev.driver->name,
xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description,
net->dev_addr [0], net->dev_addr [1],
@@ -3857,12 +1167,15 @@ out:
usb_put_dev(xdev);
return status;
}
+EXPORT_SYMBOL_GPL(usbnet_probe);
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_PM
+/* FIXME these suspend/resume methods assume non-CDC style
+ * devices, with only one interface.
+ */
-static int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
+int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
@@ -3875,8 +1188,9 @@ static int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
intf->dev.power.power_state = PMSG_SUSPEND;
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_suspend);
-static int usbnet_resume (struct usb_interface *intf)
+int usbnet_resume (struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
@@ -3885,357 +1199,27 @@ static int usbnet_resume (struct usb_interface *intf)
tasklet_schedule (&dev->bh);
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_resume);
-#else /* !CONFIG_PM */
-
-#define usbnet_suspend NULL
-#define usbnet_resume NULL
-
-#endif /* CONFIG_PM */
-
-/*-------------------------------------------------------------------------*/
-
-#ifndef HAVE_HARDWARE
-#error You need to configure some hardware for this driver
-#endif
-
-/*
- * chip vendor names won't normally be on the cables, and
- * may not be on the device.
- */
-
-static const struct usb_device_id products [] = {
-
-#ifdef CONFIG_USB_ALI_M5632
-{
- USB_DEVICE (0x0402, 0x5632), // ALi defaults
- .driver_info = (unsigned long) &ali_m5632_info,
-},
-#endif
-
-#ifdef CONFIG_USB_AN2720
-{
- USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults
- .driver_info = (unsigned long) &an2720_info,
-}, {
- USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET
- .driver_info = (unsigned long) &an2720_info,
-},
-#endif
-
-#ifdef CONFIG_USB_BELKIN
-{
- USB_DEVICE (0x050d, 0x0004), // Belkin
- .driver_info = (unsigned long) &belkin_info,
-}, {
- USB_DEVICE (0x056c, 0x8100), // eTEK
- .driver_info = (unsigned long) &belkin_info,
-}, {
- USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK)
- .driver_info = (unsigned long) &belkin_info,
-},
-#endif
-
-#ifdef CONFIG_USB_AX8817X
-{
- // Linksys USB200M
- USB_DEVICE (0x077b, 0x2226),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Netgear FA120
- USB_DEVICE (0x0846, 0x1040),
- .driver_info = (unsigned long) &netgear_fa120_info,
-}, {
- // DLink DUB-E100
- USB_DEVICE (0x2001, 0x1a00),
- .driver_info = (unsigned long) &dlink_dub_e100_info,
-}, {
- // Intellinet, ST Lab USB Ethernet
- USB_DEVICE (0x0b95, 0x1720),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Hawking UF200, TrendNet TU2-ET100
- USB_DEVICE (0x07b8, 0x420a),
- .driver_info = (unsigned long) &hawking_uf200_info,
-}, {
- // Billionton Systems, USB2AR
- USB_DEVICE (0x08dd, 0x90ff),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // ATEN UC210T
- USB_DEVICE (0x0557, 0x2009),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Buffalo LUA-U2-KTX
- USB_DEVICE (0x0411, 0x003d),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
- USB_DEVICE (0x6189, 0x182d),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // corega FEther USB2-TX
- USB_DEVICE (0x07aa, 0x0017),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // Surecom EP-1427X-2
- USB_DEVICE (0x1189, 0x0893),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // goodway corp usb gwusb2e
- USB_DEVICE (0x1631, 0x6200),
- .driver_info = (unsigned long) &ax8817x_info,
-}, {
- // ASIX AX88772 10/100
- USB_DEVICE (0x0b95, 0x7720),
- .driver_info = (unsigned long) &ax88772_info,
-},
-#endif
-
-#ifdef CONFIG_USB_EPSON2888
-{
- USB_DEVICE (0x0525, 0x2888), // EPSON USB client
- .driver_info = (unsigned long) &epson2888_info,
-},
-#endif
-
-#ifdef CONFIG_USB_GENESYS
-{
- USB_DEVICE (0x05e3, 0x0502), // GL620USB-A
- .driver_info = (unsigned long) &genelink_info,
-},
- /* NOT: USB_DEVICE (0x05e3, 0x0501), // GL620USB
- * that's half duplex, not currently supported
- */
-#endif
-
-#ifdef CONFIG_USB_NET1080
-{
- USB_DEVICE (0x0525, 0x1080), // NetChip ref design
- .driver_info = (unsigned long) &net1080_info,
-}, {
- USB_DEVICE (0x06D0, 0x0622), // Laplink Gold
- .driver_info = (unsigned long) &net1080_info,
-},
-#endif
-
-#ifdef CONFIG_USB_PL2301
-{
- USB_DEVICE (0x067b, 0x0000), // PL-2301
- .driver_info = (unsigned long) &prolific_info,
-}, {
- USB_DEVICE (0x067b, 0x0001), // PL-2302
- .driver_info = (unsigned long) &prolific_info,
-},
-#endif
-
-#ifdef CONFIG_USB_KC2190
-{
- USB_DEVICE (0x050f, 0x0190), // KC-190
- .driver_info = (unsigned long) &kc2190_info,
-},
-#endif
-
-#ifdef CONFIG_USB_RNDIS
-{
- /* RNDIS is MSFT's un-official variant of CDC ACM */
- USB_INTERFACE_INFO (USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
- .driver_info = (unsigned long) &rndis_info,
-},
-#endif
-
-#ifdef CONFIG_USB_ARMLINUX
-/*
- * SA-1100 using standard ARM Linux kernels, or compatible.
- * Often used when talking to Linux PDAs (iPaq, Yopy, etc).
- * The sa-1100 "usb-eth" driver handles the basic framing.
- *
- * PXA25x or PXA210 ... these use a "usb-eth" driver much like
- * the sa1100 one, but hardware uses different endpoint numbers.
- *
- * Or the Linux "Ethernet" gadget on hardware that can't talk
- * CDC Ethernet (e.g., no altsettings), in either of two modes:
- * - acting just like the old "usb-eth" firmware, though
- * the implementation is different
- * - supporting RNDIS as the first/default configuration for
- * MS-Windows interop; Linux needs to use the other config
- */
-{
- // 1183 = 0x049F, both used as hex values?
- // Compaq "Itsy" vendor/product id
- USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
- .driver_info = (unsigned long) &linuxdev_info,
-}, {
- USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
- .driver_info = (unsigned long) &yopy_info,
-}, {
- USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
- .driver_info = (unsigned long) &blob_info,
-}, {
- // Linux Ethernet/RNDIS gadget on pxa210/25x/26x
- // e.g. Gumstix, current OpenZaurus, ...
- USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
- .driver_info = (unsigned long) &linuxdev_info,
-},
-#endif
-
-#if defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
-/*
- * SA-1100 based Sharp Zaurus ("collie"), or compatible.
- * Same idea as above, but different framing.
- *
- * PXA-2xx based models are also lying-about-cdc.
- * Some models don't even tell the same lies ...
- *
- * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries,
- * unlike the older ones with 2.4 "embedix" kernels.
- *
- * NOTE: These entries do double-duty, serving as blacklist entries
- * whenever Zaurus support isn't enabled, but CDC Ethernet is.
- */
-#define ZAURUS_MASTER_INTERFACE \
- .bInterfaceClass = USB_CLASS_COMM, \
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
- .bInterfaceProtocol = USB_CDC_PROTO_NONE
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8004,
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_STRONGARM_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8005, /* A-300 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8006, /* B-500/SL-5600 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8007, /* C-700 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9031, /* C-750 C-760 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x9032, /* SL-6000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-}, {
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- /* reported with some C860 units */
- .idProduct = 0x9050, /* C-860 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = ZAURUS_PXA_INFO,
-},
-
-#ifdef CONFIG_USB_ZAURUS
- /* At least some (reports vary) PXA units have very different lies
- * about their standards support: they claim to be cell phones with
- * direct access to their radios. (They don't conform to CDC MDLM.)
- */
-{
- USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-},
-#endif
-
-/* Olympus has some models with a Zaurus-compatible option.
- * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x07B4,
- .idProduct = 0x0F02, /* R-1000 */
- ZAURUS_MASTER_INTERFACE,
- .driver_info = OLYMPUS_MXL_INFO,
-},
-#endif
-
-#ifdef CONFIG_USB_CDCETHER
-{
- /* CDC Ether uses two interfaces, not necessarily consecutive.
- * We match the main interface, ignoring the optional device
- * class so we could handle devices that aren't exclusively
- * CDC ether.
- *
- * NOTE: this match must come AFTER entries working around
- * bugs/quirks in a given product (like Zaurus, above).
- */
- USB_INTERFACE_INFO (USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &cdc_info,
-},
-#endif
-
- { }, // END
-};
-MODULE_DEVICE_TABLE (usb, products);
-
-static struct usb_driver usbnet_driver = {
- .owner = THIS_MODULE,
- .name = driver_name,
- .id_table = products,
- .probe = usbnet_probe,
- .disconnect = usbnet_disconnect,
- .suspend = usbnet_suspend,
- .resume = usbnet_resume,
-};
-
-/* Default ethtool_ops assigned. Devices can override in their bind() routine */
-static struct ethtool_ops usbnet_ethtool_ops = {
- .get_drvinfo = usbnet_get_drvinfo,
- .get_link = usbnet_get_link,
- .get_msglevel = usbnet_get_msglevel,
- .set_msglevel = usbnet_set_msglevel,
-};
/*-------------------------------------------------------------------------*/
-static int __init usbnet_init (void)
+static int __init usbnet_init(void)
{
- // compiler should optimize these out
+ /* compiler should optimize this out */
BUG_ON (sizeof (((struct sk_buff *)0)->cb)
< sizeof (struct skb_data));
-#ifdef CONFIG_USB_CDCETHER
- BUG_ON ((sizeof (((struct usbnet *)0)->data)
- < sizeof (struct cdc_state)));
-#endif
random_ether_addr(node_id);
-
- return usb_register(&usbnet_driver);
+ return 0;
}
-module_init (usbnet_init);
+module_init(usbnet_init);
-static void __exit usbnet_exit (void)
+static void __exit usbnet_exit(void)
{
- usb_deregister (&usbnet_driver);
}
-module_exit (usbnet_exit);
+module_exit(usbnet_exit);
-MODULE_AUTHOR ("David Brownell <dbrownell@users.sourceforge.net>");
-MODULE_DESCRIPTION ("USB Host-to-Host Link Drivers (numerous vendors)");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("USB network driver framework");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h
new file mode 100644
index 00000000000..7aa0abd1a9b
--- /dev/null
+++ b/drivers/usb/net/usbnet.h
@@ -0,0 +1,193 @@
+/*
+ * USB Networking Link Interface
+ *
+ * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __USBNET_H
+#define __USBNET_H
+
+
+/* interface from usbnet core to each USB networking link we handle */
+struct usbnet {
+ /* housekeeping */
+ struct usb_device *udev;
+ struct driver_info *driver_info;
+ wait_queue_head_t *wait;
+
+ /* i/o info: pipes etc */
+ unsigned in, out;
+ struct usb_host_endpoint *status;
+ unsigned maxpacket;
+ struct timer_list delay;
+
+ /* protocol/interface state */
+ struct net_device *net;
+ struct net_device_stats stats;
+ int msg_enable;
+ unsigned long data [5];
+ u32 xid;
+ u32 hard_mtu; /* count any extra framing */
+ size_t rx_urb_size; /* size for rx urbs */
+ struct mii_if_info mii;
+
+ /* various kinds of pending driver work */
+ struct sk_buff_head rxq;
+ struct sk_buff_head txq;
+ struct sk_buff_head done;
+ struct urb *interrupt;
+ struct tasklet_struct bh;
+
+ struct work_struct kevent;
+ unsigned long flags;
+# define EVENT_TX_HALT 0
+# define EVENT_RX_HALT 1
+# define EVENT_RX_MEMORY 2
+# define EVENT_STS_SPLIT 3
+# define EVENT_LINK_RESET 4
+};
+
+static inline struct usb_driver *driver_of(struct usb_interface *intf)
+{
+ return to_usb_driver(intf->dev.driver);
+}
+
+/* interface from the device/framing level "minidriver" to core */
+struct driver_info {
+ char *description;
+
+ int flags;
+/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */
+#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */
+#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */
+#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */
+#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */
+
+#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
+#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
+
+#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
+
+ /* init device ... can sleep, or cause probe() failure */
+ int (*bind)(struct usbnet *, struct usb_interface *);
+
+ /* cleanup device ... can sleep, but can't fail */
+ void (*unbind)(struct usbnet *, struct usb_interface *);
+
+ /* reset device ... can sleep */
+ int (*reset)(struct usbnet *);
+
+ /* see if peer is connected ... can sleep */
+ int (*check_connect)(struct usbnet *);
+
+ /* for status polling */
+ void (*status)(struct usbnet *, struct urb *);
+
+ /* link reset handling, called from defer_kevent */
+ int (*link_reset)(struct usbnet *);
+
+ /* fixup rx packet (strip framing) */
+ int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb);
+
+ /* fixup tx packet (add framing) */
+ struct sk_buff *(*tx_fixup)(struct usbnet *dev,
+ struct sk_buff *skb, unsigned flags);
+
+ /* for new devices, use the descriptor-reading code instead */
+ int in; /* rx endpoint */
+ int out; /* tx endpoint */
+
+ unsigned long data; /* Misc driver specific data */
+};
+
+/* Minidrivers are just drivers using the "usbnet" core as a powerful
+ * network-specific subroutine library ... that happens to do pretty
+ * much everything except custom framing and chip-specific stuff.
+ */
+extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
+extern int usbnet_suspend (struct usb_interface *, pm_message_t );
+extern int usbnet_resume (struct usb_interface *);
+extern void usbnet_disconnect(struct usb_interface *);
+
+
+/* Drivers that reuse some of the standard USB CDC infrastructure
+ * (notably, using multiple interfaces according to the the CDC
+ * union descriptor) get some helper code.
+ */
+struct cdc_state {
+ struct usb_cdc_header_desc *header;
+ struct usb_cdc_union_desc *u;
+ struct usb_cdc_ether_desc *ether;
+ struct usb_interface *control;
+ struct usb_interface *data;
+};
+
+extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
+
+/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
+#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
+ |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+ |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+ |USB_CDC_PACKET_TYPE_DIRECTED)
+
+
+/* we record the state for each of our queued skbs */
+enum skb_state {
+ illegal = 0,
+ tx_start, tx_done,
+ rx_start, rx_done, rx_cleanup
+};
+
+struct skb_data { /* skb->cb is one of these */
+ struct urb *urb;
+ struct usbnet *dev;
+ enum skb_state state;
+ size_t length;
+};
+
+
+extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
+extern void usbnet_defer_kevent (struct usbnet *, int);
+extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
+
+extern u32 usbnet_get_msglevel (struct net_device *);
+extern void usbnet_set_msglevel (struct net_device *, u32);
+extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
+
+/* messaging support includes the interface name, so it must not be
+ * used before it has one ... notably, in minidriver bind() calls.
+ */
+#ifdef DEBUG
+#define devdbg(usbnet, fmt, arg...) \
+ printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#else
+#define devdbg(usbnet, fmt, arg...) do {} while(0)
+#endif
+
+#define deverr(usbnet, fmt, arg...) \
+ printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+#define devwarn(usbnet, fmt, arg...) \
+ printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg)
+
+#define devinfo(usbnet, fmt, arg...) \
+ printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \
+
+
+#endif /* __USBNET_H */
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
new file mode 100644
index 00000000000..ee3b892aeab
--- /dev/null
+++ b/drivers/usb/net/zaurus.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2002 Pavel Machek <pavel@ucw.cz>
+ * Copyright (C) 2002-2005 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// #define DEBUG // error path messages, extra info
+// #define VERBOSE // more; success messages
+
+#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#endif
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/usb_cdc.h>
+
+#include "usbnet.h"
+
+
+/*
+ * All known Zaurii lie about their standards conformance. At least
+ * the earliest SA-1100 models lie by saying they support CDC Ethernet.
+ * Some later models (especially PXA-25x and PXA-27x based ones) lie
+ * and say they support CDC MDLM (for access to cell phone modems).
+ *
+ * There are non-Zaurus products that use these same protocols too.
+ *
+ * The annoying thing is that at the same time Sharp was developing
+ * that annoying standards-breaking software, the Linux community had
+ * a simple "CDC Subset" working reliably on the same SA-1100 hardware.
+ * That is, the same functionality but not violating standards.
+ *
+ * The CDC Ethernet nonconformance points are troublesome to hosts
+ * with a true CDC Ethernet implementation:
+ * - Framing appends a CRC, which the spec says drivers "must not" do;
+ * - Transfers data in altsetting zero, instead of altsetting 1;
+ * - All these peripherals use the same ethernet address.
+ *
+ * The CDC MDLM nonconformance is less immediately troublesome, since all
+ * MDLM implementations are quasi-proprietary anyway.
+ */
+
+static struct sk_buff *
+zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, unsigned flags)
+{
+ int padlen;
+ struct sk_buff *skb2;
+
+ padlen = 2;
+ if (!skb_cloned(skb)) {
+ int tailroom = skb_tailroom(skb);
+ if ((padlen + 4) <= tailroom)
+ goto done;
+ }
+ skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (skb) {
+ u32 fcs;
+done:
+ fcs = crc32_le(~0, skb->data, skb->len);
+ fcs = ~fcs;
+
+ *skb_put (skb, 1) = fcs & 0xff;
+ *skb_put (skb, 1) = (fcs>> 8) & 0xff;
+ *skb_put (skb, 1) = (fcs>>16) & 0xff;
+ *skb_put (skb, 1) = (fcs>>24) & 0xff;
+ }
+ return skb;
+}
+
+static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ /* Belcarra's funky framing has other options; mostly
+ * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes.
+ */
+ dev->net->hard_header_len += 6;
+ dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu;
+ return usbnet_generic_cdc_bind(dev, intf);
+}
+
+/* PDA style devices are always connected if present */
+static int always_connected (struct usbnet *dev)
+{
+ return 0;
+}
+
+static const struct driver_info zaurus_sl5x00_info = {
+ .description = "Sharp Zaurus SL-5x00",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .bind = zaurus_bind,
+ .unbind = usbnet_cdc_unbind,
+ .tx_fixup = zaurus_tx_fixup,
+};
+#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
+
+static const struct driver_info zaurus_pxa_info = {
+ .description = "Sharp Zaurus, PXA-2xx based",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .bind = zaurus_bind,
+ .unbind = usbnet_cdc_unbind,
+ .tx_fixup = zaurus_tx_fixup,
+};
+#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
+
+static const struct driver_info olympus_mxl_info = {
+ .description = "Olympus R1000",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .bind = zaurus_bind,
+ .unbind = usbnet_cdc_unbind,
+ .tx_fixup = zaurus_tx_fixup,
+};
+#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
+
+
+/* Some more recent products using Lineo/Belcarra code will wrongly claim
+ * CDC MDLM conformance. They aren't conformant: data endpoints live
+ * in the control interface, there's no data interface, and it's not used
+ * to talk to a cell phone radio. But at least we can detect these two
+ * pseudo-classes, rather than growing this product list with entries for
+ * each new nonconformant product (sigh).
+ */
+static const u8 safe_guid[16] = {
+ 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
+ 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
+};
+static const u8 blan_guid[16] = {
+ 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70,
+ 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37,
+};
+
+static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 *buf = intf->cur_altsetting->extra;
+ int len = intf->cur_altsetting->extralen;
+ struct usb_cdc_mdlm_desc *desc = NULL;
+ struct usb_cdc_mdlm_detail_desc *detail = NULL;
+
+ while (len > 3) {
+ if (buf [1] != USB_DT_CS_INTERFACE)
+ goto next_desc;
+
+ /* use bDescriptorSubType, and just verify that we get a
+ * "BLAN" (or "SAFE") descriptor.
+ */
+ switch (buf [2]) {
+ case USB_CDC_MDLM_TYPE:
+ if (desc) {
+ dev_dbg(&intf->dev, "extra MDLM\n");
+ goto bad_desc;
+ }
+ desc = (void *) buf;
+ if (desc->bLength != sizeof *desc) {
+ dev_dbg(&intf->dev, "MDLM len %u\n",
+ desc->bLength);
+ goto bad_desc;
+ }
+ /* expect bcdVersion 1.0, ignore */
+ if (memcmp(&desc->bGUID, blan_guid, 16)
+ && memcmp(&desc->bGUID, safe_guid, 16) ) {
+ /* hey, this one might _really_ be MDLM! */
+ dev_dbg(&intf->dev, "MDLM guid\n");
+ goto bad_desc;
+ }
+ break;
+ case USB_CDC_MDLM_DETAIL_TYPE:
+ if (detail) {
+ dev_dbg(&intf->dev, "extra MDLM detail\n");
+ goto bad_desc;
+ }
+ detail = (void *) buf;
+ switch (detail->bGuidDescriptorType) {
+ case 0: /* "SAFE" */
+ if (detail->bLength != (sizeof *detail + 2))
+ goto bad_detail;
+ break;
+ case 1: /* "BLAN" */
+ if (detail->bLength != (sizeof *detail + 3))
+ goto bad_detail;
+ break;
+ default:
+ goto bad_detail;
+ }
+
+ /* assuming we either noticed BLAN already, or will
+ * find it soon, there are some data bytes here:
+ * - bmNetworkCapabilities (unused)
+ * - bmDataCapabilities (bits, see below)
+ * - bPad (ignored, for PADAFTER -- BLAN-only)
+ * bits are:
+ * - 0x01 -- Zaurus framing (add CRC)
+ * - 0x02 -- PADBEFORE (CRC includes some padding)
+ * - 0x04 -- PADAFTER (some padding after CRC)
+ * - 0x08 -- "fermat" packet mangling (for hw bugs)
+ * the PADBEFORE appears not to matter; we interop
+ * with devices that use it and those that don't.
+ */
+ if ((detail->bDetailData[1] & ~0x02) != 0x01) {
+ /* bmDataCapabilites == 0 would be fine too,
+ * but framing is minidriver-coupled for now.
+ */
+bad_detail:
+ dev_dbg(&intf->dev,
+ "bad MDLM detail, %d %d %d\n",
+ detail->bLength,
+ detail->bDetailData[0],
+ detail->bDetailData[2]);
+ goto bad_desc;
+ }
+ break;
+ }
+next_desc:
+ len -= buf [0]; /* bLength */
+ buf += buf [0];
+ }
+
+ if (!desc || !detail) {
+ dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n",
+ desc ? "" : "func ",
+ detail ? "" : "detail ");
+ goto bad_desc;
+ }
+
+ /* There's probably a CDC Ethernet descriptor there, but we can't
+ * rely on the Ethernet address it provides since not all vendors
+ * bother to make it unique. Likewise there's no point in tracking
+ * of the CDC event notifications.
+ */
+ return usbnet_get_endpoints(dev, intf);
+
+bad_desc:
+ dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n");
+ return -ENODEV;
+}
+
+static const struct driver_info bogus_mdlm_info = {
+ .description = "pseudo-MDLM (BLAN) device",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .tx_fixup = zaurus_tx_fixup,
+ .bind = blan_mdlm_bind,
+};
+
+static const struct usb_device_id products [] = {
+#define ZAURUS_MASTER_INTERFACE \
+ .bInterfaceClass = USB_CLASS_COMM, \
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE
+
+/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8004,
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_STRONGARM_INFO,
+},
+
+/* PXA-2xx based models are also lying-about-cdc. If you add any
+ * more devices that claim to be CDC Ethernet, make sure they get
+ * added to the blacklist in cdc_ether too.
+ *
+ * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries,
+ * unlike the older ones with 2.4 "embedix" kernels.
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8005, /* A-300 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8006, /* B-500/SL-5600 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x8007, /* C-700 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x9031, /* C-750 C-760 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ .idProduct = 0x9032, /* SL-6000 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+}, {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x04DD,
+ /* reported with some C860 units */
+ .idProduct = 0x9050, /* C-860 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = ZAURUS_PXA_INFO,
+},
+
+
+/* At least some of the newest PXA units have very different lies about
+ * their standards support: they claim to be cell phones offering
+ * direct access to their radios! (No, they don't conform to CDC MDLM.)
+ */
+{
+ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
+},
+
+/* Olympus has some models with a Zaurus-compatible option.
+ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x07B4,
+ .idProduct = 0x0F02, /* R-1000 */
+ ZAURUS_MASTER_INTERFACE,
+ .driver_info = OLYMPUS_MXL_INFO,
+},
+ { }, // END
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver zaurus_driver = {
+ .owner = THIS_MODULE,
+ .name = "zaurus",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init zaurus_init(void)
+{
+ return usb_register(&zaurus_driver);
+}
+module_init(zaurus_init);
+
+static void __exit zaurus_exit(void)
+{
+ usb_deregister(&zaurus_driver);
+}
+module_exit(zaurus_exit);
+
+MODULE_AUTHOR("Pavel Machek, David Brownell");
+MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index fc013978837..c4e479ee926 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)
return;
dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
dev->name);
- zd->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(zd->tx_urb);
zd->stats.tx_errors++;
/* Restart the timeout to quiet the watchdog: */
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 012e63e0580..05c44ae3ed3 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)
priv->cbr_mask = B300;
usb_set_serial_port_data(serial->port[0], priv);
- return (0);
-}
+ return 0;
+}
static int cypress_earthmate_startup (struct usb_serial *serial)
@@ -464,14 +464,15 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
dbg("%s", __FUNCTION__);
if (generic_startup(serial)) {
- dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number);
+ dbg("%s - Failed setting up port %d", __FUNCTION__,
+ serial->port[0]->number);
return 1;
}
priv = usb_get_serial_port_data(serial->port[0]);
priv->chiptype = CT_EARTHMATE;
-
- return (0);
+
+ return 0;
} /* cypress_earthmate_startup */
@@ -482,14 +483,15 @@ static int cypress_hidcom_startup (struct usb_serial *serial)
dbg("%s", __FUNCTION__);
if (generic_startup(serial)) {
- dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number);
+ dbg("%s - Failed setting up port %d", __FUNCTION__,
+ serial->port[0]->number);
return 1;
}
priv = usb_get_serial_port_data(serial->port[0]);
priv->chiptype = CT_CYPHIDCOM;
- return (0);
+ return 0;
} /* cypress_hidcom_startup */
@@ -909,7 +911,8 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
} /* cypress_ioctl */
-static void cypress_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void cypress_set_termios (struct usb_serial_port *port,
+ struct termios *old_termios)
{
struct cypress_private *priv = usb_get_serial_port_data(port);
struct tty_struct *tty;
@@ -918,7 +921,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
unsigned long flags;
__u8 oldlines;
int linechange = 0;
-
+
dbg("%s - port %d", __FUNCTION__, port->number);
tty = port->tty;
@@ -931,10 +934,12 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
if (!priv->termios_initialized) {
if (priv->chiptype == CT_EARTHMATE) {
*(tty->termios) = tty_std_termios;
- tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |
+ CLOCAL;
} else if (priv->chiptype == CT_CYPHIDCOM) {
*(tty->termios) = tty_std_termios;
- tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
+ CLOCAL;
}
priv->termios_initialized = 1;
}
@@ -946,12 +951,15 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
/* check if there are new settings */
if (old_termios) {
if ((cflag != old_termios->c_cflag) ||
- (RELEVANT_IFLAG(iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
- dbg("%s - attempting to set new termios settings", __FUNCTION__);
- /* should make a copy of this in case something goes wrong in the function, we can restore it */
+ (RELEVANT_IFLAG(iflag) !=
+ RELEVANT_IFLAG(old_termios->c_iflag))) {
+ dbg("%s - attempting to set new termios settings",
+ __FUNCTION__);
+ /* should make a copy of this in case something goes
+ * wrong in the function, we can restore it */
spin_lock_irqsave(&priv->lock, flags);
priv->tmp_termios = *(tty->termios);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
} else {
dbg("%s - nothing to do, exiting", __FUNCTION__);
return;
@@ -962,21 +970,34 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
/* set number of data bits, parity, stop bits */
/* when parity is disabled the parity type bit is ignored */
- stop_bits = cflag & CSTOPB ? 1 : 0; /* 1 means 2 stop bits, 0 means 1 stop bit */
-
+ /* 1 means 2 stop bits, 0 means 1 stop bit */
+ stop_bits = cflag & CSTOPB ? 1 : 0;
+
if (cflag & PARENB) {
parity_enable = 1;
- parity_type = cflag & PARODD ? 1 : 0; /* 1 means odd parity, 0 means even parity */
+ /* 1 means odd parity, 0 means even parity */
+ parity_type = cflag & PARODD ? 1 : 0;
} else
parity_enable = parity_type = 0;
if (cflag & CSIZE) {
switch (cflag & CSIZE) {
- case CS5: data_bits = 0; break;
- case CS6: data_bits = 1; break;
- case CS7: data_bits = 2; break;
- case CS8: data_bits = 3; break;
- default: err("%s - CSIZE was set, but not CS5-CS8", __FUNCTION__); data_bits = 3;
+ case CS5:
+ data_bits = 0;
+ break;
+ case CS6:
+ data_bits = 1;
+ break;
+ case CS7:
+ data_bits = 2;
+ break;
+ case CS8:
+ data_bits = 3;
+ break;
+ default:
+ err("%s - CSIZE was set, but not CS5-CS8",
+ __FUNCTION__);
+ data_bits = 3;
}
} else
data_bits = 3;
@@ -991,63 +1012,85 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
} else {
baud_mask = (cflag & CBAUD);
switch(baud_mask) {
- case B300: dbg("%s - setting baud 300bps", __FUNCTION__); break;
- case B600: dbg("%s - setting baud 600bps", __FUNCTION__); break;
- case B1200: dbg("%s - setting baud 1200bps", __FUNCTION__); break;
- case B2400: dbg("%s - setting baud 2400bps", __FUNCTION__); break;
- case B4800: dbg("%s - setting baud 4800bps", __FUNCTION__); break;
- case B9600: dbg("%s - setting baud 9600bps", __FUNCTION__); break;
- case B19200: dbg("%s - setting baud 19200bps", __FUNCTION__); break;
- case B38400: dbg("%s - setting baud 38400bps", __FUNCTION__); break;
- case B57600: dbg("%s - setting baud 57600bps", __FUNCTION__); break;
- case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break;
- default: dbg("%s - unknown masked baud rate", __FUNCTION__);
+ case B300:
+ dbg("%s - setting baud 300bps", __FUNCTION__);
+ break;
+ case B600:
+ dbg("%s - setting baud 600bps", __FUNCTION__);
+ break;
+ case B1200:
+ dbg("%s - setting baud 1200bps", __FUNCTION__);
+ break;
+ case B2400:
+ dbg("%s - setting baud 2400bps", __FUNCTION__);
+ break;
+ case B4800:
+ dbg("%s - setting baud 4800bps", __FUNCTION__);
+ break;
+ case B9600:
+ dbg("%s - setting baud 9600bps", __FUNCTION__);
+ break;
+ case B19200:
+ dbg("%s - setting baud 19200bps", __FUNCTION__);
+ break;
+ case B38400:
+ dbg("%s - setting baud 38400bps", __FUNCTION__);
+ break;
+ case B57600:
+ dbg("%s - setting baud 57600bps", __FUNCTION__);
+ break;
+ case B115200:
+ dbg("%s - setting baud 115200bps", __FUNCTION__);
+ break;
+ default:
+ dbg("%s - unknown masked baud rate", __FUNCTION__);
}
priv->line_control = (CONTROL_DTR | CONTROL_RTS);
}
spin_unlock_irqrestore(&priv->lock, flags);
-
- dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)", __FUNCTION__,
- stop_bits, parity_enable, parity_type, data_bits);
- cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable,
- parity_type, 0, CYPRESS_SET_CONFIG);
+ dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, "
+ "%d data_bits (+5)", __FUNCTION__, stop_bits,
+ parity_enable, parity_type, data_bits);
+
+ cypress_serial_control(port, baud_mask, data_bits, stop_bits,
+ parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
- /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure
- * this should confirm that all is working if it returns what we just set */
+ /* we perform a CYPRESS_GET_CONFIG so that the current settings are
+ * filled into the private structure this should confirm that all is
+ * working if it returns what we just set */
cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
- /* Here we can define custom tty settings for devices
- *
- * the main tty termios flag base comes from empeg.c
- */
+ /* Here we can define custom tty settings for devices; the main tty
+ * termios flag base comes from empeg.c */
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
-
- dbg("Using custom termios settings for a baud rate of 4800bps.");
+ dbg("Using custom termios settings for a baud rate of "
+ "4800bps.");
/* define custom termios settings for NMEA protocol */
tty->termios->c_iflag /* input modes - */
- &= ~(IGNBRK /* disable ignore break */
- | BRKINT /* disable break causes interrupt */
- | PARMRK /* disable mark parity errors */
- | ISTRIP /* disable clear high bit of input characters */
- | INLCR /* disable translate NL to CR */
- | IGNCR /* disable ignore CR */
- | ICRNL /* disable translate CR to NL */
- | IXON); /* disable enable XON/XOFF flow control */
-
+ &= ~(IGNBRK /* disable ignore break */
+ | BRKINT /* disable break causes interrupt */
+ | PARMRK /* disable mark parity errors */
+ | ISTRIP /* disable clear high bit of input char */
+ | INLCR /* disable translate NL to CR */
+ | IGNCR /* disable ignore CR */
+ | ICRNL /* disable translate CR to NL */
+ | IXON); /* disable enable XON/XOFF flow control */
+
tty->termios->c_oflag /* output modes */
- &= ~OPOST; /* disable postprocess output characters */
-
- tty->termios->c_lflag /* line discipline modes */
- &= ~(ECHO /* disable echo input characters */
- | ECHONL /* disable echo new line */
- | ICANON /* disable erase, kill, werase, and rprnt special characters */
- | ISIG /* disable interrupt, quit, and suspend special characters */
- | IEXTEN); /* disable non-POSIX special characters */
+ &= ~OPOST; /* disable postprocess output char */
+ tty->termios->c_lflag /* line discipline modes */
+ &= ~(ECHO /* disable echo input characters */
+ | ECHONL /* disable echo new line */
+ | ICANON /* disable erase, kill, werase, and rprnt
+ special characters */
+ | ISIG /* disable interrupt, quit, and suspend
+ special characters */
+ | IEXTEN); /* disable non-POSIX special characters */
} /* CT_CYPHIDCOM: Application should handle this for device */
linechange = (priv->line_control != oldlines);
@@ -1060,7 +1103,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o
}
} /* cypress_set_termios */
-
+
/* returns amount of data still left in soft buffer */
static int cypress_chars_in_buffer(struct usb_serial_port *port)
{
@@ -1088,7 +1131,7 @@ static void cypress_throttle (struct usb_serial_port *port)
spin_lock_irqsave(&priv->lock, flags);
priv->rx_flags = THROTTLED;
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -1110,7 +1153,8 @@ static void cypress_unthrottle (struct usb_serial_port *port)
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
- dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
+ dev_err(&port->dev, "%s - failed submitting read urb, "
+ "error %d\n", __FUNCTION__, result);
}
}
@@ -1122,7 +1166,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
unsigned long flags;
- char tty_flag = TTY_NORMAL;
+ char tty_flag = TTY_NORMAL;
int havedata = 0;
int bytes = 0;
int result;
@@ -1131,7 +1175,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s - port %d", __FUNCTION__, port->number);
if (urb->status) {
- dbg("%s - nonzero read status received: %d", __FUNCTION__, urb->status);
+ dbg("%s - nonzero read status received: %d", __FUNCTION__,
+ urb->status);
return;
}
@@ -1155,51 +1200,55 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
case 32:
/* This is for the CY7C64013... */
priv->current_status = data[0] & 0xF8;
- bytes = data[1]+2;
- i=2;
+ bytes = data[1] + 2;
+ i = 2;
if (bytes > 2)
havedata = 1;
break;
case 8:
/* This is for the CY7C63743... */
priv->current_status = data[0] & 0xF8;
- bytes = (data[0] & 0x07)+1;
- i=1;
+ bytes = (data[0] & 0x07) + 1;
+ i = 1;
if (bytes > 1)
havedata = 1;
break;
default:
- dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length);
+ dbg("%s - wrong packet size - received %d bytes",
+ __FUNCTION__, urb->actual_length);
spin_unlock_irqrestore(&priv->lock, flags);
goto continue_read;
}
spin_unlock_irqrestore(&priv->lock, flags);
- usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+ usb_serial_debug_data (debug, &port->dev, __FUNCTION__,
+ urb->actual_length, data);
spin_lock_irqsave(&priv->lock, flags);
/* check to see if status has changed */
if (priv != NULL) {
if (priv->current_status != priv->prev_status) {
- priv->diff_status |= priv->current_status ^ priv->prev_status;
+ priv->diff_status |= priv->current_status ^
+ priv->prev_status;
wake_up_interruptible(&priv->delta_msr_wait);
priv->prev_status = priv->current_status;
}
}
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
- /* hangup, as defined in acm.c... this might be a bad place for it though */
- if (tty && !(tty->termios->c_cflag & CLOCAL) && !(priv->current_status & UART_CD)) {
+ /* hangup, as defined in acm.c... this might be a bad place for it
+ * though */
+ if (tty && !(tty->termios->c_cflag & CLOCAL) &&
+ !(priv->current_status & UART_CD)) {
dbg("%s - calling hangup", __FUNCTION__);
tty_hangup(tty);
goto continue_read;
}
- /* There is one error bit... I'm assuming it is a parity error indicator
- * as the generic firmware will set this bit to 1 if a parity error occurs.
- * I can not find reference to any other error events.
- *
- */
+ /* There is one error bit... I'm assuming it is a parity error
+ * indicator as the generic firmware will set this bit to 1 if a
+ * parity error occurs.
+ * I can not find reference to any other error events. */
spin_lock_irqsave(&priv->lock, flags);
if (priv->current_status & CYP_ERROR) {
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1211,7 +1260,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
/* process read if there is data other than line status */
if (tty && (bytes > i)) {
for (; i < bytes ; ++i) {
- dbg("pushing byte number %d - %d - %c",i,data[i],data[i]);
+ dbg("pushing byte number %d - %d - %c", i, data[i],
+ data[i]);
if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
tty_flip_buffer_push(tty);
}
@@ -1221,25 +1271,28 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
}
spin_lock_irqsave(&priv->lock, flags);
- priv->bytes_in += bytes; /* control and status byte(s) are also counted */
+ /* control and status byte(s) are also counted */
+ priv->bytes_in += bytes;
spin_unlock_irqrestore(&priv->lock, flags);
continue_read:
-
- /* Continue trying to always read... unless the port has closed. */
+
+ /* Continue trying to always read... unless the port has closed. */
if (port->open_count > 0) {
- usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
- usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress),
- port->interrupt_in_urb->transfer_buffer,
- port->interrupt_in_urb->transfer_buffer_length,
- cypress_read_int_callback, port,
- interval);
- result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
- if (result)
- dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
+ usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
+ usb_rcvintpipe(port->serial->dev,
+ port->interrupt_in_endpointAddress),
+ port->interrupt_in_urb->transfer_buffer,
+ port->interrupt_in_urb->transfer_buffer_length,
+ cypress_read_int_callback, port, interval);
+ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&urb->dev->dev, "%s - failed resubmitting "
+ "read urb, error %d\n", __FUNCTION__,
+ result);
}
-
+
return;
} /* cypress_read_int_callback */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d1964a0c416..0a6e8b474b1 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -269,6 +269,8 @@
#define DRIVER_DESC "USB FTDI Serial Converters Driver"
static int debug;
+static __u16 vendor = FTDI_VID;
+static __u16 product;
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
@@ -407,6 +409,34 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
+ /*
+ * These will probably use user-space drivers. Uncomment them if
+ * you need them or use the user-specified vendor/product module
+ * parameters (see ftdi_sio.h for the numbers). Make a fuss if
+ * you think the driver should recognize any of them by default.
+ */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
+ /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -418,6 +448,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
{ USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
{ USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
+ { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
@@ -427,12 +458,21 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
+ { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
- { } /* Terminating entry */
+ { }, /* Optional parameter entry */
+ { } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, id_table_combined);
@@ -2030,6 +2070,15 @@ static int __init ftdi_init (void)
int retval;
dbg("%s", __FUNCTION__);
+ if (vendor > 0 && product > 0) {
+ /* Add user specified VID/PID to reserved element of table. */
+ int i;
+ for (i = 0; id_table_combined[i].idVendor; i++)
+ ;
+ id_table_combined[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ id_table_combined[i].idVendor = vendor;
+ id_table_combined[i].idProduct = product;
+ }
retval = usb_serial_register(&ftdi_sio_device);
if (retval)
goto failed_sio_register;
@@ -2066,4 +2115,9 @@ MODULE_LICENSE("GPL");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(vendor, ushort, 0);
+MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
+ __MODULE_STRING(FTDI_VID)")");
+module_param(product, ushort, 0);
+MODULE_PARM_DESC(vendor, "User specified product ID");
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 9f4342093e8..2c35d74cc6d 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -142,10 +142,43 @@
/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */
#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */
-/* ELV USB Module UO100 (PID sent by Stefan Frings) */
-#define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */
-/* ELV USB Module UM100 (PID sent by Arnim Laeuger) */
-#define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */
+/*
+ * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
+ * All of these devices use FTDI's vendor ID (0x0403).
+ *
+ * The previously included PID for the UO 100 module was incorrect.
+ * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58).
+ *
+ * Armin Laeuger originally sent the PID for the UM 100 module.
+ */
+#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */
+#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */
+#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */
+#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */
+/* Additional ELV PIDs that default to using the FTDI D2XX drivers on
+ * MS Windows, rather than the FTDI Virtual Com Port drivers.
+ * Maybe these will be easier to use with the libftdi/libusb user-space
+ * drivers, or possibly the Comedi drivers in some cases. */
+#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */
+#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */
+#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */
+#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */
+#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */
+#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */
+#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */
+#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */
+#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */
+#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */
+#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */
+#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */
+#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */
+#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
+#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */
+#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */
+#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */
+#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
+#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
+#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
/*
* Definitions for ID TECH (www.idt-net.com) devices
@@ -222,6 +255,7 @@
*/
#define FALCOM_VID 0x0F94 /* Vendor Id */
#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */
+#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */
/*
* SUUNTO product ids
@@ -277,6 +311,18 @@
#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */
/*
+ * Xsens Technologies BV products (http://www.xsens.com).
+ */
+#define XSENS_CONVERTER_0_PID 0xD388
+#define XSENS_CONVERTER_1_PID 0xD389
+#define XSENS_CONVERTER_2_PID 0xD38A
+#define XSENS_CONVERTER_3_PID 0xD38B
+#define XSENS_CONVERTER_4_PID 0xD38C
+#define XSENS_CONVERTER_5_PID 0xD38D
+#define XSENS_CONVERTER_6_PID 0xD38E
+#define XSENS_CONVERTER_7_PID 0xD38F
+
+/*
* Evolution Robotics products (http://www.evolution.com/).
* Submitted by Shawn M. Lavelle.
*/
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index fb092629222..3b958e60f5e 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,
dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip);
if (this_urb->status == -EINPROGRESS) {
- if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
- break;
if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ))
break;
- this_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(this_urb);
break;
}
@@ -402,7 +399,6 @@ static int keyspan_write(struct usb_serial_port *port,
/* send the data out the bulk port */
this_urb->transfer_buffer_length = todo + dataOffset;
- this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
this_urb->dev = port->serial->dev;
if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
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)
static inline void stop_urb(struct urb *urb)
{
- if (urb && urb->status == -EINPROGRESS) {
- urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+ if (urb && urb->status == -EINPROGRESS)
usb_kill_urb(urb);
- }
}
static 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 e9256408757..92d0f925d05 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -45,29 +45,29 @@
#include "usb-serial.h"
/* Function prototypes */
-static int option_open (struct usb_serial_port *port, struct file *filp);
-static void option_close (struct usb_serial_port *port, struct file *filp);
-static int option_startup (struct usb_serial *serial);
-static void option_shutdown (struct usb_serial *serial);
-static void option_rx_throttle (struct usb_serial_port *port);
-static void option_rx_unthrottle (struct usb_serial_port *port);
-static int option_write_room (struct usb_serial_port *port);
+static int option_open(struct usb_serial_port *port, struct file *filp);
+static void option_close(struct usb_serial_port *port, struct file *filp);
+static int option_startup(struct usb_serial *serial);
+static void option_shutdown(struct usb_serial *serial);
+static void option_rx_throttle(struct usb_serial_port *port);
+static void option_rx_unthrottle(struct usb_serial_port *port);
+static int option_write_room(struct usb_serial_port *port);
static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
-static int option_write (struct usb_serial_port *port,
- const unsigned char *buf, int count);
+static int option_write(struct usb_serial_port *port,
+ const unsigned char *buf, int count);
-static int option_chars_in_buffer (struct usb_serial_port *port);
-static int option_ioctl (struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg);
-static void option_set_termios (struct usb_serial_port *port,
- struct termios *old);
-static void option_break_ctl (struct usb_serial_port *port, int break_state);
-static int option_tiocmget (struct usb_serial_port *port, struct file *file);
-static int option_tiocmset (struct usb_serial_port *port, struct file *file,
- unsigned int set, unsigned int clear);
-static int option_send_setup (struct usb_serial_port *port);
+static int option_chars_in_buffer(struct usb_serial_port *port);
+static int option_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void option_set_termios(struct usb_serial_port *port,
+ struct termios *old);
+static void option_break_ctl(struct usb_serial_port *port, int break_state);
+static int option_tiocmget(struct usb_serial_port *port, struct file *file);
+static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear);
+static int option_send_setup(struct usb_serial_port *port);
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
@@ -76,7 +76,6 @@ static int option_send_setup (struct usb_serial_port *port);
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
-
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
@@ -129,7 +128,6 @@ static int debug;
#define debug 0
#endif
-
/* per port private data */
#define N_IN_URB 4
@@ -156,10 +154,8 @@ struct option_port_private {
unsigned long tx_start_time[N_OUT_URB];
};
-
/* Functions used by new usb-serial code. */
-static int __init
-option_init (void)
+static int __init option_init(void)
{
int retval;
retval = usb_serial_register(&option_3port_device);
@@ -179,8 +175,7 @@ failed_3port_device_register:
return retval;
}
-static void __exit
-option_exit (void)
+static void __exit option_exit(void)
{
usb_deregister (&option_driver);
usb_serial_deregister (&option_3port_device);
@@ -189,39 +184,31 @@ option_exit (void)
module_init(option_init);
module_exit(option_exit);
-static void
-option_rx_throttle (struct usb_serial_port *port)
+static void option_rx_throttle(struct usb_serial_port *port)
{
dbg("%s", __FUNCTION__);
}
-
-static void
-option_rx_unthrottle (struct usb_serial_port *port)
+static void option_rx_unthrottle(struct usb_serial_port *port)
{
dbg("%s", __FUNCTION__);
}
-
-static void
-option_break_ctl (struct usb_serial_port *port, int break_state)
+static void option_break_ctl(struct usb_serial_port *port, int break_state)
{
/* Unfortunately, I don't know how to send a break */
dbg("%s", __FUNCTION__);
}
-
-static void
-option_set_termios (struct usb_serial_port *port,
- struct termios *old_termios)
+static void option_set_termios(struct usb_serial_port *port,
+ struct termios *old_termios)
{
dbg("%s", __FUNCTION__);
option_send_setup(port);
}
-static int
-option_tiocmget (struct usb_serial_port *port, struct file *file)
+static int option_tiocmget(struct usb_serial_port *port, struct file *file)
{
unsigned int value;
struct option_port_private *portdata;
@@ -238,9 +225,8 @@ option_tiocmget (struct usb_serial_port *port, struct file *file)
return value;
}
-static int
-option_tiocmset (struct usb_serial_port *port, struct file *file,
- unsigned int set, unsigned int clear)
+static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear)
{
struct option_port_private *portdata;
@@ -258,17 +244,15 @@ option_tiocmset (struct usb_serial_port *port, struct file *file,
return option_send_setup(port);
}
-static int
-option_ioctl (struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int option_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* Write */
-static int
-option_write (struct usb_serial_port *port,
- const unsigned char *buf, int count)
+static int option_write(struct usb_serial_port *port,
+ const unsigned char *buf, int count)
{
struct option_port_private *portdata;
int i;
@@ -289,28 +273,29 @@ option_write (struct usb_serial_port *port,
this_urb = portdata->out_urbs[i];
if (this_urb->status == -EINPROGRESS) {
- if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
- continue;
- if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
+ if (time_before(jiffies,
+ portdata->tx_start_time[i] + 10 * HZ))
continue;
- this_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(this_urb);
continue;
}
if (this_urb->status != 0)
- dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
+ dbg("usb_write %p failed (err=%d)",
+ this_urb, this_urb->status);
- dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
+ dbg("%s: endpoint %d buf %d", __FUNCTION__,
+ usb_pipeendpoint(this_urb->pipe), i);
/* send the data */
memcpy (this_urb->transfer_buffer, buf, todo);
this_urb->transfer_buffer_length = todo;
- this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
this_urb->dev = port->serial->dev;
err = usb_submit_urb(this_urb, GFP_ATOMIC);
if (err) {
- dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
+ dbg("usb_submit_urb %p (write bulk) failed "
+ "(%d, has %d)", this_urb,
+ err, this_urb->status);
continue;
}
portdata->tx_start_time[i] = jiffies;
@@ -323,8 +308,7 @@ option_write (struct usb_serial_port *port,
return count;
}
-static void
-option_indat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
{
int i, err;
int endpoint;
@@ -357,14 +341,14 @@ option_indat_callback (struct urb *urb, struct pt_regs *regs)
if (port->open_count && urb->status != -ESHUTDOWN) {
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
- printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err);
+ printk(KERN_ERR "%s: resubmit read urb failed. "
+ "(%d)", __FUNCTION__, err);
}
}
return;
}
-static void
-option_outdat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
{
struct usb_serial_port *port;
@@ -376,8 +360,7 @@ option_outdat_callback (struct urb *urb, struct pt_regs *regs)
schedule_work(&port->work);
}
-static void
-option_instat_callback (struct urb *urb, struct pt_regs *regs)
+static void option_instat_callback(struct urb *urb, struct pt_regs *regs)
{
int err;
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)
dbg("%s: NULL req_pkt\n", __FUNCTION__);
return;
}
- if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) {
+ if ((req_pkt->bRequestType == 0xA1) &&
+ (req_pkt->bRequest == 0x20)) {
int old_dcd_state;
unsigned char signals = *((unsigned char *)
- urb->transfer_buffer + sizeof(struct usb_ctrlrequest));
+ urb->transfer_buffer +
+ sizeof(struct usb_ctrlrequest));
dbg("%s: signal x%x", __FUNCTION__, signals);
@@ -408,12 +393,13 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
portdata->ri_state = ((signals & 0x08) ? 1 : 0);
- if (port->tty && !C_CLOCAL(port->tty)
- && old_dcd_state && !portdata->dcd_state) {
+ if (port->tty && !C_CLOCAL(port->tty) &&
+ old_dcd_state && !portdata->dcd_state)
tty_hangup(port->tty);
- }
- } else
- dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest);
+ } else {
+ dbg("%s: type %x req %x", __FUNCTION__,
+ req_pkt->bRequestType,req_pkt->bRequest);
+ }
} else
dbg("%s: error %d", __FUNCTION__, urb->status);
@@ -422,13 +408,12 @@ option_instat_callback (struct urb *urb, struct pt_regs *regs)
urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
- dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err);
+ dbg("%s: resubmit intr urb failed. (%d)",
+ __FUNCTION__, err);
}
}
-
-static int
-option_write_room (struct usb_serial_port *port)
+static int option_write_room(struct usb_serial_port *port)
{
struct option_port_private *portdata;
int i;
@@ -447,9 +432,7 @@ option_write_room (struct usb_serial_port *port)
return data_len;
}
-
-static int
-option_chars_in_buffer (struct usb_serial_port *port)
+static int option_chars_in_buffer(struct usb_serial_port *port)
{
struct option_port_private *portdata;
int i;
@@ -467,9 +450,7 @@ option_chars_in_buffer (struct usb_serial_port *port)
return data_len;
}
-
-static int
-option_open (struct usb_serial_port *port, struct file *filp)
+static int option_open(struct usb_serial_port *port, struct file *filp)
{
struct option_port_private *portdata;
struct usb_serial *serial = port->serial;
@@ -490,17 +471,21 @@ option_open (struct usb_serial_port *port, struct file *filp)
if (! urb)
continue;
if (urb->dev != serial->dev) {
- dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev);
+ dbg("%s: dev %p != %p", __FUNCTION__,
+ urb->dev, serial->dev);
continue;
}
- /* make sure endpoint data toggle is synchronized with the device */
-
+ /*
+ * make sure endpoint data toggle is synchronized with the
+ * device
+ */
usb_clear_halt(urb->dev, urb->pipe);
err = usb_submit_urb(urb, GFP_KERNEL);
if (err) {
- dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err,
+ dbg("%s: submit urb %d failed (%d) %d",
+ __FUNCTION__, i, err,
urb->transfer_buffer_length);
}
}
@@ -511,7 +496,8 @@ option_open (struct usb_serial_port *port, struct file *filp)
if (! urb)
continue;
urb->dev = serial->dev;
- /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+ /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe), 0); */
}
port->tty->low_latency = 1;
@@ -521,17 +507,13 @@ option_open (struct usb_serial_port *port, struct file *filp)
return (0);
}
-static inline void
-stop_urb (struct urb *urb)
+static inline void stop_urb(struct urb *urb)
{
- if (urb && urb->status == -EINPROGRESS) {
- urb->transfer_flags &= ~URB_ASYNC_UNLINK;
+ if (urb && urb->status == -EINPROGRESS)
usb_kill_urb(urb);
- }
}
-static void
-option_close (struct usb_serial_port *port, struct file *filp)
+static void option_close(struct usb_serial_port *port, struct file *filp)
{
int i;
struct usb_serial *serial = port->serial;
@@ -555,12 +537,10 @@ option_close (struct usb_serial_port *port, struct file *filp)
port->tty = NULL;
}
-
/* Helper functions used by option_setup_urbs */
-static struct urb *
-option_setup_urb (struct usb_serial *serial, int endpoint,
- int dir, void *ctx, char *buf, int len,
- void (*callback)(struct urb *, struct pt_regs *regs))
+static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
+ int dir, void *ctx, char *buf, int len,
+ void (*callback)(struct urb *, struct pt_regs *regs))
{
struct urb *urb;
@@ -582,8 +562,7 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
}
/* Setup urbs */
-static void
-option_setup_urbs (struct usb_serial *serial)
+static void option_setup_urbs(struct usb_serial *serial)
{
int j;
struct usb_serial_port *port;
@@ -609,9 +588,7 @@ option_setup_urbs (struct usb_serial *serial)
}
}
-
-static int
-option_send_setup (struct usb_serial_port *port)
+static int option_send_setup(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct option_port_private *portdata;
@@ -627,16 +604,15 @@ option_send_setup (struct usb_serial_port *port)
if (portdata->rts_state)
val |= 0x02;
- return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+ return usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
}
return 0;
}
-
-static int
-option_startup (struct usb_serial *serial)
+static int option_startup(struct usb_serial *serial)
{
int i, err;
struct usb_serial_port *port;
@@ -647,9 +623,10 @@ option_startup (struct usb_serial *serial)
/* Now setup per port private data */
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
- portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL);
+ portdata = kmalloc(sizeof(*portdata), GFP_KERNEL);
if (!portdata) {
- dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i);
+ dbg("%s: kmalloc for option_port_private (%d) failed!.",
+ __FUNCTION__, i);
return (1);
}
memset(portdata, 0, sizeof(struct option_port_private));
@@ -660,7 +637,8 @@ option_startup (struct usb_serial *serial)
continue;
err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (err)
- dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err);
+ dbg("%s: submit irq_in urb failed %d",
+ __FUNCTION__, err);
}
option_setup_urbs(serial);
@@ -668,8 +646,7 @@ option_startup (struct usb_serial *serial)
return (0);
}
-static void
-option_shutdown (struct usb_serial *serial)
+static void option_shutdown(struct usb_serial *serial)
{
int i, j;
struct usb_serial_port *port;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 7eab5d4cf3a..461474176cf 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)
dbg("%s - port %d", __FUNCTION__, port->number);
- usb_clear_halt(serial->dev, port->write_urb->pipe);
- usb_clear_halt(serial->dev, port->read_urb->pipe);
+ if (priv->type != HX) {
+ usb_clear_halt(serial->dev, port->write_urb->pipe);
+ usb_clear_halt(serial->dev, port->read_urb->pipe);
+ }
buf = kmalloc(10, GFP_KERNEL);
if (buf==NULL)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0267b26dde1..e77fbdfc782 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -531,7 +531,7 @@ bailout_kref_put:
static void serial_close(struct tty_struct *tty, struct file * filp)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
if (!port)
return;
@@ -561,7 +561,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
int retval = -EINVAL;
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
@@ -580,7 +580,7 @@ exit:
static int serial_write_room (struct tty_struct *tty)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
int retval = -EINVAL;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -599,7 +599,7 @@ exit:
static int serial_chars_in_buffer (struct tty_struct *tty)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
int retval = -EINVAL;
dbg("%s = port %d", __FUNCTION__, port->number);
@@ -618,7 +618,7 @@ exit:
static void serial_throttle (struct tty_struct * tty)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -634,7 +634,7 @@ static void serial_throttle (struct tty_struct * tty)
static void serial_unthrottle (struct tty_struct * tty)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -650,7 +650,7 @@ static void serial_unthrottle (struct tty_struct * tty)
static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
int retval = -ENODEV;
dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
@@ -672,7 +672,7 @@ exit:
static void serial_set_termios (struct tty_struct *tty, struct termios * old)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -688,7 +688,7 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
static void serial_break (struct tty_struct *tty, int break_state)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -749,7 +749,7 @@ done:
static int serial_tiocmget (struct tty_struct *tty, struct file *file)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -768,7 +768,7 @@ exit:
static int serial_tiocmset (struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+ struct usb_serial_port *port = tty->driver_data;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -786,7 +786,7 @@ exit:
void usb_serial_port_softint(void *private)
{
- struct usb_serial_port *port = (struct usb_serial_port *)private;
+ struct usb_serial_port *port = private;
struct tty_struct *tty;
dbg("%s - port %d", __FUNCTION__, port->number);
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index f1f1c0608c2..bb9819cc882 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -111,3 +111,15 @@ config USB_STORAGE_JUMPSHOT
Say Y here to include additional code to support the Lexar Jumpshot
USB CompactFlash reader.
+
+config USB_STORAGE_ONETOUCH
+ bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
+ depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL
+ help
+ Say Y here to include additional code to support the Maxtor OneTouch
+ USB hard drive's onetouch button.
+
+ This code registers the button on the front of Maxtor OneTouch USB
+ hard drive's as an input device. An action can be associated with
+ this input in any keybinding software. (e.g. gnome's keyboard short-
+ cuts)
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 56652ccc288..44ab8f9978f 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,6 +18,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
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 00000000000..2c9402dc702
--- /dev/null
+++ b/drivers/usb/storage/onetouch.c
@@ -0,0 +1,210 @@
+/*
+ * Support for the Maxtor OneTouch USB hard drive's button
+ *
+ * Current development and maintenance by:
+ * Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
+ *
+ * Initial work by:
+ * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
+ *
+ * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_ch9.h>
+#include <linux/usb_input.h>
+#include "usb.h"
+#include "onetouch.h"
+#include "debug.h"
+
+void onetouch_release_input(void *onetouch_);
+
+struct usb_onetouch {
+ char name[128];
+ char phys[64];
+ struct input_dev dev; /* input device interface */
+ struct usb_device *udev; /* usb device */
+
+ struct urb *irq; /* urb for interrupt in report */
+ unsigned char *data; /* input data */
+ dma_addr_t data_dma;
+};
+
+static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_onetouch *onetouch = urb->context;
+ signed char *data = onetouch->data;
+ struct input_dev *dev = &onetouch->dev;
+ int status;
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+ case -ECONNRESET: /* unlink */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ /* -EPIPE: should clear the halt */
+ default: /* error */
+ goto resubmit;
+ }
+
+ input_regs(dev, regs);
+
+ input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
+ data[0] & 0x02);
+
+ input_sync(dev);
+resubmit:
+ status = usb_submit_urb (urb, SLAB_ATOMIC);
+ if (status)
+ err ("can't resubmit intr, %s-%s/input0, status %d",
+ onetouch->udev->bus->bus_name,
+ onetouch->udev->devpath, status);
+}
+
+static int usb_onetouch_open(struct input_dev *dev)
+{
+ struct usb_onetouch *onetouch = dev->private;
+
+ onetouch->irq->dev = onetouch->udev;
+ if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
+ err("usb_submit_urb failed");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void usb_onetouch_close(struct input_dev *dev)
+{
+ struct usb_onetouch *onetouch = dev->private;
+
+ usb_kill_urb(onetouch->irq);
+}
+
+int onetouch_connect_input(struct us_data *ss)
+{
+ struct usb_device *udev = ss->pusb_dev;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_onetouch *onetouch;
+ int pipe, maxp;
+ char path[64];
+
+ interface = ss->pusb_intf->cur_altsetting;
+
+ if (interface->desc.bNumEndpoints != 3)
+ return -ENODEV;
+
+ endpoint = &interface->endpoint[2].desc;
+ if(!(endpoint->bEndpointAddress & USB_DIR_IN))
+ return -ENODEV;
+ if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ != USB_ENDPOINT_XFER_INT)
+ return -ENODEV;
+
+ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+
+ if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
+ return -ENOMEM;
+
+ onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
+ SLAB_ATOMIC, &onetouch->data_dma);
+ if (!onetouch->data){
+ kfree(onetouch);
+ return -ENOMEM;
+ }
+
+ onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!onetouch->irq){
+ kfree(onetouch);
+ usb_buffer_free(udev, ONETOUCH_PKT_LEN,
+ onetouch->data, onetouch->data_dma);
+ return -ENODEV;
+ }
+
+
+ onetouch->udev = udev;
+
+ set_bit(EV_KEY, onetouch->dev.evbit);
+ set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
+ clear_bit(0, onetouch->dev.keybit);
+
+ onetouch->dev.private = onetouch;
+ onetouch->dev.open = usb_onetouch_open;
+ onetouch->dev.close = usb_onetouch_close;
+
+ usb_make_path(udev, path, sizeof(path));
+ sprintf(onetouch->phys, "%s/input0", path);
+
+ onetouch->dev.name = onetouch->name;
+ onetouch->dev.phys = onetouch->phys;
+
+ usb_to_input_id(udev, &onetouch->dev.id);
+
+ onetouch->dev.dev = &udev->dev;
+
+ if (udev->manufacturer)
+ strcat(onetouch->name, udev->manufacturer);
+ if (udev->product)
+ sprintf(onetouch->name, "%s %s", onetouch->name,
+ udev->product);
+ if (!strlen(onetouch->name))
+ sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
+ onetouch->dev.id.vendor, onetouch->dev.id.product);
+
+ usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
+ (maxp > 8 ? 8 : maxp),
+ usb_onetouch_irq, onetouch, endpoint->bInterval);
+ onetouch->irq->transfer_dma = onetouch->data_dma;
+ onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ ss->extra_destructor = onetouch_release_input;
+ ss->extra = onetouch;
+
+ input_register_device(&onetouch->dev);
+ printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
+
+ return 0;
+}
+
+void onetouch_release_input(void *onetouch_)
+{
+ struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_;
+
+ if (onetouch) {
+ usb_kill_urb(onetouch->irq);
+ input_unregister_device(&onetouch->dev);
+ usb_free_urb(onetouch->irq);
+ usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
+ onetouch->data, onetouch->data_dma);
+ printk(KERN_INFO "usb-input: deregistering %s\n",
+ onetouch->dev.name);
+ }
+}
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
new file mode 100644
index 00000000000..41c7aa8f044
--- /dev/null
+++ b/drivers/usb/storage/onetouch.h
@@ -0,0 +1,9 @@
+#ifndef _ONETOUCH_H_
+#define _ONETOUCH_H_
+
+#define ONETOUCH_PKT_LEN 0x02
+#define ONETOUCH_BUTTON KEY_PROG1
+
+int onetouch_connect_input(struct us_data *ss);
+
+#endif
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index af294bb68c3..d34dc9f417f 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)
if (us->flags & US_FL_FIX_CAPACITY)
sdev->fix_capacity = 1;
+ /* Some devices report a SCSI revision level above 2 but are
+ * unable to handle the REPORT LUNS command (for which
+ * support is mandatory at level 3). Since we already have
+ * a Get-Max-LUN request, we won't lose much by setting the
+ * revision level down to 2. The only devices that would be
+ * affected are those with sparse LUNs. */
+ sdev->scsi_level = SCSI_2;
+
/* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
* Hardware Error) when any low-level error occurs,
* 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 f3b60288696..356342c6e7a 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,
rc = usbat_device_reset(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
+ msleep(25);
/*
- * By examining the device signature after a reset, we can identify
- * whether the device supports the ATAPI packet interface.
- * The flash-devices do not support this, whereas the HP CDRW's obviously
- * do.
- *
- * This method is not ideal, but works because no other devices have been
- * produced based on the USBAT/USBAT02.
- *
- * Section 9.1 of the ATAPI-4 spec states (amongst other things) that
- * after a device reset, a Cylinder low of 0x14 indicates that the device
- * does support packet commands.
+ * In attempt to distinguish between HP CDRW's and Flash readers, we now
+ * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash
+ * readers), this command should fail with error. On ATAPI devices (i.e.
+ * CDROM drives), it should succeed.
*/
- rc = usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, &status);
- if (rc != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
+ rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1);
+ if (rc != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("usbat_identify_device: Cylinder low is %02X\n", status);
+ rc = usbat_get_status(us, &status);
+ if (rc != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
- if (status == 0x14) {
+ // Check for error bit
+ if (status & 0x01) {
+ // Device is a CompactFlash reader/writer
+ US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
+ info->devicetype = USBAT_DEV_FLASH;
+ } else {
// Device is HP 8200
US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");
info->devicetype = USBAT_DEV_HP8200;
- } else {
- // Device is a CompactFlash reader/writer
- US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");
- info->devicetype = USBAT_DEV_FLASH;
}
return USB_STOR_TRANSPORT_GOOD;
@@ -1239,16 +1236,10 @@ static int usbat_select_and_test_registers(struct us_data *us)
{
int selector;
unsigned char *status = us->iobuf;
- unsigned char max_selector = 0xB0;
- if (usbat_get_device_type(us) == USBAT_DEV_FLASH)
- max_selector = 0xA0;
// try device = master, then device = slave.
-
- for (selector = 0xA0; selector <= max_selector; selector += 0x10) {
-
- if (usbat_get_device_type(us) == USBAT_DEV_HP8200 &&
- usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
+ for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
+ if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=
USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
@@ -1334,60 +1325,30 @@ int init_usbat(struct us_data *us)
US_DEBUGP("INIT 3\n");
- // At this point, we need to detect which device we are using
- if (usbat_set_transport(us, info))
- return USB_STOR_TRANSPORT_ERROR;
-
- US_DEBUGP("INIT 4\n");
-
- if (usbat_get_device_type(us) == USBAT_DEV_HP8200) {
- msleep(250);
-
- // Write 0x80 to ISA port 0x3F
- rc = usbat_write(us, USBAT_ISA, 0x3F, 0x80);
- if (rc != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- US_DEBUGP("INIT 5\n");
-
- // Read ISA port 0x27
- rc = usbat_read(us, USBAT_ISA, 0x27, status);
- if (rc != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- US_DEBUGP("INIT 6\n");
-
- rc = usbat_read_user_io(us, status);
- if (rc != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- US_DEBUGP("INIT 7\n");
- }
-
rc = usbat_select_and_test_registers(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- US_DEBUGP("INIT 8\n");
+ US_DEBUGP("INIT 4\n");
rc = usbat_read_user_io(us, status);
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("INIT 9\n");
+ US_DEBUGP("INIT 5\n");
// Enable peripheral control signals and card detect
rc = usbat_device_enable_cdt(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- US_DEBUGP("INIT 10\n");
+ US_DEBUGP("INIT 6\n");
rc = usbat_read_user_io(us, status);
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("INIT 11\n");
+ US_DEBUGP("INIT 7\n");
msleep(1400);
@@ -1395,13 +1356,19 @@ int init_usbat(struct us_data *us)
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("INIT 12\n");
+ US_DEBUGP("INIT 8\n");
rc = usbat_select_and_test_registers(us);
if (rc != USB_STOR_TRANSPORT_GOOD)
return rc;
- US_DEBUGP("INIT 13\n");
+ US_DEBUGP("INIT 9\n");
+
+ // At this point, we need to detect which device we are using
+ if (usbat_set_transport(us, info))
+ return USB_STOR_TRANSPORT_ERROR;
+
+ US_DEBUGP("INIT 10\n");
if (usbat_get_device_type(us) == USBAT_DEV_FLASH) {
subcountH = 0x02;
@@ -1412,7 +1379,7 @@ int init_usbat(struct us_data *us)
if (rc != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- US_DEBUGP("INIT 14\n");
+ US_DEBUGP("INIT 11\n");
return USB_STOR_TRANSPORT_GOOD;
}
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e6b1c6cf07f..c1ba5301ebf 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -96,8 +96,8 @@
* or before the URB_ACTIVE bit was set. If so, it's essential to cancel
* the URB if it hasn't been cancelled already (i.e., if the URB_ACTIVE bit
* is still set). Either way, the function must then wait for the URB to
- * finish. Note that because the URB_ASYNC_UNLINK flag is set, the URB can
- * still be in progress even after a call to usb_unlink_urb() returns.
+ * finish. Note that the URB can still be in progress even after a call to
+ * usb_unlink_urb() returns.
*
* The idea is that (1) once the ABORTING or DISCONNECTING bit is set,
* 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)
* hasn't been mapped for DMA. Yes, this is clunky, but it's
* easier than always having the caller tell us whether the
* transfer buffer has already been mapped. */
- us->current_urb->transfer_flags =
- URB_ASYNC_UNLINK | URB_NO_SETUP_DMA_MAP;
+ us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
if (us->current_urb->transfer_buffer == us->iobuf)
us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
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)
unsigned char old_sc_data_direction;
unsigned char old_cmd_len;
unsigned char old_cmnd[MAX_COMMAND_SIZE];
- unsigned long old_serial_number;
int old_resid;
US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
@@ -648,10 +646,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
old_sg = srb->use_sg;
srb->use_sg = 0;
- /* change the serial number -- toggle the high bit*/
- old_serial_number = srb->serial_number;
- srb->serial_number ^= 0x80000000;
-
/* issue the auto-sense command */
old_resid = srb->resid;
srb->resid = 0;
@@ -662,7 +656,6 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
srb->request_buffer = old_request_buffer;
srb->request_bufflen = old_request_bufflen;
srb->use_sg = old_sg;
- srb->serial_number = old_serial_number;
srb->sc_data_direction = old_sc_data_direction;
srb->cmd_len = old_cmd_len;
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)
bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
bcb->DataTransferLength = cpu_to_le32(transfer_length);
bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
- bcb->Tag = srb->serial_number;
+ bcb->Tag = ++us->tag;
bcb->Lun = srb->device->lun;
if (us->flags & US_FL_SCM_MULT_TARG)
bcb->Lun |= srb->device->id << 4;
@@ -1074,7 +1067,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
le32_to_cpu(bcs->Signature), bcs->Tag,
residue, bcs->Status);
- if (bcs->Tag != srb->serial_number || bcs->Status > US_BULK_STAT_PHASE) {
+ if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) {
US_DEBUGP("Bulk logical error\n");
return USB_STOR_TRANSPORT_ERROR;
}
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index bd0ab3039bd..ad0cfd7a782 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,
US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0),
#endif
+/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
+UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003,
+ "VIA Technologies Inc.",
+ "USB 2.0 Card Reader",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
* Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
* always fails and confuses drive.
@@ -929,6 +936,18 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
US_FL_SINGLE_LUN ),
#endif
+/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+ * Needed for OneTouch extension to usb-storage
+ *
+ */
+#ifdef CONFIG_USB_STORAGE_ONETOUCH
+ UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
+#endif
+
/* Submitted by Joris Struyve <joris@struyve.be> */
UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
"Medion",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 77e7fc258aa..cb4c770baf3 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -90,7 +90,9 @@
#ifdef CONFIG_USB_STORAGE_JUMPSHOT
#include "jumpshot.h"
#endif
-
+#ifdef CONFIG_USB_STORAGE_ONETOUCH
+#include "onetouch.h"
+#endif
/* Some informational data */
MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -786,6 +788,7 @@ static void usb_stor_release_resources(struct us_data *us)
* any more commands.
*/
US_DEBUGP("-- sending exit command to thread\n");
+ set_bit(US_FLIDX_DISCONNECTING, &us->flags);
up(&us->sema);
/* Call the destructor routine, if it exists */
@@ -816,6 +819,49 @@ static void dissociate_dev(struct us_data *us)
usb_set_intfdata(us->pusb_intf, NULL);
}
+/* First stage of disconnect processing: stop all commands and remove
+ * the host */
+static void quiesce_and_remove_host(struct us_data *us)
+{
+ /* Prevent new USB transfers, stop the current command, and
+ * interrupt a SCSI-scan or device-reset delay */
+ set_bit(US_FLIDX_DISCONNECTING, &us->flags);
+ usb_stor_stop_transport(us);
+ wake_up(&us->delay_wait);
+
+ /* It doesn't matter if the SCSI-scanning thread is still running.
+ * The thread will exit when it sees the DISCONNECTING flag. */
+
+ /* Wait for the current command to finish, then remove the host */
+ down(&us->dev_semaphore);
+ up(&us->dev_semaphore);
+
+ /* queuecommand won't accept any new commands and the control
+ * thread won't execute a previously-queued command. If there
+ * is such a command pending, complete it with an error. */
+ if (us->srb) {
+ us->srb->result = DID_NO_CONNECT << 16;
+ scsi_lock(us_to_host(us));
+ us->srb->scsi_done(us->srb);
+ us->srb = NULL;
+ scsi_unlock(us_to_host(us));
+ }
+
+ /* Now we own no commands so it's safe to remove the SCSI host */
+ scsi_remove_host(us_to_host(us));
+}
+
+/* Second stage of disconnect processing: deallocate all resources */
+static void release_everything(struct us_data *us)
+{
+ usb_stor_release_resources(us);
+ dissociate_dev(us);
+
+ /* Drop our reference to the host; the SCSI core will free it
+ * (and "us" along with it) when the refcount becomes 0. */
+ scsi_host_put(us_to_host(us));
+}
+
/* Thread to carry out delayed SCSI-device scanning */
static int usb_stor_scan_thread(void * __us)
{
@@ -956,7 +1002,7 @@ static int storage_probe(struct usb_interface *intf,
if (result < 0) {
printk(KERN_WARNING USB_STORAGE
"Unable to start the device-scanning thread\n");
- scsi_remove_host(host);
+ quiesce_and_remove_host(us);
goto BadDevice;
}
atomic_inc(&total_threads);
@@ -969,10 +1015,7 @@ static int storage_probe(struct usb_interface *intf,
/* We come here if there are any problems */
BadDevice:
US_DEBUGP("storage_probe() failed\n");
- set_bit(US_FLIDX_DISCONNECTING, &us->flags);
- usb_stor_release_resources(us);
- dissociate_dev(us);
- scsi_host_put(host);
+ release_everything(us);
return result;
}
@@ -982,28 +1025,8 @@ static void storage_disconnect(struct usb_interface *intf)
struct us_data *us = usb_get_intfdata(intf);
US_DEBUGP("storage_disconnect() called\n");
-
- /* Prevent new USB transfers, stop the current command, and
- * interrupt a SCSI-scan or device-reset delay */
- set_bit(US_FLIDX_DISCONNECTING, &us->flags);
- usb_stor_stop_transport(us);
- wake_up(&us->delay_wait);
-
- /* It doesn't matter if the SCSI-scanning thread is still running.
- * The thread will exit when it sees the DISCONNECTING flag. */
-
- /* Wait for the current command to finish, then remove the host */
- down(&us->dev_semaphore);
- up(&us->dev_semaphore);
- scsi_remove_host(us_to_host(us));
-
- /* Wait for everything to become idle and release all our resources */
- usb_stor_release_resources(us);
- dissociate_dev(us);
-
- /* Drop our reference to the host; the SCSI core will free it
- * (and "us" along with it) when the refcount becomes 0. */
- scsi_host_put(us_to_host(us));
+ quiesce_and_remove_host(us);
+ release_everything(us);
}
/***********************************************************************
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 625b7aa9807..a195adae57b 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -158,6 +158,7 @@ struct us_data {
/* SCSI interfaces */
struct scsi_cmnd *srb; /* current srb */
+ unsigned int tag; /* current dCBWTag */
/* thread information */
int pid; /* control thread */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index cde0ed097af..615874e03ce 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -650,7 +650,6 @@ config FB_NVIDIA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
@@ -681,7 +680,6 @@ config FB_RIVA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports graphics boards with the nVidia Riva/Geforce
chips.
@@ -720,7 +718,6 @@ config FB_I810
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports the on-board graphics built in to the Intel 810
and 815 chipsets. Say Y if you have and plan to use such a board.
@@ -754,6 +751,12 @@ config FB_I810_GTF
If unsure, say N.
+config FB_I810_I2C
+ bool "Enable DDC Support"
+ depends on FB_I810 && I2C && FB_I810_GTF
+ select I2C_ALGOBIT
+ help
+
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
@@ -763,7 +766,6 @@ config FB_INTEL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports the on-board graphics built in to the Intel
830M/845G/852GM/855GM/865G chipsets.
@@ -960,8 +962,7 @@ config FB_RADEON
can be build either as modules or built-in.
There is a product page at
- <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
-
+ http://apps.ati.com/ATIcompare/
config FB_RADEON_I2C
bool "DDC/I2C for ATI Radeon support"
depends on FB_RADEON
@@ -1084,15 +1085,16 @@ config FB_SAVAGE_ACCEL
choose N here.
config FB_SIS
- tristate "SiS acceleration"
+ tristate "SiS/XGI display support"
depends on FB && PCI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
help
- This is the frame buffer device driver for the SiS 300, 315 and
- 330 series VGA chipsets. Specs available at <http://www.sis.com>
+ This is the frame buffer device driver for the SiS 300, 315, 330
+ and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+ Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
To compile this driver as a module, choose M here; the module
will be called sisfb.
@@ -1104,11 +1106,12 @@ config FB_SIS_300
Say Y here to support use of the SiS 300/305, 540, 630 and 730.
config FB_SIS_315
- bool "SiS 315/330 series support"
+ bool "SiS 315/330/340 series and XGI support"
depends on FB_SIS
help
- Say Y here to support use of the SiS 315 and 330 series
- (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760).
+ Say Y here to support use of the SiS 315, 330 and 340 series
+ (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+ as XGI V3XT, V5, V8 and Z7.
config FB_NEOMAGIC
tristate "NeoMagic display support"
@@ -1180,6 +1183,32 @@ config FB_VOODOO1
Please read the <file:Documentation/fb/README-sstfb.txt> for supported
options and other important info support.
+config FB_CYBLA
+ tristate "Cyberblade/i1 support"
+ depends on FB && PCI
+ select FB_CFB_IMAGEBLIT
+ select FB_SOFT_CURSOR
+ select VIDEO_SELECT
+ ---help---
+ This driver is supposed to support the Trident Cyberblade/i1
+ graphics core integrated in the VIA VT8601A North Bridge,
+ also known as VIA Apollo PLE133.
+
+ Status:
+ - Developed, tested and working on EPIA 5000 and EPIA 800.
+ - Does work reliable on all systems with CRT/LCD connected to
+ normal VGA ports.
+ - Should work on systems that do use the internal LCD port, but
+ this is absolutely not tested.
+
+ Character imageblit, copyarea and rectangle fill are hw accelerated,
+ ypan scrolling is used by default.
+
+ Please do read <file:Documentation/fb/cyblafb/*>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cyblafb.
+
config FB_TRIDENT
tristate "Trident support"
depends on FB && PCI
@@ -1193,8 +1222,12 @@ config FB_TRIDENT
but also on some motherboards. For more information, read
<file:Documentation/fb/tridentfb.txt>
+ Cyberblade/i1 support will be removed soon, use the cyblafb driver
+ instead.
+
Say Y if you have such a graphics board.
+
To compile this driver as a module, choose M here: the
module will be called tridentfb.
@@ -1205,7 +1238,6 @@ config FB_TRIDENT_ACCEL
This will compile the Trident frame buffer device with
acceleration functions.
-
config FB_PM3
tristate "Permedia3 support"
depends on FB && PCI && BROKEN
@@ -1484,6 +1516,30 @@ config FB_S1D13XXX
working with S1D13806). Product specs at
<http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+config FB_S3C2410
+ tristate "S3C2410 LCD framebuffer support"
+ depends on FB && ARCH_S3C2410
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_SOFT_CURSOR
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Samsung
+ S3C2410 processor.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called s3c2410fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/modules.txt>.
+
+ If unsure, say N.
+config FB_S3C2410_DEBUG
+ bool "S3C2410 lcd debug messages"
+ depends on FB_S3C2410
+ help
+ Turn on debugging messages. Note that you can set/unset at run time
+ through sysfs
+
config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index b018df4e95c..1fff29f48ca 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -9,7 +9,8 @@ obj-$(CONFIG_LOGO) += logo/
obj-$(CONFIG_SYSFS) += backlight/
obj-$(CONFIG_FB) += fb.o
-fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o
+fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+ modedb.o fbcvt.o
fb-objs := $(fb-y)
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
@@ -50,7 +51,8 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
-obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
+obj-$(CONFIG_FB_CYBLA) += cyblafb.o
+obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_STI) += stifb.o
obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -92,6 +94,7 @@ obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_TX3912) += tx3912fb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
+obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index b0eba3ac642..e380ee8b024 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
/* Very simple test to make sure it appeared */
if (BIOS_IN16(0) != 0xaa55) {
- printk(KERN_ERR "aty128fb: Invalid ROM signature %x should be 0xaa55\n",
- BIOS_IN16(0));
+ printk(KERN_DEBUG "aty128fb: Invalid ROM signature %x should "
+ " be 0xaa55\n", BIOS_IN16(0));
goto failed;
}
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3e10bd837d9..037fe9d32fe 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,
vdisplay = par->lcd_height;
#endif
- if(vdisplay < 400) {
- h_sync_pol = 1;
- v_sync_pol = 0;
- } else if(vdisplay < 480) {
- h_sync_pol = 0;
- v_sync_pol = 1;
- } else if(vdisplay < 768) {
- h_sync_pol = 0;
- v_sync_pol = 0;
- } else {
- h_sync_pol = 1;
- v_sync_pol = 1;
- }
-
v_disp--;
v_sync_strt--;
v_sync_end--;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index e7e8b52014c..046b4786026 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
/* Very simple test to make sure it appeared */
if (BIOS_IN16(0) != 0xaa55) {
- printk(KERN_ERR "radeonfb (%s): Invalid ROM signature %x should be"
- "0xaa55\n", pci_name(rinfo->pdev), BIOS_IN16(0));
+ printk(KERN_DEBUG "radeonfb (%s): Invalid ROM signature %x "
+ "should be 0xaa55\n",
+ pci_name(rinfo->pdev), BIOS_IN16(0));
goto failed;
}
/* Look for the PCI data to check the ROM type */
@@ -2312,19 +2313,27 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
/* request the mem regions */
- ret = pci_request_regions(pdev, "radeonfb");
+ ret = pci_request_region(pdev, 0, "radeonfb framebuffer");
if (ret < 0) {
- printk( KERN_ERR "radeonfb (%s): cannot reserve PCI regions."
- " Someone already got them?\n", pci_name(rinfo->pdev));
+ printk( KERN_ERR "radeonfb (%s): cannot request region 0.\n",
+ pci_name(rinfo->pdev));
goto err_release_fb;
}
+ ret = pci_request_region(pdev, 2, "radeonfb mmio");
+ if (ret < 0) {
+ printk( KERN_ERR "radeonfb (%s): cannot request region 2.\n",
+ pci_name(rinfo->pdev));
+ goto err_release_pci0;
+ }
+
/* map the regions */
rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
if (!rinfo->mmio_base) {
- printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n", pci_name(rinfo->pdev));
+ printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n",
+ pci_name(rinfo->pdev));
ret = -EIO;
- goto err_release_pci;
+ goto err_release_pci2;
}
rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
@@ -2499,10 +2508,12 @@ err_unmap_rom:
if (rinfo->bios_seg)
radeon_unmap_ROM(rinfo, pdev);
iounmap(rinfo->mmio_base);
-err_release_pci:
- pci_release_regions(pdev);
+err_release_pci2:
+ pci_release_region(pdev, 2);
+err_release_pci0:
+ pci_release_region(pdev, 0);
err_release_fb:
- framebuffer_release(info);
+ framebuffer_release(info);
err_disable:
pci_disable_device(pdev);
err_out:
@@ -2548,7 +2559,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
iounmap(rinfo->mmio_base);
iounmap(rinfo->fb_base);
- pci_release_regions(pdev);
+ pci_release_region(pdev, 2);
+ pci_release_region(pdev, 0);
kfree(rinfo->mon1_EDID);
kfree(rinfo->mon2_EDID);
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 3c731577fed..9f70e512b88 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)
{
int attribute = 0;
- if (fb_get_color_depth(&info->var) == 1) {
+ if (fb_get_color_depth(&info->var, &info->fix) == 1) {
if (attr_underline(c))
attribute |= FBCON_ATTRIBUTE_UNDERLINE;
if (attr_reverse(c))
@@ -103,42 +103,104 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
info->fbops->fb_fillrect(info, &region);
}
+static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
+ const u16 *s, u32 attr, u32 cnt,
+ u32 d_pitch, u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf, u8 *dst)
+{
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 idx = vc->vc_font.width >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = vc->vc_font.data + (scr_readw(s++)&
+ charmask)*cellsize;
+
+ if (attr) {
+ update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ if (likely(idx == 1))
+ __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ image->height);
+ else
+ fb_pad_aligned_buffer(dst, d_pitch, src, idx,
+ image->height);
+
+ dst += s_pitch;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+}
+
+static inline void bit_putcs_unaligned(struct vc_data *vc,
+ struct fb_info *info, const u16 *s,
+ u32 attr, u32 cnt, u32 d_pitch,
+ u32 s_pitch, u32 cellsize,
+ struct fb_image *image, u8 *buf,
+ u8 *dst)
+{
+ u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ u32 shift_low = 0, mod = vc->vc_font.width % 8;
+ u32 shift_high = 8;
+ u32 idx = vc->vc_font.width >> 3;
+ u8 *src;
+
+ while (cnt--) {
+ src = vc->vc_font.data + (scr_readw(s++)&
+ charmask)*cellsize;
+
+ if (attr) {
+ update_attr(buf, src, attr, vc);
+ src = buf;
+ }
+
+ fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
+ image->height, shift_high,
+ shift_low, mod);
+ shift_low += mod;
+ dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
+ shift_low &= 7;
+ shift_high = 8 - shift_low;
+ }
+
+ info->fbops->fb_imageblit(info, image);
+
+}
+
static void bit_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- unsigned int width = (vc->vc_font.width + 7) >> 3;
- unsigned int cellsize = vc->vc_font.height * width;
- unsigned int maxcnt = info->pixmap.size/cellsize;
- unsigned int scan_align = info->pixmap.scan_align - 1;
- unsigned int buf_align = info->pixmap.buf_align - 1;
- unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
- unsigned int shift_high = 8, pitch, cnt, size, k;
- unsigned int idx = vc->vc_font.width >> 3;
- unsigned int attribute = get_attribute(info, scr_readw(s));
struct fb_image image;
- u8 *src, *dst, *buf = NULL;
-
- if (attribute) {
- buf = kmalloc(cellsize, GFP_KERNEL);
- if (!buf)
- return;
- }
+ u32 width = (vc->vc_font.width + 7)/8;
+ u32 cellsize = width * vc->vc_font.height;
+ u32 maxcnt = info->pixmap.size/cellsize;
+ u32 scan_align = info->pixmap.scan_align - 1;
+ u32 buf_align = info->pixmap.buf_align - 1;
+ u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
+ u32 attribute = get_attribute(info, scr_readw(s));
+ u8 *dst, *buf = NULL;
image.fg_color = fg;
image.bg_color = bg;
-
image.dx = xx * vc->vc_font.width;
image.dy = yy * vc->vc_font.height;
image.height = vc->vc_font.height;
image.depth = 1;
+ if (attribute) {
+ buf = kmalloc(cellsize, GFP_KERNEL);
+ if (!buf)
+ return;
+ }
+
while (count) {
if (count > maxcnt)
- cnt = k = maxcnt;
+ cnt = maxcnt;
else
- cnt = k = count;
+ cnt = count;
image.width = vc->vc_font.width * cnt;
pitch = ((image.width + 7) >> 3) + scan_align;
@@ -147,41 +209,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
- if (mod) {
- while (k--) {
- src = vc->vc_font.data + (scr_readw(s++)&
- charmask)*cellsize;
-
- if (attribute) {
- update_attr(buf, src, attribute, vc);
- src = buf;
- }
-
- fb_pad_unaligned_buffer(dst, pitch, src, idx,
- image.height, shift_high,
- shift_low, mod);
- shift_low += mod;
- dst += (shift_low >= 8) ? width : width - 1;
- shift_low &= 7;
- shift_high = 8 - shift_low;
- }
- } else {
- while (k--) {
- src = vc->vc_font.data + (scr_readw(s++)&
- charmask)*cellsize;
-
- if (attribute) {
- update_attr(buf, src, attribute, vc);
- src = buf;
- }
-
- fb_pad_aligned_buffer(dst, pitch, src, idx, image.height);
- dst += width;
- }
- }
- info->fbops->fb_imageblit(info, &image);
+
+ if (!mod)
+ bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
+ width, cellsize, &image, buf, dst);
+ else
+ bit_putcs_unaligned(vc, info, s, attribute, cnt,
+ pitch, width, cellsize, &image,
+ buf, dst);
+
image.dx += cnt * vc->vc_font.width;
count -= cnt;
+ s += cnt;
}
/* 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,
NULL pointers just fine */
if (unlikely(buf))
kfree(buf);
+
}
static 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 35c88bd7ba5..2e93224d2d5 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)
static inline int get_color(struct vc_data *vc, struct fb_info *info,
u16 c, int is_fg)
{
- int depth = fb_get_color_depth(&info->var);
+ int depth = fb_get_color_depth(&info->var, &info->fix);
int color = 0;
if (console_blanked) {
@@ -230,9 +230,13 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
switch (depth) {
case 1:
{
+ int col = ~(0xfff << (max(info->var.green.length,
+ max(info->var.red.length,
+ info->var.blue.length)))) & 0xff;
+
/* 0 or 1 */
- int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0;
- int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1;
+ int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
+ int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
if (console_blanked)
fg = bg;
@@ -243,9 +247,25 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
case 2:
/*
* Scale down 16-colors to 4 colors. Default 4-color palette
- * is grayscale.
+ * is grayscale. However, simply dividing the values by 4
+ * will not work, as colors 1, 2 and 3 will be scaled-down
+ * to zero rendering them invisible. So empirically convert
+ * colors to a sane 4-level grayscale.
*/
- color /= 4;
+ switch (color) {
+ case 0:
+ color = 0; /* black */
+ break;
+ case 1 ... 6:
+ color = 2; /* white */
+ break;
+ case 7 ... 8:
+ color = 1; /* gray */
+ break;
+ default:
+ color = 3; /* intense white */
+ break;
+ }
break;
case 3:
/*
@@ -311,6 +331,35 @@ static void cursor_timer_handler(unsigned long dev_addr)
mod_timer(&ops->cursor_timer, jiffies + HZ/5);
}
+static void fbcon_add_cursor_timer(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+
+ if ((!info->queue.func || info->queue.func == fb_flashcursor) &&
+ !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {
+ if (!info->queue.func)
+ INIT_WORK(&info->queue, fb_flashcursor, info);
+
+ init_timer(&ops->cursor_timer);
+ ops->cursor_timer.function = cursor_timer_handler;
+ ops->cursor_timer.expires = jiffies + HZ / 5;
+ ops->cursor_timer.data = (unsigned long ) info;
+ add_timer(&ops->cursor_timer);
+ ops->flags |= FBCON_FLAGS_CURSOR_TIMER;
+ }
+}
+
+static void fbcon_del_cursor_timer(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+
+ if (info->queue.func == fb_flashcursor &&
+ ops->flags & FBCON_FLAGS_CURSOR_TIMER) {
+ del_timer_sync(&ops->cursor_timer);
+ ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER;
+ }
+}
+
#ifndef MODULE
static int __init fb_console_setup(char *this_opt)
{
@@ -426,7 +475,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
* remove underline attribute from erase character
* if black and white framebuffer.
*/
- if (fb_get_color_depth(&info->var) == 1)
+ if (fb_get_color_depth(&info->var, &info->fix) == 1)
erase &= ~0x400;
logo_height = fb_prepare_logo(info);
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,
}
if (!err) {
- if (oldinfo->queue.func == fb_flashcursor)
- del_timer_sync(&ops->cursor_timer);
-
+ fbcon_del_cursor_timer(oldinfo);
kfree(ops->cursor_state.mask);
kfree(ops->cursor_data);
kfree(oldinfo->fbcon_par);
@@ -576,22 +623,6 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
return err;
}
-static void con2fb_init_newinfo(struct fb_info *info)
-{
- if (!info->queue.func || info->queue.func == fb_flashcursor) {
- struct fbcon_ops *ops = info->fbcon_par;
-
- if (!info->queue.func)
- INIT_WORK(&info->queue, fb_flashcursor, info);
-
- init_timer(&ops->cursor_timer);
- ops->cursor_timer.function = cursor_timer_handler;
- ops->cursor_timer.expires = jiffies + HZ / 5;
- ops->cursor_timer.data = (unsigned long ) info;
- add_timer(&ops->cursor_timer);
- }
-}
-
static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
int unit, int show_logo)
{
@@ -675,7 +706,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
logo_shown != FBCON_LOGO_DONTSHOW);
if (!found)
- con2fb_init_newinfo(info);
+ fbcon_add_cursor_timer(info);
con2fb_map_boot[unit] = newidx;
con2fb_init_display(vc, info, unit, show_logo);
}
@@ -878,18 +909,7 @@ static const char *fbcon_startup(void)
}
#endif /* CONFIG_MAC */
- /* Initialize the work queue. If the driver provides its
- * own work queue this means it will use something besides
- * default timer to flash the cursor. */
- if (!info->queue.func) {
- INIT_WORK(&info->queue, fb_flashcursor, info);
-
- init_timer(&ops->cursor_timer);
- ops->cursor_timer.function = cursor_timer_handler;
- ops->cursor_timer.expires = jiffies + HZ / 5;
- ops->cursor_timer.data = (unsigned long ) info;
- add_timer(&ops->cursor_timer);
- }
+ fbcon_add_cursor_timer(info);
return display_desc;
}
@@ -930,7 +950,7 @@ static void fbcon_init(struct vc_data *vc, int init)
}
if (p->userfont)
charcnt = FNTCHARCNT(p->fontdata);
- vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1);
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (charcnt == 256) {
vc->vc_hi_font_mask = 0;
@@ -1178,7 +1198,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
if (p->userfont)
charcnt = FNTCHARCNT(p->fontdata);
- vc->vc_can_do_color = (fb_get_color_depth(var) != 1);
+ var->activate = FB_ACTIVATE_NOW;
+ info->var.activate = var->activate;
+ info->var.yoffset = info->var.xoffset = 0;
+ fb_set_var(info, var);
+
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (charcnt == 256) {
vc->vc_hi_font_mask = 0;
@@ -1898,7 +1923,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
static int fbcon_switch(struct vc_data *vc)
{
- struct fb_info *info;
+ struct fb_info *info, *old_info = NULL;
struct display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var;
int i, prev_console;
@@ -1931,7 +1956,8 @@ static int fbcon_switch(struct vc_data *vc)
}
prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon;
-
+ if (prev_console != -1)
+ old_info = registered_fb[con2fb_map[prev_console]];
/*
* FIXME: If we have multiple fbdev's loaded, we need to
* update all info->currcon. Perhaps, we can place this
@@ -1959,15 +1985,17 @@ static int fbcon_switch(struct vc_data *vc)
info->var.yoffset = info->var.xoffset = p->yscroll = 0;
fb_set_var(info, &var);
- if (prev_console != -1 &&
- registered_fb[con2fb_map[prev_console]] != info &&
- info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
+ if (old_info != NULL && old_info != info) {
+ if (info->fbops->fb_set_par)
+ info->fbops->fb_set_par(info);
+ fbcon_del_cursor_timer(old_info);
+ fbcon_add_cursor_timer(info);
+ }
set_blitting_type(vc, info, p);
((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
- vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1);
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
updatescrollmode(p, info, vc);
@@ -2048,11 +2076,16 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
fbcon_generic_blank(vc, info, blank);
}
- if (!blank)
- update_screen(vc);
- }
+ if (!blank)
+ update_screen(vc);
+ }
- return 0;
+ if (!blank)
+ fbcon_add_cursor_timer(info);
+ else
+ fbcon_del_cursor_timer(info);
+
+ return 0;
}
static void fbcon_free_font(struct display *p)
@@ -2332,7 +2365,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
if (!CON_IS_VISIBLE(vc))
return 0;
- depth = fb_get_color_depth(&info->var);
+ depth = fb_get_color_depth(&info->var, &info->fix);
if (depth > 3) {
for (i = j = 0; i < 16; i++) {
k = table[i];
@@ -2593,6 +2626,51 @@ static void fbcon_modechanged(struct fb_info *info)
}
}
+static void fbcon_set_all_vcs(struct fb_info *info)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ struct vc_data *vc;
+ struct display *p;
+ int i, rows, cols;
+
+ if (!ops || ops->currcon < 0)
+ return;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ vc = vc_cons[i].d;
+ if (!vc || vc->vc_mode != KD_TEXT ||
+ registered_fb[con2fb_map[i]] != info)
+ continue;
+
+ p = &fb_display[vc->vc_num];
+
+ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+ var_to_display(p, &info->var, info);
+ cols = info->var.xres / vc->vc_font.width;
+ rows = info->var.yres / vc->vc_font.height;
+ vc_resize(vc, cols, rows);
+
+ if (CON_IS_VISIBLE(vc)) {
+ updatescrollmode(p, info, vc);
+ scrollback_max = 0;
+ scrollback_current = 0;
+ update_var(vc->vc_num, info);
+ fbcon_set_palette(vc, color_table);
+ update_screen(vc);
+ if (softback_buf) {
+ int l = fbcon_softback_size / vc->vc_size_row;
+ if (l > 5)
+ softback_end = softback_buf + l * vc->vc_size_row;
+ else {
+ /* Smaller scrollback makes no sense, and 0
+ would screw the operation totally */
+ softback_top = 0;
+ }
+ }
+ }
+ }
+}
+
static int fbcon_mode_deleted(struct fb_info *info,
struct fb_videomode *mode)
{
@@ -2708,6 +2786,9 @@ static int fbcon_event_notify(struct notifier_block *self,
case FB_EVENT_MODE_CHANGE:
fbcon_modechanged(info);
break;
+ case FB_EVENT_MODE_CHANGE_ALL:
+ fbcon_set_all_vcs(info);
+ break;
case FB_EVENT_MODE_DELETE:
mode = event->data;
ret = fbcon_mode_deleted(info, mode);
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 5d377860bce..08befafe11d 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -18,7 +18,8 @@
#include <asm/io.h>
-#define FBCON_FLAGS_INIT 1
+#define FBCON_FLAGS_INIT 1
+#define FBCON_FLAGS_CURSOR_TIMER 2
/*
* 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 d27fa91e588..0705cd74141 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)
}
}
+static int vgacon_doresize(struct vc_data *c,
+ unsigned int width, unsigned int height)
+{
+ unsigned long flags;
+ unsigned int scanlines = height * c->vc_font.height;
+ u8 scanlines_lo, r7, vsync_end, mode;
+
+ spin_lock_irqsave(&vga_lock, flags);
+
+ outb_p(VGA_CRTC_MODE, vga_video_port_reg);
+ mode = inb_p(vga_video_port_val);
+
+ if (mode & 0x04)
+ scanlines >>= 1;
+
+ scanlines -= 1;
+ scanlines_lo = scanlines & 0xff;
+
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ r7 = inb_p(vga_video_port_val) & ~0x42;
+
+ if (scanlines & 0x100)
+ r7 |= 0x02;
+ if (scanlines & 0x200)
+ r7 |= 0x40;
+
+ /* deprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ vsync_end = inb_p(vga_video_port_val);
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end & ~0x80, vga_video_port_val);
+
+ outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
+ outb_p(width - 1, vga_video_port_val);
+ outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
+ outb_p(width >> 1, vga_video_port_val);
+
+ outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
+ outb_p(scanlines_lo, vga_video_port_val);
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ outb_p(r7,vga_video_port_val);
+
+ /* reprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end, vga_video_port_val);
+
+ spin_unlock_irqrestore(&vga_lock, flags);
+
+ return 0;
+}
+
static int vgacon_switch(struct vc_data *c)
{
/*
@@ -510,9 +561,13 @@ static int vgacon_switch(struct vc_data *c)
/* We can only copy out the size of the video buffer here,
* otherwise we get into VGA BIOS */
- if (!vga_is_gfx)
+ if (!vga_is_gfx) {
scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
- c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size);
+ c->vc_screenbuf_size > vga_vram_size ?
+ vga_vram_size : c->vc_screenbuf_size);
+ vgacon_doresize(c, c->vc_cols, c->vc_rows);
+ }
+
return 0; /* Redrawing not needed */
}
@@ -962,6 +1017,17 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
#endif
+static int vgacon_resize(struct vc_data *c, unsigned int width,
+ unsigned int height)
+{
+ if (width % 2 || width > ORIG_VIDEO_COLS || height > ORIG_VIDEO_LINES)
+ return -EINVAL;
+
+ if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
+ vgacon_doresize(c, width, height);
+ return 0;
+}
+
static int vgacon_scrolldelta(struct vc_data *c, int lines)
{
if (!lines) /* Turn scrollback off */
@@ -1103,6 +1169,7 @@ const struct consw vga_con = {
.con_blank = vgacon_blank,
.con_font_set = vgacon_font_set,
.con_font_get = vgacon_font_get,
+ .con_resize = vgacon_resize,
.con_set_palette = vgacon_set_palette,
.con_scrolldelta = vgacon_scrolldelta,
.con_set_origin = vgacon_set_origin,
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
new file mode 100644
index 00000000000..ae2762cb560
--- /dev/null
+++ b/drivers/video/cyblafb.c
@@ -0,0 +1,1456 @@
+/*
+ * Frame buffer driver for Trident Cyberblade/i1 graphics core
+ *
+ * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de>
+ *
+ * CREDITS:
+ * tridentfb.c by Jani Monoses
+ * see files above for further credits
+ *
+ * TODO:
+ *
+ */
+
+#define CYBLAFB_DEBUG 0
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/types.h>
+#include <video/cyblafb.h>
+
+#define VERSION "0.54"
+
+struct cyblafb_par {
+ u32 pseudo_pal[16];
+ struct fb_ops ops;
+};
+
+static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
+ .id = "CyBla",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .ypanstep = 1,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .accel = FB_ACCEL_NONE,
+};
+
+static char *mode __devinitdata = NULL;
+static int bpp __devinitdata = 8;
+static int ref __devinitdata = 75;
+static int fp __devinitdata;
+static int crt __devinitdata;
+static int memsize __devinitdata;
+static int vesafb __devinitdata;
+
+static int nativex;
+static int center;
+static int stretch;
+static int pciwb = 1;
+static int pcirb = 1;
+static int pciwr = 1;
+static int pcirr = 1;
+static int verbosity;
+static int displaytype;
+
+static void __iomem * io_virt; // iospace virtual memory address
+
+module_param(mode,charp,0);
+module_param(bpp,int,0);
+module_param(ref,int,0);
+module_param(fp,int,0);
+module_param(crt,int,0);
+module_param(nativex,int,0);
+module_param(center,int,0);
+module_param(stretch,int,0);
+module_param(pciwb,int,0);
+module_param(pcirb,int,0);
+module_param(pciwr,int,0);
+module_param(pcirr,int,0);
+module_param(memsize,int,0);
+module_param(verbosity,int,0);
+module_param(vesafb,int,0);
+
+//=========================================
+//
+// Port access macros for memory mapped io
+//
+//=========================================
+
+#define out8(r,v) writeb(v,io_virt+r)
+#define out32(r,v) writel(v,io_virt+r)
+#define in8(r) readb(io_virt+r)
+#define in32(r) readl(io_virt+r)
+
+//======================================
+//
+// Hardware access inline functions
+//
+//======================================
+
+static inline unsigned char read3X4(int reg)
+{
+ out8(0x3D4,reg);
+ return in8(0x3D5);
+}
+
+static inline unsigned char read3C4(int reg)
+{
+ out8(0x3C4,reg);
+ return in8(0x3C5);
+}
+
+static inline unsigned char read3CE(int reg)
+{
+ out8(0x3CE,reg);
+ return in8(0x3CF);
+}
+
+static inline void write3X4(int reg,unsigned char val)
+{
+ out8(0x3D4,reg);
+ out8(0x3D5,val);
+}
+
+static inline void write3C4(int reg,unsigned char val)
+{
+ out8(0x3C4,reg);
+ out8(0x3C5,val);
+}
+
+static inline void write3CE(int reg,unsigned char val)
+{
+ out8(0x3CE,reg);
+ out8(0x3CF,val);
+}
+
+static inline void write3C0(int reg,unsigned char val)
+{
+ in8(0x3DA); // read to reset index
+ out8(0x3C0,reg);
+ out8(0x3C0,val);
+}
+
+//=================================================
+//
+// Enable memory mapped io and unprotect registers
+//
+//=================================================
+
+static inline void enable_mmio(void)
+{
+ int tmp;
+
+ outb(0x0B,0x3C4);
+ inb(0x3C5); // Set NEW mode
+ outb(SR0E,0x3C4); // write enable a lot of extended ports
+ outb(0x80,0x3C5);
+
+ outb(SR11,0x3C4); // write enable those extended ports that
+ outb(0x87,0x3C5); // are not affected by SR0E_New
+
+ outb(CR1E,0x3d4); // clear write protect bit for port 0x3c2
+ tmp=inb(0x3d5) & 0xBF;
+ outb(CR1E,0x3d4);
+ outb(tmp,0x3d5);
+
+ outb(CR39,0x3D4);
+ outb(inb(0x3D5)|0x01,0x3D5); // Enable mmio, everything else untouched
+}
+
+//=================================================
+//
+// Set pixel clock VCLK1
+// - multipliers set elswhere
+// - freq in units of 0.01 MHz
+//
+//=================================================
+
+static void set_vclk(struct cyblafb_par *par, int freq)
+{
+ u32 m,n,k;
+ int f,fi,d,di;
+ u8 lo=0,hi=0;
+
+ d = 2000;
+ k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
+ for(m = 0;m<64;m++)
+ for(n = 0;n<250;n++) { // max 249 is a hardware limit for cybla/i1 !
+ fi = (int)(((5864727*(n+8))/((m+2)*(1<<k)))>>12);
+ if ((di = abs(fi - freq)) < d) {
+ d = di;
+ f = fi;
+ lo = (u8) n;
+ hi = (u8) ((k<<6) | m);
+ }
+ }
+ write3C4(SR19,hi);
+ write3C4(SR18,lo);
+ if(verbosity > 1)
+ output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
+ freq/100,freq%100,(hi&0xc0)>>6,hi&0x3f,lo);
+}
+
+//================================================
+//
+// Cyberblade specific Graphics Engine (GE) setup
+//
+//================================================
+
+static void cyblafb_setup_GE(int pitch,int bpp)
+{
+ int base = (pitch>>3)<<20;
+
+ switch (bpp) {
+ case 8: base |= (0<<29); break;
+ case 15: base |= (5<<29); break;
+ case 16: base |= (1<<29); break;
+ case 24:
+ case 32: base |= (2<<29); break;
+ }
+
+ write3X4(CR36,0x90); // reset GE
+ write3X4(CR36,0x80); // enable GE
+
+ out32(GE24,1<<7); // reset all GE pointers
+ out32(GE24,0);
+
+ write3X4(CR2D,0x00); // GE Timinigs, no delays
+
+ out32(GEB8,base); // Destination Stride / Buffer Base 0, p 133
+ out32(GEBC,base); // Destination Stride / Buffer Base 1, p 133
+ out32(GEC0,base); // Destination Stride / Buffer Base 2, p 133
+ out32(GEC4,base); // Destination Stride / Buffer Base 3, p 133
+ out32(GEC8,base); // Source Stride / Buffer Base 0, p 133
+ out32(GECC,base); // Source Stride / Buffer Base 1, p 133
+ out32(GED0,base); // Source Stride / Buffer Base 2, p 133
+ out32(GED4,base); // Source Stride / Buffer Base 3, p 133
+ out32(GE6C,0); // Pattern and Style, p 129, ok
+}
+
+//=====================================================================
+//
+// Although this is a .fb_sync function that could be enabled in
+// cyblafb_ops, we do not include it there. We sync immediately before
+// new GE operations to improve performance.
+//
+//=====================================================================
+
+static int cyblafb_sync(struct fb_info *info)
+{
+ int status, i=100000;
+ while( ((status=in32(GE20)) & 0xFA800000) && i != 0)
+ i--;
+
+ if (i == 0) {
+ // The timeout might be caused by disabled mmio.
+ // Cause:
+ // - bit CR39 & 1 == 0 upon return, X trident driver bug
+ // - kdm bug (KD_GRAPHICS not set on first switch)
+ // - kernel design flaw (it believes in the correctness
+ // of kdm/X
+ // So we make sure that mmio is enabled first ...
+ enable_mmio();
+// show_trace(NULL,&status);
+ i=1000000;
+ while( ((status=in32(GE20)) & 0xFA800000) && i != 0)
+ i--;
+ if (i == 0) {
+ output("GE Timeout, status: %x\n",status);
+ if(status & 0x80000000)
+ output("Bresenham Engine : Busy\n");
+ if(status & 0x40000000)
+ output("Setup Engine : Busy\n");
+ if(status & 0x20000000)
+ output("SP / DPE : Busy\n");
+ if(status & 0x10000000)
+ output("Memory Interface : Busy\n");
+ if(status & 0x08000000)
+ output("Com Lst Proc : Busy\n");
+ if(status & 0x04000000)
+ output("Block Write : Busy\n");
+ if(status & 0x02000000)
+ output("Command Buffer : Full\n");
+ if(status & 0x01000000)
+ output("RESERVED : Busy\n");
+ if(status & 0x00800000)
+ output("PCI Write Buffer : Busy\n");
+ cyblafb_setup_GE(info->var.xres,
+ info->var.bits_per_pixel);
+ }
+ }
+
+ return 0;
+}
+
+//==============================
+//
+// Cyberblade specific fillrect
+//
+//==============================
+
+static void cyblafb_fillrect(struct fb_info * info,
+ const struct fb_fillrect *fr)
+{
+ int bpp = info->var.bits_per_pixel;
+ int col;
+
+ switch (bpp) {
+ default:
+ case 8: col = fr->color;
+ col |= col <<8;
+ col |= col <<16;
+ break;
+ case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
+ col |= col <<16;
+ break;
+ case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
+ break;
+ }
+
+ cyblafb_sync(info);
+
+ out32(GE60,col);
+ out32(GE48,fr->rop ? 0x66:ROP_S);
+ out32(GE44,0x20000000|1<<19|1<<4|2<<2);
+ out32(GE08,point(fr->dx,fr->dy));
+ out32(GE0C,point(fr->dx+fr->width-1,fr->dy+fr->height-1));
+
+}
+
+//==============================
+//
+// Cyberblade specific copyarea
+//
+//==============================
+
+static void cyblafb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *ca)
+{
+ __u32 s1,s2,d1,d2;
+ int direction;
+
+ s1 = point(ca->sx,ca->sy);
+ s2 = point(ca->sx+ca->width-1,ca->sy+ca->height-1);
+ d1 = point(ca->dx,ca->dy);
+ d2 = point(ca->dx+ca->width-1,ca->dy+ca->height-1);
+ if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
+ direction = 0;
+ else
+ direction = 2;
+
+ cyblafb_sync(info);
+
+ out32(GE44,0xa0000000|1<<19|1<<2|direction);
+ out32(GE00,direction?s2:s1);
+ out32(GE04,direction?s1:s2);
+ out32(GE08,direction?d2:d1);
+ out32(GE0C,direction?d1:d2);
+
+}
+
+//=======================================================================
+//
+// Cyberblade specific imageblit
+//
+// Accelerated for the most usual case, blitting 1-bit deep character
+// character images. Everything else is passed to the generic imageblit.
+//
+//=======================================================================
+
+static void cyblafb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+
+ u32 fgcol, bgcol;
+
+ int i;
+ int bpp = info->var.bits_per_pixel;
+ int index = 0;
+ int index_end=image->height * image->width / 8;
+ int width_dds=image->width / 32;
+ int width_dbs=image->width % 32;
+
+ if (image->depth != 1 || bpp < 8 || bpp > 32 || bpp % 8 != 0 ||
+ image->width % 8 != 0 || image->width == 0 || image->height == 0) {
+ cfb_imageblit(info,image);
+ return;
+ }
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fgcol = ((u32*)(info->pseudo_palette))[image->fg_color];
+ bgcol = ((u32*)(info->pseudo_palette))[image->bg_color];
+ } else {
+ fgcol = image->fg_color;
+ bgcol = image->bg_color;
+ }
+
+ switch (bpp) {
+ case 8:
+ fgcol |= fgcol <<8; fgcol |= fgcol <<16;
+ bgcol |= bgcol <<8; bgcol |= bgcol <<16;
+ break;
+ case 16:
+ fgcol |= fgcol <<16;
+ bgcol |= bgcol <<16;
+ break;
+ default:
+ break;
+ }
+
+ cyblafb_sync(info);
+
+ out32(GE60,fgcol);
+ out32(GE64,bgcol);
+ out32(GE44,0xa0000000 | 1<<20 | 1<<19);
+ out32(GE08,point(image->dx,image->dy));
+ out32(GE0C,point(image->dx+image->width-1,image->dy+image->height-1));
+
+ while(index < index_end) {
+ for(i=0;i<width_dds;i++) {
+ out32(GE9C,*((u32*) ((u32)image->data + index)));
+ index+=4;
+ }
+ switch(width_dbs) {
+ case 0: break;
+ case 8: out32(GE9C,*((u8*)((u32)image->data+index)));
+ index+=1;
+ break;
+ case 16: out32(GE9C,*((u16*)((u32)image->data+index)));
+ index+=2;
+ break;
+ case 24: out32(GE9C,(u32)(*((u16*)((u32)image->data+index))) |
+ (u32)(*((u8*)((u32)image->data+index+2)))<<16);
+ index+=3;
+ break;
+ }
+ }
+}
+
+//==========================================================
+//
+// Check if video mode is acceptable. We change var->??? if
+// video mode is slightly off or return error otherwise.
+// info->??? must not be changed!
+//
+//==========================================================
+
+static int cyblafb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int bpp = var->bits_per_pixel;
+ int s,t,maxvyres;
+
+ //
+ // we try to support 8, 16, 24 and 32 bpp modes,
+ // default to 8
+ //
+ // there is a 24 bpp mode, but for now we change requests to 32 bpp
+ // (This is what tridentfb does ... will be changed in the future)
+ //
+ //
+ if ( bpp % 8 != 0 || bpp < 8 || bpp >32)
+ bpp = 8;
+ if (bpp == 24 )
+ bpp = var->bits_per_pixel = 32;
+
+ //
+ // interlaced modes are broken, fail if one is requested
+ //
+ if (var->vmode & FB_VMODE_INTERLACED)
+ return -EINVAL;
+
+ //
+ // fail if requested resolution is higher than physical
+ // flatpanel resolution
+ //
+ if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex)
+ return -EINVAL;
+
+ //
+ // xres != xres_virtual is broken, fail if such an
+ // unusual mode is requested
+ //
+ if (var->xres != var->xres_virtual)
+ return -EINVAL;
+
+ //
+ // we do not allow vclk to exceed 230 MHz
+ //
+ if ((bpp==32 ? 200000000 : 100000000) / var->pixclock > 23000)
+ return -EINVAL;
+
+ //
+ // calc max yres_virtual that would fit in memory
+ // and max yres_virtual that could be used for scrolling
+ // and use minimum of the results as maxvyres
+ //
+ // adjust vyres_virtual to maxvyres if necessary
+ // fail if requested yres is bigger than maxvyres
+ //
+ s = (0x1fffff / (var->xres * bpp/8)) + var->yres;
+ t = info->fix.smem_len / (var->xres * bpp/8);
+ maxvyres = t < s ? t : s;
+ if (maxvyres < var->yres_virtual)
+ var->yres_virtual=maxvyres;
+ if (maxvyres < var->yres)
+ return -EINVAL;
+
+ switch (bpp) {
+ case 8:
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ break;
+ case 16:
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case 32:
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+
+}
+
+//=====================================================================
+//
+// Pan the display
+//
+// The datasheets defines crt start address to be 20 bits wide and
+// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is
+// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use
+// it, so it is also safe to be used here. BTW: datasheet CR0E on page
+// 90 really is CR1E, the real CRE is documented on page 72.
+//
+//=====================================================================
+
+static int cyblafb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ unsigned int offset;
+
+ offset=(var->xoffset+(var->yoffset*var->xres))*var->bits_per_pixel/32;
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+
+ write3X4(CR0D,offset & 0xFF);
+ write3X4(CR0C,(offset & 0xFF00) >> 8);
+ write3X4(CR1E,(read3X4(CR1E) & 0xDF) | ((offset & 0x10000) >> 11));
+ write3X4(CR27,(read3X4(CR27) & 0xF8) | ((offset & 0xE0000) >> 17));
+ write3X4(CR2B,(read3X4(CR2B) & 0xDF) | ((offset & 0x100000) >> 15));
+
+ return 0;
+}
+
+//============================================
+//
+// This will really help in case of a bug ...
+// dump most gaphics core registers.
+//
+//============================================
+
+static void regdump(struct cyblafb_par *par)
+{
+ int i;
+
+ if (verbosity < 2)
+ return;
+
+ printk("\n");
+ for(i=0; i<=0xff; i++) {
+ outb(i,0x3d4);
+ printk("CR%02x=%02x ",i,inb(0x3d5));
+ if (i%16==15)
+ printk("\n");
+ }
+
+ outb(0x30,0x3ce);
+ outb(inb(0x3cf) | 0x40,0x3cf);
+ for(i=0; i<=0x1f; i++) {
+ if (i==0 || (i>2 && i<8) || i==0x10 || i==0x11 || i==0x16) {
+ outb(i,0x3d4);
+ printk("CR%02x=%02x ",i,inb(0x3d5));
+ } else
+ printk("------- ");
+ if (i%16==15)
+ printk("\n");
+ }
+ outb(0x30,0x3ce);
+ outb(inb(0x3cf) & 0xbf,0x3cf);
+
+ printk("\n");
+ for(i=0; i<=0x7f; i++) {
+ outb(i,0x3ce);
+ printk("GR%02x=%02x ",i,inb(0x3cf));
+ if (i%16==15)
+ printk("\n");
+ }
+
+ printk("\n");
+ for(i=0; i<=0xff; i++) {
+ outb(i,0x3c4);
+ printk("SR%02x=%02x ",i,inb(0x3c5));
+ if (i%16==15)
+ printk("\n");
+ }
+
+ printk("\n");
+ for(i=0; i <= 0x1F; i++) {
+ inb(0x3da); // next access is index!
+ outb(i,0x3c0);
+ printk("AR%02x=%02x ",i,inb(0x3c1));
+ if (i%16==15)
+ printk("\n");
+ }
+ printk("\n");
+
+ inb(0x3DA); // reset internal flag to 3c0 index
+ outb(0x20,0x3C0); // enable attr
+
+ return;
+}
+
+//======================================
+//
+// Set hardware to requested video mode
+//
+//======================================
+
+static int cyblafb_set_par(struct fb_info *info)
+{
+ struct cyblafb_par *par = info->par;
+ u32
+ htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,preendfetch,
+ vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend;
+ struct fb_var_screeninfo *var = &info->var;
+ int bpp = var->bits_per_pixel;
+ int i;
+
+ if (verbosity > 0)
+ output("Switching to new mode: "
+ "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
+ var->xres,var->yres,var->xres_virtual,
+ var->yres_virtual,var->bits_per_pixel,var->pixclock,
+ var->left_margin,var->right_margin,var->upper_margin,
+ var->lower_margin,var->hsync_len,var->vsync_len);
+
+ htotal = (var->xres + var->left_margin + var->right_margin +
+ var->hsync_len) / 8 - 5;
+ hdispend = var->xres/8 - 1;
+ hsyncstart = (var->xres + var->right_margin)/8;
+ hsyncend = var->hsync_len/8;
+ hblankstart = hdispend + 1;
+ hblankend = htotal + 3; // should be htotal + 5, bios does it this way
+ preendfetch = ((var->xres >> 3) + 1) * ((bpp+1) >> 3);
+
+ vtotal = var->yres + var->upper_margin + var->lower_margin +
+ var->vsync_len - 2;
+ vdispend = var->yres - 1;
+ vsyncstart = var->yres + var->lower_margin;
+ vblankstart = var->yres;
+ vblankend = vtotal; // should be vtotal + 2, but bios does it this way
+ vsyncend = var->vsync_len;
+
+ enable_mmio(); // necessary! ... check X ...
+
+ write3X4(CR11,read3X4(CR11) & 0x7F); // unlock cr00 .. cr07
+
+ write3CE(GR30,8);
+
+ if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
+
+ // stretch or center ?
+
+ out8(0x3C2,0xEB);
+
+ write3CE(GR30,read3CE(GR30) | 0x81); // shadow mode on
+
+ if (center) {
+ write3CE(GR52,(read3CE(GR52) & 0x7C) | 0x80);
+ write3CE(GR53,(read3CE(GR53) & 0x7C) | 0x80);
+ }
+ else if (stretch) {
+ write3CE(GR5D,0);
+ write3CE(GR52,(read3CE(GR52) & 0x7C) | 1);
+ write3CE(GR53,(read3CE(GR53) & 0x7C) | 1);
+ }
+
+ } else {
+ out8(0x3C2,0x2B);
+ write3CE(GR30,8);
+ }
+
+ //
+ // Setup CRxx regs
+ //
+
+ write3X4(CR00,htotal & 0xFF);
+ write3X4(CR01,hdispend & 0xFF);
+ write3X4(CR02,hblankstart & 0xFF);
+ write3X4(CR03,hblankend & 0x1F);
+ write3X4(CR04,hsyncstart & 0xFF);
+ write3X4(CR05,(hsyncend & 0x1F) | ((hblankend & 0x20)<<2));
+ write3X4(CR06,vtotal & 0xFF);
+ write3X4(CR07,(vtotal & 0x100) >> 8 |
+ (vdispend & 0x100) >> 7 |
+ (vsyncstart & 0x100) >> 6 |
+ (vblankstart & 0x100) >> 5 |
+ 0x10 |
+ (vtotal & 0x200) >> 4 |
+ (vdispend & 0x200) >> 3 |
+ (vsyncstart & 0x200) >> 2);
+ write3X4(CR08,0);
+ write3X4(CR09,(vblankstart & 0x200) >> 4 | 0x40 | // FIX !!!
+ ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
+ write3X4(CR0A,0); // Init to some reasonable default
+ write3X4(CR0B,0); // Init to some reasonable default
+ write3X4(CR0C,0); // Offset 0
+ write3X4(CR0D,0); // Offset 0
+ write3X4(CR0E,0); // Init to some reasonable default
+ write3X4(CR0F,0); // Init to some reasonable default
+ write3X4(CR10,vsyncstart & 0xFF);
+ write3X4(CR11,(vsyncend & 0x0F));
+ write3X4(CR12,vdispend & 0xFF);
+ write3X4(CR13,((info->var.xres * bpp)/(4*16)) & 0xFF);
+ write3X4(CR14,0x40); // double word mode
+ write3X4(CR15,vblankstart & 0xFF);
+ write3X4(CR16,vblankend & 0xFF);
+ write3X4(CR17,0xC3);
+ write3X4(CR18,0xFF);
+ // CR19: needed for interlaced modes ... ignore it for now
+ write3X4(CR1A,0x07); // Arbitration Control Counter 1
+ write3X4(CR1B,0x07); // Arbitration Control Counter 2
+ write3X4(CR1C,0x07); // Arbitration Control Counter 3
+ write3X4(CR1D,0x00); // Don't know, doesn't hurt ;-)
+ write3X4(CR1E,(info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
+ // CR1F: do not set, contains BIOS info about memsize
+ write3X4(CR20,0x20); // enabe wr buf, disable 16bit planar mode
+ write3X4(CR21,0x20); // enable linear memory access
+ // CR22: RO cpu latch readback
+ // CR23: ???
+ // CR24: RO AR flag state
+ // CR25: RAMDAC rw timing, pclk buffer tristate control ????
+ // CR26: ???
+ write3X4(CR27,(vdispend & 0x400) >> 6 |
+ (vsyncstart & 0x400) >> 5 |
+ (vblankstart & 0x400) >> 4 |
+ (vtotal & 0x400) >> 3 |
+ 0x8);
+ // CR28: ???
+ write3X4(CR29,(read3X4(CR29) & 0xCF) |
+ ((((info->var.xres * bpp) / (4*16)) & 0x300) >>4));
+ write3X4(CR2A,read3X4(CR2A) | 0x40);
+ write3X4(CR2B,(htotal & 0x100) >> 8 |
+ (hdispend & 0x100) >> 7 |
+ // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ???
+ (hsyncstart & 0x100) >> 5 |
+ (hblankstart & 0x100) >> 4);
+ // CR2C: ???
+ // CR2D: initialized in cyblafb_setup_GE()
+ write3X4(CR2F,0x92); // conservative, better signal quality
+ // CR30: reserved
+ // CR31: reserved
+ // CR32: reserved
+ // CR33: reserved
+ // CR34: disabled in CR36
+ // CR35: disabled in CR36
+ // CR36: initialized in cyblafb_setup_GE
+ // CR37: i2c, ignore for now
+ write3X4(CR38,(bpp == 8) ? 0x00 : //
+ (bpp == 16) ? 0x05 : // highcolor
+ (bpp == 24) ? 0x29 : // packed 24bit truecolor
+ (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
+ write3X4(CR39,0x01 | // MMIO enable
+ (pcirb ? 0x02 : 0) | // pci read burst enable
+ (pciwb ? 0x04 : 0)); // pci write burst enable
+ write3X4(CR55,0x1F | // pci clocks * 2 for STOP# during 1st data phase
+ (pcirr ? 0x40 : 0) | // pci read retry enable
+ (pciwr ? 0x80 : 0)); // pci write retry enable
+ write3X4(CR56,preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01)|2 : 0);
+ write3X4(CR57,preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
+ write3X4(CR58,0x82); // Bios does this .... don't know more
+ //
+ // Setup SRxx regs
+ //
+ write3C4(SR00,3);
+ write3C4(SR01,1); //set char clock 8 dots wide
+ write3C4(SR02,0x0F); //enable 4 maps needed in chain4 mode
+ write3C4(SR03,0); //no character map select
+ write3C4(SR04,0x0E); //memory mode: ext mem, even, chain4
+
+ out8(0x3C4,0x0b);
+ in8(0x3C5); // Set NEW mode
+ write3C4(SR0D,0x00); // test ... check
+
+ set_vclk(par,(bpp==32 ? 200000000 : 100000000)/
+ info->var.pixclock); //SR18,SR19
+
+ //
+ // Setup GRxx regs
+ //
+ write3CE(GR00,0x00); // test ... check
+ write3CE(GR01,0x00); // test ... check
+ write3CE(GR02,0x00); // test ... check
+ write3CE(GR03,0x00); // test ... check
+ write3CE(GR04,0x00); // test ... check
+ write3CE(GR05,0x40); // no CGA compat,allow 256 col
+ write3CE(GR06,0x05); // graphics mode
+ write3CE(GR07,0x0F); // planes?
+ write3CE(GR08,0xFF); // test ... check
+ write3CE(GR0F,(bpp==32)?0x1A:0x12); // div vclk by 2 if 32bpp, chain4
+ write3CE(GR20,0xC0); // test ... check
+ write3CE(GR2F,0xA0); // PCLK = VCLK, no skew,
+
+ //
+ // Setup ARxx regs
+ //
+ for(i = 0;i < 0x10;i++) // set AR00 .. AR0f
+ write3C0(i,i);
+ write3C0(AR10,0x41); // graphics mode and support 256 color modes
+ write3C0(AR12,0x0F); // planes
+ write3C0(AR13,0); // horizontal pel panning
+ in8(0x3DA); // reset internal flag to 3c0 index
+ out8(0x3C0,0x20); // enable attr
+
+ //
+ // Setup hidden RAMDAC command register
+ //
+ in8(0x3C8); // these reads are
+ in8(0x3C6); // necessary to
+ in8(0x3C6); // unmask the RAMDAC
+ in8(0x3C6); // command reg, otherwise
+ in8(0x3C6); // we would write the pixelmask reg!
+ out8(0x3C6,(bpp == 8) ? 0x00 : // 256 colors
+ (bpp == 15) ? 0x10 : //
+ (bpp == 16) ? 0x30 : // hicolor
+ (bpp == 24) ? 0xD0 : // truecolor
+ (bpp == 32) ? 0xD0 : 0); // truecolor
+ in8(0x3C8);
+
+ //
+ // GR31 is not mentioned in the datasheet
+ //
+ if (displaytype == DISPLAY_FP)
+ write3CE(GR31,(read3CE(GR31) & 0x8F) |
+ ((info->var.yres > 1024) ? 0x50 :
+ (info->var.yres > 768) ? 0x30 :
+ (info->var.yres > 600) ? 0x20 :
+ (info->var.yres > 480) ? 0x10 : 0));
+
+ info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
+ : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = info->var.xres * (bpp >> 3);
+ info->cmap.len = (bpp == 8) ? 256: 16;
+
+ //
+ // init acceleration engine
+ //
+ cyblafb_setup_GE(info->var.xres,info->var.bits_per_pixel);
+
+ regdump(par);
+
+ return 0;
+}
+
+//========================
+//
+// Set one color register
+//
+//========================
+
+static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ int bpp = info->var.bits_per_pixel;
+
+ if (regno >= info->cmap.len)
+ return 1;
+
+ if (bpp == 8) {
+ out8(0x3C6,0xFF);
+ out8(0x3C8,regno);
+ out8(0x3C9,red>>10);
+ out8(0x3C9,green>>10);
+ out8(0x3C9,blue>>10);
+
+ } else if (bpp == 16) // RGB 565
+ ((u32*)info->pseudo_palette)[regno] =
+ (red & 0xF800) |
+ ((green & 0xFC00) >> 5) |
+ ((blue & 0xF800) >> 11);
+ else if (bpp == 32) // ARGB 8888
+ ((u32*)info->pseudo_palette)[regno] =
+ ((transp & 0xFF00) <<16) |
+ ((red & 0xFF00) << 8) |
+ ((green & 0xFF00)) |
+ ((blue & 0xFF00)>>8);
+
+ return 0;
+}
+
+//==========================================================
+//
+// Try blanking the screen. For flat panels it does nothing
+//
+//==========================================================
+
+static int cyblafb_blank(int blank_mode, struct fb_info *info)
+{
+ unsigned char PMCont,DPMSCont;
+
+ if (displaytype == DISPLAY_FP)
+ return 0;
+
+ out8(0x83C8,0x04); // DPMS Control
+ PMCont = in8(0x83C6) & 0xFC;
+
+ DPMSCont = read3CE(GR23) & 0xFC;
+
+ switch (blank_mode)
+ {
+ case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On
+ case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
+ PMCont |= 0x03;
+ DPMSCont |= 0x00;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On
+ PMCont |= 0x02;
+ DPMSCont |= 0x01;
+ break;
+ case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off
+ PMCont |= 0x02;
+ DPMSCont |= 0x02;
+ break;
+ case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off
+ PMCont |= 0x00;
+ DPMSCont |= 0x03;
+ break;
+ }
+
+ write3CE(GR23,DPMSCont);
+ out8(0x83C8,4);
+ out8(0x83C6,PMCont);
+ //
+ // let fbcon do a softblank for us
+ //
+ return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops cyblafb_ops __devinitdata = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = cyblafb_setcolreg,
+ .fb_pan_display = cyblafb_pan_display,
+ .fb_blank = cyblafb_blank,
+ .fb_check_var = cyblafb_check_var,
+ .fb_set_par = cyblafb_set_par,
+ .fb_fillrect = cyblafb_fillrect,
+ .fb_copyarea= cyblafb_copyarea,
+ .fb_imageblit = cyblafb_imageblit,
+ .fb_cursor = soft_cursor,
+};
+
+//==========================================================================
+//
+// getstartupmode() decides about the inital video mode
+//
+// There is no reason to use modedb, a lot of video modes there would
+// need altered timings to display correctly. So I decided that it is much
+// better to provide a limited optimized set of modes plus the option of
+// using the mode in effect at startup time (might be selected using the
+// vga=??? paramter). After that the user might use fbset to select any
+// mode he likes, check_var will not try to alter geometry parameters as
+// it would be necessary otherwise.
+//
+//==========================================================================
+
+static int __devinit getstartupmode(struct fb_info *info)
+{
+ u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,
+ vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend,
+ cr00,cr01,cr02,cr03,cr04,cr05,cr2b,
+ cr06,cr07,cr09,cr10,cr11,cr12,cr15,cr16,cr27,
+ cr38,
+ sr0d,sr18,sr19,
+ gr0f,
+ fi,pxclkdiv,vclkdiv,tmp,i;
+
+ struct modus {
+ int xres; int yres; int vyres; int bpp; int pxclk;
+ int left_margin; int right_margin; int upper_margin;
+ int lower_margin; int hsync_len; int vsync_len;
+ } modedb[5] = {
+ { 0, 0, 8000, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 640, 480, 3756, 0, 0, -40, 24, 17, 0, 216, 3},
+ { 800, 600, 3221, 0, 0, 96, 24, 14, 0, 136, 11},
+ {1024, 768, 2815, 0, 0, 144, 24, 29, 0, 120, 3},
+ {1280, 1024, 2662, 0, 0, 232, 16, 39, 0, 160, 3}
+ };
+
+ outb(0x00,0x3d4); cr00=inb(0x3d5); outb(0x01,0x3d4); cr01=inb(0x3d5);
+ outb(0x02,0x3d4); cr02=inb(0x3d5); outb(0x03,0x3d4); cr03=inb(0x3d5);
+ outb(0x04,0x3d4); cr04=inb(0x3d5); outb(0x05,0x3d4); cr05=inb(0x3d5);
+ outb(0x06,0x3d4); cr06=inb(0x3d5); outb(0x07,0x3d4); cr07=inb(0x3d5);
+ outb(0x09,0x3d4); cr09=inb(0x3d5); outb(0x10,0x3d4); cr10=inb(0x3d5);
+ outb(0x11,0x3d4); cr11=inb(0x3d5); outb(0x12,0x3d4); cr12=inb(0x3d5);
+ outb(0x15,0x3d4); cr15=inb(0x3d5); outb(0x16,0x3d4); cr16=inb(0x3d5);
+ outb(0x27,0x3d4); cr27=inb(0x3d5); outb(0x2b,0x3d4); cr2b=inb(0x3d5);
+ outb(0x38,0x3d4); cr38=inb(0x3d5); outb(0x0b,0x3c4); inb(0x3c5);
+ outb(0x0d,0x3c4); sr0d=inb(0x3c5); outb(0x18,0x3c4); sr18=inb(0x3c5);
+ outb(0x19,0x3c4); sr19=inb(0x3c5); outb(0x0f,0x3ce); gr0f=inb(0x3cf);
+
+ htotal = cr00 | (cr2b & 0x01) << 8;
+ hdispend = cr01 | (cr2b & 0x02) << 7;
+ hblankstart = cr02 | (cr2b & 0x10) << 4;
+ hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
+ hsyncstart = cr04 | (cr2b & 0x08) << 5;
+ hsyncend = cr05 & 0x1f;
+
+ modedb[0].xres = hblankstart * 8;
+ modedb[0].hsync_len = hsyncend * 8;
+ modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
+ modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
+ modedb[0].right_margin - modedb[0].hsync_len;
+
+ vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
+ | (cr27 & 0x80) << 3;
+ vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
+ | (cr27 & 0x10) << 6;
+ vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
+ | (cr27 & 0x20) << 5;
+ vsyncend = cr11 & 0x0f;
+ vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
+ | (cr27 & 0x40) << 4;
+ vblankend = cr16;
+
+ modedb[0].yres = vdispend + 1;
+ modedb[0].vsync_len = vsyncend;
+ modedb[0].lower_margin = vsyncstart - modedb[0].yres;
+ modedb[0].upper_margin = vtotal - modedb[0].yres -
+ modedb[0].lower_margin - modedb[0].vsync_len + 2;
+
+ tmp = cr38 & 0x3c;
+ modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
+ tmp == 8 ? 32 : 8;
+
+ fi = ((5864727*(sr18+8))/(((sr19&0x3f)+2)*(1<<((sr19&0xc0)>>6))))>>12;
+ pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
+ tmp = sr0d & 0x06;
+ vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
+ modedb[0].pxclk = ((100000000 * pxclkdiv * vclkdiv) >> 1) / fi;
+
+ if (verbosity > 0)
+ output("detected startup mode: "
+ "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
+ modedb[0].xres,modedb[0].yres,modedb[0].xres,
+ modedb[0].bpp,modedb[0].pxclk,modedb[0].left_margin,
+ modedb[0].right_margin,modedb[0].upper_margin,
+ modedb[0].lower_margin,modedb[0].hsync_len,
+ modedb[0].vsync_len);
+
+ //
+ // We use this goto target in case of a failed check_var. No, I really
+ // do not want to do it in another way!
+ //
+
+ tryagain:
+
+ i = (mode == NULL) ? 0 :
+ !strncmp(mode,"640x480",7) ? 1 :
+ !strncmp(mode,"800x600",7) ? 2 :
+ !strncmp(mode,"1024x768",8) ? 3 :
+ !strncmp(mode,"1280x1024",9) ? 4 : 0;
+
+ ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
+
+ if(i==0) {
+ info->var.pixclock = modedb[i].pxclk;
+ info->var.bits_per_pixel = modedb[i].bpp;
+ } else {
+ info->var.pixclock = (100000000 /
+ ((modedb[i].left_margin + modedb[i].xres +
+ modedb[i].right_margin + modedb[i].hsync_len
+ ) * (
+ modedb[i].upper_margin + modedb[i].yres +
+ modedb[i].lower_margin + modedb[i].vsync_len
+ ) *
+ ref / 10000
+ ));
+ info->var.bits_per_pixel = bpp;
+ }
+
+ info->var.left_margin = modedb[i].left_margin;
+ info->var.right_margin = modedb[i].right_margin;
+ info->var.xres = modedb[i].xres;
+ info->var.xres_virtual = modedb[i].xres;
+ info->var.xoffset = 0;
+ info->var.hsync_len = modedb[i].hsync_len;
+ info->var.upper_margin = modedb[i].upper_margin;
+ info->var.yres = modedb[i].yres;
+ info->var.yres_virtual = modedb[i].vyres;
+ info->var.yoffset = 0;
+ info->var.lower_margin = modedb[i].lower_margin;
+ info->var.vsync_len = modedb[i].vsync_len;
+ info->var.sync = 0;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+
+ if(cyblafb_check_var(&info->var,info)) {
+ // 640x480-8@75 should really never fail. One case would
+ // be fp == 1 and nativex < 640 ... give up then
+ if(i==1 && bpp == 8 && ref == 75){
+ output("Can't find a valid mode :-(\n");
+ return -EINVAL;
+ }
+ // Our detected mode is unlikely to fail. If it does,
+ // try 640x480-8@75 ...
+ if(i==0) {
+ mode="640x480";
+ bpp=8;
+ ref=75;
+ output("Detected mode failed check_var! "
+ "Trying 640x480-8@75\n");
+ goto tryagain;
+ }
+ // A specified video mode failed for some reason.
+ // Try the startup mode first
+ output("Specified mode '%s' failed check! "
+ "Falling back to startup mode.\n",mode);
+ mode=NULL;
+ goto tryagain;
+ }
+
+ return 0;
+
+}
+
+//========================================================
+//
+// Detect activated memory size. Undefined values require
+// memsize parameter.
+//
+//========================================================
+
+static unsigned int __devinit get_memsize(void)
+{
+ unsigned char tmp;
+ unsigned int k;
+
+ if (memsize)
+ k = memsize * Kb;
+ else {
+ tmp = read3X4(CR1F) & 0x0F;
+ switch (tmp) {
+ case 0x03: k = 1 * Mb; break;
+ case 0x07: k = 2 * Mb; break;
+ case 0x0F: k = 4 * Mb; break;
+ case 0x04: k = 8 * Mb; break;
+ default:
+ k = 1 * Mb;
+ output("Unknown memory size code %x in CR1F."
+ " We default to 1 Mb for now, please"
+ " do provide a memsize parameter!\n",
+ tmp);
+ }
+ }
+
+ if (verbosity > 0)
+ output("framebuffer size = %d Kb\n",k/Kb);
+ return k;
+}
+
+//=========================================================
+//
+// Detect if a flat panel monitor connected to the special
+// interface is active. Override is possible by fp and crt
+// parameters.
+//
+//=========================================================
+
+static unsigned int __devinit get_displaytype(void)
+{
+ if (fp)
+ return DISPLAY_FP;
+ if (crt)
+ return DISPLAY_CRT;
+ return (read3CE(GR33) & 0x10)?DISPLAY_FP:DISPLAY_CRT;
+}
+
+//=====================================
+//
+// Get native resolution of flat panel
+//
+//=====================================
+
+static int __devinit get_nativex(void)
+{
+ int x,y,tmp;
+
+ if (nativex)
+ return nativex;
+
+ tmp = (read3CE(GR52) >> 4) & 3;
+
+ switch (tmp) {
+ case 0: x = 1280; y = 1024; break;
+ case 2: x = 1024; y = 768; break;
+ case 3: x = 800; y = 600; break;
+ case 4: x = 1400; y = 1050; break;
+ case 1:
+ default: x = 640; y = 480; break;
+ }
+
+ if (verbosity > 0)
+ output("%dx%d flat panel found\n",x,y);
+ return x;
+}
+
+static int __devinit cybla_pci_probe(struct pci_dev * dev,
+ const struct pci_device_id * id)
+{
+ struct fb_info *info;
+ struct cyblafb_par *par;
+
+ info = framebuffer_alloc(sizeof(struct cyblafb_par),&dev->dev);
+
+ if (!info)
+ goto errout_alloc;
+
+ par = info->par;
+ par->ops = cyblafb_ops;
+
+ info->fix = cyblafb_fix;
+ info->fbops = &par->ops;
+ info->fix = cyblafb_fix;
+
+ if (pci_enable_device(dev)) {
+ output("could not enable device!\n");
+ goto errout_enable;
+ }
+
+ // might already be requested by vga console or vesafb,
+ // so we do care about success
+ request_region(0x3c0,32,"cyblafb");
+
+ //
+ // Graphics Engine Registers
+ //
+ request_region(GEBase,0x100,"cyblafb");
+
+ regdump(par);
+
+ enable_mmio();
+
+ // setup MMIO region
+ info->fix.mmio_start = pci_resource_start(dev,1);
+ info->fix.mmio_len = 0x20000;
+
+ if (!request_mem_region(info->fix.mmio_start,
+ info->fix.mmio_len,"cyblafb")) {
+ output("request_mem_region failed for mmio region!\n");
+ goto errout_mmio_reqmem;
+ }
+
+ io_virt = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
+
+ if (!io_virt) {
+ output("ioremap failed for mmio region\n");
+ goto errout_mmio_remap;
+ }
+
+ // setup framebuffer memory ... might already be requested
+ // by vesafb. Not to fail in case of an unsuccessful request
+ // is useful for the development cycle
+ info->fix.smem_start = pci_resource_start(dev,0);
+ info->fix.smem_len = get_memsize();
+
+ if (!request_mem_region(info->fix.smem_start,
+ info->fix.smem_len,"cyblafb")) {
+ output("request_mem_region failed for smem region!\n");
+ if (!vesafb)
+ goto errout_smem_req;
+ }
+
+ info->screen_base = ioremap_nocache(info->fix.smem_start,
+ info->fix.smem_len);
+
+ if (!info->screen_base) {
+ output("ioremap failed for smem region\n");
+ goto errout_smem_remap;
+ }
+
+ displaytype = get_displaytype();
+
+ if(displaytype == DISPLAY_FP)
+ nativex = get_nativex();
+
+ //
+ // FBINFO_HWACCEL_YWRAP .... does not work (could be made to work?)
+ // FBINFO_PARTIAL_PAN_OK .... is not ok
+ // FBINFO_READS_FAST .... is necessary for optimal scrolling
+ //
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN
+ | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT
+ | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_READS_FAST;
+
+ info->pseudo_palette = par->pseudo_pal;
+
+ if(getstartupmode(info))
+ goto errout_findmode;
+
+ fb_alloc_cmap(&info->cmap,256,0);
+
+ if (register_framebuffer(info)) {
+ output("Could not register CyBla framebuffer\n");
+ goto errout_register;
+ }
+
+ pci_set_drvdata(dev,info);
+
+ //
+ // normal exit and error paths
+ //
+
+ return 0;
+
+ errout_register:
+ errout_findmode:
+ iounmap(info->screen_base);
+ errout_smem_remap:
+ release_mem_region(info->fix.smem_start,
+ info->fix.smem_len);
+ errout_smem_req:
+ iounmap(io_virt);
+ errout_mmio_remap:
+ release_mem_region(info->fix.mmio_start,
+ info->fix.mmio_len);
+ errout_mmio_reqmem:
+// release_region(0x3c0,32);
+ errout_enable:
+ framebuffer_release(info);
+ errout_alloc:
+ output("CyblaFB version %s aborting init.\n",VERSION);
+ return -ENODEV;
+}
+
+static void __devexit cybla_pci_remove(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+
+ unregister_framebuffer(info);
+ iounmap(io_virt);
+ iounmap(info->screen_base);
+ release_mem_region(info->fix.smem_start,info->fix.smem_len);
+ release_mem_region(info->fix.mmio_start,info->fix.mmio_len);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+ output("CyblaFB version %s normal exit.\n",VERSION);
+}
+
+//
+// List of boards that we are trying to support
+//
+static struct pci_device_id cybla_devices[] = {
+ {PCI_VENDOR_ID_TRIDENT,CYBERBLADEi1,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci,cybla_devices);
+
+static struct pci_driver cyblafb_pci_driver = {
+ .name = "cyblafb",
+ .id_table = cybla_devices,
+ .probe = cybla_pci_probe,
+ .remove = __devexit_p(cybla_pci_remove)
+};
+
+//=============================================================
+//
+// kernel command line example:
+//
+// video=cyblafb:1280x1024,bpp=16,ref=50 ...
+//
+// modprobe command line example:
+//
+// modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
+//
+//=============================================================
+
+static int __devinit cyblafb_init(void)
+{
+#ifndef MODULE
+ char *options = NULL;
+ char *opt;
+
+ if (fb_get_options("cyblafb",&options))
+ return -ENODEV;
+
+ if (options && *options)
+ while((opt = strsep(&options,",")) != NULL ) {
+ if (!*opt) continue;
+ else if (!strncmp(opt,"bpp=",4))
+ bpp = simple_strtoul(opt+4,NULL,0);
+ else if (!strncmp(opt,"ref=",4))
+ ref = simple_strtoul(opt+4,NULL,0);
+ else if (!strncmp(opt,"fp",2))
+ displaytype = DISPLAY_FP;
+ else if (!strncmp(opt,"crt",3))
+ displaytype = DISPLAY_CRT;
+ else if (!strncmp(opt,"nativex=",8))
+ nativex = simple_strtoul(opt+8,NULL,0);
+ else if (!strncmp(opt,"center",6))
+ center = 1;
+ else if (!strncmp(opt,"stretch",7))
+ stretch = 1;
+ else if (!strncmp(opt,"pciwb=",6))
+ pciwb = simple_strtoul(opt+6,NULL,0);
+ else if (!strncmp(opt,"pcirb=",6))
+ pcirb = simple_strtoul(opt+6,NULL,0);
+ else if (!strncmp(opt,"pciwr=",6))
+ pciwr = simple_strtoul(opt+6,NULL,0);
+ else if (!strncmp(opt,"pcirr=",6))
+ pcirr = simple_strtoul(opt+6,NULL,0);
+ else if (!strncmp(opt,"memsize=",8))
+ memsize = simple_strtoul(opt+8,NULL,0);
+ else if (!strncmp(opt,"verbosity=",10))
+ verbosity = simple_strtoul(opt+10,NULL,0);
+ else if (!strncmp(opt,"vesafb",6))
+ vesafb = 1;
+ else
+ mode = opt;
+ }
+#endif
+ output("CyblaFB version %s initializing\n",VERSION);
+ return pci_module_init(&cyblafb_pci_driver);
+}
+
+static void __exit cyblafb_exit(void)
+{
+ pci_unregister_driver(&cyblafb_pci_driver);
+}
+
+module_init(cyblafb_init);
+module_exit(cyblafb_exit);
+
+MODULE_AUTHOR("Knut Petersen <knut_petersen@t-online.de>");
+MODULE_DESCRIPTION("Framebuffer driver for Cyberblade/i1 graphics core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
new file mode 100644
index 00000000000..cfa61b512de
--- /dev/null
+++ b/drivers/video/fbcvt.c
@@ -0,0 +1,380 @@
+/*
+ * linux/drivers/video/fbcvt.c - VESA(TM) Coordinated Video Timings
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
+ *
+ * Based from the VESA(TM) Coordinated Video Timing Generator by
+ * Graham Loveridge April 9, 2003 available at
+ * http://www.vesa.org/public/CVT/CVTd6r1.xls
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/fb.h>
+
+#define FB_CVT_CELLSIZE 8
+#define FB_CVT_GTF_C 40
+#define FB_CVT_GTF_J 20
+#define FB_CVT_GTF_K 128
+#define FB_CVT_GTF_M 600
+#define FB_CVT_MIN_VSYNC_BP 550
+#define FB_CVT_MIN_VPORCH 3
+#define FB_CVT_MIN_BPORCH 6
+
+#define FB_CVT_RB_MIN_VBLANK 460
+#define FB_CVT_RB_HBLANK 160
+#define FB_CVT_RB_V_FPORCH 3
+
+#define FB_CVT_FLAG_REDUCED_BLANK 1
+#define FB_CVT_FLAG_MARGINS 2
+#define FB_CVT_FLAG_INTERLACED 4
+
+struct fb_cvt_data {
+ u32 xres;
+ u32 yres;
+ u32 refresh;
+ u32 f_refresh;
+ u32 pixclock;
+ u32 hperiod;
+ u32 hblank;
+ u32 hfreq;
+ u32 htotal;
+ u32 vtotal;
+ u32 vsync;
+ u32 hsync;
+ u32 h_front_porch;
+ u32 h_back_porch;
+ u32 v_front_porch;
+ u32 v_back_porch;
+ u32 h_margin;
+ u32 v_margin;
+ u32 interlace;
+ u32 aspect_ratio;
+ u32 active_pixels;
+ u32 flags;
+ u32 status;
+};
+
+static int fb_cvt_vbi_tab[] = {
+ 4, /* 4:3 */
+ 5, /* 16:9 */
+ 6, /* 16:10 */
+ 7, /* 5:4 */
+ 7, /* 15:9 */
+ 8, /* reserved */
+ 9, /* reserved */
+ 10 /* custom */
+};
+
+/* returns hperiod * 1000 */
+static u32 fb_cvt_hperiod(struct fb_cvt_data *cvt)
+{
+ u32 num = 1000000000/cvt->f_refresh;
+ u32 den;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
+ num -= FB_CVT_RB_MIN_VBLANK * 1000;
+ den = 2 * (cvt->yres/cvt->interlace + 2 * cvt->v_margin);
+ } else {
+ num -= FB_CVT_MIN_VSYNC_BP * 1000;
+ den = 2 * (cvt->yres/cvt->interlace + cvt->v_margin * 2
+ + FB_CVT_MIN_VPORCH + cvt->interlace/2);
+ }
+
+ return 2 * (num/den);
+}
+
+/* returns ideal duty cycle * 1000 */
+static u32 fb_cvt_ideal_duty_cycle(struct fb_cvt_data *cvt)
+{
+ u32 c_prime = (FB_CVT_GTF_C - FB_CVT_GTF_J) *
+ (FB_CVT_GTF_K) + 256 * FB_CVT_GTF_J;
+ u32 m_prime = (FB_CVT_GTF_K * FB_CVT_GTF_M);
+ u32 h_period_est = cvt->hperiod;
+
+ return (1000 * c_prime - ((m_prime * h_period_est)/1000))/256;
+}
+
+static u32 fb_cvt_hblank(struct fb_cvt_data *cvt)
+{
+ u32 hblank = 0;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
+ hblank = FB_CVT_RB_HBLANK;
+ else {
+ u32 ideal_duty_cycle = fb_cvt_ideal_duty_cycle(cvt);
+ u32 active_pixels = cvt->active_pixels;
+
+ if (ideal_duty_cycle < 20000)
+ hblank = (active_pixels * 20000)/
+ (100000 - 20000);
+ else {
+ hblank = (active_pixels * ideal_duty_cycle)/
+ (100000 - ideal_duty_cycle);
+ }
+ }
+
+ hblank &= ~((2 * FB_CVT_CELLSIZE) - 1);
+
+ return hblank;
+}
+
+static u32 fb_cvt_hsync(struct fb_cvt_data *cvt)
+{
+ u32 hsync;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
+ hsync = 32;
+ else
+ hsync = (FB_CVT_CELLSIZE * cvt->htotal)/100;
+
+ hsync &= ~(FB_CVT_CELLSIZE - 1);
+ return hsync;
+}
+
+static u32 fb_cvt_vbi_lines(struct fb_cvt_data *cvt)
+{
+ u32 vbi_lines, min_vbi_lines, act_vbi_lines;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
+ vbi_lines = (1000 * FB_CVT_RB_MIN_VBLANK)/cvt->hperiod + 1;
+ min_vbi_lines = FB_CVT_RB_V_FPORCH + cvt->vsync +
+ FB_CVT_MIN_BPORCH;
+
+ } else {
+ vbi_lines = (FB_CVT_MIN_VSYNC_BP * 1000)/cvt->hperiod + 1 +
+ FB_CVT_MIN_VPORCH;
+ min_vbi_lines = cvt->vsync + FB_CVT_MIN_BPORCH +
+ FB_CVT_MIN_VPORCH;
+ }
+
+ if (vbi_lines < min_vbi_lines)
+ act_vbi_lines = min_vbi_lines;
+ else
+ act_vbi_lines = vbi_lines;
+
+ return act_vbi_lines;
+}
+
+static u32 fb_cvt_vtotal(struct fb_cvt_data *cvt)
+{
+ u32 vtotal = cvt->yres/cvt->interlace;
+
+ vtotal += 2 * cvt->v_margin + cvt->interlace/2 + fb_cvt_vbi_lines(cvt);
+ vtotal |= cvt->interlace/2;
+
+ return vtotal;
+}
+
+static u32 fb_cvt_pixclock(struct fb_cvt_data *cvt)
+{
+ u32 pixclock;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
+ pixclock = (cvt->f_refresh * cvt->vtotal * cvt->htotal)/1000;
+ else
+ pixclock = (cvt->htotal * 1000000)/cvt->hperiod;
+
+ pixclock /= 250;
+ pixclock *= 250;
+ pixclock *= 1000;
+
+ return pixclock;
+}
+
+static u32 fb_cvt_aspect_ratio(struct fb_cvt_data *cvt)
+{
+ u32 xres = cvt->xres;
+ u32 yres = cvt->yres;
+ u32 aspect = -1;
+
+ if (xres == (yres * 4)/3 && !((yres * 4) % 3))
+ aspect = 0;
+ else if (xres == (yres * 16)/9 && !((yres * 16) % 9))
+ aspect = 1;
+ else if (xres == (yres * 16)/10 && !((yres * 16) % 10))
+ aspect = 2;
+ else if (xres == (yres * 5)/4 && !((yres * 5) % 4))
+ aspect = 3;
+ else if (xres == (yres * 15)/9 && !((yres * 15) % 9))
+ aspect = 4;
+ else {
+ printk(KERN_INFO "fbcvt: Aspect ratio not CVT "
+ "standard\n");
+ aspect = 7;
+ cvt->status = 1;
+ }
+
+ return aspect;
+}
+
+static void fb_cvt_print_name(struct fb_cvt_data *cvt)
+{
+ u32 pixcount, pixcount_mod;
+ int cnt = 255, offset = 0, read = 0;
+ u8 *buf = kmalloc(256, GFP_KERNEL);
+
+ if (!buf)
+ return;
+
+ memset(buf, 0, 256);
+ pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000;
+ pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000;
+ pixcount_mod /= 1000;
+
+ read = snprintf(buf+offset, cnt, "fbcvt: %dx%d@%d: CVT Name - ",
+ cvt->xres, cvt->yres, cvt->refresh);
+ offset += read;
+ cnt -= read;
+
+ if (cvt->status)
+ snprintf(buf+offset, cnt, "Not a CVT standard - %d.%03d Mega "
+ "Pixel Image\n", pixcount, pixcount_mod);
+ else {
+ if (pixcount) {
+ read = snprintf(buf+offset, cnt, "%d", pixcount);
+ cnt -= read;
+ offset += read;
+ }
+
+ read = snprintf(buf+offset, cnt, ".%03dM", pixcount_mod);
+ cnt -= read;
+ offset += read;
+
+ if (cvt->aspect_ratio == 0)
+ read = snprintf(buf+offset, cnt, "3");
+ else if (cvt->aspect_ratio == 3)
+ read = snprintf(buf+offset, cnt, "4");
+ else if (cvt->aspect_ratio == 1 || cvt->aspect_ratio == 4)
+ read = snprintf(buf+offset, cnt, "9");
+ else if (cvt->aspect_ratio == 2)
+ read = snprintf(buf+offset, cnt, "A");
+ else
+ read = 0;
+ cnt -= read;
+ offset += read;
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
+ read = snprintf(buf+offset, cnt, "-R");
+ cnt -= read;
+ offset += read;
+ }
+ }
+
+ printk(KERN_INFO "%s\n", buf);
+ kfree(buf);
+}
+
+static void fb_cvt_convert_to_mode(struct fb_cvt_data *cvt,
+ struct fb_videomode *mode)
+{
+ mode->refresh = cvt->f_refresh;
+ mode->pixclock = KHZ2PICOS(cvt->pixclock/1000);
+ mode->left_margin = cvt->h_front_porch;
+ mode->right_margin = cvt->h_back_porch;
+ mode->hsync_len = cvt->hsync;
+ mode->upper_margin = cvt->v_front_porch;
+ mode->lower_margin = cvt->v_back_porch;
+ mode->vsync_len = cvt->vsync;
+
+ mode->sync &= ~(FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
+
+ if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
+ mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+ else
+ mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+}
+
+/*
+ * fb_find_mode_cvt - calculate mode using VESA(TM) CVT
+ * @mode: pointer to fb_videomode; xres, yres, refresh and vmode must be
+ * pre-filled with the desired values
+ * @margins: add margin to calculation (1.8% of xres and yres)
+ * @rb: compute with reduced blanking (for flatpanels)
+ *
+ * RETURNS:
+ * 0 for success
+ * @mode is filled with computed values. If interlaced, the refresh field
+ * will be filled with the field rate (2x the frame rate)
+ *
+ * DESCRIPTION:
+ * Computes video timings using VESA(TM) Coordinated Video Timings
+ */
+int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
+{
+ struct fb_cvt_data cvt;
+
+ memset(&cvt, 0, sizeof(cvt));
+
+ if (margins)
+ cvt.flags |= FB_CVT_FLAG_MARGINS;
+
+ if (rb)
+ cvt.flags |= FB_CVT_FLAG_REDUCED_BLANK;
+
+ if (mode->vmode & FB_VMODE_INTERLACED)
+ cvt.flags |= FB_CVT_FLAG_INTERLACED;
+
+ cvt.xres = mode->xres;
+ cvt.yres = mode->yres;
+ cvt.refresh = mode->refresh;
+ cvt.f_refresh = cvt.refresh;
+ cvt.interlace = 1;
+
+ if (!cvt.xres || !cvt.yres || !cvt.refresh) {
+ printk(KERN_INFO "fbcvt: Invalid input parameters\n");
+ return 1;
+ }
+
+ if (!(cvt.refresh == 50 || cvt.refresh == 60 || cvt.refresh == 70 ||
+ cvt.refresh == 85)) {
+ printk(KERN_INFO "fbcvt: Refresh rate not CVT "
+ "standard\n");
+ cvt.status = 1;
+ }
+
+ cvt.xres &= ~(FB_CVT_CELLSIZE - 1);
+
+ if (cvt.flags & FB_CVT_FLAG_INTERLACED) {
+ cvt.interlace = 2;
+ cvt.f_refresh *= 2;
+ }
+
+ if (cvt.flags & FB_CVT_FLAG_REDUCED_BLANK) {
+ if (cvt.refresh != 60) {
+ printk(KERN_INFO "fbcvt: 60Hz refresh rate "
+ "advised for reduced blanking\n");
+ cvt.status = 1;
+ }
+ }
+
+ if (cvt.flags & FB_CVT_FLAG_MARGINS) {
+ cvt.h_margin = (cvt.xres * 18)/1000;
+ cvt.h_margin &= ~(FB_CVT_CELLSIZE - 1);
+ cvt.v_margin = ((cvt.yres/cvt.interlace)* 18)/1000;
+ }
+
+ cvt.aspect_ratio = fb_cvt_aspect_ratio(&cvt);
+ cvt.active_pixels = cvt.xres + 2 * cvt.h_margin;
+ cvt.hperiod = fb_cvt_hperiod(&cvt);
+ cvt.vsync = fb_cvt_vbi_tab[cvt.aspect_ratio];
+ cvt.vtotal = fb_cvt_vtotal(&cvt);
+ cvt.hblank = fb_cvt_hblank(&cvt);
+ cvt.htotal = cvt.active_pixels + cvt.hblank;
+ cvt.hsync = fb_cvt_hsync(&cvt);
+ cvt.pixclock = fb_cvt_pixclock(&cvt);
+ cvt.hfreq = cvt.pixclock/cvt.htotal;
+ cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin;
+ cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch +
+ 2 * cvt.h_margin;
+ cvt.v_back_porch = 3 + cvt.v_margin;
+ cvt.v_front_porch = cvt.vtotal - cvt.yres/cvt.interlace -
+ cvt.v_back_porch - cvt.vsync;
+ fb_cvt_print_name(&cvt);
+ fb_cvt_convert_to_mode(&cvt, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(fb_find_mode_cvt);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 4ff853fbe0b..70be7009f8a 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -62,16 +62,26 @@ int num_registered_fb;
* Helpers
*/
-int fb_get_color_depth(struct fb_var_screeninfo *var)
+int fb_get_color_depth(struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
{
- if (var->green.length == var->blue.length &&
- var->green.length == var->red.length &&
- !var->green.offset && !var->blue.offset &&
- !var->red.offset)
- return var->green.length;
- else
- return (var->green.length + var->red.length +
- var->blue.length);
+ int depth = 0;
+
+ if (fix->visual == FB_VISUAL_MONO01 ||
+ fix->visual == FB_VISUAL_MONO10)
+ depth = 1;
+ else {
+ if (var->green.length == var->blue.length &&
+ var->green.length == var->red.length &&
+ var->green.offset == var->blue.offset &&
+ var->green.offset == var->red.offset)
+ depth = var->green.length;
+ else
+ depth = var->green.length + var->red.length +
+ var->blue.length;
+ }
+
+ return depth;
}
EXPORT_SYMBOL(fb_get_color_depth);
@@ -80,15 +90,7 @@ EXPORT_SYMBOL(fb_get_color_depth);
*/
void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
{
- int i, j;
-
- for (i = height; i--; ) {
- /* s_pitch is a few bytes at the most, memcpy is suboptimal */
- for (j = 0; j < s_pitch; j++)
- dst[j] = src[j];
- src += s_pitch;
- dst += d_pitch;
- }
+ __fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, height);
}
EXPORT_SYMBOL(fb_pad_aligned_buffer);
@@ -249,13 +251,18 @@ static void fb_set_logo(struct fb_info *info,
const struct linux_logo *logo, u8 *dst,
int depth)
{
- int i, j, k, fg = 1;
+ int i, j, k;
const u8 *src = logo->data;
- u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
+ u8 xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
+ u8 fg = 1, d;
- if (fb_get_color_depth(&info->var) == 3)
+ if (fb_get_color_depth(&info->var, &info->fix) == 3)
fg = 7;
+ if (info->fix.visual == FB_VISUAL_MONO01 ||
+ info->fix.visual == FB_VISUAL_MONO10)
+ fg = ~((u8) (0xfff << info->var.green.length));
+
switch (depth) {
case 4:
for (i = 0; i < logo->height; i++)
@@ -318,7 +325,7 @@ static struct logo_data {
int fb_prepare_logo(struct fb_info *info)
{
- int depth = fb_get_color_depth(&info->var);
+ int depth = fb_get_color_depth(&info->var, &info->fix);
memset(&fb_logo, 0, sizeof(struct logo_data));
@@ -684,11 +691,13 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
if (!err && (flags & FBINFO_MISC_USEREVENT)) {
struct fb_event event;
+ int evnt = (var->activate & FB_ACTIVATE_ALL) ?
+ FB_EVENT_MODE_CHANGE_ALL :
+ FB_EVENT_MODE_CHANGE;
info->flags &= ~FBINFO_MISC_USEREVENT;
event.info = info;
- notifier_call_chain(&fb_notifier_list,
- FB_EVENT_MODE_CHANGE,
+ notifier_call_chain(&fb_notifier_list, evnt,
&event);
}
}
@@ -1012,6 +1021,7 @@ register_framebuffer(struct fb_info *fb_info)
{
int i;
struct fb_event event;
+ struct fb_videomode mode;
if (num_registered_fb == FB_MAX)
return -ENXIO;
@@ -1042,16 +1052,11 @@ register_framebuffer(struct fb_info *fb_info)
}
fb_info->pixmap.offset = 0;
- if (!fb_info->modelist.prev ||
- !fb_info->modelist.next ||
- list_empty(&fb_info->modelist)) {
- struct fb_videomode mode;
-
+ if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
- fb_var_to_videomode(&mode, &fb_info->var);
- fb_add_videomode(&mode, &fb_info->modelist);
- }
+ fb_var_to_videomode(&mode, &fb_info->var);
+ fb_add_videomode(&mode, &fb_info->modelist);
registered_fb[i] = fb_info;
devfs_mk_cdev(MKDEV(FB_MAJOR, i),
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index c2718bb9494..713226cdf3c 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -29,6 +29,7 @@
#include <linux/tty.h>
#include <linux/fb.h>
#include <linux/module.h>
+#include <video/edid.h>
#ifdef CONFIG_PPC_OF
#include <linux/pci.h>
#include <asm/prom.h>
@@ -313,11 +314,13 @@ static int edid_is_monitor_block(unsigned char *block)
return 0;
}
-static void calc_mode_timings(int xres, int yres, int refresh, struct fb_videomode *mode)
+static void calc_mode_timings(int xres, int yres, int refresh,
+ struct fb_videomode *mode)
{
struct fb_var_screeninfo var;
struct fb_info info;
+ memset(&var, 0, sizeof(struct fb_var_screeninfo));
var.xres = xres;
var.yres = yres;
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)
-EINVAL : 0;
}
+#if defined(__i386__)
+#include <linux/pci.h>
+
+/*
+ * We need to ensure that the EDID block is only returned for
+ * the primary graphics adapter.
+ */
+
+const unsigned char *fb_firmware_edid(struct device *device)
+{
+ struct pci_dev *dev = NULL;
+ struct resource *res = NULL;
+ unsigned char *edid = NULL;
+
+ if (device)
+ dev = to_pci_dev(device);
+
+ if (dev)
+ res = &dev->resource[PCI_ROM_RESOURCE];
+
+ if (res && res->flags & IORESOURCE_ROM_SHADOW)
+ edid = edid_info.dummy;
+
+ return edid;
+}
+#else
+const unsigned char *fb_firmware_edid(struct device *device)
+{
+ return NULL;
+}
+#endif /* _i386_ */
+
EXPORT_SYMBOL(fb_parse_edid);
EXPORT_SYMBOL(fb_edid_to_monspecs);
-
+EXPORT_SYMBOL(fb_firmware_edid);
EXPORT_SYMBOL(fb_get_mode);
EXPORT_SYMBOL(fb_validate_mode);
EXPORT_SYMBOL(fb_destroy_modedb);
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index b075fd02de3..5a9b89c3831 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -3,15 +3,13 @@
#
config FB_GEODE
bool "AMD Geode family framebuffer support (EXPERIMENTAL)"
- default n
- depends on FB && EXPERIMENTAL && X86
+ depends on FB && PCI && EXPERIMENTAL && X86
---help---
Say 'Y' here to allow you to select framebuffer drivers for
the AMD Geode family of processors.
config FB_GEODE_GX1
tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
- default n
depends on FB_GEODE && EXPERIMENTAL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -21,9 +19,7 @@ config FB_GEODE_GX1
Framebuffer driver for the display controller integrated into the
AMD Geode GX1 processor.
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called gx1fb. If you want to compile it as a module,
- say M here and read <file:Documentation/modules.txt>.
+ To compile this driver as a module, choose M here: the module will be
+ called gx1fb.
If unsure, say N.
diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/geode/display_gx1.c
index f4983879fcc..926d53eeb54 100644
--- a/drivers/video/geode/display_gx1.c
+++ b/drivers/video/geode/display_gx1.c
@@ -22,7 +22,7 @@
#include "geodefb.h"
#include "display_gx1.h"
-static spinlock_t gx1_conf_reg_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(gx1_conf_reg_lock);
static u8 gx1_read_conf_reg(u8 reg)
{
diff --git a/drivers/video/geode/geodefb.h b/drivers/video/geode/geodefb.h
index b7bac0a526b..ae04820e0c5 100644
--- a/drivers/video/geode/geodefb.h
+++ b/drivers/video/geode/geodefb.h
@@ -29,7 +29,6 @@ struct geodefb_par {
int enable_crt;
int panel_x; /* dimensions of an attached flat panel, non-zero => enable panel */
int panel_y;
- struct pci_dev *vid_dev;
void __iomem *dc_regs;
void __iomem *vid_regs;
struct geode_dc_ops *dc_ops;
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 83830d24bcd..74a5fca86b8 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";
static int crt_option = 1;
static char panel_option[32] = "";
+/* Modes relevant to the GX1 (taken from modedb.c) */
+static const struct fb_videomode __initdata gx1_modedb[] = {
+ /* 640x480-60 VESA */
+ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 640x480-75 VESA */
+ { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 640x480-85 VESA */
+ { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 800x600-60 VESA */
+ { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 800x600-75 VESA */
+ { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 800x600-85 VESA */
+ { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1024x768-60 VESA */
+ { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1024x768-75 VESA */
+ { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1024x768-85 VESA */
+ { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1280x960-60 VESA */
+ { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1280x960-85 VESA */
+ { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1280x1024-60 VESA */
+ { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1280x1024-75 VESA */
+ { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+ /* 1280x1024-85 VESA */
+ { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
+};
+
static int gx1_line_delta(int xres, int bpp)
{
int line_delta = xres * (bpp >> 3);
@@ -47,8 +103,6 @@ static int gx1fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct geodefb_par *par = info->par;
- printk(KERN_DEBUG "%s()\n", __FUNCTION__);
-
/* Maximum resolution is 1280x1024. */
if (var->xres > 1280 || var->yres > 1024)
return -EINVAL;
@@ -146,40 +200,48 @@ static int gx1fb_blank(int blank_mode, struct fb_info *info)
return par->vid_ops->blank_display(info, blank_mode);
}
-static int __init gx1fb_map_video_memory(struct fb_info *info)
+static int __init gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
{
struct geodefb_par *par = info->par;
unsigned gx_base;
int fb_len;
+ int ret;
gx_base = gx1_gx_base();
if (!gx_base)
return -ENODEV;
- par->vid_dev = pci_get_device(PCI_VENDOR_ID_CYRIX,
- PCI_DEVICE_ID_CYRIX_5530_VIDEO, NULL);
- if (!par->vid_dev)
- return -ENODEV;
+ ret = pci_enable_device(dev);
+ if (ret < 0)
+ return ret;
- par->vid_regs = ioremap(pci_resource_start(par->vid_dev, 1),
- pci_resource_len(par->vid_dev, 1));
+ ret = pci_request_region(dev, 1, "gx1fb (video)");
+ if (ret < 0)
+ return ret;
+ par->vid_regs = ioremap(pci_resource_start(dev, 1),
+ pci_resource_len(dev, 1));
if (!par->vid_regs)
return -ENOMEM;
+ if (!request_mem_region(gx_base + 0x8300, 0x100, "gx1fb (display controller)"))
+ return -EBUSY;
par->dc_regs = ioremap(gx_base + 0x8300, 0x100);
if (!par->dc_regs)
return -ENOMEM;
- info->fix.smem_start = gx_base + 0x800000;
+ ret = pci_request_region(dev, 0, "gx1fb (frame buffer)");
+ if (ret < 0 )
+ return -EBUSY;
if ((fb_len = gx1_frame_buffer_size()) < 0)
return -ENOMEM;
+ info->fix.smem_start = pci_resource_start(dev, 0);
info->fix.smem_len = fb_len;
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
if (!info->screen_base)
return -ENOMEM;
- printk(KERN_INFO "%s: %d Kibyte of video memory at 0x%lx\n",
- info->fix.id, info->fix.smem_len / 1024, info->fix.smem_start);
+ dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
+ info->fix.smem_len / 1024, info->fix.smem_start);
return 0;
}
@@ -216,13 +278,13 @@ static struct fb_ops gx1fb_ops = {
.fb_cursor = soft_cursor,
};
-static struct fb_info * __init gx1fb_init_fbinfo(void)
+static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
{
- struct fb_info *info;
struct geodefb_par *par;
+ struct fb_info *info;
/* Alloc enough space for the pseudo palette. */
- info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, NULL);
+ info = framebuffer_alloc(sizeof(struct geodefb_par) + sizeof(u32) * 16, dev);
if (!info)
return NULL;
@@ -255,47 +317,37 @@ static struct fb_info * __init gx1fb_init_fbinfo(void)
/* CRT and panel options */
par->enable_crt = crt_option;
if (parse_panel_option(info) < 0)
- printk(KERN_WARNING "%s: invalid 'panel' option -- disabling flat panel\n",
- info->fix.id);
+ printk(KERN_WARNING "gx1fb: invalid 'panel' option -- disabling flat panel\n");
if (!par->panel_x)
par->enable_crt = 1; /* fall back to CRT if no panel is specified */
return info;
}
-
-static struct fb_info *gx1fb_info;
-
-static int __init gx1fb_init(void)
+static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct geodefb_par *par;
struct fb_info *info;
- struct geodefb_par *par;
int ret;
-#ifndef MODULE
- if (fb_get_options("gx1fb", NULL))
- return -ENODEV;
-#endif
-
- info = gx1fb_init_fbinfo();
+ info = gx1fb_init_fbinfo(&pdev->dev);
if (!info)
return -ENOMEM;
- gx1fb_info = info;
-
par = info->par;
/* GX1 display controller and CS5530 video device */
par->dc_ops = &gx1_dc_ops;
par->vid_ops = &cs5530_vid_ops;
- if ((ret = gx1fb_map_video_memory(info)) < 0) {
- printk(KERN_ERR "%s: gx1fb_map_video_memory() failed\n", info->fix.id);
+ if ((ret = gx1fb_map_video_memory(info, pdev)) < 0) {
+ dev_err(&pdev->dev, "failed to map frame buffer or controller registers\n");
goto err;
}
- ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16);
+ ret = fb_find_mode(&info->var, info, mode_option,
+ gx1_modedb, ARRAY_SIZE(gx1_modedb), NULL, 16);
if (ret == 0 || ret == 4) {
- printk(KERN_ERR "%s: could not find valid video mode\n", info->fix.id);
+ dev_err(&pdev->dev, "could not find valid video mode\n");
ret = -EINVAL;
goto err;
}
@@ -310,39 +362,83 @@ static int __init gx1fb_init(void)
ret = -EINVAL;
goto err;
}
+ pci_set_drvdata(pdev, info);
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
return 0;
err:
- if (info->screen_base)
+ if (info->screen_base) {
iounmap(info->screen_base);
- if (par->vid_regs)
+ pci_release_region(pdev, 0);
+ }
+ if (par->vid_regs) {
iounmap(par->vid_regs);
- if (par->dc_regs)
+ pci_release_region(pdev, 1);
+ }
+ if (par->dc_regs) {
iounmap(par->dc_regs);
- if (par->vid_dev)
- pci_dev_put(par->vid_dev);
+ release_mem_region(gx1_gx_base() + 0x8300, 0x100);
+ }
+
+ pci_disable_device(pdev);
+
if (info)
framebuffer_release(info);
return ret;
}
-static void __exit gx1fb_cleanup(void)
+static void gx1fb_remove(struct pci_dev *pdev)
{
- struct fb_info *info = gx1fb_info;
- struct geodefb_par *par = gx1fb_info->par;
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct geodefb_par *par = info->par;
unregister_framebuffer(info);
iounmap((void __iomem *)info->screen_base);
+ pci_release_region(pdev, 0);
+
iounmap(par->vid_regs);
+ pci_release_region(pdev, 1);
+
iounmap(par->dc_regs);
+ release_mem_region(gx1_gx_base() + 0x8300, 0x100);
- pci_dev_put(par->vid_dev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
}
+static struct pci_device_id gx1fb_id_table[] = {
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_VIDEO,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+ 0xff0000, 0 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, gx1fb_id_table);
+
+static struct pci_driver gx1fb_driver = {
+ .name = "gx1fb",
+ .id_table = gx1fb_id_table,
+ .probe = gx1fb_probe,
+ .remove = gx1fb_remove,
+};
+
+static int __init gx1fb_init(void)
+{
+#ifndef MODULE
+ if (fb_get_options("gx1fb", NULL))
+ return -ENODEV;
+#endif
+ return pci_register_driver(&gx1fb_driver);
+}
+
+static void __exit gx1fb_cleanup(void)
+{
+ pci_unregister_driver(&gx1fb_driver);
+}
+
module_init(gx1fb_init);
module_exit(gx1fb_cleanup);
diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/geode/video_cs5530.c
index d3764acf844..649c3943d43 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[] = {
{ 4310, 0x2FB1B802, }, /* 232.0000 */
};
-#define NUM_CS5530_FREQUENCIES sizeof(cs5530_pll_table)/sizeof(struct cs5530_pll_entry)
-
static void cs5530_set_dclk_frequency(struct fb_info *info)
{
struct geodefb_par *par = info->par;
@@ -82,7 +80,7 @@ static void cs5530_set_dclk_frequency(struct fb_info *info)
value = cs5530_pll_table[0].pll_value;
min = cs5530_pll_table[0].pixclock - info->var.pixclock;
if (min < 0) min = -min;
- for (i = 1; i < NUM_CS5530_FREQUENCIES; i++) {
+ for (i = 1; i < ARRAY_SIZE(cs5530_pll_table); i++) {
diff = cs5530_pll_table[i].pixclock - info->var.pixclock;
if (diff < 0L) diff = -diff;
if (diff < min) {
diff --git a/drivers/video/i810/Makefile b/drivers/video/i810/Makefile
index 794ae76c7c4..96e08c8ded9 100644
--- a/drivers/video/i810/Makefile
+++ b/drivers/video/i810/Makefile
@@ -4,7 +4,6 @@
obj-$(CONFIG_FB_I810) += i810fb.o
-
i810fb-objs := i810_main.o i810_accel.o
ifdef CONFIG_FB_I810_GTF
@@ -12,3 +11,7 @@ i810fb-objs += i810_gtf.o
else
i810fb-objs += i810_dvt.o
endif
+
+ifdef CONFIG_FB_I810_I2C
+i810fb-objs += i810-i2c.o
+endif
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
new file mode 100644
index 00000000000..fda53aac1fc
--- /dev/null
+++ b/drivers/video/i810/i810-i2c.c
@@ -0,0 +1,257 @@
+ /*-*- linux-c -*-
+ * linux/drivers/video/i810-i2c.c -- Intel 810/815 I2C support
+ *
+ * Copyright (C) 2004 Antonino Daplas<adaplas@pol.net>
+ * All Rights Reserved
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+#include "i810.h"
+#include "i810_regs.h"
+#include "../edid.h"
+
+#define I810_DDC 0x50
+/* bit locations in the registers */
+#define SCL_DIR_MASK 0x0001
+#define SCL_DIR 0x0002
+#define SCL_VAL_MASK 0x0004
+#define SCL_VAL_OUT 0x0008
+#define SCL_VAL_IN 0x0010
+#define SDA_DIR_MASK 0x0100
+#define SDA_DIR 0x0200
+#define SDA_VAL_MASK 0x0400
+#define SDA_VAL_OUT 0x0800
+#define SDA_VAL_IN 0x1000
+
+#define DEBUG /* define this for verbose EDID parsing output */
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(fmt,## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+static void i810i2c_setscl(void *data, int state)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
+ SCL_DIR_MASK | SCL_VAL_MASK);
+ i810_readl(mmio, GPIOB); /* flush posted write */
+}
+
+static void i810i2c_setsda(void *data, int state)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
+ SDA_DIR_MASK | SDA_VAL_MASK);
+ i810_readl(mmio, GPIOB); /* flush posted write */
+}
+
+static int i810i2c_getscl(void *data)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOB, SCL_DIR_MASK);
+ i810_writel(mmio, GPIOB, 0);
+ return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN));
+}
+
+static int i810i2c_getsda(void *data)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOB, SDA_DIR_MASK);
+ i810_writel(mmio, GPIOB, 0);
+ return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN));
+}
+
+static void i810ddc_setscl(void *data, int state)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
+ SCL_DIR_MASK | SCL_VAL_MASK);
+ i810_readl(mmio, GPIOA); /* flush posted write */
+}
+
+static void i810ddc_setsda(void *data, int state)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
+ SDA_DIR_MASK | SDA_VAL_MASK);
+ i810_readl(mmio, GPIOA); /* flush posted write */
+}
+
+static int i810ddc_getscl(void *data)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOA, SCL_DIR_MASK);
+ i810_writel(mmio, GPIOA, 0);
+ return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
+}
+
+static int i810ddc_getsda(void *data)
+{
+ struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
+ struct i810fb_par *par = chan->par;
+ u8 *mmio = par->mmio_start_virtual;
+
+ i810_writel(mmio, GPIOA, SDA_DIR_MASK);
+ i810_writel(mmio, GPIOA, 0);
+ return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
+}
+
+#define I2C_ALGO_DDC_I810 0x0e0000
+#define I2C_ALGO_I2C_I810 0x0f0000
+static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
+ int conn)
+{
+ int rc;
+
+ strcpy(chan->adapter.name, name);
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = &chan->par->dev->dev;
+ switch (conn) {
+ case 1:
+ chan->adapter.id = I2C_ALGO_DDC_I810;
+ chan->algo.setsda = i810ddc_setsda;
+ chan->algo.setscl = i810ddc_setscl;
+ chan->algo.getsda = i810ddc_getsda;
+ chan->algo.getscl = i810ddc_getscl;
+ break;
+ case 2:
+ chan->adapter.id = I2C_ALGO_I2C_I810;
+ chan->algo.setsda = i810i2c_setsda;
+ chan->algo.setscl = i810i2c_setscl;
+ chan->algo.getsda = i810i2c_getsda;
+ chan->algo.getscl = i810i2c_getscl;
+ break;
+ }
+ chan->algo.udelay = 10;
+ chan->algo.mdelay = 10;
+ chan->algo.timeout = (HZ/2);
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ /* Raise SCL and SDA */
+ chan->algo.setsda(chan, 1);
+ chan->algo.setscl(chan, 1);
+ udelay(20);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
+ else
+ dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
+ "%s.\n", name);
+ return rc;
+}
+
+void i810_create_i2c_busses(struct i810fb_par *par)
+{
+ par->chan[0].par = par;
+ par->chan[1].par = par;
+ i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1);
+ i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2);
+}
+
+void i810_delete_i2c_busses(struct i810fb_par *par)
+{
+ if (par->chan[0].par)
+ i2c_bit_del_bus(&par->chan[0].adapter);
+ par->chan[0].par = NULL;
+ if (par->chan[1].par)
+ i2c_bit_del_bus(&par->chan[1].adapter);
+ par->chan[1].par = NULL;
+}
+
+static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
+{
+ u8 start = 0x0;
+ struct i2c_msg msgs[] = {
+ {
+ .addr = I810_DDC,
+ .len = 1,
+ .buf = &start,
+ }, {
+ .addr = I810_DDC,
+ .flags = I2C_M_RD,
+ .len = EDID_LENGTH,
+ },
+ };
+ u8 *buf;
+
+ buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!buf) {
+ DPRINTK("i810-i2c: Failed to allocate memory\n");
+ return NULL;
+ }
+ msgs[1].buf = buf;
+
+ if (i2c_transfer(&chan->adapter, msgs, 2) == 2) {
+ DPRINTK("i810-i2c: I2C Transfer successful\n");
+ return buf;
+ }
+ DPRINTK("i810-i2c: Unable to read EDID block.\n");
+ kfree(buf);
+ return NULL;
+}
+
+int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
+{
+ struct i810fb_par *par = info->par;
+ u8 *edid = NULL;
+ int i;
+
+ DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
+ if (conn < 3) {
+ for (i = 0; i < 3; i++) {
+ /* Do the real work */
+ edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
+ if (edid)
+ break;
+ }
+ } else {
+ DPRINTK("i810-i2c: Getting EDID from BIOS\n");
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, fb_firmware_edid(info->device),
+ EDID_LENGTH);
+ }
+
+ if (out_edid)
+ *out_edid = edid;
+
+ return (edid) ? 0 : 1;
+}
+
+
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index fe3b7579475..d48949ceaac 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -16,6 +16,9 @@
#include <linux/list.h>
#include <linux/agp_backend.h>
#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
#include <video/vga.h>
/* Fence */
@@ -201,7 +204,6 @@
#define HAS_ACCELERATION 2
#define ALWAYS_SYNC 4
#define LOCKUP 8
-#define USE_HWCUR 16
struct gtt_data {
struct agp_memory *i810_fb_memory;
@@ -241,6 +243,14 @@ struct state_registers {
u8 cr39, cr41, cr70, sr01, msr;
};
+struct i810fb_par;
+
+struct i810fb_i2c_chan {
+ struct i810fb_par *par;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
struct i810fb_par {
struct mode_registers regs;
struct state_registers hw_state;
@@ -252,10 +262,12 @@ struct i810fb_par {
struct heap_data iring;
struct heap_data cursor_heap;
struct vgastate state;
+ struct i810fb_i2c_chan chan[2];
atomic_t use_count;
u32 pseudo_palette[17];
unsigned long mmio_start_phys;
u8 __iomem *mmio_start_virtual;
+ u8 *edid;
u32 pitch;
u32 pixconf;
u32 watermark;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 6db183462b9..7018ffffcbc 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 = {
.resume = i810fb_resume,
};
-static int vram __initdata = 4;
-static int bpp __initdata = 8;
-static int mtrr __initdata = 0;
-static int accel __initdata = 0;
-static int hsync1 __initdata = 0;
-static int hsync2 __initdata = 0;
-static int vsync1 __initdata = 0;
-static int vsync2 __initdata = 0;
-static int xres __initdata = 640;
-static int yres __initdata = 480;
-static int vyres __initdata = 0;
-static int sync __initdata = 0;
-static int ext_vga __initdata = 0;
-static int dcolor __initdata = 0;
+static char *mode_option __devinitdata = NULL;
+static int vram __devinitdata = 4;
+static int bpp __devinitdata = 8;
+static int mtrr __devinitdata = 0;
+static int accel __devinitdata = 0;
+static int hsync1 __devinitdata = 0;
+static int hsync2 __devinitdata = 0;
+static int vsync1 __devinitdata = 0;
+static int vsync2 __devinitdata = 0;
+static int xres __devinitdata = 640;
+static int yres __devinitdata = 480;
+static int vyres __devinitdata = 0;
+static int sync __devinitdata = 0;
+static int ext_vga __devinitdata = 0;
+static int dcolor __devinitdata = 0;
/*------------------------------------------------------------*/
@@ -310,6 +311,8 @@ static void i810_hires(u8 __iomem *mmio)
val = i810_readb(CR_DATA_CGA, mmio);
i810_writeb(CR_INDEX_CGA, mmio, CR80);
i810_writeb(CR_DATA_CGA, mmio, val | 1);
+ /* Stop LCD displays from flickering */
+ i810_writel(MEM_MODE, mmio, i810_readl(MEM_MODE, mmio) | 4);
}
/**
@@ -947,31 +950,24 @@ static int i810_check_params(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct i810fb_par *par = (struct i810fb_par *) info->par;
- int line_length, vidmem;
- u32 xres, yres, vxres, vyres;
-
- xres = var->xres;
- yres = var->yres;
- vxres = var->xres_virtual;
- vyres = var->yres_virtual;
-
+ int line_length, vidmem, mode_valid = 0;
+ u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
/*
* Memory limit
*/
- line_length = get_line_length(par, vxres,
- var->bits_per_pixel);
-
+ line_length = get_line_length(par, vxres, var->bits_per_pixel);
vidmem = line_length*vyres;
+
if (vidmem > par->fb.size) {
vyres = par->fb.size/line_length;
- if (vyres < yres) {
+ if (vyres < var->yres) {
vyres = yres;
vxres = par->fb.size/vyres;
vxres /= var->bits_per_pixel >> 3;
line_length = get_line_length(par, vxres,
var->bits_per_pixel);
vidmem = line_length * yres;
- if (vxres < xres) {
+ if (vxres < var->xres) {
printk("i810fb: required video memory, "
"%d bytes, for %dx%d-%d (virtual) "
"is out of range\n",
@@ -981,6 +977,10 @@ static int i810_check_params(struct fb_var_screeninfo *var,
}
}
}
+
+ var->xres_virtual = vxres;
+ var->yres_virtual = vyres;
+
/*
* Monitor limit
*/
@@ -996,25 +996,39 @@ static int i810_check_params(struct fb_var_screeninfo *var,
info->monspecs.dclkmax = 204000000;
break;
}
+
info->monspecs.dclkmin = 15000000;
- if (fb_validate_mode(var, info)) {
+ if (!fb_validate_mode(var, info))
+ mode_valid = 1;
+
+#ifdef CONFIG_FB_I810_I2C
+ if (!mode_valid && info->monspecs.gtf &&
+ !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ mode_valid = 1;
+
+ if (!mode_valid && info->monspecs.modedb_len) {
+ struct fb_videomode *mode;
+
+ mode = fb_find_best_mode(var, &info->modelist);
+ if (mode) {
+ fb_videomode_to_var(var, mode);
+ mode_valid = 1;
+ }
+ }
+#endif
+ if (!mode_valid && info->monspecs.modedb_len == 0) {
if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
int default_sync = (info->monspecs.hfmin-HFMIN)
- |(info->monspecs.hfmax-HFMAX)
- |(info->monspecs.vfmin-VFMIN)
- |(info->monspecs.vfmax-VFMAX);
+ |(info->monspecs.hfmax-HFMAX)
+ |(info->monspecs.vfmin-VFMIN)
+ |(info->monspecs.vfmax-VFMAX);
printk("i810fb: invalid video mode%s\n",
- default_sync ? "" :
- ". Specifying vsyncN/hsyncN parameters may help");
- return -EINVAL;
+ default_sync ? "" : ". Specifying "
+ "vsyncN/hsyncN parameters may help");
}
}
-
- var->xres = xres;
- var->yres = yres;
- var->xres_virtual = vxres;
- var->yres_virtual = vyres;
+
return 0;
}
@@ -1375,7 +1389,6 @@ static int i810fb_set_par(struct fb_info *info)
decode_var(&info->var, par);
i810_load_regs(par);
i810_init_cursor(par);
-
encode_fix(&info->fix, info);
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)
struct i810fb_par *par = (struct i810fb_par *)info->par;
u8 __iomem *mmio = par->mmio_start_virtual;
- if (!(par->dev_flags & USE_HWCUR) || !info->var.accel_flags ||
- par->dev_flags & LOCKUP)
- return soft_cursor(info, cursor);
+ if (!par->dev_flags & LOCKUP)
+ return -ENXIO;
if (cursor->image.width > 64 || cursor->image.height > 64)
return -ENXIO;
@@ -1814,8 +1826,72 @@ i810_allocate_pci_resource(struct i810fb_par *par,
return 0;
}
+static void __devinit i810fb_find_init_mode(struct fb_info *info)
+{
+ struct fb_videomode mode;
+ struct fb_var_screeninfo var;
+ struct fb_monspecs *specs = NULL;
+ int found = 0;
+#ifdef CONFIG_FB_I810_I2C
+ int i;
+ int err;
+ struct i810fb_par *par = info->par;
+#endif
+
+ INIT_LIST_HEAD(&info->modelist);
+ memset(&mode, 0, sizeof(struct fb_videomode));
+ var = info->var;
+#ifdef CONFIG_FB_I810_I2C
+ i810_create_i2c_busses(par);
+
+ for (i = 0; i < 3; i++) {
+ err = i810_probe_i2c_connector(info, &par->edid, i+1);
+ if (!err)
+ break;
+ }
+
+ if (!err)
+ printk("i810fb_init_pci: DDC probe successful\n");
+
+ fb_edid_to_monspecs(par->edid, &info->monspecs);
+
+ if (info->monspecs.modedb == NULL)
+ printk("i810fb_init_pci: Unable to get Mode Database\n");
+
+ specs = &info->monspecs;
+ fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
+ &info->modelist);
+ if (specs->modedb != NULL) {
+ if (specs->misc & FB_MISC_1ST_DETAIL) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+ mode = specs->modedb[i];
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ mode = specs->modedb[0];
+ found = 1;
+ }
+
+ fb_videomode_to_var(&var, &mode);
+ }
+#endif
+ if (mode_option)
+ fb_find_mode(&var, info, mode_option, specs->modedb,
+ specs->modedb_len, (found) ? &mode : NULL,
+ info->var.bits_per_pixel);
+
+ info->var = var;
+ fb_destroy_modedb(specs->modedb);
+ specs->modedb = NULL;
+}
+
#ifndef MODULE
-static int __init i810fb_setup(char *options)
+static int __devinit i810fb_setup(char *options)
{
char *this_opt, *suffix = NULL;
@@ -1857,6 +1933,8 @@ static int __init i810fb_setup(char *options)
vsync2 = simple_strtoul(this_opt+7, NULL, 0);
else if (!strncmp(this_opt, "dcolor", 6))
dcolor = 1;
+ else
+ mode_option = this_opt;
}
return 0;
}
@@ -1867,6 +1945,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
{
struct fb_info *info;
struct i810fb_par *par = NULL;
+ struct fb_videomode mode;
int i, err = -1, vfreq, hfreq, pixclock;
i = 0;
@@ -1875,7 +1954,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
if (!info)
return -ENOMEM;
- par = (struct i810fb_par *) info->par;
+ par = info->par;
par->dev = dev;
if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
@@ -1906,15 +1985,20 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
info->fbops = &par->i810fb_ops;
info->pseudo_palette = par->pseudo_palette;
fb_alloc_cmap(&info->cmap, 256, 0);
+ i810fb_find_init_mode(info);
if ((err = info->fbops->fb_check_var(&info->var, info))) {
i810fb_release_resource(info, par);
return err;
}
+
+ fb_var_to_videomode(&mode, &info->var);
+ fb_add_videomode(&mode, &info->modelist);
encode_fix(&info->fix, info);
i810fb_init_ringbuffer(info);
err = register_framebuffer(info);
+
if (err < 0) {
i810fb_release_resource(info, par);
printk("i810fb_init: cannot register framebuffer device\n");
@@ -1953,6 +2037,8 @@ static void i810fb_release_resource(struct fb_info *info,
struct gtt_data *gtt = &par->i810_gtt;
unset_mtrr(par);
+ i810_delete_i2c_busses(par);
+
if (par->i810_gtt.i810_cursor_memory)
agp_free_memory(gtt->i810_cursor_memory);
if (par->i810_gtt.i810_fb_memory)
@@ -1962,7 +2048,8 @@ static void i810fb_release_resource(struct fb_info *info,
iounmap(par->mmio_start_virtual);
if (par->aperture.virtual)
iounmap(par->aperture.virtual);
-
+ if (par->edid)
+ kfree(par->edid);
if (par->res_flags & FRAMEBUFFER_REQ)
release_mem_region(par->aperture.physical,
par->aperture.size);
@@ -1988,7 +2075,7 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)
}
#ifndef MODULE
-static int __init i810fb_init(void)
+static int __devinit i810fb_init(void)
{
char *option = NULL;
@@ -2006,7 +2093,7 @@ static int __init i810fb_init(void)
#ifdef MODULE
-static int __init i810fb_init(void)
+static int __devinit i810fb_init(void)
{
hsync1 *= 1000;
hsync2 *= 1000;
@@ -2054,6 +2141,8 @@ MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
module_param(dcolor, bool, 0);
MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
" (default = 0 = TrueColor)");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Specify initial video mode");
MODULE_AUTHOR("Tony A. Daplas");
MODULE_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 43b4297b4d4..06072a6466f 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);
extern void i810fb_init_ringbuffer(struct fb_info *info);
extern void i810fb_load_front (u32 offset, struct fb_info *info);
+#ifdef CONFIG_FB_I810_I2C
+/* I2C */
+extern int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid,
+ int conn);
+extern void i810_create_i2c_busses(struct i810fb_par *par);
+extern void i810_delete_i2c_busses(struct i810fb_par *par);
+#else
+static inline int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid,
+ int conn)
+{
+ return 1;
+}
+static inline void i810_create_i2c_busses(struct i810fb_par *par) { }
+static inline void i810_delete_i2c_busses(struct i810fb_par *par) { }
+#endif
+
/* Conditionals */
#ifdef CONFIG_X86
inline void flush_cache(void)
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6680ec9ba69..011e1162655 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -234,7 +234,6 @@ struct intelfb_info {
/* palette */
u32 pseudo_palette[17];
- struct { u8 red, green, blue, pad; } palette[256];
/* chip info */
int pci_chipset;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index a112a178685..bf62e6ed038 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -117,14 +117,10 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
#include <linux/pagemap.h>
#include <linux/version.h>
@@ -242,7 +238,7 @@ static int voffset = 48;
static char *mode = NULL;
module_param(accel, bool, S_IRUGO);
-MODULE_PARM_DESC(accel, "Enable console acceleration");
+MODULE_PARM_DESC(accel, "Enable hardware acceleration");
module_param(vram, int, S_IRUGO);
MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB");
module_param(voffset, int, S_IRUGO);
@@ -498,7 +494,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct fb_info *info;
struct intelfb_info *dinfo;
- int i, j, err, dvo;
+ int i, err, dvo;
int aperture_size, stolen_size;
struct agp_kern_info gtt_info;
int agp_memtype;
@@ -845,13 +841,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
if (bailearly == 5)
bailout(dinfo);
- for (i = 0; i < 16; i++) {
- j = color_table[i];
- dinfo->palette[i].red = default_red[j];
- dinfo->palette[i].green = default_grn[j];
- dinfo->palette[i].blue = default_blu[j];
- }
-
if (bailearly == 6)
bailout(dinfo);
@@ -1363,10 +1352,6 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
green >>= 8;
blue >>= 8;
- dinfo->palette[regno].red = red;
- dinfo->palette[regno].green = green;
- dinfo->palette[regno].blue = blue;
-
intelfbhw_setcolreg(dinfo, regno, red, green, blue,
transp);
}
@@ -1499,7 +1484,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
#endif
if (!dinfo->hwcursor)
- return soft_cursor(info, cursor);
+ return -ENXIO;
intelfbhw_cursor_hide(dinfo);
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index f5bed581dc4..5bafc3c54db 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -29,14 +29,10 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
#include <linux/pagemap.h>
#include <linux/version.h>
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index a18dd024fc8..d9d3e9f6c08 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -68,6 +68,9 @@
* "David C. Hansen" <haveblue@us.ibm.com>
* Fixes
*
+ * "Ian Romanick" <idr@us.ibm.com>
+ * Find PInS data in BIOS on PowerPC systems.
+ *
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
@@ -496,10 +499,35 @@ static void parse_bios(unsigned char __iomem* vbios, struct matrox_bios* bd) {
get_bios_version(vbios, bd);
get_bios_output(vbios, bd);
get_bios_tvout(vbios, bd);
+#if defined(__powerpc__)
+ /* On PowerPC cards, the PInS offset isn't stored at the end of the
+ * BIOS image. Instead, you must search the entire BIOS image for
+ * the magic PInS signature.
+ *
+ * This actually applies to all OpenFirmware base cards. Since these
+ * cards could be put in a MIPS or SPARC system, should the condition
+ * be something different?
+ */
+ for ( pins_offset = 0 ; pins_offset <= 0xFF80 ; pins_offset++ ) {
+ unsigned char header[3];
+
+ header[0] = readb(vbios + pins_offset);
+ header[1] = readb(vbios + pins_offset + 1);
+ header[2] = readb(vbios + pins_offset + 2);
+ if ( (header[0] == 0x2E) && (header[1] == 0x41)
+ && ((header[2] == 0x40) || (header[2] == 0x80)) ) {
+ printk(KERN_INFO "PInS data found at offset %u\n",
+ pins_offset);
+ get_pins(vbios + pins_offset, bd);
+ break;
+ }
+ }
+#else
pins_offset = readb(vbios + 0x7FFC) | (readb(vbios + 0x7FFD) << 8);
if (pins_offset <= 0xFF80) {
get_pins(vbios + pins_offset, bd);
}
+#endif
}
#define get_u16(x) (le16_to_cpu(get_unaligned((__u16*)(x))))
@@ -755,6 +783,8 @@ void matroxfb_read_pins(WPMINFO2) {
}
#endif
matroxfb_set_limits(PMINFO &ACCESS_FBINFO(bios));
+ printk(KERN_INFO "PInS memtype = %u\n",
+ (ACCESS_FBINFO(values).reg.opt & 0x1C00) >> 10);
}
EXPORT_SYMBOL(matroxfb_DAC_in);
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3edc9f49344..47516c44a39 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,
*
* Valid mode specifiers for @mode_option:
*
- * <xres>x<yres>[-<bpp>][@<refresh>] or
+ * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
* <name>[-<bpp>][@<refresh>]
*
* with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
* <name> a string.
*
+ * If 'M' is present after yres (and before refresh/bpp if present),
+ * the function will compute the timings using VESA(tm) Coordinated
+ * Video Timings (CVT). If 'R' is present after 'M', will compute with
+ * reduced blanking (for flatpanels). If 'i' is present, compute
+ * interlaced mode. If 'm' is present, add margins equal to 1.8%
+ * of xres rounded down to 8 pixels, and 1.8% of yres. The char
+ * 'i' and 'm' must be after 'M' and 'R'. Example:
+ *
+ * 1024x768MR-8@60m - Reduced blank with margins at 60Hz.
+ *
* NOTE: The passed struct @var is _not_ cleared! This allows you
* to supply values for e.g. the grayscale and accel_flags fields.
*
@@ -495,7 +505,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
- int yres_specified = 0;
+ int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
u32 best, diff;
for (i = namelen-1; i >= 0; i--) {
@@ -506,6 +516,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
!yres_specified) {
refresh = my_atoi(&name[i+1]);
refresh_specified = 1;
+ if (cvt || rb)
+ cvt = 0;
} else
goto done;
break;
@@ -514,6 +526,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
if (!bpp_specified && !yres_specified) {
bpp = my_atoi(&name[i+1]);
bpp_specified = 1;
+ if (cvt || rb)
+ cvt = 0;
} else
goto done;
break;
@@ -526,6 +540,22 @@ int fb_find_mode(struct fb_var_screeninfo *var,
break;
case '0'...'9':
break;
+ case 'M':
+ if (!yres_specified)
+ cvt = 1;
+ break;
+ case 'R':
+ if (!cvt)
+ rb = 1;
+ break;
+ case 'm':
+ if (!cvt)
+ margins = 1;
+ break;
+ case 'i':
+ if (!cvt)
+ interlace = 1;
+ break;
default:
goto done;
}
@@ -535,6 +565,34 @@ int fb_find_mode(struct fb_var_screeninfo *var,
res_specified = 1;
}
done:
+ if (cvt) {
+ struct fb_videomode cvt_mode;
+ int ret;
+
+ DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
+ (refresh) ? refresh : 60, (rb) ? " reduced blanking" :
+ "", (margins) ? " with margins" : "", (interlace) ?
+ " interlaced" : "");
+
+ cvt_mode.xres = xres;
+ cvt_mode.yres = yres;
+ cvt_mode.refresh = (refresh) ? refresh : 60;
+
+ if (interlace)
+ cvt_mode.vmode |= FB_VMODE_INTERLACED;
+ else
+ cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
+
+ ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
+
+ if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
+ DPRINTK("modedb CVT: CVT mode ok\n");
+ return 1;
+ }
+
+ DPRINTK("CVT mode invalid, getting mode from database\n");
+ }
+
DPRINTK("Trying specified video mode%s %ix%i\n",
refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 1a91bffdda2..ace484fa61c 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)
return NULL;
}
-int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
+int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
{
+ struct nvidia_par *par = info->par;
u8 *edid = NULL;
int i;
@@ -205,10 +206,17 @@ int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
if (edid)
break;
}
+
+ if (!edid && conn == 1) {
+ /* try to get from firmware */
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, fb_firmware_edid(info->device),
+ EDID_LENGTH);
+ }
+
if (out_edid)
*out_edid = edid;
- if (!edid)
- return 1;
- return 0;
+ return (edid) ? 0 : 1;
}
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index 9da320986f4..afee284fc73 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -95,6 +95,7 @@
#define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2)
+#ifdef __LITTLE_ENDIAN
#define reverse_order(l) \
do { \
u8 *a = (u8 *)(l); \
@@ -103,5 +104,8 @@ do { \
*a = byte_rev[*a], a++; \
*a = byte_rev[*a]; \
} while(0)
+#else
+#define reverse_order(l)
+#endif /* __LITTLE_ENDIAN */
#endif /* __NV_LOCAL_H__ */
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 42847ce1b8d..cac44fc7f58 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);
#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
void nvidia_create_i2c_busses(struct nvidia_par *par);
void nvidia_delete_i2c_busses(struct nvidia_par *par);
-int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn,
+int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
u8 ** out_edid);
#else
#define nvidia_create_i2c_busses(...)
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 0bbdca2e0f9..11c84178f42 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)
nvidia_create_i2c_busses(par);
if (!par->twoHeads) {
par->CRTCnumber = 0;
- nvidia_probe_i2c_connector(par, 1, &edidA);
+ nvidia_probe_i2c_connector(info, 1, &edidA);
if (edidA && !fb_parse_edid(edidA, &var)) {
printk("nvidiafb: EDID found from BUS1\n");
monA = &monitorA;
@@ -488,14 +488,14 @@ void NVCommonSetup(struct fb_info *info)
oldhead = NV_RD32(par->PCRTC0, 0x00000860);
NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
- nvidia_probe_i2c_connector(par, 1, &edidA);
+ nvidia_probe_i2c_connector(info, 1, &edidA);
if (edidA && !fb_parse_edid(edidA, &var)) {
printk("nvidiafb: EDID found from BUS1\n");
monA = &monitorA;
fb_edid_to_monspecs(edidA, monA);
}
- nvidia_probe_i2c_connector(par, 2, &edidB);
+ nvidia_probe_i2c_connector(info, 2, &edidB);
if (edidB && !fb_parse_edid(edidB, &var)) {
printk("nvidiafb: EDID found from BUS2\n");
monB = &monitorB;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 52b16850a54..3620de0f252 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)
{
struct nvidia_par *par = info->par;
struct _riva_hw_state *state = &par->ModeReg;
- int i, depth = fb_get_color_depth(&info->var);
+ int i, depth = fb_get_color_depth(&info->var, &info->fix);
int h_display = info->var.xres / 8 - 1;
int h_start = (info->var.xres + info->var.right_margin) / 8 - 1;
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)
int i, set = cursor->set;
u16 fg, bg;
- if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
+ if (!hwcur || cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
return -ENXIO;
NVShowHideCursor(par, 0);
@@ -978,6 +978,9 @@ static int nvidiafb_set_par(struct fb_info *info)
!par->twoHeads)
par->FPDither = 0;
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
nvidia_init_vga(info);
nvidia_calc_regs(info);
nvidia_write_regs(par);
@@ -992,9 +995,6 @@ static int nvidiafb_set_par(struct fb_info *info)
NVWriteCrtc(par, 0x11, 0x00);
info->fix.line_length = (info->var.xres_virtual *
info->var.bits_per_pixel) >> 3;
- info->fix.visual = (info->var.bits_per_pixel == 8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
-
if (info->var.accel_flags) {
info->fbops->fb_imageblit = nvidiafb_imageblit;
info->fbops->fb_fillrect = nvidiafb_fillrect;
@@ -1328,7 +1328,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
char buf[16];
memset(buf, 0, 16);
- snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight);
+ snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
specs->modedb_len, &modedb, 8);
}
@@ -1356,8 +1356,6 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
info->pixmap.size = 8 * 1024;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
- if (!hwcur)
- info->fbops->fb_cursor = soft_cursor;
info->var.accel_flags = (!noaccel);
switch (par->Architecture) {
@@ -1473,10 +1471,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par->Chipset = (pd->vendor << 16) | pd->device;
printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
-#ifdef CONFIG_PCI_NAMES
- printk(KERN_INFO PFX "%s\n", pd->pretty_name);
-#endif
-
if (par->Architecture == 0) {
printk(KERN_ERR PFX "unknown NV_ARCH\n");
goto err_out_free_base0;
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 42a6591e863..611922c0b22 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)
address = (u_long) dp->addrs[i].address;
#ifdef CONFIG_PPC64
- address += dp->phb->pci_mem_offset;
+ address += ((struct pci_dn *)dp->data)->phb->pci_mem_offset;
#endif
/* kludge for valkyrie */
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 30112816420..34d4dcc0320 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -468,6 +468,36 @@ static inline unsigned int get_pcd(unsigned int pixclock)
}
/*
+ * Some touchscreens need hsync information from the video driver to
+ * function correctly. We export it here.
+ */
+static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
+{
+ unsigned long long htime;
+
+ if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
+ fbi->hsync_time=0;
+ return;
+ }
+
+ htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000;
+ do_div(htime, pcd * fbi->fb.var.hsync_len);
+ fbi->hsync_time = htime;
+}
+
+unsigned long pxafb_get_hsync_time(struct device *dev)
+{
+ struct pxafb_info *fbi = dev_get_drvdata(dev);
+
+ /* If display is blanked/suspended, hsync isn't active */
+ if (!fbi || (fbi->state != C_ENABLE))
+ return 0;
+
+ return fbi->hsync_time;
+}
+EXPORT_SYMBOL(pxafb_get_hsync_time);
+
+/*
* pxafb_activate_var():
* Configures LCD Controller based on entries in var parameter. Settings are
* 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 *
fbi->reg_lccr1 = new_regs.lccr1;
fbi->reg_lccr2 = new_regs.lccr2;
fbi->reg_lccr3 = new_regs.lccr3;
+ set_hsync_time(fbi, pcd);
local_irq_restore(flags);
/*
@@ -907,6 +938,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
case CPUFREQ_POSTCHANGE:
pcd = get_pcd(fbi->fb.var.pixclock);
+ set_hsync_time(fbi, pcd);
fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
break;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index de15fec5f82..22c00be786a 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -83,6 +83,8 @@ struct pxafb_info {
u_int reg_lccr2;
u_int reg_lccr3;
+ unsigned long hsync_time;
+
volatile u_char state;
volatile u_char task_state;
struct semaphore ctrlr_sem;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index ae297e22268..3e9f96e9237 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,
default_par->Chipset = (pd->vendor << 16) | pd->device;
printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
-#ifdef CONFIG_PCI_NAMES
- printk(KERN_INFO PFX "%s\n", pd->pretty_name);
-#endif
-
if(default_par->riva.Architecture == 0) {
printk(KERN_ERR PFX "unknown NV_ARCH\n");
ret=-ENODEV;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
new file mode 100644
index 00000000000..00c0223a352
--- /dev/null
+++ b/drivers/video/s3c2410fb.c
@@ -0,0 +1,915 @@
+/*
+ * linux/drivers/video/s3c2410fb.c
+ * Copyright (c) Arnaud Patard, Ben Dooks
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * S3C2410 LCD Controller Frame Buffer Driver
+ * based on skeletonfb.c, sa1100fb.c and others
+ *
+ * ChangeLog
+ * 2005-04-07: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - u32 state -> pm_message_t state
+ * - S3C2410_{VA,SZ}_LCD -> S3C24XX
+ *
+ * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Removed the ioctl
+ * - use readl/writel instead of __raw_writel/__raw_readl
+ *
+ * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Added the possibility to set on or off the
+ * debugging mesaages
+ * - Replaced 0 and 1 by on or off when reading the
+ * /sys files
+ *
+ * 2005-03-23: Ben Dooks <ben-linux@fluff.org>
+ * - added non 16bpp modes
+ * - updated platform information for range of x/y/bpp
+ * - add code to ensure palette is written correctly
+ * - add pixel clock divisor control
+ *
+ * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Removed the use of currcon as it no more exist
+ * - Added LCD power sysfs interface
+ *
+ * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
+ * - minor cleanups
+ * - add suspend/resume support
+ * - s3c2410fb_setcolreg() not valid in >8bpp modes
+ * - removed last CONFIG_FB_S3C2410_FIXED
+ * - ensure lcd controller stopped before cleanup
+ * - added sysfs interface for backlight power
+ * - added mask for gpio configuration
+ * - ensured IRQs disabled during GPIO configuration
+ * - disable TPAL before enabling video
+ *
+ * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Suppress command line options
+ *
+ * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - code cleanup
+ *
+ * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Renamed from h1940fb.c to s3c2410fb.c
+ * - Add support for different devices
+ * - Backlight support
+ *
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ * - added clock (de-)allocation code
+ * - added fixem fbmem option
+ *
+ * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - code cleanup
+ * - added a forgotten return in h1940fb_init
+ *
+ * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
+ * - code cleanup and extended debugging
+ *
+ * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - First version
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h>
+
+#include <asm/mach/map.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/fb.h>
+#include <asm/hardware/clock.h>
+
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+
+#include "s3c2410fb.h"
+
+
+static struct s3c2410fb_mach_info *mach_info;
+
+/* Debugging stuff */
+#ifdef CONFIG_FB_S3C2410_DEBUG
+static int debug = 1;
+#else
+static int debug = 0;
+#endif
+
+#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
+
+/* useful functions */
+
+/* s3c2410fb_set_lcdaddr
+ *
+ * initialise lcd controller address pointers
+*/
+
+static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
+{
+ struct fb_var_screeninfo *var = &fbi->fb->var;
+ unsigned long saddr1, saddr2, saddr3;
+
+ saddr1 = fbi->fb->fix.smem_start >> 1;
+ saddr2 = fbi->fb->fix.smem_start;
+ saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
+ saddr2>>= 1;
+
+ saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres);
+
+ dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
+ dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
+ dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
+
+ writel(saddr1, S3C2410_LCDSADDR1);
+ writel(saddr2, S3C2410_LCDSADDR2);
+ writel(saddr3, S3C2410_LCDSADDR3);
+}
+
+/* s3c2410fb_calc_pixclk()
+ *
+ * calculate divisor for clk->pixclk
+*/
+
+static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
+ unsigned long pixclk)
+{
+ unsigned long clk = clk_get_rate(fbi->clk);
+ unsigned long long div;
+
+ /* pixclk is in picoseoncds, our clock is in Hz
+ *
+ * Hz -> picoseconds is / 10^-12
+ */
+
+ div = (unsigned long long)clk * pixclk;
+ do_div(div,1000000UL);
+ do_div(div,1000000UL);
+
+ dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div);
+ return div;
+}
+
+/*
+ * s3c2410fb_check_var():
+ * Get the video params out of 'var'. If a value doesn't fit, round it up,
+ * if it's too big, return -EINVAL.
+ *
+ */
+static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct s3c2410fb_info *fbi = info->par;
+
+ dprintk("check_var(var=%p, info=%p)\n", var, info);
+
+ /* validate x/y resolution */
+
+ if (var->yres > fbi->mach_info->yres.max)
+ var->yres = fbi->mach_info->yres.max;
+ else if (var->yres < fbi->mach_info->yres.min)
+ var->yres = fbi->mach_info->yres.min;
+
+ if (var->xres > fbi->mach_info->xres.max)
+ var->yres = fbi->mach_info->xres.max;
+ else if (var->xres < fbi->mach_info->xres.min)
+ var->xres = fbi->mach_info->xres.min;
+
+ /* validate bpp */
+
+ if (var->bits_per_pixel > fbi->mach_info->bpp.max)
+ var->bits_per_pixel = fbi->mach_info->bpp.max;
+ else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
+ var->bits_per_pixel = fbi->mach_info->bpp.min;
+
+ /* set r/g/b positions */
+
+ if (var->bits_per_pixel == 16) {
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ var->transp.length = 0;
+ } else {
+ var->red.length = var->bits_per_pixel;
+ var->red.offset = 0;
+ var->green.length = var->bits_per_pixel;
+ var->green.offset = 0;
+ var->blue.length = var->bits_per_pixel;
+ var->blue.offset = 0;
+ var->transp.length = 0;
+ }
+
+ return 0;
+}
+
+/* s3c2410fb_activate_var
+ *
+ * activate (set) the controller from the given framebuffer
+ * information
+*/
+
+static int s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
+ struct fb_var_screeninfo *var)
+{
+ fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
+
+ dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
+ dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
+ dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
+
+ switch (var->bits_per_pixel) {
+ case 1:
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
+ break;
+ case 2:
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
+ break;
+ case 4:
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
+ break;
+ case 8:
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
+ break;
+ case 16:
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
+ break;
+ }
+
+ /* check to see if we need to update sync/borders */
+
+ if (!fbi->mach_info->fixed_syncs) {
+ dprintk("setting vert: up=%d, low=%d, sync=%d\n",
+ var->upper_margin, var->lower_margin,
+ var->vsync_len);
+
+ dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
+ var->left_margin, var->right_margin,
+ var->hsync_len);
+
+ fbi->regs.lcdcon2 =
+ S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
+ S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
+ S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
+
+ fbi->regs.lcdcon3 =
+ S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
+ S3C2410_LCDCON3_HFPD(var->left_margin - 1);
+
+ fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff);
+ fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
+ }
+
+ /* update X/Y info */
+
+ fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
+ fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
+
+ fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
+ fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(var->xres - 1);
+
+ if (var->pixclock > 0) {
+ int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
+
+ clkdiv = (clkdiv / 2) -1;
+ if (clkdiv < 0)
+ clkdiv = 0;
+
+ fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
+ }
+
+ /* write new registers */
+
+ dprintk("new register set:\n");
+ dprintk("lcdcon[1] = 0x%08lx\n", fbi->regs.lcdcon1);
+ dprintk("lcdcon[2] = 0x%08lx\n", fbi->regs.lcdcon2);
+ dprintk("lcdcon[3] = 0x%08lx\n", fbi->regs.lcdcon3);
+ dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
+ dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);
+
+ writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
+ writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
+ writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
+ writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
+ writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);
+
+ /* set lcd address pointers */
+ s3c2410fb_set_lcdaddr(fbi);
+
+ writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
+}
+
+
+/*
+ * s3c2410fb_set_par - Optional function. Alters the hardware state.
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ */
+static int s3c2410fb_set_par(struct fb_info *info)
+{
+ struct s3c2410fb_info *fbi = info->par;
+ struct fb_var_screeninfo *var = &info->var;
+
+ if (var->bits_per_pixel == 16)
+ fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8;
+
+ /* activate this new configuration */
+
+ s3c2410fb_activate_var(fbi, var);
+ return 0;
+}
+
+static void schedule_palette_update(struct s3c2410fb_info *fbi,
+ unsigned int regno, unsigned int val)
+{
+ unsigned long flags;
+ unsigned long irqen;
+
+ local_irq_save(flags);
+
+ fbi->palette_buffer[regno] = val;
+
+ if (!fbi->palette_ready) {
+ fbi->palette_ready = 1;
+
+ /* enable IRQ */
+ irqen = readl(S3C2410_LCDINTMSK);
+ irqen &= ~S3C2410_LCDINT_FRSYNC;
+ writel(irqen, S3C2410_LCDINTMSK);
+ }
+
+ local_irq_restore(flags);
+}
+
+/* from pxafb.c */
+static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int s3c2410fb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ struct s3c2410fb_info *fbi = info->par;
+ unsigned int val;
+
+ /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */
+
+ switch (fbi->fb->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /* true-colour, use pseuo-palette */
+
+ if (regno < 16) {
+ u32 *pal = fbi->fb->pseudo_palette;
+
+ val = chan_to_field(red, &fbi->fb->var.red);
+ val |= chan_to_field(green, &fbi->fb->var.green);
+ val |= chan_to_field(blue, &fbi->fb->var.blue);
+
+ pal[regno] = val;
+ }
+ break;
+
+ case FB_VISUAL_PSEUDOCOLOR:
+ if (regno < 256) {
+ /* currently assume RGB 5-6-5 mode */
+
+ val = ((red >> 0) & 0xf800);
+ val |= ((green >> 5) & 0x07e0);
+ val |= ((blue >> 11) & 0x001f);
+
+ writel(val, S3C2410_TFTPAL(regno));
+ schedule_palette_update(fbi, regno, val);
+ }
+
+ break;
+
+ default:
+ return 1; /* unknown type */
+ }
+
+ return 0;
+}
+
+
+/**
+ * s3c2410fb_blank
+ * @blank_mode: the blank mode we want.
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ * Blank the screen if blank_mode != 0, else unblank. Return 0 if
+ * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
+ * video mode which doesn't support it. Implements VESA suspend
+ * and powerdown modes on hardware that supports disabling hsync/vsync:
+ * blank_mode == 2: suspend vsync
+ * blank_mode == 3: suspend hsync
+ * blank_mode == 4: powerdown
+ *
+ * Returns negative errno on error, or zero on success.
+ *
+ */
+static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
+{
+ dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
+
+ if (mach_info == NULL)
+ return -EINVAL;
+
+ if (blank_mode == FB_BLANK_UNBLANK)
+ writel(0x0, S3C2410_TPAL);
+ else {
+ dprintk("setting TPAL to output 0x000000\n");
+ writel(S3C2410_TPAL_EN, S3C2410_TPAL);
+ }
+
+ return 0;
+}
+
+static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
+}
+static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ if (mach_info == NULL)
+ return -EINVAL;
+
+ if (len < 1)
+ return -EINVAL;
+
+ if (strnicmp(buf, "on", 2) == 0 ||
+ strnicmp(buf, "1", 1) == 0) {
+ debug = 1;
+ printk(KERN_DEBUG "s3c2410fb: Debug On");
+ } else if (strnicmp(buf, "off", 3) == 0 ||
+ strnicmp(buf, "0", 1) == 0) {
+ debug = 0;
+ printk(KERN_DEBUG "s3c2410fb: Debug Off");
+ } else {
+ return -EINVAL;
+ }
+
+ return len;
+}
+
+
+static DEVICE_ATTR(debug, 0666,
+ s3c2410fb_debug_show,
+ s3c2410fb_debug_store);
+
+static struct fb_ops s3c2410fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = s3c2410fb_check_var,
+ .fb_set_par = s3c2410fb_set_par,
+ .fb_blank = s3c2410fb_blank,
+ .fb_setcolreg = s3c2410fb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
+};
+
+
+/*
+ * s3c2410fb_map_video_memory():
+ * Allocates the DRAM memory for the frame buffer. This buffer is
+ * remapped into a non-cached, non-buffered, memory region to
+ * allow palette and pixel writes to occur without flushing the
+ * cache. Once this area is remapped, all virtual memory
+ * access to the video memory should occur at the new region.
+ */
+static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi)
+{
+ dprintk("map_video_memory(fbi=%p)\n", fbi);
+
+ fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);
+ fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
+ &fbi->map_dma, GFP_KERNEL);
+
+ fbi->map_size = fbi->fb->fix.smem_len;
+
+ if (fbi->map_cpu) {
+ /* prevent initial garbage on screen */
+ dprintk("map_video_memory: clear %p:%08x\n",
+ fbi->map_cpu, fbi->map_size);
+ memset(fbi->map_cpu, 0xf0, fbi->map_size);
+
+ fbi->screen_dma = fbi->map_dma;
+ fbi->fb->screen_base = fbi->map_cpu;
+ fbi->fb->fix.smem_start = fbi->screen_dma;
+
+ dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n",
+ fbi->map_dma, fbi->map_cpu, fbi->fb->fix.smem_len);
+ }
+
+ return fbi->map_cpu ? 0 : -ENOMEM;
+}
+
+static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi)
+{
+ dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma);
+}
+
+static inline void modify_gpio(void __iomem *reg,
+ unsigned long set, unsigned long mask)
+{
+ unsigned long tmp;
+
+ tmp = readl(reg) & ~mask;
+ writel(tmp | set, reg);
+}
+
+
+/*
+ * s3c2410fb_init_registers - Initialise all LCD-related registers
+ */
+
+int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
+{
+ unsigned long flags;
+
+ /* Initialise LCD with values from haret */
+
+ local_irq_save(flags);
+
+ /* modify the gpio(s) with interrupts set (bjd) */
+
+ modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask);
+ modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask);
+ modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask);
+ modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask);
+
+ local_irq_restore(flags);
+
+ writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
+ writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
+ writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
+ writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
+ writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);
+
+ s3c2410fb_set_lcdaddr(fbi);
+
+ dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
+ writel(mach_info->lpcsel, S3C2410_LPCSEL);
+
+ dprintk("replacing TPAL %08x\n", readl(S3C2410_TPAL));
+
+ /* ensure temporary palette disabled */
+ writel(0x00, S3C2410_TPAL);
+
+ /* Enable video by setting the ENVID bit to 1 */
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
+ writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
+ return 0;
+}
+
+static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
+{
+ unsigned int i;
+ unsigned long ent;
+
+ fbi->palette_ready = 0;
+
+ for (i = 0; i < 256; i++) {
+ if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR)
+ continue;
+
+ writel(ent, S3C2410_TFTPAL(i));
+
+ /* it seems the only way to know exactly
+ * if the palette wrote ok, is to check
+ * to see if the value verifies ok
+ */
+
+ if (readw(S3C2410_TFTPAL(i)) == ent)
+ fbi->palette_buffer[i] = PALETTE_BUFF_CLEAR;
+ else
+ fbi->palette_ready = 1; /* retry */
+ }
+}
+
+static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r)
+{
+ struct s3c2410fb_info *fbi = dev_id;
+ unsigned long lcdirq = readl(S3C2410_LCDINTPND);
+
+ if (lcdirq & S3C2410_LCDINT_FRSYNC) {
+ if (fbi->palette_ready)
+ s3c2410fb_write_palette(fbi);
+
+ writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDINTPND);
+ writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDSRCPND);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static char driver_name[]="s3c2410fb";
+
+int __init s3c2410fb_probe(struct device *dev)
+{
+ struct s3c2410fb_info *info;
+ struct fb_info *fbinfo;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s3c2410fb_hw *mregs;
+ int ret;
+ int irq;
+ int i;
+
+ mach_info = dev->platform_data;
+ if (mach_info == NULL) {
+ dev_err(dev,"no platform data for lcd, cannot attach\n");
+ return -EINVAL;
+ }
+
+ mregs = &mach_info->regs;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no irq for device\n");
+ return -ENOENT;
+ }
+
+ fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), dev);
+ if (!fbinfo) {
+ return -ENOMEM;
+ }
+
+
+ info = fbinfo->par;
+ info->fb = fbinfo;
+ dev_set_drvdata(dev, fbinfo);
+
+ s3c2410fb_init_registers(info);
+
+ dprintk("devinit\n");
+
+ strcpy(fbinfo->fix.id, driver_name);
+
+ memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
+
+ info->mach_info = dev->platform_data;
+
+ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
+ fbinfo->fix.type_aux = 0;
+ fbinfo->fix.xpanstep = 0;
+ fbinfo->fix.ypanstep = 0;
+ fbinfo->fix.ywrapstep = 0;
+ fbinfo->fix.accel = FB_ACCEL_NONE;
+
+ fbinfo->var.nonstd = 0;
+ fbinfo->var.activate = FB_ACTIVATE_NOW;
+ fbinfo->var.height = mach_info->height;
+ fbinfo->var.width = mach_info->width;
+ fbinfo->var.accel_flags = 0;
+ fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
+
+ fbinfo->fbops = &s3c2410fb_ops;
+ fbinfo->flags = FBINFO_FLAG_DEFAULT;
+ fbinfo->pseudo_palette = &info->pseudo_pal;
+
+ fbinfo->var.xres = mach_info->xres.defval;
+ fbinfo->var.xres_virtual = mach_info->xres.defval;
+ fbinfo->var.yres = mach_info->yres.defval;
+ fbinfo->var.yres_virtual = mach_info->yres.defval;
+ fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
+
+ fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) +1;
+ fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) +1;
+ fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
+
+ fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
+ fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
+ fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
+
+ fbinfo->var.red.offset = 11;
+ fbinfo->var.green.offset = 5;
+ fbinfo->var.blue.offset = 0;
+ fbinfo->var.transp.offset = 0;
+ fbinfo->var.red.length = 5;
+ fbinfo->var.green.length = 6;
+ fbinfo->var.blue.length = 5;
+ fbinfo->var.transp.length = 0;
+ fbinfo->fix.smem_len = mach_info->xres.max *
+ mach_info->yres.max *
+ mach_info->bpp.max / 8;
+
+ for (i = 0; i < 256; i++)
+ info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
+
+ if (!request_mem_region((unsigned long)S3C24XX_VA_LCD, SZ_1M, "s3c2410-lcd")) {
+ ret = -EBUSY;
+ goto dealloc_fb;
+ }
+
+
+ dprintk("got LCD region\n");
+
+ ret = request_irq(irq, s3c2410fb_irq, SA_INTERRUPT, pdev->name, info);
+ if (ret) {
+ dev_err(dev, "cannot get irq %d - err %d\n", irq, ret);
+ ret = -EBUSY;
+ goto release_mem;
+ }
+
+ info->clk = clk_get(NULL, "lcd");
+ if (!info->clk || IS_ERR(info->clk)) {
+ printk(KERN_ERR "failed to get lcd clock source\n");
+ ret = -ENOENT;
+ goto release_irq;
+ }
+
+ clk_use(info->clk);
+ clk_enable(info->clk);
+ dprintk("got and enabled clock\n");
+
+ msleep(1);
+
+ /* Initialize video memory */
+ ret = s3c2410fb_map_video_memory(info);
+ if (ret) {
+ printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret);
+ ret = -ENOMEM;
+ goto release_clock;
+ }
+ dprintk("got video memory\n");
+
+ ret = s3c2410fb_init_registers(info);
+
+ ret = s3c2410fb_check_var(&fbinfo->var, fbinfo);
+
+ ret = register_framebuffer(fbinfo);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
+ goto free_video_memory;
+ }
+
+ /* create device files */
+ device_create_file(dev, &dev_attr_debug);
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ fbinfo->node, fbinfo->fix.id);
+
+ return 0;
+
+free_video_memory:
+ s3c2410fb_unmap_video_memory(info);
+release_clock:
+ clk_disable(info->clk);
+ clk_unuse(info->clk);
+ clk_put(info->clk);
+release_irq:
+ free_irq(irq,info);
+release_mem:
+ release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD);
+dealloc_fb:
+ framebuffer_release(fbinfo);
+ return ret;
+}
+
+/* s3c2410fb_stop_lcd
+ *
+ * shutdown the lcd controller
+*/
+
+static void s3c2410fb_stop_lcd(void)
+{
+ unsigned long flags;
+ unsigned long tmp;
+
+ local_irq_save(flags);
+
+ tmp = readl(S3C2410_LCDCON1);
+ writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
+
+ local_irq_restore(flags);
+}
+
+/*
+ * Cleanup
+ */
+static int s3c2410fb_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct s3c2410fb_info *info = fbinfo->par;
+ int irq;
+
+ s3c2410fb_stop_lcd();
+ msleep(1);
+
+ s3c2410fb_unmap_video_memory(info);
+
+ if (info->clk) {
+ clk_disable(info->clk);
+ clk_unuse(info->clk);
+ clk_put(info->clk);
+ info->clk = NULL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq,info);
+ release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD);
+ unregister_framebuffer(fbinfo);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+/* suspend and resume support for the lcd controller */
+
+static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level)
+{
+ struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct s3c2410fb_info *info = fbinfo->par;
+
+ if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
+ s3c2410fb_stop_lcd();
+
+ /* sleep before disabling the clock, we need to ensure
+ * the LCD DMA engine is not going to get back on the bus
+ * before the clock goes off again (bjd) */
+
+ msleep(1);
+ clk_disable(info->clk);
+ }
+
+ return 0;
+}
+
+static int s3c2410fb_resume(struct device *dev, u32 level)
+{
+ struct fb_info *fbinfo = dev_get_drvdata(dev);
+ struct s3c2410fb_info *info = fbinfo->par;
+
+ if (level == RESUME_ENABLE) {
+ clk_enable(info->clk);
+ msleep(1);
+
+ s3c2410fb_init_registers(info);
+
+ }
+
+ return 0;
+}
+
+#else
+#define s3c2410fb_suspend NULL
+#define s3c2410fb_resume NULL
+#endif
+
+static struct device_driver s3c2410fb_driver = {
+ .name = "s3c2410-lcd",
+ .bus = &platform_bus_type,
+ .probe = s3c2410fb_probe,
+ .suspend = s3c2410fb_suspend,
+ .resume = s3c2410fb_resume,
+ .remove = s3c2410fb_remove
+};
+
+int __devinit s3c2410fb_init(void)
+{
+ return driver_register(&s3c2410fb_driver);
+}
+
+static void __exit s3c2410fb_cleanup(void)
+{
+ driver_unregister(&s3c2410fb_driver);
+}
+
+
+module_init(s3c2410fb_init);
+module_exit(s3c2410fb_cleanup);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>");
+MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
new file mode 100644
index 00000000000..be40968f899
--- /dev/null
+++ b/drivers/video/s3c2410fb.h
@@ -0,0 +1,56 @@
+/*
+ * linux/drivers/s3c2410fb.h
+ * Copyright (c) Arnaud Patard
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * S3C2410 LCD Controller Frame Buffer Driver
+ * based on skeletonfb.c, sa1100fb.h
+ *
+ * ChangeLog
+ *
+ * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Moved dprintk to s3c2410fb.c
+ *
+ * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - Renamed from h1940fb.h to s3c2410fb.h
+ * - Chenged h1940 to s3c2410
+ *
+ * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
+ * - First version
+ */
+
+#ifndef __S3C2410FB_H
+#define __S3C2410FB_H
+
+struct s3c2410fb_info {
+ struct fb_info *fb;
+ struct device *dev;
+ struct clk *clk;
+
+ struct s3c2410fb_mach_info *mach_info;
+
+ /* raw memory addresses */
+ dma_addr_t map_dma; /* physical */
+ u_char * map_cpu; /* virtual */
+ u_int map_size;
+
+ struct s3c2410fb_hw regs;
+
+ /* addresses of pieces placed in raw buffer */
+ u_char * screen_cpu; /* virtual address of buffer */
+ dma_addr_t screen_dma; /* physical address of buffer */
+ unsigned int palette_ready;
+
+ /* keep these registers in case we need to re-write palette */
+ u32 palette_buffer[256];
+ u32 pseudo_pal[16];
+};
+
+#define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */
+
+int s3c2410fb_init(void);
+
+#endif
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 847698b5cfe..959404ad68f 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)
return buf;
}
-int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
+int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
{
+ struct savagefb_par *par = info->par;
u8 *edid = NULL;
int i;
@@ -270,12 +271,19 @@ int savagefb_probe_i2c_connector(struct savagefb_par *par, u8 **out_edid)
if (edid)
break;
}
+
+ if (!edid) {
+ /* try to get from firmware */
+ edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (edid)
+ memcpy(edid, fb_firmware_edid(info->device),
+ EDID_LENGTH);
+ }
+
if (out_edid)
*out_edid = edid;
- if (!edid)
- return 1;
- return 0;
+ return (edid) ? 0 : 1;
}
MODULE_LICENSE("GPL");
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index 8594b1e42d7..d6f94742c9f 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -60,6 +60,7 @@
#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
+#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) || (chip == S3_PROSAVAGEDDR))
/* Chip tags. These are used to group the adapters into
* related families.
@@ -73,6 +74,8 @@ typedef enum {
S3_PROSAVAGE,
S3_SUPERSAVAGE,
S3_SAVAGE2000,
+ S3_PROSAVAGEDDR,
+ S3_TWISTER,
S3_LAST
} savage_chipset;
@@ -128,6 +131,10 @@ typedef enum {
#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16))
#define BCI_CMD_SEND_COLOR 0x00008000
+#define DISP_CRT 1
+#define DISP_LCD 2
+#define DISP_DFP 3
+
struct xtimings {
unsigned int Clock;
unsigned int HDisplay;
@@ -166,6 +173,10 @@ struct savagefb_par {
struct savagefb_i2c_chan chan;
unsigned char *edid;
u32 pseudo_palette[16];
+ int pm_state;
+ int display_type;
+ int dvi;
+ int crtonly;
int dacSpeedBpp;
int maxClock;
int minClock;
@@ -338,7 +349,7 @@ do { \
} \
}
-extern int savagefb_probe_i2c_connector(struct savagefb_par *par,
+extern int savagefb_probe_i2c_connector(struct fb_info *info,
u8 **out_edid);
extern void savagefb_create_i2c_busses(struct fb_info *info);
extern 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 117ad42f120..b5ca3ef8271 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,
return 0;
}
+static int savagefb_blank(int blank, struct fb_info *info)
+{
+ struct savagefb_par *par = info->par;
+ u8 sr8 = 0, srd = 0;
+
+ if (par->display_type == DISP_CRT) {
+ vga_out8(0x3c4, 0x08);
+ sr8 = vga_in8(0x3c5);
+ sr8 |= 0x06;
+ vga_out8(0x3c5, sr8);
+ vga_out8(0x3c4, 0x0d);
+ srd = vga_in8(0x3c5);
+ srd &= 0x03;
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ srd |= 0x10;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ srd |= 0x40;
+ break;
+ case FB_BLANK_POWERDOWN:
+ srd |= 0x50;
+ break;
+ }
+
+ vga_out8(0x3c4, 0x0d);
+ vga_out8(0x3c5, srd);
+ }
+
+ if (par->display_type == DISP_LCD ||
+ par->display_type == DISP_DFP) {
+ switch(blank) {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ vga_out8(0x3c5, vga_in8(0x3c5) | 0x10);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10);
+ break;
+ }
+ }
+
+ return (blank == FB_BLANK_NORMAL) ? 1 : 0;
+}
static struct fb_ops savagefb_ops = {
.owner = THIS_MODULE,
@@ -1407,6 +1459,7 @@ static struct fb_ops savagefb_ops = {
.fb_set_par = savagefb_set_par,
.fb_setcolreg = savagefb_setcolreg,
.fb_pan_display = savagefb_pan_display,
+ .fb_blank = savagefb_blank,
#if defined(CONFIG_FB_SAVAGE_ACCEL)
.fb_fillrect = savagefb_fillrect,
.fb_copyarea = savagefb_copyarea,
@@ -1583,8 +1636,7 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 2, 2 };
-
- int videoRam, videoRambytes;
+ int videoRam, videoRambytes, dvi;
DBG("savage_init_hw");
@@ -1705,6 +1757,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n",
par->MCLK);
+ /* check for DVI/flat panel */
+ dvi = 0;
+
+ if (par->chip == S3_SAVAGE4) {
+ unsigned char sr30 = 0x00;
+
+ vga_out8(0x3c4, 0x30);
+ /* clear bit 1 */
+ vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02);
+ sr30 = vga_in8(0x3c5);
+ if (sr30 & 0x02 /*0x04 */) {
+ dvi = 1;
+ printk("savagefb: Digital Flat Panel Detected\n");
+ }
+ }
+
+ if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
+ (S3_MOBILE_TWISTER_SERIES(par->chip) && !par->crtonly))
+ par->display_type = DISP_LCD;
+ else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi))
+ par->display_type = DISP_DFP;
+ else
+ par->display_type = DISP_CRT;
+
/* Check LCD panel parrmation */
if (par->chip == S3_SAVAGE_MX) {
@@ -1759,7 +1835,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
par->SavagePanelWidth = panelX;
par->SavagePanelHeight = panelY;
- }
+ } else
+ par->display_type = DISP_CRT;
}
savage_get_default_par (par);
@@ -1845,15 +1922,15 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
snprintf (info->fix.id, 16, "ProSavageKM");
break;
case FB_ACCEL_S3TWISTER_P:
- par->chip = S3_PROSAVAGE;
+ par->chip = S3_TWISTER;
snprintf (info->fix.id, 16, "TwisterP");
break;
case FB_ACCEL_S3TWISTER_K:
- par->chip = S3_PROSAVAGE;
+ par->chip = S3_TWISTER;
snprintf (info->fix.id, 16, "TwisterK");
break;
case FB_ACCEL_PROSAVAGE_DDR:
- par->chip = S3_PROSAVAGE;
+ par->chip = S3_PROSAVAGEDDR;
snprintf (info->fix.id, 16, "ProSavageDDR");
break;
case FB_ACCEL_PROSAVAGE_DDRK:
@@ -1899,12 +1976,11 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
info->pixmap.buf_align = 4;
info->pixmap.access_align = 32;
- fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
+ err = fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
+ if (!err)
info->flags |= FBINFO_HWACCEL_COPYAREA |
FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_IMAGEBLIT;
-
- err = 0;
}
#endif
return err;
@@ -1932,14 +2008,14 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
if (err)
goto failed_enable;
- if (pci_request_regions(dev, "savagefb")) {
+ if ((err = pci_request_regions(dev, "savagefb"))) {
printk(KERN_ERR "cannot request PCI regions\n");
goto failed_enable;
}
err = -ENOMEM;
- if (savage_init_fb_info(info, dev, id))
+ if ((err = savage_init_fb_info(info, dev, id)))
goto failed_init;
err = savage_map_mmio(info);
@@ -1947,6 +2023,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
goto failed_mmio;
video_len = savage_init_hw(par);
+ /* FIXME: cant be negative */
if (video_len < 0) {
err = video_len;
goto failed_mmio;
@@ -1959,7 +2036,8 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
INIT_LIST_HEAD(&info->modelist);
#if defined(CONFIG_FB_SAVAGE_I2C)
savagefb_create_i2c_busses(info);
- savagefb_probe_i2c_connector(par, &par->edid);
+ savagefb_probe_i2c_connector(info, &par->edid);
+ kfree(par->edid);
fb_edid_to_monspecs(par->edid, &info->monspecs);
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len,
@@ -2111,13 +2189,30 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
DBG("savagefb_suspend");
+
+ par->pm_state = state.event;
+
+ /*
+ * For PM_EVENT_FREEZE, do not power down so the console
+ * can remain active.
+ */
+ if (state.event == PM_EVENT_FREEZE) {
+ dev->dev.power.power_state = state;
+ return 0;
+ }
+
acquire_console_sem();
- fb_set_suspend(info, pci_choose_state(dev, state));
- savage_disable_mmio(par);
- release_console_sem();
+ fb_set_suspend(info, 1);
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ savagefb_blank(FB_BLANK_POWERDOWN, info);
+ savage_disable_mmio(par);
+ pci_save_state(dev);
pci_disable_device(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
+ release_console_sem();
return 0;
}
@@ -2127,22 +2222,34 @@ static int savagefb_resume (struct pci_dev* dev)
struct fb_info *info =
(struct fb_info *)pci_get_drvdata(dev);
struct savagefb_par *par = (struct savagefb_par *)info->par;
+ int cur_state = par->pm_state;
DBG("savage_resume");
- pci_set_power_state(dev, 0);
- pci_restore_state(dev);
- if(pci_enable_device(dev))
- DBG("err");
+ par->pm_state = PM_EVENT_ON;
- SavagePrintRegs();
+ /*
+ * The adapter was not powered down coming back from a
+ * PM_EVENT_FREEZE.
+ */
+ if (cur_state == PM_EVENT_FREEZE) {
+ pci_set_power_state(dev, PCI_D0);
+ return 0;
+ }
acquire_console_sem();
+ pci_set_power_state(dev, PCI_D0);
+ pci_restore_state(dev);
+
+ if(pci_enable_device(dev))
+ DBG("err");
+
+ pci_set_master(dev);
savage_enable_mmio(par);
savage_init_hw(par);
savagefb_set_par (info);
-
+ savagefb_blank(FB_BLANK_UNBLANK, info);
fb_set_suspend (info, 0);
release_console_sem();
@@ -2276,3 +2383,6 @@ static int __init savagefb_init(void)
module_init(savagefb_init);
module_exit(savage_done);
+
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Specify initial video mode");
diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
index b6d5c71b256..e4b4a2626da 100644
--- a/drivers/video/sis/300vtbl.h
+++ b/drivers/video/sis/300vtbl.h
@@ -3,7 +3,7 @@
/*
* Register settings for SiS 300 series
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,31 +50,7 @@
*
*/
-static const SiS_StStruct SiS300_SModeIDTable[] =
-{
- {0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
- {0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
- {0x01,0x1010,0x17,0x02,0x02,0x00,0x00,0x00, 0},
- {0x03,0x8208,0x03,0x00,0x00,0x00,0x00,0x00, 0},
- {0x03,0x0210,0x16,0x01,0x01,0x00,0x00,0x00, 0},
- {0x03,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
- {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x00, 0},
- {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x00, 0},
- {0x07,0x0000,0x07,0x03,0x03,0x00,0x00,0x00, 0},
- {0x07,0x0000,0x19,0x02,0x02,0x00,0x00,0x00, 0},
- {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x00, 0},
- {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x00, 0},
- {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x00, 0},
- {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x00, 0},
- {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00, 0},
- {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00, 0},
- {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00, 0},
- {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00, 0},
- {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00, 0},
- {0xff, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-static const SiS_ExtStruct SiS300_EModeIDTable[] =
+static const struct SiS_Ext SiS300_EModeIDTable[] =
{
{0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */
{0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
@@ -110,7 +86,7 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
{0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */
{0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */
{0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */
- {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
+ {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
{0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
{0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */
{0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
@@ -119,8 +95,8 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
{0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
{0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
{0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
- {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 - not in BIOS! */
- {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 - not in BIOS! */
+ {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 */
+ {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 */
{0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */
{0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */
{0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */
@@ -166,77 +142,77 @@ static const SiS_ExtStruct SiS300_EModeIDTable[] =
{0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
};
-static const SiS_Ext2Struct SiS300_RefIndex[] =
-{
- {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
- {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
- {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
- {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0}, /* 03 */
- {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0}, /* 04 */
- {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0}, /* 05 */
- {0x0047,0x11,0x4e,0x00,0x05,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
- {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0}, /* 07 */
- {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
- {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
- {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
- {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
- {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 0c */
- {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0}, /* 0d */
- {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0}, /* 0e */
- {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0}, /* 0f */
- {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
- {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0}, /* 11 */
- {0x006f,0x32,0x03,0x06,0x14,0x32, 720, 576, 0}, /* 12 */
- {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0}, /* 13 */
- {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
- {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
- {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
- {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
- {0x0047,0x1a,0x52,0x00,0x06,0x37,1024, 768, 0}, /* 18 */
- {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
- {0x0387,0x1c,0x4d,0x00,0x07,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
- {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0}, /* 1b */
- {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0}, /* 1c */
- {0x0007,0x1f,0x98,0x00,0x07,0x3a,1280,1024, 0}, /* 1d */
- {0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
- {0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
- {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
- {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
- {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */
- {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
- {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */
- {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */
- {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */ /* was c077 */
- {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */
- {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */
- {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */
- {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
- {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
- {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */ /* VCLK 0x09 */
- {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0}, /* 2d */
- {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0}, /* 2e */
- {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0}, /* 2f */
- {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0}, /* 30 */
- {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0}, /* 31 */
- {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0}, /* 32 */
- {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0}, /* 33 */
- {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0}, /* 34 */
- {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0}, /* 35 */
- {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0}, /* 36 1152x864-60Hz */
- {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0}, /* 37 1152x864-75Hz */
- {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0}, /* 38 1152x864-85Hz */
- {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0}, /* 39 848x480-38Hzi */
- {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0}, /* 3a 848x480-60Hz */
- {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3b 856x480-38Hzi */
- {0xc047,0x42,0x28,0x00,0x17,0x3f, 856, 480, 0}, /* 3c 856x480-60Hz */
- {0x0067,0x43,0x3e,0x0c,0x1b,0x48,1360, 768, 0}, /* 3d 1360x768-60Hz */
- {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0}, /* 3e 1280x768-60Hz */
- {0x006f,0x47,0x03,0x06,0x15,0x5f, 768, 576, 0}, /* 3f 768x576 */
- {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0}, /* 40 1360x1024-59Hz (BARCO1366 only) */
- {0xffff, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
+static const struct SiS_Ext2 SiS300_RefIndex[] =
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 00 */
+ {0x0467,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 01 */
+ {0x0067,0x0f,0x07,0x48,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 02 - CRT1CRTC was 0x4f */
+ {0x0067,0x10,0x06,0x8b,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 03 */
+ {0x0147,0x11,0x08,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 04 */
+ {0x0147,0x12,0x0c,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 05 */
+ {0x0047,0x11,0x0e,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 06 - CRT1CRTC was 0x51 */
+ {0x0047,0x11,0x13,0x00,0x05,0x6a, 800, 600, 0, 0x00, 0x00}, /* 07 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 08 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 09 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0a */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0b */
+ {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0c */
+ {0xc047,0x0a,0x08,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0d */
+ {0xc047,0x0b,0x0a,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0e */
+ {0xc047,0x0c,0x10,0x00,0x04,0x2e, 640, 480, 0, 0x00, 0x00}, /* 0f */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0, 0x4a, 0x49}, /* 10 */
+ {0xc06f,0x31,0x01,0x06,0x13,0x31, 720, 480, 0, 0x00, 0x00}, /* 11 */
+ {0x006f,0x32,0x4a,0x06,0x14,0x32, 720, 576, 0, 0x00, 0x00}, /* 12 */ /* 4a was 03 */
+ {0x0187,0x15,0x05,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 13 */
+ {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 14 */
+ {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 15 - CRT1CRTC was 0x97 */
+ {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 16 */
+ {0x0047,0x19,0x11,0x8c,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 17 - CRT1CRTC was 0x59 */
+ {0x0047,0x1a,0x12,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 18 */
+ {0x0007,0x1b,0x16,0x00,0x06,0x37,1024, 768, 0, 0x00, 0x00}, /* 19 - CRT1CRTC was 0x5b */
+ {0x0387,0x1c,0x0d,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1a - CRT1CRTC was 0x5c */
+ {0x0077,0x1d,0x14,0x07,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1b */
+ {0x0047,0x1e,0x17,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1c */
+ {0x0007,0x1f,0x18,0x00,0x07,0x3a,1280,1024, 0, 0x00, 0x00}, /* 1d */
+ {0x0007,0x20,0x19,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1e - CRT1CRTC was 0x60 */
+ {0x0007,0x21,0x1a,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 1f */
+ {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 20 */
+ {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 21 - CRT1CRTC was 0x63 */
+ {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0, 0x00, 0x00}, /* 22 */
+ {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0, 0x4b, 0x4b}, /* 23 */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0, 0x00, 0x00}, /* 24 */
+ {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0, 0x00, 0x00}, /* 25 */
+ {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0, 0x00, 0x00}, /* 26 */ /* was c077 */
+ {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0, 0x00, 0x00}, /* 27 */
+ {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0, 0x00, 0x00}, /* 28 */
+ {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 29 - 1280x960-60 */
+ {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0, 0x00, 0x00}, /* 2a - 1280x960-85 */
+ {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0, 0x00, 0x00}, /* 2b */
+ {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0, 0x00, 0x00}, /* 2c */ /* VCLK 0x09 */
+ {0x0077,0x35,0x27,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2d */
+ {0x0047,0x36,0x37,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2e */
+ {0x0047,0x37,0x08,0x08,0x18,0x70, 800, 480, 0, 0x00, 0x00}, /* 2f */
+ {0x0077,0x38,0x09,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 30 */
+ {0x0047,0x39,0x38,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 31 */
+ {0x0047,0x3a,0x11,0x09,0x19,0x71,1024, 576, 0, 0x00, 0x00}, /* 32 */
+ {0x0077,0x3b,0x39,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 33 */
+ {0x0047,0x3c,0x3a,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 34 */
+ {0x0007,0x3d,0x3b,0x0a,0x0c,0x75,1280, 720, 0, 0x00, 0x00}, /* 35 */
+ {0x0067,0x49,0x35,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 36 1152x864-60Hz */
+ {0x0067,0x3e,0x34,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 37 1152x864-75Hz */
+ {0x0047,0x44,0x3a,0x06,0x1a,0x29,1152, 864, 0, 0x00, 0x00}, /* 38 1152x864-85Hz */
+ {0x00c7,0x3f,0x28,0x00,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 39 848x480-38Hzi */
+ {0xc067,0x40,0x3d,0x0b,0x16,0x39, 848, 480, 0, 0x00, 0x00}, /* 3a 848x480-60Hz */
+ {0x00c7,0x41,0x28,0x00,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3b 856x480-38Hzi */
+ {0xc067,0x42,0x28,0x0c,0x17,0x3f, 856, 480, 0, 0x00, 0x00}, /* 3c 856x480-60Hz */
+ {0x0067,0x43,0x3e,0x0d,0x1b,0x48,1360, 768, 0, 0x00, 0x00}, /* 3d 1360x768-60Hz */
+ {0x0077,0x46,0x3f,0x08,0x08,0x55,1280, 768, 0, 0x00, 0x00}, /* 3e 1280x768-60Hz */
+ {0x006f,0x47,0x4c,0x06,0x15,0x5f, 768, 576, 0, 0x00, 0x00}, /* 3f 768x576 */
+ {0x0027,0x48,0x13,0x08,0x00,0x67,1360,1024, 0, 0x00, 0x00}, /* 40 1360x1024-59Hz (BARCO1366 only) */
+ {0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00}
+};
+
+static const struct SiS_VBMode SiS300_VBModeIDTable[] =
{
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
@@ -303,53 +279,26 @@ static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
-static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
+static const struct SiS_CRT1Table SiS300_CRT1Table[] =
{
-#if 1
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
0x00}},
-#endif
-#if 0
- {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f, /* 0x00 - corrected 320x200-72 - does not work */
- 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
- 0x00}},
-#endif
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* 0x01 */
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, /* HRE [4],[15] is invalid - but correcting it does not work */
0x00}},
-#if 0
- {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e, /* 0x01 - corrected 320x240-60 - does not work */
- 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
- 0x00}},
-#endif
{{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 */
0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
0x01}},
-#if 0
- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, /* 0x02 - corrected 400x300-60 */
- 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
- 0x01}},
-#endif
{{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
0x01}},
{{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
0x00}},
-#if 0
- {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e, /* 0x05 */
- 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
- 0x00}},
-#endif
{{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
0x00}},
-#if 0
- {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e, /* 0x06 */
- 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
- 0x00}},
-#endif
{{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
0x00}},
@@ -359,19 +308,9 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
{{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
0x00}},
-#if 0
- {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e, /* 0x09 */
- 0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
- 0x00}},
-#endif
{{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x09 - corrected 640x480-100 */
0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
0x00}},
-#if 0
- {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e, /* 0x0a */
- 0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
- 0x00}},
-#endif
{{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e, /* 0x0a - corrected 640x480-120 */
0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
0x00}},
@@ -459,11 +398,6 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
{{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
0x00}},
-#if 0
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 0x27: 1280x960-70 - invalid! */
- 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
- 0x01}},
-#endif
{{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 0x27: 1280x960-60 - correct */
0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
0x01}},
@@ -497,9 +431,9 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
{{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
0x00}},
- {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 0x32 */
- 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
- 0x01}},
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 0x32: 720x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}},
{{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* 0x33 - 1024x600 */
0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
0x01}},
@@ -560,18 +494,24 @@ static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
{{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, /* 1280x768-60 */
0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
0x01}}, /* 0x46 */
- {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
- 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
- 0x01}}, /* 0x47 */
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}}, /* 0x47 */
{{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52, /* 1360x1024 (Barco iQ Pro R300) */
0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
0x00}}, /* 0x48 */
{{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
- 0x41}} /* 0x49 */
+ 0x41}}, /* 0x49 */
+ {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
+ 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
+ 0x40}}, /* 0x4a */
+ {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
+ 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
+ 0x00}} /* 0x4b */
};
-static const SiS_MCLKDataStruct SiS300_MCLKData_630[] =
+static const struct SiS_MCLKData SiS300_MCLKData_630[] =
{
{ 0x5a,0x64,0x80, 66},
{ 0xb3,0x45,0x80, 83},
@@ -583,7 +523,7 @@ static const SiS_MCLKDataStruct SiS300_MCLKData_630[] =
{ 0x37,0x61,0x80,100}
};
-static const SiS_MCLKDataStruct SiS300_MCLKData_300[] =
+static const struct SiS_MCLKData SiS300_MCLKData_300[] =
{
{ 0x68,0x43,0x80,125},
{ 0x68,0x43,0x80,125},
@@ -595,7 +535,7 @@ static const SiS_MCLKDataStruct SiS300_MCLKData_300[] =
{ 0x37,0x61,0x80,100}
};
-static SiS_VCLKDataStruct SiS300_VCLKData[] =
+static struct SiS_VCLKData SiS300_VCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
@@ -669,53 +609,26 @@ static SiS_VCLKDataStruct SiS300_VCLKData[] =
{ 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */
{ 0x70,0x29, 81}, /* 0x46 */ /* unused */
{ 0, 0, 0}, /* 0x47 custom (will be filled out) */
- { 0xce,0x25,189} /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */
+ { 0xce,0x25,189}, /* 0x48 */ /* Replacement for index 0x1b for 730 (and 540?) */
+ { 0x15,0xe1, 20}, /* 0x49 */ /* 640x400@60 (fake, not actually used) */
+ { 0x5f,0xc6, 33}, /* 0x4a */ /* 720x576@60 */
+ { 0x37,0x5a, 10}, /* 0x4b */ /* 320x200@60 (fake, not actually used) */
+ { 0x2b,0xc2, 35} /* 0x4c */ /* 768@576@60 */
};
-#ifdef LINUX_KERNEL
-static UCHAR SiS300_SR07 = 0x10;
-#endif
-
-static const DRAM4Type SiS300_SR15[8] =
+static const unsigned char SiS300_SR15[4 * 8] =
{
- {0x01,0x09,0xa3,0x00},
- {0x43,0x43,0x43,0x00},
- {0x1e,0x1e,0x1e,0x00},
- {0x2a,0x2a,0x2a,0x00},
- {0x06,0x06,0x06,0x00},
- {0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00}
+ 0x01,0x09,0xa3,0x00,
+ 0x43,0x43,0x43,0x00,
+ 0x1e,0x1e,0x1e,0x00,
+ 0x2a,0x2a,0x2a,0x00,
+ 0x06,0x06,0x06,0x00,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00
};
-#ifdef LINUX_KERNEL
-static UCHAR SiS300_SR1F = 0x00;
-static UCHAR SiS300_SR21 = 0x16;
-static UCHAR SiS300_SR22 = 0xb2;
-static UCHAR SiS300_SR23 = 0xf6;
-static UCHAR SiS300_SR24 = 0x0d;
-static UCHAR SiS300_SR25[] = {0x0,0x0};
-static UCHAR SiS300_SR31 = 0x00;
-static UCHAR SiS300_SR32 = 0x11;
-static UCHAR SiS300_SR33 = 0x00;
-static UCHAR SiS300_CRT2Data_1_2 = 0x40;
-static UCHAR SiS300_CRT2Data_4_D = 0x00;
-static UCHAR SiS300_CRT2Data_4_E = 0x00;
-static UCHAR SiS300_CRT2Data_4_10 = 0x80;
-
-static const USHORT SiS300_RGBSenseData = 0xd1;
-static const USHORT SiS300_VideoSenseData = 0xb3;
-static const USHORT SiS300_YCSenseData = 0xb9;
-static const USHORT SiS300_RGBSenseData2 = 0x0190;
-static const USHORT SiS300_VideoSenseData2 = 0x0174;
-static const USHORT SiS300_YCSenseData2 = 0x016b;
-
-static const DRAM4Type SiS300_CR40[5];
-
-static UCHAR SiS300_CR49[2];
-#endif
-
-static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+static const struct SiS_PanelDelayTbl SiS300_PanelDelayTbl[] =
{
{{0x05,0xaa}},
{{0x05,0x14}},
@@ -735,33 +648,11 @@ static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
{{0x05,0x60}}
};
-#if 0
-static const SiS_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
-{
- {{0x05,0xaa}},
- {{0x05,0x14}},
- {{0x05,0x36}},
- {{0x05,0x14}},
- {{0x05,0x14}},
- {{0x05,0x14}},
- {{0x05,0x90}},
- {{0x05,0x90}},
- {{0x05,0x14}},
- {{0x05,0x14}},
- {{0x05,0x14}},
- {{0x05,0x14}}, /* 2.07a (JVC): 14,96 */
- {{0x05,0x28}}, /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
- {{0x05,0x14}},
- {{0x05,0x14}}, /* Some BIOSes: 05, 40 */
- {{0x05,0x60}}
-};
-#endif
-
/**************************************************************/
/* SIS VIDEO BRIDGE ----------------------------------------- */
/**************************************************************/
-static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] =
+static const struct SiS_LCDData SiS300_St2LCD1024x768Data[] =
{
{ 62, 25, 800, 546,1344, 806},
{ 32, 15, 930, 546,1344, 806},
@@ -772,7 +663,7 @@ static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] =
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
+static const struct SiS_LCDData SiS300_ExtLCD1024x768Data[] =
{
{ 12, 5, 896, 512,1344, 806},
{ 12, 5, 896, 510,1344, 806},
@@ -789,7 +680,7 @@ static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
+static const struct SiS_LCDData SiS300_St2LCD1280x1024Data[] =
{
{ 22, 5, 800, 510,1650,1088},
{ 22, 5, 800, 510,1650,1088},
@@ -801,7 +692,7 @@ static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
+static const struct SiS_LCDData SiS300_ExtLCD1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
@@ -813,53 +704,116 @@ static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_1[] =
{ /* VESA Timing */
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
};
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_2[] =
{ /* Non-VESA */
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
};
-static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+static const struct SiS_Part2PortTbl SiS300_CRT2Part2_1024x768_3[] =
{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
};
/**************************************************************/
/* LVDS/Chrontel -------------------------------------------- */
/**************************************************************/
-static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] =
+/* Custom data for Barco iQ R series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_1[]=
+{
+ { 832, 438,1331, 806},
+ { 832, 388,1331, 806},
+ { 832, 438,1331, 806},
+ { 832, 388,1331, 806},
+ { 832, 518,1331, 806},
+ {1050, 638,1344, 806},
+ {1344, 806,1344, 806},
+ {1688,1066,1688,1066},
+ {1688,1066,1688,1066} /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ R series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1366Data_2[]=
+{
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1344, 806,1344, 806},
+ {1688,1066,1688,1066},
+ {1688,1066,1688,1066} /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ G series */
+static const struct SiS_LVDSData SiS300_LVDSBARCO1024Data_1[]=
+{
+ { 832, 438,1331, 806},
+ { 832, 409,1331, 806},
+ { 832, 438,1331, 806},
+ { 832, 409,1331, 806},
+ { 832, 518,1331, 806}, /* 640x480 */
+ {1050, 638,1344, 806}, /* 800x600 */
+ {1344, 806,1344, 806}, /* 1024x768 */
+};
+
+/* Custom data for 848x480 and 856x480 parallel LVDS panels */
+static const struct SiS_LVDSData SiS300_LVDS848x480Data_1[]=
+{
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ {1088, 525,1088, 525}, /* 640x480 TODO */
+ {1088, 525,1088, 525}, /* 800x600 TODO */
+ {1088, 525,1088, 525}, /* 1024x768 TODO */
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ {1088, 525,1088, 525}, /* 848x480 */
+ {1088, 525,1088, 525}, /* 856x480 */
+ {1088, 525,1088, 525} /* 1360x768 TODO */
+};
+
+/* Custom data for 848x480 parallel panel */
+static const struct SiS_LVDSData SiS300_LVDS848x480Data_2[]=
+{
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ {1088, 525,1088, 525}, /* 640x480 */
+ {1088, 525,1088, 525}, /* 800x600 */
+ {1088, 525,1088, 525}, /* 1024x768 */
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ { 0, 0, 0, 0},
+ {1088, 525,1088, 525}, /* 848x480 */
+ {1088, 525,1088, 525}, /* 856x480 */
+ {1088, 525,1088, 525} /* 1360x768 TODO */
+};
+
+static const struct SiS_LVDSData SiS300_CHTVUPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -869,7 +823,7 @@ static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] =
{ 936, 836, 936, 836}
};
-static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] =
+static const struct SiS_LVDSData SiS300_CHTVOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -879,7 +833,7 @@ static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] =
{ 960, 750, 960, 750}
};
-static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] =
+static const struct SiS_LVDSData SiS300_CHTVSOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -889,486 +843,8 @@ static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] =
{ 944, 625, 944, 625}
};
-
-static const SiS_LVDSDesStruct SiS300_PanelType00_1[] =
-{
- { 1059, 626 }, /* 2.08 */
- { 1059, 624 },
- { 1059, 626 },
- { 1059, 624 },
- { 1059, 624 },
- { 0, 627 },
- { 0, 627 },
- { 0, 0 },
- { 0, 0 }
-#if 0
- {0, 626},
- {0, 624},
- {0, 626},
- {0, 624},
- {0, 624},
- {0, 627},
- {0, 627},
- {0, 0},
- {0, 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType01_1[] =
-{
- { 0, 0 }, /* 2.08 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-#if 0
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType02_1[] =
-{
- { 1059, 626 }, /* 2.08 */
- { 1059, 624 },
- { 1059, 626 },
- { 1059, 624 },
- { 1059, 624 },
- { 0, 627 },
- { 0, 627 },
- { 0, 0 },
- { 0, 0 }
-#if 0
- {0, 626},
- {0, 624},
- {0, 626},
- {0, 624},
- {0, 624},
- {0, 627},
- {0, 627},
- {0, 0},
- {0, 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType03_1[] =
-{
- { 8, 436},
- { 8, 440},
- { 8, 436},
- { 8, 440},
- { 8, 512},
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType05_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType06_1[] = /* Clevo Trumpion 1024x768 */
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType07_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType08_1[] =
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType09_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0a_1[] =
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0b_1[] =
-{
- {1343, 0},
- {1343, 0},
- {1343, 0},
- {1343, 0},
- {1343, 0},
- {1343, 0},
- { 0, 799},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0c_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0d_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0e_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0}, /* 640x480 */
- {1343, 0}, /* 800x600 */
- { 0, 805}, /* 1024x768 */
- { 0, 794}, /* 1280x1024 */
- { 0, 0} /* 1280x960 - not applicable */
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0f_1[] =
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType00_2[] =
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType01_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType02_2[] =
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType03_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- {1152, 622},
- {1152, 597}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType04_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType05_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType06_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType07_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType08_2[] =
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType09_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0a_2[] =
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0b_2[] =
-{
- { 1152, 700},
- { 1152, 675},
- { 1152, 700},
- { 1152, 675},
- { 1152, 740},
- { 1232, 799},
- { 0, 799},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0c_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0d_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0e_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelType0f_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelTypeNS_1[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 805},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS300_PanelTypeNS_2[] =
-{
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
-/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
-static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
+/* Custom des data for Barco iQ R200/300/400 (BIOS 2.00.07) */
+static const struct SiS_LVDSDes SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
{
{1330, 798}, /* 320x200 */
{1330, 794},
@@ -1381,7 +857,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x102
{ 0, 0} /* 1360x1024 */
};
-static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] =
+static const struct SiS_LVDSDes SiS300_PanelType04_2a[] =
{
{1152, 622},
{1152, 597},
@@ -1394,8 +870,8 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] =
{ 0, 0}
};
-/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
-static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
+/* Custom des data for Barco iQ G200/300/400 (BIOS 2.00.07) */
+static const struct SiS_LVDSDes SiS300_PanelType04_1b[] = /* 1024x768 */
{
{1330, 798}, /* 320x200 */
{1330, 794},
@@ -1406,7 +882,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
{ 0, 805} /* 1024x768 / 512x384 */
};
-static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] =
+static const struct SiS_LVDSDes SiS300_PanelType04_2b[] =
{
{1152, 622},
{1152, 597},
@@ -1419,376 +895,7 @@ static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] =
/* CRT1 CRTC for slave modes */
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] =
-{
- {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
- 0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
- 0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
- 0x00 }},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
-{
- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
- 0x00 }},
- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
- 0x00 }},
- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
- 0x00 }},
- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
- 0x00 }},
- {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
- 0x00 }},
- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
-{
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
- 0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00 }},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
- 0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
- 0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
- 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
- 0x01}},
- {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01 }}
-
-#if 0
- {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00 }},
- {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
- 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
- 0x00}},
- {{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x37,0x27,0x9B,0x2b,0x94,0x97,0x1f,
- 0x60,0x87,0x5D,0x83,0x01,0x00,0x44,
- 0x00}},
- {{0x37,0x27,0x9B,0x2b,0x94,0x04,0x3e,
- 0xE2,0x89,0xDf,0x05,0x00,0x00,0x44,
- 0x00}},
- {{0x41,0x31,0x85,0x35,0x1d,0x7c,0xf0,
- 0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
- 0x01}},
- {{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
- 0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
- 0x01 }}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
-{
- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00 }},
- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00 }},
- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00 }},
- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00 }},
- {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
- 0x00 }},
- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
- 0x01 }},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
- 0x00 }},
- {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
- 0x00 }},
- {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
- 0x00 }},
- {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
- 0x00 }},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
- 0x00 }},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
- 0x01 }},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] =
-{
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
- 0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
-{
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
- 0x00 }},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
- 0x00 }},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
- 0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
- 0x00 }},
- {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
- 0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
- 0x00 }},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
- 0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
- 0x00 }},
- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
- 0x01 }},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
- 0x01 }},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
- 0x01 }},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
- 0x01 }},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
- 0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
- 0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
- 0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-
-static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UNTSC[] =
{
{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -1810,7 +917,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
0x01 }}
};
-static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1ONTSC[] =
{
{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -1832,7 +939,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
0x01 }}
};
-static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1UPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1854,7 +961,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
0x01 }}
};
-static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1OPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1876,7 +983,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
0x01 }}
};
-static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
+static const struct SiS_LVDSCRT1Data SiS300_CHTVCRT1SOPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -1898,7 +1005,7 @@ static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
0x01 }}
};
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_UNTSC[] =
{
{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{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[] =
{{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
};
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_ONTSC[] =
{
{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{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[] =
{{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
};
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_UPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
{{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[] =
};
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_OPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
{{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[] =
};
-static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+static const struct SiS_CHTVRegData SiS300_CHTVReg_SOPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
- {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
- {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* TW: Mode 19: 800x600 PAL 1/1 */
+ {{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 13: 640x480 PAL 5/4 */
+ {{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 19: 800x600 PAL 1/1 */
};
-static const UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+static const unsigned char SiS300_CHTVVCLKUNTSC[] = { 0x29,0x29,0x29,0x29,0x2a,0x2e };
-static const UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+static const unsigned char SiS300_CHTVVCLKONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
-static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+static const unsigned char SiS300_CHTVVCLKSONTSC[] = { 0x2c,0x2c,0x2c,0x2c,0x2d,0x2b };
-static const UCHAR SiS300_CHTVVCLKUPAL[] = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
+static const unsigned char SiS300_CHTVVCLKUPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x2f,0x31 };
-static const UCHAR SiS300_CHTVVCLKOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+static const unsigned char SiS300_CHTVVCLKOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x30,0x32 };
-static const UCHAR SiS300_CHTVVCLKSOPAL[] = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
+static const unsigned char SiS300_CHTVVCLKSOPAL[] = { 0x2f,0x2f,0x2f,0x2f,0x36,0x29 };
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
index 2c71d048f7c..54fcbbf4ef6 100644
--- a/drivers/video/sis/310vtbl.h
+++ b/drivers/video/sis/310vtbl.h
@@ -1,9 +1,9 @@
/* $XFree86$ */
/* $XdotOrg$ */
/*
- * Register settings for SiS 315/330 series
+ * Register settings for SiS 315/330/340 series
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,37 +50,13 @@
*
*/
-static const SiS_StStruct SiS310_SModeIDTable[]=
-{
- {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
- {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
- {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01, 0x40},
- {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02, 0x40},
- {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02, 0x40},
- {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03, 0x40},
- {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04, 0x40},
- {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05, 0x40},
- {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03, 0x40},
- {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03, 0x40},
- {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04, 0x40},
- {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05, 0x40},
- {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05, 0x40},
- {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05, 0x40},
- {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05, 0x40},
- {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05, 0x40},
- {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04, 0x40},
- {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05, 0x40},
- {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05, 0x40},
- {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
-};
-
-static const SiS_ExtStruct SiS310_EModeIDTable[]=
+static const struct SiS_Ext SiS310_EModeIDTable[] =
{
{0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
{0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
- {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
+ {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
{0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
- {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
+ {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
{0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
{0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
{0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
@@ -103,10 +79,10 @@ static const SiS_ExtStruct SiS310_EModeIDTable[]=
{0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
{0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */
{0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */
- {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
+ {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
{0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
{0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
- {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
+ {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
{0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */
{0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */
{0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
@@ -139,406 +115,335 @@ static const SiS_ExtStruct SiS310_EModeIDTable[]=
{0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
{0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
{0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
- {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */
- {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */
- {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/
- {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
- {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
- {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
- {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1}, /* 848x480 */
- {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1},
- {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x46,-1},
- {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 856x480 */
- {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1},
- {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x48,-1},
- {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 1360x768 */
- {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
- {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4a,-1},
+ {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x8 */
+ {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x16 */
+ {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x43, 9}, /* 1400x1050x32*/
+ {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1}, /* 1152x864 */
+ {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
+ {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x45,-1},
+ {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1}, /* 848x480 */
+ {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
+ {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x48,-1},
+ {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1}, /* 856x480 */
+ {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
+ {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x4a,-1},
+ {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1}, /* 1360x768 */
+ {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
+ {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x4c,-1},
{0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
{0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
{0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
- {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1}, /* 768x576 */
- {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1},
- {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4b,-1},
- {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7}, /* 1280x800 */
- {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
- {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4c, 7},
- {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9}, /* 1680x1050 */
- {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
- {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4d, 9},
- {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1}, /* 1920x1080(i) */
- {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
- {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4e,-1},
- {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1}, /* 960x540 */
- {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1},
- {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4f,-1},
- {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1}, /* 960x600 */
- {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1},
- {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x50,-1},
+ {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1}, /* 768x576 */
+ {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
+ {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4d,-1},
+ {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7}, /* 1280x800 */
+ {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
+ {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4e, 7},
+ {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9}, /* 1680x1050 */
+ {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
+ {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x51, 9},
+ {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1}, /* 1920x1080(i) */
+ {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
+ {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x52,-1},
+ {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1}, /* 960x540 */
+ {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
+ {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x53,-1},
+ {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1}, /* 960x600 */
+ {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
+ {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x54,-1},
+ {0x1a,0x0e3b,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8}, /* 1280x854 */
+ {0x1b,0x0e7d,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
+ {0x1c,0x0eff,0x0000,SIS_RI_1280x854, 0x00,0x00,0x00,0x00,0x55, 8},
{0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
};
-static const SiS_Ext2Struct SiS310_RefIndex[]=
-{
- {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
- {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
- {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */
- {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */
- {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */
- {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */
- {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */
- {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */
- {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
- {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
- {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */
- {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */
- {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */
- {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */
- {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */
- {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */
- {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
- {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */
- {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */
- {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */
- {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
- {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */
- {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */
- {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */
- {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */
- {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */
- {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */
- {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
- {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */
- {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */
- {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
- {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */
- {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */
- {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */
- {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */
- {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */
- {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */
- {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
- {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
- {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
- {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
- {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
- {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
- {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
- {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
- {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
- {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
- {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
- {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
- {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
- {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
- {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
- {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */
- {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */
- {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */
- {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */
- {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */
- {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */
- {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */
- {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */
- {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */
- {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */
- {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */
- {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */ /* FSTN 320x240 */
- {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */ /* 0x5b was 0x12 */
- {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
- {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
- {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-60Hz */
- {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-75Hz */
- {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x45 1152x864-85Hz */
- {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-38Hzi */
- {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x47 848x480-60Hz */
- {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-38Hzi */
- {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x49 856x480-60Hz */
- {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x4a 1360x768-60Hz */
- {0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4b 768x576-56Hz */
- {0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4c 1280x800-60Hz */
- {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4d 1680x1050-60Hz */
- {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4e 1920x1080 60Hzi */
- {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4f 960x540 60Hz */
- {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30}, /* 0x50 960x600 60Hz */
- {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0}
-};
-
-#ifdef LINUX_XF86
-static const struct {
- UCHAR Ext_ModeID; /* ModeID in new ROM */
- UCHAR Ext_MyModeID; /* corresponding ModeID in my tables (0 = identical) */
- USHORT Ext_VESAID; /* corresponding VESA ID in new ROM */
-} SiS_EModeIDTable661[] = {
- { 0x6a, 0x00, 0x0102 },
- { 0x1d, 0x20, 0x0000 },
- { 0x1e, 0x21, 0x0000 },
- { 0x1f, 0x22, 0x0000 },
- { 0x20, 0x29, 0x0000 },
- { 0x21, 0x2a, 0x0000 },
- { 0x22, 0x2b, 0x0000 },
- { 0x23, 0x00, 0x011c },
- { 0x24, 0x00, 0x011d },
- { 0x25, 0x00, 0x011e },
- { 0x26, 0x00, 0x011f },
- { 0x27, 0x00, 0x0120 },
- { 0x28, 0x00, 0x0121 },
- { 0x2a, 0x14, 0x013d },
- { 0x2b, 0x15, 0x013e },
- { 0x2c, 0x16, 0x013f },
- { 0x2e, 0x00, 0x0101 },
- { 0x2f, 0x00, 0x0100 },
- { 0x30, 0x00, 0x0103 },
- { 0x37, 0x00, 0x0104 },
- { 0x38, 0x00, 0x0105 },
- { 0x3a, 0x00, 0x0107 },
- { 0x3c, 0x00, 0x0125 },
- { 0x3d, 0x00, 0x0126 },
- { 0x40, 0x00, 0x010d },
- { 0x41, 0x00, 0x010e },
- { 0x43, 0x00, 0x0110 },
- { 0x44, 0x00, 0x0111 },
- { 0x46, 0x00, 0x0113 },
- { 0x47, 0x00, 0x0114 },
- { 0x49, 0x00, 0x0116 },
- { 0x4a, 0x00, 0x0117 },
- { 0x4c, 0x00, 0x0119 },
- { 0x4d, 0x00, 0x011a },
- { 0x50, 0x00, 0x0127 },
- { 0x51, 0x00, 0x0128 },
- { 0x52, 0x00, 0x0129 },
- { 0x56, 0x00, 0x012a },
- { 0x57, 0x00, 0x012b },
- { 0x58, 0x00, 0x012c },
- { 0x59, 0x00, 0x012d },
- { 0x5a, 0x17, 0x012e },
- { 0x5b, 0x18, 0x012f },
- { 0x5c, 0x19, 0x0130 },
- { 0x5d, 0x00, 0x0131 },
- { 0x62, 0x00, 0x0112 },
- { 0x63, 0x00, 0x0115 },
- { 0x64, 0x00, 0x0118 },
- { 0x65, 0x00, 0x011b },
- { 0x66, 0x00, 0x0132 },
- { 0x75, 0x00, 0x013a },
- { 0x78, 0x00, 0x013b },
- { 0x79, 0x00, 0x013c },
- { 0x7b, 0x7c, 0x0136 },
- { 0x7c, 0x7d, 0x0137 },
- { 0x7d, 0x7e, 0x0138 },
- { 0xff, 0xff, 0xffff }
-};
-#endif
-
-static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
+static const struct SiS_Ext2 SiS310_RefIndex[] =
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x0 */
+ {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3 */
+ {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4 */
+ {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x5 */
+ {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x6 */
+ {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x7 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xb */
+ {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xc */
+ {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xd */
+ {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xe */
+ {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0xf */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00}, /* 0x10 */
+ {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x11 */
+ {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x12 (6f was 03) */
+ {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x14 */
+ {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x15 */
+ {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x17 */
+ {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x18 */
+ {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x19 */
+ {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1a */
+ {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1b */
+ {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1c */
+ {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1d */
+ {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1e */
+ {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x1f */
+ {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x20 */
+ {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x21 */
+ {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x22 */
+ {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x23 */
+ {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x24 */
+ {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30, 0x56, 0x4e, 0x00, 0x00, 0x00, 0x00}, /* 0x25 */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x26 */
+ {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x27 */
+ {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x28 */
+ {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x29 */
+ {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2a */
+ {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2b */
+ {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2c */
+ {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2d */
+ {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2e */
+ {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x2f */
+ {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x30 */
+ {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x31 */
+ {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x32 */
+ {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x33 */
+ {0x2077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x32, 0x40, 0x5e, 0x73}, /* 0x34 */
+ {0x2047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x33, 0x07, 0xff, 0xff}, /* 0x35 */
+ {0x2047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00, 0x34, 0x0a, 0xff, 0xff}, /* 0x36 */
+ {0x2077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x35, 0x0b, 0x5f, 0x74}, /* 0x37 */
+ {0x2047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x36, 0x11, 0xff, 0xff}, /* 0x38 */
+ {0x2047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00, 0x37, 0x16, 0xff, 0xff}, /* 0x39 */
+ {0x3137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x38, 0x19, 0x60, 0x75}, /* 0x3a */
+ {0x3107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x39, 0x1e, 0xff, 0xff}, /* 0x3b */
+ {0x3307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00, 0x3a, 0x20, 0xff, 0xff}, /* 0x3c */
+ {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3d */
+ {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3e */
+ {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x3f */ /* FSTN 320x240 */
+ {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x58, 0x19, 0x42, 0x5b}, /* 0x40 */ /* 0x5b was 0x12 */
+ {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x59, 0x1e, 0xff, 0xff}, /* 0x41 */
+ {0x2077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00, 0x5a, 0x20, 0xff, 0xff}, /* 0x42 */
+ {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x43 */
+ {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x44 1400x1050-75Hz */
+ {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x45 1152x864-60Hz */
+ {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x46 1152x864-75Hz */
+ {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x47 1152x864-85Hz */
+ {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x48 848x480-38Hzi */
+ {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x49 848x480-60Hz */
+ {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4a 856x480-38Hzi */
+ {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4b 856x480-60Hz */
+ {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4c 1360x768-60Hz */
+ {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x4d 768x576-56Hz */
+ {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5b, 0x19, 0x4f, 0x5c}, /* 0x4e 1280x800-60Hz */
+ {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5c, 0x1e, 0xff, 0xff}, /* 0x4f 1280x800-75Hz */
+ {0x2067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30, 0x00, 0x00, 0x5d, 0x20, 0xff, 0xff}, /* 0x50 1280x800-85Hz */
+ {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x51 1680x1050-60Hz */
+ {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x52 1920x1080 60Hzi */
+ {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x53 960x540 60Hz */
+ {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0x54 960x600 60Hz */
+ {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x62, 0x19, 0x61, 0x76}, /* 0x55 1280x854-60Hz */
+ {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x63, 0x1e, 0xff, 0xff}, /* 0x56 1280x854-75Hz */
+ {0x2067,0x61,0x76,0x0d,0x22,0x1a,1280, 854, 0x30, 0x00, 0x00, 0x64, 0x20, 0xff, 0xff}, /* 0x57 1280x854-85Hz */
+ {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static const struct SiS_CRT1Table SiS310_CRT1Table[] =
{
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
- 0x00}}, /* 0x0 */
+ 0x00}}, /* 0x0 */
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
- 0x00}}, /* 0x1 */
+ 0x00}}, /* 0x1 */
{{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
- 0x01}}, /* 0x2 */
+ 0x01}}, /* 0x2 */
{{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
- 0x01}}, /* 0x3 */
+ 0x01}}, /* 0x3 */
{{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
- 0x00}}, /* 0x4 */
-#if 0
- {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
- 0x00}}, /* 0x5 */
-#endif
- {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
+ 0x00}}, /* 0x4 */
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* corrected 640x480-60 */
0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
- 0x00}},
-#if 0
- {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
- 0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
- 0x00}}, /* 0x6 */
-#endif
- {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* 0x06 - corrected 640x480-72 */
+ 0x00}}, /* 0x5 */
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, /* corrected 640x480-72 */
0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
- 0x00}},
+ 0x00}}, /* 0x6 */
{{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
- 0x00}}, /* 0x7 */
+ 0x00}}, /* 0x7 */
{{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
- 0x00}}, /* 0x8 */
+ 0x00}}, /* 0x8 */
{{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
- 0x61}}, /* 0x9 */
+ 0x61}}, /* 0x9 */
{{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
- 0x61}}, /* 0xa */
+ 0x61}}, /* 0xa */
{{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
- 0x61}}, /* 0xb */
+ 0x61}}, /* 0xb */
{{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
- 0x00}}, /* 0xc */
+ 0x00}}, /* 0xc */
{{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
- 0x01}}, /* 0xd */
+ 0x01}}, /* 0xd */
{{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
- 0x01}}, /* 0xe */
+ 0x01}}, /* 0xe */
{{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
- 0x01}}, /* 0xf */
+ 0x01}}, /* 0xf */
{{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
- 0x01}}, /* 0x10 */
+ 0x01}}, /* 0x10 */
{{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
- 0x01}}, /* 0x11 */
+ 0x01}}, /* 0x11 */
{{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
- 0x61}}, /* 0x12 */
+ 0x61}}, /* 0x12 */
{{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
- 0x61}}, /* 0x13 */
+ 0x61}}, /* 0x13 */
{{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
- 0x61}}, /* 0x14 */
+ 0x61}}, /* 0x14 */
{{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
- 0x00}}, /* 0x15 */
+ 0x00}}, /* 0x15 */
{{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}, /* 0x16 */
+ 0x01}}, /* 0x16 */
{{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}, /* 0x17 */
+ 0x01}}, /* 0x17 */
{{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
- 0x01}}, /* 0x18 */
+ 0x01}}, /* 0x18 */
{{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
- 0x01}}, /* 0x19 */
+ 0x01}}, /* 0x19 */
{{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
- 0x62}}, /* 0x1a */
+ 0x62}}, /* 0x1a */
{{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
- 0x62}}, /* 0x1b */
+ 0x62}}, /* 0x1b */
{{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
- 0x00}}, /* 0x1c */
+ 0x00}}, /* 0x1c */
{{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
- 0x01}}, /* 0x1d */
+ 0x01}}, /* 0x1d */
{{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
- 0x01}}, /* 0x1e */
+ 0x01}}, /* 0x1e */
{{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
- 0x01}}, /* 0x1f */
+ 0x01}}, /* 0x1f */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x20 */
+ 0x00}}, /* 0x20 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x21 @ 4084 */
+ 0x00}}, /* 0x21 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x22 */
+ 0x00}}, /* 0x22 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x23 */
+ 0x00}}, /* 0x23 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x24 */
+ 0x00}}, /* 0x24 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x25 */
+ 0x00}}, /* 0x25 */
{{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
- 0x00}}, /* 0x26 */
+ 0x00}}, /* 0x26 */
{{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
- 0x00}}, /* 0x27 */
+ 0x00}}, /* 0x27 */
{{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
- 0x63}}, /* 0x28 */
+ 0x63}}, /* 0x28 */
{{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
- 0x63}}, /* 0x29 */
+ 0x63}}, /* 0x29 */
{{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
- 0x00}}, /* 0x2a */
+ 0x00}}, /* 0x2a */
{{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
- 0x00}}, /* 0x2b */
+ 0x00}}, /* 0x2b */
{{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
- 0x00}}, /* 0x2c */
+ 0x00}}, /* 0x2c */
{{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
- 0x44}}, /* 0x2d */
+ 0x44}}, /* 0x2d */
{{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
- 0x44}}, /* 0x2e */
+ 0x44}}, /* 0x2e */
{{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
- 0x44}}, /* 0x2f */
+ 0x44}}, /* 0x2f */
{{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
- 0x44}}, /* 0x30 */
+ 0x44}}, /* 0x30 */
{{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
- 0x00}}, /* 0x31 */
+ 0x00}}, /* 0x31 */
{{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
- 0x01}}, /* 0x32 */
+ 0x01}}, /* 0x32 */
{{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
- 0x01}}, /* 0x33 */
+ 0x01}}, /* 0x33 */
{{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
- 0x01}}, /* 0x34 */
+ 0x01}}, /* 0x34 */
{{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
- 0x01}}, /* 0x35 */
+ 0x01}}, /* 0x35 */
{{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
- 0x01}}, /* 0x36 */
+ 0x01}}, /* 0x36 */
{{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
- 0x01}}, /* 0x37 */
+ 0x01}}, /* 0x37 */
{{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
- 0x01}}, /* 0x38 */
+ 0x01}}, /* 0x38 */
{{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
- 0x01}}, /* 0x39 */
+ 0x01}}, /* 0x39 */
{{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
- 0x01}}, /* 0x3a */
-#if 0
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef, /* 1280x960 - invalid */
- 0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
- 0x01}}, /* 0x3b */
-#endif
+ 0x01}}, /* 0x3a */
{{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, /* 1280x960-60 - corrected */
0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
- 0x01}}, /* 0x3b */
+ 0x01}}, /* 0x3b */
{{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
- 0x00}}, /* 0x3c */
- {{0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
- 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
- 0x01}}, /* 0x3d */
+ 0x00}}, /* 0x3c */
+ {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, /* 720x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}}, /* 0x3d */
{{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15,
0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02,
- 0x00}}, /* 0x3e */
+ 0x00}}, /* 0x3e */
{{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
- 0x00}}, /* 0x3f */
+ 0x00}}, /* 0x3f */
{{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
0x01}}, /* 0x40 */
@@ -578,11 +483,11 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
{{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
0x01}}, /* 0x4c */
- {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
- 0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
- 0x01}}, /* 0x4d */
- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
- 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+ {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, /* 768x576, corrected to 60Hz */
+ 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05,
+ 0x41}}, /* 0x4d */
+ {{0x5f,0x27,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* FSTN 320x240 (working) */
+ 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
0x00}}, /* 0x4e */
{{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
@@ -601,10 +506,58 @@ static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
0x01}}, /* 0x53 */
{{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, /* 1152x864-60 */
0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07,
- 0x41}} /* 0x54 */
-};
-
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
+ 0x41}}, /* 0x54 */
+ {{0x5c,0x4f,0x4f,0x80,0x57,0x80,0xa3,0x1f, /* fake 640x400@60Hz (for LCD and TV, not actually used) */
+ 0x98,0x8c,0x8f,0x96,0xa4,0x30,0x00,0x05,
+ 0x40}}, /* 0x55 */
+ {{0x2c,0x27,0x27,0x90,0x2d,0x92,0xa4,0x1f, /* fake 320x200@60Hz (for LCD and TV, not actually used) */
+ 0x98,0x8c,0x8f,0x96,0xa5,0x30,0x00,0x04,
+ 0x00}}, /* 0x56 */
+ {{0xd7,0xc7,0xc7,0x9b,0xd1,0x15,0xd1,0x10, /* 1600x1200 for LCDA */
+ 0xb2,0x86,0xaf,0xb0,0xd2,0x2f,0x00,0x03,
+ 0x00}}, /* 0x57 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 60 Hz */
+ 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x58 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xdc, /* 1280x768 (1280x1024) 75 Hz */
+ 0x92,0x86,0xff,0x91,0x29,0x21,0x00,0x07,
+ 0x01}}, /* 0x59 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xdc, /* 1280x768 (1280x1024) 85 Hz */
+ 0x95,0x89,0xff,0x94,0x2f,0x21,0x00,0x07,
+ 0x01}}, /* 0x5a */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x800 (1280x1024) 60 Hz */
+ 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
+ 0x01}}, /* 0x5b */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x800 (1280x1024) 75 Hz */
+ 0xa2,0x86,0x1f,0xa1,0x29,0x01,0x00,0x07,
+ 0x01}}, /* 0x5c */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x800 (1280x1024) 85 Hz */
+ 0xa5,0x89,0x1f,0xa4,0x2f,0x01,0x00,0x07,
+ 0x01}}, /* 0x5d */
+ {{0x7f,0x63,0x63,0x83,0x6d,0x1d,0x0b,0x3e, /* 800x480 (wide) 60 Hz */
+ 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x06,
+ 0x00}}, /* 0x5e */
+ {{0xa0,0x7f,0x7f,0x84,0x85,0x97,0x52,0xf0, /* 1024x576 (wide) 60 Hz */
+ 0x41,0x85,0x3f,0x40,0x53,0x00,0x00,0x02,
+ 0x01}}, /* 0x5f */
+ {{0xc9,0x9f,0x9f,0x8d,0xb0,0x15,0xec,0xf0, /* 1280x720 (wide) 60 Hz */
+ 0xd4,0x89,0xcf,0xd3,0xed,0x20,0x00,0x07,
+ 0x01}}, /* 0x60 */
+ {{0xcb,0x9f,0x9f,0x8f,0xa5,0x13,0x5b,0xff, /* 1280x854-60 wide */
+ 0x56,0x89,0x55,0x55,0x5c,0x30,0x00,0x07,
+ 0x01}}, /* 0x61 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xde, /* 1280x854 (1280x1024) 60 Hz */
+ 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
+ 0x41}}, /* 0x62 */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xde, /* 1280x854 (1280x1024) 75 Hz */
+ 0xbd,0x81,0x55,0xbc,0x29,0x01,0x00,0x07,
+ 0x41}}, /* 0x63 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xde, /* 1280x854 (1280x1024) 85 Hz */
+ 0xc0,0x84,0x55,0xbf,0x2f,0x01,0x00,0x07,
+ 0x41}} /* 0x64 */
+};
+
+static const struct SiS_MCLKData SiS310_MCLKData_0_315[] =
{
{ 0x3b,0x22,0x01,143},
{ 0x5c,0x23,0x01,166},
@@ -616,7 +569,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
{ 0x5c,0x23,0x01,166}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_650[] =
{
{ 0x5a,0x64,0x82, 66},
{ 0xb3,0x45,0x82, 83},
@@ -628,7 +581,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
{ 0x37,0x22,0x82,133}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_330[] =
{
{ 0x5c,0x23,0x01,166},
{ 0x5c,0x23,0x01,166},
@@ -640,7 +593,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
{ 0x79,0x06,0x01,250}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_660[] =
{
{ 0x5c,0x23,0x82,166},
{ 0x5c,0x23,0x82,166},
@@ -652,7 +605,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
{ 0x37,0x21,0x82,200}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_760[] =
{
{ 0x37,0x22,0x82,133},
{ 0x5c,0x23,0x82,166},
@@ -664,7 +617,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
{ 0x37,0x21,0x82,200}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_761[] =
{
{ 0x37,0x22,0x82,133}, /* Preliminary */
{ 0x5c,0x23,0x82,166},
@@ -676,7 +629,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_761[] =
{ 0x37,0x21,0x82,200}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
+static const struct SiS_MCLKData SiS310_MCLKData_0_340[] =
{
{ 0x79,0x06,0x01,250},
{ 0x7c,0x08,0x01,200},
@@ -688,9 +641,9 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_0_340[] =
{ 0x29,0x01,0x81,300}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
+static const struct SiS_MCLKData SiS310_MCLKData_1[] = /* ECLK */
{
- { 0x29,0x21,0x82,150},
+ { 0x29,0x21,0x82,150},
{ 0x5c,0x23,0x82,166},
{ 0x65,0x23,0x82,183},
{ 0x37,0x21,0x82,200},
@@ -700,7 +653,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
{ 0x37,0x22,0x82,133}
};
-static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
+static const struct SiS_MCLKData SiS310_MCLKData_1_340[] =
{
{ 0x7c,0x08,0x01,200},
{ 0x7c,0x08,0x01,200},
@@ -712,7 +665,7 @@ static const SiS_MCLKDataStruct SiS310_MCLKData_1_340[] =
{ 0x29,0x01,0x81,300}
};
-static SiS_VCLKDataStruct SiS310_VCLKData[]=
+static struct SiS_VCLKData SiS310_VCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
@@ -805,7 +758,7 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
{ 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
{ 0x52,0x07,149}, /* 0x59 1280x960-85 */
{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
- { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
{ 0x45,0x25, 83}, /* 0x5c 1280x800 */
{ 0x70,0x0a,147}, /* 0x5d 1680x1050 */
{ 0x70,0x24,162}, /* 0x5e 1600x1200 */
@@ -823,10 +776,19 @@ static SiS_VCLKDataStruct SiS310_VCLKData[]=
{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
{ 0x45,0x25, 83}, /* 0x6c 1280x800 */
- { 0x70,0x28, 90} /* 0x6d 1152x864@60 */
+ { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
+ { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
+ { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
+ { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
+ { 0x2b,0xc2, 35}, /* 0x71 768x576@60 */
+ { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
+ { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
+ { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
+ { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
+ { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (wide) */
};
-static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
+static struct SiS_VBVCLKData SiS310_VBVCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
@@ -858,12 +820,6 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
{ 0x5e,0x43,113}, /* 0x1b */
{ 0xbc,0x44,116}, /* 0x1c */
{ 0xe0,0x46,132}, /* 0x1d */
-#if 0
- { 0xd4,0x28,135}, /* 0x1e */
- { 0xea,0x2a,139}, /* 0x1f */
- { 0x41,0x22,157}, /* 0x20 */
- { 0x70,0x24,162}, /* 0x21 */
-#endif
{ 0xe2,0x46,135}, /* 0x1e */ /* 1280x1024-75, better clock for VGA2 */
{ 0xe5,0x46,139}, /* 0x1f */ /* 1024x768-120, better clock for VGA2 */
{ 0x15,0x01,157}, /* 0x20 */ /* 1280x1024-85, better clock for VGA2 */
@@ -912,7 +868,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
{ 0x34,0x61, 95}, /* 0x4b UNUSED */
{ 0x78,0x27,108}, /* 0x4c UNUSED */
{ 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
- { 0x41,0x4e, 21}, /* 0x4e UNUSED */
+ { 0x41,0x4e, 21}, /* 0x4e */
{ 0xa1,0x4a, 29}, /* 0x4f UNUSED */
{ 0x19,0x42, 42}, /* 0x50 UNUSED */
{ 0x54,0x46, 58}, /* 0x51 UNUSED */
@@ -925,7 +881,7 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
{ 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
{ 0x52,0x07,149}, /* 0x59 1280x960-85 */
{ 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
- { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD (TMDS) */
{ 0xce,0x1e, 73}, /* 0x5c 1280x800_2 LCD (SiS LVDS) - (CRT1: 45 25 83) */
{ 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
{ 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
@@ -943,57 +899,33 @@ static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
{ 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */
{ 0xe3,0x56, 41}, /* 0x6b 960x600@60 */
{ 0x9c,0x62, 69}, /* 0x6c 1280x800 (SiS TMDS) (special) */
- { 0x70,0x28, 90} /* 0x6d 1152x864@60 */
+ { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */
+ { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */
+ { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */
+ { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */
+ { 0x2b,0xc2, 35}, /* 0x71 768@576@60 */
+ { 0xa8,0x42,131}, /* 0x72 1600x1200@60 for LCDA */
+ { 0x1b,0xc1, 34}, /* 0x73 800x480 60Hz (wide) */
+ { 0x41,0x64, 48}, /* 0x74 1024x576 60Hz (wide) */
+ { 0x52,0x27, 75}, /* 0x75 1280x720 60Hz (wide) */
+ { 0x75,0x13, 84} /* 0x76 1280x854 60Hz (SiS LVDS) LCD */
};
-static const DRAM4Type SiS310_SR15[8] = {
- {0x00,0x04,0x60,0x60},
- {0x0f,0x0f,0x0f,0x0f},
- {0xba,0xba,0xba,0xba},
- {0xa9,0xa9,0xac,0xac},
- {0xa0,0xa0,0xa0,0xa8},
- {0x00,0x00,0x02,0x02},
- {0x30,0x30,0x40,0x40},
- {0x00,0xa5,0xfb,0xf6}
-};
-
-#ifdef LINUX_KERNEL
-
-static UCHAR SiS310_SR07 = 0x18;
-
-static const DRAM4Type SiS310_CR40[5] = {
- {0x77,0x77,0x33,0x33},
- {0x77,0x77,0x33,0x33},
- {0x00,0x00,0x00,0x00},
- {0x5b,0x5b,0x03,0x03},
- {0x00,0x00,0xf0,0xf8}
+static const unsigned char SiS310_SR15[4 * 8] =
+{
+ 0x00,0x04,0x60,0x60,
+ 0x0f,0x0f,0x0f,0x0f,
+ 0xba,0xba,0xba,0xba,
+ 0xa9,0xa9,0xac,0xac,
+ 0xa0,0xa0,0xa0,0xa8,
+ 0x00,0x00,0x02,0x02,
+ 0x30,0x30,0x40,0x40,
+ 0x00,0xa5,0xfb,0xf6
};
-static UCHAR SiS310_CR49[] = {0xaa,0x88};
-static UCHAR SiS310_SR1F = 0x00;
-static UCHAR SiS310_SR21 = 0xa5;
-static UCHAR SiS310_SR22 = 0xfb;
-static UCHAR SiS310_SR23 = 0xf6;
-static UCHAR SiS310_SR24 = 0x0d;
-static UCHAR SiS310_SR25[] = {0x33,0x3};
-static UCHAR SiS310_SR31 = 0x00;
-static UCHAR SiS310_SR32 = 0x11;
-static UCHAR SiS310_SR33 = 0x00;
-static UCHAR SiS310_CRT2Data_1_2 = 0x00;
-static UCHAR SiS310_CRT2Data_4_D = 0x00;
-static UCHAR SiS310_CRT2Data_4_E = 0x00;
-static UCHAR SiS310_CRT2Data_4_10 = 0x80;
-static const USHORT SiS310_RGBSenseData = 0xd1;
-static const USHORT SiS310_VideoSenseData = 0xb9;
-static const USHORT SiS310_YCSenseData = 0xb3;
-static const USHORT SiS310_RGBSenseData2 = 0x0190;
-static const USHORT SiS310_VideoSenseData2 = 0x0174;
-static const USHORT SiS310_YCSenseData2 = 0x016b;
-#endif
-
-static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+static const struct SiS_PanelDelayTbl SiS310_PanelDelayTbl[] =
{
- {{0x10,0x40}},
+ {{0x10,0x40}},
{{0x10,0x40}},
{{0x10,0x40}},
{{0x10,0x40}},
@@ -1011,7 +943,7 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
{{0x10,0x40}}
};
-static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+static const struct SiS_PanelDelayTbl SiS310_PanelDelayTblLVDS[] =
{
{{0x28,0xc8}},
{{0x28,0xc8}},
@@ -1035,18 +967,18 @@ static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
/* SIS VIDEO BRIDGE ----------------------------------------- */
/**************************************************************/
-static const SiS_LCDDataStruct SiS310_St2LCD1024x768Data[] =
+static const struct SiS_LCDData SiS310_St2LCD1024x768Data[] =
{
{ 62, 25, 800, 546,1344, 806},
{ 32, 15, 930, 546,1344, 806},
- { 62, 25, 800, 546,1344, 806},
+ { 62, 25, 800, 546,1344, 806},
{ 104, 45, 945, 496,1344, 806},
{ 62, 25, 800, 546,1344, 806},
{ 31, 18,1008, 624,1344, 806},
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
+static const struct SiS_LCDData SiS310_ExtLCD1024x768Data[] =
{
{ 42, 25,1536, 419,1344, 806},
{ 48, 25,1536, 369,1344, 806},
@@ -1057,7 +989,7 @@ static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
+static const struct SiS_LCDData SiS310_St2LCD1280x1024Data[] =
{
{ 22, 5, 800, 510,1650,1088},
{ 22, 5, 800, 510,1650,1088},
@@ -1069,7 +1001,7 @@ static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
+static const struct SiS_LCDData SiS310_ExtLCD1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
@@ -1081,45 +1013,22 @@ static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const struct SiS_Part2PortTbl SiS310_CRT2Part2_1024x768_1[] =
{
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
};
-/* *** LCDA *** */
-
-#if 0
-static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
-{ /* Clevo, 651+301C */
- {1200, 450, 2048,1250},
- {1200, 400, 2048,1250},
- {1280, 450, 2048,1250},
- {1280, 400, 2048,1250},
- {1200, 530, 2048,1250},
- {1360, 650, 2048,1250},
- {1584, 818, 2048,1250},
- {1688,1066, 2048,1250},
- {1688,1066, 2048,1250},
-#if 0
- {2048,1250, 2048,1250} /* this should be correct */
-#endif
-#if 1
- {2160,1250, 2048,1250} /* ? */
-#endif
-};
-#endif
-
/**************************************************************/
/* LVDS, CHRONTEL ------------------------------------------- */
/**************************************************************/
-static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -1130,7 +1039,7 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]=
{1400,1000,1400,1000}
};
-static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -1138,10 +1047,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]=
{1008, 625,1008, 625},
{ 840, 625, 840, 625},
{ 944, 625, 944, 625},
- {1400, 875,1400, 875}
+ {1400, 875,1400, 875}
};
-static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALMData[] =
{
{ 840, 600, 840, 600},
{ 840, 600, 840, 600},
@@ -1149,10 +1058,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]=
{ 840, 600, 840, 600},
{ 784, 600, 784, 600},
{1064, 750,1064, 750},
- {1160, 945,1160, 945}
+ {1160, 945,1160, 945}
};
-static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALMData[] =
{
{ 840, 525, 840, 525},
{ 840, 525, 840, 525},
@@ -1160,10 +1069,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]=
{ 840, 525, 840, 525},
{ 784, 525, 784, 525},
{1040, 700,1040, 700},
- {1160, 840,1160, 840}
+ {1160, 840,1160, 840}
};
-static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]=
+static const struct SiS_LVDSData SiS310_CHTVUPALNData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -1174,7 +1083,7 @@ static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]=
{1400,1000,1400,1000}
};
-static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]=
+static const struct SiS_LVDSData SiS310_CHTVOPALNData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -1182,10 +1091,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]=
{1008, 625,1008, 625},
{ 840, 625, 840, 625},
{ 944, 625, 944, 625},
- {1400, 875,1400, 875}
+ {1400, 875,1400, 875}
};
-static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan - no effect on 7019) */
+static const struct SiS_LVDSData SiS310_CHTVSOPALData[] = /* (super overscan - no effect on 7019) */
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
@@ -1196,1333 +1105,10 @@ static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan -
{1400, 875,1400, 875}
};
-
-static const SiS_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 805},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 1065},
- { 0, 0},
- { 0, 0}
-};
-
-
-static const SiS_LVDSDesStruct SiS310_PanelType03_1[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType04_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType05_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType06_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType07_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
-{
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 8, 524},
- { 0, 524}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
-{
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 0, 524},
- { 8, 524},
- { 0, 524}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0d_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0e_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0f_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343, 0},
- {1343, 0},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType00_2[]=
-{
- {980, 528},
- {980, 503},
- {980, 528},
- {980, 503},
- {980, 568},
- { 0, 628},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType01_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 806},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType02_2[]=
-{
- {1368, 754},
- {1368, 729},
- {1368, 754},
- {1368, 729},
- {1368, 794},
- {1448, 854},
- {1560, 938},
- { 0,1066},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType03_2[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType04_2[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType05_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType06_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType07_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */
-{
- {1308, 741},
- {1308, 716},
- {1308, 741},
- {1308, 716},
- {1308, 781},
- {1388, 841},
- {1500, 925},
- {1628,1053},
- { 0,1065},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */
-{
- {1083, 622},
- {1083, 597},
- {1083, 622},
- {1083, 597},
- {1083, 662},
- {1163, 722},
- {1286, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */
-{
- {1568, 920},
- {1568, 895},
- {1568, 920},
- {1568, 895},
- {1568, 960},
- {1648,1020},
- {1760,1104},
- {1888,1232},
- {1948,1245},
- { 0, 0}
-#if 0
- {1568, 850},
- {1568, 825},
- {1568, 850},
- {1568, 825},
- {1568, 890},
- {1648, 950},
- {1760,1034},
- {1888,1162},
- {1948,1175},
- { 0, 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0d_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0e_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelType0f_2[] =
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelTypeNS_1[]=
-{
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 806},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS310_PanelTypeNS_2[] =
-{
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
-/* CRT1 CRTC for SlaveModes and LCDA */
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
-{
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
- 0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
- 0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0x78,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x6b,0x4f,0x8f,0x55,0x85,0xfa,0x1f,
- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
- 0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
-{
- {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
- 0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
- 0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
- 0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0x78,0x1f,
- 0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
- 0x00 }},
- {{0x43,0x27,0x87,0x2d,0x1d,0xfa,0x1f,
- 0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
- 0x00 }},
- {{0x4d,0x31,0x91,0x37,0x07,0x72,0xf0,
- 0x58,0x8d,0x57,0x73,0x20,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]=
-{
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
- 0xe6,0x8b,0x5d,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
- 0x27,0x8c,0xdf,0x73,0x00,0x00,0x06,
- 0x00 }},
- {{0x7f,0x63,0x83,0x69,0x19,0x72,0xf0,
- 0x58,0x8d,0x57,0x73,0x20,0x00,0x06,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
-{
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
- 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
- 0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
- 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
- 0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
- 0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
- 0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
- 0xd6,0x8b,0x5d,0x73,0x00,0x00,0x01,
- 0x00 }},
- {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0xba,
- 0x27,0x8c,0xdf,0x73,0x00,0x00,0x01,
- 0x00 }},
- {{0x4d,0x31,0x91,0x3a,0x0a,0x72,0xf0,
- 0x63,0x88,0x57,0x73,0x00,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
-{
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x82,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x97,0x53,0x84,0x04,0x3e,
- 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
- 0x00}},
- {{0x87,0x63,0x8B,0x67,0x18,0x7c,0xf0,
- 0x5A,0x81,0x57,0x7D,0x00,0x00,0x06,
- 0x01}},
- {{0xA3,0x7f,0x87,0x83,0x94,0x24,0xf5,
- 0x02,0x89,0xFf,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
-{
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
- 0x00 }},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
- 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x82,0x1f,
- 0x60,0x87,0x5D,0x83,0x01,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x8f,0x2b,0x1c,0x04,0x3e,
- 0xE2,0x89,0xDf,0x05,0x00,0x00,0x05,
- 0x00}},
- {{0x55,0x31,0x99,0x35,0x06,0x7c,0xf0,
- 0x5A,0x81,0x57,0x7D,0x00,0x00,0x01,
- 0x01}},
- {{0x63,0x3F,0x87,0x43,0x94,0x24,0xf5,
- 0x02,0x89,0xFf,0x25,0x10,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
- 0x00 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x3e,0x85,0x5d,0x25,0x10,0x00,0x06,
- 0x01 }},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x7f,0x86,0xdf,0x25,0x10,0x00,0x06,
- 0x00 }},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xbb,0x82,0x57,0x25,0x10,0x00,0x02,
- 0x01 }},
- {{0xa3,0x7f,0x87,0x83,0x94,0x24,0xf5,
- 0x02,0x89,0xff,0x25,0x10,0x00,0x02,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
-{
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x3e,0x85,0x5d,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x7f,0x86,0xdf,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x71,0x31,0x95,0x46,0x97,0x24,0xf1,
- 0xbb,0x82,0x57,0x25,0x10,0x00,0x01,
- 0x01 }},
- {{0x63,0x3f,0x87,0x46,0x97,0x24,0xf5,
- 0x0f,0x86,0xff,0x25,0x30,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
-{
- {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
- 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
- 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
- 0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
- 0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e,
- 0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
- 0x00}},
- {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0,
- 0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
- 0x01}},
- {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5,
- 0x00,0x84,0xff,0x29,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
-{
- {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
- 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
- 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
- 0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
- 0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
- 0x01}},
- {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e,
- 0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
- 0x00}},
- {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0,
- 0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
- 0x01}},
- {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5,
- 0x00,0x84,0xff,0x29,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
-{
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
- 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
- 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
- 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
- 0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
- 0xf0,0x84,0x85,0x84,0x11,0x00,0x02,
- 0x01}},
- {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
- 0x01}},
- {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
-{
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
- 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
- 0xaf,0x83,0x44,0x43,0x21,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
- 0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
- 0xfa,0x83,0x44,0x43,0x31,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
- 0xf0,0x84,0x85,0x84,0x11,0x00,0x06,
- 0x01}},
- {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
- 0x01}},
- {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
-{
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
- 0xdf,0x82,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
- 0x57,0x8e,0x57,0x67,0x20,0x00,0x06,
- 0x01}},
- {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1,
- 0xff,0x86,0xff,0x0f,0x10,0x00,0x02,
- 0x01,}},
- {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde,
- 0xff,0x86,0xff,0x0f,0x01,0x00,0x07,
- 0x01}},
- {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
- 0x19,0x80,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-#if 0
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
- 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
- 0x5a,0x8e,0x57,0x67,0x20,0x00,0x06,
- 0x01}},
- {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
- 0x02,0x86,0xff,0x0f,0x10,0x00,0x02,
- 0x01}},
- {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
- 0x02,0x86,0xff,0x0f,0x09,0x00,0x07,
- 0x01}},
- {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
- 0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] =
-{
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
- 0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
- 0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
- 0xdf,0x86,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
- 0x57,0x8e,0x57,0x67,0x20,0x00,0x01,
- 0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1,
- 0xff,0x86,0xff,0x0f,0x10,0x00,0x01,
- 0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
- 0x01}},
- {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
- 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
- 0x00}}
-#if 0
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
- 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
- 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
- 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
- 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
- 0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
- 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
- 0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
- 0x01}},
- {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
- 0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] =
-{
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
- 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
- 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
- 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
- 0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
- 0x01}},
- {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
- 0xff,0x83,0x85,0x84,0x11,0x00,0x02,
- 0x01}},
- {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
- 0x01}},
- {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a,
- 0x13,0x87,0xff,0x29,0x29,0x00,0x07,
- 0x01}},
- {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
- 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-#if 0
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
- 0x01}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
- 0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
- 0x00}},
- {{0xce,0x63,0x92,0x96,0x04,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x07,
- 0x01}},
- {{0xce,0x7f,0x92,0xa4,0x12,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xb4,0x02,0x28,0x5a,
- 0x13,0x87,0xff,0x29,0x29,0x00,0x03,
- 0x01}},
- {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
- 0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] =
-{
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
- 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
- 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
- 0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
- 0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
- 0x01}},
- {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
- 0xff,0x83,0x85,0x84,0x11,0x00,0x06,
- 0x01}},
- {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
- 0x01}},
- {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
- 0x01}},
- {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a,
- 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
- 0x01}},
- {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
- 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
- 0x00}}
-#if 0
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9e,
- 0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0x9c,0x31,0x80,0x64,0x92,0x28,0xd4,
- 0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
- 0x01}},
- {{0x8e,0x3f,0x92,0x64,0x12,0x28,0xd4,
- 0x93,0x87,0xff,0x29,0x21,0x00,0x06,
- 0x01}},
- {{0x7e,0x4f,0x82,0x64,0x12,0x28,0x5a,
- 0x13,0x87,0xff,0x29,0x29,0x00,0x06,
- 0x01}},
- {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
- 0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
-{
- {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
- 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
- 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
- 0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
- 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0x56,0xBA,
- 0x03,0x86,0xDF,0x57,0x00,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x9B,0x6F,0x07,0xCE,0xF0,
- 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x02,
- 0x01}},
- {{0xB3,0x7F,0x97,0x8B,0x83,0x76,0xF5,
- 0x23,0x86,0xFF,0x77,0x10,0x00,0x06,
- 0x01}},
- {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
- 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
- 0x01}},
- {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
- 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
- 0x00}},
- {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
- 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
- 0x00}}
-#if 0
- {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
- 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
- 0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
- 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
- 0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
- 0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
- 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e,
- 0xe0,0x84,0xdf,0x11,0x00,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0,
- 0x58,0x8c,0x57,0x89,0x20,0x00,0x06,
- 0x01}},
- {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5,
- 0x00,0x84,0xff,0x31,0x10,0x00,0x02,
- 0x01}},
- {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a,
- 0x00,0x84,0xff,0x31,0x09,0x00,0x07,
- 0x01}},
- {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10,
- 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03,
- 0x00}},
- {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
- 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
-{
- {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
- 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
- 0x00}},
- {{0x5B,0x27,0x9F,0x29,0x01,0x8E,0x1F,
- 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
- 0x00}},
- {{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
- 0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
- 0x00}},
- {{0x83,0x4F,0x87,0x5B,0x13,0xD4,0x1F,
- 0x81,0x84,0x5D,0xD5,0x10,0x00,0x06,
- 0x00}},
- {{0x5B,0x27,0x9F,0x33,0x0B,0x56,0xBA,
- 0x03,0x86,0xDF,0x57,0x00,0x00,0x01,
- 0x00}},
- {{0x65,0x31,0x89,0x3D,0x95,0xCE,0xF0,
- 0x7B,0x8E,0x57,0xCF,0x20,0x00,0x01,
- 0x01}},
- {{0x73,0x3F,0x97,0x4B,0x83,0x76,0xF5,
- 0x23,0x86,0xFF,0x77,0x10,0x00,0x05,
- 0x01}},
- {{0xD3,0x9F,0x97,0xAB,0x03,0x76,0x5A,
- 0x23,0x86,0xFF,0x77,0x09,0x00,0x03,
- 0x01}},
- {{0xE2,0xAE,0x86,0xBA,0x92,0x90,0x10,
- 0x3D,0x80,0x19,0x91,0x0F,0x00,0x03,
- 0x00}},
- {{0x97,0x63,0x9B,0x6F,0x07,0xE0,0x10,
- 0xB0,0x84,0xAF,0xE1,0x2F,0x00,0x06,
- 0x00}}
-#if 0
- {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
- 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
- 0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
- 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
- 0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
- 0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
- 0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
- 0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
- 0x00}},
- {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e,
- 0xe0,0x84,0xdf,0x11,0x00,0x00,0x01,
- 0x00}},
- {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0,
- 0x58,0x8c,0x57,0x89,0x20,0x00,0x01,
- 0x01}},
- {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5,
- 0x00,0x84,0xff,0x31,0x10,0x00,0x01,
- 0x01}},
- {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a,
- 0x00,0x84,0xff,0x31,0x09,0x00,0x06,
- 0x01}},
- {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10,
- 0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
- 0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
-{
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
- 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
- 0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
- 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
- 0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
- 0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
- 0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
- 0x2A,0x8D,0xC2,0xC1,0x11,0x00,0x07,
- 0x01}},
- {{0xFB,0x87,0x86,0x97,0x0F,0x26,0x9F,
- 0x6B,0x8E,0x03,0x02,0x01,0x00,0x07,
- 0x01}},
- {{0xFB,0x63,0x9F,0xA1,0x99,0x26,0xD5,
- 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x07,
- 0x01}},
- {{0xFB,0x7F,0x9F,0xAF,0x87,0x26,0xDD,
- 0xFB,0x8E,0x13,0x12,0x31,0x00,0x03,
- 0x01}},
- {{0xFB,0x9F,0x9F,0xBF,0x97,0x26,0x5B,
- 0x7B,0x8E,0xFF,0x27,0x39,0x00,0x03,
- 0x01}},
- {{0xFB,0xAE,0x9F,0xC6,0x9E,0x26,0x11,
- 0x88,0x8B,0x19,0x27,0x1F,0x00,0x03,
- 0x00}},
- {{0xFB,0xC7,0x9F,0xD3,0x8B,0x26,0x11,
- 0xD3,0x86,0xAF,0x27,0x3F,0x00,0x07,
- 0x00}}
-#if 0
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
- 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
- 0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
- 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
- 0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
- 0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
- 0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
- 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
- 0x01}},
- {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
- 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07,
- 0x01}},
- {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4,
- 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07,
- 0x01}},
- {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4,
- 0xef,0x83,0xff,0xe1,0x21,0x00,0x03,
- 0x01}},
- {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a,
- 0x6f,0x83,0xff,0xe1,0x29,0x00,0x03,
- 0x01}},
- {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10,
- 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03,
- 0x00}},
- {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
- 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] =
-{
- {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
- 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
- 0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
- 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
- 0x01}},
- {{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
- 0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
- 0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
- 0x07,0x8B,0xA0,0x9F,0x01,0x00,0x02,
- 0x01}},
- {{0xD3,0x27,0x97,0x6F,0x07,0x26,0x97,
- 0x6B,0x8E,0x83,0x82,0x01,0x00,0x03,
- 0x01}},
- {{0xC9,0x31,0x8D,0x6F,0x07,0x26,0xD5,
- 0xA7,0x8A,0xBF,0xBE,0x01,0x00,0x03,
- 0x01}},
- {{0xBB,0x3F,0x9F,0x6F,0x87,0x26,0xDD,
- 0xFB,0x8E,0x13,0x12,0x31,0x00,0x02,
- 0x01}},
- {{0xAB,0x4F,0x8F,0x68,0x80,0xE0,0x5A,
- 0x6F,0x83,0xFF,0xE1,0x29,0x00,0x02,
- 0x01}},
- {{0xA3,0x56,0x87,0x67,0x9F,0xE0,0x10,
- 0x7C,0x80,0x19,0xE1,0x0F,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x9B,0x68,0x00,0xE0,0x10,
- 0xC7,0x8B,0xAF,0xE1,0x0F,0x00,0x02,
- 0x00}}
-#if 0
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
- 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
- 0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
- 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
- 0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
- 0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
- 0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
- 0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
- 0x01}},
- {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
- 0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02,
- 0x01}},
- {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4,
- 0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03,
- 0x01}},
- {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4,
- 0xef,0x83,0xff,0xe1,0x21,0x00,0x02,
- 0x01}},
- {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a,
- 0x6f,0x83,0xff,0xe1,0x29,0x00,0x02,
- 0x01}},
- {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10,
- 0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
- 0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
- 0x00}}
-#endif
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
- 0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
- 0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
- 0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-
/* CRT1 CRTC for Chrontel TV slave modes */
-static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
-{
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UNTSC[] =
+{
{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
0x00 }},
@@ -2546,7 +1132,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
0x01}}
};
-static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1ONTSC[] =
{
{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -2571,8 +1157,8 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
0x01 }}
};
-static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
-{
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1UPAL[] =
+{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
0x00 }},
@@ -2596,7 +1182,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
0x01}}
};
-static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
+static const struct SiS_LVDSCRT1Data SiS310_CHTVCRT1OPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2621,8 +1207,7 @@ static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
0x01 }}
};
-
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UNTSC[] =
{
{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
for PAL-M and PAL-N all above is corrected.
*/
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_ONTSC[] =
{
{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
{{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPAL[] =
{
{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPAL[] =
{
{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALM[] =
{
{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
#endif
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALM[] =
{
{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{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[] =
#endif
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_UPALN[] =
{
{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
{{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[] =
#endif
};
-static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+static const struct SiS_CHTVRegData SiS310_CHTVReg_OPALN[] =
{
{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
{{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[] =
#endif
};
-static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+static const unsigned char SiS310_CHTVVCLKUNTSC[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
+static const unsigned char SiS310_CHTVVCLKONTSC[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
-static const UCHAR SiS310_CHTVVCLKUPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-static const UCHAR SiS310_CHTVVCLKOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+static const unsigned char SiS310_CHTVVCLKUPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
+static const unsigned char SiS310_CHTVVCLKOPAL[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
-static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
-static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+static const unsigned char SiS310_CHTVVCLKUPALM[] = { 0x41,0x41,0x41,0x41,0x42,0x46,0x53 };
+static const unsigned char SiS310_CHTVVCLKOPALM[] = { 0x48,0x48,0x48,0x48,0x45,0x43,0x51 };
-static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
-static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+static const unsigned char SiS310_CHTVVCLKUPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4a,0x54 };
+static const unsigned char SiS310_CHTVVCLKOPALN[] = { 0x47,0x47,0x47,0x47,0x48,0x4f,0x52 };
diff --git a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
index aaed8c2b4a6..f7c0046e5b1 100644
--- a/drivers/video/sis/Makefile
+++ b/drivers/video/sis/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_FB_SIS) += sisfb.o
-sisfb-objs := sis_main.o sis_accel.o init.o init301.o
+sisfb-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 ecfd72178db..2ab3868efde 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -2,11 +2,12 @@
/* $XdotOrg$ */
/*
* Mode initializing code (CRT1 section) for
- * for SiS 300/305/540/630/730 and
- * SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ * for SiS 300/305/540/630/730,
+ * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI Volari V3XT/V5/V8, Z7
+ * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -53,17 +54,12 @@
*
* Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
* Used by permission.
- *
- * TW says: This code looks awful, I know. But please don't do anything about
- * this otherwise debugging will be hell.
- * The code is extremely fragile as regards the different chipsets, different
- * video bridges and combinations thereof. If anything is changed, extreme
- * care has to be taken that that change doesn't break it for other chipsets,
- * bridges or combinations thereof.
- * All comments in this file are by me, regardless if they are marked TW or not.
- *
*/
-
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "init.h"
#ifdef SIS300
@@ -84,24 +80,13 @@
#if defined(SIS300) || defined(SIS315H)
static void
-InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitCommonPointer(struct SiS_Private *SiS_Pr)
{
+ SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable;
SiS_Pr->SiS_StResInfo = SiS_StResInfo;
SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo;
SiS_Pr->SiS_StandTable = SiS_StandTable;
- SiS_Pr->SiS_NTSCPhase = SiS_NTSCPhase;
- SiS_Pr->SiS_PALPhase = SiS_PALPhase;
- SiS_Pr->SiS_NTSCPhase2 = SiS_NTSCPhase2;
- SiS_Pr->SiS_PALPhase2 = SiS_PALPhase2;
- SiS_Pr->SiS_PALMPhase = SiS_PALMPhase;
- SiS_Pr->SiS_PALNPhase = SiS_PALNPhase;
- SiS_Pr->SiS_PALMPhase2 = SiS_PALMPhase2;
- SiS_Pr->SiS_PALNPhase2 = SiS_PALNPhase2;
- SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
- SiS_Pr->SiS_SpecialPhaseM = SiS_SpecialPhaseM;
- SiS_Pr->SiS_SpecialPhaseJ = SiS_SpecialPhaseJ;
-
SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming;
SiS_Pr->SiS_PALTiming = SiS_PALTiming;
SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing;
@@ -137,6 +122,7 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data;
+ SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data;
SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
@@ -145,67 +131,30 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
- SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1;
+ SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1;
+ SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2;
+ SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1;
- SiS_Pr->SiS_LVDS800x600Data_2 = SiS_LVDS800x600Data_2;
- SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
- SiS_Pr->SiS_LVDS1024x768Data_2 = SiS_LVDS1024x768Data_2;
- SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
- SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
- SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
- SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
- SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
- SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
- SiS_Pr->SiS_LVDS1280x768Data_1 = SiS_LVDS1280x768Data_1;
- SiS_Pr->SiS_LVDS1280x768Data_2 = SiS_LVDS1280x768Data_2;
SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1;
- SiS_Pr->SiS_LVDS1024x600Data_2 = SiS_LVDS1024x600Data_2;
- SiS_Pr->SiS_LVDS1152x768Data_1 = SiS_LVDS1152x768Data_1;
- SiS_Pr->SiS_LVDS1152x768Data_2 = SiS_LVDS1152x768Data_2;
- SiS_Pr->SiS_LVDSXXXxXXXData_1 = SiS_LVDSXXXxXXXData_1;
- SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x960Data_1;
- SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x960Data_2;
- SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
- SiS_Pr->SiS_LVDS1280x960Data_1 = SiS_LVDS1280x1024Data_1;
- SiS_Pr->SiS_LVDS1280x960Data_2 = SiS_LVDS1280x1024Data_2;
- SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
- SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2;
-
- SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1;
- SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2;
- SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
- SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
- SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
- SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
+ SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1;
- SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1;
+ SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1;
+ SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2;
+ SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H;
+ SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3;
+ SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H;
+ SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
+ SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
+#if 0
SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
- SiS_Pr->SiS_LVDSCRT11152x768_1 = SiS_LVDSCRT11152x768_1;
- SiS_Pr->SiS_LVDSCRT11280x768_1_H = SiS_LVDSCRT11280x768_1_H;
SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H;
- SiS_Pr->SiS_LVDSCRT11152x768_1_H = SiS_LVDSCRT11152x768_1_H;
- SiS_Pr->SiS_LVDSCRT11280x768_2 = SiS_LVDSCRT11280x768_2;
SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2;
- SiS_Pr->SiS_LVDSCRT11152x768_2 = SiS_LVDSCRT11152x768_2;
- SiS_Pr->SiS_LVDSCRT11280x768_2_H = SiS_LVDSCRT11280x768_2_H;
SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
- SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H;
- SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1;
- SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
- SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
- SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2;
- SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H;
- SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3;
- SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H;
+#endif
SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
- SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
- SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
- SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
- SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
-
SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
}
@@ -213,50 +162,24 @@ InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS300
static void
-InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitTo300Pointer(struct SiS_Private *SiS_Pr)
{
- InitCommonPointer(SiS_Pr, HwInfo);
+ InitCommonPointer(SiS_Pr);
- SiS_Pr->SiS_SModeIDTable = SiS300_SModeIDTable;
SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
- if(HwInfo->jChipType == SIS_300) {
- SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
+ if(SiS_Pr->ChipType == SIS_300) {
+ SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
} else {
- SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
+ SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
}
SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
- SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData;
SiS_Pr->SiS_SR15 = SiS300_SR15;
-#ifdef LINUX_KERNEL
- SiS_Pr->pSiS_SR07 = &SiS300_SR07;
- SiS_Pr->SiS_CR40 = SiS300_CR40;
- SiS_Pr->SiS_CR49 = SiS300_CR49;
- SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
- SiS_Pr->pSiS_SR21 = &SiS300_SR21;
- SiS_Pr->pSiS_SR22 = &SiS300_SR22;
- SiS_Pr->pSiS_SR23 = &SiS300_SR23;
- SiS_Pr->pSiS_SR24 = &SiS300_SR24;
- SiS_Pr->SiS_SR25 = SiS300_SR25;
- SiS_Pr->pSiS_SR31 = &SiS300_SR31;
- SiS_Pr->pSiS_SR32 = &SiS300_SR32;
- SiS_Pr->pSiS_SR33 = &SiS300_SR33;
- SiS_Pr->pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
- SiS_Pr->pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
- SiS_Pr->pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
- SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
- SiS_Pr->pSiS_RGBSenseData = &SiS300_RGBSenseData;
- SiS_Pr->pSiS_VideoSenseData = &SiS300_VideoSenseData;
- SiS_Pr->pSiS_YCSenseData = &SiS300_YCSenseData;
- SiS_Pr->pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
- SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
- SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2;
-#endif
-
SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
@@ -266,11 +189,8 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
- SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
- SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
- SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
@@ -280,64 +200,16 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */
SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
- SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1;
- SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1;
- SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1;
- SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1;
- SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1;
- SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1;
- SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1;
- SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1;
- SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1;
- SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1;
- SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
- SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
- SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
- SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
- SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
- SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
- SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
- SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
- SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
- SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
- SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
- SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
- SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
- SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
- SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
- SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
- SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
- SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
- SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
- SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
- SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
- SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
- SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
- SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
-
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
- SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
- }
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
- SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
- SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
- }
-
- SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS300_LVDSCRT1800x600_1;
- SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS300_LVDSCRT1800x600_1_H;
- SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS300_LVDSCRT1800x600_2;
- SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS300_LVDSCRT1800x600_2_H;
- SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS300_LVDSCRT11024x768_1;
- SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS300_LVDSCRT11024x768_1_H;
- SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS300_LVDSCRT11024x768_2;
- SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS300_LVDSCRT11024x768_2_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS300_LVDSCRT11280x1024_1;
- SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS300_LVDSCRT11280x1024_2;
- SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS300_LVDSCRT1XXXxXXX_1;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS300_LVDSCRT1XXXxXXX_1_H;
+ SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1;
+ SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2;
+ SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
+ SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
+ SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
+
+ SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
+ SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
+ SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
+ SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
@@ -367,64 +239,38 @@ InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS315H
static void
-InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+InitTo310Pointer(struct SiS_Private *SiS_Pr)
{
- InitCommonPointer(SiS_Pr, HwInfo);
+ InitCommonPointer(SiS_Pr);
- SiS_Pr->SiS_SModeIDTable = SiS310_SModeIDTable;
SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
- SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex;
+ SiS_Pr->SiS_RefIndex = SiS310_RefIndex;
SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
- if(HwInfo->jChipType >= SIS_340) {
- SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 */
- } else if(HwInfo->jChipType >= SIS_761) {
+ if(SiS_Pr->ChipType >= SIS_340) {
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 + XGI */
+ } else if(SiS_Pr->ChipType >= SIS_761) {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */
- } else if(HwInfo->jChipType >= SIS_760) {
+ } else if(SiS_Pr->ChipType >= SIS_760) {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */
- } else if(HwInfo->jChipType >= SIS_661) {
+ } else if(SiS_Pr->ChipType >= SIS_661) {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */
- } else if(HwInfo->jChipType == SIS_330) {
+ } else if(SiS_Pr->ChipType == SIS_330) {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */
- } else if(HwInfo->jChipType > SIS_315PRO) {
+ } else if(SiS_Pr->ChipType > SIS_315PRO) {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */
} else {
SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */
}
- if(HwInfo->jChipType >= SIS_340) {
- SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
+ if(SiS_Pr->ChipType >= SIS_340) {
+ SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
} else {
- SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
+ SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
}
SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
SiS_Pr->SiS_SR15 = SiS310_SR15;
-#ifdef LINUX_KERNEL
- SiS_Pr->pSiS_SR07 = &SiS310_SR07;
- SiS_Pr->SiS_CR40 = SiS310_CR40;
- SiS_Pr->SiS_CR49 = SiS310_CR49;
- SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
- SiS_Pr->pSiS_SR21 = &SiS310_SR21;
- SiS_Pr->pSiS_SR22 = &SiS310_SR22;
- SiS_Pr->pSiS_SR23 = &SiS310_SR23;
- SiS_Pr->pSiS_SR24 = &SiS310_SR24;
- SiS_Pr->SiS_SR25 = SiS310_SR25;
- SiS_Pr->pSiS_SR31 = &SiS310_SR31;
- SiS_Pr->pSiS_SR32 = &SiS310_SR32;
- SiS_Pr->pSiS_SR33 = &SiS310_SR33;
- SiS_Pr->pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
- SiS_Pr->pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
- SiS_Pr->pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
- SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
- SiS_Pr->pSiS_RGBSenseData = &SiS310_RGBSenseData;
- SiS_Pr->pSiS_VideoSenseData = &SiS310_VideoSenseData;
- SiS_Pr->pSiS_YCSenseData = &SiS310_YCSenseData;
- SiS_Pr->pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
- SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
- SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2;
-#endif
-
SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
@@ -435,41 +281,6 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
- SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
- SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
- SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
- SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
- SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
- SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
- SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
- SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
- SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
- SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
- SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
- SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
- SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
- SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
- SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
- SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
- SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
- SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
- SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
- SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
- SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
- SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
- SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
- SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
- SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
- SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
- SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
- SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
- SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
- SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
- SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
- SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
- SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
- SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
-
SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
@@ -478,33 +289,11 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
- SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS310_LVDSCRT1800x600_1;
- SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS310_LVDSCRT11024x768_1;
- SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS310_LVDSCRT11280x1024_1;
- SiS_Pr->SiS_LVDSCRT11400x1050_1 = SiS310_LVDSCRT11400x1050_1;
- SiS_Pr->SiS_LVDSCRT11600x1200_1 = SiS310_LVDSCRT11600x1200_1;
- SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS310_LVDSCRT1800x600_1_H;
- SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS310_LVDSCRT11024x768_1_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
- SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
- SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
- SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS310_LVDSCRT1800x600_2;
- SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS310_LVDSCRT11024x768_2;
- SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS310_LVDSCRT11280x1024_2;
- SiS_Pr->SiS_LVDSCRT11400x1050_2 = SiS310_LVDSCRT11400x1050_2;
- SiS_Pr->SiS_LVDSCRT11600x1200_2 = SiS310_LVDSCRT11600x1200_2;
- SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS310_LVDSCRT1800x600_2_H;
- SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS310_LVDSCRT11024x768_2_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
- SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
- SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS310_LVDSCRT1XXXxXXX_1;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS310_LVDSCRT1XXXxXXX_1_H;
- SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
- SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
- SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
- SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
- SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
+ SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
@@ -528,208 +317,203 @@ InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
#endif
-static void
-SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+BOOLEAN
+SiSInitPtr(struct SiS_Private *SiS_Pr)
{
- switch(HwInfo->jChipType) {
-#ifdef SIS315H
- case SIS_315H:
- case SIS_315:
- case SIS_315PRO:
- case SIS_550:
- case SIS_650:
- case SIS_740:
- case SIS_330:
- case SIS_661:
- case SIS_741:
- case SIS_660:
- case SIS_760:
- case SIS_761:
- case SIS_340:
- InitTo310Pointer(SiS_Pr, HwInfo);
- break;
-#endif
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300
- case SIS_300:
- case SIS_540:
- case SIS_630:
- case SIS_730:
- InitTo300Pointer(SiS_Pr, HwInfo);
- break;
+ InitTo300Pointer(SiS_Pr);
+#else
+ return FALSE;
+#endif
+ } else {
+#ifdef SIS315H
+ InitTo310Pointer(SiS_Pr);
+#else
+ return FALSE;
#endif
- default:
- break;
}
+ return TRUE;
}
/*********************************************/
/* HELPER: Get ModeID */
/*********************************************/
-#ifdef LINUX_XF86
-USHORT
-SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
{
- USHORT ModeIndex = 0;
+ unsigned short ModeIndex = 0;
switch(HDisplay)
{
- case 320:
- if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
- else if(VDisplay == 240) {
- if(FSTN) ModeIndex = ModeIndex_320x240_FSTN[Depth];
- else ModeIndex = ModeIndex_320x240[Depth];
- }
- break;
- case 400:
- if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
- }
- break;
- case 512:
- if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
- }
- break;
- case 640:
- if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
- else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
- break;
- case 720:
- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
- else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
- break;
- case 768:
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
- break;
- case 800:
- if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
- else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
- break;
- case 848:
- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
- break;
- case 856:
- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
- break;
- case 960:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
- else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
- }
- break;
- case 1024:
- if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
- else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
- else if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
- }
- break;
- case 1152:
- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
- if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
- }
- break;
- case 1280:
- switch(VDisplay) {
- case 720:
- ModeIndex = ModeIndex_1280x720[Depth];
- break;
- case 768:
- if(VGAEngine == SIS_300_VGA) {
- ModeIndex = ModeIndex_300_1280x768[Depth];
- } else {
- ModeIndex = ModeIndex_310_1280x768[Depth];
- }
- break;
- case 800:
- if(VGAEngine == SIS_315_VGA) {
- ModeIndex = ModeIndex_1280x800[Depth];
- }
- break;
- case 960:
- ModeIndex = ModeIndex_1280x960[Depth];
- break;
- case 1024:
- ModeIndex = ModeIndex_1280x1024[Depth];
- break;
- }
- break;
- case 1360:
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
- if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
- }
- break;
- case 1400:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1050) {
- ModeIndex = ModeIndex_1400x1050[Depth];
- }
- }
- break;
- case 1600:
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
- break;
- case 1680:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
- }
- break;
- case 1920:
- if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
- else if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
- }
- break;
- case 2048:
- if(VDisplay == 1536) {
- if(VGAEngine == SIS_300_VGA) {
- ModeIndex = ModeIndex_300_2048x1536[Depth];
- } else {
- ModeIndex = ModeIndex_310_2048x1536[Depth];
- }
- }
- break;
+ case 320:
+ if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+ else if(VDisplay == 240) {
+ if((VBFlags & CRT2_LCD) && (FSTN))
+ ModeIndex = ModeIndex_320x240_FSTN[Depth];
+ else
+ ModeIndex = ModeIndex_320x240[Depth];
+ }
+ break;
+ case 400:
+ if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ }
+ break;
+ case 512:
+ if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ }
+ break;
+ case 640:
+ if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
+ else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+ break;
+ case 720:
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+ break;
+ case 768:
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ break;
+ case 800:
+ if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+ else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+ break;
+ case 848:
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+ break;
+ case 856:
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ break;
+ case 960:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+ else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
+ }
+ break;
+ case 1024:
+ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ else if(VGAEngine == SIS_300_VGA) {
+ if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
+ }
+ break;
+ case 1152:
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ if(VGAEngine == SIS_300_VGA) {
+ if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
+ }
+ break;
+ case 1280:
+ switch(VDisplay) {
+ case 720:
+ ModeIndex = ModeIndex_1280x720[Depth];
+ break;
+ case 768:
+ if(VGAEngine == SIS_300_VGA) {
+ ModeIndex = ModeIndex_300_1280x768[Depth];
+ } else {
+ ModeIndex = ModeIndex_310_1280x768[Depth];
+ }
+ break;
+ case 800:
+ if(VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1280x800[Depth];
+ }
+ break;
+ case 854:
+ if(VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1280x854[Depth];
+ }
+ break;
+ case 960:
+ ModeIndex = ModeIndex_1280x960[Depth];
+ break;
+ case 1024:
+ ModeIndex = ModeIndex_1280x1024[Depth];
+ break;
+ }
+ break;
+ case 1360:
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+ if(VGAEngine == SIS_300_VGA) {
+ if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
+ }
+ break;
+ case 1400:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 1050) {
+ ModeIndex = ModeIndex_1400x1050[Depth];
+ }
+ }
+ break;
+ case 1600:
+ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ break;
+ case 1680:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ }
+ break;
+ case 1920:
+ if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+ else if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
+ }
+ break;
+ case 2048:
+ if(VDisplay == 1536) {
+ if(VGAEngine == SIS_300_VGA) {
+ ModeIndex = ModeIndex_300_2048x1536[Depth];
+ } else {
+ ModeIndex = ModeIndex_310_2048x1536[Depth];
+ }
+ }
+ break;
}
- return(ModeIndex);
+ return ModeIndex;
}
-#endif
-USHORT
-SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, USHORT CustomT, int LCDwidth, int LCDheight)
+unsigned short
+SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
+ unsigned int VBFlags2)
{
- USHORT ModeIndex = 0;
+ unsigned short ModeIndex = 0;
- if(VBFlags & (VB_LVDS | VB_30xBDH)) {
+ if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
switch(HDisplay)
{
case 320:
- if(CustomT != CUT_PANEL848) {
- if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
- else if(VDisplay == 240) {
+ if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+ if(VDisplay == 200) {
+ if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
+ } else if(VDisplay == 240) {
if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
- else if(VGAEngine == SIS_315_VGA) {
- ModeIndex = ModeIndex_320x240_FSTN[Depth];
+ else if(VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_320x240_FSTN[Depth];
}
}
}
- break;
- case 400:
- if(CustomT != CUT_PANEL848) {
- if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ break;
+ case 400:
+ if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+ if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
}
}
- break;
+ break;
case 512:
- if(CustomT != CUT_PANEL848) {
- if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
+ if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
+ if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
if(VDisplay == 384) {
ModeIndex = ModeIndex_512x384[Depth];
@@ -739,9 +523,10 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
}
break;
case 640:
- if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
else if(VDisplay == 400) {
- if(CustomT != CUT_PANEL848) ModeIndex = ModeIndex_640x400[Depth];
+ if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
+ ModeIndex = ModeIndex_640x400[Depth];
}
break;
case 800:
@@ -752,6 +537,11 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
}
break;
+ case 856:
+ if(CustomT == CUT_PANEL856) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ }
+ break;
case 1024:
if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
else if(VGAEngine == SIS_300_VGA) {
@@ -762,7 +552,7 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
break;
case 1152:
if(VGAEngine == SIS_300_VGA) {
- if((VDisplay == 768) && (LCDheight == 768)) {
+ if((VDisplay == 768) && (LCDheight == 768)) {
ModeIndex = ModeIndex_1152x768[Depth];
}
}
@@ -770,49 +560,49 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
case 1280:
if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
else if(VGAEngine == SIS_315_VGA) {
- if((VDisplay == 768) && (LCDheight == 768)) {
+ if((VDisplay == 768) && (LCDheight == 768)) {
ModeIndex = ModeIndex_310_1280x768[Depth];
}
}
break;
case 1360:
if(VGAEngine == SIS_300_VGA) {
- if(CustomT == CUT_BARCO1366) {
+ if(CustomT == CUT_BARCO1366) {
if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
}
}
if(CustomT == CUT_PANEL848) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
}
break;
case 1400:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
}
break;
case 1600:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
}
break;
}
- } else if(VBFlags & VB_SISBRIDGE) {
+ } else if(VBFlags2 & VB2_SISBRIDGE) {
switch(HDisplay)
{
case 320:
- if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+ if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
- break;
- case 400:
+ break;
+ case 400:
if(LCDwidth >= 800 && LCDheight >= 600) {
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
}
- break;
+ break;
case 512:
if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
}
break;
case 640:
@@ -821,96 +611,115 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
break;
case 720:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
}
break;
case 768:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
}
break;
case 800:
if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
}
break;
case 848:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
}
break;
case 856:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
}
break;
case 960:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
}
break;
case 1024:
if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
}
break;
case 1152:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
}
break;
case 1280:
switch(VDisplay) {
case 720:
- ModeIndex = ModeIndex_1280x720[Depth];
+ ModeIndex = ModeIndex_1280x720[Depth];
case 768:
- if(VGAEngine == SIS_300_VGA) {
+ if(VGAEngine == SIS_300_VGA) {
ModeIndex = ModeIndex_300_1280x768[Depth];
} else {
ModeIndex = ModeIndex_310_1280x768[Depth];
}
break;
case 800:
- if(VGAEngine == SIS_315_VGA) {
+ if(VGAEngine == SIS_315_VGA) {
ModeIndex = ModeIndex_1280x800[Depth];
}
break;
+ case 854:
+ if(VGAEngine == SIS_315_VGA) {
+ ModeIndex = ModeIndex_1280x854[Depth];
+ }
+ break;
case 960:
- ModeIndex = ModeIndex_1280x960[Depth];
+ ModeIndex = ModeIndex_1280x960[Depth];
break;
case 1024:
- ModeIndex = ModeIndex_1280x1024[Depth];
+ ModeIndex = ModeIndex_1280x1024[Depth];
break;
}
break;
case 1360:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+ if(VGAEngine == SIS_315_VGA) { /* OVER1280 only? */
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
}
break;
case 1400:
if(VGAEngine == SIS_315_VGA) {
- if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
+ if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
}
}
break;
case 1600:
if(VGAEngine == SIS_315_VGA) {
- if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
+ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
}
}
break;
#ifndef VB_FORBID_CRT2LCD_OVER_1600
case 1680:
if(VGAEngine == SIS_315_VGA) {
- if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ }
+ }
+ break;
+ case 1920:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
+ if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+ }
+ }
+ break;
+ case 2048:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
+ if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
}
}
break;
@@ -921,16 +730,17 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
return ModeIndex;
}
-USHORT
-SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+unsigned short
+SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
+ unsigned int VBFlags2)
{
- USHORT ModeIndex = 0;
+ unsigned short ModeIndex = 0;
- if(VBFlags & VB_CHRONTEL) {
+ if(VBFlags2 & VB2_CHRONTEL) {
switch(HDisplay)
{
- case 512:
+ case 512:
if(VGAEngine == SIS_315_VGA) {
if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
}
@@ -944,27 +754,27 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
break;
case 1024:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
}
break;
}
- } else if(VBFlags & VB_SISTVBRIDGE) {
+ } else if(VBFlags2 & VB2_SISTVBRIDGE) {
switch(HDisplay)
{
case 320:
- if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
+ if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
- break;
- case 400:
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
- break;
- case 512:
+ break;
+ case 400:
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ break;
+ case 512:
if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
- (VBFlags & TV_HIVISION) ||
- ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ (VBFlags & TV_HIVISION) ||
+ ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
}
break;
case 640:
@@ -973,34 +783,34 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
break;
case 720:
if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
- if(VDisplay == 480) {
- ModeIndex = ModeIndex_720x480[Depth];
- } else if(VDisplay == 576) {
+ if(VDisplay == 480) {
+ ModeIndex = ModeIndex_720x480[Depth];
+ } else if(VDisplay == 576) {
if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
- ModeIndex = ModeIndex_720x576[Depth];
- }
+ ModeIndex = ModeIndex_720x576[Depth];
+ }
}
break;
case 768:
if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
- if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+ if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
}
}
break;
case 800:
if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
else if(VDisplay == 480) {
- if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+ if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
ModeIndex = ModeIndex_800x480[Depth];
}
}
break;
case 960:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 600) {
+ if(VDisplay == 600) {
if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
ModeIndex = ModeIndex_960x600[Depth];
}
@@ -1009,25 +819,28 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
break;
case 1024:
if(VDisplay == 768) {
- if(VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) {
+ if(VBFlags2 & VB2_30xBLV) {
ModeIndex = ModeIndex_1024x768[Depth];
}
} else if(VDisplay == 576) {
- if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+ if( (VBFlags & TV_HIVISION) ||
+ ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
+ ((VBFlags2 & VB2_30xBLV) &&
+ ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
ModeIndex = ModeIndex_1024x576[Depth];
}
}
break;
case 1280:
if(VDisplay == 720) {
- if((VBFlags & TV_HIVISION) ||
+ if((VBFlags & TV_HIVISION) ||
((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
- ModeIndex = ModeIndex_1280x720[Depth];
+ ModeIndex = ModeIndex_1280x720[Depth];
}
} else if(VDisplay == 1024) {
- if((VBFlags & TV_HIVISION) ||
+ if((VBFlags & TV_HIVISION) ||
((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
- ModeIndex = ModeIndex_1280x1024[Depth];
+ ModeIndex = ModeIndex_1280x1024[Depth];
}
}
break;
@@ -1036,99 +849,31 @@ SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int D
return ModeIndex;
}
-USHORT
-SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth)
+unsigned short
+SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
+ unsigned int VBFlags2)
{
- USHORT ModeIndex = 0;
+ if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
- if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
+ if(HDisplay >= 1920) return 0;
switch(HDisplay)
{
- case 320:
- if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
- else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
- break;
- case 400:
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
- break;
- case 512:
- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
- break;
- case 640:
- if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
- else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
- break;
- case 720:
- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
- else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
- break;
- case 768:
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
- break;
- case 800:
- if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
- else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
- break;
- case 848:
- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
- break;
- case 856:
- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
- break;
- case 960:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
- else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
- }
- break;
- case 1024:
- if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
- else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
- break;
- case 1152:
- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
- else if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
- }
- break;
- case 1280:
- if(VDisplay == 768) {
- if(VGAEngine == SIS_300_VGA) {
- ModeIndex = ModeIndex_300_1280x768[Depth];
- } else {
- ModeIndex = ModeIndex_310_1280x768[Depth];
- }
- } else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
- else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
- else if(VDisplay == 800) ModeIndex = ModeIndex_1280x800[Depth];
- else if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
- break;
- case 1360:
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
- break;
- case 1400:
- if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
- }
- break;
case 1600:
- if(VGAEngine == SIS_315_VGA) {
- if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
- }
+ if(VDisplay == 1200) {
+ if(VGAEngine != SIS_315_VGA) return 0;
+ if(!(VBFlags2 & VB2_30xB)) return 0;
}
break;
case 1680:
- if(VGAEngine == SIS_315_VGA) {
- if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
- }
+ if(VDisplay == 1050) {
+ if(VGAEngine != SIS_315_VGA) return 0;
+ if(!(VBFlags2 & VB2_30xB)) return 0;
}
break;
}
- return ModeIndex;
+ return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, FALSE, 0, 0);
}
@@ -1137,83 +882,83 @@ SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int
/*********************************************/
void
-SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data)
+SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
{
- OutPortByte(port,index);
- OutPortByte(port + 1,data);
+ OutPortByte(port, index);
+ OutPortByte(port + 1, data);
}
void
-SiS_SetRegByte(SISIOADDRESS port, USHORT data)
+SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
{
- OutPortByte(port,data);
+ OutPortByte(port, data);
}
void
-SiS_SetRegShort(SISIOADDRESS port, USHORT data)
+SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
{
- OutPortWord(port,data);
+ OutPortWord(port, data);
}
void
-SiS_SetRegLong(SISIOADDRESS port, ULONG data)
+SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
{
- OutPortLong(port,data);
+ OutPortLong(port, data);
}
-UCHAR
-SiS_GetReg(SISIOADDRESS port, USHORT index)
+unsigned char
+SiS_GetReg(SISIOADDRESS port, unsigned short index)
{
- OutPortByte(port,index);
+ OutPortByte(port, index);
return(InPortByte(port + 1));
}
-UCHAR
+unsigned char
SiS_GetRegByte(SISIOADDRESS port)
{
return(InPortByte(port));
}
-USHORT
+unsigned short
SiS_GetRegShort(SISIOADDRESS port)
{
return(InPortWord(port));
}
-ULONG
+unsigned int
SiS_GetRegLong(SISIOADDRESS port)
{
return(InPortLong(port));
}
void
-SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR)
{
- USHORT temp;
+ unsigned short temp;
- temp = SiS_GetReg(Port,Index);
- temp = (temp & (DataAND)) | DataOR;
- SiS_SetReg(Port,Index,temp);
+ temp = SiS_GetReg(Port, Index);
+ temp = (temp & (DataAND)) | DataOR;
+ SiS_SetReg(Port, Index, temp);
}
void
-SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND)
+SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND)
{
- USHORT temp;
+ unsigned short temp;
- temp = SiS_GetReg(Port,Index);
- temp &= DataAND;
- SiS_SetReg(Port,Index,temp);
+ temp = SiS_GetReg(Port, Index);
+ temp &= DataAND;
+ SiS_SetReg(Port, Index, temp);
}
void
-SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
+SiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR)
{
- USHORT temp;
+ unsigned short temp;
- temp = SiS_GetReg(Port,Index);
- temp |= DataOR;
- SiS_SetReg(Port,Index,temp);
+ temp = SiS_GetReg(Port, Index);
+ temp |= DataOR;
+ SiS_SetReg(Port, Index, temp);
}
/*********************************************/
@@ -1221,13 +966,13 @@ SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
/*********************************************/
void
-SiS_DisplayOn(SiS_Private *SiS_Pr)
+SiS_DisplayOn(struct SiS_Private *SiS_Pr)
{
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
}
void
-SiS_DisplayOff(SiS_Private *SiS_Pr)
+SiS_DisplayOff(struct SiS_Private *SiS_Pr)
{
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
}
@@ -1238,7 +983,7 @@ SiS_DisplayOff(SiS_Private *SiS_Pr)
/*********************************************/
void
-SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
+SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
{
SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
@@ -1251,16 +996,17 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
+ SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
- SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* Digital video interface registers (LCD) */
- SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 TV Encoder registers */
- SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 Macrovision registers */
- SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
- SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
- SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; /* DDC Port ( = P3C4, SR11/0A) */
- SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
- SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
+ SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+ SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+ SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
+ SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
+ SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
+ SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;
+ SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
+ SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
}
/*********************************************/
@@ -1268,7 +1014,7 @@ SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
/*********************************************/
static void
-SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
{
unsigned char cr5f, temp1, temp2;
@@ -1276,9 +1022,9 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* (SR11 is used for DDC and in enable/disablebridge) */
SiS_Pr->SiS_SensibleSR11 = FALSE;
SiS_Pr->SiS_MyCR63 = 0x63;
- if(HwInfo->jChipType >= SIS_330) {
+ if(SiS_Pr->ChipType >= SIS_330) {
SiS_Pr->SiS_MyCR63 = 0x53;
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
SiS_Pr->SiS_SensibleSR11 = TRUE;
}
}
@@ -1286,43 +1032,52 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* You should use the macros, not these flags directly */
SiS_Pr->SiS_SysFlags = 0;
- if(HwInfo->jChipType == SIS_650) {
+ if(SiS_Pr->ChipType == SIS_650) {
cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
if((!temp1) || (temp2)) {
- switch(cr5f) {
+ switch(cr5f) {
case 0x80:
case 0x90:
case 0xc0:
- SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+ SiS_Pr->SiS_SysFlags |= SF_IsM650;
+ break;
case 0xa0:
case 0xb0:
case 0xe0:
- SiS_Pr->SiS_SysFlags |= SF_Is651; break;
+ SiS_Pr->SiS_SysFlags |= SF_Is651;
+ break;
}
} else {
- switch(cr5f) {
+ switch(cr5f) {
case 0x90:
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
switch(temp1) {
- case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
+ case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
}
break;
case 0xb0:
- SiS_Pr->SiS_SysFlags |= SF_Is652; break;
+ SiS_Pr->SiS_SysFlags |= SF_Is652;
+ break;
default:
- SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+ SiS_Pr->SiS_SysFlags |= SF_IsM650;
+ break;
}
}
}
- if(HwInfo->jChipType == SIS_760) {
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78);
- if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB;
+
+ if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
+ SiS_Pr->SiS_SysFlags |= SF_760LFB;
+ }
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
+ SiS_Pr->SiS_SysFlags |= SF_760UMA;
+ }
}
}
@@ -1331,18 +1086,20 @@ SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSInitPCIetc(struct SiS_Private *SiS_Pr)
{
- switch(HwInfo->jChipType) {
+ switch(SiS_Pr->ChipType) {
+#ifdef SIS300
case SIS_300:
case SIS_540:
case SIS_630:
case SIS_730:
/* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
- * - RELOCATED VGA IO (0x20)
- * - MMIO ENABLE (0x1)
+ * - RELOCATED VGA IO ENABLED (0x20)
+ * - MMIO ENABLED (0x01)
+ * Leave other bits untouched.
*/
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
/* - Enable 2D (0x40)
* - Enable 3D (0x02)
* - Enable 3D Vertex command fetch (0x10) ?
@@ -1350,6 +1107,8 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
*/
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
break;
+#endif
+#ifdef SIS315H
case SIS_315H:
case SIS_315:
case SIS_315PRO:
@@ -1362,21 +1121,30 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
case SIS_760:
case SIS_761:
case SIS_340:
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
- /* - Enable 2D (0x40)
- * - Enable 3D (0x02)
+ case XGI_40:
+ /* See above */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* - Enable 3D G/L transformation engine (0x80)
+ * - Enable 2D (0x40)
* - Enable 3D vertex command fetch (0x10)
* - Enable 3D command parser (0x08)
- * - Enable 3D G/L transformation engine (0x80)
+ * - Enable 3D (0x02)
*/
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
break;
+ case XGI_20:
case SIS_550:
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* See above */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
/* No 3D engine ! */
/* - Enable 2D (0x40)
+ * - disable 3D
*/
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x40);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
+ break;
+#endif
+ default:
+ break;
}
}
@@ -1384,38 +1152,40 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* HELPER: SetLVDSetc */
/*********************************************/
-static void
-SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
SiS_Pr->SiS_IF_DEF_LVDS = 0;
SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
SiS_Pr->SiS_IF_DEF_CH70xx = 0;
- SiS_Pr->SiS_IF_DEF_DSTN = 0;
- SiS_Pr->SiS_IF_DEF_FSTN = 0;
SiS_Pr->SiS_IF_DEF_CONEX = 0;
SiS_Pr->SiS_ChrontelInit = 0;
+ if(SiS_Pr->ChipType == XGI_20) return;
+
/* Check for SiS30x first */
temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
if((temp == 1) || (temp == 2)) return;
- switch(HwInfo->jChipType) {
+ switch(SiS_Pr->ChipType) {
#ifdef SIS300
case SIS_540:
case SIS_630:
case SIS_730:
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
- temp = (temp & 0x0E) >> 1;
- if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
- if((temp == 4) || (temp == 5)) {
+ temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
+ if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+ if((temp == 4) || (temp == 5)) {
/* Save power status (and error check) - UNUSED */
SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
SiS_Pr->SiS_IF_DEF_CH70xx = 1;
- }
+ }
break;
#endif
#ifdef SIS315H
@@ -1423,26 +1193,26 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
case SIS_650:
case SIS_740:
case SIS_330:
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
- temp = (temp & 0x0E) >> 1;
- if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
- break;
+ temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
+ if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+ break;
case SIS_661:
case SIS_741:
case SIS_660:
case SIS_760:
case SIS_761:
case SIS_340:
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- temp = (temp & 0xe0) >> 5;
- if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
- if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
- break;
+ case XGI_20:
+ case XGI_40:
+ temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
+ if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+ if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
+ break;
#endif
default:
- break;
+ break;
}
}
@@ -1451,35 +1221,55 @@ SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
void
-SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
+SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
{
SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
}
void
-SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
+SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
{
SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
}
/*********************************************/
+/* HELPER: Get modeflag */
+/*********************************************/
+
+unsigned short
+SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
+{
+ if(SiS_Pr->UseCustomMode) {
+ return SiS_Pr->CModeFlag;
+ } else if(ModeNo <= 0x13) {
+ return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+}
+
+/*********************************************/
/* HELPER: Determine ROM usage */
/*********************************************/
BOOLEAN
-SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romversoffs, romvmaj = 1, romvmin = 0;
-
- if(HwInfo->jChipType >= SIS_761) {
- /* I very much assume 761 and 340 will use new layout */
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romversoffs, romvmaj = 1, romvmin = 0;
+
+ if(SiS_Pr->ChipType >= XGI_20) {
+ /* XGI ROMs don't qualify */
+ return FALSE;
+ } else if(SiS_Pr->ChipType >= SIS_761) {
+ /* I very much assume 761, 340 and newer will use new layout */
return TRUE;
- } else if(HwInfo->jChipType >= SIS_661) {
+ } else if(SiS_Pr->ChipType >= SIS_661) {
if((ROMAddr[0x1a] == 'N') &&
- (ROMAddr[0x1b] == 'e') &&
- (ROMAddr[0x1c] == 'w') &&
- (ROMAddr[0x1d] == 'V')) {
+ (ROMAddr[0x1b] == 'e') &&
+ (ROMAddr[0x1c] == 'w') &&
+ (ROMAddr[0x1d] == 'V')) {
return TRUE;
}
romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
@@ -1494,9 +1284,9 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
} else if(IS_SIS650740) {
if((ROMAddr[0x1a] == 'N') &&
- (ROMAddr[0x1b] == 'e') &&
- (ROMAddr[0x1c] == 'w') &&
- (ROMAddr[0x1d] == 'V')) {
+ (ROMAddr[0x1b] == 'e') &&
+ (ROMAddr[0x1c] == 'w') &&
+ (ROMAddr[0x1d] == 'V')) {
return TRUE;
}
}
@@ -1504,45 +1294,50 @@ SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
static void
-SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr = 0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr = 0;
SiS_Pr->SiS_UseROM = FALSE;
SiS_Pr->SiS_ROMNew = FALSE;
+ SiS_Pr->SiS_PWDOffset = 0;
- if((ROMAddr) && (HwInfo->UseROM)) {
- if(HwInfo->jChipType == SIS_300) {
- /* 300: We check if the code starts below 0x220 by
+ if(SiS_Pr->ChipType >= XGI_20) return;
+
+ if((ROMAddr) && (SiS_Pr->UseROM)) {
+ if(SiS_Pr->ChipType == SIS_300) {
+ /* 300: We check if the code starts below 0x220 by
* checking the jmp instruction at the beginning
* of the BIOS image.
*/
if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
SiS_Pr->SiS_UseROM = TRUE;
- } else if(HwInfo->jChipType < SIS_315H) {
+ } else if(SiS_Pr->ChipType < SIS_315H) {
/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
* the others do as well
*/
SiS_Pr->SiS_UseROM = TRUE;
} else {
- /* 315/330 series stick to the standard(s) */
+ /* 315/330 series stick to the standard(s) */
SiS_Pr->SiS_UseROM = TRUE;
- if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+ if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
SiS_Pr->SiS_EMIOffset = 14;
+ SiS_Pr->SiS_PWDOffset = 17;
SiS_Pr->SiS661LCD2TableSize = 36;
/* Find out about LCD data table entry size */
if((romptr = SISGETROMW(0x0102))) {
if(ROMAddr[romptr + (32 * 16)] == 0xff)
- SiS_Pr->SiS661LCD2TableSize = 32;
+ SiS_Pr->SiS661LCD2TableSize = 32;
else if(ROMAddr[romptr + (34 * 16)] == 0xff)
- SiS_Pr->SiS661LCD2TableSize = 34;
- else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94 */
- SiS_Pr->SiS661LCD2TableSize = 36;
+ SiS_Pr->SiS661LCD2TableSize = 34;
+ else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */
+ SiS_Pr->SiS661LCD2TableSize = 36;
else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */
- (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00+ */
- SiS_Pr->SiS661LCD2TableSize = 38;
+ (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */
+ SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */
SiS_Pr->SiS_EMIOffset = 16;
+ SiS_Pr->SiS_PWDOffset = 19;
}
}
}
@@ -1555,9 +1350,9 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
{
- USHORT temp;
+ unsigned short temp;
value &= 0x00ff;
temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
@@ -1569,9 +1364,9 @@ SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
}
static void
-SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
{
- USHORT temp;
+ unsigned short temp;
value &= 0x00ff;
temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
@@ -1583,22 +1378,22 @@ SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
}
static void
-SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
{
SiS_SetSegRegLower(SiS_Pr, value);
SiS_SetSegRegUpper(SiS_Pr, value);
}
static void
-SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
+SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
{
SiS_SetSegmentReg(SiS_Pr, 0);
}
static void
-SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
+SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
{
- USHORT temp = value >> 8;
+ unsigned short temp = value >> 8;
temp &= 0x07;
temp |= (temp << 4);
@@ -1607,15 +1402,15 @@ SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
}
static void
-SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
+SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
{
SiS_SetSegmentRegOver(SiS_Pr, 0);
}
static void
-SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
+SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
{
- if((IS_SIS65x) || (HwInfo->jChipType >= SIS_661)) {
+ if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
SiS_ResetSegmentReg(SiS_Pr);
SiS_ResetSegmentRegOver(SiS_Pr);
}
@@ -1625,89 +1420,86 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
/* HELPER: GetVBType */
/*********************************************/
-static void
-SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_GetVBType(struct SiS_Private *SiS_Pr)
{
- USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
-
- SiS_Pr->SiS_VBType = 0;
-
- if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
- return;
-
- flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
-
- if(flag > 3) return;
-
- rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
-
- if(flag >= 2) {
- SiS_Pr->SiS_VBType = VB_SIS302B;
- } else if(flag == 1) {
- if(rev >= 0xC0) {
- SiS_Pr->SiS_VBType = VB_SIS301C;
- } else if(rev >= 0xB0) {
- SiS_Pr->SiS_VBType = VB_SIS301B;
- /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
- nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
- if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
- } else {
- SiS_Pr->SiS_VBType = VB_SIS301;
- }
- }
- if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
- if(rev >= 0xE0) {
- flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
- if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
- else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
- } else if(rev >= 0xD0) {
- SiS_Pr->SiS_VBType = VB_SIS301LV;
- }
- }
- if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
- p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
- p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
- p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
- if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
- SiS_Pr->SiS_VBType |= VB_UMC;
- }
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
- }
+ unsigned short flag = 0, rev = 0, nolcd = 0;
+ unsigned short p4_0f, p4_25, p4_27;
+
+ SiS_Pr->SiS_VBType = 0;
+
+ if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
+ return;
+
+ if(SiS_Pr->ChipType == XGI_20)
+ return;
+
+ flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+
+ if(flag > 3)
+ return;
+
+ rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+
+ if(flag >= 2) {
+ SiS_Pr->SiS_VBType = VB_SIS302B;
+ } else if(flag == 1) {
+ if(rev >= 0xC0) {
+ SiS_Pr->SiS_VBType = VB_SIS301C;
+ } else if(rev >= 0xB0) {
+ SiS_Pr->SiS_VBType = VB_SIS301B;
+ /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+ nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
+ if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+ } else {
+ SiS_Pr->SiS_VBType = VB_SIS301;
+ }
+ }
+ if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
+ if(rev >= 0xE0) {
+ flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
+ if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
+ else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
+ } else if(rev >= 0xD0) {
+ SiS_Pr->SiS_VBType = VB_SIS301LV;
+ }
+ }
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+ p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
+ p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
+ p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
+ if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
+ SiS_Pr->SiS_VBType |= VB_UMC;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
+ }
}
/*********************************************/
/* HELPER: Check RAM size */
/*********************************************/
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
static BOOLEAN
-SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
+SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
{
- USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024);
- USHORT memorysize,modeflag;
-
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
- }
-
- memorysize = modeflag & MemoryInfoFlag;
- memorysize >>= MemorySizeShift; /* Get required memory size */
- memorysize++;
-
- if(AdapterMemSize < memorysize) return FALSE;
- return TRUE;
+ unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
+ unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+ unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
+
+ if(!AdapterMemSize) return TRUE;
+
+ if(AdapterMemSize < memorysize) return FALSE;
+ return TRUE;
}
#endif
@@ -1716,63 +1508,65 @@ SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/*********************************************/
#ifdef SIS315H
-static UCHAR
-SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned char
+SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
{
- UCHAR data, temp;
+ unsigned char data;
if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
- data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
+ data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
} else {
- if(HwInfo->jChipType >= SIS_340) {
- /* TODO */
- data = 0;
- } if(HwInfo->jChipType >= SIS_661) {
- data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
- if(SiS_Pr->SiS_ROMNew) {
- data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
- }
- } else if(IS_SIS550650740) {
- data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
- } else { /* 315, 330 */
- data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
- if(HwInfo->jChipType == SIS_330) {
- if(data > 1) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
- switch(temp) {
- case 0x00: data = 1; break;
- case 0x10: data = 3; break;
- case 0x20: data = 3; break;
- case 0x30: data = 2; break;
- }
- } else {
- data = 0;
- }
- }
- }
+ if(SiS_Pr->ChipType >= XGI_20) {
+ /* Do I need this? SR17 seems to be zero anyway... */
+ data = 0;
+ } else if(SiS_Pr->ChipType >= SIS_340) {
+ /* TODO */
+ data = 0;
+ } if(SiS_Pr->ChipType >= SIS_661) {
+ if(SiS_Pr->SiS_ROMNew) {
+ data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
+ } else {
+ data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
+ }
+ } else if(IS_SIS550650740) {
+ data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+ } else { /* 315, 330 */
+ data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+ if(SiS_Pr->ChipType == SIS_330) {
+ if(data > 1) {
+ switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
+ case 0x00: data = 1; break;
+ case 0x10: data = 3; break;
+ case 0x20: data = 3; break;
+ case 0x30: data = 2; break;
+ }
+ } else {
+ data = 0;
+ }
+ }
+ }
}
return data;
}
-static USHORT
-SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+SiS_GetMCLK(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index;
-
- index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
- if(HwInfo->jChipType >= SIS_661) {
- if(SiS_Pr->SiS_ROMNew) {
- return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3))));
- }
- return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
- } else if(index >= 4) {
- index -= 4;
- return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
- } else {
- return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
- }
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index;
+
+ index = SiS_Get310DRAMType(SiS_Pr);
+ if(SiS_Pr->ChipType >= SIS_661) {
+ if(SiS_Pr->SiS_ROMNew) {
+ return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
+ }
+ return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+ } else if(index >= 4) {
+ return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
+ } else {
+ return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+ }
}
#endif
@@ -1780,30 +1574,30 @@ SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* HELPER: ClearBuffer */
/*********************************************/
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
static void
-SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- UCHAR SISIOMEMTYPE *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
- ULONG AdapterMemorySize = HwInfo->ulVideoMemorySize;
- USHORT SISIOMEMTYPE *pBuffer;
- int i;
-
- if(SiS_Pr->SiS_ModeType >= ModeEGA) {
- if(ModeNo > 0x13) {
- SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
- } else {
- pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
- for(i=0; i<0x4000; i++) writew(0x0000, &pBuffer[i]);
- }
- } else {
- if(SiS_Pr->SiS_ModeType < ModeCGA) {
- pBuffer = (USHORT SISIOMEMTYPE *)VideoMemoryAddress;
- for(i=0; i<0x4000; i++) writew(0x0720, &pBuffer[i]);
- } else {
- SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
- }
- }
+ unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
+ unsigned int memsize = SiS_Pr->VideoMemorySize;
+ unsigned short SISIOMEMTYPE *pBuffer;
+ int i;
+
+ if(!memaddr || !memsize) return;
+
+ if(SiS_Pr->SiS_ModeType >= ModeEGA) {
+ if(ModeNo > 0x13) {
+ SiS_SetMemory(memaddr, memsize, 0);
+ } else {
+ pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
+ for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
+ }
+ } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
+ pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
+ for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
+ } else {
+ SiS_SetMemory(memaddr, 0x8000, 0);
+ }
}
#endif
@@ -1812,35 +1606,36 @@ SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
/*********************************************/
BOOLEAN
-SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
+SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+ unsigned short *ModeIdIndex)
{
- UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+ unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
- if(*ModeNo <= 0x13) {
+ if((*ModeNo) <= 0x13) {
if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
- for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
- if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
- if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) return FALSE;
+ for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
+ if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
+ if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE;
}
- if(*ModeNo == 0x07) {
- if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
- /* else 350 lines */
+ if((*ModeNo) == 0x07) {
+ if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
+ /* else 350 lines */
}
- if(*ModeNo <= 0x03) {
- if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
- if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
- /* else 350 lines */
+ if((*ModeNo) <= 0x03) {
+ if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
+ if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */
+ /* else 350 lines */
}
/* else 200 lines */
} else {
- for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
- if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
- if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return FALSE;
+ for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
+ if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
+ if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE;
}
}
@@ -1851,10 +1646,10 @@ SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
/* HELPER: GetModePtr */
/*********************************************/
-UCHAR
-SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+unsigned short
+SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR index;
+ unsigned short index;
if(ModeNo <= 0x13) {
index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
@@ -1866,79 +1661,125 @@ SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
}
/*********************************************/
+/* HELPERS: Get some indices */
+/*********************************************/
+
+unsigned short
+SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
+{
+ if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
+ if(UseWide == 1) {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
+ } else {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
+ }
+ } else {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
+ }
+}
+
+unsigned short
+SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
+{
+ if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
+ if(UseWide == 1) {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
+ } else {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
+ }
+ } else {
+ return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
+ }
+}
+
+/*********************************************/
/* HELPER: LowModeTests */
/*********************************************/
static BOOLEAN
-SiS_DoLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- USHORT temp,temp1,temp2;
-
- if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
- return(TRUE);
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
- temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
- if((HwInfo->jChipType >= SIS_315H) ||
- (HwInfo->jChipType == SIS_300)) {
- if(temp2 == 0x55) return(FALSE);
- else return(TRUE);
- } else {
- if(temp2 != 0x55) return(TRUE);
- else {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
- return(FALSE);
- }
- }
+ unsigned short temp, temp1, temp2;
+
+ if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+ return TRUE;
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
+ temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
+ if((SiS_Pr->ChipType >= SIS_315H) ||
+ (SiS_Pr->ChipType == SIS_300)) {
+ if(temp2 == 0x55) return FALSE;
+ else return TRUE;
+ } else {
+ if(temp2 != 0x55) return TRUE;
+ else {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+ return FALSE;
+ }
+ }
}
static void
-SiS_SetLowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- if(SiS_DoLowModeTest(SiS_Pr, ModeNo, HwInfo)) {
- SiS_Pr->SiS_SetFlag |= LowModeTests;
- }
+ if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
+ SiS_Pr->SiS_SetFlag |= LowModeTests;
+ }
}
/*********************************************/
-/* HELPER: ENABLE CRT1 */
+/* HELPER: OPEN/CLOSE CRT1 CRTC */
/*********************************************/
static void
-SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_OpenCRTC(struct SiS_Private *SiS_Pr)
+{
+ if(IS_SIS650) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ } else if(IS_SIS661741660760) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ if(!SiS_Pr->SiS_ROMNew) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+ }
+ }
+}
+
+static void
+SiS_CloseCRTC(struct SiS_Private *SiS_Pr)
{
- if(IS_SIS650) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- }
- } else if(IS_SIS661741660760) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- if(!SiS_Pr->SiS_ROMNew) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
- }
- }
+#if 0 /* This locks some CRTC registers. We don't want that. */
+ unsigned short temp1 = 0, temp2 = 0;
+
+ if(IS_SIS661741660760) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ temp1 = 0xa0; temp2 = 0x08;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
+ }
+#endif
}
static void
-SiS_HandleCRT1(SiS_Private *SiS_Pr)
+SiS_HandleCRT1(struct SiS_Private *SiS_Pr)
{
- /* Enable CRT1 gating */
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
+ /* Enable CRT1 gating */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
#if 0
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
- if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
- (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
- }
- }
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+ if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+ (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
+ }
+ }
#endif
}
@@ -1946,57 +1787,54 @@ SiS_HandleCRT1(SiS_Private *SiS_Pr)
/* HELPER: GetColorDepth */
/*********************************************/
-USHORT
-SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
+unsigned short
+SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
{
- USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
- SHORT index;
- USHORT modeflag;
-
- /* Do NOT check UseCustomMode, will skrew up FIFO */
- if(ModeNo == 0xfe) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- if(ModeNo <= 0x13)
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- else
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- index = (modeflag & ModeTypeMask) - ModeEGA;
- if(index < 0) index = 0;
- return(ColorDepth[index]);
+ static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+ unsigned short modeflag;
+ short index;
+
+ /* Do NOT check UseCustomMode, will skrew up FIFO */
+ if(ModeNo == 0xfe) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ index = (modeflag & ModeTypeMask) - ModeEGA;
+ if(index < 0) index = 0;
+ return ColorDepth[index];
}
/*********************************************/
/* HELPER: GetOffset */
/*********************************************/
-USHORT
-SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
- USHORT xres, temp, colordepth, infoflag;
-
- if(SiS_Pr->UseCustomMode) {
- infoflag = SiS_Pr->CInfoFlag;
- xres = SiS_Pr->CHDisplay;
- } else {
- infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
- }
-
- colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
-
- temp = xres / 16;
- if(infoflag & InterlaceMode) temp <<= 1;
- temp *= colordepth;
- if(xres % 16) {
- colordepth >>= 1;
- temp += colordepth;
- }
-
- return(temp);
+ unsigned short xres, temp, colordepth, infoflag;
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ xres = SiS_Pr->CHDisplay;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
+ xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
+ }
+
+ colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
+
+ temp = xres / 16;
+ if(infoflag & InterlaceMode) temp <<= 1;
+ temp *= colordepth;
+ if(xres % 16) temp += (colordepth >> 1);
+
+ return temp;
}
/*********************************************/
@@ -2004,55 +1842,29 @@ SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
{
- UCHAR SRdata;
- USHORT i;
+ unsigned char SRdata;
+ int i;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); /* Set SR0 */
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
- SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
+ /* or "display off" */
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SRdata |= 0x01;
- }
- if(HwInfo->jChipType >= SIS_661) {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SRdata |= 0x01; /* 8 dot clock */
- }
- }
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_VBType & VB_NoLCD) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SRdata |= 0x01; /* 8 dot clock */
- }
- }
- }
- }
+ /* determine whether to force x8 dotclock */
+ if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SRdata |= 0x01; /* 8 dot clock */
- }
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SRdata |= 0x01; /* 8 dot clock */
- }
- }
- }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01;
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
- SRdata |= 0x20; /* screen off */
+ }
SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
for(i = 2; i <= 4; i++) {
- SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+ SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
}
}
@@ -2062,17 +1874,17 @@ SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
{
- UCHAR Miscdata;
+ unsigned char Miscdata;
Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
- if(HwInfo->jChipType < SIS_661) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- Miscdata |= 0x0C;
- }
+ if(SiS_Pr->ChipType < SIS_661) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ Miscdata |= 0x0C;
+ }
}
}
@@ -2084,33 +1896,34 @@ SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex, PSIS_HW_INFO HwInfo
/*********************************************/
static void
-SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT StandTableIndex)
+SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
{
- UCHAR CRTCdata;
- USHORT i;
-
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* Unlock CRTC */
-
- for(i = 0; i <= 0x18; i++) {
- CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */
- }
- if(HwInfo->jChipType >= SIS_661) {
- SiS_SetupCR5x(SiS_Pr, HwInfo);
- for(i = 0x13; i <= 0x14; i++) {
- CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
- }
- } else if( ( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) &&
- (HwInfo->jChipRevision >= 0x30) ) { /* for 630S0 */
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
- }
- }
- }
+ unsigned char CRTCdata;
+ unsigned short i;
+
+ /* Unlock CRTC */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+ for(i = 0; i <= 0x18; i++) {
+ CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+ SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+ }
+
+ if(SiS_Pr->ChipType >= SIS_661) {
+ SiS_OpenCRTC(SiS_Pr);
+ for(i = 0x13; i <= 0x14; i++) {
+ CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+ SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+ }
+ } else if( ( (SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730) ) &&
+ (SiS_Pr->ChipRevision >= 0x30) ) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
+ }
+ }
+ }
}
/*********************************************/
@@ -2118,64 +1931,58 @@ SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/*********************************************/
static void
-SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
{
- UCHAR ARdata;
- USHORT i;
+ unsigned char ARdata;
+ unsigned short i;
for(i = 0; i <= 0x13; i++) {
ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
-#if 0
- if((i <= 0x0f) || (i == 0x11)) {
- if(ds:489 & 0x08) {
- continue;
- }
- }
-#endif
+
if(i == 0x13) {
- /* Pixel shift. If screen on LCD or TV is shifted left or right,
- * this might be the cause.
- */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata=0;
- }
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
- }
- }
- }
- if(HwInfo->jChipType >= SIS_661) {
+ /* Pixel shift. If screen on LCD or TV is shifted left or right,
+ * this might be the cause.
+ */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
+ }
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
+ }
+ }
+ }
+ if(SiS_Pr->ChipType >= SIS_661) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(IS_SIS550650740660) {
- /* 315, 330 don't do this */
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
- } else {
- ARdata = 0;
- }
+ /* 315, 330 don't do this */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
+ } else {
+ ARdata = 0;
+ }
}
} else {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
}
- }
+ }
}
- SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
- SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */
- SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */
+ SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */
}
- SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
- SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */
- SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */
+
+ SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */
SiS_GetRegByte(SiS_Pr->SiS_P3da);
- SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */
SiS_GetRegByte(SiS_Pr->SiS_P3da);
}
@@ -2184,10 +1991,10 @@ SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
/*********************************************/
static void
-SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
{
- UCHAR GRdata;
- USHORT i;
+ unsigned char GRdata;
+ unsigned short i;
for(i = 0; i <= 0x08; i++) {
GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
@@ -2205,22 +2012,22 @@ SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
/*********************************************/
static void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- USHORT i;
+ unsigned short i;
- for(i = 0x0A; i <= 0x0E; i++) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
- }
+ for(i = 0x0A; i <= 0x0E; i++) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
+ }
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
- if(ModeNo <= 0x13) {
- if(ModeNo == 0x06 || ModeNo >= 0x0e) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
- }
- }
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+ if(ModeNo <= 0x13) {
+ if(ModeNo == 0x06 || ModeNo >= 0x0e) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
+ }
+ }
+ }
}
/*********************************************/
@@ -2228,32 +2035,24 @@ SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
/*********************************************/
static void
-SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
{
- if(HwInfo->jChipType >= SIS_315H) {
- if(HwInfo->jChipType < SIS_661) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_661) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
}
} else {
if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
- (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+ (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
return;
}
}
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
@@ -2264,19 +2063,19 @@ SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
+SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
{
- USHORT sync;
+ unsigned short sync;
- if(SiS_Pr->UseCustomMode) {
- sync = SiS_Pr->CInfoFlag >> 8;
- } else {
- sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
- }
+ if(SiS_Pr->UseCustomMode) {
+ sync = SiS_Pr->CInfoFlag >> 8;
+ } else {
+ sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
+ }
- sync &= 0xC0;
- sync |= 0x2f;
- SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
+ sync &= 0xC0;
+ sync |= 0x2f;
+ SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
}
/*********************************************/
@@ -2284,72 +2083,67 @@ SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
/*********************************************/
static void
-SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
- UCHAR index;
- USHORT temp,i,j,modeflag;
-
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* unlock cr0-7 */
-
- if(SiS_Pr->UseCustomMode) {
-
- modeflag = SiS_Pr->CModeFlag;
-
- for(i=0,j=0;i<=7;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
- }
- for(j=0x10;i<=10;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
- }
- for(j=0x15;i<=12;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
- }
- for(j=0x0A;i<=15;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
- }
-
- temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
- temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
-
- } else {
-
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- for(i=0,j=0;i<=7;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x10;i<=10;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x15;i<=12;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x0A;i<=15;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
-
- temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
- temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
-
- }
-
- if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
+ unsigned short temp, i, j, modeflag;
+ unsigned char *crt1data = NULL;
+
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if(SiS_Pr->UseCustomMode) {
+
+ crt1data = &SiS_Pr->CCRT1CRTC[0];
+
+ } else {
+
+ temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
+
+ /* Alternate for 1600x1200 LCDA */
+ if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
+
+ crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
+
+ }
+
+ /* unlock cr0-7 */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+ for(i = 0, j = 0; i <= 7; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+ }
+ for(j = 0x10; i <= 10; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+ }
+ for(j = 0x15; i <= 12; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
+ }
+ for(j = 0x0A; i <= 15; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
+ }
+
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
+
+ temp = (crt1data[16] & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
+
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
+ }
+
+#ifdef SIS315H
+ if(SiS_Pr->ChipType == XGI_20) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
+ if(!(temp = crt1data[5] & 0x1f)) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
+ temp = (crt1data[16] >> 5) + 3;
+ if(temp > 7) temp -= 7;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
+ }
+#endif
}
/*********************************************/
@@ -2359,33 +2153,32 @@ SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
- USHORT temp, DisplayUnit, infoflag;
+ unsigned short temp, DisplayUnit, infoflag;
if(SiS_Pr->UseCustomMode) {
infoflag = SiS_Pr->CInfoFlag;
} else {
- infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
}
- DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
+ DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
temp = (DisplayUnit >> 8) & 0x0f;
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
- temp = DisplayUnit & 0xFF;
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
if(infoflag & InterlaceMode) DisplayUnit >>= 1;
DisplayUnit <<= 5;
- temp = (DisplayUnit & 0xff00) >> 8;
+ temp = (DisplayUnit >> 8) + 1;
if(DisplayUnit & 0xff) temp++;
- temp++;
+ if(SiS_Pr->ChipType == XGI_20) {
+ if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
+ }
SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
}
@@ -2394,39 +2187,49 @@ SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
- USHORT index=0, clka, clkb;
-
- if(SiS_Pr->UseCustomMode) {
- clka = SiS_Pr->CSR2B;
- clkb = SiS_Pr->CSR2C;
- } else {
- index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
- clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
- } else {
- clka = SiS_Pr->SiS_VCLKData[index].SR2B;
- clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
- }
- }
-
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
- }
-
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,clka);
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,clkb);
-
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
- }
+ unsigned short index = 0, clka, clkb;
+
+ if(SiS_Pr->UseCustomMode) {
+ clka = SiS_Pr->CSR2B;
+ clkb = SiS_Pr->CSR2C;
+ } else {
+ index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
+ if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ /* Alternate for 1600x1200 LCDA */
+ if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
+ clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
+ clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
+ } else {
+ clka = SiS_Pr->SiS_VCLKData[index].SR2B;
+ clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
+ }
+ }
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
+
+ if(SiS_Pr->ChipType >= SIS_315H) {
+#ifdef SIS315H
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
+ if(SiS_Pr->ChipType == XGI_20) {
+ unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+ if(mf & HalfDCLK) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
+ clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
+ clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
+ }
+ }
+#endif
+ } else {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
+ }
}
/*********************************************/
@@ -2434,415 +2237,358 @@ SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
#ifdef SIS300
-static USHORT
-SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
+void
+SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
+ unsigned short *idx2)
+{
+ unsigned short temp1, temp2;
+ static const unsigned char ThTiming[8] = {
+ 1, 2, 2, 3, 0, 1, 1, 2
+ };
+
+ temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
+ (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
+ (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
+ (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
+ (*idx1) <<= 1;
+}
+
+static unsigned short
+SiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
+{
+ static const unsigned char ThLowA[8 * 3] = {
+ 61, 3,52, 5,68, 7,100,11,
+ 43, 3,42, 5,54, 7, 78,11,
+ 34, 3,37, 5,47, 7, 67,11
+ };
+
+ return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
+}
+
+unsigned short
+SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
+{
+ static const unsigned char ThLowB[8 * 3] = {
+ 81, 4,72, 6,88, 8,120,12,
+ 55, 4,54, 6,66, 8, 90,12,
+ 42, 4,45, 6,55, 8, 75,12
+ };
+
+ return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
+}
+
+static unsigned short
+SiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
+ unsigned short colordepth, unsigned short key)
{
- const UCHAR ThLowA[] = { 61, 3,52, 5,68, 7,100,11,
- 43, 3,42, 5,54, 7, 78,11,
- 34, 3,37, 5,47, 7, 67,11 };
-
- const UCHAR ThLowB[] = { 81, 4,72, 6,88, 8,120,12,
- 55, 4,54, 6,66, 8, 90,12,
- 42, 4,45, 6,55, 8, 75,12 };
-
- const UCHAR ThTiming[] = { 1, 2, 2, 3, 0, 1, 1, 2 };
-
- USHORT tempah, tempal, tempcl, tempbx, temp;
- ULONG longtemp;
-
- tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
- tempah &= 0x62;
- tempah >>= 1;
- tempal = tempah;
- tempah >>= 3;
- tempal |= tempah;
- tempal &= 0x07;
- tempcl = ThTiming[tempal];
- tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
- tempbx >>= 6;
- tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- tempah >>= 4;
- tempah &= 0x0c;
- tempbx |= tempah;
- tempbx <<= 1;
- if(key == 0) {
- tempal = ThLowA[tempbx + 1];
- tempal *= tempcl;
- tempal += ThLowA[tempbx];
- } else {
- tempal = ThLowB[tempbx + 1];
- tempal *= tempcl;
- tempal += ThLowB[tempbx];
- }
- longtemp = tempal * VCLK * colordepth;
- temp = longtemp % (MCLK * 16);
- longtemp /= (MCLK * 16);
- if(temp) longtemp++;
- return((USHORT)longtemp);
+ unsigned short idx1, idx2;
+ unsigned int longtemp = VCLK * colordepth;
+
+ SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
+
+ if(key == 0) {
+ longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
+ } else {
+ longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
+ }
+ idx1 = longtemp % (MCLK * 16);
+ longtemp /= (MCLK * 16);
+ if(idx1) longtemp++;
+ return (unsigned short)longtemp;
}
-static USHORT
-SiS_CalcDelay(SiS_Private *SiS_Pr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
+static unsigned short
+SiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
+ unsigned short colordepth, unsigned short MCLK)
{
- USHORT tempax, tempbx;
-
- tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
- tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
- if(tempax < 4) tempax = 4;
- tempax -= 4;
- if(tempbx < tempax) tempbx = tempax;
- return(tempbx);
+ unsigned short temp1, temp2;
+
+ temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
+ temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
+ if(temp1 < 4) temp1 = 4;
+ temp1 -= 4;
+ if(temp2 < temp1) temp2 = temp1;
+ return temp2;
}
static void
-SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo,
- USHORT RefreshRateTableIndex)
+SiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short ThresholdLow = 0;
+ unsigned short temp, index, VCLK, MCLK, colorth;
+ static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
+
+ if(ModeNo > 0x13) {
+
+ /* Get VCLK */
+ if(SiS_Pr->UseCustomMode) {
+ VCLK = SiS_Pr->CSRClock;
+ } else {
+ index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+
+ /* Get half colordepth */
+ colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
+
+ /* Get MCLK */
+ index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
+ MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
+
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
+
+ do {
+ ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
+ if(ThresholdLow < 0x13) break;
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
+ ThresholdLow = 0x13;
+ temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
+ if(!temp) break;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
+ } while(0);
+
+ } else ThresholdLow = 2;
+
+ /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+ temp = (ThresholdLow << 4) | 0x0f;
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
+
+ temp = (ThresholdLow & 0x10) << 1;
+ if(ModeNo > 0x13) temp |= 0x40;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
+
+ /* What is this? */
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
+
+ /* Write CRT/CPU threshold high */
+ temp = ThresholdLow + 3;
+ if(temp > 0x0f) temp = 0x0f;
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
+}
+
+unsigned short
+SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
{
- USHORT ThresholdLow = 0;
- USHORT index, VCLK, MCLK, colorth=0;
- USHORT tempah, temp;
-
- if(ModeNo > 0x13) {
-
- if(SiS_Pr->UseCustomMode) {
- VCLK = SiS_Pr->CSRClock;
- } else {
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- index &= 0x3F;
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
- }
-
- switch (SiS_Pr->SiS_ModeType - ModeEGA) { /* Get half colordepth */
- case 0 : colorth = 1; break;
- case 1 : colorth = 1; break;
- case 2 : colorth = 2; break;
- case 3 : colorth = 2; break;
- case 4 : colorth = 3; break;
- case 5 : colorth = 4; break;
- }
-
- index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
- index &= 0x07;
- MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
-
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- tempah &= 0xc3;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
-
- do {
- ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK);
- ThresholdLow++;
- if(ThresholdLow < 0x13) break;
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
- ThresholdLow = 0x13;
- tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
- tempah >>= 6;
- if(!(tempah)) break;
- tempah--;
- tempah <<= 6;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
- } while(0);
-
- } else ThresholdLow = 2;
-
- /* Write CRT/CPU threshold low, CRT/Engine threshold high */
- temp = (ThresholdLow << 4) | 0x0f;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
-
- temp = (ThresholdLow & 0x10) << 1;
- if(ModeNo > 0x13) temp |= 0x40;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
-
- /* What is this? */
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
-
- /* Write CRT/CPU threshold high */
- temp = ThresholdLow + 3;
- if(temp > 0x0f) temp = 0x0f;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
+ static const unsigned char LatencyFactor[] = {
+ 97, 88, 86, 79, 77, 0, /* 64 bit BQ=2 */
+ 0, 87, 85, 78, 76, 54, /* 64 bit BQ=1 */
+ 97, 88, 86, 79, 77, 0, /* 128 bit BQ=2 */
+ 0, 79, 77, 70, 68, 48, /* 128 bit BQ=1 */
+ 80, 72, 69, 63, 61, 0, /* 64 bit BQ=2 */
+ 0, 70, 68, 61, 59, 37, /* 64 bit BQ=1 */
+ 86, 77, 75, 68, 66, 0, /* 128 bit BQ=2 */
+ 0, 68, 66, 59, 57, 37 /* 128 bit BQ=1 */
+ };
+ static const unsigned char LatencyFactor730[] = {
+ 69, 63, 61,
+ 86, 79, 77,
+ 103, 96, 94,
+ 120,113,111,
+ 137,130,128
+ };
+
+ if(SiS_Pr->ChipType == SIS_730) {
+ return (unsigned short)LatencyFactor730[index];
+ } else {
+ return (unsigned short)LatencyFactor[index];
+ }
}
-static USHORT
-SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR key, PSIS_HW_INFO HwInfo)
+static unsigned short
+SiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
{
- USHORT data,index;
- const UCHAR LatencyFactor[] = {
- 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
- 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
- 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
- 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
- 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
- 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
- 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
- 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
- };
- const UCHAR LatencyFactor730[] = {
- 69, 63, 61,
- 86, 79, 77,
- 103, 96, 94,
- 120,113,111,
- 137,130,128, /* --- Table ends with this entry, data below */
- 137,130,128, /* to avoid using illegal values */
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- };
-
- if(HwInfo->jChipType == SIS_730) {
- index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
- data = LatencyFactor730[index];
- } else {
- index = (key & 0xE0) >> 5;
- if(key & 0x10) index +=6;
- if(!(key & 0x01)) index += 24;
- data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- if(data & 0x0080) index += 12;
- data = LatencyFactor[index];
- }
- return(data);
+ unsigned short index;
+
+ if(SiS_Pr->ChipType == SIS_730) {
+ index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
+ } else {
+ index = (key & 0xe0) >> 5;
+ if(key & 0x10) index += 6;
+ if(!(key & 0x01)) index += 24;
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
+ }
+ return SiS_GetLatencyFactor630(SiS_Pr, index);
}
static void
-SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo,
- PSIS_HW_INFO HwInfo,
- USHORT RefreshRateTableIndex)
+SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short RefreshRateTableIndex)
{
- USHORT i,index,data,VCLK,MCLK,colorth=0;
- ULONG B,eax,bl,data2;
- USHORT ThresholdLow=0;
- UCHAR FQBQData[]= {
- 0x01,0x21,0x41,0x61,0x81,
- 0x31,0x51,0x71,0x91,0xb1,
- 0x00,0x20,0x40,0x60,0x80,
- 0x30,0x50,0x70,0x90,0xb0,
- 0xFF
- };
- UCHAR FQBQData730[]= {
- 0x34,0x74,0xb4,
- 0x23,0x63,0xa3,
- 0x12,0x52,0x92,
- 0x01,0x41,0x81,
- 0x00,0x40,0x80,
- 0xff
- };
-
- i=0;
- if(ModeNo > 0x13) {
- if(SiS_Pr->UseCustomMode) {
- VCLK = SiS_Pr->CSRClock;
- } else {
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- index &= 0x3F;
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
- }
-
- index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
- index &= 0x07;
- MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
-
- data2 = SiS_Pr->SiS_ModeType - ModeEGA; /* Get half colordepth */
- switch (data2) {
- case 0 : colorth = 1; break;
- case 1 : colorth = 1; break;
- case 2 : colorth = 2; break;
- case 3 : colorth = 2; break;
- case 4 : colorth = 3; break;
- case 5 : colorth = 4; break;
- }
-
- if(HwInfo->jChipType == SIS_730) {
-
- do {
- B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
- bl = B / (MCLK * 16);
-
- if(B == bl * 16 * MCLK) {
- bl = bl + 1;
- } else {
- bl = bl + 2;
- }
-
- if(bl > 0x13) {
- if(FQBQData730[i+1] == 0xFF) {
- ThresholdLow = 0x13;
- break;
- }
- i++;
- } else {
- ThresholdLow = bl;
- break;
- }
- } while(FQBQData730[i] != 0xFF);
+ unsigned short ThresholdLow = 0;
+ unsigned short i, data, VCLK, MCLK16, colorth = 0;
+ unsigned int templ, datal;
+ const unsigned char *queuedata = NULL;
+ static const unsigned char FQBQData[21] = {
+ 0x01,0x21,0x41,0x61,0x81,
+ 0x31,0x51,0x71,0x91,0xb1,
+ 0x00,0x20,0x40,0x60,0x80,
+ 0x30,0x50,0x70,0x90,0xb0,
+ 0xff
+ };
+ static const unsigned char FQBQData730[16] = {
+ 0x34,0x74,0xb4,
+ 0x23,0x63,0xa3,
+ 0x12,0x52,0x92,
+ 0x01,0x41,0x81,
+ 0x00,0x40,0x80,
+ 0xff
+ };
+ static const unsigned short colortharray[6] = {
+ 1, 1, 2, 2, 3, 4
+ };
- } else {
+ i = 0;
- do {
- B = SiS_CalcDelay2(SiS_Pr, FQBQData[i], HwInfo) * VCLK * colorth;
- bl = B / (MCLK * 16);
+ if(ModeNo > 0x13) {
- if(B == bl * 16 * MCLK) {
- bl = bl + 1;
- } else {
- bl = bl + 2;
- }
+ /* Get VCLK */
+ if(SiS_Pr->UseCustomMode) {
+ VCLK = SiS_Pr->CSRClock;
+ } else {
+ data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
+ VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
+ }
- if(bl > 0x13) {
- if(FQBQData[i+1] == 0xFF) {
- ThresholdLow = 0x13;
- break;
- }
- i++;
- } else {
- ThresholdLow = bl;
- break;
- }
- } while(FQBQData[i] != 0xFF);
- }
- }
- else {
- if(HwInfo->jChipType == SIS_730) {
- } else {
- i = 9;
- }
- ThresholdLow = 0x02;
- }
+ /* Get MCLK * 16 */
+ data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
+ MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
+
+ /* Get half colordepth */
+ colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
+
+ if(SiS_Pr->ChipType == SIS_730) {
+ queuedata = &FQBQData730[0];
+ } else {
+ queuedata = &FQBQData[0];
+ }
+
+ do {
+ templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
+
+ datal = templ % MCLK16;
+ templ = (templ / MCLK16) + 1;
+ if(datal) templ++;
+
+ if(templ > 0x13) {
+ if(queuedata[i + 1] == 0xFF) {
+ ThresholdLow = 0x13;
+ break;
+ }
+ i++;
+ } else {
+ ThresholdLow = templ;
+ break;
+ }
+ } while(queuedata[i] != 0xFF);
+
+ } else {
+
+ if(SiS_Pr->ChipType != SIS_730) i = 9;
+ ThresholdLow = 0x02;
+
+ }
+
+ /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+ data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
+
+ data = (ThresholdLow & 0x10) << 1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+
+ /* What is this? */
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
+
+ /* Write CRT/CPU threshold high (gap = 3) */
+ data = ThresholdLow + 3;
+ if(data > 0x0f) data = 0x0f;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
/* Write foreground and background queue */
- if(HwInfo->jChipType == SIS_730) {
-
- data2 = FQBQData730[i];
- data2 = (data2 & 0xC0) >> 5;
- data2 <<= 8;
-
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x80000050);
- eax = SiS_GetRegLong(0xcfc);
- eax &= 0xfffff9ff;
- eax |= data2;
- SiS_SetRegLong(0xcfc,eax);
+#ifdef SIS_LINUX_KERNEL
+ templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
#else
- /* We use pci functions X offers. We use pcitag 0, because
- * we want to read/write to the host bridge (which is always
- * 00:00.0 on 630, 730 and 540), not the VGA device.
- */
- eax = pciReadLong(0x00000000, 0x50);
- eax &= 0xfffff9ff;
- eax |= data2;
- pciWriteLong(0x00000000, 0x50, eax);
+ templ = pciReadLong(0x00000000, 0x50);
#endif
- /* Write GUI grant timer (PCI config 0xA3) */
- data2 = FQBQData730[i] << 8;
- data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
- data2 <<= 20;
-
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x800000A0);
- eax = SiS_GetRegLong(0xcfc);
- eax &= 0x00ffffff;
- eax |= data2;
- SiS_SetRegLong(0xcfc,eax);
-#else
- eax = pciReadLong(0x00000000, 0xA0);
- eax &= 0x00ffffff;
- eax |= data2;
- pciWriteLong(0x00000000, 0xA0, eax);
-#endif
+ if(SiS_Pr->ChipType == SIS_730) {
- } else {
+ templ &= 0xfffff9ff;
+ templ |= ((queuedata[i] & 0xc0) << 3);
- data2 = FQBQData[i];
- data2 = (data2 & 0xf0) >> 4;
- data2 <<= 24;
+ } else {
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x80000050);
- eax = SiS_GetRegLong(0xcfc);
- eax &= 0xf0ffffff;
- eax |= data2;
- SiS_SetRegLong(0xcfc,eax);
-#else
- eax = pciReadLong(0x00000000, 0x50);
- eax &= 0xf0ffffff;
- eax |= data2;
- pciWriteLong(0x00000000, 0x50, eax);
-#endif
+ templ &= 0xf0ffffff;
+ if( (ModeNo <= 0x13) &&
+ (SiS_Pr->ChipType == SIS_630) &&
+ (SiS_Pr->ChipRevision >= 0x30) ) {
+ templ |= 0x0b000000;
+ } else {
+ templ |= ((queuedata[i] & 0xf0) << 20);
+ }
+
+ }
- /* Write GUI grant timer (PCI config 0xA3) */
- data2 = FQBQData[i];
- data2 &= 0x0f;
- data2 <<= 24;
-
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x800000A0);
- eax = SiS_GetRegLong(0xcfc);
- eax &= 0xf0ffffff;
- eax |= data2;
- SiS_SetRegLong(0xcfc,eax);
+#ifdef SIS_LINUX_KERNEL
+ sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
+ templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
#else
- eax = pciReadLong(0x00000000, 0xA0);
- eax &= 0xf0ffffff;
- eax |= data2;
- pciWriteLong(0x00000000, 0xA0, eax);
+ pciWriteLong(0x00000000, 0x50, templ);
+ templ = pciReadLong(0x00000000, 0xA0);
#endif
- }
+ /* GUI grant timer (PCI config 0xA3) */
+ if(SiS_Pr->ChipType == SIS_730) {
+
+ templ &= 0x00ffffff;
+ datal = queuedata[i] << 8;
+ templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
- /* Write CRT/CPU threshold low, CRT/Engine threshold high */
- data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
+ } else {
- data = (ThresholdLow & 0x10) << 1;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+ templ &= 0xf0ffffff;
+ templ |= ((queuedata[i] & 0x0f) << 24);
- /* What is this? */
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
+ }
- /* Write CRT/CPU threshold high (gap = 3) */
- data = ThresholdLow + 3;
- if(data > 0x0f) data = 0x0f;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
-}
+#ifdef SIS_LINUX_KERNEL
+ sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
+#else
+ pciWriteLong(0x00000000, 0xA0, templ);
#endif
+}
+#endif /* SIS300 */
#ifdef SIS315H
static void
-SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT modeflag;
-
- /* disable auto-threshold */
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
-
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
- if(ModeNo > 0x13) {
- if(HwInfo->jChipType >= SIS_661) {
- if(!(modeflag & HalfDCLK)) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
- }
- } else {
- if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
- }
- }
- }
+ unsigned short modeflag;
+
+ /* disable auto-threshold */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
+
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->ChipType >= XGI_20) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+ } else if(SiS_Pr->ChipType >= SIS_661) {
+ if(!(modeflag & HalfDCLK)) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+ }
+ } else {
+ if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+ }
+ }
+ }
}
#endif
@@ -2851,385 +2597,370 @@ SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT RefreshRateTableIndex,
- USHORT ModeIdIndex)
+SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
{
- USHORT data=0, VCLK=0, index=0;
+ unsigned short data = 0, VCLK = 0, index = 0;
- if(ModeNo > 0x13) {
- if(SiS_Pr->UseCustomMode) {
- VCLK = SiS_Pr->CSRClock;
- } else {
- index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
- }
- }
-
- if(HwInfo->jChipType < SIS_315H) {
-
- if(VCLK > 150) data |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
-
- data = 0x00;
- if(VCLK >= 150) data |= 0x08;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->UseCustomMode) {
+ VCLK = SiS_Pr->CSRClock;
+ } else {
+ index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+ }
- } else {
+ if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+ if(VCLK > 150) data |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
- if(VCLK >= 166) data |= 0x0c;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+ data = 0x00;
+ if(VCLK >= 150) data |= 0x08;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
+#endif
+ } else if(SiS_Pr->ChipType < XGI_20) {
+#ifdef SIS315H
+ if(VCLK >= 166) data |= 0x0c;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
- if(VCLK >= 166) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
- }
- }
+ if(VCLK >= 166) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+ }
+#endif
+ } else {
+#ifdef SIS315H
+ if(VCLK >= 200) data |= 0x0c;
+ if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+ if(SiS_Pr->ChipType != XGI_20) {
+ data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
+ if(VCLK < 200) data |= 0x10;
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
+ }
+#endif
+ }
- /* DAC speed */
- if(HwInfo->jChipType >= SIS_661) {
+ /* DAC speed */
+ if(SiS_Pr->ChipType >= SIS_661) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
- } else {
+ } else {
- data = 0x03;
- if((VCLK >= 135) && (VCLK < 160)) data = 0x02;
- else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
- else if(VCLK >= 260) data = 0x00;
+ data = 0x03;
+ if(VCLK >= 260) data = 0x00;
+ else if(VCLK >= 160) data = 0x01;
+ else if(VCLK >= 135) data = 0x02;
- if(HwInfo->jChipType == SIS_540) {
- if((VCLK == 203) || (VCLK < 234)) data = 0x02;
- }
+ if(SiS_Pr->ChipType == SIS_540) {
+ if((VCLK == 203) || (VCLK < 234)) data = 0x02;
+ }
- if(HwInfo->jChipType < SIS_315H) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
- } else {
- if(HwInfo->jChipType > SIS_315PRO) {
- if(ModeNo > 0x13) data &= 0xfc;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
- }
+ if(SiS_Pr->ChipType < SIS_315H) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
+ } else {
+ if(SiS_Pr->ChipType > SIS_315PRO) {
+ if(ModeNo > 0x13) data &= 0xfc;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
+ }
- }
+ }
}
static void
-SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
- USHORT data,infoflag=0,modeflag;
- USHORT resindex,xres;
+ unsigned short data, infoflag = 0, modeflag, resindex;
#ifdef SIS315H
- USHORT data2,data3;
- ULONG longdata;
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short data2, data3;
#endif
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- infoflag = SiS_Pr->CInfoFlag;
- xres = SiS_Pr->CHDisplay;
- } else {
- resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
- if(ModeNo > 0x13) {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
- } else {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
- }
- }
-
- /* Disable DPMS */
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
-
- data = 0;
- if(ModeNo > 0x13) {
- if(SiS_Pr->SiS_ModeType > ModeEGA) {
- data |= 0x02;
- data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
- }
- if(infoflag & InterlaceMode) data |= 0x20;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
-
- if(HwInfo->jChipType != SIS_300) {
- data = 0;
- if(infoflag & InterlaceMode) {
- if(xres <= 800) data = 0x0020;
- else if(xres <= 1024) data = 0x0035;
- else data = 0x0048;
- }
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
- }
-
- if(modeflag & HalfDCLK) {
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
- }
-
- data = 0;
- if(modeflag & LineCompareOff) data = 0x08;
- if(HwInfo->jChipType == SIS_300) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
- if(SiS_Pr->SiS_ModeType == ModeEGA) {
- if(ModeNo > 0x13) {
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
- }
- }
- }
-
- if(HwInfo->jChipType >= SIS_661) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
- }
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+ if(ModeNo > 0x13) {
+ infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
+ }
+ }
+
+ /* Disable DPMS */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
+
+ data = 0;
+ if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_ModeType > ModeEGA) {
+ data |= 0x02;
+ data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
+ }
+ if(infoflag & InterlaceMode) data |= 0x20;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
+
+ if(SiS_Pr->ChipType != SIS_300) {
+ data = 0;
+ if(infoflag & InterlaceMode) {
+ /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
+ int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
+ ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
+ int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
+ ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
+ data = hrs - (hto >> 1) + 3;
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
+ }
+
+ if(modeflag & HalfDCLK) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
+ }
+
+ data = 0;
+ if(modeflag & LineCompareOff) data = 0x08;
+ if(SiS_Pr->ChipType == SIS_300) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
+ } else {
+ if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
+ if(SiS_Pr->SiS_ModeType == ModeEGA) {
+ if(ModeNo > 0x13) {
+ data |= 0x40;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
+ }
#ifdef SIS315H
- if(HwInfo->jChipType == SIS_315PRO) {
-
- data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
- data = SiS_Pr->SiS_SR15[2][data];
- if(SiS_Pr->SiS_ModeType == ModeText) {
- data &= 0xc7;
- } else {
- data2 = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- data2 >>= 1;
- if(infoflag & InterlaceMode) data2 >>= 1;
- data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
- if(!data3) data3++;
- data2 /= data3;
- if(data2 >= 0x50) {
- data &= 0x0f;
- data |= 0x50;
- }
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
-
- } else if( (HwInfo->jChipType == SIS_330) ||
- ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
-
- data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
- if(HwInfo->jChipType == SIS_330) {
- data = SiS_Pr->SiS_SR15[2][data];
- } else {
- if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
- else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
- else data = 0xba;
- }
- if(SiS_Pr->SiS_ModeType <= ModeEGA) {
- data &= 0xc7;
- } else {
- if(SiS_Pr->UseCustomMode) {
- data2 = SiS_Pr->CSRClock;
- } else {
- data2 = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
+ }
- data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
- if(data3) data2 *= data3;
-
- longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024;
-
- data2 = longdata / data2;
-
- if(HwInfo->jChipType == SIS_330) {
- if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
- if (data2 >= 0x19c) data = 0xba;
- else if(data2 >= 0x140) data = 0x7a;
- else if(data2 >= 0x101) data = 0x3a;
- else if(data2 >= 0xf5) data = 0x32;
- else if(data2 >= 0xe2) data = 0x2a;
- else if(data2 >= 0xc4) data = 0x22;
- else if(data2 >= 0xac) data = 0x1a;
- else if(data2 >= 0x9e) data = 0x12;
- else if(data2 >= 0x8e) data = 0x0a;
- else data = 0x02;
- } else {
- if(data2 >= 0x127) data = 0xba;
- else data = 0x7a;
- }
- } else { /* 760+LFB */
- if (data2 >= 0x190) data = 0xba;
- else if(data2 >= 0xff) data = 0x7a;
- else if(data2 >= 0xd3) data = 0x3a;
- else if(data2 >= 0xa9) data = 0x1a;
- else if(data2 >= 0x93) data = 0x0a;
- else data = 0x02;
- }
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
- } else if(HwInfo->jChipType == SIS_340) {
- /* TODO */
- }
+ if(SiS_Pr->ChipType == SIS_315PRO) {
+
+ data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
+ if(SiS_Pr->SiS_ModeType == ModeText) {
+ data &= 0xc7;
+ } else {
+ data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
+ if(infoflag & InterlaceMode) data2 >>= 1;
+ data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
+ if(data3) data2 /= data3;
+ if(data2 >= 0x50) {
+ data &= 0x0f;
+ data |= 0x50;
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+
+ } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
+
+ data = SiS_Get310DRAMType(SiS_Pr);
+ if(SiS_Pr->ChipType == SIS_330) {
+ data = SiS_Pr->SiS_SR15[(2 * 4) + data];
+ } else {
+ if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
+ else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
+ else data = 0xba;
+ }
+ if(SiS_Pr->SiS_ModeType <= ModeEGA) {
+ data &= 0xc7;
+ } else {
+ if(SiS_Pr->UseCustomMode) {
+ data2 = SiS_Pr->CSRClock;
+ } else {
+ data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
+ data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
+ }
+
+ data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
+ if(data3) data2 *= data3;
+
+ data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
+
+ if(SiS_Pr->ChipType == SIS_330) {
+ if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+ if (data2 >= 0x19c) data = 0xba;
+ else if(data2 >= 0x140) data = 0x7a;
+ else if(data2 >= 0x101) data = 0x3a;
+ else if(data2 >= 0xf5) data = 0x32;
+ else if(data2 >= 0xe2) data = 0x2a;
+ else if(data2 >= 0xc4) data = 0x22;
+ else if(data2 >= 0xac) data = 0x1a;
+ else if(data2 >= 0x9e) data = 0x12;
+ else if(data2 >= 0x8e) data = 0x0a;
+ else data = 0x02;
+ } else {
+ if(data2 >= 0x127) data = 0xba;
+ else data = 0x7a;
+ }
+ } else { /* 76x+LFB */
+ if (data2 >= 0x190) data = 0xba;
+ else if(data2 >= 0xff) data = 0x7a;
+ else if(data2 >= 0xd3) data = 0x3a;
+ else if(data2 >= 0xa9) data = 0x1a;
+ else if(data2 >= 0x93) data = 0x0a;
+ else data = 0x02;
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+
+ }
+ /* XGI: Nothing. */
+ /* TODO: Check SiS340 */
#endif
- data = 0x60;
- if(SiS_Pr->SiS_ModeType != ModeText) {
- data ^= 0x60;
- if(SiS_Pr->SiS_ModeType != ModeEGA) {
- data ^= 0xA0;
- }
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
+ data = 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeText) {
+ data ^= 0x60;
+ if(SiS_Pr->SiS_ModeType != ModeEGA) {
+ data ^= 0xA0;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
- SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
+ SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
- }
- }
+ if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
+ (SiS_Pr->ChipType == XGI_40)) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
+ } else {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
+ }
+ } else if(SiS_Pr->ChipType == XGI_20) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
+ } else {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
+ }
#endif
}
-/*********************************************/
-/* LOAD DAC */
-/*********************************************/
-
-#if 0
+#ifdef SIS315H
static void
-SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
+SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
{
+#if 0
+ /* TODO: Find out about IOAddress2 */
+ SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
+ SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
+ SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
int i;
- OutPortByte(port, 0);
- port++;
- for (i=0; i < (256 * 3); i++) {
- OutPortByte(port, 0);
+ if((SiS_Pr->ChipRevision != 0) ||
+ (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
+ return;
+
+ for(i = 0; i <= 4; i++) { /* SR00 - SR04 */
+ SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
}
+ for(i = 0; i <= 8; i++) { /* GR00 - GR08 */
+ SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
+ }
+ SiS_SetReg(P2_3c4,0x05,0x86);
+ SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06)); /* SR06 */
+ SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21)); /* SR21 */
+ SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc)); /* MISC */
+ SiS_SetReg(P2_3c4,0x05,0x00);
+#endif
}
#endif
+/*********************************************/
+/* LOAD DAC */
+/*********************************************/
+
static void
-SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
- USHORT dl, USHORT ah, USHORT al, USHORT dh)
+SiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
+ unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
{
- USHORT temp,bh,bl;
-
- bh = ah;
- bl = al;
- if(dl != 0) {
- temp = bh;
- bh = dh;
- dh = temp;
- if(dl == 1) {
- temp = bl;
- bl = dh;
- dh = temp;
- } else {
- temp = bl;
- bl = bh;
- bh = temp;
- }
- }
- if(shiftflag) {
- dh <<= 2;
- bh <<= 2;
- bl <<= 2;
- }
- SiS_SetRegByte(DACData,(USHORT)dh);
- SiS_SetRegByte(DACData,(USHORT)bh);
- SiS_SetRegByte(DACData,(USHORT)bl);
+ unsigned short d1, d2, d3;
+
+ switch(dl) {
+ case 0: d1 = dh; d2 = ah; d3 = al; break;
+ case 1: d1 = ah; d2 = al; d3 = dh; break;
+ default: d1 = al; d2 = dh; d3 = ah;
+ }
+ SiS_SetRegByte(DACData, (d1 << shiftflag));
+ SiS_SetRegByte(DACData, (d2 << shiftflag));
+ SiS_SetRegByte(DACData, (d3 << shiftflag));
}
void
-SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
+SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT data,data2;
- USHORT time,i,j,k,m,n,o;
- USHORT si,di,bx,dl,al,ah,dh;
- USHORT shiftflag;
+ unsigned short data, data2, time, i, j, k, m, n, o;
+ unsigned short si, di, bx, sf;
SISIOADDRESS DACAddr, DACData;
- const USHORT *table = NULL;
+ const unsigned char *table = NULL;
- if(ModeNo <= 0x13) {
- data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- if(SiS_Pr->UseCustomMode) {
- data = SiS_Pr->CModeFlag;
- } else {
- data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
- }
+ data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
- data &= DACInfoFlag;
- time = 64;
- if(data == 0x00) table = SiS_MDA_DAC;
- if(data == 0x08) table = SiS_CGA_DAC;
- if(data == 0x10) table = SiS_EGA_DAC;
- if(data == 0x18) {
+ j = time = 64;
+ if(data == 0x00) table = SiS_MDA_DAC;
+ else if(data == 0x08) table = SiS_CGA_DAC;
+ else if(data == 0x10) table = SiS_EGA_DAC;
+ else if(data == 0x18) {
+ j = 16;
time = 256;
table = SiS_VGA_DAC;
}
- if(time == 256) j = 16;
- else j = time;
if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
(SiS_Pr->SiS_VBType & VB_NoLCD) ) ||
(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */
(!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
+ SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
DACAddr = SiS_Pr->SiS_P3c8;
DACData = SiS_Pr->SiS_P3c9;
- shiftflag = 0;
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
+ sf = 0;
} else {
- shiftflag = 1;
DACAddr = SiS_Pr->SiS_Part5Port;
DACData = SiS_Pr->SiS_Part5Port + 1;
+ sf = 2;
}
SiS_SetRegByte(DACAddr,0x00);
- for(i=0; i<j; i++) {
+ for(i = 0; i < j; i++) {
data = table[i];
- for(k=0; k<3; k++) {
+ for(k = 0; k < 3; k++) {
data2 = 0;
- if(data & 0x01) data2 = 0x2A;
+ if(data & 0x01) data2 += 0x2A;
if(data & 0x02) data2 += 0x15;
- if(shiftflag) data2 <<= 2;
- SiS_SetRegByte(DACData, data2);
+ SiS_SetRegByte(DACData, (data2 << sf));
data >>= 2;
}
}
if(time == 256) {
for(i = 16; i < 32; i++) {
- data = table[i];
- if(shiftflag) data <<= 2;
+ data = table[i] << sf;
for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
}
si = 32;
for(m = 0; m < 9; m++) {
- di = si;
- bx = si + 4;
- dl = 0;
- for(n = 0; n < 3; n++) {
- for(o = 0; o < 5; o++) {
- dh = table[si];
- ah = table[di];
- al = table[bx];
+ di = si;
+ bx = si + 4;
+ for(n = 0; n < 3; n++) {
+ for(o = 0; o < 5; o++) {
+ SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
si++;
- SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
}
si -= 2;
for(o = 0; o < 3; o++) {
- dh = table[bx];
- ah = table[di];
- al = table[si];
+ SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
si--;
- SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
}
- dl++;
} /* for n < 3 */
si += 5;
} /* for m < 9 */
@@ -3241,89 +2972,114 @@ SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/*********************************************/
static void
-SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
+SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT StandTableIndex,RefreshRateTableIndex;
-
- SiS_Pr->SiS_CRT1Mode = ModeNo;
- StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
- if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
- SiS_DisableBridge(SiS_Pr, HwInfo);
- }
- }
-
- SiS_ResetSegmentRegisters(SiS_Pr, HwInfo);
-
- SiS_SetSeqRegs(SiS_Pr, StandTableIndex, HwInfo);
- SiS_SetMiscRegs(SiS_Pr, StandTableIndex, HwInfo);
- SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
- SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
- SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
- SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo);
- SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
-
- SiS_Pr->SiS_SelectCRT2Rate = 0;
- SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-
-#ifdef LINUX_XF86
- xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+ unsigned short StandTableIndex, RefreshRateTableIndex;
+
+ SiS_Pr->SiS_CRT1Mode = ModeNo;
+
+ StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+ if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
+ SiS_DisableBridge(SiS_Pr);
+ }
+ }
+
+ SiS_ResetSegmentRegisters(SiS_Pr);
+
+ SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
+ SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
+ SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
+ SiS_SetATTRegs(SiS_Pr, StandTableIndex);
+ SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
+ SiS_ClearExt1Regs(SiS_Pr, ModeNo);
+ SiS_ResetCRT1VCLK(SiS_Pr);
+
+ SiS_Pr->SiS_SelectCRT2Rate = 0;
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+
+#ifdef SIS_XORG_XF86
+ xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
#endif
- if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ }
- RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
- }
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+ }
- if(RefreshRateTableIndex != 0xFFFF) {
- SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
- SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
- }
+ if(RefreshRateTableIndex != 0xFFFF) {
+ SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
+ SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+ switch(SiS_Pr->ChipType) {
#ifdef SIS300
- if(HwInfo->jChipType == SIS_300) {
- SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo,HwInfo,RefreshRateTableIndex);
- } else if((HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ||
- (HwInfo->jChipType == SIS_540)) {
- SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, HwInfo, RefreshRateTableIndex);
- }
+ case SIS_300:
+ SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
+ break;
+ case SIS_540:
+ case SIS_630:
+ case SIS_730:
+ SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
+ break;
#endif
+ default:
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- }
+ if(SiS_Pr->ChipType == XGI_20) {
+ unsigned char sr2b = 0, sr2c = 0;
+ switch(ModeNo) {
+ case 0x00:
+ case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
+ case 0x04:
+ case 0x05:
+ case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
+ }
+ if(sr2b) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
+ SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
+ }
+ }
+ SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
#endif
+ break;
+ }
+
+ SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
- SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+#ifdef SIS315H
+ if(SiS_Pr->ChipType == XGI_40) {
+ SiS_SetupDualChip(SiS_Pr);
+ }
+#endif
- SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+ SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
-#ifdef LINUX_KERNEL
- if(SiS_Pr->SiS_flag_clearbuffer) {
- SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
- }
+#ifdef SIS_LINUX_KERNEL
+ if(SiS_Pr->SiS_flag_clearbuffer) {
+ SiS_ClearBuffer(SiS_Pr, ModeNo);
+ }
#endif
- if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
- SiS_WaitRetrace1(SiS_Pr);
- SiS_DisplayOn(SiS_Pr);
- }
+ if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
+ SiS_WaitRetrace1(SiS_Pr);
+ SiS_DisplayOn(SiS_Pr);
+ }
}
/*********************************************/
@@ -3331,33 +3087,62 @@ SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/*********************************************/
static void
-SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_InitVB(struct SiS_Private *SiS_Pr)
+{
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+
+ SiS_Pr->Init_P4_0E = 0;
+ if(SiS_Pr->SiS_ROMNew) {
+ SiS_Pr->Init_P4_0E = ROMAddr[0x82];
+ } else if(SiS_Pr->ChipType >= XGI_40) {
+ if(SiS_Pr->SiS_XGIROM) {
+ SiS_Pr->Init_P4_0E = ROMAddr[0x80];
+ }
+ }
+}
+
+static void
+SiS_ResetVB(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp;
+#ifdef SIS315H
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short temp;
/* VB programming clock */
if(SiS_Pr->SiS_UseROM) {
- if(HwInfo->jChipType < SIS_330) {
- temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
+ if(SiS_Pr->ChipType < SIS_330) {
+ temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
- } else if(HwInfo->jChipType >= SIS_661) {
- temp = ROMAddr[0x7e] | 0x40;
- if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+ } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
+ temp = ROMAddr[0x7e] | 0x40;
+ if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
}
+ } else if(SiS_Pr->ChipType >= XGI_40) {
+ temp = 0x40;
+ if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
+ /* Can we do this on any chipset? */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
}
+#endif
}
/*********************************************/
-/* HELPER: SET VIDEO REGISTERS */
+/* HELPER: SET VIDEO/CAPTURE REGISTERS */
/*********************************************/
static void
-SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
{
- if((IS_SIS651) || (IS_SISM650)) {
+ /* SiS65x and XGI set up some sort of "lock mode" for text
+ * which locks CRT2 in some way to CRT1 timing. Disable
+ * this here.
+ */
+#ifdef SIS315H
+ if((IS_SIS651) || (IS_SISM650) ||
+ SiS_Pr->ChipType == SIS_340 ||
+ SiS_Pr->ChipType == XGI_40) {
SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */
SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
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)
SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
}
/* !!! This does not support modes < 0x13 !!! */
+#endif
}
/*********************************************/
-/* XFree86: SET SCREEN PITCH */
+/* HELPER: SET AGP TIMING FOR SiS760 */
/*********************************************/
-#ifdef LINUX_XF86
static void
-SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_Handle760(struct SiS_Private *SiS_Pr)
+{
+#ifdef SIS315H
+ unsigned int somebase;
+ unsigned char temp1, temp2, temp3;
+
+ if( (SiS_Pr->ChipType != SIS_760) ||
+ ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
+ (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) ||
+ (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
+ return;
+
+#ifdef SIS_LINUX_KERNEL
+ somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
+#else
+ somebase = pciReadWord(0x00001000, 0x74);
+#endif
+ somebase &= 0xffff;
+
+ if(somebase == 0) return;
+
+ temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
+
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+ temp1 = 0x21;
+ temp2 = 0x03;
+ temp3 |= 0x08;
+ } else {
+ temp1 = 0x25;
+ temp2 = 0x0b;
+ }
+
+#ifdef SIS_LINUX_KERNEL
+ sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
+ sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
+#else
+ pciWriteByte(0x00000000, 0x7e, temp1);
+ pciWriteByte(0x00000000, 0x8d, temp2);
+#endif
+
+ SiS_SetRegByte((somebase + 0x85), temp3);
+#endif
+}
+
+/*********************************************/
+/* X.org/XFree86: SET SCREEN PITCH */
+/*********************************************/
+
+#ifdef SIS_XORG_XF86
+static void
+SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
- UShort HDisplay = pSiS->scrnPitch >> 3;
+ unsigned short HDisplay = pSiS->scrnPitch >> 3;
SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay>>8));
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
}
static void
-SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
- UShort HDisplay = pSiS->scrnPitch2 >> 3;
+ unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
/* Unlock CRT2 */
if(pSiS->VGAEngine == SIS_315_VGA)
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
else
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
}
static void
-SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
+SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
BOOLEAN isslavemode = FALSE;
- if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+ if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
( ((pSiS->VGAEngine == SIS_300_VGA) &&
- (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
+ (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
isslavemode = TRUE;
}
@@ -3427,59 +3262,59 @@ SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
/* SiSSetMode() */
/*********************************************/
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
/* We need pScrn for setting the pitch correctly */
BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
+SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, BOOLEAN dosetpitch)
#else
BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
+SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
#endif
{
- USHORT ModeIdIndex;
- SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
- unsigned char backupreg=0;
-#ifdef LINUX_KERNEL
- USHORT KeepLockReg;
- ULONG temp;
+ SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
+ unsigned short RealModeNo, ModeIdIndex;
+ unsigned char backupreg = 0;
+#ifdef SIS_LINUX_KERNEL
+ unsigned short KeepLockReg;
SiS_Pr->UseCustomMode = FALSE;
SiS_Pr->CRT1UsesCustomMode = FALSE;
#endif
+ SiS_Pr->SiS_flag_clearbuffer = 0;
+
if(SiS_Pr->UseCustomMode) {
ModeNo = 0xfe;
+ } else {
+#ifdef SIS_LINUX_KERNEL
+ if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
+#endif
+ ModeNo &= 0x7f;
}
- SiSInitPtr(SiS_Pr, HwInfo);
+ /* Don't use FSTN mode for CRT1 */
+ RealModeNo = ModeNo;
+ if(ModeNo == 0x5b) ModeNo = 0x56;
+
+ SiSInitPtr(SiS_Pr);
SiSRegInit(SiS_Pr, BaseAddr);
- SiS_GetSysFlags(SiS_Pr, HwInfo);
+ SiS_GetSysFlags(SiS_Pr);
-#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ SiS_Pr->SiS_VGAINFO = 0x11;
+#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
- else
-#endif
- SiS_Pr->SiS_VGAINFO = 0x11;
-
- SiSInitPCIetc(SiS_Pr, HwInfo);
- SiSSetLVDSetc(SiS_Pr, HwInfo);
- SiSDetermineROMUsage(SiS_Pr, HwInfo);
-
- SiS_Pr->SiS_flag_clearbuffer = 0;
-
- if(!SiS_Pr->UseCustomMode) {
-#ifdef LINUX_KERNEL
- if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
#endif
- ModeNo &= 0x7f;
- }
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
#endif
SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
- SiS_UnLockCRT2(SiS_Pr, HwInfo);
+ SiSInitPCIetc(SiS_Pr);
+ SiSSetLVDSetc(SiS_Pr);
+ SiSDetermineROMUsage(SiS_Pr);
+
+ SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3487,13 +3322,13 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
ModeIdIndex = 0;
}
- SiS_GetVBType(SiS_Pr, HwInfo);
+ SiS_GetVBType(SiS_Pr);
/* Init/restore some VB registers */
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_ResetVB(SiS_Pr, HwInfo);
+ SiS_InitVB(SiS_Pr);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_ResetVB(SiS_Pr);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -3503,21 +3338,20 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
}
/* Get VB information (connectors, connected devices) */
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1);
- SiS_SetYPbPr(SiS_Pr, HwInfo);
- SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
-
-#ifdef LINUX_KERNEL
- /* 3. Check memory size (Kernel framebuffer driver only) */
- temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
- if(!temp) return(0);
+ SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
+ SiS_SetYPbPr(SiS_Pr);
+ SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_SetLowModeTest(SiS_Pr, ModeNo);
+
+#ifdef SIS_LINUX_KERNEL
+ /* Check memory size (kernel framebuffer driver only) */
+ if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
+ return FALSE;
+ }
#endif
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetupCR5x(SiS_Pr, HwInfo);
- }
+ SiS_OpenCRTC(SiS_Pr);
if(SiS_Pr->UseCustomMode) {
SiS_Pr->CRT1UsesCustomMode = TRUE;
@@ -3530,38 +3364,41 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
/* Set mode on CRT1 */
if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
(!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
- SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+ SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
}
/* Set mode on CRT2 */
if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
- (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
- (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
- (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
- SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+ (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
+ (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
+ SiS_SetCRT2Group(SiS_Pr, RealModeNo);
}
}
SiS_HandleCRT1(SiS_Pr);
- SiS_StrangeStuff(SiS_Pr, HwInfo);
+ SiS_StrangeStuff(SiS_Pr);
SiS_DisplayOn(SiS_Pr);
SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
- if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+ if(!(SiS_IsDualEdge(SiS_Pr))) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
}
}
}
+#endif
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
- if(!SiS_Pr->SiS_ROMNew) {
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+#ifdef SIS315H
+ if(!SiS_Pr->SiS_ROMNew) {
+ if(SiS_IsVAMode(SiS_Pr)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
} else {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3574,23 +3411,24 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
if((ModeNo == 0x03) || (ModeNo == 0x10)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
- }
+ }
}
if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
}
- } else if((HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730)) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
+#endif
+ } else if((SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730)) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
}
}
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
if(pScrn) {
/* SetPitch: Adapt to virtual size & position */
if((ModeNo > 0x13) && (dosetpitch)) {
- SiS_SetPitch(SiS_Pr, pScrn);
+ SiS_SetPitch(SiS_Pr, pScrn);
}
/* Backup/Set ModeNo in BIOS scratch area */
@@ -3598,33 +3436,37 @@ SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
}
#endif
-#ifdef LINUX_KERNEL /* We never lock registers in XF86 */
- if(KeepLockReg == 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
- else SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
+ SiS_CloseCRTC(SiS_Pr);
+
+ SiS_Handle760(SiS_Pr);
+
+#ifdef SIS_LINUX_KERNEL
+ /* We never lock registers in XF86 */
+ if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
#endif
return TRUE;
}
/*********************************************/
-/* XFree86: SiSBIOSSetMode() */
+/* X.org/XFree86: SiSBIOSSetMode() */
/* for non-Dual-Head mode */
/*********************************************/
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
BOOLEAN
-SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
DisplayModePtr mode, BOOLEAN IsCustom)
{
SISPtr pSiS = SISPTR(pScrn);
- UShort ModeNo = 0;
+ unsigned short ModeNo = 0;
SiS_Pr->UseCustomMode = FALSE;
if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
- SiS_Pr->CHDisplay,
+ SiS_Pr->CHDisplay,
(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
(mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
SiS_Pr->CVDisplay)));
@@ -3632,32 +3474,33 @@ SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
} else {
/* Don't need vbflags here; checks done earlier */
- ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
+ ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
if(!ModeNo) return FALSE;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
}
- return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
+ return(SiSSetMode(SiS_Pr, pScrn, ModeNo, TRUE));
}
/*********************************************/
-/* XFree86: SiSBIOSSetModeCRT2() */
+/* X.org/XFree86: SiSBIOSSetModeCRT2() */
/* for Dual-Head modes */
/*********************************************/
+
BOOLEAN
-SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
DisplayModePtr mode, BOOLEAN IsCustom)
{
- USHORT ModeIdIndex;
- SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
- UShort ModeNo = 0;
- unsigned char backupreg=0;
- SISPtr pSiS = SISPTR(pScrn);
+ SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
+ SISPtr pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
#endif
+ unsigned short ModeIdIndex;
+ unsigned short ModeNo = 0;
+ unsigned char backupreg = 0;
SiS_Pr->UseCustomMode = FALSE;
@@ -3672,22 +3515,25 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
} else {
- ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
- if(!ModeNo) return FALSE;
+ ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
+ if(!ModeNo) return FALSE;
}
SiSRegInit(SiS_Pr, BaseAddr);
- SiSInitPtr(SiS_Pr, HwInfo);
- SiS_GetSysFlags(SiS_Pr, HwInfo);
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ SiSInitPtr(SiS_Pr);
+ SiS_GetSysFlags(SiS_Pr);
+#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
#else
SiS_Pr->SiS_VGAINFO = 0x11;
#endif
- SiSInitPCIetc(SiS_Pr, HwInfo);
- SiSSetLVDSetc(SiS_Pr, HwInfo);
- SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+ SiSInitPCIetc(SiS_Pr);
+ SiSSetLVDSetc(SiS_Pr);
+ SiSDetermineROMUsage(SiS_Pr);
/* Save mode info so we can set it from within SetMode for CRT1 */
#ifdef SISDUALHEAD
@@ -3700,23 +3546,20 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
#if 0
- /* We can't set CRT2 mode before CRT1 mode is set */
+ /* We can't set CRT2 mode before CRT1 mode is set - says who...? */
if(pSiSEnt->CRT1ModeNo == -1) {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Setting CRT2 mode delayed until after setting CRT1 mode\n");
- return TRUE;
+ return TRUE;
}
#endif
pSiSEnt->CRT2ModeSet = TRUE;
}
#endif
- /* We don't clear the buffer in X */
- SiS_Pr->SiS_flag_clearbuffer=0;
-
if(SiS_Pr->UseCustomMode) {
- USHORT temptemp = SiS_Pr->CVDisplay;
+ unsigned short temptemp = SiS_Pr->CVDisplay;
if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
@@ -3728,13 +3571,11 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
} else {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting standard mode 0x%x on CRT2\n", ModeNo);
+ "Setting standard mode 0x%x on CRT2\n", ModeNo);
}
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
- SiS_UnLockCRT2(SiS_Pr, HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3742,56 +3583,59 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
ModeIdIndex = 0;
}
- SiS_GetVBType(SiS_Pr, HwInfo);
+ SiS_GetVBType(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_ResetVB(SiS_Pr, HwInfo);
+ SiS_InitVB(SiS_Pr);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_ResetVB(SiS_Pr);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
} else {
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+ backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
}
}
/* Get VB information (connectors, connected devices) */
if(!SiS_Pr->UseCustomMode) {
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 1);
+ SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
} else {
/* If this is a custom mode, we don't check the modeflag for CRT2Mode */
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
+ SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
}
- SiS_SetYPbPr(SiS_Pr, HwInfo);
- SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
+ SiS_SetYPbPr(SiS_Pr);
+ SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_SetLowModeTest(SiS_Pr, ModeNo);
+
+ SiS_ResetSegmentRegisters(SiS_Pr);
/* Set mode on CRT2 */
if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
(SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
(SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
- SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+ SiS_SetCRT2Group(SiS_Pr, ModeNo);
}
- SiS_StrangeStuff(SiS_Pr, HwInfo);
+ SiS_StrangeStuff(SiS_Pr);
SiS_DisplayOn(SiS_Pr);
SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+ if(!(SiS_IsDualEdge(SiS_Pr))) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
}
}
}
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
- if(!SiS_Pr->SiS_ROMNew) {
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(!SiS_Pr->SiS_ROMNew) {
+ if(SiS_IsVAMode(SiS_Pr)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
} else {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
@@ -3803,8 +3647,8 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
}
- } else if((HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730)) {
+ } else if((SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730)) {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
}
}
@@ -3812,25 +3656,27 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
/* SetPitch: Adapt to virtual size & position */
SiS_SetPitchCRT2(SiS_Pr, pScrn);
+ SiS_Handle760(SiS_Pr);
+
return TRUE;
}
/*********************************************/
-/* XFree86: SiSBIOSSetModeCRT1() */
+/* X.org/XFree86: SiSBIOSSetModeCRT1() */
/* for Dual-Head modes */
/*********************************************/
BOOLEAN
-SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
DisplayModePtr mode, BOOLEAN IsCustom)
{
+ SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
SISPtr pSiS = SISPTR(pScrn);
- SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
- USHORT ModeIdIndex, ModeNo=0;
- UCHAR backupreg=0;
+ unsigned short ModeIdIndex, ModeNo = 0;
+ unsigned char backupreg = 0;
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
- UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
+ unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
BOOLEAN backupcustom;
#endif
@@ -3838,43 +3684,41 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
- USHORT temptemp = SiS_Pr->CVDisplay;
+ unsigned short temptemp = SiS_Pr->CVDisplay;
- if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
- else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
+ if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
+ else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Setting custom mode %dx%d on CRT1\n",
SiS_Pr->CHDisplay, temptemp);
ModeNo = 0xfe;
} else {
- ModeNo = SiS_GetModeNumber(pScrn, mode, 0);
- if(!ModeNo) return FALSE;
+ ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
+ if(!ModeNo) return FALSE;
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Setting standard mode 0x%x on CRT1\n", ModeNo);
}
- SiSInitPtr(SiS_Pr, HwInfo);
+ SiSInitPtr(SiS_Pr);
SiSRegInit(SiS_Pr, BaseAddr);
- SiS_GetSysFlags(SiS_Pr, HwInfo);
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ SiS_GetSysFlags(SiS_Pr);
+#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
#else
SiS_Pr->SiS_VGAINFO = 0x11;
#endif
- SiSInitPCIetc(SiS_Pr, HwInfo);
- SiSSetLVDSetc(SiS_Pr, HwInfo);
- SiSDetermineROMUsage(SiS_Pr, HwInfo);
-
- /* We don't clear the buffer in X */
- SiS_Pr->SiS_flag_clearbuffer = 0;
SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
- SiS_UnLockCRT2(SiS_Pr, HwInfo);
+ SiSInitPCIetc(SiS_Pr);
+ SiSSetLVDSetc(SiS_Pr);
+ SiSDetermineROMUsage(SiS_Pr);
+
+ SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
@@ -3883,10 +3727,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
}
/* Determine VBType */
- SiS_GetVBType(SiS_Pr, HwInfo);
+ SiS_GetVBType(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
+ SiS_InitVB(SiS_Pr);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
} else {
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
@@ -3895,25 +3740,29 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
/* Get VB information (connectors, connected devices) */
/* (We don't care if the current mode is a CRT2 mode) */
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
- SiS_SetYPbPr(SiS_Pr, HwInfo);
- SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
+ SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
+ SiS_SetYPbPr(SiS_Pr);
+ SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_SetLowModeTest(SiS_Pr, ModeNo);
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetupCR5x(SiS_Pr, HwInfo);
- }
+ SiS_OpenCRTC(SiS_Pr);
/* Set mode on CRT1 */
- SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+ SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+ SiS_SetCRT2Group(SiS_Pr, ModeNo);
}
/* SetPitch: Adapt to virtual size & position */
SiS_SetPitchCRT1(SiS_Pr, pScrn);
+ SiS_HandleCRT1(SiS_Pr);
+
+ SiS_StrangeStuff(SiS_Pr);
+
+ SiS_CloseCRTC(SiS_Pr);
+
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
pSiSEnt->CRT1ModeNo = ModeNo;
@@ -3933,7 +3782,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
if(pSiSEnt->CRT2ModeNo != -1) {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"(Re-)Setting mode for CRT2\n");
backupcustom = SiS_Pr->UseCustomMode;
backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
@@ -3952,9 +3801,11 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
}
- SiSBIOSSetModeCRT2(SiS_Pr, HwInfo, pSiSEnt->pScrn_1,
+
+ SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
+
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
@@ -3970,22 +3821,20 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
* possibly overwritten
*/
- SiS_HandleCRT1(SiS_Pr);
-
- SiS_StrangeStuff(SiS_Pr, HwInfo);
-
SiS_DisplayOn(SiS_Pr);
SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
- } else if((HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730)) {
+ } else if((SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730)) {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
}
}
+ SiS_Handle760(SiS_Pr);
+
/* Backup/Set ModeNo in BIOS scratch area */
SiS_GetSetModeID(pScrn,ModeNo);
@@ -3993,84 +3842,6 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
}
#endif /* Linux_XF86 */
-
-#ifdef LINUX_XF86
-BOOLEAN
-SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
- const USHORT PanelTypeTable300[16] = {
- 0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
- 0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
- };
- const USHORT PanelTypeTable31030x[16] = {
- 0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
- 0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
- const USHORT PanelTypeTable310LVDS[16] = {
- 0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
- 0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- };
- USHORT tempax,tempbx,temp;
-
- if(HwInfo->jChipType < SIS_315H) {
-
- tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
- tempbx = tempax & 0x0F;
- if(!(tempax & 0x10)){
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
- tempbx = 0;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x38);
- if(temp & 0x40) tempbx |= 0x08;
- if(temp & 0x20) tempbx |= 0x02;
- if(temp & 0x01) tempbx |= 0x01;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x39);
- if(temp & 0x80) tempbx |= 0x04;
- } else {
- return 0;
- }
- }
- tempbx = PanelTypeTable300[tempbx];
- tempbx |= LCDSync;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
- temp = (tempbx & 0xFF00) >> 8;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
-
- } else {
-
- if(HwInfo->jChipType >= SIS_661) return 0;
-
- tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1a);
- tempax &= 0x1e;
- tempax >>= 1;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(tempax == 0) {
- /* TODO: Include HUGE detection routine
- (Probably not worth bothering)
- */
- return 0;
- }
- temp = tempax & 0xff;
- tempax--;
- tempbx = PanelTypeTable310LVDS[tempax];
- } else {
- tempbx = PanelTypeTable31030x[tempax];
- temp = tempbx & 0xff;
- }
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
- tempbx = (tempbx & 0xff00) >> 8;
- temp = tempbx & 0xc1;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- temp = tempbx & 0x04;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
- }
-
- }
- return 1;
-}
-#endif
-
#ifndef GETBITSTR
#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
#define GENMASK(mask) BITMASK(1?mask,0?mask)
@@ -4078,26 +3849,28 @@ SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
#endif
-static void
-SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
+void
+SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
{
+ int x = 1; /* Fix sync */
+
SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
- (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+ (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
- SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
- SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
- | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
- | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
- | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+ SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
+ SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
+ | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+ | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
+ | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
| 0x10
- | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
- | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
- | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
+ | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
+ | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
@@ -4106,55 +3879,44 @@ SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
}
-#if 0
- if (mode->VScan >= 32)
- regp->CRTC[9] |= 0x1F;
- else if (mode->VScan > 1)
- regp->CRTC[9] |= mode->VScan - 1;
-#endif
-
- SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart ) & 0xFF; /* CR10 */
- SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* CR11 */
+ SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF; /* CR10 */
+ SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80; /* CR11 */
SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
SiS_Pr->CCRT1CRTC[13] = /* SRA */
- GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
- GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
- GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
- GETBITSTR((SiS_Pr->CVSyncStart ), 10:10, 3:3) |
- GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
- GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
+ GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
+ GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
+ GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+ GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
+ GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
+ GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
SiS_Pr->CCRT1CRTC[14] = /* SRB */
- GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
- GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
- GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
- GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
+ GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+ GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
SiS_Pr->CCRT1CRTC[15] = /* SRC */
- GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
- GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+ GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+ GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
}
void
-SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex)
{
- USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE;
- int i,j;
+ unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
+ unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
+ int i, j;
/* 1:1 data: use data set by setcrt1crtc() */
if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
if(modeflag & HalfDCLK) VGAHDE >>= 1;
@@ -4164,32 +3926,91 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
- tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
- tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempax = SiS_Pr->PanelXRes;
+ if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+ tempbx = SiS_Pr->SiS_VGAHT;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempbx = SiS_Pr->PanelHT;
+ }
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+ remaining = tempbx % 8;
+#endif
+ } else {
+#ifdef SIS315H
+ /* OK for LCDA, LVDS */
+ tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
+ tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax = SiS_Pr->PanelXRes;
+ }
+ tempbx += tempax;
+ if(modeflag & HalfDCLK) tempbx -= VGAHDE;
+#endif
}
- tempbx += tempax;
- if(modeflag & HalfDCLK) tempbx -= VGAHDE;
SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
- tempax = VGAHDE;
- tempbx = SiS_Pr->CHTotal;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempbx = SiS_Pr->PanelXRes;
- if(modeflag & HalfDCLK) tempbx >>= 1;
- tempax += ((tempbx - tempax) >> 1);
+ if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+ if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
+ SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
+ SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
+ if(modeflag & HalfDCLK) {
+ SiS_Pr->CHSyncStart >>= 1;
+ SiS_Pr->CHSyncEnd >>= 1;
+ }
+ } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
+ tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
+ if(modeflag & HalfDCLK) {
+ tempax >>= 1;
+ tempbx >>= 1;
+ }
+ SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
+ tempax = SiS_Pr->PanelHRE + 7;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
+ } else {
+ SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) {
+ SiS_Pr->CHSyncStart >>= 1;
+ tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
+ SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
+ } else {
+ SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
+ SiS_Pr->CHSyncStart += 8;
+ }
+ }
+#endif
+ } else {
+#ifdef SIS315H
+ tempax = VGAHDE;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempbx = SiS_Pr->PanelXRes;
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+ tempax += ((tempbx - tempax) >> 1);
+ }
+ tempax += SiS_Pr->PanelHRS;
+ SiS_Pr->CHSyncStart = tempax;
+ tempax += SiS_Pr->PanelHRE;
+ SiS_Pr->CHSyncEnd = tempax;
+#endif
}
- tempax += SiS_Pr->PanelHRS;
- SiS_Pr->CHSyncStart = tempax;
- tempax += SiS_Pr->PanelHRE;
- SiS_Pr->CHSyncEnd = tempax;
-
tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
tempax = SiS_Pr->SiS_VGAVDE;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
tempax = SiS_Pr->PanelYRes;
+ } else if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+ /* Stupid hack for 640x400/320x200 */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if((tempax + tempbx) == 438) tempbx += 16;
+ } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
+ tempax = 0;
+ tempbx = SiS_Pr->SiS_VGAVT;
+ }
+#endif
}
SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
@@ -4201,22 +4022,28 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
SiS_Pr->CVSyncStart = tempax;
tempax += SiS_Pr->PanelVRE;
SiS_Pr->CVSyncEnd = tempax;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ SiS_Pr->CVSyncStart--;
+ SiS_Pr->CVSyncEnd--;
+ }
SiS_CalcCRRegisters(SiS_Pr, 8);
+ SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
+ SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
- for(i=0,j=0;i<=7;i++,j++) {
+ for(i = 0, j = 0; i <= 7; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
}
- for(j=0x10;i<=10;i++,j++) {
+ for(j = 0x10; i <= 10; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
}
- for(j=0x15;i<=12;i++,j++) {
+ for(j = 0x15; i <= 12; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
}
- for(j=0x0A;i<=15;i++,j++) {
+ for(j = 0x0A; i <= 15; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
}
@@ -4227,1092 +4054,192 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
if(modeflag & DoubleScanMode) tempax |= 0x80;
SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
- SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+ SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
-
xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+ SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+ SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
#endif
+#endif
}
-#ifdef LINUX_XF86
-
void
-SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
-{
- int out_n, out_dn, out_div, out_sbit, out_scale;
- unsigned int vclk[5];
-
-#define Midx 0
-#define Nidx 1
-#define VLDidx 2
-#define Pidx 3
-#define PSNidx 4
-
- if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
- (*p2b) = (out_div == 2) ? 0x80 : 0x00;
- (*p2b) |= ((out_n - 1) & 0x7f);
- (*p2c) = (out_dn - 1) & 0x1f;
- (*p2c) |= (((out_scale - 1) & 3) << 5);
- (*p2c) |= ((out_sbit & 0x01) << 7);
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
- clock, out_n, out_dn, out_div, out_sbit, out_scale);
+SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
+ int xres, int yres,
+#ifdef SIS_XORG_XF86
+ DisplayModePtr current
#endif
- } else {
- SiSCalcClock(pScrn, clock, 2, vclk);
- (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
- (*p2b) |= (vclk[Midx] - 1) & 0x7f;
- (*p2c) = (vclk[Nidx] - 1) & 0x1f;
- if(vclk[Pidx] <= 4) {
- /* postscale 1,2,3,4 */
- (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
- } else {
- /* postscale 6,8 */
- (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
- (*p2c) |= 0x80;
- }
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
- clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#ifdef SIS_LINUX_KERNEL
+ struct fb_var_screeninfo *var, BOOLEAN writeres
#endif
- }
-}
-
-#endif
-
-/* ================ XFREE86/X.ORG ================= */
-
-/* Helper functions */
-
-#ifdef LINUX_XF86
-
-USHORT
-SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
+)
{
- SISPtr pSiS = SISPTR(pScrn);
- int depth = pSiS->CurrentLayout.bitsPerPixel;
-
- pSiS->SiS_Pr->CModeFlag = 0;
-
- pSiS->SiS_Pr->CDClock = mode->Clock;
-
- pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
- pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
- pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
- pSiS->SiS_Pr->CHTotal = mode->HTotal;
-
- pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
- pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
- pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
- pSiS->SiS_Pr->CVTotal = mode->VTotal;
-
- pSiS->SiS_Pr->CFlags = mode->Flags;
-
- if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
- pSiS->SiS_Pr->CVDisplay >>= 1;
- pSiS->SiS_Pr->CVSyncStart >>= 1;
- pSiS->SiS_Pr->CVSyncEnd >>= 1;
- pSiS->SiS_Pr->CVTotal >>= 1;
- }
- if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
- /* pSiS->SiS_Pr->CDClock <<= 1; */
- pSiS->SiS_Pr->CVDisplay <<= 1;
- pSiS->SiS_Pr->CVSyncStart <<= 1;
- pSiS->SiS_Pr->CVSyncEnd <<= 1;
- pSiS->SiS_Pr->CVTotal <<= 1;
- }
-
- pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
- pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
- pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
- pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+ unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+ unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+ unsigned char sr_data, cr_data, cr_data2;
+ int A, B, C, D, E, F, temp;
- SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
+ sr_data = crdata[14];
- pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+ /* Horizontal total */
+ HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
+ A = HT + 5;
- SiS_CalcCRRegisters(pSiS->SiS_Pr, depth);
+ /* Horizontal display enable end */
+ HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
+ E = HDE + 1;
- switch(depth) {
- case 8: pSiS->SiS_Pr->CModeFlag |= 0x223b; break;
- case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break;
- case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
- default: return 0;
- }
+ /* Horizontal retrace (=sync) start */
+ HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
+ F = HRS - E - 3;
- if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
- pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
+ /* Horizontal blank start */
+ HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
- if((pSiS->SiS_Pr->CVDisplay >= 1024) ||
- (pSiS->SiS_Pr->CVTotal >= 1024) ||
- (pSiS->SiS_Pr->CHDisplay >= 1024))
- pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+ sr_data = crdata[15];
+ cr_data = crdata[5];
- if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
- pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+ /* Horizontal blank end */
+ HBE = (crdata[3] & 0x1f) |
+ ((unsigned short)(cr_data & 0x80) >> 2) |
+ ((unsigned short)(sr_data & 0x03) << 6);
- pSiS->SiS_Pr->CInfoFlag = 0x0007;
+ /* Horizontal retrace (=sync) end */
+ HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
- if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
- pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+ temp = HBE - ((E - 1) & 255);
+ B = (temp > 0) ? temp : (temp + 256);
- if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
- pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+ temp = HRE - ((E + F + 3) & 63);
+ C = (temp > 0) ? temp : (temp + 64);
- if(pSiS->SiS_Pr->CFlags & V_INTERLACE)
- pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
+ D = B - F - C;
- pSiS->SiS_Pr->UseCustomMode = TRUE;
+#ifdef SIS_XORG_XF86
+ current->HDisplay = (E * 8);
+ current->HSyncStart = (E * 8) + (F * 8);
+ current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
+ current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
- pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
- xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
- pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
- xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
- pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
- pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
- pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
- xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
- pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
- pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
- pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
- xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
- xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
- pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
-#endif
- return 1;
-}
-
-int
-SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy)
-{
- int i, j;
- BOOLEAN done = FALSE;
-
- i = 0;
- while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) {
- if(SiS_PlasmaTable[i].vendor == panelvendor) {
- for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
- if(SiS_PlasmaTable[i].product[j] == panelproduct) {
- if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) {
- (*maxx) = (int)SiS_PlasmaTable[i].maxx;
- (*maxy) = (int)SiS_PlasmaTable[i].maxy;
- (*prefx) = (int)SiS_PlasmaTable[i].prefx;
- (*prefy) = (int)SiS_PlasmaTable[i].prefy;
- done = TRUE;
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "Identified %s, correcting max X res %d, max Y res %d\n",
- SiS_PlasmaTable[i].plasmaname,
- SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy);
- break;
- }
- }
- }
- }
- i++;
- }
- return (done) ? 1 : 0;
-}
-
-/* Build a list of supported modes:
- * Built-in modes for which we have all data are M_T_DEFAULT,
- * modes derived from DDC or database data are M_T_BUILTIN
- */
-DisplayModePtr
-SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
-{
- SISPtr pSiS = SISPTR(pScrn);
- unsigned short VRE, VBE, VRS, VBS, VDE, VT;
- unsigned short HRE, HBE, HRS, HBS, HDE, HT;
- unsigned char sr_data, cr_data, cr_data2, cr_data3;
- unsigned char sr2b, sr2c;
- float num, denum, postscalar, divider;
- int A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
- DisplayModePtr new = NULL, current = NULL, first = NULL;
- BOOLEAN done = FALSE;
-#if 0
- DisplayModePtr backup = NULL;
-#endif
-
- pSiS->backupmodelist = NULL;
- pSiS->AddedPlasmaModes = FALSE;
-
- /* Initialize our pointers */
- if(pSiS->VGAEngine == SIS_300_VGA) {
-#ifdef SIS300
- InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ xf86DrvMsg(0, X_INFO,
+ "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",
+ A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
#else
- return NULL;
+ (void)VBS; (void)HBS; (void)A;
#endif
- } else if(pSiS->VGAEngine == SIS_315_VGA) {
-#ifdef SIS315H
- InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
- return NULL;
-#endif
- } else return NULL;
-
- i = 0;
- while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
-
- index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
-
- /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
- if((!pSiS->FSTN) &&
- (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a)) {
- i++;
- continue;
- }
- if((pSiS->FSTN) &&
- (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
- (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
- (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
- i++;
- continue;
- }
-
- if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
- memset(new, 0, sizeof(DisplayModeRec));
- if(!(new->name = xalloc(10))) {
- xfree(new);
- return first;
- }
- if(!first) first = new;
- if(current) {
- current->next = new;
- new->prev = current;
- }
-
- current = new;
-
- sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
- pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
-
- current->status = MODE_OK;
-
- current->type = M_T_DEFAULT;
-
- vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
- if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
-
- sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
- sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-
- divider = (sr2b & 0x80) ? 2.0 : 1.0;
- postscalar = (sr2c & 0x80) ?
- ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
- num = (sr2b & 0x7f) + 1.0;
- denum = (sr2c & 0x1f) + 1.0;
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "------------\n");
- xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
- sr2b, sr2c, divider, postscalar, num, denum);
#endif
-
- current->Clock = (int)(14318 * (divider / postscalar) * (num / denum));
-
- sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14];
- /* inSISIDXREG(SISSR, 0x0b, sr_data); */
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0];
- /* inSISIDXREG(SISCR, 0x00, cr_data); */
-
- /* Horizontal total */
- HT = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x03) << 8);
- A = HT + 5;
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1];
- /* inSISIDXREG(SISCR, 0x01, cr_data); */
-
- /* Horizontal display enable end */
- HDE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x0C) << 6);
- E = HDE + 1; /* 0x80 0x64 */
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
- /* inSISIDXREG(SISCR, 0x04, cr_data); */
-
- /* Horizontal retrace (=sync) start */
- HRS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0xC0) << 2);
- F = HRS - E - 3; /* 0x06 0x06 */
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
- /* inSISIDXREG(SISCR, 0x02, cr_data); */
-
- /* Horizontal blank start */
- HBS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x30) << 4);
-
- sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15];
- /* inSISIDXREG(SISSR, 0x0c, sr_data); */
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3];
- /* inSISIDXREG(SISCR, 0x03, cr_data); */
-
- cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5];
- /* inSISIDXREG(SISCR, 0x05, cr_data2); */
-
- /* Horizontal blank end */
- HBE = (cr_data & 0x1f) |
- ((unsigned short) (cr_data2 & 0x80) >> 2) |
- ((unsigned short) (sr_data & 0x03) << 6);
-
- /* Horizontal retrace (=sync) end */
- HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
- temp = HBE - ((E - 1) & 255);
- B = (temp > 0) ? temp : (temp + 256);
-
- temp = HRE - ((E + F + 3) & 63);
- C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
-
- D = B - F - C;
-
- if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
- ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
- (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
-
- /* Terrible hack, but correct CRTC data for
- * these modes only produces a black screen...
- * (HRE is 0, leading into a too large C and
- * a negative D. The CRT controller does not
- * seem to like correcting HRE to 50
- */
- current->HDisplay = 320;
- current->HSyncStart = 328;
- current->HSyncEnd = 376;
- current->HTotal = 400;
-
- } else {
-
- current->HDisplay = (E * 8);
- current->HSyncStart = (E * 8) + (F * 8);
- current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
- current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-
- }
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO,
- "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",
- A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
+#ifdef SIS_LINUX_KERNEL
+ if(writeres) var->xres = xres = E * 8;
+ var->left_margin = D * 8;
+ var->right_margin = F * 8;
+ var->hsync_len = C * 8;
#endif
- sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13];
- /* inSISIDXREG(SISSR, 0x0A, sr_data); */
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6];
- /* inSISIDXREG(SISCR, 0x06, cr_data); */
-
- cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7];
- /* inSISIDXREG(SISCR, 0x07, cr_data2); */
-
- /* Vertical total */
- VT = (cr_data & 0xFF) |
- ((unsigned short) (cr_data2 & 0x01) << 8) |
- ((unsigned short)(cr_data2 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x01) << 10);
- A = VT + 2;
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10];
- /* inSISIDXREG(SISCR, 0x12, cr_data); */
-
- /* Vertical display enable end */
- VDE = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x02) << 7) |
- ((unsigned short) (cr_data2 & 0x40) << 3) |
- ((unsigned short) (sr_data & 0x02) << 9);
- E = VDE + 1;
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8];
- /* inSISIDXREG(SISCR, 0x10, cr_data); */
-
- /* Vertical retrace (=sync) start */
- VRS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x04) << 6) |
- ((unsigned short) (cr_data2 & 0x80) << 2) |
- ((unsigned short) (sr_data & 0x08) << 7);
- F = VRS + 1 - E;
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11];
- /* inSISIDXREG(SISCR, 0x15, cr_data); */
-
- cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
- /* inSISIDXREG(SISCR, 0x09, cr_data3); */
-
- /* Vertical blank start */
- VBS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x08) << 5) |
- ((unsigned short) (cr_data3 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x04) << 8);
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12];
- /* inSISIDXREG(SISCR, 0x16, cr_data); */
-
- /* Vertical blank end */
- VBE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x10) << 4);
- temp = VBE - ((E - 1) & 511);
- B = (temp > 0) ? temp : (temp + 512);
-
- cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9];
- /* inSISIDXREG(SISCR, 0x11, cr_data); */
-
- /* Vertical retrace (=sync) end */
- VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
- temp = VRE - ((E + F - 1) & 31);
- C = (temp > 0) ? temp : (temp + 32);
-
- D = B - F - C;
-
- current->VDisplay = VDE + 1;
- current->VSyncStart = VRS + 1;
- current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
- if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
- current->VTotal = E + D + C + F;
-
+ /* Vertical */
+ sr_data = crdata[13];
+ cr_data = crdata[7];
+
+ /* Vertical total */
+ VT = crdata[6] |
+ ((unsigned short)(cr_data & 0x01) << 8) |
+ ((unsigned short)(cr_data & 0x20) << 4) |
+ ((unsigned short)(sr_data & 0x01) << 10);
+ A = VT + 2;
+
+ /* Vertical display enable end */
+ VDE = crdata[10] |
+ ((unsigned short)(cr_data & 0x02) << 7) |
+ ((unsigned short)(cr_data & 0x40) << 3) |
+ ((unsigned short)(sr_data & 0x02) << 9);
+ E = VDE + 1;
+
+ /* Vertical retrace (=sync) start */
+ VRS = crdata[8] |
+ ((unsigned short)(cr_data & 0x04) << 6) |
+ ((unsigned short)(cr_data & 0x80) << 2) |
+ ((unsigned short)(sr_data & 0x08) << 7);
+ F = VRS + 1 - E;
+
+ cr_data2 = (crdata[16] & 0x01) << 5;
+
+ /* Vertical blank start */
+ VBS = crdata[11] |
+ ((unsigned short)(cr_data & 0x08) << 5) |
+ ((unsigned short)(cr_data2 & 0x20) << 4) |
+ ((unsigned short)(sr_data & 0x04) << 8);
+
+ /* Vertical blank end */
+ VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
+ temp = VBE - ((E - 1) & 511);
+ B = (temp > 0) ? temp : (temp + 512);
+
+ /* Vertical retrace (=sync) end */
+ VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
+ temp = VRE - ((E + F - 1) & 31);
+ C = (temp > 0) ? temp : (temp + 32);
+
+ D = B - F - C;
+
+#ifdef SIS_XORG_XF86
+ current->VDisplay = VDE + 1;
+ current->VSyncStart = VRS + 1;
+ current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
+ if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
+ current->VTotal = E + D + C + F;
#if 0
- current->VDisplay = E;
- current->VSyncStart = E + D;
- current->VSyncEnd = E + D + C;
- current->VTotal = E + D + C + F;
+ current->VDisplay = E;
+ current->VSyncStart = E + D;
+ current->VSyncEnd = E + D + C;
+ current->VTotal = E + D + C + F;
#endif
-
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO,
- "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",
- A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
+ xf86DrvMsg(0, X_INFO,
+ "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",
+ A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
#endif
-
- if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
- current->Flags |= V_NHSYNC;
- else
- current->Flags |= V_PHSYNC;
-
- if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
- current->Flags |= V_NVSYNC;
- else
- current->Flags |= V_PVSYNC;
-
- if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
- current->Flags |= V_INTERLACE;
-
- j = 0;
- while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
- if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
- pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) {
- if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
- current->Flags |= V_DBLSCAN;
- }
- break;
- }
- j++;
- }
-
- if(current->Flags & V_INTERLACE) {
- current->VDisplay <<= 1;
- current->VSyncStart <<= 1;
- current->VSyncEnd <<= 1;
- current->VTotal <<= 1;
- current->VTotal |= 1;
- }
- if(current->Flags & V_DBLSCAN) {
- current->Clock >>= 1;
- current->VDisplay >>= 1;
- current->VSyncStart >>= 1;
- current->VSyncEnd >>= 1;
- current->VTotal >>= 1;
- }
-
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
- current->name, (float)current->Clock / 1000,
- current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
- current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
-#else
- (void)VBS; (void)HBS; (void)A;
#endif
-
- i++;
- }
-
- /* Add non-standard LCD modes for panel's detailed timings */
-
- if(!includelcdmodes) return first;
-
- if(pSiS->SiS_Pr->CP_Vendor) {
- xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
- pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
- }
-
- i = 0;
- while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
-
- if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
-
- for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
-
- if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
-
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Identified %s panel, adding specific modes\n",
- SiS_PlasmaTable[i].plasmaname);
-
- for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
-
- if(isfordvi) {
- if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
- } else {
- if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
- }
-
- l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
-
- if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) {
- if(isfordvi) {
- if(SiS_PlasmaMode[l].VDisplay > 1024) continue;
- }
- }
-
- if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-
- memset(new, 0, sizeof(DisplayModeRec));
- if(!(new->name = xalloc(12))) {
- xfree(new);
- return first;
- }
- if(!first) first = new;
- if(current) {
- current->next = new;
- new->prev = current;
- }
-
- current = new;
-
- pSiS->AddedPlasmaModes = TRUE;
-
- strcpy(current->name, SiS_PlasmaMode[l].name);
- /* sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
- SiS_PlasmaMode[l].VDisplay); */
-
- current->status = MODE_OK;
-
- current->type = M_T_BUILTIN;
-
- current->Clock = SiS_PlasmaMode[l].clock;
- current->SynthClock = current->Clock;
-
- current->HDisplay = SiS_PlasmaMode[l].HDisplay;
- current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
- current->HSyncEnd = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
- current->HTotal = SiS_PlasmaMode[l].HTotal;
-
- current->VDisplay = SiS_PlasmaMode[l].VDisplay;
- current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
- current->VSyncEnd = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
- current->VTotal = SiS_PlasmaMode[l].VTotal;
-
- current->CrtcHDisplay = current->HDisplay;
- current->CrtcHBlankStart = current->HSyncStart;
- current->CrtcHSyncStart = current->HSyncStart;
- current->CrtcHSyncEnd = current->HSyncEnd;
- current->CrtcHBlankEnd = current->HSyncEnd;
- current->CrtcHTotal = current->HTotal;
-
- current->CrtcVDisplay = current->VDisplay;
- current->CrtcVBlankStart = current->VSyncStart;
- current->CrtcVSyncStart = current->VSyncStart;
- current->CrtcVSyncEnd = current->VSyncEnd;
- current->CrtcVBlankEnd = current->VSyncEnd;
- current->CrtcVTotal = current->VTotal;
-
- if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
- current->Flags |= V_PHSYNC;
- else
- current->Flags |= V_NHSYNC;
-
- if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
- current->Flags |= V_PVSYNC;
- else
- current->Flags |= V_NVSYNC;
-
- if(current->HDisplay > pSiS->LCDwidth)
- pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
- if(current->VDisplay > pSiS->LCDheight)
- pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
-
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "\tAdding \"%s\" to list of built-in modes\n", current->name);
-
- }
- done = TRUE;
- break;
- }
- }
- }
-
- i++;
-
- }
-
- if(pSiS->SiS_Pr->CP_HaveCustomData) {
-
- for(i=0; i<7; i++) {
-
- if(pSiS->SiS_Pr->CP_DataValid[i]) {
-
- if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
-
- memset(new, 0, sizeof(DisplayModeRec));
- if(!(new->name = xalloc(10))) {
- xfree(new);
- return first;
- }
- if(!first) first = new;
- if(current) {
- current->next = new;
- new->prev = current;
- }
-
- current = new;
-
- sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
- pSiS->SiS_Pr->CP_VDisplay[i]);
-
- current->status = MODE_OK;
-
- current->type = M_T_BUILTIN;
-
- current->Clock = pSiS->SiS_Pr->CP_Clock[i];
- current->SynthClock = current->Clock;
-
- current->HDisplay = pSiS->SiS_Pr->CP_HDisplay[i];
- current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
- current->HSyncEnd = pSiS->SiS_Pr->CP_HSyncEnd[i];
- current->HTotal = pSiS->SiS_Pr->CP_HTotal[i];
-
- current->VDisplay = pSiS->SiS_Pr->CP_VDisplay[i];
- current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
- current->VSyncEnd = pSiS->SiS_Pr->CP_VSyncEnd[i];
- current->VTotal = pSiS->SiS_Pr->CP_VTotal[i];
-
- current->CrtcHDisplay = current->HDisplay;
- current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
- current->CrtcHSyncStart = current->HSyncStart;
- current->CrtcHSyncEnd = current->HSyncEnd;
- current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
- current->CrtcHTotal = current->HTotal;
-
- current->CrtcVDisplay = current->VDisplay;
- current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
- current->CrtcVSyncStart = current->VSyncStart;
- current->CrtcVSyncEnd = current->VSyncEnd;
- current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
- current->CrtcVTotal = current->VTotal;
-
- if(pSiS->SiS_Pr->CP_SyncValid[i]) {
- if(pSiS->SiS_Pr->CP_HSync_P[i])
- current->Flags |= V_PHSYNC;
- else
- current->Flags |= V_NHSYNC;
-
- if(pSiS->SiS_Pr->CP_VSync_P[i])
- current->Flags |= V_PVSYNC;
- else
- current->Flags |= V_NVSYNC;
- } else {
- /* No sync data? Use positive sync... */
- current->Flags |= V_PHSYNC;
- current->Flags |= V_PVSYNC;
- }
- }
- }
- }
-
- return first;
-
-}
-
-/* Translate a mode number into the VESA pendant */
-int
-SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
-{
- SISPtr pSiS = SISPTR(pScrn);
- int i = 0;
-
- /* Initialize our pointers */
- if(pSiS->VGAEngine == SIS_300_VGA) {
-#ifdef SIS300
- InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
- return -1;
-#endif
- } else if(pSiS->VGAEngine == SIS_315_VGA) {
-#ifdef SIS315H
- InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
-#else
- return -1;
+#ifdef SIS_LINUX_KERNEL
+ if(writeres) var->yres = yres = E;
+ var->upper_margin = D;
+ var->lower_margin = F;
+ var->vsync_len = C;
#endif
- } else return -1;
-
- if(modenumber <= 0x13) return modenumber;
-#ifdef SIS315H
- if(pSiS->ROM661New) {
- while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
- if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
- return (int)SiS_EModeIDTable661[i].Ext_VESAID;
- }
- i++;
- }
- } else {
+ if((xres == 320) && ((yres == 200) || (yres == 240))) {
+ /* Terrible hack, but correct CRTC data for
+ * these modes only produces a black screen...
+ * (HRE is 0, leading into a too large C and
+ * a negative D. The CRT controller does not
+ * seem to like correcting HRE to 50)
+ */
+#ifdef SIS_XORG_XF86
+ current->HDisplay = 320;
+ current->HSyncStart = 328;
+ current->HSyncEnd = 376;
+ current->HTotal = 400;
#endif
- while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) {
- if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) {
- return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID;
- }
- i++;
- }
-#ifdef SIS315H
- }
+#ifdef SIS_LINUX_KERNEL
+ var->left_margin = (400 - 376);
+ var->right_margin = (328 - 320);
+ var->hsync_len = (376 - 328);
#endif
- return -1;
-}
-/* Translate a new BIOS mode number into the driver's pendant */
-int
-SiSTranslateToOldMode(int modenumber)
-{
-#ifdef SIS315H
- int i = 0;
-
- while(SiS_EModeIDTable661[i].Ext_ModeID != 0xff) {
- if(SiS_EModeIDTable661[i].Ext_ModeID == modenumber) {
- if(SiS_EModeIDTable661[i].Ext_MyModeID)
- return (int)SiS_EModeIDTable661[i].Ext_MyModeID;
- else
- return modenumber;
- }
- i++;
}
-#endif
- return modenumber;
-}
-
-#endif /* Xfree86 */
-
-#ifdef LINUX_KERNEL
-int
-sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- unsigned char modeno, unsigned char rateindex)
-{
- USHORT ModeNo = modeno;
- USHORT ModeIdIndex = 0, ClockIndex = 0;
- USHORT RefreshRateTableIndex = 0;
- int Clock;
-
- if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
- InitTo300Pointer(SiS_Pr, HwInfo);
-#else
- return 65 * 1000;
-#endif
- } else {
-#ifdef SIS315H
- InitTo310Pointer(SiS_Pr, HwInfo);
-#else
- return 65 * 1000;
-#endif
- }
-
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
- printk(KERN_ERR "Could not find mode %x\n", ModeNo);
- return 65 * 1000;
- }
-
- RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
- RefreshRateTableIndex += (rateindex - 1);
- ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- ClockIndex &= 0x3F;
- }
- Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
-
- return(Clock);
-}
-
-BOOLEAN
-sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
-{
- USHORT ModeNo = modeno;
- USHORT ModeIdIndex = 0, CRT1Index = 0;
- USHORT RefreshRateTableIndex = 0;
- unsigned char sr_data, cr_data, cr_data2;
-
- if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
- InitTo300Pointer(SiS_Pr, HwInfo);
-#else
- return FALSE;
-#endif
- } else {
-#ifdef SIS315H
- InitTo310Pointer(SiS_Pr, HwInfo);
-#else
- return FALSE;
-#endif
- }
-
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
-
- RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
- RefreshRateTableIndex += (rateindex - 1);
- CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
- cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
- *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
- sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
- cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
- cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
- *vtotal = ((cr_data & 0xFF) |
- ((unsigned short)(cr_data2 & 0x01) << 8) |
- ((unsigned short)(cr_data2 & 0x20) << 4) |
- ((unsigned short)(sr_data & 0x01) << 10)) + 2;
-
- if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
- *vtotal *= 2;
-
- return TRUE;
}
-int
-sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- unsigned char modeno, unsigned char rateindex,
- struct fb_var_screeninfo *var)
-{
- USHORT ModeNo = modeno;
- USHORT ModeIdIndex = 0, index = 0;
- USHORT RefreshRateTableIndex = 0;
- unsigned short VRE, VBE, VRS, VBS, VDE, VT;
- unsigned short HRE, HBE, HRS, HBS, HDE, HT;
- unsigned char sr_data, cr_data, cr_data2, cr_data3;
- int A, B, C, D, E, F, temp, j;
-
- if(HwInfo->jChipType < SIS_315H) {
-#ifdef SIS300
- InitTo300Pointer(SiS_Pr, HwInfo);
-#else
- return 0;
-#endif
- } else {
-#ifdef SIS315H
- InitTo310Pointer(SiS_Pr, HwInfo);
-#else
- return 0;
-#endif
- }
-
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
-
- RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
- RefreshRateTableIndex += (rateindex - 1);
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14];
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0];
-
- /* Horizontal total */
- HT = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x03) << 8);
- A = HT + 5;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1];
-
- /* Horizontal display enable end */
- HDE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x0C) << 6);
- E = HDE + 1;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4];
-
- /* Horizontal retrace (=sync) start */
- HRS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0xC0) << 2);
- F = HRS - E - 3;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2];
-
- /* Horizontal blank start */
- HBS = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x30) << 4);
-
- sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15];
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3];
-
- cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5];
-
- /* Horizontal blank end */
- HBE = (cr_data & 0x1f) |
- ((unsigned short) (cr_data2 & 0x80) >> 2) |
- ((unsigned short) (sr_data & 0x03) << 6);
-
- /* Horizontal retrace (=sync) end */
- HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
- temp = HBE - ((E - 1) & 255);
- B = (temp > 0) ? temp : (temp + 256);
- temp = HRE - ((E + F + 3) & 63);
- C = (temp > 0) ? temp : (temp + 64);
-
- D = B - F - C;
-
- if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
- ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
- (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
-
- /* Terrible hack, but the correct CRTC data for
- * these modes only produces a black screen...
- */
- var->left_margin = (400 - 376);
- var->right_margin = (328 - 320);
- var->hsync_len = (376 - 328);
-
- } else {
-
- var->left_margin = D * 8;
- var->right_margin = F * 8;
- var->hsync_len = C * 8;
-
- }
-
- sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
-
- cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
-
- /* Vertical total */
- VT = (cr_data & 0xFF) |
- ((unsigned short) (cr_data2 & 0x01) << 8) |
- ((unsigned short)(cr_data2 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x01) << 10);
- A = VT + 2;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10];
-
- /* Vertical display enable end */
- VDE = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x02) << 7) |
- ((unsigned short) (cr_data2 & 0x40) << 3) |
- ((unsigned short) (sr_data & 0x02) << 9);
- E = VDE + 1;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8];
-
- /* Vertical retrace (=sync) start */
- VRS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x04) << 6) |
- ((unsigned short) (cr_data2 & 0x80) << 2) |
- ((unsigned short) (sr_data & 0x08) << 7);
- F = VRS + 1 - E;
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[11];
-
- cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
-
- /* Vertical blank start */
- VBS = (cr_data & 0xff) |
- ((unsigned short) (cr_data2 & 0x08) << 5) |
- ((unsigned short) (cr_data3 & 0x20) << 4) |
- ((unsigned short) (sr_data & 0x04) << 8);
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[12];
-
- /* Vertical blank end */
- VBE = (cr_data & 0xff) |
- ((unsigned short) (sr_data & 0x10) << 4);
- temp = VBE - ((E - 1) & 511);
- B = (temp > 0) ? temp : (temp + 512);
-
- cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9];
-
- /* Vertical retrace (=sync) end */
- VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
- temp = VRE - ((E + F - 1) & 31);
- C = (temp > 0) ? temp : (temp + 32);
-
- D = B - F - C;
-
- var->upper_margin = D;
- var->lower_margin = F;
- var->vsync_len = C;
-
- if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
- var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
- else
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
-
- if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
- var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
- else
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
-
- var->vmode = FB_VMODE_NONINTERLACED;
- if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
- var->vmode = FB_VMODE_INTERLACED;
- else {
- j = 0;
- while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
- if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
- SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
- if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
- var->vmode = FB_VMODE_DOUBLE;
- }
- break;
- }
- j++;
- }
- }
-
- if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-#if 0 /* Do this? */
- var->upper_margin <<= 1;
- var->lower_margin <<= 1;
- var->vsync_len <<= 1;
-#endif
- } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- var->upper_margin >>= 1;
- var->lower_margin >>= 1;
- var->vsync_len >>= 1;
- }
-
- return 1;
-}
-
-#endif
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 7e36b7ac147..634c0a9d219 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -3,7 +3,7 @@
/*
* Data and prototypes for init.c
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,18 +50,24 @@
*
*/
-#ifndef _INIT_
-#define _INIT_
+#ifndef _INIT_H_
+#define _INIT_H_
#include "osdef.h"
#include "initdef.h"
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
#include "sis.h"
+#define SIS_NEED_inSISREG
+#define SIS_NEED_inSISREGW
+#define SIS_NEED_inSISREGL
+#define SIS_NEED_outSISREG
+#define SIS_NEED_outSISREGW
+#define SIS_NEED_outSISREGL
#include "sis_regs.h"
#endif
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
#include "vgatypes.h"
#include "vstruct.h"
#ifdef SIS_CP
@@ -73,6 +79,10 @@
#include <asm/io.h>
#include <linux/fb.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
+#include "sis.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/sisfb.h>
#else
#include <video/sisfb.h>
@@ -80,44 +90,45 @@
#endif
/* Mode numbers */
-static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
-static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
-static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
-static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
-static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
-static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
-static const USHORT ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
-static const USHORT ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
-static const USHORT ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
-static const USHORT ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
-static const USHORT ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
-static const USHORT ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
-static const USHORT ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
-static const USHORT ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
-static const USHORT ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
-static const USHORT ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */
-static const USHORT ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
-static const USHORT ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
-static const USHORT ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
-static const USHORT ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
-static const USHORT ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
-static const USHORT ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
-static const USHORT ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
-static const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
-static const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
-static const USHORT ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
-static const USHORT ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
-static const USHORT ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
-static const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
-static const USHORT ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
-static const USHORT ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
-static const USHORT ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
-static const USHORT ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
-static const USHORT ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
-static const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
-static const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
-
-static const USHORT SiS_DRAMType[17][5]={
+static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
+static const unsigned short ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
+static const unsigned short ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
+static const unsigned short ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
+static const unsigned short ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
+static const unsigned short ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
+static const unsigned short ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62};
+static const unsigned short ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35};
+static const unsigned short ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36};
+static const unsigned short ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61};
+static const unsigned short ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76};
+static const unsigned short ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
+static const unsigned short ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
+static const unsigned short ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
+static const unsigned short ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
+static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; /* 315 series only */
+static const unsigned short ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
+static const unsigned short ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
+static const unsigned short ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
+static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65};
+static const unsigned short ModeIndex_1280x960[] = {0x7c, 0x7d, 0x00, 0x7e};
+static const unsigned short ModeIndex_1152x768[] = {0x23, 0x24, 0x00, 0x25}; /* 300 series only */
+static const unsigned short ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b};
+static const unsigned short ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
+static const unsigned short ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
+static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
+static const unsigned short ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
+static const unsigned short ModeIndex_1280x854[] = {0x1a, 0x1b, 0x00, 0x1c};
+static const unsigned short ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
+static const unsigned short ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
+static const unsigned short ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
+static const unsigned short ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
+static const unsigned short ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
+static const unsigned short ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
+static const unsigned short ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
+static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
+static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
+
+static const unsigned short SiS_DRAMType[17][5]={
{0x0C,0x0A,0x02,0x40,0x39},
{0x0D,0x0A,0x01,0x40,0x48},
{0x0C,0x09,0x02,0x20,0x35},
@@ -137,7 +148,7 @@ static const USHORT SiS_DRAMType[17][5]={
{0x09,0x08,0x01,0x01,0x00}
};
-static const USHORT SiS_SDRDRAM_TYPE[13][5] =
+static const unsigned short SiS_SDRDRAM_TYPE[13][5] =
{
{ 2,12, 9,64,0x35},
{ 1,13, 9,64,0x44},
@@ -154,7 +165,7 @@ static const USHORT SiS_SDRDRAM_TYPE[13][5] =
{ 1, 9, 8, 2,0x00}
};
-static const USHORT SiS_DDRDRAM_TYPE[4][5] =
+static const unsigned short SiS_DDRDRAM_TYPE[4][5] =
{
{ 2,12, 9,64,0x35},
{ 2,12, 8,32,0x31},
@@ -162,7 +173,7 @@ static const USHORT SiS_DDRDRAM_TYPE[4][5] =
{ 2, 9, 8, 4,0x01}
};
-static const USHORT SiS_MDA_DAC[] =
+static const unsigned char SiS_MDA_DAC[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -174,7 +185,7 @@ static const USHORT SiS_MDA_DAC[] =
0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
};
-static const USHORT SiS_CGA_DAC[] =
+static const unsigned char SiS_CGA_DAC[] =
{
0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -186,7 +197,7 @@ static const USHORT SiS_CGA_DAC[] =
0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
};
-static const USHORT SiS_EGA_DAC[] =
+static const unsigned char SiS_EGA_DAC[] =
{
0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -198,7 +209,7 @@ static const USHORT SiS_EGA_DAC[] =
0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
};
-static const USHORT SiS_VGA_DAC[] =
+static const unsigned char SiS_VGA_DAC[] =
{
0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -212,7 +223,31 @@ static const USHORT SiS_VGA_DAC[] =
0x0B,0x0C,0x0D,0x0F,0x10
};
-static const SiS_StResInfoStruct SiS_StResInfo[]=
+static const struct SiS_St SiS_SModeIDTable[] =
+{
+ {0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00,0x40},
+ {0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00,0x40},
+ {0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01,0x40},
+ {0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02,0x40},
+ {0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02,0x40},
+ {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40},
+ {0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04,0x40},
+ {0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05,0x40},
+ {0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03,0x40},
+ {0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03,0x40},
+ {0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04,0x40},
+ {0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05,0x40},
+ {0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05,0x40},
+ {0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05,0x40},
+ {0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05,0x40},
+ {0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05,0x40},
+ {0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04,0x40},
+ {0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05,0x40},
+ {0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05,0x40},
+ {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+
+static const struct SiS_StResInfo_S SiS_StResInfo[]=
{
{ 640,400},
{ 640,350},
@@ -221,7 +256,7 @@ static const SiS_StResInfoStruct SiS_StResInfo[]=
{ 640,480}
};
-static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
+static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
{
{ 320, 200, 8, 8}, /* 0x00 */
{ 320, 240, 8, 8}, /* 0x01 */
@@ -256,11 +291,12 @@ static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
{ 1280, 800, 8,16}, /* 0x1e */
{ 1920,1080, 8,16}, /* 0x1f */
{ 960, 540, 8,16}, /* 0x20 */
- { 960, 600, 8,16} /* 0x21 */
+ { 960, 600, 8,16}, /* 0x21 */
+ { 1280, 854, 8,16} /* 0x22 */
};
#if defined(SIS300) || defined(SIS315H)
-static const SiS_StandTableStruct SiS_StandTable[]=
+static const struct SiS_StandTable_S SiS_StandTable[]=
{
/* 0x00: MD_0_200 */
{
@@ -704,11 +740,11 @@ static const SiS_StandTableStruct SiS_StandTable[]=
/* SIS VIDEO BRIDGE ----------------------------------------- */
/**************************************************************/
-static const UCHAR SiS_SoftSetting = 0x30; /* RAM setting */
+static const unsigned char SiS_SoftSetting = 0x30; /* RAM setting */
-static const UCHAR SiS_OutputSelect = 0x40;
+static const unsigned char SiS_OutputSelect = 0x40;
-static const UCHAR SiS_NTSCTiming[] = {
+static const unsigned char SiS_NTSCTiming[] = {
0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -719,7 +755,7 @@ static const UCHAR SiS_NTSCTiming[] = {
0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
};
-static const UCHAR SiS_PALTiming[] = {
+static const unsigned char SiS_PALTiming[] = {
0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -730,8 +766,8 @@ static const UCHAR SiS_PALTiming[] = {
0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
};
-static const UCHAR SiS_HiTVExtTiming[] = {
- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+static const unsigned char SiS_HiTVExtTiming[] = {
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -741,8 +777,8 @@ static const UCHAR SiS_HiTVExtTiming[] = {
0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
};
-static const UCHAR SiS_HiTVSt1Timing[] = {
- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+static const unsigned char SiS_HiTVSt1Timing[] = {
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
@@ -752,8 +788,8 @@ static const UCHAR SiS_HiTVSt1Timing[] = {
0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
};
-static const UCHAR SiS_HiTVSt2Timing[] = {
- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+static const unsigned char SiS_HiTVSt2Timing[] = {
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
@@ -764,8 +800,8 @@ static const UCHAR SiS_HiTVSt2Timing[] = {
};
#if 0
-static const UCHAR SiS_HiTVTextTiming[] = {
- 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+static const unsigned char SiS_HiTVTextTiming[] = {
+ 0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
@@ -776,8 +812,8 @@ static const UCHAR SiS_HiTVTextTiming[] = {
};
#endif
-static const UCHAR SiS_HiTVGroup3Data[] = {
- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+static const unsigned char SiS_HiTVGroup3Data[] = {
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
@@ -787,8 +823,8 @@ static const UCHAR SiS_HiTVGroup3Data[] = {
0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
};
-static const UCHAR SiS_HiTVGroup3Simu[] = {
- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+static const unsigned char SiS_HiTVGroup3Simu[] = {
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
@@ -799,8 +835,8 @@ static const UCHAR SiS_HiTVGroup3Simu[] = {
};
#if 0
-static const UCHAR SiS_HiTVGroup3Text[] = {
- 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+static const unsigned char SiS_HiTVGroup3Text[] = {
+ 0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
@@ -811,136 +847,141 @@ static const UCHAR SiS_HiTVGroup3Text[] = {
};
#endif
-static const UCHAR SiS_NTSCPhase[] = {0x21,0xed,0xba,0x08};
-static const UCHAR SiS_PALPhase[] = {0x2a,0x05,0xe3,0x00};
-static const UCHAR SiS_PALMPhase[] = {0x21,0xE4,0x2E,0x9B};
-static const UCHAR SiS_PALNPhase[] = {0x21,0xF4,0x3E,0xBA};
-static const UCHAR SiS_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
-static const UCHAR SiS_PALPhase2[] = {0x2a,0x09,0x86,0xe9};
-static const UCHAR SiS_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4};
-static const UCHAR SiS_PALNPhase2[] = {0x21,0xF6,0x94,0x46};
-static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
-static const UCHAR SiS_SpecialPhaseM[]= {0x1e,0x83,0x0a,0xe0};
-static const UCHAR SiS_SpecialPhaseJ[]= {0x25,0xd4,0xfd,0x5e};
-
-static const SiS_TVDataStruct SiS_StPALData[] =
+static const struct SiS_TVData SiS_StPALData[] =
{
- { 1, 1, 864, 525,1270, 400, 100, 0, 760,0xf4,0xff,0x1c,0x22},
- { 1, 1, 864, 525,1270, 350, 100, 0, 760,0xf4,0xff,0x1c,0x22},
- { 1, 1, 864, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
- { 1, 1, 864, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
- { 1, 1, 864, 525,1270, 480, 50, 0, 760,0xf4,0xff,0x1c,0x22},
- { 1, 1, 864, 525,1270, 600, 50, 0, 0,0xf4,0xff,0x1c,0x22}
+ { 1, 1, 864, 525,1270, 400, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 350, 100, 0, 760, 0,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 864, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 864, 525,1270, 480, 50, 0, 760, 0,0xf4,0xff,0x1c,0x22},
+ { 1, 1, 864, 525,1270, 600, 50, 0, 0,0x300,0xf4,0xff,0x1c,0x22}
};
-static const SiS_TVDataStruct SiS_ExtPALData[] =
+static const struct SiS_TVData SiS_ExtPALData[] =
{
- { 27, 10, 848, 448,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
- { 108, 35, 848, 398,1270, 530, 50, 0, 50,0xf4,0xff,0x1c,0x22},
- { 12, 5, 954, 448,1270, 530, 50, 0, 50,0xf1,0x04,0x1f,0x18},
- { 9, 4, 960, 463,1644, 438, 50, 0, 50,0xf4,0x0b,0x1c,0x0a},
- { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
-/*{ 36, 25,1060, 648,1316, 530, 438, 0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */
- { 36, 25,1060, 648,1270, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 - better */
- { 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */
- { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
- { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
- { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a} /* 720x480 test */
+ { 27, 10, 848, 448,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22}, /* 640x400, 320x200 */
+ { 108, 35, 848, 398,1270, 530, 50, 0, 50, 0,0xf4,0xff,0x1c,0x22},
+ { 12, 5, 954, 448,1270, 530, 50, 0, 50, 0,0xf1,0x04,0x1f,0x18},
+ { 9, 4, 960, 463,1644, 438, 50, 0, 50, 0,0xf4,0x0b,0x1c,0x0a},
+ { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a}, /* 640x480, 320x240 */
+ { 36, 25,1060, 648,1270, 530, 438, 0, 438, 0,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 */
+ { 3, 2,1080, 619,1270, 540, 438, 0, 438, 0,0xf3,0x00,0x1d,0x20}, /* 720x576 */
+ { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
+ { 1, 1,1170, 821,1270, 520, 686, 0, 686, 0,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
+ { 9, 4, 848, 528,1270, 530, 0, 0, 50, 0,0xf5,0xfb,0x1b,0x2a} /* 720x480 */
};
-static const SiS_TVDataStruct SiS_StNTSCData[] =
+static const struct SiS_TVData SiS_StNTSCData[] =
{
- { 1, 1, 858, 525,1270, 400, 50, 0, 760,0xf1,0x04,0x1f,0x18},
- { 1, 1, 858, 525,1270, 350, 50, 0, 640,0xf1,0x04,0x1f,0x18},
- { 1, 1, 858, 525,1270, 400, 0, 0, 720,0xf1,0x04,0x1f,0x18},
- { 1, 1, 858, 525,1270, 350, 0, 0, 720,0xf4,0x0b,0x1c,0x0a},
- { 1, 1, 858, 525,1270, 480, 0, 0, 760,0xf1,0x04,0x1f,0x18}
+ { 1, 1, 858, 525,1270, 400, 50, 0, 760, 0,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 50, 0, 640, 0,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 400, 0, 0, 720, 0,0xf1,0x04,0x1f,0x18},
+ { 1, 1, 858, 525,1270, 350, 0, 0, 720, 0,0xf4,0x0b,0x1c,0x0a},
+ { 1, 1, 858, 525,1270, 480, 0, 0, 760, 0,0xf1,0x04,0x1f,0x18}
};
-static const SiS_TVDataStruct SiS_ExtNTSCData[] =
+static const struct SiS_TVData SiS_ExtNTSCData[] =
{
- { 143, 65, 858, 443,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
- { 88, 35, 858, 393,1270, 440, 171, 0, 171,0xf1,0x04,0x1f,0x18},
- { 143, 70, 924, 443,1270, 440, 92, 0, 92,0xf1,0x04,0x1f,0x18},
- { 143, 70, 924, 393,1270, 440, 92, 0, 92,0xf4,0x0b,0x1c,0x0a},
- { 143, 76, 836, 523,1270, 440, 224, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
- { 143, 120,1056, 643,1270, 440, 0, 128, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
-/*{ 2, 1, 858, 503,1270, 480, 0, 128, 0,0xee,0x0c,0x22,0x08},*/ /* 720x480 (old, from 650) */
- { 143, 76, 836, 523,1270, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
-/*{ 65, 64,1056, 791,1270, 480, 638, 0, 0,0xEE,0x0C,0x22,0x08} */ /* 1024x768 (525i) */
- { 1, 1,1100, 811,1412, 440, 0, 128, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */
- { 65, 64,1056, 791,1270, 480, 455, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+ { 143, 65, 858, 443,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18}, /* 640x400, 320x200 */
+ { 88, 35, 858, 393,1270, 440, 171, 0, 171, 0,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 443,1270, 440, 92, 0, 92, 0,0xf1,0x04,0x1f,0x18},
+ { 143, 70, 924, 393,1270, 440, 92, 0, 92, 0,0xf4,0x0b,0x1c,0x0a},
+ { 143, 76, 836, 523,1270, 440, 224, 0, 0, 0,0xf1,0x05,0x1f,0x16}, /* 640x480, 320x240 */
+ { 143, 120,1056, 643,1270, 440, 0, 1, 0, 0,0xf4,0x10,0x1c,0x00}, /* 800x600, 400x300 */
+ { 143, 76, 836, 523,1270, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 720x480 - BETTER (from 300 series) */
+ { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0xee,0x0c,0x22,0x08}, /* 1024x768 (525i) CORRECTED */
+#if 0 /* flimmert und ist unten abgeschnitten (NTSCHT, NTSC clock) */
+ { 65, 64,1056, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 0
+ { 1, 1,1100, 811,1412, 440, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 0
+ { 1, 1,1120, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 0
+ { 1, 1, 938, 821,1516, 420, 0, 1, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 0 /* zoom hin, unten abgeschnitten (NTSC2HT, NTSC1024 clock) */
+ { 1, 1,1072, 791,1270, 480, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 1 /* zu weit links (squeezed) (NTSC2HT, NTSC1024 clock) */
+ { 1, 1,1100, 846,1270, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
+#if 0 /* zu weit links, rechts abgeschnitten (NTSC2HT, NTSC1024 clock) */
+ { 1, 1,1100, 846,1412, 440, 455, 0, 0, 0,0x00,0x00,0x00,0x00} /* 1024x768 (525p) */
+#endif
};
-static const SiS_TVDataStruct SiS_StHiTVData[] = /* Slave + TVSimu */
+static const struct SiS_TVData SiS_StHiTVData[] = /* Slave + TVSimu */
{
- { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150,128, 0, 0x00,0x00,0x00,0x00}
+ { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x320, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x150, 1, 0, 0, 0, 0, 0, 0}
};
-static const SiS_TVDataStruct SiS_St2HiTVData[] = /* Slave */
+static const struct SiS_TVData SiS_St2HiTVData[] = /* Slave */
{
- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+ { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 1, 0x348,0x1e3,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x37c,0x233,0x2b2,0x2bc, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 5, 2, 0x348,0x233,0x670,0x3c0,0x08d, 1, 0, 0, 0, 0, 0, 0},
+ { 8, 5, 0x41a,0x2ab,0x670,0x3c0,0x17c, 1, 0, 0, 0, 0, 0, 0}
};
-static const SiS_TVDataStruct SiS_ExtHiTVData[] =
-{
- { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0x00,0x00,0x00,0x00},
- { 5, 1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
- { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
- { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
- { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x1024 */
- { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00}, /* 800x480 */
- { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x576 */
- { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0x00,0x00,0x00,0x00}, /* 1280x720 */
- { 137, 32, 0x3d4,0x233,0x663,0x3bf,0x143, 0, 0, 0x00,0x00,0x00,0x00} /* 960x600 */
+static const struct SiS_TVData SiS_ExtHiTVData[] =
+{ /* all ok */
+ { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 1, 0x348,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 1, 0x3c0,0x233,0x660,0x3c0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 5, 1, 0x348,0x233,0x670,0x3c0,0x166, 1, 0, 0, 0, 0, 0, 0}, /* 640x480 */
+ { 16, 5, 0x41a,0x2ab,0x670,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x600 */
+ { 25, 12, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 */
+ { 5, 4, 0x627,0x464,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x1024 */
+ { 4, 1, 0x41a,0x233,0x60c,0x3c0,0x143, 1, 0, 0, 0, 0, 0, 0}, /* 800x480 */
+ { 5, 2, 0x578,0x293,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 1024x576 */
+ { 8, 5, 0x6d6,0x323,0x670,0x3c0,0x128, 0, 0, 0, 0, 0, 0, 0}, /* 1280x720 */
+ { 8, 3, 0x4ec,0x353,0x670,0x3c0,0x032, 0, 0, 0, 0, 0, 0, 0}, /* 960x600 */
};
-static const SiS_TVDataStruct SiS_St525pData[] =
+static const struct SiS_TVData SiS_St525pData[] =
{
- { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00}
+ { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
+ { 1, 1, 0x6b4,0x20d,0x4f6,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ { 1, 1, 0x6b4,0x20d,0x4f6,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
+ { 1, 1, 0x6b4,0x20d,0x4f6,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
};
-static const SiS_TVDataStruct SiS_St750pData[] =
+static const struct SiS_TVData SiS_St750pData[] =
{
- { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0x00,0x00,0x00,0x00},
- { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0x00,0x00,0x00,0x00}
+ { 1, 1, 0x672,0x2ee,0x500,0x190, 50, 0, 0x2f8, 0, 0, 0, 0, 0},
+ { 1, 1, 0x672,0x2ee,0x500,0x15e, 50, 0, 0x280, 0, 0, 0, 0, 0},
+ { 1, 1, 0x672,0x2ee,0x500,0x190, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x672,0x2ee,0x500,0x15e, 0, 0, 0x2d0, 0, 0, 0, 0, 0},
+ { 1, 1, 0x672,0x2ee,0x500,0x1e0, 0, 0, 0x2f8, 0, 0, 0, 0, 0}
};
-static const SiS_TVDataStruct SiS_Ext750pData[] =
-{
- { 143, 65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
- { 88, 35, 0x35a,0x189,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
- { 18, 5, 0x339,0x1ae,0x500,0x2d0,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
- { 143, 70, 0x39c,0x189,0x4f6,0x1b8,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
- { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
- { 5, 4, 0x5d8,0x29e,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
- { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 720x480 test WORKS */
- { 68, 64, 0x55f,0x346,0x500,0x2a8,0x27e, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
- { 5, 2, 0x3a7,0x226,0x500,0x2a8, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x576 */
- { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 WORKS */
+static const struct SiS_TVData SiS_Ext750pData[] =
+{ /* all ok */
+ { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0}, /* 320x200/640x400 */
+ { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 1, 935, 470, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
+ { 24, 7, 935, 420, 1130, 680, 50, 0, 0, 0, 0, 0, 0, 0},
+ { 2, 1, 1100, 590, 1130, 640, 50, 0, 0, 0, 0, 0, 0, 0}, /* 640x480 */
+ { 3, 2, 1210, 690, 1130, 660, 50, 0, 0, 0, 0, 0, 0, 0}, /* 800x600 OK */
+ { 2, 1, 1100, 562, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720x480 OK */
+ { 1, 1, 1375, 878, 1130, 640, 638, 0, 0, 0, 0, 0, 0, 0}, /* 1024x768 OK */
+ { 5, 3, 1100, 675, 1130, 640, 0, 1, 0, 0, 0, 0, 0, 0}, /* 720/768x576 OK */
+ { 25, 24, 1496, 755, 1120, 680, 50, 0, 0, 0, 0, 0, 0, 0} /* 1280x720 OK */
};
-static const SiS_LCDDataStruct SiS_LCD1280x720Data[] = /* 2.03.00 */
+static const struct SiS_LCDData SiS_LCD1280x720Data[] = /* 2.03.00 */
{
{ 44, 15, 864, 430, 1408, 806 }, /* 640x400 */
{ 128, 35, 792, 385, 1408, 806 },
@@ -962,7 +1003,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x720Data[] = /* 2.03.00 */
* (Note: 1280x768_3 is now special for SiS301/NetVista
*/
-static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
+static const struct SiS_LCDData SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
{
{ 64, 21, 858, 434, 1408, 806 }, /* 640x400 */
{ 32, 9, 858, 372, 1408, 806 },
@@ -977,7 +1018,7 @@ static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] = /* 2.03.00 */
{ 16, 15, 1600, 750, 1600, 806 } /* 1280x720 - from Ext */
};
-static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
+static const struct SiS_LCDData SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
{
{ 16, 5, 960, 410, 1600, 806 }, /* 640x400 */
{ 64, 21, 1152, 364, 1600, 806 },
@@ -993,7 +1034,7 @@ static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] = /* 2.03.00 */
};
#if 0 /* Not used; _3 now reserved for NetVista (SiS301) */
-static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] =
+static const struct SiS_LCDData SiS_LCD1280x768_3Data[] =
{
{ 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
{ 128, 39, 884, 396, 1408, 806 }, /* ,640 */
@@ -1009,7 +1050,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] =
};
#endif
-static const SiS_LCDDataStruct SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
+static const struct SiS_LCDData SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
{
{ 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
{ 128, 49, 1232, 361, 1408, 816 },
@@ -1024,7 +1065,7 @@ static const SiS_LCDDataStruct SiS_LCD1280x800Data[] = /* 0.93.12a (TMDS) */
{ 0, 0, 0, 0, 0, 0 } /* 1280x720 */
};
-static const SiS_LCDDataStruct SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
+static const struct SiS_LCDData SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
{
{ 97, 42, 1344, 409, 1552, 812 }, /* 640x400 */
{ 97, 35, 1280, 358, 1552, 812 },
@@ -1039,7 +1080,42 @@ static const SiS_LCDDataStruct SiS_LCD1280x800_2Data[] = /* 2.03.00 (LVDS) */
{ 97, 90, 1600, 730, 1552, 812 } /* 1280x720 */
};
-static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
+#if 0
+static const struct SiS_LCDData SiS_LCD1280x800_3Data[] = /* 2.02.05a (LVDS); m250 */
+{
+ { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
+ { 128, 49, 1232, 361, 1408, 816 },
+ { 128, 51, 1122, 412, 1408, 816 },
+ { 128, 49, 1232, 361, 1408, 816 },
+ { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
+ { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
+ { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
+ { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
+ { 1, 1, 1408, 816, 1408, 816 }, /* 1280x800 */
+ { 0, 0, 0, 0, 0, 0 }, /* 1280x768 - patch index */
+ { 0, 0, 0, 0, 0, 0 } /* 1280x720 */
+};
+#endif
+
+static const struct SiS_LCDData SiS_LCD1280x854Data[] = /* 2.21.00CS (LVDS) */
+{
+ { 56, 15, 936, 410, 1664, 861 }, /* 640x400 */
+ { 64, 25, 1586, 355, 1664, 861 },
+ { 56, 15, 936, 410, 1664, 861 },
+ { 64, 25, 1586, 355, 1664, 861 },
+ { 91, 45, 1464, 485, 1664, 861 }, /* 640x480 */
+ { 182, 75, 976, 605, 1664, 861 }, /* 800x600 */
+ { 91, 66, 1342, 774, 1664, 861 }, /* 1024x768 */
+ { 0, 0, 0, 0, 0, 0 }, /* 1280x1024 */
+ { 26, 25, 1708, 807, 1664, 861 }, /* 1280x800 */
+ { 13, 12, 1708, 774, 1664, 861 }, /* 1280x768 - patch index */
+ { 52, 45, 1708, 725, 1664, 861 }, /* 1280x720 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1664, 861, 1664, 861 } /* 1280x854 */
+};
+
+static const struct SiS_LCDData SiS_LCD1280x960Data[] =
{
{ 9, 2, 800, 500, 1800, 1000 },
{ 9, 2, 800, 500, 1800, 1000 },
@@ -1049,10 +1125,15 @@ static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
{ 30, 11, 1056, 625, 1800, 1000 },
{ 5, 3, 1350, 800, 1800, 1000 },
{ 1, 1, 1576, 1050, 1576, 1050 },
- { 1, 1, 1800, 1000, 1800, 1000 }
+ { 1, 1, 1800, 1000, 1800, 1000 },
+ { 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 }
};
-static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
+static const struct SiS_LCDData SiS_StLCD1400x1050Data[] =
{
{ 211, 100, 2100, 408, 1688, 1066 },
{ 211, 64, 1536, 358, 1688, 1066 },
@@ -1062,10 +1143,15 @@ static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
{ 211, 72, 1008, 609, 1688, 1066 },
{ 211, 128, 1400, 776, 1688, 1066 },
{ 211, 205, 1680, 1041, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 }
+ { 1, 1, 1688, 1066, 1688, 1066 },
+ { 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 }
};
-static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
+static const struct SiS_LCDData SiS_ExtLCD1400x1050Data[] =
{
/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */
{ 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */
@@ -1080,10 +1166,13 @@ static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
{ 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
{ 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
{ 0, 0, 0, 0, 0, 0 }, /* kludge */
- { 211, 120, 1400, 730, 1688, 1066 } /* 1280x720 */
+ { 211, 120, 1400, 730, 1688, 1066 }, /* 1280x720 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
};
-static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] =
+static const struct SiS_LCDData SiS_LCD1680x1050Data[] =
{
{ 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */
{ 10, 3, 1710, 362, 1900, 1066 },
@@ -1097,10 +1186,11 @@ static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] =
{ 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch index */
{ 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */
{ 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch index */
- { 1, 1, 1900, 1066, 1900, 1066 } /* 12 1680x1050 */
+ { 1, 1, 1900, 1066, 1900, 1066 }, /* 12 1680x1050 */
+ { 0, 0, 0, 0, 0, 0 }
};
-static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
+static const struct SiS_LCDData SiS_StLCD1600x1200Data[] =
{
{27, 4, 800, 500, 2160, 1250 },
{27, 4, 800, 500, 2160, 1250 },
@@ -1111,10 +1201,14 @@ static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
{ 5, 2,1350, 800, 2160, 1250 },
{135,88,1600,1100, 2160, 1250 },
{72, 49,1680,1092, 2160, 1250 },
- { 1, 1,2160,1250, 2160, 1250 }
+ { 1, 1,2160,1250, 2160, 1250 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
};
-static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
+static const struct SiS_LCDData SiS_ExtLCD1600x1200Data[] =
{
{72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */
@@ -1127,10 +1221,14 @@ static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
{ 5, 2,1350, 800, 2160, 1250 },
{27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
{72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
- { 1, 1,2160,1250, 2160, 1250 }
+ { 1, 1,2160,1250, 2160, 1250 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
};
-static const SiS_LCDDataStruct SiS_NoScaleData[] =
+static const struct SiS_LCDData SiS_NoScaleData[] =
{
{ 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */
{ 1, 1, 800, 449, 800, 449 },
@@ -1162,14 +1260,18 @@ static const SiS_LCDDataStruct SiS_NoScaleData[] =
{ 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */
{ 1, 1,1104, 563,1104, 563 }, /* 0x1c: 960x540 */
{ 1, 1,1120, 618,1120, 618 }, /* 0x1d: 960x600 */
- { 1, 1,1408, 816,1408, 816 } /* 0x1f: 1280x800 (TMDS special) */
+ { 1, 1,1408, 816,1408, 816 }, /* 0x1f: 1280x800 (TMDS special) */
+ { 1, 1,1760,1235,1760,1235 }, /* 0x20: 1600x1200 for LCDA */
+ { 1, 1,2048,1320,2048,1320 }, /* 0x21: 1600x1200 for non-SiS LVDS */
+ { 1, 1,1664, 861,1664, 861 } /* 0x22: 1280x854 */
};
/**************************************************************/
/* LVDS ----------------------------------------------------- */
/**************************************************************/
-static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]=
+/* FSTN/DSTN 320x240, 2 variants */
+static const struct SiS_LVDSData SiS_LVDS320x240Data_1[]=
{
{ 848, 433, 400, 525},
{ 848, 389, 400, 525},
@@ -1177,157 +1279,40 @@ static const SiS_LVDSDataStruct SiS_LVDS320x480Data_1[]=
{ 848, 389, 400, 525},
{ 848, 518, 400, 525},
{1056, 628, 400, 525},
- { 400, 525, 400, 525},
- { 800, 449,1000, 644},
- { 800, 525,1000, 635}
+ { 400, 525, 400, 525} /* xSTN */
};
-static const SiS_LVDSDataStruct SiS_LVDS640x480Data_1[]=
+static const struct SiS_LVDSData SiS_LVDS320x240Data_2[]=
{
- { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
+ { 800, 445, 800, 525},
{ 800, 395, 800, 525},
{ 800, 445, 800, 525},
{ 800, 395, 800, 525},
{ 800, 525, 800, 525},
- { 800, 525, 800, 525}, /* pseudo */
- { 800, 525, 800, 525} /* pseudo */
+ {1056, 628,1056, 628},
+ { 480, 525, 480, 525} /* xSTN */
};
-/* FSTN 320x240 */
-static const SiS_LVDSDataStruct SiS_LVDS640x480Data_2[]=
+static const struct SiS_LVDSData SiS_LVDS640x480Data_1[]=
{
- { 800, 445, 800, 525},
+ { 800, 445, 800, 525}, /* 800, 449, 800, 449 */
{ 800, 395, 800, 525},
{ 800, 445, 800, 525},
{ 800, 395, 800, 525},
- { 800, 525, 800, 525},
- { 800, 525, 800, 525}, /* pseudo */
- { 800, 525, 800, 525} /* pseudo */
+ { 800, 525, 800, 525}
};
-static const SiS_LVDSDataStruct SiS_LVDS800x600Data_1[]=
+static const struct SiS_LVDSData SiS_LVDS800x600Data_1[]=
{
{ 848, 433,1060, 629},
{ 848, 389,1060, 629},
{ 848, 433,1060, 629},
{ 848, 389,1060, 629},
{ 848, 518,1060, 629},
- {1056, 628,1056, 628},
{1056, 628,1056, 628}
};
-static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]=
-{
- {1056, 628,1056, 628}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]=
-{
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 518,1344, 806}, /* 640x480 */
- {1050, 638,1344, 806}, /* 800x600 */
- {1344, 806,1344, 806}, /* 1024x768 */
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]=
-{
- {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]=
-{
- {1048, 442,1688,1066},
- {1048, 392,1688,1066},
- {1048, 442,1688,1066},
- {1048, 392,1688,1066},
- {1048, 522,1688,1066},
- {1208, 642,1688,1066},
- {1432, 810,1688,1066},
- {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_2[]=
-{
- {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_1[]=
-{
- { 928, 416, 1688,1066},
- { 928, 366, 1688,1066},
- { 928, 416, 1688,1066},
- { 928, 366, 1688,1066},
- { 928, 496, 1688,1066},
- {1088, 616, 1688,1066},
- {1312, 784, 1688,1066},
- {1568,1040, 1688,1066},
- {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1400x1050Data_2[]=
-{
- {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_1[]=
-{
- {1088, 520, 2048,1320},
- {1088, 470, 2048,1320},
- {1088, 520, 2048,1320},
- {1088, 470, 2048,1320},
- {1088, 600, 2048,1320},
- {1248, 720, 2048,1320},
- {1472, 888, 2048,1320},
- {1728,1144, 2048,1320},
- {1848,1170, 2048,1320},
- {2048,1320, 2048,1320}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1600x1200Data_2[]=
-{
- {2048,1320, 2048,1320}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_1[]=
-{
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 518,1344, 806},
- {1050, 638,1344, 806},
- {1344, 806,1344, 806},
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x960Data_2[]=
-{
- {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_1[]=
-{
- { 768, 438, 1408, 806},
- { 768, 388, 1408, 806},
- { 768, 438, 1408, 806},
- { 768, 388, 1408, 806},
- { 768, 518, 1408, 806},
- { 928, 638, 1408, 806},
- {1152, 806, 1408, 806},
- {1408, 806, 1408, 806},
- {1408, 806, 1408, 806}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1280x768Data_2[]=
-{
- {1408, 806, 1408, 806}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
+static const struct SiS_LVDSData SiS_LVDS1024x600Data_1[] =
{
{ 840, 604,1344, 800},
{ 840, 560,1344, 800},
@@ -1338,124 +1323,18 @@ static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_1[] =
{1344, 800,1344, 800}
};
-static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] =
-{
- {1344, 800,1344, 800}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] =
+static const struct SiS_LVDSData SiS_LVDS1024x768Data_1[]=
{
{ 840, 438,1344, 806},
{ 840, 409,1344, 806},
{ 840, 438,1344, 806},
{ 840, 409,1344, 806},
- { 840, 518,1344, 806},
- {1050, 638,1344, 806},
- {1344, 806,1344, 806}
-};
-
-static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] =
-{
- {1344, 806,1344, 806}
-};
-
-/* Pass 1:1 data */
-static const SiS_LVDSDataStruct SiS_LVDSXXXxXXXData_1[]=
-{
- { 800, 449, 800, 449},
- { 800, 449, 800, 449},
- { 900, 449, 900, 449},
- { 900, 449, 900, 449},
- { 800, 525, 800, 525}, /* 640x480 */
- {1056, 628, 1056, 628}, /* 800x600 */
- {1344, 806, 1344, 806}, /* 1024x768 */
- {1688,1066, 1688,1066}, /* 1280x1024 */ /* INSERTED */
- {1688, 806, 1688, 806}, /* 1280x768 */
-};
-
-/* Custom data for Barco iQ R series */
-static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_1[]=
-{
- { 832, 438,1331, 806},
- { 832, 388,1331, 806},
- { 832, 438,1331, 806},
- { 832, 388,1331, 806},
- { 832, 518,1331, 806},
- {1050, 638,1344, 806},
- {1344, 806,1344, 806},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066} /* 1360x1024 */
-};
-
-/* Custom data for Barco iQ R series */
-static const SiS_LVDSDataStruct SiS_LVDSBARCO1366Data_2[]=
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066} /* 1360x1024 */
-};
-
-/* Custom data for Barco iQ G series */
-static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_1[]=
-{
- { 832, 438,1331, 806},
- { 832, 409,1331, 806},
- { 832, 438,1331, 806},
- { 832, 409,1331, 806},
- { 832, 518,1331, 806}, /* 640x480 */
+ { 840, 518,1344, 806}, /* 640x480 */
{1050, 638,1344, 806}, /* 800x600 */
{1344, 806,1344, 806}, /* 1024x768 */
};
-/* Custom data for Barco iQ G series */
-static const SiS_LVDSDataStruct SiS_LVDSBARCO1024Data_2[]=
-{
- {1344, 806,1344, 806}
-};
-
-/* Custom data for 848x480 parallel panel */
-static const SiS_LVDSDataStruct SiS_LVDS848x480Data_1[]=
-{
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- {1088, 525,1088, 525}, /* 640x480 TODO */
- {1088, 525,1088, 525}, /* 800x600 TODO */
- {1088, 525,1088, 525}, /* 1024x768 TODO */
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- {1088, 525,1088, 525}, /* 848x480 */
- {1088, 525,1088, 525} /* 1360x768 TODO */
-};
-
-/* Custom data for 848x480 parallel panel */
-static const SiS_LVDSDataStruct SiS_LVDS848x480Data_2[]=
-{
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- {1088, 525,1088, 525}, /* 640x480 */
- {1088, 525,1088, 525}, /* 800x600 */
- {1088, 525,1088, 525}, /* 1024x768 */
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- {1088, 525,1088, 525}, /* 848x480 */
- {1088, 525,1088, 525} /* 1360x768 TODO */
-};
-
-static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
+static const struct SiS_LVDSData SiS_CHTVUNTSCData[]=
{
{ 840, 600, 840, 600},
{ 840, 600, 840, 600},
@@ -1466,7 +1345,7 @@ static const SiS_LVDSDataStruct SiS_CHTVUNTSCData[]=
{1160, 945,1160, 945}
};
-static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]=
+static const struct SiS_LVDSData SiS_CHTVONTSCData[]=
{
{ 840, 525, 840, 525},
{ 840, 525, 840, 525},
@@ -1477,55 +1356,9 @@ static const SiS_LVDSDataStruct SiS_CHTVONTSCData[]=
{1160, 840,1160, 840}
};
-/* Chrontel TV Skew */
-
-static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS_CHTVONTSCDesData[]=
-{
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS_CHTVUPALDesData[]=
-{
- {256, 0},
- {256, 0},
- {256, 0},
- {256, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS_CHTVOPALDesData[]=
-{
- {256, 0},
- {256, 0},
- {256, 0},
- {256, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0}
-};
-
/* CRT1 CRTC data for slave modes */
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_1[] =
{
{{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1550,48 +1383,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1320x480_1[] =
0x00 }}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
- 0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_1_H[] =
-{
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
- 0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
- 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
- 0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
- 0x00}},
- {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
- 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
- 0x00}},
- {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
- 0x00}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2[] =
{
{{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
@@ -1611,12 +1403,17 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2[] =
{{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
0x01}},
+#if 0
{{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
0x00}}
+#endif
+ {{0x5f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xe8,0x0c,0x00,0x00,0x05,
+ 0x00}},
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_2_H[] =
{
{{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1641,7 +1438,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_2_H[] =
0x00}}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3[] =
{
{{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
@@ -1666,7 +1463,7 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3[] =
0x00}}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1320x240_3_H[] =
{
{{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -1691,778 +1488,175 @@ static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1640x480_3_H[] =
0x00}}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1[] =
-{
- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
- 0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
- 0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
- 0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
- 0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
- 0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
- 0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
- 0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
- 0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11024x600_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
- 0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1[] =
-{
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
- 0x00}},
- {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
- 0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_1_H[] =
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
- 0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
- 0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
- 0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
- 0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
- 0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
- 0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
- 0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2[] =
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11152x768_2_H[] =
-{
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
- 0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
- 0x00}},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
- 0xae,0x84,0x57,0x25,0x30,0x00,0x01,
- 0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1[] =
-{
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
- 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
- 0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
- 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
- 0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
- 0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
- 0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
- 0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
- 0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
- 0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
- 0x00}},
- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
- 0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
- 0x01}},
- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
- 0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_1_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1[] =
{
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
- 0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
- 0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
- 0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
- 0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
- 0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
- 0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
- 0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
- 0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
- 0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2[] =
-{
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
- 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
- 0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
- 0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
- 0x01}},
- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
- 0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
- 0x01}},
- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
0x01}}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT11280x768_2_H[] =
+static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
{
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
- 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
- 0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
- 0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+ 0x83,0x85,0x63,0xba,0x00,0x00,0x00,
0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
- 0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
- 0x01}},
- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
- 0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
- 0x01}},
- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
- 0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
- 0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
- 0x01}}
-};
-
-/**************************************************************/
-/* COMMON --------------------------------------------------- */
-/**************************************************************/
-
-#ifdef LINUX_XF86
-
-#define SIS_PL_HSYNCP 0x01
-#define SIS_PL_HSYNCN 0x02
-#define SIS_PL_VSYNCP 0x04
-#define SIS_PL_VSYNCN 0x08
-#define SIS_PL_DVI 0x80
-
-typedef struct _SiS_PlasmaModes
-{
- const char *name;
- ULONG clock;
- USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
- USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
- UCHAR SyncFlags;
-} SiS_PlasmaModes;
-
-typedef struct _SiS_PlasmaTables
-{
- USHORT vendor;
- UCHAR productnum;
- USHORT product[5];
- const char *DDCnames[5];
- const char *plasmaname;
- USHORT maxx,maxy;
- USHORT prefx, prefy;
- UCHAR modenum;
- UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */
-} SiS_PlasmaTables;
-
-static const SiS_PlasmaModes SiS_PlasmaMode[] = {
- { "640x400", /* 00: IBM 400@70 */
- 25175,
- 640, 800, 17, 64,
- 400, 449, 13, 2,
- SIS_PL_HSYNCN | SIS_PL_VSYNCN },
- { "640x480", /* 01: VESA 480@72 */
- 31500,
- 640, 832, 24, 40,
- 480, 520, 9, 3,
- SIS_PL_HSYNCN | SIS_PL_VSYNCN },
- { "800x600", /* 02: VESA 600@72 */
- 50000,
- 800, 1040, 56, 120,
- 600, 666, 37, 6,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "864x480", /* 03: Cereb wide 1 */
- 42526,
- 864, 1134, 22, 86,
- 480, 500, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCN },
- { "848x480", /* 04: VESA wide (NEC1) */
- 33750,
- 848, 1088, 16, 112,
- 480, 517, 6, 8,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1024x576", /* 05: VESA wide (NEC2) */
- 47250,
- 1024, 1320, 16, 144,
- 576, 596, 2, 4,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x720", /* 06: VESA wide (NEC3) */
- 76500,
- 1280, 1696, 48, 176,
- 720, 750, 4, 8,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1360x765", /* 07: VESA wide (NEC4) */
- 85500,
- 1360, 1792, 64, 176,
- 765, 795, 4, 8,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1024x600", /* 08: CEREB wide 2 */
- 51200,
- 1024, 1352, 51, 164,
- 600, 628, 1, 4,
- SIS_PL_HSYNCN | SIS_PL_VSYNCP },
- { "1024x768", /* 09: VESA 768@75 */
- 78750,
- 1024, 1312, 16, 96,
- 768, 800, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1152x864", /* 10: VESA 1152x864@75 */
- 108000,
- 1152, 1600, 64, 128,
- 864, 900, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x1024", /* 11: VESA 1024@60 */
- 108000,
- 1280, 1688, 48, 112,
- 1024, 1066, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x768", /* 12: W_XGA */
- 81000,
- 1280, 1688, 48, 112,
- 768, 802, 3, 6,
- SIS_PL_HSYNCP | SIS_PL_VSYNCN },
- { "1280x768", /* 13: I/O Data W_XGA@56Hz */
- 76064,
- 1280, 1688, 48, 112,
- 768, 802, 2, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1376x768", /* 14: I/O Wide XGA */
- 87340,
- 1376, 1808, 32, 128,
- 768, 806, 3, 6,
- SIS_PL_HSYNCN | SIS_PL_VSYNCP },
- { "1280x960", /* 15: VESA 960@60 */
- 108000,
- 1280, 1800, 96, 112,
- 960, 1000, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1400x1050", /* 16: VESA 1050@60Hz */
- 108000,
- 1400, 1688, 48, 112,
- 1050, 1066, 1, 3,
- SIS_PL_HSYNCN | SIS_PL_VSYNCN },
- { "1360x768", /* 17: VESA wide (NEC4/2) */
- 85500,
- 1360, 1792, 64, 112,
- 765, 795, 3, 6,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "800x600", /* 18: VESA 600@56 */
- 36000,
- 800, 1024, 24, 2,
- 600, 625, 1, 2,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1072x600", /* 19: Panasonic 1072x600 (sync?) */
- 54100,
- 1072, 1424, 48, 176,
- 600, 628, 16, 1,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "848x480", /* 20: Panasonic 848x480 (sync?) */
- 33070, /* is 852x480, but we can't use 852 */
- 848, 1068, 20, 40, /* differs from DDC data, better centered */
- 480, 516, 3, 5, /* won't work assumingly, because data is % 8 */
- SIS_PL_HSYNCN | SIS_PL_VSYNCN },
- { "1280x720", /* 21: WIDE720(60) (aka "750p") (Panasonic) */
- 74300,
- 1280, 1650,110, 40,
- 720, 750, 5, 5,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x768", /* 22: 1280x768@56.5 (Panasonic) */
- 76200, /* (According to manual not supported for HDMI; but works) */
- 1280, 1680, 16, 24,
- 768, 802, 2, 5,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x720@50", /* 23: WIDE720(50) (aka "750p") (Panasonic) */
- 74300, /* Panasonic states 45.0kHz. Not possible. This one works (with some overscan) */
- 1280, 1980,400, 80,
- 720, 750, 1, 2,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "720x480", /* 24: 720x480 (aka "525p" and "480p") (Panasonic) */
- 27000,
- 720, 856, 40, 32,
- 480, 525, 1, 3,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "720x576", /* 25: 720x576 (aka "625p"and "576p") (Panasonic) */
- 27500,
- 720, 864, 16, 64,
- 576, 625, 5, 6,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
- { "1280x720@50", /* 26: WIDE720(50) (aka "750p") (Generic) */
- 74300,
- 1280, 1980,400, 80,
- 720, 750, 5, 5,
- SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}}
};
-/*
-27.00 720 755 791 858 480 480 484 525
-27.50 720 732 795 864 576 581 587 625
-*/
-
-static const SiS_PlasmaTables SiS_PlasmaTable[] = {
-#if 0 /* Product IDs missing */
- { 0x38a3, 4,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
- 0, 0,
- 0, 0,
- 11, /* All DVI, except 0, 7, 13 */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
- 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
+BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
+#ifdef SIS_XORG_XF86
+unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
#endif
-#if 0 /* Product IDs missing */
- { 0x38a3, 3,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 42PD1/50PD1/50PD2",
- 0, 0,
- 0, 0,
- 5, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 42PD3",
- 0, 0,
- 0, 0,
- 10, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 2,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 42VM3/61XM1",
- 0, 0,
- 0, 0,
- 11, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
- 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 2,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 42MP1/42MP2",
- 0, 0,
- 0, 0,
- 6, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 50MP1",
- 0, 0,
- 0, 0,
- 10, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
+unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, BOOLEAN FSTN,
+ unsigned short CustomT, int LCDwith, int LCDheight,
+ unsigned int VBFlags2);
+unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, unsigned int VBFlags2);
+unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, unsigned int VBFlags2);
+
+void SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data);
+void SiS_SetRegByte(SISIOADDRESS port, unsigned short data);
+void SiS_SetRegShort(SISIOADDRESS port, unsigned short data);
+void SiS_SetRegLong(SISIOADDRESS port, unsigned int data);
+unsigned char SiS_GetReg(SISIOADDRESS port, unsigned short index);
+unsigned char SiS_GetRegByte(SISIOADDRESS port);
+unsigned short SiS_GetRegShort(SISIOADDRESS port);
+unsigned int SiS_GetRegLong(SISIOADDRESS port);
+void SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND,
+ unsigned short DataOR);
+void SiS_SetRegAND(SISIOADDRESS Port,unsigned short Index, unsigned short DataAND);
+void SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR);
+
+void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
+void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
+void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+#ifndef SIS_LINUX_KERNEL
+void SiSSetLVDSetc(struct SiS_Private *SiS_Pr);
#endif
- { 0x38a3, 4,
- { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
- { "PX-42VM", "", "", "", "" },
- "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
- 0, 0,
- 0, 0,
- 11, /* All DVI except 0, 7, 13, 17 */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
- 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
-#if 0 /* Product IDs missing */
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 3300W",
- 0, 0,
- 0, 0,
- 3,
- { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 4200W",
- 4, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0 , 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 4210W",
- 0, 0,
- 0, 0,
- 6, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x38a3, 1,
- { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "NEC PlasmaSync 5000W",
- 0, 0,
- 0, 0,
- 7, /* DVI entirely unknown */
- { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
-#endif
- { 0x412f, 2,
- { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "Pioneer 503CMX/PDA-5002",
- 0, 0,
- 0, 0,
- 6, /* DVI unknown */
- { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x34a9, 1,
- { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "", "", "", "", "" },
- "Panasonic TH-42",
- 0, 0,
- 0, 0,
- 5, /* No DVI output */
- { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x34a9, 1,
- { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "TH-42PW*4", "", "", "", "" },
- "Panasonic TH-42PW5",
- 0, 0,
- 0, 0,
- 1, /* No special modes otherwise; no DVI. */
- {20|0x40,19|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x4c2e, 1,
- { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "PLV-Z2", "", "", "", "" },
- "Sanyo PLV-Z2 (non HDCP-mode)", /* HDCP mode would be id 9b06, but not needed */
- 1280, 768, /* as it then advertises correct size */
- 1280, 720,
- 1, /* 1280x720, no special modes otherwise */
- {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x34a9, 1,
- { 0xd034, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "AE500U (DVI-D)", "", "", "", "" },
- "Panasonic AE500U",
- 1280, 768,
- 1280, 720,
- 1, /* 1280x720, no special modes otherwise */
- {21|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x34a9, 1,
- { 0xd043, 0x0000, 0x0000, 0x0000, 0x0000 },
- { "AE700U (HDMI)", "", "", "", "" },
- "Panasonic AE700U",
- 1360, 768,
- 1280, 720,
- 6, /* 1280x720/60, 1280x720/50, 1280x768@56(digital/analog), 720x480, 720x576 */
- {21|0xc0,23|0xc0,22|0x80,13|0x40,24|0x80,25|0x80, 0 , 0 , 0 , 0 ,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
- },
- { 0x0000 }
-};
+void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
+void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
+unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void SiS_GetVBType(struct SiS_Private *SiS_Pr);
#endif
-#ifdef LINUX_XF86
-USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+ unsigned short *ModeIdIndex);
+unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI);
+#ifdef SIS300
+void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
+ unsigned short *idx2);
+unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
+unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
#endif
-USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
- USHORT CustomT, int LCDwith, int LCDheight);
-USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-
-void SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data);
-void SiS_SetRegByte(SISIOADDRESS port, USHORT data);
-void SiS_SetRegShort(SISIOADDRESS port, USHORT data);
-void SiS_SetRegLong(SISIOADDRESS port, ULONG data);
-UCHAR SiS_GetReg(SISIOADDRESS port, USHORT index);
-UCHAR SiS_GetRegByte(SISIOADDRESS port);
-USHORT SiS_GetRegShort(SISIOADDRESS port);
-ULONG SiS_GetRegLong(SISIOADDRESS port);
-void SiS_SetRegANDOR(SISIOADDRESS Port, USHORT Index, USHORT DataAND, USHORT DataOR);
-void SiS_SetRegAND(SISIOADDRESS Port,USHORT Index, USHORT DataAND);
-void SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR);
-void SiS_DisplayOn(SiS_Private *SiS_Pr);
-void SiS_DisplayOff(SiS_Private *SiS_Pr);
-void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
-UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
-void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-
-#ifdef LINUX_XF86
-BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
-BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
-int SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
-int SiSTranslateToOldMode(int modenumber);
-BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
-USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
-DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
-int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy, int *prefx, int *prefy);
-void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
-#else
-BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
+void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+#ifdef SIS_XORG_XF86
+BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
+ BOOLEAN dosetpitch);
+BOOLEAN SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, BOOLEAN IsCustom);
+#endif
+#ifdef SIS_LINUX_KERNEL
+BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+#endif
+void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
+void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+#ifdef SIS_XORG_XF86
+void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+ int yres, DisplayModePtr current);
+#endif
+#ifdef SIS_LINUX_KERNEL
+void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+ int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
#endif
-#ifdef LINUX_KERNEL
-int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- UCHAR modeno, UCHAR rateindex);
-int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- UCHAR modeno, UCHAR rateindex,
- struct fb_var_screeninfo *var);
-BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- UCHAR modeno, int *htotal, int *vtotal, UCHAR rateindex);
+/* From init301.c: */
+extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, int chkcrt2mode);
+extern void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
+extern void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
+extern void SiS_DisableBridge(struct SiS_Private *);
+extern BOOLEAN SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
+extern unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
+extern unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI);
+extern BOOLEAN SiS_IsVAMode(struct SiS_Private *);
+extern BOOLEAN SiS_IsDualEdge(struct SiS_Private *);
+
+#ifdef SIS_XORG_XF86
+/* From other modules: */
+extern unsigned short SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned int VBFlags);
+extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset,
+ unsigned char value);
+extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned int VBFlags);
#endif
-/* init301.c: */
-extern void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, int chkcrt2mode);
-extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo);
-extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
-extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
-extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo);
-extern void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
-extern USHORT SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-extern USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-extern BOOLEAN SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
-extern BOOLEAN SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
-
-#ifdef LINUX_XF86
-/* From other sis driver modules: */
-extern int SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
- int *out_sbit, int *out_scale);
-extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
-
-extern UCHAR SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, UCHAR value);
-extern UCHAR SiS_GetSetModeID(ScrnInfoPtr pScrn, UCHAR id);
-extern USHORT SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ULONG VBFlags);
+#ifdef SIS_LINUX_KERNEL
+#ifdef SIS300
+extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
+ unsigned int val);
+#endif
+#ifdef SIS315H
+extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
+ unsigned char val);
+extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
+#endif
#endif
#endif
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 274dacd54bb..2d88f908170 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -2,11 +2,12 @@
/* $XdotOrg$ */
/*
* Mode initializing code (CRT2 section)
- * for SiS 300/305/540/630/730 and
- * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
+ * for SiS 300/305/540/630/730,
+ * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
+ * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -38,7 +39,7 @@
* * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
@@ -54,20 +55,20 @@
* Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
* Used by permission.
*
- * TW says: This code looks awful, I know. But please don't do anything about
- * this otherwise debugging will be hell.
- * The code is extremely fragile as regards the different chipsets, different
- * video bridges and combinations thereof. If anything is changed, extreme
- * care has to be taken that that change doesn't break it for other chipsets,
- * bridges or combinations thereof.
- * All comments in this file are by me, regardless if marked TW or not.
- *
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#if 1
#define SET_EMI /* 302LV/ELV: Set EMI values */
#endif
+#if 1
+#define SET_PWD /* 301/302LV: Set PWD */
+#endif
+
#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
@@ -85,26 +86,35 @@
#define SiS_I2CDELAY 1000
#define SiS_I2CDELAYSHORT 150
-static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
-static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx);
+static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
+#ifdef SIS_LINUX_KERNEL
+static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+#endif
/*********************************************/
/* HELPER: Lock/Unlock CRT2 */
/*********************************************/
void
-SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
{
- if(HwInfo->jChipType >= SIS_315H)
+ if(SiS_Pr->ChipType == XGI_20)
+ return;
+ else if(SiS_Pr->ChipType >= SIS_315H)
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
else
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
}
-static void
-SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_LockCRT2(struct SiS_Private *SiS_Pr)
{
- if(HwInfo->jChipType >= SIS_315H)
+ if(SiS_Pr->ChipType == XGI_20)
+ return;
+ else if(SiS_Pr->ChipType >= SIS_315H)
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
else
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
@@ -115,9 +125,9 @@ SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
+SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
{
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
DataAND &= 0x0f;
DataOR &= 0x0f;
}
@@ -129,12 +139,12 @@ SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, US
/*********************************************/
#ifdef SIS315H
-static UCHAR *
-GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned char *
+GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- UCHAR *myptr = NULL;
- USHORT romindex = 0, reg = 0, idx = 0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned char *myptr = NULL;
+ unsigned short romindex = 0, reg = 0, idx = 0;
/* Use the BIOS tables only for LVDS panels; TMDS is unreliable
* 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)
*/
if((SiS_Pr->SiS_ROMNew) &&
- ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+ ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
- if(HwInfo->jChipType < SIS_661) reg = 0x3c;
- else reg = 0x7d;
+ if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
+ else reg = 0x7d;
idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
if(idx < (8*26)) {
- myptr = (UCHAR *)&SiS_LCDStruct661[idx];
+ myptr = (unsigned char *)&SiS_LCDStruct661[idx];
}
romindex = SISGETROMW(0x100);
if(romindex) {
@@ -163,11 +173,11 @@ GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
return myptr;
}
-static USHORT
-GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr = 0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr = 0;
/* Use the BIOS tables only for LVDS panels; TMDS is unreliable
* 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)
*/
if((SiS_Pr->SiS_ROMNew) &&
- ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) || (!SiS_Pr->PanelSelfDetected))) {
+ ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
romptr = SISGETROMW(0x102);
romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
}
- return(romptr);
+ return romptr;
}
#endif
@@ -191,186 +201,187 @@ GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static BOOLEAN
-SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RRTI, USHORT *i, PSIS_HW_INFO HwInfo)
+SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RRTI, unsigned short *i)
{
- USHORT checkmask=0,modeid,infoflag;
+ unsigned short checkmask=0, modeid, infoflag;
- modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
+ modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- checkmask |= SupportRAMDAC2;
- if(HwInfo->jChipType >= SIS_315H) {
- checkmask |= SupportRAMDAC2_135;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- checkmask |= SupportRAMDAC2_162;
- if(SiS_Pr->SiS_VBType & VB_SIS301C) {
- checkmask |= SupportRAMDAC2_202;
- }
- }
- }
+ checkmask |= SupportRAMDAC2;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ checkmask |= SupportRAMDAC2_135;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ checkmask |= SupportRAMDAC2_162;
+ if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
+ checkmask |= SupportRAMDAC2_202;
+ }
+ }
+ }
- } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- checkmask |= SupportLCD;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(modeid == 0x2e) checkmask |= Support64048060Hz;
- }
- }
- }
+ checkmask |= SupportLCD;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(modeid == 0x2e) checkmask |= Support64048060Hz;
+ }
+ }
+ }
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- checkmask |= SupportHiVision;
+ checkmask |= SupportHiVision;
- } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+ } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
- checkmask |= SupportTV;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- checkmask |= SupportTV1024;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
- checkmask |= SupportYPbPr750p;
- }
- }
- }
+ checkmask |= SupportTV;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ checkmask |= SupportTV1024;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+ checkmask |= SupportYPbPr750p;
+ }
+ }
+ }
- }
+ }
- } else { /* LVDS */
+ } else { /* LVDS */
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- checkmask |= SupportCHTV;
- }
- }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ checkmask |= SupportCHTV;
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- checkmask |= SupportLCD;
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ checkmask |= SupportLCD;
+ }
- }
+ }
- /* Look backwards in table for matching CRT2 mode */
- for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
- infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
- if(infoflag & checkmask) return TRUE;
- if((*i) == 0) break;
- }
+ /* Look backwards in table for matching CRT2 mode */
+ for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
+ infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
+ if(infoflag & checkmask) return TRUE;
+ if((*i) == 0) break;
+ }
- /* Look through the whole mode-section of the table from the beginning
- * for a matching CRT2 mode if no mode was found yet.
- */
- for((*i) = 0; ; (*i)++) {
- if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
- infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
- if(infoflag & checkmask) return TRUE;
- }
- return FALSE;
+ /* Look through the whole mode-section of the table from the beginning
+ * for a matching CRT2 mode if no mode was found yet.
+ */
+ for((*i) = 0; ; (*i)++) {
+ if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
+ infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
+ if(infoflag & checkmask) return TRUE;
+ }
+ return FALSE;
}
/*********************************************/
/* Get rate index */
/*********************************************/
-USHORT
-SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
-{
- SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00 };
- USHORT RRTI,i,backup_i;
- USHORT modeflag,index,temp,backupindex;
+unsigned short
+SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
+{
+ unsigned short RRTI,i,backup_i;
+ unsigned short modeflag,index,temp,backupindex;
+ static const unsigned short LCDRefreshIndex[] = {
+ 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00
+ };
- /* Do NOT check for UseCustomMode here, will skrew up FIFO */
- if(ModeNo == 0xfe) return 0;
+ /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+ if(ModeNo == 0xfe) return 0;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(modeflag & HalfDCLK) return 0;
- }
- }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(modeflag & HalfDCLK) return 0;
+ }
+ }
- if(ModeNo < 0x14) return 0xFFFF;
+ if(ModeNo < 0x14) return 0xFFFF;
- index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
- backupindex = index;
+ index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
+ backupindex = index;
- if(index > 0) index--;
+ if(index > 0) index--;
- if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
- else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
- }
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
- temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
- if(index > temp) index = temp;
- }
- }
- } else {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
- }
- }
- }
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
+ else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+ temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
+ if(index > temp) index = temp;
+ }
+ }
+ } else {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
+ }
+ }
+ }
- RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
- ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
+ RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
- if(HwInfo->jChipType >= SIS_315H) {
- if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
- if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
- (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
- if(backupindex <= 1) RRTI++;
- }
- }
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+ if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+ (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
+ if(backupindex <= 1) RRTI++;
+ }
+ }
+ }
- i = 0;
- do {
- if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
- temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
- temp &= ModeTypeMask;
- if(temp < SiS_Pr->SiS_ModeType) break;
- i++;
- index--;
- } while(index != 0xFFFF);
-
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
- if(temp & InterlaceMode) i++;
- }
- }
+ i = 0;
+ do {
+ if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
+ temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
+ temp &= ModeTypeMask;
+ if(temp < SiS_Pr->SiS_ModeType) break;
+ i++;
+ index--;
+ } while(index != 0xFFFF);
+
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
+ if(temp & InterlaceMode) i++;
+ }
+ }
- i--;
+ i--;
- if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
- backup_i = i;
- if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i, HwInfo))) {
- i = backup_i;
- }
- }
+ if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
+ backup_i = i;
+ if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
+ i = backup_i;
+ }
+ }
- return(RRTI + i);
+ return (RRTI + i);
}
/*********************************************/
@@ -378,15 +389,15 @@ SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- USHORT temp1,temp2;
+ unsigned short temp1, temp2;
- /* Store CRT1 ModeNo in CR34 */
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
- temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
- temp2 = ~(SetInSlaveMode >> 8);
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
+ /* Store CRT1 ModeNo in CR34 */
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+ temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
}
/*********************************************/
@@ -395,35 +406,35 @@ SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
#ifdef SIS300
static BOOLEAN
-SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp,temp1;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short temp,temp1;
- if(SiS_Pr->SiS_UseROM) {
- if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
- temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
- temp1 = SISGETROMW(0x23b);
- if(temp1 & temp) return TRUE;
- }
- }
- return FALSE;
+ if(SiS_Pr->SiS_UseROM) {
+ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+ temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
+ temp1 = SISGETROMW(0x23b);
+ if(temp1 & temp) return TRUE;
+ }
+ }
+ return FALSE;
}
static BOOLEAN
-SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp,temp1;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short temp,temp1;
- if(SiS_Pr->SiS_UseROM) {
- if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
- temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
- temp1 = SISGETROMW(0x23d);
- if(temp1 & temp) return TRUE;
- }
- }
- return FALSE;
+ if(SiS_Pr->SiS_UseROM) {
+ if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+ temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
+ temp1 = SISGETROMW(0x23d);
+ if(temp1 & temp) return TRUE;
+ }
+ }
+ return FALSE;
}
#endif
@@ -432,85 +443,76 @@ SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
void
-SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
+SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
{
- USHORT i, j;
+ unsigned int i, j;
- for(i=0; i<delaytime; i++) {
- j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
- }
+ for(i = 0; i < delaytime; i++) {
+ j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+ }
}
#if defined(SIS300) || defined(SIS315H)
static void
-SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
- USHORT temp,flag;
-
- flag = SiS_GetRegByte(0x61) & 0x10;
-
- while(delay) {
- temp = SiS_GetRegByte(0x61) & 0x10;
- if(temp == flag) continue;
- flag = temp;
- delay--;
- }
+ SiS_DDC2Delay(SiS_Pr, delay * 36);
}
#endif
#ifdef SIS315H
static void
-SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
- while(delay--) {
- SiS_GenericDelay(SiS_Pr,0x19df);
- }
+ while(delay--) {
+ SiS_GenericDelay(SiS_Pr, 6623);
+ }
}
#endif
#if defined(SIS300) || defined(SIS315H)
static void
-SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
- while(delay--) {
- SiS_GenericDelay(SiS_Pr,0x42);
- }
+ while(delay--) {
+ SiS_GenericDelay(SiS_Pr, 66);
+ }
}
#endif
static void
-SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
+SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
{
#if defined(SIS300) || defined(SIS315H)
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT PanelID, DelayIndex, Delay=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short PanelID, DelayIndex, Delay=0;
#endif
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300
PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
+ if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
}
DelayIndex = PanelID >> 4;
if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
- Delay = 3;
+ Delay = 3;
} else {
- if(DelayTime >= 2) DelayTime -= 2;
- if(!(DelayTime & 0x01)) {
- Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
- } else {
- Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
- }
+ if(DelayTime >= 2) DelayTime -= 2;
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+ }
if(SiS_Pr->SiS_UseROM) {
- if(ROMAddr[0x220] & 0x40) {
- if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
- else Delay = (USHORT)ROMAddr[0x226];
- }
- }
+ if(ROMAddr[0x220] & 0x40) {
+ if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
+ else Delay = (unsigned short)ROMAddr[0x226];
+ }
+ }
}
SiS_ShortDelay(SiS_Pr, Delay);
@@ -520,23 +522,23 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
#ifdef SIS315H
- if((HwInfo->jChipType >= SIS_661) ||
- (HwInfo->jChipType <= SIS_315PRO) ||
- (HwInfo->jChipType == SIS_330) ||
+ if((SiS_Pr->ChipType >= SIS_661) ||
+ (SiS_Pr->ChipType <= SIS_315PRO) ||
+ (SiS_Pr->ChipType == SIS_330) ||
(SiS_Pr->SiS_ROMNew)) {
- if(!(DelayTime & 0x01)) {
+ if(!(DelayTime & 0x01)) {
SiS_DDC2Delay(SiS_Pr, 0x1000);
- } else {
+ } else {
SiS_DDC2Delay(SiS_Pr, 0x4000);
- }
+ }
} else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+ (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+ PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
}
@@ -546,35 +548,35 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
DelayIndex = PanelID >> 4;
}
if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
- Delay = 3;
- } else {
- if(DelayTime >= 2) DelayTime -= 2;
- if(!(DelayTime & 0x01)) {
- Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
- } else {
- Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
- }
+ Delay = 3;
+ } else {
+ if(DelayTime >= 2) DelayTime -= 2;
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+ }
if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
- if(ROMAddr[0x13c] & 0x40) {
- if(!(DelayTime & 0x01)) {
- Delay = (USHORT)ROMAddr[0x17e];
- } else {
- Delay = (USHORT)ROMAddr[0x17f];
- }
- }
- }
- }
+ if(ROMAddr[0x13c] & 0x40) {
+ if(!(DelayTime & 0x01)) {
+ Delay = (unsigned short)ROMAddr[0x17e];
+ } else {
+ Delay = (unsigned short)ROMAddr[0x17f];
+ }
+ }
+ }
+ }
SiS_ShortDelay(SiS_Pr, Delay);
}
} else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
- if(!(DelayTime & 0x01)) {
- Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
- } else {
- Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
- }
+ if(!(DelayTime & 0x01)) {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+ } else {
+ Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+ }
Delay <<= 8;
SiS_DDC2Delay(SiS_Pr, Delay);
@@ -587,12 +589,11 @@ SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
#ifdef SIS315H
static void
-SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT DelayTime, USHORT DelayLoop)
+SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
{
int i;
- for(i=0; i<DelayLoop; i++) {
- SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
+ for(i = 0; i < DelayLoop; i++) {
+ SiS_PanelDelay(SiS_Pr, DelayTime);
}
}
#endif
@@ -602,86 +603,86 @@ SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/*********************************************/
void
-SiS_WaitRetrace1(SiS_Private *SiS_Pr)
+SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
{
- USHORT watchdog;
+ unsigned short watchdog;
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
- if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
- watchdog = 65535;
- while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
- watchdog = 65535;
- while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+ watchdog = 65535;
+ while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+ watchdog = 65535;
+ while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
}
#if defined(SIS300) || defined(SIS315H)
static void
-SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
+SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
{
- USHORT watchdog;
+ unsigned short watchdog;
- watchdog = 65535;
- while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
- watchdog = 65535;
- while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
+ watchdog = 65535;
+ while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
+ watchdog = 65535;
+ while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
}
#endif
static void
-SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
{
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
- }
- if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
- SiS_WaitRetrace1(SiS_Pr);
- } else {
- SiS_WaitRetrace2(SiS_Pr, 0x25);
- }
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
+ }
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
+ SiS_WaitRetrace1(SiS_Pr);
+ } else {
+ SiS_WaitRetrace2(SiS_Pr, 0x25);
+ }
#endif
- } else {
+ } else {
#ifdef SIS315H
- if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
- SiS_WaitRetrace1(SiS_Pr);
- } else {
- SiS_WaitRetrace2(SiS_Pr, 0x30);
- }
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
+ SiS_WaitRetrace1(SiS_Pr);
+ } else {
+ SiS_WaitRetrace2(SiS_Pr, 0x30);
+ }
#endif
- }
+ }
}
static void
-SiS_VBWait(SiS_Private *SiS_Pr)
+SiS_VBWait(struct SiS_Private *SiS_Pr)
{
- USHORT tempal,temp,i,j;
+ unsigned short tempal,temp,i,j;
- temp = 0;
- for(i=0; i<3; i++) {
- for(j=0; j<100; j++) {
- tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
- if(temp & 0x01) {
- if((tempal & 0x08)) continue;
- else break;
- } else {
- if(!(tempal & 0x08)) continue;
- else break;
- }
- }
- temp ^= 0x01;
- }
+ temp = 0;
+ for(i = 0; i < 3; i++) {
+ for(j = 0; j < 100; j++) {
+ tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
+ if(temp & 0x01) {
+ if((tempal & 0x08)) continue;
+ else break;
+ } else {
+ if(!(tempal & 0x08)) continue;
+ else break;
+ }
+ }
+ temp ^= 0x01;
+ }
}
static void
-SiS_VBLongWait(SiS_Private *SiS_Pr)
+SiS_VBLongWait(struct SiS_Private *SiS_Pr)
{
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SiS_VBWait(SiS_Pr);
- } else {
- SiS_WaitRetrace1(SiS_Pr);
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SiS_VBWait(SiS_Pr);
+ } else {
+ SiS_WaitRetrace1(SiS_Pr);
+ }
}
/*********************************************/
@@ -690,237 +691,225 @@ SiS_VBLongWait(SiS_Private *SiS_Pr)
#ifdef SIS300
static BOOLEAN
-SiS_Is301B(SiS_Private *SiS_Pr)
+SiS_Is301B(struct SiS_Private *SiS_Pr)
{
- if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
- return FALSE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
+ return FALSE;
}
#endif
static BOOLEAN
-SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
-
- if(HwInfo->jChipType == SIS_730) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
- if(flag & 0x20) return TRUE;
- }
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & 0x20) return TRUE;
- return FALSE;
+ if(SiS_Pr->ChipType == SIS_730) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
+ }
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
+ return FALSE;
}
BOOLEAN
-SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
- USHORT flag;
-
- if(HwInfo->jChipType >= SIS_315H) {
- if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & EnableDualEdge) return TRUE;
- }
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
+ }
+ }
#endif
- return FALSE;
+ return FALSE;
}
BOOLEAN
-SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsVAMode(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
- USHORT flag;
+ unsigned short flag;
- if(HwInfo->jChipType >= SIS_315H) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
+ }
#endif
- return FALSE;
+ return FALSE;
}
#ifdef SIS315H
static BOOLEAN
-SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
{
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
- return FALSE;
+ if(SiS_IsVAMode(SiS_Pr)) return TRUE;
+ if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
+ return FALSE;
}
#endif
static BOOLEAN
-SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsDualLink(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
- if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
- (SiS_IsVAMode(SiS_Pr, HwInfo))) {
- if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
- }
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if((SiS_CRT2IsLCD(SiS_Pr)) ||
+ (SiS_IsVAMode(SiS_Pr))) {
+ if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
+ }
+ }
#endif
- return FALSE;
+ return FALSE;
}
#ifdef SIS315H
static BOOLEAN
-SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_TVEnabled(struct SiS_Private *SiS_Pr)
{
- if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
- if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
- }
- return FALSE;
+ if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
+ if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+ if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
+ }
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_LCDAEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
{
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
- return FALSE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
{
- if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
- }
- return FALSE;
+ if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
+ }
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_IsNotM650orLater(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
- if(HwInfo->jChipType == SIS_650) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
- flag &= 0xF0;
- /* Check for revision != A0 only */
- if((flag == 0xe0) || (flag == 0xc0) ||
- (flag == 0xb0) || (flag == 0x90)) return FALSE;
- } else if(HwInfo->jChipType >= SIS_661) return FALSE;
- return TRUE;
+ if(SiS_Pr->ChipType == SIS_650) {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
+ /* Check for revision != A0 only */
+ if((flag == 0xe0) || (flag == 0xc0) ||
+ (flag == 0xb0) || (flag == 0x90)) return FALSE;
+ } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
+ return TRUE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
-
- if(HwInfo->jChipType >= SIS_315H) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
- }
- return FALSE;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ /* YPrPb = 0x08 */
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
+ }
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsChScart(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
-
- if(HwInfo->jChipType >= SIS_315H) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 */
- }
- return FALSE;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ /* Scart = 0x04 */
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
+ }
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
- if(HwInfo->jChipType >= SIS_315H) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToTV) return TRUE;
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
- if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
- } else {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToTV) return TRUE;
- }
- return FALSE;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToTV) return TRUE;
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
+ if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
+ } else {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToTV) return TRUE;
+ }
+ return FALSE;
}
#endif
#ifdef SIS315H
static BOOLEAN
-SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
- if(HwInfo->jChipType >= SIS_315H) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToLCD) return TRUE;
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & SetToLCDA) return TRUE;
- } else {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToLCD) return TRUE;
- }
- return FALSE;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToLCD) return TRUE;
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ if(flag & SetToLCDA) return TRUE;
+ } else {
+ flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(flag & SetCRT2ToLCD) return TRUE;
+ }
+ return FALSE;
}
#endif
static BOOLEAN
-SiS_BridgeIsOn(SiS_Private *SiS_Pr)
+SiS_HaveBridge(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- return TRUE;
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
- if((flag == 1) || (flag == 2)) return TRUE;
- }
- return FALSE;
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ return TRUE;
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+ if((flag == 1) || (flag == 2)) return TRUE;
+ }
+ return FALSE;
}
static BOOLEAN
-SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
- if(SiS_BridgeIsOn(SiS_Pr)) {
- flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- if(HwInfo->jChipType < SIS_315H) {
- flag &= 0xa0;
- if((flag == 0x80) || (flag == 0x20)) return TRUE;
- } else {
- flag &= 0x50;
- if((flag == 0x40) || (flag == 0x10)) return TRUE;
- }
- }
- return FALSE;
+ if(SiS_HaveBridge(SiS_Pr)) {
+ flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+ if(SiS_Pr->ChipType < SIS_315H) {
+ flag &= 0xa0;
+ if((flag == 0x80) || (flag == 0x20)) return TRUE;
+ } else {
+ flag &= 0x50;
+ if((flag == 0x40) || (flag == 0x10)) return TRUE;
+ }
+ }
+ return FALSE;
}
static BOOLEAN
-SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
+SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
{
- USHORT flag1;
+ unsigned short flag1;
- flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
- if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
- return FALSE;
+ flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+ if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
+ return FALSE;
}
/*********************************************/
@@ -928,119 +917,97 @@ SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
/*********************************************/
/* Setup general purpose IO for Chrontel communication */
+#ifdef SIS300
void
-SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
+SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
{
- unsigned long acpibase;
+ unsigned int acpibase;
unsigned short temp;
if(!(SiS_Pr->SiS_ChSW)) return;
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
- acpibase = SiS_GetRegLong(0xcfc);
+#ifdef SIS_LINUX_KERNEL
+ acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
#else
acpibase = pciReadLong(0x00000800, 0x74);
#endif
acpibase &= 0xFFFF;
- temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
+ if(!acpibase) return;
+ temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
temp &= 0xFEFF;
- SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
- temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
- temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
+ SiS_SetRegShort((acpibase + 0x3c), temp);
+ temp = SiS_GetRegShort((acpibase + 0x3c));
+ temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
temp &= 0xFEFF;
if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
- SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
- temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
+ SiS_SetRegShort((acpibase + 0x3a), temp);
+ temp = SiS_GetRegShort((acpibase + 0x3a));
}
+#endif
void
-SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, int checkcrt2mode)
+SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, int checkcrt2mode)
{
- USHORT tempax,tempbx,temp;
- USHORT modeflag, resinfo=0;
+ unsigned short tempax, tempbx, temp;
+ unsigned short modeflag, resinfo = 0;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
+ SiS_Pr->SiS_SetFlag = 0;
- SiS_Pr->SiS_SetFlag = 0;
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
+ SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
- tempbx = 0;
- if(SiS_BridgeIsOn(SiS_Pr)) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
-#if 0
- if(HwInfo->jChipType < SIS_661) {
- /* NO - YPbPr not set yet ! */
- if(SiS_Pr->SiS_YPbPr & <all ypbpr except 525i>) {
- temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
- temp |= SetCRT2ToHiVision; /* 0x80 */
- }
- if(SiS_Pr->SiS_YPbPr & <ypbpr525i>) {
- temp &= (SetCRT2ToHiVision | SwitchCRT2 | SetSimuScanMode); /* 0x83 */
- temp |= SetCRT2ToSVIDEO; /* 0x08 */
- }
- }
-#endif
- tempbx |= temp;
- tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
- tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
- tempbx |= tempax;
+ if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ tempbx = 0;
+
+ if(SiS_HaveBridge(SiS_Pr)) {
+
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ tempbx |= temp;
+ tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
+ tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
+ tempbx |= tempax;
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
if(ModeNo == 0x03) {
- /* Mode 0x03 is never in driver mode */
+ /* Mode 0x03 is never in driver mode */
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
}
if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
- /* Reset LCDA setting if not driver mode */
+ /* Reset LCDA setting if not driver mode */
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
}
if(IS_SIS650) {
- if(SiS_Pr->SiS_UseLCDA) {
+ if(SiS_Pr->SiS_UseLCDA) {
if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
}
}
}
}
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
- tempbx |= SetCRT2ToLCDA;
+ if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
+ tempbx |= SetCRT2ToLCDA;
}
}
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
- tempbx &= ~(SetCRT2ToRAMDAC);
- }
-
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
- if(temp & 0x04) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
- if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
- else tempbx |= SetCRT2ToYPbPr525750;
- }
- } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) {
- if(temp & 0x04) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
- if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
+ if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
+ else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+ tempbx |= SetCRT2ToYPbPr525750;
}
}
- }
+ }
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
@@ -1048,7 +1015,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempbx |= SetCRT2ToLCDA;
}
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(temp & EnableCHYPbPr) {
+ if(temp & EnableCHYPbPr) {
tempbx |= SetCRT2ToCHYPbPr;
}
}
@@ -1057,44 +1024,49 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#endif /* SIS315H */
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
+ tempbx &= ~(SetCRT2ToRAMDAC);
+ }
+
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
temp = SetCRT2ToSVIDEO |
- SetCRT2ToAVIDEO |
- SetCRT2ToSCART |
- SetCRT2ToLCDA |
- SetCRT2ToLCD |
- SetCRT2ToRAMDAC |
- SetCRT2ToHiVision |
+ SetCRT2ToAVIDEO |
+ SetCRT2ToSCART |
+ SetCRT2ToLCDA |
+ SetCRT2ToLCD |
+ SetCRT2ToRAMDAC |
+ SetCRT2ToHiVision |
SetCRT2ToYPbPr525750;
- } else {
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- temp = SetCRT2ToAVIDEO |
+ } else {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ temp = SetCRT2ToAVIDEO |
SetCRT2ToSVIDEO |
SetCRT2ToSCART |
SetCRT2ToLCDA |
SetCRT2ToLCD |
SetCRT2ToCHYPbPr;
- } else {
- temp = SetCRT2ToLCDA |
+ } else {
+ temp = SetCRT2ToLCDA |
SetCRT2ToLCD;
}
} else {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- temp = SetCRT2ToTV | SetCRT2ToLCD;
- } else {
- temp = SetCRT2ToLCD;
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ temp = SetCRT2ToTV | SetCRT2ToLCD;
+ } else {
+ temp = SetCRT2ToLCD;
}
}
- }
+ }
+
+ if(!(tempbx & temp)) {
+ tempax = DisableCRT2Display;
+ tempbx = 0;
+ }
- if(!(tempbx & temp)) {
- tempax = DisableCRT2Display;
- tempbx = 0;
- }
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- USHORT clearmask = ( DriverMode |
+ unsigned short clearmask = ( DriverMode |
DisableCRT2Display |
LoadDACFlag |
SetNotSimuMode |
@@ -1102,106 +1074,104 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SetPALTV |
SwitchCRT2 |
SetSimuScanMode );
- if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
+
+ if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
- } else {
- if(HwInfo->jChipType >= SIS_315H) {
+
+ } else {
+
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(tempbx & SetCRT2ToLCDA) {
- tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
+ tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
}
}
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(tempbx & SetCRT2ToTV) {
- tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(tempbx & SetCRT2ToTV) {
+ tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
}
- }
- if(tempbx & SetCRT2ToLCD) {
- tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
}
- if(HwInfo->jChipType >= SIS_315H) {
+ if(tempbx & SetCRT2ToLCD) {
+ tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
+ }
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(tempbx & SetCRT2ToLCDA) {
tempbx |= SetCRT2ToLCD;
}
}
+
}
- if(tempax & DisableCRT2Display) {
- if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
- tempbx = SetSimuScanMode | DisableCRT2Display;
- }
- }
+ if(tempax & DisableCRT2Display) {
+ if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
+ tempbx = SetSimuScanMode | DisableCRT2Display;
+ }
+ }
- if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
+ if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
if(SiS_Pr->SiS_ModeType <= ModeVGA) {
if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
- modeflag &= (~CRT2Mode);
+ modeflag &= (~CRT2Mode);
}
}
- if(!(tempbx & SetSimuScanMode)) {
- if(tempbx & SwitchCRT2) {
- if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
- if( (HwInfo->jChipType >= SIS_315H) &&
- (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
- if(resinfo != SIS_RI_1600x1200) {
- tempbx |= SetSimuScanMode;
- }
- } else {
- tempbx |= SetSimuScanMode;
- }
+ if(!(tempbx & SetSimuScanMode)) {
+ if(tempbx & SwitchCRT2) {
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if(resinfo != SIS_RI_1600x1200) {
+ tempbx |= SetSimuScanMode;
+ }
}
- } else {
- if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
- if(!(tempbx & DriverMode)) {
- if(SiS_BridgeInSlavemode(SiS_Pr)) {
+ } else {
+ if(SiS_BridgeIsEnabled(SiS_Pr)) {
+ if(!(tempbx & DriverMode)) {
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
tempbx |= SetSimuScanMode;
- }
- }
- }
- }
- }
-
- if(!(tempbx & DisableCRT2Display)) {
- if(tempbx & DriverMode) {
- if(tempbx & SetSimuScanMode) {
- if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
- if( (HwInfo->jChipType >= SIS_315H) &&
- (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
- if(resinfo != SIS_RI_1600x1200) {
- tempbx |= SetInSlaveMode;
- }
- } else {
- tempbx |= SetInSlaveMode;
- }
- }
- }
- } else {
- tempbx |= SetInSlaveMode;
- }
- }
+ }
+ }
+ }
+ }
+ }
- }
+ if(!(tempbx & DisableCRT2Display)) {
+ if(tempbx & DriverMode) {
+ if(tempbx & SetSimuScanMode) {
+ if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+ if(resinfo != SIS_RI_1600x1200) {
+ tempbx |= SetInSlaveMode;
+ }
+ }
+ }
+ } else {
+ tempbx |= SetInSlaveMode;
+ }
+ }
- SiS_Pr->SiS_VBInfo = tempbx;
+ }
- if(HwInfo->jChipType == SIS_630) {
- SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
- }
+ SiS_Pr->SiS_VBInfo = tempbx;
-#ifdef TWDEBUG
-#ifdef LINUX_KERNEL
- printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
+#ifdef SIS300
+ if(SiS_Pr->ChipType == SIS_630) {
+ SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+ }
+#endif
+
+#ifdef SIS_LINUX_KERNEL
+#if 0
+ printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
#endif
-#ifdef LINUX_XF86
- xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
+#endif
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
#endif
#endif
@@ -1212,41 +1182,41 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
void
-SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
{
- UCHAR temp;
+ unsigned char temp;
- /* Note: This variable is only used on 30xLV systems.
- * CR38 has a different meaning on LVDS/CH7019 systems.
- * On 661 and later, these bits moved to CR35.
- *
- * On 301, 301B, only HiVision 1080i is supported.
- * On 30xLV, 301C, only YPbPr 1080i is supported.
- */
+ /* Note: This variable is only used on 30xLV systems.
+ * CR38 has a different meaning on LVDS/CH7019 systems.
+ * On 661 and later, these bits moved to CR35.
+ *
+ * On 301, 301B, only HiVision 1080i is supported.
+ * On 30xLV, 301C, only YPbPr 1080i is supported.
+ */
- SiS_Pr->SiS_YPbPr = 0;
- if(HwInfo->jChipType >= SIS_661) return;
+ SiS_Pr->SiS_YPbPr = 0;
+ if(SiS_Pr->ChipType >= SIS_661) return;
- if(SiS_Pr->SiS_VBType) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- SiS_Pr->SiS_YPbPr = YPbPrHiVision;
- }
- }
+ if(SiS_Pr->SiS_VBType) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ SiS_Pr->SiS_YPbPr = YPbPrHiVision;
+ }
+ }
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_SIS301C)) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(temp & 0x08) {
- switch((temp >> 4)) {
- case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
- case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
- case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
- case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
- }
- }
- }
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ if(temp & 0x08) {
+ switch((temp >> 4)) {
+ case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
+ case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
+ case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
+ case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
+ }
+ }
+ }
+ }
}
@@ -1255,199 +1225,204 @@ SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
void
-SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo)
+SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp, temp1, resinfo = 0, romindex = 0;
- UCHAR OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short temp, temp1, resinfo = 0, romindex = 0;
+ unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
- SiS_Pr->SiS_TVMode = 0;
+ SiS_Pr->SiS_TVMode = 0;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
- if(SiS_Pr->UseCustomMode) return;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
+ if(SiS_Pr->UseCustomMode) return;
- if(ModeNo > 0x13) {
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
+ if(ModeNo > 0x13) {
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
- if(HwInfo->jChipType < SIS_661) {
+ if(SiS_Pr->ChipType < SIS_661) {
- if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
+ if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- temp = 0;
- if((HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730)) {
- temp = 0x35;
- romindex = 0xfe;
- } else if(HwInfo->jChipType >= SIS_315H) {
- temp = 0x38;
- romindex = 0xf3;
- if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
- }
- if(temp) {
- if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
- OutputSelect = ROMAddr[romindex];
- if(!(OutputSelect & EnablePALMN)) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
- }
- }
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- if(temp1 & EnablePALM) { /* 0x40 */
- SiS_Pr->SiS_TVMode |= TVSetPALM;
- SiS_Pr->SiS_TVMode &= ~TVSetPAL;
- } else if(temp1 & EnablePALN) { /* 0x80 */
- SiS_Pr->SiS_TVMode |= TVSetPALN;
- }
- } else {
- if(temp1 & EnableNTSCJ) { /* 0x40 */
- SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
- }
- }
- }
- /* Translate HiVision/YPbPr to our new flags */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
- else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
- else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
- else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
- if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
- SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
- SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
- } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
- SiS_Pr->SiS_TVMode |= TVSetPAL;
- }
- }
- } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_CHOverScan) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
- SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
- }
- } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
- if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
- SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
- }
- }
- if(SiS_Pr->SiS_CHSOverScan) {
- SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
- }
- }
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
- else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
- } else {
- if(temp & EnableNTSCJ) {
- SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
- }
- }
- }
- }
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ temp = 0;
+ if((SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730)) {
+ temp = 0x35;
+ romindex = 0xfe;
+ } else if(SiS_Pr->ChipType >= SIS_315H) {
+ temp = 0x38;
+ if(SiS_Pr->ChipType < XGI_20) {
+ romindex = 0xf3;
+ if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
+ }
+ }
+ if(temp) {
+ if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
+ OutputSelect = ROMAddr[romindex];
+ if(!(OutputSelect & EnablePALMN)) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
+ }
+ }
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ if(temp1 & EnablePALM) { /* 0x40 */
+ SiS_Pr->SiS_TVMode |= TVSetPALM;
+ SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+ } else if(temp1 & EnablePALN) { /* 0x80 */
+ SiS_Pr->SiS_TVMode |= TVSetPALN;
+ }
+ } else {
+ if(temp1 & EnableNTSCJ) { /* 0x40 */
+ SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+ }
+ }
+ }
+ /* Translate HiVision/YPbPr to our new flags */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+ else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+ else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
+ else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+ if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
+ SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
+ SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
+ } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
+ SiS_Pr->SiS_TVMode |= TVSetPAL;
+ }
+ }
+ } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_CHOverScan) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+ if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
+ SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+ }
+ } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+ if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
+ SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+ }
+ }
+ if(SiS_Pr->SiS_CHSOverScan) {
+ SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+ }
+ }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
+ else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
+ } else {
+ if(temp & EnableNTSCJ) {
+ SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+ }
+ }
+ }
+ }
- } else { /* 661 and later */
+ } else { /* 661 and later */
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- if(temp1 & 0x01) {
- SiS_Pr->SiS_TVMode |= TVSetPAL;
- if(temp1 & 0x08) {
- SiS_Pr->SiS_TVMode |= TVSetPALN;
- } else if(temp1 & 0x04) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SiS_Pr->SiS_TVMode &= ~TVSetPAL;
- }
- SiS_Pr->SiS_TVMode |= TVSetPALM;
- }
- } else {
- if(temp1 & 0x02) {
- SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
- }
- }
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(SiS_Pr->SiS_CHOverScan) {
- if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
- SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
- }
- }
- }
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- temp1 &= 0xe0;
- if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
- else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
- else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
- }
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
- if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
- SiS_Pr->SiS_TVMode |= TVAspect169;
- } else {
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
- if(temp1 & 0x02) {
- if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
- SiS_Pr->SiS_TVMode |= TVAspect169;
- } else {
- SiS_Pr->SiS_TVMode |= TVAspect43LB;
- }
- } else {
- SiS_Pr->SiS_TVMode |= TVAspect43;
- }
- }
- }
- }
- }
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+ if(temp1 & 0x01) {
+ SiS_Pr->SiS_TVMode |= TVSetPAL;
+ if(temp1 & 0x08) {
+ SiS_Pr->SiS_TVMode |= TVSetPALN;
+ } else if(temp1 & 0x04) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ SiS_Pr->SiS_TVMode &= ~TVSetPAL;
+ }
+ SiS_Pr->SiS_TVMode |= TVSetPALM;
+ }
+ } else {
+ if(temp1 & 0x02) {
+ SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
+ }
+ }
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(SiS_Pr->SiS_CHOverScan) {
+ if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
+ SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ temp1 &= 0xe0;
+ if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
+ else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
+ else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
+ if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
+ SiS_Pr->SiS_TVMode |= TVAspect169;
+ } else {
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
+ if(temp1 & 0x02) {
+ if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
+ SiS_Pr->SiS_TVMode |= TVAspect169;
+ } else {
+ SiS_Pr->SiS_TVMode |= TVAspect43LB;
+ }
+ } else {
+ SiS_Pr->SiS_TVMode |= TVAspect43;
+ }
+ }
+ }
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- SiS_Pr->SiS_TVMode |= TVSetPAL;
- SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
- SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ SiS_Pr->SiS_TVMode |= TVSetPAL;
+ SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
+ SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
- SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+ }
+ }
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
- /* BIOS sets TVNTSC1024 without checking 525p here. Wrong? */
- if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr525p | TVSetYPbPr750p))) {
- if(resinfo == SIS_RI_1024x768) {
- SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
- }
- }
- }
+ if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+ if(resinfo == SIS_RI_1024x768) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+ SiS_Pr->SiS_TVMode |= TVSet525p1024;
+ } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
+ SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
+ }
+ }
+ }
- SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
- (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
- } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
- SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
- } else if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
- }
- }
+ SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
+ (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+ } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+ SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+ } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+ SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
+ }
+ }
- }
+ }
- SiS_Pr->SiS_VBInfo &= ~SetPALTV;
+ SiS_Pr->SiS_VBInfo &= ~SetPALTV;
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
+ xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
+#endif
#endif
}
@@ -1455,41 +1430,46 @@ SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_IN
/* GET LCD INFO */
/*********************************************/
-static USHORT
-SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
{
- USHORT temp = SiS_Pr->SiS_LCDResInfo;
+ unsigned short temp = SiS_Pr->SiS_LCDResInfo;
/* Translate my LCDResInfo to BIOS value */
- if(temp == Panel_1280x768_2) temp = Panel_1280x768;
- if(temp == Panel_1280x800_2) temp = Panel_1280x800;
+ switch(temp) {
+ case Panel_1280x768_2: temp = Panel_1280x768; break;
+ case Panel_1280x800_2: temp = Panel_1280x800; break;
+ case Panel_1280x854: temp = Panel661_1280x854; break;
+ }
return temp;
}
static void
-SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
- UCHAR *ROMAddr;
- USHORT temp;
+ unsigned char *ROMAddr;
+ unsigned short temp;
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
- SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+ SiS_Pr->PanelHT, SiS_Pr->PanelVT,
SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
#endif
+#endif
- if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
- SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->SiS_NeedRomModeData = TRUE;
SiS_Pr->PanelHT = temp;
}
if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
- SiS_Pr->SiS_NeedRomModeData = TRUE;
- SiS_Pr->PanelVT = temp;
+ SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->PanelVT = temp;
}
SiS_Pr->PanelHRS = SISGETROMW(10);
SiS_Pr->PanelHRE = SISGETROMW(12);
@@ -1497,56 +1477,58 @@ SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->PanelVRE = SISGETROMW(16);
SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
- SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
+ SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
- SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+ SiS_Pr->PanelHT, SiS_Pr->PanelVT,
SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
#endif
+#endif
}
#endif
}
static void
-SiS_CheckScaling(SiS_Private *SiS_Pr, USHORT resinfo, const UCHAR *nonscalingmodes)
-{
- int i = 0;
- while(nonscalingmodes[i] != 0xff) {
- if(nonscalingmodes[i++] == resinfo) {
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
- (SiS_Pr->UsePanelScaler == -1)) {
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- break;
- }
- }
+SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
+ const unsigned char *nonscalingmodes)
+{
+ int i = 0;
+ while(nonscalingmodes[i] != 0xff) {
+ if(nonscalingmodes[i++] == resinfo) {
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
+ (SiS_Pr->UsePanelScaler == -1)) {
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
+ }
+ }
}
void
-SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
+ unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
+ BOOLEAN panelcanscale = FALSE;
#ifdef SIS300
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- const unsigned char SiS300SeriesLCDRes[] =
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ static const unsigned char SiS300SeriesLCDRes[] =
{ 0, 1, 2, 3, 7, 4, 5, 8,
0, 0, 10, 0, 0, 0, 0, 15 };
#endif
#ifdef SIS315H
- UCHAR *myptr = NULL;
+ unsigned char *myptr = NULL;
#endif
- USHORT temp,modeflag,resinfo=0,modexres=0,modeyres=0;
- BOOLEAN panelcanscale = FALSE;
SiS_Pr->SiS_LCDResInfo = 0;
SiS_Pr->SiS_LCDTypeInfo = 0;
@@ -1557,14 +1539,14 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->PanelVRE = 999; /* VSync end */
SiS_Pr->SiS_NeedRomModeData = FALSE;
+ /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
+ SiS_Pr->Alternate1600x1200 = FALSE;
+
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
+
+ if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
@@ -1575,16 +1557,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* For broken BIOSes: Assume 1024x768 */
if(temp == 0) temp = 0x02;
- if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+ if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
- } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
+ } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
} else {
SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
}
temp &= 0x0f;
#ifdef SIS300
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
/* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
if(SiS_Pr->SiS_VBType & VB_SIS301) {
if(temp < 0x0f) temp &= 0x07;
@@ -1595,17 +1577,22 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#endif
/* Translate to our internal types */
- if(HwInfo->jChipType == SIS_550) {
- if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
- if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
+#ifdef SIS315H
+ if(SiS_Pr->ChipType == SIS_550) {
+ if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
+ else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
+ else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
+ } else if(SiS_Pr->ChipType >= SIS_661) {
+ if(temp == Panel661_1280x854) temp = Panel_1280x854;
}
+#endif
- if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
if(temp == Panel310_1280x768) {
temp = Panel_1280x768_2;
}
if(SiS_Pr->SiS_ROMNew) {
- if(temp == Panel661_1280x800) {
+ if(temp == Panel661_1280x800) {
temp = Panel_1280x800_2;
}
}
@@ -1613,13 +1600,17 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->SiS_LCDResInfo = temp;
+#ifdef SIS300
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
+ SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
- SiS_Pr->SiS_LCDResInfo = Panel_848x480;
+ SiS_Pr->SiS_LCDResInfo = Panel_848x480;
+ } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+ SiS_Pr->SiS_LCDResInfo = Panel_856x480;
}
}
+#endif
if(SiS_Pr->SiS_VBType & VB_SISVB) {
if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
@@ -1633,10 +1624,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
/* Need temp below! */
- /* These can't scale no matter what */
+ /* These must/can't scale no matter what */
switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_320x240_1:
+ case Panel_320x240_2:
+ case Panel_320x240_3:
case Panel_1280x960:
SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+ break;
+ case Panel_640x480:
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
}
panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
@@ -1646,41 +1643,41 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* Dual link, Pass 1:1 BIOS default, etc. */
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
}
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- if(SiS_Pr->SiS_ROMNew) {
+ if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+ if(SiS_Pr->SiS_ROMNew) {
if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
- } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
- if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
+ if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
}
}
- } else if(HwInfo->jChipType >= SIS_315H) {
+ } else if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
}
if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
- SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
+ SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+ if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
}
} else if(!(SiS_Pr->SiS_ROMNew)) {
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+ if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+ if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
SiS_Pr->SiS_LCDInfo |= LCDDualLink;
}
- if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
SiS_Pr->SiS_LCDInfo |= LCDDualLink;
}
- }
+ }
}
}
#endif
@@ -1691,12 +1688,12 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
- /* Always center screen on SiS LVDS (if scaling is disabled) */
- SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ /* Always center screen on SiS LVDS (if scaling is disabled) */
+ SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
} else {
- /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
- if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
- if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
+ if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
}
}
@@ -1704,19 +1701,15 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
switch(SiS_Pr->SiS_LCDResInfo) {
- case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
- SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
- SiS_Pr->PanelVCLKIdx300 = VCLK28;
- SiS_Pr->PanelVCLKIdx315 = VCLK28;
- break;
- case Panel_640x480_2:
- case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
- SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
+ case Panel_320x240_1:
+ case Panel_320x240_2:
+ case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx300 = VCLK28;
SiS_Pr->PanelVCLKIdx315 = VCLK28;
break;
case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
- SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx300 = VCLK28;
SiS_Pr->PanelVCLKIdx315 = VCLK28;
break;
@@ -1728,52 +1721,52 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->PanelVCLKIdx315 = VCLK40;
break;
case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
- SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
- SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
- break;
+ break;
case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
- SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
SiS_Pr->PanelHRS = 23;
- SiS_Pr->PanelVRE = 5;
+ SiS_Pr->PanelVRE = 5;
}
SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
- SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
- SiS_Pr->PanelHRS = 24;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
SiS_Pr->PanelHRS = 23;
- SiS_Pr->PanelVRE = 5;
+ SiS_Pr->PanelVRE = 5;
}
- SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
- break;
+ break;
case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
- break;
+ break;
case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
- SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
+ SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
/* Data above for TMDS (projector); get from BIOS for LVDS */
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
} else {
- SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
@@ -1781,77 +1774,100 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
break;
case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
- SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806;
SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
- SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
+ SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816;
SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24;
SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
- SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
+ SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812;
SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
+ break;
+ case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854;
+ SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861;
+ SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112;
+ SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
- SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
+ SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
- if(resinfo == SIS_RI_1280x1024) {
+ if(resinfo == SIS_RI_1280x1024) {
SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
}
break;
case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
- SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
- SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
- SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
- SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
+ SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235;
+ SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
+ SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
+ SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
+ SiS_Pr->Alternate1600x1200 = TRUE;
+ }
+ } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
+ SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
+ SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
+ SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
+ }
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
- SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
- SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ SiS_GetLCDInfoBIOS(SiS_Pr);
break;
case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
- SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
- break;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ break;
case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
- SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
- break;
+ SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
+ break;
+ case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
+ break;
case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
- SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
+ SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
SiS_Pr->PanelHT = SiS_Pr->CHTotal;
SiS_Pr->PanelVT = SiS_Pr->CVTotal;
if(SiS_Pr->CP_PreferredIndex != -1) {
SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
- SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
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,
SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
if(SiS_Pr->CP_PrefClock) {
- int idx;
- SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+ int idx;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
- if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
+ if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
else idx = VCLK_CUSTOM_315;
- SiS_Pr->SiS_VCLKData[idx].CLOCK =
- SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
- SiS_Pr->SiS_VCLKData[idx].SR2B =
- SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
- SiS_Pr->SiS_VCLKData[idx].SR2C =
- SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
+ SiS_Pr->SiS_VCLKData[idx].CLOCK =
+ SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
+ SiS_Pr->SiS_VCLKData[idx].SR2B =
+ SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
+ SiS_Pr->SiS_VCLKData[idx].SR2C =
+ SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
}
}
break;
default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
- SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
break;
}
@@ -1887,14 +1903,16 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
(SiS_Pr->SiS_IF_DEF_DSTN) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
SiS_Pr->PanelHRS = 999;
SiS_Pr->PanelHRE = 999;
}
if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
SiS_Pr->PanelVRS = 999;
SiS_Pr->PanelVRE = 999;
}
@@ -1912,18 +1930,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
case Panel_Custom:
case Panel_1152x864:
case Panel_1280x768: /* TMDS only */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
break;
case Panel_800x600: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
break;
}
case Panel_1024x768: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
0xff
@@ -1932,7 +1950,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
break;
}
case Panel_1280x720: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
0xff
@@ -1944,7 +1962,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
break;
}
case Panel_1280x768_2: { /* LVDS only */
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,0xff
@@ -1952,23 +1970,23 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
switch(resinfo) {
case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- break;
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
}
- break;
+ break;
}
case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
- break;
+ break;
}
case Panel_1280x800_2: { /* SiS LVDS */
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,0xff
@@ -1977,66 +1995,83 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
switch(resinfo) {
case SIS_RI_1280x720:
case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) {
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- break;
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
}
- break;
+ break;
+ }
+ case Panel_1280x854: { /* SiS LVDS */
+ static const unsigned char nonscalingmodes[] = {
+ SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
+ SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
+ SIS_RI_1152x768,0xff
+ };
+ SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
+ switch(resinfo) {
+ case SIS_RI_1280x720:
+ case SIS_RI_1280x768:
+ case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) {
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
+ }
+ break;
}
case Panel_1280x960: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
- 0xff
+ SIS_RI_1280x854,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
- break;
+ break;
}
case Panel_1280x1024: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
- SIS_RI_1280x960,0xff
+ SIS_RI_1280x854,SIS_RI_1280x960,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
break;
}
case Panel_1400x1050: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
- SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x960,
- 0xff
+ SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
+ SIS_RI_1280x960,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
- switch(resinfo) {
+ switch(resinfo) {
case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) {
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- break;
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- break;
+ break;
}
break;
}
case Panel_1600x1200: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
- SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
+ SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
- break;
+ break;
}
case Panel_1680x1050: {
- static const UCHAR nonscalingmodes[] = {
+ static const unsigned char nonscalingmodes[] = {
SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
- SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,
- 0xff
+ SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
+ SIS_RI_1360x1024,0xff
};
SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
break;
@@ -2044,25 +2079,25 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
}
+#ifdef SIS300
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
- SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
+ if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+ SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
}
}
-#ifdef SIS300
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
- if(!(ROMAddr[0x235] & 0x02)) {
- SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
- }
+ if(!(ROMAddr[0x235] & 0x02)) {
+ SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+ }
}
- }
- } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ }
+ } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
- SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+ SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
}
}
}
@@ -2080,7 +2115,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_640x480:
- SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
break;
case Panel_1280x800:
/* Don't pass 1:1 by default (TMDS special) */
@@ -2097,7 +2132,7 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
break;
}
- if(SiS_Pr->UseCustomMode) {
+ if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
}
@@ -2107,19 +2142,19 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
/* LVDS DDA */
- if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+ if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
if(ModeNo == 0x12) {
if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
}
} else if(ModeNo > 0x13) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
- SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
}
}
}
@@ -2128,18 +2163,18 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
if(modeflag & HalfDCLK) {
- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
} else if(ModeNo > 0x13) {
- if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
- if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
+ if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
}
}
@@ -2148,21 +2183,21 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* VESA timing */
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
- SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+ SiS_Pr->SiS_SetFlag |= LCDVESATiming;
}
} else {
SiS_Pr->SiS_SetFlag |= LCDVESATiming;
}
-#ifdef LINUX_KERNEL
-#ifdef TWDEBUG
+#ifdef SIS_LINUX_KERNEL
+#if 0
printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
#endif
#endif
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
xf86DrvMsgVerb(0, X_PROBED, 4,
- "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
+ "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
#endif
}
@@ -2171,45 +2206,46 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* GET VCLK */
/*********************************************/
-USHORT
-SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+unsigned short
+SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
- USHORT modeflag,resinfo,tempbx;
- const UCHAR *CHTVVCLKPtr = NULL;
+ unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
+ unsigned short modeflag, resinfo, tempbx;
+ const unsigned char *CHTVVCLKPtr = NULL;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
+ VCLKIndexGENCRT = VCLKIndexGEN;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
+ VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
+ (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
}
if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
- CRT2Index >>= 6;
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
+ CRT2Index >>= 6;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
VCLKIndex = SiS_Pr->PanelVCLKIdx300;
if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- VCLKIndex = VCLKIndexGEN;
+ VCLKIndex = VCLKIndexGEN;
}
} else {
VCLKIndex = SiS_Pr->PanelVCLKIdx315;
if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
switch(resinfo) {
- /* Only those whose IndexGEN doesn't match VBVCLK array */
- case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
+ /* Correct those whose IndexGEN doesn't match VBVCLK array */
case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
@@ -2218,18 +2254,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
+ case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
default: VCLKIndex = VCLKIndexGEN;
}
if(ModeNo <= 0x13) {
- if(HwInfo->jChipType <= SIS_315PRO) {
+ if(SiS_Pr->ChipType <= SIS_315PRO) {
if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
- } else {
+ } else {
if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
}
}
- if(HwInfo->jChipType <= SIS_315PRO) {
+ if(SiS_Pr->ChipType <= SIS_315PRO) {
if(VCLKIndex == 0) VCLKIndex = 0x41;
if(VCLKIndex == 1) VCLKIndex = 0x43;
if(VCLKIndex == 4) VCLKIndex = 0x44;
@@ -2237,49 +2274,46 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
}
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
- else VCLKIndex = HiTVVCLK;
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
- else VCLKIndex = HiTVTextVCLK;
- }
- } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
- else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
- else VCLKIndex = TVVCLK;
-
- if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
- else VCLKIndex += TVCLKBASE_315;
-
- } else { /* VGA2 */
-
- VCLKIndex = VCLKIndexGEN;
- if(HwInfo->jChipType < SIS_315H) {
- if(ModeNo > 0x13) {
- if( (HwInfo->jChipType == SIS_630) &&
- (HwInfo->jChipRevision >= 0x30)) {
+ if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
+ else VCLKIndex = HiTVVCLK;
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK;
+ } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
+ else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
+ else VCLKIndex = TVVCLK;
+
+ if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
+ else VCLKIndex += TVCLKBASE_315;
+
+ } else { /* VGA2 */
+
+ VCLKIndex = VCLKIndexGENCRT;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
+ if( (SiS_Pr->ChipType == SIS_630) &&
+ (SiS_Pr->ChipRevision >= 0x30)) {
if(VCLKIndex == 0x14) VCLKIndex = 0x34;
}
/* Better VGA2 clock for 1280x1024@75 */
if(VCLKIndex == 0x17) VCLKIndex = 0x45;
}
- }
- }
+ }
+ }
} else { /* If not programming CRT2 */
- VCLKIndex = VCLKIndexGEN;
- if(HwInfo->jChipType < SIS_315H) {
- if(ModeNo > 0x13) {
- if( (HwInfo->jChipType != SIS_630) &&
- (HwInfo->jChipType != SIS_300) ) {
+ VCLKIndex = VCLKIndexGENCRT;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
+ if( (SiS_Pr->ChipType != SIS_630) &&
+ (SiS_Pr->ChipType != SIS_300) ) {
if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
}
}
- }
+ }
}
} else { /* LVDS */
@@ -2288,12 +2322,12 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
- if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+ if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
VCLKIndex &= 0x1f;
- tempbx = 0;
+ tempbx = 0;
if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
tempbx += 2;
if(SiS_Pr->SiS_ModeType > ModeVGA) {
if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
@@ -2306,66 +2340,68 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
}
}
- switch(tempbx) {
- case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
- case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
- case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
- case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
+ switch(tempbx) {
+ case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break;
+ case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break;
+ case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break;
+ case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break;
- case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
- case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
- case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
+ case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break;
+ case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break;
+ case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break;
case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break;
default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break;
- }
- VCLKIndex = CHTVVCLKPtr[VCLKIndex];
+ }
+ VCLKIndex = CHTVVCLKPtr[VCLKIndex];
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
VCLKIndex = SiS_Pr->PanelVCLKIdx300;
} else {
VCLKIndex = SiS_Pr->PanelVCLKIdx315;
}
+#ifdef SIS300
/* Special Timing: Barco iQ Pro R series */
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
- /* Special Timing: 848x480 parallel lvds */
- if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
- if(HwInfo->jChipType < SIS_315H) {
+ /* Special Timing: 848x480 and 856x480 parallel lvds panels */
+ if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
+ if(SiS_Pr->ChipType < SIS_315H) {
VCLKIndex = VCLK34_300;
- /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
+ /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
} else {
VCLKIndex = VCLK34_315;
/* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
}
}
+#endif
- } else {
+ } else {
- VCLKIndex = VCLKIndexGEN;
- if(HwInfo->jChipType < SIS_315H) {
- if(ModeNo > 0x13) {
- if( (HwInfo->jChipType == SIS_630) &&
- (HwInfo->jChipRevision >= 0x30) ) {
+ VCLKIndex = VCLKIndexGENCRT;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
+ if( (SiS_Pr->ChipType == SIS_630) &&
+ (SiS_Pr->ChipRevision >= 0x30) ) {
if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
- }
- }
+ }
+ }
}
- }
+ }
} else { /* if not programming CRT2 */
- VCLKIndex = VCLKIndexGEN;
- if(HwInfo->jChipType < SIS_315H) {
- if(ModeNo > 0x13) {
- if( (HwInfo->jChipType != SIS_630) &&
- (HwInfo->jChipType != SIS_300) ) {
+ VCLKIndex = VCLKIndexGENCRT;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
+ if( (SiS_Pr->ChipType != SIS_630) &&
+ (SiS_Pr->ChipType != SIS_300) ) {
if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
}
#if 0
- if(HwInfo->jChipType == SIS_730) {
+ if(SiS_Pr->ChipType == SIS_730) {
if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */
if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */
}
@@ -2377,11 +2413,13 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
#endif
+#endif
- return(VCLKIndex);
+ return VCLKIndex;
}
/*********************************************/
@@ -2389,26 +2427,19 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT i,j,modeflag;
- USHORT tempcl,tempah=0;
+ unsigned short i, j, modeflag, tempah=0;
+ short tempcl;
#if defined(SIS300) || defined(SIS315H)
- USHORT tempbl;
+ unsigned short tempbl;
#endif
#ifdef SIS315H
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT tempah2, tempbl2;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short tempah2, tempbl2;
#endif
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
@@ -2418,18 +2449,18 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
} else {
for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
}
tempcl = SiS_Pr->SiS_ModeType;
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* ---- 300 series ---- */
- /* For 301BDH: (with LCD via LVDS) */
- if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ /* For 301BDH: (with LCD via LVDS) */
+ if(SiS_Pr->SiS_VBType & VB_NoLCD) {
tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
tempbl &= 0xef;
tempbl |= 0x02;
@@ -2438,16 +2469,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempbl &= 0xfd;
}
SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
- }
+ }
- if(ModeNo > 0x13) {
- tempcl -= ModeVGA;
- if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
- tempah = ((0x10 >> tempcl) | 0x80);
- }
- } else tempah = 0x80;
+ if(ModeNo > 0x13) {
+ tempcl -= ModeVGA;
+ if(tempcl >= 0) {
+ tempah = ((0x10 >> tempcl) | 0x80);
+ }
+ } else tempah = 0x80;
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
#endif /* SIS300 */
@@ -2455,22 +2486,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#ifdef SIS315H /* ------- 315/330 series ------ */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
- }
- }
-
- if(ModeNo > 0x13) {
- tempcl -= ModeVGA;
- if((tempcl > 0) || (tempcl == 0)) { /* tempcl is USHORT -> always true! */
- tempah = (0x08 >> tempcl);
- if (tempah == 0) tempah = 1;
- tempah |= 0x40;
- }
- } else tempah = 0x40;
+ if(ModeNo > 0x13) {
+ tempcl -= ModeVGA;
+ if(tempcl >= 0) {
+ tempah = (0x08 >> tempcl);
+ if (tempah == 0) tempah = 1;
+ tempah |= 0x40;
+ }
+ } else tempah = 0x40;
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
#endif /* SIS315H */
@@ -2478,84 +2503,89 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
- if(HwInfo->jChipType < SIS_315H) {
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
+ if(SiS_Pr->ChipType < SIS_315H) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
} else {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(IS_SIS740) {
+#ifdef SIS315H
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(IS_SIS740) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
} else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
}
- }
+ }
+#endif
}
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempah = 0x01;
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- tempah |= 0x02;
- }
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
- tempah ^= 0x05;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- tempah ^= 0x01;
- }
- }
+ tempah = 0x01;
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ tempah |= 0x02;
+ }
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ tempah ^= 0x05;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ tempah ^= 0x01;
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
+ if(SiS_Pr->ChipType < SIS_315H) {
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
- tempah = (tempah << 5) & 0xFF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
- tempah = (tempah >> 5) & 0xFF;
+ tempah = (tempah << 5) & 0xFF;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+ tempah = (tempah >> 5) & 0xFF;
- } else {
+ } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08;
+ else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
+ tempah &= ~0x08;
- }
+ }
- if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
- tempah |= 0x10;
- }
+ if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+ tempah |= 0x10;
+ }
tempah |= 0x80;
- if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
- }
+ }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- tempah |= 0x20;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ tempah |= 0x20;
}
- }
- }
+ }
+ }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
tempah = 0x80;
if(SiS_Pr->SiS_VBType & VB_SIS301) {
if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
}
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
+ if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
- tempah |= 0x40;
- }
- }
+ tempah |= 0x40;
+ }
+ }
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
} else { /* LVDS */
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
#ifdef SIS315H
/* LVDS can only be slave in 8bpp modes */
@@ -2566,36 +2596,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
}
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- tempah |= 0x02;
- }
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tempah ^= 0x01;
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01;
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- tempah = 1;
- }
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
#endif
- } else {
+ } else {
#ifdef SIS300
tempah = 0;
if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
- tempah |= 0x02;
- }
+ tempah |= 0x02;
+ }
tempah <<= 5;
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
#endif
- }
+ }
}
@@ -2603,10 +2627,10 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
#ifdef SIS315H
- unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+ /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
/* The following is nearly unpreditable and varies from machine
* 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,
/* 740 variants match for 30xB, 301B-DH, 30xLV */
- if(!(IS_SIS740)) {
- tempah = 0x04; /* For all bridges */
- tempbl = 0xfb;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- tempah = 0x00;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+ if(!(IS_SIS740)) {
+ tempah = 0x04; /* For all bridges */
+ tempbl = 0xfb;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr)) {
tempbl = 0xff;
}
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
}
/* The following two are responsible for eventually wrong colors
* in TV output. The DH (VB_NoLCD) conditions are unknown; the
* b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
* in a 650 box (Jake). What is the criteria?
+ * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
+ * treatment like the 651+301B-DH(b0) case. Seems more to be the
+ * chipset than the bridge revision.
*/
- if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+ if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
tempah = 0x30;
tempbl = 0xc0;
if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
@@ -2649,20 +2676,30 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
/* Fixes "TV-blue-bug" on 315+301 */
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
- } else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
- } else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xB-DH rev b0 (or "DH on 651"?) */
+ } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
+ } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */
+ tempah = 0x30; tempah2 = 0xc0;
+ tempbl = 0xcf; tempbl2 = 0x3f;
+ if(SiS_Pr->SiS_TVBlue == 0) {
+ tempah = tempah2 = 0x00;
+ } else if(SiS_Pr->SiS_TVBlue == -1) {
+ /* Set on 651/M650, clear on 315/650 */
+ if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
+ tempah = tempah2 = 0x00;
+ }
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
} else {
- tempah = 0x30; tempah2 = 0xc0; /* For 30xB (and 301BDH rev b1) */
+ tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */
tempbl = 0xcf; tempbl2 = 0x3f;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
tempah = tempah2 = 0x00;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+ if(SiS_IsDualEdge(SiS_Pr)) {
tempbl = tempbl2 = 0xff;
}
}
@@ -2676,23 +2713,23 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
} else {
tempah = 0x00;
- tempbl = 0x7f;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- tempbl = 0xff;
- if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+ tempbl = 0x7f;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+ if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
}
#endif /* SIS315H */
- } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
#ifdef SIS300
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
- if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
- ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+ if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+ ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
} else {
@@ -2702,9 +2739,9 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
- if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
}
}
@@ -2712,16 +2749,16 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
} else { /* LVDS */
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- tempah = 0x04;
+ tempah = 0x04;
tempbl = 0xfb;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- tempah = 0x00;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
- }
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ tempah = 0x00;
+ if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
+ }
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
@@ -2730,7 +2767,7 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
- } else if(HwInfo->jChipType == SIS_550) {
+ } else if(SiS_Pr->ChipType == SIS_550) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
@@ -2748,212 +2785,120 @@ SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* GET RESOLUTION DATA */
/*********************************************/
-USHORT
-SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+unsigned short
+SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
- else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
+ if(ModeNo <= 0x13)
+ return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
+ else
+ return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
}
static void
-SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT xres,yres,modeflag=0,resindex;
+ unsigned short xres, yres, modeflag=0, resindex;
- if(SiS_Pr->UseCustomMode) {
- xres = SiS_Pr->CHDisplay;
- if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
- SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
- yres = SiS_Pr->CVDisplay;
- if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
- SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
- return;
- }
-
- resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
+ if(SiS_Pr->UseCustomMode) {
+ xres = SiS_Pr->CHDisplay;
+ if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
+ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+ /* DoubleScanMode-check done in CheckCalcCustomMode()! */
+ SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+ return;
+ }
- if(ModeNo <= 0x13) {
- xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
- yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
- } else {
- xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
- yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
- if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
+ if(ModeNo <= 0x13) {
+ xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+ yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
+ } else {
+ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+ yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
- if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
- if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
- if(yres == 350) yres = 400;
- }
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
- if(ModeNo == 0x12) yres = 400;
- }
- }
+ if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
- if(modeflag & HalfDCLK) xres *= 2;
- if(modeflag & DoubleScanMode) yres *= 2;
+ if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+ if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+ if(yres == 350) yres = 400;
+ }
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+ if(ModeNo == 0x12) yres = 400;
+ }
+ }
- }
+ if(modeflag & HalfDCLK) xres <<= 1;
+ if(modeflag & DoubleScanMode) yres <<= 1;
- if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ }
-#if 0
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
- if(xres == 720) xres = 640;
- }
-#endif
+ if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- switch(SiS_Pr->SiS_LCDResInfo) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_1024x768:
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if(yres == 350) yres = 357;
- if(yres == 400) yres = 420;
- if(yres == 480) yres = 525;
- }
- }
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ if(yres == 350) yres = 357;
+ if(yres == 400) yres = 420;
+ if(yres == 480) yres = 525;
+ }
+ }
break;
case Panel_1280x1024:
if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
/* BIOS bug - does this regardless of scaling */
- if(yres == 400) yres = 405;
+ if(yres == 400) yres = 405;
+ }
+ if(yres == 350) yres = 360;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if(yres == 360) yres = 375;
}
- if(yres == 350) yres = 360;
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
- if(yres == 360) yres = 375;
- }
break;
case Panel_1600x1200:
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(yres == 1024) yres = 1056;
- }
+ if(yres == 1024) yres = 1056;
+ }
break;
- }
- }
+ }
+ }
- } else {
+ } else {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
- if(xres == 720) xres = 640;
- }
- } else if(xres == 720) xres = 640;
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
+ if(xres == 720) xres = 640;
+ }
+ } else if(xres == 720) xres = 640;
- if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- yres = 400;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
- } else {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
- }
- if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
- }
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+ yres = 400;
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+ } else {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+ }
+ if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
+ }
- }
- SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
- SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
+ }
+ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+ SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
}
/*********************************************/
/* GET CRT2 TIMING DATA */
/*********************************************/
-static BOOLEAN
-SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT *ResIndex,
- USHORT *DisplayType)
- {
- USHORT modeflag=0;
-
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
- }
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
- } else
- return FALSE;
-
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- (*ResIndex) &= 0x3F;
-
- if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
- (*DisplayType) = 18;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- (*DisplayType) += 2;
- if(SiS_Pr->SiS_ModeType > ModeVGA) {
- if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
- }
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- (*DisplayType) = 18; /* PALM uses NTSC data */
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
- } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- (*DisplayType) = 20; /* PALN uses PAL data */
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
- }
- }
- } else {
- switch(SiS_Pr->SiS_LCDResInfo) {
- case Panel_640x480: (*DisplayType) = 50; break;
- case Panel_640x480_2: (*DisplayType) = 52; break;
- case Panel_640x480_3: (*DisplayType) = 54; break;
- case Panel_800x600: (*DisplayType) = 0; break;
- case Panel_1024x600: (*DisplayType) = 23; break;
- case Panel_1024x768: (*DisplayType) = 4; break;
- case Panel_1152x768: (*DisplayType) = 27; break;
- case Panel_1280x768: (*DisplayType) = 40; break;
- case Panel_1280x1024: (*DisplayType) = 8; break;
- case Panel_1400x1050: (*DisplayType) = 14; break;
- case Panel_1600x1200: (*DisplayType) = 36; break;
- default: return FALSE;
- }
-
- if(modeflag & HalfDCLK) (*DisplayType)++;
-
- switch(SiS_Pr->SiS_LCDResInfo) {
- case Panel_640x480:
- case Panel_640x480_2:
- case Panel_640x480_3:
- break;
- default:
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
- }
-
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- (*DisplayType) = 12;
- if(modeflag & HalfDCLK) (*DisplayType)++;
- }
- }
-
-#if 0
- if(SiS_Pr->SiS_IF_DEF_FSTN) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
- (*DisplayType) = 22;
- }
- }
-#endif
-
- return TRUE;
-}
-
static void
-SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
- PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
+ unsigned short *ResIndex)
{
- USHORT tempbx=0,tempal=0,resinfo=0;
+ unsigned short tempbx=0, tempal=0, resinfo=0;
if(ModeNo <= 0x13) {
tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -2966,18 +2911,20 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
- tempbx = SiS_Pr->SiS_LCDResInfo;
+ tempbx = SiS_Pr->SiS_LCDResInfo;
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
+ /* patch index */
if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
if (resinfo == SIS_RI_1280x800) tempal = 9;
else if(resinfo == SIS_RI_1400x1050) tempal = 11;
} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2)) {
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
if (resinfo == SIS_RI_1280x768) tempal = 9;
}
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
/* Pass 1:1 only (center-screen handled outside) */
/* This is never called for the panel's native resolution */
/* since Pass1:1 will not be set in this case */
@@ -2991,8 +2938,8 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- tempbx = 200;
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+ tempbx = 200;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
}
}
}
@@ -3000,23 +2947,23 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
} else { /* TV */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
- tempbx = 2;
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
+ tempbx = 2;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
tempbx = 13;
- if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
- }
+ if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
+ }
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
- else tempbx = 5;
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
- } else {
- if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
- else tempbx = 4;
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
- }
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6;
+ else tempbx = 5;
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
+ } else {
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3;
+ else tempbx = 4;
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5;
+ }
}
@@ -3024,26 +2971,34 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(ModeNo > 0x13) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
- if(tempal == 6) tempal = 7;
- if((resinfo == SIS_RI_720x480) ||
- (resinfo == SIS_RI_720x576) ||
- (resinfo == SIS_RI_768x576)) {
+ switch(resinfo) {
+ case SIS_RI_720x480:
tempal = 6;
- if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
- if(resinfo == SIS_RI_720x480) tempal = 9;
+ if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9;
+ break;
+ case SIS_RI_720x576:
+ case SIS_RI_768x576:
+ case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
+ tempal = 6;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8;
}
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
- if(resinfo == SIS_RI_1024x768) tempal = 8;
+ break;
+ case SIS_RI_800x480:
+ tempal = 4;
+ break;
+ case SIS_RI_512x384:
+ case SIS_RI_1024x768:
+ tempal = 7;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8;
}
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
- if((resinfo == SIS_RI_720x576) ||
- (resinfo == SIS_RI_768x576)) {
- tempal = 8;
- }
- if(resinfo == SIS_RI_1280x720) tempal = 9;
+ break;
+ case SIS_RI_1280x720:
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9;
}
+ break;
}
}
}
@@ -3056,65 +3011,60 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
tempbx = 0;
if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
- tempbx = 10;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- tempbx += 2;
+ tempbx = 90;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ tempbx = 92;
if(SiS_Pr->SiS_ModeType > ModeVGA) {
if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
}
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- tempbx = 90;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- tempbx = 92;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- }
- }
+ if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94;
+ else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
+ }
+ if(tempbx != 99) {
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
+ }
} else {
- switch(SiS_Pr->SiS_LCDResInfo) {
- case Panel_640x480: tempbx = 6; break;
- case Panel_640x480_2:
- case Panel_640x480_3: tempbx = 30; break;
- case Panel_800x600: tempbx = 0; break;
- case Panel_1024x600: tempbx = 15; break;
- case Panel_1024x768: tempbx = 2; break;
- case Panel_1152x768: tempbx = 17; break;
- case Panel_1280x768: tempbx = 18; break;
- case Panel_1280x1024: tempbx = 4; break;
- case Panel_1400x1050: tempbx = 8; break;
- case Panel_1600x1200: tempbx = 21; break;
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480: tempbx = 12; break;
+ case Panel_320x240_1: tempbx = 10; break;
+ case Panel_320x240_2:
+ case Panel_320x240_3: tempbx = 14; break;
+ case Panel_800x600: tempbx = 16; break;
+ case Panel_1024x600: tempbx = 18; break;
+ case Panel_1152x768:
+ case Panel_1024x768: tempbx = 20; break;
+ case Panel_1280x768: tempbx = 22; break;
+ case Panel_1280x1024: tempbx = 24; break;
+ case Panel_1400x1050: tempbx = 26; break;
+ case Panel_1600x1200: tempbx = 28; break;
+#ifdef SIS300
case Panel_Barco1366: tempbx = 80; break;
+#endif
}
switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_320x240_1:
+ case Panel_320x240_2:
+ case Panel_320x240_3:
case Panel_640x480:
- case Panel_640x480_2:
- case Panel_640x480_3:
break;
default:
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
}
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
+#ifdef SIS300
if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
tempbx = 82;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+ } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
tempbx = 84;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
}
-
- if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
- (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
- if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
- (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
- tempal = 0;
- }
- }
+#endif
}
@@ -3124,12 +3074,11 @@ SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
}
static void
-SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT tempax=0,tempbx=0;
- USHORT temp1=0,modeflag=0,tempcx=0;
- USHORT index;
+ unsigned short tempax=0, tempbx=0, index, dotclock;
+ unsigned short temp1=0, modeflag=0, tempcx=0;
SiS_Pr->SiS_RVBHCMAX = 1;
SiS_Pr->SiS_RVBHCFACT = 1;
@@ -3143,10 +3092,12 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
+ dotclock = (modeflag & Charx8Dot) ? 8 : 9;
+
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
@@ -3158,22 +3109,16 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
tempbx |= tempcx;
temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7];
+ dotclock = 8;
+
}
if(temp1 & 0x01) tempbx |= 0x0100;
if(temp1 & 0x20) tempbx |= 0x0200;
tempax += 5;
-
- /* Charx8Dot is no more used (and assumed), so we set it */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- modeflag |= Charx8Dot;
- }
-
- if(modeflag & Charx8Dot) tempax *= 8;
- else tempax *= 9;
-
- if(modeflag & HalfDCLK) tempax <<= 1;
+ tempax *= dotclock;
+ if(modeflag & HalfDCLK) tempax <<= 1;
tempbx++;
@@ -3182,13 +3127,56 @@ SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
}
static void
-SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
+{
+ unsigned short ResIndex;
+
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ if(SiS_Pr->UseCustomMode) {
+ ResIndex = SiS_Pr->CHTotal;
+ if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
+ } else {
+ if(ModeNo < 0x13) {
+ ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+ }
+ if(ResIndex == 0x09) {
+ if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */
+ else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
+ }
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
+ SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
+ SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
+ }
+ } else {
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ }
+ } else {
+ /* This handles custom modes and custom panels */
+ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+ SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
+ SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
+ }
+}
+
+static void
+SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT CRT2Index, ResIndex;
- const SiS_LVDSDataStruct *LVDSData = NULL;
+ unsigned short CRT2Index, ResIndex, backup;
+ const struct SiS_LVDSData *LVDSData = NULL;
- SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
if(SiS_Pr->SiS_VBType & VB_SISVB) {
SiS_Pr->SiS_RVBHCMAX = 1;
@@ -3199,133 +3187,94 @@ SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
SiS_Pr->SiS_RY2COE = 0;
SiS_Pr->SiS_RY3COE = 0;
SiS_Pr->SiS_RY4COE = 0;
+ SiS_Pr->SiS_RVBHRS2 = 0;
}
if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
#ifdef SIS315H
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- if(SiS_Pr->UseCustomMode) {
- SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
- SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
- } else {
- if(ModeNo < 0x13) {
- ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- } else {
- ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
- }
- SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
- SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
- SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
- SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
- }
- } else {
- SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
- }
- } else {
- /* This handles custom modes and custom panels */
- SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
- SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
- SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
- SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
- SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
- }
-
- SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
-
+ SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
#endif
} else {
/* 301BDH needs LVDS Data */
+ backup = SiS_Pr->SiS_IF_DEF_LVDS;
if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
SiS_Pr->SiS_IF_DEF_LVDS = 1;
}
SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &CRT2Index, &ResIndex, HwInfo);
+ &CRT2Index, &ResIndex);
- /* 301BDH needs LVDS Data */
- if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- SiS_Pr->SiS_IF_DEF_LVDS = 0;
- }
+ SiS_Pr->SiS_IF_DEF_LVDS = backup;
- switch (CRT2Index) {
- case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
- case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
- case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
- case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
- case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
- case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
- case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
- case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
- case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
- case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
- case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
- case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
- case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
- case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
- case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
- case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
- case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
- case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
- case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
- case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
- case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
- case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
- case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
- case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
+ switch(CRT2Index) {
+ case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break;
+ case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break;
+ case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
+ case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
+ case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
+ case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+#ifdef SIS300
case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
- case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
- case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
- case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
- case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
- case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
- case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
- default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+#endif
+ case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
+ case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
+ case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
+ case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
+ case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
+ case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
+ case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
+ case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
+ case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break;
}
- SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
- SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
- SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
- SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
-
- if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
- if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
- SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
- SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- if(ResIndex < 0x08) {
- SiS_Pr->SiS_HDE = 1280;
- SiS_Pr->SiS_VDE = 1024;
- }
- }
- }
+ if(LVDSData) {
+ SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+ SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+ SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
+ SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
+ } else {
+ SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+
+ if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
+ (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+ (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
+ if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
+ (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
+ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+#ifdef SIS300
+ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+ if(ResIndex < 0x08) {
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 1024;
+ }
+ }
+#endif
}
}
}
}
static void
-SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
-{
- UCHAR *ROMAddr = NULL;
- USHORT tempax,tempbx,modeflag,romptr=0;
- USHORT resinfo,CRT2Index,ResIndex;
- const SiS_LCDDataStruct *LCDPtr = NULL;
- const SiS_TVDataStruct *TVPtr = NULL;
+SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned char *ROMAddr = NULL;
+ unsigned short tempax, tempbx, modeflag, romptr=0;
+ unsigned short resinfo, CRT2Index, ResIndex;
+ const struct SiS_LCDData *LCDPtr = NULL;
+ const struct SiS_TVData *TVPtr = NULL;
#ifdef SIS315H
- SHORT resinfo661;
+ short resinfo661;
#endif
if(ModeNo <= 0x13) {
@@ -3340,67 +3289,69 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
#ifdef SIS315H
resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
- (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
- (resinfo661 >= 0) &&
+ (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
+ (resinfo661 >= 0) &&
(SiS_Pr->SiS_NeedRomModeData) ) {
- if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
if((romptr = (SISGETROMW(21)))) {
- romptr += (resinfo661 * 10);
- ROMAddr = HwInfo->pjVirtualRomBase;
+ romptr += (resinfo661 * 10);
+ ROMAddr = SiS_Pr->VirtualRomBase;
}
}
}
#endif
}
-
+
SiS_Pr->SiS_NewFlickerMode = 0;
SiS_Pr->SiS_RVBHRS = 50;
SiS_Pr->SiS_RY1COE = 0;
SiS_Pr->SiS_RY2COE = 0;
SiS_Pr->SiS_RY3COE = 0;
SiS_Pr->SiS_RY4COE = 0;
+ SiS_Pr->SiS_RVBHRS2 = 0;
- SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
+ SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->SiS_RVBHCMAX = 1;
- SiS_Pr->SiS_RVBHCFACT = 1;
- SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
- SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
- SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
- SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
+ SiS_Pr->SiS_RVBHCMAX = 1;
+ SiS_Pr->SiS_RVBHCFACT = 1;
SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
- SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
+ SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
+
+ tempax = SiS_Pr->CHTotal;
+ if(modeflag & HalfDCLK) tempax <<= 1;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
} else {
- SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
- &CRT2Index,&ResIndex,HwInfo);
+ &CRT2Index,&ResIndex);
switch(CRT2Index) {
- case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
- case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
- case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
- case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
- case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
- case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
- case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
- case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
- case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
- case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
- case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
- case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
- case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
- default: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
+ case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
+ case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
+ case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
+ case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
+ case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
+ case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
+ case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
+ case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
+ case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
+ case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
+ case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
+ default: TVPtr = SiS_Pr->SiS_StPALData; break;
}
SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3409,73 +3360,77 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT;
SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE;
SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE;
- SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
- SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+ SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
if(modeflag & HalfDCLK) {
- SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
+ if(SiS_Pr->SiS_RVBHRS2) {
+ SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
+ tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
+ if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
+ else SiS_Pr->SiS_RVBHRS2 += tempax;
+ }
+ } else {
+ SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS;
}
+ SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if((resinfo == SIS_RI_1024x768) ||
- (resinfo == SIS_RI_1280x1024) ||
- (resinfo == SIS_RI_1280x720)) {
+ if((resinfo == SIS_RI_960x600) ||
+ (resinfo == SIS_RI_1024x768) ||
+ (resinfo == SIS_RI_1280x1024) ||
+ (resinfo == SIS_RI_1280x720)) {
SiS_Pr->SiS_NewFlickerMode = 0x40;
}
- if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
+ if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
- SiS_Pr->SiS_HT = ExtHiTVHT;
- SiS_Pr->SiS_VT = ExtHiTVVT;
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- SiS_Pr->SiS_HT = StHiTVHT;
- SiS_Pr->SiS_VT = StHiTVVT;
-#if 0
- if(!(modeflag & Charx8Dot)) {
- SiS_Pr->SiS_HT = StHiTextTVHT;
- SiS_Pr->SiS_VT = StHiTextTVVT;
- }
-#endif
- }
- }
+ SiS_Pr->SiS_HT = ExtHiTVHT;
+ SiS_Pr->SiS_VT = ExtHiTVVT;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+ SiS_Pr->SiS_HT = StHiTVHT;
+ SiS_Pr->SiS_VT = StHiTVVT;
+ }
+ }
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
- SiS_Pr->SiS_HT = 1650;
- SiS_Pr->SiS_VT = 750;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+ SiS_Pr->SiS_HT = 1650;
+ SiS_Pr->SiS_VT = 750;
} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
SiS_Pr->SiS_HT = NTSCHT;
+ if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
SiS_Pr->SiS_VT = NTSCVT;
- } else {
- SiS_Pr->SiS_HT = NTSCHT;
+ } else {
+ SiS_Pr->SiS_HT = NTSCHT;
if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
- SiS_Pr->SiS_VT = NTSCVT;
- }
+ SiS_Pr->SiS_VT = NTSCVT;
+ }
} else {
- SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
- SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
- SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
- SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+ SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+ SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+ SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+ SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
- if(modeflag & HalfDCLK) {
- SiS_Pr->SiS_RY1COE = 0x00;
- SiS_Pr->SiS_RY2COE = 0xf4;
- SiS_Pr->SiS_RY3COE = 0x10;
- SiS_Pr->SiS_RY4COE = 0x38;
- }
+ if(modeflag & HalfDCLK) {
+ SiS_Pr->SiS_RY1COE = 0x00;
+ SiS_Pr->SiS_RY2COE = 0xf4;
+ SiS_Pr->SiS_RY3COE = 0x10;
+ SiS_Pr->SiS_RY4COE = 0x38;
+ }
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
- SiS_Pr->SiS_HT = NTSCHT;
+ if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+ SiS_Pr->SiS_HT = NTSCHT;
if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
- SiS_Pr->SiS_VT = NTSCVT;
- } else {
- SiS_Pr->SiS_HT = PALHT;
- SiS_Pr->SiS_VT = PALVT;
- }
+ SiS_Pr->SiS_VT = NTSCVT;
+ } else {
+ SiS_Pr->SiS_HT = PALHT;
+ SiS_Pr->SiS_VT = PALVT;
+ }
}
@@ -3486,42 +3441,53 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
- SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
- SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
- SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE;
- SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
+ SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE;
+
+ tempax = SiS_Pr->CHTotal;
+ if(modeflag & HalfDCLK) tempax <<= 1;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
} else {
- BOOLEAN gotit = FALSE;
+ BOOLEAN gotit = FALSE;
- if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
- SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
- SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
gotit = TRUE;
} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
#ifdef SIS315H
SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
- SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
- SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
- SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
- SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
- SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
+ SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
+ SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
+ SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
+ SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
+ SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
+ SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
+ if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
+ tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
+ if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
+ else SiS_Pr->SiS_RVBHRS2 += tempax;
+ }
if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
else {
SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ SiS_Pr->SiS_RVBHCMAX = 1;
+ SiS_Pr->SiS_RVBHCFACT = 1;
SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
- SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
- SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_RVBHRS2 = 0;
gotit = TRUE;
}
#endif
@@ -3530,28 +3496,30 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(!gotit) {
- SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
- &CRT2Index,&ResIndex,HwInfo);
+ SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex);
- switch(CRT2Index) {
+ switch(CRT2Index) {
case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
case Panel_1280x720 :
case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
- case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
+ case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
case Panel_1280x800 :
case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
case Panel_1280x800_2 :
case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break;
+ case Panel_1280x854 :
+ case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break;
case Panel_1280x960 :
case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
- case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
- case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
- case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
- case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
- case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
- case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
+ case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
+ case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
+ case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
+ case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
+ case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
+ case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
case Panel_1680x1050 :
case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
@@ -3559,271 +3527,340 @@ SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
#endif
- default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
- }
+ default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
+ }
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+ xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif
#endif
- SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
- SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
- SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
- SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
- SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
- SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+ SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
+ SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+ SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
+ SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
+ SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
+ SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
}
tempax = SiS_Pr->PanelXRes;
- tempbx = SiS_Pr->PanelYRes;
+ tempbx = SiS_Pr->PanelYRes;
- if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
- if(HwInfo->jChipType < SIS_315H) {
- if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
- }
- } else {
- if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
- else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
- else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
- else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
- else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
- if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
- else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
- } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
- if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
- else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
- else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
- } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_1024x768:
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+ }
+ } else {
+ if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+ else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+ else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+ else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+ else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+ }
+ break;
+ case Panel_1280x960:
+ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
+ else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+ break;
+ case Panel_1280x1024:
+ if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+ else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+ else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+ break;
+ case Panel_1600x1200:
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
- else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
- }
- }
+ if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
+ else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
+ }
+ break;
+ }
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempax = SiS_Pr->SiS_VGAHDE;
- tempbx = SiS_Pr->SiS_VGAVDE;
- }
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax = SiS_Pr->SiS_VGAHDE;
+ tempbx = SiS_Pr->SiS_VGAVDE;
+ }
- SiS_Pr->SiS_HDE = tempax;
- SiS_Pr->SiS_VDE = tempbx;
+ SiS_Pr->SiS_HDE = tempax;
+ SiS_Pr->SiS_VDE = tempbx;
}
}
}
static void
-SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- } else {
- if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- /* Need LVDS Data for LCD on 301B-DH */
- SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- } else {
- SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ } else {
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ /* Need LVDS Data for LCD on 301B-DH */
+ SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ } else {
+ SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+ }
- } else {
+ } else {
- SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
- }
+ }
}
/*********************************************/
/* GET LVDS DES (SKEW) DATA */
/*********************************************/
-static void
-SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT *PanelIndex,
- USHORT *ResIndex, PSIS_HW_INFO HwInfo)
+static const struct SiS_LVDSDes *
+SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
{
- USHORT modeflag;
+ const struct SiS_LVDSDes *PanelDesPtr = NULL;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
+#ifdef SIS300
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDTypeInfo == 4) {
+ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+ PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
+ }
+ } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+ PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
+ }
+ }
+ }
+ }
+ }
+#endif
+ return PanelDesPtr;
+}
- (*ResIndex) &= 0x1F;
- (*PanelIndex) = 0;
+static void
+SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short modeflag, ResIndex;
+ const struct SiS_LVDSDes *PanelDesPtr = NULL;
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- (*PanelIndex) = 50;
- if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
- /* Nothing special needed for SOverscan */
- /* PALM uses NTSC data, PALN uses PAL data */
- }
- }
+ SiS_Pr->SiS_LCDHDES = 0;
+ SiS_Pr->SiS_LCDVDES = 0;
+ /* Some special cases */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
- if(HwInfo->jChipType >= SIS_661) {
- /* As long as we don's use the BIOS tables, we
- * need to convert the TypeInfo as for 315 series
- */
- (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
- }
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- (*PanelIndex) += 16;
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- (*PanelIndex) = 32;
- if(modeflag & HalfDCLK) (*PanelIndex)++;
+
+ /* Trumpion */
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ }
}
+ return;
}
- }
- if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
- (*ResIndex) = 7;
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
- }
+ /* 640x480 on LVDS */
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
+ SiS_Pr->SiS_LCDHDES = 8;
+ if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
+ else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
+ else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
+ return;
+ }
}
- }
-}
-
-static void
-SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
-{
- USHORT modeflag;
- USHORT PanelIndex,ResIndex;
- const SiS_LVDSDesStruct *PanelDesPtr = NULL;
- SiS_Pr->SiS_LCDHDES = 0;
- SiS_Pr->SiS_LCDVDES = 0;
+ } /* LCD */
if( (SiS_Pr->UseCustomMode) ||
(SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
(SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
- ((SiS_Pr->SiS_VBType & VB_SISVB) &&
- (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
- (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
+ (SiS_Pr->SiS_CustomT == CUT_PANEL856) ||
+ (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
return;
}
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
#ifdef SIS315H
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- /* non-pass 1:1 only, see above */
- if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
- SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+ /* non-pass 1:1 only, see above */
+ if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
}
if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
}
}
if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
- switch(SiS_Pr->SiS_CustomT) {
- case CUT_UNIWILL1024:
- case CUT_UNIWILL10242:
- case CUT_CLEVO1400:
+ switch(SiS_Pr->SiS_CustomT) {
+ case CUT_UNIWILL1024:
+ case CUT_UNIWILL10242:
+ case CUT_CLEVO1400:
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
}
break;
}
- if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_1280x1024:
if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
}
+ break;
+ case Panel_1280x800: /* Verified for Averatec 6240 */
+ case Panel_1280x800_2: /* Verified for Asus A4L */
+ case Panel_1280x854: /* Not verified yet FIXME */
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ break;
}
}
#endif
} else {
- SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &PanelIndex, &ResIndex, HwInfo);
-
- switch(PanelIndex) {
- case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
- case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
- case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
- case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
- case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
- case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
- case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
- case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
- case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
- case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
- case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
- case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
- case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
- case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
- case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
- case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
- case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
- case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
- case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
- case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
- case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
- case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
- case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
- case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
- case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
- case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
- case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
- case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
- case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
- case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
- case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
- case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
- case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
- case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
- case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
- case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
- case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
- case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
- default: return;
- }
-
- SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
- SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+ if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
+ if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
+ if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
+ }
+
+ } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
+
+ SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+ SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+ } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+
+ if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+ }
+ if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
+ } else {
+ if(SiS_Pr->ChipType < SIS_315H) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ } else {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_800x600:
+ case Panel_1024x768:
+ case Panel_1280x1024:
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
+ break;
+ case Panel_1400x1050:
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ break;
+ }
+ }
+ }
+
+ } else {
+
+ if(SiS_Pr->ChipType < SIS_315H) {
+#ifdef SIS300
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_800x600:
+ if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ } else {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
+ if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
+ else SiS_Pr->SiS_LCDVDES -= 4;
+ }
+ break;
+ case Panel_1024x768:
+ if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ } else {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
+ if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
+ if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
+ }
+ break;
+ case Panel_1024x600:
+ default:
+ if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
+ (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ } else {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
+ }
+ break;
+ }
+
+ switch(SiS_Pr->SiS_LCDTypeInfo) {
+ case 1:
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
+ break;
+ case 3: /* 640x480 only? */
+ SiS_Pr->SiS_LCDHDES = 8;
+ if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
+ else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
+ else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
+ break;
+ }
+#endif
+ } else {
+#ifdef SIS315H
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_1024x768:
+ case Panel_1280x1024:
+ if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ }
+ break;
+ case Panel_320x240_1:
+ case Panel_320x240_2:
+ case Panel_320x240_3:
+ SiS_Pr->SiS_LCDVDES = 524;
+ break;
+ }
+#endif
+ }
+ }
if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
- } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
- if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
- if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
- if(HwInfo->jChipType < SIS_315H) {
+ } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+ if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
+ if(SiS_Pr->ChipType < SIS_315H) {
if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
} else {
- if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
- if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
+#ifdef SIS315H
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
- if(!(modeflag & HalfDCLK)) {
- SiS_Pr->SiS_LCDHDES = 320;
- if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
+ if(!(modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_LCDHDES = 320;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
- }
- }
- }
- }
- }
+ }
+#endif
+ }
+ }
+ }
+ }
}
}
}
@@ -3832,54 +3869,90 @@ SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
/* DISABLE VIDEO BRIDGE */
/*********************************************/
+#ifdef SIS315H
+static int
+SiS_HandlePWD(struct SiS_Private *SiS_Pr)
+{
+ int ret = 0;
+#ifdef SET_PWD
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
+ unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
+ unsigned short temp;
+
+ if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
+ (romptr) &&
+ (SiS_Pr->SiS_PWDOffset) ) {
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
+ temp = 0x00;
+ if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
+ temp = 0x80;
+ ret = 1;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+ xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
+#endif
+#endif
+ }
+#endif
+ return ret;
+}
+#endif
+
/* NEVER use any variables (VBInfo), this will be called
* from outside the context of modeswitch!
* MUST call getVBType before calling this
*/
void
-SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_DisableBridge(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
- USHORT tempah,pushax=0,modenum;
+ unsigned short tempah, pushax=0, modenum;
#endif
- USHORT temp=0;
+ unsigned short temp=0;
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
} else {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
}
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ SiS_PanelDelay(SiS_Pr, 3);
}
if(SiS_Is301B(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
SiS_ShortDelay(SiS_Pr,1);
- }
+ }
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
SiS_DisplayOff(SiS_Pr);
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
- if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ SiS_UnLockCRT2(SiS_Pr);
+ if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
}
- if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
- (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+ SiS_PanelDelay(SiS_Pr, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
} else {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
}
}
@@ -3889,130 +3962,127 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS315H /* 315 series */
+ int didpwd = 0;
BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
(SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
}
}
#endif
- if( (modenum <= 0x13) ||
- (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
- if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+
+ didpwd = SiS_HandlePWD(SiS_Pr);
+
+ if( (modenum <= 0x13) ||
+ (SiS_IsVAMode(SiS_Pr)) ||
+ (!(SiS_IsDualEdge(SiS_Pr))) ) {
+ if(!didpwd) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
+ if(custom1) SiS_PanelDelay(SiS_Pr, 3);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
+ }
}
if(!custom1) {
SiS_DDC2Delay(SiS_Pr,0xff00);
SiS_DDC2Delay(SiS_Pr,0xe000);
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
- pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+ SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+ pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
if(IS_SIS740) {
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
}
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ SiS_PanelDelay(SiS_Pr, 3);
}
- }
+ }
- if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
- if(HwInfo->jChipType < SIS_340) {
- tempah = 0xef;
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
- }
+ if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+ /* if(SiS_Pr->ChipType < SIS_340) {*/
+ tempah = 0xef;
+ if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ /*}*/
}
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
}
tempah = 0x3f;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+ if(SiS_IsDualEdge(SiS_Pr)) {
tempah = 0x7f;
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
+ if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
}
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+ if((SiS_IsVAMode(SiS_Pr)) ||
+ ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
SiS_DisplayOff(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_PanelDelay(SiS_Pr, 2);
}
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
}
- if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
- ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+ if((!(SiS_IsVAMode(SiS_Pr))) ||
+ ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
- if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+ if(!(SiS_IsDualEdge(SiS_Pr))) {
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
SiS_DisplayOff(SiS_Pr);
}
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_PanelDelay(SiS_Pr, 2);
}
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
}
- if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+ if(SiS_IsNotM650orLater(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
}
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-
- if(!custom1) {
-
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
- if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
- }
- }
- }
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+ if( (!(SiS_IsVAMode(SiS_Pr))) &&
+ (!(SiS_CRT2IsLCD(SiS_Pr))) &&
+ (!(SiS_IsDualEdge(SiS_Pr))) ) {
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
- }
- }
-
- } else {
+ if(custom1) SiS_PanelDelay(SiS_Pr, 2);
+ if(!didpwd) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ }
+ if(custom1) SiS_PanelDelay(SiS_Pr, 4);
+ }
- if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
- if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
- (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
- SiS_PanelDelay(SiS_Pr, HwInfo, 4);
+ if(!custom1) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ if(SiS_IsVAorLCD(SiS_Pr)) {
+ SiS_PanelDelayLoop(SiS_Pr, 3, 20);
}
}
-
}
- }
+
+ }
#endif /* SIS315H */
@@ -4020,36 +4090,36 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
} else { /* ============ For 301 ================ */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+ SiS_PanelDelay(SiS_Pr, 3);
}
#endif
}
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
- SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
+ SiS_DisplayOff(SiS_Pr);
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
}
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */
- if(HwInfo->jChipType >= SIS_315H) {
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
} else {
#ifdef SIS300
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
- if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
- (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
+ if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+ SiS_PanelDelay(SiS_Pr, 2);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
}
#endif
}
@@ -4058,34 +4128,34 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
} else { /* ============ For LVDS =============*/
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
- SiS_SetCH700x(SiS_Pr,0x090E);
+ SiS_SetCH700x(SiS_Pr,0x0E,0x09);
}
- if(HwInfo->jChipType == SIS_730) {
+ if(SiS_Pr->ChipType == SIS_730) {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ SiS_WaitVBRetrace(SiS_Pr);
}
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+ SiS_PanelDelay(SiS_Pr, 3);
}
} else {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_WaitVBRetrace(SiS_Pr);
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
SiS_DisplayOff(SiS_Pr);
- }
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
- }
- }
+ }
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+ SiS_PanelDelay(SiS_Pr, 3);
+ }
+ }
}
}
@@ -4094,14 +4164,14 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
- if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
- (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+ if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
+ SiS_PanelDelay(SiS_Pr, 2);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
}
#endif /* SIS300 */
@@ -4110,113 +4180,113 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS315H /* 315 series */
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- if(HwInfo->jChipType < SIS_340) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
- }
- }
+ if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+ /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+ /* } */
+ }
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
temp = SiS_GetCH701x(SiS_Pr,0x61);
if(temp < 1) {
- SiS_SetCH701x(SiS_Pr,0xac76);
- SiS_SetCH701x(SiS_Pr,0x0066);
+ SiS_SetCH701x(SiS_Pr,0x76,0xac);
+ SiS_SetCH701x(SiS_Pr,0x66,0x00);
}
- if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
- SiS_SetCH701x(SiS_Pr,0x3e49);
+ if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
+ SiS_SetCH701x(SiS_Pr,0x49,0x3e);
}
}
- if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
+ if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (SiS_IsVAMode(SiS_Pr)) ) {
SiS_Chrontel701xBLOff(SiS_Pr);
- SiS_Chrontel701xOff(SiS_Pr,HwInfo);
+ SiS_Chrontel701xOff(SiS_Pr);
}
- if(HwInfo->jChipType != SIS_740) {
- if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
- SiS_SetCH701x(SiS_Pr,0x0149);
- }
+ if(SiS_Pr->ChipType != SIS_740) {
+ if( (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
+ SiS_SetCH701x(SiS_Pr,0x49,0x01);
+ }
}
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
+ SiS_PanelDelay(SiS_Pr, 3);
}
if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
+ (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
SiS_DisplayOff(SiS_Pr);
}
if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+ (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (!(SiS_IsVAMode(SiS_Pr))) ) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
}
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
}
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+ (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (!(SiS_IsVAMode(SiS_Pr))) ) {
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
- if(HwInfo->jChipType == SIS_550) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
+ if(SiS_Pr->ChipType == SIS_550) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
}
}
} else {
- if(HwInfo->jChipType == SIS_740) {
- if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+ if(SiS_Pr->ChipType == SIS_740) {
+ if(SiS_IsLCDOrLCDA(SiS_Pr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
}
- } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+ } else if(SiS_IsVAMode(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
}
}
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+ if(SiS_IsDualEdge(SiS_Pr)) {
/* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
} else {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
}
}
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
- if(HwInfo->jChipType == SIS_550) {
+ if(SiS_Pr->ChipType == SIS_550) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+ (!(SiS_IsDualEdge(SiS_Pr))) ||
+ (!(SiS_IsVAMode(SiS_Pr))) ) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 2);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
}
}
}
@@ -4237,78 +4307,81 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
* from outside the context of a mode switch!
* MUST call getVBType before calling this
*/
-static void
-SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_EnableBridge(struct SiS_Private *SiS_Pr)
{
- USHORT temp=0,tempah;
+ unsigned short temp=0, tempah;
#ifdef SIS315H
- USHORT temp1,pushax=0;
+ unsigned short temp1, pushax=0;
BOOLEAN delaylong = FALSE;
#endif
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
}
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
- if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+ if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 0);
}
}
}
if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+ (SiS_CRT2IsLCD(SiS_Pr))) {
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
- SiS_DisplayOn(SiS_Pr);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_UnLockCRT2(SiS_Pr);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
if(SiS_BridgeInSlavemode(SiS_Pr)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
- }
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ }
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- }
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
- }
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ }
+ SiS_WaitVBRetrace(SiS_Pr);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
+ }
}
} else {
temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
- if(SiS_BridgeInSlavemode(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
+ tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
SiS_DisplayOn(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- }
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ }
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
- }
+ }
}
}
@@ -4322,31 +4395,32 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS315H /* 315 series */
#ifdef SET_EMI
- UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
- /* USHORT emidelay=0; */
+ unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
+ int didpwd = 0;
+ /* unsigned short emidelay=0; */
#endif
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
}
#endif
}
- if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
- if(HwInfo->jChipType < SIS_340) {
+ if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+ /*if(SiS_Pr->ChipType < SIS_340) { */
tempah = 0x10;
- if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
- if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
- else tempah = 0x08;
+ if(SiS_LCDAEnabled(SiS_Pr)) {
+ if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
+ else tempah = 0x08;
}
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
- }
+ /*}*/
}
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
SiS_DisplayOff(SiS_Pr);
@@ -4355,42 +4429,51 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
}
- if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_GenericDelay(SiS_Pr, 0x4500);
+ didpwd = SiS_HandlePWD(SiS_Pr);
+
+ if(SiS_IsVAorLCD(SiS_Pr)) {
+ if(!didpwd) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+ SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_GenericDelay(SiS_Pr, 17664);
+ }
+ }
+ } else {
+ SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_GenericDelay(SiS_Pr, 17664);
}
}
}
if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ SiS_PanelDelayLoop(SiS_Pr, 3, 10);
delaylong = TRUE;
}
}
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+ if(!(SiS_IsVAMode(SiS_Pr))) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
if(SiS_BridgeInSlavemode(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) {
- if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
+ tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) {
+ if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
}
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ SiS_PanelDelay(SiS_Pr, 2);
}
} else {
@@ -4402,38 +4485,48 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+ if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
+ if( (SiS_LCDAEnabled(SiS_Pr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr)) ) {
+ /* Enable "LVDS PLL power on" (even on 301C) */
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
+ /* Enable "LVDS Driver Power on" (even on 301C) */
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
+ }
+ }
+
tempah = 0xc0;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+ if(SiS_IsDualEdge(SiS_Pr)) {
tempah = 0x80;
- if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
+ if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ SiS_PanelDelay(SiS_Pr, 2);
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
- SiS_GenericDelay(SiS_Pr, 0x500);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+ SiS_GenericDelay(SiS_Pr, 2048);
}
#endif
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
#ifdef SET_EMI
cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
if(SiS_Pr->SiS_ROMNew) {
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
if(romptr) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
SiS_Pr->EMI_30 = 0;
SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
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)
if(!SiS_Pr->OverruleEMI) {
#ifdef COMPAL_HACK
if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
- if((cr36 & 0x0f) == 0x09) {
+ if((cr36 & 0x0f) == 0x09) {
r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
}
}
#endif
#ifdef COMPAQ_HACK
if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if((cr36 & 0x0f) == 0x03) {
+ if((cr36 & 0x0f) == 0x03) {
r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
}
}
#endif
#ifdef ASUS_HACK
if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- if((cr36 & 0x0f) == 0x02) {
+ if((cr36 & 0x0f) == 0x02) {
/* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
/* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
/* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
@@ -4533,11 +4626,11 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
}
#endif
- }
+ }
if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
- SiS_GenericDelay(SiS_Pr, 0x500);
+ SiS_GenericDelay(SiS_Pr, 2048);
}
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
@@ -4547,36 +4640,44 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
#ifdef SET_EMI
- if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
- if(r30 & 0x40) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+ if( (SiS_LCDAEnabled(SiS_Pr)) ||
+ (SiS_CRT2IsLCD(SiS_Pr)) ) {
+ if(r30 & 0x40) {
+ /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
+ SiS_PanelDelayLoop(SiS_Pr, 3, 5);
if(delaylong) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+ SiS_PanelDelayLoop(SiS_Pr, 3, 5);
delaylong = FALSE;
}
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ SiS_WaitVBRetrace(SiS_Pr);
+ SiS_WaitVBRetrace(SiS_Pr);
if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- SiS_GenericDelay(SiS_Pr, 0x500);
+ SiS_GenericDelay(SiS_Pr, 1280);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
- }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
+ /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
+ }
}
#endif
}
}
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+ if(SiS_IsVAorLCD(SiS_Pr)) {
+ SiS_PanelDelayLoop(SiS_Pr, 3, 10);
if(delaylong) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ SiS_PanelDelayLoop(SiS_Pr, 3, 10);
}
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_GenericDelay(SiS_Pr, 0x500);
+ SiS_WaitVBRetrace(SiS_Pr);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_GenericDelay(SiS_Pr, 2048);
+ SiS_WaitVBRetrace(SiS_Pr);
+ }
+ if(!didpwd) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+ } else {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
}
}
@@ -4586,7 +4687,7 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
}
@@ -4596,26 +4697,26 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
} else { /* ============ For 301 ================ */
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+ SiS_PanelDelay(SiS_Pr, 0);
}
}
temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
if(SiS_BridgeInSlavemode(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
}
SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
- if(HwInfo->jChipType >= SIS_315H) {
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
- if(!(temp & 0x80)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+ if(!(temp & 0x80)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */
}
}
@@ -4623,15 +4724,15 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_VBLongWait(SiS_Pr);
SiS_DisplayOn(SiS_Pr);
- if(HwInfo->jChipType >= SIS_315H) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
}
SiS_VBLongWait(SiS_Pr);
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
}
}
@@ -4639,49 +4740,49 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
} else { /* =================== For LVDS ================== */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(HwInfo->jChipType == SIS_730) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ if(SiS_Pr->ChipType == SIS_730) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ SiS_PanelDelay(SiS_Pr, 1);
+ SiS_PanelDelay(SiS_Pr, 1);
}
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
- if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 0);
}
}
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_DisplayOn(SiS_Pr);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
if(SiS_BridgeInSlavemode(SiS_Pr)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
} else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
- if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
- SiS_WaitVBRetrace(SiS_Pr, HwInfo);
- SiS_SetCH700x(SiS_Pr,0x0B0E);
- }
+ if(!(SiS_CRT2IsLCD(SiS_Pr))) {
+ SiS_WaitVBRetrace(SiS_Pr);
+ SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
+ }
}
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- }
- SiS_WaitVBRetrace(SiS_Pr, HwInfo);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
- }
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ SiS_PanelDelay(SiS_Pr, 1);
+ }
+ SiS_WaitVBRetrace(SiS_Pr);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
+ }
}
}
@@ -4691,94 +4792,94 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
#ifdef SIS315H /* 315 series */
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- if(HwInfo->jChipType < SIS_340) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
- }
+ if(!(SiS_IsNotM650orLater(SiS_Pr))) {
+ /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+ /*}*/
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
- }
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
+ SiS_PanelDelay(SiS_Pr, 0);
+ }
}
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
temp &= 0x20;
SiS_Chrontel701xBLOff(SiS_Pr);
}
- if(HwInfo->jChipType != SIS_550) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ if(SiS_Pr->ChipType != SIS_550) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
}
- if(HwInfo->jChipType == SIS_740) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ if(SiS_Pr->ChipType == SIS_740) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(SiS_IsLCDOrLCDA(SiS_Pr)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
}
}
}
temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
if(!(temp1 & 0x80)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(temp) {
- SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
+ if(temp) {
+ SiS_Chrontel701xBLOn(SiS_Pr);
}
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
- if(HwInfo->jChipType == SIS_550) {
+ if(SiS_Pr->ChipType == SIS_550) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
}
}
- } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
- if(HwInfo->jChipType != SIS_740) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+ } else if(SiS_IsVAMode(SiS_Pr)) {
+ if(SiS_Pr->ChipType != SIS_740) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
}
}
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
- SiS_Chrontel701xOn(SiS_Pr,HwInfo);
- }
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
- SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
- }
+ if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
+ SiS_Chrontel701xOn(SiS_Pr);
+ }
+ if( (SiS_IsVAMode(SiS_Pr)) ||
+ (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
+ SiS_ChrontelDoSomething1(SiS_Pr);
+ }
}
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
- SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
- SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
- }
- }
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+ if( (SiS_IsVAMode(SiS_Pr)) ||
+ (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
+ SiS_Chrontel701xBLOn(SiS_Pr);
+ SiS_ChrontelInitTVVSync(SiS_Pr);
+ }
+ }
} else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
+ if(SiS_CRT2IsLCD(SiS_Pr)) {
+ SiS_PanelDelay(SiS_Pr, 1);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
}
}
}
@@ -4797,243 +4898,204 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* Set CRT2 OFFSET / PITCH */
static void
-SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RRTI, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RRTI)
{
- USHORT offset;
- UCHAR temp;
+ unsigned short offset;
+ unsigned char temp;
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
- offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
+ offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
- if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
- offset >>= 1;
- }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
- temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
- if(offset % 8) temp++;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
+ temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
+ if(offset & 0x07) temp++;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
}
/* Set CRT2 sync and PanelLink mode */
static void
-SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
{
- USHORT tempah=0,tempbl,infoflag;
+ unsigned short tempah=0, tempbl, infoflag;
- tempbl = 0xC0;
+ tempbl = 0xC0;
- if(SiS_Pr->UseCustomMode) {
- infoflag = SiS_Pr->CInfoFlag;
- } else {
- infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- }
+ if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ }
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tempah = 0;
- } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
- tempah = SiS_Pr->SiS_LCDInfo;
- } else tempah = infoflag >> 8;
- tempah &= 0xC0;
- tempah |= 0x20;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
- (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- tempah |= 0xf0;
- }
- if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
- (SiS_Pr->SiS_IF_DEF_DSTN) ||
- (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
- tempah |= 0x30;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(HwInfo->jChipType >= SIS_315H) {
- tempah >>= 3;
- tempah &= 0x18;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
- /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
- }
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ tempah = 0;
+ } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ } else tempah = infoflag >> 8;
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+ (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+ tempah |= 0xf0;
+ }
+ if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+ (SiS_Pr->SiS_IF_DEF_DSTN) ||
+ (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
+ tempah |= 0x30;
+ }
+ if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+ (SiS_Pr->SiS_IF_DEF_DSTN) ) {
+ tempah &= ~0xc0;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ tempah >>= 3;
+ tempah &= 0x18;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+ /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
+ }
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ }
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* ---- 300 series --- */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
- tempah = infoflag >> 8;
- tempbl = 0;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
- tempah = SiS_Pr->SiS_LCDInfo;
- tempbl = (tempah >> 6) & 0x03;
- }
- }
- tempah &= 0xC0;
- tempah |= 0x20;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- tempah |= 0xc0;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
- }
+ tempah = infoflag >> 8;
+ tempbl = 0;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ tempah = SiS_Pr->SiS_LCDInfo;
+ tempbl = (tempah >> 6) & 0x03;
+ }
+ }
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ tempah |= 0xc0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
- } else { /* 630 - 301 */
+ } else { /* 630 - 301 */
- tempah = infoflag >> 8;
- tempah &= 0xC0;
- tempah |= 0x20;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ tempah = ((infoflag >> 8) & 0xc0) | 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- }
+ }
#endif /* SIS300 */
- } else {
+ } else {
#ifdef SIS315H /* ------- 315 series ------ */
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
- tempbl = 0;
- if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
- tempah = infoflag >> 8;
- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
- tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
- }
- } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
- (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
- tempah = infoflag >> 8;
- tempbl = 0x03;
- } else {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
- tempbl = (tempah >> 6) & 0x03;
- tempbl |= 0x08;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
- }
- tempah &= 0xC0;
- tempah |= 0x20;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
- }
- }
+ tempbl = 0;
+ if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+ tempah = infoflag >> 8;
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
+ }
+ } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
+ tempah = infoflag >> 8;
+ tempbl = 0x03;
+ } else {
+ tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+ tempbl = (tempah >> 6) & 0x03;
+ tempbl |= 0x08;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
+ }
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
+ }
- } else { /* 315 - TMDS */
+ } else { /* 315 - TMDS */
- tempah = tempbl = infoflag >> 8;
- if(!SiS_Pr->UseCustomMode) {
- tempbl = 0;
- if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
- if(ModeNo <= 0x13) {
- tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
- }
- }
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
- tempah = SiS_Pr->SiS_LCDInfo;
+ tempah = tempbl = infoflag >> 8;
+ if(!SiS_Pr->UseCustomMode) {
+ tempbl = 0;
+ if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ if(ModeNo <= 0x13) {
+ tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ tempah = SiS_Pr->SiS_LCDInfo;
tempbl = (tempah >> 6) & 0x03;
}
- }
- }
- }
- tempah &= 0xC0;
- tempah |= 0x20;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
- if(SiS_Pr->SiS_VBType & VB_NoLCD) {
- /* Imitate BIOS bug */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
- }
- if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
- tempah >>= 3;
- tempah &= 0x18;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
- }
- }
- }
+ }
+ }
+ }
+ tempah &= 0xC0;
+ tempah |= 0x20;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ /* Imitate BIOS bug */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
+ }
+ if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ tempah >>= 3;
+ tempah &= 0x18;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
+ }
+ }
- }
+ }
#endif /* SIS315H */
}
}
}
-/* Set CRT2 FIFO on 300/630/730 */
+/* Set CRT2 FIFO on 300/540/630/730 */
#ifdef SIS300
static void
-SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
- PSIS_HW_INFO HwInfo)
-{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp,index;
- USHORT modeidindex,refreshratetableindex;
- USHORT VCLK=0,MCLK,colorth=0,data2=0;
- USHORT tempal, tempah, tempbx, tempcl, tempax;
- USHORT CRT1ModeNo,CRT2ModeNo;
- USHORT SelectRate_backup;
- ULONG data,eax;
- const UCHAR LatencyFactor[] = {
- 97, 88, 86, 79, 77, 00, /*; 64 bit BQ=2 */
- 00, 87, 85, 78, 76, 54, /*; 64 bit BQ=1 */
- 97, 88, 86, 79, 77, 00, /*; 128 bit BQ=2 */
- 00, 79, 77, 70, 68, 48, /*; 128 bit BQ=1 */
- 80, 72, 69, 63, 61, 00, /*; 64 bit BQ=2 */
- 00, 70, 68, 61, 59, 37, /*; 64 bit BQ=1 */
- 86, 77, 75, 68, 66, 00, /*; 128 bit BQ=2 */
- 00, 68, 66, 59, 57, 37 /*; 128 bit BQ=1 */
- };
- const UCHAR LatencyFactor730[] = {
- 69, 63, 61,
- 86, 79, 77,
- 103, 96, 94,
- 120,113,111,
- 137,130,128, /* <-- last entry, data below */
- 137,130,128, /* to avoid using illegal values */
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- 137,130,128,
- };
- const UCHAR ThLowB[] = {
- 81, 4, 72, 6, 88, 8,120,12,
- 55, 4, 54, 6, 66, 8, 90,12,
- 42, 4, 45, 6, 55, 8, 75,12
- };
- const UCHAR ThTiming[] = {
- 1, 2, 2, 3, 0, 1, 1, 2
+SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
+{
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short temp, index, modeidindex, refreshratetableindex;
+ unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
+ unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
+ unsigned int data, pci50, pciA0;
+ static const unsigned char colortharray[] = {
+ 1, 1, 2, 2, 3, 4
};
SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
@@ -5044,232 +5106,159 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
SiS_Pr->SiS_SelectCRT2Rate = 0;
- refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
+ refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
if(CRT1ModeNo >= 0x13) {
- index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
- index &= 0x3F;
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ /* Get VCLK */
+ index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
- colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
- colorth >>= 1;
- if(!colorth) colorth++;
+ /* Get colordepth */
+ colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
+ if(!colorth) colorth++;
}
} else {
CRT1ModeNo = 0xfe;
- VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
- data2 = (SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2;
- switch(data2) { /* Get color depth */
- case 0 : colorth = 1; break;
- case 1 : colorth = 1; break;
- case 2 : colorth = 2; break;
- case 3 : colorth = 2; break;
- case 4 : colorth = 3; break;
- case 5 : colorth = 4; break;
- default: colorth = 2;
- }
+
+ /* Get VCLK */
+ VCLK = SiS_Pr->CSRClock_CRT1;
+
+ /* Get color depth */
+ colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
}
if(CRT1ModeNo >= 0x13) {
- if(HwInfo->jChipType == SIS_300) {
- index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
- } else {
- index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
- }
- index &= 0x07;
- MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; /* Get MCLK */
+ /* Get MCLK */
+ if(SiS_Pr->ChipType == SIS_300) {
+ index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
+ } else {
+ index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
+ }
+ index &= 0x07;
+ MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
- data2 = (colorth * VCLK) / MCLK;
+ temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
+ if(!temp) temp++;
+ temp <<= 2;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- temp = ((temp & 0x00FF) >> 6) << 1;
- if(temp == 0) temp = 1;
- temp <<= 2;
- temp &= 0xff;
+ data2 = temp - ((colorth * VCLK) / MCLK);
- data2 = temp - data2;
+ temp = (28 * 16) % data2;
+ data2 = (28 * 16) / data2;
+ if(temp) data2++;
- if((28 * 16) % data2) {
- data2 = (28 * 16) / data2;
- data2++;
- } else {
- data2 = (28 * 16) / data2;
- }
+ if(SiS_Pr->ChipType == SIS_300) {
- if(HwInfo->jChipType == SIS_300) {
-
- tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
- tempah &= 0x62;
- tempah >>= 1;
- tempal = tempah;
- tempah >>= 3;
- tempal |= tempah;
- tempal &= 0x07;
- tempcl = ThTiming[tempal];
- tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
- tempbx >>= 6;
- tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- tempah >>= 4;
- tempah &= 0x0c;
- tempbx |= tempah;
- tempbx <<= 1;
- tempal = ThLowB[tempbx + 1];
- tempal *= tempcl;
- tempal += ThLowB[tempbx];
- data = tempal;
-
- } else if(HwInfo->jChipType == SIS_730) {
-
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x80000050);
- eax = SiS_GetRegLong(0xcfc);
+ SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
+ data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
+
+ } else {
+
+#ifdef SIS_LINUX_KERNEL
+ pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
+ pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
#else
- eax = pciReadLong(0x00000000, 0x50);
+ pci50 = pciReadLong(0x00000000, 0x50);
+ pciA0 = pciReadLong(0x00000000, 0xA0);
#endif
- tempal = (USHORT)(eax >> 8);
- tempal &= 0x06;
- tempal <<= 5;
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x800000A0);
- eax = SiS_GetRegLong(0xcfc);
-#else
- eax = pciReadLong(0x00000000, 0xA0);
-#endif
- temp = (USHORT)(eax >> 28);
- temp &= 0x0F;
- tempal |= temp;
-
- tempbx = tempal; /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
- tempbx = 0; /* -- do it like the BIOS anyway... */
- tempax = tempbx;
- tempbx &= 0xc0;
- tempbx >>= 6;
- tempax &= 0x0f;
- tempax *= 3;
- tempbx += tempax;
-
- data = LatencyFactor730[tempbx];
- data += 15;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- if(!(temp & 0x80)) data += 5;
+ if(SiS_Pr->ChipType == SIS_730) {
- } else {
+ index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
+ index += (unsigned short)(((pci50 >> 9)) & 0x03);
- index = 0;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- if(temp & 0x0080) index += 12;
+ /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+ index = 0; /* -- do it like the BIOS anyway... */
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x800000A0);
- eax = SiS_GetRegLong(0xcfc);
-#else
- /* We use pci functions X offers. We use tag 0, because
- * we want to read/write to the host bridge (which is always
- * 00:00.0 on 630, 730 and 540), not the VGA device.
- */
- eax = pciReadLong(0x00000000, 0xA0);
-#endif
- temp = (USHORT)(eax >> 24);
- if(!(temp&0x01)) index += 24;
-
-#ifdef LINUX_KERNEL
- SiS_SetRegLong(0xcf8,0x80000050);
- eax = SiS_GetRegLong(0xcfc);
-#else
- eax = pciReadLong(0x00000000, 0x50);
-#endif
- temp=(USHORT)(eax >> 24);
- if(temp & 0x01) index += 6;
+ } else {
- temp = (temp & 0x0F) >> 1;
- index += temp;
+ pci50 >>= 24;
+ pciA0 >>= 24;
- data = LatencyFactor[index];
- data += 15;
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- if(!(temp & 0x80)) data += 5;
- }
+ index = (pci50 >> 1) & 0x07;
- data += data2; /* CRT1 Request Period */
+ if(pci50 & 0x01) index += 6;
+ if(!(pciA0 & 0x01)) index += 24;
- SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
- SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
- if(!SiS_Pr->UseCustomMode) {
+ }
- CRT2ModeNo = ModeNo;
- SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
+ data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
- refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
+ }
- index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
- refreshratetableindex,HwInfo);
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ data += data2; /* CRT1 Request Period */
- if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- if(SiS_Pr->SiS_UseROM) {
- if(ROMAddr[0x220] & 0x01) {
- VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
- }
- }
- }
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
- } else {
+ if(!SiS_Pr->UseCustomMode) {
- CRT2ModeNo = 0xfe;
- VCLK = SiS_Pr->CSRClock; /* Get VCLK */
+ CRT2ModeNo = ModeNo;
+ SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
- }
+ refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
- colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
- colorth >>= 1;
- if(!colorth) colorth++;
+ /* Get VCLK */
+ index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
- data = data * VCLK * colorth;
- if(data % (MCLK << 4)) {
- data = data / (MCLK << 4);
- data++;
- } else {
- data = data / (MCLK << 4);
- }
+ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+ if(SiS_Pr->SiS_UseROM) {
+ if(ROMAddr[0x220] & 0x01) {
+ VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
+ }
+ }
+ }
- if(data <= 6) data = 6;
- if(data > 0x14) data = 0x14;
+ } else {
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
- if(HwInfo->jChipType == SIS_300) {
- if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
- else temp = (temp & (~0x1F)) | 0x16;
- if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
- temp = (temp & (~0x1F)) | 0x13;
- }
- } else {
- if( ( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) &&
- (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
- {
- temp = (temp & (~0x1F)) | 0x1b;
- } else {
- temp = (temp & (~0x1F)) | 0x16;
- }
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
+ /* Get VCLK */
+ CRT2ModeNo = 0xfe;
+ VCLK = SiS_Pr->CSRClock;
- if( (HwInfo->jChipType == SIS_630) &&
- (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
- {
- if(data > 0x13) data = 0x13;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
+ }
+
+ /* Get colordepth */
+ colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
+ if(!colorth) colorth++;
+
+ data = data * VCLK * colorth;
+ temp = data % (MCLK << 4);
+ data = data / (MCLK << 4);
+ if(temp) data++;
+
+ if(data < 6) data = 6;
+ else if(data > 0x14) data = 0x14;
+
+ if(SiS_Pr->ChipType == SIS_300) {
+ temp = 0x16;
+ if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
+ temp = 0x13;
+ } else {
+ temp = 0x16;
+ if(( (SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730) ) &&
+ (SiS_Pr->ChipRevision >= 0x30))
+ temp = 0x1b;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
+
+ if((SiS_Pr->ChipType == SIS_630) &&
+ (SiS_Pr->ChipRevision >= 0x30)) {
+ if(data > 0x13) data = 0x13;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
} else { /* If mode <= 0x13, we just restore everything */
- SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
- SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
}
}
@@ -5278,10 +5267,10 @@ SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
/* Set CRT2 FIFO on 315/330 series */
#ifdef SIS315H
static void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
{
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
- if( (HwInfo->jChipType == SIS_760) &&
+ if( (SiS_Pr->ChipType == SIS_760) &&
(SiS_Pr->SiS_SysFlags & SF_760LFB) &&
(SiS_Pr->SiS_ModeType == Mode32Bpp) &&
(SiS_Pr->SiS_VGAHDE >= 1280) &&
@@ -5299,337 +5288,162 @@ SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
#endif
-static USHORT
-SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
{
- ULONG tempax,tempbx;
+ unsigned int tempax,tempbx;
tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
- return((USHORT)tempax);
+ return (unsigned short)tempax;
}
/* Set Part 1 / SiS bridge slave mode */
static void
-SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
-{
- USHORT push1,push2;
- USHORT tempax,tempbx,tempcx,temp;
- USHORT resinfo,modeflag,xres=0;
- unsigned char p1_7, p1_8;
+SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
+ static const unsigned short CRTranslation[] = {
+ /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */
+ 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
+ /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */
+ 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
+ };
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
} else if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
- resinfo = 0;
xres = SiS_Pr->CHDisplay;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
}
/* The following is only done if bridge is in slave mode: */
- if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
- if(xres >= 1600) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(xres >= 1600) { /* BIOS: == 1600 */
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
}
}
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
+ SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */
- if(modeflag & Charx8Dot) tempcx = 0x08;
- else tempcx = 0x09;
-
- tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax = ((tempax / tempcx) - 1) & 0xff;
- tempbx = tempax;
-
- temp = tempax;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
+ SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
+ if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
+ SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
- temp += 2;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(resinfo == SIS_RI_800x600) temp -= 2;
- }
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
-
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
-
- tempax = 0xFFFF;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
- if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax = (tempax / tempcx) - 5;
- tempcx = tempax;
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- temp = tempcx - 1;
- if(!(modeflag & HalfDCLK)) {
- temp -= 6;
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- temp -= 2;
- if(ModeNo > 0x13) temp -= 10;
- }
- }
- } else {
- tempcx = (tempcx + tempbx) >> 1;
- temp = (tempcx & 0x00FF) + 2;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- temp--;
- if(!(modeflag & HalfDCLK)) {
- if((modeflag & Charx8Dot)) {
- temp += 4;
- if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
- }
- }
- }
- } else {
- if(!(modeflag & HalfDCLK)) {
- temp -= 4;
- if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
- (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
- if(SiS_Pr->SiS_VGAHDE >= 800) {
- temp -= 7;
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_ModeType == ModeEGA) {
- if(SiS_Pr->SiS_VGAVDE == 1024) {
- temp += 15;
- if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
- temp += 7;
- }
- }
- }
- if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
- if(SiS_Pr->SiS_VGAHDE >= 1280) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
- }
- }
- }
- }
- }
- }
+ SiS_Pr->CHBlankStart += 16;
}
- p1_7 = temp;
- p1_8 = 0x00;
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(ModeNo <= 0x01) {
- p1_7 = 0x2a;
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_8 = 0x61;
- else p1_8 = 0x41;
- } else if(SiS_Pr->SiS_ModeType == ModeText) {
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) p1_7 = 0x54;
- else p1_7 = 0x55;
- p1_8 = 0x00;
- } else if(ModeNo <= 0x13) {
- if(modeflag & HalfDCLK) {
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
- p1_7 = 0x30;
- p1_8 = 0x03;
- } else {
- p1_7 = 0x2f;
- p1_8 = 0x02;
- }
- } else {
- p1_7 = 0x5b;
- p1_8 = 0x03;
- }
- } else if( ((HwInfo->jChipType >= SIS_315H) &&
- ((ModeNo == 0x50) || (ModeNo == 0x56) || (ModeNo == 0x53))) ||
- ((HwInfo->jChipType < SIS_315H) &&
- (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
- p1_7 = 0x30,
- p1_8 = 0x03;
- } else {
- p1_7 = 0x2f;
- p1_8 = 0x03;
- }
- }
- }
+ SiS_Pr->CHBlankEnd = 32;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
}
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p)) {
- p1_7 = 0x63;
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) p1_7 = 0x55;
- }
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(!(modeflag & HalfDCLK)) {
- p1_7 = 0xb2;
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
- p1_7 = 0xab;
- }
- }
- } else {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
- if(modeflag & HalfDCLK) p1_7 = 0x30;
- }
- }
+ temp = SiS_Pr->SiS_VGAHT - 96;
+ if(!(modeflag & HalfDCLK)) temp -= 32;
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
+ temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
+ temp -= 3;
+ temp <<= 3;
+ } else {
+ if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
}
+ SiS_Pr->CHSyncStart = temp;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7); /* 0x07 Horizontal Retrace Start */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8); /* 0x08 Horizontal Retrace End */
+ SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03); /* 0x18 SR08 (FIFO Threshold?) */
+ SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+ VGAVDE = SiS_Pr->SiS_VGAVDE;
+ if (VGAVDE == 357) VGAVDE = 350;
+ else if(VGAVDE == 360) VGAVDE = 350;
+ else if(VGAVDE == 375) VGAVDE = 350;
+ else if(VGAVDE == 405) VGAVDE = 400;
+ else if(VGAVDE == 420) VGAVDE = 400;
+ else if(VGAVDE == 525) VGAVDE = 480;
+ else if(VGAVDE == 1056) VGAVDE = 1024;
+ SiS_Pr->CVDisplay = VGAVDE;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF); /* 0x09 Set Max VT */
+ SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
- tempcx = 0x121;
- tempbx = SiS_Pr->SiS_VGAVDE; /* 0x0E Vertical Display End */
- if (tempbx == 357) tempbx = 350;
- else if(tempbx == 360) tempbx = 350;
- else if(tempbx == 375) tempbx = 350;
- else if(tempbx == 405) tempbx = 400;
- else if(tempbx == 420) tempbx = 400;
- else if(tempbx == 525) tempbx = 480;
- push2 = tempbx;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if (tempbx == 350) tempbx += 5;
- else if(tempbx == 480) tempbx += 5;
- }
- }
- }
- tempbx -= 2;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* 0x10 vertical Blank Start */
-
- tempbx = push2;
- tempbx--;
- temp = tempbx & 0x00FF;
-#if 0
- /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
- if(xxx()) {
- if(temp == 0xdf) temp = 0xda;
- }
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
-
- temp = 0;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- if(HwInfo->jChipType >= SIS_661) {
- if(tempbx & 0x0200) temp |= 0x20;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x0B,0x5F,temp);
- if(tempbx & 0x0100) tempcx |= 0x000a;
- if(tempbx & 0x0400) tempcx |= 0x1200;
- } else {
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
- if(tempbx & 0x0100) tempcx |= 0x0002;
- if(tempbx & 0x0400) tempcx |= 0x0600;
- }
+ SiS_Pr->CVBlankEnd = 1;
+ if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
- if(tempbx & 0x0200) tempcx |= 0x0040;
+ temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
+ SiS_Pr->CVSyncStart = VGAVDE + temp;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00); /* 0x11 Vertical Blank End */
+ temp >>= 3;
+ SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
- tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+ SiS_CalcCRRegisters(SiS_Pr, 0);
+ SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
- if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
- if(resinfo != SIS_RI_1280x1024) {
- tempbx += (tempax << 1);
- }
- } else if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
- tempbx += (tempax << 1);
- }
+ for(i = 0; i <= 7; i++) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
}
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- tempbx -= 10;
- } else {
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- tempbx += 40;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
- }
- }
- }
- }
- tempax >>= 2;
- tempax++;
- tempax += tempbx;
- push1 = tempax;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- if(tempbx <= 513) {
- if(tempax >= 513) tempbx = 513;
- }
+ for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
}
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* 0x0C Vertical Retrace Start */
-
- tempbx--;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
-
- if(tempbx & 0x0100) tempcx |= 0x0008;
-
- if(tempbx & 0x0200) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+ for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
}
- tempbx++;
-
- if(tempbx & 0x0100) tempcx |= 0x0004;
- if(tempbx & 0x0200) tempcx |= 0x0080;
- if(tempbx & 0x0400) {
- if(HwInfo->jChipType >= SIS_661) tempcx |= 0x0800;
- else if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
- else tempcx |= 0x0C00;
+ for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
}
- tempbx = push1;
- temp = tempbx & 0x000F;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* 0x0D vertical Retrace End */
-
- if(tempbx & 0x0010) tempcx |= 0x2000;
-
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* 0x0A CR07 */
-
- temp = (tempcx & 0xFF00) >> 8;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* 0x17 SR0A */
+ temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
- tempax = modeflag;
- temp = (tempax & 0xFF00) >> 8;
- temp = (temp >> 1) & 0x09;
- if(!(SiS_Pr->SiS_VBType & VB_SIS301)) temp |= 0x01; /* Always 8 dotclock */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* 0x16 SR01 */
+ temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* 0x0F CR14 */
+ temp = 0;
+ temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
+ if(modeflag & HalfDCLK) temp |= 0x08;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* 0x12 CR17 */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */
- temp = 0x00;
+ temp = 0;
if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
- temp = 0x80;
- }
+ temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
}
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */
temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
+
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
+ SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+ SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
+ SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
+
+ xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+ SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+ SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
+ SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
+ SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
+ xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+ SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+ SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
+ SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
+ SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
+ xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
+#endif
+#endif
}
/* Setup panel link
@@ -5637,18 +5451,18 @@ SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
* 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
*/
static void
-SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT modeflag,resinfo;
- USHORT push2,tempax,tempbx,tempcx,temp;
- ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+ unsigned short modeflag, resinfo = 0;
+ unsigned short push2, tempax, tempbx, tempcx, temp;
+ unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
#ifdef SIS300
- USHORT crt2crtc;
+ unsigned short crt2crtc = 0;
#endif
#ifdef SIS315H
- USHORT pushcx;
+ unsigned short pushcx;
#endif
if(ModeNo <= 0x13) {
@@ -5659,15 +5473,11 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#endif
} else if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
- resinfo = 0;
-#ifdef SIS300
- crt2crtc = 0;
-#endif
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
#ifdef SIS300
- crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
#endif
}
@@ -5681,14 +5491,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
issis = TRUE;
}
- if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
+ if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
chkdclkfirst = TRUE;
}
}
#ifdef SIS315H
- if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
if(IS_SIS330) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
} else if(IS_SIS740) {
@@ -5704,7 +5514,7 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
- if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
@@ -5720,10 +5530,10 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempax = SiS_Pr->SiS_LCDHDES;
if(islvds) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
- tempax -= 8;
+ if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+ tempax -= 8;
}
}
}
@@ -5736,13 +5546,14 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempbx = SiS_Pr->SiS_HDE;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
- tempbx >>= 1;
- }
if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
tempbx = SiS_Pr->PanelXRes;
}
+ if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
+ tempbx >>= 1;
+ }
}
tempax += tempbx;
@@ -5767,25 +5578,25 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
temp = (tempcx >> 3) & 0x00FF;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
- if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- switch(ModeNo) {
- case 0x04:
- case 0x05:
- case 0x0d: temp = 0x56; break;
- case 0x10: temp = 0x60; break;
- case 0x13: temp = 0x5f; break;
- case 0x40:
- case 0x41:
- case 0x4f:
- case 0x43:
- case 0x44:
- case 0x62:
- case 0x56:
- case 0x53:
- case 0x5d:
- case 0x5e: temp = 0x54; break;
- }
- }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ switch(ModeNo) {
+ case 0x04:
+ case 0x05:
+ case 0x0d: temp = 0x56; break;
+ case 0x10: temp = 0x60; break;
+ case 0x13: temp = 0x5f; break;
+ case 0x40:
+ case 0x41:
+ case 0x4f:
+ case 0x43:
+ case 0x44:
+ case 0x62:
+ case 0x56:
+ case 0x53:
+ case 0x5d:
+ case 0x5e: temp = 0x54; break;
+ }
+ }
}
}
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
@@ -5793,12 +5604,12 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
temp += 2;
if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- temp += 8;
- if(SiS_Pr->PanelHRE != 999) {
- temp = tempcx + SiS_Pr->PanelHRE;
+ temp += 8;
+ if(SiS_Pr->PanelHRE != 999) {
+ temp = tempcx + SiS_Pr->PanelHRE;
if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
temp >>= 3;
- }
+ }
}
} else {
temp += 10;
@@ -5806,9 +5617,6 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
temp &= 0x1F;
temp |= ((tempcx & 0x07) << 5);
-#if 0
- if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
-#endif
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
/* Vertical */
@@ -5826,9 +5634,9 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
push2 = tempbx;
tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
}
}
@@ -5844,19 +5652,19 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(issis) tempbx++;
} else {
tempbx += tempcx;
- if(HwInfo->jChipType < SIS_315H) tempbx++;
+ if(SiS_Pr->ChipType < SIS_315H) tempbx++;
else if(issis) tempbx++;
}
- if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
+ if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
temp = tempbx & 0x00FF;
if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(ModeNo == 0x10) temp = 0xa9;
+ if(ModeNo == 0x10) temp = 0xa9;
}
}
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */
tempcx >>= 3;
tempcx++;
@@ -5879,13 +5687,13 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
} else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
tempbx = 0x87;
- if((HwInfo->jChipType >= SIS_315H) ||
- (HwInfo->jChipRevision >= 0x30)) {
+ if((SiS_Pr->ChipType >= SIS_315H) ||
+ (SiS_Pr->ChipRevision >= 0x30)) {
tempbx = 0x07;
if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
}
- /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
+ /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
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,
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
- tempbx = push2; /* BPLVDEE */
+ tempbx = push2; /* BPLVDEE */
- tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
+ tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_640x480:
- tempbx = SiS_Pr->SiS_VGAVDE - 1;
- tempcx = SiS_Pr->SiS_VGAVDE;
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ tempcx = SiS_Pr->SiS_VGAVDE;
break;
case Panel_800x600:
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- if(resinfo == SIS_RI_800x600) tempcx++;
- }
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_800x600) tempcx++;
+ }
break;
case Panel_1024x600:
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- if(resinfo == SIS_RI_1024x600) tempcx++;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_1024x600) tempcx++;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
if(resinfo == SIS_RI_800x600) tempcx++;
}
- }
+ }
break;
case Panel_1024x768:
- if(HwInfo->jChipType < SIS_315H) {
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- if(resinfo == SIS_RI_1024x768) tempcx++;
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_1024x768) tempcx++;
}
- }
+ }
break;
}
}
temp = ((tempbx >> 8) & 0x07) << 3;
- temp = temp | ((tempcx >> 8) & 0x07);
+ temp |= ((tempcx >> 8) & 0x07);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
- /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
/* Vertical scaling */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
tempeax = SiS_Pr->SiS_VGAVDE << 6;
- temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
- tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+ temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
+ tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
if(temp) tempeax++;
if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
- temp = (USHORT)(tempeax & 0x00FF);
+ temp = (unsigned short)(tempeax & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
tempvcfact = temp;
#endif /* SIS300 */
@@ -5963,20 +5770,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(temp) tempeax++;
tempvcfact = tempeax;
- temp = (USHORT)(tempeax & 0x00FF);
+ temp = (unsigned short)(tempeax & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
- temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+ temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
- temp = (USHORT)((tempeax & 0x00030000) >> 16);
+ temp = (unsigned short)((tempeax & 0x00030000) >> 16);
if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
- temp = (USHORT)(tempeax & 0x00FF);
+ if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
+ temp = (unsigned short)(tempeax & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
- temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+ temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
- temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
+ temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
temp = 0;
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,
tempecx = 0xFFFF;
} else {
tempecx = tempebx / SiS_Pr->SiS_HDE;
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
}
}
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
tempeax = (tempebx / tempecx) - 1;
} else {
tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
}
tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
- temp = (USHORT)(tempecx & 0x00FF);
+ temp = (unsigned short)(tempecx & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
- tempbx = (USHORT)(tempeax & 0xFFFF);
+ tempbx = (unsigned short)(tempeax & 0xFFFF);
} else {
tempeax = SiS_Pr->SiS_VGAVDE << 6;
tempbx = tempvcfact & 0x3f;
if(tempbx == 0) tempbx = 64;
tempeax /= tempbx;
- tempbx = (USHORT)(tempeax & 0xFFFF);
+ tempbx = (unsigned short)(tempeax & 0xFFFF);
}
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
@@ -6032,24 +5839,24 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
- tempecx >>= 16; /* BPLHCFACT */
+ tempecx >>= 16; /* BPLHCFACT */
if(!chkdclkfirst) {
if(modeflag & HalfDCLK) tempecx >>= 1;
}
- temp = (USHORT)((tempecx & 0xFF00) >> 8);
+ temp = (unsigned short)((tempecx & 0xFF00) >> 8);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
- temp = (USHORT)(tempecx & 0x00FF);
+ temp = (unsigned short)(tempecx & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+ if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
}
} else {
if(islvds) {
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
} else {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
@@ -6061,17 +5868,26 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#ifdef SIS300
if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
- int i;
- UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
- UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
- UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned char *trumpdata;
+ int i, j = crt2crtc;
+ unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
+ unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
+ unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+
+ if(SiS_Pr->SiS_UseROM) {
+ trumpdata = &ROMAddr[0x8001 + (j * 80)];
+ } else {
+ if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
+ trumpdata = &SiS300_TrumpionData[j][0];
+ }
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
for(i=0; i<5; i++) {
- SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
+ SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
}
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(ModeNo == 0x13) {
+ if(ModeNo == 0x13) {
for(i=0; i<4; i++) {
SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
}
@@ -6095,67 +5911,66 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
- tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
- if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
+ tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
tempax += 64;
- temp = tempax & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
- temp = ((tempax & 0xFF00) >> 8) << 3;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
+ temp = (tempax >> 8) << 3;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
- tempax += 32; /* Blpe=lBlps+32 */
- temp = tempax & 0x00FF;
- if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml=0 */
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+ tempax += 32; /* Blpe = lBlps+32 */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
tempax = SiS_Pr->SiS_VDE;
- if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
tempax >>= 1;
- temp = tempax & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
- temp = ((tempax & 0xFF00) >> 8) << 3;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
+ temp = (tempax >> 8) << 3;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
tempeax = SiS_Pr->SiS_HDE;
- if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
- tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
- tempebx = 128;
- temp = (USHORT)(tempeax % tempebx);
- tempeax = tempeax / tempebx;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
+ tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
+ temp = tempeax & 0x7f;
+ tempeax >>= 7;
if(temp) tempeax++;
- temp = (USHORT)(tempeax & 0x003F);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
+ temp = tempeax & 0x3f;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
tempax = SiS_Pr->SiS_HDE;
- if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
- tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
+ tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
pushcx = tempax;
temp = tempax & 0x00FF;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
temp = ((tempax & 0xFF00) >> 8) << 3;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
- tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
- if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
- tempeax = (tempax * pushcx);
- tempebx = 0x00100000 + tempeax;
- temp = (USHORT)tempebx & 0x000000FF;
+ tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
+ tempeax = tempax * pushcx;
+ temp = tempeax & 0xFF;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
- temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+ temp = (tempeax & 0xFF00) >> 8;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
- temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
+ temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
- temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
+ temp = ((tempeax & 0x01000000) >> 24) << 7;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
@@ -6192,20 +6007,20 @@ SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* Set Part 1 */
static void
-SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
#if defined(SIS300) || defined(SIS315H)
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
#endif
- USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
- USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
+ unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
+ unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
#ifdef SIS315H
- USHORT tempbl=0;
+ unsigned short tempbl=0;
#endif
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
return;
}
@@ -6214,47 +6029,47 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
} else if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
} else {
- CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
- SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
- if( ! ((HwInfo->jChipType >= SIS_315H) &&
+ if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
(SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
- if(HwInfo->jChipType < SIS_315H ) {
+ if(SiS_Pr->ChipType < SIS_315H ) {
#ifdef SIS300
- SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
+ SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
#endif
} else {
#ifdef SIS315H
- SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
+ SiS_SetCRT2FIFO_310(SiS_Pr);
#endif
}
/* 1. Horizontal setup */
- if(HwInfo->jChipType < SIS_315H ) {
+ if(SiS_Pr->ChipType < SIS_315H ) {
#ifdef SIS300 /* ------------- 300 series --------------*/
- temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
+ temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
- temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+ temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
- temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
+ temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
- tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
- tempbx = pushbx + tempcx;
- tempcx <<= 1;
- tempcx += tempbx;
+ tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+ tempbx = pushbx + tempcx;
+ tempcx <<= 1;
+ tempcx += tempbx;
bridgeadd = 12;
@@ -6301,7 +6116,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
bridgeadd = 16;
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
if(resinfo == SIS_RI_1280x1024) {
@@ -6319,7 +6134,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->UseCustomMode) {
+ if(SiS_Pr->UseCustomMode) {
tempbx = SiS_Pr->CHSyncStart + bridgeadd;
tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
tempax = SiS_Pr->SiS_VGAHT;
@@ -6341,22 +6156,22 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
}
- tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
tempcx &= 0x00FF;
tempcx |= (tempbx & 0xFF00);
- tempbx += bridgeadd;
- tempcx += bridgeadd;
+ tempbx += bridgeadd;
+ tempcx += bridgeadd;
tempax = SiS_Pr->SiS_VGAHT;
if(modeflag & HalfDCLK) tempax >>= 1;
tempax--;
if(tempcx > tempax) tempcx = tempax;
- }
+ }
- if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
- tempbx = 1040;
- tempcx = 1044; /* HWCursor bug! */
- }
+ if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
+ tempbx = 1040;
+ tempcx = 1044; /* HWCursor bug! */
+ }
}
@@ -6372,18 +6187,18 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempcx = SiS_Pr->SiS_VGAVT - 1;
temp = tempcx & 0x00FF;
- if(HwInfo->jChipType < SIS_661) {
+ if(SiS_Pr->ChipType < SIS_661) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
temp--;
}
- }
+ }
} else {
- temp--;
- }
- } else if(HwInfo->jChipType >= SIS_315H) {
+ temp--;
+ }
+ } else if(SiS_Pr->ChipType >= SIS_315H) {
temp--;
}
}
@@ -6395,9 +6210,9 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
- if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- tempbx++;
- tempax = tempbx;
+ if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
+ tempbx++;
+ tempax = tempbx;
tempcx++;
tempcx -= tempax;
tempcx >>= 2;
@@ -6407,8 +6222,8 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempcx += tempbx;
tempcx++;
} else {
- tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
- tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
}
if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -6416,7 +6231,7 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempbx = SiS_Pr->CVSyncStart;
tempcx = SiS_Pr->CVSyncEnd;
}
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
unsigned char cr8, cr7, cr13;
if(SiS_Pr->UseCustomMode) {
cr8 = SiS_Pr->CCRT1CRTC[8];
@@ -6429,11 +6244,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
}
- tempbx = cr8;
- if(cr7 & 0x04) tempbx |= 0x0100;
- if(cr7 & 0x80) tempbx |= 0x0200;
- if(cr13 & 0x08) tempbx |= 0x0400;
- }
+ tempbx = cr8;
+ if(cr7 & 0x04) tempbx |= 0x0100;
+ if(cr7 & 0x80) tempbx |= 0x0200;
+ if(cr13 & 0x08) tempbx |= 0x0400;
+ }
}
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
@@ -6442,13 +6257,13 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* 3. Panel delay compensation */
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300 /* ---------- 300 series -------------- */
if(SiS_Pr->SiS_VBType & VB_SISVB) {
temp = 0x20;
- if(HwInfo->jChipType == SIS_300) {
+ if(SiS_Pr->ChipType == SIS_300) {
temp = 0x10;
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
@@ -6460,24 +6275,23 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
- else temp = 0x20;
- }
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
+ else temp = 0x20;
+ }
if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x80) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
- temp = ROMAddr[0x221];
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
+ temp = ROMAddr[0x221];
else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
temp = ROMAddr[0x222];
else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
temp = ROMAddr[0x223];
else
temp = ROMAddr[0x224];
- temp &= 0x3c;
}
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
+ if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
}
} else {
@@ -6487,15 +6301,17 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x80) {
- temp = ROMAddr[0x220] & 0x3c;
+ temp = ROMAddr[0x220];
}
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
+ if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
}
- }
+ }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+ temp &= 0x3c;
+
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
#endif /* SIS300 */
@@ -6503,16 +6319,16 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#ifdef SIS315H /* --------------- 315/330 series ---------------*/
- if(HwInfo->jChipType < SIS_661) {
+ if(SiS_Pr->ChipType < SIS_661) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(HwInfo->jChipType == SIS_740) temp = 0x03;
- else temp = 0x00;
+ if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
+ else temp = 0x00;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
tempbl = 0xF0;
- if(HwInfo->jChipType == SIS_650) {
+ if(SiS_Pr->ChipType == SIS_650) {
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
}
@@ -6531,10 +6347,10 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
} /* < 661 */
- tempax = 0;
- if(modeflag & DoubleScanMode) tempax |= 0x80;
- if(modeflag & HalfDCLK) tempax |= 0x40;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+ tempax = 0;
+ if(modeflag & DoubleScanMode) tempax |= 0x80;
+ if(modeflag & HalfDCLK) tempax |= 0x40;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
#endif /* SIS315H */
@@ -6544,21 +6360,21 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBType & VB_SISVB) {
if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- /* For 301BDH with LCD, we set up the Panel Link */
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ /* For 301BDH with LCD, we set up the Panel Link */
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
} else {
- if(HwInfo->jChipType < SIS_315H) {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ if(SiS_Pr->ChipType < SIS_315H) {
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
} else {
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
- }
+ if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
+ }
} else {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
}
}
}
@@ -6569,11 +6385,11 @@ SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
#ifdef SIS315H
-static UCHAR *
-SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
+static unsigned char *
+SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
{
- const UCHAR *tableptr = NULL;
- USHORT a, b, p = 0;
+ const unsigned char *tableptr = NULL;
+ unsigned short a, b, p = 0;
a = SiS_Pr->SiS_VGAHDE;
b = SiS_Pr->SiS_HDE;
@@ -6606,25 +6422,25 @@ SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
}
p += 2;
- return((UCHAR *)&tableptr[p]);
+ return ((unsigned char *)&tableptr[p]);
}
static void
-SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- UCHAR *tableptr;
+ unsigned char *tableptr;
+ unsigned char temp;
int i, j;
- UCHAR temp;
- if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
- tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0, HwInfo);
+ tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1, HwInfo);
+ tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
}
@@ -6635,12 +6451,12 @@ SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
static BOOLEAN
-SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,USHORT *CRT2Index,
- USHORT *ResIndex,PSIS_HW_INFO HwInfo)
+SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
+ unsigned short *ResIndex)
{
- if(HwInfo->jChipType < SIS_315H) return FALSE;
+ if(SiS_Pr->ChipType < SIS_315H) return FALSE;
if(ModeNo <= 0x13)
(*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -6661,82 +6477,79 @@ SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
}
}
- return(((*CRT2Index) != 0));
+ return (((*CRT2Index) != 0));
}
#endif
#ifdef SIS300
static void
-SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
+SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
{
- USHORT tempcx;
- const UCHAR atable[] = {
+ unsigned short tempcx;
+ static const unsigned char atable[] = {
0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
};
if(!SiS_Pr->UseCustomMode) {
- if( ( ( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) &&
- (HwInfo->jChipRevision > 2) ) &&
- (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
- (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
- (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
- if(ModeNo == 0x13) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
- } else {
- if((crt2crtc & 0x3F) == 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
- }
- }
+ if( ( ( (SiS_Pr->ChipType == SIS_630) ||
+ (SiS_Pr->ChipType == SIS_730) ) &&
+ (SiS_Pr->ChipRevision > 2) ) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
+ (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
+ (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+ if(ModeNo == 0x13) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+ } else if((crt2crtc & 0x3F) == 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+ }
}
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
- crt2crtc &= 0x1f;
- tempcx = 0;
- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- tempcx += 7;
- }
- }
- tempcx += crt2crtc;
- if(crt2crtc >= 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
- }
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+ crt2crtc &= 0x1f;
+ tempcx = 0;
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ tempcx += 7;
+ }
+ }
+ tempcx += crt2crtc;
+ if(crt2crtc >= 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
+ }
- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(crt2crtc == 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
- }
- }
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
- }
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(crt2crtc == 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
+ }
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+ }
}
}
}
/* For ECS A907. Highly preliminary. */
static void
-SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- USHORT ModeNo)
+SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
+ unsigned short ModeNo)
{
- USHORT crt2crtc, resindex;
- int i,j;
- const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+ const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
+ unsigned short crt2crtc, resindex;
+ int i, j;
- if(HwInfo->jChipType != SIS_300) return;
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+ if(SiS_Pr->ChipType != SIS_300) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
if(SiS_Pr->UseCustomMode) return;
if(ModeNo <= 0x13) {
@@ -6758,13 +6571,13 @@ SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
}
for(j = 0x1c; j <= 0x1d; i++, j++ ) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
}
for(j = 0x1f; j <= 0x21; i++, j++ ) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
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,
#endif
static void
-SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
- const UCHAR specialtv[] = {
+ const unsigned char specialtv[] = {
0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
0x58,0xe4,0x73,0xda,0x13
@@ -6813,16 +6626,16 @@ SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
}
static void
-SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
+SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- USHORT temp;
+ unsigned short temp;
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
if(SiS_Pr->SiS_VGAVDE == 525) {
temp = 0xc3;
if(SiS_Pr->SiS_ModeType <= ModeVGA) {
temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
@@ -6830,7 +6643,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
temp = 0x4d;
if(SiS_Pr->SiS_ModeType <= ModeVGA) {
temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
}
@@ -6838,7 +6651,7 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
/* Not always for LV, see SetGrp2 */
}
@@ -6872,17 +6685,17 @@ SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
}
static void
-SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
-{
- USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
- USHORT push2, modeflag, crt2crtc, bridgeoffset;
- ULONG longtemp;
- const UCHAR *PhasePoint;
- const UCHAR *TimingPoint;
+SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
+ unsigned short push2, modeflag, crt2crtc, bridgeoffset;
+ unsigned int longtemp, PhaseIndex;
+ BOOLEAN newtvphase;
+ const unsigned char *TimingPoint;
#ifdef SIS315H
- USHORT resindex, CRT2Index;
- const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+ unsigned short resindex, CRT2Index;
+ const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
#endif
@@ -6908,9 +6721,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
- PhasePoint = SiS_Pr->SiS_PALPhase;
+ PhaseIndex = 0x01; /* SiS_PALPhase */
TimingPoint = SiS_Pr->SiS_PALTiming;
+ newtvphase = FALSE;
+ if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
+ ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+ (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
+ newtvphase = TRUE;
+ }
+
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
@@ -6918,82 +6738,54 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-#if 0
- if(!(modeflag & Charx8Dot)) TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
-#endif
}
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) TimingPoint = &SiS_YPbPrTable[2][0];
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) TimingPoint = &SiS_YPbPrTable[1][0];
- else TimingPoint = &SiS_YPbPrTable[0][0];
+ i = 0;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
+
+ TimingPoint = &SiS_YPbPrTable[i][0];
- PhasePoint = SiS_Pr->SiS_NTSCPhase;
+ PhaseIndex = 0x00; /* SiS_NTSCPhase */
} else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
- (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
- PhasePoint = SiS_Pr->SiS_PALPhase2;
- }
+ if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
} else {
TimingPoint = SiS_Pr->SiS_NTSCTiming;
- PhasePoint = SiS_Pr->SiS_NTSCPhase;
- if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
- PhasePoint = SiS_Pr->SiS_PALPhase;
- }
-
- if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
- (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
- PhasePoint = SiS_Pr->SiS_NTSCPhase2;
- if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
- PhasePoint = SiS_Pr->SiS_PALPhase2;
- }
- }
-
- }
+ PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */
+ if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- PhasePoint = SiS_Pr->SiS_PALMPhase;
- if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
- (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
- PhasePoint = SiS_Pr->SiS_PALMPhase2;
- }
}
- if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- PhasePoint = SiS_Pr->SiS_PALNPhase;
- if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
- ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
- (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
- PhasePoint = SiS_Pr->SiS_PALNPhase2;
- }
+ if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
+ PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */
+ if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */
}
if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
- PhasePoint = SiS_Pr->SiS_SpecialPhase;
if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- PhasePoint = SiS_Pr->SiS_SpecialPhaseM;
+ PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
} else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
- PhasePoint = SiS_Pr->SiS_SpecialPhaseJ;
+ PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
+ } else {
+ PhaseIndex = 0x10; /* SiS_SpecialPhase */
}
}
- for(i=0x31, j=0; i<=0x34; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
+ for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
}
- for(i=0x01, j=0; i<=0x2D; i++, j++) {
+ for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
}
- for(i=0x39; i<=0x45; i++, j++) {
+ for(i = 0x39; i <= 0x45; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
}
@@ -7010,28 +6802,32 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
- else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
- else tempax = 440; /* NTSC, YPbPr 525, 750 */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680;
+ else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
+ else tempax = 440; /* NTSC, YPbPr 525 */
- if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+ if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
tempax -= SiS_Pr->SiS_VDE;
- tempax >>= 2;
+ tempax >>= 1;
+ if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
+ tempax >>= 1;
+ }
tempax &= 0x00ff;
- temp = tempax + (USHORT)TimingPoint[0];
+ temp = tempax + (unsigned short)TimingPoint[0];
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
- temp = tempax + (USHORT)TimingPoint[1];
+ temp = tempax + (unsigned short)TimingPoint[1];
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
} else {
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
@@ -7041,14 +6837,14 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
}
tempcx = SiS_Pr->SiS_HT;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
tempcx--;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
tempcx = SiS_Pr->SiS_HT >> 1;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
tempcx += 7;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
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
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
tempcx = SiS_Pr->SiS_HT >> 1;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
j += 2;
tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
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
} else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
tempbx >>= 1;
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
@@ -7123,23 +6919,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
}
-#if 0
- /* TEST qqqq */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- for(i=0x01, j=0; i<=0x2D; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
- }
- for(i=0x39; i<=0x45; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
- }
- }
-#endif
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
tempbx = SiS_Pr->SiS_VDE;
if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
@@ -7150,7 +6934,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
}
}
@@ -7165,14 +6949,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
tempch = tempcl = 0x01;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(SiS_Pr->SiS_VGAHDE >= 1024) {
- if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
- tempch = 0x19;
+ if(SiS_Pr->SiS_VGAHDE >= 960) {
+ if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
tempcl = 0x20;
- if(SiS_Pr->SiS_VGAHDE >= 1280) {
- tempch = 0x14;
+ if(SiS_Pr->SiS_VGAHDE >= 1280) {
+ tempch = 20;
tempbx &= ~0x20;
- }
+ } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
+ tempch = 25;
+ } else {
+ tempch = 25; /* OK */
+ }
}
}
}
@@ -7180,7 +6967,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
if(!(tempbx & 0x20)) {
if(modeflag & HalfDCLK) tempcl <<= 1;
longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
tempax = longtemp / SiS_Pr->SiS_HDE;
if(longtemp % SiS_Pr->SiS_HDE) tempax++;
tempbx |= ((tempax >> 8) & 0x1F);
@@ -7190,7 +6977,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
tempcx &= 0x07;
if(tempbx & 0x20) tempcx = 0;
@@ -7219,7 +7006,7 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
SiS_SetTVSpecial(SiS_Pr, ModeNo);
- if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
temp = 0;
if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
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
/* From here: Part2 LCD setup */
tempbx = SiS_Pr->SiS_HDE;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
tempbx--; /* RHACTE = HDE - 1 */
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
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
if(SiS_Pr->SiS_ModeType == ModeEGA) {
if(SiS_Pr->SiS_VGAHDE >= 1024) {
temp = 0x02;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
- temp = 0x01;
- }
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ temp = 0x01;
}
}
}
@@ -7289,11 +7074,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
#ifdef SIS315H
if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &CRT2Index, &resindex, HwInfo)) {
+ &CRT2Index, &resindex)) {
switch(CRT2Index) {
+ case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
+ default:
case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
- case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
- default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
}
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
SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
-
} else {
#endif
@@ -7349,9 +7133,11 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
/* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
#endif
+#endif
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
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
tempbx = SiS_Pr->CVSyncStart;
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
#endif
+#endif
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
@@ -7416,26 +7204,30 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
temp |= (SiS_Pr->CVSyncEnd & 0x0f);
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
#endif
+#endif
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
#ifdef SIS300
- SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
+ SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
#endif
bridgeoffset = 7;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2;
+ if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
+ if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++;
+ else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */
+ /* Higher bridgeoffset shifts to the LEFT */
temp = 0;
if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
- temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
+ temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+ if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
}
}
temp += bridgeoffset;
@@ -7450,15 +7242,17 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
}
}
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+ if(SiS_IsDualLink(SiS_Pr)) {
tempcx >>= 1;
tempbx >>= 1;
tempax >>= 1;
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
#endif
+#endif
tempbx += bridgeoffset;
@@ -7480,13 +7274,16 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
if(SiS_Pr->UseCustomMode) {
tempbx = SiS_Pr->CHSyncStart;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ if(modeflag & HalfDCLK) tempbx <<= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
tempbx += bridgeoffset;
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
#endif
+#endif
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
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
if(SiS_Pr->UseCustomMode) {
tempbx = SiS_Pr->CHSyncEnd;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ if(modeflag & HalfDCLK) tempbx <<= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
tempbx += bridgeoffset;
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
#endif
+#endif
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
#ifdef SIS300
- SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
+ SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
#endif
#ifdef SIS315H
} /* CRT2-LCD from table */
@@ -7526,11 +7326,10 @@ SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT Refr
/*********************************************/
static void
-SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT i;
- const UCHAR *tempdi;
+ unsigned short i;
+ const unsigned char *tempdi;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
@@ -7570,7 +7369,7 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
for(i=0; i<=0x3E; i++) {
SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
}
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
}
@@ -7587,35 +7386,43 @@ SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
#ifdef SIS315H
+#if 0
static void
-SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
+SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
{
- USHORT temp, temp1, temp2;
+ unsigned short temp, temp1, temp2;
temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
- temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+ temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
- temp = (USHORT)((int)(temp) + shift);
+ temp = (unsigned short)((int)(temp) + shift);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
- temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+ temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
}
+#endif
static void
-SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
+SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT temp, temp1, resinfo = 0;
+ unsigned short temp, temp1, resinfo = 0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
- if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
+ if(SiS_Pr->ChipType >= XGI_20) return;
+
+ if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
+ if(!(ROMAddr[0x61] & 0x04)) return;
+ }
+
if(ModeNo > 0x13) {
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
}
@@ -7625,7 +7432,7 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
if(!(temp & 0x01)) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
- if((HwInfo->jChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
+ if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
}
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
@@ -7633,24 +7440,29 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
else temp = 0x0402;
- if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+ if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
temp1 = 0;
if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+ if(ModeNo > 0x13) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
+ }
} else {
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
if(temp1 == 0x01) temp |= 0x01;
if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
- if(ModeNo > 0x13) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+ if(ModeNo > 0x13) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
+ }
}
- if(HwInfo->jChipType >= SIS_661) { /* ? */
+#if 0
+ if(SiS_Pr->ChipType >= SIS_661) { /* ? */
if(SiS_Pr->SiS_TVMode & TVAspect43) {
if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
if(resinfo == SIS_RI_1024x768) {
@@ -7663,29 +7475,30 @@ SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
}
}
+#endif
+
}
+
}
#endif
static void
-SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT vclkindex;
- USHORT temp, reg1, reg2;
+ unsigned short vclkindex, temp, reg1, reg2;
if(SiS_Pr->UseCustomMode) {
reg1 = SiS_Pr->CSR2B;
reg2 = SiS_Pr->CSR2C;
} else {
- vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwInfo);
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
}
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
+ if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
@@ -7705,11 +7518,35 @@ SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
}
static void
-SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
+{
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
+ if((SiS_CRT2IsLCD(SiS_Pr)) ||
+ (SiS_IsVAMode(SiS_Pr))) {
+ if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
+ }
+ }
+ }
+ }
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+ }
+}
+
+static void
+SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
- ULONG tempebx,tempeax,templong;
+ unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
+ unsigned int tempebx, tempeax, templong;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
@@ -7722,38 +7559,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
}
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
- }
+ if(SiS_Pr->ChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+ }
}
}
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV)) {
+ if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
}
}
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
- }
-
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-#ifdef SET_EMI
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
- }
- }
- return;
+ SiS_SetDualLinkEtc(SiS_Pr);
+ return;
}
}
@@ -7777,16 +7600,16 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
tempbx = SiS_Pr->SiS_VGAHDE;
- if(modeflag & HalfDCLK) tempbx >>= 1;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
temp = 0;
if(tempbx > 800) temp = 0x60;
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
temp = 0;
- if(tempbx == 1024) temp = 0xA0;
- else if(tempbx > 1024) temp = 0xC0;
+ if(tempbx > 1024) temp = 0xC0;
+ else if(tempbx >= 960) temp = 0xA0;
} else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
temp = 0;
if(tempbx >= 1280) temp = 0x40;
@@ -7796,8 +7619,13 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(tempbx >= 1024) temp = 0xA0;
}
+ temp |= SiS_Pr->Init_P4_0E;
+
if(SiS_Pr->SiS_VBType & VB_SIS301) {
- if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+ temp &= 0xf0;
+ temp |= 0x0A;
+ }
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
@@ -7824,15 +7652,15 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempeax /= tempebx;
if(templong) tempeax++;
- temp = (USHORT)(tempeax & 0x000000FF);
+ temp = (unsigned short)(tempeax & 0x000000FF);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
- temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
+ temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
- temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
+ temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
temp |= (tempcx & 0x4F);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
@@ -7840,23 +7668,26 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
tempbx = 0;
if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
tempax = SiS_Pr->SiS_VGAHDE;
- if(modeflag & HalfDCLK) tempax >>= 1;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
if(tempax > 800) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
tempax -= 800;
- } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
+ } else {
tempbx = 0x08;
- if(tempax == 1024) tempax *= 25;
- else tempax *= 20;
+ if(tempax == 960) tempax *= 25; /* Correct */
+ else if(tempax == 1024) tempax *= 25;
+ else tempax *= 20;
temp = tempax % 32;
tempax /= 32;
if(temp) tempax++;
tempax++;
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
- (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
- if(resinfo == SIS_RI_1024x768) {
- /* Otherwise white line at right edge */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(resinfo == SIS_RI_1024x768 ||
+ resinfo == SIS_RI_1024x576 ||
+ resinfo == SIS_RI_1280x1024 ||
+ resinfo == SIS_RI_1280x720) {
+ /* Otherwise white line or garbage at right edge */
tempax = (tempax & 0xff00) | 0x20;
}
}
@@ -7868,7 +7699,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
temp = 0x0036; tempbx = 0xD0;
- if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
@@ -7884,36 +7715,24 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
tempbx = SiS_Pr->SiS_HT >> 1;
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
tempbx -= 2;
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
temp = (tempbx >> 5) & 0x38;
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
/* LCD-too-dark-error-source, see FinalizeLCD() */
}
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
- }
- }
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-#ifdef SET_EMI
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
- }
}
+ SiS_SetDualLinkEtc(SiS_Pr);
+
} /* 301B */
- SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
/*********************************************/
@@ -7921,8 +7740,7 @@ SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
@@ -7930,7 +7748,7 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_ModeType == ModeVGA) {
if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
- SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+ SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
}
}
}
@@ -7939,116 +7757,156 @@ SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* MODIFY CRT1 GROUP FOR SLAVE MODE */
/*********************************************/
-static void
-SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
-{
- USHORT tempah,i,modeflag,j;
- USHORT ResIndex,DisplayType;
- const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+static BOOLEAN
+SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
+ unsigned short *DisplayType)
+ {
+ unsigned short modeflag = 0;
+ BOOLEAN checkhd = TRUE;
- if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ /* Pass 1:1 not supported here */
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ (*ResIndex) &= 0x3F;
+
+ if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+
+ (*DisplayType) = 80;
+ if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
+ (*DisplayType) = 82;
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
+ }
+ }
+ if((*DisplayType) != 84) {
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+ }
+
+ } else {
+
+ (*DisplayType = 0);
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_320x240_1: (*DisplayType) = 50;
+ checkhd = FALSE;
+ break;
+ case Panel_320x240_2: (*DisplayType) = 14;
+ break;
+ case Panel_320x240_3: (*DisplayType) = 18;
+ break;
+ case Panel_640x480: (*DisplayType) = 10;
+ break;
+ case Panel_1024x600: (*DisplayType) = 26;
+ break;
+ default: return TRUE;
+ }
+
+ if(checkhd) {
+ if(modeflag & HalfDCLK) (*DisplayType)++;
+ }
+
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
+ }
+
+ }
+
+ return TRUE;
+}
+
+static void
+SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
+{
+ unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
+ const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
+ static const unsigned short CRIdx[] = {
+ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x10, 0x11, 0x15, 0x16
+ };
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848))
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
return;
+ if(SiS_Pr->SiS_IF_DEF_LVDS) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
+ }
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
+ } else return;
+
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
+
+ if(SiS_Pr->ChipType < SIS_315H) {
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
+ }
+
if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
&ResIndex, &DisplayType))) {
return;
}
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
+ switch(DisplayType) {
+ case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */
+ case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */
+ case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */
+ case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */
+ case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */
+ case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
+ case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
+#if 0 /* Works better with calculated numbers */
+ case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
+ case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
+ case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
+ case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
+#endif
+ case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
+ case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
+ case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
+ case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
+ case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
}
- switch(DisplayType) {
- case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
- case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
- case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
- case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
- case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
- case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
- case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
- case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
- case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
- case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
- case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
- case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
- case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
- case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
- case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1; break;
- case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H; break;
- case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2; break;
- case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H; break;
- case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break;
- case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break;
- case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break;
- case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break;
- case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1; break; /* FSTN */
- case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break;
- case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break;
- case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break;
- case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break;
- case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1; break;
- case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H; break;
- case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2; break;
- case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H; break;
- case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1; break;
- case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H; break;
- case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2; break;
- case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H; break;
- case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1; break;
- case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H; break;
- case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2; break;
- case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H; break;
- case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break;
- case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break;
- case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2; break;
- case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H; break;
- case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3; break;
- case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H; break;
- case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break;
- default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
- }
-
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
-
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
-
- for(i=0x02,j=1;i<=0x05;i++,j++){
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
- }
- for(i=0x06,j=5;i<=0x07;i++,j++){
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
- }
- for(i=0x10,j=7;i<=0x11;i++,j++){
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
- }
- for(i=0x15,j=9;i<=0x16;i++,j++){
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
- }
- for(i=0x0A,j=11;i<=0x0C;i++,j++){
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
- SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
- }
-
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
- tempah &= 0xE0;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
-
- tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
- tempah &= 0x01;
- tempah <<= 5;
- if(modeflag & DoubleScanMode) tempah |= 0x080;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+ if(LVDSCRT1Ptr) {
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+ for(i = 0; i <= 10; i++) {
+ tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
+ SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
+ }
+
+ for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
+ tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+ SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
+ }
+
+ tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
+
+ if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
+ if(modeflag & DoubleScanMode) tempah |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
+
+ } else {
+
+ SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
+
+ }
}
/*********************************************/
@@ -8056,24 +7914,24 @@ SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT clkbase, vclkindex=0;
- UCHAR sr2b, sr2c;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short clkbase, vclkindex = 0;
+ unsigned char sr2b, sr2c;
- if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
- if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
- RefreshRateTableIndex--;
- }
- vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, HwInfo);
- SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+ if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
+ RefreshRateTableIndex--;
+ }
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex);
+ SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
} else {
- vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, HwInfo);
+ vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex);
}
sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
@@ -8082,7 +7940,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x01) {
- sr2b = ROMAddr[0x227];
+ sr2b = ROMAddr[0x227];
sr2c = ROMAddr[0x228];
}
}
@@ -8091,7 +7949,7 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
clkbase = 0x02B;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- clkbase += 3;
+ clkbase += 3;
}
}
@@ -8111,368 +7969,331 @@ SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/*********************************************/
static void
-SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex)
+SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex)
{
-#if defined(SIS300) || defined(SIS315H)
- USHORT temp, tempbx;
-#endif
- USHORT tempcl;
- USHORT TVType, resindex;
- const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
+ unsigned short TVType, resindex;
+ const struct SiS_CHTVRegData *CHTVRegData = NULL;
- if(ModeNo <= 0x13)
- tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- else
- tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ if(ModeNo <= 0x13)
+ resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- TVType = 0;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- TVType += 2;
- if(SiS_Pr->SiS_ModeType > ModeVGA) {
- if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
- }
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- TVType = 4;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
- } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- TVType = 6;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
- }
- }
- switch(TVType) {
- case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
- case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
- case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
- case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
- case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
- case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
- case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
- case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
- case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
- default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
- }
- resindex = tempcl & 0x3F;
+ resindex &= 0x3F;
+
+ TVType = 0;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ TVType += 2;
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+ }
+ if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+ TVType = 4;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+ } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+ TVType = 6;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
+ }
+ }
+
+ switch(TVType) {
+ case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
+ case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
+ case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
+ case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
+ case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
+ case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
+ case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
+ case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
+ case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
+ default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
+ }
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
#ifdef SIS300
- /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
+ /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
- /* We don't support modes >800x600 */
- if (resindex > 5) return;
+ /* We don't support modes >800x600 */
+ if (resindex > 5) return;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- SiS_SetCH700x(SiS_Pr,0x4304); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
- SiS_SetCH700x(SiS_Pr,0x6909); /* Black level for PAL (105)*/
- } else {
- SiS_SetCH700x(SiS_Pr,0x0304); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
- SiS_SetCH700x(SiS_Pr,0x7109); /* Black level for NTSC (113)*/
- }
-
- temp = CHTVRegData[resindex].Reg[0];
- tempbx=((temp&0x00FF)<<8)|0x00; /* Mode register */
- SiS_SetCH700x(SiS_Pr,tempbx);
- temp = CHTVRegData[resindex].Reg[1];
- tempbx=((temp&0x00FF)<<8)|0x07; /* Start active video register */
- SiS_SetCH700x(SiS_Pr,tempbx);
- temp = CHTVRegData[resindex].Reg[2];
- tempbx=((temp&0x00FF)<<8)|0x08; /* Position overflow register */
- SiS_SetCH700x(SiS_Pr,tempbx);
- temp = CHTVRegData[resindex].Reg[3];
- tempbx=((temp&0x00FF)<<8)|0x0A; /* Horiz Position register */
- SiS_SetCH700x(SiS_Pr,tempbx);
- temp = CHTVRegData[resindex].Reg[4];
- tempbx=((temp&0x00FF)<<8)|0x0B; /* Vertical Position register */
- SiS_SetCH700x(SiS_Pr,tempbx);
-
- /* Set minimum flicker filter for Luma channel (SR1-0=00),
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+ SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/
+ } else {
+ SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+ SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/
+ }
+
+ SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */
+ SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */
+ SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */
+ SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */
+ SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */
+
+ /* Set minimum flicker filter for Luma channel (SR1-0=00),
minimum text enhancement (S3-2=10),
maximum flicker filter for Chroma channel (S5-4=10)
=00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
- */
- SiS_SetCH700x(SiS_Pr,0x2801);
+ */
+ SiS_SetCH700x(SiS_Pr,0x01,0x28);
- /* Set video bandwidth
+ /* Set video bandwidth
High bandwith Luma composite video filter(S0=1)
low bandwith Luma S-video filter (S2-1=00)
disable peak filter in S-video channel (S3=0)
high bandwidth Chroma Filter (S5-4=11)
=00110001=0x31
- */
- SiS_SetCH700x(SiS_Pr,0xb103); /* old: 3103 */
+ */
+ SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */
- /* Register 0x3D does not exist in non-macrovision register map
+ /* Register 0x3D does not exist in non-macrovision register map
(Maybe this is a macrovision register?)
- */
+ */
#ifndef SIS_CP
- SiS_SetCH70xx(SiS_Pr,0x003D);
+ SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
#endif
- /* Register 0x10 only contains 1 writable bit (S0) for sensing,
- all other bits a read-only. Macrovision?
- */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
+ /* Register 0x10 only contains 1 writable bit (S0) for sensing,
+ all other bits a read-only. Macrovision?
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
- /* Register 0x11 only contains 3 writable bits (S0-S2) for
- contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
- */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
+ /* Register 0x11 only contains 3 writable bits (S0-S2) for
+ contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
- /* Clear DSEN
- */
- SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
-
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
- if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on, no need to set FSCI */
- } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF); /* Loop filter on for mode 23 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
- }
- } else {
- if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
- } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
+ /* Clear DSEN
+ */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
+
+ if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
+ if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */
+ } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */
+ }
+ } else {
+ if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
+ } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */
#if 0
- SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0); /* FSCI for mode 24 is 428,554,851 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0); /* 198b3a63 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off for mode 24 */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE); /* ACIV off, need to set FSCI */
-#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */
+#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
+ }
}
- }
- } else { /* ---- PAL ---- */
- /* We don't play around with FSCI in PAL mode */
+ } else { /* ---- PAL ---- */
+ /* We don't play around with FSCI in PAL mode */
if(resindex == 0x04) {
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
} else {
- SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); /* loop filter off */
- SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE); /* ACIV on */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */
+ SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on */
}
- }
-
+ }
+
#endif /* 300 */
- } else {
+ } else {
- /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
+ /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
#ifdef SIS315H
- /* We don't support modes >1024x768 */
- if (resindex > 6) return;
-
- temp = CHTVRegData[resindex].Reg[0];
- if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
- temp |= 0x10;
- }
- tempbx=((temp & 0x00FF) << 8) | 0x00;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[1];
- tempbx=((temp & 0x00FF) << 8) | 0x01;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[2];
- tempbx=((temp & 0x00FF) << 8) | 0x02;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[3];
- tempbx=((temp & 0x00FF) << 8) | 0x04;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[4];
- tempbx=((temp & 0x00FF) << 8) | 0x03;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[5];
- tempbx=((temp & 0x00FF) << 8) | 0x05;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[6];
- tempbx=((temp & 0x00FF) << 8) | 0x06;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[7];
- if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
- temp = 0x66;
- }
- tempbx=((temp & 0x00FF) << 8) | 0x07;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[8];
- tempbx=((temp & 0x00FF) << 8) | 0x08;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[9];
- tempbx=((temp & 0x00FF) << 8) | 0x15;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[10];
- tempbx=((temp & 0x00FF) << 8) | 0x1f;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[11];
- tempbx=((temp & 0x00FF) << 8) | 0x0c;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[12];
- tempbx=((temp & 0x00FF) << 8) | 0x0d;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[13];
- tempbx=((temp & 0x00FF) << 8) | 0x0e;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[14];
- tempbx=((temp & 0x00FF) << 8) | 0x0f;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = CHTVRegData[resindex].Reg[15];
- tempbx=((temp & 0x00FF) << 8) | 0x10;
- SiS_SetCH701x(SiS_Pr,tempbx);
-
- temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
- /* D1 should be set for PAL, PAL-N and NTSC-J,
- but I won't do that for PAL unless somebody
- tells me to do so. Since the BIOS uses
- non-default CIV values and blacklevels,
- this might be compensated anyway.
- */
- if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
- SiS_SetCH701x(SiS_Pr,((temp << 8) | 0x21));
+ unsigned short temp;
+
+ /* We don't support modes >1024x768 */
+ if (resindex > 6) return;
+
+ temp = CHTVRegData[resindex].Reg[0];
+ if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
+ SiS_SetCH701x(SiS_Pr,0x00,temp);
+
+ SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
+ SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
+ SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
+ SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
+ SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
+ SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
+
+ temp = CHTVRegData[resindex].Reg[7];
+ if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
+ SiS_SetCH701x(SiS_Pr,0x07,temp);
+
+ SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
+ SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
+ SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
+ SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
+ SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
+ SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
+ SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
+ SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
+
+ temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
+ /* D1 should be set for PAL, PAL-N and NTSC-J,
+ but I won't do that for PAL unless somebody
+ tells me to do so. Since the BIOS uses
+ non-default CIV values and blacklevels,
+ this might be compensated anyway.
+ */
+ if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
+ SiS_SetCH701x(SiS_Pr,0x21,temp);
#endif /* 315 */
- }
+ }
#ifdef SIS_CP
- SIS_CP_INIT301_CP3
+ SIS_CP_INIT301_CP3
#endif
}
+#ifdef SIS315H /* ----------- 315 series only ---------- */
+
void
-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
- /* Enable Chrontel 7019 LCD panel backlight */
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(HwInfo->jChipType == SIS_740) {
- SiS_SetCH701x(SiS_Pr,0x6566);
- } else {
- temp = SiS_GetCH701x(SiS_Pr,0x66);
- temp |= 0x20;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
- }
- }
+ /* Enable Chrontel 7019 LCD panel backlight */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(SiS_Pr->ChipType == SIS_740) {
+ SiS_SetCH701x(SiS_Pr,0x66,0x65);
+ } else {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp |= 0x20;
+ SiS_SetCH701x(SiS_Pr,0x66,temp);
+ }
+ }
}
void
-SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
+SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
- /* Disable Chrontel 7019 LCD panel backlight */
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- temp = SiS_GetCH701x(SiS_Pr,0x66);
- temp &= 0xDF;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
- }
+ /* Disable Chrontel 7019 LCD panel backlight */
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ temp = SiS_GetCH701x(SiS_Pr,0x66);
+ temp &= 0xDF;
+ SiS_SetCH701x(SiS_Pr,0x66,temp);
+ }
}
-#ifdef SIS315H /* ----------- 315 series only ---------- */
-
static void
-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
- UCHAR regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
- UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
- UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
- UCHAR asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
- UCHAR asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
- UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
- UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
- UCHAR *tableptr = NULL;
+SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
+{
+ static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+ static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+ static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+ static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+ static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+ static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+ static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+ const unsigned char *tableptr = NULL;
int i;
/* Set up Power up/down timing */
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
- else tableptr = table1024_740;
+ if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
+ else tableptr = table1024_740;
} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
else tableptr = table1400_740;
} else return;
} else {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- tableptr = table1024_650;
+ tableptr = table1024_650;
} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
- tableptr = table1400_650;
+ tableptr = table1400_650;
} else return;
}
for(i=0; i<5; i++) {
- SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+ SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
}
}
static void
-SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
- UCHAR regtable[] = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
- 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
- UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
- 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
- UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
- UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
- UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
- 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
- UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
- 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
- UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
- 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
- UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
- 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
- UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
- 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
- UCHAR *tableptr = NULL;
- USHORT tempbh;
+SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
+{
+ const unsigned char *tableptr = NULL;
+ unsigned short tempbh;
int i;
+ static const unsigned char regtable[] = {
+ 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+ 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
+ };
+ static const unsigned char table1024_740[] = {
+ 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+ 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
+ };
+ static const unsigned char table1280_740[] = {
+ 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
+ };
+ static const unsigned char table1400_740[] = {
+ 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
+ };
+ static const unsigned char table1600_740[] = {
+ 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+ 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
+ };
+ static const unsigned char table1024_650[] = {
+ 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+ 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
+ };
+ static const unsigned char table1280_650[] = {
+ 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+ 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
+ };
+ static const unsigned char table1400_650[] = {
+ 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+ 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
+ };
+ static const unsigned char table1600_650[] = {
+ 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+ 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
+ };
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
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)
}
}
- if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
- else tempbh = 0x0c;
+ if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
+ else tempbh = 0x0c;
for(i = 0; i < tempbh; i++) {
- SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+ SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
}
- SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
+ SiS_ChrontelPowerSequencing(SiS_Pr);
tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
tempbh |= 0xc0;
- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+ SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
tempbh &= 0xfb;
- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+ SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
tempbh = SiS_GetCH701x(SiS_Pr,0x64);
tempbh |= 0x40;
- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+ SiS_SetCH701x(SiS_Pr,0x64,tempbh);
tempbh = SiS_GetCH701x(SiS_Pr,0x03);
tempbh &= 0x3f;
- SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+ SiS_SetCH701x(SiS_Pr,0x03,tempbh);
}
}
static void
-SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
+SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
{
unsigned char temp, temp1;
temp1 = SiS_GetCH701x(SiS_Pr,0x49);
- SiS_SetCH701x(SiS_Pr,0x3e49);
+ SiS_SetCH701x(SiS_Pr,0x49,0x3e);
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp &= 0x7f; /* Use external VSYNC */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
- SiS_LongDelay(SiS_Pr,3);
+ SiS_SetCH701x(SiS_Pr,0x47,temp);
+ SiS_LongDelay(SiS_Pr, 3);
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp |= 0x80; /* Use internal VSYNC */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
- SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
+ SiS_SetCH701x(SiS_Pr,0x47,temp);
+ SiS_SetCH701x(SiS_Pr,0x49,temp1);
}
static void
-SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
temp = SiS_GetCH701x(SiS_Pr,0x1c);
temp |= 0x04; /* Invert XCLK phase */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+ SiS_SetCH701x(SiS_Pr,0x1c,temp);
}
- if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
+ if(SiS_IsYPbPr(SiS_Pr)) {
temp = SiS_GetCH701x(SiS_Pr,0x01);
temp &= 0x3f;
temp |= 0x80; /* Enable YPrPb (HDTV) */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ SiS_SetCH701x(SiS_Pr,0x01,temp);
}
- if(SiS_IsChScart(SiS_Pr, HwInfo)) {
+ if(SiS_IsChScart(SiS_Pr)) {
temp = SiS_GetCH701x(SiS_Pr,0x01);
temp &= 0x3f;
temp |= 0xc0; /* Enable SCART + CVBS */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+ SiS_SetCH701x(SiS_Pr,0x01,temp);
}
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
SiS_ChrontelResetVSync(SiS_Pr);
- SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
+ SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
} else {
- SiS_SetCH701x(SiS_Pr,0x2049); /* Enable TV path */
+ SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */
temp = SiS_GetCH701x(SiS_Pr,0x49);
- if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
+ if(SiS_IsYPbPr(SiS_Pr)) {
temp = SiS_GetCH701x(SiS_Pr,0x73);
temp |= 0x60;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+ SiS_SetCH701x(SiS_Pr,0x73,temp);
}
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp &= 0x7f;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
- SiS_LongDelay(SiS_Pr,2);
+ SiS_SetCH701x(SiS_Pr,0x47,temp);
+ SiS_LongDelay(SiS_Pr, 2);
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp |= 0x80;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+ SiS_SetCH701x(SiS_Pr,0x47,temp);
}
}
}
static void
-SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
/* Complete power down of LVDS */
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
- if(HwInfo->jChipType == SIS_740) {
- SiS_LongDelay(SiS_Pr,1);
- SiS_GenericDelay(SiS_Pr,0x16ff);
- SiS_SetCH701x(SiS_Pr,0xac76);
- SiS_SetCH701x(SiS_Pr,0x0066);
+ if(SiS_Pr->ChipType == SIS_740) {
+ SiS_LongDelay(SiS_Pr, 1);
+ SiS_GenericDelay(SiS_Pr, 5887);
+ SiS_SetCH701x(SiS_Pr,0x76,0xac);
+ SiS_SetCH701x(SiS_Pr,0x66,0x00);
} else {
- SiS_LongDelay(SiS_Pr,2);
+ SiS_LongDelay(SiS_Pr, 2);
temp = SiS_GetCH701x(SiS_Pr,0x76);
temp &= 0xfc;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
- SiS_SetCH701x(SiS_Pr,0x0066);
+ SiS_SetCH701x(SiS_Pr,0x76,temp);
+ SiS_SetCH701x(SiS_Pr,0x66,0x00);
}
}
}
static void
-SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */
temp &= 0x01;
if(!temp) {
- if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
temp = SiS_GetCH701x(SiS_Pr,0x49);
- SiS_SetCH701x(SiS_Pr,0x3e49);
+ SiS_SetCH701x(SiS_Pr,0x49,0x3e);
}
+
/* Reset Chrontel 7019 datapath */
- SiS_SetCH701x(SiS_Pr,0x1048);
- SiS_LongDelay(SiS_Pr,1);
- SiS_SetCH701x(SiS_Pr,0x1848);
+ SiS_SetCH701x(SiS_Pr,0x48,0x10);
+ SiS_LongDelay(SiS_Pr, 1);
+ SiS_SetCH701x(SiS_Pr,0x48,0x18);
- if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
SiS_ChrontelResetVSync(SiS_Pr);
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+ SiS_SetCH701x(SiS_Pr,0x49,temp);
}
} else {
@@ -8638,72 +8460,72 @@ SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* Clear/set/clear GPIO */
temp = SiS_GetCH701x(SiS_Pr,0x5c);
temp &= 0xef;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+ SiS_SetCH701x(SiS_Pr,0x5c,temp);
temp = SiS_GetCH701x(SiS_Pr,0x5c);
temp |= 0x10;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+ SiS_SetCH701x(SiS_Pr,0x5c,temp);
temp = SiS_GetCH701x(SiS_Pr,0x5c);
temp &= 0xef;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+ SiS_SetCH701x(SiS_Pr,0x5c,temp);
temp = SiS_GetCH701x(SiS_Pr,0x61);
if(!temp) {
- SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
+ SiS_SetCH701xForLCD(SiS_Pr);
}
}
} else { /* 650 */
/* Reset Chrontel 7019 datapath */
- SiS_SetCH701x(SiS_Pr,0x1048);
- SiS_LongDelay(SiS_Pr,1);
- SiS_SetCH701x(SiS_Pr,0x1848);
+ SiS_SetCH701x(SiS_Pr,0x48,0x10);
+ SiS_LongDelay(SiS_Pr, 1);
+ SiS_SetCH701x(SiS_Pr,0x48,0x18);
}
}
static void
-SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
- if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
SiS_ChrontelResetVSync(SiS_Pr);
}
} else {
- SiS_SetCH701x(SiS_Pr,0xaf76); /* Power up LVDS block */
+ SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */
temp = SiS_GetCH701x(SiS_Pr,0x49);
temp &= 1;
if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp &= 0x70;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* enable VSYNC */
- SiS_LongDelay(SiS_Pr,3);
+ SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */
+ SiS_LongDelay(SiS_Pr, 3);
temp = SiS_GetCH701x(SiS_Pr,0x47);
temp |= 0x80;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47); /* disable VSYNC */
+ SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */
}
}
}
static void
-SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- USHORT temp,temp1;
+ unsigned short temp,temp1;
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
temp = SiS_GetCH701x(SiS_Pr,0x61);
if(temp < 1) {
temp++;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+ SiS_SetCH701x(SiS_Pr,0x61,temp);
}
- SiS_SetCH701x(SiS_Pr,0x4566); /* Panel power on */
- SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on */
- SiS_LongDelay(SiS_Pr,1);
- SiS_GenericDelay(SiS_Pr,0x16ff);
+ SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */
+ SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */
+ SiS_LongDelay(SiS_Pr, 1);
+ SiS_GenericDelay(SiS_Pr, 5887);
} else { /* 650 */
@@ -8711,38 +8533,38 @@ SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo
temp = SiS_GetCH701x(SiS_Pr,0x61);
if(temp < 2) {
temp++;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+ SiS_SetCH701x(SiS_Pr,0x61,temp);
temp1 = 1;
}
- SiS_SetCH701x(SiS_Pr,0xac76);
+ SiS_SetCH701x(SiS_Pr,0x76,0xac);
temp = SiS_GetCH701x(SiS_Pr,0x66);
temp |= 0x5f;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+ SiS_SetCH701x(SiS_Pr,0x66,temp);
if(ModeNo > 0x13) {
- if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
- SiS_GenericDelay(SiS_Pr,0x3ff);
+ if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
+ SiS_GenericDelay(SiS_Pr, 1023);
} else {
- SiS_GenericDelay(SiS_Pr,0x2ff);
+ SiS_GenericDelay(SiS_Pr, 767);
}
} else {
if(!temp1)
- SiS_GenericDelay(SiS_Pr,0x2ff);
+ SiS_GenericDelay(SiS_Pr, 767);
}
temp = SiS_GetCH701x(SiS_Pr,0x76);
temp |= 0x03;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+ SiS_SetCH701x(SiS_Pr,0x76,temp);
temp = SiS_GetCH701x(SiS_Pr,0x66);
temp &= 0x7f;
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
- SiS_LongDelay(SiS_Pr,1);
+ SiS_SetCH701x(SiS_Pr,0x66,temp);
+ SiS_LongDelay(SiS_Pr, 1);
}
}
static void
-SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
{
- USHORT temp,tempcl,tempch;
+ unsigned short temp,tempcl,tempch;
SiS_LongDelay(SiS_Pr, 1);
tempcl = 3;
@@ -8753,87 +8575,87 @@ SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
temp &= 0x04; /* PLL stable? -> bail out */
if(temp == 0x04) break;
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
/* Power down LVDS output, PLL normal operation */
- SiS_SetCH701x(SiS_Pr,0xac76);
+ SiS_SetCH701x(SiS_Pr,0x76,0xac);
}
- SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
+ SiS_SetCH701xForLCD(SiS_Pr);
if(tempcl == 0) {
if(tempch == 3) break;
- SiS_ChrontelResetDB(SiS_Pr,HwInfo);
+ SiS_ChrontelResetDB(SiS_Pr);
tempcl = 3;
tempch++;
}
tempcl--;
temp = SiS_GetCH701x(SiS_Pr,0x76);
temp &= 0xfb; /* Reset PLL */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
- SiS_LongDelay(SiS_Pr,2);
+ SiS_SetCH701x(SiS_Pr,0x76,temp);
+ SiS_LongDelay(SiS_Pr, 2);
temp = SiS_GetCH701x(SiS_Pr,0x76);
temp |= 0x04; /* PLL normal operation */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
- if(HwInfo->jChipType == SIS_740) {
- SiS_SetCH701x(SiS_Pr,0xe078); /* PLL loop filter */
+ SiS_SetCH701x(SiS_Pr,0x76,temp);
+ if(SiS_Pr->ChipType == SIS_740) {
+ SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */
} else {
- SiS_SetCH701x(SiS_Pr,0x6078);
+ SiS_SetCH701x(SiS_Pr,0x78,0x60);
}
- SiS_LongDelay(SiS_Pr,2);
+ SiS_LongDelay(SiS_Pr, 2);
} while(0);
- SiS_SetCH701x(SiS_Pr,0x0077); /* MV? */
+ SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */
}
static void
-SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
{
- USHORT temp;
+ unsigned short temp;
temp = SiS_GetCH701x(SiS_Pr,0x03);
temp |= 0x80; /* Set datapath 1 to TV */
temp &= 0xbf; /* Set datapath 2 to LVDS */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+ SiS_SetCH701x(SiS_Pr,0x03,temp);
- if(HwInfo->jChipType == SIS_740) {
+ if(SiS_Pr->ChipType == SIS_740) {
temp = SiS_GetCH701x(SiS_Pr,0x1c);
temp &= 0xfb; /* Normal XCLK phase */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+ SiS_SetCH701x(SiS_Pr,0x1c,temp);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
temp = SiS_GetCH701x(SiS_Pr,0x64);
temp |= 0x40; /* ? Bit not defined */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+ SiS_SetCH701x(SiS_Pr,0x64,temp);
temp = SiS_GetCH701x(SiS_Pr,0x03);
temp &= 0x3f; /* D1 input to both LVDS and TV */
- SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+ SiS_SetCH701x(SiS_Pr,0x03,temp);
if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
- SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
+ SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
SiS_LongDelay(SiS_Pr, 1);
- SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
- SiS_ChrontelResetDB(SiS_Pr, HwInfo);
- SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
- SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+ SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
+ SiS_ChrontelResetDB(SiS_Pr);
+ SiS_ChrontelDoSomething2(SiS_Pr);
+ SiS_ChrontelDoSomething3(SiS_Pr, 0);
} else {
temp = SiS_GetCH701x(SiS_Pr,0x66);
if(temp != 0x45) {
- SiS_ChrontelResetDB(SiS_Pr, HwInfo);
- SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
- SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+ SiS_ChrontelResetDB(SiS_Pr);
+ SiS_ChrontelDoSomething2(SiS_Pr);
+ SiS_ChrontelDoSomething3(SiS_Pr, 0);
}
}
} else { /* 650 */
- SiS_ChrontelResetDB(SiS_Pr,HwInfo);
- SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
+ SiS_ChrontelResetDB(SiS_Pr);
+ SiS_ChrontelDoSomething2(SiS_Pr);
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
- SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
- SiS_SetCH701x(SiS_Pr,0xaf76); /* All power on, LVDS normal operation */
+ SiS_ChrontelDoSomething3(SiS_Pr,temp);
+ SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */
}
@@ -8845,15 +8667,12 @@ SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
BOOLEAN
-SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
#ifdef SIS300
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
-#endif
- USHORT ModeIdIndex, RefreshRateTableIndex;
-#if 0
- USHORT temp;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
#endif
+ unsigned short ModeIdIndex, RefreshRateTableIndex;
SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
@@ -8866,37 +8685,37 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
/* Used for shifting CR33 */
SiS_Pr->SiS_SelectCRT2Rate = 4;
- SiS_UnLockCRT2(SiS_Pr, HwInfo);
+ SiS_UnLockCRT2(SiS_Pr);
- RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
SiS_SaveCRT2Info(SiS_Pr,ModeNo);
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- SiS_DisableBridge(SiS_Pr,HwInfo);
- if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
+ SiS_DisableBridge(SiS_Pr);
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
}
- SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
}
if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- SiS_LockCRT2(SiS_Pr, HwInfo);
+ SiS_LockCRT2(SiS_Pr);
SiS_DisplayOn(SiS_Pr);
return TRUE;
}
- SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
/* Set up Panel Link for LVDS and LCDA */
SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
- ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
- SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
+ SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
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)
#endif
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+ if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
#ifdef SIS315H
- SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
#endif
- SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
#ifdef SIS315H
- SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+ SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
#endif
- SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+ SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
- /* For 301BDH (Panel link initialization): */
- if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
- if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- }
- }
- }
- SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- }
- }
+ /* For 301BDH (Panel link initialization): */
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+
+ if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+ }
+ SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ }
+ }
} else {
- SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+ SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
- }
+ SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
- SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
+ SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
- if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+ if(SiS_Pr->SiS_SetFlag & LowModeTests) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
#ifdef SIS315H
- SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
+ SiS_SetCH701xForLCD(SiS_Pr);
#endif
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
- }
- }
- }
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+ }
+ }
+ }
}
#ifdef SIS300
- if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->ChipType < SIS_315H) {
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(SiS_Pr->SiS_UseOEM) {
if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
- SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
- RefreshRateTableIndex);
+ SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
} else {
- SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
- RefreshRateTableIndex);
+ SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
}
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+ if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
+ SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
}
SiS_DisplayOn(SiS_Pr);
}
@@ -8995,21 +8807,21 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
#endif
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- if(HwInfo->jChipType < SIS_661) {
- SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ if(SiS_Pr->ChipType < SIS_661) {
+ SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
+ SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
} else {
- SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+ SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
}
}
#endif
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- SiS_EnableBridge(SiS_Pr, HwInfo);
+ SiS_EnableBridge(SiS_Pr);
}
SiS_DisplayOn(SiS_Pr);
@@ -9017,15 +8829,15 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
/* Disable LCD panel when using TV */
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFF,0x0C);
+ SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
} else {
/* Disable TV when using LCD */
- SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+ SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
}
}
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
- SiS_LockCRT2(SiS_Pr,HwInfo);
+ SiS_LockCRT2(SiS_Pr);
}
return TRUE;
@@ -9037,13 +8849,13 @@ SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
/*********************************************/
void
-SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
{
/* Switch on LCD backlight on SiS30xLV */
SiS_DDC2Delay(SiS_Pr,0xff00);
if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ SiS_WaitVBRetrace(SiS_Pr);
}
if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
@@ -9051,12 +8863,11 @@ SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
void
-SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
{
/* Switch off LCD backlight on SiS30xLV */
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
- SiS_DDC2Delay(SiS_Pr,0xe000);
+ SiS_DDC2Delay(SiS_Pr,0xff00);
}
/*********************************************/
@@ -9064,7 +8875,7 @@ SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/*********************************************/
static void
-SiS_SetupDDCN(SiS_Private *SiS_Pr)
+SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
{
SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk;
@@ -9075,12 +8886,12 @@ SiS_SetupDDCN(SiS_Private *SiS_Pr)
}
#ifdef SIS300
-static UCHAR *
-SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
+static unsigned char *
+SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
{
int i, j, num;
- USHORT tempah,temp;
- UCHAR *mydataptr;
+ unsigned short tempah,temp;
+ unsigned char *mydataptr;
for(i=0; i<20; i++) { /* Do 20 attempts to write */
mydataptr = dataptr;
@@ -9088,7 +8899,7 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
if(!num) return mydataptr;
if(i) {
SiS_SetStop(SiS_Pr);
- SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
}
if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
tempah = SiS_Pr->SiS_DDC_DeviceAddr;
@@ -9110,12 +8921,12 @@ SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
}
static BOOLEAN
-SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
+SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
{
SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
SiS_SetSwitchDDC2(SiS_Pr);
@@ -9124,9 +8935,11 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
if(!dataptr) return FALSE;
}
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
#endif
+#endif
return TRUE;
}
#endif
@@ -9139,155 +8952,121 @@ SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
*/
static BOOLEAN
-SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
+SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
{
- USHORT tempah,temp,i;
+ unsigned short temp, i;
for(i=0; i<20; i++) { /* Do 20 attempts to write */
if(i) {
- SiS_SetStop(SiS_Pr);
- SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
- }
- if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
- tempah = SiS_Pr->SiS_DDC_DeviceAddr;
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
- if(temp) continue; /* (ERROR: no ack) */
- tempah = tempbx & 0x00FF; /* Write RAB */
- tempah |= myor; /* (700x: set bit 7, see datasheet) */
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
- if(temp) continue; /* (ERROR: no ack) */
- tempah = (tempbx & 0xFF00) >> 8;
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write data */
- if(temp) continue; /* (ERROR: no ack) */
- if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
+ SiS_SetStop(SiS_Pr);
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
+ }
+ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
+ if(temp) continue; /* (ERROR: no ack) */
+ temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */
+ if(temp) continue; /* (ERROR: no ack) */
+ temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */
+ if(temp) continue; /* (ERROR: no ack) */
+ if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
SiS_Pr->SiS_ChrontelInit = 1;
return TRUE;
}
return FALSE;
}
-#if 0
-#ifdef SIS300
-/* Write Trumpion register */
-static void
-SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
-{
- SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
- SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
- SiS_SetupDDCN(SiS_Pr);
- SiS_SetChReg(SiS_Pr, tempbx, 0);
-}
-#endif
-#endif
-
/* Write to Chrontel 700x */
-/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
void
-SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
{
SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+
if(!(SiS_Pr->SiS_ChrontelInit)) {
SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
}
- if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
+ if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
(!(SiS_Pr->SiS_ChrontelInit)) ) {
- SiS_Pr->SiS_DDC_Index = 0x0a; /* Bit 7 = SC; Bit 6 = SD */
- SiS_Pr->SiS_DDC_Data = 0x80; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x40; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Index = 0x0a;
+ SiS_Pr->SiS_DDC_Data = 0x80;
+ SiS_Pr->SiS_DDC_Clk = 0x40;
SiS_SetupDDCN(SiS_Pr);
- SiS_SetChReg(SiS_Pr, tempbx, 0x80);
+ SiS_SetChReg(SiS_Pr, reg, val, 0x80);
}
}
/* Write to Chrontel 701x */
/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
void
-SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
{
SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
- SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
- SiS_SetChReg(SiS_Pr, tempbx, 0);
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
+ SiS_SetChReg(SiS_Pr, reg, val, 0);
}
-static void
-SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+void
+SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
{
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
- SiS_SetCH700x(SiS_Pr,tempbx);
+ SiS_SetCH700x(SiS_Pr, reg, val);
else
- SiS_SetCH701x(SiS_Pr,tempbx);
+ SiS_SetCH701x(SiS_Pr, reg, val);
}
-static USHORT
-SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
+static unsigned short
+SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
{
- USHORT tempah,temp,i;
+ unsigned short tempah, temp, i;
for(i=0; i<20; i++) { /* Do 20 attempts to read */
if(i) {
- SiS_SetStop(SiS_Pr);
- SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
- }
- if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
- tempah = SiS_Pr->SiS_DDC_DeviceAddr;
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
- if(temp) continue; /* (ERROR: no ack) */
- tempah = SiS_Pr->SiS_DDC_ReadAddr | myor; /* Write RAB (700x: | 0x80) */
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
- if(temp) continue; /* (ERROR: no ack) */
- if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
- tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
- temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* DAB (S0=1=read) */
- if(temp) continue; /* (ERROR: no ack) */
- tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* Read byte */
- if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
+ SiS_SetStop(SiS_Pr);
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
+ }
+ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */
+ if(temp) continue; /* (ERROR: no ack) */
+ temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */
+ if(temp) continue; /* (ERROR: no ack) */
+ if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */
+ temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
+ if(temp) continue; /* (ERROR: no ack) */
+ tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */
+ if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */
SiS_Pr->SiS_ChrontelInit = 1;
- return(tempah);
+ return tempah;
}
return 0xFFFF;
}
-#if 0
-#ifdef SIS300
-/* Read from Trumpion */
-static USHORT
-SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
-{
- SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
- SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
- SiS_SetupDDCN(SiS_Pr);
- SiS_Pr->SiS_DDC_ReadAddr = tempbx;
- return(SiS_GetChReg(SiS_Pr,0));
-}
-#endif
-#endif
-
/* Read from Chrontel 700x */
/* Parameter is [Register no (S7-S0)] */
-USHORT
-SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
+unsigned short
+SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
{
- USHORT result;
+ unsigned short result;
SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+
if(!(SiS_Pr->SiS_ChrontelInit)) {
SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
}
@@ -9303,52 +9082,69 @@ SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
result = SiS_GetChReg(SiS_Pr,0x80);
}
- return(result);
+ return result;
}
/* Read from Chrontel 701x */
/* Parameter is [Register no (S7-S0)] */
-USHORT
-SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
+unsigned short
+SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
{
SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
- SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
- SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
+ SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */
SiS_Pr->SiS_DDC_ReadAddr = tempbx;
- return(SiS_GetChReg(SiS_Pr,0));
+ return SiS_GetChReg(SiS_Pr,0);
}
/* Read from Chrontel 70xx */
/* Parameter is [Register no (S7-S0)] */
-static USHORT
-SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+#ifdef SIS_LINUX_KERNEL
+static
+#endif
+unsigned short
+SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
{
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
- return(SiS_GetCH700x(SiS_Pr, tempbx));
+ return SiS_GetCH700x(SiS_Pr, tempbx);
else
- return(SiS_GetCH701x(SiS_Pr, tempbx));
+ return SiS_GetCH701x(SiS_Pr, tempbx);
+}
+
+void
+SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+ unsigned char myor, unsigned short myand)
+{
+ unsigned short tempbl;
+
+ tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
+ SiS_SetCH70xx(SiS_Pr, reg, tempbl);
}
/* Our own DDC functions */
-static USHORT
-SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+ unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
+ unsigned int VBFlags2)
{
unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
unsigned char flag, cr32;
- USHORT temp = 0, myadaptnum = adaptnum;
+ unsigned short temp = 0, myadaptnum = adaptnum;
if(adaptnum != 0) {
- if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
- if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
- }
-
+ if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
+ if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+ }
+
/* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
-
+
SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */
SiS_Pr->SiS_DDC_SecAddr = 0;
@@ -9360,7 +9156,7 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
#if 0
- if(VBFlags & VB_SISBRIDGE) {
+ if(VBFlags2 & VB2_SISBRIDGE) {
if(myadaptnum == 0) {
if(!(cr32 & 0x20)) {
myadaptnum = 2;
@@ -9376,20 +9172,20 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
#endif
if(VGAEngine == SIS_300_VGA) { /* 300 series */
-
+
if(myadaptnum != 0) {
flag = 0;
- if(VBFlags & VB_SISBRIDGE) {
+ if(VBFlags2 & VB2_SISBRIDGE) {
SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
SiS_Pr->SiS_DDC_Index = 0x0f;
}
}
- if(!(VBFlags & VB_301)) {
+ if(!(VBFlags2 & VB2_301)) {
if((cr32 & 0x80) && (checkcr32)) {
if(myadaptnum >= 1) {
if(!(cr32 & 0x08)) {
- myadaptnum = 1;
+ myadaptnum = 1;
if(!(cr32 & 0x10)) return 0xFFFF;
}
}
@@ -9401,17 +9197,17 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
} else { /* 315/330 series */
- /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
+ /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
- if(VBFlags & VB_SISBRIDGE) {
+ if(VBFlags2 & VB2_SISBRIDGE) {
if(myadaptnum == 2) {
myadaptnum = 1;
- }
+ }
}
if(myadaptnum == 1) {
- flag = 0;
- if(VBFlags & VB_SISBRIDGE) {
+ flag = 0;
+ if(VBFlags2 & VB2_SISBRIDGE) {
SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
SiS_Pr->SiS_DDC_Index = 0x0f;
}
@@ -9429,93 +9225,96 @@ SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
temp = myadaptnum;
if(myadaptnum == 1) {
temp = 0;
- if(VBFlags & VB_LVDS) flag = 0xff;
+ if(VBFlags2 & VB2_LVDS) flag = 0xff;
}
if(flag) temp = 0;
}
-
+
SiS_Pr->SiS_DDC_Data = 0x02 << temp;
SiS_Pr->SiS_DDC_Clk = 0x01 << temp;
SiS_SetupDDCN(SiS_Pr);
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
#endif
-
+#endif
return 0;
}
-static USHORT
-SiS_WriteDABDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
{
if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
- return 0xFFFF;
+ return 0xFFFF;
}
if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
- return 0xFFFF;
+ return 0xFFFF;
}
- return(0);
+ return 0;
}
-static USHORT
-SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
{
if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
- return 0xFFFF;
+ return 0xFFFF;
}
- return(0);
+ return 0;
}
-static USHORT
-SiS_PrepareDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
{
if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
- if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
- return(0);
+ if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
+ return 0;
}
static void
-SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
+SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
{
SiS_SetSCLKLow(SiS_Pr);
if(yesno) {
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
SiS_Pr->SiS_DDC_Data);
} else {
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
0);
}
SiS_SetSCLKHigh(SiS_Pr);
}
-static USHORT
-SiS_DoProbeDDC(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
{
unsigned char mask, value;
- USHORT temp, ret=0;
+ unsigned short temp, ret=0;
BOOLEAN failed = FALSE;
SiS_SetSwitchDDC2(SiS_Pr);
if(SiS_PrepareDDC(SiS_Pr)) {
SiS_SetStop(SiS_Pr);
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
#endif
- return(0xFFFF);
+#endif
+ return 0xFFFF;
}
mask = 0xf0;
value = 0x20;
if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
- temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
SiS_SendACK(SiS_Pr, 0);
if(temp == 0) {
mask = 0xff;
@@ -9523,34 +9322,41 @@ SiS_DoProbeDDC(SiS_Private *SiS_Pr)
} else {
failed = TRUE;
ret = 0xFFFF;
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
#endif
+#endif
}
}
if(failed == FALSE) {
- temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
SiS_SendACK(SiS_Pr, 1);
temp &= mask;
if(temp == value) ret = 0;
else {
ret = 0xFFFF;
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
#endif
+#endif
if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
if(temp == 0x30) ret = 0;
}
}
}
SiS_SetStop(SiS_Pr);
- return(ret);
+ return ret;
}
-static USHORT
-SiS_ProbeDDC(SiS_Private *SiS_Pr)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
{
- USHORT flag;
+ unsigned short flag;
flag = 0x180;
SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
@@ -9560,16 +9366,19 @@ SiS_ProbeDDC(SiS_Private *SiS_Pr)
SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
if(!(flag & 0x1a)) flag = 0;
- return(flag);
+ return flag;
}
-static USHORT
-SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
+#ifndef SIS_XORG_XF86
+static
+#endif
+unsigned short
+SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
{
- USHORT flag, length, i;
+ unsigned short flag, length, i;
unsigned char chksum,gotcha;
- if(DDCdatatype > 4) return 0xFFFF;
+ if(DDCdatatype > 4) return 0xFFFF;
flag = 0;
SiS_SetSwitchDDC2(SiS_Pr);
@@ -9579,21 +9388,21 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
chksum = 0;
gotcha = 0;
for(i=0; i<length; i++) {
- buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
chksum += buffer[i];
gotcha |= buffer[i];
SiS_SendACK(SiS_Pr, 0);
}
- buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+ buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
chksum += buffer[i];
SiS_SendACK(SiS_Pr, 1);
- if(gotcha) flag = (USHORT)chksum;
+ if(gotcha) flag = (unsigned short)chksum;
else flag = 0xFFFF;
} else {
flag = 0xFFFF;
}
SiS_SetStop(SiS_Pr);
- return(flag);
+ return flag;
}
/* Our private DDC functions
@@ -9617,17 +9426,25 @@ SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
if DDCdatatype = 0: Returns supported DDC modes
*/
-USHORT
-SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
+unsigned short
+SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+ unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
+ unsigned int VBFlags2)
{
- unsigned char sr1f,cr17=1;
- USHORT result;
+ unsigned char sr1f, cr17=1;
+ unsigned short result;
- if(adaptnum > 2) return 0xFFFF;
- if(DDCdatatype > 4) return 0xFFFF;
- if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
- if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE) == 0xFFFF) return 0xFFFF;
+ if(adaptnum > 2)
+ return 0xFFFF;
+
+ if(DDCdatatype > 4)
+ return 0xFFFF;
+
+ if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
+ return 0xFFFF;
+
+ if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
+ return 0xFFFF;
sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
@@ -9656,10 +9473,12 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
(buffer[4] == 0xff) && (buffer[5] == 0xff) &&
(buffer[6] == 0xff) && (buffer[7] == 0x00) &&
(buffer[0x12] == 1)) {
- if(adaptnum == 1) {
- if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
- } else {
- if(buffer[0x14] & 0x80) result = 0xFFFE;
+ if(!SiS_Pr->DDCPortMixup) {
+ if(adaptnum == 1) {
+ if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
+ } else {
+ if(buffer[0x14] & 0x80) result = 0xFFFE;
+ }
}
}
}
@@ -9671,832 +9490,10 @@ SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
return result;
}
-#ifdef LINUX_XF86
-
-static BOOLEAN
-checkedid1(unsigned char *buffer)
-{
- /* Check header */
- if((buffer[0] != 0x00) ||
- (buffer[1] != 0xff) ||
- (buffer[2] != 0xff) ||
- (buffer[3] != 0xff) ||
- (buffer[4] != 0xff) ||
- (buffer[5] != 0xff) ||
- (buffer[6] != 0xff) ||
- (buffer[7] != 0x00))
- return FALSE;
-
- /* Check EDID version and revision */
- if((buffer[0x12] != 1) || (buffer[0x13] > 4)) return FALSE;
-
- /* Check week of manufacture for sanity */
- if(buffer[0x10] > 53) return FALSE;
-
- /* Check year of manufacture for sanity */
- if(buffer[0x11] > 40) return FALSE;
-
- return TRUE;
-}
-
-static BOOLEAN
-checkedid2(unsigned char *buffer)
-{
- USHORT year = buffer[6] | (buffer[7] << 8);
-
- /* Check EDID version */
- if((buffer[0] & 0xf0) != 0x20) return FALSE;
-
- /* Check week of manufacture for sanity */
- if(buffer[5] > 53) return FALSE;
-
- /* Check year of manufacture for sanity */
- if((year != 0) && ((year < 1990) || (year > 2030))) return FALSE;
-
- return TRUE;
-}
-
-/* Sense the LCD parameters (CR36, CR37) via DDC */
-/* SiS30x(B) only */
-USHORT
-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
- USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
- USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct;
- int maxx=0, maxy=0, prefx=0, prefy=0;
- unsigned char cr37=0, seekcode;
- BOOLEAN checkexpand = FALSE;
- BOOLEAN havesync = FALSE;
- BOOLEAN indb = FALSE;
- int retry, i;
- unsigned char buffer[256];
-
- for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
- SiS_Pr->CP_HaveCustomData = FALSE;
- SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
- SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
- SiS_Pr->CP_PreferredIndex = -1;
- SiS_Pr->CP_PrefClock = 0;
- SiS_Pr->PanelSelfDetected = FALSE;
-
- if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
- if(pSiS->VBFlags & VB_30xBDH) return 0;
-
- if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
-
- SiS_Pr->SiS_DDC_SecAddr = 0x00;
-
- /* Probe supported DA's */
- flag = SiS_ProbeDDC(SiS_Pr);
-#ifdef TWDEBUG
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
- "CRT2 DDC capabilities 0x%x\n", flag);
-#endif
- if(flag & 0x10) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
- DDCdatatype = 4;
- } else if(flag & 0x08) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
- DDCdatatype = 3;
- } else if(flag & 0x02) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
- DDCdatatype = 1;
- } else return 0; /* no DDC support (or no device attached) */
-
- /* Read the entire EDID */
- retry = 2;
- do {
- if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "CRT2: DDC read failed (attempt %d), %s\n",
- (3-retry), (retry == 1) ? "giving up" : "retrying");
- retry--;
- if(retry == 0) return 0xFFFF;
- } else break;
- } while(1);
-
-#ifdef TWDEBUG
- for(i=0; i<256; i+=16) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- buffer[i], buffer[i+1], buffer[i+2], buffer[i+3],
- buffer[i+4], buffer[i+5], buffer[i+6], buffer[i+7],
- buffer[i+8], buffer[i+9], buffer[i+10], buffer[i+11],
- buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
- }
-#endif
-
- /* Analyze EDID and retrieve LCD panel information */
- paneltype = 0;
- switch(DDCdatatype) {
- case 1: /* Analyze EDID V1 */
- /* Catch a few clear cases: */
- if(!(checkedid1(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: EDID corrupt\n");
- return 0;
- }
-
- if(!(buffer[0x14] & 0x80)) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: Attached display expects analog input (0x%02x)\n",
- buffer[0x14]);
- return 0;
- }
-
- if((buffer[0x18] & 0x18) != 0x08) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: Warning: Attached display is not of RGB but of %s type (0x%02x)\n",
- ((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
- ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" :
- "undefined"),
- buffer[0x18]);
- }
-
- /* Now analyze the first Detailed Timing Block and see
- * if the preferred timing mode is stored there. If so,
- * check if this is a standard panel for which we already
- * know the timing.
- */
-
- paneltype = Panel_Custom;
- checkexpand = FALSE;
-
- panelvendor = buffer[9] | (buffer[8] << 8);
- panelproduct = buffer[10] | (buffer[11] << 8);
-
- /* Overrule bogus preferred modes from database */
- if((indb = SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
- if(prefx) SiS_Pr->CP_PreferredX = xres = prefx;
- if(prefy) SiS_Pr->CP_PreferredY = yres = prefy;
- }
-
- if(buffer[0x18] & 0x02) {
-
- USHORT pclk = (buffer[0x36] | (buffer[0x37] << 8));
- USHORT phb = (buffer[0x39] | ((buffer[0x3a] & 0x0f) << 8));
- USHORT pvb = (buffer[0x3c] | ((buffer[0x3d] & 0x0f) << 8));
-
- if(!xres) SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
- if(!yres) SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
-
- switch(xres) {
-#if 0 /* Treat as custom */
- case 800:
- if(yres == 600) {
- paneltype = Panel_800x600;
- checkexpand = TRUE;
- }
- break;
-#endif
- case 1024:
- if(yres == 768) {
- paneltype = Panel_1024x768;
- checkexpand = TRUE;
- }
- break;
- case 1280:
- if(yres == 1024) {
- paneltype = Panel_1280x1024;
- checkexpand = TRUE;
- } else if(yres == 960) {
- if(pSiS->VGAEngine == SIS_300_VGA) {
- paneltype = Panel300_1280x960;
- } else {
- paneltype = Panel310_1280x960;
- }
- } else if(yres == 768) {
- if( (pclk == 8100) &&
- (phb == (1688 - 1280)) &&
- (pvb == (802 - 768)) ) {
- paneltype = Panel_1280x768;
- checkexpand = FALSE;
- cr37 |= 0x10;
- }
- } else if(yres == 800) {
- if( (pclk == 6900) &&
- (phb == (1408 - 1280)) &&
- (pvb == (816 - 800)) ) {
- paneltype = Panel_1280x800;
- }
- }
- break;
- case 1400:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1050) {
- paneltype = Panel310_1400x1050;
- checkexpand = TRUE;
- }
- }
- break;
- case 1600:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_301C) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
- }
- }
- }
- break;
- }
-
- /* Save sync: This is used if "Pass 1:1" is off; in this case
- * we always use the panel's native mode = this "preferred mode"
- * we just have been analysing. Hence, we also need its sync.
- */
- if((buffer[0x47] & 0x18) == 0x18) {
- cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
- havesync = TRUE;
- } else {
- /* What now? There is no digital separate output timing... */
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "LCD sense: Unable to retrieve Sync polarity information\n");
- cr37 |= 0xc0; /* Default */
- }
-
- }
-
- /* Check against our database; eg. Sanyo Z2 projector reports
- * 1024x768 as preferred mode, although it supports 1280x720
- * natively in non-HDCP mode. Treat such wrongly reporting
- * panels as custom and fixup actual maximum resolutions.
- */
- if(paneltype != Panel_Custom) {
- if(indb) {
- paneltype = Panel_Custom;
- SiS_Pr->CP_MaxX = maxx;
- SiS_Pr->CP_MaxY = maxy;
- /* Leave preferred unchanged (MUST contain a valid mode!) */
- }
- }
-
- /* If we still don't know what panel this is, we take it
- * as a custom panel and derive the timing data from the
- * detailed timing blocks
- */
- if(paneltype == Panel_Custom) {
-
- int i, temp, base = 0x36;
- unsigned long estpack;
- const unsigned short estx[] = {
- 720, 720, 640, 640, 640, 640, 800, 800,
- 800, 800, 832,1024,1024,1024,1024,1280,
- 1152
- };
- const unsigned short esty[] = {
- 400, 400, 480, 480, 480, 480, 600, 600,
- 600, 600, 624, 768, 768, 768, 768,1024,
- 870
- };
- const int estclk[] = {
- 0, 0, 25100, 0, 31500, 31500, 36100, 40000,
- 50100, 49500, 0, 0, 65100, 75200, 78700,135200,
- 0
- };
-
- paneltype = 0;
- SiS_Pr->CP_Supports64048075 = TRUE;
-
- /* Find the maximum resolution */
-
- /* 1. From Established timings */
- estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
- for(i=16; i>=0; i--) {
- if(estpack & (1 << i)) {
- if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
- if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
- if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i];
- }
- }
-
- /* By default we drive the LCD at 75Hz in 640x480 mode; if
- * the panel does not provide this mode, use 60hz
- */
- if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE;
-
- /* 2. From Standard Timings */
- for(i=0x26; i < 0x36; i+=2) {
- if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
- temp = (buffer[i] + 31) * 8;
- if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
- switch((buffer[i+1] & 0xc0) >> 6) {
- case 0x03: temp = temp * 9 / 16; break;
- case 0x02: temp = temp * 4 / 5; break;
- case 0x01: temp = temp * 3 / 4; break;
- }
- if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
- }
- }
-
- /* Now extract the Detailed Timings and convert them into modes */
-
- for(i = 0; i < 4; i++, base += 18) {
-
- /* Is this a detailed timing block or a monitor descriptor? */
- if(buffer[base] || buffer[base+1] || buffer[base+2]) {
-
- xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
- yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
-
- SiS_Pr->CP_HDisplay[i] = xres;
- SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
- SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
- SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
- SiS_Pr->CP_HBlankStart[i] = xres + 1;
- SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
- SiS_Pr->CP_VDisplay[i] = yres;
- SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
- SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
- SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
- SiS_Pr->CP_VBlankStart[i] = yres + 1;
- SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
- SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
-
- SiS_Pr->CP_DataValid[i] = TRUE;
-
- /* Sort out invalid timings, interlace and too high clocks */
- if((SiS_Pr->CP_HDisplay[i] & 7) ||
- (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
- (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
- ((!(pSiS->VBFlags & VB_301C)) &&
- ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024) ||
- (SiS_Pr->CP_HDisplay[i] > 1600)))) ||
- (buffer[base+17] & 0x80)) {
-
- SiS_Pr->CP_DataValid[i] = FALSE;
-
- } else {
-
- SiS_Pr->CP_HaveCustomData = TRUE;
-
- if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
- if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
- if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-
- if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
- SiS_Pr->CP_PreferredIndex = i;
- SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
- SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
- }
-
- /* Extract the sync polarisation information. This only works
- * if the Flags indicate a digital separate output.
- */
- if((buffer[base+17] & 0x18) == 0x18) {
- SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
- SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
- SiS_Pr->CP_SyncValid[i] = TRUE;
- if((i == SiS_Pr->CP_PreferredIndex) && (!havesync)) {
- cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
- havesync = TRUE;
- }
- } else {
- SiS_Pr->CP_SyncValid[i] = FALSE;
- }
-
- }
-
- } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) {
-
- /* Maximum pixclock from Monitor Range Limits */
- if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
- int maxclk = buffer[base+9] * 10;
- /* More than 170 is not supported anyway */
- if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
- }
-
- }
-
- }
-
- if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) {
- paneltype = Panel_Custom;
- checkexpand = FALSE;
- cr37 |= 0x10;
- SiS_Pr->CP_Vendor = panelvendor;
- SiS_Pr->CP_Product = panelproduct;
- }
-
- }
-
- if(paneltype && checkexpand) {
- /* If any of the Established low-res modes is supported, the
- * panel can scale automatically. For 800x600 panels, we only
- * check the even lower ones.
- */
- if(paneltype == Panel_800x600) {
- if(buffer[0x23] & 0xfc) cr37 |= 0x10;
- } else {
- if(buffer[0x23]) cr37 |= 0x10;
- }
- }
-
- break;
-
- case 3: /* Analyze EDID V2 */
- case 4:
- index = 0;
-
- if(!(checkedid2(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: EDID corrupt\n");
- return 0;
- }
-
- if((buffer[0x41] & 0x0f) == 0x03) {
- index = 0x42 + 3;
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: Display supports TMDS input on primary interface\n");
- } else if((buffer[0x41] & 0xf0) == 0x30) {
- index = 0x46 + 3;
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: Display supports TMDS input on secondary interface\n");
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "LCD sense: Display does not support TMDS video interface (0x%02x)\n",
- buffer[0x41]);
- return 0;
- }
-
- SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8);
- SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8);
-
- paneltype = Panel_Custom;
- SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8);
- SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8);
-
- switch(xres) {
-#if 0
- case 800:
- if(yres == 600) {
- paneltype = Panel_800x600;
- checkexpand = TRUE;
- }
- break;
-#endif
- case 1024:
- if(yres == 768) {
- paneltype = Panel_1024x768;
- checkexpand = TRUE;
- }
- break;
- case 1280:
- if(yres == 960) {
- if(pSiS->VGAEngine == SIS_315_VGA) {
- paneltype = Panel310_1280x960;
- } else {
- paneltype = Panel300_1280x960;
- }
- } else if(yres == 1024) {
- paneltype = Panel_1280x1024;
- checkexpand = TRUE;
- }
- /* 1280x768 treated as custom here */
- break;
- case 1400:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1050) {
- paneltype = Panel310_1400x1050;
- checkexpand = TRUE;
- }
- }
- break;
- case 1600:
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_301C) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
- }
- }
- }
- break;
- }
-
- /* Determine if RGB18 or RGB24 */
- if(index) {
- if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
- cr37 |= 0x01;
- }
- }
-
- if(checkexpand) {
- /* TODO - for now, we let the panel scale */
- cr37 |= 0x10;
- }
-
- /* Now seek 4-Byte Timing codes and extract sync pol info */
- index = 0x80;
- if(buffer[0x7e] & 0x20) { /* skip Luminance Table (if provided) */
- lumsize = buffer[0x80] & 0x1f;
- if(buffer[0x80] & 0x80) lumsize *= 3;
- lumsize++; /* luminance header byte */
- index += lumsize;
- }
-#if 0 /* "pixel rate" = pixel clock? */
- if(buffer[0x7e] & 0x1c) {
- for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) {
- if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) {
- int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000;
- if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
- }
- }
- }
-#endif
- index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */
- if(buffer[0x7e] & 0x03) {
- for(i=0; i<(buffer[0x7e] & 0x03); i++) {
- if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) {
- int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10;
- if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk;
- }
- }
- }
- index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */
- numcodes = (buffer[0x7f] & 0xf8) >> 3;
- if(numcodes) {
- myindex = index;
- seekcode = (xres - 256) / 16;
- for(i=0; i<numcodes; i++) {
- if(buffer[myindex] == seekcode) break;
- myindex += 4;
- }
- if(buffer[myindex] == seekcode) {
- cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
- havesync = TRUE;
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "LCD sense: Unable to retrieve Sync polarity information\n");
- }
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
- "LCD sense: Unable to retrieve Sync polarity information\n");
- }
-
- /* Check against our database; Eg. Sanyo projector reports
- * 1024x768 in non-HDPC mode, although it supports 1280x720.
- * Treat such wrongly reporting panels as custom.
- */
- if(paneltype != Panel_Custom) {
- int maxx, maxy, prefx, prefy;
- if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy, &prefx, &prefy))) {
- paneltype = Panel_Custom;
- SiS_Pr->CP_MaxX = maxx;
- SiS_Pr->CP_MaxY = maxy;
- cr37 |= 0x10;
- /* Leave preferred unchanged (MUST be a valid mode!) */
- }
- }
-
- /* Now seek the detailed timing descriptions for custom panels */
- if(paneltype == Panel_Custom) {
-
- SiS_Pr->CP_Supports64048075 = TRUE;
-
- index += (numcodes * 4);
- numcodes = buffer[0x7f] & 0x07;
- for(i=0; i<numcodes; i++, index += 18) {
- xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
- yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
-
- SiS_Pr->CP_HDisplay[i] = xres;
- SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
- SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
- SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
- SiS_Pr->CP_HBlankStart[i] = xres + 1;
- SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
-
- SiS_Pr->CP_VDisplay[i] = yres;
- SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
- SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
- SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
- SiS_Pr->CP_VBlankStart[i] = yres + 1;
- SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
-
- SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
-
- SiS_Pr->CP_DataValid[i] = TRUE;
-
- if((SiS_Pr->CP_HDisplay[i] & 7) ||
- (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
- (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) ||
- (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) ||
- (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) ||
- (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) ||
- (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) ||
- ((!(pSiS->VBFlags & VB_301C)) &&
- ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) ||
- (buffer[index + 17] & 0x80)) {
-
- SiS_Pr->CP_DataValid[i] = FALSE;
-
- } else {
-
- SiS_Pr->CP_HaveCustomData = TRUE;
-
- if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
-
- if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
- SiS_Pr->CP_PreferredIndex = i;
- SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
- SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
- if(!havesync) {
- cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
- havesync = TRUE;
- }
- }
-
- SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
- SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
- SiS_Pr->CP_SyncValid[i] = TRUE;
-
- }
- }
-
- cr37 |= 0x10;
-
- }
-
- break;
-
- }
-
- /* 1280x960 panels are always RGB24, unable to scale and use
- * high active sync polarity
- */
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
- } else {
- if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
- }
-
- for(i = 0; i < 7; i++) {
- if(SiS_Pr->CP_DataValid[i]) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "Non-standard LCD/DVI-D timing data no. %d:\n", i);
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- " HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
- SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
- SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- " VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
- SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
- SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- " Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
- " To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
- SiS_Pr->CP_HDisplay[i],
- SiS_Pr->CP_VDisplay[i]);
- }
- }
-
- if(paneltype) {
- if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
- if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
- cr37 &= 0xf1;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
- SiS_Pr->PanelSelfDetected = TRUE;
-#ifdef TWDEBUG
- xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
- "LCD sense: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
-#endif
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
- }
- return 0;
-}
-
-USHORT
-SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
- USHORT DDCdatatype,flag;
- BOOLEAN foundcrt = FALSE;
- int retry;
- unsigned char buffer[256];
-
- if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
-
- if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
-
- SiS_Pr->SiS_DDC_SecAddr = 0x00;
-
- /* Probe supported DA's */
- flag = SiS_ProbeDDC(SiS_Pr);
- if(flag & 0x10) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; /* EDID V2 (FP) */
- DDCdatatype = 4;
- } else if(flag & 0x08) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; /* EDID V2 (P&D-D Monitor) */
- DDCdatatype = 3;
- } else if(flag & 0x02) {
- SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; /* EDID V1 */
- DDCdatatype = 1;
- } else {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "VGA2 sense: Do DDC answer\n");
- return 0; /* no DDC support (or no device attached) */
- }
-
- /* Read the entire EDID */
- retry = 2;
- do {
- if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
- "VGA2 sense: DDC read failed (attempt %d), %s\n",
- (3-retry), (retry == 1) ? "giving up" : "retrying");
- retry--;
- if(retry == 0) return 0xFFFF;
- } else break;
- } while(1);
-
- /* Analyze EDID. We don't have many chances to
- * distinguish a flat panel from a CRT...
- */
- switch(DDCdatatype) {
- case 1:
- if(!(checkedid1(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "VGA2 sense: EDID corrupt\n");
- return 0;
- }
- if(buffer[0x14] & 0x80) { /* Display uses digital input */
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "VGA2 sense: Attached display expects digital input\n");
- return 0;
- }
- SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
- SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
- foundcrt = TRUE;
- break;
- case 3:
- case 4:
- if(!(checkedid2(buffer))) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "VGA2 sense: EDID corrupt\n");
- return 0;
- }
- if( ((buffer[0x41] & 0x0f) != 0x01) && /* Display does not support analog input */
- ((buffer[0x41] & 0x0f) != 0x02) &&
- ((buffer[0x41] & 0xf0) != 0x10) &&
- ((buffer[0x41] & 0xf0) != 0x20) ) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "VGA2 sense: Attached display does not support analog input (0x%02x)\n",
- buffer[0x41]);
- return 0;
- }
- SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
- SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
- foundcrt = TRUE;
- break;
- }
-
- if(foundcrt) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
- }
- return(0);
-}
-
-#endif
-
-void
-SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
-{
- USHORT tempbl;
-
- tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
- tempbl = (((tempbl & tempbh) << 8) | tempax);
- SiS_SetCH70xx(SiS_Pr,tempbl);
-}
-
/* Generic I2C functions for Chrontel & DDC --------- */
static void
-SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
+SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
{
SiS_SetSCLKHigh(SiS_Pr);
SiS_WaitRetrace1(SiS_Pr);
@@ -10505,125 +9502,127 @@ SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
SiS_WaitRetrace1(SiS_Pr);
}
-USHORT
-SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
+unsigned short
+SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
{
SiS_WaitRetrace1(SiS_Pr);
- return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
+ return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
}
/* Set I2C start condition */
/* This is done by a SD high-to-low transition while SC is high */
-static USHORT
-SiS_SetStart(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetStart(struct SiS_Private *SiS_Pr)
{
- if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- SiS_Pr->SiS_DDC_Data); /* SD->high */
- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Data); /* SD->high */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- 0x00); /* SD->low = start condition */
- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ 0x00); /* SD->low = start condition */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */
return 0;
}
/* Set I2C stop condition */
/* This is done by a SD low-to-high transition while SC is high */
-static USHORT
-SiS_SetStop(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetStop(struct SiS_Private *SiS_Pr)
{
- if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
+ if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- 0x00); /* SD->low */
- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ 0x00); /* SD->low */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
- if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */
+ if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */
return 0;
}
/* Write 8 bits of data */
-static USHORT
-SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+static unsigned short
+SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
{
- USHORT i,flag,temp;
+ unsigned short i,flag,temp;
flag = 0x80;
- for(i=0; i<8; i++) {
- SiS_SetSCLKLow(SiS_Pr); /* SC->low */
+ for(i = 0; i < 8; i++) {
+ SiS_SetSCLKLow(SiS_Pr); /* SC->low */
if(tempax & flag) {
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */
} else {
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- 0x00); /* Write bit (0) to SD */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ 0x00); /* Write bit (0) to SD */
}
- SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
+ SiS_SetSCLKHigh(SiS_Pr); /* SC->high */
flag >>= 1;
}
- temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
- return(temp);
+ temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */
+ return temp;
}
-static USHORT
-SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
+static unsigned short
+SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
{
- USHORT i,temp,getdata;
+ unsigned short i, temp, getdata;
- getdata=0;
- for(i=0; i<8; i++) {
+ getdata = 0;
+ for(i = 0; i < 8; i++) {
getdata <<= 1;
SiS_SetSCLKLow(SiS_Pr);
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
SiS_Pr->SiS_DDC_Data);
SiS_SetSCLKHigh(SiS_Pr);
temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
}
- return(getdata);
+ return getdata;
}
-static USHORT
-SiS_SetSCLKLow(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
{
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NClk,
- 0x00); /* SetSCLKLow() */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NClk,
+ 0x00); /* SetSCLKLow() */
SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
return 0;
}
-static USHORT
-SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
{
- USHORT temp, watchdog=1000;
+ unsigned short temp, watchdog=1000;
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NClk,
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NClk,
SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */
do {
temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
} while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
if (!watchdog) {
+#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
#endif
+#endif
return 0xFFFF;
}
SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
@@ -10632,21 +9631,21 @@ SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
/* Check I2C acknowledge */
/* Returns 0 if ack ok, non-0 if ack not ok */
-static USHORT
-SiS_CheckACK(SiS_Private *SiS_Pr)
+static unsigned short
+SiS_CheckACK(struct SiS_Private *SiS_Pr)
{
- USHORT tempah;
+ unsigned short tempah;
SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */
SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
- SiS_Pr->SiS_DDC_Index,
- SiS_Pr->SiS_DDC_NData,
- SiS_Pr->SiS_DDC_Data); /* (SD->high) */
+ SiS_Pr->SiS_DDC_Index,
+ SiS_Pr->SiS_DDC_NData,
+ SiS_Pr->SiS_DDC_Data); /* (SD->high) */
SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */
tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */
- if(tempah & SiS_Pr->SiS_DDC_Data) return(1); /* Ack OK if bit = 0 */
- else return(0);
+ if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */
+ return 0;
}
/* End of I2C functions ----------------------- */
@@ -10656,67 +9655,67 @@ SiS_CheckACK(SiS_Private *SiS_Pr)
#ifdef SIS315H
-static USHORT
-GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetRAMDACromptr(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr;
- if(HwInfo->jChipType < SIS_330) {
+ if(SiS_Pr->ChipType < SIS_330) {
romptr = SISGETROMW(0x128);
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xB)
romptr = SISGETROMW(0x12a);
} else {
romptr = SISGETROMW(0x1a8);
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xB)
romptr = SISGETROMW(0x1aa);
}
- return(romptr);
+ return romptr;
}
-static USHORT
-GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDromptr(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr;
- if(HwInfo->jChipType < SIS_330) {
+ if(SiS_Pr->ChipType < SIS_330) {
romptr = SISGETROMW(0x120);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
romptr = SISGETROMW(0x122);
} else {
romptr = SISGETROMW(0x1a0);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
romptr = SISGETROMW(0x1a2);
}
- return(romptr);
+ return romptr;
}
-static USHORT
-GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetTVromptr(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr;
- if(HwInfo->jChipType < SIS_330) {
+ if(SiS_Pr->ChipType < SIS_330) {
romptr = SISGETROMW(0x114);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
romptr = SISGETROMW(0x11a);
} else {
romptr = SISGETROMW(0x194);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
romptr = SISGETROMW(0x19a);
}
- return(romptr);
+ return romptr;
}
-static USHORT
-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static unsigned short
+GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
{
- USHORT index;
+ unsigned short index;
- if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
- if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+ if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+ if(!(SiS_IsNotM650orLater(SiS_Pr))) {
if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
index >>= 4;
index *= 3;
@@ -10729,7 +9728,12 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
- else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
+ }
index--;
index *= 3;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -10737,10 +9741,10 @@ GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
return index;
}
-static USHORT
-GetLCDPtrIndex(SiS_Private *SiS_Pr)
+static unsigned short
+GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
{
- USHORT index;
+ unsigned short index;
index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
@@ -10748,10 +9752,10 @@ GetLCDPtrIndex(SiS_Private *SiS_Pr)
return index;
}
-static USHORT
-GetTVPtrIndex(SiS_Private *SiS_Pr)
+static unsigned short
+GetTVPtrIndex(struct SiS_Private *SiS_Pr)
{
- USHORT index;
+ unsigned short index;
index = 0;
if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
@@ -10769,10 +9773,10 @@ GetTVPtrIndex(SiS_Private *SiS_Pr)
return index;
}
-static ULONG
-GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
+static unsigned int
+GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
{
- USHORT index = 0, temp = 0;
+ unsigned short index = 0, temp = 0;
if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2;
@@ -10784,7 +9788,7 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
}
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
index += addme;
@@ -10792,25 +9796,25 @@ GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
}
temp += 0x0100;
}
- return(ULONG)(index | (temp << 16));
+ return (unsigned int)(index | (temp << 16));
}
-static ULONG
-GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
+static unsigned int
+GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
{
- return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
+ return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
}
#if 0
-static ULONG
-GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
+static unsigned int
+GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
{
- return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
+ return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
}
#endif
static int
-GetOEMTVPtr661(SiS_Private *SiS_Pr)
+GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
{
int index = 0;
@@ -10833,10 +9837,10 @@ GetOEMTVPtr661(SiS_Private *SiS_Pr)
}
static void
-SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT delay=0,index,myindex,temp,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short delay=0,index,myindex,temp,romptr=0;
BOOLEAN dochiptest = TRUE;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
@@ -10848,19 +9852,19 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
/* Find delay (from ROM, internal tables, PCI subsystem) */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
-
+
if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
- romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
+ romptr = GetRAMDACromptr(SiS_Pr);
}
if(romptr) delay = ROMAddr[romptr];
else {
delay = 0x04;
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
if(IS_SIS650) {
delay = 0x0a;
} else if(IS_SIS740) {
delay = 0x00;
- } else if(HwInfo->jChipType < SIS_330) {
+ } else if(SiS_Pr->ChipType < SIS_330) {
delay = 0x0c;
} else {
delay = 0x0c;
@@ -10901,8 +9905,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
} else {
delay = 0x0c;
- if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
- else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ delay = 0x03;
+ if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
+ delay = 0x00;
+ }
+ } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
if(IS_SIS740) delay = 0x01;
else delay = 0x03;
}
@@ -10947,12 +9955,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
if(!gotitfrompci) {
- index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
+ index = GetLCDPtrIndexBIOS(SiS_Pr);
myindex = GetLCDPtrIndex(SiS_Pr);
- if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
- if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
+ if(SiS_IsNotM650orLater(SiS_Pr)) {
if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
/* Always use the second pointer on 650; some BIOSes */
@@ -10978,11 +9986,12 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
(!(SiS_Pr->SiS_ROMNew)) &&
(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
(SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
- (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
+ (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
+ (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) &&
+ ((romptr = GetLCDromptr(SiS_Pr)))) {
/* Data for 1280x1024 wrong in 301B BIOS */
- romptr = GetLCDromptr(SiS_Pr, HwInfo);
- if(!romptr) return;
+ /* Data for 1600x1200 wrong in 301C BIOS */
delay = ROMAddr[(romptr + index)];
} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
@@ -10993,14 +10002,15 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
} else {
delay = SiS310_LCDDelayCompensation_301[myindex];
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
if(IS_SIS740) delay = 0x01;
- else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
+ else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
} else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
if(IS_SIS740) delay = 0x01; /* ? */
else delay = 0x03;
- } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
+ } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
if(IS_SIS740) delay = 0x01;
else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
}
@@ -11013,14 +10023,14 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
dochiptest = FALSE;
}
-
+
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
index = GetTVPtrIndex(SiS_Pr);
-
- if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
- if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+ if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
+
+ if(SiS_IsNotM650orLater(SiS_Pr)) {
if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
/* Always use the second pointer on 650; some BIOSes */
@@ -11062,7 +10072,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
} else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
- romptr = GetTVromptr(SiS_Pr, HwInfo);
+ romptr = GetTVromptr(SiS_Pr);
if(!romptr) return;
delay = ROMAddr[romptr + index];
@@ -11073,7 +10083,7 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
} else {
delay = SiS310_TVDelayCompensation_301[index];
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
if(IS_SIS740) {
delay = SiS310_TVDelayCompensation_740301B[index];
/* LV: use 301 data? BIOS bug? */
@@ -11085,18 +10095,18 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
}
- if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+ if(SiS_LCDAEnabled(SiS_Pr)) {
delay &= 0x0f;
dochiptest = FALSE;
}
-
+
} else return;
/* Write delay */
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
+ if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */
@@ -11134,11 +10144,10 @@ SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
}
static void
-SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,temp1,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,temp1,romptr=0;
if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
@@ -11152,14 +10161,14 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
temp1 = temp;
if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
temp1 = GetOEMTVPtr661(SiS_Pr);
temp1 >>= 1;
romptr = SISGETROMW(0x260);
- if(HwInfo->jChipType >= SIS_760) {
+ if(SiS_Pr->ChipType >= SIS_760) {
romptr = SISGETROMW(0x360);
}
- } else if(HwInfo->jChipType >= SIS_330) {
+ } else if(SiS_Pr->ChipType >= SIS_330) {
romptr = SISGETROMW(0x192);
} else {
romptr = SISGETROMW(0x112);
@@ -11178,11 +10187,10 @@ SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,temp1,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,temp1,romptr=0;
temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
@@ -11192,14 +10200,14 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
- if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->ChipType >= SIS_661) {
romptr = SISGETROMW(0x26c);
- if(HwInfo->jChipType >= SIS_760) {
+ if(SiS_Pr->ChipType >= SIS_760) {
romptr = SISGETROMW(0x36c);
}
temp1 = GetOEMTVPtr661(SiS_Pr);
temp1 >>= 1;
- } else if(HwInfo->jChipType >= SIS_330) {
+ } else if(SiS_Pr->ChipType >= SIS_330) {
romptr = SISGETROMW(0x1a4);
} else {
romptr = SISGETROMW(0x124);
@@ -11217,10 +10225,9 @@ SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
{
- USHORT index, temp, i, j;
+ unsigned short index, temp, i, j;
if(ModeNo <= 0x13) {
index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
@@ -11235,7 +10242,7 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
for(i=0x35, j=0; i<=0x38; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
}
@@ -11250,23 +10257,22 @@ SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,i,j,resinfo,romptr=0;
- ULONG lindex;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,i,j,resinfo,romptr=0;
+ unsigned int lindex;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
/* NTSC-J data not in BIOS, and already set in SetGroup2 */
if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
- if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
+ if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
lindex <<= 2;
for(j=0, i=0x31; i<=0x34; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
}
return;
}
@@ -11286,17 +10292,17 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
*/
if(SiS_Pr->SiS_UseROM) {
romptr = SISGETROMW(0x116);
- if(HwInfo->jChipType >= SIS_330) {
+ if(SiS_Pr->ChipType >= SIS_330) {
romptr = SISGETROMW(0x196);
}
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
romptr = SISGETROMW(0x11c);
- if(HwInfo->jChipType >= SIS_330) {
+ if(SiS_Pr->ChipType >= SIS_330) {
romptr = SISGETROMW(0x19c);
}
if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
romptr = SISGETROMW(0x116);
- if(HwInfo->jChipType >= SIS_330) {
+ if(SiS_Pr->ChipType >= SIS_330) {
romptr = SISGETROMW(0x196);
}
}
@@ -11311,7 +10317,7 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
index = temp % 2;
temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */
for(j=0, i=0x31; i<=0x34; i++, j++) {
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
+ if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
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,
}
}
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
+ if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
if((resinfo == SIS_RI_640x480) ||
(resinfo == SIS_RI_800x600)) {
@@ -11339,11 +10345,11 @@ SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
- USHORT ModeIdIndex, USHORT RTI)
+SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RTI)
{
- USHORT delay = 0, romptr = 0, index, lcdpdcindex;
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
return;
@@ -11359,7 +10365,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
if(SiS_Pr->UseCustomMode) {
index = SiS_Pr->CSRClock;
} else if(ModeNo > 0x13) {
- index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
index = SiS_Pr->SiS_VCLKData[index].CLOCK;
}
if(index < 25) index = 25;
@@ -11387,7 +10393,36 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
delay |= (delay << 8);
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(SiS_Pr->ChipType >= XGI_20) {
+
+ delay = 0x0606;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+ delay = 0x0404;
+ if(SiS_Pr->SiS_XGIROM) {
+ index = GetTVPtrIndex(SiS_Pr);
+ if((romptr = SISGETROMW(0x35e))) {
+ delay = (ROMAddr[romptr + index] & 0x0f) << 1;
+ delay |= (delay << 8);
+ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
+ delay -= 0x0404;
+ }
+ }
+ }
+
+ } else if(SiS_Pr->ChipType >= SIS_340) {
+
+ delay = 0x0606;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ delay = 0x0404;
+ }
+ /* TODO (eventually) */
+
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
/* 3. TV */
@@ -11406,7 +10441,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
/* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
- ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
+ ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
@@ -11426,6 +10461,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
case Panel_1280x768_2:delay = 0x0004; break;
case Panel_1280x800:
case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
+ case Panel_1280x854: delay = 0x0004; break; /* FIXME */
case Panel_1280x1024: delay = 0x1e04; break;
case Panel_1400x1050: delay = 0x0004; break;
case Panel_1600x1200: delay = 0x0400; break;
@@ -11469,10 +10505,10 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
}
static void
-SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT RTI)
+SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
{
- USHORT infoflag;
- UCHAR temp;
+ unsigned short infoflag;
+ unsigned char temp;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11513,12 +10549,16 @@ SetCRT2SyncDither661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, US
}
static void
-SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SetPanelParms661(struct SiS_Private *SiS_Pr)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT romptr, temp1, temp2;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short romptr, temp1, temp2;
+
+ if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
+ }
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
if(SiS_Pr->LVDSHL != -1) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
}
@@ -11526,8 +10566,8 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
if(SiS_Pr->SiS_ROMNew) {
- if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+ if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
+ if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
temp2 = 0xfc;
if(SiS_Pr->LVDSHL != -1) {
@@ -11546,48 +10586,47 @@ SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
}
static void
-SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex,USHORT RRTI)
+SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
{
if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
- SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+ SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
- SetPanelParms661(SiS_Pr,HwInfo);
+ SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
+ SetPanelParms661(SiS_Pr);
}
} else {
- SetDelayComp(SiS_Pr,HwInfo,ModeNo);
+ SetDelayComp(SiS_Pr,ModeNo);
}
if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
- SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+ SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
+ SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
+ SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
if(SiS_Pr->SiS_VBType & VB_SIS301) {
- SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+ SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
}
}
}
static void
-SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI)
+SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, unsigned short RRTI)
{
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SetDelayComp661(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,RRTI);
+ SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- SetCRT2SyncDither661(SiS_Pr,HwInfo,ModeNo,RRTI);
- SetPanelParms661(SiS_Pr,HwInfo);
+ SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
+ SetPanelParms661(SiS_Pr);
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+ SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
+ SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
+ SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
if(SiS_Pr->SiS_VBType & VB_SIS301) {
- SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+ SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
}
}
}
@@ -11601,13 +10640,12 @@ SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
* pray that we have a backup...
*/
static void
-SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo)
+SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
- USHORT resinfo,modeflag;
+ unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
+ unsigned short resinfo,modeflag;
- if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+ if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
if(SiS_Pr->SiS_ROMNew) return;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11678,7 +10716,7 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
#ifdef SET_EMI
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
@@ -11806,11 +10844,11 @@ SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
#ifdef SIS300
static void
-SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
+SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
+ unsigned short RefTabIndex)
{
- USHORT crt2crtc=0, modeflag, myindex=0;
- UCHAR temp;
+ unsigned short crt2crtc=0, modeflag, myindex=0;
+ unsigned char temp;
int i;
if(ModeNo <= 0x13) {
@@ -11849,21 +10887,21 @@ SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
}
-static USHORT
-GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
+static unsigned short
+GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT tempbx=0,romptr=0;
- UCHAR customtable300[] = {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short tempbx=0,romptr=0;
+ static const unsigned char customtable300[] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
- UCHAR customtable630[] = {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ static const unsigned char customtable630[] = {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
- if(HwInfo->jChipType == SIS_300) {
+ if(SiS_Pr->ChipType == SIS_300) {
tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
@@ -11912,11 +10950,10 @@ GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
}
static void
-SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,romptr=0;
if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
@@ -11927,22 +10964,22 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
/* The Panel Compensation Delay should be set according to tables
- * here. Unfortunately, various BIOS versions don't case about
+ * here. Unfortunately, various BIOS versions don't care about
* a uniform way using eg. ROM byte 0x220, but use different
* hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
- * Thus we don't set this if the user select a custom pdc or if
+ * Thus we don't set this if the user selected a custom pdc or if
* we otherwise detected a valid pdc.
*/
if(SiS_Pr->PDC != -1) return;
- temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
+ temp = GetOEMLCDPtr(SiS_Pr, 0);
if(SiS_Pr->UseCustomMode)
index = 0;
else
index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
- if(HwInfo->jChipType != SIS_300) {
+ if(SiS_Pr->ChipType != SIS_300) {
if(romptr) {
romptr += (temp * 2);
romptr = SISGETROMW(romptr);
@@ -11986,12 +11023,11 @@ SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
#if 0 /* Unfinished; Data table missing */
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp;
if((SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x237] & 0x01)) return;
@@ -11999,8 +11035,8 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
/* No rom pointer in BIOS header! */
}
- temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
- if(temp = 0xFFFF) return;
+ temp = GetOEMLCDPtr(SiS_Pr, 1);
+ if(temp == 0xFFFF) return;
index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
for(i=0x14, j=0; i<=0x17; i++, j++) {
@@ -12018,10 +11054,10 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
#endif
}
-static USHORT
-GetOEMTVPtr(SiS_Private *SiS_Pr)
+static unsigned short
+GetOEMTVPtr(struct SiS_Private *SiS_Pr)
{
- USHORT index;
+ unsigned short index;
index = 0;
if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4;
@@ -12037,11 +11073,10 @@ GetOEMTVPtr(SiS_Private *SiS_Pr)
}
static void
-SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,romptr=0;
if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12070,11 +11105,10 @@ SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
+SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,romptr=0;
if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
@@ -12099,11 +11133,10 @@ SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,i,j,temp,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,i,j,temp,romptr=0;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
@@ -12119,7 +11152,7 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
for(i=0x31, j=0; i<=0x34; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
}
@@ -12140,11 +11173,10 @@ SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
static void
-SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index,temp,i,j,romptr=0;
+ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
+ unsigned short index,temp,i,j,romptr=0;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
@@ -12162,7 +11194,7 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
for(i=0x35, j=0; i<=0x38; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
}
@@ -12185,11 +11217,11 @@ SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
}
-static USHORT
-SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
+static unsigned short
+SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
{
- USHORT ModeIdIndex;
- UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+ unsigned short ModeIdIndex;
+ unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
if(*ModeNo <= 5) *ModeNo |= 1;
@@ -12210,10 +11242,10 @@ SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
}
static void
-SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
+SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefTableIndex)
{
- USHORT OEMModeIdIndex=0;
+ unsigned short OEMModeIdIndex = 0;
if(!SiS_Pr->UseCustomMode) {
OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
@@ -12221,18 +11253,18 @@ SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+ SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+ SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
}
}
if(SiS_Pr->UseCustomMode) return;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
+ SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
- SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
- SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+ SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
+ SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
+ SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
}
}
}
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index f84eb54164a..f475b21a85c 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -3,7 +3,7 @@
/*
* Data and prototypes for init301.c
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,18 +50,18 @@
*
*/
-#ifndef _INIT301_
-#define _INIT301_
+#ifndef _INIT301_H_
+#define _INIT301_H_
#include "osdef.h"
#include "initdef.h"
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
#include "sis.h"
#include "sis_regs.h"
#endif
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
#include "vgatypes.h"
#include "vstruct.h"
#ifdef SIS_CP
@@ -69,8 +69,13 @@
#endif
#include <linux/config.h>
#include <linux/version.h>
-#include <asm/io.h>
#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
+#include "sis.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/sisfb.h>
#else
@@ -78,7 +83,7 @@
#endif
#endif
-static const UCHAR SiS_YPbPrTable[3][64] = {
+static const unsigned char SiS_YPbPrTable[3][64] = {
{
0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
@@ -90,17 +95,17 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
},
{
- 0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
+ 0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
- 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13,
+ 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
- 0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40,
- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
+ 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
},
{
-#if 1
+#if 0 /* OK, but sticks to left edge */
0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
@@ -110,20 +115,42 @@ static const UCHAR SiS_YPbPrTable[3][64] = {
0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
#endif
-#if 0
- 0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c, /* TEST (0.93) - BAD */
+#if 1 /* Perfect */
+ 0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
- 0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13,
- 0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0,
- 0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f,
- 0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00
+ 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
+ 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
+ 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
+ 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
#endif
}
};
-static const UCHAR SiS_HiTVGroup3_1[] = {
+static const unsigned char SiS_TVPhase[] =
+{
+ 0x21,0xED,0xBA,0x08, /* 0x00 SiS_NTSCPhase */
+ 0x2A,0x05,0xE3,0x00, /* 0x01 SiS_PALPhase */
+ 0x21,0xE4,0x2E,0x9B, /* 0x02 SiS_PALMPhase */
+ 0x21,0xF4,0x3E,0xBA, /* 0x03 SiS_PALNPhase */
+ 0x1E,0x8B,0xA2,0xA7,
+ 0x1E,0x83,0x0A,0xE0, /* 0x05 SiS_SpecialPhaseM */
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,
+ 0x21,0xF0,0x7B,0xD6, /* 0x08 SiS_NTSCPhase2 */
+ 0x2A,0x09,0x86,0xE9, /* 0x09 SiS_PALPhase2 */
+ 0x21,0xE6,0xEF,0xA4, /* 0x0a SiS_PALMPhase2 */
+ 0x21,0xF6,0x94,0x46, /* 0x0b SiS_PALNPhase2 */
+ 0x1E,0x8B,0xA2,0xA7,
+ 0x1E,0x83,0x0A,0xE0, /* 0x0d SiS_SpecialPhaseM */
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,
+ 0x1e,0x8c,0x5c,0x7a, /* 0x10 SiS_SpecialPhase */
+ 0x25,0xd4,0xfd,0x5e /* 0x11 SiS_SpecialPhaseJ */
+};
+
+static const unsigned char SiS_HiTVGroup3_1[] = {
0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -134,7 +161,7 @@ static const UCHAR SiS_HiTVGroup3_1[] = {
0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
};
-static const UCHAR SiS_HiTVGroup3_2[] = {
+static const unsigned char SiS_HiTVGroup3_2[] = {
0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
@@ -147,7 +174,7 @@ static const UCHAR SiS_HiTVGroup3_2[] = {
/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
-static const UCHAR SiS_Part2CLVX_1[] = {
+static const unsigned char SiS_Part2CLVX_1[] = {
0x00,0x00,
0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
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[] = {
0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
};
-static const UCHAR SiS_Part2CLVX_2[] = {
+static const unsigned char SiS_Part2CLVX_2[] = {
0x00,0x00,
0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
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[] = {
0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
};
-static const UCHAR SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
+static const unsigned char SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */
0xE0,0x01,
0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
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 */
0xFF,0xFF
};
-static const UCHAR SiS_Part2CLVX_4[] = { /* PAL */
+static const unsigned char SiS_Part2CLVX_4[] = { /* PAL */
0x58,0x02,
0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
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 */
0xFF,0xFF
};
-static const UCHAR SiS_Part2CLVX_5[] = { /* 750p */
+static const unsigned char SiS_Part2CLVX_5[] = { /* 750p */
0x00,0x03,
0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
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 */
0xFF,0xFF
};
-static const UCHAR SiS_Part2CLVX_6[] = { /* 1080i */
+static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
0x00,0x04,
0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
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 */
#ifdef SIS315H
/* 661 et al LCD data structure (2.03.00) */
-static const UCHAR SiS_LCDStruct661[] = {
+static const unsigned char SiS_LCDStruct661[] = {
/* 1024x768 */
/* type|CR37| HDE | VDE | HT | VT | hss | hse */
0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
@@ -249,11 +276,20 @@ static const UCHAR SiS_LCDStruct661[] = {
/* 1680x1050 */
0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
+ /* 1280x800_3 */
+ 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
+ 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
+ /* 800x600 */
+ 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
+ 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
+ /* 1280x854 */
+ 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
+ 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
};
#endif
#ifdef SIS300
-static UCHAR SiS300_TrumpionData[7][80] = {
+static unsigned char SiS300_TrumpionData[14][80] = {
{ 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
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] = {
0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
- 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }
+ 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+ /* variant 2 */
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+ 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
+ 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+ 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
+ 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
+ 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+ 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+ 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
+ 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+ 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+ 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+ 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
+ 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
+ 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
+ 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
+ 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
+ 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
+ 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
+ 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
};
#endif
-void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_EnableCRT2(SiS_Private *SiS_Pr);
-USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-void SiS_WaitRetrace1(SiS_Private *SiS_Pr);
-BOOLEAN SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-BOOLEAN SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-void SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
- USHORT ModeIdIndex, PSIS_HW_INFO HwInfo,
- int checkcrt2mode);
-void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
-USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
-void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
-void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void SiS_LockCRT2(struct SiS_Private *SiS_Pr);
+#endif
+void SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
+unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
+BOOLEAN SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
+BOOLEAN SiS_IsVAMode(struct SiS_Private *SiS_Pr);
+void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex, int checkcrt2mode);
+void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
+void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+void SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex);
+unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
+void SiS_DisableBridge(struct SiS_Private *SiS_Pr);
+#ifndef SIS_LINUX_KERNEL
+void SiS_EnableBridge(struct SiS_Private *SiS_Pr);
+#endif
+BOOLEAN SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
+void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
-void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
+#ifndef SIS_LINUX_KERNEL
+void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax);
+#endif
+void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+ unsigned char orval,unsigned short andval);
#ifdef SIS315H
-static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-static void SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-static void SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-static void SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
+static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
+static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
+static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
+void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
+void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
#endif /* 315 */
#ifdef SIS300
-#if 0
-static void SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-static USHORT SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
-#endif
-static BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
+static BOOLEAN SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
+void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
#endif
-void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, UCHAR *buffer);
-#ifdef LINUX_XF86
-USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-#endif
+void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
+unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
+unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+ unsigned short adaptnum, unsigned short DDCdatatype,
+ unsigned char *buffer, unsigned int VBFlags2);
-static void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-static USHORT SiS_SetStart(SiS_Private *SiS_Pr);
-static USHORT SiS_SetStop(SiS_Private *SiS_Pr);
-static USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-static USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-static USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-static USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-static USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
-static USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-static USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-static USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-static USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
-static void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-static USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-static USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
-static USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, UCHAR *buffer);
+#ifdef SIS_XORG_XF86
+unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
+ int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
+ BOOLEAN checkcr32, unsigned int VBFlags2);
+unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
+unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
+ unsigned char *buffer);
+#else
+static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
+ int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
+ BOOLEAN checkcr32, unsigned int VBFlags2);
+static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
+ unsigned char *buffer);
+#endif
+static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
+static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
+static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
+static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
+static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
+#ifdef SIS300
+static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
+ unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
+static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
+ unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
+#endif
#ifdef SIS315H
-static void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
-static void SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
-static void SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
+static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
+ unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
+static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
+ unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
+static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
#endif
+
+extern void SiS_SetReg(SISIOADDRESS, unsigned short, unsigned short);
+extern void SiS_SetRegByte(SISIOADDRESS, unsigned short);
+extern void SiS_SetRegShort(SISIOADDRESS, unsigned short);
+extern void SiS_SetRegLong(SISIOADDRESS, unsigned int);
+extern unsigned char SiS_GetReg(SISIOADDRESS, unsigned short);
+extern unsigned char SiS_GetRegByte(SISIOADDRESS);
+extern unsigned short SiS_GetRegShort(SISIOADDRESS);
+extern unsigned int SiS_GetRegLong(SISIOADDRESS);
+extern void SiS_SetRegANDOR(SISIOADDRESS, unsigned short, unsigned short, unsigned short);
+extern void SiS_SetRegOR(SISIOADDRESS, unsigned short, unsigned short);
+extern void SiS_SetRegAND(SISIOADDRESS, unsigned short, unsigned short);
+extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
+extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
+extern BOOLEAN SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
+extern unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+extern unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
+extern unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
+ unsigned short RefreshRateTableIndex);
+extern void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
+ unsigned short ModeIdIndex);
+extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
+extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
+extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
#ifdef SIS300
-static void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-static void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
+ unsigned short *tempcl);
+extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
+extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
+#ifdef SIS_LINUX_KERNEL
+extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
#endif
-
-extern void SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
-extern void SiS_SetRegByte(SISIOADDRESS, USHORT);
-extern void SiS_SetRegShort(SISIOADDRESS, USHORT);
-extern void SiS_SetRegLong(SISIOADDRESS, ULONG);
-extern UCHAR SiS_GetReg(SISIOADDRESS, USHORT);
-extern UCHAR SiS_GetRegByte(SISIOADDRESS);
-extern USHORT SiS_GetRegShort(SISIOADDRESS);
-extern ULONG SiS_GetRegLong(SISIOADDRESS);
-extern void SiS_SetRegANDOR(SISIOADDRESS, USHORT, USHORT, USHORT);
-extern void SiS_SetRegOR(SISIOADDRESS, USHORT, USHORT);
-extern void SiS_SetRegAND(SISIOADDRESS, USHORT, USHORT);
-extern void SiS_DisplayOff(SiS_Private *SiS_Pr);
-extern void SiS_DisplayOn(SiS_Private *SiS_Pr);
-extern BOOLEAN SiS_SearchModeID(SiS_Private *, USHORT *, USHORT *);
-extern UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-extern USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-extern USHORT SiS_GetOffset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
-extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO, USHORT ModeNo,
- USHORT ModeIdIndex);
-extern void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
-#ifdef LINUX_XF86
-extern void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
-extern int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct,
- int *maxx, int *maxy, int *prefx, int *prefy);
#endif
#endif
diff --git a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
index 55a82d6dc4c..264b55a5947 100644
--- a/drivers/video/sis/initdef.h
+++ b/drivers/video/sis/initdef.h
@@ -3,7 +3,7 @@
/*
* Global definitions for init.c and init301.c
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -53,19 +53,20 @@
#ifndef _INITDEF_
#define _INITDEF_
-#define IS_SIS330 (HwInfo->jChipType == SIS_330)
-#define IS_SIS550 (HwInfo->jChipType == SIS_550)
-#define IS_SIS650 (HwInfo->jChipType == SIS_650) /* All versions, incl 651, M65x */
-#define IS_SIS740 (HwInfo->jChipType == SIS_740)
+#define IS_SIS330 (SiS_Pr->ChipType == SIS_330)
+#define IS_SIS550 (SiS_Pr->ChipType == SIS_550)
+#define IS_SIS650 (SiS_Pr->ChipType == SIS_650) /* All versions, incl 651, M65x */
+#define IS_SIS740 (SiS_Pr->ChipType == SIS_740)
#define IS_SIS651 (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
#define IS_SISM650 (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
#define IS_SIS65x (IS_SIS651 || IS_SISM650) /* Only special versions of 65x */
-#define IS_SIS661 (HwInfo->jChipType == SIS_661)
-#define IS_SIS741 (HwInfo->jChipType == SIS_741)
-#define IS_SIS660 (HwInfo->jChipType == SIS_660)
-#define IS_SIS760 (HwInfo->jChipType == SIS_760)
-#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760)
-#define IS_SIS650740 ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330))
+#define IS_SIS661 (SiS_Pr->ChipType == SIS_661)
+#define IS_SIS741 (SiS_Pr->ChipType == SIS_741)
+#define IS_SIS660 (SiS_Pr->ChipType == SIS_660)
+#define IS_SIS760 (SiS_Pr->ChipType == SIS_760)
+#define IS_SIS761 (SiS_Pr->ChipType == SIS_761)
+#define IS_SIS661741660760 (IS_SIS661 || IS_SIS741 || IS_SIS660 || IS_SIS760 || IS_SIS761)
+#define IS_SIS650740 ((SiS_Pr->ChipType >= SIS_650) && (SiS_Pr->ChipType < SIS_330))
#define IS_SIS550650740 (IS_SIS550 || IS_SIS650740)
#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
@@ -73,24 +74,37 @@
#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
/* SiS_VBType */
-#define VB_SIS301 0x0001
-#define VB_SIS301B 0x0002
-#define VB_SIS302B 0x0004
-#define VB_SIS301LV 0x0008
-#define VB_SIS302LV 0x0010
+#define VB_SIS301 0x0001
+#define VB_SIS301B 0x0002
+#define VB_SIS302B 0x0004
+#define VB_SIS301LV 0x0008
+#define VB_SIS302LV 0x0010
#define VB_SIS302ELV 0x0020
-#define VB_SIS301C 0x0040
+#define VB_SIS301C 0x0040
+#define VB_SIS307T 0x0080
+#define VB_SIS307LV 0x0100
#define VB_UMC 0x4000
#define VB_NoLCD 0x8000
-#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
-#define VB_SIS301B302B (VB_SIS301B|VB_SIS301C|VB_SIS302B)
-#define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
-#define VB_SISVB (VB_SIS301 | VB_SIS301BLV302BLV)
-#define VB_SISTMDS (VB_SIS301 | VB_SIS301B302B)
-#define VB_SISLVDS VB_SIS301LV302LV
-#define VB_SISLCDA (VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
-#define VB_SISYPBPR (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
-#define VB_SISHIVISION (VB_SIS301|VB_SIS301B|VB_SIS302B)
+#define VB_SIS30xB (VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SIS30xC (VB_SIS301C | VB_SIS307T)
+#define VB_SISTMDS (VB_SIS301 | VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_SIS307T)
+#define VB_SISLVDS (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SIS30xBLV (VB_SIS30xB | VB_SISLVDS)
+#define VB_SIS30xCLV (VB_SIS30xC | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISVB (VB_SIS301 | VB_SIS30xBLV)
+#define VB_SISLCDA (VB_SIS302B | VB_SIS301C | VB_SIS307T | VB_SISLVDS)
+#define VB_SISTMDSLCDA (VB_SIS301C | VB_SIS307T)
+#define VB_SISPART4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISHIVISION (VB_SIS301 | VB_SIS301B | VB_SIS302B)
+#define VB_SISYPBPR (VB_SIS301C | VB_SIS307T | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISTAP4SCALER (VB_SIS301C | VB_SIS307T | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPART4OVERFLOW (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPWD (VB_SIS301C | VB_SIS307T | VB_SISLVDS)
+#define VB_SISEMI (VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISPOWER (VB_SIS301C | VB_SIS307T | VB_SIS302LV | VB_SIS302ELV | VB_SIS307LV)
+#define VB_SISDUALLINK (VB_SIS302LV | VB_SIS302ELV | VB_SIS307T | VB_SIS307LV)
+#define VB_SISVGA2 VB_SISTMDS
+#define VB_SISRAMDAC202 (VB_SIS301C | VB_SIS307T)
/* VBInfo */
#define SetSimuScanMode 0x0001 /* CR 30 */
@@ -160,6 +174,7 @@
#define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */
#define InterlaceMode 0x0080
#define SyncPP 0x0000
+#define HaveWideTiming 0x2000 /* Have specific wide- and non-wide timing */
#define SyncPN 0x4000
#define SyncNP 0x8000
#define SyncNN 0xc000
@@ -188,6 +203,7 @@
#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
+#define TVSet525p1024 0x1000 /* TW */
#define TVAspect43 0x2000
#define TVAspect169 0x4000
#define TVAspect43LB 0x8000
@@ -208,7 +224,8 @@
#define SF_IsM661 0x0020
#define SF_IsM741 0x0040
#define SF_IsM760 0x0080
-#define SF_760LFB 0x8000 /* 760: We have LFB */
+#define SF_760UMA 0x4000 /* 76x: We have UMA */
+#define SF_760LFB 0x8000 /* 76x: We have LFB */
/* CR32 (Newer 630, and 315 series)
@@ -228,25 +245,19 @@
#define TVOverScanShift 4
/* CR35 (661 series only)
-
[0] 1 = PAL, 0 = NTSC
[1] 1 = NTSC-J (if D0 = 0)
[2] 1 = PALM (if D0 = 1)
[3] 1 = PALN (if D0 = 1)
[4] 1 = Overscan (Chrontel only)
[7:5] (only if D2 in CR38 is set)
- 000 525i
- 001 525p
+ 000 525i
+ 001 525p
010 750p
011 1080i (or HiVision on 301, 301B)
-
- These bits are being translated to TVMode flag.
-
*/
-/*
- CR37
-
+/* CR37
[0] Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
[3:1] External chip
300 series:
@@ -260,7 +271,7 @@
010 LVDS
011 LVDS + Chrontel 7019
660 series [2:1] only:
- reserved (now in CR38)
+ reserved (chip type now in CR38)
All other combinations reserved
[3] 661 only: Pass 1:1 data
[4] LVDS: 0: Panel Link expands / 1: Panel Link does not expand
@@ -320,6 +331,7 @@
#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
/* CR39 (661 and later)
+ D[7] LVDS (SiS or third party)
D[1:0] YPbPr Aspect Ratio
00 4:3 letterbox
01 4:3
@@ -341,7 +353,7 @@
0101 Set Contrast event
0110 Set Mute event
0111 Set Volume Up/Down event
- [4] Enable Backlight Control by BIOS/driver
+ [4] Enable Backlight Control by BIOS/driver
(set by driver; set means that the BIOS should
not touch the backlight registers because eg.
the driver already switched off the backlight)
@@ -350,6 +362,26 @@
[7] TV UnderScan/OverScan (set by BIOS)
*/
+/* CR7C - 661 and later
+ [7] DualEdge enabled (or: to be enabled)
+ [6] CRT2 = TV/LCD/VGA enabled (or: to be enabled)
+ [5] Init done (set at end of SiS_Init)
+ {4] LVDS LCD capabilities
+ [3] LVDS LCD capabilities
+ [2] LVDS LCD capabilities (PWD)
+ [1] LVDS LCD capabilities (PWD)
+ [0] LVDS=1, TMDS=0 (SiS or third party)
+*/
+
+/* CR7E - 661 and later
+ VBType:
+ [7] LVDS (third party)
+ [3] 301C
+ [2] 302LV
+ [1] 301LV
+ [0] 301B
+*/
+
/* LCDResInfo */
#define Panel300_800x600 0x01 /* CR36 */
#define Panel300_1024x768 0x02
@@ -359,7 +391,6 @@
#define Panel300_1024x600 0x06
#define Panel300_1152x768 0x07
#define Panel300_1280x768 0x0a
-#define Panel300_320x480 0x0e /* fstn - This is fake, can be any */
#define Panel300_Custom 0x0f
#define Panel300_Barco1366 0x10
@@ -374,9 +405,9 @@
#define Panel310_1400x1050 0x09
#define Panel310_1280x768 0x0a
#define Panel310_1600x1200 0x0b
-#define Panel310_640x480_2 0x0c
-#define Panel310_640x480_3 0x0d
-#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */
+#define Panel310_320x240_2 0x0c /* xSTN */
+#define Panel310_320x240_3 0x0d /* xSTN */
+#define Panel310_320x240_1 0x0e /* xSTN - This is fake, can be any */
#define Panel310_Custom 0x0f
#define Panel661_800x600 0x01
@@ -386,7 +417,7 @@
#define Panel661_1024x600 0x05
#define Panel661_1152x864 0x06
#define Panel661_1280x960 0x07
-#define Panel661_1152x768 0x08
+#define Panel661_1280x854 0x08
#define Panel661_1400x1050 0x09
#define Panel661_1280x768 0x0a
#define Panel661_1600x1200 0x0b
@@ -410,14 +441,16 @@
#define Panel_1680x1050 0x0d /* 661etc */
#define Panel_1280x720 0x0e /* 661etc */
#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection) */
-#define Panel_320x480 0x10 /* SiS 550 fstn - TW: This is fake, can be any */
+#define Panel_320x240_1 0x10 /* SiS 550 xSTN */
#define Panel_Barco1366 0x11
#define Panel_848x480 0x12
-#define Panel_640x480_2 0x13 /* SiS 550 */
-#define Panel_640x480_3 0x14 /* SiS 550 */
+#define Panel_320x240_2 0x13 /* SiS 550 xSTN */
+#define Panel_320x240_3 0x14 /* SiS 550 xSTN */
#define Panel_1280x768_2 0x15 /* 30xLV */
#define Panel_1280x768_3 0x16 /* (unused) */
#define Panel_1280x800_2 0x17 /* 30xLV */
+#define Panel_856x480 0x18
+#define Panel_1280x854 0x19 /* 661etc */
/* Index in ModeResInfo table */
#define SIS_RI_320x200 0
@@ -454,6 +487,7 @@
#define SIS_RI_1920x1080 31
#define SIS_RI_960x540 32
#define SIS_RI_960x600 33
+#define SIS_RI_1280x854 34
/* CR5F */
#define IsM650 0x80
@@ -482,16 +516,18 @@
#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
#define VCLK_CUSTOM_300 0x47
-#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */
-#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */
-#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */
-#define VCLK162_315 0x5e /* Index in (VB)VCLKData table (315) */
-#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */
-#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */
+
+#define VCLK65_315 0x0b /* Indices in (VB)VCLKData table (315) */
+#define VCLK108_2_315 0x19
+#define VCLK81_315 0x5b
+#define VCLK162_315 0x5e
+#define VCLK108_3_315 0x45
+#define VCLK100_315 0x46
#define VCLK34_315 0x55
#define VCLK68_315 0x0d
-#define VCLK_1280x800_315_2 0x5c /* Index in VBVCLKData table (315) */
-#define VCLK121_315 0x5d /* Index in VBVCLKData table (315) */
+#define VCLK_1280x800_315_2 0x5c
+#define VCLK121_315 0x5d
+#define VCLK130_315 0x72
#define VCLK_1280x720 0x5f
#define VCLK_1280x768_2 0x60
#define VCLK_1280x768_3 0x61 /* (unused?) */
@@ -507,6 +543,7 @@
#define VCLK_1152x864 0x64
#define VCLK_1360x768 0x58
#define VCLK_1280x800_315 0x6c
+#define VCLK_1280x854 0x76
#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
#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 00000000000..cc856d90903
--- /dev/null
+++ b/drivers/video/sis/initextlfb.c
@@ -0,0 +1,238 @@
+/*
+ * SiS 300/540/630[S]/730[S]
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX]
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
+ *
+ * Linux kernel specific extensions to init.c/init301.c
+ *
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ */
+
+#include "osdef.h"
+#include "initdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
+ unsigned char modeno, unsigned char rateindex);
+int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ unsigned char rateindex, struct fb_var_screeninfo *var);
+#endif
+BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ int *htotal, int *vtotal, unsigned char rateindex);
+
+extern BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
+extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+ unsigned short *ModeIdIndex);
+extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
+ int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+int
+sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ unsigned char rateindex)
+{
+ unsigned short ModeNo = modeno;
+ unsigned short ModeIdIndex = 0, ClockIndex = 0;
+ unsigned short RRTI = 0;
+ int Clock;
+
+ if(!SiSInitPtr(SiS_Pr)) return 65000;
+
+ if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+ switch(ModeNo) {
+ case 0x5a: ModeNo = 0x50; break;
+ case 0x5b: ModeNo = 0x56;
+ }
+#endif
+
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
+ printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+ return 65000;
+ }
+
+ RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+ if(SiS_Pr->SiS_UseWide == 1) {
+ /* Wide screen: Ignore rateindex */
+ ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_WIDE;
+ } else {
+ RRTI += rateindex;
+ ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_NORM;
+ }
+ } else {
+ RRTI += rateindex;
+ ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK;
+ }
+
+ Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
+
+ return Clock;
+}
+
+int
+sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ unsigned char rateindex, struct fb_var_screeninfo *var)
+{
+ unsigned short ModeNo = modeno;
+ unsigned short ModeIdIndex = 0, index = 0, RRTI = 0;
+ int j;
+
+ if(!SiSInitPtr(SiS_Pr)) return 0;
+
+ if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+ switch(ModeNo) {
+ case 0x5a: ModeNo = 0x50; break;
+ case 0x5b: ModeNo = 0x56;
+ }
+#endif
+
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
+
+ RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+ if(SiS_Pr->SiS_UseWide == 1) {
+ /* Wide screen: Ignore rateindex */
+ index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
+ } else {
+ RRTI += rateindex;
+ index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
+ }
+ } else {
+ RRTI += rateindex;
+ index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
+ }
+
+ SiS_Generic_ConvertCRData(SiS_Pr,
+ (unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
+ SiS_Pr->SiS_RefIndex[RRTI].XRes,
+ SiS_Pr->SiS_RefIndex[RRTI].YRes,
+ var, FALSE);
+
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
+ var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ else
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x4000)
+ var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ else
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+
+ var->vmode = FB_VMODE_NONINTERLACED;
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x0080)
+ var->vmode = FB_VMODE_INTERLACED;
+ else {
+ j = 0;
+ while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+ if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
+ SiS_Pr->SiS_RefIndex[RRTI].ModeID) {
+ if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
+ var->vmode = FB_VMODE_DOUBLE;
+ }
+ break;
+ }
+ j++;
+ }
+ }
+
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+#if 0 /* Do this? */
+ var->upper_margin <<= 1;
+ var->lower_margin <<= 1;
+ var->vsync_len <<= 1;
+#endif
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ var->upper_margin >>= 1;
+ var->lower_margin >>= 1;
+ var->vsync_len >>= 1;
+ }
+
+ return 1;
+}
+#endif /* Linux >= 2.5 */
+
+BOOLEAN
+sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
+ int *vtotal, unsigned char rateindex)
+{
+ unsigned short ModeNo = modeno;
+ unsigned short ModeIdIndex = 0, CRT1Index = 0;
+ unsigned short RRTI = 0;
+ unsigned char sr_data, cr_data, cr_data2;
+
+ if(!SiSInitPtr(SiS_Pr)) return FALSE;
+
+ if(rateindex > 0) rateindex--;
+
+#ifdef SIS315H
+ switch(ModeNo) {
+ case 0x5a: ModeNo = 0x50; break;
+ case 0x5b: ModeNo = 0x56;
+ }
+#endif
+
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+
+ RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
+ if(SiS_Pr->SiS_UseWide == 1) {
+ /* Wide screen: Ignore rateindex */
+ CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
+ } else {
+ RRTI += rateindex;
+ CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
+ }
+ } else {
+ RRTI += rateindex;
+ CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
+ }
+
+ sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+ cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+ *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
+
+ sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+ cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+ cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+ *vtotal = ((cr_data & 0xFF) |
+ ((unsigned short)(cr_data2 & 0x01) << 8) |
+ ((unsigned short)(cr_data2 & 0x20) << 4) |
+ ((unsigned short)(sr_data & 0x01) << 10)) + 2;
+
+ if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
+ *vtotal *= 2;
+
+ return TRUE;
+}
+
+
+
diff --git a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
index b1358b750f5..b73f2684014 100644
--- a/drivers/video/sis/oem300.h
+++ b/drivers/video/sis/oem300.h
@@ -3,7 +3,7 @@
/*
* OEM Data for 300 series
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,7 +50,7 @@
*
*/
-static const UCHAR SiS300_OEMTVDelay301[8][4] =
+static const unsigned char SiS300_OEMTVDelay301[8][4] =
{
{0x08,0x08,0x08,0x08},
{0x08,0x08,0x08,0x08},
@@ -62,7 +62,7 @@ static const UCHAR SiS300_OEMTVDelay301[8][4] =
{0x20,0x20,0x20,0x20}
};
-static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+static const unsigned char SiS300_OEMTVDelayLVDS[8][4] =
{
{0x20,0x20,0x20,0x20},
{0x20,0x20,0x20,0x20},
@@ -74,7 +74,7 @@ static const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
{0x20,0x20,0x20,0x20}
};
-static const UCHAR SiS300_OEMTVFlicker[8][4] =
+static const unsigned char SiS300_OEMTVFlicker[8][4] =
{
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
@@ -86,25 +86,7 @@ static const UCHAR SiS300_OEMTVFlicker[8][4] =
{0x00,0x00,0x00,0x00}
};
-#if 0 /* TW: Not used */
-static const UCHAR SiS300_OEMLCDDelay1[12][4]={
- {0x2c,0x2c,0x2c,0x2c},
- {0x20,0x20,0x20,0x20},
- {0x20,0x20,0x20,0x20},
- {0x2c,0x2c,0x2c,0x2c},
- {0x2c,0x2c,0x2c,0x2c},
- {0x20,0x20,0x20,0x20},
- {0x20,0x20,0x20,0x20},
- {0x24,0x24,0x24,0x24},
- {0x24,0x24,0x24,0x24},
- {0x20,0x20,0x20,0x20},
- {0x20,0x20,0x20,0x20},
- {0x24,0x24,0x24,0x24}
-};
-#endif
-
-/* From 630/301B BIOS */
-static const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
+static const unsigned char SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302LV */
{
{0x20,0x20,0x20,0x20},
{0x20,0x20,0x20,0x20},
@@ -172,8 +154,7 @@ static const UCHAR SiS300_OEMLCDDelay2[64][4] = /* for 301/301b/302b/301LV/302
{0x20,0x20,0x20,0x20}
};
-/* From 300/301LV BIOS */
-static const UCHAR SiS300_OEMLCDDelay4[12][4] =
+static const unsigned char SiS300_OEMLCDDelay4[12][4] =
{
{0x2c,0x2c,0x2c,0x2c},
{0x20,0x20,0x20,0x20},
@@ -189,8 +170,7 @@ static const UCHAR SiS300_OEMLCDDelay4[12][4] =
{0x24,0x24,0x24,0x24}
};
-/* From 300/301LV BIOS */
-static const UCHAR SiS300_OEMLCDDelay5[32][4] =
+static const unsigned char SiS300_OEMLCDDelay5[32][4] =
{
{0x20,0x20,0x20,0x20},
{0x20,0x20,0x20,0x20},
@@ -226,8 +206,8 @@ static const UCHAR SiS300_OEMLCDDelay5[32][4] =
{0x20,0x20,0x20,0x20},
};
-/* Added for LVDS */
-static const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */
+static const unsigned char SiS300_OEMLCDDelay3[64][4] = /* For LVDS */
+{
{0x20,0x20,0x20,0x20},
{0x20,0x20,0x20,0x20},
{0x20,0x20,0x20,0x20},
@@ -294,7 +274,7 @@ static const UCHAR SiS300_OEMLCDDelay3[64][4] = { /* For LVDS */
{0x20,0x20,0x20,0x20}
};
-static const UCHAR SiS300_Phase1[8][5][4] =
+static const unsigned char SiS300_Phase1[8][5][4] =
{
{
{0x21,0xed,0x00,0x08},
@@ -354,11 +334,10 @@ static const UCHAR SiS300_Phase1[8][5][4] =
}
};
-
-static const UCHAR SiS300_Phase2[8][5][4] =
+static const unsigned char SiS300_Phase2[8][5][4] =
{
{
- {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x00,0x08},
{0x21,0xed,0x8a,0x08},
{0x21,0xed,0x8a,0x08},
{0x21,0xed,0x8a,0x08},
@@ -372,42 +351,42 @@ static const UCHAR SiS300_Phase2[8][5][4] =
{0x2a,0x05,0xd3,0x00}
},
{
- {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
},
{
- {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
},
{
- {0x21,0xed,0x00,0x08},
+ {0x21,0xed,0x00,0x08},
{0x21,0xed,0x8a,0x08},
{0x21,0xed,0x8a,0x08},
{0x21,0xed,0x8a,0x08},
{0x21,0xed,0x8a,0x08}
},
{
- {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
},
{
- {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
},
{
- {0x2a,0x05,0xd3,0x00},
+ {0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00},
@@ -415,7 +394,7 @@ static const UCHAR SiS300_Phase2[8][5][4] =
}
};
-static const UCHAR SiS300_Filter1[10][16][4] =
+static const unsigned char SiS300_Filter1[10][16][4] =
{
{
{0x00,0xf4,0x10,0x38},
@@ -599,7 +578,7 @@ static const UCHAR SiS300_Filter1[10][16][4] =
},
};
-static const UCHAR SiS300_Filter2[10][9][7] =
+static const unsigned char SiS300_Filter2[10][9][7] =
{
{
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -714,142 +693,144 @@ static const UCHAR SiS300_Filter2[10][9][7] =
};
/* Custom data for Barco iQ Pro R300 */
-static const UCHAR barco_p1[2][9][7][3] = {
- {
- { { 0x16, 0xcf, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x19, 0x00 }
- },
- {
- { 0x16, 0xcf, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x1e, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x16, 0x00 }
- },
- {
- { 0x16, 0xcf, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x19, 0x00 },
- { 0, 0, 0 }
- },
- {
- { 0, 0, 0 }
- },
- {
- { 0x16, 0xcf, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x1e, 0x00 },
- { 0, 0, 0 }
- },
- {
- { 0x16, 0xd1, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x11, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x26, 0x00 }
- },
- {
- { 0x16, 0xd1, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x30, 0x00 },
- { 0, 0, 0 }
- },
- {
- { 0x16, 0x00, 0x00 },
- { 0x17, 0xa0, 0x00 },
- { 0x1a, 0xa0, 0x00 },
- { 0x1b, 0x2a, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0, 0, 0 }
- },
- {
- { 0x16, 0x00, 0x00 },
- { 0x17, 0xaa, 0x00 },
- { 0x1a, 0xa0, 0x00 },
- { 0x1b, 0x2a, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0, 0, 0 }
- }
- },
- {
- {
- { 0x16, 0xcf, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x19, 0x00 }
- },
- {
- { 0, 0, 0 }
- },
- {
- { 0x16, 0xcf, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x19, 0x00 },
- },
- {
- { 0, 0, 0 }
- },
- {
- { 0x16, 0xcf, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe7, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x1e, 0x00 }
- },
- {
- { 0x16, 0xd1, 0x00 },
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe6, 0x00 },
- { 0x1b, 0x11, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x26, 0x00 }
- },
- {
- { 0x18, 0x00, 0x00 },
- { 0x1a, 0xe0, 0x00 },
- { 0x1b, 0x26, 0x00 },
- { 0x1c, 0xff, 0x00 },
- { 0x1d, 0x1c, 0x00 },
- { 0x1e, 0x30, 0x00 },
- { 0, 0, 0 }
- },
- {
- { 0, 0, 0 }
- },
- {
- { 0, 0, 0 }
- }
- }
+static const unsigned char barco_p1[2][9][7][3] =
+{
+ {
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x19, 0x00 }
+ },
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x1e, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x16, 0x00 }
+ },
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x19, 0x00 },
+ { 0, 0, 0 }
+ },
+ {
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x1e, 0x00 },
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0xd1, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x11, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x26, 0x00 }
+ },
+ {
+ { 0x16, 0xd1, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x30, 0x00 },
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0x00, 0x00 },
+ { 0x17, 0xa0, 0x00 },
+ { 0x1a, 0xa0, 0x00 },
+ { 0x1b, 0x2a, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0x00, 0x00 },
+ { 0x17, 0xaa, 0x00 },
+ { 0x1a, 0xa0, 0x00 },
+ { 0x1b, 0x2a, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0, 0, 0 }
+ }
+ },
+ {
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x19, 0x00 }
+ },
+ {
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x19, 0x00 },
+ },
+ {
+ { 0, 0, 0 }
+ },
+ {
+ { 0x16, 0xcf, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe7, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x1e, 0x00 }
+ },
+ {
+ { 0x16, 0xd1, 0x00 },
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe6, 0x00 },
+ { 0x1b, 0x11, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x26, 0x00 }
+ },
+ {
+ { 0x18, 0x00, 0x00 },
+ { 0x1a, 0xe0, 0x00 },
+ { 0x1b, 0x26, 0x00 },
+ { 0x1c, 0xff, 0x00 },
+ { 0x1d, 0x1c, 0x00 },
+ { 0x1e, 0x30, 0x00 },
+ { 0, 0, 0 }
+ },
+ {
+ { 0, 0, 0 }
+ },
+ {
+ { 0, 0, 0 }
+ }
+ }
};
diff --git a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
index 2b7db916b7e..8fce56e4482 100644
--- a/drivers/video/sis/oem310.h
+++ b/drivers/video/sis/oem310.h
@@ -1,9 +1,9 @@
/* $XFree86$ */
/* $XdotOrg$ */
/*
- * OEM Data for 315/330 series
+ * OEM Data for 315/330/340 series
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,206 +50,206 @@
*
*/
-static const UCHAR SiS310_LCDDelayCompensation_301[] = /* 301 */
+static const unsigned char SiS310_LCDDelayCompensation_301[] = /* 301 */
{
- 0x00,0x00,0x00, /* 800x600 */
- 0x0b,0x0b,0x0b, /* 1024x768 */
- 0x08,0x08,0x08, /* 1280x1024 */
- 0x00,0x00,0x00, /* 640x480 (unknown) */
- 0x00,0x00,0x00, /* 1024x600 (unknown) */
- 0x00,0x00,0x00, /* 1152x864 (unknown) */
- 0x08,0x08,0x08, /* 1280x960 (guessed) */
- 0x00,0x00,0x00, /* 1152x768 (unknown) */
- 0x08,0x08,0x08, /* 1400x1050 */
- 0x08,0x08,0x08, /* 1280x768 (guessed) */
- 0x00,0x00,0x00, /* 1600x1200 */
- 0x00,0x00,0x00, /* 320x480 (unknown) */
- 0x00,0x00,0x00,
- 0x00,0x00,0x00,
- 0x00,0x00,0x00
+ 0x00,0x00,0x00, /* 800x600 */
+ 0x0b,0x0b,0x0b, /* 1024x768 */
+ 0x08,0x08,0x08, /* 1280x1024 */
+ 0x00,0x00,0x00, /* 640x480 (unknown) */
+ 0x00,0x00,0x00, /* 1024x600 (unknown) */
+ 0x00,0x00,0x00, /* 1152x864 (unknown) */
+ 0x08,0x08,0x08, /* 1280x960 (guessed) */
+ 0x00,0x00,0x00, /* 1152x768 (unknown) */
+ 0x08,0x08,0x08, /* 1400x1050 */
+ 0x08,0x08,0x08, /* 1280x768 (guessed) */
+ 0x00,0x00,0x00, /* 1600x1200 */
+ 0x00,0x00,0x00, /* 320x480 (unknown) */
+ 0x00,0x00,0x00,
+ 0x00,0x00,0x00,
+ 0x00,0x00,0x00
};
/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
-static const UCHAR SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */
+static const unsigned char SiS310_LCDDelayCompensation_650301LV[] = /* 650 + 30xLV */
{
- 0x01,0x01,0x01, /* 800x600 */
- 0x01,0x01,0x01, /* 1024x768 */
- 0x01,0x01,0x01, /* 1280x1024 */
- 0x01,0x01,0x01, /* 640x480 (unknown) */
- 0x01,0x01,0x01, /* 1024x600 (unknown) */
- 0x01,0x01,0x01, /* 1152x864 (unknown) */
- 0x01,0x01,0x01, /* 1280x960 (guessed) */
- 0x01,0x01,0x01, /* 1152x768 (unknown) */
- 0x01,0x01,0x01, /* 1400x1050 */
- 0x01,0x01,0x01, /* 1280x768 (guessed) */
- 0x01,0x01,0x01, /* 1600x1200 */
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02
+ 0x01,0x01,0x01, /* 800x600 */
+ 0x01,0x01,0x01, /* 1024x768 */
+ 0x01,0x01,0x01, /* 1280x1024 */
+ 0x01,0x01,0x01, /* 640x480 (unknown) */
+ 0x01,0x01,0x01, /* 1024x600 (unknown) */
+ 0x01,0x01,0x01, /* 1152x864 (unknown) */
+ 0x01,0x01,0x01, /* 1280x960 (guessed) */
+ 0x01,0x01,0x01, /* 1152x768 (unknown) */
+ 0x01,0x01,0x01, /* 1400x1050 */
+ 0x01,0x01,0x01, /* 1280x768 (guessed) */
+ 0x01,0x01,0x01, /* 1600x1200 */
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02
};
-static const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
+static const unsigned char SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
{
- 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
- 0x33,0x33,0x33, /* 1024x768 */
- 0x33,0x33,0x33, /* 1280x1024 */
- 0x33,0x33,0x33, /* 640x480 (unknown) */
- 0x33,0x33,0x33, /* 1024x600 (unknown) */
- 0x33,0x33,0x33, /* 1152x864 (unknown) */
- 0x33,0x33,0x33, /* 1280x960 (guessed) */
- 0x33,0x33,0x33, /* 1152x768 (unknown) */
- 0x33,0x33,0x33, /* 1400x1050 */
- 0x33,0x33,0x33, /* 1280x768 (guessed) */
- 0x33,0x33,0x33, /* 1600x1200 */
- 0x33,0x33,0x33,
- 0x33,0x33,0x33,
- 0x33,0x33,0x33,
- 0x33,0x33,0x33
+ 0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
+ 0x33,0x33,0x33, /* 1024x768 */
+ 0x33,0x33,0x33, /* 1280x1024 */
+ 0x33,0x33,0x33, /* 640x480 (unknown) */
+ 0x33,0x33,0x33, /* 1024x600 (unknown) */
+ 0x33,0x33,0x33, /* 1152x864 (unknown) */
+ 0x33,0x33,0x33, /* 1280x960 (guessed) */
+ 0x33,0x33,0x33, /* 1152x768 (unknown) */
+ 0x33,0x33,0x33, /* 1400x1050 */
+ 0x33,0x33,0x33, /* 1280x768 (guessed) */
+ 0x33,0x33,0x33, /* 1600x1200 */
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33
};
-static const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
+static const unsigned char SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
{
- 0x33,0x33,0x33, /* 800x600 (guessed) */
- 0x33,0x33,0x33, /* 1024x768 */
- 0x33,0x33,0x33, /* 1280x1024 */
- 0x33,0x33,0x33, /* 640x480 (unknown) */
- 0x33,0x33,0x33, /* 1024x600 (unknown) */
- 0x33,0x33,0x33, /* 1152x864 (unknown) */
- 0x33,0x33,0x33, /* 1280x960 (guessed) */
- 0x33,0x33,0x33, /* 1152x768 (unknown) */
- 0x33,0x33,0x33, /* 1400x1050 */
- 0x33,0x33,0x33, /* 1280x768 (guessed) */
- 0x33,0x33,0x33, /* 1600x1200 */
- 0x33,0x33,0x33,
- 0x33,0x33,0x33,
- 0x33,0x33,0x33,
- 0x33,0x33,0x33
+ 0x33,0x33,0x33, /* 800x600 (guessed) */
+ 0x33,0x33,0x33, /* 1024x768 */
+ 0x33,0x33,0x33, /* 1280x1024 */
+ 0x33,0x33,0x33, /* 640x480 (unknown) */
+ 0x33,0x33,0x33, /* 1024x600 (unknown) */
+ 0x33,0x33,0x33, /* 1152x864 (unknown) */
+ 0x33,0x33,0x33, /* 1280x960 (guessed) */
+ 0x33,0x33,0x33, /* 1152x768 (unknown) */
+ 0x33,0x33,0x33, /* 1400x1050 */
+ 0x33,0x33,0x33, /* 1280x768 (guessed) */
+ 0x33,0x33,0x33, /* 1600x1200 */
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33,
+ 0x33,0x33,0x33
};
-static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
+static const unsigned char SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
{
- 0x01,0x01,0x01, /* 800x600 */
- 0x0C,0x0C,0x0C, /* 1024x768 */
- 0x0C,0x0C,0x0C, /* 1280x1024 */
- 0x08,0x08,0x08, /* 640x480 */
- 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
- 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
- 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
- 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
- 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
- 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
- 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02
+ 0x01,0x01,0x01, /* 800x600 */
+ 0x0C,0x0C,0x0C, /* 1024x768 */
+ 0x0C,0x0C,0x0C, /* 1280x1024 */
+ 0x08,0x08,0x08, /* 640x480 */
+ 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02
};
-static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
+static const unsigned char SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
{
- 0x01,0x01,0x01, /* 800x600 */
- 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
- 0x0C,0x0C,0x0C, /* 1280x1024 */
- 0x08,0x08,0x08, /* 640x480 */
- 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
- 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
- 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
- 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
- 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
- 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
- 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02,
- 0x02,0x02,0x02
+ 0x01,0x01,0x01, /* 800x600 */
+ 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
+ 0x0C,0x0C,0x0C, /* 1280x1024 */
+ 0x08,0x08,0x08, /* 640x480 */
+ 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02
};
-static const UCHAR SiS310_TVDelayCompensation_301[] = /* 301 */
+static const unsigned char SiS310_TVDelayCompensation_301[] = /* 301 */
{
- 0x02,0x02, /* NTSC Enhanced, Standard */
- 0x02,0x02, /* PAL */
- 0x08,0x0b /* HiVision */
+ 0x02,0x02, /* NTSC Enhanced, Standard */
+ 0x02,0x02, /* PAL */
+ 0x08,0x0b /* HiVision */
};
-static const UCHAR SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */
+static const unsigned char SiS310_TVDelayCompensation_301B[] = /* 30xB, 30xLV */
{
- 0x03,0x03,
- 0x03,0x03,
- 0x03,0x03
+ 0x03,0x03,
+ 0x03,0x03,
+ 0x03,0x03
};
-static const UCHAR SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */
+static const unsigned char SiS310_TVDelayCompensation_740301B[] = /* 740 + 30xB (30xLV?) */
{
- 0x05,0x05,
- 0x05,0x05,
- 0x05,0x05
+ 0x05,0x05,
+ 0x05,0x05,
+ 0x05,0x05
};
-static const UCHAR SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
+static const unsigned char SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
{
- 0x33,0x33,
- 0x33,0x33,
- 0x33,0x33
+ 0x33,0x33,
+ 0x33,0x33,
+ 0x33,0x33
};
-static const UCHAR SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */
+static const unsigned char SiS310_TVDelayCompensation_651302LV[] = /* M650, 651, 302LV */
{
- 0x33,0x33,
- 0x33,0x33,
- 0x33,0x33
+ 0x33,0x33,
+ 0x33,0x33,
+ 0x33,0x33
};
-static const UCHAR SiS_TVDelay661_301[] = /* 661, 301 */
+static const unsigned char SiS_TVDelay661_301[] = /* 661, 301 */
{
- 0x44,0x44,
- 0x44,0x44,
- 0x00,0x00,
- 0x44,0x44,
- 0x44,0x44,
- 0x44,0x44
+ 0x44,0x44,
+ 0x44,0x44,
+ 0x00,0x00,
+ 0x44,0x44,
+ 0x44,0x44,
+ 0x44,0x44
};
-static const UCHAR SiS_TVDelay661_301B[] = /* 661, 301B et al */
+static const unsigned char SiS_TVDelay661_301B[] = /* 661, 301B et al */
{
- 0x44,0x44,
- 0x44,0x44,
- 0x00,0x00,
- 0x44,0x44,
- 0x44,0x44,
- 0x44,0x44
+ 0x44,0x44,
+ 0x44,0x44,
+ 0x00,0x00,
+ 0x44,0x44,
+ 0x44,0x44,
+ 0x44,0x44
};
-static const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
+static const unsigned char SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
{
- 0x0a,0x0a,
- 0x0a,0x0a,
- 0x0a,0x0a
+ 0x0a,0x0a,
+ 0x0a,0x0a,
+ 0x0a,0x0a
};
-static const UCHAR SiS310_TVAntiFlick1[6][2] =
+static const unsigned char SiS310_TVAntiFlick1[6][2] =
{
- {0x4,0x0},
- {0x4,0x8},
- {0x0,0x0},
- {0x0,0x0},
- {0x0,0x0},
- {0x0,0x0}
+ {0x4,0x0},
+ {0x4,0x8},
+ {0x0,0x0},
+ {0x0,0x0},
+ {0x0,0x0},
+ {0x0,0x0}
};
-static const UCHAR SiS310_TVEdge1[6][2] =
+static const unsigned char SiS310_TVEdge1[6][2] =
{
- {0x0,0x4},
- {0x0,0x4},
- {0x0,0x0},
- {0x0,0x0},
- {0x0,0x0},
- {0x0,0x0}
+ {0x0,0x4},
+ {0x0,0x4},
+ {0x0,0x0},
+ {0x0,0x0},
+ {0x0,0x0},
+ {0x0,0x0}
};
-static const UCHAR SiS310_TVYFilter1[5][8][4] =
+static const unsigned char SiS310_TVYFilter1[5][8][4] =
{
- {
+ {
{0x00,0xf4,0x10,0x38}, /* NTSC */
{0x00,0xf4,0x10,0x38},
{0xeb,0x04,0x25,0x18},
@@ -258,8 +258,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
{0xeb,0x04,0x25,0x18},
{0xee,0x0c,0x22,0x08},
{0xeb,0x15,0x25,0xf6}
- },
- {
+ },
+ {
{0x00,0xf4,0x10,0x38}, /* PAL */
{0x00,0xf4,0x10,0x38},
{0xf1,0xf7,0x1f,0x32},
@@ -268,8 +268,8 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
{0xf1,0xf7,0x1f,0x32},
{0xf3,0x00,0x1d,0x20},
{0xfc,0xfb,0x14,0x2a}
- },
- {
+ },
+ {
{0x00,0x00,0x00,0x00}, /* HiVision */
{0x00,0xf4,0x10,0x38},
{0x00,0xf4,0x10,0x38},
@@ -278,9 +278,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
{0x00,0xf4,0x10,0x38},
{0xeb,0x04,0x25,0x18},
{0xee,0x0c,0x22,0x08}
- },
- {
- {0x00,0xf4,0x10,0x38}, /* PAL-M */
+ },
+ {
+ {0x00,0xf4,0x10,0x38}, /* PAL-M */
{0x00,0xf4,0x10,0x38},
{0xeb,0x04,0x10,0x18},
{0xf7,0x06,0x19,0x14},
@@ -288,9 +288,9 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
{0xeb,0x04,0x25,0x18},
{0xeb,0x04,0x25,0x18},
{0xeb,0x15,0x25,0xf6}
- },
- {
- {0x00,0xf4,0x10,0x38}, /* PAL-N */
+ },
+ {
+ {0x00,0xf4,0x10,0x38}, /* PAL-N */
{0x00,0xf4,0x10,0x38},
{0xeb,0x04,0x10,0x18},
{0xf7,0x06,0x19,0x14},
@@ -298,12 +298,12 @@ static const UCHAR SiS310_TVYFilter1[5][8][4] =
{0xeb,0x04,0x25,0x18},
{0xeb,0x04,0x25,0x18},
{0xeb,0x15,0x25,0xf6}
- }
+ }
};
-static const UCHAR SiS310_TVYFilter2[5][9][7] =
+static const unsigned char SiS310_TVYFilter2[5][9][7] =
{
- {
+ {
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* NTSC */
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -313,8 +313,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
+ },
+ {
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL */
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -324,8 +324,8 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
+ },
+ {
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}, /* HiVision */
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
@@ -335,9 +335,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22},
{0x00,0x00,0x00,0xF4,0xFF,0x1C,0x22}
- },
- {
- {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */
+ },
+ {
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-M */
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -346,9 +346,9 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- },
- {
- {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */
+ },
+ {
+ {0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46}, /* PAL-N */
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -357,58 +357,39 @@ static const UCHAR SiS310_TVYFilter2[5][9][7] =
{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
{0x01,0x01,0xFC,0xF8,0x08,0x26,0x38},
{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
- }
+ }
};
-static const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
+static const unsigned char SiS310_TVPhaseIncr1[3][2][4] =
{
- {
+ {
{0x21,0xed,0xba,0x08},
{0x21,0xed,0xba,0x08}
- },
- {
+ },
+ {
{0x2a,0x05,0xe3,0x00},
{0x2a,0x05,0xe3,0x00}
- },
- {
+ },
+ {
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
- }
+ }
};
-static const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
+static const unsigned char SiS310_TVPhaseIncr2[3][2][4] =
{
- {
+ {
{0x21,0xf0,0x7b,0xd6},
{0x21,0xf0,0x7b,0xd6}
- },
- {
+ },
+ {
{0x2a,0x0a,0x41,0xe9},
{0x2a,0x0a,0x41,0xe9}
- },
- {
+ },
+ {
{0x2a,0x05,0xd3,0x00},
{0x2a,0x05,0xd3,0x00}
- }
-};
-
-static const UCHAR SiS661_TVPhase[] = {
- 0x21,0xED,0xBA,0x08,
- 0x2A,0x05,0xE3,0x00,
- 0x21,0xE4,0x2E,0x9B,
- 0x21,0xF4,0x3E,0xBA,
- 0x1E,0x8B,0xA2,0xA7,
- 0x1E,0x83,0x0A,0xE0,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x21,0xF0,0x7B,0xD6,
- 0x2A,0x09,0x86,0xE9,
- 0x21,0xE6,0xEF,0xA4,
- 0x21,0xF6,0x94,0x46,
- 0x1E,0x8B,0xA2,0xA7,
- 0x1E,0x83,0x0A,0xE0,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00
+ }
};
/**************************************************************/
@@ -417,7 +398,7 @@ static const UCHAR SiS661_TVPhase[] = {
/* Inventec / Compaq Presario 3045US, 3017 */
-static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] =
+static const struct SiS_LCDData SiS310_ExtCompaq1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
@@ -431,17 +412,17 @@ static const SiS_LCDDataStruct SiS310_ExtCompaq1280x1024Data[] =
/* Asus A2xxxH _2 */
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
+static const struct SiS_Part2PortTbl SiS310_CRT2Part2_Asus1024x768_3[] =
{
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x13,0x16,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
};
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index 15939b05771..841ca3190cd 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -3,7 +3,7 @@
/*
* OS depending defines
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -55,8 +55,11 @@
#define _SIS_OSDEF_H_
/* The choices are: */
-#define LINUX_KERNEL /* Linux kernel framebuffer */
-/* #define LINUX_XF86 */ /* XFree86/X.org */
+#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
+#undef SIS_XORG_XF86 /* XFree86/X.org */
+
+#undef SIS_LINUX_KERNEL_24
+#undef SIS_LINUX_KERNEL_26
#ifdef OutPortByte
#undef OutPortByte
@@ -86,8 +89,9 @@
/* LINUX KERNEL */
/**********************************************************************/
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
#include <linux/config.h>
+#include <linux/version.h>
#ifdef CONFIG_FB_SIS_300
#define SIS300
@@ -97,6 +101,12 @@
#define SIS315H
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define SIS_LINUX_KERNEL_26
+#else
+#define SIS_LINUX_KERNEL_24
+#endif
+
#if !defined(SIS300) && !defined(SIS315H)
#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
#warning sisfb will not work!
@@ -109,13 +119,15 @@
#define InPortWord(p) inw((SISIOADDRESS)(p))
#define InPortLong(p) inl((SISIOADDRESS)(p))
#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
-#endif
+
+#endif /* LINUX_KERNEL */
/**********************************************************************/
/* XFree86/X.org */
/**********************************************************************/
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
+
#define SIS300
#define SIS315H
@@ -126,6 +138,7 @@
#define InPortWord(p) inSISREGW((IOADDRESS)(p))
#define InPortLong(p) inSISREGL((IOADDRESS)(p))
#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#endif
+
+#endif /* XF86 */
#endif /* _OSDEF_H_ */
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index d0103c162e4..0b6e625d733 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -1,8 +1,10 @@
/*
- * SiS 300/630/730/540/315/550/[M]650/651/[M]661[FM]X/740/[M]741[GX]/330/[M]760[GX]
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]65x/[M]661[F|M]X/740/[M]741[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
* frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
*
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*/
-#ifndef _SIS_H
-#define _SIS_H
+#ifndef _SIS_H_
+#define _SIS_H_
#include <linux/config.h>
#include <linux/version.h>
@@ -35,26 +37,37 @@
#include "vgatypes.h"
#include "vstruct.h"
-#define VER_MAJOR 1
-#define VER_MINOR 7
-#define VER_LEVEL 17
-
-#undef SIS_CONFIG_COMPAT
+#define VER_MAJOR 1
+#define VER_MINOR 8
+#define VER_LEVEL 9
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/spinlock.h>
+#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b)
+#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
+#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
+#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
#ifdef CONFIG_COMPAT
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
#include <linux/ioctl32.h>
-#define SIS_CONFIG_COMPAT
-#endif
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
-#ifdef __x86_64__
-/* Shouldn't we check for CONFIG_IA32_EMULATION here? */
+#define SIS_OLD_CONFIG_COMPAT
+#else
+#include <linux/smp_lock.h>
+#define SIS_NEW_CONFIG_COMPAT
+#endif
+#endif /* CONFIG_COMPAT */
+#else /* 2.4 */
+#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
+#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
+#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
+#define SIS_PCI_PUT_DEVICE(a)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
+#ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
#include <asm/ioctl32.h>
-#define SIS_CONFIG_COMPAT
+#define SIS_OLD_CONFIG_COMPAT
#endif
#endif
-
+#endif /* 2.4 */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#define SIS_IOTYPE1 void __iomem
#define SIS_IOTYPE2 __iomem
@@ -79,228 +92,312 @@
/* To be included in pci_ids.h */
#ifndef PCI_DEVICE_ID_SI_650_VGA
-#define PCI_DEVICE_ID_SI_650_VGA 0x6325
+#define PCI_DEVICE_ID_SI_650_VGA 0x6325
#endif
#ifndef PCI_DEVICE_ID_SI_650
-#define PCI_DEVICE_ID_SI_650 0x0650
+#define PCI_DEVICE_ID_SI_650 0x0650
#endif
#ifndef PCI_DEVICE_ID_SI_651
-#define PCI_DEVICE_ID_SI_651 0x0651
+#define PCI_DEVICE_ID_SI_651 0x0651
#endif
#ifndef PCI_DEVICE_ID_SI_740
-#define PCI_DEVICE_ID_SI_740 0x0740
+#define PCI_DEVICE_ID_SI_740 0x0740
#endif
#ifndef PCI_DEVICE_ID_SI_330
-#define PCI_DEVICE_ID_SI_330 0x0330
+#define PCI_DEVICE_ID_SI_330 0x0330
#endif
#ifndef PCI_DEVICE_ID_SI_660_VGA
-#define PCI_DEVICE_ID_SI_660_VGA 0x6330
+#define PCI_DEVICE_ID_SI_660_VGA 0x6330
#endif
#ifndef PCI_DEVICE_ID_SI_661
-#define PCI_DEVICE_ID_SI_661 0x0661
+#define PCI_DEVICE_ID_SI_661 0x0661
#endif
#ifndef PCI_DEVICE_ID_SI_741
-#define PCI_DEVICE_ID_SI_741 0x0741
+#define PCI_DEVICE_ID_SI_741 0x0741
#endif
#ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660 0x0660
+#define PCI_DEVICE_ID_SI_660 0x0660
#endif
#ifndef PCI_DEVICE_ID_SI_760
-#define PCI_DEVICE_ID_SI_760 0x0760
+#define PCI_DEVICE_ID_SI_760 0x0760
+#endif
+#ifndef PCI_DEVICE_ID_SI_761
+#define PCI_DEVICE_ID_SI_761 0x0761
+#endif
+
+#ifndef PCI_VENDOR_ID_XGI
+#define PCI_VENDOR_ID_XGI 0x18ca
+#endif
+
+#ifndef PCI_DEVICE_ID_XGI_20
+#define PCI_DEVICE_ID_XGI_20 0x0020
+#endif
+
+#ifndef PCI_DEVICE_ID_XGI_40
+#define PCI_DEVICE_ID_XGI_40 0x0040
#endif
/* To be included in fb.h */
#ifndef FB_ACCEL_SIS_GLAMOUR_2
-#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
+#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
#endif
#ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 760 */
+#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 76x */
+#endif
+#ifndef FB_ACCEL_XGI_VOLARI_V
+#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari Vx (V3XT, V5, V8) */
+#endif
+#ifndef FB_ACCEL_XGI_VOLARI_Z
+#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
#endif
-
-#define MAX_ROM_SCAN 0x10000
/* ivideo->caps */
-#define HW_CURSOR_CAP 0x80
-#define TURBO_QUEUE_CAP 0x40
-#define AGP_CMD_QUEUE_CAP 0x20
-#define VM_CMD_QUEUE_CAP 0x10
-#define MMIO_CMD_QUEUE_CAP 0x08
+#define HW_CURSOR_CAP 0x80
+#define TURBO_QUEUE_CAP 0x40
+#define AGP_CMD_QUEUE_CAP 0x20
+#define VM_CMD_QUEUE_CAP 0x10
+#define MMIO_CMD_QUEUE_CAP 0x08
/* For 300 series */
-#define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */
-#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
+#define TURBO_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
+#define HW_CURSOR_AREA_SIZE_300 4096 /* 4K */
/* For 315/Xabre series */
-#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
-#define COMMAND_QUEUE_THRESHOLD 0x1F
-#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
-
-#define SIS_OH_ALLOC_SIZE 4000
-#define SENTINEL 0x7fffffff
-
-#define SEQ_ADR 0x14
-#define SEQ_DATA 0x15
-#define DAC_ADR 0x18
-#define DAC_DATA 0x19
-#define CRTC_ADR 0x24
-#define CRTC_DATA 0x25
-#define DAC2_ADR (0x16-0x30)
-#define DAC2_DATA (0x17-0x30)
-#define VB_PART1_ADR (0x04-0x30)
-#define VB_PART1_DATA (0x05-0x30)
-#define VB_PART2_ADR (0x10-0x30)
-#define VB_PART2_DATA (0x11-0x30)
-#define VB_PART3_ADR (0x12-0x30)
-#define VB_PART3_DATA (0x13-0x30)
-#define VB_PART4_ADR (0x14-0x30)
-#define VB_PART4_DATA (0x15-0x30)
-
-#define SISSR ivideo->SiS_Pr.SiS_P3c4
-#define SISCR ivideo->SiS_Pr.SiS_P3d4
-#define SISDACA ivideo->SiS_Pr.SiS_P3c8
-#define SISDACD ivideo->SiS_Pr.SiS_P3c9
-#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
-#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
-#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
-#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
-#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
-#define SISDAC2A SISPART5
-#define SISDAC2D (SISPART5 + 1)
-#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
-#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
-#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
-#define SISPEL ivideo->SiS_Pr.SiS_P3c6
-
-#define IND_SIS_PASSWORD 0x05 /* SRs */
-#define IND_SIS_COLOR_MODE 0x06
-#define IND_SIS_RAMDAC_CONTROL 0x07
-#define IND_SIS_DRAM_SIZE 0x14
-#define IND_SIS_MODULE_ENABLE 0x1E
-#define IND_SIS_PCI_ADDRESS_SET 0x20
-#define IND_SIS_TURBOQUEUE_ADR 0x26
-#define IND_SIS_TURBOQUEUE_SET 0x27
-#define IND_SIS_POWER_ON_TRAP 0x38
-#define IND_SIS_POWER_ON_TRAP2 0x39
-#define IND_SIS_CMDQUEUE_SET 0x26
-#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
-
-#define IND_SIS_AGP_IO_PAD 0x48
-
-#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
-#define SIS_CRT2_WENABLE_315 0x2F
-
-#define SIS_PASSWORD 0x86 /* SR05 */
-
-#define SIS_INTERLACED_MODE 0x20 /* SR06 */
-#define SIS_8BPP_COLOR_MODE 0x0
-#define SIS_15BPP_COLOR_MODE 0x1
-#define SIS_16BPP_COLOR_MODE 0x2
-#define SIS_32BPP_COLOR_MODE 0x4
-
-#define SIS_ENABLE_2D 0x40 /* SR1E */
-
-#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
-#define SIS_PCI_ADDR_ENABLE 0x80
-
-#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330 series SR26 */
-#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
-#define SIS_MMIO_CMD_ENABLE 0x20
-#define SIS_CMD_QUEUE_SIZE_512k 0x00
-#define SIS_CMD_QUEUE_SIZE_1M 0x04
-#define SIS_CMD_QUEUE_SIZE_2M 0x08
-#define SIS_CMD_QUEUE_SIZE_4M 0x0C
-#define SIS_CMD_QUEUE_RESET 0x01
-#define SIS_CMD_AUTO_CORR 0x02
-
-#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
-#define SIS_MODE_SELECT_CRT2 0x02
-#define SIS_VB_OUTPUT_COMPOSITE 0x04
-#define SIS_VB_OUTPUT_SVIDEO 0x08
-#define SIS_VB_OUTPUT_SCART 0x10
-#define SIS_VB_OUTPUT_LCD 0x20
-#define SIS_VB_OUTPUT_CRT2 0x40
-#define SIS_VB_OUTPUT_HIVISION 0x80
-
-#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
-#define SIS_DRIVER_MODE 0x40
-
-#define SIS_VB_COMPOSITE 0x01 /* CR32 */
-#define SIS_VB_SVIDEO 0x02
-#define SIS_VB_SCART 0x04
-#define SIS_VB_LCD 0x08
-#define SIS_VB_CRT2 0x10
-#define SIS_CRT1 0x20
-#define SIS_VB_HIVISION 0x40
-#define SIS_VB_YPBPR 0x80
-#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
- SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
-
-#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
-#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS 0x02
-#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
-#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
-#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
-#define SIS310_EXTERNAL_CHIP_LVDS 0x02
-#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
-
-#define SIS_AGP_2X 0x20 /* CR48 */
-
-#define HW_DEVICE_EXTENSION SIS_HW_INFO
-#define PHW_DEVICE_EXTENSION PSIS_HW_INFO
+#define COMMAND_QUEUE_AREA_SIZE (512 * 1024) /* 512K */
+#define COMMAND_QUEUE_AREA_SIZE_Z7 (128 * 1024) /* 128k for XGI Z7 */
+#define HW_CURSOR_AREA_SIZE_315 16384 /* 16K */
+#define COMMAND_QUEUE_THRESHOLD 0x1F
+
+#define SIS_OH_ALLOC_SIZE 4000
+#define SENTINEL 0x7fffffff
+
+#define SEQ_ADR 0x14
+#define SEQ_DATA 0x15
+#define DAC_ADR 0x18
+#define DAC_DATA 0x19
+#define CRTC_ADR 0x24
+#define CRTC_DATA 0x25
+#define DAC2_ADR (0x16-0x30)
+#define DAC2_DATA (0x17-0x30)
+#define VB_PART1_ADR (0x04-0x30)
+#define VB_PART1_DATA (0x05-0x30)
+#define VB_PART2_ADR (0x10-0x30)
+#define VB_PART2_DATA (0x11-0x30)
+#define VB_PART3_ADR (0x12-0x30)
+#define VB_PART3_DATA (0x13-0x30)
+#define VB_PART4_ADR (0x14-0x30)
+#define VB_PART4_DATA (0x15-0x30)
+
+#define SISSR ivideo->SiS_Pr.SiS_P3c4
+#define SISCR ivideo->SiS_Pr.SiS_P3d4
+#define SISDACA ivideo->SiS_Pr.SiS_P3c8
+#define SISDACD ivideo->SiS_Pr.SiS_P3c9
+#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
+#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
+#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
+#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
+#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
+#define SISDAC2A SISPART5
+#define SISDAC2D (SISPART5 + 1)
+#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
+#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
+#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
+#define SISPEL ivideo->SiS_Pr.SiS_P3c6
+#define SISVGAENABLE (ivideo->SiS_Pr.RelIO + 0x13)
+#define SISVID (ivideo->SiS_Pr.RelIO + 0x02 - 0x30)
+#define SISCAP (ivideo->SiS_Pr.RelIO + 0x00 - 0x30)
+
+#define IND_SIS_PASSWORD 0x05 /* SRs */
+#define IND_SIS_COLOR_MODE 0x06
+#define IND_SIS_RAMDAC_CONTROL 0x07
+#define IND_SIS_DRAM_SIZE 0x14
+#define IND_SIS_MODULE_ENABLE 0x1E
+#define IND_SIS_PCI_ADDRESS_SET 0x20
+#define IND_SIS_TURBOQUEUE_ADR 0x26
+#define IND_SIS_TURBOQUEUE_SET 0x27
+#define IND_SIS_POWER_ON_TRAP 0x38
+#define IND_SIS_POWER_ON_TRAP2 0x39
+#define IND_SIS_CMDQUEUE_SET 0x26
+#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
+
+#define IND_SIS_AGP_IO_PAD 0x48
+
+#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
+#define SIS_CRT2_WENABLE_315 0x2F
+
+#define SIS_PASSWORD 0x86 /* SR05 */
+
+#define SIS_INTERLACED_MODE 0x20 /* SR06 */
+#define SIS_8BPP_COLOR_MODE 0x0
+#define SIS_15BPP_COLOR_MODE 0x1
+#define SIS_16BPP_COLOR_MODE 0x2
+#define SIS_32BPP_COLOR_MODE 0x4
+
+#define SIS_ENABLE_2D 0x40 /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
+#define SIS_PCI_ADDR_ENABLE 0x80
+
+#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */
+#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
+#define SIS_MMIO_CMD_ENABLE 0x20
+#define SIS_CMD_QUEUE_SIZE_512k 0x00
+#define SIS_CMD_QUEUE_SIZE_1M 0x04
+#define SIS_CMD_QUEUE_SIZE_2M 0x08
+#define SIS_CMD_QUEUE_SIZE_4M 0x0C
+#define SIS_CMD_QUEUE_RESET 0x01
+#define SIS_CMD_AUTO_CORR 0x02
+
+#define SIS_CMD_QUEUE_SIZE_Z7_64k 0x00 /* XGI Z7 */
+#define SIS_CMD_QUEUE_SIZE_Z7_128k 0x04
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
+#define SIS_MODE_SELECT_CRT2 0x02
+#define SIS_VB_OUTPUT_COMPOSITE 0x04
+#define SIS_VB_OUTPUT_SVIDEO 0x08
+#define SIS_VB_OUTPUT_SCART 0x10
+#define SIS_VB_OUTPUT_LCD 0x20
+#define SIS_VB_OUTPUT_CRT2 0x40
+#define SIS_VB_OUTPUT_HIVISION 0x80
+
+#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
+#define SIS_DRIVER_MODE 0x40
+
+#define SIS_VB_COMPOSITE 0x01 /* CR32 */
+#define SIS_VB_SVIDEO 0x02
+#define SIS_VB_SCART 0x04
+#define SIS_VB_LCD 0x08
+#define SIS_VB_CRT2 0x10
+#define SIS_CRT1 0x20
+#define SIS_VB_HIVISION 0x40
+#define SIS_VB_YPBPR 0x80
+#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+ SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
+
+#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
+#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS 0x02
+#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
+#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
+#define SIS310_EXTERNAL_CHIP_LVDS 0x02
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
+
+#define SIS_AGP_2X 0x20 /* CR48 */
+
+/* vbflags, private entries (others in sisfb.h) */
+#define VB_CONEXANT 0x00000800 /* 661 series only */
+#define VB_TRUMPION VB_CONEXANT /* 300 series only */
+#define VB_302ELV 0x00004000
+#define VB_301 0x00100000 /* Video bridge type */
+#define VB_301B 0x00200000
+#define VB_302B 0x00400000
+#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
+#define VB_LVDS 0x01000000
+#define VB_CHRONTEL 0x02000000
+#define VB_301LV 0x04000000
+#define VB_302LV 0x08000000
+#define VB_301C 0x10000000
+
+#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
+#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
+
+/* vbflags2 (static stuff only!) */
+#define VB2_SISUMC 0x00000001
+#define VB2_301 0x00000002 /* Video bridge type */
+#define VB2_301B 0x00000004
+#define VB2_301C 0x00000008
+#define VB2_307T 0x00000010
+#define VB2_302B 0x00000800
+#define VB2_301LV 0x00001000
+#define VB2_302LV 0x00002000
+#define VB2_302ELV 0x00004000
+#define VB2_307LV 0x00008000
+#define VB2_30xBDH 0x08000000 /* 30xB DH version (w/o LCD support) */
+#define VB2_CONEXANT 0x10000000
+#define VB2_TRUMPION 0x20000000
+#define VB2_LVDS 0x40000000
+#define VB2_CHRONTEL 0x80000000
+
+#define VB2_SISLVDSBRIDGE (VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_SISTMDSBRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+#define VB2_SISBRIDGE (VB2_SISLVDSBRIDGE | VB2_SISTMDSBRIDGE)
+
+#define VB2_SISTMDSLCDABRIDGE (VB2_301C | VB2_307T)
+#define VB2_SISLCDABRIDGE (VB2_SISTMDSLCDABRIDGE | VB2_301LV | VB2_302LV | VB2_302ELV | VB2_307LV)
+
+#define VB2_SISHIVISIONBRIDGE (VB2_301 | VB2_301B | VB2_302B)
+#define VB2_SISYPBPRBRIDGE (VB2_301C | VB2_307T | VB2_SISLVDSBRIDGE)
+#define VB2_SISYPBPRARBRIDGE (VB2_301C | VB2_307T | VB2_307LV)
+#define VB2_SISTAP4SCALER (VB2_301C | VB2_307T | VB2_302ELV | VB2_307LV)
+#define VB2_SISTVBRIDGE (VB2_SISHIVISIONBRIDGE | VB2_SISYPBPRBRIDGE)
+
+#define VB2_SISVGA2BRIDGE (VB2_301 | VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+
+#define VB2_VIDEOBRIDGE (VB2_SISBRIDGE | VB2_LVDS | VB2_CHRONTEL | VB2_CONEXANT)
+
+#define VB2_30xB (VB2_301B | VB2_301C | VB2_302B | VB2_307T)
+#define VB2_30xBLV (VB2_30xB | VB2_SISLVDSBRIDGE)
+#define VB2_30xC (VB2_301C | VB2_307T)
+#define VB2_30xCLV (VB2_301C | VB2_307T | VB2_302ELV| VB2_307LV)
+#define VB2_SISEMIBRIDGE (VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCD162MHZBRIDGE (VB2_301C | VB2_307T)
+#define VB2_LCDOVER1280BRIDGE (VB2_301C | VB2_307T | VB2_302LV | VB2_302ELV | VB2_307LV)
+#define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV)
+#define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T)
/* I/O port access macros */
-#define inSISREG(base) inb(base)
+#define inSISREG(base) inb(base)
-#define outSISREG(base,val) outb(val,base)
+#define outSISREG(base,val) outb(val,base)
#define orSISREG(base,val) \
- do { \
- u8 __Temp = inSISREG(base); \
- outSISREG(base, __Temp | (val)); \
- } while (0)
+ do { \
+ u8 __Temp = inSISREG(base); \
+ outSISREG(base, __Temp | (val));\
+ } while (0)
#define andSISREG(base,val) \
- do { \
- u8 __Temp = inSISREG(base); \
- outSISREG(base, __Temp & (val)); \
- } while (0)
-
-#define inSISIDXREG(base,idx,var) \
- do { \
- outSISREG(base, idx); \
- var = inSISREG((base)+1); \
- } while (0)
-
-#define outSISIDXREG(base,idx,val) \
- do { \
- outSISREG(base, idx); \
- outSISREG((base)+1, val); \
- } while (0)
-
-#define orSISIDXREG(base,idx,val) \
- do { \
- u8 __Temp; \
- outSISREG(base, idx); \
- __Temp = inSISREG((base)+1) | (val); \
- outSISREG((base)+1, __Temp); \
- } while (0)
-
-#define andSISIDXREG(base,idx,and) \
- do { \
- u8 __Temp; \
- outSISREG(base, idx); \
- __Temp = inSISREG((base)+1) & (and); \
- outSISREG((base)+1, __Temp); \
- } while (0)
-
-#define setSISIDXREG(base,idx,and,or) \
- do { \
- u8 __Temp; \
- outSISREG(base, idx); \
- __Temp = (inSISREG((base)+1) & (and)) | (or); \
- outSISREG((base)+1, __Temp); \
- } while (0)
+ do { \
+ u8 __Temp = inSISREG(base); \
+ outSISREG(base, __Temp & (val));\
+ } while (0)
+
+#define inSISIDXREG(base,idx,var) \
+ do { \
+ outSISREG(base, idx); \
+ var = inSISREG((base)+1); \
+ } while (0)
+
+#define outSISIDXREG(base,idx,val) \
+ do { \
+ outSISREG(base, idx); \
+ outSISREG((base)+1, val); \
+ } while (0)
+
+#define orSISIDXREG(base,idx,val) \
+ do { \
+ u8 __Temp; \
+ outSISREG(base, idx); \
+ __Temp = inSISREG((base)+1) | (val); \
+ outSISREG((base)+1, __Temp); \
+ } while (0)
+
+#define andSISIDXREG(base,idx,and) \
+ do { \
+ u8 __Temp; \
+ outSISREG(base, idx); \
+ __Temp = inSISREG((base)+1) & (and); \
+ outSISREG((base)+1, __Temp); \
+ } while (0)
+
+#define setSISIDXREG(base,idx,and,or) \
+ do { \
+ u8 __Temp; \
+ outSISREG(base, idx); \
+ __Temp = (inSISREG((base)+1) & (and)) | (or); \
+ outSISREG((base)+1, __Temp); \
+ } while (0)
/* MMIO access macros */
#define MMIO_IN8(base, offset) readb((base+offset))
@@ -322,19 +419,19 @@
#define MMIO_QUEUE_READPORT Q_READ_PTR
#ifndef FB_BLANK_UNBLANK
-#define FB_BLANK_UNBLANK 0
+#define FB_BLANK_UNBLANK 0
#endif
#ifndef FB_BLANK_NORMAL
-#define FB_BLANK_NORMAL 1
+#define FB_BLANK_NORMAL 1
#endif
#ifndef FB_BLANK_VSYNC_SUSPEND
-#define FB_BLANK_VSYNC_SUSPEND 2
+#define FB_BLANK_VSYNC_SUSPEND 2
#endif
#ifndef FB_BLANK_HSYNC_SUSPEND
-#define FB_BLANK_HSYNC_SUSPEND 3
+#define FB_BLANK_HSYNC_SUSPEND 3
#endif
#ifndef FB_BLANK_POWERDOWN
-#define FB_BLANK_POWERDOWN 4
+#define FB_BLANK_POWERDOWN 4
#endif
enum _SIS_LCD_TYPE {
@@ -347,18 +444,19 @@ enum _SIS_LCD_TYPE {
LCD_1600x1200,
LCD_1920x1440,
LCD_2048x1536,
- LCD_320x480, /* FSTN */
+ LCD_320x240, /* FSTN */
LCD_1400x1050,
LCD_1152x864,
LCD_1152x768,
LCD_1280x768,
LCD_1024x600,
- LCD_640x480_2, /* DSTN */
- LCD_640x480_3, /* DSTN */
+ LCD_320x240_2, /* DSTN */
+ LCD_320x240_3, /* DSTN */
LCD_848x480,
LCD_1280x800,
LCD_1680x1050,
LCD_1280x720,
+ LCD_1280x854,
LCD_CUSTOM,
LCD_UNKNOWN
};
@@ -368,31 +466,50 @@ enum _SIS_CMDTYPE {
AGP_CMD_QUEUE,
VM_CMD_QUEUE,
};
-typedef unsigned int SIS_CMDTYPE;
+
+struct SIS_OH {
+ struct SIS_OH *poh_next;
+ struct SIS_OH *poh_prev;
+ u32 offset;
+ u32 size;
+};
+
+struct SIS_OHALLOC {
+ struct SIS_OHALLOC *poha_next;
+ struct SIS_OH aoh[1];
+};
+
+struct SIS_HEAP {
+ struct SIS_OH oh_free;
+ struct SIS_OH oh_used;
+ struct SIS_OH *poh_freelist;
+ struct SIS_OHALLOC *poha_chain;
+ u32 max_freesize;
+ struct sis_video_info *vinfo;
+};
/* Our "par" */
struct sis_video_info {
int cardnumber;
struct fb_info *memyselfandi;
- SIS_HW_INFO sishw_ext;
- SiS_Private SiS_Pr;
+ struct SiS_Private SiS_Pr;
- sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
+ struct sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
struct fb_var_screeninfo default_var;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
struct fb_fix_screeninfo sisfb_fix;
- u32 pseudo_palette[17];
+ u32 pseudo_palette[17];
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- struct display sis_disp;
+ struct display sis_disp;
struct display_switch sisfb_sw;
struct {
u16 red, green, blue, pad;
- } sis_palette[256];
+ } sis_palette[256];
union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
@@ -400,10 +517,10 @@ struct sis_video_info {
#ifdef FBCON_HAS_CFB32
u32 cfb32[16];
#endif
- } sis_fbcon_cmap;
+ } sis_fbcon_cmap;
#endif
- struct sisfb_monitor {
+ struct sisfb_monitor {
u16 hmin;
u16 hmax;
u16 vmin;
@@ -411,163 +528,166 @@ struct sis_video_info {
u32 dclockmax;
u8 feature;
BOOLEAN datavalid;
- } sisfb_thismonitor;
+ } sisfb_thismonitor;
- int chip_id;
+ unsigned short chip_id; /* PCI ID of chip */
+ unsigned short chip_vendor; /* PCI ID of vendor */
char myid[40];
struct pci_dev *nbridge;
+ struct pci_dev *lpcdev;
int mni; /* Mode number index */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int currcon;
+ int currcon;
#endif
unsigned long video_size;
- unsigned long video_base;
+ unsigned long video_base;
unsigned long mmio_size;
- unsigned long mmio_base;
- unsigned long vga_base;
+ unsigned long mmio_base;
+ unsigned long vga_base;
+
+ unsigned long video_offset;
- SIS_IOTYPE1 *video_vbase;
- SIS_IOTYPE1 *mmio_vbase;
+ unsigned long UMAsize, LFBsize;
- unsigned char *bios_abase;
+ SIS_IOTYPE1 *video_vbase;
+ SIS_IOTYPE1 *mmio_vbase;
- int mtrr;
+ unsigned char *bios_abase;
+
+ int mtrr;
u32 sisfb_mem;
- u32 sisfb_parm_mem;
- int sisfb_accel;
- int sisfb_ypan;
- int sisfb_max;
- int sisfb_userom;
- int sisfb_useoem;
+ u32 sisfb_parm_mem;
+ int sisfb_accel;
+ int sisfb_ypan;
+ int sisfb_max;
+ int sisfb_userom;
+ int sisfb_useoem;
int sisfb_mode_idx;
int sisfb_parm_rate;
int sisfb_crt1off;
int sisfb_forcecrt1;
int sisfb_crt2type;
int sisfb_crt2flags;
- int sisfb_dstn;
- int sisfb_fstn;
+ int sisfb_dstn;
+ int sisfb_fstn;
int sisfb_tvplug;
int sisfb_tvstd;
- int sisfb_filter;
int sisfb_nocrt2rate;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int sisfb_inverse;
#endif
- u32 heapstart; /* offset */
- SIS_IOTYPE1 *sisfb_heap_start; /* address */
- SIS_IOTYPE1 *sisfb_heap_end; /* address */
- u32 sisfb_heap_size;
+ u32 heapstart; /* offset */
+ SIS_IOTYPE1 *sisfb_heap_start; /* address */
+ SIS_IOTYPE1 *sisfb_heap_end; /* address */
+ u32 sisfb_heap_size;
int havenoheap;
-#if 0
- SIS_HEAP sisfb_heap;
-#endif
+ struct SIS_HEAP sisfb_heap; /* This card's vram heap */
- int video_bpp;
- int video_cmap_len;
- int video_width;
- int video_height;
- unsigned int refresh_rate;
+ int video_bpp;
+ int video_cmap_len;
+ int video_width;
+ int video_height;
+ unsigned int refresh_rate;
- unsigned int chip;
- u8 revision_id;
+ unsigned int chip;
+ u8 revision_id;
+ int sisvga_enabled; /* PCI device was enabled */
- int video_linelength; /* real pitch */
+ int video_linelength; /* real pitch */
int scrnpitchCRT1; /* pitch regarding interlace */
- u16 DstColor; /* For 2d acceleration */
- u32 SiS310_AccelDepth;
- u32 CommandReg;
- int cmdqueuelength;
+ u16 DstColor; /* For 2d acceleration */
+ u32 SiS310_AccelDepth;
+ u32 CommandReg;
+ int cmdqueuelength; /* Current (for accel) */
+ u32 cmdQueueSize; /* Total size in KB */
- spinlock_t lockaccel; /* Do not use outside of kernel! */
+ spinlock_t lockaccel; /* Do not use outside of kernel! */
- unsigned int pcibus;
- unsigned int pcislot;
- unsigned int pcifunc;
+ unsigned int pcibus;
+ unsigned int pcislot;
+ unsigned int pcifunc;
- int accel;
+ int accel;
+ int engineok;
- u16 subsysvendor;
- u16 subsysdevice;
+ u16 subsysvendor;
+ u16 subsysdevice;
- u32 vbflags; /* Replacing deprecated stuff from above */
- u32 currentvbflags;
+ u32 vbflags; /* Replacing deprecated stuff from above */
+ u32 currentvbflags;
+ u32 vbflags2;
int lcdxres, lcdyres;
int lcddefmodeidx, tvdefmodeidx, defmodeidx;
- u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */
-
- int current_bpp;
- int current_width;
- int current_height;
- int current_htotal;
- int current_vtotal;
+ u32 CRT2LCDType; /* defined in "SIS_LCD_TYPE" */
+ u32 curFSTN, curDSTN;
+
+ int current_bpp;
+ int current_width;
+ int current_height;
+ int current_htotal;
+ int current_vtotal;
int current_linelength;
- __u32 current_pixclock;
- int current_refresh_rate;
+ __u32 current_pixclock;
+ int current_refresh_rate;
+
+ unsigned int current_base;
- u8 mode_no;
- u8 rate_idx;
- int modechanged;
- unsigned char modeprechange;
+ u8 mode_no;
+ u8 rate_idx;
+ int modechanged;
+ unsigned char modeprechange;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- u8 sisfb_lastrates[128];
+ u8 sisfb_lastrates[128];
#endif
- int newrom;
- int registered;
+ int newrom;
+ int haveXGIROM;
+ int registered;
int warncount;
+#ifdef SIS_OLD_CONFIG_COMPAT
+ int ioctl32registered;
+#endif
- int sisvga_engine;
- int hwcursor_size;
- int CRT2_write_enable;
- u8 caps;
+ int sisvga_engine;
+ int hwcursor_size;
+ int CRT2_write_enable;
+ u8 caps;
- u8 detectedpdc;
- u8 detectedpdca;
- u8 detectedlcda;
+ u8 detectedpdc;
+ u8 detectedpdca;
+ u8 detectedlcda;
- SIS_IOTYPE1 *hwcursor_vbase;
+ SIS_IOTYPE1 *hwcursor_vbase;
- int chronteltype;
- int tvxpos, tvypos;
- u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
+ int chronteltype;
+ int tvxpos, tvypos;
+ u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
int tvx, tvy;
- u8 sisfblocked;
+ u8 sisfblocked;
+
+ struct sisfb_info sisfb_infoblock;
+
+ struct sisfb_cmd sisfb_command;
+
+ u32 sisfb_id;
+
+ u8 sisfb_can_post;
+ u8 sisfb_card_posted;
+ u8 sisfb_was_boot_device;
struct sis_video_info *next;
};
-typedef struct _SIS_OH {
- struct _SIS_OH *poh_next;
- struct _SIS_OH *poh_prev;
- u32 offset;
- u32 size;
-} SIS_OH;
-
-typedef struct _SIS_OHALLOC {
- struct _SIS_OHALLOC *poha_next;
- SIS_OH aoh[1];
-} SIS_OHALLOC;
-
-typedef struct _SIS_HEAP {
- SIS_OH oh_free;
- SIS_OH oh_used;
- SIS_OH *poh_freelist;
- SIS_OHALLOC *poha_chain;
- u32 max_freesize;
- struct sis_video_info *vinfo;
-} SIS_HEAP;
-
#endif
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index 30e90a553e8..bab933e6c6a 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -1,6 +1,8 @@
/*
- * SiS 300/630/730/540/315/550/65x/74x/330/760 frame buffer driver
- * for Linux kernels 2.4.x and 2.6.x
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
*
* 2D acceleration part
*
@@ -19,7 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
* Based on the XFree86/X.org driver which is
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* Author: Thomas Winischhofer <thomas@winischhofer.net>
* (see http://www.winischhofer.net/
@@ -30,13 +32,11 @@
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/errno.h>
#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/console.h>
-#include <linux/selection.h>
+#endif
#include <linux/ioport.h>
-#include <linux/capability.h>
-#include <linux/fs.h>
#include <linux/types.h>
#include <asm/io.h>
@@ -188,7 +188,7 @@ SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
}
#endif
-/* 315/330 series ------------------------------------------------- */
+/* 315/330/340 series ---------------------------------------------- */
#ifdef CONFIG_FB_SIS_315
static void
@@ -202,7 +202,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
{
SiS310SetupDSTColorDepth(ivideo->DstColor);
SiS310SetupSRCPitch(ivideo->video_linelength)
- SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+ SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
if(trans_color != -1) {
SiS310SetupROP(0x0A)
SiS310SetupSRCTrans(trans_color)
@@ -213,7 +213,7 @@ SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int tra
/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
}
SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
- /* The 315 series is smart enough to know the direction */
+ /* The chip is smart enough to know the direction */
}
static void
@@ -223,35 +223,38 @@ SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int
u32 srcbase = 0, dstbase = 0;
int mymin = min(src_y, dst_y);
int mymax = max(src_y, dst_y);
-
+
/* Although the chip knows the direction to use
- * if the source and destination areas overlap,
+ * if the source and destination areas overlap,
* that logic fails if we fiddle with the bitmap
* addresses. Therefore, we check if the source
- * and destination blitting areas overlap and
- * adapt the bitmap addresses synchronously
+ * and destination blitting areas overlap and
+ * adapt the bitmap addresses synchronously
* if the coordinates exceed the valid range.
- * The the areas do not overlap, we do our
+ * The the areas do not overlap, we do our
* normal check.
*/
- if((mymax - mymin) < height) {
- if((src_y >= 2048) || (dst_y >= 2048)) {
- srcbase = ivideo->video_linelength * mymin;
- dstbase = ivideo->video_linelength * mymin;
- src_y -= mymin;
- dst_y -= mymin;
- }
+ if((mymax - mymin) < height) {
+ if((src_y >= 2048) || (dst_y >= 2048)) {
+ srcbase = ivideo->video_linelength * mymin;
+ dstbase = ivideo->video_linelength * mymin;
+ src_y -= mymin;
+ dst_y -= mymin;
+ }
} else {
- if(src_y >= 2048) {
- srcbase = ivideo->video_linelength * src_y;
- src_y = 0;
- }
- if(dst_y >= 2048) {
- dstbase = ivideo->video_linelength * dst_y;
- dst_y = 0;
- }
+ if(src_y >= 2048) {
+ srcbase = ivideo->video_linelength * src_y;
+ src_y = 0;
+ }
+ if(dst_y >= 2048) {
+ dstbase = ivideo->video_linelength * dst_y;
+ dst_y = 0;
+ }
}
+ srcbase += ivideo->video_offset;
+ dstbase += ivideo->video_offset;
+
SiS310SetupSRCBase(srcbase);
SiS310SetupDSTBase(dstbase);
SiS310SetupRect(width, height)
@@ -264,7 +267,7 @@ static void
SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
{
SiS310SetupPATFG(color)
- SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+ SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff)
SiS310SetupDSTColorDepth(ivideo->DstColor);
SiS310SetupROP(sisPatALUConv[rop])
SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
@@ -279,6 +282,7 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
dstbase = ivideo->video_linelength * y;
y = 0;
}
+ dstbase += ivideo->video_offset;
SiS310SetupDSTBase(dstbase)
SiS310SetupDSTXY(x,y)
SiS310SetupRect(w,h)
@@ -294,384 +298,153 @@ SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w
int sisfb_initaccel(struct sis_video_info *ivideo)
{
#ifdef SISFB_USE_SPINLOCKS
- spin_lock_init(&ivideo->lockaccel);
+ spin_lock_init(&ivideo->lockaccel);
#endif
- return(0);
+ return 0;
}
void sisfb_syncaccel(struct sis_video_info *ivideo)
{
- if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
- SiS300Sync(ivideo);
+ SiS300Sync(ivideo);
#endif
- } else {
+ } else {
#ifdef CONFIG_FB_SIS_315
- SiS310Sync(ivideo);
+ SiS310Sync(ivideo);
#endif
- }
+ }
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
int fbcon_sis_sync(struct fb_info *info)
{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- CRITFLAGS
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ CRITFLAGS
- if(!ivideo->accel)
- return 0;
+ if((!ivideo->accel) || (!ivideo->engineok))
+ return 0;
- if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
- SiS300Sync(ivideo);
-#endif
- } else {
-#ifdef CONFIG_FB_SIS_315
- SiS310Sync(ivideo);
-#endif
- }
- CRITEND
- return 0;
+ CRITBEGIN
+ sisfb_syncaccel(ivideo);
+ CRITEND
+
+ return 0;
}
void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- u32 col = 0;
- u32 vxres = info->var.xres_virtual;
- u32 vyres = info->var.yres_virtual;
- int width, height;
- CRITFLAGS
-
- if(info->state != FBINFO_STATE_RUNNING) {
- return;
- }
-
- if(!ivideo->accel) {
- cfb_fillrect(info, rect);
- return;
- }
-
- if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
- return;
- }
-
- /* Clipping */
- width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
- height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
-
- switch(info->var.bits_per_pixel) {
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ u32 col = 0;
+ u32 vxres = info->var.xres_virtual;
+ u32 vyres = info->var.yres_virtual;
+ int width, height;
+ CRITFLAGS
+
+ if(info->state != FBINFO_STATE_RUNNING)
+ return;
+
+ if((!ivideo->accel) || (!ivideo->engineok)) {
+ cfb_fillrect(info, rect);
+ return;
+ }
+
+ if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres)
+ return;
+
+ /* Clipping */
+ width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
+ height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
+
+ switch(info->var.bits_per_pixel) {
case 8: col = rect->color;
break;
case 16:
case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
break;
- }
+ }
- if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
- CRITBEGIN
- SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
- SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
- CRITEND
- SiS300Sync(ivideo);
+ CRITBEGIN
+ SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+ SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
+ CRITEND
#endif
- } else {
+ } else {
#ifdef CONFIG_FB_SIS_315
- CRITBEGIN
- SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
- SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
- CRITEND
- SiS310Sync(ivideo);
+ CRITBEGIN
+ SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+ SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
+ CRITEND
#endif
- }
+ }
+ sisfb_syncaccel(ivideo);
}
void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- u32 vxres = info->var.xres_virtual;
- u32 vyres = info->var.yres_virtual;
- int width = area->width;
- int height = area->height;
- CRITFLAGS
-
- if(info->state != FBINFO_STATE_RUNNING) {
- return;
- }
-
- if(!ivideo->accel) {
- cfb_copyarea(info, area);
- return;
- }
-
- if(!width || !height ||
- area->sx >= vxres || area->sy >= vyres ||
- area->dx >= vxres || area->dy >= vyres) {
- return;
- }
-
- /* Clipping */
- if((area->sx + width) > vxres) width = vxres - area->sx;
- if((area->dx + width) > vxres) width = vxres - area->dx;
- if((area->sy + height) > vyres) height = vyres - area->sy;
- if((area->dy + height) > vyres) height = vyres - area->dy;
-
- if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
- int xdir, ydir;
-
- if(area->sx < area->dx) xdir = 0;
- else xdir = 1;
- if(area->sy < area->dy) ydir = 0;
- else ydir = 1;
-
- CRITBEGIN
- SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
- SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
- width, height);
- CRITEND
- SiS300Sync(ivideo);
-#endif
- } else {
-#ifdef CONFIG_FB_SIS_315
- CRITBEGIN
- SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
- SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
- width, height);
- CRITEND
- SiS310Sync(ivideo);
-#endif
- }
-}
-
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
-
-void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
- int dsty, int dstx, int height, int width)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
-
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ u32 vxres = info->var.xres_virtual;
+ u32 vyres = info->var.yres_virtual;
+ int width = area->width;
+ int height = area->height;
CRITFLAGS
- if(!ivideo->accel) {
- switch(ivideo->video_bpp) {
- case 8:
-#ifdef FBCON_HAS_CFB8
- fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
- break;
- case 16:
-#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
- break;
- case 32:
-#ifdef FBCON_HAS_CFB32
- fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
-#endif
- break;
- }
- return;
- }
-
- srcx *= fontwidth(p);
- srcy *= fontheight(p);
- dstx *= fontwidth(p);
- dsty *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
+ if(info->state != FBINFO_STATE_RUNNING)
+ return;
- if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
- int xdir, ydir;
-
- if(srcx < dstx) xdir = 0;
- else xdir = 1;
- if(srcy < dsty) ydir = 0;
- else ydir = 1;
-
- CRITBEGIN
- SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
- SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
- CRITEND
- SiS300Sync(ivideo);
-#endif
- } else {
-#ifdef CONFIG_FB_SIS_315
- CRITBEGIN
- SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
- SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
- CRITEND
- SiS310Sync(ivideo);
-#endif
+ if((!ivideo->accel) || (!ivideo->engineok)) {
+ cfb_copyarea(info, area);
+ return;
}
-}
-static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
- int srcy, int srcx, int height, int width, int color)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
- CRITFLAGS
+ if(!width || !height ||
+ area->sx >= vxres || area->sy >= vyres ||
+ area->dx >= vxres || area->dy >= vyres)
+ return;
- srcx *= fontwidth(p);
- srcy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
+ /* Clipping */
+ if((area->sx + width) > vxres) width = vxres - area->sx;
+ if((area->dx + width) > vxres) width = vxres - area->dx;
+ if((area->sy + height) > vyres) height = vyres - area->sy;
+ if((area->dy + height) > vyres) height = vyres - area->dy;
if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
- CRITBEGIN
- SiS300SetupForSolidFill(ivideo, color, 3);
- SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
- CRITEND
- SiS300Sync(ivideo);
+ int xdir, ydir;
+
+ if(area->sx < area->dx) xdir = 0;
+ else xdir = 1;
+ if(area->sy < area->dy) ydir = 0;
+ else ydir = 1;
+
+ CRITBEGIN
+ SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+ SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
+ area->dx, area->dy, width, height);
+ CRITEND
#endif
} else {
#ifdef CONFIG_FB_SIS_315
- CRITBEGIN
- SiS310SetupForSolidFill(ivideo, color, 3);
- SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
- CRITEND
- SiS310Sync(ivideo);
-#endif
- }
-}
-
-void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
- int srcy, int srcx, int height, int width)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
- u32 bgx;
-
- if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB8
- fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
+ CRITBEGIN
+ SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+ SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy,
+ area->dx, area->dy, width, height);
+ CRITEND
#endif
- return;
}
- bgx = attr_bgcol_ec(p, conp);
- fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+ sisfb_syncaccel(ivideo);
}
-void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
- int srcy, int srcx, int height, int width)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
- u32 bgx;
-
- if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
#endif
- return;
- }
-
- bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
- fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
- int srcy, int srcx, int height, int width)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
- u32 bgx;
-
- if(!ivideo->accel) {
-#ifdef FBCON_HAS_CFB32
- fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
-#endif
- return;
- }
-
- bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
- fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
-}
-
-void fbcon_sis_revc(struct display *p, int srcx, int srcy)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
- CRITFLAGS
-
- if(!ivideo->accel) {
- switch(ivideo->video_bpp) {
- case 16:
-#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_revc(p, srcx, srcy);
-#endif
- break;
- case 32:
-#ifdef FBCON_HAS_CFB32
- fbcon_cfb32_revc(p, srcx, srcy);
-#endif
- break;
- }
- return;
- }
-
- srcx *= fontwidth(p);
- srcy *= fontheight(p);
-
- if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
- CRITBEGIN
- SiS300SetupForSolidFill(ivideo, 0, 0x0a);
- SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
- CRITEND
- SiS300Sync(ivideo);
-#endif
- } else {
-#ifdef CONFIG_FB_SIS_315
- CRITBEGIN
- SiS310SetupForSolidFill(ivideo, 0, 0x0a);
- SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
- CRITEND
- SiS310Sync(ivideo);
-#endif
- }
-}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
-#ifdef FBCON_HAS_CFB8
-struct display_switch fbcon_sis8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear8,
- .putc = fbcon_cfb8_putc,
- .putcs = fbcon_cfb8_putcs,
- .revc = fbcon_cfb8_revc,
- .clear_margins = fbcon_cfb8_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-struct display_switch fbcon_sis16 = {
- .setup = fbcon_cfb16_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear16,
- .putc = fbcon_cfb16_putc,
- .putcs = fbcon_cfb16_putcs,
- .revc = fbcon_sis_revc,
- .clear_margins = fbcon_cfb16_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-struct display_switch fbcon_sis32 = {
- .setup = fbcon_cfb32_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear32,
- .putc = fbcon_cfb32_putc,
- .putcs = fbcon_cfb32_putcs,
- .revc = fbcon_sis_revc,
- .clear_margins = fbcon_cfb32_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
+#include "sisfb_accel_2_4.h"
#endif /* KERNEL VERSION */
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
index bb28f331d60..046e2c4a8e0 100644
--- a/drivers/video/sis/sis_accel.h
+++ b/drivers/video/sis/sis_accel.h
@@ -1,6 +1,8 @@
/*
- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
- * for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX],
+ * XGI V3XT/V5/V8, Z7
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
*
* 2D acceleration part
*
@@ -283,6 +285,8 @@
{ \
while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
CmdQueLen = 0; \
}
@@ -402,6 +406,7 @@ void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
int srcx, int height, int width);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
+int fbcon_sis_sync(struct fb_info *info);
void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
#endif
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 69826603681..42c54b69726 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1,9 +1,10 @@
/*
- * SiS 300/305/540/630(S)/730(S)
- * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * SiS 300/540/630[S]/730[S],
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
* frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
*
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,11 +20,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
*
* Author of (practically wiped) code base:
* SiS (www.sis.com)
- * Copyright (C) 1999 Silicon Integrated Systems, Inc.
+ * Copyright (C) 1999 Silicon Integrated Systems, Inc.
*
* See http://www.winischhofer.net/ for more information and updates
*
@@ -46,16 +47,15 @@
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/fb.h>
-#include <linux/console.h>
#include <linux/selection.h>
-#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/vt_kern.h>
+#endif
#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/types.h>
@@ -94,71 +94,75 @@ extern struct display_switch fbcon_sis32;
#endif
#endif
+static void sisfb_handle_command(struct sis_video_info *ivideo,
+ struct sisfb_cmd *sisfb_command);
+
/* ------------------ Internal helper routines ----------------- */
static void __init
sisfb_setdefaultparms(void)
{
- sisfb_off = 0;
- sisfb_parm_mem = 0;
- sisfb_accel = -1;
- sisfb_ypan = -1;
- sisfb_max = -1;
- sisfb_userom = -1;
- sisfb_useoem = -1;
+ sisfb_off = 0;
+ sisfb_parm_mem = 0;
+ sisfb_accel = -1;
+ sisfb_ypan = -1;
+ sisfb_max = -1;
+ sisfb_userom = -1;
+ sisfb_useoem = -1;
#ifdef MODULE
/* Module: "None" for 2.4, default mode for 2.5+ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- sisfb_mode_idx = -1;
+ sisfb_mode_idx = -1;
#else
- sisfb_mode_idx = MODE_INDEX_NONE;
+ sisfb_mode_idx = MODE_INDEX_NONE;
#endif
#else
/* Static: Default mode */
- sisfb_mode_idx = -1;
-#endif
- sisfb_parm_rate = -1;
- sisfb_crt1off = 0;
- sisfb_forcecrt1 = -1;
- sisfb_crt2type = -1;
- sisfb_crt2flags = 0;
- sisfb_pdc = 0xff;
- sisfb_pdca = 0xff;
- sisfb_scalelcd = -1;
+ sisfb_mode_idx = -1;
+#endif
+ sisfb_parm_rate = -1;
+ sisfb_crt1off = 0;
+ sisfb_forcecrt1 = -1;
+ sisfb_crt2type = -1;
+ sisfb_crt2flags = 0;
+ sisfb_pdc = 0xff;
+ sisfb_pdca = 0xff;
+ sisfb_scalelcd = -1;
sisfb_specialtiming = CUT_NONE;
- sisfb_lvdshl = -1;
- sisfb_dstn = 0;
- sisfb_fstn = 0;
- sisfb_tvplug = -1;
- sisfb_tvstd = -1;
- sisfb_tvxposoffset = 0;
- sisfb_tvyposoffset = 0;
- sisfb_filter = -1;
- sisfb_nocrt2rate = 0;
+ sisfb_lvdshl = -1;
+ sisfb_dstn = 0;
+ sisfb_fstn = 0;
+ sisfb_tvplug = -1;
+ sisfb_tvstd = -1;
+ sisfb_tvxposoffset = 0;
+ sisfb_tvyposoffset = 0;
+ sisfb_nocrt2rate = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- sisfb_inverse = 0;
- sisfb_fontname[0] = 0;
+ sisfb_inverse = 0;
+ sisfb_fontname[0] = 0;
#endif
#if !defined(__i386__) && !defined(__x86_64__)
- sisfb_resetcard = 0;
- sisfb_videoram = 0;
+ sisfb_resetcard = 0;
+ sisfb_videoram = 0;
#endif
}
+/* ------------- Parameter parsing -------------- */
+
static void __devinit
sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
{
int i = 0, j = 0;
- /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+ /* We don't know the hardware specs yet and there is no ivideo */
if(vesamode == 0) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
sisfb_mode_idx = MODE_INDEX_NONE;
#else
- if(!quiet) {
- printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
- }
+ if(!quiet)
+ printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
+
sisfb_mode_idx = DEFAULT_MODE;
#endif
return;
@@ -169,95 +173,102 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
while(sisbios_mode[i++].mode_no[0] != 0) {
if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
(sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
- if(sisfb_fstn) {
- if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
- sisbios_mode[i-1].mode_no[1] == 0x56 ||
- sisbios_mode[i-1].mode_no[1] == 0x53) continue;
- } else {
- if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
- sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
- }
- sisfb_mode_idx = i - 1;
- j = 1;
- break;
+ if(sisfb_fstn) {
+ if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+ sisbios_mode[i-1].mode_no[1] == 0x56 ||
+ sisbios_mode[i-1].mode_no[1] == 0x53)
+ continue;
+ } else {
+ if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+ sisbios_mode[i-1].mode_no[1] == 0x5b)
+ continue;
+ }
+ sisfb_mode_idx = i - 1;
+ j = 1;
+ break;
}
}
- if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+ if((!j) && !quiet)
+ printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
}
-static void
+static void __devinit
sisfb_search_mode(char *name, BOOLEAN quiet)
{
- int i = 0;
unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+ int i = 0;
char strbuf[16], strbuf1[20];
char *nameptr = name;
- /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+ /* We don't know the hardware specs yet and there is no ivideo */
if(name == NULL) {
- if(!quiet) {
- printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
- }
- sisfb_mode_idx = DEFAULT_MODE;
- return;
+ if(!quiet)
+ printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+
+ sisfb_mode_idx = DEFAULT_MODE;
+ return;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
- if(!quiet) {
- printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
- }
- sisfb_mode_idx = DEFAULT_MODE;
- return;
+ if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
+ if(!quiet)
+ printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+
+ sisfb_mode_idx = DEFAULT_MODE;
+ return;
}
#endif
if(strlen(name) <= 19) {
- strcpy(strbuf1, name);
- for(i=0; i<strlen(strbuf1); i++) {
- if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
- }
+ strcpy(strbuf1, name);
+ for(i = 0; i < strlen(strbuf1); i++) {
+ if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+ }
- /* This does some fuzzy mode naming detection */
- if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
- if((rate <= 32) || (depth > 32)) {
- j = rate; rate = depth; depth = j;
- }
- sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
- nameptr = strbuf;
- sisfb_parm_rate = rate;
- } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
- sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
- nameptr = strbuf;
- } else {
- xres = 0;
- if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
- sprintf(strbuf, "%ux%ux8", xres, yres);
- nameptr = strbuf;
- } else {
- sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
- return;
- }
- }
+ /* This does some fuzzy mode naming detection */
+ if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+ if((rate <= 32) || (depth > 32)) {
+ j = rate; rate = depth; depth = j;
+ }
+ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+ nameptr = strbuf;
+ sisfb_parm_rate = rate;
+ } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+ nameptr = strbuf;
+ } else {
+ xres = 0;
+ if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+ sprintf(strbuf, "%ux%ux8", xres, yres);
+ nameptr = strbuf;
+ } else {
+ sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+ return;
+ }
+ }
}
i = 0; j = 0;
while(sisbios_mode[i].mode_no[0] != 0) {
if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
- if(sisfb_fstn) {
- if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
- sisbios_mode[i-1].mode_no[1] == 0x56 ||
- sisbios_mode[i-1].mode_no[1] == 0x53) continue;
- } else {
- if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
- sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
- }
- sisfb_mode_idx = i - 1;
- j = 1;
- break;
- }
- }
- if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
+ if(sisfb_fstn) {
+ if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+ sisbios_mode[i-1].mode_no[1] == 0x56 ||
+ sisbios_mode[i-1].mode_no[1] == 0x53)
+ continue;
+ } else {
+ if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+ sisbios_mode[i-1].mode_no[1] == 0x5b)
+ continue;
+ }
+ sisfb_mode_idx = i - 1;
+ j = 1;
+ break;
+ }
+ }
+
+ if((!j) && !quiet)
+ printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
}
#ifndef MODULE
@@ -265,7 +276,7 @@ static void __devinit
sisfb_get_vga_mode_from_kernel(void)
{
#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
- char mymode[32];
+ char mymode[32];
int mydepth = screen_info.lfb_depth;
if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
@@ -274,15 +285,17 @@ sisfb_get_vga_mode_from_kernel(void)
(screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
(mydepth >= 8) && (mydepth <= 32) ) {
- if(mydepth == 24) mydepth = 32;
+ if(mydepth == 24) mydepth = 32;
- sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
- screen_info.lfb_height,
+ sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
+ screen_info.lfb_height,
mydepth);
- printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode);
+ printk(KERN_DEBUG
+ "sisfb: Using vga mode %s pre-set by kernel as default\n",
+ mymode);
- sisfb_search_mode(mymode, TRUE);
+ sisfb_search_mode(mymode, TRUE);
}
#endif
return;
@@ -294,26 +307,25 @@ sisfb_search_crt2type(const char *name)
{
int i = 0;
- /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+ /* We don't know the hardware specs yet and there is no ivideo */
if(name == NULL) return;
while(sis_crt2type[i].type_no != -1) {
- if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
- sisfb_crt2type = sis_crt2type[i].type_no;
- sisfb_tvplug = sis_crt2type[i].tvplug_no;
- sisfb_crt2flags = sis_crt2type[i].flags;
- break;
- }
- i++;
+ if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+ sisfb_crt2type = sis_crt2type[i].type_no;
+ sisfb_tvplug = sis_crt2type[i].tvplug_no;
+ sisfb_crt2flags = sis_crt2type[i].flags;
+ break;
+ }
+ i++;
}
sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
- if(sisfb_crt2type < 0) {
+ if(sisfb_crt2type < 0)
printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
- }
}
static void __init
@@ -321,16 +333,17 @@ sisfb_search_tvstd(const char *name)
{
int i = 0;
- /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+ /* We don't know the hardware specs yet and there is no ivideo */
- if(name == NULL) return;
+ if(name == NULL)
+ return;
while(sis_tvtype[i].type_no != -1) {
- if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
- sisfb_tvstd = sis_tvtype[i].type_no;
- break;
- }
- i++;
+ if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
+ sisfb_tvstd = sis_tvtype[i].type_no;
+ break;
+ }
+ i++;
}
}
@@ -340,38 +353,101 @@ sisfb_search_specialtiming(const char *name)
int i = 0;
BOOLEAN found = FALSE;
- /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+ /* We don't know the hardware specs yet and there is no ivideo */
- if(name == NULL) return;
+ if(name == NULL)
+ return;
if(!strnicmp(name, "none", 4)) {
- sisfb_specialtiming = CUT_FORCENONE;
+ sisfb_specialtiming = CUT_FORCENONE;
printk(KERN_DEBUG "sisfb: Special timing disabled\n");
} else {
- while(mycustomttable[i].chipID != 0) {
- if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
- sisfb_specialtiming = mycustomttable[i].SpecialID;
- found = TRUE;
- printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
- mycustomttable[i].vendorName, mycustomttable[i].cardName,
- mycustomttable[i].optionName);
- break;
- }
- i++;
- }
- if(!found) {
- printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
- printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
- i = 0;
- while(mycustomttable[i].chipID != 0) {
- printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
- mycustomttable[i].optionName,
- mycustomttable[i].vendorName,
- mycustomttable[i].cardName);
- i++;
- }
- }
- }
+ while(mycustomttable[i].chipID != 0) {
+ if(!strnicmp(name,mycustomttable[i].optionName,
+ strlen(mycustomttable[i].optionName))) {
+ sisfb_specialtiming = mycustomttable[i].SpecialID;
+ found = TRUE;
+ printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
+ mycustomttable[i].vendorName,
+ mycustomttable[i].cardName,
+ mycustomttable[i].optionName);
+ break;
+ }
+ i++;
+ }
+ if(!found) {
+ printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
+ printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
+ i = 0;
+ while(mycustomttable[i].chipID != 0) {
+ printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
+ mycustomttable[i].optionName,
+ mycustomttable[i].vendorName,
+ mycustomttable[i].cardName);
+ i++;
+ }
+ }
+ }
+}
+
+/* ----------- Various detection routines ----------- */
+
+static void __devinit
+sisfb_detect_custom_timing(struct sis_video_info *ivideo)
+{
+ unsigned char *biosver = NULL;
+ unsigned char *biosdate = NULL;
+ BOOLEAN footprint;
+ u32 chksum = 0;
+ int i, j;
+
+ if(ivideo->SiS_Pr.UseROM) {
+ biosver = ivideo->SiS_Pr.VirtualRomBase + 0x06;
+ biosdate = ivideo->SiS_Pr.VirtualRomBase + 0x2c;
+ for(i = 0; i < 32768; i++)
+ chksum += ivideo->SiS_Pr.VirtualRomBase[i];
+ }
+
+ i = 0;
+ do {
+ if( (mycustomttable[i].chipID == ivideo->chip) &&
+ ((!strlen(mycustomttable[i].biosversion)) ||
+ (ivideo->SiS_Pr.UseROM &&
+ (!strncmp(mycustomttable[i].biosversion, biosver,
+ strlen(mycustomttable[i].biosversion))))) &&
+ ((!strlen(mycustomttable[i].biosdate)) ||
+ (ivideo->SiS_Pr.UseROM &&
+ (!strncmp(mycustomttable[i].biosdate, biosdate,
+ strlen(mycustomttable[i].biosdate))))) &&
+ ((!mycustomttable[i].bioschksum) ||
+ (ivideo->SiS_Pr.UseROM &&
+ (mycustomttable[i].bioschksum == chksum))) &&
+ (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
+ (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
+ footprint = TRUE;
+ for(j = 0; j < 5; j++) {
+ if(mycustomttable[i].biosFootprintAddr[j]) {
+ if(ivideo->SiS_Pr.UseROM) {
+ if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+ mycustomttable[i].biosFootprintData[j]) {
+ footprint = FALSE;
+ }
+ } else
+ footprint = FALSE;
+ }
+ }
+ if(footprint) {
+ ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+ printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
+ mycustomttable[i].vendorName,
+ mycustomttable[i].cardName);
+ printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
+ mycustomttable[i].optionName);
+ break;
+ }
+ }
+ i++;
+ } while(mycustomttable[i].chipID);
}
static BOOLEAN __devinit
@@ -384,22 +460,23 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
buffer[2] != 0xff || buffer[3] != 0xff ||
buffer[4] != 0xff || buffer[5] != 0xff ||
buffer[6] != 0xff || buffer[7] != 0x00) {
- printk(KERN_DEBUG "sisfb: Bad EDID header\n");
- return FALSE;
+ printk(KERN_DEBUG "sisfb: Bad EDID header\n");
+ return FALSE;
}
if(buffer[0x12] != 0x01) {
- printk(KERN_INFO "sisfb: EDID version %d not supported\n",
- buffer[0x12]);
- return FALSE;
+ printk(KERN_INFO "sisfb: EDID version %d not supported\n",
+ buffer[0x12]);
+ return FALSE;
}
monitor->feature = buffer[0x18];
if(!buffer[0x14] & 0x80) {
- if(!(buffer[0x14] & 0x08)) {
- printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
- }
+ if(!(buffer[0x14] & 0x08)) {
+ printk(KERN_INFO
+ "sisfb: WARNING: Monitor does not support separate syncs\n");
+ }
}
if(buffer[0x13] >= 0x01) {
@@ -409,7 +486,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
j = 0x36;
for(i=0; i<4; i++) {
if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
- buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
+ buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
buffer[j + 4] == 0x00) {
monitor->hmin = buffer[j + 7];
monitor->hmax = buffer[j + 8];
@@ -435,7 +512,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
for(i = 0; i < 13; i++) {
if(emodes & sisfb_ddcsmodes[i].mask) {
- if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
+ if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
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)
for(i = 0; i < 8; i++) {
xres = (buffer[index] + 31) * 8;
switch(buffer[index + 1] & 0xc0) {
- case 0xc0: yres = (xres * 9) / 16; break;
- case 0x80: yres = (xres * 4) / 5; break;
- case 0x40: yres = (xres * 3) / 4; break;
- default: yres = xres; break;
+ case 0xc0: yres = (xres * 9) / 16; break;
+ case 0x80: yres = (xres * 4) / 5; break;
+ case 0x40: yres = (xres * 3) / 4; break;
+ default: yres = xres; break;
}
refresh = (buffer[index + 1] & 0x3f) + 60;
if((xres >= 640) && (yres >= 480)) {
- for(j = 0; j < 8; j++) {
- if((xres == sisfb_ddcfmodes[j].x) &&
- (yres == sisfb_ddcfmodes[j].y) &&
+ for(j = 0; j < 8; j++) {
+ if((xres == sisfb_ddcfmodes[j].x) &&
+ (yres == sisfb_ddcfmodes[j].y) &&
(refresh == sisfb_ddcfmodes[j].v)) {
if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
- if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
- }
- }
+ if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[j].d;
+ }
+ }
}
index += 2;
- }
+ }
if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
monitor->datavalid = TRUE;
}
}
- return(monitor->datavalid);
+ return monitor->datavalid;
}
static void __devinit
sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
{
- USHORT temp, i, realcrtno = crtno;
- u8 buffer[256];
+ unsigned short temp, i, realcrtno = crtno;
+ unsigned char buffer[256];
monitor->datavalid = FALSE;
if(crtno) {
- if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
- else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
- else return;
- }
+ if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
+ else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
+ else return;
+ }
- if((ivideo->sisfb_crt1off) && (!crtno)) return;
+ if((ivideo->sisfb_crt1off) && (!crtno))
+ return;
- temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
- realcrtno, 0, &buffer[0]);
- if((!temp) || (temp == 0xffff)) {
- printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+ realcrtno, 0, &buffer[0], ivideo->vbflags2);
+ if((!temp) || (temp == 0xffff)) {
+ printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
return;
- } else {
- printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
- printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
- crtno + 1,
- (temp & 0x1a) ? "" : "[none of the supported]",
- (temp & 0x02) ? "2 " : "",
- (temp & 0x08) ? "D&P" : "",
- (temp & 0x10) ? "FPDI-2" : "");
- if(temp & 0x02) {
+ } else {
+ printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
+ printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
+ crtno + 1,
+ (temp & 0x1a) ? "" : "[none of the supported]",
+ (temp & 0x02) ? "2 " : "",
+ (temp & 0x08) ? "D&P" : "",
+ (temp & 0x10) ? "FPDI-2" : "");
+ if(temp & 0x02) {
i = 3; /* Number of retrys */
do {
- temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
- realcrtno, 1, &buffer[0]);
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+ realcrtno, 1, &buffer[0], ivideo->vbflags2);
} while((temp) && i--);
- if(!temp) {
- if(sisfb_interpret_edid(monitor, &buffer[0])) {
+ if(!temp) {
+ if(sisfb_interpret_edid(monitor, &buffer[0])) {
printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
- monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
+ monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
monitor->dclockmax / 1000);
} else {
- printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
- }
+ printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
+ }
} else {
- printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
+ printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
}
} else {
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
}
}
+/* -------------- Mode validation --------------- */
+
static BOOLEAN
sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
int mode_idx, int rate_idx, int rate)
@@ -534,42 +614,49 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
int htotal, vtotal;
unsigned int dclock, hsync;
- if(!monitor->datavalid) return TRUE;
+ if(!monitor->datavalid)
+ return TRUE;
- if(mode_idx < 0) return FALSE;
+ if(mode_idx < 0)
+ return FALSE;
/* Skip for 320x200, 320x240, 640x400 */
- switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
- case 0x59:
- case 0x41:
- case 0x4f:
- case 0x50:
- case 0x56:
- case 0x53:
- case 0x2f:
- case 0x5d:
- case 0x5e:
- return TRUE;
+ switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
+ case 0x59:
+ case 0x41:
+ case 0x4f:
+ case 0x50:
+ case 0x56:
+ case 0x53:
+ case 0x2f:
+ case 0x5d:
+ case 0x5e:
+ return TRUE;
#ifdef CONFIG_FB_SIS_315
case 0x5a:
case 0x5b:
if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
#endif
- }
+ }
- if(rate < (monitor->vmin - 1)) return FALSE;
- if(rate > (monitor->vmax + 1)) return FALSE;
+ if(rate < (monitor->vmin - 1))
+ return FALSE;
+ if(rate > (monitor->vmax + 1))
+ return FALSE;
- if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+ if(sisfb_gettotalfrommode(&ivideo->SiS_Pr,
sisbios_mode[mode_idx].mode_no[ivideo->mni],
- &htotal, &vtotal, rate_idx)) {
+ &htotal, &vtotal, rate_idx)) {
dclock = (htotal * vtotal * rate) / 1000;
- if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+ if(dclock > (monitor->dclockmax + 1000))
+ return FALSE;
hsync = dclock / htotal;
- if(hsync < (monitor->hmin - 1)) return FALSE;
- if(hsync > (monitor->hmax + 1)) return FALSE;
+ if(hsync < (monitor->hmin - 1))
+ return FALSE;
+ if(hsync > (monitor->hmax + 1))
+ return FALSE;
} else {
- return FALSE;
+ return FALSE;
}
return TRUE;
}
@@ -577,82 +664,79 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
static int
sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
{
- u16 xres=0, yres, myres;
+ u16 xres=0, yres, myres;
#ifdef CONFIG_FB_SIS_300
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
- }
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(!(sisbios_mode[myindex].chipset & MD_SIS300))
+ return -1 ;
+ }
#endif
#ifdef CONFIG_FB_SIS_315
- if(ivideo->sisvga_engine == SIS_315_VGA) {
- if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
- }
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if(!(sisbios_mode[myindex].chipset & MD_SIS315))
+ return -1;
+ }
#endif
- myres = sisbios_mode[myindex].yres;
-
- switch(vbflags & VB_DISPTYPE_DISP2) {
+ myres = sisbios_mode[myindex].yres;
- case CRT2_LCD:
+ switch(vbflags & VB_DISPTYPE_DISP2) {
- xres = ivideo->lcdxres; yres = ivideo->lcdyres;
+ case CRT2_LCD:
+ xres = ivideo->lcdxres; yres = ivideo->lcdyres;
- if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {
- if(sisbios_mode[myindex].xres > xres) return(-1);
- if(myres > yres) return(-1);
- }
+ if((ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) &&
+ (ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL856)) {
+ if(sisbios_mode[myindex].xres > xres)
+ return -1;
+ if(myres > yres)
+ return -1;
+ }
- if(vbflags & (VB_LVDS | VB_30xBDH)) {
- if(sisbios_mode[myindex].xres == 320) {
- if((myres == 240) || (myres == 480)) {
- if(!ivideo->sisfb_fstn) {
- if(sisbios_mode[myindex].mode_no[1] == 0x5a ||
- sisbios_mode[myindex].mode_no[1] == 0x5b)
- return(-1);
- } else {
- if(sisbios_mode[myindex].mode_no[1] == 0x50 ||
- sisbios_mode[myindex].mode_no[1] == 0x56 ||
- sisbios_mode[myindex].mode_no[1] == 0x53)
- return(-1);
- }
- }
- }
- }
+ if(ivideo->sisfb_fstn) {
+ if(sisbios_mode[myindex].xres == 320) {
+ if(myres == 240) {
+ switch(sisbios_mode[myindex].mode_no[1]) {
+ case 0x50: myindex = MODE_FSTN_8; break;
+ case 0x56: myindex = MODE_FSTN_16; break;
+ case 0x53: return -1;
+ }
+ }
+ }
+ }
- if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
- sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
- ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
- return(-1);
- }
- break;
+ if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
+ ivideo->SiS_Pr.SiS_CustomT, xres, yres, ivideo->vbflags2) < 0x14) {
+ return -1;
+ }
+ break;
- case CRT2_TV:
- if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
- sisbios_mode[myindex].yres, 0) < 0x14) {
- return(-1);
- }
- break;
+ case CRT2_TV:
+ if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
+ return -1;
+ }
+ break;
- case CRT2_VGA:
- if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
- sisbios_mode[myindex].yres, 0) < 0x14) {
- return(-1);
+ case CRT2_VGA:
+ if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ sisbios_mode[myindex].yres, 0, ivideo->vbflags2) < 0x14) {
+ return -1;
+ }
+ break;
}
- break;
- }
- return(myindex);
+ return myindex;
}
static u8
sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
{
- u16 xres, yres;
int i = 0;
-
- xres = sisbios_mode[mode_idx].xres;
- yres = sisbios_mode[mode_idx].yres;
+ u16 xres = sisbios_mode[mode_idx].xres;
+ u16 yres = sisbios_mode[mode_idx].yres;
ivideo->rate_idx = 0;
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
rate, sisfb_vrate[i-1].refresh);
ivideo->rate_idx = sisfb_vrate[i-1].idx;
ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
- }
+ }
break;
} else if((rate - sisfb_vrate[i].refresh) <= 2) {
DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
rate, sisfb_vrate[i].refresh);
- ivideo->rate_idx = sisfb_vrate[i].idx;
- break;
- }
+ ivideo->rate_idx = sisfb_vrate[i].idx;
+ break;
+ }
}
i++;
}
@@ -695,252 +779,321 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
static BOOLEAN
sisfb_bridgeisslave(struct sis_video_info *ivideo)
{
- unsigned char P1_00;
+ unsigned char P1_00;
- if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;
+ if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE))
+ return FALSE;
- inSISIDXREG(SISPART1,0x00,P1_00);
- if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
- ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
- return TRUE;
- } else {
- return FALSE;
- }
+ inSISIDXREG(SISPART1,0x00,P1_00);
+ if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
+ ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
}
static BOOLEAN
sisfballowretracecrt1(struct sis_video_info *ivideo)
{
- u8 temp;
+ u8 temp;
- inSISIDXREG(SISCR,0x17,temp);
- if(!(temp & 0x80)) return FALSE;
+ inSISIDXREG(SISCR,0x17,temp);
+ if(!(temp & 0x80))
+ return FALSE;
- inSISIDXREG(SISSR,0x1f,temp);
- if(temp & 0xc0) return FALSE;
+ inSISIDXREG(SISSR,0x1f,temp);
+ if(temp & 0xc0)
+ return FALSE;
- return TRUE;
+ return TRUE;
}
static BOOLEAN
sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
{
- if(!sisfballowretracecrt1(ivideo)) return FALSE;
+ if(!sisfballowretracecrt1(ivideo))
+ return FALSE;
- if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
- else return FALSE;
+ if(inSISREG(SISINPSTAT) & 0x08)
+ return TRUE;
+ else
+ return FALSE;
}
static void
sisfbwaitretracecrt1(struct sis_video_info *ivideo)
{
- int watchdog;
+ int watchdog;
- if(!sisfballowretracecrt1(ivideo)) return;
+ if(!sisfballowretracecrt1(ivideo))
+ return;
- watchdog = 65536;
- while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
- watchdog = 65536;
- while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
+ watchdog = 65536;
+ while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
+ watchdog = 65536;
+ while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
}
static BOOLEAN
sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
{
- unsigned char temp, reg;
+ unsigned char temp, reg;
- switch(ivideo->sisvga_engine) {
- case SIS_300_VGA: reg = 0x25; break;
- case SIS_315_VGA: reg = 0x30; break;
- default: return FALSE;
- }
+ switch(ivideo->sisvga_engine) {
+ case SIS_300_VGA: reg = 0x25; break;
+ case SIS_315_VGA: reg = 0x30; break;
+ default: return FALSE;
+ }
- inSISIDXREG(SISPART1, reg, temp);
- if(temp & 0x02) return TRUE;
- else return FALSE;
+ inSISIDXREG(SISPART1, reg, temp);
+ if(temp & 0x02)
+ return TRUE;
+ else
+ return FALSE;
}
static BOOLEAN
sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
{
- if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
- if(sisfb_bridgeisslave(ivideo)) {
- return(sisfbcheckvretracecrt1(ivideo));
- } else {
- return(sisfbcheckvretracecrt2(ivideo));
- }
- }
- return(sisfbcheckvretracecrt1(ivideo));
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+ if(!sisfb_bridgeisslave(ivideo)) {
+ return sisfbcheckvretracecrt2(ivideo);
+ }
+ }
+ return sisfbcheckvretracecrt1(ivideo);
}
static u32
sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
{
- u8 idx, reg1, reg2, reg3, reg4;
- u32 ret = 0;
-
- (*vcount) = (*hcount) = 0;
-
- if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
- ret |= (FB_VBLANK_HAVE_VSYNC |
- FB_VBLANK_HAVE_HBLANK |
- FB_VBLANK_HAVE_VBLANK |
- FB_VBLANK_HAVE_VCOUNT |
- FB_VBLANK_HAVE_HCOUNT);
- switch(ivideo->sisvga_engine) {
- case SIS_300_VGA: idx = 0x25; break;
- default:
- case SIS_315_VGA: idx = 0x30; break;
- }
- inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
- inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
- inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
- inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
- if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
- if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
- if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
- (*vcount) = reg3 | ((reg4 & 0x70) << 4);
- (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
- } else if(sisfballowretracecrt1(ivideo)) {
- ret |= (FB_VBLANK_HAVE_VSYNC |
- FB_VBLANK_HAVE_VBLANK |
- FB_VBLANK_HAVE_VCOUNT |
- FB_VBLANK_HAVE_HCOUNT);
- reg1 = inSISREG(SISINPSTAT);
- if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
- if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
- inSISIDXREG(SISCR,0x20,reg1);
- inSISIDXREG(SISCR,0x1b,reg1);
- inSISIDXREG(SISCR,0x1c,reg2);
- inSISIDXREG(SISCR,0x1d,reg3);
- (*vcount) = reg2 | ((reg3 & 0x07) << 8);
- (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
- }
- return ret;
+ u8 idx, reg1, reg2, reg3, reg4;
+ u32 ret = 0;
+
+ (*vcount) = (*hcount) = 0;
+
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
+
+ ret |= (FB_VBLANK_HAVE_VSYNC |
+ FB_VBLANK_HAVE_HBLANK |
+ FB_VBLANK_HAVE_VBLANK |
+ FB_VBLANK_HAVE_VCOUNT |
+ FB_VBLANK_HAVE_HCOUNT);
+ switch(ivideo->sisvga_engine) {
+ case SIS_300_VGA: idx = 0x25; break;
+ default:
+ case SIS_315_VGA: idx = 0x30; break;
+ }
+ inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
+ inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
+ inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
+ inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
+ if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+ if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING;
+ if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING;
+ (*vcount) = reg3 | ((reg4 & 0x70) << 4);
+ (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
+
+ } else if(sisfballowretracecrt1(ivideo)) {
+
+ ret |= (FB_VBLANK_HAVE_VSYNC |
+ FB_VBLANK_HAVE_VBLANK |
+ FB_VBLANK_HAVE_VCOUNT |
+ FB_VBLANK_HAVE_HCOUNT);
+ reg1 = inSISREG(SISINPSTAT);
+ if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
+ if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+ inSISIDXREG(SISCR,0x20,reg1);
+ inSISIDXREG(SISCR,0x1b,reg1);
+ inSISIDXREG(SISCR,0x1c,reg2);
+ inSISIDXREG(SISCR,0x1d,reg3);
+ (*vcount) = reg2 | ((reg3 & 0x07) << 8);
+ (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
+ }
+
+ return ret;
}
static int
sisfb_myblank(struct sis_video_info *ivideo, int blank)
{
- u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
- BOOLEAN backlight = TRUE;
-
- switch(blank) {
- case FB_BLANK_UNBLANK: /* on */
- sr01 = 0x00;
- sr11 = 0x00;
- sr1f = 0x00;
- cr63 = 0x00;
- p2_0 = 0x20;
- p1_13 = 0x00;
- backlight = TRUE;
- break;
- case FB_BLANK_NORMAL: /* blank */
- sr01 = 0x20;
- sr11 = 0x00;
- sr1f = 0x00;
- cr63 = 0x00;
- p2_0 = 0x20;
- p1_13 = 0x00;
- backlight = TRUE;
- break;
- case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
- sr01 = 0x20;
- sr11 = 0x08;
- sr1f = 0x80;
- cr63 = 0x40;
- p2_0 = 0x40;
- p1_13 = 0x80;
- backlight = FALSE;
- break;
- case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
- sr01 = 0x20;
- sr11 = 0x08;
- sr1f = 0x40;
- cr63 = 0x40;
- p2_0 = 0x80;
- p1_13 = 0x40;
- backlight = FALSE;
- break;
- case FB_BLANK_POWERDOWN: /* off */
- sr01 = 0x20;
- sr11 = 0x08;
- sr1f = 0xc0;
- cr63 = 0x40;
- p2_0 = 0xc0;
- p1_13 = 0xc0;
- backlight = FALSE;
- break;
- default:
- return 1;
- }
-
- if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
-
- if( (!ivideo->sisfb_thismonitor.datavalid) ||
- ((ivideo->sisfb_thismonitor.datavalid) &&
- (ivideo->sisfb_thismonitor.feature & 0xe0))) {
-
- if(ivideo->sisvga_engine == SIS_315_VGA) {
- setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
- }
-
- if(!(sisfb_bridgeisslave(ivideo))) {
- setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
- setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
- }
- }
-
- }
-
- if(ivideo->currentvbflags & CRT2_LCD) {
-
- if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
- if(backlight) {
- SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);
- } else {
- SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);
- }
- } else if(ivideo->sisvga_engine == SIS_315_VGA) {
- if(ivideo->vbflags & VB_CHRONTEL) {
- if(backlight) {
- SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);
- } else {
- SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
- }
- }
- }
-
- if(((ivideo->sisvga_engine == SIS_300_VGA) &&
- (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
- ((ivideo->sisvga_engine == SIS_315_VGA) &&
- ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
- setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
- }
-
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
- (!(ivideo->vbflags & VB_30xBDH))) {
- setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
- }
- } else if(ivideo->sisvga_engine == SIS_315_VGA) {
- if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
- (!(ivideo->vbflags & VB_30xBDH))) {
- setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
- }
- }
-
- } else if(ivideo->currentvbflags & CRT2_VGA) {
-
- if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {
- setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
- }
-
- }
-
- return(0);
+ u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
+ BOOLEAN backlight = TRUE;
+
+ switch(blank) {
+ case FB_BLANK_UNBLANK: /* on */
+ sr01 = 0x00;
+ sr11 = 0x00;
+ sr1f = 0x00;
+ cr63 = 0x00;
+ p2_0 = 0x20;
+ p1_13 = 0x00;
+ backlight = TRUE;
+ break;
+ case FB_BLANK_NORMAL: /* blank */
+ sr01 = 0x20;
+ sr11 = 0x00;
+ sr1f = 0x00;
+ cr63 = 0x00;
+ p2_0 = 0x20;
+ p1_13 = 0x00;
+ backlight = TRUE;
+ break;
+ case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
+ sr01 = 0x20;
+ sr11 = 0x08;
+ sr1f = 0x80;
+ cr63 = 0x40;
+ p2_0 = 0x40;
+ p1_13 = 0x80;
+ backlight = FALSE;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
+ sr01 = 0x20;
+ sr11 = 0x08;
+ sr1f = 0x40;
+ cr63 = 0x40;
+ p2_0 = 0x80;
+ p1_13 = 0x40;
+ backlight = FALSE;
+ break;
+ case FB_BLANK_POWERDOWN: /* off */
+ sr01 = 0x20;
+ sr11 = 0x08;
+ sr1f = 0xc0;
+ cr63 = 0x40;
+ p2_0 = 0xc0;
+ p1_13 = 0xc0;
+ backlight = FALSE;
+ break;
+ default:
+ return 1;
+ }
+
+ if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
+
+ if( (!ivideo->sisfb_thismonitor.datavalid) ||
+ ((ivideo->sisfb_thismonitor.datavalid) &&
+ (ivideo->sisfb_thismonitor.feature & 0xe0))) {
+
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
+ }
+
+ if(!(sisfb_bridgeisslave(ivideo))) {
+ setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+ setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+ }
+ }
+
+ }
+
+ if(ivideo->currentvbflags & CRT2_LCD) {
+
+ if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
+ if(backlight) {
+ SiS_SiS30xBLOn(&ivideo->SiS_Pr);
+ } else {
+ SiS_SiS30xBLOff(&ivideo->SiS_Pr);
+ }
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->vbflags2 & VB2_CHRONTEL) {
+ if(backlight) {
+ SiS_Chrontel701xBLOn(&ivideo->SiS_Pr);
+ } else {
+ SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
+ }
+ }
+#endif
+ }
+
+ if(((ivideo->sisvga_engine == SIS_300_VGA) &&
+ (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) ||
+ ((ivideo->sisvga_engine == SIS_315_VGA) &&
+ ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) {
+ setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
+ }
+
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if((ivideo->vbflags2 & VB2_30xB) &&
+ (!(ivideo->vbflags2 & VB2_30xBDH))) {
+ setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
+ }
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if((ivideo->vbflags2 & VB2_30xB) &&
+ (!(ivideo->vbflags2 & VB2_30xBDH))) {
+ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+ }
+ }
+
+ } else if(ivideo->currentvbflags & CRT2_VGA) {
+
+ if(ivideo->vbflags2 & VB2_30xB) {
+ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+ }
+
+ }
+
+ return 0;
+}
+
+/* ------------- Callbacks from init.c/init301.c -------------- */
+
+#ifdef CONFIG_FB_SIS_300
+unsigned int
+sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+ u32 val = 0;
+
+ pci_read_config_dword(ivideo->nbridge, reg, &val);
+ return (unsigned int)val;
+}
+
+void
+sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+
+ pci_write_config_dword(ivideo->nbridge, reg, (u32)val);
}
+unsigned int
+sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+ u32 val = 0;
+
+ if(!ivideo->lpcdev) return 0;
+
+ pci_read_config_dword(ivideo->lpcdev, reg, &val);
+ return (unsigned int)val;
+}
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+void
+sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+
+ pci_write_config_byte(ivideo->nbridge, reg, (u8)val);
+}
+
+unsigned int
+sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;
+ u16 val = 0;
+
+ if(!ivideo->lpcdev) return 0;
+
+ pci_read_config_word(ivideo->lpcdev, reg, &val);
+ return (unsigned int)val;
+}
+#endif
+
/* ----------- FBDev related routines for all series ----------- */
static int
@@ -952,7 +1105,7 @@ sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
static void
sisfb_set_vparms(struct sis_video_info *ivideo)
{
- switch(ivideo->video_bpp) {
+ switch(ivideo->video_bpp) {
case 8:
ivideo->DstColor = 0x0000;
ivideo->SiS310_AccelDepth = 0x00000000;
@@ -972,14 +1125,13 @@ sisfb_set_vparms(struct sis_video_info *ivideo)
ivideo->video_cmap_len = 16;
printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
ivideo->accel = 0;
- break;
- }
+ }
}
static int
sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
{
- int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3));
+ int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3));
if(maxyres > 32767) maxyres = 32767;
@@ -996,30 +1148,29 @@ sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
ivideo->scrnpitchCRT1 <<= 1;
}
}
-
}
static void
sisfb_set_pitch(struct sis_video_info *ivideo)
{
- BOOLEAN isslavemode = FALSE;
+ BOOLEAN isslavemode = FALSE;
unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
unsigned short HDisplay2 = ivideo->video_linelength >> 3;
- if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
+ if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
- /* We need to set pitch for CRT1 if bridge is in slave mode, too */
- if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
- outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
- setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
+ /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
+ outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
+ setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
}
- /* We must not set the pitch for CRT2 if bridge is in slave mode */
- if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
+ /* We must not set the pitch for CRT2 if bridge is in slave mode */
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
- outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
- setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
- }
+ outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
+ setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
+ }
}
static void
@@ -1056,12 +1207,41 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
}
static int
+sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
+{
+ unsigned short modeno = ivideo->mode_no;
+
+ /* >=2.6.12's fbcon clears the screen anyway */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
+ if(!clrscrn) modeno |= 0x80;
+#else
+ modeno |= 0x80;
+#endif
+
+ outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+ sisfb_pre_setmode(ivideo);
+
+ if(SiSSetMode(&ivideo->SiS_Pr, modeno) == 0) {
+ printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
+ return -EINVAL;
+ }
+
+ outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+ sisfb_post_setmode(ivideo);
+
+ return 0;
+}
+
+
+static int
sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
unsigned int htotal = 0, vtotal = 0;
unsigned int drate = 0, hrate = 0;
- int found_mode = 0;
+ int found_mode = 0, ret;
int old_mode;
u32 pixclock;
@@ -1088,11 +1268,11 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
}
if(pixclock && htotal && vtotal) {
- drate = 1000000000 / pixclock;
- hrate = (drate * 1000) / htotal;
- ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ drate = 1000000000 / pixclock;
+ hrate = (drate * 1000) / htotal;
+ ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
} else {
- ivideo->refresh_rate = 60;
+ ivideo->refresh_rate = 60;
}
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
if(found_mode) {
ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+ ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
} else {
ivideo->sisfb_mode_idx = -1;
}
@@ -1131,10 +1312,10 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
if(ivideo->sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
ivideo->rate_idx, ivideo->refresh_rate)) {
- printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
- }
+ printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+ }
}
#endif
@@ -1143,24 +1324,9 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
#else
if(isactive) {
#endif
- sisfb_pre_setmode(ivideo);
-
- if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
- printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
- return -EINVAL;
- }
-
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
- sisfb_post_setmode(ivideo);
-
- ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
- ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
- ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
-
- sisfb_calc_pitch(ivideo, var);
- sisfb_set_pitch(ivideo);
-
+ /* If acceleration to be used? Need to know
+ * before pre/post_set_mode()
+ */
ivideo->accel = 0;
#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
#ifdef STUPID_ACCELF_TEXT_SHIT
@@ -1175,6 +1341,17 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in
if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
#endif
+ if((ret = sisfb_set_mode(ivideo, 1))) {
+ return ret;
+ }
+
+ ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+ ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+ ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
+
+ sisfb_calc_pitch(ivideo, var);
+ sisfb_set_pitch(ivideo);
+
sisfb_set_vparms(ivideo);
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
ivideo->current_pixclock = var->pixclock;
ivideo->current_refresh_rate = ivideo->refresh_rate;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
+ ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
#endif
}
return 0;
}
-static int
-sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+static void
+sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base)
{
- unsigned int base;
-
- if(var->xoffset > (var->xres_virtual - var->xres)) {
- return -EINVAL;
- }
- if(var->yoffset > (var->yres_virtual - var->yres)) {
- return -EINVAL;
- }
-
- base = (var->yoffset * var->xres_virtual) + var->xoffset;
-
- /* calculate base bpp dep. */
- switch(var->bits_per_pixel) {
- case 32:
- break;
- case 16:
- base >>= 1;
- break;
- case 8:
- default:
- base >>= 2;
- break;
- }
-
outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
if(ivideo->sisvga_engine == SIS_315_VGA) {
setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
}
- if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
- orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
- outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
- outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
- outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
- if(ivideo->sisvga_engine == SIS_315_VGA) {
- setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
- }
- }
- return 0;
}
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
static void
-sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
-{
- u16 VRE, VBE, VRS, VBS, VDE, VT;
- u16 HRE, HBE, HRS, HBS, HDE, HT;
- u8 sr_data, cr_data, cr_data2, cr_data3, mr_data;
- int A, B, C, D, E, F, temp;
- unsigned int hrate, drate, maxyres;
-
- inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
-
- if(sr_data & SIS_INTERLACED_MODE)
- var->vmode = FB_VMODE_INTERLACED;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-
- switch((sr_data & 0x1C) >> 2) {
- case SIS_8BPP_COLOR_MODE:
- var->bits_per_pixel = 8;
- break;
- case SIS_16BPP_COLOR_MODE:
- var->bits_per_pixel = 16;
- break;
- case SIS_32BPP_COLOR_MODE:
- var->bits_per_pixel = 32;
- break;
- }
-
- sisfb_bpp_to_var(ivideo, var);
-
- inSISIDXREG(SISSR, 0x0A, sr_data);
- inSISIDXREG(SISCR, 0x06, cr_data);
- inSISIDXREG(SISCR, 0x07, cr_data2);
-
- VT = (cr_data & 0xFF) |
- ((u16) (cr_data2 & 0x01) << 8) |
- ((u16) (cr_data2 & 0x20) << 4) |
- ((u16) (sr_data & 0x01) << 10);
- A = VT + 2;
-
- inSISIDXREG(SISCR, 0x12, cr_data);
-
- VDE = (cr_data & 0xff) |
- ((u16) (cr_data2 & 0x02) << 7) |
- ((u16) (cr_data2 & 0x40) << 3) |
- ((u16) (sr_data & 0x02) << 9);
- E = VDE + 1;
-
- inSISIDXREG(SISCR, 0x10, cr_data);
-
- VRS = (cr_data & 0xff) |
- ((u16) (cr_data2 & 0x04) << 6) |
- ((u16) (cr_data2 & 0x80) << 2) |
- ((u16) (sr_data & 0x08) << 7);
- F = VRS + 1 - E;
-
- inSISIDXREG(SISCR, 0x15, cr_data);
- inSISIDXREG(SISCR, 0x09, cr_data3);
-
- if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
-
- VBS = (cr_data & 0xff) |
- ((u16) (cr_data2 & 0x08) << 5) |
- ((u16) (cr_data3 & 0x20) << 4) |
- ((u16) (sr_data & 0x04) << 8);
-
- inSISIDXREG(SISCR, 0x16, cr_data);
-
- VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
- temp = VBE - ((E - 1) & 511);
- B = (temp > 0) ? temp : (temp + 512);
-
- inSISIDXREG(SISCR, 0x11, cr_data);
-
- VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
- temp = VRE - ((E + F - 1) & 31);
- C = (temp > 0) ? temp : (temp + 32);
-
- D = B - F - C;
-
- var->yres = E;
- var->upper_margin = D;
- var->lower_margin = F;
- var->vsync_len = C;
-
- if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- var->yres <<= 1;
- var->upper_margin <<= 1;
- var->lower_margin <<= 1;
- var->vsync_len <<= 1;
- } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- var->yres >>= 1;
- var->upper_margin >>= 1;
- var->lower_margin >>= 1;
- var->vsync_len >>= 1;
- }
-
- inSISIDXREG(SISSR, 0x0b, sr_data);
- inSISIDXREG(SISCR, 0x00, cr_data);
-
- HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
- A = HT + 5;
-
- inSISIDXREG(SISCR, 0x01, cr_data);
-
- HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
- E = HDE + 1;
-
- inSISIDXREG(SISCR, 0x04, cr_data);
-
- HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
- F = HRS - E - 3;
-
- inSISIDXREG(SISCR, 0x02, cr_data);
-
- HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
-
- inSISIDXREG(SISSR, 0x0c, sr_data);
- inSISIDXREG(SISCR, 0x03, cr_data);
- inSISIDXREG(SISCR, 0x05, cr_data2);
-
- HBE = (cr_data & 0x1f) |
- ((u16) (cr_data2 & 0x80) >> 2) |
- ((u16) (sr_data & 0x03) << 6);
- HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
- temp = HBE - ((E - 1) & 255);
- B = (temp > 0) ? temp : (temp + 256);
-
- temp = HRE - ((E + F + 3) & 63);
- C = (temp > 0) ? temp : (temp + 64);
-
- D = B - F - C;
-
- var->xres = E * 8;
- if(var->xres_virtual < var->xres) {
- var->xres_virtual = var->xres;
- }
-
- if((var->xres == 320) &&
- (var->yres == 200 || var->yres == 240)) {
- /* Terrible hack, but the correct CRTC data for
- * these modes only produces a black screen...
- */
- var->left_margin = (400 - 376);
- var->right_margin = (328 - 320);
- var->hsync_len = (376 - 328);
- } else {
- var->left_margin = D * 8;
- var->right_margin = F * 8;
- var->hsync_len = C * 8;
- }
- var->activate = FB_ACTIVATE_NOW;
-
- var->sync = 0;
-
- mr_data = inSISREG(SISMISCR);
- if(mr_data & 0x80)
- var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
- else
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
-
- if(mr_data & 0x40)
- var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
- else
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
-
- VT += 2;
- VT <<= 1;
- HT = (HT + 5) * 8;
-
- if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- VT <<= 1;
- }
- hrate = ivideo->refresh_rate * VT / 2;
- drate = (hrate * HT) / 1000;
- var->pixclock = (u32) (1000000000 / drate);
-
- if(ivideo->sisfb_ypan) {
- maxyres = sisfb_calc_maxyres(ivideo, var);
- if(ivideo->sisfb_max) {
- var->yres_virtual = maxyres;
- } else {
- if(var->yres_virtual > maxyres) {
- var->yres_virtual = maxyres;
- }
- }
- if(var->yres_virtual <= var->yres) {
- var->yres_virtual = var->yres;
- }
- } else {
- var->yres_virtual = var->yres;
- }
-
-}
-
-static int
-sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
- unsigned *transp, struct fb_info *info)
+sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base)
{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
- if(regno >= ivideo->video_cmap_len) return 1;
-
- *red = ivideo->sis_palette[regno].red;
- *green = ivideo->sis_palette[regno].green;
- *blue = ivideo->sis_palette[regno].blue;
- *transp = 0;
-
- return 0;
-}
-
-static int
-sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
- if(regno >= ivideo->video_cmap_len) return 1;
-
- ivideo->sis_palette[regno].red = red;
- ivideo->sis_palette[regno].green = green;
- ivideo->sis_palette[regno].blue = blue;
-
- switch(ivideo->video_bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- outSISREG(SISDACA, regno);
- outSISREG(SISDACD, (red >> 10));
- outSISREG(SISDACD, (green >> 10));
- outSISREG(SISDACD, (blue >> 10));
- if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
- outSISREG(SISDAC2A, regno);
- outSISREG(SISDAC2D, (red >> 8));
- outSISREG(SISDAC2D, (green >> 8));
- outSISREG(SISDAC2D, (blue >> 8));
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+ orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
+ outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
+ outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
+ outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
}
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- ivideo->sis_fbcon_cmap.cfb16[regno] =
- ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
- break;
-#endif
- }
-
- return 0;
-}
-
-static void
-sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- struct display *display;
- struct display_switch *sw;
- struct fb_fix_screeninfo fix;
- long flags;
-
- display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
-
- sisfb_get_fix(&fix, con, info);
-
- display->var = *var;
- display->screen_base = (char *)ivideo->video_vbase;
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->line_length = fix.line_length;
- display->can_soft_blank = 1;
- display->inverse = ivideo->sisfb_inverse;
- display->next_line = fix.line_length;
-
- save_flags(flags);
-
- switch(ivideo->video_bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
- display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
- display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
- break;
-#endif
- default:sw = &fbcon_dummy;
- break;
- }
- memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
- display->dispsw = &ivideo->sisfb_sw;
-
- restore_flags(flags);
-
- if(ivideo->sisfb_ypan) {
- /* display->scrollmode = 0; */
- } else {
- display->scrollmode = SCROLL_YREDRAW;
- ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
- }
-}
-
-static void
-sisfb_do_install_cmap(int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
- if(con != ivideo->currcon) return;
-
- if(fb_display[con].cmap.len) {
- fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
- } else {
- int size = sisfb_get_cmap_len(&fb_display[con].var);
- fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
}
}
static int
-sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
- if(con == -1) {
- memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
- } else {
- *var = fb_display[con].var;
- }
-
- if(ivideo->sisfb_fstn) {
- if(var->xres == 320 && var->yres == 480) var->yres = 240;
- }
-
- return 0;
-}
-
-static int
-sisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- int err;
-
- fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
- if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
- sisfb_crtc_to_var(ivideo, var);
+ if(var->xoffset > (var->xres_virtual - var->xres)) {
return -EINVAL;
}
-
- sisfb_crtc_to_var(ivideo, var);
-
- sisfb_set_disp(con, var, info);
-
- if(info->changevar) {
- (*info->changevar)(con);
- }
-
- if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
- return err;
- }
-
- sisfb_do_install_cmap(con, info);
-
-#if 0 /* Why was this called here? */
- unsigned int cols, rows;
- cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
- rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
- vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-#endif
- return 0;
-}
-
-static int
-sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- struct display *display;
-
- display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
-
- if(con == ivideo->currcon) {
-
- return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
-
- } else if(display->cmap.len) {
-
- fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
-
- } else {
-
- int size = sisfb_get_cmap_len(&display->var);
- fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-
+ if(var->yoffset > (var->yres_virtual - var->yres)) {
+ return -EINVAL;
}
- return 0;
-}
+ ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;
-static int
-sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- struct display *display;
- int err, size;
-
- display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
-
- size = sisfb_get_cmap_len(&display->var);
- if(display->cmap.len != size) {
- err = fb_alloc_cmap(&display->cmap, size, 0);
- if(err) return err;
- }
-
- if(con == ivideo->currcon) {
- return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
- } else {
- fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
- }
-
- return 0;
-}
-
-static int
-sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- int err;
-
- if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
-
- if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
- (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
- return -EINVAL;
+ /* calculate base bpp dep. */
+ switch(var->bits_per_pixel) {
+ case 32:
+ break;
+ case 16:
+ ivideo->current_base >>= 1;
+ break;
+ case 8:
+ default:
+ ivideo->current_base >>= 2;
+ break;
}
- if(con == ivideo->currcon) {
- if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
- }
+ ivideo->current_base += (ivideo->video_offset >> 2);
- fb_display[con].var.xoffset = var->xoffset;
- fb_display[con].var.yoffset = var->yoffset;
+ sisfb_set_base_CRT1(ivideo, ivideo->current_base);
+ sisfb_set_base_CRT2(ivideo, ivideo->current_base);
return 0;
}
-static int
-sisfb_update_var(int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-
- return(sisfb_pan_var(ivideo, &fb_display[con].var));
-}
-
-static int
-sisfb_switch(int con, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- int cols, rows;
-
- if(fb_display[ivideo->currcon].cmap.len) {
- fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
- }
-
- fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
- if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
- sizeof(struct fb_var_screeninfo))) {
- ivideo->currcon = con;
- return 1;
- }
-
- ivideo->currcon = con;
-
- sisfb_do_set_var(&fb_display[con].var, 1, info);
-
- sisfb_set_disp(con, &fb_display[con].var, info);
-
- sisfb_do_install_cmap(con, info);
-
- cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
- rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
- vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-
- sisfb_update_var(con, info);
+/* ------------ FBDev related routines for 2.4 series ----------- */
- return 1;
-}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static void
-sisfb_blank(int blank, struct fb_info *info)
-{
- struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+#include "sisfb_fbdev_2_4.h"
- sisfb_myblank(ivideo, blank);
-}
#endif
/* ------------ FBDev related routines for 2.6 series ----------- */
@@ -1761,13 +1445,13 @@ sisfb_blank(int blank, struct fb_info *info)
static int
sisfb_open(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
static int
sisfb_release(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
static int
@@ -1776,16 +1460,17 @@ sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- if(regno >= sisfb_get_cmap_len(&info->var)) return 1;
+ if(regno >= sisfb_get_cmap_len(&info->var))
+ return 1;
switch(info->var.bits_per_pixel) {
case 8:
- outSISREG(SISDACA, regno);
+ outSISREG(SISDACA, regno);
outSISREG(SISDACD, (red >> 10));
outSISREG(SISDACD, (green >> 10));
outSISREG(SISDACD, (blue >> 10));
if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
- outSISREG(SISDAC2A, regno);
+ outSISREG(SISDAC2A, regno);
outSISREG(SISDAC2D, (red >> 8));
outSISREG(SISDAC2D, (green >> 8));
outSISREG(SISDAC2D, (blue >> 8));
@@ -1793,7 +1478,9 @@ sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
break;
case 16:
((u32 *)(info->pseudo_palette))[regno] =
- ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+ (red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
break;
case 32:
red >>= 8;
@@ -1811,13 +1498,13 @@ sisfb_set_par(struct fb_info *info)
{
int err;
- if((err = sisfb_do_set_var(&info->var, 1, info))) {
+ if((err = sisfb_do_set_var(&info->var, 1, info)))
return err;
- }
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
sisfb_get_fix(&info->fix, info->currcon, info);
#else
- sisfb_get_fix(&info->fix, -1, info);
+ sisfb_get_fix(&info->fix, -1, info);
#endif
return 0;
}
@@ -1829,7 +1516,7 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
unsigned int drate = 0, hrate = 0, maxyres;
int found_mode = 0;
- int refresh_rate, search_idx;
+ int refresh_rate, search_idx, tidx;
BOOLEAN recalc_clock = FALSE;
u32 pixclock;
@@ -1848,7 +1535,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
vtotal += var->yres;
vtotal <<= 1;
- } else vtotal += var->yres;
+ } else
+ vtotal += var->yres;
if(!(htotal) || !(vtotal)) {
SISFAIL("sisfb: no valid timing data");
@@ -1860,60 +1548,68 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if( (sisbios_mode[search_idx].xres == var->xres) &&
(sisbios_mode[search_idx].yres == var->yres) &&
(sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
- if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {
- found_mode = 1;
- break;
+ if((tidx = sisfb_validate_mode(ivideo, search_idx,
+ ivideo->currentvbflags)) > 0) {
+ found_mode = 1;
+ search_idx = tidx;
+ break;
}
}
search_idx++;
}
if(!found_mode) {
- search_idx = 0;
+ search_idx = 0;
while(sisbios_mode[search_idx].mode_no[0] != 0) {
if( (var->xres <= sisbios_mode[search_idx].xres) &&
(var->yres <= sisbios_mode[search_idx].yres) &&
(var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
- if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {
- found_mode = 1;
- break;
- }
+ if((tidx = sisfb_validate_mode(ivideo,search_idx,
+ ivideo->currentvbflags)) > 0) {
+ found_mode = 1;
+ search_idx = tidx;
+ break;
+ }
}
search_idx++;
- }
+ }
if(found_mode) {
- printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
- var->xres, var->yres, var->bits_per_pixel,
+ printk(KERN_DEBUG
+ "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
+ var->xres, var->yres, var->bits_per_pixel,
sisbios_mode[search_idx].xres,
sisbios_mode[search_idx].yres,
var->bits_per_pixel);
var->xres = sisbios_mode[search_idx].xres;
- var->yres = sisbios_mode[search_idx].yres;
-
-
+ var->yres = sisbios_mode[search_idx].yres;
} else {
- printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
+ printk(KERN_ERR
+ "sisfb: Failed to find supported mode near %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel);
- return -EINVAL;
+ return -EINVAL;
}
}
- if( ((ivideo->vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */
- ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
+ if( ((ivideo->vbflags2 & VB2_LVDS) ||
+ ((ivideo->vbflags2 & VB2_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
(var->bits_per_pixel == 8) ) {
- refresh_rate = 60;
+ /* Slave modes on LVDS and 301B-DH */
+ refresh_rate = 60;
recalc_clock = TRUE;
- } else if( (ivideo->current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */
- (ivideo->current_vtotal == vtotal) &&
- (ivideo->current_pixclock == pixclock) ) {
+ } else if( (ivideo->current_htotal == htotal) &&
+ (ivideo->current_vtotal == vtotal) &&
+ (ivideo->current_pixclock == pixclock) ) {
+ /* x=x & y=y & c=c -> assume depth change */
drate = 1000000000 / pixclock;
- hrate = (drate * 1000) / htotal;
- refresh_rate = (unsigned int) (hrate * 2 / vtotal);
- } else if( ( (ivideo->current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */
- (ivideo->current_vtotal != vtotal) ) &&
- (ivideo->current_pixclock == var->pixclock) ) {
+ hrate = (drate * 1000) / htotal;
+ refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ } else if( ( (ivideo->current_htotal != htotal) ||
+ (ivideo->current_vtotal != vtotal) ) &&
+ (ivideo->current_pixclock == var->pixclock) ) {
+ /* x!=x | y!=y & c=c -> invalid pixclock */
if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
- refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
+ refresh_rate =
+ ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
} else if(ivideo->sisfb_parm_rate != -1) {
/* Sic, sisfb_parm_rate - want to know originally desired rate here */
refresh_rate = ivideo->sisfb_parm_rate;
@@ -1923,8 +1619,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
recalc_clock = TRUE;
} else if((pixclock) && (htotal) && (vtotal)) {
drate = 1000000000 / pixclock;
- hrate = (drate * 1000) / htotal;
- refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ hrate = (drate * 1000) / htotal;
+ refresh_rate = (unsigned int) (hrate * 2 / vtotal);
} else if(ivideo->current_refresh_rate) {
refresh_rate = ivideo->current_refresh_rate;
recalc_clock = TRUE;
@@ -1937,72 +1633,72 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
/* Eventually recalculate timing and clock */
if(recalc_clock) {
- if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
- var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
- &ivideo->sishw_ext,
+ if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
+ var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
sisbios_mode[search_idx].mode_no[ivideo->mni],
myrateindex));
- sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
- sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var);
- if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- var->pixclock <<= 1;
- }
+ sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr,
+ sisbios_mode[search_idx].mode_no[ivideo->mni],
+ myrateindex, var);
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ var->pixclock <<= 1;
+ }
}
if(ivideo->sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
- myrateindex, refresh_rate)) {
- printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
- }
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
+ myrateindex, refresh_rate)) {
+ printk(KERN_INFO
+ "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+ }
}
/* Adapt RGB settings */
sisfb_bpp_to_var(ivideo, var);
-
+
/* Sanity check for offsets */
if(var->xoffset < 0) var->xoffset = 0;
if(var->yoffset < 0) var->yoffset = 0;
- if(var->xres > var->xres_virtual) {
- var->xres_virtual = var->xres;
- }
+ if(var->xres > var->xres_virtual)
+ var->xres_virtual = var->xres;
if(ivideo->sisfb_ypan) {
- maxyres = sisfb_calc_maxyres(ivideo, var);
- if(ivideo->sisfb_max) {
- var->yres_virtual = maxyres;
- } else {
- if(var->yres_virtual > maxyres) {
- var->yres_virtual = maxyres;
- }
- }
- if(var->yres_virtual <= var->yres) {
- var->yres_virtual = var->yres;
- }
+ maxyres = sisfb_calc_maxyres(ivideo, var);
+ if(ivideo->sisfb_max) {
+ var->yres_virtual = maxyres;
+ } else {
+ if(var->yres_virtual > maxyres) {
+ var->yres_virtual = maxyres;
+ }
+ }
+ if(var->yres_virtual <= var->yres) {
+ var->yres_virtual = var->yres;
+ }
} else {
- if(var->yres != var->yres_virtual) {
- var->yres_virtual = var->yres;
- }
- var->xoffset = 0;
- var->yoffset = 0;
+ if(var->yres != var->yres_virtual) {
+ var->yres_virtual = var->yres;
+ }
+ var->xoffset = 0;
+ var->yoffset = 0;
}
-
+
/* Truncate offsets to maximum if too high */
if(var->xoffset > var->xres_virtual - var->xres) {
- var->xoffset = var->xres_virtual - var->xres - 1;
+ var->xoffset = var->xres_virtual - var->xres - 1;
}
if(var->yoffset > var->yres_virtual - var->yres) {
- var->yoffset = var->yres_virtual - var->yres - 1;
+ var->yoffset = var->yres_virtual - var->yres - 1;
}
-
+
/* Set everything else to 0 */
- var->red.msb_right =
- var->green.msb_right =
- var->blue.msb_right =
- var->transp.offset =
- var->transp.length =
- var->transp.msb_right = 0;
+ var->red.msb_right =
+ var->green.msb_right =
+ var->blue.msb_right =
+ var->transp.offset =
+ var->transp.length =
+ var->transp.msb_right = 0;
return 0;
}
@@ -2013,21 +1709,21 @@ sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
int err;
- if(var->xoffset > (var->xres_virtual - var->xres)) {
+ if(var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
- }
- if(var->yoffset > (var->yres_virtual - var->yres)) {
+
+ if(var->yoffset > (var->yres_virtual - var->yres))
return -EINVAL;
- }
- if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
+ if(var->vmode & FB_VMODE_YWRAP)
+ return -EINVAL;
if(var->xoffset + info->var.xres > info->var.xres_virtual ||
- var->yoffset + info->var.yres > info->var.yres_virtual) {
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
- }
- if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
+ if((err = sisfb_pan_var(ivideo, var)) < 0)
+ return err;
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
@@ -2040,7 +1736,7 @@ sisfb_blank(int blank, struct fb_info *info)
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- return(sisfb_myblank(ivideo, blank));
+ return sisfb_myblank(ivideo, blank);
}
#endif
@@ -2056,153 +1752,184 @@ sisfb_ioctl(struct inode *inode, struct file *file,
struct fb_info *info)
{
struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- struct sis_memreq sismemreq;
- struct fb_vblank sisvbblank;
- sisfb_info x;
+ struct sis_memreq sismemreq;
+ struct fb_vblank sisvbblank;
u32 gpu32 = 0;
#ifndef __user
#define __user
#endif
u32 __user *argp = (u32 __user *)arg;
- switch (cmd) {
+ switch(cmd) {
case FBIO_ALLOC:
- if(!capable(CAP_SYS_RAWIO)) {
+ if(!capable(CAP_SYS_RAWIO))
return -EPERM;
- }
- if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq))) {
- return -EFAULT;
- }
+
+ if(copy_from_user(&sismemreq, (void __user *)arg, sizeof(sismemreq)))
+ return -EFAULT;
+
sis_malloc(&sismemreq);
+
if(copy_to_user((void __user *)arg, &sismemreq, sizeof(sismemreq))) {
sis_free((u32)sismemreq.offset);
- return -EFAULT;
+ return -EFAULT;
}
break;
case FBIO_FREE:
- if(!capable(CAP_SYS_RAWIO)) {
+ if(!capable(CAP_SYS_RAWIO))
return -EPERM;
- }
- if(get_user(gpu32, argp)) {
+
+ if(get_user(gpu32, argp))
return -EFAULT;
- }
+
sis_free(gpu32);
break;
case FBIOGET_VBLANK:
sisvbblank.count = 0;
sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
- if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank))) {
+
+ if(copy_to_user((void __user *)arg, &sisvbblank, sizeof(sisvbblank)))
return -EFAULT;
- }
+
break;
case SISFB_GET_INFO_SIZE:
- return put_user(sizeof(sisfb_info), argp);
+ return put_user(sizeof(struct sisfb_info), argp);
case SISFB_GET_INFO_OLD:
- if(ivideo->warncount++ < 50) {
- printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
- }
+ if(ivideo->warncount++ < 10)
+ printk(KERN_INFO
+ "sisfb: Deprecated ioctl call received - update your application!\n");
case SISFB_GET_INFO: /* For communication with X driver */
- x.sisfb_id = SISFB_ID;
- x.sisfb_version = VER_MAJOR;
- x.sisfb_revision = VER_MINOR;
- x.sisfb_patchlevel = VER_LEVEL;
- x.chip_id = ivideo->chip_id;
- x.memory = ivideo->video_size / 1024;
- x.heapstart = ivideo->heapstart / 1024;
+ ivideo->sisfb_infoblock.sisfb_id = SISFB_ID;
+ ivideo->sisfb_infoblock.sisfb_version = VER_MAJOR;
+ ivideo->sisfb_infoblock.sisfb_revision = VER_MINOR;
+ ivideo->sisfb_infoblock.sisfb_patchlevel = VER_LEVEL;
+ ivideo->sisfb_infoblock.chip_id = ivideo->chip_id;
+ ivideo->sisfb_infoblock.sisfb_pci_vendor = ivideo->chip_vendor;
+ ivideo->sisfb_infoblock.memory = ivideo->video_size / 1024;
+ ivideo->sisfb_infoblock.heapstart = ivideo->heapstart / 1024;
if(ivideo->modechanged) {
- x.fbvidmode = ivideo->mode_no;
+ ivideo->sisfb_infoblock.fbvidmode = ivideo->mode_no;
} else {
- x.fbvidmode = ivideo->modeprechange;
- }
- x.sisfb_caps = ivideo->caps;
- x.sisfb_tqlen = 512; /* yet fixed */
- x.sisfb_pcibus = ivideo->pcibus;
- x.sisfb_pcislot = ivideo->pcislot;
- x.sisfb_pcifunc = ivideo->pcifunc;
- x.sisfb_lcdpdc = ivideo->detectedpdc;
- x.sisfb_lcdpdca = ivideo->detectedpdca;
- x.sisfb_lcda = ivideo->detectedlcda;
- x.sisfb_vbflags = ivideo->vbflags;
- x.sisfb_currentvbflags = ivideo->currentvbflags;
- x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
- x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
- x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
- x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
- x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
- x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
- x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
- x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
- x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
- x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
-
- if(copy_to_user((void __user *)arg, &x, sizeof(x))) {
- return -EFAULT;
+ ivideo->sisfb_infoblock.fbvidmode = ivideo->modeprechange;
}
+ ivideo->sisfb_infoblock.sisfb_caps = ivideo->caps;
+ ivideo->sisfb_infoblock.sisfb_tqlen = ivideo->cmdQueueSize / 1024;
+ ivideo->sisfb_infoblock.sisfb_pcibus = ivideo->pcibus;
+ ivideo->sisfb_infoblock.sisfb_pcislot = ivideo->pcislot;
+ ivideo->sisfb_infoblock.sisfb_pcifunc = ivideo->pcifunc;
+ ivideo->sisfb_infoblock.sisfb_lcdpdc = ivideo->detectedpdc;
+ ivideo->sisfb_infoblock.sisfb_lcdpdca = ivideo->detectedpdca;
+ ivideo->sisfb_infoblock.sisfb_lcda = ivideo->detectedlcda;
+ ivideo->sisfb_infoblock.sisfb_vbflags = ivideo->vbflags;
+ ivideo->sisfb_infoblock.sisfb_currentvbflags = ivideo->currentvbflags;
+ ivideo->sisfb_infoblock.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
+ ivideo->sisfb_infoblock.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
+ ivideo->sisfb_infoblock.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
+ ivideo->sisfb_infoblock.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
+ ivideo->sisfb_infoblock.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
+ ivideo->sisfb_infoblock.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
+ ivideo->sisfb_infoblock.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
+ ivideo->sisfb_infoblock.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
+ ivideo->sisfb_infoblock.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
+ ivideo->sisfb_infoblock.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
+ ivideo->sisfb_infoblock.sisfb_heapsize = ivideo->sisfb_heap_size / 1024;
+ ivideo->sisfb_infoblock.sisfb_videooffset = ivideo->video_offset;
+ ivideo->sisfb_infoblock.sisfb_curfstn = ivideo->curFSTN;
+ ivideo->sisfb_infoblock.sisfb_curdstn = ivideo->curDSTN;
+ ivideo->sisfb_infoblock.sisfb_vbflags2 = ivideo->vbflags2;
+ ivideo->sisfb_infoblock.sisfb_can_post = ivideo->sisfb_can_post ? 1 : 0;
+ ivideo->sisfb_infoblock.sisfb_card_posted = ivideo->sisfb_card_posted ? 1 : 0;
+ ivideo->sisfb_infoblock.sisfb_was_boot_device = ivideo->sisfb_was_boot_device ? 1 : 0;
+
+ if(copy_to_user((void __user *)arg, &ivideo->sisfb_infoblock,
+ sizeof(ivideo->sisfb_infoblock)))
+ return -EFAULT;
+
break;
case SISFB_GET_VBRSTATUS_OLD:
- if(ivideo->warncount++ < 50) {
- printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
- }
+ if(ivideo->warncount++ < 10)
+ printk(KERN_INFO
+ "sisfb: Deprecated ioctl call received - update your application!\n");
case SISFB_GET_VBRSTATUS:
- if(sisfb_CheckVBRetrace(ivideo)) {
+ if(sisfb_CheckVBRetrace(ivideo))
return put_user((u32)1, argp);
- } else {
+ else
return put_user((u32)0, argp);
- }
case SISFB_GET_AUTOMAXIMIZE_OLD:
- if(ivideo->warncount++ < 50) {
- printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
- }
+ if(ivideo->warncount++ < 10)
+ printk(KERN_INFO
+ "sisfb: Deprecated ioctl call received - update your application!\n");
case SISFB_GET_AUTOMAXIMIZE:
- if(ivideo->sisfb_max) return put_user((u32)1, argp);
- else return put_user((u32)0, argp);
+ if(ivideo->sisfb_max)
+ return put_user((u32)1, argp);
+ else
+ return put_user((u32)0, argp);
case SISFB_SET_AUTOMAXIMIZE_OLD:
- if(ivideo->warncount++ < 50) {
- printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
- }
+ if(ivideo->warncount++ < 10)
+ printk(KERN_INFO
+ "sisfb: Deprecated ioctl call received - update your application!\n");
case SISFB_SET_AUTOMAXIMIZE:
- if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ if(get_user(gpu32, argp))
return -EFAULT;
- }
+
ivideo->sisfb_max = (gpu32) ? 1 : 0;
break;
case SISFB_SET_TVPOSOFFSET:
- if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ if(get_user(gpu32, argp))
return -EFAULT;
- }
+
sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
break;
case SISFB_GET_TVPOSOFFSET:
- return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
- argp);
+ return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)),
+ argp);
+
+ case SISFB_COMMAND:
+ if(copy_from_user(&ivideo->sisfb_command, (void __user *)arg,
+ sizeof(struct sisfb_cmd)))
+ return -EFAULT;
+
+ sisfb_handle_command(ivideo, &ivideo->sisfb_command);
+
+ if(copy_to_user((void __user *)arg, &ivideo->sisfb_command,
+ sizeof(struct sisfb_cmd)))
+ return -EFAULT;
+
+ break;
case SISFB_SET_LOCK:
- if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ if(get_user(gpu32, argp))
return -EFAULT;
- }
+
ivideo->sisfblocked = (gpu32) ? 1 : 0;
break;
default:
+#ifdef SIS_NEW_CONFIG_COMPAT
return -ENOIOCTLCMD;
+#else
+ return -EINVAL;
+#endif
}
return 0;
}
-#ifdef CONFIG_COMPAT
-static long sisfb_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg, struct fb_info *info)
+#ifdef SIS_NEW_CONFIG_COMPAT
+static long
+sisfb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg, struct fb_info *info)
{
int ret;
+
lock_kernel();
ret = sisfb_ioctl(NULL, f, cmd, arg, info);
unlock_kernel();
@@ -2219,7 +1946,7 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
strcpy(fix->id, ivideo->myid);
- fix->smem_start = ivideo->video_base;
+ fix->smem_start = ivideo->video_base + ivideo->video_offset;
fix->smem_len = ivideo->sisfb_mem;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -2231,11 +1958,17 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
fix->mmio_start = ivideo->mmio_base;
fix->mmio_len = ivideo->mmio_size;
if(ivideo->sisvga_engine == SIS_300_VGA) {
- fix->accel = FB_ACCEL_SIS_GLAMOUR;
- } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {
- fix->accel = FB_ACCEL_SIS_XABRE;
+ fix->accel = FB_ACCEL_SIS_GLAMOUR;
+ } else if((ivideo->chip == SIS_330) ||
+ (ivideo->chip == SIS_760) ||
+ (ivideo->chip == SIS_761)) {
+ fix->accel = FB_ACCEL_SIS_XABRE;
+ } else if(ivideo->chip == XGI_20) {
+ fix->accel = FB_ACCEL_XGI_VOLARI_Z;
+ } else if(ivideo->chip >= XGI_40) {
+ fix->accel = FB_ACCEL_XGI_VOLARI_V;
} else {
- fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
+ fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
}
return 0;
@@ -2251,40 +1984,41 @@ static struct fb_ops sisfb_ops = {
.fb_set_var = sisfb_set_var,
.fb_get_cmap = sisfb_get_cmap,
.fb_set_cmap = sisfb_set_cmap,
- .fb_pan_display = sisfb_pan_display,
+ .fb_pan_display = sisfb_pan_display,
.fb_ioctl = sisfb_ioctl
};
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
static struct fb_ops sisfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = sisfb_open,
- .fb_release = sisfb_release,
- .fb_check_var = sisfb_check_var,
- .fb_set_par = sisfb_set_par,
- .fb_setcolreg = sisfb_setcolreg,
- .fb_pan_display = sisfb_pan_display,
- .fb_blank = sisfb_blank,
- .fb_fillrect = fbcon_sis_fillrect,
- .fb_copyarea = fbcon_sis_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
- .fb_sync = fbcon_sis_sync,
- .fb_ioctl = sisfb_ioctl,
-#ifdef CONFIG_COMPAT
- .fb_compat_ioctl = sisfb_compat_ioctl,
+ .owner = THIS_MODULE,
+ .fb_open = sisfb_open,
+ .fb_release = sisfb_release,
+ .fb_check_var = sisfb_check_var,
+ .fb_set_par = sisfb_set_par,
+ .fb_setcolreg = sisfb_setcolreg,
+ .fb_pan_display = sisfb_pan_display,
+ .fb_blank = sisfb_blank,
+ .fb_fillrect = fbcon_sis_fillrect,
+ .fb_copyarea = fbcon_sis_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
+ .fb_sync = fbcon_sis_sync,
+#ifdef SIS_NEW_CONFIG_COMPAT
+ .fb_compat_ioctl= sisfb_compat_ioctl,
#endif
+ .fb_ioctl = sisfb_ioctl
};
#endif
/* ---------------- Chip generation dependent routines ---------------- */
-static struct pci_dev * sisfb_get_northbridge(int basechipid)
+static struct pci_dev * __devinit
+sisfb_get_northbridge(int basechipid)
{
struct pci_dev *pdev = NULL;
int nbridgenum, nbridgeidx, i;
- const unsigned short nbridgeids[] = {
+ static const unsigned short nbridgeids[] = {
PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */
PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */
PCI_DEVICE_ID_SI_730,
@@ -2292,13 +2026,14 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */
PCI_DEVICE_ID_SI_651,
PCI_DEVICE_ID_SI_740,
- PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760 VGA */
+ PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760/761 VGA */
PCI_DEVICE_ID_SI_741,
PCI_DEVICE_ID_SI_660,
- PCI_DEVICE_ID_SI_760
+ PCI_DEVICE_ID_SI_760,
+ PCI_DEVICE_ID_SI_761
};
- switch(basechipid) {
+ switch(basechipid) {
#ifdef CONFIG_FB_SIS_300
case SIS_540: nbridgeidx = 0; nbridgenum = 1; break;
case SIS_630: nbridgeidx = 1; nbridgenum = 2; break;
@@ -2306,35 +2041,40 @@ static struct pci_dev * sisfb_get_northbridge(int basechipid)
#ifdef CONFIG_FB_SIS_315
case SIS_550: nbridgeidx = 3; nbridgenum = 1; break;
case SIS_650: nbridgeidx = 4; nbridgenum = 3; break;
- case SIS_660: nbridgeidx = 7; nbridgenum = 4; break;
+ case SIS_660: nbridgeidx = 7; nbridgenum = 5; break;
#endif
default: return NULL;
}
for(i = 0; i < nbridgenum; i++) {
- if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;
+ if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI,
+ nbridgeids[nbridgeidx+i], NULL)))
+ break;
}
return pdev;
}
-static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
+static int __devinit
+sisfb_get_dram_size(struct sis_video_info *ivideo)
{
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
u8 reg;
#endif
ivideo->video_size = 0;
+ ivideo->UMAsize = ivideo->LFBsize = 0;
switch(ivideo->chip) {
#ifdef CONFIG_FB_SIS_300
case SIS_300:
- inSISIDXREG(SISSR, 0x14, reg);
+ inSISIDXREG(SISSR, 0x14, reg);
ivideo->video_size = ((reg & 0x3F) + 1) << 20;
break;
case SIS_540:
case SIS_630:
case SIS_730:
- if(!ivideo->nbridge) return -1;
- pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
+ if(!ivideo->nbridge)
+ return -1;
+ pci_read_config_byte(ivideo->nbridge, 0x63, &reg);
ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
break;
#endif
@@ -2342,45 +2082,68 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
case SIS_315H:
case SIS_315PRO:
case SIS_315:
- inSISIDXREG(SISSR, 0x14, reg);
+ inSISIDXREG(SISSR, 0x14, reg);
ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
switch((reg >> 2) & 0x03) {
case 0x01:
case 0x03:
- ivideo->video_size <<= 1;
- break;
+ ivideo->video_size <<= 1;
+ break;
case 0x02:
- ivideo->video_size += (ivideo->video_size/2);
+ ivideo->video_size += (ivideo->video_size/2);
}
- break;
+ break;
case SIS_330:
- inSISIDXREG(SISSR, 0x14, reg);
+ inSISIDXREG(SISSR, 0x14, reg);
ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
if(reg & 0x0c) ivideo->video_size <<= 1;
- break;
+ break;
case SIS_550:
case SIS_650:
case SIS_740:
- inSISIDXREG(SISSR, 0x14, reg);
+ inSISIDXREG(SISSR, 0x14, reg);
ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
break;
case SIS_661:
case SIS_741:
- inSISIDXREG(SISCR, 0x79, reg);
+ inSISIDXREG(SISCR, 0x79, reg);
ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
- break;
+ break;
case SIS_660:
case SIS_760:
+ case SIS_761:
inSISIDXREG(SISCR, 0x79, reg);
reg = (reg & 0xf0) >> 4;
- if(reg) ivideo->video_size = (1 << reg) << 20;
+ if(reg) {
+ ivideo->video_size = (1 << reg) << 20;
+ ivideo->UMAsize = ivideo->video_size;
+ }
inSISIDXREG(SISCR, 0x78, reg);
reg &= 0x30;
if(reg) {
- if(reg == 0x10) ivideo->video_size += (32 << 20);
- else ivideo->video_size += (64 << 20);
+ if(reg == 0x10) {
+ ivideo->LFBsize = (32 << 20);
+ } else {
+ ivideo->LFBsize = (64 << 20);
+ }
+ ivideo->video_size += ivideo->LFBsize;
}
- break;
+ break;
+ case SIS_340:
+ case XGI_20:
+ case XGI_40:
+ inSISIDXREG(SISSR, 0x14, reg);
+ ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+ if(ivideo->chip != XGI_20) {
+ reg = (reg & 0x0c) >> 2;
+ if(ivideo->revision_id == 2) {
+ if(reg & 0x01) reg = 0x02;
+ else reg = 0x00;
+ }
+ if(reg == 0x02) ivideo->video_size <<= 1;
+ else if(reg == 0x03) ivideo->video_size <<= 2;
+ }
+ break;
#endif
default:
return -1;
@@ -2390,17 +2153,24 @@ static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
/* -------------- video bridge device detection --------------- */
-static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_detect_VB_connect(struct sis_video_info *ivideo)
{
u8 cr32, temp;
+ /* No CRT2 on XGI Z7 */
+ if(ivideo->chip == XGI_20) {
+ ivideo->sisfb_crt1off = 0;
+ return;
+ }
+
#ifdef CONFIG_FB_SIS_300
if(ivideo->sisvga_engine == SIS_300_VGA) {
inSISIDXREG(SISSR, 0x17, temp);
if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
/* PAL/NTSC is stored on SR16 on such machines */
if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
- inSISIDXREG(SISSR, 0x16, temp);
+ inSISIDXREG(SISSR, 0x16, temp);
if(temp & 0x20)
ivideo->vbflags |= TV_PAL;
else
@@ -2435,28 +2205,29 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
if(ivideo->sisfb_tvplug != -1) {
if( (ivideo->sisvga_engine != SIS_315_VGA) ||
- (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {
+ (!(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) ) {
if(ivideo->sisfb_tvplug & TV_YPBPR) {
- ivideo->sisfb_tvplug = -1;
+ ivideo->sisfb_tvplug = -1;
printk(KERN_ERR "sisfb: YPbPr not supported\n");
}
}
}
if(ivideo->sisfb_tvplug != -1) {
if( (ivideo->sisvga_engine != SIS_315_VGA) ||
- (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) {
+ (!(ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) ) {
if(ivideo->sisfb_tvplug & TV_HIVISION) {
- ivideo->sisfb_tvplug = -1;
+ ivideo->sisfb_tvplug = -1;
printk(KERN_ERR "sisfb: HiVision not supported\n");
}
}
}
if(ivideo->sisfb_tvstd != -1) {
- if( (!(ivideo->vbflags & VB_SISBRIDGE)) &&
- (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) {
+ if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) &&
+ (!((ivideo->sisvga_engine == SIS_315_VGA) &&
+ (ivideo->vbflags2 & VB2_CHRONTEL))) ) {
if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
- ivideo->sisfb_tvstd = -1;
- printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
+ ivideo->sisfb_tvstd = -1;
+ printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
}
}
}
@@ -2468,7 +2239,7 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION;
else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART;
- else {
+ else {
if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO;
if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
}
@@ -2485,165 +2256,44 @@ static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
}
if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
if(ivideo->sisvga_engine == SIS_300_VGA) {
- inSISIDXREG(SISSR, 0x38, temp);
+ inSISIDXREG(SISSR, 0x38, temp);
if(temp & 0x01) ivideo->vbflags |= TV_PAL;
else ivideo->vbflags |= TV_NTSC;
} else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
- inSISIDXREG(SISSR, 0x38, temp);
+ inSISIDXREG(SISSR, 0x38, temp);
if(temp & 0x01) ivideo->vbflags |= TV_PAL;
else ivideo->vbflags |= TV_NTSC;
- } else {
- inSISIDXREG(SISCR, 0x79, temp);
+ } else {
+ inSISIDXREG(SISCR, 0x79, temp);
if(temp & 0x20) ivideo->vbflags |= TV_PAL;
else ivideo->vbflags |= TV_NTSC;
- }
+ }
}
}
/* Copy forceCRT1 option to CRT1off if option is given */
- if(ivideo->sisfb_forcecrt1 != -1) {
- ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
- }
-}
-
-static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
-{
- char stdstr[] = "sisfb: Detected";
- char bridgestr[] = "video bridge";
- u8 vb_chipid;
- u8 reg;
-
- inSISIDXREG(SISPART4, 0x00, vb_chipid);
- switch(vb_chipid) {
- case 0x01:
- inSISIDXREG(SISPART4, 0x01, reg);
- if(reg < 0xb0) {
- ivideo->vbflags |= VB_301;
- printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
- } else if(reg < 0xc0) {
- ivideo->vbflags |= VB_301B;
- inSISIDXREG(SISPART4,0x23,reg);
- if(!(reg & 0x02)) {
- ivideo->vbflags |= VB_30xBDH;
- printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
- } else {
- printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
- }
- } else if(reg < 0xd0) {
- ivideo->vbflags |= VB_301C;
- printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
- } else if(reg < 0xe0) {
- ivideo->vbflags |= VB_301LV;
- printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
- } else if(reg <= 0xe1) {
- inSISIDXREG(SISPART4,0x39,reg);
- if(reg == 0xff) {
- ivideo->vbflags |= VB_302LV;
- printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
- } else {
- ivideo->vbflags |= VB_301C;
- printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
-#if 0
- ivideo->vbflags |= VB_302ELV;
- printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
-#endif
- }
- }
- break;
- case 0x02:
- ivideo->vbflags |= VB_302B;
- printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
- break;
- }
-
- if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
- inSISIDXREG(SISCR, 0x37, reg);
- reg &= SIS_EXTERNAL_CHIP_MASK;
- reg >>= 1;
- if(ivideo->sisvga_engine == SIS_300_VGA) {
-#ifdef CONFIG_FB_SIS_300
- switch(reg) {
- case SIS_EXTERNAL_CHIP_LVDS:
- ivideo->vbflags |= VB_LVDS;
- break;
- case SIS_EXTERNAL_CHIP_TRUMPION:
- ivideo->vbflags |= VB_TRUMPION;
- break;
- case SIS_EXTERNAL_CHIP_CHRONTEL:
- ivideo->vbflags |= VB_CHRONTEL;
- break;
- case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
- ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
- break;
- }
- if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
-#endif
- } else if(ivideo->chip < SIS_661) {
-#ifdef CONFIG_FB_SIS_315
- switch (reg) {
- case SIS310_EXTERNAL_CHIP_LVDS:
- ivideo->vbflags |= VB_LVDS;
- break;
- case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
- ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
- break;
- }
- if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
-#endif
- } else if(ivideo->chip >= SIS_661) {
-#ifdef CONFIG_FB_SIS_315
- inSISIDXREG(SISCR, 0x38, reg);
- reg >>= 5;
- switch(reg) {
- case 0x02:
- ivideo->vbflags |= VB_LVDS;
- break;
- case 0x03:
- ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
- break;
- case 0x04:
- ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
- break;
- }
- if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
-#endif
- }
- if(ivideo->vbflags & VB_LVDS) {
- printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
- }
- if(ivideo->vbflags & VB_TRUMPION) {
- printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
- }
- if(ivideo->vbflags & VB_CHRONTEL) {
- printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
- }
- if(ivideo->vbflags & VB_CONEXANT) {
- printk(KERN_INFO "%s Conexant external device\n", stdstr);
- }
- }
-
- if(ivideo->vbflags & VB_SISBRIDGE) {
- SiS_Sense30x(ivideo);
- } else if(ivideo->vbflags & VB_CHRONTEL) {
- SiS_SenseCh(ivideo);
+ if(ivideo->sisfb_forcecrt1 != -1) {
+ ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
}
}
/* ------------------ Sensing routines ------------------ */
-static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo)
+static BOOLEAN __devinit
+sisfb_test_DDC1(struct sis_video_info *ivideo)
{
unsigned short old;
int count = 48;
old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
do {
- if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
+ if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
} while(count--);
return (count == -1) ? FALSE : TRUE;
}
-static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_sense_crt1(struct sis_video_info *ivideo)
{
BOOLEAN mustwait = FALSE;
u8 sr1F, cr17;
@@ -2699,7 +2349,8 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
if(temp == 0xffff) {
i = 3;
do {
- temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL);
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
+ ivideo->sisvga_engine, 0, 0, NULL, ivideo->vbflags2);
} while(((temp == 0) || (temp == 0xffff)) && i--);
if((temp == 0) || (temp == 0xffff)) {
@@ -2723,7 +2374,96 @@ static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
}
/* Determine and detect attached devices on SiS30x */
-static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
+static void __devinit
+SiS_SenseLCD(struct sis_video_info *ivideo)
+{
+ unsigned char buffer[256];
+ unsigned short temp, realcrtno, i;
+ u8 reg, cr37 = 0, paneltype = 0;
+ u16 xres, yres;
+
+ ivideo->SiS_Pr.PanelSelfDetected = FALSE;
+
+ /* LCD detection only for TMDS bridges */
+ if(!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE))
+ return;
+ if(ivideo->vbflags2 & VB2_30xBDH)
+ return;
+
+ /* If LCD already set up by BIOS, skip it */
+ inSISIDXREG(SISCR, 0x32, reg);
+ if(reg & 0x08)
+ return;
+
+ realcrtno = 1;
+ if(ivideo->SiS_Pr.DDCPortMixup)
+ realcrtno = 0;
+
+ /* Check DDC capabilities */
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+ realcrtno, 0, &buffer[0], ivideo->vbflags2);
+
+ if((!temp) || (temp == 0xffff) || (!(temp & 0x02)))
+ return;
+
+ /* Read DDC data */
+ i = 3; /* Number of retrys */
+ do {
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags,
+ ivideo->sisvga_engine, realcrtno, 1,
+ &buffer[0], ivideo->vbflags2);
+ } while((temp) && i--);
+
+ if(temp)
+ return;
+
+ /* No digital device */
+ if(!(buffer[0x14] & 0x80))
+ return;
+
+ /* First detailed timing preferred timing? */
+ if(!(buffer[0x18] & 0x02))
+ return;
+
+ xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+ yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+ switch(xres) {
+ case 1024:
+ if(yres == 768)
+ paneltype = 0x02;
+ break;
+ case 1280:
+ if(yres == 1024)
+ paneltype = 0x03;
+ break;
+ case 1600:
+ if((yres == 1200) && (ivideo->vbflags2 & VB2_30xC))
+ paneltype = 0x0b;
+ break;
+ }
+
+ if(!paneltype)
+ return;
+
+ if(buffer[0x23])
+ cr37 |= 0x10;
+
+ if((buffer[0x47] & 0x18) == 0x18)
+ cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+ else
+ cr37 |= 0xc0;
+
+ outSISIDXREG(SISCR, 0x36, paneltype);
+ cr37 &= 0xf1;
+ setSISIDXREG(SISCR, 0x37, 0x0c, cr37);
+ orSISIDXREG(SISCR, 0x32, 0x08);
+
+ ivideo->SiS_Pr.PanelSelfDetected = TRUE;
+}
+
+static int __devinit
+SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
{
int temp, mytest, result, i, j;
@@ -2749,10 +2489,11 @@ static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 tes
}
if((result == 0) || (result >= 2)) break;
}
- return(result);
+ return result;
}
-static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
+static void __devinit
+SiS_Sense30x(struct sis_video_info *ivideo)
{
u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
u16 svhs=0, svhs_c=0;
@@ -2762,36 +2503,51 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
char stdstr[] = "sisfb: Detected";
char tvstr[] = "TV connected to";
- if(ivideo->vbflags & VB_301) {
+ if(ivideo->vbflags2 & VB2_301) {
svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
inSISIDXREG(SISPART4,0x01,myflag);
if(myflag & 0x04) {
svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
}
- } else if(ivideo->vbflags & (VB_301B | VB_302B)) {
+ } else if(ivideo->vbflags2 & (VB2_301B | VB2_302B)) {
svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
- } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) {
+ } else if(ivideo->vbflags2 & (VB2_301LV | VB2_302LV)) {
svhs = 0x0200; cvbs = 0x0100;
- } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) {
+ } else if(ivideo->vbflags2 & (VB2_301C | VB2_302ELV | VB2_307T | VB2_307LV)) {
svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
- } else return;
+ } else
+ return;
vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
- if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ if(ivideo->vbflags & (VB2_301LV|VB2_302LV|VB2_302ELV|VB2_307LV)) {
svhs_c = 0x0408; cvbs_c = 0x0808;
}
+
biosflag = 2;
+ if(ivideo->haveXGIROM) {
+ biosflag = ivideo->bios_abase[0x58] & 0x03;
+ } else if(ivideo->newrom) {
+ if(ivideo->bios_abase[0x5d] & 0x04) biosflag |= 0x01;
+ } else if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->bios_abase) {
+ biosflag = ivideo->bios_abase[0xfe] & 0x03;
+ }
+ }
if(ivideo->chip == SIS_300) {
inSISIDXREG(SISSR,0x3b,myflag);
if(!(myflag & 0x01)) vga2 = vga2_c = 0;
}
+ if(!(ivideo->vbflags2 & VB2_SISVGA2BRIDGE)) {
+ vga2 = vga2_c = 0;
+ }
+
inSISIDXREG(SISSR,0x1e,backupSR_1e);
orSISIDXREG(SISSR,0x1e,0x20);
inSISIDXREG(SISPART4,0x0d,backupP4_0d);
- if(ivideo->vbflags & VB_301C) {
+ if(ivideo->vbflags2 & VB2_30xC) {
setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
} else {
orSISIDXREG(SISPART4,0x0d,0x04);
@@ -2802,11 +2558,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
inSISIDXREG(SISPART2,0x4d,backupP2_4d);
- if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) {
+ if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) {
outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
}
- if(!(ivideo->vbflags & VB_301C)) {
+ if(!(ivideo->vbflags2 & VB2_30xCLV)) {
SISDoSense(ivideo, 0, 0);
}
@@ -2826,12 +2582,11 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
andSISIDXREG(SISCR, 0x32, 0x3f);
- if(ivideo->vbflags & VB_301C) {
+ if(ivideo->vbflags2 & VB2_30xCLV) {
orSISIDXREG(SISPART4,0x0d,0x04);
}
- if((ivideo->sisvga_engine == SIS_315_VGA) &&
- (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
+ if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
if((result = SISDoSense(ivideo, svhs, 0x0604))) {
@@ -2864,7 +2619,7 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
outSISIDXREG(SISPART4,0x0d,backupP4_0d);
outSISIDXREG(SISSR,0x1e,backupSR_1e);
- if(ivideo->vbflags & VB_301C) {
+ if(ivideo->vbflags2 & VB2_30xCLV) {
inSISIDXREG(SISPART2,0x00,biosflag);
if(biosflag & 0x20) {
for(myflag = 2; myflag > 0; myflag--) {
@@ -2878,7 +2633,8 @@ static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
}
/* Determine and detect attached TV's on Chrontel */
-static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
+static void __devinit
+SiS_SenseCh(struct sis_video_info *ivideo)
{
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
u8 temp1, temp2;
@@ -2899,7 +2655,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
/* See Chrontel TB31 for explanation */
temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
- SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e, 0x0b);
SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
}
temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
@@ -2909,15 +2665,15 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
/* Read power status */
temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
if((temp1 & 0x03) != 0x03) {
- /* Power all outputs */
- SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E);
+ /* Power all outputs */
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0e,0x0b);
SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
}
/* Sense connected TV devices */
for(i = 0; i < 3; i++) {
- SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x01);
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
- SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x10, 0x00);
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
if(!(temp1 & 0x08)) test[i] = 0x02;
@@ -2930,7 +2686,7 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
else if(test[0] == test[2]) temp1 = test[0];
else if(test[1] == test[2]) temp1 = test[1];
else {
- printk(KERN_INFO
+ printk(KERN_INFO
"sisfb: TV detection unreliable - test results varied\n");
temp1 = test[2];
}
@@ -2945,11 +2701,11 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
orSISIDXREG(SISCR, 0x32, 0x01);
andSISIDXREG(SISCR, 0x32, ~0x06);
} else {
- SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
andSISIDXREG(SISCR, 0x32, ~0x07);
}
} else if(temp1 == 0) {
- SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8);
andSISIDXREG(SISCR, 0x32, ~0x07);
}
/* Set general purpose IO for Chrontel communication */
@@ -2960,19 +2716,19 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
#ifdef CONFIG_FB_SIS_315
ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
- temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
- SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049);
+ temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
+ SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, 0x20);
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
temp2 |= 0x01;
- SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+ SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
temp2 ^= 0x01;
- SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+ SiS_SetCH701x(&ivideo->SiS_Pr, 0x20, temp2);
SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
- SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49);
- temp1 = 0;
+ SiS_SetCH701x(&ivideo->SiS_Pr, 0x49, temp1);
+ temp1 = 0;
if(temp2 & 0x02) temp1 |= 0x01;
if(temp2 & 0x10) temp1 |= 0x01;
if(temp2 & 0x04) temp1 |= 0x02;
@@ -2983,18 +2739,18 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
ivideo->vbflags |= TV_AVIDEO;
orSISIDXREG(SISCR, 0x32, 0x01);
andSISIDXREG(SISCR, 0x32, ~0x06);
- break;
+ break;
case 0x02:
printk(KERN_INFO "%s SVIDEO output\n", stdstr);
ivideo->vbflags |= TV_SVIDEO;
orSISIDXREG(SISCR, 0x32, 0x02);
andSISIDXREG(SISCR, 0x32, ~0x05);
- break;
+ break;
case 0x04:
printk(KERN_INFO "%s SCART output\n", stdstr);
orSISIDXREG(SISCR, 0x32, 0x04);
andSISIDXREG(SISCR, 0x32, ~0x03);
- break;
+ break;
default:
andSISIDXREG(SISCR, 0x32, ~0x07);
}
@@ -3002,165 +2758,589 @@ static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
}
}
-/* ------------------------ Heap routines -------------------------- */
-
-static u32 __devinit
-sisfb_getheapstart(struct sis_video_info *ivideo)
+static void __devinit
+sisfb_get_VB_type(struct sis_video_info *ivideo)
{
- u32 ret = ivideo->sisfb_parm_mem * 1024;
- u32 max = ivideo->video_size - ivideo->hwcursor_size;
- u32 def;
+ char stdstr[] = "sisfb: Detected";
+ char bridgestr[] = "video bridge";
+ u8 vb_chipid;
+ u8 reg;
- /* Calculate heap start = end of memory for console
- *
- * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
- * C = console, D = heap, H = HWCursor, Q = cmd-queue
- *
- * Basically given by "mem" parameter
- *
- * maximum = videosize - cmd_queue - hwcursor
- * (results in a heap of size 0)
- * default = SiS 300: depends on videosize
- * SiS 315/330: 32k below max
- */
+ /* No CRT2 on XGI Z7 */
+ if(ivideo->chip == XGI_20)
+ return;
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- max -= TURBO_QUEUE_AREA_SIZE;
- if(ivideo->video_size > 0x1000000) {
- def = 0xc00000;
- } else if(ivideo->video_size > 0x800000) {
- def = 0x800000;
- } else {
- def = 0x400000;
- }
- } else {
- max -= COMMAND_QUEUE_AREA_SIZE;
- def = max - 0x8000;
+ inSISIDXREG(SISPART4, 0x00, vb_chipid);
+ switch(vb_chipid) {
+ case 0x01:
+ inSISIDXREG(SISPART4, 0x01, reg);
+ if(reg < 0xb0) {
+ ivideo->vbflags |= VB_301; /* Deprecated */
+ ivideo->vbflags2 |= VB2_301;
+ printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
+ } else if(reg < 0xc0) {
+ ivideo->vbflags |= VB_301B; /* Deprecated */
+ ivideo->vbflags2 |= VB2_301B;
+ inSISIDXREG(SISPART4,0x23,reg);
+ if(!(reg & 0x02)) {
+ ivideo->vbflags |= VB_30xBDH; /* Deprecated */
+ ivideo->vbflags2 |= VB2_30xBDH;
+ printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
+ } else {
+ printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
+ }
+ } else if(reg < 0xd0) {
+ ivideo->vbflags |= VB_301C; /* Deprecated */
+ ivideo->vbflags2 |= VB2_301C;
+ printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
+ } else if(reg < 0xe0) {
+ ivideo->vbflags |= VB_301LV; /* Deprecated */
+ ivideo->vbflags2 |= VB2_301LV;
+ printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
+ } else if(reg <= 0xe1) {
+ inSISIDXREG(SISPART4,0x39,reg);
+ if(reg == 0xff) {
+ ivideo->vbflags |= VB_302LV; /* Deprecated */
+ ivideo->vbflags2 |= VB2_302LV;
+ printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
+ } else {
+ ivideo->vbflags |= VB_301C; /* Deprecated */
+ ivideo->vbflags2 |= VB2_301C;
+ printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
+#if 0
+ ivideo->vbflags |= VB_302ELV; /* Deprecated */
+ ivideo->vbflags2 |= VB2_302ELV;
+ printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
+#endif
+ }
+ }
+ break;
+ case 0x02:
+ ivideo->vbflags |= VB_302B; /* Deprecated */
+ ivideo->vbflags2 |= VB2_302B;
+ printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
+ break;
}
- if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) {
- ret = def;
- }
+ if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
+ inSISIDXREG(SISCR, 0x37, reg);
+ reg &= SIS_EXTERNAL_CHIP_MASK;
+ reg >>= 1;
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
+ switch(reg) {
+ case SIS_EXTERNAL_CHIP_LVDS:
+ ivideo->vbflags |= VB_LVDS; /* Deprecated */
+ ivideo->vbflags2 |= VB2_LVDS;
+ break;
+ case SIS_EXTERNAL_CHIP_TRUMPION:
+ ivideo->vbflags |= (VB_LVDS | VB_TRUMPION); /* Deprecated */
+ ivideo->vbflags2 |= (VB2_LVDS | VB2_TRUMPION);
+ break;
+ case SIS_EXTERNAL_CHIP_CHRONTEL:
+ ivideo->vbflags |= VB_CHRONTEL; /* Deprecated */
+ ivideo->vbflags2 |= VB2_CHRONTEL;
+ break;
+ case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
+ ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+ break;
+ }
+ if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 1;
+#endif
+ } else if(ivideo->chip < SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+ switch (reg) {
+ case SIS310_EXTERNAL_CHIP_LVDS:
+ ivideo->vbflags |= VB_LVDS; /* Deprecated */
+ ivideo->vbflags2 |= VB2_LVDS;
+ break;
+ case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
+ ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+ break;
+ }
+ if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+ } else if(ivideo->chip >= SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+ inSISIDXREG(SISCR, 0x38, reg);
+ reg >>= 5;
+ switch(reg) {
+ case 0x02:
+ ivideo->vbflags |= VB_LVDS; /* Deprecated */
+ ivideo->vbflags2 |= VB2_LVDS;
+ break;
+ case 0x03:
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL); /* Deprecated */
+ ivideo->vbflags2 |= (VB2_LVDS | VB2_CHRONTEL);
+ break;
+ case 0x04:
+ ivideo->vbflags |= (VB_LVDS | VB_CONEXANT); /* Deprecated */
+ ivideo->vbflags2 |= (VB2_LVDS | VB2_CONEXANT);
+ break;
+ }
+ if(ivideo->vbflags2 & VB2_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+ }
+ if(ivideo->vbflags2 & VB2_LVDS) {
+ printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
+ }
+ if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags2 & VB2_TRUMPION)) {
+ printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
+ }
+ if(ivideo->vbflags2 & VB2_CHRONTEL) {
+ printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
+ }
+ if((ivideo->chip >= SIS_661) && (ivideo->vbflags2 & VB2_CONEXANT)) {
+ printk(KERN_INFO "%s Conexant external device\n", stdstr);
+ }
+ }
- return ret;
+ if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+ SiS_SenseLCD(ivideo);
+ SiS_Sense30x(ivideo);
+ } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
+ SiS_SenseCh(ivideo);
+ }
}
-static int __devinit
-sisfb_heap_init(struct sis_video_info *ivideo)
+/* ---------- Engine initialization routines ------------ */
+
+static void
+sisfb_engine_init(struct sis_video_info *ivideo)
{
- SIS_OH *poh;
- ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo);
+ /* Initialize command queue (we use MMIO only) */
- ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
- ivideo->sisfb_heap_end = ivideo->video_vbase + ivideo->video_size;
+ /* BEFORE THIS IS CALLED, THE ENGINES *MUST* BE SYNC'ED */
- /* Initialize command queue (We use MMIO only) */
+ ivideo->caps &= ~(TURBO_QUEUE_CAP |
+ MMIO_CMD_QUEUE_CAP |
+ VM_CMD_QUEUE_CAP |
+ AGP_CMD_QUEUE_CAP);
+
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ u32 tqueue_pos;
+ u8 tq_state;
+
+ tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024);
+
+ inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+ tq_state |= 0xf0;
+ tq_state &= 0xfc;
+ tq_state |= (u8)(tqueue_pos >> 8);
+ outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+
+ outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
+
+ ivideo->caps |= TURBO_QUEUE_CAP;
+ }
+#endif
#ifdef CONFIG_FB_SIS_315
- if(ivideo->sisvga_engine == SIS_315_VGA) {
- u32 tempq = 0;
- u8 temp = 0;
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ u32 tempq = 0, templ;
+ u8 temp;
+
+ if(ivideo->chip == XGI_20) {
+ switch(ivideo->cmdQueueSize) {
+ case (64 * 1024):
+ temp = SIS_CMD_QUEUE_SIZE_Z7_64k;
+ break;
+ case (128 * 1024):
+ default:
+ temp = SIS_CMD_QUEUE_SIZE_Z7_128k;
+ }
+ } else {
+ switch(ivideo->cmdQueueSize) {
+ case (4 * 1024 * 1024):
+ temp = SIS_CMD_QUEUE_SIZE_4M;
+ break;
+ case (2 * 1024 * 1024):
+ temp = SIS_CMD_QUEUE_SIZE_2M;
+ break;
+ case (1 * 1024 * 1024):
+ temp = SIS_CMD_QUEUE_SIZE_1M;
+ break;
+ default:
+ case (512 * 1024):
+ temp = SIS_CMD_QUEUE_SIZE_512k;
+ }
+ }
+
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+
+ if((ivideo->chip >= XGI_40) && ivideo->modechanged) {
+ /* Must disable dual pipe on XGI_40. Can't do
+ * this in MMIO mode, because it requires
+ * setting/clearing a bit in the MMIO fire trigger
+ * register.
+ */
+ if(!((templ = MMIO_IN32(ivideo->mmio_vbase, 0x8240)) & (1 << 10))) {
+
+ MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0);
+
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE));
+
+ tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR);
+ MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq);
+
+ tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
+ MMIO_OUT32(ivideo->mmio_vbase, Q_BASE_ADDR, tempq);
+
+ writel(0x16800000 + 0x8240, ivideo->video_vbase + tempq);
+ writel(templ | (1 << 10), ivideo->video_vbase + tempq + 4);
+ writel(0x168F0000, ivideo->video_vbase + tempq + 8);
+ writel(0x168F0000, ivideo->video_vbase + tempq + 12);
+
+ MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, (tempq + 16));
+
+ sisfb_syncaccel(ivideo);
+
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+
+ }
+ }
+
+ tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
+ MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
+
+ temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+
+ tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize);
+ MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
- ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
+ ivideo->caps |= MMIO_CMD_QUEUE_CAP;
+ }
+#endif
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+ ivideo->engineok = 1;
+}
- tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
- MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
+static void __devinit
+sisfb_detect_lcd_type(struct sis_video_info *ivideo)
+{
+ u8 reg;
+ int i;
- temp = SIS_CMD_QUEUE_SIZE_512k;
- temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+ inSISIDXREG(SISCR, 0x36, reg);
+ reg &= 0x0f;
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ ivideo->CRT2LCDType = sis300paneltype[reg];
+ } else if(ivideo->chip >= SIS_661) {
+ ivideo->CRT2LCDType = sis661paneltype[reg];
+ } else {
+ ivideo->CRT2LCDType = sis310paneltype[reg];
+ if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
+ if((ivideo->CRT2LCDType != LCD_320x240_2) &&
+ (ivideo->CRT2LCDType != LCD_320x240_3)) {
+ ivideo->CRT2LCDType = LCD_320x240;
+ }
+ }
+ }
- tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE);
- MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
+ if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
+ /* For broken BIOSes: Assume 1024x768, RGB18 */
+ ivideo->CRT2LCDType = LCD_1024x768;
+ setSISIDXREG(SISCR,0x36,0xf0,0x02);
+ setSISIDXREG(SISCR,0x37,0xee,0x01);
+ printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
+ }
- ivideo->caps |= MMIO_CMD_QUEUE_CAP;
- }
+ for(i = 0; i < SIS_LCD_NUMBER; i++) {
+ if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
+ ivideo->lcdxres = sis_lcd_data[i].xres;
+ ivideo->lcdyres = sis_lcd_data[i].yres;
+ ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
+ break;
+ }
+ }
+
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+ ivideo->lcdxres = 1360; ivideo->lcdyres = 1024;
+ ivideo->lcddefmodeidx = DEFAULT_MODE_1360;
+ } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+ ivideo->lcdxres = 848; ivideo->lcdyres = 480;
+ ivideo->lcddefmodeidx = DEFAULT_MODE_848;
+ } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL856) {
+ ivideo->lcdxres = 856; ivideo->lcdyres = 480;
+ ivideo->lcddefmodeidx = DEFAULT_MODE_856;
+ }
#endif
+ printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
+ ivideo->lcdxres, ivideo->lcdyres);
+}
+
+static void __devinit
+sisfb_save_pdc_emi(struct sis_video_info *ivideo)
+{
#ifdef CONFIG_FB_SIS_300
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- unsigned long tqueue_pos;
- u8 tq_state;
+ /* Save the current PanelDelayCompensation if the LCD is currently used */
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) {
+ int tmp;
+ inSISIDXREG(SISCR,0x30,tmp);
+ if(tmp & 0x20) {
+ /* Currently on LCD? If yes, read current pdc */
+ inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
+ ivideo->detectedpdc &= 0x3c;
+ if(ivideo->SiS_Pr.PDC == -1) {
+ /* Let option override detection */
+ ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+ }
+ printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
+ ivideo->detectedpdc);
+ }
+ if((ivideo->SiS_Pr.PDC != -1) &&
+ (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
+ ivideo->SiS_Pr.PDC);
+ }
+ }
+ }
+#endif
- ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
- tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
+ /* Try to find about LCDA */
+ if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) {
+ int tmp;
+ inSISIDXREG(SISPART1,0x13,tmp);
+ if(tmp & 0x04) {
+ ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
+ ivideo->detectedlcda = 0x03;
+ }
+ }
- inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
- tq_state |= 0xf0;
- tq_state &= 0xfc;
- tq_state |= (u8)(tqueue_pos >> 8);
- outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+ /* Save PDC */
+ if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) {
+ int tmp;
+ inSISIDXREG(SISCR,0x30,tmp);
+ if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+ /* Currently on LCD? If yes, read current pdc */
+ u8 pdc;
+ inSISIDXREG(SISPART1,0x2D,pdc);
+ ivideo->detectedpdc = (pdc & 0x0f) << 1;
+ ivideo->detectedpdca = (pdc & 0xf0) >> 3;
+ inSISIDXREG(SISPART1,0x35,pdc);
+ ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
+ inSISIDXREG(SISPART1,0x20,pdc);
+ ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
+ if(ivideo->newrom) {
+ /* New ROM invalidates other PDC resp. */
+ if(ivideo->detectedlcda != 0xff) {
+ ivideo->detectedpdc = 0xff;
+ } else {
+ ivideo->detectedpdca = 0xff;
+ }
+ }
+ if(ivideo->SiS_Pr.PDC == -1) {
+ if(ivideo->detectedpdc != 0xff) {
+ ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+ }
+ }
+ if(ivideo->SiS_Pr.PDCA == -1) {
+ if(ivideo->detectedpdca != 0xff) {
+ ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
+ }
+ }
+ if(ivideo->detectedpdc != 0xff) {
+ printk(KERN_INFO
+ "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
+ ivideo->detectedpdc);
+ }
+ if(ivideo->detectedpdca != 0xff) {
+ printk(KERN_INFO
+ "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
+ ivideo->detectedpdca);
+ }
+ }
- outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
+ /* Save EMI */
+ if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) {
+ inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
+ inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
+ inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
+ inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
+ ivideo->SiS_Pr.HaveEMI = TRUE;
+ if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+ ivideo->SiS_Pr.HaveEMILCD = TRUE;
+ }
+ }
+ }
- ivideo->caps |= TURBO_QUEUE_CAP;
- }
+ /* Let user override detected PDCs (all bridges) */
+ if(ivideo->vbflags2 & VB2_30xBLV) {
+ if((ivideo->SiS_Pr.PDC != -1) &&
+ (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
+ ivideo->SiS_Pr.PDC);
+ }
+ if((ivideo->SiS_Pr.PDCA != -1) &&
+ (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
+ ivideo->SiS_Pr.PDCA);
+ }
+ }
+
+ }
#endif
+}
- /* Reserve memory for the HWCursor */
- ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
- ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
- ivideo->caps |= HW_CURSOR_CAP;
+/* -------------------- Memory manager routines ---------------------- */
- ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start;
+static u32 __devinit
+sisfb_getheapstart(struct sis_video_info *ivideo)
+{
+ u32 ret = ivideo->sisfb_parm_mem * 1024;
+ u32 maxoffs = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
+ u32 def;
- if(ivideo->cardnumber == 0) {
+ /* Calculate heap start = end of memory for console
+ *
+ * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
+ * C = console, D = heap, H = HWCursor, Q = cmd-queue
+ *
+ * On 76x in UMA+LFB mode, the layout is as follows:
+ * DDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCHHHHQQQQQQQQQQQ
+ * where the heap is the entire UMA area, eventually
+ * into the LFB area if the given mem parameter is
+ * higher than the size of the UMA memory.
+ *
+ * Basically given by "mem" parameter
+ *
+ * maximum = videosize - cmd_queue - hwcursor
+ * (results in a heap of size 0)
+ * default = SiS 300: depends on videosize
+ * SiS 315/330/340/XGI: 32k below max
+ */
- printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
- (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->video_size > 0x1000000) {
+ def = 0xc00000;
+ } else if(ivideo->video_size > 0x800000) {
+ def = 0x800000;
+ } else {
+ def = 0x400000;
+ }
+ } else if(ivideo->UMAsize && ivideo->LFBsize) {
+ ret = def = 0;
+ } else {
+ def = maxoffs - 0x8000;
+ }
- sisfb_heap.vinfo = ivideo;
+ /* Use default for secondary card for now (FIXME) */
+ if((!ret) || (ret > maxoffs) || (ivideo->cardnumber != 0))
+ ret = def;
- sisfb_heap.poha_chain = NULL;
- sisfb_heap.poh_freelist = NULL;
+ return ret;
+}
- poh = sisfb_poh_new_node();
- if(poh == NULL) return 1;
+static u32 __devinit
+sisfb_getheapsize(struct sis_video_info *ivideo)
+{
+ u32 max = ivideo->video_size - ivideo->hwcursor_size - ivideo->cmdQueueSize;
+ u32 ret = 0;
+
+ if(ivideo->UMAsize && ivideo->LFBsize) {
+ if( (!ivideo->sisfb_parm_mem) ||
+ ((ivideo->sisfb_parm_mem * 1024) > max) ||
+ ((max - (ivideo->sisfb_parm_mem * 1024)) < ivideo->UMAsize) ) {
+ ret = ivideo->UMAsize;
+ max -= ivideo->UMAsize;
+ } else {
+ ret = max - (ivideo->sisfb_parm_mem * 1024);
+ max = ivideo->sisfb_parm_mem * 1024;
+ }
+ ivideo->video_offset = ret;
+ ivideo->sisfb_mem = max;
+ } else {
+ ret = max - ivideo->heapstart;
+ ivideo->sisfb_mem = ivideo->heapstart;
+ }
- poh->poh_next = &sisfb_heap.oh_free;
- poh->poh_prev = &sisfb_heap.oh_free;
- poh->size = ivideo->sisfb_heap_size;
- poh->offset = ivideo->heapstart;
+ return ret;
+}
- sisfb_heap.oh_free.poh_next = poh;
- sisfb_heap.oh_free.poh_prev = poh;
- sisfb_heap.oh_free.size = 0;
- sisfb_heap.max_freesize = poh->size;
+static int __devinit
+sisfb_heap_init(struct sis_video_info *ivideo)
+{
+ struct SIS_OH *poh;
- sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
- sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
- sisfb_heap.oh_used.size = SENTINEL;
+ ivideo->video_offset = 0;
+ if(ivideo->sisfb_parm_mem) {
+ if( (ivideo->sisfb_parm_mem < (2 * 1024 * 1024)) ||
+ (ivideo->sisfb_parm_mem > ivideo->video_size) ) {
+ ivideo->sisfb_parm_mem = 0;
+ }
+ }
- } else {
+ ivideo->heapstart = sisfb_getheapstart(ivideo);
+ ivideo->sisfb_heap_size = sisfb_getheapsize(ivideo);
- printk(KERN_INFO "Skipped heap initialization for secondary cards\n");
+ ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
+ ivideo->sisfb_heap_end = ivideo->sisfb_heap_start + ivideo->sisfb_heap_size;
- }
+ printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
+ (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
- return 0;
+ ivideo->sisfb_heap.vinfo = ivideo;
+
+ ivideo->sisfb_heap.poha_chain = NULL;
+ ivideo->sisfb_heap.poh_freelist = NULL;
+
+ poh = sisfb_poh_new_node(&ivideo->sisfb_heap);
+ if(poh == NULL)
+ return 1;
+
+ poh->poh_next = &ivideo->sisfb_heap.oh_free;
+ poh->poh_prev = &ivideo->sisfb_heap.oh_free;
+ poh->size = ivideo->sisfb_heap_size;
+ poh->offset = ivideo->heapstart;
+
+ ivideo->sisfb_heap.oh_free.poh_next = poh;
+ ivideo->sisfb_heap.oh_free.poh_prev = poh;
+ ivideo->sisfb_heap.oh_free.size = 0;
+ ivideo->sisfb_heap.max_freesize = poh->size;
+
+ ivideo->sisfb_heap.oh_used.poh_next = &ivideo->sisfb_heap.oh_used;
+ ivideo->sisfb_heap.oh_used.poh_prev = &ivideo->sisfb_heap.oh_used;
+ ivideo->sisfb_heap.oh_used.size = SENTINEL;
+
+ if(ivideo->cardnumber == 0) {
+ /* For the first card, make this heap the "global" one
+ * for old DRM (which could handle only one card)
+ */
+ sisfb_heap = &ivideo->sisfb_heap;
+ }
+
+ return 0;
}
-static SIS_OH *
-sisfb_poh_new_node(void)
+static struct SIS_OH *
+sisfb_poh_new_node(struct SIS_HEAP *memheap)
{
- int i;
- unsigned long cOhs;
- SIS_OHALLOC *poha;
- SIS_OH *poh;
+ struct SIS_OHALLOC *poha;
+ struct SIS_OH *poh;
+ unsigned long cOhs;
+ int i;
- if(sisfb_heap.poh_freelist == NULL) {
+ if(memheap->poh_freelist == NULL) {
poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
- if(!poha) return NULL;
+ if(!poha)
+ return NULL;
- poha->poha_next = sisfb_heap.poha_chain;
- sisfb_heap.poha_chain = poha;
+ poha->poha_next = memheap->poha_chain;
+ memheap->poha_chain = poha;
- cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
+ cOhs = (SIS_OH_ALLOC_SIZE - sizeof(struct SIS_OHALLOC)) / sizeof(struct SIS_OH) + 1;
poh = &poha->aoh[0];
for(i = cOhs - 1; i != 0; i--) {
@@ -3169,32 +3349,32 @@ sisfb_poh_new_node(void)
}
poh->poh_next = NULL;
- sisfb_heap.poh_freelist = &poha->aoh[0];
+ memheap->poh_freelist = &poha->aoh[0];
}
- poh = sisfb_heap.poh_freelist;
- sisfb_heap.poh_freelist = poh->poh_next;
+ poh = memheap->poh_freelist;
+ memheap->poh_freelist = poh->poh_next;
- return (poh);
+ return poh;
}
-static SIS_OH *
-sisfb_poh_allocate(u32 size)
+static struct SIS_OH *
+sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size)
{
- SIS_OH *pohThis;
- SIS_OH *pohRoot;
- int bAllocated = 0;
+ struct SIS_OH *pohThis;
+ struct SIS_OH *pohRoot;
+ int bAllocated = 0;
- if(size > sisfb_heap.max_freesize) {
+ if(size > memheap->max_freesize) {
DPRINTK("sisfb: Can't allocate %dk video memory\n",
(unsigned int) size / 1024);
- return (NULL);
+ return NULL;
}
- pohThis = sisfb_heap.oh_free.poh_next;
+ pohThis = memheap->oh_free.poh_next;
- while(pohThis != &sisfb_heap.oh_free) {
- if (size <= pohThis->size) {
+ while(pohThis != &memheap->oh_free) {
+ if(size <= pohThis->size) {
bAllocated = 1;
break;
}
@@ -3204,18 +3384,16 @@ sisfb_poh_allocate(u32 size)
if(!bAllocated) {
DPRINTK("sisfb: Can't allocate %dk video memory\n",
(unsigned int) size / 1024);
- return (NULL);
+ return NULL;
}
if(size == pohThis->size) {
pohRoot = pohThis;
sisfb_delete_node(pohThis);
} else {
- pohRoot = sisfb_poh_new_node();
-
- if(pohRoot == NULL) {
- return (NULL);
- }
+ pohRoot = sisfb_poh_new_node(memheap);
+ if(pohRoot == NULL)
+ return NULL;
pohRoot->offset = pohThis->offset;
pohRoot->size = size;
@@ -3224,33 +3402,25 @@ sisfb_poh_allocate(u32 size)
pohThis->size -= size;
}
- sisfb_heap.max_freesize -= size;
+ memheap->max_freesize -= size;
- pohThis = &sisfb_heap.oh_used;
+ pohThis = &memheap->oh_used;
sisfb_insert_node(pohThis, pohRoot);
- return (pohRoot);
+ return pohRoot;
}
static void
-sisfb_delete_node(SIS_OH *poh)
+sisfb_delete_node(struct SIS_OH *poh)
{
- SIS_OH *poh_prev;
- SIS_OH *poh_next;
-
- poh_prev = poh->poh_prev;
- poh_next = poh->poh_next;
-
- poh_prev->poh_next = poh_next;
- poh_next->poh_prev = poh_prev;
+ poh->poh_prev->poh_next = poh->poh_next;
+ poh->poh_next->poh_prev = poh->poh_prev;
}
static void
-sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
+sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh)
{
- SIS_OH *pohTemp;
-
- pohTemp = pohList->poh_next;
+ struct SIS_OH *pohTemp = pohList->poh_next;
pohList->poh_next = poh;
pohTemp->poh_prev = poh;
@@ -3259,20 +3429,20 @@ sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
poh->poh_next = pohTemp;
}
-static SIS_OH *
-sisfb_poh_free(u32 base)
+static struct SIS_OH *
+sisfb_poh_free(struct SIS_HEAP *memheap, u32 base)
{
- SIS_OH *pohThis;
- SIS_OH *poh_freed;
- SIS_OH *poh_prev;
- SIS_OH *poh_next;
- u32 ulUpper;
- u32 ulLower;
- int foundNode = 0;
+ struct SIS_OH *pohThis;
+ struct SIS_OH *poh_freed;
+ struct SIS_OH *poh_prev;
+ struct SIS_OH *poh_next;
+ u32 ulUpper;
+ u32 ulLower;
+ int foundNode = 0;
- poh_freed = sisfb_heap.oh_used.poh_next;
+ poh_freed = memheap->oh_used.poh_next;
- while(poh_freed != &sisfb_heap.oh_used) {
+ while(poh_freed != &memheap->oh_used) {
if(poh_freed->offset == base) {
foundNode = 1;
break;
@@ -3281,17 +3451,18 @@ sisfb_poh_free(u32 base)
poh_freed = poh_freed->poh_next;
}
- if(!foundNode) return(NULL);
+ if(!foundNode)
+ return NULL;
- sisfb_heap.max_freesize += poh_freed->size;
+ memheap->max_freesize += poh_freed->size;
poh_prev = poh_next = NULL;
ulUpper = poh_freed->offset + poh_freed->size;
ulLower = poh_freed->offset;
- pohThis = sisfb_heap.oh_free.poh_next;
+ pohThis = memheap->oh_free.poh_next;
- while(pohThis != &sisfb_heap.oh_free) {
+ while(pohThis != &memheap->oh_free) {
if(pohThis->offset == ulUpper) {
poh_next = pohThis;
} else if((pohThis->offset + pohThis->size) == ulLower) {
@@ -3305,70 +3476,88 @@ sisfb_poh_free(u32 base)
if(poh_prev && poh_next) {
poh_prev->size += (poh_freed->size + poh_next->size);
sisfb_delete_node(poh_next);
- sisfb_free_node(poh_freed);
- sisfb_free_node(poh_next);
- return(poh_prev);
+ sisfb_free_node(memheap, poh_freed);
+ sisfb_free_node(memheap, poh_next);
+ return poh_prev;
}
if(poh_prev) {
poh_prev->size += poh_freed->size;
- sisfb_free_node(poh_freed);
- return(poh_prev);
+ sisfb_free_node(memheap, poh_freed);
+ return poh_prev;
}
if(poh_next) {
poh_next->size += poh_freed->size;
poh_next->offset = poh_freed->offset;
- sisfb_free_node(poh_freed);
- return(poh_next);
+ sisfb_free_node(memheap, poh_freed);
+ return poh_next;
}
- sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
+ sisfb_insert_node(&memheap->oh_free, poh_freed);
- return(poh_freed);
+ return poh_freed;
}
static void
-sisfb_free_node(SIS_OH *poh)
+sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh)
{
- if(poh == NULL) return;
+ if(poh == NULL)
+ return;
- poh->poh_next = sisfb_heap.poh_freelist;
- sisfb_heap.poh_freelist = poh;
+ poh->poh_next = memheap->poh_freelist;
+ memheap->poh_freelist = poh;
}
-void
-sis_malloc(struct sis_memreq *req)
+static void
+sis_int_malloc(struct sis_video_info *ivideo, struct sis_memreq *req)
{
- struct sis_video_info *ivideo = sisfb_heap.vinfo;
- SIS_OH *poh = NULL;
+ struct SIS_OH *poh = NULL;
- if((ivideo) && (!ivideo->havenoheap)) {
- poh = sisfb_poh_allocate((u32)req->size);
- }
+ if((ivideo) && (ivideo->sisfb_id == SISFB_ID) && (!ivideo->havenoheap))
+ poh = sisfb_poh_allocate(&ivideo->sisfb_heap, (u32)req->size);
if(poh == NULL) {
- req->offset = req->size = 0;
- DPRINTK("sisfb: Video RAM allocation failed\n");
+ req->offset = req->size = 0;
+ DPRINTK("sisfb: Video RAM allocation failed\n");
} else {
- req->offset = poh->offset;
- req->size = poh->size;
- DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
- (poh->offset + ivideo->video_vbase));
+ req->offset = poh->offset;
+ req->size = poh->size;
+ DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
+ (poh->offset + ivideo->video_vbase));
}
}
-/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
+void
+sis_malloc(struct sis_memreq *req)
+{
+ struct sis_video_info *ivideo = sisfb_heap->vinfo;
+
+ if(&ivideo->sisfb_heap == sisfb_heap)
+ sis_int_malloc(ivideo, req);
+ else
+ req->offset = req->size = 0;
+}
void
-sis_free(u32 base)
+sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req)
{
- struct sis_video_info *ivideo = sisfb_heap.vinfo;
- SIS_OH *poh;
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+ sis_int_malloc(ivideo, req);
+}
+
+/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
- if((!ivideo) || (ivideo->havenoheap)) return;
+static void
+sis_int_free(struct sis_video_info *ivideo, u32 base)
+{
+ struct SIS_OH *poh;
- poh = sisfb_poh_free((u32)base);
+ if((!ivideo) || (ivideo->sisfb_id != SISFB_ID) || (ivideo->havenoheap))
+ return;
+
+ poh = sisfb_poh_free(&ivideo->sisfb_heap, base);
if(poh == NULL) {
DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
@@ -3376,9 +3565,63 @@ sis_free(u32 base)
}
}
+void
+sis_free(u32 base)
+{
+ struct sis_video_info *ivideo = sisfb_heap->vinfo;
+
+ sis_int_free(ivideo, base);
+}
+
+void
+sis_free_new(struct pci_dev *pdev, u32 base)
+{
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+ sis_int_free(ivideo, base);
+}
+
/* --------------------- SetMode routines ------------------------- */
static void
+sisfb_check_engine_and_sync(struct sis_video_info *ivideo)
+{
+ u8 cr30, cr31;
+
+ /* Check if MMIO and engines are enabled,
+ * and sync in case they are. Can't use
+ * ivideo->accel here, as this might have
+ * been changed before this is called.
+ */
+ inSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, cr30);
+ inSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, cr31);
+ /* MMIO and 2D/3D engine enabled? */
+ if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) {
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ /* Don't care about TurboQueue. It's
+ * enough to know that the engines
+ * are enabled
+ */
+ sisfb_syncaccel(ivideo);
+ }
+#endif
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ /* Check that any queue mode is
+ * enabled, and that the queue
+ * is not in the state of "reset"
+ */
+ inSISIDXREG(SISSR, 0x26, cr30);
+ if((cr30 & 0xe0) && (!(cr30 & 0x01))) {
+ sisfb_syncaccel(ivideo);
+ }
+ }
+#endif
+ }
+}
+
+static void
sisfb_pre_setmode(struct sis_video_info *ivideo)
{
u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
@@ -3386,6 +3629,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
+ outSISIDXREG(SISSR, 0x05, 0x86);
+
inSISIDXREG(SISCR, 0x31, cr31);
cr31 &= ~0x60;
cr31 |= 0x04;
@@ -3413,41 +3658,43 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->curFSTN = ivideo->curDSTN = 0;
switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
case CRT2_TV:
cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */
- if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) {
+ if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) {
#ifdef CONFIG_FB_SIS_315
- if(ivideo->chip >= SIS_661) {
- cr38 |= 0x04;
- if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
+ if(ivideo->chip >= SIS_661) {
+ cr38 |= 0x04;
+ if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40;
else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
cr35 &= ~0x01;
ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
- } else if(ivideo->sisvga_engine == SIS_315_VGA) {
- cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+ cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
cr38 |= 0x08;
- if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
+ if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20;
else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
cr31 &= ~0x01;
ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
- }
-#endif
- } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) {
- if(ivideo->chip >= SIS_661) {
- cr38 |= 0x04;
- cr35 |= 0x60;
- } else {
- cr30 |= 0x80;
- }
+ }
+#endif
+ } else if((ivideo->vbflags & TV_HIVISION) &&
+ (ivideo->vbflags2 & VB2_SISHIVISIONBRIDGE)) {
+ if(ivideo->chip >= SIS_661) {
+ cr38 |= 0x04;
+ cr35 |= 0x60;
+ } else {
+ cr30 |= 0x80;
+ }
cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
- cr31 |= 0x01;
- cr35 |= 0x01;
+ cr31 |= 0x01;
+ cr35 |= 0x01;
ivideo->currentvbflags |= TV_HIVISION;
} else if(ivideo->vbflags & TV_SCART) {
cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
@@ -3466,8 +3713,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
}
cr31 |= SIS_DRIVER_MODE;
- if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) {
- if(ivideo->vbflags & TV_PAL) {
+ if(ivideo->vbflags & (TV_AVIDEO | TV_SVIDEO)) {
+ if(ivideo->vbflags & TV_PAL) {
cr31 |= 0x01; cr35 |= 0x01;
ivideo->currentvbflags |= TV_PAL;
if(ivideo->vbflags & TV_PALM) {
@@ -3476,14 +3723,14 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
} else if(ivideo->vbflags & TV_PALN) {
cr38 |= 0x80; cr35 |= 0x08;
ivideo->currentvbflags |= TV_PALN;
- }
- } else {
+ }
+ } else {
cr31 &= ~0x01; cr35 &= ~0x01;
ivideo->currentvbflags |= TV_NTSC;
if(ivideo->vbflags & TV_NTSCJ) {
cr38 |= 0x40; cr35 |= 0x02;
ivideo->currentvbflags |= TV_NTSCJ;
- }
+ }
}
}
break;
@@ -3493,6 +3740,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
cr31 |= SIS_DRIVER_MODE;
SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
+ ivideo->curFSTN = ivideo->sisfb_fstn;
+ ivideo->curDSTN = ivideo->sisfb_dstn;
break;
case CRT2_VGA:
@@ -3525,9 +3774,9 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
}
outSISIDXREG(SISCR, 0x31, cr31);
- if(ivideo->accel) sisfb_syncaccel(ivideo);
-
ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
+
+ sisfb_check_engine_and_sync(ivideo);
}
/* Fix SR11 for 661 and later */
@@ -3535,125 +3784,129 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
static void
sisfb_fixup_SR11(struct sis_video_info *ivideo)
{
- u8 tmpreg;
-
- if(ivideo->chip >= SIS_661) {
- inSISIDXREG(SISSR,0x11,tmpreg);
- if(tmpreg & 0x20) {
- inSISIDXREG(SISSR,0x3e,tmpreg);
- tmpreg = (tmpreg + 1) & 0xff;
- outSISIDXREG(SISSR,0x3e,tmpreg);
- inSISIDXREG(SISSR,0x11,tmpreg);
- }
- if(tmpreg & 0xf0) {
- andSISIDXREG(SISSR,0x11,0x0f);
- }
- }
+ u8 tmpreg;
+
+ if(ivideo->chip >= SIS_661) {
+ inSISIDXREG(SISSR,0x11,tmpreg);
+ if(tmpreg & 0x20) {
+ inSISIDXREG(SISSR,0x3e,tmpreg);
+ tmpreg = (tmpreg + 1) & 0xff;
+ outSISIDXREG(SISSR,0x3e,tmpreg);
+ inSISIDXREG(SISSR,0x11,tmpreg);
+ }
+ if(tmpreg & 0xf0) {
+ andSISIDXREG(SISSR,0x11,0x0f);
+ }
+ }
}
#endif
-static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
+static void
+sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
{
- if(val > 32) val = 32;
- if(val < -32) val = -32;
- ivideo->tvxpos = val;
+ if(val > 32) val = 32;
+ if(val < -32) val = -32;
+ ivideo->tvxpos = val;
- if(ivideo->sisfblocked) return;
- if(!ivideo->modechanged) return;
+ if(ivideo->sisfblocked) return;
+ if(!ivideo->modechanged) return;
- if(ivideo->currentvbflags & CRT2_TV) {
+ if(ivideo->currentvbflags & CRT2_TV) {
- if(ivideo->vbflags & VB_CHRONTEL) {
+ if(ivideo->vbflags2 & VB2_CHRONTEL) {
- int x = ivideo->tvx;
+ int x = ivideo->tvx;
- switch(ivideo->chronteltype) {
- case 1:
- x += val;
- if(x < 0) x = 0;
- outSISIDXREG(SISSR,0x05,0x86);
- SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
- SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
- break;
- case 2:
- /* Not supported by hardware */
- break;
- }
-
- } else if(ivideo->vbflags & VB_SISBRIDGE) {
-
- u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
- unsigned short temp;
-
- p2_1f = ivideo->p2_1f;
- p2_20 = ivideo->p2_20;
- p2_2b = ivideo->p2_2b;
- p2_42 = ivideo->p2_42;
- p2_43 = ivideo->p2_43;
-
- temp = p2_1f | ((p2_20 & 0xf0) << 4);
- temp += (val * 2);
- p2_1f = temp & 0xff;
- p2_20 = (temp & 0xf00) >> 4;
- p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
- temp = p2_43 | ((p2_42 & 0xf0) << 4);
- temp += (val * 2);
- p2_43 = temp & 0xff;
- p2_42 = (temp & 0xf00) >> 4;
- outSISIDXREG(SISPART2,0x1f,p2_1f);
- setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
- setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
- setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
- outSISIDXREG(SISPART2,0x43,p2_43);
- }
- }
+ switch(ivideo->chronteltype) {
+ case 1:
+ x += val;
+ if(x < 0) x = 0;
+ outSISIDXREG(SISSR,0x05,0x86);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff));
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD);
+ break;
+ case 2:
+ /* Not supported by hardware */
+ break;
+ }
+
+ } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+
+ u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
+ unsigned short temp;
+
+ p2_1f = ivideo->p2_1f;
+ p2_20 = ivideo->p2_20;
+ p2_2b = ivideo->p2_2b;
+ p2_42 = ivideo->p2_42;
+ p2_43 = ivideo->p2_43;
+
+ temp = p2_1f | ((p2_20 & 0xf0) << 4);
+ temp += (val * 2);
+ p2_1f = temp & 0xff;
+ p2_20 = (temp & 0xf00) >> 4;
+ p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
+ temp = p2_43 | ((p2_42 & 0xf0) << 4);
+ temp += (val * 2);
+ p2_43 = temp & 0xff;
+ p2_42 = (temp & 0xf00) >> 4;
+ outSISIDXREG(SISPART2,0x1f,p2_1f);
+ setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
+ setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
+ setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
+ outSISIDXREG(SISPART2,0x43,p2_43);
+ }
+ }
}
-static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
+static void
+sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
{
- if(val > 32) val = 32;
- if(val < -32) val = -32;
- ivideo->tvypos = val;
-
- if(ivideo->sisfblocked) return;
- if(!ivideo->modechanged) return;
-
- if(ivideo->currentvbflags & CRT2_TV) {
-
- if(ivideo->vbflags & VB_CHRONTEL) {
-
- int y = ivideo->tvy;
-
- switch(ivideo->chronteltype) {
- case 1:
- y -= val;
- if(y < 0) y = 0;
- outSISIDXREG(SISSR,0x05,0x86);
- SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
- SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
- break;
- case 2:
- /* Not supported by hardware */
- break;
- }
-
- } else if(ivideo->vbflags & VB_SISBRIDGE) {
-
- char p2_01, p2_02;
- val /= 2;
- p2_01 = ivideo->p2_01;
- p2_02 = ivideo->p2_02;
-
- p2_01 += val;
- p2_02 += val;
- while((p2_01 <= 0) || (p2_02 <= 0)) {
- p2_01 += 2;
- p2_02 += 2;
- }
- outSISIDXREG(SISPART2,0x01,p2_01);
- outSISIDXREG(SISPART2,0x02,p2_02);
- }
- }
+ if(val > 32) val = 32;
+ if(val < -32) val = -32;
+ ivideo->tvypos = val;
+
+ if(ivideo->sisfblocked) return;
+ if(!ivideo->modechanged) return;
+
+ if(ivideo->currentvbflags & CRT2_TV) {
+
+ if(ivideo->vbflags2 & VB2_CHRONTEL) {
+
+ int y = ivideo->tvy;
+
+ switch(ivideo->chronteltype) {
+ case 1:
+ y -= val;
+ if(y < 0) y = 0;
+ outSISIDXREG(SISSR,0x05,0x86);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff));
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE);
+ break;
+ case 2:
+ /* Not supported by hardware */
+ break;
+ }
+
+ } else if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+
+ char p2_01, p2_02;
+ val /= 2;
+ p2_01 = ivideo->p2_01;
+ p2_02 = ivideo->p2_02;
+
+ p2_01 += val;
+ p2_02 += val;
+ if(!(ivideo->currentvbflags & (TV_HIVISION | TV_YPBPR))) {
+ while((p2_01 <= 0) || (p2_02 <= 0)) {
+ p2_01 += 2;
+ p2_02 += 2;
+ }
+ }
+ outSISIDXREG(SISPART2,0x01,p2_01);
+ outSISIDXREG(SISPART2,0x02,p2_02);
+ }
+ }
}
static void
@@ -3668,207 +3921,172 @@ sisfb_post_setmode(struct sis_video_info *ivideo)
u8 reg1;
#endif
- outSISIDXREG(SISSR,0x05,0x86);
+ outSISIDXREG(SISSR, 0x05, 0x86);
#ifdef CONFIG_FB_SIS_315
sisfb_fixup_SR11(ivideo);
#endif
/* Now we actually HAVE changed the display mode */
- ivideo->modechanged = 1;
+ ivideo->modechanged = 1;
/* We can't switch off CRT1 if bridge is in slave mode */
- if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+ if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
- } else ivideo->sisfb_crt1off = 0;
+ } else
+ ivideo->sisfb_crt1off = 0;
#ifdef CONFIG_FB_SIS_300
if(ivideo->sisvga_engine == SIS_300_VGA) {
- if((ivideo->sisfb_crt1off) && (doit)) {
- crt1isoff = TRUE;
- reg = 0x00;
- } else {
- crt1isoff = FALSE;
- reg = 0x80;
- }
- setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+ if((ivideo->sisfb_crt1off) && (doit)) {
+ crt1isoff = TRUE;
+ reg = 0x00;
+ } else {
+ crt1isoff = FALSE;
+ reg = 0x80;
+ }
+ setSISIDXREG(SISCR, 0x17, 0x7f, reg);
}
#endif
#ifdef CONFIG_FB_SIS_315
if(ivideo->sisvga_engine == SIS_315_VGA) {
- if((ivideo->sisfb_crt1off) && (doit)) {
- crt1isoff = TRUE;
- reg = 0x40;
- reg1 = 0xc0;
- } else {
- crt1isoff = FALSE;
- reg = 0x00;
- reg1 = 0x00;
-
- }
- setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
- setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
+ if((ivideo->sisfb_crt1off) && (doit)) {
+ crt1isoff = TRUE;
+ reg = 0x40;
+ reg1 = 0xc0;
+ } else {
+ crt1isoff = FALSE;
+ reg = 0x00;
+ reg1 = 0x00;
+ }
+ setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
+ setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
}
#endif
if(crt1isoff) {
- ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
- ivideo->currentvbflags |= VB_SINGLE_MODE;
+ ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
+ ivideo->currentvbflags |= VB_SINGLE_MODE;
} else {
- ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
- if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
- ivideo->currentvbflags |= VB_MIRROR_MODE;
- } else {
- ivideo->currentvbflags |= VB_SINGLE_MODE;
- }
+ ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
+ if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
+ ivideo->currentvbflags |= VB_MIRROR_MODE;
+ } else {
+ ivideo->currentvbflags |= VB_SINGLE_MODE;
+ }
}
- andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+ andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
if(ivideo->currentvbflags & CRT2_TV) {
- if(ivideo->vbflags & VB_SISBRIDGE) {
- inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
- inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
- inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
- inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
- inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
- inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
- inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
- } else if(ivideo->vbflags & VB_CHRONTEL) {
- if(ivideo->chronteltype == 1) {
- ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
- ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
- ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
- ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
- }
- }
+ if(ivideo->vbflags2 & VB2_SISBRIDGE) {
+ inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
+ inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
+ inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
+ inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
+ inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
+ inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
+ inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
+ } else if(ivideo->vbflags2 & VB2_CHRONTEL) {
+ if(ivideo->chronteltype == 1) {
+ ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
+ ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
+ ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
+ ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
+ }
+ }
}
if(ivideo->tvxpos) {
- sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
+ sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
}
if(ivideo->tvypos) {
- sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
+ sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
}
- if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) { /* Set filter for SiS301 */
+ /* Eventually sync engines */
+ sisfb_check_engine_and_sync(ivideo);
- unsigned char filter_tb = 0;
+ /* (Re-)Initialize chip engines */
+ if(ivideo->accel) {
+ sisfb_engine_init(ivideo);
+ } else {
+ ivideo->engineok = 0;
+ }
+}
- switch (ivideo->video_width) {
- case 320:
- filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12;
- break;
- case 640:
- filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
- break;
- case 720:
- filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
- break;
- case 400:
- case 800:
- filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
- break;
- default:
- ivideo->sisfb_filter = -1;
- break;
- }
+static int
+sisfb_reset_mode(struct sis_video_info *ivideo)
+{
+ if(sisfb_set_mode(ivideo, 0))
+ return 1;
- orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
+ sisfb_set_pitch(ivideo);
+ sisfb_set_base_CRT1(ivideo, ivideo->current_base);
+ sisfb_set_base_CRT2(ivideo, ivideo->current_base);
- if(ivideo->vbflags & TV_NTSC) {
-
- andSISIDXREG(SISPART2, 0x3a, 0x1f);
-
- if (ivideo->vbflags & TV_SVIDEO) {
-
- andSISIDXREG(SISPART2, 0x30, 0xdf);
-
- } else if (ivideo->vbflags & TV_AVIDEO) {
-
- orSISIDXREG(SISPART2, 0x30, 0x20);
-
- switch (ivideo->video_width) {
- case 640:
- outSISIDXREG(SISPART2, 0x35, 0xEB);
- outSISIDXREG(SISPART2, 0x36, 0x04);
- outSISIDXREG(SISPART2, 0x37, 0x25);
- outSISIDXREG(SISPART2, 0x38, 0x18);
- break;
- case 720:
- outSISIDXREG(SISPART2, 0x35, 0xEE);
- outSISIDXREG(SISPART2, 0x36, 0x0C);
- outSISIDXREG(SISPART2, 0x37, 0x22);
- outSISIDXREG(SISPART2, 0x38, 0x08);
- break;
- case 400:
- case 800:
- outSISIDXREG(SISPART2, 0x35, 0xEB);
- outSISIDXREG(SISPART2, 0x36, 0x15);
- outSISIDXREG(SISPART2, 0x37, 0x25);
- outSISIDXREG(SISPART2, 0x38, 0xF6);
- break;
- }
- }
+ return 0;
+}
+
+static void
+sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_command)
+{
+ int mycrt1off;
- } else if(ivideo->vbflags & TV_PAL) {
-
- andSISIDXREG(SISPART2, 0x3A, 0x1F);
-
- if (ivideo->vbflags & TV_SVIDEO) {
-
- andSISIDXREG(SISPART2, 0x30, 0xDF);
-
- } else if (ivideo->vbflags & TV_AVIDEO) {
-
- orSISIDXREG(SISPART2, 0x30, 0x20);
-
- switch (ivideo->video_width) {
- case 640:
- outSISIDXREG(SISPART2, 0x35, 0xF1);
- outSISIDXREG(SISPART2, 0x36, 0xF7);
- outSISIDXREG(SISPART2, 0x37, 0x1F);
- outSISIDXREG(SISPART2, 0x38, 0x32);
- break;
- case 720:
- outSISIDXREG(SISPART2, 0x35, 0xF3);
- outSISIDXREG(SISPART2, 0x36, 0x00);
- outSISIDXREG(SISPART2, 0x37, 0x1D);
- outSISIDXREG(SISPART2, 0x38, 0x20);
- break;
- case 400:
- case 800:
- outSISIDXREG(SISPART2, 0x35, 0xFC);
- outSISIDXREG(SISPART2, 0x36, 0xFB);
- outSISIDXREG(SISPART2, 0x37, 0x14);
- outSISIDXREG(SISPART2, 0x38, 0x2A);
- break;
+ switch(sisfb_command->sisfb_cmd) {
+ case SISFB_CMD_GETVBFLAGS:
+ if(!ivideo->modechanged) {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
+ } else {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+ sisfb_command->sisfb_result[1] = ivideo->currentvbflags;
+ sisfb_command->sisfb_result[2] = ivideo->vbflags2;
+ }
+ break;
+ case SISFB_CMD_SWITCHCRT1:
+ /* arg[0]: 0 = off, 1 = on, 99 = query */
+ if(!ivideo->modechanged) {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_EARLY;
+ } else if(sisfb_command->sisfb_arg[0] == 99) {
+ /* Query */
+ sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+ } else if(ivideo->sisfblocked) {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_LOCKED;
+ } else if((!(ivideo->currentvbflags & CRT2_ENABLE)) &&
+ (sisfb_command->sisfb_arg[0] == 0)) {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_NOCRT2;
+ } else {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OK;
+ mycrt1off = sisfb_command->sisfb_arg[0] ? 0 : 1;
+ if( ((ivideo->currentvbflags & VB_DISPTYPE_CRT1) && mycrt1off) ||
+ ((!(ivideo->currentvbflags & VB_DISPTYPE_CRT1)) && !mycrt1off) ) {
+ ivideo->sisfb_crt1off = mycrt1off;
+ if(sisfb_reset_mode(ivideo)) {
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_OTHER;
}
}
+ sisfb_command->sisfb_result[1] = ivideo->sisfb_crt1off ? 0 : 1;
}
-
- if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) {
- outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0]));
- outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1]));
- outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2]));
- outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3]));
- }
-
+ break;
+ /* more to come */
+ default:
+ sisfb_command->sisfb_result[0] = SISFB_CMD_ERR_UNKNOWN;
+ printk(KERN_ERR "sisfb: Unknown command 0x%x\n",
+ sisfb_command->sisfb_cmd);
}
}
#ifndef MODULE
-SISINITSTATIC int __init sisfb_setup(char *options)
+SISINITSTATIC int __init
+sisfb_setup(char *options)
{
char *this_opt;
-
- sisfb_setdefaultparms();
- printk(KERN_DEBUG "sisfb: Options %s\n", options);
+ sisfb_setdefaultparms();
- if(!options || !(*options)) {
+ if(!options || !(*options))
return 0;
- }
while((this_opt = strsep(&options, ",")) != NULL) {
@@ -3880,9 +4098,9 @@ SISINITSTATIC int __init sisfb_setup(char *options)
/* Need to check crt2 type first for fstn/dstn */
sisfb_search_crt2type(this_opt + 14);
} else if(!strnicmp(this_opt, "tvmode:",7)) {
- sisfb_search_tvstd(this_opt + 7);
- } else if(!strnicmp(this_opt, "tvstandard:",11)) {
sisfb_search_tvstd(this_opt + 7);
+ } else if(!strnicmp(this_opt, "tvstandard:",11)) {
+ sisfb_search_tvstd(this_opt + 11);
} else if(!strnicmp(this_opt, "mode:", 5)) {
sisfb_search_mode(this_opt + 5, FALSE);
} else if(!strnicmp(this_opt, "vesa:", 5)) {
@@ -3892,74 +4110,72 @@ SISINITSTATIC int __init sisfb_setup(char *options)
sisfb_inverse = 1;
/* fb_invert_cmaps(); */
} else if(!strnicmp(this_opt, "font:", 5)) {
- if(strlen(this_opt + 5) < 40) {
+ if(strlen(this_opt + 5) < 40) {
strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
}
#endif
} else if(!strnicmp(this_opt, "rate:", 5)) {
sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
- } else if(!strnicmp(this_opt, "filter:", 7)) {
- sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
} else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
- } else if(!strnicmp(this_opt, "mem:",4)) {
- sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
+ } else if(!strnicmp(this_opt, "mem:",4)) {
+ sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
} else if(!strnicmp(this_opt, "pdc:", 4)) {
- sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
+ sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
} else if(!strnicmp(this_opt, "pdc1:", 5)) {
- sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
+ sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
} else if(!strnicmp(this_opt, "noaccel", 7)) {
sisfb_accel = 0;
} else if(!strnicmp(this_opt, "accel", 5)) {
sisfb_accel = -1;
} else if(!strnicmp(this_opt, "noypan", 6)) {
- sisfb_ypan = 0;
+ sisfb_ypan = 0;
} else if(!strnicmp(this_opt, "ypan", 4)) {
- sisfb_ypan = -1;
+ sisfb_ypan = -1;
} else if(!strnicmp(this_opt, "nomax", 5)) {
- sisfb_max = 0;
+ sisfb_max = 0;
} else if(!strnicmp(this_opt, "max", 3)) {
- sisfb_max = -1;
+ sisfb_max = -1;
} else if(!strnicmp(this_opt, "userom:", 7)) {
sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
} else if(!strnicmp(this_opt, "useoem:", 7)) {
sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
} else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
sisfb_nocrt2rate = 1;
- } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
- unsigned long temp = 2;
- temp = simple_strtoul(this_opt + 9, NULL, 0);
- if((temp == 0) || (temp == 1)) {
+ } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
+ unsigned long temp = 2;
+ temp = simple_strtoul(this_opt + 9, NULL, 0);
+ if((temp == 0) || (temp == 1)) {
sisfb_scalelcd = temp ^ 1;
- }
+ }
} else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
- int temp = 0;
- temp = (int)simple_strtol(this_opt + 13, NULL, 0);
- if((temp >= -32) && (temp <= 32)) {
+ int temp = 0;
+ temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+ if((temp >= -32) && (temp <= 32)) {
sisfb_tvxposoffset = temp;
- }
+ }
} else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
- int temp = 0;
- temp = (int)simple_strtol(this_opt + 13, NULL, 0);
- if((temp >= -32) && (temp <= 32)) {
+ int temp = 0;
+ temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+ if((temp >= -32) && (temp <= 32)) {
sisfb_tvyposoffset = temp;
- }
+ }
} else if(!strnicmp(this_opt, "specialtiming:", 14)) {
sisfb_search_specialtiming(this_opt + 14);
} else if(!strnicmp(this_opt, "lvdshl:", 7)) {
- int temp = 4;
- temp = simple_strtoul(this_opt + 7, NULL, 0);
- if((temp >= 0) && (temp <= 3)) {
+ int temp = 4;
+ temp = simple_strtoul(this_opt + 7, NULL, 0);
+ if((temp >= 0) && (temp <= 3)) {
sisfb_lvdshl = temp;
- }
+ }
} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
sisfb_search_mode(this_opt, TRUE);
#if !defined(__i386__) && !defined(__x86_64__)
- } else if(!strnicmp(this_opt, "resetcard", 9)) {
- sisfb_resetcard = 1;
+ } else if(!strnicmp(this_opt, "resetcard", 9)) {
+ sisfb_resetcard = 1;
} else if(!strnicmp(this_opt, "videoram:", 9)) {
- sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
+ sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
#endif
} else {
printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
@@ -3967,63 +4183,99 @@ SISINITSTATIC int __init sisfb_setup(char *options)
}
-
-
return 0;
}
#endif
-static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
+static int __devinit
+sisfb_check_rom(SIS_IOTYPE1 *rom_base, struct sis_video_info *ivideo)
+{
+ SIS_IOTYPE1 *rom;
+ int romptr;
+
+ if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa))
+ return 0;
+
+ romptr = (readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+ if(romptr > (0x10000 - 8))
+ return 0;
+
+ rom = rom_base + romptr;
+
+ if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
+ (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R'))
+ return 0;
+
+ if((readb(rom + 4) | (readb(rom + 5) << 8)) != ivideo->chip_vendor)
+ return 0;
+
+ if((readb(rom + 6) | (readb(rom + 7) << 8)) != ivideo->chip_id)
+ return 0;
+
+ return 1;
+}
+
+static unsigned char * __devinit
+sisfb_find_rom(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
- USHORT pciid;
- int romptr;
- UCHAR *myrombase;
- u32 temp;
- SIS_IOTYPE1 *rom_base, *rom;
+ SIS_IOTYPE1 *rom_base;
+ unsigned char *myrombase = NULL;
+ u32 temp;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+ size_t romsize;
+
+ /* First, try the official pci ROM functions (except
+ * on integrated chipsets which have no ROM).
+ */
- if(!(myrombase = vmalloc(65536))) return NULL;
+ if(!ivideo->nbridge) {
-#if defined(__i386__) || defined(__x86_64__)
+ if((rom_base = pci_map_rom(pdev, &romsize))) {
- for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
+ if(sisfb_check_rom(rom_base, ivideo)) {
- rom_base = ioremap(temp, 0x10000);
- if(!rom_base) continue;
+ if((myrombase = vmalloc(65536))) {
- if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
- iounmap(rom_base);
- continue;
- }
+ /* Work around bug in pci/rom.c: Folks forgot to check
+ * whether the size retrieved from the BIOS image eventually
+ * is larger than the mapped size
+ */
+ if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize)
+ romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE);
- romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
- if(romptr > (0x10000 - 8)) {
- iounmap(rom_base);
- continue;
- }
+ memcpy_fromio(myrombase, rom_base,
+ (romsize > 65536) ? 65536 : romsize);
+ }
+ }
+ pci_unmap_rom(pdev, rom_base);
+ }
+ }
- rom = rom_base + romptr;
+ if(myrombase) return myrombase;
+#endif
- if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
- (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
- iounmap(rom_base);
- continue;
- }
+ /* Otherwise do it the conventional way. */
- pciid = readb(rom + 4) | (readb(rom + 5) << 8);
- if(pciid != 0x1039) {
- iounmap(rom_base);
- continue;
- }
+#if defined(__i386__) || defined(__x86_64__)
- pciid = readb(rom + 6) | (readb(rom + 7) << 8);
- if(pciid == ivideo->chip_id) {
- memcpy_fromio(myrombase, rom_base, 65536);
- iounmap(rom_base);
- return myrombase;
- }
+ for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
+
+ rom_base = ioremap(temp, 65536);
+ if(!rom_base)
+ continue;
+
+ if(!sisfb_check_rom(rom_base, ivideo)) {
+ iounmap(rom_base);
+ continue;
+ }
+
+ if((myrombase = vmalloc(65536)))
+ memcpy_fromio(myrombase, rom_base, 65536);
+
+ iounmap(rom_base);
+ break;
- iounmap(rom_base);
}
#else
@@ -4034,752 +4286,1603 @@ static UCHAR * __devinit sis_find_rom(struct pci_dev *pdev)
rom_base = ioremap(ivideo->video_base, 65536);
if(rom_base) {
- if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) {
- romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
- if(romptr <= (0x10000 - 8)) {
- rom = rom_base + romptr;
- if((readb(rom) == 'P') && (readb(rom + 1) == 'C') &&
- (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
- pciid = readb(rom + 4) | (readb(rom + 5) << 8);
- if(pciid == 0x1039) {
- pciid = readb(rom + 6) | (readb(rom + 7) << 8);
- if(pciid == ivideo->chip_id) {
- memcpy_fromio(myrombase, rom_base, 65536);
- iounmap(rom_base);
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
- return myrombase;
- }
- }
- }
- }
- }
- iounmap(rom_base);
+ if(sisfb_check_rom(rom_base, ivideo)) {
+ if((myrombase = vmalloc(65536)))
+ memcpy_fromio(myrombase, rom_base, 65536);
+ }
+ iounmap(rom_base);
}
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
+
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
#endif
- vfree(myrombase);
- return NULL;
+ return myrombase;
+}
+
+static void __devinit
+sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
+ unsigned int min)
+{
+ ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize));
+
+ if(!ivideo->video_vbase) {
+ printk(KERN_ERR
+ "sisfb: Unable to map maximum video RAM for size detection\n");
+ (*mapsize) >>= 1;
+ while((!(ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize))))) {
+ (*mapsize) >>= 1;
+ if((*mapsize) < (min << 20))
+ break;
+ }
+ if(ivideo->video_vbase) {
+ printk(KERN_ERR
+ "sisfb: Video RAM size detection limited to %dMB\n",
+ (int)((*mapsize) >> 20));
+ }
+ }
}
#ifdef CONFIG_FB_SIS_300
static int __devinit
-sisfb_chkbuswidth300(struct pci_dev *pdev, SIS_IOTYPE1 *FBAddress)
+sisfb_post_300_buswidth(struct sis_video_info *ivideo)
{
- struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ SIS_IOTYPE1 *FBAddress = ivideo->video_vbase;
+ unsigned short temp;
+ unsigned char reg;
int i, j;
- USHORT temp;
- UCHAR reg;
-
- andSISIDXREG(SISSR,0x15,0xFB);
- orSISIDXREG(SISSR,0x15,0x04);
- outSISIDXREG(SISSR,0x13,0x00);
- outSISIDXREG(SISSR,0x14,0xBF);
-
- for(i=0; i<2; i++) {
- temp = 0x1234;
- for(j=0; j<4; j++) {
- writew(temp, FBAddress);
- if(readw(FBAddress) == temp) break;
- orSISIDXREG(SISSR,0x3c,0x01);
- inSISIDXREG(SISSR,0x05,reg);
- inSISIDXREG(SISSR,0x05,reg);
- andSISIDXREG(SISSR,0x3c,0xfe);
- inSISIDXREG(SISSR,0x05,reg);
- inSISIDXREG(SISSR,0x05,reg);
- temp++;
- }
+
+ andSISIDXREG(SISSR, 0x15, 0xFB);
+ orSISIDXREG(SISSR, 0x15, 0x04);
+ outSISIDXREG(SISSR, 0x13, 0x00);
+ outSISIDXREG(SISSR, 0x14, 0xBF);
+
+ for(i = 0; i < 2; i++) {
+ temp = 0x1234;
+ for(j = 0; j < 4; j++) {
+ writew(temp, FBAddress);
+ if(readw(FBAddress) == temp)
+ break;
+ orSISIDXREG(SISSR, 0x3c, 0x01);
+ inSISIDXREG(SISSR, 0x05, reg);
+ inSISIDXREG(SISSR, 0x05, reg);
+ andSISIDXREG(SISSR, 0x3c, 0xfe);
+ inSISIDXREG(SISSR, 0x05, reg);
+ inSISIDXREG(SISSR, 0x05, reg);
+ temp++;
+ }
}
writel(0x01234567L, FBAddress);
- writel(0x456789ABL, (FBAddress+4));
- writel(0x89ABCDEFL, (FBAddress+8));
- writel(0xCDEF0123L, (FBAddress+12));
- inSISIDXREG(SISSR,0x3b,reg);
+ writel(0x456789ABL, (FBAddress + 4));
+ writel(0x89ABCDEFL, (FBAddress + 8));
+ writel(0xCDEF0123L, (FBAddress + 12));
+
+ inSISIDXREG(SISSR, 0x3b, reg);
if(reg & 0x01) {
- if(readl((FBAddress+12)) == 0xCDEF0123L) return(4); /* Channel A 128bit */
+ if(readl((FBAddress + 12)) == 0xCDEF0123L)
+ return 4; /* Channel A 128bit */
}
- if(readl((FBAddress+4)) == 0x456789ABL) return(2); /* Channel B 64bit */
- return(1); /* 32bit */
+
+ if(readl((FBAddress + 4)) == 0x456789ABL)
+ return 2; /* Channel B 64bit */
+
+ return 1; /* 32bit */
+}
+
+static int __devinit
+sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth,
+ int PseudoRankCapacity, int PseudoAdrPinCount,
+ unsigned int mapsize)
+{
+ SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
+ unsigned short sr14;
+ unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
+ unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
+ static const unsigned short SiS_DRAMType[17][5] = {
+ {0x0C,0x0A,0x02,0x40,0x39},
+ {0x0D,0x0A,0x01,0x40,0x48},
+ {0x0C,0x09,0x02,0x20,0x35},
+ {0x0D,0x09,0x01,0x20,0x44},
+ {0x0C,0x08,0x02,0x10,0x31},
+ {0x0D,0x08,0x01,0x10,0x40},
+ {0x0C,0x0A,0x01,0x20,0x34},
+ {0x0C,0x09,0x01,0x08,0x32},
+ {0x0B,0x08,0x02,0x08,0x21},
+ {0x0C,0x08,0x01,0x08,0x30},
+ {0x0A,0x08,0x02,0x04,0x11},
+ {0x0B,0x0A,0x01,0x10,0x28},
+ {0x09,0x08,0x02,0x02,0x01},
+ {0x0B,0x09,0x01,0x08,0x24},
+ {0x0B,0x08,0x01,0x04,0x20},
+ {0x0A,0x08,0x01,0x02,0x10},
+ {0x09,0x08,0x01,0x01,0x00}
+ };
+
+ for(k = 0; k <= 16; k++) {
+
+ RankCapacity = buswidth * SiS_DRAMType[k][3];
+
+ if(RankCapacity != PseudoRankCapacity)
+ continue;
+
+ if((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount)
+ continue;
+
+ BankNumHigh = RankCapacity * 16 * iteration - 1;
+ if(iteration == 3) { /* Rank No */
+ BankNumMid = RankCapacity * 16 - 1;
+ } else {
+ BankNumMid = RankCapacity * 16 * iteration / 2 - 1;
+ }
+
+ PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+ PhysicalAdrHigh = BankNumHigh;
+ PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+ PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
+
+ andSISIDXREG(SISSR, 0x15, 0xFB); /* Test */
+ orSISIDXREG(SISSR, 0x15, 0x04); /* Test */
+ sr14 = (SiS_DRAMType[k][3] * buswidth) - 1;
+ if(buswidth == 4) sr14 |= 0x80;
+ else if(buswidth == 2) sr14 |= 0x40;
+ outSISIDXREG(SISSR, 0x13, SiS_DRAMType[k][4]);
+ outSISIDXREG(SISSR, 0x14, sr14);
+
+ BankNumHigh <<= 16;
+ BankNumMid <<= 16;
+
+ if((BankNumHigh + PhysicalAdrHigh >= mapsize) ||
+ (BankNumMid + PhysicalAdrHigh >= mapsize) ||
+ (BankNumHigh + PhysicalAdrHalfPage >= mapsize) ||
+ (BankNumHigh + PhysicalAdrOtherPage >= mapsize))
+ continue;
+
+ /* Write data */
+ writew(((unsigned short)PhysicalAdrHigh),
+ (FBAddr + BankNumHigh + PhysicalAdrHigh));
+ writew(((unsigned short)BankNumMid),
+ (FBAddr + BankNumMid + PhysicalAdrHigh));
+ writew(((unsigned short)PhysicalAdrHalfPage),
+ (FBAddr + BankNumHigh + PhysicalAdrHalfPage));
+ writew(((unsigned short)PhysicalAdrOtherPage),
+ (FBAddr + BankNumHigh + PhysicalAdrOtherPage));
+
+ /* Read data */
+ if(readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh)
+ return 1;
+ }
+
+ return 0;
}
static void __devinit
-sisfb_setramsize300(struct pci_dev *pdev)
+sisfb_post_300_ramsize(struct pci_dev *pdev, unsigned int mapsize)
{
- struct sis_video_info *ivideo = pci_get_drvdata(pdev);
- SIS_IOTYPE1 *FBAddr = ivideo->video_vbase;
- SIS_IOTYPE1 *Addr;
- USHORT sr13, sr14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
- int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
- int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
- int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
- const USHORT SiS_DRAMType[17][5] = {
- {0x0C,0x0A,0x02,0x40,0x39},
- {0x0D,0x0A,0x01,0x40,0x48},
- {0x0C,0x09,0x02,0x20,0x35},
- {0x0D,0x09,0x01,0x20,0x44},
- {0x0C,0x08,0x02,0x10,0x31},
- {0x0D,0x08,0x01,0x10,0x40},
- {0x0C,0x0A,0x01,0x20,0x34},
- {0x0C,0x09,0x01,0x08,0x32},
- {0x0B,0x08,0x02,0x08,0x21},
- {0x0C,0x08,0x01,0x08,0x30},
- {0x0A,0x08,0x02,0x04,0x11},
- {0x0B,0x0A,0x01,0x10,0x28},
- {0x09,0x08,0x02,0x02,0x01},
- {0x0B,0x09,0x01,0x08,0x24},
- {0x0B,0x08,0x01,0x04,0x20},
- {0x0A,0x08,0x01,0x02,0x10},
- {0x09,0x08,0x01,0x01,0x00}
- };
-
- buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
-
- MB2Bank = 16;
- Done = 0;
- for(i = 6; i >= 0; i--) {
- if(Done) break;
- PseudoRankCapacity = 1 << i;
- for(j = 4; j >= 1; j--) {
- if(Done) break;
- PseudoTotalCapacity = PseudoRankCapacity * j;
- PseudoAdrPinCount = 15 - j;
- if(PseudoTotalCapacity <= 64) {
- for(k = 0; k <= 16; k++) {
- if(Done) break;
- RankCapacity = buswidth * SiS_DRAMType[k][3];
- AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
- if(RankCapacity == PseudoRankCapacity)
- if(AdrPinCount <= PseudoAdrPinCount) {
- if(j == 3) { /* Rank No */
- BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
- BankNumMid = RankCapacity * MB2Bank * 1 - 1;
- } else {
- BankNumHigh = RankCapacity * MB2Bank * j - 1;
- BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
- }
- PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
- PhysicalAdrHigh = BankNumHigh;
- PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
- PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
- /* Write data */
- andSISIDXREG(SISSR,0x15,0xFB); /* Test */
- orSISIDXREG(SISSR,0x15,0x04); /* Test */
- TotalCapacity = SiS_DRAMType[k][3] * buswidth;
- sr13 = SiS_DRAMType[k][4];
- if(buswidth == 4) sr14 = (TotalCapacity - 1) | 0x80;
- if(buswidth == 2) sr14 = (TotalCapacity - 1) | 0x40;
- if(buswidth == 1) sr14 = (TotalCapacity - 1) | 0x00;
- outSISIDXREG(SISSR,0x13,sr13);
- outSISIDXREG(SISSR,0x14,sr14);
- Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
- /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
- writew(((USHORT)PhysicalAdrHigh), Addr);
- Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
- /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
- writew(((USHORT)BankNumMid), Addr);
- Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
- /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
- writew(((USHORT)PhysicalAdrHalfPage), Addr);
- Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
- /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
- writew(((USHORT)PhysicalAdrOtherPage), Addr);
- /* Read data */
- Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
- data = readw(Addr); /* *((USHORT *)(Addr)); */
- if(data == PhysicalAdrHigh) Done = 1;
- } /* if */
- } /* for k */
- } /* if */
- } /* for j */
- } /* for i */
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ int i, j, buswidth;
+ int PseudoRankCapacity, PseudoAdrPinCount;
+
+ buswidth = sisfb_post_300_buswidth(ivideo);
+
+ for(i = 6; i >= 0; i--) {
+ PseudoRankCapacity = 1 << i;
+ for(j = 4; j >= 1; j--) {
+ PseudoAdrPinCount = 15 - j;
+ if((PseudoRankCapacity * j) <= 64) {
+ if(sisfb_post_300_rwtest(ivideo,
+ j,
+ buswidth,
+ PseudoRankCapacity,
+ PseudoAdrPinCount,
+ mapsize))
+ return;
+ }
+ }
+ }
}
-static void __devinit sisfb_post_sis300(struct pci_dev *pdev)
+static void __devinit
+sisfb_post_sis300(struct pci_dev *pdev)
{
struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ unsigned char *bios = ivideo->SiS_Pr.VirtualRomBase;
u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
u16 index, rindex, memtype = 0;
+ unsigned int mapsize;
- outSISIDXREG(SISSR,0x05,0x86);
+ if(!ivideo->SiS_Pr.UseROM)
+ bios = NULL;
- if(ivideo->sishw_ext.UseROM) {
- if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) {
- memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
- } else {
- inSISIDXREG(SISSR,0x3a,memtype);
- }
- memtype &= 0x07;
+ outSISIDXREG(SISSR, 0x05, 0x86);
+
+ if(bios) {
+ if(bios[0x52] & 0x80) {
+ memtype = bios[0x52];
+ } else {
+ inSISIDXREG(SISSR, 0x3a, memtype);
+ }
+ memtype &= 0x07;
}
+ v3 = 0x80; v6 = 0x80;
if(ivideo->revision_id <= 0x13) {
- v1 = 0x44; v2 = 0x42; v3 = 0x80;
- v4 = 0x44; v5 = 0x42; v6 = 0x80;
+ v1 = 0x44; v2 = 0x42;
+ v4 = 0x44; v5 = 0x42;
} else {
- v1 = 0x68; v2 = 0x43; v3 = 0x80; /* Assume 125Mhz MCLK */
- v4 = 0x68; v5 = 0x43; v6 = 0x80; /* Assume 125Mhz ECLK */
- if(ivideo->sishw_ext.UseROM) {
- index = memtype * 5;
- rindex = index + 0x54;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- rindex = index + 0x7c;
- v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- }
+ v1 = 0x68; v2 = 0x43; /* Assume 125Mhz MCLK */
+ v4 = 0x68; v5 = 0x43; /* Assume 125Mhz ECLK */
+ if(bios) {
+ index = memtype * 5;
+ rindex = index + 0x54;
+ v1 = bios[rindex++];
+ v2 = bios[rindex++];
+ v3 = bios[rindex++];
+ rindex = index + 0x7c;
+ v4 = bios[rindex++];
+ v5 = bios[rindex++];
+ v6 = bios[rindex++];
+ }
}
- outSISIDXREG(SISSR,0x28,v1);
- outSISIDXREG(SISSR,0x29,v2);
- outSISIDXREG(SISSR,0x2a,v3);
- outSISIDXREG(SISSR,0x2e,v4);
- outSISIDXREG(SISSR,0x2f,v5);
- outSISIDXREG(SISSR,0x30,v6);
+ outSISIDXREG(SISSR, 0x28, v1);
+ outSISIDXREG(SISSR, 0x29, v2);
+ outSISIDXREG(SISSR, 0x2a, v3);
+ outSISIDXREG(SISSR, 0x2e, v4);
+ outSISIDXREG(SISSR, 0x2f, v5);
+ outSISIDXREG(SISSR, 0x30, v6);
+
v1 = 0x10;
- if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4];
- outSISIDXREG(SISSR,0x07,v1); /* DAC speed */
- outSISIDXREG(SISSR,0x11,0x0f); /* DDC, power save */
+ if(bios)
+ v1 = bios[0xa4];
+ outSISIDXREG(SISSR, 0x07, v1); /* DAC speed */
+
+ outSISIDXREG(SISSR, 0x11, 0x0f); /* DDC, power save */
+
v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- memtype += 0xa5;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16];
- v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40];
- v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48];
- v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56];
- }
- if(ivideo->revision_id >= 0x80) v3 &= 0xfd;
- outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
- outSISIDXREG(SISSR,0x16,v2);
- outSISIDXREG(SISSR,0x17,v3);
- outSISIDXREG(SISSR,0x18,v4);
- outSISIDXREG(SISSR,0x19,v5);
- outSISIDXREG(SISSR,0x1a,v6);
- outSISIDXREG(SISSR,0x1b,v7);
- outSISIDXREG(SISSR,0x1c,v8); /* ---- */
- andSISIDXREG(SISSR,0x15,0xfb);
- orSISIDXREG(SISSR,0x15,0x04);
- if(ivideo->sishw_ext.UseROM) {
- if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) {
- orSISIDXREG(SISSR,0x19,0x20);
- }
+ if(bios) {
+ memtype += 0xa5;
+ v1 = bios[memtype];
+ v2 = bios[memtype + 8];
+ v3 = bios[memtype + 16];
+ v4 = bios[memtype + 24];
+ v5 = bios[memtype + 32];
+ v6 = bios[memtype + 40];
+ v7 = bios[memtype + 48];
+ v8 = bios[memtype + 56];
+ }
+ if(ivideo->revision_id >= 0x80)
+ v3 &= 0xfd;
+ outSISIDXREG(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
+ outSISIDXREG(SISSR, 0x16, v2);
+ outSISIDXREG(SISSR, 0x17, v3);
+ outSISIDXREG(SISSR, 0x18, v4);
+ outSISIDXREG(SISSR, 0x19, v5);
+ outSISIDXREG(SISSR, 0x1a, v6);
+ outSISIDXREG(SISSR, 0x1b, v7);
+ outSISIDXREG(SISSR, 0x1c, v8); /* ---- */
+ andSISIDXREG(SISSR, 0x15 ,0xfb);
+ orSISIDXREG(SISSR, 0x15, 0x04);
+ if(bios) {
+ if(bios[0x53] & 0x02) {
+ orSISIDXREG(SISSR, 0x19, 0x20);
+ }
}
v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */
- if(ivideo->revision_id >= 0x80) v1 |= 0x01;
- outSISIDXREG(SISSR,0x1f,v1);
- outSISIDXREG(SISSR,0x20,0xa0); /* linear & relocated io */
+ if(ivideo->revision_id >= 0x80)
+ v1 |= 0x01;
+ outSISIDXREG(SISSR, 0x1f, v1);
+ outSISIDXREG(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */
v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea];
- }
- outSISIDXREG(SISSR,0x23,v1);
- outSISIDXREG(SISSR,0x24,v2);
- outSISIDXREG(SISSR,0x25,v3);
- outSISIDXREG(SISSR,0x21,0x84);
- outSISIDXREG(SISSR,0x22,0x00);
- outSISIDXREG(SISCR,0x37,0x00);
- orSISIDXREG(SISPART1,0x24,0x01); /* unlock crt2 */
- outSISIDXREG(SISPART1,0x00,0x00);
+ if(bios) {
+ v1 = bios[0xe8];
+ v2 = bios[0xe9];
+ v3 = bios[0xea];
+ }
+ outSISIDXREG(SISSR, 0x23, v1);
+ outSISIDXREG(SISSR, 0x24, v2);
+ outSISIDXREG(SISSR, 0x25, v3);
+ outSISIDXREG(SISSR, 0x21, 0x84);
+ outSISIDXREG(SISSR, 0x22, 0x00);
+ outSISIDXREG(SISCR, 0x37, 0x00);
+ orSISIDXREG(SISPART1, 0x24, 0x01); /* unlock crt2 */
+ outSISIDXREG(SISPART1, 0x00, 0x00);
v1 = 0x40; v2 = 0x11;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb];
+ if(bios) {
+ v1 = bios[0xec];
+ v2 = bios[0xeb];
}
- outSISIDXREG(SISPART1,0x02,v1);
- if(ivideo->revision_id >= 0x80) v2 &= ~0x01;
- inSISIDXREG(SISPART4,0x00,reg);
+ outSISIDXREG(SISPART1, 0x02, v1);
+
+ if(ivideo->revision_id >= 0x80)
+ v2 &= ~0x01;
+
+ inSISIDXREG(SISPART4, 0x00, reg);
if((reg == 1) || (reg == 2)) {
- outSISIDXREG(SISCR,0x37,0x02);
- outSISIDXREG(SISPART2,0x00,0x1c);
- v4 = 0x00; v5 = 0x00; v6 = 0x10;
- if(ivideo->sishw_ext.UseROM) {
- v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7];
- }
- outSISIDXREG(SISPART4,0x0d,v4);
- outSISIDXREG(SISPART4,0x0e,v5);
- outSISIDXREG(SISPART4,0x10,v6);
- outSISIDXREG(SISPART4,0x0f,0x3f);
- inSISIDXREG(SISPART4,0x01,reg);
- if(reg >= 0xb0) {
- inSISIDXREG(SISPART4,0x23,reg);
- reg &= 0x20;
- reg <<= 1;
- outSISIDXREG(SISPART4,0x23,reg);
- }
+ outSISIDXREG(SISCR, 0x37, 0x02);
+ outSISIDXREG(SISPART2, 0x00, 0x1c);
+ v4 = 0x00; v5 = 0x00; v6 = 0x10;
+ if(ivideo->SiS_Pr.UseROM) {
+ v4 = bios[0xf5];
+ v5 = bios[0xf6];
+ v6 = bios[0xf7];
+ }
+ outSISIDXREG(SISPART4, 0x0d, v4);
+ outSISIDXREG(SISPART4, 0x0e, v5);
+ outSISIDXREG(SISPART4, 0x10, v6);
+ outSISIDXREG(SISPART4, 0x0f, 0x3f);
+ inSISIDXREG(SISPART4, 0x01, reg);
+ if(reg >= 0xb0) {
+ inSISIDXREG(SISPART4, 0x23, reg);
+ reg &= 0x20;
+ reg <<= 1;
+ outSISIDXREG(SISPART4, 0x23, reg);
+ }
} else {
- v2 &= ~0x10;
+ v2 &= ~0x10;
}
- outSISIDXREG(SISSR,0x32,v2);
- andSISIDXREG(SISPART1,0x24,0xfe); /* Lock CRT2 */
- inSISIDXREG(SISSR,0x16,reg);
+ outSISIDXREG(SISSR, 0x32, v2);
+
+ andSISIDXREG(SISPART1, 0x24, 0xfe); /* Lock CRT2 */
+
+ inSISIDXREG(SISSR, 0x16, reg);
reg &= 0xc3;
- outSISIDXREG(SISCR,0x35,reg);
- outSISIDXREG(SISCR,0x83,0x00);
+ outSISIDXREG(SISCR, 0x35, reg);
+ outSISIDXREG(SISCR, 0x83, 0x00);
#if !defined(__i386__) && !defined(__x86_64__)
if(sisfb_videoram) {
- outSISIDXREG(SISSR,0x13,0x28); /* ? */
- reg = ((sisfb_videoram >> 10) - 1) | 0x40;
- outSISIDXREG(SISSR,0x14,reg);
+ outSISIDXREG(SISSR, 0x13, 0x28); /* ? */
+ reg = ((sisfb_videoram >> 10) - 1) | 0x40;
+ outSISIDXREG(SISSR, 0x14, reg);
} else {
#endif
- /* Need to map max FB size for finding out about RAM size */
- ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
- if(ivideo->video_vbase) {
- sisfb_setramsize300(pdev);
- iounmap(ivideo->video_vbase);
- } else {
- printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
- outSISIDXREG(SISSR,0x13,0x28); /* ? */
- outSISIDXREG(SISSR,0x14,0x47); /* 8MB, 64bit default */
- }
+ /* Need to map max FB size for finding out about RAM size */
+ mapsize = 64 << 20;
+ sisfb_post_map_vram(ivideo, &mapsize, 4);
+
+ if(ivideo->video_vbase) {
+ sisfb_post_300_ramsize(pdev, mapsize);
+ iounmap(ivideo->video_vbase);
+ } else {
+ printk(KERN_DEBUG
+ "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+ outSISIDXREG(SISSR, 0x13, 0x28); /* ? */
+ outSISIDXREG(SISSR, 0x14, 0x47); /* 8MB, 64bit default */
+ }
#if !defined(__i386__) && !defined(__x86_64__)
}
#endif
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7];
+ if(bios) {
+ v1 = bios[0xe6];
+ v2 = bios[0xe7];
} else {
- inSISIDXREG(SISSR,0x3a,reg);
- if((reg & 0x30) == 0x30) {
- v1 = 0x04; /* PCI */
- v2 = 0x92;
- } else {
- v1 = 0x14; /* AGP */
- v2 = 0xb2;
- }
+ inSISIDXREG(SISSR, 0x3a, reg);
+ if((reg & 0x30) == 0x30) {
+ v1 = 0x04; /* PCI */
+ v2 = 0x92;
+ } else {
+ v1 = 0x14; /* AGP */
+ v2 = 0xb2;
+ }
}
- outSISIDXREG(SISSR,0x21,v1);
- outSISIDXREG(SISSR,0x22,v2);
+ outSISIDXREG(SISSR, 0x21, v1);
+ outSISIDXREG(SISSR, 0x22, v2);
+
+ /* Sense CRT1 */
+ sisfb_sense_crt1(ivideo);
+
+ /* Set default mode, don't clear screen */
+ ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->curFSTN = ivideo->curDSTN = 0;
+ ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
+ SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
+
+ outSISIDXREG(SISSR, 0x05, 0x86);
+
+ /* Display off */
+ orSISIDXREG(SISSR, 0x01, 0x20);
+
+ /* Save mode number in CR34 */
+ outSISIDXREG(SISCR, 0x34, 0x2e);
+
+ /* Let everyone know what the current mode is */
+ ivideo->modeprechange = 0x2e;
}
#endif
#ifdef CONFIG_FB_SIS_315
-static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
+#if 0
+static void __devinit
+sisfb_post_sis315330(struct pci_dev *pdev)
{
-#ifdef YET_TO_BE_DONE
- struct sis_video_info *ivideo = pci_get_drvdata(pdev);
- u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
- u16 index, rindex, memtype = 0;
- u32 reg1_32, reg2_32, reg3_32;
+ /* TODO */
+}
+#endif
+
+static void __devinit
+sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
+{
+ unsigned int i;
+ u8 reg;
+
+ for(i = 0; i <= (delay * 10 * 36); i++) {
+ inSISIDXREG(SISSR, 0x05, reg);
+ reg++;
+ }
+}
+
+static int __devinit
+sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
+ unsigned short pcivendor)
+{
+ struct pci_dev *pdev = NULL;
+ unsigned short temp;
+ int ret = 0;
+
+ while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) {
+ temp = pdev->vendor;
+ SIS_PCI_PUT_DEVICE(pdev);
+ if(temp == pcivendor) {
+ ret = 1;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int __devinit
+sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
+ unsigned int enda, unsigned int mapsize)
+{
+ unsigned int pos;
int i;
- /* Unlock */
- /* outSISIDXREG(0x3c4,0x05,0x86); */
- outSISIDXREG(SISSR,0x05,0x86);
+ writel(0, ivideo->video_vbase);
- /* Enable relocated i/o ports */
- /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */
- setSISIDXREG(SISSR,0x20,~0x10,0x20);
+ for(i = starta; i <= enda; i++) {
+ pos = 1 << i;
+ if(pos < mapsize)
+ writel(pos, ivideo->video_vbase + pos);
+ }
+
+ sisfb_post_xgi_delay(ivideo, 150);
+
+ if(readl(ivideo->video_vbase) != 0)
+ return 0;
- /* Clear regs */
+ for(i = starta; i <= enda; i++) {
+ pos = 1 << i;
+ if(pos < mapsize) {
+ if(readl(ivideo->video_vbase + pos) != pos)
+ return 0;
+ } else
+ return 0;
+ }
+
+ return 1;
+}
+
+static void __devinit
+sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
+{
+ unsigned int buswidth, ranksize, channelab, mapsize;
+ int i, j, k, l;
+ u8 reg, sr14;
+ static const u8 dramsr13[12 * 5] = {
+ 0x02, 0x0e, 0x0b, 0x80, 0x5d,
+ 0x02, 0x0e, 0x0a, 0x40, 0x59,
+ 0x02, 0x0d, 0x0b, 0x40, 0x4d,
+ 0x02, 0x0e, 0x09, 0x20, 0x55,
+ 0x02, 0x0d, 0x0a, 0x20, 0x49,
+ 0x02, 0x0c, 0x0b, 0x20, 0x3d,
+ 0x02, 0x0e, 0x08, 0x10, 0x51,
+ 0x02, 0x0d, 0x09, 0x10, 0x45,
+ 0x02, 0x0c, 0x0a, 0x10, 0x39,
+ 0x02, 0x0d, 0x08, 0x08, 0x41,
+ 0x02, 0x0c, 0x09, 0x08, 0x35,
+ 0x02, 0x0c, 0x08, 0x04, 0x31
+ };
+ static const u8 dramsr13_4[4 * 5] = {
+ 0x02, 0x0d, 0x09, 0x40, 0x45,
+ 0x02, 0x0c, 0x09, 0x20, 0x35,
+ 0x02, 0x0c, 0x08, 0x10, 0x31,
+ 0x02, 0x0b, 0x08, 0x08, 0x21
+ };
+
+ /* Enable linear mode, disable 0xa0000 address decoding */
+ /* We disable a0000 address decoding, because
+ * - if running on x86, if the card is disabled, it means
+ * that another card is in the system. We don't want
+ * to interphere with that primary card's textmode.
+ * - if running on non-x86, there usually is no VGA window
+ * at a0000.
+ */
+ orSISIDXREG(SISSR, 0x20, (0x80 | 0x04));
+
+ /* Need to map max FB size for finding out about RAM size */
+ mapsize = 256 << 20;
+ sisfb_post_map_vram(ivideo, &mapsize, 32);
+
+ if(!ivideo->video_vbase) {
+ printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n");
+ outSISIDXREG(SISSR, 0x13, 0x35);
+ outSISIDXREG(SISSR, 0x14, 0x41);
+ /* TODO */
+ return;
+ }
+
+ /* Non-interleaving */
+ outSISIDXREG(SISSR, 0x15, 0x00);
+ /* No tiling */
+ outSISIDXREG(SISSR, 0x1c, 0x00);
+
+ if(ivideo->chip == XGI_20) {
+
+ channelab = 1;
+ inSISIDXREG(SISCR, 0x97, reg);
+ if(!(reg & 0x01)) { /* Single 32/16 */
+ buswidth = 32;
+ outSISIDXREG(SISSR, 0x13, 0xb1);
+ outSISIDXREG(SISSR, 0x14, 0x52);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x02;
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x31);
+ outSISIDXREG(SISSR, 0x14, 0x42);
+ sisfb_post_xgi_delay(ivideo, 1);
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize))
+ goto bail_out;
+
+ buswidth = 16;
+ outSISIDXREG(SISSR, 0x13, 0xb1);
+ outSISIDXREG(SISSR, 0x14, 0x41);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x01;
+ if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+ goto bail_out;
+ else
+ outSISIDXREG(SISSR, 0x13, 0x31);
+ } else { /* Dual 16/8 */
+ buswidth = 16;
+ outSISIDXREG(SISSR, 0x13, 0xb1);
+ outSISIDXREG(SISSR, 0x14, 0x41);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x01;
+ if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x31);
+ outSISIDXREG(SISSR, 0x14, 0x31);
+ sisfb_post_xgi_delay(ivideo, 1);
+ if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize))
+ goto bail_out;
+
+ buswidth = 8;
+ outSISIDXREG(SISSR, 0x13, 0xb1);
+ outSISIDXREG(SISSR, 0x14, 0x30);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x00;
+ if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize))
+ goto bail_out;
+ else
+ outSISIDXREG(SISSR, 0x13, 0x31);
+ }
+
+ } else { /* XGI_40 */
+
+ inSISIDXREG(SISCR, 0x97, reg);
+ if(!(reg & 0x10)) {
+ inSISIDXREG(SISSR, 0x39, reg);
+ reg >>= 1;
+ }
+
+ if(reg & 0x01) { /* DDRII */
+ buswidth = 32;
+ if(ivideo->revision_id == 2) {
+ channelab = 2;
+ outSISIDXREG(SISSR, 0x13, 0xa1);
+ outSISIDXREG(SISSR, 0x14, 0x44);
+ sr14 = 0x04;
+ sisfb_post_xgi_delay(ivideo, 1);
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x21);
+ outSISIDXREG(SISSR, 0x14, 0x34);
+ if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+ goto bail_out;
+
+ channelab = 1;
+ outSISIDXREG(SISSR, 0x13, 0xa1);
+ outSISIDXREG(SISSR, 0x14, 0x40);
+ sr14 = 0x00;
+ if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x21);
+ outSISIDXREG(SISSR, 0x14, 0x30);
+ } else {
+ channelab = 3;
+ outSISIDXREG(SISSR, 0x13, 0xa1);
+ outSISIDXREG(SISSR, 0x14, 0x4c);
+ sr14 = 0x0c;
+ sisfb_post_xgi_delay(ivideo, 1);
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize))
+ goto bail_out;
+
+ channelab = 2;
+ outSISIDXREG(SISSR, 0x14, 0x48);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x08;
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x21);
+ outSISIDXREG(SISSR, 0x14, 0x3c);
+ sr14 = 0x0c;
+
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) {
+ channelab = 3;
+ } else {
+ channelab = 2;
+ outSISIDXREG(SISSR, 0x14, 0x38);
+ sr14 = 0x08;
+ }
+ }
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ } else { /* DDR */
+
+ buswidth = 64;
+ if(ivideo->revision_id == 2) {
+ channelab = 1;
+ outSISIDXREG(SISSR, 0x13, 0xa1);
+ outSISIDXREG(SISSR, 0x14, 0x52);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x02;
+ if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x21);
+ outSISIDXREG(SISSR, 0x14, 0x42);
+ } else {
+ channelab = 2;
+ outSISIDXREG(SISSR, 0x13, 0xa1);
+ outSISIDXREG(SISSR, 0x14, 0x5a);
+ sisfb_post_xgi_delay(ivideo, 1);
+ sr14 = 0x0a;
+ if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize))
+ goto bail_out;
+
+ outSISIDXREG(SISSR, 0x13, 0x21);
+ outSISIDXREG(SISSR, 0x14, 0x4a);
+ }
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ }
+ }
+
+bail_out:
+ setSISIDXREG(SISSR, 0x14, 0xf0, sr14);
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ j = (ivideo->chip == XGI_20) ? 5 : 9;
+ k = (ivideo->chip == XGI_20) ? 12 : 4;
+
+ for(i = 0; i < k; i++) {
+
+ reg = (ivideo->chip == XGI_20) ?
+ dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4];
+ setSISIDXREG(SISSR, 0x13, 0x80, reg);
+ sisfb_post_xgi_delay(ivideo, 50);
+
+ ranksize = (ivideo->chip == XGI_20) ?
+ dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3];
+
+ inSISIDXREG(SISSR, 0x13, reg);
+ if(reg & 0x80) ranksize <<= 1;
+
+ if(ivideo->chip == XGI_20) {
+ if(buswidth == 16) ranksize <<= 1;
+ else if(buswidth == 32) ranksize <<= 2;
+ } else {
+ if(buswidth == 64) ranksize <<= 1;
+ }
+
+ reg = 0;
+ l = channelab;
+ if(l == 3) l = 4;
+ if((ranksize * l) <= 256) {
+ while((ranksize >>= 1)) reg += 0x10;
+ }
+
+ if(!reg) continue;
+
+ setSISIDXREG(SISSR, 0x14, 0x0f, (reg & 0xf0));
+ sisfb_post_xgi_delay(ivideo, 1);
+
+ if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
+ break;
+ }
+
+ iounmap(ivideo->video_vbase);
+}
+
+static void __devinit
+sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
+{
+ u8 v1, v2, v3;
+ int index;
+ static const u8 cs90[8 * 3] = {
+ 0x16, 0x01, 0x01,
+ 0x3e, 0x03, 0x01,
+ 0x7c, 0x08, 0x01,
+ 0x79, 0x06, 0x01,
+ 0x29, 0x01, 0x81,
+ 0x5c, 0x23, 0x01,
+ 0x5c, 0x23, 0x01,
+ 0x5c, 0x23, 0x01
+ };
+ static const u8 csb8[8 * 3] = {
+ 0x5c, 0x23, 0x01,
+ 0x29, 0x01, 0x01,
+ 0x7c, 0x08, 0x01,
+ 0x79, 0x06, 0x01,
+ 0x29, 0x01, 0x81,
+ 0x5c, 0x23, 0x01,
+ 0x5c, 0x23, 0x01,
+ 0x5c, 0x23, 0x01
+ };
+
+ regb = 0; /* ! */
+
+ index = regb * 3;
+ v1 = cs90[index]; v2 = cs90[index + 1]; v3 = cs90[index + 2];
+ if(ivideo->haveXGIROM) {
+ v1 = ivideo->bios_abase[0x90 + index];
+ v2 = ivideo->bios_abase[0x90 + index + 1];
+ v3 = ivideo->bios_abase[0x90 + index + 2];
+ }
+ outSISIDXREG(SISSR, 0x28, v1);
+ outSISIDXREG(SISSR, 0x29, v2);
+ outSISIDXREG(SISSR, 0x2a, v3);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ index = regb * 3;
+ v1 = csb8[index]; v2 = csb8[index + 1]; v3 = csb8[index + 2];
+ if(ivideo->haveXGIROM) {
+ v1 = ivideo->bios_abase[0xb8 + index];
+ v2 = ivideo->bios_abase[0xb8 + index + 1];
+ v3 = ivideo->bios_abase[0xb8 + index + 2];
+ }
+ outSISIDXREG(SISSR, 0x2e, v1);
+ outSISIDXREG(SISSR, 0x2f, v2);
+ outSISIDXREG(SISSR, 0x30, v3);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+}
+
+static int __devinit
+sisfb_post_xgi(struct pci_dev *pdev)
+{
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ unsigned char *bios = ivideo->bios_abase;
+ struct pci_dev *mypdev = NULL;
+ const u8 *ptr, *ptr2;
+ u8 v1, v2, v3, v4, v5, reg, ramtype;
+ u32 rega, regb, regd;
+ int i, j, k, index;
+ static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
+ static const u8 cs76[2] = { 0xa3, 0xfb };
+ static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
+ static const u8 cs158[8] = {
+ 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs160[8] = {
+ 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs168[8] = {
+ 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs128[3 * 8] = {
+ 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs148[2 * 8] = {
+ 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs31a[8 * 4] = {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs33a[8 * 4] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs45a[8 * 2] = {
+ 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs170[7 * 8] = {
+ 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs1a8[3 * 8] = {
+ 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static const u8 cs100[2 * 8] = {
+ 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ /* VGA enable */
+ reg = inSISREG(SISVGAENABLE) | 0x01;
+ outSISREG(SISVGAENABLE, reg);
+
+ /* Misc */
+ reg = inSISREG(SISMISCR) | 0x01;
+ outSISREG(SISMISCW, reg);
+
+ /* Unlock SR */
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ inSISIDXREG(SISSR, 0x05, reg);
+ if(reg != 0xa1)
+ return 0;
+
+ /* Clear some regs */
for(i = 0; i < 0x22; i++) {
- outSISIDXREG(SISSR,(0x06 + i),0x00);
+ if(0x06 + i == 0x20) continue;
+ outSISIDXREG(SISSR, 0x06 + i, 0x00);
}
- v1 = 0x0d;
- if( is 330) v1 = 0x0b;
- for(i = 0; i < v1; i++) {
- outSISIDXREG(SISSR,(0x31 + i),0x00);
+ for(i = 0; i < 0x0b; i++) {
+ outSISIDXREG(SISSR, 0x31 + i, 0x00);
}
for(i = 0; i < 0x10; i++) {
- outSISIDXREG(SISCR,(0x30 + i),0x00);
- }
-
- /* Reset clocks */
- reg = inSISREG(SISMISCR);
- outSISIDXREG(SISSR,0x28,0x81);
- outSISIDXREG(SISSR,0x2A,0x00);
- outSISIDXREG(SISSR,0x29,0xE1);
- outSISREG(SISMISCW,(reg | 0x0c));
- outSISIDXREG(SISSR,0x2B,0x81);
- outSISIDXREG(SISSR,0x2D,0x00);
- outSISIDXREG(SISSR,0x2C,0xE1);
- outSISIDXREG(SISSR,0x2E,0x81);
- outSISIDXREG(SISSR,0x30,0x00);
- outSISIDXREG(SISSR,0x2F,0xE1);
- SiS_DDC2Delay(....);
- outSISREG(SISMISCW,reg);
-
- /* Get memory type */
- if(ivideo->sishw_ext.UseROM) {
- if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
- memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
- } else {
- inSISIDXREG(SISSR,0x3a,memtype);
- }
- memtype &= 0x03;
- if( is 330 ) {
- if(memtype <= 1) memtype = 0;
- else {
- inSISIDXREG(SISCR,0x5F,reg);
- reg &= 0x30;
- switch(reg) {
- case 0x00: memtype = 1; break;
- case 0x10: memtype = 3; break;
- case 0x20: memtype = 3; break;
- default: memtype = 2;
- }
- }
- }
+ outSISIDXREG(SISCR, 0x30 + i, 0x00);
}
- /* Set clocks */
- v1 = 0x3b; v2 = 0x22; v3 = 0x01; /* Assume 143Mhz MCLK */
- v4 = 0x5c; v5 = 0x23; v6 = 0x01; /* Assume 166Mhz ECLK */
- if(ivideo->sishw_ext.UseROM) {
- index = memtype * 5;
- rindex = index + 0x54;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- rindex = index + 0x68;
- v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
- }
- outSISIDXREG(SISSR,0x28,v1);
- outSISIDXREG(SISSR,0x29,v2);
- outSISIDXREG(SISSR,0x2a,v3);
- if( is 330 ) {
- inSISIDXREG(SISSR,0x3a,reg);
- reg &= 0x03;
- if(reg >= 2) {
- ...
- }
+ ptr = cs78;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x78];
+ }
+ for(i = 0; i < 3; i++) {
+ outSISIDXREG(SISSR, 0x23 + i, ptr[i]);
+ }
+
+ ptr = cs76;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x76];
+ }
+ for(i = 0; i < 2; i++) {
+ outSISIDXREG(SISSR, 0x21 + i, ptr[i]);
+ }
+
+ v1 = 0x18; v2 = 0x00;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0x74];
+ v2 = bios[0x75];
+ }
+ outSISIDXREG(SISSR, 0x07, v1);
+ outSISIDXREG(SISSR, 0x11, 0x0f);
+ outSISIDXREG(SISSR, 0x1f, v2);
+ /* PCI linear mode, RelIO enabled, A0000 decoding disabled */
+ outSISIDXREG(SISSR, 0x20, 0x80 | 0x20 | 0x04);
+ outSISIDXREG(SISSR, 0x27, 0x74);
+
+ ptr = cs7b;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x7b];
+ }
+ for(i = 0; i < 3; i++) {
+ outSISIDXREG(SISSR, 0x31 + i, ptr[i]);
}
- outSISIDXREG(SISSR,0x2e,v4);
- outSISIDXREG(SISSR,0x2f,v5);
- outSISIDXREG(SISSR,0x30,v6);
-
- /* End of comp with 330 */
-
- v1 = 0x18;
- if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
- outSISIDXREG(SISSR,0x07,v1);
- outSISIDXREG(SISSR,0x11,0x0f);
-
- v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
- v5 = 0xa0; v6 = 0x00; v7 = 0x30;
- if(ivideo->sishw_ext.UseROM) {
- index = memtype + 0x7d;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
- v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
- v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
- }
- outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0x7d step 4) */
- outSISIDXREG(SISSR,0x16,v2);
- outSISIDXREG(SISSR,0x17,v3);
- outSISIDXREG(SISSR,0x18,v4);
- outSISIDXREG(SISSR,0x19,v5);
- outSISIDXREG(SISSR,0x1a,v6);
- outSISIDXREG(SISSR,0x1b,v7);
- outSISIDXREG(SISSR,0x1c,v8); /* ---- */
-
- v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- index = memtype + 0xa2;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
- v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
- }
- outSISIDXREG(SISCR,0x40,v1);
- outSISIDXREG(SISCR,0x41,v2);
- outSISIDXREG(SISCR,0x42,v3);
- outSISIDXREG(SISCR,0x43,v4);
- outSISIDXREG(SISCR,0x44,v5);
-
- if( is 330 ) {
-
- v1 = 0x;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
- }
- outSISIDXREG(SISCR,0x59,v1);
-
- v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
- v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
- if(ivideo->sishw_ext.UseROM) {
- index = memtype + 0xbe;
- v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
- v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
- v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
- v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
- v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
- v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
- }
- outSISIDXREG(SISCR,0x68,v1);
- outSISIDXREG(SISCR,0x69,v2);
- outSISIDXREG(SISCR,0x6a,v3);
- outSISIDXREG(SISCR,0x6b,v4);
- outSISIDXREG(SISCR,0x6c,v5);
- outSISIDXREG(SISCR,0x6d,v6);
- outSISIDXREG(SISCR,0x6e,v7);
- outSISIDXREG(SISCR,0x6f,v8);
-
- v1 = 0x20;
- inSISIDXREG(SISSR,0x3b,reg);
-
- if(!(reg & 0x04)) {
- inSISIDXREG(SISCR,0x5F,reg);
- reg &= 0x30;
- if(reg) v1 = 0x23;
- }
- outSISIDXREG(SISCR,0x48,v1);
- outSISIDXREG(SISCR,0x4c,0x20);
-
- xx= xxx();
- if(xx >= 1) {
- v1 = 0x;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
- }
- outSISIDXREG(SISCR,0x59,v1);
- }
+ if(ivideo->chip == XGI_40) {
+ if(ivideo->revision_id == 2) {
+ setSISIDXREG(SISSR, 0x3b, 0x3f, 0xc0);
+ }
+ outSISIDXREG(SISCR, 0x7d, 0xfe);
+ outSISIDXREG(SISCR, 0x7e, 0x0f);
+ }
+ if(ivideo->revision_id == 0) { /* 40 *and* 20? */
+ andSISIDXREG(SISCR, 0x58, 0xd7);
+ inSISIDXREG(SISCR, 0xcb, reg);
+ if(reg & 0x20) {
+ setSISIDXREG(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */
+ }
+ }
+ reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00;
+ setSISIDXREG(SISCR, 0x38, 0x1f, reg);
+ if(ivideo->chip == XGI_20) {
+ outSISIDXREG(SISSR, 0x36, 0x70);
} else {
+ outSISIDXREG(SISVID, 0x00, 0x86);
+ outSISIDXREG(SISVID, 0x32, 0x00);
+ outSISIDXREG(SISVID, 0x30, 0x00);
+ outSISIDXREG(SISVID, 0x32, 0x01);
+ outSISIDXREG(SISVID, 0x30, 0x00);
+ andSISIDXREG(SISVID, 0x2f, 0xdf);
+ andSISIDXREG(SISCAP, 0x00, 0x3f);
+
+ outSISIDXREG(SISPART1, 0x2f, 0x01);
+ outSISIDXREG(SISPART1, 0x00, 0x00);
+ outSISIDXREG(SISPART1, 0x02, bios[0x7e]);
+ outSISIDXREG(SISPART1, 0x2e, 0x08);
+ andSISIDXREG(SISPART1, 0x35, 0x7f);
+ andSISIDXREG(SISPART1, 0x50, 0xfe);
+
+ inSISIDXREG(SISPART4, 0x00, reg);
+ if(reg == 1 || reg == 2) {
+ outSISIDXREG(SISPART2, 0x00, 0x1c);
+ outSISIDXREG(SISPART4, 0x0d, bios[0x7f]);
+ outSISIDXREG(SISPART4, 0x0e, bios[0x80]);
+ outSISIDXREG(SISPART4, 0x10, bios[0x81]);
+ andSISIDXREG(SISPART4, 0x0f, 0x3f);
+
+ inSISIDXREG(SISPART4, 0x01, reg);
+ if((reg & 0xf0) >= 0xb0) {
+ inSISIDXREG(SISPART4, 0x23, reg);
+ if(reg & 0x20) reg |= 0x40;
+ outSISIDXREG(SISPART4, 0x23, reg);
+ reg = (reg & 0x20) ? 0x02 : 0x00;
+ setSISIDXREG(SISPART1, 0x1e, 0xfd, reg);
+ }
+ }
- outSISIDXREG(SISCR,0x48,0x23);
+ v1 = bios[0x77];
+
+ inSISIDXREG(SISSR, 0x3b, reg);
+ if(reg & 0x02) {
+ inSISIDXREG(SISSR, 0x3a, reg);
+ v2 = (reg & 0x30) >> 3;
+ if(!(v2 & 0x04)) v2 ^= 0x02;
+ inSISIDXREG(SISSR, 0x39, reg);
+ if(reg & 0x80) v2 |= 0x80;
+ v2 |= 0x01;
+
+ if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
+ SIS_PCI_PUT_DEVICE(mypdev);
+ if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
+ v2 &= 0xf9;
+ v2 |= 0x08;
+ v1 &= 0xfe;
+ } else {
+ mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL);
+ if(!mypdev)
+ mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL);
+ if(!mypdev)
+ mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL);
+ if(mypdev) {
+ pci_read_config_dword(mypdev, 0x94, &regd);
+ regd &= 0xfffffeff;
+ pci_write_config_dword(mypdev, 0x94, regd);
+ v1 &= 0xfe;
+ SIS_PCI_PUT_DEVICE(mypdev);
+ } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
+ v1 &= 0xfe;
+ } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
+ sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
+ sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
+ sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
+ if((v2 & 0x06) == 4)
+ v2 ^= 0x06;
+ v2 |= 0x08;
+ }
+ }
+ setSISIDXREG(SISCR, 0x5f, 0xf0, v2);
+ }
+ outSISIDXREG(SISSR, 0x22, v1);
+
+ if(ivideo->revision_id == 2) {
+ inSISIDXREG(SISSR, 0x3b, v1);
+ inSISIDXREG(SISSR, 0x3a, v2);
+ regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
+ if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
+ setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
+
+ if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) {
+ /* TODO: set CR5f &0xf1 | 0x01 for version 6570
+ * of nforce 2 ROM
+ */
+ if(0)
+ setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
+ SIS_PCI_PUT_DEVICE(mypdev);
+ }
+ }
- andSISIDXREG(SISSR,0x16,0x0f);
- if(memtype <= 1) {
- orSISIDXREG(SISSR,0x16,0x80);
- } else {
- v1 = 0x0f;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype];
- }
- if(!(v1 & 0x10)) v2 = 0xc0;
- else v2 = 0xd0;
- orSISIDXREG(SISSR,0x16,v2);
- andSISIDXREG(SISSR,0x16,0x0f);
- if(!(v1 & 0x10)) v2 = 0x80;
- else v2 = 0xA0;
- orSISIDXREG(SISSR,0x16,v2);
- }
-
- if(memtype >= 2) {
- const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
- const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
- for(i = 0; i < 11; i++) {
- outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
- }
- outSISIDXREG(SISSR,0x3d,0x00);
- outSISIDXREG(SISSR,0x3d,0x04);
- SiS_DDC2Delay(0x200);
- v1 = inSISIDXREG(SISCR,0xEC);
- v2 = inSISIDXREG(SISCR,0xED);
- reg1_32 = (v2 << 8) | v1;
- outSISIDXREG(SISSR,0x3D,0x00);
- for(i = 0; i < 11; i++) {
- outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
- }
- outSISIDXREG(SISSR,0x3d,0x00);
- outSISIDXREG(SISSR,0x3d,0x04);
- SiS_DDC2Delay(0x200);
- v1 = inSISIDXREG(SISCR,0xEC);
- v2 = inSISIDXREG(SISCR,0xED);
- reg2_32 = (v2 << 8) | v1;
- outSISIDXREG(SISSR,0x3D,0x00);
- reg3_32 = reg2_32 << 1;
- reg2_32 >>= 1;
- reg3_32 += reg2_32;
- v1 = 0x40;
- if(reg3_32 > reg1_32) v1 = 0x10;
- outSISIDXREG(SISCR,0x59,v1);
- }
+ v1 = 0x30;
+ inSISIDXREG(SISSR, 0x3b, reg);
+ inSISIDXREG(SISCR, 0x5f, v2);
+ if((!(reg & 0x02)) && (v2 & 0x0e))
+ v1 |= 0x08;
+ outSISIDXREG(SISSR, 0x27, v1);
+
+ if(bios[0x64] & 0x01) {
+ setSISIDXREG(SISCR, 0x5f, 0xf0, bios[0x64]);
+ }
+ v1 = bios[0x4f7];
+ pci_read_config_dword(pdev, 0x50, &regd);
+ regd = (regd >> 20) & 0x0f;
+ if(regd == 1) {
+ v1 &= 0xfc;
+ orSISIDXREG(SISCR, 0x5f, 0x08);
+ }
+ outSISIDXREG(SISCR, 0x48, v1);
+
+ setSISIDXREG(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb);
+ setSISIDXREG(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f);
+ setSISIDXREG(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f);
+ setSISIDXREG(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7);
+ setSISIDXREG(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f);
+ outSISIDXREG(SISCR, 0x70, bios[0x4fc]);
+ setSISIDXREG(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f);
+ outSISIDXREG(SISCR, 0x74, 0xd0);
+ setSISIDXREG(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30);
+ setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
+ setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
+ v1 = bios[0x501];
+ if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) {
+ v1 = 0xf0;
+ SIS_PCI_PUT_DEVICE(mypdev);
+ }
+ outSISIDXREG(SISCR, 0x77, v1);
}
- v1 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99];
+ /* RAM type */
+
+ regb = 0; /* ! */
+
+ v1 = 0xff;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0x140 + regb];
}
- outSISIDXREG(SISSR,0x1f,v1);
+ outSISIDXREG(SISCR, 0x6d, v1);
- outSISIDXREG(SISSR,0x20,0x20);
+ ptr = cs128;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x128];
+ }
+ for(i = 0, j = 0; i < 3; i++, j += 8) {
+ outSISIDXREG(SISCR, 0x68 + i, ptr[j + regb]);
+ }
- v1 = 0xf6; v2 = 0x0d; v3 = 0x33;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e];
+ ptr = cs31a;
+ ptr2 = cs33a;
+ if(ivideo->haveXGIROM) {
+ index = (ivideo->chip == XGI_20) ? 0x31a : 0x3a6;
+ ptr = (const u8 *)&bios[index];
+ ptr2 = (const u8 *)&bios[index + 0x20];
+ }
+ for(i = 0; i < 2; i++) {
+ if(i == 0) {
+ regd = le32_to_cpu(((u32 *)ptr)[regb]);
+ rega = 0x6b;
+ } else {
+ regd = le32_to_cpu(((u32 *)ptr2)[regb]);
+ rega = 0x6e;
+ }
+ reg = 0x00;
+ for(j = 0; j < 16; j++) {
+ reg &= 0xf3;
+ if(regd & 0x01) reg |= 0x04;
+ if(regd & 0x02) reg |= 0x08;
+ regd >>= 2;
+ outSISIDXREG(SISCR, rega, reg);
+ inSISIDXREG(SISCR, rega, reg);
+ inSISIDXREG(SISCR, rega, reg);
+ reg += 0x10;
+ }
}
- outSISIDXREG(SISSR,0x23,v1);
- outSISIDXREG(SISSR,0x24,v2);
- outSISIDXREG(SISSR,0x25,v3);
- outSISIDXREG(SISSR,0x21,0x84);
- outSISIDXREG(SISSR,0x22,0x00);
- outSISIDXREG(SISSR,0x27,0x1f);
+ andSISIDXREG(SISCR, 0x6e, 0xfc);
- v1 = 0x00; v2 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1];
- }
- outSISIDXREG(SISSR,0x31,v1);
- outSISIDXREG(SISSR,0x33,v2);
-
- v1 = 0x11;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0];
- }
- v2 = inSISIDXREG(SISPART4,0x00);
- if((v2 != 1) && (v2 != 2)) v1 &= 0xef;
- outSISIDXREG(SISSR,0x32,v1);
-
- /* AGP */
- pci_read_config_long(pdev, 0x50, &reg1_32);
- reg1_32 >>= 20;
- reg1_32 &= 0x0f;
- if(reg1_32 == 1) {
- v1 = 0xAA; v2 = 0x33;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E];
- }
- } else {
- v1 = 0x88; v2 = 0x03;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
- }
+ ptr = NULL;
+ if(ivideo->haveXGIROM) {
+ index = (ivideo->chip == XGI_20) ? 0x35a : 0x3e6;
+ ptr = (const u8 *)&bios[index];
+ }
+ for(i = 0; i < 4; i++) {
+ setSISIDXREG(SISCR, 0x6e, 0xfc, i);
+ reg = 0x00;
+ for(j = 0; j < 2; j++) {
+ regd = 0;
+ if(ptr) {
+ regd = le32_to_cpu(((u32 *)ptr)[regb * 8]);
+ ptr += 4;
+ }
+ /* reg = 0x00; */
+ for(k = 0; k < 16; k++) {
+ reg &= 0xfc;
+ if(regd & 0x01) reg |= 0x01;
+ if(regd & 0x02) reg |= 0x02;
+ regd >>= 2;
+ outSISIDXREG(SISCR, 0x6f, reg);
+ inSISIDXREG(SISCR, 0x6f, reg);
+ inSISIDXREG(SISCR, 0x6f, reg);
+ reg += 0x08;
+ }
+ }
}
- outSISIDXREG(SISCR,0x49,v1);
- outSISIDXREG(SISSR,0x25,v2);
- v1 = inSISIDXREG(SISPART4,0x00);
- if((v1 == 1) || (v1 == 2)) {
- orSISIDXREG(SISPART1,0x2F,0x01); /* Unlock CRT2 */
- outSISIDXREG(SISPART1,0x00,0x00);
- v1 = 0x00;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
- }
- outSISIDXREG(SISPART1,0x02,v1);
- outSISIDXREG(SISPART1,0x2E,0x08);
- outSISIDXREG(SISPART2,0x00,0x1c);
- v1 = 0x40; v2 = 0x00; v3 = 0x80;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
- v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
- }
- outSISIDXREG(SISPART4,0x0d,v1);
- outSISIDXREG(SISPART4,0x0e,v2);
- outSISIDXREG(SISPART4,0x10,v3);
- outSISIDXREG(SISPART4,0x0F,0x3F);
-
- inSISIDXREG(SISPART4,0x01,reg);
- if(reg >= 0xb0) {
- inSISIDXREG(SISPART4,0x23,reg);
- reg &= 0x20;
- reg <<= 1;
- outSISIDXREG(SISPART4,0x23,reg);
- }
+ ptr = cs148;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x148];
+ }
+ for(i = 0, j = 0; i < 2; i++, j += 8) {
+ outSISIDXREG(SISCR, 0x80 + i, ptr[j + regb]);
}
- outSISIDXREG(SISCR,0x37,0x02); /* Why? */
-
- outSISIDXREG(SISCR,0x83,0x00);
- outSISIDXREG(SISCR,0x90,0x00);
- andSISIDXREG(SISSR,0x5B,0xDF);
- outSISIDXREG(SISVID,0x00,0x86);
- outSISIDXREG(SISVID,0x32,0x00);
- outSISIDXREG(SISVID,0x30,0x00);
- outSISIDXREG(SISVID,0x32,0x01);
- outSISIDXREG(SISVID,0x30,0x00);
- orSISIDXREG(SISCR,0x63,0x80);
- /* End of Init1 */
-
- /* Set Mode 0x2e */
-
- /* Ramsize */
- orSISIDXREG(SISSR,0x16,0x0f);
- orSISIDXREG(SISSR,0x18,0xA9);
- orSISIDXREG(SISSR,0x19,0xA0);
- orSISIDXREG(SISSR,0x1B,0x30);
- andSISIDXREG(SISSR,0x17,0xF8);
- orSISIDXREG(SISSR,0x19,0x03);
- andSIDIDXREG(SISSR,0x13,0x00);
- /* Need to map max FB size for finding out about RAM size */
- ivideo->video_vbase = ioremap(ivideo->video_base, 0x4000000);
- if(ivideo->video_vbase) {
- /* Find out about bus width */
- if(memtype <= 1) {
- outSISIDXREG(SISSR,0x14,0x02);
- andSISIDXREG(SISSR,0x16,0x0F);
- orSISIDXREG(SISSR,0x16,0x80);
+ andSISIDXREG(SISCR, 0x89, 0x8f);
- ...
+ ptr = cs45a;
+ if(ivideo->haveXGIROM) {
+ index = (ivideo->chip == XGI_20) ? 0x45a : 0x4e6;
+ ptr = (const u8 *)&bios[index];
+ }
+ regd = le16_to_cpu(((const u16 *)ptr)[regb]);
+ reg = 0x80;
+ for(i = 0; i < 5; i++) {
+ reg &= 0xfc;
+ if(regd & 0x01) reg |= 0x01;
+ if(regd & 0x02) reg |= 0x02;
+ regd >>= 2;
+ outSISIDXREG(SISCR, 0x89, reg);
+ inSISIDXREG(SISCR, 0x89, reg);
+ inSISIDXREG(SISCR, 0x89, reg);
+ reg += 0x10;
+ }
- } else {
+ v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0x118 + regb];
+ v2 = bios[0xf8 + regb];
+ v3 = bios[0x120 + regb];
+ v4 = bios[0x1ca];
+ }
+ outSISIDXREG(SISCR, 0x45, v1 & 0x0f);
+ outSISIDXREG(SISCR, 0x99, (v1 >> 4) & 0x07);
+ orSISIDXREG(SISCR, 0x40, v1 & 0x80);
+ outSISIDXREG(SISCR, 0x41, v2);
- ...
+ ptr = cs170;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x170];
+ }
+ for(i = 0, j = 0; i < 7; i++, j += 8) {
+ outSISIDXREG(SISCR, 0x90 + i, ptr[j + regb]);
+ }
- }
+ outSISIDXREG(SISCR, 0x59, v3);
- /* Find out about size */
+ ptr = cs1a8;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x1a8];
+ }
+ for(i = 0, j = 0; i < 3; i++, j += 8) {
+ outSISIDXREG(SISCR, 0xc3 + i, ptr[j + regb]);
+ }
+ ptr = cs100;
+ if(ivideo->haveXGIROM) {
+ ptr = (const u8 *)&bios[0x100];
+ }
+ for(i = 0, j = 0; i < 2; i++, j += 8) {
+ outSISIDXREG(SISCR, 0x8a + i, ptr[j + regb]);
+ }
- iounmap(ivideo->video_vbase);
- } else {
- printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
- outSISIDXREG(SISSR,0x14,0x??); /* 8MB, 64bit default */
+ outSISIDXREG(SISCR, 0xcf, v4);
+
+ outSISIDXREG(SISCR, 0x83, 0x09);
+ outSISIDXREG(SISCR, 0x87, 0x00);
+
+ if(ivideo->chip == XGI_40) {
+ if( (ivideo->revision_id == 1) ||
+ (ivideo->revision_id == 2) ) {
+ outSISIDXREG(SISCR, 0x8c, 0x87);
+ }
+ }
+
+ outSISIDXREG(SISSR, 0x17, 0x00);
+ outSISIDXREG(SISSR, 0x1a, 0x87);
+
+ if(ivideo->chip == XGI_20) {
+ outSISIDXREG(SISSR, 0x15, 0x00);
+ outSISIDXREG(SISSR, 0x1c, 0x00);
+ }
+
+ ramtype = 0x00; v1 = 0x10;
+ if(ivideo->haveXGIROM) {
+ ramtype = bios[0x62];
+ v1 = bios[0x1d2];
+ }
+ if(!(ramtype & 0x80)) {
+ if(ivideo->chip == XGI_20) {
+ outSISIDXREG(SISCR, 0x97, v1);
+ inSISIDXREG(SISCR, 0x97, reg);
+ if(reg & 0x10) {
+ ramtype = (reg & 0x01) << 1;
+ }
+ } else {
+ inSISIDXREG(SISSR, 0x39, reg);
+ ramtype = reg & 0x02;
+ if(!(ramtype)) {
+ inSISIDXREG(SISSR, 0x3a, reg);
+ ramtype = (reg >> 1) & 0x01;
+ }
+ }
+ }
+ ramtype &= 0x07;
+
+ regb = 0; /* ! */
+
+ switch(ramtype) {
+ case 0:
+ sisfb_post_xgi_setclocks(ivideo, regb);
+ if((ivideo->chip == XGI_20) ||
+ (ivideo->revision_id == 1) ||
+ (ivideo->revision_id == 2)) {
+ v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
+ if(ivideo->haveXGIROM) {
+ v1 = bios[regb + 0x158];
+ v2 = bios[regb + 0x160];
+ v3 = bios[regb + 0x168];
+ }
+ outSISIDXREG(SISCR, 0x82, v1);
+ outSISIDXREG(SISCR, 0x85, v2);
+ outSISIDXREG(SISCR, 0x86, v3);
+ } else {
+ outSISIDXREG(SISCR, 0x82, 0x88);
+ outSISIDXREG(SISCR, 0x86, 0x00);
+ inSISIDXREG(SISCR, 0x86, reg);
+ outSISIDXREG(SISCR, 0x86, 0x88);
+ inSISIDXREG(SISCR, 0x86, reg);
+ outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
+ outSISIDXREG(SISCR, 0x82, 0x77);
+ outSISIDXREG(SISCR, 0x85, 0x00);
+ inSISIDXREG(SISCR, 0x85, reg);
+ outSISIDXREG(SISCR, 0x85, 0x88);
+ inSISIDXREG(SISCR, 0x85, reg);
+ outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
+ outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
+ }
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISCR, 0x97, 0x00);
+ }
+ outSISIDXREG(SISCR, 0x98, 0x01);
+ outSISIDXREG(SISCR, 0x9a, 0x02);
+
+ outSISIDXREG(SISSR, 0x18, 0x01);
+ if((ivideo->chip == XGI_20) ||
+ (ivideo->revision_id == 2)) {
+ outSISIDXREG(SISSR, 0x19, 0x40);
+ } else {
+ outSISIDXREG(SISSR, 0x19, 0x20);
+ }
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) {
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ outSISIDXREG(SISSR, 0x18, 0x00);
+ if((ivideo->chip == XGI_20) ||
+ (ivideo->revision_id == 2)) {
+ outSISIDXREG(SISSR, 0x19, 0x40);
+ } else {
+ outSISIDXREG(SISSR, 0x19, 0x20);
+ }
+ } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) {
+ /* outSISIDXREG(SISSR, 0x16, 0x0c); */ /* ? */
+ }
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ sisfb_post_xgi_delay(ivideo, 4);
+ v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0xf0];
+ index = (ivideo->chip == XGI_20) ? 0x4b2 : 0x53e;
+ v2 = bios[index];
+ v3 = bios[index + 1];
+ v4 = bios[index + 2];
+ v5 = bios[index + 3];
+ }
+ outSISIDXREG(SISSR, 0x18, v1);
+ outSISIDXREG(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01));
+ outSISIDXREG(SISSR, 0x16, v2);
+ outSISIDXREG(SISSR, 0x16, v3);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ outSISIDXREG(SISSR, 0x1b, 0x03);
+ sisfb_post_xgi_delay(ivideo, 0x22);
+ outSISIDXREG(SISSR, 0x18, v1);
+ outSISIDXREG(SISSR, 0x19, 0x00);
+ outSISIDXREG(SISSR, 0x16, v4);
+ outSISIDXREG(SISSR, 0x16, v5);
+ outSISIDXREG(SISSR, 0x1b, 0x00);
+ break;
+ case 1:
+ outSISIDXREG(SISCR, 0x82, 0x77);
+ outSISIDXREG(SISCR, 0x86, 0x00);
+ inSISIDXREG(SISCR, 0x86, reg);
+ outSISIDXREG(SISCR, 0x86, 0x88);
+ inSISIDXREG(SISCR, 0x86, reg);
+ v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
+ if(ivideo->haveXGIROM) {
+ v1 = bios[regb + 0x168];
+ v2 = bios[regb + 0x160];
+ v3 = bios[regb + 0x158];
+ }
+ outSISIDXREG(SISCR, 0x86, v1);
+ outSISIDXREG(SISCR, 0x82, 0x77);
+ outSISIDXREG(SISCR, 0x85, 0x00);
+ inSISIDXREG(SISCR, 0x85, reg);
+ outSISIDXREG(SISCR, 0x85, 0x88);
+ inSISIDXREG(SISCR, 0x85, reg);
+ outSISIDXREG(SISCR, 0x85, v2);
+ outSISIDXREG(SISCR, 0x82, v3);
+ outSISIDXREG(SISCR, 0x98, 0x01);
+ outSISIDXREG(SISCR, 0x9a, 0x02);
+
+ outSISIDXREG(SISSR, 0x28, 0x64);
+ outSISIDXREG(SISSR, 0x29, 0x63);
+ sisfb_post_xgi_delay(ivideo, 15);
+ outSISIDXREG(SISSR, 0x18, 0x00);
+ outSISIDXREG(SISSR, 0x19, 0x20);
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ outSISIDXREG(SISSR, 0x18, 0xc5);
+ outSISIDXREG(SISSR, 0x19, 0x23);
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ sisfb_post_xgi_delay(ivideo, 1);
+ outSISIDXREG(SISCR, 0x97,0x11);
+ sisfb_post_xgi_setclocks(ivideo, regb);
+ sisfb_post_xgi_delay(ivideo, 0x46);
+ outSISIDXREG(SISSR, 0x18, 0xc5);
+ outSISIDXREG(SISSR, 0x19, 0x23);
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ sisfb_post_xgi_delay(ivideo, 1);
+ outSISIDXREG(SISSR, 0x1b, 0x04);
+ sisfb_post_xgi_delay(ivideo, 1);
+ outSISIDXREG(SISSR, 0x1b, 0x00);
+ sisfb_post_xgi_delay(ivideo, 1);
+ v1 = 0x31;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0xf0];
+ }
+ outSISIDXREG(SISSR, 0x18, v1);
+ outSISIDXREG(SISSR, 0x19, 0x06);
+ outSISIDXREG(SISSR, 0x16, 0x04);
+ outSISIDXREG(SISSR, 0x16, 0x84);
+ sisfb_post_xgi_delay(ivideo, 1);
+ break;
+ default:
+ sisfb_post_xgi_setclocks(ivideo, regb);
+ if((ivideo->chip == XGI_40) &&
+ ((ivideo->revision_id == 1) ||
+ (ivideo->revision_id == 2))) {
+ outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]);
+ outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]);
+ outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]);
+ } else {
+ outSISIDXREG(SISCR, 0x82, 0x88);
+ outSISIDXREG(SISCR, 0x86, 0x00);
+ inSISIDXREG(SISCR, 0x86, reg);
+ outSISIDXREG(SISCR, 0x86, 0x88);
+ outSISIDXREG(SISCR, 0x82, 0x77);
+ outSISIDXREG(SISCR, 0x85, 0x00);
+ inSISIDXREG(SISCR, 0x85, reg);
+ outSISIDXREG(SISCR, 0x85, 0x88);
+ inSISIDXREG(SISCR, 0x85, reg);
+ v1 = cs160[regb]; v2 = cs158[regb];
+ if(ivideo->haveXGIROM) {
+ v1 = bios[regb + 0x160];
+ v2 = bios[regb + 0x158];
+ }
+ outSISIDXREG(SISCR, 0x85, v1);
+ outSISIDXREG(SISCR, 0x82, v2);
+ }
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISCR, 0x97, 0x11);
+ }
+ if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) {
+ outSISIDXREG(SISCR, 0x98, 0x01);
+ } else {
+ outSISIDXREG(SISCR, 0x98, 0x03);
+ }
+ outSISIDXREG(SISCR, 0x9a, 0x02);
+
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISSR, 0x18, 0x01);
+ } else {
+ outSISIDXREG(SISSR, 0x18, 0x00);
+ }
+ outSISIDXREG(SISSR, 0x19, 0x40);
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) {
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ outSISIDXREG(SISSR, 0x18, 0x00);
+ outSISIDXREG(SISSR, 0x19, 0x40);
+ outSISIDXREG(SISSR, 0x16, 0x00);
+ outSISIDXREG(SISSR, 0x16, 0x80);
+ }
+ sisfb_post_xgi_delay(ivideo, 4);
+ v1 = 0x31;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0xf0];
+ }
+ outSISIDXREG(SISSR, 0x18, v1);
+ outSISIDXREG(SISSR, 0x19, 0x01);
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISSR, 0x16, bios[0x53e]);
+ outSISIDXREG(SISSR, 0x16, bios[0x53f]);
+ } else {
+ outSISIDXREG(SISSR, 0x16, 0x05);
+ outSISIDXREG(SISSR, 0x16, 0x85);
+ }
+ sisfb_post_xgi_delay(ivideo, 0x43);
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISSR, 0x1b, 0x01);
+ } else {
+ outSISIDXREG(SISSR, 0x1b, 0x03);
+ }
+ sisfb_post_xgi_delay(ivideo, 0x22);
+ outSISIDXREG(SISSR, 0x18, v1);
+ outSISIDXREG(SISSR, 0x19, 0x00);
+ if(ivideo->chip == XGI_40) {
+ outSISIDXREG(SISSR, 0x16, bios[0x540]);
+ outSISIDXREG(SISSR, 0x16, bios[0x541]);
+ } else {
+ outSISIDXREG(SISSR, 0x16, 0x05);
+ outSISIDXREG(SISSR, 0x16, 0x85);
+ }
+ outSISIDXREG(SISSR, 0x1b, 0x00);
+ }
+
+ regb = 0; /* ! */
+ v1 = 0x03;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0x110 + regb];
+ }
+ outSISIDXREG(SISSR, 0x1b, v1);
+
+ /* RAM size */
+ v1 = 0x00; v2 = 0x00;
+ if(ivideo->haveXGIROM) {
+ v1 = bios[0x62];
+ v2 = bios[0x63];
}
+ regb = 0; /* ! */
+ regd = 1 << regb;
+ if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) {
+
+ outSISIDXREG(SISSR, 0x13, bios[regb + 0xe0]);
+ outSISIDXREG(SISSR, 0x14, bios[regb + 0xe0 + 8]);
+
+ } else {
+
+ /* Set default mode, don't clear screen */
+ ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->curFSTN = ivideo->curDSTN = 0;
+ ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
+ SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
+
+ outSISIDXREG(SISSR, 0x05, 0x86);
+
+ /* Disable read-cache */
+ andSISIDXREG(SISSR, 0x21, 0xdf);
+ sisfb_post_xgi_ramsize(ivideo);
+ /* Enable read-cache */
+ orSISIDXREG(SISSR, 0x21, 0x20);
- /* AGP (Missing: Checks for VIA and AMD hosts) */
- v1 = 0xA5; v2 = 0xFB;
- if(ivideo->sishw_ext.UseROM) {
- v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
- v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
}
- outSISIDXREG(SISSR,0x21,v1);
- outSISIDXREG(SISSR,0x22,v2);
+#if 0
+ printk(KERN_DEBUG "-----------------\n");
+ for(i = 0; i < 0xff; i++) {
+ inSISIDXREG(SISCR, i, reg);
+ printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg);
+ }
+ for(i = 0; i < 0x40; i++) {
+ inSISIDXREG(SISSR, i, reg);
+ printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg);
+ }
+ printk(KERN_DEBUG "-----------------\n");
#endif
- return;
+
+ /* Sense CRT1 */
+ if(ivideo->chip == XGI_20) {
+ orSISIDXREG(SISCR, 0x32, 0x20);
+ } else {
+ inSISIDXREG(SISPART4, 0x00, reg);
+ if((reg == 1) || (reg == 2)) {
+ sisfb_sense_crt1(ivideo);
+ } else {
+ orSISIDXREG(SISCR, 0x32, 0x20);
+ }
+ }
+
+ /* Set default mode, don't clear screen */
+ ivideo->SiS_Pr.SiS_UseOEM = FALSE;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->curFSTN = ivideo->curDSTN = 0;
+ SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
+
+ outSISIDXREG(SISSR, 0x05, 0x86);
+
+ /* Display off */
+ orSISIDXREG(SISSR, 0x01, 0x20);
+
+ /* Save mode number in CR34 */
+ outSISIDXREG(SISCR, 0x34, 0x2e);
+
+ /* Let everyone know what the current mode is */
+ ivideo->modeprechange = 0x2e;
+
+ if(ivideo->chip == XGI_40) {
+ inSISIDXREG(SISCR, 0xca, reg);
+ inSISIDXREG(SISCR, 0xcc, v1);
+ if((reg & 0x10) && (!(v1 & 0x04))) {
+ printk(KERN_ERR
+ "sisfb: Please connect power to the card.\n");
+ return 0;
+ }
+ }
+
+ return 1;
}
#endif
-
-static int __devinit sisfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int __devinit
+sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
- struct sis_video_info *ivideo = NULL;
- struct fb_info *sis_fb_info = NULL;
+ struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
+ struct sis_video_info *ivideo = NULL;
+ struct fb_info *sis_fb_info = NULL;
u16 reg16;
u8 reg;
- int sisvga_enabled = 0, i;
+ int i, ret;
- if(sisfb_off) return -ENXIO;
+ if(sisfb_off)
+ return -ENXIO;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
- if(!sis_fb_info) return -ENOMEM;
+ if(!sis_fb_info)
+ return -ENOMEM;
#else
sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
- if(!sis_fb_info) return -ENOMEM;
+ if(!sis_fb_info)
+ return -ENOMEM;
memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
#endif
@@ -4787,27 +5890,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo = (struct sis_video_info *)sis_fb_info->par;
ivideo->memyselfandi = sis_fb_info;
+ ivideo->sisfb_id = SISFB_ID;
+
if(card_list == NULL) {
- ivideo->cardnumber = 0;
+ ivideo->cardnumber = 0;
} else {
- struct sis_video_info *countvideo = card_list;
- ivideo->cardnumber = 1;
- while((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+ struct sis_video_info *countvideo = card_list;
+ ivideo->cardnumber = 1;
+ while((countvideo = countvideo->next) != 0)
+ ivideo->cardnumber++;
}
strncpy(ivideo->myid, chipinfo->chip_name, 30);
ivideo->warncount = 0;
ivideo->chip_id = pdev->device;
+ ivideo->chip_vendor = pdev->vendor;
pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
- ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
+ ivideo->SiS_Pr.ChipRevision = ivideo->revision_id;
pci_read_config_word(pdev, PCI_COMMAND, &reg16);
- sisvga_enabled = reg16 & 0x01;
+ ivideo->sisvga_enabled = reg16 & 0x01;
ivideo->pcibus = pdev->bus->number;
ivideo->pcislot = PCI_SLOT(pdev->devfn);
ivideo->pcifunc = PCI_FUNC(pdev->devfn);
ivideo->subsysvendor = pdev->subsystem_vendor;
ivideo->subsysdevice = pdev->subsystem_device;
+#ifdef SIS_OLD_CONFIG_COMPAT
+ ivideo->ioctl32registered = 0;
+#endif
#ifndef MODULE
if(sisfb_mode_idx == -1) {
@@ -4827,6 +5937,24 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->sisfb_thismonitor.datavalid = FALSE;
+ ivideo->current_base = 0;
+
+ ivideo->engineok = 0;
+
+ ivideo->sisfb_was_boot_device = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12))
+ if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) {
+ if(ivideo->sisvga_enabled)
+ ivideo->sisfb_was_boot_device = 1;
+ else {
+ printk(KERN_DEBUG "sisfb: PCI device is disabled, "
+ "but marked as boot video device ???\n");
+ printk(KERN_DEBUG "sisfb: I will not accept this "
+ "as the primary VGA device\n");
+ }
+ }
+#endif
+
ivideo->sisfb_parm_mem = sisfb_parm_mem;
ivideo->sisfb_accel = sisfb_accel;
ivideo->sisfb_ypan = sisfb_ypan;
@@ -4846,7 +5974,6 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->sisfb_tvstd = sisfb_tvstd;
ivideo->tvxpos = sisfb_tvxposoffset;
ivideo->tvypos = sisfb_tvyposoffset;
- ivideo->sisfb_filter = sisfb_filter;
ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
ivideo->sisfb_inverse = sisfb_inverse;
@@ -4854,7 +5981,7 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->refresh_rate = 0;
if(ivideo->sisfb_parm_rate != -1) {
- ivideo->refresh_rate = ivideo->sisfb_parm_rate;
+ ivideo->refresh_rate = ivideo->sisfb_parm_rate;
}
ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
@@ -4863,8 +5990,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
- ivideo->SiS_Pr.SiS_CHOverScan = -1;
- ivideo->SiS_Pr.SiS_ChSW = FALSE;
+ ivideo->SiS_Pr.SiS_CHOverScan = -1;
+ ivideo->SiS_Pr.SiS_ChSW = FALSE;
ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
ivideo->SiS_Pr.HaveEMI = FALSE;
ivideo->SiS_Pr.HaveEMILCD = FALSE;
@@ -4873,12 +6000,13 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
ivideo->SiS_Pr.PDC = -1;
ivideo->SiS_Pr.PDCA = -1;
+ ivideo->SiS_Pr.DDCPortMixup = FALSE;
#ifdef CONFIG_FB_SIS_315
if(ivideo->chip >= SIS_330) {
- ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
- if(ivideo->chip >= SIS_661) {
- ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
- }
+ ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
+ if(ivideo->chip >= SIS_661) {
+ ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
+ }
}
#endif
@@ -4891,9 +6019,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
switch(ivideo->nbridge->device) {
#ifdef CONFIG_FB_SIS_300
case PCI_DEVICE_ID_SI_730:
- ivideo->chip = SIS_730;
+ ivideo->chip = SIS_730;
strcpy(ivideo->myid, "SiS 730");
- break;
+ break;
#endif
#ifdef CONFIG_FB_SIS_315
case PCI_DEVICE_ID_SI_651:
@@ -4901,22 +6029,28 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
strcpy(ivideo->myid, "SiS 651");
break;
case PCI_DEVICE_ID_SI_740:
- ivideo->chip = SIS_740;
+ ivideo->chip = SIS_740;
strcpy(ivideo->myid, "SiS 740");
break;
case PCI_DEVICE_ID_SI_661:
- ivideo->chip = SIS_661;
+ ivideo->chip = SIS_661;
strcpy(ivideo->myid, "SiS 661");
break;
case PCI_DEVICE_ID_SI_741:
- ivideo->chip = SIS_741;
+ ivideo->chip = SIS_741;
strcpy(ivideo->myid, "SiS 741");
break;
case PCI_DEVICE_ID_SI_760:
- ivideo->chip = SIS_760;
+ ivideo->chip = SIS_760;
strcpy(ivideo->myid, "SiS 760");
break;
+ case PCI_DEVICE_ID_SI_761:
+ ivideo->chip = SIS_761;
+ strcpy(ivideo->myid, "SiS 761");
+ break;
#endif
+ default:
+ break;
}
}
@@ -4924,71 +6058,83 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
strcpy(sis_fb_info->modename, ivideo->myid);
#endif
- ivideo->sishw_ext.jChipType = ivideo->chip;
+ ivideo->SiS_Pr.ChipType = ivideo->chip;
+
+ ivideo->SiS_Pr.ivideo = (void *)ivideo;
#ifdef CONFIG_FB_SIS_315
- if((ivideo->sishw_ext.jChipType == SIS_315PRO) ||
- (ivideo->sishw_ext.jChipType == SIS_315)) {
- ivideo->sishw_ext.jChipType = SIS_315H;
+ if((ivideo->SiS_Pr.ChipType == SIS_315PRO) ||
+ (ivideo->SiS_Pr.ChipType == SIS_315)) {
+ ivideo->SiS_Pr.ChipType = SIS_315H;
}
#endif
+ if(!ivideo->sisvga_enabled) {
+ if(pci_enable_device(pdev)) {
+ if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ pci_set_drvdata(pdev, NULL);
+ kfree(sis_fb_info);
+ return -EIO;
+ }
+ }
+
ivideo->video_base = pci_resource_start(pdev, 0);
ivideo->mmio_base = pci_resource_start(pdev, 1);
ivideo->mmio_size = pci_resource_len(pdev, 1);
ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
- ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
+ ivideo->SiS_Pr.IOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
- if(!sisvga_enabled) {
- if(pci_enable_device(pdev)) {
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -EIO;
- }
- }
-
- SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
+ SiSRegInit(&ivideo->SiS_Pr, ivideo->SiS_Pr.IOAddress);
#ifdef CONFIG_FB_SIS_300
/* Find PCI systems for Chrontel/GPIO communication setup */
if(ivideo->chip == SIS_630) {
- i=0;
- do {
- if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
- mychswtable[i].subsysCard == ivideo->subsysdevice) {
- ivideo->SiS_Pr.SiS_ChSW = TRUE;
- printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
- mychswtable[i].vendorName, mychswtable[i].cardName);
- break;
- }
- i++;
- } while(mychswtable[i].subsysVendor != 0);
+ i = 0;
+ do {
+ if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
+ mychswtable[i].subsysCard == ivideo->subsysdevice) {
+ ivideo->SiS_Pr.SiS_ChSW = TRUE;
+ printk(KERN_DEBUG "sisfb: Identified [%s %s] "
+ "requiring Chrontel/GPIO setup\n",
+ mychswtable[i].vendorName,
+ mychswtable[i].cardName);
+ ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL);
+ break;
+ }
+ i++;
+ } while(mychswtable[i].subsysVendor != 0);
+ }
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+ if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
+ ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3));
}
#endif
- outSISIDXREG(SISSR, 0x05, 0x86);
+ outSISIDXREG(SISSR, 0x05, 0x86);
- if( (!sisvga_enabled)
+ if( (!ivideo->sisvga_enabled)
#if !defined(__i386__) && !defined(__x86_64__)
- || (sisfb_resetcard)
+ || (sisfb_resetcard)
#endif
- ) {
- for(i = 0x30; i <= 0x3f; i++) {
- outSISIDXREG(SISCR,i,0x00);
- }
+ ) {
+ for(i = 0x30; i <= 0x3f; i++) {
+ outSISIDXREG(SISCR, i, 0x00);
+ }
}
/* Find out about current video mode */
ivideo->modeprechange = 0x03;
- inSISIDXREG(SISCR,0x34,reg);
+ inSISIDXREG(SISCR, 0x34, reg);
if(reg & 0x7f) {
ivideo->modeprechange = reg & 0x7f;
- } else if(sisvga_enabled) {
+ } else if(ivideo->sisvga_enabled) {
#if defined(__i386__) || defined(__x86_64__)
- unsigned char SIS_IOTYPE2 *tt = ioremap(0, 0x1000);
+ unsigned char SIS_IOTYPE2 *tt = ioremap(0x400, 0x100);
if(tt) {
- ivideo->modeprechange = readb(tt + 0x449);
- iounmap(tt);
+ ivideo->modeprechange = readb(tt + 0x49);
+ iounmap(tt);
}
#endif
}
@@ -4996,219 +6142,221 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#ifdef MODULE
if((reg & 0x80) && (reg != 0xff)) {
- if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF) {
- printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -EBUSY;
- }
+ if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni])
+ != 0xFF) {
+ printk(KERN_INFO "sisfb: Cannot initialize display mode, "
+ "X server is active\n");
+ ret = -EBUSY;
+ goto error_4;
+ }
}
-#endif
#endif
-
- ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
-#ifdef CONFIG_FB_SIS_300
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- if(ivideo->chip != SIS_300) {
- inSISIDXREG(SISSR, 0x1a, reg);
- if(!(reg & 0x10)) {
- ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
- }
- }
- }
#endif
+ /* Search and copy ROM image */
ivideo->bios_abase = NULL;
+ ivideo->SiS_Pr.VirtualRomBase = NULL;
+ ivideo->SiS_Pr.UseROM = FALSE;
+ ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = FALSE;
if(ivideo->sisfb_userom) {
- ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
- ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase;
- if(ivideo->sishw_ext.pjVirtualRomBase) {
- printk(KERN_INFO "sisfb: Video ROM found and copied\n");
- ivideo->sishw_ext.UseROM = TRUE;
- } else {
- ivideo->sishw_ext.UseROM = FALSE;
- printk(KERN_INFO "sisfb: Video ROM not found\n");
- }
+ ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
+ ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase;
+ ivideo->SiS_Pr.UseROM = (ivideo->SiS_Pr.VirtualRomBase) ? TRUE : FALSE;
+ printk(KERN_INFO "sisfb: Video ROM %sfound\n",
+ ivideo->SiS_Pr.UseROM ? "" : "not ");
+ if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) {
+ ivideo->SiS_Pr.UseROM = FALSE;
+ ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = TRUE;
+ if( (ivideo->revision_id == 2) &&
+ (!(ivideo->bios_abase[0x1d1] & 0x01)) ) {
+ ivideo->SiS_Pr.DDCPortMixup = TRUE;
+ }
+ }
} else {
- ivideo->sishw_ext.pjVirtualRomBase = NULL;
- ivideo->sishw_ext.UseROM = FALSE;
- printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
+ printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
}
- /* Find systems for special custom timing */
+ /* Find systems for special custom timing */
if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
- int j;
- unsigned char *biosver = NULL;
- unsigned char *biosdate = NULL;
- BOOLEAN footprint;
- u32 chksum = 0;
-
- if(ivideo->sishw_ext.UseROM) {
- biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
- biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
- for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
- }
-
- i=0;
- do {
- if( (mycustomttable[i].chipID == ivideo->chip) &&
- ((!strlen(mycustomttable[i].biosversion)) ||
- (ivideo->sishw_ext.UseROM &&
- (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
- ((!strlen(mycustomttable[i].biosdate)) ||
- (ivideo->sishw_ext.UseROM &&
- (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
- ((!mycustomttable[i].bioschksum) ||
- (ivideo->sishw_ext.UseROM &&
- (mycustomttable[i].bioschksum == chksum))) &&
- (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
- (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
- footprint = TRUE;
- for(j = 0; j < 5; j++) {
- if(mycustomttable[i].biosFootprintAddr[j]) {
- if(ivideo->sishw_ext.UseROM) {
- if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
- mycustomttable[i].biosFootprintData[j]) {
- footprint = FALSE;
- }
- } else footprint = FALSE;
- }
- }
- if(footprint) {
- ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
- printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
- mycustomttable[i].vendorName,
- mycustomttable[i].cardName);
- printk(KERN_DEBUG "sisfb: [specialtiming parameter name: %s]\n",
- mycustomttable[i].optionName);
- break;
- }
- }
- i++;
- } while(mycustomttable[i].chipID);
+ sisfb_detect_custom_timing(ivideo);
}
-#ifdef CONFIG_FB_SIS_300
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- if( (!sisvga_enabled)
+ /* POST card in case this has not been done by the BIOS */
+ if( (!ivideo->sisvga_enabled)
#if !defined(__i386__) && !defined(__x86_64__)
- || (sisfb_resetcard)
+ || (sisfb_resetcard)
#endif
- ) {
+ ) {
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
if(ivideo->chip == SIS_300) {
sisfb_post_sis300(pdev);
+ ivideo->sisfb_can_post = 1;
}
}
- }
#endif
#ifdef CONFIG_FB_SIS_315
- if(ivideo->sisvga_engine == SIS_315_VGA) {
- if( (!sisvga_enabled)
-#if !defined(__i386__) && !defined(__x86_64__)
- || (sisfb_resetcard)
-#endif
- ) {
- if((ivideo->chip == SIS_315H) ||
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ int result = 1;
+ /* if((ivideo->chip == SIS_315H) ||
(ivideo->chip == SIS_315) ||
(ivideo->chip == SIS_315PRO) ||
(ivideo->chip == SIS_330)) {
sisfb_post_sis315330(pdev);
+ } else */ if(ivideo->chip == XGI_20) {
+ result = sisfb_post_xgi(pdev);
+ ivideo->sisfb_can_post = 1;
+ } else if((ivideo->chip == XGI_40) && ivideo->haveXGIROM) {
+ result = sisfb_post_xgi(pdev);
+ ivideo->sisfb_can_post = 1;
+ } else {
+ printk(KERN_INFO "sisfb: Card is not "
+ "POSTed and sisfb can't do this either.\n");
+ }
+ if(!result) {
+ printk(KERN_ERR "sisfb: Failed to POST card\n");
+ ret = -ENODEV;
+ goto error_3;
}
}
- }
#endif
+ }
+ ivideo->sisfb_card_posted = 1;
+
+ /* Find out about RAM size */
if(sisfb_get_dram_size(ivideo)) {
- printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -ENODEV;
+ printk(KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n");
+ ret = -ENODEV;
+ goto error_3;
}
+
+ /* Enable PCI addressing and MMIO */
if((ivideo->sisfb_mode_idx < 0) ||
((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
- /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
- orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
- /* Enable 2D accelerator engine */
- orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
+ /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
+ orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
+ /* Enable 2D accelerator engine */
+ orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
}
if(sisfb_pdc != 0xff) {
- if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
- else sisfb_pdc &= 0x1f;
- ivideo->SiS_Pr.PDC = sisfb_pdc;
+ if(ivideo->sisvga_engine == SIS_300_VGA)
+ sisfb_pdc &= 0x3c;
+ else
+ sisfb_pdc &= 0x1f;
+ ivideo->SiS_Pr.PDC = sisfb_pdc;
}
#ifdef CONFIG_FB_SIS_315
if(ivideo->sisvga_engine == SIS_315_VGA) {
- if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
+ if(sisfb_pdca != 0xff)
+ ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
}
#endif
if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
- printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
+ printk(KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n",
+ (int)(ivideo->video_size >> 20));
printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -ENODEV;
+ ret = -ENODEV;
+ goto error_3;
}
if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
- release_mem_region(ivideo->video_base, ivideo->video_size);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -ENODEV;
+ ret = -ENODEV;
+ goto error_2;
}
ivideo->video_vbase = ioremap(ivideo->video_base, ivideo->video_size);
- ivideo->sishw_ext.pjVideoMemoryAddress = ivideo->video_vbase;
+ ivideo->SiS_Pr.VideoMemoryAddress = ivideo->video_vbase;
if(!ivideo->video_vbase) {
- printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n");
- release_mem_region(ivideo->video_base, ivideo->video_size);
- release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -ENODEV;
+ printk(KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
+ ret = -ENODEV;
+ goto error_1;
}
ivideo->mmio_vbase = ioremap(ivideo->mmio_base, ivideo->mmio_size);
if(!ivideo->mmio_vbase) {
- printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
- iounmap(ivideo->video_vbase);
- release_mem_region(ivideo->video_base, ivideo->video_size);
- release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
+ ret = -ENODEV;
+error_0: iounmap(ivideo->video_vbase);
+error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
+error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+error_3: vfree(ivideo->bios_abase);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+error_4:
+#endif
+ if(ivideo->lpcdev)
+ SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+ if(ivideo->nbridge)
+ SIS_PCI_PUT_DEVICE(ivideo->nbridge);
pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -ENODEV;
+ if(!ivideo->sisvga_enabled)
+ pci_disable_device(pdev);
+ kfree(sis_fb_info);
+ return ret;
}
- printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
- ivideo->video_base, (ULONG)ivideo->video_vbase, ivideo->video_size / 1024);
+ printk(KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n",
+ ivideo->video_base, (unsigned long)ivideo->video_vbase, ivideo->video_size / 1024);
+
+ if(ivideo->video_offset) {
+ printk(KERN_INFO "sisfb: Viewport offset %ldk\n",
+ ivideo->video_offset / 1024);
+ }
printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
- ivideo->mmio_base, (ULONG)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
+ ivideo->mmio_base, (unsigned long)ivideo->mmio_vbase, ivideo->mmio_size / 1024);
+
+ /* Determine the size of the command queue */
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ ivideo->cmdQueueSize = TURBO_QUEUE_AREA_SIZE;
+ } else {
+ if(ivideo->chip == XGI_20) {
+ ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE_Z7;
+ } else {
+ ivideo->cmdQueueSize = COMMAND_QUEUE_AREA_SIZE;
+ }
+ }
+
+ /* Engines are no longer initialized here; this is
+ * now done after the first mode-switch (if the
+ * submitted var has its acceleration flags set).
+ */
+
+ /* Calculate the base of the (unused) hw cursor */
+ ivideo->hwcursor_vbase = ivideo->video_vbase
+ + ivideo->video_size
+ - ivideo->cmdQueueSize
+ - ivideo->hwcursor_size;
+ ivideo->caps |= HW_CURSOR_CAP;
+
+ /* Initialize offscreen memory manager */
if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
}
/* Used for clearing the screen only, therefore respect our mem limit */
- ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem;
+ ivideo->SiS_Pr.VideoMemoryAddress += ivideo->video_offset;
+ ivideo->SiS_Pr.VideoMemorySize = ivideo->sisfb_mem;
- ivideo->mtrr = 0;
+ ivideo->mtrr = -1;
ivideo->vbflags = 0;
ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
ivideo->tvdefmodeidx = DEFAULT_TVMODE;
ivideo->defmodeidx = DEFAULT_MODE;
- ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext);
+ ivideo->newrom = 0;
+ if(ivideo->chip < XGI_20) {
+ if(ivideo->bios_abase) {
+ ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr);
+ }
+ }
if((ivideo->sisfb_mode_idx < 0) ||
((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
@@ -5217,192 +6365,57 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
sisfb_get_VB_type(ivideo);
- if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+ if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
sisfb_detect_VB_connect(ivideo);
}
ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
- if(ivideo->vbflags & VB_VIDEOBRIDGE) {
- if(ivideo->sisfb_crt2type != -1) {
- if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) {
- ivideo->currentvbflags |= CRT2_LCD;
- } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
- ivideo->currentvbflags |= ivideo->sisfb_crt2type;
- }
- } else {
- /* Chrontel 700x TV detection often unreliable, therefore use a
- * different default order on such machines
- */
- if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) {
- if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
- else if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
- else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
- } else {
- if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
- else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
- else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
- }
- }
+ /* Decide on which CRT2 device to use */
+ if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
+ if(ivideo->sisfb_crt2type != -1) {
+ if((ivideo->sisfb_crt2type == CRT2_LCD) &&
+ (ivideo->vbflags & CRT2_LCD)) {
+ ivideo->currentvbflags |= CRT2_LCD;
+ } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
+ ivideo->currentvbflags |= ivideo->sisfb_crt2type;
+ }
+ } else {
+ /* Chrontel 700x TV detection often unreliable, therefore
+ * use a different default order on such machines
+ */
+ if((ivideo->sisvga_engine == SIS_300_VGA) &&
+ (ivideo->vbflags2 & VB2_CHRONTEL)) {
+ if(ivideo->vbflags & CRT2_LCD)
+ ivideo->currentvbflags |= CRT2_LCD;
+ else if(ivideo->vbflags & CRT2_TV)
+ ivideo->currentvbflags |= CRT2_TV;
+ else if(ivideo->vbflags & CRT2_VGA)
+ ivideo->currentvbflags |= CRT2_VGA;
+ } else {
+ if(ivideo->vbflags & CRT2_TV)
+ ivideo->currentvbflags |= CRT2_TV;
+ else if(ivideo->vbflags & CRT2_LCD)
+ ivideo->currentvbflags |= CRT2_LCD;
+ else if(ivideo->vbflags & CRT2_VGA)
+ ivideo->currentvbflags |= CRT2_VGA;
+ }
+ }
}
if(ivideo->vbflags & CRT2_LCD) {
- inSISIDXREG(SISCR, 0x36, reg);
- reg &= 0x0f;
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- ivideo->CRT2LCDType = sis300paneltype[reg];
- } else if(ivideo->chip >= SIS_661) {
- ivideo->CRT2LCDType = sis661paneltype[reg];
- } else {
- ivideo->CRT2LCDType = sis310paneltype[reg];
- if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
- if((ivideo->CRT2LCDType != LCD_640x480_2) &&
- (ivideo->CRT2LCDType != LCD_640x480_3)) {
- ivideo->CRT2LCDType = LCD_320x480;
- }
- }
- }
- if(ivideo->CRT2LCDType == LCD_UNKNOWN) {
- /* For broken BIOSes: Assume 1024x768, RGB18 */
- ivideo->CRT2LCDType = LCD_1024x768;
- setSISIDXREG(SISCR,0x36,0xf0,0x02);
- setSISIDXREG(SISCR,0x37,0xee,0x01);
- printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
- }
- for(i = 0; i < SIS_LCD_NUMBER; i++) {
- if(ivideo->CRT2LCDType == sis_lcd_data[i].lcdtype) {
- ivideo->lcdxres = sis_lcd_data[i].xres;
- ivideo->lcdyres = sis_lcd_data[i].yres;
- ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
- break;
- }
- }
- if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
- ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
- } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
- ivideo->lcdxres = 848; ivideo->lcdyres = 480; ivideo->lcddefmodeidx = 47;
- }
- printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
- ivideo->lcdxres, ivideo->lcdyres);
- }
-
-#ifdef CONFIG_FB_SIS_300
- /* Save the current PanelDelayCompensation if the LCD is currently used */
- if(ivideo->sisvga_engine == SIS_300_VGA) {
- if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
- int tmp;
- inSISIDXREG(SISCR,0x30,tmp);
- if(tmp & 0x20) {
- /* Currently on LCD? If yes, read current pdc */
- inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
- ivideo->detectedpdc &= 0x3c;
- if(ivideo->SiS_Pr.PDC == -1) {
- /* Let option override detection */
- ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
- }
- printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
- ivideo->detectedpdc);
- }
- if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
- printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
- ivideo->SiS_Pr.PDC);
- }
- }
+ sisfb_detect_lcd_type(ivideo);
}
-#endif
-
-#ifdef CONFIG_FB_SIS_315
- if(ivideo->sisvga_engine == SIS_315_VGA) {
-
- /* Try to find about LCDA */
- if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
- int tmp;
- inSISIDXREG(SISPART1,0x13,tmp);
- if(tmp & 0x04) {
- ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
- ivideo->detectedlcda = 0x03;
- }
- }
-
- /* Save PDC */
- if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
- int tmp;
- inSISIDXREG(SISCR,0x30,tmp);
- if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
- /* Currently on LCD? If yes, read current pdc */
- u8 pdc;
- inSISIDXREG(SISPART1,0x2D,pdc);
- ivideo->detectedpdc = (pdc & 0x0f) << 1;
- ivideo->detectedpdca = (pdc & 0xf0) >> 3;
- inSISIDXREG(SISPART1,0x35,pdc);
- ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
- inSISIDXREG(SISPART1,0x20,pdc);
- ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
- if(ivideo->newrom) {
- /* New ROM invalidates other PDC resp. */
- if(ivideo->detectedlcda != 0xff) {
- ivideo->detectedpdc = 0xff;
- } else {
- ivideo->detectedpdca = 0xff;
- }
- }
- if(ivideo->SiS_Pr.PDC == -1) {
- if(ivideo->detectedpdc != 0xff) {
- ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
- }
- }
- if(ivideo->SiS_Pr.PDCA == -1) {
- if(ivideo->detectedpdca != 0xff) {
- ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
- }
- }
- if(ivideo->detectedpdc != 0xff) {
- printk(KERN_INFO
- "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
- ivideo->detectedpdc);
- }
- if(ivideo->detectedpdca != 0xff) {
- printk(KERN_INFO
- "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
- ivideo->detectedpdca);
- }
- }
-
- /* Save EMI */
- if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
- inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
- inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
- inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
- inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
- ivideo->SiS_Pr.HaveEMI = TRUE;
- if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
- ivideo->SiS_Pr.HaveEMILCD = TRUE;
- }
- }
- }
-
- /* Let user override detected PDCs (all bridges) */
- if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
- if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
- printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
- ivideo->SiS_Pr.PDC);
- }
- if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
- printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
- ivideo->SiS_Pr.PDCA);
- }
- }
- }
-#endif
+ sisfb_save_pdc_emi(ivideo);
if(!ivideo->sisfb_crt1off) {
- sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
+ sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
} else {
- if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
- (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
- sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
- }
+ if((ivideo->vbflags2 & VB2_SISTMDSBRIDGE) &&
+ (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
+ sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
+ }
}
if(ivideo->sisfb_mode_idx >= 0) {
@@ -5434,7 +6447,8 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
if(ivideo->refresh_rate != 0) {
- sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx);
+ sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate,
+ ivideo->sisfb_mode_idx);
}
if(ivideo->rate_idx == 0) {
@@ -5443,9 +6457,12 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
}
if(ivideo->sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
- ivideo->rate_idx, ivideo->refresh_rate)) {
- printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor,
+ ivideo->sisfb_mode_idx,
+ ivideo->rate_idx,
+ ivideo->refresh_rate)) {
+ printk(KERN_INFO "sisfb: WARNING: Refresh rate "
+ "exceeds monitor specs!\n");
}
}
@@ -5454,28 +6471,34 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
sisfb_set_vparms(ivideo);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- /* ---------------- For 2.4: Now switch the mode ------------------ */
-
- printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
- ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+ /* ---------------- For 2.4: Now switch the mode ------------------ */
+
+ printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
+ ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
ivideo->refresh_rate);
+ /* Determine whether or not acceleration is to be
+ * used. Need to know before pre/post_set_mode()
+ */
+ ivideo->accel = 0;
+ ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
+ if(ivideo->sisfb_accel) {
+ ivideo->accel = -1;
+ ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+ }
+
+ /* Now switch the mode */
sisfb_pre_setmode(ivideo);
- if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
+ if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
ivideo->mode_no);
- iounmap(ivideo->video_vbase);
+ ret = -EINVAL;
iounmap(ivideo->mmio_vbase);
- release_mem_region(ivideo->video_base, ivideo->video_size);
- release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -EINVAL;
+ goto error_0;
}
outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
@@ -5488,18 +6511,17 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
/* Force reset of x virtual in crtc_to_var */
ivideo->default_var.xres_virtual = 0;
+ /* Copy mode timing to var */
sisfb_crtc_to_var(ivideo, &ivideo->default_var);
+ /* Find out about screen pitch */
sisfb_calc_pitch(ivideo, &ivideo->default_var);
sisfb_set_pitch(ivideo);
- ivideo->accel = 0;
- if(ivideo->sisfb_accel) {
- ivideo->accel = -1;
- ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
- }
+ /* Init the accelerator (does nothing currently) */
sisfb_initaccel(ivideo);
-
+
+ /* Init some fbinfo entries */
sis_fb_info->node = -1;
sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
sis_fb_info->fbops = &sisfb_ops;
@@ -5515,41 +6537,42 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
- ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+ ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
ivideo->refresh_rate);
+ /* Set up the default var according to chosen default display mode */
ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
sisfb_bpp_to_var(ivideo, &ivideo->default_var);
-
+
ivideo->default_var.pixclock = (u32) (1000000000 /
- sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext,
- ivideo->mode_no, ivideo->rate_idx));
-
- if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
- ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) {
- if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- ivideo->default_var.pixclock <<= 1;
- }
- }
+ sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, ivideo->mode_no, ivideo->rate_idx));
+
+ if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, ivideo->mode_no,
+ ivideo->rate_idx, &ivideo->default_var)) {
+ if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ ivideo->default_var.pixclock <<= 1;
+ }
+ }
if(ivideo->sisfb_ypan) {
- /* Maximize regardless of sisfb_max at startup */
- ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var);
- if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
- ivideo->default_var.yres_virtual = ivideo->default_var.yres;
- }
+ /* Maximize regardless of sisfb_max at startup */
+ ivideo->default_var.yres_virtual =
+ sisfb_calc_maxyres(ivideo, &ivideo->default_var);
+ if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
+ ivideo->default_var.yres_virtual = ivideo->default_var.yres;
+ }
}
sisfb_calc_pitch(ivideo, &ivideo->default_var);
ivideo->accel = 0;
if(ivideo->sisfb_accel) {
- ivideo->accel = -1;
+ ivideo->accel = -1;
#ifdef STUPID_ACCELF_TEXT_SHIT
- ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+ ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
#endif
}
sisfb_initaccel(ivideo);
@@ -5566,21 +6589,21 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
#endif
sis_fb_info->var = ivideo->default_var;
sis_fb_info->fix = ivideo->sisfb_fix;
- sis_fb_info->screen_base = ivideo->video_vbase;
+ sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
sis_fb_info->fbops = &sisfb_ops;
sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
-
+
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
#endif /* 2.6 */
- printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags);
+ printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
#ifdef CONFIG_MTRR
ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
MTRR_TYPE_WRCOMB, 1);
- if(!ivideo->mtrr) {
+ if(ivideo->mtrr < 0) {
printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
}
#endif
@@ -5591,14 +6614,9 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
if(register_framebuffer(sis_fb_info) < 0) {
printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
- iounmap(ivideo->video_vbase);
+ ret = -EINVAL;
iounmap(ivideo->mmio_vbase);
- release_mem_region(ivideo->video_base, ivideo->video_size);
- release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
- pci_set_drvdata(pdev, NULL);
- kfree(sis_fb_info);
- return -EINVAL;
+ goto error_0;
}
ivideo->registered = 1;
@@ -5607,21 +6625,47 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
ivideo->next = card_list;
card_list = ivideo;
+#ifdef SIS_OLD_CONFIG_COMPAT
+ {
+ int ret;
+ /* Our ioctls are all "32/64bit compatible" */
+ ret = register_ioctl32_conversion(FBIO_ALLOC, NULL);
+ ret |= register_ioctl32_conversion(FBIO_FREE, NULL);
+ ret |= register_ioctl32_conversion(FBIOGET_VBLANK, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_INFO, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_LOCK, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_COMMAND, NULL);
+ if(ret)
+ printk(KERN_ERR
+ "sisfb: Error registering ioctl32 translations\n");
+ else
+ ivideo->ioctl32registered = 1;
+ }
+#endif
+
printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
- ivideo->sisfb_accel ? "enabled" : "disabled",
- ivideo->sisfb_ypan ?
- (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled");
+ ivideo->sisfb_accel ? "enabled" : "disabled",
+ ivideo->sisfb_ypan ?
+ (ivideo->sisfb_max ? "enabled (auto-max)" :
+ "enabled (no auto-max)") :
+ "disabled");
- printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n",
+ printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n",
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- GET_FB_IDX(sis_fb_info->node),
+ GET_FB_IDX(sis_fb_info->node),
#else
- sis_fb_info->node,
+ sis_fb_info->node,
#endif
ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
- printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n");
+ printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
} /* if mode = "none" */
@@ -5634,26 +6678,62 @@ static int __devinit sisfb_probe(struct pci_dev *pdev,
static void __devexit sisfb_remove(struct pci_dev *pdev)
{
- struct sis_video_info *ivideo = pci_get_drvdata(pdev);
- struct fb_info *sis_fb_info = ivideo->memyselfandi;
- int registered = ivideo->registered;
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ struct fb_info *sis_fb_info = ivideo->memyselfandi;
+ int registered = ivideo->registered;
+ int modechanged = ivideo->modechanged;
+
+#ifdef SIS_OLD_CONFIG_COMPAT
+ if(ivideo->ioctl32registered) {
+ int ret;
+ ret = unregister_ioctl32_conversion(FBIO_ALLOC);
+ ret |= unregister_ioctl32_conversion(FBIO_FREE);
+ ret |= unregister_ioctl32_conversion(FBIOGET_VBLANK);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
+ ret |= unregister_ioctl32_conversion(SISFB_COMMAND);
+ if(ret)
+ printk(KERN_ERR
+ "sisfb: Error unregistering ioctl32 translations\n");
+ }
+#endif
/* Unmap */
- iounmap(ivideo->video_vbase);
iounmap(ivideo->mmio_vbase);
- vfree(ivideo->bios_abase);
+ iounmap(ivideo->video_vbase);
/* Release mem regions */
release_mem_region(ivideo->video_base, ivideo->video_size);
release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+ vfree(ivideo->bios_abase);
+
+ if(ivideo->lpcdev)
+ SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+
+ if(ivideo->nbridge)
+ SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+
#ifdef CONFIG_MTRR
/* Release MTRR region */
- if(ivideo->mtrr) {
+ if(ivideo->mtrr >= 0)
mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
- }
#endif
+ pci_set_drvdata(pdev, NULL);
+
+ /* If device was disabled when starting, disable
+ * it when quitting.
+ */
+ if(!ivideo->sisvga_enabled)
+ pci_disable_device(pdev);
+
/* Unregister the framebuffer */
if(ivideo->registered) {
unregister_framebuffer(sis_fb_info);
@@ -5664,7 +6744,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
#endif
}
- pci_set_drvdata(pdev, NULL);
+ /* OK, our ivideo is gone for good from here. */
/* TODO: Restore the initial mode
* This sounds easy but is as good as impossible
@@ -5673,15 +6753,15 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
* from machine to machine. Depends on the type
* of integration between chipset and bridge.
*/
- if(registered) {
- printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n");
- }
+ if(registered && modechanged)
+ printk(KERN_INFO
+ "sisfb: Restoring of text mode not supported yet\n");
};
static struct pci_driver sisfb_driver = {
.name = "sisfb",
.id_table = sisfb_pci_table,
- .probe = sisfb_probe,
+ .probe = sisfb_probe,
.remove = __devexit_p(sisfb_remove)
};
@@ -5693,10 +6773,11 @@ SISINITSTATIC int __init sisfb_init(void)
if(fb_get_options("sisfb", &options))
return -ENODEV;
+
sisfb_setup(options);
#endif
#endif
- return(pci_register_driver(&sisfb_driver));
+ return pci_register_driver(&sisfb_driver);
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
@@ -5711,36 +6792,129 @@ module_init(sisfb_init);
#ifdef MODULE
-static char *mode = NULL;
-static int vesa = -1;
-static unsigned int rate = 0;
-static unsigned int crt1off = 1;
-static unsigned int mem = 0;
-static char *forcecrt2type = NULL;
-static int forcecrt1 = -1;
-static int pdc = -1;
-static int pdc1 = -1;
-static int noaccel = -1;
-static int noypan = -1;
-static int nomax = -1;
+static char *mode = NULL;
+static int vesa = -1;
+static unsigned int rate = 0;
+static unsigned int crt1off = 1;
+static unsigned int mem = 0;
+static char *forcecrt2type = NULL;
+static int forcecrt1 = -1;
+static int pdc = -1;
+static int pdc1 = -1;
+static int noaccel = -1;
+static int noypan = -1;
+static int nomax = -1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int inverse = 0;
+#endif
+static int userom = -1;
+static int useoem = -1;
+static char *tvstandard = NULL;
+static int nocrt2rate = 0;
+static int scalelcd = -1;
+static char *specialtiming = NULL;
+static int lvdshl = -1;
+static int tvxposoffset = 0, tvyposoffset = 0;
+#if !defined(__i386__) && !defined(__x86_64__)
+static int resetcard = 0;
+static int videoram = 0;
+#endif
+
+static int __init sisfb_init_module(void)
+{
+ sisfb_setdefaultparms();
+
+ if(rate)
+ sisfb_parm_rate = rate;
+
+ if((scalelcd == 0) || (scalelcd == 1))
+ sisfb_scalelcd = scalelcd ^ 1;
+
+ /* Need to check crt2 type first for fstn/dstn */
+
+ if(forcecrt2type)
+ sisfb_search_crt2type(forcecrt2type);
+
+ if(tvstandard)
+ sisfb_search_tvstd(tvstandard);
+
+ if(mode)
+ sisfb_search_mode(mode, FALSE);
+ else if(vesa != -1)
+ sisfb_search_vesamode(vesa, FALSE);
+
+ sisfb_crt1off = (crt1off == 0) ? 1 : 0;
+
+ sisfb_forcecrt1 = forcecrt1;
+ if(forcecrt1 == 1)
+ sisfb_crt1off = 0;
+ else if(forcecrt1 == 0)
+ sisfb_crt1off = 1;
+
+ if(noaccel == 1)
+ sisfb_accel = 0;
+ else if(noaccel == 0)
+ sisfb_accel = 1;
+
+ if(noypan == 1)
+ sisfb_ypan = 0;
+ else if(noypan == 0)
+ sisfb_ypan = 1;
+
+ if(nomax == 1)
+ sisfb_max = 0;
+ else if(nomax == 0)
+ sisfb_max = 1;
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int inverse = 0;
-#endif
-static int userom = -1;
-static int useoem = -1;
-static char *tvstandard = NULL;
-static int nocrt2rate = 0;
-static int scalelcd = -1;
-static char *specialtiming = NULL;
-static int lvdshl = -1;
-static int tvxposoffset = 0, tvyposoffset = 0;
-static int filter = -1;
+ if(inverse) sisfb_inverse = 1;
+#endif
+
+ if(mem)
+ sisfb_parm_mem = mem;
+
+ if(userom != -1)
+ sisfb_userom = userom;
+
+ if(useoem != -1)
+ sisfb_useoem = useoem;
+
+ if(pdc != -1)
+ sisfb_pdc = (pdc & 0x7f);
+
+ if(pdc1 != -1)
+ sisfb_pdca = (pdc1 & 0x1f);
+
+ sisfb_nocrt2rate = nocrt2rate;
+
+ if(specialtiming)
+ sisfb_search_specialtiming(specialtiming);
+
+ if((lvdshl >= 0) && (lvdshl <= 3))
+ sisfb_lvdshl = lvdshl;
+
+ sisfb_tvxposoffset = tvxposoffset;
+ sisfb_tvyposoffset = tvyposoffset;
+
#if !defined(__i386__) && !defined(__x86_64__)
-static int resetcard = 0;
-static int videoram = 0;
+ sisfb_resetcard = (resetcard) ? 1 : 0;
+ if(videoram)
+ sisfb_videoram = videoram;
#endif
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver");
+ return sisfb_init();
+}
+
+static void __exit sisfb_remove_module(void)
+{
+ pci_unregister_driver(&sisfb_driver);
+ printk(KERN_DEBUG "sisfb: Module unloaded\n");
+}
+
+module_init(sisfb_init_module);
+module_exit(sisfb_remove_module);
+
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
@@ -5764,7 +6938,6 @@ MODULE_PARM(lvdshl, "i");
MODULE_PARM(tvstandard, "s");
MODULE_PARM(tvxposoffset, "i");
MODULE_PARM(tvyposoffset, "i");
-MODULE_PARM(filter, "i");
MODULE_PARM(nocrt2rate, "i");
MODULE_PARM(inverse, "i");
#if !defined(__i386__) && !defined(__x86_64__)
@@ -5793,7 +6966,6 @@ module_param(lvdshl, int, 0);
module_param(tvstandard, charp, 0);
module_param(tvxposoffset, int, 0);
module_param(tvyposoffset, int, 0);
-module_param(filter, int, 0);
module_param(nocrt2rate, int, 0);
#if !defined(__i386__) && !defined(__x86_64__)
module_param(resetcard, int, 0);
@@ -5801,25 +6973,35 @@ module_param(videoram, int, 0);
#endif
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
MODULE_PARM_DESC(mem,
"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
"for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
"on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
"the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
- "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
+ "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
"The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
"for XFree86 4.x/X.org 6.7 and later.\n");
+#else
+MODULE_PARM_DESC(mem,
+ "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+ "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
+ "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
+ "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
+ "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
+ "The value is to be specified without 'KB'.\n");
+#endif
MODULE_PARM_DESC(noaccel,
- "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+ "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
"(default: 0)\n");
MODULE_PARM_DESC(noypan,
- "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
- "will be performed by redrawing the screen. (default: 0)\n");
+ "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+ "will be performed by redrawing the screen. (default: 0)\n");
MODULE_PARM_DESC(nomax,
- "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
+ "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
"memory for the virtual screen in order to optimize scrolling performance. If\n"
"this is set to anything other than 0, sisfb will not do this and thereby \n"
"enable the user to positively specify a virtual Y size of the screen using\n"
@@ -5827,30 +7009,30 @@ MODULE_PARM_DESC(nomax,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
MODULE_PARM_DESC(mode,
- "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
- "1024x768x16. Other formats supported include XxY-Depth and\n"
- "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+ "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+ "1024x768x16. Other formats supported include XxY-Depth and\n"
+ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
"number, it will be interpreted as a VESA mode number. (default: none if\n"
"sisfb is a module; this leaves the console untouched and the driver will\n"
"only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
"is in the kernel)\n");
MODULE_PARM_DESC(vesa,
- "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
- "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
+ "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
+ "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
"and the driver will only do the video memory management for eg. DRM/DRI;\n"
"0x0103 if sisfb is in the kernel)\n");
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
MODULE_PARM_DESC(mode,
- "\nSelects the desired default display mode in the format XxYxDepth,\n"
- "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+ "\nSelects the desired default display mode in the format XxYxDepth,\n"
+ "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
"XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
"number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
MODULE_PARM_DESC(vesa,
- "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
- "0x117 (default: 0x0103)\n");
+ "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+ "0x117 (default: 0x0103)\n");
#endif
MODULE_PARM_DESC(rate,
@@ -5880,16 +7062,16 @@ MODULE_PARM_DESC(scalelcd,
"themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
MODULE_PARM_DESC(pdc,
- "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
+ "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
"should detect this correctly in most cases; however, sometimes this is not\n"
"possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
- "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
- "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
- "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
+ "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n"
+ "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n"
+ "value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
#ifdef CONFIG_FB_SIS_315
MODULE_PARM_DESC(pdc1,
- "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
+ "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n"
"series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
"startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
"implemented yet.\n");
@@ -5913,17 +7095,13 @@ MODULE_PARM_DESC(tvyposoffset,
"\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
"Default: 0\n");
-MODULE_PARM_DESC(filter,
- "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
- "(Possible values 0-7, default: [no filter])\n");
-
MODULE_PARM_DESC(nocrt2rate,
"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
"CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
MODULE_PARM_DESC(inverse,
- "\nSetting this to anything but 0 should invert the display colors, but this\n"
+ "\nSetting this to anything but 0 should invert the display colors, but this\n"
"does not seem to work. (default: 0)\n");
#endif
@@ -5931,98 +7109,23 @@ MODULE_PARM_DESC(inverse,
#ifdef CONFIG_FB_SIS_300
MODULE_PARM_DESC(resetcard,
"\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
- "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n"
- "Default: 0\n");
+ "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n"
+ "currently). Default: 0\n");
MODULE_PARM_DESC(videoram,
"\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
"some non-x86 architectures where the memory auto detection fails. Only\n"
- "relevant if resetcard is set, too. Default: [auto-detect]\n");
-#endif
+ "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n");
#endif
-
-static int __devinit sisfb_init_module(void)
-{
- sisfb_setdefaultparms();
-
- if(rate) sisfb_parm_rate = rate;
-
- if((scalelcd == 0) || (scalelcd == 1)) {
- sisfb_scalelcd = scalelcd ^ 1;
- }
-
- /* Need to check crt2 type first for fstn/dstn */
-
- if(forcecrt2type)
- sisfb_search_crt2type(forcecrt2type);
-
- if(tvstandard)
- sisfb_search_tvstd(tvstandard);
-
- if(mode)
- sisfb_search_mode(mode, FALSE);
- else if(vesa != -1)
- sisfb_search_vesamode(vesa, FALSE);
-
- sisfb_crt1off = (crt1off == 0) ? 1 : 0;
-
- sisfb_forcecrt1 = forcecrt1;
- if(forcecrt1 == 1) sisfb_crt1off = 0;
- else if(forcecrt1 == 0) sisfb_crt1off = 1;
-
- if(noaccel == 1) sisfb_accel = 0;
- else if(noaccel == 0) sisfb_accel = 1;
-
- if(noypan == 1) sisfb_ypan = 0;
- else if(noypan == 0) sisfb_ypan = 1;
-
- if(nomax == 1) sisfb_max = 0;
- else if(nomax == 0) sisfb_max = 1;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if(inverse) sisfb_inverse = 1;
#endif
- if(mem) sisfb_parm_mem = mem;
-
- if(userom != -1) sisfb_userom = userom;
- if(useoem != -1) sisfb_useoem = useoem;
-
- if(pdc != -1) sisfb_pdc = (pdc & 0x7f);
- if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
-
- sisfb_nocrt2rate = nocrt2rate;
-
- if(specialtiming)
- sisfb_search_specialtiming(specialtiming);
-
- if((lvdshl >= 0) && (lvdshl <= 3)) sisfb_lvdshl = lvdshl;
-
- if(filter != -1) sisfb_filter = filter;
-
- sisfb_tvxposoffset = tvxposoffset;
- sisfb_tvyposoffset = tvyposoffset;
-
-#if !defined(__i386__) && !defined(__x86_64__)
- sisfb_resetcard = (resetcard) ? 1 : 0;
- if(videoram) sisfb_videoram = videoram;
-#endif
-
- return(sisfb_init());
-}
-
-static void __exit sisfb_remove_module(void)
-{
- pci_unregister_driver(&sisfb_driver);
- printk(KERN_DEBUG "sisfb: Module unloaded\n");
-}
-
-module_init(sisfb_init_module);
-module_exit(sisfb_remove_module);
-
#endif /* /MODULE */
+/* _GPL only for new symbols. */
EXPORT_SYMBOL(sis_malloc);
EXPORT_SYMBOL(sis_free);
+EXPORT_SYMBOL_GPL(sis_malloc_new);
+EXPORT_SYMBOL_GPL(sis_free_new);
+
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index a6678a7aff3..445bcbba03a 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -1,9 +1,10 @@
/*
- * SiS 300/305/540/630(S)/730(S)
- * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * SiS 300/305/540/630(S)/730(S),
+ * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX],
+ * XGI V3XT/V5/V8, Z7
* frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
*
- * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +24,9 @@
#ifndef _SISFB_MAIN
#define _SISFB_MAIN
-#include <linux/spinlock.h>
-
#include "vstruct.h"
#include "sis.h"
-#define MODE_INDEX_NONE 0 /* index for mode=none */
-
/* Fbcon stuff */
static struct fb_var_screeninfo my_default_var = {
.xres = 0,
@@ -60,6 +57,8 @@ static struct fb_var_screeninfo my_default_var = {
.vmode = FB_VMODE_NONINTERLACED,
};
+#define MODE_INDEX_NONE 0 /* index for mode=none */
+
/* Boot-time parameters */
static int sisfb_off = 0;
static int sisfb_parm_mem = 0;
@@ -93,7 +92,6 @@ static int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
static int sisfb_tvstd = -1;
static int sisfb_tvxposoffset = 0;
static int sisfb_tvyposoffset = 0;
-static int sisfb_filter = -1;
static int sisfb_nocrt2rate = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int sisfb_inverse = 0;
@@ -106,12 +104,12 @@ static int sisfb_videoram = 0;
/* List of supported chips */
static struct sisfb_chip_info {
- int chip;
- int vgaengine;
+ int chip;
+ int vgaengine;
int mni;
- int hwcursor_size;
+ int hwcursor_size;
int CRT2_write_enable;
- const char *chip_name;
+ const char *chip_name;
} sisfb_chip_info[] __devinitdata = {
{ SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
{ 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 {
{ SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
{ SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
{ SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
+ { XGI_20, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI Z7" },
+ { XGI_40, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "XGI V3XT/V5/V8" },
};
static struct pci_device_id __devinitdata sisfb_pci_table[] = {
@@ -139,6 +139,8 @@ static struct pci_device_id __devinitdata sisfb_pci_table[] = {
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+ { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0,10},
+ { PCI_VENDOR_ID_XGI,PCI_DEVICE_ID_XGI_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0,11},
#endif
{ 0 }
};
@@ -147,13 +149,12 @@ MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
static struct sis_video_info *card_list = NULL;
-/* TODO: This is not handled card-wise because the DRM
- does not refer to a unique fb when calling sis_alloc
- or sis_free. Therefore, this is handled globally for
- now (hoping that nobody is crazy enough to run two
- SiS cards at the same time).
+/* The memory heap is now handled card-wise, by using
+ sis_malloc_new/sis_free_new. However, the DRM does
+ not do this yet. Until it does, we keep a "global"
+ heap which is actually the first card's one.
*/
-static SIS_HEAP sisfb_heap;
+static struct SIS_HEAP *sisfb_heap;
#define MD_SIS300 1
#define MD_SIS315 2
@@ -181,8 +182,10 @@ static const struct _sisbios_mode {
{"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
{"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
{"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
- {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* FSTN */
-/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* FSTN */
+#define MODE_FSTN_8 9
+#define MODE_FSTN_16 10
+ {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS315}, /* FSTN */
+/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS315}, /* FSTN */
{"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
{"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
{"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
@@ -215,18 +218,20 @@ static const struct _sisbios_mode {
/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
{"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
{"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
-#define DEFAULT_MODE 43 /* index for 800x600x8 */
-#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
-#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
+#define DEFAULT_MODE 43 /* index for 800x600x8 */
+#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
+#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
{"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
{"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
{"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
{"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
{"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
+#define DEFAULT_MODE_848 48
{"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
{"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
{"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
+#define DEFAULT_MODE_856 52
{"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
{"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
{"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
@@ -270,42 +275,47 @@ static const struct _sisbios_mode {
{"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315},
{"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
{"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
+ {"1280x854x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 854, 8, 1, 160, 53, MD_SIS315},
+ {"1280x854x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 854, 16, 1, 160, 53, MD_SIS315},
+ {"1280x854x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
+ {"1280x854x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 854, 32, 1, 160, 53, MD_SIS315},
{"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
- {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+/*100*/ {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
{"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
{"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
{"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
-/*100*/ {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
{"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
{"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
{"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
{"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
{"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
- {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+/*110*/ {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
{"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
+#define DEFAULT_MODE_1360 112
{"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
{"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
-/*110*/ {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
+ {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
{"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
{"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
{"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
{"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
{"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
- {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+/*120*/ {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
{"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
{"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
{"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315},
-/*120*/ {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
+ {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
{"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
{"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
{"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315},
{"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315},
{"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
- {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
+/*130*/ {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
{"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
{"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
{"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-/*130*/ {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
{"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
{"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
{"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
@@ -313,13 +323,13 @@ static const struct _sisbios_mode {
{"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
};
-#define SIS_LCD_NUMBER 17
-static const struct _sis_lcd_data {
+#define SIS_LCD_NUMBER 18
+static struct _sis_lcd_data {
u32 lcdtype;
u16 xres;
u16 yres;
u8 default_mode_idx;
-} sis_lcd_data[] = {
+} sis_lcd_data[] __devinitdata = {
{ LCD_640x480, 640, 480, 23 },
{ LCD_800x600, 800, 600, 43 },
{ LCD_1024x600, 1024, 600, 67 },
@@ -329,34 +339,38 @@ static const struct _sis_lcd_data {
{ LCD_1280x720, 1280, 720, 83 },
{ LCD_1280x768, 1280, 768, 87 },
{ LCD_1280x800, 1280, 800, 91 },
- { LCD_1280x960, 1280, 960, 95 },
- { LCD_1280x1024, 1280, 1024, 99 },
- { LCD_1400x1050, 1400, 1050, 111 },
- { LCD_1680x1050, 1680, 1050, 119 },
- { LCD_1600x1200, 1600, 1200, 115 },
- { LCD_640x480_2, 640, 480, 23 },
- { LCD_640x480_3, 640, 480, 23 },
- { LCD_320x480, 320, 480, 9 },
+ { LCD_1280x854, 1280, 854, 95 },
+ { LCD_1280x960, 1280, 960, 99 },
+ { LCD_1280x1024, 1280, 1024, 103 },
+ { LCD_1400x1050, 1400, 1050, 115 },
+ { LCD_1680x1050, 1680, 1050, 123 },
+ { LCD_1600x1200, 1600, 1200, 119 },
+ { LCD_320x240_2, 320, 240, 9 },
+ { LCD_320x240_3, 320, 240, 9 },
+ { LCD_320x240, 320, 240, 9 },
};
/* CR36 evaluation */
-static const USHORT sis300paneltype[] =
- { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
- LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
- LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
- LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN };
-
-static const USHORT sis310paneltype[] =
- { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
- LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
- LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
- LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN, LCD_UNKNOWN };
-
-static const USHORT sis661paneltype[] =
- { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
- LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
- LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
- LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN };
+static unsigned short sis300paneltype[] __devinitdata = {
+ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+ LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
+ LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
+ LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN
+};
+
+static unsigned short sis310paneltype[] __devinitdata = {
+ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+ LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
+ LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
+ LCD_320x240_2, LCD_320x240_3, LCD_UNKNOWN, LCD_UNKNOWN
+};
+
+static unsigned short sis661paneltype[] __devinitdata = {
+ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+ LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
+ LCD_1280x854, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
+ LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN
+};
#define FL_550_DSTN 0x01
#define FL_550_FSTN 0x02
@@ -413,7 +427,6 @@ static const struct _sis_vrate {
} sisfb_vrate[] = {
{1, 320, 200, 70, TRUE},
{1, 320, 240, 60, TRUE},
- {1, 320, 480, 60, TRUE},
{1, 400, 300, 60, TRUE},
{1, 512, 384, 60, TRUE},
{1, 640, 400, 72, TRUE},
@@ -437,10 +450,11 @@ static const struct _sis_vrate {
{4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
{7, 1024, 768, 120, TRUE},
{1, 1152, 768, 60, TRUE},
- {1, 1152, 864, 60, TRUE}, {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE},
+ {1, 1152, 864, 60, TRUE}, {2, 1152, 864, 75, TRUE}, {3, 1152, 864, 84, TRUE},
{1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
{1, 1280, 768, 60, TRUE},
{1, 1280, 800, 60, TRUE},
+ {1, 1280, 854, 60, TRUE},
{1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
{1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
{4, 1280, 1024, 85, TRUE},
@@ -459,12 +473,12 @@ static const struct _sis_vrate {
{0, 0, 0, 0, FALSE}
};
-static const struct _sisfbddcsmodes {
+static struct _sisfbddcsmodes {
u32 mask;
u16 h;
u16 v;
u32 d;
-} sisfb_ddcsmodes[] = {
+} sisfb_ddcsmodes[] __devinitdata = {
{ 0x10000, 67, 75, 108000},
{ 0x08000, 48, 72, 50000},
{ 0x04000, 46, 75, 49500},
@@ -480,49 +494,49 @@ static const struct _sisfbddcsmodes {
{ 0x00001, 38, 60, 40000}
};
-static const struct _sisfbddcfmodes {
+static struct _sisfbddcfmodes {
u16 x;
u16 y;
u16 v;
u16 h;
u32 d;
-} sisfb_ddcfmodes[] = {
- { 1280, 1024, 85, 92, 157500},
- { 1600, 1200, 60, 75, 162000},
- { 1600, 1200, 65, 82, 175500},
- { 1600, 1200, 70, 88, 189000},
- { 1600, 1200, 75, 94, 202500},
- { 1600, 1200, 85, 107,229500},
- { 1920, 1440, 60, 90, 234000},
- { 1920, 1440, 75, 113,297000}
+} sisfb_ddcfmodes[] __devinitdata = {
+ { 1280, 1024, 85, 92, 157500},
+ { 1600, 1200, 60, 75, 162000},
+ { 1600, 1200, 65, 82, 175500},
+ { 1600, 1200, 70, 88, 189000},
+ { 1600, 1200, 75, 94, 202500},
+ { 1600, 1200, 85, 107,229500},
+ { 1920, 1440, 60, 90, 234000},
+ { 1920, 1440, 75, 113,297000}
};
#ifdef CONFIG_FB_SIS_300
static struct _chswtable {
- u16 subsysVendor;
- u16 subsysCard;
- char *vendorName;
- char *cardName;
+ u16 subsysVendor;
+ u16 subsysCard;
+ char *vendorName;
+ char *cardName;
} mychswtable[] __devinitdata = {
- { 0x1631, 0x1002, "Mitachi", "0x1002" },
+ { 0x1631, 0x1002, "Mitachi", "0x1002" },
{ 0x1071, 0x7521, "Mitac" , "7521P" },
{ 0, 0, "" , "" }
};
#endif
static struct _customttable {
- u16 chipID;
- char *biosversion;
- char *biosdate;
- u32 bioschksum;
- u16 biosFootprintAddr[5];
- u8 biosFootprintData[5];
- u16 pcisubsysvendor;
- u16 pcisubsyscard;
- char *vendorName;
- char *cardName;
- u32 SpecialID;
- char *optionName;
+ u16 chipID;
+ char *biosversion;
+ char *biosdate;
+ u32 bioschksum;
+ u16 biosFootprintAddr[5];
+ u8 biosFootprintData[5];
+ u16 pcisubsysvendor;
+ u16 pcisubsyscard;
+ char *vendorName;
+ char *cardName;
+ u32 SpecialID;
+ char *optionName;
} mycustomttable[] __devinitdata = {
{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
0x3240A8,
@@ -643,6 +657,13 @@ static struct _customttable {
0, 0,
"Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
},
+ { 4322, "", "", /* never autodetected */
+ 0,
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ 0, 0,
+ "Generic", "LVDS/Parallel 856x480", CUT_PANEL856, "PANEL856x480"
+ },
{ 0, "", "",
0,
{ 0, 0, 0, 0 },
@@ -652,155 +673,6 @@ static struct _customttable {
}
};
-static const struct _sis_TV_filter {
- u8 filter[9][4];
-} sis_TV_filter[] = {
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_0 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_1 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_2 */
- {0xF5,0xEE,0x1B,0x44},
- {0xF8,0xF4,0x18,0x38},
- {0xEB,0x04,0x25,0x18},
- {0xF1,0x05,0x1F,0x16},
- {0xF6,0x06,0x1A,0x14},
- {0xFA,0x06,0x16,0x14},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_3 */
- {0xF1,0x04,0x1F,0x18},
- {0xEE,0x0D,0x22,0x06},
- {0xF7,0x06,0x19,0x14},
- {0xF4,0x0B,0x1C,0x0A},
- {0xFA,0x07,0x16,0x12},
- {0xF9,0x0A,0x17,0x0C},
- {0x00,0x07,0x10,0x12},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_4 - 320 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_5 - 640 */
- {0xF5,0xEE,0x1B,0x44},
- {0xF8,0xF4,0x18,0x38},
- {0xEB,0x04,0x25,0x18},
- {0xF1,0x05,0x1F,0x16},
- {0xF6,0x06,0x1A,0x14},
- {0xFA,0x06,0x16,0x14},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_6 - 720 */
- {0xEB,0x04,0x25,0x18},
- {0xE7,0x0E,0x29,0x04},
- {0xEE,0x0C,0x22,0x08},
- {0xF6,0x0B,0x1A,0x0A},
- {0xF9,0x0A,0x17,0x0C},
- {0xFC,0x0A,0x14,0x0C},
- {0x00,0x08,0x10,0x10},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* NTSCFilter_7 - 800 */
- {0xEC,0x02,0x24,0x1C},
- {0xF2,0x04,0x1E,0x18},
- {0xEB,0x15,0x25,0xF6},
- {0xF4,0x10,0x1C,0x00},
- {0xF8,0x0F,0x18,0x02},
- {0x00,0x04,0x10,0x18},
- {0x01,0x06,0x0F,0x14},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_0 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_1 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_2 */
- {0xF5,0xEE,0x1B,0x44},
- {0xF8,0xF4,0x18,0x38},
- {0xF1,0xF7,0x01,0x32},
- {0xF5,0xFB,0x1B,0x2A},
- {0xF9,0xFF,0x17,0x22},
- {0xFB,0x01,0x15,0x1E},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_3 */
- {0xF5,0xFB,0x1B,0x2A},
- {0xEE,0xFE,0x22,0x24},
- {0xF3,0x00,0x1D,0x20},
- {0xF9,0x03,0x17,0x1A},
- {0xFB,0x02,0x14,0x1E},
- {0xFB,0x04,0x15,0x18},
- {0x00,0x06,0x10,0x14},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_4 - 320 */
- {0x00,0xE0,0x10,0x60},
- {0x00,0xEE,0x10,0x44},
- {0x00,0xF4,0x10,0x38},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0x00,0x00,0x10,0x20},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_5 - 640 */
- {0xF5,0xEE,0x1B,0x44},
- {0xF8,0xF4,0x18,0x38},
- {0xF1,0xF7,0x1F,0x32},
- {0xF5,0xFB,0x1B,0x2A},
- {0xF9,0xFF,0x17,0x22},
- {0xFB,0x01,0x15,0x1E},
- {0x00,0x04,0x10,0x18},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_6 - 720 */
- {0xF5,0xEE,0x1B,0x2A},
- {0xEE,0xFE,0x22,0x24},
- {0xF3,0x00,0x1D,0x20},
- {0xF9,0x03,0x17,0x1A},
- {0xFB,0x02,0x14,0x1E},
- {0xFB,0x04,0x15,0x18},
- {0x00,0x06,0x10,0x14},
- {0xFF,0xFF,0xFF,0xFF} }},
- { {{0x00,0x00,0x00,0x40}, /* PALFilter_7 - 800 */
- {0xF5,0xEE,0x1B,0x44},
- {0xF8,0xF4,0x18,0x38},
- {0xFC,0xFB,0x14,0x2A},
- {0xEB,0x05,0x25,0x16},
- {0xF1,0x05,0x1F,0x16},
- {0xFA,0x07,0x16,0x12},
- {0x00,0x07,0x10,0x12},
- {0xFF,0xFF,0xFF,0xFF} }}
-};
-
/* ---------------------- Prototypes ------------------------- */
/* Interface used by the world */
@@ -811,145 +683,159 @@ SISINITSTATIC int sisfb_setup(char *options);
/* Interface to the low level console driver */
SISINITSTATIC int sisfb_init(void);
-
/* fbdev routines */
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
- int con,
- struct fb_info *info);
-static int sisfb_get_var(struct fb_var_screeninfo *var,
- int con,
- struct fb_info *info);
-static int sisfb_set_var(struct fb_var_screeninfo *var,
- int con,
- struct fb_info *info);
-static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
- struct fb_var_screeninfo *var);
-static int sisfb_get_cmap(struct fb_cmap *cmap,
- int kspc,
- int con,
- struct fb_info *info);
-static int sisfb_set_cmap(struct fb_cmap *cmap,
- int kspc,
- int con,
- struct fb_info *info);
-static int sisfb_update_var(int con,
- struct fb_info *info);
-static int sisfb_switch(int con,
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
+ int con,
+ struct fb_info *info);
+static int sisfb_get_var(struct fb_var_screeninfo *var,
+ int con,
+ struct fb_info *info);
+static int sisfb_set_var(struct fb_var_screeninfo *var,
+ int con,
+ struct fb_info *info);
+static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
+ struct fb_var_screeninfo *var);
+static int sisfb_get_cmap(struct fb_cmap *cmap,
+ int kspc,
+ int con,
+ struct fb_info *info);
+static int sisfb_set_cmap(struct fb_cmap *cmap,
+ int kspc,
+ int con,
+ struct fb_info *info);
+static int sisfb_update_var(int con,
+ struct fb_info *info);
+static int sisfb_switch(int con,
struct fb_info *info);
-static void sisfb_blank(int blank,
- struct fb_info *info);
-static void sisfb_set_disp(int con,
- struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *fb_info);
-static void sisfb_do_install_cmap(int con,
- struct fb_info *info);
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info);
-#endif
+static void sisfb_blank(int blank,
+ struct fb_info *info);
+static void sisfb_set_disp(int con,
+ struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *fb_info);
+static void sisfb_do_install_cmap(int con,
+ struct fb_info *info);
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info);
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info);
-static int sisfb_set_par(struct fb_info *info);
-static int sisfb_blank(int blank,
- struct fb_info *info);
-extern void fbcon_sis_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect);
-extern void fbcon_sis_copyarea(struct fb_info *info,
- const struct fb_copyarea *area);
-extern int fbcon_sis_sync(struct fb_info *info);
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ struct fb_info *info);
+static int sisfb_set_par(struct fb_info *info);
+static int sisfb_blank(int blank,
+ struct fb_info *info);
+extern void fbcon_sis_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect);
+extern void fbcon_sis_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area);
+extern int fbcon_sis_sync(struct fb_info *info);
#endif
-
+
/* Internal 2D accelerator functions */
-extern int sisfb_initaccel(struct sis_video_info *ivideo);
-extern void sisfb_syncaccel(struct sis_video_info *ivideo);
+extern int sisfb_initaccel(struct sis_video_info *ivideo);
+extern void sisfb_syncaccel(struct sis_video_info *ivideo);
/* Internal general routines */
-static void sisfb_search_mode(char *name, BOOLEAN quiet);
-static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
-static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
- int index);
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *fb_info);
-static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
- struct fb_info *info);
-static void sisfb_pre_setmode(struct sis_video_info *ivideo);
-static void sisfb_post_setmode(struct sis_video_info *ivideo);
-static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
-static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
-static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
-static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
-static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
-static void sisfb_get_VB_type(struct sis_video_info *ivideo);
-static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
-static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+static void sisfb_search_mode(char *name, BOOLEAN quiet);
+static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
+static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
+ int index);
+static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *fb_info);
+static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+ struct fb_info *info);
+static void sisfb_pre_setmode(struct sis_video_info *ivideo);
+static void sisfb_post_setmode(struct sis_video_info *ivideo);
+static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
+static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
+static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
+static void sisfb_get_VB_type(struct sis_video_info *ivideo);
+static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
+static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+#ifdef CONFIG_FB_SIS_300
+unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val);
+unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+#endif
+#ifdef CONFIG_FB_SIS_315
+void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val);
+unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
+#endif
/* SiS-specific exported functions */
-void sis_malloc(struct sis_memreq *req);
-void sis_free(u32 base);
+void sis_malloc(struct sis_memreq *req);
+void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
+void sis_free(u32 base);
+void sis_free_new(struct pci_dev *pdev, u32 base);
/* Internal heap routines */
-static int sisfb_heap_init(struct sis_video_info *ivideo);
-static SIS_OH *sisfb_poh_new_node(void);
-static SIS_OH *sisfb_poh_allocate(u32 size);
-static void sisfb_delete_node(SIS_OH *poh);
-static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
-static SIS_OH *sisfb_poh_free(u32 base);
-static void sisfb_free_node(SIS_OH *poh);
-
-/* Sensing routines */
-static void SiS_Sense30x(struct sis_video_info *ivideo);
-static void SiS_SenseCh(struct sis_video_info *ivideo);
+static int sisfb_heap_init(struct sis_video_info *ivideo);
+static struct SIS_OH * sisfb_poh_new_node(struct SIS_HEAP *memheap);
+static struct SIS_OH * sisfb_poh_allocate(struct SIS_HEAP *memheap, u32 size);
+static void sisfb_delete_node(struct SIS_OH *poh);
+static void sisfb_insert_node(struct SIS_OH *pohList, struct SIS_OH *poh);
+static struct SIS_OH * sisfb_poh_free(struct SIS_HEAP *memheap, u32 base);
+static void sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh);
/* Routines from init.c/init301.c */
-extern USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth,
- BOOLEAN FSTN, USHORT CustomT, int LCDwith, int LCDheight);
-extern USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-extern USHORT SiS_GetModeID_VGA2(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
-
-extern void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHORT ModeNo);
-extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
-extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
-
-extern BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
-
-extern BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
- unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+extern unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, BOOLEAN FSTN, unsigned short CustomT,
+ int LCDwith, int LCDheight, unsigned int VBFlags2);
+extern unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, unsigned int VBFlags2);
+extern unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
+ int VDisplay, int Depth, unsigned int VBFlags2);
+extern void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+extern BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+extern void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
+extern void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
+
+extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+
+extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ int *htotal, int *vtotal, unsigned char rateindex);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-extern int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr,
- PSIS_HW_INFO HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex);
-extern int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex,
- struct fb_var_screeninfo *var);
+extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
+ unsigned char modeno, unsigned char rateindex);
+extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
+ unsigned char rateindex, struct fb_var_screeninfo *var);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
+ int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
#endif
/* Chrontel TV, DDC and DPMS functions */
-extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
-extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
-extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
-extern USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
+extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg);
+extern void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+extern unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg);
+extern void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
+extern void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
+ unsigned char myor, unsigned char myand);
+extern void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime);
+extern void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
+extern unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
+ unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
+ unsigned int VBFlags2);
+extern unsigned short SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr);
+#ifdef CONFIG_FB_SIS_315
+extern void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
+extern void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
+#endif
+extern void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
+extern void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
#endif
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 507bba1a71b..831b9f42264 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -3,7 +3,7 @@
/*
* General type definitions for universal mode switching modules
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,11 +50,10 @@
*
*/
-#ifndef _VGATYPES_
-#define _VGATYPES_
+#ifndef _VGATYPES_H_
+#define _VGATYPES_H_
-#ifdef LINUX_KERNEL /* We don't want the X driver to depend on kernel source */
-#include <linux/ioctl.h>
+#ifdef SIS_LINUX_KERNEL
#include <linux/version.h>
#endif
@@ -66,41 +65,13 @@
#define TRUE 1
#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CHAR
-typedef char CHAR;
-#endif
-
-#ifndef SHORT
-typedef short SHORT;
-#endif
-
-#ifndef LONG
-typedef long LONG;
-#endif
-
-#ifndef UCHAR
-typedef unsigned char UCHAR;
-#endif
-
-#ifndef USHORT
-typedef unsigned short USHORT;
-#endif
-
-#ifndef ULONG
-typedef unsigned long ULONG;
-#endif
-
#ifndef BOOLEAN
-typedef unsigned char BOOLEAN;
+typedef unsigned int BOOLEAN;
#endif
#define SISIOMEMTYPE
-#ifdef LINUX_KERNEL
+#ifdef SIS_LINUX_KERNEL
typedef unsigned long SISIOADDRESS;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#include <linux/types.h> /* Need __iomem */
@@ -109,7 +80,7 @@ typedef unsigned long SISIOADDRESS;
#endif
#endif
-#ifdef LINUX_XF86
+#ifdef SIS_XORG_XF86
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
typedef unsigned long IOADDRESS;
typedef unsigned long SISIOADDRESS;
@@ -118,7 +89,7 @@ typedef IOADDRESS SISIOADDRESS;
#endif
#endif
-enum _SIS_CHIP_TYPE {
+typedef enum _SIS_CHIP_TYPE {
SIS_VGALegacy = 0,
SIS_530,
SIS_OLD,
@@ -128,115 +99,27 @@ enum _SIS_CHIP_TYPE {
SIS_540,
SIS_315H, /* SiS 310 */
SIS_315,
- SIS_315PRO,
+ SIS_315PRO, /* SiS 325 */
SIS_550,
SIS_650,
SIS_740,
SIS_330,
SIS_661,
SIS_741,
- SIS_660,
+ SIS_670,
+ SIS_660 = 35,
SIS_760,
SIS_761,
- SIS_340,
+ SIS_762,
+ SIS_770,
+ SIS_340 = 55,
+ SIS_341,
+ SIS_342,
+ XGI_20 = 75,
+ XGI_40,
MAX_SIS_CHIP
-};
-
-#ifndef SIS_HW_INFO
-typedef struct _SIS_HW_INFO SIS_HW_INFO, *PSIS_HW_INFO;
-
-struct _SIS_HW_INFO
-{
-#ifdef LINUX_XF86
- PCITAG PciTag; /* PCI Tag */
-#endif
-
- UCHAR *pjVirtualRomBase; /* ROM image */
-
- BOOLEAN UseROM; /* Use the ROM image if provided */
-
-#ifdef LINUX_KERNEL
- UCHAR SISIOMEMTYPE *pjVideoMemoryAddress;
- /* base virtual memory address */
- /* of Linear VGA memory */
-
- ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
-#endif
-
- SISIOADDRESS ulIOAddress; /* base I/O address of VGA ports (0x3B0; relocated) */
-
- UCHAR jChipType; /* Used to Identify SiS Graphics Chip */
- /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
+} SIS_CHIP_TYPE;
- UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */
-
- BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-};
-#endif
-
-/* Addtional IOCTLs for communication sisfb <> X driver */
-/* If changing this, sisfb.h must also be changed (for sisfb) */
-
-#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
-
-/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_SIZE 0x8004f300
-#define SISFB_GET_INFO 0x8000f301 /* Must be patched with result from ..._SIZE at D[29:16] */
-/* deprecated ioctl number (for older versions of sisfb) */
-#define SISFB_GET_INFO_OLD 0x80046ef8
-
-/* ioctls for tv parameters (position) */
-#define SISFB_SET_TVPOSOFFSET 0x4004f304
-
-/* lock sisfb from register access */
-#define SISFB_SET_LOCK 0x4004f306
-
-/* Structure argument for SISFB_GET_INFO ioctl */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
- CARD32 sisfb_id; /* for identifying sisfb */
-#ifndef SISFB_ID
-#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
-#endif
- CARD32 chip_id; /* PCI ID of detected chip */
- CARD32 memory; /* video memory in KB which sisfb manages */
- CARD32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
- CARD8 fbvidmode; /* current sisfb mode */
-
- CARD8 sisfb_version;
- CARD8 sisfb_revision;
- CARD8 sisfb_patchlevel;
-
- CARD8 sisfb_caps; /* sisfb's capabilities */
-
- CARD32 sisfb_tqlen; /* turbo queue length (in KB) */
-
- CARD32 sisfb_pcibus; /* The card's PCI ID */
- CARD32 sisfb_pcislot;
- CARD32 sisfb_pcifunc;
-
- CARD8 sisfb_lcdpdc;
-
- CARD8 sisfb_lcda;
-
- CARD32 sisfb_vbflags;
- CARD32 sisfb_currentvbflags;
-
- CARD32 sisfb_scalelcd;
- CARD32 sisfb_specialtiming;
-
- CARD8 sisfb_haveemi;
- CARD8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
- CARD8 sisfb_haveemilcd;
-
- CARD8 sisfb_lcdpdca;
-
- CARD16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
-
- CARD8 reserved[208]; /* for future use */
-};
-#endif
#endif
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index d4d55c98bce..9ae32923c14 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -3,7 +3,7 @@
/*
* General structure definitions for universal mode switching modules
*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
*
* If distributed as part of the Linux kernel, the following license terms
* apply:
@@ -50,627 +50,514 @@
*
*/
-#ifndef _VSTRUCT_
-#define _VSTRUCT_
-
-typedef struct _SiS_PanelDelayTblStruct
-{
- UCHAR timer[2];
-} SiS_PanelDelayTblStruct;
-
-typedef struct _SiS_LCDDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS_LCDDataStruct;
-
-typedef struct _SiS_TVDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT TVHDE;
- USHORT TVVDE;
- USHORT RVBHRS;
- UCHAR FlickerMode;
- USHORT HALFRVBHRS;
- UCHAR RY1COE;
- UCHAR RY2COE;
- UCHAR RY3COE;
- UCHAR RY4COE;
-} SiS_TVDataStruct;
-
-typedef struct _SiS_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS_LVDSDataStruct;
-
-typedef struct _SiS_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} SiS_LVDSDesStruct;
-
-typedef struct _SiS_LVDSCRT1DataStruct
-{
- UCHAR CR[15];
-} SiS_LVDSCRT1DataStruct;
-
-typedef struct _SiS_LCDACRT1DataStruct
-{
- UCHAR CR[17];
-} SiS_LCDACRT1DataStruct;
-
-typedef struct _SiS_CHTVRegDataStruct
-{
- UCHAR Reg[16];
-} SiS_CHTVRegDataStruct;
-
-typedef struct _SiS_StStruct
-{
- UCHAR St_ModeID;
- USHORT St_ModeFlag;
- UCHAR St_StTableIndex;
- UCHAR St_CRT2CRTC;
- UCHAR St_ResInfo;
- UCHAR VB_StTVFlickerIndex;
- UCHAR VB_StTVEdgeIndex;
- UCHAR VB_StTVYFilterIndex;
- UCHAR St_PDC;
-} SiS_StStruct;
-
-typedef struct _SiS_VBModeStruct
-{
- UCHAR ModeID;
- UCHAR VB_TVDelayIndex;
- UCHAR VB_TVFlickerIndex;
- UCHAR VB_TVPhaseIndex;
- UCHAR VB_TVYFilterIndex;
- UCHAR VB_LCDDelayIndex;
- UCHAR _VB_LCDHIndex;
- UCHAR _VB_LCDVIndex;
-} SiS_VBModeStruct;
-
-typedef struct _SiS_StandTableStruct
-{
- UCHAR CRT_COLS;
- UCHAR ROWS;
- UCHAR CHAR_HEIGHT;
- USHORT CRT_LEN;
- UCHAR SR[4];
- UCHAR MISC;
- UCHAR CRTC[0x19];
- UCHAR ATTR[0x14];
- UCHAR GRC[9];
-} SiS_StandTableStruct;
-
-typedef struct _SiS_ExtStruct
-{
- UCHAR Ext_ModeID;
- USHORT Ext_ModeFlag;
- USHORT Ext_VESAID;
- UCHAR Ext_RESINFO;
- UCHAR VB_ExtTVFlickerIndex;
- UCHAR VB_ExtTVEdgeIndex;
- UCHAR VB_ExtTVYFilterIndex;
- UCHAR VB_ExtTVYFilterIndexROM661;
- UCHAR REFindex;
- CHAR ROMMODEIDX661;
-} SiS_ExtStruct;
-
-typedef struct _SiS_Ext2Struct
-{
- USHORT Ext_InfoFlag;
- UCHAR Ext_CRT1CRTC;
- UCHAR Ext_CRTVCLK;
- UCHAR Ext_CRT2CRTC;
- UCHAR Ext_CRT2CRTC_NS;
- UCHAR ModeID;
- USHORT XRes;
- USHORT YRes;
- UCHAR Ext_PDC;
-} SiS_Ext2Struct;
-
-typedef struct _SiS_Part2PortTblStruct
-{
- UCHAR CR[12];
-} SiS_Part2PortTblStruct;
-
-typedef struct _SiS_CRT1TableStruct
-{
- UCHAR CR[17];
-} SiS_CRT1TableStruct;
-
-typedef struct _SiS_MCLKDataStruct
-{
- UCHAR SR28,SR29,SR2A;
- USHORT CLOCK;
-} SiS_MCLKDataStruct;
-
-typedef struct _SiS_VCLKDataStruct
-{
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} SiS_VCLKDataStruct;
-
-typedef struct _SiS_VBVCLKDataStruct
-{
- UCHAR Part4_A,Part4_B;
- USHORT CLOCK;
-} SiS_VBVCLKDataStruct;
-
-typedef struct _SiS_StResInfoStruct
-{
- USHORT HTotal;
- USHORT VTotal;
-} SiS_StResInfoStruct;
-
-typedef struct _SiS_ModeResInfoStruct
-{
- USHORT HTotal;
- USHORT VTotal;
- UCHAR XChar;
- UCHAR YChar;
-} SiS_ModeResInfoStruct;
-
-
-
-typedef UCHAR DRAM4Type[4];
+#ifndef _VSTRUCT_H_
+#define _VSTRUCT_H_
+
+struct SiS_PanelDelayTbl {
+ unsigned char timer[2];
+};
+
+struct SiS_LCDData {
+ unsigned short RVBHCMAX;
+ unsigned short RVBHCFACT;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short LCDHT;
+ unsigned short LCDVT;
+};
+
+struct SiS_TVData {
+ unsigned short RVBHCMAX;
+ unsigned short RVBHCFACT;
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short TVHDE;
+ unsigned short TVVDE;
+ unsigned short RVBHRS;
+ unsigned char FlickerMode;
+ unsigned short HALFRVBHRS;
+ unsigned short RVBHRS2;
+ unsigned char RY1COE;
+ unsigned char RY2COE;
+ unsigned char RY3COE;
+ unsigned char RY4COE;
+};
+
+struct SiS_LVDSData {
+ unsigned short VGAHT;
+ unsigned short VGAVT;
+ unsigned short LCDHT;
+ unsigned short LCDVT;
+};
+
+struct SiS_LVDSDes {
+ unsigned short LCDHDES;
+ unsigned short LCDVDES;
+};
+
+struct SiS_LVDSCRT1Data {
+ unsigned char CR[15];
+};
+
+struct SiS_CHTVRegData {
+ unsigned char Reg[16];
+};
+
+struct SiS_St {
+ unsigned char St_ModeID;
+ unsigned short St_ModeFlag;
+ unsigned char St_StTableIndex;
+ unsigned char St_CRT2CRTC;
+ unsigned char St_ResInfo;
+ unsigned char VB_StTVFlickerIndex;
+ unsigned char VB_StTVEdgeIndex;
+ unsigned char VB_StTVYFilterIndex;
+ unsigned char St_PDC;
+};
+
+struct SiS_VBMode {
+ unsigned char ModeID;
+ unsigned char VB_TVDelayIndex;
+ unsigned char VB_TVFlickerIndex;
+ unsigned char VB_TVPhaseIndex;
+ unsigned char VB_TVYFilterIndex;
+ unsigned char VB_LCDDelayIndex;
+ unsigned char _VB_LCDHIndex;
+ unsigned char _VB_LCDVIndex;
+};
+
+struct SiS_StandTable_S {
+ unsigned char CRT_COLS;
+ unsigned char ROWS;
+ unsigned char CHAR_HEIGHT;
+ unsigned short CRT_LEN;
+ unsigned char SR[4];
+ unsigned char MISC;
+ unsigned char CRTC[0x19];
+ unsigned char ATTR[0x14];
+ unsigned char GRC[9];
+};
+
+struct SiS_Ext {
+ unsigned char Ext_ModeID;
+ unsigned short Ext_ModeFlag;
+ unsigned short Ext_VESAID;
+ unsigned char Ext_RESINFO;
+ unsigned char VB_ExtTVFlickerIndex;
+ unsigned char VB_ExtTVEdgeIndex;
+ unsigned char VB_ExtTVYFilterIndex;
+ unsigned char VB_ExtTVYFilterIndexROM661;
+ unsigned char REFindex;
+ char ROMMODEIDX661;
+};
+
+struct SiS_Ext2 {
+ unsigned short Ext_InfoFlag;
+ unsigned char Ext_CRT1CRTC;
+ unsigned char Ext_CRTVCLK;
+ unsigned char Ext_CRT2CRTC;
+ unsigned char Ext_CRT2CRTC_NS;
+ unsigned char ModeID;
+ unsigned short XRes;
+ unsigned short YRes;
+ unsigned char Ext_PDC;
+ unsigned char Ext_FakeCRT2CRTC;
+ unsigned char Ext_FakeCRT2Clk;
+ unsigned char Ext_CRT1CRTC_NORM;
+ unsigned char Ext_CRTVCLK_NORM;
+ unsigned char Ext_CRT1CRTC_WIDE;
+ unsigned char Ext_CRTVCLK_WIDE;
+};
+
+struct SiS_Part2PortTbl {
+ unsigned char CR[12];
+};
+
+struct SiS_CRT1Table {
+ unsigned char CR[17];
+};
+
+struct SiS_MCLKData {
+ unsigned char SR28,SR29,SR2A;
+ unsigned short CLOCK;
+};
+
+struct SiS_VCLKData {
+ unsigned char SR2B,SR2C;
+ unsigned short CLOCK;
+};
+
+struct SiS_VBVCLKData {
+ unsigned char Part4_A,Part4_B;
+ unsigned short CLOCK;
+};
+
+struct SiS_StResInfo_S {
+ unsigned short HTotal;
+ unsigned short VTotal;
+};
+
+struct SiS_ModeResInfo_S {
+ unsigned short HTotal;
+ unsigned short VTotal;
+ unsigned char XChar;
+ unsigned char YChar;
+};
/* Defines for SiS_CustomT */
/* Never change these for sisfb compatibility */
-#define CUT_NONE 0
-#define CUT_FORCENONE 1
-#define CUT_BARCO1366 2
-#define CUT_BARCO1024 3
-#define CUT_COMPAQ1280 4
-#define CUT_COMPAQ12802 5
-#define CUT_PANEL848 6
-#define CUT_CLEVO1024 7
-#define CUT_CLEVO10242 8
-#define CUT_CLEVO1400 9
-#define CUT_CLEVO14002 10
-#define CUT_UNIWILL1024 11
-#define CUT_ASUSL3000D 12
-#define CUT_UNIWILL10242 13
-#define CUT_ACER1280 14
-#define CUT_COMPAL1400_1 15
-#define CUT_COMPAL1400_2 16
-#define CUT_ASUSA2H_1 17
-#define CUT_ASUSA2H_2 18
-
-typedef struct _SiS_Private
+#define CUT_NONE 0
+#define CUT_FORCENONE 1
+#define CUT_BARCO1366 2
+#define CUT_BARCO1024 3
+#define CUT_COMPAQ1280 4
+#define CUT_COMPAQ12802 5
+#define CUT_PANEL848 6
+#define CUT_CLEVO1024 7
+#define CUT_CLEVO10242 8
+#define CUT_CLEVO1400 9
+#define CUT_CLEVO14002 10
+#define CUT_UNIWILL1024 11
+#define CUT_ASUSL3000D 12
+#define CUT_UNIWILL10242 13
+#define CUT_ACER1280 14
+#define CUT_COMPAL1400_1 15
+#define CUT_COMPAL1400_2 16
+#define CUT_ASUSA2H_1 17
+#define CUT_ASUSA2H_2 18
+#define CUT_UNKNOWNLCD 19
+#define CUT_AOP8060 20
+#define CUT_PANEL856 21
+
+struct SiS_Private
{
-#ifdef LINUX_KERNEL
- SISIOADDRESS RelIO;
+ unsigned char ChipType;
+ unsigned char ChipRevision;
+#ifdef SIS_XORG_XF86
+ PCITAG PciTag;
#endif
- SISIOADDRESS SiS_P3c4;
- SISIOADDRESS SiS_P3d4;
- SISIOADDRESS SiS_P3c0;
- SISIOADDRESS SiS_P3ce;
- SISIOADDRESS SiS_P3c2;
- SISIOADDRESS SiS_P3ca;
- SISIOADDRESS SiS_P3c6;
- SISIOADDRESS SiS_P3c7;
- SISIOADDRESS SiS_P3c8;
- SISIOADDRESS SiS_P3c9;
- SISIOADDRESS SiS_P3cb;
- SISIOADDRESS SiS_P3cd;
- SISIOADDRESS SiS_P3da;
- SISIOADDRESS SiS_Part1Port;
- SISIOADDRESS SiS_Part2Port;
- SISIOADDRESS SiS_Part3Port;
- SISIOADDRESS SiS_Part4Port;
- SISIOADDRESS SiS_Part5Port;
- SISIOADDRESS SiS_VidCapt;
- SISIOADDRESS SiS_VidPlay;
- USHORT SiS_IF_DEF_LVDS;
- USHORT SiS_IF_DEF_CH70xx;
- USHORT SiS_IF_DEF_CONEX;
- USHORT SiS_IF_DEF_TRUMPION;
- USHORT SiS_IF_DEF_DSTN;
- USHORT SiS_IF_DEF_FSTN;
- USHORT SiS_SysFlags;
- UCHAR SiS_VGAINFO;
-#ifdef LINUX_XF86
- USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#ifdef SIS_LINUX_KERNEL
+ void *ivideo;
#endif
- BOOLEAN SiS_UseROM;
- BOOLEAN SiS_ROMNew;
- BOOLEAN SiS_NeedRomModeData;
- BOOLEAN PanelSelfDetected;
- int SiS_CHOverScan;
- BOOLEAN SiS_CHSOverScan;
- BOOLEAN SiS_ChSW;
- BOOLEAN SiS_UseLCDA;
- int SiS_UseOEM;
- ULONG SiS_CustomT;
- USHORT SiS_Backup70xx;
- BOOLEAN HaveEMI;
- BOOLEAN HaveEMILCD;
- BOOLEAN OverruleEMI;
- UCHAR EMI_30,EMI_31,EMI_32,EMI_33;
- USHORT SiS_EMIOffset;
- SHORT PDC, PDCA;
- UCHAR SiS_MyCR63;
- USHORT SiS_CRT1Mode;
- USHORT SiS_flag_clearbuffer;
- int SiS_RAMType;
- UCHAR SiS_ChannelAB;
- UCHAR SiS_DataBusWidth;
- USHORT SiS_ModeType;
- USHORT SiS_VBInfo;
- USHORT SiS_TVMode;
- USHORT SiS_LCDResInfo;
- USHORT SiS_LCDTypeInfo;
- USHORT SiS_LCDInfo;
- USHORT SiS_LCDInfo661;
- USHORT SiS_VBType;
- USHORT SiS_VBExtInfo;
- USHORT SiS_YPbPr;
- USHORT SiS_SelectCRT2Rate;
- USHORT SiS_SetFlag;
- USHORT SiS_RVBHCFACT;
- USHORT SiS_RVBHCMAX;
- USHORT SiS_RVBHRS;
- USHORT SiS_VGAVT;
- USHORT SiS_VGAHT;
- USHORT SiS_VT;
- USHORT SiS_HT;
- USHORT SiS_VGAVDE;
- USHORT SiS_VGAHDE;
- USHORT SiS_VDE;
- USHORT SiS_HDE;
- USHORT SiS_NewFlickerMode;
- USHORT SiS_RY1COE;
- USHORT SiS_RY2COE;
- USHORT SiS_RY3COE;
- USHORT SiS_RY4COE;
- USHORT SiS_LCDHDES;
- USHORT SiS_LCDVDES;
- USHORT SiS_DDC_Port;
- USHORT SiS_DDC_Index;
- USHORT SiS_DDC_Data;
- USHORT SiS_DDC_NData;
- USHORT SiS_DDC_Clk;
- USHORT SiS_DDC_NClk;
- USHORT SiS_DDC_DeviceAddr;
- USHORT SiS_DDC_ReadAddr;
- USHORT SiS_DDC_SecAddr;
- USHORT SiS_ChrontelInit;
- BOOLEAN SiS_SensibleSR11;
- USHORT SiS661LCD2TableSize;
-
- USHORT SiS_PanelMinLVDS;
- USHORT SiS_PanelMin301;
-
- const SiS_StStruct *SiS_SModeIDTable;
- const SiS_StandTableStruct *SiS_StandTable;
- const SiS_ExtStruct *SiS_EModeIDTable;
- const SiS_Ext2Struct *SiS_RefIndex;
- const SiS_VBModeStruct *SiS_VBModeIDTable;
- const SiS_CRT1TableStruct *SiS_CRT1Table;
- const SiS_MCLKDataStruct *SiS_MCLKData_0;
- const SiS_MCLKDataStruct *SiS_MCLKData_1;
- SiS_VCLKDataStruct *SiS_VCLKData;
- SiS_VBVCLKDataStruct *SiS_VBVCLKData;
- const SiS_StResInfoStruct *SiS_StResInfo;
- const SiS_ModeResInfoStruct *SiS_ModeResInfo;
-
- const UCHAR *pSiS_OutputSelect;
- const UCHAR *pSiS_SoftSetting;
-
- const DRAM4Type *SiS_SR15; /* pointer : point to array */
-#ifdef LINUX_KERNEL
- UCHAR *pSiS_SR07;
- const DRAM4Type *SiS_CR40; /* pointer : point to array */
- UCHAR *SiS_CR49;
- UCHAR *SiS_SR25;
- UCHAR *pSiS_SR1F;
- UCHAR *pSiS_SR21;
- UCHAR *pSiS_SR22;
- UCHAR *pSiS_SR23;
- UCHAR *pSiS_SR24;
- UCHAR *pSiS_SR31;
- UCHAR *pSiS_SR32;
- UCHAR *pSiS_SR33;
- UCHAR *pSiS_CRT2Data_1_2;
- UCHAR *pSiS_CRT2Data_4_D;
- UCHAR *pSiS_CRT2Data_4_E;
- UCHAR *pSiS_CRT2Data_4_10;
- const USHORT *pSiS_RGBSenseData;
- const USHORT *pSiS_VideoSenseData;
- const USHORT *pSiS_YCSenseData;
- const USHORT *pSiS_RGBSenseData2;
- const USHORT *pSiS_VideoSenseData2;
- const USHORT *pSiS_YCSenseData2;
+ unsigned char *VirtualRomBase;
+ BOOLEAN UseROM;
+#ifdef SIS_LINUX_KERNEL
+ unsigned char SISIOMEMTYPE *VideoMemoryAddress;
+ unsigned int VideoMemorySize;
#endif
+ SISIOADDRESS IOAddress;
+ SISIOADDRESS IOAddress2; /* For dual chip XGI volari */
- const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
- const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+#ifdef SIS_LINUX_KERNEL
+ SISIOADDRESS RelIO;
+#endif
+ SISIOADDRESS SiS_P3c4;
+ SISIOADDRESS SiS_P3d4;
+ SISIOADDRESS SiS_P3c0;
+ SISIOADDRESS SiS_P3ce;
+ SISIOADDRESS SiS_P3c2;
+ SISIOADDRESS SiS_P3ca;
+ SISIOADDRESS SiS_P3c6;
+ SISIOADDRESS SiS_P3c7;
+ SISIOADDRESS SiS_P3c8;
+ SISIOADDRESS SiS_P3c9;
+ SISIOADDRESS SiS_P3cb;
+ SISIOADDRESS SiS_P3cc;
+ SISIOADDRESS SiS_P3cd;
+ SISIOADDRESS SiS_P3da;
+ SISIOADDRESS SiS_Part1Port;
+ SISIOADDRESS SiS_Part2Port;
+ SISIOADDRESS SiS_Part3Port;
+ SISIOADDRESS SiS_Part4Port;
+ SISIOADDRESS SiS_Part5Port;
+ SISIOADDRESS SiS_VidCapt;
+ SISIOADDRESS SiS_VidPlay;
+ unsigned short SiS_IF_DEF_LVDS;
+ unsigned short SiS_IF_DEF_CH70xx;
+ unsigned short SiS_IF_DEF_CONEX;
+ unsigned short SiS_IF_DEF_TRUMPION;
+ unsigned short SiS_IF_DEF_DSTN;
+ unsigned short SiS_IF_DEF_FSTN;
+ unsigned short SiS_SysFlags;
+ unsigned char SiS_VGAINFO;
+#ifdef SIS_XORG_XF86
+ unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#endif
+ BOOLEAN SiS_UseROM;
+ BOOLEAN SiS_ROMNew;
+ BOOLEAN SiS_XGIROM;
+ BOOLEAN SiS_NeedRomModeData;
+ BOOLEAN PanelSelfDetected;
+ BOOLEAN DDCPortMixup;
+ int SiS_CHOverScan;
+ BOOLEAN SiS_CHSOverScan;
+ BOOLEAN SiS_ChSW;
+ BOOLEAN SiS_UseLCDA;
+ int SiS_UseOEM;
+ unsigned int SiS_CustomT;
+ int SiS_UseWide, SiS_UseWideCRT2;
+ int SiS_TVBlue;
+ unsigned short SiS_Backup70xx;
+ BOOLEAN HaveEMI;
+ BOOLEAN HaveEMILCD;
+ BOOLEAN OverruleEMI;
+ unsigned char EMI_30,EMI_31,EMI_32,EMI_33;
+ unsigned short SiS_EMIOffset;
+ unsigned short SiS_PWDOffset;
+ short PDC, PDCA;
+ unsigned char SiS_MyCR63;
+ unsigned short SiS_CRT1Mode;
+ unsigned short SiS_flag_clearbuffer;
+ int SiS_RAMType;
+ unsigned char SiS_ChannelAB;
+ unsigned char SiS_DataBusWidth;
+ unsigned short SiS_ModeType;
+ unsigned short SiS_VBInfo;
+ unsigned short SiS_TVMode;
+ unsigned short SiS_LCDResInfo;
+ unsigned short SiS_LCDTypeInfo;
+ unsigned short SiS_LCDInfo;
+ unsigned short SiS_LCDInfo661;
+ unsigned short SiS_VBType;
+ unsigned short SiS_VBExtInfo;
+ unsigned short SiS_YPbPr;
+ unsigned short SiS_SelectCRT2Rate;
+ unsigned short SiS_SetFlag;
+ unsigned short SiS_RVBHCFACT;
+ unsigned short SiS_RVBHCMAX;
+ unsigned short SiS_RVBHRS;
+ unsigned short SiS_RVBHRS2;
+ unsigned short SiS_VGAVT;
+ unsigned short SiS_VGAHT;
+ unsigned short SiS_VT;
+ unsigned short SiS_HT;
+ unsigned short SiS_VGAVDE;
+ unsigned short SiS_VGAHDE;
+ unsigned short SiS_VDE;
+ unsigned short SiS_HDE;
+ unsigned short SiS_NewFlickerMode;
+ unsigned short SiS_RY1COE;
+ unsigned short SiS_RY2COE;
+ unsigned short SiS_RY3COE;
+ unsigned short SiS_RY4COE;
+ unsigned short SiS_LCDHDES;
+ unsigned short SiS_LCDVDES;
+ unsigned short SiS_DDC_Port;
+ unsigned short SiS_DDC_Index;
+ unsigned short SiS_DDC_Data;
+ unsigned short SiS_DDC_NData;
+ unsigned short SiS_DDC_Clk;
+ unsigned short SiS_DDC_NClk;
+ unsigned short SiS_DDC_DeviceAddr;
+ unsigned short SiS_DDC_ReadAddr;
+ unsigned short SiS_DDC_SecAddr;
+ unsigned short SiS_ChrontelInit;
+ BOOLEAN SiS_SensibleSR11;
+ unsigned short SiS661LCD2TableSize;
+
+ unsigned short SiS_PanelMinLVDS;
+ unsigned short SiS_PanelMin301;
+
+ const struct SiS_St *SiS_SModeIDTable;
+ const struct SiS_StandTable_S *SiS_StandTable;
+ const struct SiS_Ext *SiS_EModeIDTable;
+ const struct SiS_Ext2 *SiS_RefIndex;
+ const struct SiS_VBMode *SiS_VBModeIDTable;
+ const struct SiS_CRT1Table *SiS_CRT1Table;
+ const struct SiS_MCLKData *SiS_MCLKData_0;
+ const struct SiS_MCLKData *SiS_MCLKData_1;
+ struct SiS_VCLKData *SiS_VCLKData;
+ struct SiS_VBVCLKData *SiS_VBVCLKData;
+ const struct SiS_StResInfo_S *SiS_StResInfo;
+ const struct SiS_ModeResInfo_S *SiS_ModeResInfo;
+
+ const unsigned char *pSiS_OutputSelect;
+ const unsigned char *pSiS_SoftSetting;
+
+ const unsigned char *SiS_SR15;
+
+ const struct SiS_PanelDelayTbl *SiS_PanelDelayTbl;
+ const struct SiS_PanelDelayTbl *SiS_PanelDelayTblLVDS;
/* SiS bridge */
- const UCHAR *SiS_NTSCPhase;
- const UCHAR *SiS_PALPhase;
- const UCHAR *SiS_NTSCPhase2;
- const UCHAR *SiS_PALPhase2;
- const UCHAR *SiS_PALMPhase;
- const UCHAR *SiS_PALNPhase;
- const UCHAR *SiS_PALMPhase2;
- const UCHAR *SiS_PALNPhase2;
- const UCHAR *SiS_SpecialPhase;
- const UCHAR *SiS_SpecialPhaseM;
- const UCHAR *SiS_SpecialPhaseJ;
- const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
- const SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
- const SiS_LCDDataStruct *SiS_LCD1280x720Data;
- const SiS_LCDDataStruct *SiS_StLCD1280x768_2Data;
- const SiS_LCDDataStruct *SiS_ExtLCD1280x768_2Data;
- const SiS_LCDDataStruct *SiS_LCD1280x800Data;
- const SiS_LCDDataStruct *SiS_LCD1280x800_2Data;
- const SiS_LCDDataStruct *SiS_LCD1280x960Data;
- const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
- const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
- const SiS_LCDDataStruct *SiS_StLCD1400x1050Data;
- const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data;
- const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
- const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data;
- const SiS_LCDDataStruct *SiS_LCD1680x1050Data;
- const SiS_LCDDataStruct *SiS_NoScaleData;
- const SiS_TVDataStruct *SiS_StPALData;
- const SiS_TVDataStruct *SiS_ExtPALData;
- const SiS_TVDataStruct *SiS_StNTSCData;
- const SiS_TVDataStruct *SiS_ExtNTSCData;
- const SiS_TVDataStruct *SiS_St1HiTVData;
- const SiS_TVDataStruct *SiS_St2HiTVData;
- const SiS_TVDataStruct *SiS_ExtHiTVData;
- const SiS_TVDataStruct *SiS_St525iData;
- const SiS_TVDataStruct *SiS_St525pData;
- const SiS_TVDataStruct *SiS_St750pData;
- const SiS_TVDataStruct *SiS_Ext525iData;
- const SiS_TVDataStruct *SiS_Ext525pData;
- const SiS_TVDataStruct *SiS_Ext750pData;
- const UCHAR *SiS_NTSCTiming;
- const UCHAR *SiS_PALTiming;
- const UCHAR *SiS_HiTVExtTiming;
- const UCHAR *SiS_HiTVSt1Timing;
- const UCHAR *SiS_HiTVSt2Timing;
- const UCHAR *SiS_HiTVGroup3Data;
- const UCHAR *SiS_HiTVGroup3Simu;
+ const struct SiS_LCDData *SiS_ExtLCD1024x768Data;
+ const struct SiS_LCDData *SiS_St2LCD1024x768Data;
+ const struct SiS_LCDData *SiS_LCD1280x720Data;
+ const struct SiS_LCDData *SiS_StLCD1280x768_2Data;
+ const struct SiS_LCDData *SiS_ExtLCD1280x768_2Data;
+ const struct SiS_LCDData *SiS_LCD1280x800Data;
+ const struct SiS_LCDData *SiS_LCD1280x800_2Data;
+ const struct SiS_LCDData *SiS_LCD1280x854Data;
+ const struct SiS_LCDData *SiS_LCD1280x960Data;
+ const struct SiS_LCDData *SiS_ExtLCD1280x1024Data;
+ const struct SiS_LCDData *SiS_St2LCD1280x1024Data;
+ const struct SiS_LCDData *SiS_StLCD1400x1050Data;
+ const struct SiS_LCDData *SiS_ExtLCD1400x1050Data;
+ const struct SiS_LCDData *SiS_StLCD1600x1200Data;
+ const struct SiS_LCDData *SiS_ExtLCD1600x1200Data;
+ const struct SiS_LCDData *SiS_LCD1680x1050Data;
+ const struct SiS_LCDData *SiS_NoScaleData;
+ const struct SiS_TVData *SiS_StPALData;
+ const struct SiS_TVData *SiS_ExtPALData;
+ const struct SiS_TVData *SiS_StNTSCData;
+ const struct SiS_TVData *SiS_ExtNTSCData;
+ const struct SiS_TVData *SiS_St1HiTVData;
+ const struct SiS_TVData *SiS_St2HiTVData;
+ const struct SiS_TVData *SiS_ExtHiTVData;
+ const struct SiS_TVData *SiS_St525iData;
+ const struct SiS_TVData *SiS_St525pData;
+ const struct SiS_TVData *SiS_St750pData;
+ const struct SiS_TVData *SiS_Ext525iData;
+ const struct SiS_TVData *SiS_Ext525pData;
+ const struct SiS_TVData *SiS_Ext750pData;
+ const unsigned char *SiS_NTSCTiming;
+ const unsigned char *SiS_PALTiming;
+ const unsigned char *SiS_HiTVExtTiming;
+ const unsigned char *SiS_HiTVSt1Timing;
+ const unsigned char *SiS_HiTVSt2Timing;
+ const unsigned char *SiS_HiTVGroup3Data;
+ const unsigned char *SiS_HiTVGroup3Simu;
#if 0
- const UCHAR *SiS_HiTVTextTiming;
- const UCHAR *SiS_HiTVGroup3Text;
+ const unsigned char *SiS_HiTVTextTiming;
+ const unsigned char *SiS_HiTVGroup3Text;
#endif
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_1;
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_2;
+ const struct SiS_Part2PortTbl *SiS_CRT2Part2_1024x768_3;
/* LVDS, Chrontel */
- const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS800x600Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1280x1024Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1280x960Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1400x1050Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1600x1200Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1280x768Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1024x600Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS1152x768Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1;
- const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1;
- const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1;
- const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2;
- const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_1;
- const SiS_LVDSDataStruct *SiS_LVDSBARCO1024Data_2;
- const SiS_LVDSDataStruct *SiS_LVDS848x480Data_1;
- const SiS_LVDSDataStruct *SiS_LVDS848x480Data_2;
- const SiS_LVDSDataStruct *SiS_CHTVUNTSCData;
- const SiS_LVDSDataStruct *SiS_CHTVONTSCData;
- const SiS_LVDSDataStruct *SiS_CHTVUPALData;
- const SiS_LVDSDataStruct *SiS_CHTVOPALData;
- const SiS_LVDSDataStruct *SiS_CHTVUPALMData;
- const SiS_LVDSDataStruct *SiS_CHTVOPALMData;
- const SiS_LVDSDataStruct *SiS_CHTVUPALNData;
- const SiS_LVDSDataStruct *SiS_CHTVOPALNData;
- const SiS_LVDSDataStruct *SiS_CHTVSOPALData;
-
- const SiS_LVDSDesStruct *SiS_PanelType00_1;
- const SiS_LVDSDesStruct *SiS_PanelType01_1;
- const SiS_LVDSDesStruct *SiS_PanelType02_1;
- const SiS_LVDSDesStruct *SiS_PanelType03_1;
- const SiS_LVDSDesStruct *SiS_PanelType04_1;
- const SiS_LVDSDesStruct *SiS_PanelType05_1;
- const SiS_LVDSDesStruct *SiS_PanelType06_1;
- const SiS_LVDSDesStruct *SiS_PanelType07_1;
- const SiS_LVDSDesStruct *SiS_PanelType08_1;
- const SiS_LVDSDesStruct *SiS_PanelType09_1;
- const SiS_LVDSDesStruct *SiS_PanelType0a_1;
- const SiS_LVDSDesStruct *SiS_PanelType0b_1;
- const SiS_LVDSDesStruct *SiS_PanelType0c_1;
- const SiS_LVDSDesStruct *SiS_PanelType0d_1;
- const SiS_LVDSDesStruct *SiS_PanelType0e_1;
- const SiS_LVDSDesStruct *SiS_PanelType0f_1;
- const SiS_LVDSDesStruct *SiS_PanelTypeNS_1;
- const SiS_LVDSDesStruct *SiS_PanelType00_2;
- const SiS_LVDSDesStruct *SiS_PanelType01_2;
- const SiS_LVDSDesStruct *SiS_PanelType02_2;
- const SiS_LVDSDesStruct *SiS_PanelType03_2;
- const SiS_LVDSDesStruct *SiS_PanelType04_2;
- const SiS_LVDSDesStruct *SiS_PanelType05_2;
- const SiS_LVDSDesStruct *SiS_PanelType06_2;
- const SiS_LVDSDesStruct *SiS_PanelType07_2;
- const SiS_LVDSDesStruct *SiS_PanelType08_2;
- const SiS_LVDSDesStruct *SiS_PanelType09_2;
- const SiS_LVDSDesStruct *SiS_PanelType0a_2;
- const SiS_LVDSDesStruct *SiS_PanelType0b_2;
- const SiS_LVDSDesStruct *SiS_PanelType0c_2;
- const SiS_LVDSDesStruct *SiS_PanelType0d_2;
- const SiS_LVDSDesStruct *SiS_PanelType0e_2;
- const SiS_LVDSDesStruct *SiS_PanelType0f_2;
- const SiS_LVDSDesStruct *SiS_PanelTypeNS_2;
- const SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData;
- const SiS_LVDSDesStruct *SiS_CHTVONTSCDesData;
- const SiS_LVDSDesStruct *SiS_CHTVUPALDesData;
- const SiS_LVDSDesStruct *SiS_CHTVOPALDesData;
-
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11400x1050_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x768_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x600_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11152x768_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11600x1200_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1XXXxXXX_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_1_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1;
- const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
- const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
- const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
- const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
- const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL;
-
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
- const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
-
- const UCHAR *SiS_CHTVVCLKUNTSC;
- const UCHAR *SiS_CHTVVCLKONTSC;
- const UCHAR *SiS_CHTVVCLKUPAL;
- const UCHAR *SiS_CHTVVCLKOPAL;
- const UCHAR *SiS_CHTVVCLKUPALM;
- const UCHAR *SiS_CHTVVCLKOPALM;
- const UCHAR *SiS_CHTVVCLKUPALN;
- const UCHAR *SiS_CHTVVCLKOPALN;
- const UCHAR *SiS_CHTVVCLKSOPAL;
-
- USHORT PanelXRes, PanelHT;
- USHORT PanelYRes, PanelVT;
- USHORT PanelHRS, PanelHRE;
- USHORT PanelVRS, PanelVRE;
- USHORT PanelVCLKIdx300;
- USHORT PanelVCLKIdx315;
-
- BOOLEAN UseCustomMode;
- BOOLEAN CRT1UsesCustomMode;
- USHORT CHDisplay;
- USHORT CHSyncStart;
- USHORT CHSyncEnd;
- USHORT CHTotal;
- USHORT CHBlankStart;
- USHORT CHBlankEnd;
- USHORT CVDisplay;
- USHORT CVSyncStart;
- USHORT CVSyncEnd;
- USHORT CVTotal;
- USHORT CVBlankStart;
- USHORT CVBlankEnd;
- ULONG CDClock;
- ULONG CFlags;
- UCHAR CCRT1CRTC[17];
- UCHAR CSR2B;
- UCHAR CSR2C;
- USHORT CSRClock;
- USHORT CSRClock_CRT1;
- USHORT CModeFlag;
- USHORT CModeFlag_CRT1;
- USHORT CInfoFlag;
-
- int LVDSHL;
-
- BOOLEAN Backup;
- UCHAR Backup_Mode;
- UCHAR Backup_14;
- UCHAR Backup_15;
- UCHAR Backup_16;
- UCHAR Backup_17;
- UCHAR Backup_18;
- UCHAR Backup_19;
- UCHAR Backup_1a;
- UCHAR Backup_1b;
- UCHAR Backup_1c;
- UCHAR Backup_1d;
-
- int UsePanelScaler;
- int CenterScreen;
-
- USHORT CP_Vendor, CP_Product;
- BOOLEAN CP_HaveCustomData;
- int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
- int CP_MaxX, CP_MaxY, CP_MaxClock;
- UCHAR CP_PrefSR2B, CP_PrefSR2C;
- USHORT CP_PrefClock;
- BOOLEAN CP_Supports64048075;
- int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
- int CP_HTotal[7], CP_VTotal[7];
- int CP_HSyncStart[7], CP_VSyncStart[7];
- int CP_HSyncEnd[7], CP_VSyncEnd[7];
- int CP_HBlankStart[7], CP_VBlankStart[7];
- int CP_HBlankEnd[7], CP_VBlankEnd[7];
- int CP_Clock[7];
- BOOLEAN CP_DataValid[7];
- BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
-} SiS_Private;
+ const struct SiS_LVDSData *SiS_LVDS320x240Data_1;
+ const struct SiS_LVDSData *SiS_LVDS320x240Data_2;
+ const struct SiS_LVDSData *SiS_LVDS640x480Data_1;
+ const struct SiS_LVDSData *SiS_LVDS800x600Data_1;
+ const struct SiS_LVDSData *SiS_LVDS1024x600Data_1;
+ const struct SiS_LVDSData *SiS_LVDS1024x768Data_1;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_1;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1366Data_2;
+ const struct SiS_LVDSData *SiS_LVDSBARCO1024Data_1;
+ const struct SiS_LVDSData *SiS_LVDS848x480Data_1;
+ const struct SiS_LVDSData *SiS_LVDS848x480Data_2;
+ const struct SiS_LVDSData *SiS_CHTVUNTSCData;
+ const struct SiS_LVDSData *SiS_CHTVONTSCData;
+ const struct SiS_LVDSData *SiS_CHTVUPALData;
+ const struct SiS_LVDSData *SiS_CHTVOPALData;
+ const struct SiS_LVDSData *SiS_CHTVUPALMData;
+ const struct SiS_LVDSData *SiS_CHTVOPALMData;
+ const struct SiS_LVDSData *SiS_CHTVUPALNData;
+ const struct SiS_LVDSData *SiS_CHTVOPALNData;
+ const struct SiS_LVDSData *SiS_CHTVSOPALData;
+
+ const struct SiS_LVDSDes *SiS_PanelType04_1a;
+ const struct SiS_LVDSDes *SiS_PanelType04_2a;
+ const struct SiS_LVDSDes *SiS_PanelType04_1b;
+ const struct SiS_LVDSDes *SiS_PanelType04_2b;
+
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_1;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_2_H;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1320x240_3_H;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1;
+ const struct SiS_LVDSCRT1Data *SiS_LVDSCRT1640x480_1_H;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UNTSC;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1ONTSC;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1UPAL;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1OPAL;
+ const struct SiS_LVDSCRT1Data *SiS_CHTVCRT1SOPAL;
+
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UNTSC;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_ONTSC;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPAL;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPAL;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPALM;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPALM;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_UPALN;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_OPALN;
+ const struct SiS_CHTVRegData *SiS_CHTVReg_SOPAL;
+
+ const unsigned char *SiS_CHTVVCLKUNTSC;
+ const unsigned char *SiS_CHTVVCLKONTSC;
+ const unsigned char *SiS_CHTVVCLKUPAL;
+ const unsigned char *SiS_CHTVVCLKOPAL;
+ const unsigned char *SiS_CHTVVCLKUPALM;
+ const unsigned char *SiS_CHTVVCLKOPALM;
+ const unsigned char *SiS_CHTVVCLKUPALN;
+ const unsigned char *SiS_CHTVVCLKOPALN;
+ const unsigned char *SiS_CHTVVCLKSOPAL;
+
+ unsigned short PanelXRes, PanelHT;
+ unsigned short PanelYRes, PanelVT;
+ unsigned short PanelHRS, PanelHRE;
+ unsigned short PanelVRS, PanelVRE;
+ unsigned short PanelVCLKIdx300;
+ unsigned short PanelVCLKIdx315;
+ BOOLEAN Alternate1600x1200;
+
+ BOOLEAN UseCustomMode;
+ BOOLEAN CRT1UsesCustomMode;
+ unsigned short CHDisplay;
+ unsigned short CHSyncStart;
+ unsigned short CHSyncEnd;
+ unsigned short CHTotal;
+ unsigned short CHBlankStart;
+ unsigned short CHBlankEnd;
+ unsigned short CVDisplay;
+ unsigned short CVSyncStart;
+ unsigned short CVSyncEnd;
+ unsigned short CVTotal;
+ unsigned short CVBlankStart;
+ unsigned short CVBlankEnd;
+ unsigned int CDClock;
+ unsigned int CFlags;
+ unsigned char CCRT1CRTC[17];
+ unsigned char CSR2B;
+ unsigned char CSR2C;
+ unsigned short CSRClock;
+ unsigned short CSRClock_CRT1;
+ unsigned short CModeFlag;
+ unsigned short CModeFlag_CRT1;
+ unsigned short CInfoFlag;
+
+ int LVDSHL;
+
+ BOOLEAN Backup;
+ unsigned char Backup_Mode;
+ unsigned char Backup_14;
+ unsigned char Backup_15;
+ unsigned char Backup_16;
+ unsigned char Backup_17;
+ unsigned char Backup_18;
+ unsigned char Backup_19;
+ unsigned char Backup_1a;
+ unsigned char Backup_1b;
+ unsigned char Backup_1c;
+ unsigned char Backup_1d;
+
+ unsigned char Init_P4_0E;
+
+ int UsePanelScaler;
+ int CenterScreen;
+
+ unsigned short CP_Vendor, CP_Product;
+ BOOLEAN CP_HaveCustomData;
+ int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
+ int CP_MaxX, CP_MaxY, CP_MaxClock;
+ unsigned char CP_PrefSR2B, CP_PrefSR2C;
+ unsigned short CP_PrefClock;
+ BOOLEAN CP_Supports64048075;
+ int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
+ int CP_HTotal[7], CP_VTotal[7];
+ int CP_HSyncStart[7], CP_VSyncStart[7];
+ int CP_HSyncEnd[7], CP_VSyncEnd[7];
+ int CP_HBlankStart[7], CP_VBlankStart[7];
+ int CP_HBlankEnd[7], CP_VBlankEnd[7];
+ int CP_Clock[7];
+ BOOLEAN CP_DataValid[7];
+ BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+};
#endif
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 698ca9232e7..81a6d9f188c 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
chip_id = id->device;
+ if(chip_id == CYBERBLADEi1)
+ output("*** Please do use cyblafb, Cyberblade/i1 support "
+ "will soon be removed from tridentfb!\n");
+
+
/* If PCI id is 0x9660 then further detect chip type */
if (chip_id == TGUI9660) {
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index a272592b037..1ca80264c7b 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -19,6 +19,7 @@
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <video/vga.h>
#include <asm/io.h>
#include <asm/mtrr.h>
@@ -54,6 +55,7 @@ static unsigned short *pmi_base = NULL;
static void (*pmi_start)(void);
static void (*pmi_pal)(void);
static int depth;
+static int vga_compat;
/* --------------------------------------------------------------------- */
@@ -86,6 +88,37 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
return 0;
}
+static int vesafb_blank(int blank, struct fb_info *info)
+{
+ int err = 1;
+
+ if (vga_compat) {
+ int loop = 10000;
+ u8 seq = 0, crtc17 = 0;
+
+ err = 0;
+
+ if (blank) {
+ seq = 0x20;
+ crtc17 = 0x00;
+ } else {
+ seq = 0x00;
+ crtc17 = 0x80;
+ }
+
+ vga_wseq(NULL, 0x00, 0x01);
+ seq |= vga_rseq(NULL, 0x01) & ~0x20;
+ vga_wseq(NULL, 0x00, seq);
+
+ crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
+ while (loop--);
+ vga_wcrt(NULL, 0x17, crtc17);
+ vga_wseq(NULL, 0x00, 0x03);
+ }
+
+ return err;
+}
+
static void vesa_setpalette(int regno, unsigned red, unsigned green,
unsigned blue)
{
@@ -176,6 +209,7 @@ static struct fb_ops vesafb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = vesafb_setcolreg,
.fb_pan_display = vesafb_pan_display,
+ .fb_blank = vesafb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
@@ -429,6 +463,10 @@ static int __init vesafb_probe(struct device *device)
info->flags = FBINFO_FLAG_DEFAULT |
(ypan) ? FBINFO_HWACCEL_YPAN : 0;
+ vga_compat = (screen_info.capabilities & 2) ? 0 : 1;
+ printk("vesafb: Mode is %sVGA compatible\n",
+ (vga_compat) ? "" : "not ");
+
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
err = -ENOMEM;
goto err;
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 711b90903e7..9a1e00dd3e0 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -54,4 +54,20 @@ config W1_SMEM
Say Y here if you want to connect 1-wire
simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
+config W1_DS2433
+ tristate "4kb EEPROM family support (DS2433)"
+ depends on W1
+ help
+ Say Y here if you want to use a 1-wire
+ 4kb EEPROM family device (DS2433).
+
+config W1_DS2433_CRC
+ bool "Protect DS2433 data with a CRC16"
+ depends on W1_DS2433
+ select CRC16
+ help
+ Say Y here to protect DS2433 data with a CRC16.
+ Each block has 30 bytes of data and a two byte CRC16.
+ Full block writes are only allowed if the CRC is valid.
+
endmenu
diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile
index 80725c348e7..01fb5439147 100644
--- a/drivers/w1/Makefile
+++ b/drivers/w1/Makefile
@@ -6,6 +6,10 @@ ifneq ($(CONFIG_NET), y)
EXTRA_CFLAGS += -DNETLINK_DISABLED
endif
+ifeq ($(CONFIG_W1_DS2433_CRC), y)
+EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC
+endif
+
obj-$(CONFIG_W1) += wire.o
wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o
@@ -13,8 +17,9 @@ obj-$(CONFIG_W1_MATROX) += matrox_w1.o
obj-$(CONFIG_W1_THERM) += w1_therm.o
obj-$(CONFIG_W1_SMEM) += w1_smem.o
-obj-$(CONFIG_W1_DS9490) += ds9490r.o
+obj-$(CONFIG_W1_DS9490) += ds9490r.o
ds9490r-objs := dscore.o
obj-$(CONFIG_W1_DS9490_BRIDGE) += ds_w1_bridge.o
+obj-$(CONFIG_W1_DS2433) += w1_ds2433.o
diff --git a/drivers/w1/ds_w1_bridge.c b/drivers/w1/ds_w1_bridge.c
index 7bddd8ac7d7..a79d16d5666 100644
--- a/drivers/w1/ds_w1_bridge.c
+++ b/drivers/w1/ds_w1_bridge.c
@@ -1,8 +1,8 @@
/*
- * ds_w1_bridge.c
+ * ds_w1_bridge.c
*
* Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- *
+ *
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
#include "../w1/w1.h"
#include "../w1/w1_int.h"
#include "dscore.h"
-
+
static struct ds_device *ds_dev;
static struct w1_bus_master *ds_bus_master;
@@ -120,7 +120,7 @@ static u8 ds9490r_reset(unsigned long data)
static int __devinit ds_w1_init(void)
{
int err;
-
+
ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL);
if (!ds_bus_master) {
printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n");
@@ -136,14 +136,14 @@ static int __devinit ds_w1_init(void)
memset(ds_bus_master, 0, sizeof(*ds_bus_master));
- ds_bus_master->data = (unsigned long)ds_dev;
- ds_bus_master->touch_bit = &ds9490r_touch_bit;
- ds_bus_master->read_bit = &ds9490r_read_bit;
- ds_bus_master->write_bit = &ds9490r_write_bit;
- ds_bus_master->read_byte = &ds9490r_read_byte;
- ds_bus_master->write_byte = &ds9490r_write_byte;
- ds_bus_master->read_block = &ds9490r_read_block;
- ds_bus_master->write_block = &ds9490r_write_block;
+ ds_bus_master->data = (unsigned long)ds_dev;
+ ds_bus_master->touch_bit = &ds9490r_touch_bit;
+ ds_bus_master->read_bit = &ds9490r_read_bit;
+ ds_bus_master->write_bit = &ds9490r_write_bit;
+ ds_bus_master->read_byte = &ds9490r_read_byte;
+ ds_bus_master->write_byte = &ds9490r_write_byte;
+ ds_bus_master->read_block = &ds9490r_read_block;
+ ds_bus_master->write_block = &ds9490r_write_block;
ds_bus_master->reset_bus = &ds9490r_reset;
err = w1_add_master_device(ds_bus_master);
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c
index eee6644d33d..15fb250451e 100644
--- a/drivers/w1/dscore.c
+++ b/drivers/w1/dscore.c
@@ -1,8 +1,8 @@
/*
- * dscore.c
+ * dscore.c
*
* Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- *
+ *
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,19 +32,16 @@ static struct usb_device_id ds_id_table [] = {
};
MODULE_DEVICE_TABLE(usb, ds_id_table);
-int ds_probe(struct usb_interface *, const struct usb_device_id *);
-void ds_disconnect(struct usb_interface *);
+static int ds_probe(struct usb_interface *, const struct usb_device_id *);
+static void ds_disconnect(struct usb_interface *);
int ds_touch_bit(struct ds_device *, u8, u8 *);
int ds_read_byte(struct ds_device *, u8 *);
int ds_read_bit(struct ds_device *, u8 *);
int ds_write_byte(struct ds_device *, u8);
int ds_write_bit(struct ds_device *, u8);
-int ds_start_pulse(struct ds_device *, int);
-int ds_set_speed(struct ds_device *, int);
+static int ds_start_pulse(struct ds_device *, int);
int ds_reset(struct ds_device *, struct ds_status *);
-int ds_detect(struct ds_device *, struct ds_status *);
-int ds_stop_pulse(struct ds_device *, int);
struct ds_device * ds_get_device(void);
void ds_put_device(struct ds_device *);
@@ -79,11 +76,11 @@ void ds_put_device(struct ds_device *dev)
static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
{
int err;
-
- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+
+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
CONTROL_CMD, 0x40, value, index, NULL, 0, 1000);
if (err < 0) {
- printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",
+ printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n",
value, index, err);
return err;
}
@@ -94,11 +91,11 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
{
int err;
-
- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+
+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
MODE_CMD, 0x40, value, index, NULL, 0, 1000);
if (err < 0) {
- printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",
+ printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n",
value, index, err);
return err;
}
@@ -109,11 +106,11 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
{
int err;
-
- err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
+
+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
COMM_CMD, 0x40, value, index, NULL, 0, 1000);
if (err < 0) {
- printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",
+ printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n",
value, index, err);
return err;
}
@@ -126,19 +123,20 @@ static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int of
printk("%45s: %8x\n", str, buf[off]);
}
-int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, unsigned char *buf, int size)
+static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
+ unsigned char *buf, int size)
{
int count, err;
-
+
memset(st, 0, sizeof(st));
-
+
count = 0;
err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100);
if (err < 0) {
printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err);
return err;
}
-
+
if (count >= sizeof(*st))
memcpy(st, buf, sizeof(*st));
@@ -149,13 +147,13 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
{
unsigned char buf[64];
int count, err = 0, i;
-
+
memcpy(st, buf, sizeof(*st));
-
+
count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
if (count < 0)
return err;
-
+
printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
for (i=0; i<count; ++i)
printk("%02x ", buf[i]);
@@ -199,7 +197,7 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
return err;
}
#endif
-
+
return err;
}
@@ -207,9 +205,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
{
int count, err;
struct ds_status st;
-
+
count = 0;
- err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
+ err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
buf, size, &count, 1000);
if (err < 0) {
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)
static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
{
int count, err;
-
+
count = 0;
err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
if (err < 0) {
@@ -245,12 +243,14 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
return err;
}
+#if 0
+
int ds_stop_pulse(struct ds_device *dev, int limit)
{
struct ds_status st;
int count = 0, err = 0;
u8 buf[0x20];
-
+
do {
err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
if (err)
@@ -275,7 +275,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
int ds_detect(struct ds_device *dev, struct ds_status *st)
{
int err;
-
+
err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
if (err)
return err;
@@ -283,11 +283,11 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
if (err)
return err;
-
+
err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
if (err)
return err;
-
+
err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
if (err)
return err;
@@ -297,7 +297,9 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
return err;
}
-int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+#endif /* 0 */
+
+static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
{
u8 buf[0x20];
int err, count = 0;
@@ -305,7 +307,7 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
do {
err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
#if 0
- if (err >= 0) {
+ if (err >= 0) {
int i;
printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
for (i=0; i<err; ++i)
@@ -319,10 +321,8 @@ int ds_wait_status(struct ds_device *dev, struct ds_status *st)
if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
ds_recv_status(dev, st);
return -1;
- }
- else {
+ } else
return 0;
- }
}
int 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)
return 0;
}
+#if 0
int ds_set_speed(struct ds_device *dev, int speed)
{
int err;
@@ -356,20 +357,21 @@ int ds_set_speed(struct ds_device *dev, int speed)
speed = SPEED_FLEXIBLE;
speed &= 0xff;
-
+
err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
if (err)
return err;
return err;
}
+#endif /* 0 */
-int ds_start_pulse(struct ds_device *dev, int delay)
+static int ds_start_pulse(struct ds_device *dev, int delay)
{
int err;
u8 del = 1 + (u8)(delay >> 4);
struct ds_status st;
-
+
#if 0
err = ds_stop_pulse(dev, 10);
if (err)
@@ -390,7 +392,7 @@ int ds_start_pulse(struct ds_device *dev, int delay)
mdelay(delay);
ds_wait_status(dev, &st);
-
+
return err;
}
@@ -400,7 +402,7 @@ int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
struct ds_status st;
u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
u16 cmd;
-
+
err = ds_send_control(dev, value, 0);
if (err)
return err;
@@ -430,7 +432,7 @@ int ds_write_bit(struct ds_device *dev, u8 bit)
{
int err;
struct ds_status st;
-
+
err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
if (err)
return err;
@@ -445,7 +447,7 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
int err;
struct ds_status st;
u8 rbyte;
-
+
err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
if (err)
return err;
@@ -453,11 +455,11 @@ int ds_write_byte(struct ds_device *dev, u8 byte)
err = ds_wait_status(dev, &st);
if (err)
return err;
-
+
err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
if (err < 0)
return err;
-
+
ds_start_pulse(dev, PULLUP_PULSE_DURATION);
return !(byte == rbyte);
@@ -470,11 +472,11 @@ int ds_read_bit(struct ds_device *dev, u8 *bit)
err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
if (err)
return err;
-
+
err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0);
if (err)
return err;
-
+
err = ds_recv_data(dev, bit, sizeof(*bit));
if (err < 0)
return err;
@@ -492,7 +494,7 @@ int ds_read_byte(struct ds_device *dev, u8 *byte)
return err;
ds_wait_status(dev, &st);
-
+
err = ds_recv_data(dev, byte, sizeof(*byte));
if (err < 0)
return err;
@@ -509,17 +511,17 @@ int ds_read_block(struct ds_device *dev, u8 *buf, int len)
return -E2BIG;
memset(buf, 0xFF, len);
-
+
err = ds_send_data(dev, buf, len);
if (err < 0)
return err;
-
+
err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
if (err)
return err;
ds_wait_status(dev, &st);
-
+
memset(buf, 0x00, len);
err = ds_recv_data(dev, buf, len);
@@ -530,11 +532,11 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len)
{
int err;
struct ds_status st;
-
+
err = ds_send_data(dev, buf, len);
if (err < 0)
return err;
-
+
ds_wait_status(dev, &st);
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)
return err;
ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-
+
return !(err == len);
}
+#if 0
+
int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search)
{
int err;
@@ -559,11 +563,11 @@ int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int condi
struct ds_status st;
memset(buf, 0, sizeof(buf));
-
+
err = ds_send_data(ds_dev, (unsigned char *)&init, 8);
if (err)
return err;
-
+
ds_wait_status(ds_dev, &st);
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)
err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
if (err)
return err;
-
+
ds_wait_status(dev, &st);
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)
memcpy(buf, &init, 8);
buf[8] = BRANCH_MAIN;
-
+
err = ds_send_data(dev, buf, sizeof(buf));
if (err)
return err;
-
+
ds_wait_status(dev, &st);
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)
return 0;
}
-int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
+#endif /* 0 */
+
+static int ds_probe(struct usb_interface *intf,
+ const struct usb_device_id *udev_id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_endpoint_descriptor *endpoint;
@@ -653,7 +660,7 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err);
return err;
}
-
+
iface_desc = &intf->altsetting[0];
if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
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)
atomic_set(&ds_dev->refcnt, 0);
memset(ds_dev->ep, 0, sizeof(ds_dev->ep));
-
+
/*
- * This loop doesn'd show control 0 endpoint,
+ * This loop doesn'd show control 0 endpoint,
* so we will fill only 1-3 endpoints entry.
*/
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
ds_dev->ep[i+1] = endpoint->bEndpointAddress;
-
+
printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
}
-
+
#if 0
{
int err, i;
u64 buf[3];
u64 init=0xb30000002078ee81ull;
struct ds_status st;
-
+
ds_reset(ds_dev, &st);
err = ds_search(ds_dev, init, buf, 3, 0);
if (err < 0)
return err;
for (i=0; i<err; ++i)
printk("%d: %llx\n", i, buf[i]);
-
- printk("Resetting...\n");
+
+ printk("Resetting...\n");
ds_reset(ds_dev, &st);
printk("Setting path for %llx.\n", init);
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)
err = ds_search(ds_dev, init, buf, 3, 0);
printk("ds_search() returned %d\n", err);
-
+
if (err < 0)
return err;
for (i=0; i<err; ++i)
printk("%d: %llx\n", i, buf[i]);
-
+
return 0;
}
#endif
@@ -720,10 +727,10 @@ int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id)
return 0;
}
-void ds_disconnect(struct usb_interface *intf)
+static void ds_disconnect(struct usb_interface *intf)
{
struct ds_device *dev;
-
+
dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
@@ -740,7 +747,7 @@ void ds_disconnect(struct usb_interface *intf)
ds_dev = NULL;
}
-int ds_init(void)
+static int ds_init(void)
{
int err;
@@ -753,7 +760,7 @@ int ds_init(void)
return 0;
}
-void ds_fini(void)
+static void ds_fini(void)
{
usb_deregister(&ds_driver);
}
@@ -776,8 +783,8 @@ EXPORT_SYMBOL(ds_get_device);
EXPORT_SYMBOL(ds_put_device);
/*
- * This functions can be used for EEPROM programming,
- * when driver will be included into mainline this will
+ * This functions can be used for EEPROM programming,
+ * when driver will be included into mainline this will
* require uncommenting.
*/
#if 0
diff --git a/drivers/w1/dscore.h b/drivers/w1/dscore.h
index 9c767ef4ac2..6cf5671d6eb 100644
--- a/drivers/w1/dscore.h
+++ b/drivers/w1/dscore.h
@@ -1,8 +1,8 @@
/*
- * dscore.h
+ * dscore.h
*
* Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- *
+ *
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@
struct ds_device
{
- struct usb_device *udev;
+ struct usb_device *udev;
struct usb_interface *intf;
int ep[NUM_EP];
@@ -156,11 +156,7 @@ int ds_read_byte(struct ds_device *, u8 *);
int ds_read_bit(struct ds_device *, u8 *);
int ds_write_byte(struct ds_device *, u8);
int ds_write_bit(struct ds_device *, u8);
-int ds_start_pulse(struct ds_device *, int);
-int ds_set_speed(struct ds_device *, int);
int ds_reset(struct ds_device *, struct ds_status *);
-int ds_detect(struct ds_device *, struct ds_status *);
-int ds_stop_pulse(struct ds_device *, int);
struct ds_device * ds_get_device(void);
void ds_put_device(struct ds_device *);
int ds_write_block(struct ds_device *, u8 *, int);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 0bbf029b1ef..1b6b74c116a 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -45,10 +45,12 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
static int w1_timeout = 10;
+static int w1_control_timeout = 1;
int w1_max_slave_count = 10;
int w1_max_slave_ttl = 10;
module_param_named(timeout, w1_timeout, int, 0);
+module_param_named(control_timeout, w1_control_timeout, int, 0);
module_param_named(max_slave_count, w1_max_slave_count, int, 0);
module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
@@ -59,19 +61,6 @@ static pid_t control_thread;
static int control_needs_exit;
static DECLARE_COMPLETION(w1_control_complete);
-/* stuff for the default family */
-static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
- return(sprintf(buf, "%s\n", sl->name));
-}
-static struct w1_family_ops w1_default_fops = {
- .rname = &w1_famdefault_read_name,
-};
-static struct w1_family w1_default_family = {
- .fops = &w1_default_fops,
-};
-
static int w1_master_match(struct device *dev, struct device_driver *drv)
{
return 1;
@@ -82,73 +71,116 @@ static int w1_master_probe(struct device *dev)
return -ENODEV;
}
-static int w1_master_remove(struct device *dev)
-{
- return 0;
-}
-
static void w1_master_release(struct device *dev)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
- complete(&md->dev_released);
+ dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name);
+
+ if (md->nls && md->nls->sk_socket)
+ sock_release(md->nls->sk_socket);
+ memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
+ kfree(md);
}
static void w1_slave_release(struct device *dev)
{
- struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+ struct w1_slave *sl = dev_to_w1_slave(dev);
+
+ dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
+
+ while (atomic_read(&sl->refcnt)) {
+ dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
+ sl->name, atomic_read(&sl->refcnt));
+ if (msleep_interruptible(1000))
+ flush_signals(current);
+ }
+
+ w1_family_put(sl->family);
+ sl->master->slave_count--;
- complete(&sl->dev_released);
+ complete(&sl->released);
}
-static ssize_t w1_default_read_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "No family registered.\n");
+ struct w1_slave *sl = dev_to_w1_slave(dev);
+
+ return sprintf(buf, "%s\n", sl->name);
}
-static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off,
- size_t count)
+static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
{
- return sprintf(buf, "No family registered.\n");
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+
+ atomic_inc(&sl->refcnt);
+ if (off > 8) {
+ count = 0;
+ } else {
+ if (off + count > 8)
+ count = 8 - off;
+
+ memcpy(buf, (u8 *)&sl->reg_num, count);
+ }
+ atomic_dec(&sl->refcnt);
+
+ return count;
}
-static struct device_attribute w1_slave_attribute =
- __ATTR(name, S_IRUGO, w1_default_read_name, NULL);
-
-static struct bin_attribute w1_slave_bin_attribute = {
- .attr = {
- .name = "w1_slave",
- .mode = S_IRUGO,
- .owner = THIS_MODULE,
- },
- .size = W1_SLAVE_DATA_SIZE,
- .read = &w1_default_read_bin,
+static struct device_attribute w1_slave_attr_name =
+ __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
+
+static struct bin_attribute w1_slave_attr_bin_id = {
+ .attr = {
+ .name = "id",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = 8,
+ .read = w1_slave_read_id,
};
+/* Default family */
+static struct w1_family w1_default_family;
+
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
static struct bus_type w1_bus_type = {
.name = "w1",
.match = w1_master_match,
+ .hotplug = w1_hotplug,
};
-struct device_driver w1_driver = {
- .name = "w1_driver",
+struct device_driver w1_master_driver = {
+ .name = "w1_master_driver",
.bus = &w1_bus_type,
.probe = w1_master_probe,
- .remove = w1_master_remove,
};
-struct device w1_device = {
+struct device w1_master_device = {
.parent = NULL,
.bus = &w1_bus_type,
.bus_id = "w1 bus master",
- .driver = &w1_driver,
+ .driver = &w1_master_driver,
.release = &w1_master_release
};
+struct device_driver w1_slave_driver = {
+ .name = "w1_slave_driver",
+ .bus = &w1_bus_type,
+};
+
+struct device w1_slave_device = {
+ .parent = NULL,
+ .bus = &w1_bus_type,
+ .bus_id = "w1 bus slave",
+ .driver = &w1_slave_driver,
+ .release = &w1_slave_release
+};
+
static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible (&md->mutex))
@@ -165,7 +197,7 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
if (down_interruptible (&md->mutex))
return -EBUSY;
@@ -181,7 +213,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible (&md->mutex))
@@ -196,7 +228,7 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible(&md->mutex))
@@ -217,7 +249,7 @@ static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct devic
static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible(&md->mutex))
@@ -231,7 +263,7 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru
static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible(&md->mutex))
@@ -245,7 +277,7 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi
static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;
if (down_interruptible(&md->mutex))
@@ -259,7 +291,7 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct w1_master *md = container_of(dev, struct w1_master, dev);
+ struct w1_master *md = dev_to_w1_master(dev);
int c = PAGE_SIZE;
if (down_interruptible(&md->mutex))
@@ -329,12 +361,55 @@ void w1_destroy_master_attributes(struct w1_master *master)
sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
}
+#ifdef CONFIG_HOTPLUG
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+ struct w1_master *md = NULL;
+ struct w1_slave *sl = NULL;
+ char *event_owner, *name;
+ int err, cur_index=0, cur_len=0;
+
+ if (dev->driver == &w1_master_driver) {
+ md = container_of(dev, struct w1_master, dev);
+ event_owner = "master";
+ name = md->name;
+ } else if (dev->driver == &w1_slave_driver) {
+ sl = container_of(dev, struct w1_slave, dev);
+ event_owner = "slave";
+ name = sl->name;
+ } else {
+ dev_dbg(dev, "Unknown hotplug event.\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id);
+
+ if (dev->driver != &w1_slave_driver || !sl)
+ return 0;
+
+ err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
+ if (err)
+ return err;
+
+ err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
+ if (err)
+ return err;
+
+ return 0;
+};
+#else
+static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+{
+ return 0;
+}
+#endif
+
static int __w1_attach_slave_device(struct w1_slave *sl)
{
int err;
sl->dev.parent = &sl->master->dev;
- sl->dev.driver = sl->master->driver;
+ sl->dev.driver = &w1_slave_driver;
sl->dev.bus = &w1_bus_type;
sl->dev.release = &w1_slave_release;
@@ -347,8 +422,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
(unsigned int) sl->reg_num.family,
(unsigned long long) sl->reg_num.id);
- dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,
- &sl->dev.bus_id[0]);
+ dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]);
err = device_register(&sl->dev);
if (err < 0) {
@@ -358,36 +432,44 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
return err;
}
- memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));
- memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));
-
- sl->attr_bin.read = sl->family->fops->rbin;
- sl->attr_name.show = sl->family->fops->rname;
+ /* Create "name" entry */
+ err = device_create_file(&sl->dev, &w1_slave_attr_name);
+ if (err < 0) {
+ dev_err(&sl->dev,
+ "sysfs file creation for [%s] failed. err=%d\n",
+ sl->dev.bus_id, err);
+ goto out_unreg;
+ }
- err = device_create_file(&sl->dev, &sl->attr_name);
+ /* Create "id" entry */
+ err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
if (err < 0) {
dev_err(&sl->dev,
"sysfs file creation for [%s] failed. err=%d\n",
sl->dev.bus_id, err);
- device_unregister(&sl->dev);
- return err;
+ goto out_rem1;
}
- if ( sl->attr_bin.read ) {
- err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);
- if (err < 0) {
- dev_err(&sl->dev,
- "sysfs file creation for [%s] failed. err=%d\n",
- sl->dev.bus_id, err);
- device_remove_file(&sl->dev, &sl->attr_name);
- device_unregister(&sl->dev);
- return err;
- }
+ /* if the family driver needs to initialize something... */
+ if (sl->family->fops && sl->family->fops->add_slave &&
+ ((err = sl->family->fops->add_slave(sl)) < 0)) {
+ dev_err(&sl->dev,
+ "sysfs file creation for [%s] failed. err=%d\n",
+ sl->dev.bus_id, err);
+ goto out_rem2;
}
list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
return 0;
+
+out_rem2:
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+out_rem1:
+ device_remove_file(&sl->dev, &w1_slave_attr_name);
+out_unreg:
+ device_unregister(&sl->dev);
+ return err;
}
static 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)
memcpy(&sl->reg_num, rn, sizeof(sl->reg_num));
atomic_set(&sl->refcnt, 0);
- init_completion(&sl->dev_released);
+ init_completion(&sl->released);
spin_lock(&w1_flock);
f = w1_family_registered(rn->family);
@@ -452,28 +534,23 @@ static void w1_slave_detach(struct w1_slave *sl)
{
struct w1_netlink_msg msg;
- dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);
-
- while (atomic_read(&sl->refcnt)) {
- printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
- sl->name, atomic_read(&sl->refcnt));
+ dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl);
- if (msleep_interruptible(1000))
- flush_signals(current);
- }
-
- if ( sl->attr_bin.read ) {
- sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
- }
- device_remove_file(&sl->dev, &sl->attr_name);
- device_unregister(&sl->dev);
- w1_family_put(sl->family);
+ list_del(&sl->w1_slave_entry);
- sl->master->slave_count--;
+ if (sl->family->fops && sl->family->fops->remove_slave)
+ sl->family->fops->remove_slave(sl);
memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
msg.type = W1_SLAVE_REMOVE;
w1_netlink_send(sl->master, &msg);
+
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+ device_remove_file(&sl->dev, &w1_slave_attr_name);
+ device_unregister(&sl->dev);
+
+ wait_for_completion(&sl->released);
+ kfree(sl);
}
static struct w1_master *w1_search_master(unsigned long data)
@@ -500,14 +577,13 @@ void w1_reconnect_slaves(struct w1_family *f)
spin_lock_bh(&w1_mlock);
list_for_each_entry(dev, &w1_masters, w1_master_entry) {
- dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
+ dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
dev->name, f->fid);
set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
}
spin_unlock_bh(&w1_mlock);
}
-
static void w1_slave_found(unsigned long data, u64 rn)
{
int slave_count;
@@ -646,7 +722,7 @@ static int w1_control(void *data)
have_to_wait = 0;
try_to_freeze();
- msleep_interruptible(w1_timeout * 1000);
+ msleep_interruptible(w1_control_timeout * 1000);
if (signal_pending(current))
flush_signals(current);
@@ -679,33 +755,30 @@ static int w1_control(void *data)
list_del(&dev->w1_master_entry);
spin_unlock_bh(&w1_mlock);
+ down(&dev->mutex);
list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
- list_del(&sl->w1_slave_entry);
-
w1_slave_detach(sl);
- kfree(sl);
}
w1_destroy_master_attributes(dev);
+ up(&dev->mutex);
atomic_dec(&dev->refcnt);
continue;
}
if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
- dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
+ dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
down(&dev->mutex);
- list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
if (sl->family->fid == W1_FAMILY_DEFAULT) {
struct w1_reg_num rn;
- list_del(&sl->w1_slave_entry);
- w1_slave_detach(sl);
memcpy(&rn, &sl->reg_num, sizeof(rn));
-
- kfree(sl);
+ w1_slave_detach(sl);
w1_attach_slave_device(dev, &rn);
}
}
+ dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
up(&dev->mutex);
}
@@ -749,10 +822,7 @@ int w1_process(void *data)
list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
- list_del (&sl->w1_slave_entry);
-
- w1_slave_detach (sl);
- kfree (sl);
+ w1_slave_detach(sl);
dev->slave_count--;
} else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
@@ -783,7 +853,7 @@ static int w1_init(void)
goto err_out_exit_init;
}
- retval = driver_register(&w1_driver);
+ retval = driver_register(&w1_master_driver);
if (retval) {
printk(KERN_ERR
"Failed to register master driver. err=%d.\n",
@@ -791,18 +861,29 @@ static int w1_init(void)
goto err_out_bus_unregister;
}
+ retval = driver_register(&w1_slave_driver);
+ if (retval) {
+ printk(KERN_ERR
+ "Failed to register master driver. err=%d.\n",
+ retval);
+ goto err_out_master_unregister;
+ }
+
control_thread = kernel_thread(&w1_control, NULL, 0);
if (control_thread < 0) {
printk(KERN_ERR "Failed to create control thread. err=%d\n",
control_thread);
retval = control_thread;
- goto err_out_driver_unregister;
+ goto err_out_slave_unregister;
}
return 0;
-err_out_driver_unregister:
- driver_unregister(&w1_driver);
+err_out_slave_unregister:
+ driver_unregister(&w1_slave_driver);
+
+err_out_master_unregister:
+ driver_unregister(&w1_master_driver);
err_out_bus_unregister:
bus_unregister(&w1_bus_type);
@@ -821,7 +902,8 @@ static void w1_fini(void)
control_needs_exit = 1;
wait_for_completion(&w1_control_complete);
- driver_unregister(&w1_driver);
+ driver_unregister(&w1_slave_driver);
+ driver_unregister(&w1_master_driver);
bus_unregister(&w1_bus_type);
}
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index 4f0a986e33e..d8900780c3b 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -75,11 +75,9 @@ struct w1_slave
struct w1_master *master;
struct w1_family *family;
+ void *family_data;
struct device dev;
- struct completion dev_released;
-
- struct bin_attribute attr_bin;
- struct device_attribute attr_name;
+ struct completion released;
};
typedef void (* w1_slave_found_callback)(unsigned long, u64);
@@ -179,7 +177,6 @@ struct w1_master
struct device_driver *driver;
struct device dev;
- struct completion dev_released;
struct completion dev_exited;
struct w1_bus_master *bus_master;
@@ -191,6 +188,21 @@ struct w1_master
int w1_create_master_attributes(struct w1_master *);
void w1_search(struct w1_master *dev, w1_slave_found_callback cb);
+static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
+{
+ return container_of(dev, struct w1_slave, dev);
+}
+
+static inline struct w1_slave* kobj_to_w1_slave(struct kobject *kobj)
+{
+ return dev_to_w1_slave(container_of(kobj, struct device, kobj));
+}
+
+static inline struct w1_master* dev_to_w1_master(struct device *dev)
+{
+ return container_of(dev, struct w1_master, dev);
+}
+
#endif /* __KERNEL__ */
#endif /* __W1_H */
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
new file mode 100644
index 00000000000..b7c24b34d27
--- /dev/null
+++ b/drivers/w1/w1_ds2433.c
@@ -0,0 +1,327 @@
+/*
+ * w1_ds2433.c - w1 family 23 (DS2433) driver
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#ifdef CONFIG_W1_F23_CRC
+#include <linux/crc16.h>
+#endif
+
+#include "w1.h"
+#include "w1_io.h"
+#include "w1_int.h"
+#include "w1_family.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("w1 family 23 driver for DS2433, 4kb EEPROM");
+
+#define W1_EEPROM_SIZE 512
+#define W1_PAGE_COUNT 16
+#define W1_PAGE_SIZE 32
+#define W1_PAGE_BITS 5
+#define W1_PAGE_MASK 0x1F
+
+#define W1_F23_TIME 300
+
+#define W1_F23_READ_EEPROM 0xF0
+#define W1_F23_WRITE_SCRATCH 0x0F
+#define W1_F23_READ_SCRATCH 0xAA
+#define W1_F23_COPY_SCRATCH 0x55
+
+struct w1_f23_data {
+ u8 memory[W1_EEPROM_SIZE];
+ u32 validcrc;
+};
+
+/**
+ * Check the file size bounds and adjusts count as needed.
+ * This would not be needed if the file size didn't reset to 0 after a write.
+ */
+static inline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size)
+{
+ if (off > size)
+ return 0;
+
+ if ((off + count) > size)
+ return (size - off);
+
+ return count;
+}
+
+#ifdef CONFIG_W1_F23_CRC
+static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data,
+ int block)
+{
+ u8 wrbuf[3];
+ int off = block * W1_PAGE_SIZE;
+
+ if (data->validcrc & (1 << block))
+ return 0;
+
+ if (w1_reset_select_slave(sl)) {
+ data->validcrc = 0;
+ return -EIO;
+ }
+
+ wrbuf[0] = W1_F23_READ_EEPROM;
+ wrbuf[1] = off & 0xff;
+ wrbuf[2] = off >> 8;
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
+
+ /* cache the block if the CRC is valid */
+ if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
+ data->validcrc |= (1 << block);
+
+ return 0;
+}
+#endif /* CONFIG_W1_F23_CRC */
+
+static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+#ifdef CONFIG_W1_F23_CRC
+ struct w1_f23_data *data = sl->family_data;
+ int i, min_page, max_page;
+#else
+ u8 wrbuf[3];
+#endif
+
+ if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
+ return 0;
+
+ atomic_inc(&sl->refcnt);
+ if (down_interruptible(&sl->master->mutex)) {
+ count = 0;
+ goto out_dec;
+ }
+
+#ifdef CONFIG_W1_F23_CRC
+
+ min_page = (off >> W1_PAGE_BITS);
+ max_page = (off + count - 1) >> W1_PAGE_BITS;
+ for (i = min_page; i <= max_page; i++) {
+ if (w1_f23_refresh_block(sl, data, i)) {
+ count = -EIO;
+ goto out_up;
+ }
+ }
+ memcpy(buf, &data->memory[off], count);
+
+#else /* CONFIG_W1_F23_CRC */
+
+ /* read directly from the EEPROM */
+ if (w1_reset_select_slave(sl)) {
+ count = -EIO;
+ goto out_up;
+ }
+
+ wrbuf[0] = W1_F23_READ_EEPROM;
+ wrbuf[1] = off & 0xff;
+ wrbuf[2] = off >> 8;
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_read_block(sl->master, buf, count);
+
+#endif /* CONFIG_W1_F23_CRC */
+
+out_up:
+ up(&sl->master->mutex);
+out_dec:
+ atomic_dec(&sl->refcnt);
+
+ return count;
+}
+
+/**
+ * Writes to the scratchpad and reads it back for verification.
+ * Then copies the scratchpad to EEPROM.
+ * The data must be on one page.
+ * The master must be locked.
+ *
+ * @param sl The slave structure
+ * @param addr Address for the write
+ * @param len length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
+ * @param data The data to write
+ * @return 0=Success -1=failure
+ */
+static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
+{
+ u8 wrbuf[4];
+ u8 rdbuf[W1_PAGE_SIZE + 3];
+ u8 es = (addr + len - 1) & 0x1f;
+
+ /* Write the data to the scratchpad */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ wrbuf[0] = W1_F23_WRITE_SCRATCH;
+ wrbuf[1] = addr & 0xff;
+ wrbuf[2] = addr >> 8;
+
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_write_block(sl->master, data, len);
+
+ /* Read the scratchpad and verify */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ w1_write_8(sl->master, W1_F23_READ_SCRATCH);
+ w1_read_block(sl->master, rdbuf, len + 3);
+
+ /* Compare what was read against the data written */
+ if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
+ (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
+ return -1;
+
+ /* Copy the scratchpad to EEPROM */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ wrbuf[0] = W1_F23_COPY_SCRATCH;
+ wrbuf[3] = es;
+ w1_write_block(sl->master, wrbuf, 4);
+
+ /* Sleep for 5 ms to wait for the write to complete */
+ msleep(5);
+
+ /* Reset the bus to wake up the EEPROM (this may not be needed) */
+ w1_reset_bus(sl->master);
+
+ return 0;
+}
+
+static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+ int addr, len, idx;
+
+ if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0)
+ return 0;
+
+#ifdef CONFIG_W1_F23_CRC
+ /* can only write full blocks in cached mode */
+ if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
+ dev_err(&sl->dev, "invalid offset/count off=%d cnt=%d\n",
+ (int)off, count);
+ return -EINVAL;
+ }
+
+ /* make sure the block CRCs are valid */
+ for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
+ if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) != CRC16_VALID) {
+ dev_err(&sl->dev, "bad CRC at offset %d\n", (int)off);
+ return -EINVAL;
+ }
+ }
+#endif /* CONFIG_W1_F23_CRC */
+
+ atomic_inc(&sl->refcnt);
+ if (down_interruptible(&sl->master->mutex)) {
+ count = 0;
+ goto out_dec;
+ }
+
+ /* Can only write data to one page at a time */
+ idx = 0;
+ while (idx < count) {
+ addr = off + idx;
+ len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
+ if (len > (count - idx))
+ len = count - idx;
+
+ if (w1_f23_write(sl, addr, len, &buf[idx]) < 0) {
+ count = -EIO;
+ goto out_up;
+ }
+ idx += len;
+ }
+
+out_up:
+ up(&sl->master->mutex);
+out_dec:
+ atomic_dec(&sl->refcnt);
+
+ return count;
+}
+
+static struct bin_attribute w1_f23_bin_attr = {
+ .attr = {
+ .name = "eeprom",
+ .mode = S_IRUGO | S_IWUSR,
+ .owner = THIS_MODULE,
+ },
+ .size = W1_EEPROM_SIZE,
+ .read = w1_f23_read_bin,
+ .write = w1_f23_write_bin,
+};
+
+static int w1_f23_add_slave(struct w1_slave *sl)
+{
+ int err;
+#ifdef CONFIG_W1_F23_CRC
+ struct w1_f23_data *data;
+
+ data = kmalloc(sizeof(struct w1_f23_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ memset(data, 0, sizeof(struct w1_f23_data));
+ sl->family_data = data;
+
+#endif /* CONFIG_W1_F23_CRC */
+
+ err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
+
+#ifdef CONFIG_W1_F23_CRC
+ if (err)
+ kfree(data);
+#endif /* CONFIG_W1_F23_CRC */
+
+ return err;
+}
+
+static void w1_f23_remove_slave(struct w1_slave *sl)
+{
+#ifdef CONFIG_W1_F23_CRC
+ if (sl->family_data) {
+ kfree(sl->family_data);
+ sl->family_data = NULL;
+ }
+#endif /* CONFIG_W1_F23_CRC */
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
+}
+
+static struct w1_family_ops w1_f23_fops = {
+ .add_slave = w1_f23_add_slave,
+ .remove_slave = w1_f23_remove_slave,
+};
+
+static struct w1_family w1_family_23 = {
+ .fid = W1_EEPROM_DS2433,
+ .fops = &w1_f23_fops,
+};
+
+static int __init w1_f23_init(void)
+{
+ return w1_register_family(&w1_family_23);
+}
+
+static void __exit w1_f23_fini(void)
+{
+ w1_unregister_family(&w1_family_23);
+}
+
+module_init(w1_f23_init);
+module_exit(w1_f23_fini);
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index 02eee57d3c0..88c517a4c17 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -29,23 +29,12 @@ DEFINE_SPINLOCK(w1_flock);
static LIST_HEAD(w1_families);
extern void w1_reconnect_slaves(struct w1_family *f);
-static int w1_check_family(struct w1_family *f)
-{
- if (!f->fops->rname || !f->fops->rbin)
- return -EINVAL;
-
- return 0;
-}
-
int w1_register_family(struct w1_family *newf)
{
struct list_head *ent, *n;
struct w1_family *f;
int ret = 0;
- if (w1_check_family(newf))
- return -EINVAL;
-
spin_lock(&w1_flock);
list_for_each_safe(ent, n, &w1_families) {
f = list_entry(ent, struct w1_family, family_entry);
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index b26da01bbc3..2ca0489c716 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -31,14 +31,17 @@
#define W1_FAMILY_SMEM_81 0x81
#define W1_THERM_DS18S20 0x10
#define W1_THERM_DS1822 0x22
+#define W1_EEPROM_DS2433 0x23
#define W1_THERM_DS18B20 0x28
#define MAXNAMELEN 32
+struct w1_slave;
+
struct w1_family_ops
{
- ssize_t (* rname)(struct device *, struct device_attribute *, char *);
- ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
+ int (* add_slave)(struct w1_slave *);
+ void (* remove_slave)(struct w1_slave *);
};
struct w1_family
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 498ad505fa5..c3f67eafc7e 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -29,9 +29,9 @@
static u32 w1_ids = 1;
-extern struct device_driver w1_driver;
+extern struct device_driver w1_master_driver;
extern struct bus_type w1_bus_type;
-extern struct device w1_device;
+extern struct device w1_master_device;
extern int w1_max_slave_count;
extern int w1_max_slave_ttl;
extern struct list_head w1_masters;
@@ -76,7 +76,6 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
INIT_LIST_HEAD(&dev->slist);
init_MUTEX(&dev->mutex);
- init_completion(&dev->dev_released);
init_completion(&dev->dev_exited);
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,
dev->groups = 1;
dev->seq = 1;
- dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
- if (!dev->nls) {
- printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
- NETLINK_NFLOG, dev->dev.bus_id);
- }
+ dev_init_netlink(dev);
err = device_register(&dev->dev);
if (err) {
printk(KERN_ERR "Failed to register master device. err=%d\n", err);
- if (dev->nls && dev->nls->sk_socket)
- sock_release(dev->nls->sk_socket);
+
+ dev_fini_netlink(dev);
+
memset(dev, 0, sizeof(struct w1_master));
kfree(dev);
dev = NULL;
@@ -107,13 +103,9 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
return dev;
}
-static void w1_free_dev(struct w1_master *dev)
+void w1_free_dev(struct w1_master *dev)
{
device_unregister(&dev->dev);
- if (dev->nls && dev->nls->sk_socket)
- sock_release(dev->nls->sk_socket);
- memset(dev, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
- kfree(dev);
}
int w1_add_master_device(struct w1_bus_master *master)
@@ -129,7 +121,7 @@ int w1_add_master_device(struct w1_bus_master *master)
return(-EINVAL);
}
- dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
+ dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
if (!dev)
return -ENOMEM;
@@ -188,7 +180,7 @@ void __w1_remove_master_device(struct w1_master *dev)
__func__, dev->kpid);
while (atomic_read(&dev->refcnt)) {
- printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
+ dev_dbg(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
dev->name, atomic_read(&dev->refcnt));
if (msleep_interruptible(1000))
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 00f03222017..e2a043354dd 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)
w1_search(dev, cb);
}
+/**
+ * Resets the bus and then selects the slave by sending either a skip rom
+ * or a rom match.
+ * The w1 master lock must be held.
+ *
+ * @param sl the slave to select
+ * @return 0=success, anything else=error
+ */
+int w1_reset_select_slave(struct w1_slave *sl)
+{
+ if (w1_reset_bus(sl->master))
+ return -1;
+
+ if (sl->master->slave_count == 1)
+ w1_write_8(sl->master, W1_SKIP_ROM);
+ else {
+ u8 match[9] = {W1_MATCH_ROM, };
+ memcpy(&match[1], (u8 *)&sl->reg_num, 8);
+ w1_write_block(sl->master, match, 9);
+ }
+ return 0;
+}
+
EXPORT_SYMBOL(w1_touch_bit);
EXPORT_SYMBOL(w1_write_8);
EXPORT_SYMBOL(w1_read_8);
@@ -286,3 +309,4 @@ EXPORT_SYMBOL(w1_delay);
EXPORT_SYMBOL(w1_read_block);
EXPORT_SYMBOL(w1_write_block);
EXPORT_SYMBOL(w1_search_devices);
+EXPORT_SYMBOL(w1_reset_select_slave);
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
index af5829778aa..232860184a2 100644
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -34,5 +34,6 @@ u8 w1_calc_crc8(u8 *, int);
void w1_write_block(struct w1_master *, const u8 *, int);
u8 w1_read_block(struct w1_master *, u8 *, int);
void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
+int w1_reset_select_slave(struct w1_slave *sl);
#endif /* __W1_IO_H */
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index e7b774423dd..328645da797 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)
nlmsg_failure:
return;
}
+
+int dev_init_netlink(struct w1_master *dev)
+{
+ dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
+ if (!dev->nls) {
+ printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
+ NETLINK_W1, dev->dev.bus_id);
+ }
+
+ return 0;
+}
+
+void dev_fini_netlink(struct w1_master *dev)
+{
+ if (dev->nls && dev->nls->sk_socket)
+ sock_release(dev->nls->sk_socket);
+}
#else
#warning Netlink support is disabled. Please compile with NET support enabled.
void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
{
}
+
+int dev_init_netlink(struct w1_master *dev)
+{
+ return 0;
+}
+
+void dev_fini_netlink(struct w1_master *dev)
+{
+}
#endif
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
index 8615756946d..eb0c8b3152c 100644
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -52,6 +52,8 @@ struct w1_netlink_msg
#ifdef __KERNEL__
void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *);
+int dev_init_netlink(struct w1_master *dev);
+void dev_fini_netlink(struct w1_master *dev);
#endif /* __KERNEL__ */
#endif /* __W1_NETLINK_H */
diff --git a/drivers/w1/w1_smem.c b/drivers/w1/w1_smem.c
index 70d2d469963..e3209d0aca9 100644
--- a/drivers/w1/w1_smem.c
+++ b/drivers/w1/w1_smem.c
@@ -36,61 +36,12 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
-static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
-static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
-
-static struct w1_family_ops w1_smem_fops = {
- .rname = &w1_smem_read_name,
- .rbin = &w1_smem_read_bin,
-};
-
-static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
- return sprintf(buf, "%s\n", sl->name);
-}
-
-static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
-{
- struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
- struct w1_slave, dev);
- int i;
-
- atomic_inc(&sl->refcnt);
- if (down_interruptible(&sl->master->mutex)) {
- count = 0;
- goto out_dec;
- }
-
- if (off > W1_SLAVE_DATA_SIZE) {
- count = 0;
- goto out;
- }
- if (off + count > W1_SLAVE_DATA_SIZE) {
- count = 0;
- goto out;
- }
- for (i = 0; i < 8; ++i)
- count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
- count += sprintf(buf + count, "\n");
-
-out:
- up(&sl->master->mutex);
-out_dec:
- atomic_dec(&sl->refcnt);
-
- return count;
-}
-
static struct w1_family w1_smem_family_01 = {
.fid = W1_FAMILY_SMEM_01,
- .fops = &w1_smem_fops,
};
static struct w1_family w1_smem_family_81 = {
.fid = W1_FAMILY_SMEM_81,
- .fops = &w1_smem_fops,
};
static int __init w1_smem_init(void)
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
index 165526c9360..4577df3cfc4 100644
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -42,12 +42,31 @@ static u8 bad_roms[][9] = {
{}
};
-static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
+static struct bin_attribute w1_therm_bin_attr = {
+ .attr = {
+ .name = "w1_slave",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = W1_SLAVE_DATA_SIZE,
+ .read = w1_therm_read_bin,
+};
+
+static int w1_therm_add_slave(struct w1_slave *sl)
+{
+ return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+}
+
+static void w1_therm_remove_slave(struct w1_slave *sl)
+{
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+}
+
static struct w1_family_ops w1_therm_fops = {
- .rname = &w1_therm_read_name,
- .rbin = &w1_therm_read_bin,
+ .add_slave = w1_therm_add_slave,
+ .remove_slave = w1_therm_remove_slave,
};
static struct w1_family w1_therm_family_DS18S20 = {
@@ -59,6 +78,7 @@ static struct w1_family w1_therm_family_DS18B20 = {
.fid = W1_THERM_DS18B20,
.fops = &w1_therm_fops,
};
+
static struct w1_family w1_therm_family_DS1822 = {
.fid = W1_THERM_DS1822,
.fops = &w1_therm_fops,
@@ -90,13 +110,6 @@ static struct w1_therm_family_converter w1_therm_families[] = {
},
};
-static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
- return sprintf(buf, "%s\n", sl->name);
-}
-
static inline int w1_DS18B20_convert_temp(u8 rom[9])
{
int t = (rom[1] << 8) | rom[0];
@@ -148,8 +161,7 @@ static int w1_therm_check_rom(u8 rom[9])
static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
{
- struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
- struct w1_slave, dev);
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
struct w1_master *dev = sl->master;
u8 rom[9], crc, verdict;
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
crc = 0;
while (max_trying--) {
- if (!w1_reset_bus (dev)) {
+ if (!w1_reset_select_slave(sl)) {
int count = 0;
- u8 match[9] = {W1_MATCH_ROM, };
unsigned int tm = 750;
- memcpy(&match[1], (u64 *) & sl->reg_num, 8);
-
- w1_write_block(dev, match, 9);
-
w1_write_8(dev, W1_CONVERT_TEMP);
while (tm) {
@@ -195,8 +202,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
flush_signals(current);
}
- if (!w1_reset_bus (dev)) {
- w1_write_block(dev, match, 9);
+ if (!w1_reset_select_slave(sl)) {
w1_write_8(dev, W1_READ_SCRATCHPAD);
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
if (rom[8] == crc && rom[0])
verdict = 1;
-
}
}
diff --git a/fs/9p/9p.c b/fs/9p/9p.c
new file mode 100644
index 00000000000..e847f504a47
--- /dev/null
+++ b/fs/9p/9p.c
@@ -0,0 +1,359 @@
+/*
+ * linux/fs/9p/9p.c
+ *
+ * This file contains functions 9P2000 functions
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "mux.h"
+
+/**
+ * v9fs_t_version - negotiate protocol parameters with sever
+ * @v9ses: 9P2000 session information
+ * @msize: requested max size packet
+ * @version: requested version.extension string
+ * @fcall: pointer to response fcall pointer
+ *
+ */
+
+int
+v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
+ char *version, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version);
+ msg.id = TVERSION;
+ msg.params.tversion.msize = msize;
+ msg.params.tversion.version = version;
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_attach - mount the server
+ * @v9ses: 9P2000 session information
+ * @uname: user name doing the attach
+ * @aname: remote name being attached to
+ * @fid: mount fid to attatch to root node
+ * @afid: authentication fid (in this case result key)
+ * @fcall: pointer to response fcall pointer
+ *
+ */
+
+int
+v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
+ u32 fid, u32 afid, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname,
+ aname, fid, afid);
+ msg.id = TATTACH;
+ msg.params.tattach.fid = fid;
+ msg.params.tattach.afid = afid;
+ msg.params.tattach.uname = uname;
+ msg.params.tattach.aname = aname;
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_clunk - release a fid (finish a transaction)
+ * @v9ses: 9P2000 session information
+ * @fid: fid to release
+ * @fcall: pointer to response fcall pointer
+ *
+ */
+
+int
+v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d\n", fid);
+ msg.id = TCLUNK;
+ msg.params.tclunk.fid = fid;
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_v9fs_t_flush - flush a pending transaction
+ * @v9ses: 9P2000 session information
+ * @tag: tid to release
+ *
+ */
+
+int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "oldtag %d\n", tag);
+ msg.id = TFLUSH;
+ msg.params.tflush.oldtag = tag;
+ return v9fs_mux_rpc(v9ses, &msg, NULL);
+}
+
+/**
+ * v9fs_t_stat - read a file's meta-data
+ * @v9ses: 9P2000 session information
+ * @fid: fid pointing to file or directory to get info about
+ * @fcall: pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d\n", fid);
+ if (fcall)
+ *fcall = NULL;
+
+ msg.id = TSTAT;
+ msg.params.tstat.fid = fid;
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_wstat - write a file's meta-data
+ * @v9ses: 9P2000 session information
+ * @fid: fid pointing to file or directory to write info about
+ * @stat: metadata
+ * @fcall: pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_stat *stat, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length);
+ msg.id = TWSTAT;
+ msg.params.twstat.fid = fid;
+ msg.params.twstat.stat = stat;
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_walk - walk a fid to a new file or directory
+ * @v9ses: 9P2000 session information
+ * @fid: fid to walk
+ * @newfid: new fid (for clone operations)
+ * @name: path to walk fid to
+ * @fcall: pointer to response fcall
+ *
+ */
+
+/* TODO: support multiple walk */
+
+int
+v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
+ char *name, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name);
+ msg.id = TWALK;
+ msg.params.twalk.fid = fid;
+ msg.params.twalk.newfid = newfid;
+
+ if (name) {
+ msg.params.twalk.nwname = 1;
+ msg.params.twalk.wnames = &name;
+ } else {
+ msg.params.twalk.nwname = 0;
+ }
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_open - open a file
+ *
+ * @v9ses - 9P2000 session information
+ * @fid - fid to open
+ * @mode - mode to open file (R, RW, etc)
+ * @fcall - pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
+ struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+ long errorno = -1;
+
+ dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode);
+ msg.id = TOPEN;
+ msg.params.topen.fid = fid;
+ msg.params.topen.mode = mode;
+
+ errorno = v9fs_mux_rpc(v9ses, &msg, fcall);
+
+ return errorno;
+}
+
+/**
+ * v9fs_t_remove - remove a file or directory
+ * @v9ses: 9P2000 session information
+ * @fid: fid to remove
+ * @fcall: pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d\n", fid);
+ msg.id = TREMOVE;
+ msg.params.tremove.fid = fid;
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_create - create a file or directory
+ * @v9ses: 9P2000 session information
+ * @fid: fid to create
+ * @name: name of the file or directory to create
+ * @perm: permissions to create with
+ * @mode: mode to open file (R, RW, etc)
+ * @fcall: pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
+ u32 perm, u8 mode, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+
+ dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
+ fid, name, perm, mode);
+
+ msg.id = TCREATE;
+ msg.params.tcreate.fid = fid;
+ msg.params.tcreate.name = name;
+ msg.params.tcreate.perm = perm;
+ msg.params.tcreate.mode = mode;
+
+ return v9fs_mux_rpc(v9ses, &msg, fcall);
+}
+
+/**
+ * v9fs_t_read - read data
+ * @v9ses: 9P2000 session information
+ * @fid: fid to read from
+ * @offset: offset to start read at
+ * @count: how many bytes to read
+ * @fcall: pointer to response fcall (with data)
+ *
+ */
+
+int
+v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
+ u32 count, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+ struct v9fs_fcall *rc = NULL;
+ long errorno = -1;
+
+ dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid,
+ (long unsigned int)offset, count);
+ msg.id = TREAD;
+ msg.params.tread.fid = fid;
+ msg.params.tread.offset = offset;
+ msg.params.tread.count = count;
+ errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
+
+ if (!errorno) {
+ errorno = rc->params.rread.count;
+ dump_data(rc->params.rread.data, rc->params.rread.count);
+ }
+
+ if (fcall)
+ *fcall = rc;
+ else
+ kfree(rc);
+
+ return errorno;
+}
+
+/**
+ * v9fs_t_write - write data
+ * @v9ses: 9P2000 session information
+ * @fid: fid to write to
+ * @offset: offset to start write at
+ * @count: how many bytes to write
+ * @fcall: pointer to response fcall
+ *
+ */
+
+int
+v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid,
+ u64 offset, u32 count, void *data, struct v9fs_fcall **fcall)
+{
+ struct v9fs_fcall msg;
+ struct v9fs_fcall *rc = NULL;
+ long errorno = -1;
+
+ dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid,
+ (unsigned long long)offset, count);
+ dump_data(data, count);
+
+ msg.id = TWRITE;
+ msg.params.twrite.fid = fid;
+ msg.params.twrite.offset = offset;
+ msg.params.twrite.count = count;
+ msg.params.twrite.data = data;
+
+ errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
+
+ if (!errorno)
+ errorno = rc->params.rwrite.count;
+
+ if (fcall)
+ *fcall = rc;
+ else
+ kfree(rc);
+
+ return errorno;
+}
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
new file mode 100644
index 00000000000..f55424216be
--- /dev/null
+++ b/fs/9p/9p.h
@@ -0,0 +1,341 @@
+/*
+ * linux/fs/9p/9p.h
+ *
+ * 9P protocol definitions.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+/* Message Types */
+enum {
+ TVERSION = 100,
+ RVERSION,
+ TAUTH = 102,
+ RAUTH,
+ TATTACH = 104,
+ RATTACH,
+ TERROR = 106,
+ RERROR,
+ TFLUSH = 108,
+ RFLUSH,
+ TWALK = 110,
+ RWALK,
+ TOPEN = 112,
+ ROPEN,
+ TCREATE = 114,
+ RCREATE,
+ TREAD = 116,
+ RREAD,
+ TWRITE = 118,
+ RWRITE,
+ TCLUNK = 120,
+ RCLUNK,
+ TREMOVE = 122,
+ RREMOVE,
+ TSTAT = 124,
+ RSTAT,
+ TWSTAT = 126,
+ RWSTAT,
+};
+
+/* modes */
+enum {
+ V9FS_OREAD = 0x00,
+ V9FS_OWRITE = 0x01,
+ V9FS_ORDWR = 0x02,
+ V9FS_OEXEC = 0x03,
+ V9FS_OEXCL = 0x04,
+ V9FS_OTRUNC = 0x10,
+ V9FS_OREXEC = 0x20,
+ V9FS_ORCLOSE = 0x40,
+ V9FS_OAPPEND = 0x80,
+};
+
+/* permissions */
+enum {
+ V9FS_DMDIR = 0x80000000,
+ V9FS_DMAPPEND = 0x40000000,
+ V9FS_DMEXCL = 0x20000000,
+ V9FS_DMMOUNT = 0x10000000,
+ V9FS_DMAUTH = 0x08000000,
+ V9FS_DMTMP = 0x04000000,
+ V9FS_DMSYMLINK = 0x02000000,
+ V9FS_DMLINK = 0x01000000,
+ /* 9P2000.u extensions */
+ V9FS_DMDEVICE = 0x00800000,
+ V9FS_DMNAMEDPIPE = 0x00200000,
+ V9FS_DMSOCKET = 0x00100000,
+ V9FS_DMSETUID = 0x00080000,
+ V9FS_DMSETGID = 0x00040000,
+};
+
+/* qid.types */
+enum {
+ V9FS_QTDIR = 0x80,
+ V9FS_QTAPPEND = 0x40,
+ V9FS_QTEXCL = 0x20,
+ V9FS_QTMOUNT = 0x10,
+ V9FS_QTAUTH = 0x08,
+ V9FS_QTTMP = 0x04,
+ V9FS_QTSYMLINK = 0x02,
+ V9FS_QTLINK = 0x01,
+ V9FS_QTFILE = 0x00,
+};
+
+/* ample room for Twrite/Rread header (iounit) */
+#define V9FS_IOHDRSZ 24
+
+/* qids are the unique ID for a file (like an inode */
+struct v9fs_qid {
+ u8 type;
+ u32 version;
+ u64 path;
+};
+
+/* Plan 9 file metadata (stat) structure */
+struct v9fs_stat {
+ u16 size;
+ u16 type;
+ u32 dev;
+ struct v9fs_qid qid;
+ u32 mode;
+ u32 atime;
+ u32 mtime;
+ u64 length;
+ char *name;
+ char *uid;
+ char *gid;
+ char *muid;
+ char *extension; /* 9p2000.u extensions */
+ u32 n_uid; /* 9p2000.u extensions */
+ u32 n_gid; /* 9p2000.u extensions */
+ u32 n_muid; /* 9p2000.u extensions */
+ char data[0];
+};
+
+/* Structures for Protocol Operations */
+
+struct Tversion {
+ u32 msize;
+ char *version;
+};
+
+struct Rversion {
+ u32 msize;
+ char *version;
+};
+
+struct Tauth {
+ u32 afid;
+ char *uname;
+ char *aname;
+};
+
+struct Rauth {
+ struct v9fs_qid qid;
+};
+
+struct Rerror {
+ char *error;
+ u32 errno; /* 9p2000.u extension */
+};
+
+struct Tflush {
+ u32 oldtag;
+};
+
+struct Rflush {
+};
+
+struct Tattach {
+ u32 fid;
+ u32 afid;
+ char *uname;
+ char *aname;
+};
+
+struct Rattach {
+ struct v9fs_qid qid;
+};
+
+struct Twalk {
+ u32 fid;
+ u32 newfid;
+ u32 nwname;
+ char **wnames;
+};
+
+struct Rwalk {
+ u32 nwqid;
+ struct v9fs_qid *wqids;
+};
+
+struct Topen {
+ u32 fid;
+ u8 mode;
+};
+
+struct Ropen {
+ struct v9fs_qid qid;
+ u32 iounit;
+};
+
+struct Tcreate {
+ u32 fid;
+ char *name;
+ u32 perm;
+ u8 mode;
+};
+
+struct Rcreate {
+ struct v9fs_qid qid;
+ u32 iounit;
+};
+
+struct Tread {
+ u32 fid;
+ u64 offset;
+ u32 count;
+};
+
+struct Rread {
+ u32 count;
+ u8 *data;
+};
+
+struct Twrite {
+ u32 fid;
+ u64 offset;
+ u32 count;
+ u8 *data;
+};
+
+struct Rwrite {
+ u32 count;
+};
+
+struct Tclunk {
+ u32 fid;
+};
+
+struct Rclunk {
+};
+
+struct Tremove {
+ u32 fid;
+};
+
+struct Rremove {
+};
+
+struct Tstat {
+ u32 fid;
+};
+
+struct Rstat {
+ struct v9fs_stat *stat;
+};
+
+struct Twstat {
+ u32 fid;
+ struct v9fs_stat *stat;
+};
+
+struct Rwstat {
+};
+
+/*
+ * fcall is the primary packet structure
+ *
+ */
+
+struct v9fs_fcall {
+ u32 size;
+ u8 id;
+ u16 tag;
+
+ union {
+ struct Tversion tversion;
+ struct Rversion rversion;
+ struct Tauth tauth;
+ struct Rauth rauth;
+ struct Rerror rerror;
+ struct Tflush tflush;
+ struct Rflush rflush;
+ struct Tattach tattach;
+ struct Rattach rattach;
+ struct Twalk twalk;
+ struct Rwalk rwalk;
+ struct Topen topen;
+ struct Ropen ropen;
+ struct Tcreate tcreate;
+ struct Rcreate rcreate;
+ struct Tread tread;
+ struct Rread rread;
+ struct Twrite twrite;
+ struct Rwrite rwrite;
+ struct Tclunk tclunk;
+ struct Rclunk rclunk;
+ struct Tremove tremove;
+ struct Rremove rremove;
+ struct Tstat tstat;
+ struct Rstat rstat;
+ struct Twstat twstat;
+ struct Rwstat rwstat;
+ } params;
+};
+
+#define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "")
+
+int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
+ char *version, struct v9fs_fcall **rcall);
+
+int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
+ u32 fid, u32 afid, struct v9fs_fcall **rcall);
+
+int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_fcall **rcall);
+
+int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag);
+
+int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_fcall **rcall);
+
+int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_stat *stat, struct v9fs_fcall **rcall);
+
+int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
+ char *name, struct v9fs_fcall **rcall);
+
+int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
+ struct v9fs_fcall **rcall);
+
+int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
+ struct v9fs_fcall **rcall);
+
+int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
+ u32 perm, u8 mode, struct v9fs_fcall **rcall);
+
+int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
+ u64 offset, u32 count, struct v9fs_fcall **rcall);
+
+int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
+ u32 count, void *data, struct v9fs_fcall **rcall);
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
new file mode 100644
index 00000000000..e4e4ffe5a7d
--- /dev/null
+++ b/fs/9p/Makefile
@@ -0,0 +1,17 @@
+obj-$(CONFIG_9P_FS) := 9p2000.o
+
+9p2000-objs := \
+ vfs_super.o \
+ vfs_inode.o \
+ vfs_file.o \
+ vfs_dir.o \
+ vfs_dentry.o \
+ error.o \
+ mux.o \
+ trans_fd.o \
+ trans_sock.o \
+ 9p.o \
+ conv.o \
+ v9fs.o \
+ fid.o
+
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
new file mode 100644
index 00000000000..1554731bd65
--- /dev/null
+++ b/fs/9p/conv.c
@@ -0,0 +1,693 @@
+/*
+ * linux/fs/9p/conv.c
+ *
+ * 9P protocol conversion functions
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "conv.h"
+
+/*
+ * Buffer to help with string parsing
+ */
+struct cbuf {
+ unsigned char *sp;
+ unsigned char *p;
+ unsigned char *ep;
+};
+
+static inline void buf_init(struct cbuf *buf, void *data, int datalen)
+{
+ buf->sp = buf->p = data;
+ buf->ep = data + datalen;
+}
+
+static inline int buf_check_overflow(struct cbuf *buf)
+{
+ return buf->p > buf->ep;
+}
+
+static inline void buf_check_size(struct cbuf *buf, int len)
+{
+ if (buf->p+len > buf->ep) {
+ if (buf->p < buf->ep) {
+ eprintk(KERN_ERR, "buffer overflow\n");
+ buf->p = buf->ep + 1;
+ }
+ }
+}
+
+static inline void *buf_alloc(struct cbuf *buf, int len)
+{
+ void *ret = NULL;
+
+ buf_check_size(buf, len);
+ ret = buf->p;
+ buf->p += len;
+
+ return ret;
+}
+
+static inline void buf_put_int8(struct cbuf *buf, u8 val)
+{
+ buf_check_size(buf, 1);
+
+ buf->p[0] = val;
+ buf->p++;
+}
+
+static inline void buf_put_int16(struct cbuf *buf, u16 val)
+{
+ buf_check_size(buf, 2);
+
+ *(__le16 *) buf->p = cpu_to_le16(val);
+ buf->p += 2;
+}
+
+static inline void buf_put_int32(struct cbuf *buf, u32 val)
+{
+ buf_check_size(buf, 4);
+
+ *(__le32 *)buf->p = cpu_to_le32(val);
+ buf->p += 4;
+}
+
+static inline void buf_put_int64(struct cbuf *buf, u64 val)
+{
+ buf_check_size(buf, 8);
+
+ *(__le64 *)buf->p = cpu_to_le64(val);
+ buf->p += 8;
+}
+
+static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
+{
+ buf_check_size(buf, slen + 2);
+
+ buf_put_int16(buf, slen);
+ memcpy(buf->p, s, slen);
+ buf->p += slen;
+}
+
+static inline void buf_put_string(struct cbuf *buf, const char *s)
+{
+ buf_put_stringn(buf, s, strlen(s));
+}
+
+static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
+{
+ buf_check_size(buf, datalen);
+
+ memcpy(buf->p, data, datalen);
+ buf->p += datalen;
+}
+
+static inline u8 buf_get_int8(struct cbuf *buf)
+{
+ u8 ret = 0;
+
+ buf_check_size(buf, 1);
+ ret = buf->p[0];
+
+ buf->p++;
+
+ return ret;
+}
+
+static inline u16 buf_get_int16(struct cbuf *buf)
+{
+ u16 ret = 0;
+
+ buf_check_size(buf, 2);
+ ret = le16_to_cpu(*(__le16 *)buf->p);
+
+ buf->p += 2;
+
+ return ret;
+}
+
+static inline u32 buf_get_int32(struct cbuf *buf)
+{
+ u32 ret = 0;
+
+ buf_check_size(buf, 4);
+ ret = le32_to_cpu(*(__le32 *)buf->p);
+
+ buf->p += 4;
+
+ return ret;
+}
+
+static inline u64 buf_get_int64(struct cbuf *buf)
+{
+ u64 ret = 0;
+
+ buf_check_size(buf, 8);
+ ret = le64_to_cpu(*(__le64 *)buf->p);
+
+ buf->p += 8;
+
+ return ret;
+}
+
+static inline int
+buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
+{
+
+ u16 len = buf_get_int16(buf);
+ buf_check_size(buf, len);
+ if (len + 1 > datalen)
+ return 0;
+
+ memcpy(data, buf->p, len);
+ data[len] = 0;
+ buf->p += len;
+
+ return len + 1;
+}
+
+static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
+{
+ char *ret = NULL;
+ int n = buf_get_string(buf, sbuf->p, sbuf->ep - sbuf->p);
+
+ if (n > 0) {
+ ret = sbuf->p;
+ sbuf->p += n;
+ }
+
+ return ret;
+}
+
+static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
+{
+ buf_check_size(buf, datalen);
+
+ memcpy(data, buf->p, datalen);
+ buf->p += datalen;
+
+ return datalen;
+}
+
+static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
+ int datalen)
+{
+ char *ret = NULL;
+ int n = 0;
+
+ buf_check_size(dbuf, datalen);
+
+ n = buf_get_data(buf, dbuf->p, datalen);
+
+ if (n > 0) {
+ ret = dbuf->p;
+ dbuf->p += n;
+ }
+
+ return ret;
+}
+
+/**
+ * v9fs_size_stat - calculate the size of a variable length stat struct
+ * @v9ses: session information
+ * @stat: metadata (stat) structure
+ *
+ */
+
+static int v9fs_size_stat(struct v9fs_session_info *v9ses,
+ struct v9fs_stat *stat)
+{
+ int size = 0;
+
+ if (stat == NULL) {
+ eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n");
+ return 0;
+ }
+
+ size = /* 2 + *//* size[2] */
+ 2 + /* type[2] */
+ 4 + /* dev[4] */
+ 1 + /* qid.type[1] */
+ 4 + /* qid.vers[4] */
+ 8 + /* qid.path[8] */
+ 4 + /* mode[4] */
+ 4 + /* atime[4] */
+ 4 + /* mtime[4] */
+ 8 + /* length[8] */
+ 8; /* minimum sum of string lengths */
+
+ if (stat->name)
+ size += strlen(stat->name);
+ if (stat->uid)
+ size += strlen(stat->uid);
+ if (stat->gid)
+ size += strlen(stat->gid);
+ if (stat->muid)
+ size += strlen(stat->muid);
+
+ if (v9ses->extended) {
+ size += 4 + /* n_uid[4] */
+ 4 + /* n_gid[4] */
+ 4 + /* n_muid[4] */
+ 2; /* string length of extension[4] */
+ if (stat->extension)
+ size += strlen(stat->extension);
+ }
+
+ return size;
+}
+
+/**
+ * serialize_stat - safely format a stat structure for transmission
+ * @v9ses: session info
+ * @stat: metadata (stat) structure
+ * @bufp: buffer to serialize structure into
+ *
+ */
+
+static int
+serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
+ struct cbuf *bufp)
+{
+ buf_put_int16(bufp, stat->size);
+ buf_put_int16(bufp, stat->type);
+ buf_put_int32(bufp, stat->dev);
+ buf_put_int8(bufp, stat->qid.type);
+ buf_put_int32(bufp, stat->qid.version);
+ buf_put_int64(bufp, stat->qid.path);
+ buf_put_int32(bufp, stat->mode);
+ buf_put_int32(bufp, stat->atime);
+ buf_put_int32(bufp, stat->mtime);
+ buf_put_int64(bufp, stat->length);
+
+ buf_put_string(bufp, stat->name);
+ buf_put_string(bufp, stat->uid);
+ buf_put_string(bufp, stat->gid);
+ buf_put_string(bufp, stat->muid);
+
+ if (v9ses->extended) {
+ buf_put_string(bufp, stat->extension);
+ buf_put_int32(bufp, stat->n_uid);
+ buf_put_int32(bufp, stat->n_gid);
+ buf_put_int32(bufp, stat->n_muid);
+ }
+
+ if (buf_check_overflow(bufp))
+ return 0;
+
+ return stat->size;
+}
+
+/**
+ * deserialize_stat - safely decode a recieved metadata (stat) structure
+ * @v9ses: session info
+ * @bufp: buffer to deserialize
+ * @stat: metadata (stat) structure
+ * @dbufp: buffer to deserialize variable strings into
+ *
+ */
+
+static inline int
+deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
+ struct v9fs_stat *stat, struct cbuf *dbufp)
+{
+
+ stat->size = buf_get_int16(bufp);
+ stat->type = buf_get_int16(bufp);
+ stat->dev = buf_get_int32(bufp);
+ stat->qid.type = buf_get_int8(bufp);
+ stat->qid.version = buf_get_int32(bufp);
+ stat->qid.path = buf_get_int64(bufp);
+ stat->mode = buf_get_int32(bufp);
+ stat->atime = buf_get_int32(bufp);
+ stat->mtime = buf_get_int32(bufp);
+ stat->length = buf_get_int64(bufp);
+ stat->name = buf_get_stringb(bufp, dbufp);
+ stat->uid = buf_get_stringb(bufp, dbufp);
+ stat->gid = buf_get_stringb(bufp, dbufp);
+ stat->muid = buf_get_stringb(bufp, dbufp);
+
+ if (v9ses->extended) {
+ stat->extension = buf_get_stringb(bufp, dbufp);
+ stat->n_uid = buf_get_int32(bufp);
+ stat->n_gid = buf_get_int32(bufp);
+ stat->n_muid = buf_get_int32(bufp);
+ }
+
+ if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
+ return 0;
+
+ return stat->size + 2;
+}
+
+/**
+ * deserialize_statb - wrapper for decoding a received metadata structure
+ * @v9ses: session info
+ * @bufp: buffer to deserialize
+ * @dbufp: buffer to deserialize variable strings into
+ *
+ */
+
+static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info
+ *v9ses, struct cbuf *bufp,
+ struct cbuf *dbufp)
+{
+ struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat));
+
+ if (ret) {
+ int n = deserialize_stat(v9ses, bufp, ret, dbufp);
+ if (n <= 0)
+ return NULL;
+ }
+
+ return ret;
+}
+
+/**
+ * v9fs_deserialize_stat - decode a received metadata structure
+ * @v9ses: session info
+ * @buf: buffer to deserialize
+ * @buflen: length of received buffer
+ * @stat: metadata structure to decode into
+ * @statlen: length of destination metadata structure
+ *
+ */
+
+int
+v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf,
+ u32 buflen, struct v9fs_stat *stat, u32 statlen)
+{
+ struct cbuf buffer;
+ struct cbuf *bufp = &buffer;
+ struct cbuf dbuffer;
+ struct cbuf *dbufp = &dbuffer;
+
+ buf_init(bufp, buf, buflen);
+ buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat),
+ statlen - sizeof(struct v9fs_stat));
+
+ return deserialize_stat(v9ses, bufp, stat, dbufp);
+}
+
+static inline int
+v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
+{
+ int size = 4 + 1 + 2; /* size[4] msg[1] tag[2] */
+ int i = 0;
+
+ switch (fcall->id) {
+ default:
+ eprintk(KERN_ERR, "bad msg type %d\n", fcall->id);
+ return 0;
+ case TVERSION: /* msize[4] version[s] */
+ size += 4 + 2 + strlen(fcall->params.tversion.version);
+ break;
+ case TAUTH: /* afid[4] uname[s] aname[s] */
+ size += 4 + 2 + strlen(fcall->params.tauth.uname) +
+ 2 + strlen(fcall->params.tauth.aname);
+ break;
+ case TFLUSH: /* oldtag[2] */
+ size += 2;
+ break;
+ case TATTACH: /* fid[4] afid[4] uname[s] aname[s] */
+ size += 4 + 4 + 2 + strlen(fcall->params.tattach.uname) +
+ 2 + strlen(fcall->params.tattach.aname);
+ break;
+ case TWALK: /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
+ size += 4 + 4 + 2;
+ /* now compute total for the array of names */
+ for (i = 0; i < fcall->params.twalk.nwname; i++)
+ size += 2 + strlen(fcall->params.twalk.wnames[i]);
+ break;
+ case TOPEN: /* fid[4] mode[1] */
+ size += 4 + 1;
+ break;
+ case TCREATE: /* fid[4] name[s] perm[4] mode[1] */
+ size += 4 + 2 + strlen(fcall->params.tcreate.name) + 4 + 1;
+ break;
+ case TREAD: /* fid[4] offset[8] count[4] */
+ size += 4 + 8 + 4;
+ break;
+ case TWRITE: /* fid[4] offset[8] count[4] data[count] */
+ size += 4 + 8 + 4 + fcall->params.twrite.count;
+ break;
+ case TCLUNK: /* fid[4] */
+ size += 4;
+ break;
+ case TREMOVE: /* fid[4] */
+ size += 4;
+ break;
+ case TSTAT: /* fid[4] */
+ size += 4;
+ break;
+ case TWSTAT: /* fid[4] stat[n] */
+ fcall->params.twstat.stat->size =
+ v9fs_size_stat(v9ses, fcall->params.twstat.stat);
+ size += 4 + 2 + 2 + fcall->params.twstat.stat->size;
+ }
+ return size;
+}
+
+/*
+ * v9fs_serialize_fcall - marshall fcall struct into a packet
+ * @v9ses: session information
+ * @fcall: structure to convert
+ * @data: buffer to serialize fcall into
+ * @datalen: length of buffer to serialize fcall into
+ *
+ */
+
+int
+v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
+ void *data, u32 datalen)
+{
+ int i = 0;
+ struct v9fs_stat *stat = NULL;
+ struct cbuf buffer;
+ struct cbuf *bufp = &buffer;
+
+ buf_init(bufp, data, datalen);
+
+ if (!fcall) {
+ eprintk(KERN_ERR, "no fcall\n");
+ return -EINVAL;
+ }
+
+ fcall->size = v9fs_size_fcall(v9ses, fcall);
+
+ buf_put_int32(bufp, fcall->size);
+ buf_put_int8(bufp, fcall->id);
+ buf_put_int16(bufp, fcall->tag);
+
+ dprintk(DEBUG_CONV, "size %d id %d tag %d\n", fcall->size, fcall->id,
+ fcall->tag);
+
+ /* now encode it */
+ switch (fcall->id) {
+ default:
+ eprintk(KERN_ERR, "bad msg type: %d\n", fcall->id);
+ return -EPROTO;
+ case TVERSION:
+ buf_put_int32(bufp, fcall->params.tversion.msize);
+ buf_put_string(bufp, fcall->params.tversion.version);
+ break;
+ case TAUTH:
+ buf_put_int32(bufp, fcall->params.tauth.afid);
+ buf_put_string(bufp, fcall->params.tauth.uname);
+ buf_put_string(bufp, fcall->params.tauth.aname);
+ break;
+ case TFLUSH:
+ buf_put_int16(bufp, fcall->params.tflush.oldtag);
+ break;
+ case TATTACH:
+ buf_put_int32(bufp, fcall->params.tattach.fid);
+ buf_put_int32(bufp, fcall->params.tattach.afid);
+ buf_put_string(bufp, fcall->params.tattach.uname);
+ buf_put_string(bufp, fcall->params.tattach.aname);
+ break;
+ case TWALK:
+ buf_put_int32(bufp, fcall->params.twalk.fid);
+ buf_put_int32(bufp, fcall->params.twalk.newfid);
+ buf_put_int16(bufp, fcall->params.twalk.nwname);
+ for (i = 0; i < fcall->params.twalk.nwname; i++)
+ buf_put_string(bufp, fcall->params.twalk.wnames[i]);
+ break;
+ case TOPEN:
+ buf_put_int32(bufp, fcall->params.topen.fid);
+ buf_put_int8(bufp, fcall->params.topen.mode);
+ break;
+ case TCREATE:
+ buf_put_int32(bufp, fcall->params.tcreate.fid);
+ buf_put_string(bufp, fcall->params.tcreate.name);
+ buf_put_int32(bufp, fcall->params.tcreate.perm);
+ buf_put_int8(bufp, fcall->params.tcreate.mode);
+ break;
+ case TREAD:
+ buf_put_int32(bufp, fcall->params.tread.fid);
+ buf_put_int64(bufp, fcall->params.tread.offset);
+ buf_put_int32(bufp, fcall->params.tread.count);
+ break;
+ case TWRITE:
+ buf_put_int32(bufp, fcall->params.twrite.fid);
+ buf_put_int64(bufp, fcall->params.twrite.offset);
+ buf_put_int32(bufp, fcall->params.twrite.count);
+ buf_put_data(bufp, fcall->params.twrite.data,
+ fcall->params.twrite.count);
+ break;
+ case TCLUNK:
+ buf_put_int32(bufp, fcall->params.tclunk.fid);
+ break;
+ case TREMOVE:
+ buf_put_int32(bufp, fcall->params.tremove.fid);
+ break;
+ case TSTAT:
+ buf_put_int32(bufp, fcall->params.tstat.fid);
+ break;
+ case TWSTAT:
+ buf_put_int32(bufp, fcall->params.twstat.fid);
+ stat = fcall->params.twstat.stat;
+
+ buf_put_int16(bufp, stat->size + 2);
+ serialize_stat(v9ses, stat, bufp);
+ break;
+ }
+
+ if (buf_check_overflow(bufp))
+ return -EIO;
+
+ return fcall->size;
+}
+
+/**
+ * deserialize_fcall - unmarshal a response
+ * @v9ses: session information
+ * @msgsize: size of rcall message
+ * @buf: recieved buffer
+ * @buflen: length of received buffer
+ * @rcall: fcall structure to populate
+ * @rcalllen: length of fcall structure to populate
+ *
+ */
+
+int
+v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
+ void *buf, u32 buflen, struct v9fs_fcall *rcall,
+ int rcalllen)
+{
+
+ struct cbuf buffer;
+ struct cbuf *bufp = &buffer;
+ struct cbuf dbuffer;
+ struct cbuf *dbufp = &dbuffer;
+ int i = 0;
+
+ buf_init(bufp, buf, buflen);
+ buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall),
+ rcalllen - sizeof(struct v9fs_fcall));
+
+ rcall->size = msgsize;
+ rcall->id = buf_get_int8(bufp);
+ rcall->tag = buf_get_int16(bufp);
+
+ dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id,
+ rcall->tag);
+ switch (rcall->id) {
+ default:
+ eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id);
+ return -EPROTO;
+ case RVERSION:
+ rcall->params.rversion.msize = buf_get_int32(bufp);
+ rcall->params.rversion.version = buf_get_stringb(bufp, dbufp);
+ break;
+ case RFLUSH:
+ break;
+ case RATTACH:
+ rcall->params.rattach.qid.type = buf_get_int8(bufp);
+ rcall->params.rattach.qid.version = buf_get_int32(bufp);
+ rcall->params.rattach.qid.path = buf_get_int64(bufp);
+ break;
+ case RWALK:
+ rcall->params.rwalk.nwqid = buf_get_int16(bufp);
+ rcall->params.rwalk.wqids = buf_alloc(bufp,
+ rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid));
+ if (rcall->params.rwalk.wqids)
+ for (i = 0; i < rcall->params.rwalk.nwqid; i++) {
+ rcall->params.rwalk.wqids[i].type =
+ buf_get_int8(bufp);
+ rcall->params.rwalk.wqids[i].version =
+ buf_get_int16(bufp);
+ rcall->params.rwalk.wqids[i].path =
+ buf_get_int64(bufp);
+ }
+ break;
+ case ROPEN:
+ rcall->params.ropen.qid.type = buf_get_int8(bufp);
+ rcall->params.ropen.qid.version = buf_get_int32(bufp);
+ rcall->params.ropen.qid.path = buf_get_int64(bufp);
+ rcall->params.ropen.iounit = buf_get_int32(bufp);
+ break;
+ case RCREATE:
+ rcall->params.rcreate.qid.type = buf_get_int8(bufp);
+ rcall->params.rcreate.qid.version = buf_get_int32(bufp);
+ rcall->params.rcreate.qid.path = buf_get_int64(bufp);
+ rcall->params.rcreate.iounit = buf_get_int32(bufp);
+ break;
+ case RREAD:
+ rcall->params.rread.count = buf_get_int32(bufp);
+ rcall->params.rread.data = buf_get_datab(bufp, dbufp,
+ rcall->params.rread.count);
+ break;
+ case RWRITE:
+ rcall->params.rwrite.count = buf_get_int32(bufp);
+ break;
+ case RCLUNK:
+ break;
+ case RREMOVE:
+ break;
+ case RSTAT:
+ buf_get_int16(bufp);
+ rcall->params.rstat.stat =
+ deserialize_statb(v9ses, bufp, dbufp);
+ break;
+ case RWSTAT:
+ break;
+ case RERROR:
+ rcall->params.rerror.error = buf_get_stringb(bufp, dbufp);
+ if (v9ses->extended)
+ rcall->params.rerror.errno = buf_get_int16(bufp);
+ break;
+ }
+
+ if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
+ return -EIO;
+
+ return rcall->size;
+}
diff --git a/fs/9p/conv.h b/fs/9p/conv.h
new file mode 100644
index 00000000000..ee849613c61
--- /dev/null
+++ b/fs/9p/conv.h
@@ -0,0 +1,36 @@
+/*
+ * linux/fs/9p/conv.h
+ *
+ * 9P protocol conversion definitions
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf,
+ u32 buflen, struct v9fs_stat *stat, u32 statlen);
+int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall,
+ void *buf, u32 buflen);
+int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen,
+ void *buf, u32 buflen, struct v9fs_fcall *rcall,
+ int rcalllen);
+
+/* this one is actually in error.c right now */
+int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/debug.h b/fs/9p/debug.h
new file mode 100644
index 00000000000..4445f06919d
--- /dev/null
+++ b/fs/9p/debug.h
@@ -0,0 +1,70 @@
+/*
+ * linux/fs/9p/debug.h - V9FS Debug Definitions
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#define DEBUG_ERROR (1<<0)
+#define DEBUG_CURRENT (1<<1)
+#define DEBUG_9P (1<<2)
+#define DEBUG_VFS (1<<3)
+#define DEBUG_CONV (1<<4)
+#define DEBUG_MUX (1<<5)
+#define DEBUG_TRANS (1<<6)
+#define DEBUG_SLABS (1<<7)
+
+#define DEBUG_DUMP_PKT 0
+
+extern int v9fs_debug_level;
+
+#define dprintk(level, format, arg...) \
+do { \
+ if((v9fs_debug_level & level)==level) \
+ printk(KERN_NOTICE "-- %s (%d): " \
+ format , __FUNCTION__, current->pid , ## arg); \
+} while(0)
+
+#define eprintk(level, format, arg...) \
+do { \
+ printk(level "v9fs: %s (%d): " \
+ format , __FUNCTION__, current->pid , ## arg); \
+} while(0)
+
+#if DEBUG_DUMP_PKT
+static inline void dump_data(const unsigned char *data, unsigned int datalen)
+{
+ int i, j;
+ int len = datalen;
+
+ printk(KERN_DEBUG "data ");
+ for (i = 0; i < len; i += 4) {
+ for (j = 0; (j < 4) && (i + j < len); j++)
+ printk(KERN_DEBUG "%02x", data[i + j]);
+ printk(KERN_DEBUG " ");
+ }
+ printk(KERN_DEBUG "\n");
+}
+#else /* DEBUG_DUMP_PKT */
+static inline void dump_data(const unsigned char *data, unsigned int datalen)
+{
+
+}
+#endif /* DEBUG_DUMP_PKT */
diff --git a/fs/9p/error.c b/fs/9p/error.c
new file mode 100644
index 00000000000..fee5d19179c
--- /dev/null
+++ b/fs/9p/error.c
@@ -0,0 +1,93 @@
+/*
+ * linux/fs/9p/error.c
+ *
+ * Error string handling
+ *
+ * Plan 9 uses error strings, Unix uses error numbers. These functions
+ * try to help manage that and provide for dynamically adding error
+ * mappings.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/list.h>
+#include <linux/jhash.h>
+
+#include "debug.h"
+#include "error.h"
+
+/**
+ * v9fs_error_init - preload
+ * @errstr: error string
+ *
+ */
+
+int v9fs_error_init(void)
+{
+ struct errormap *c;
+ int bucket;
+
+ /* initialize hash table */
+ for (bucket = 0; bucket < ERRHASHSZ; bucket++)
+ INIT_HLIST_HEAD(&hash_errmap[bucket]);
+
+ /* load initial error map into hash table */
+ for (c = errmap; c->name != NULL; c++) {
+ bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ;
+ INIT_HLIST_NODE(&c->list);
+ hlist_add_head(&c->list, &hash_errmap[bucket]);
+ }
+
+ return 1;
+}
+
+/**
+ * errstr2errno - convert error string to error number
+ * @errstr: error string
+ *
+ */
+
+int v9fs_errstr2errno(char *errstr)
+{
+ int errno = 0;
+ struct hlist_node *p = NULL;
+ struct errormap *c = NULL;
+ int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ;
+
+ hlist_for_each_entry(c, p, &hash_errmap[bucket], list) {
+ if (!strcmp(c->name, errstr)) {
+ errno = c->val;
+ break;
+ }
+ }
+
+ if (errno == 0) {
+ /* TODO: if error isn't found, add it dynamically */
+ printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__,
+ errstr);
+ errno = 1;
+ }
+
+ return -errno;
+}
diff --git a/fs/9p/error.h b/fs/9p/error.h
new file mode 100644
index 00000000000..78f89acf7c9
--- /dev/null
+++ b/fs/9p/error.h
@@ -0,0 +1,178 @@
+/*
+ * linux/fs/9p/error.h
+ *
+ * Huge Nasty Error Table
+ *
+ * Plan 9 uses error strings, Unix uses error numbers. This table tries to
+ * match UNIX strings and Plan 9 strings to unix error numbers. It is used
+ * to preload the dynamic error table which can also track user-specific error
+ * strings.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/errno.h>
+#include <asm/errno.h>
+
+struct errormap {
+ char *name;
+ int val;
+
+ struct hlist_node list;
+};
+
+#define ERRHASHSZ 32
+static struct hlist_head hash_errmap[ERRHASHSZ];
+
+/* FixMe - reduce to a reasonable size */
+static struct errormap errmap[] = {
+ {"Operation not permitted", EPERM},
+ {"wstat prohibited", EPERM},
+ {"No such file or directory", ENOENT},
+ {"directory entry not found", ENOENT},
+ {"file not found", ENOENT},
+ {"Interrupted system call", EINTR},
+ {"Input/output error", EIO},
+ {"No such device or address", ENXIO},
+ {"Argument list too long", E2BIG},
+ {"Bad file descriptor", EBADF},
+ {"Resource temporarily unavailable", EAGAIN},
+ {"Cannot allocate memory", ENOMEM},
+ {"Permission denied", EACCES},
+ {"Bad address", EFAULT},
+ {"Block device required", ENOTBLK},
+ {"Device or resource busy", EBUSY},
+ {"File exists", EEXIST},
+ {"Invalid cross-device link", EXDEV},
+ {"No such device", ENODEV},
+ {"Not a directory", ENOTDIR},
+ {"Is a directory", EISDIR},
+ {"Invalid argument", EINVAL},
+ {"Too many open files in system", ENFILE},
+ {"Too many open files", EMFILE},
+ {"Text file busy", ETXTBSY},
+ {"File too large", EFBIG},
+ {"No space left on device", ENOSPC},
+ {"Illegal seek", ESPIPE},
+ {"Read-only file system", EROFS},
+ {"Too many links", EMLINK},
+ {"Broken pipe", EPIPE},
+ {"Numerical argument out of domain", EDOM},
+ {"Numerical result out of range", ERANGE},
+ {"Resource deadlock avoided", EDEADLK},
+ {"File name too long", ENAMETOOLONG},
+ {"No locks available", ENOLCK},
+ {"Function not implemented", ENOSYS},
+ {"Directory not empty", ENOTEMPTY},
+ {"Too many levels of symbolic links", ELOOP},
+ {"No message of desired type", ENOMSG},
+ {"Identifier removed", EIDRM},
+ {"No data available", ENODATA},
+ {"Machine is not on the network", ENONET},
+ {"Package not installed", ENOPKG},
+ {"Object is remote", EREMOTE},
+ {"Link has been severed", ENOLINK},
+ {"Communication error on send", ECOMM},
+ {"Protocol error", EPROTO},
+ {"Bad message", EBADMSG},
+ {"File descriptor in bad state", EBADFD},
+ {"Streams pipe error", ESTRPIPE},
+ {"Too many users", EUSERS},
+ {"Socket operation on non-socket", ENOTSOCK},
+ {"Message too long", EMSGSIZE},
+ {"Protocol not available", ENOPROTOOPT},
+ {"Protocol not supported", EPROTONOSUPPORT},
+ {"Socket type not supported", ESOCKTNOSUPPORT},
+ {"Operation not supported", EOPNOTSUPP},
+ {"Protocol family not supported", EPFNOSUPPORT},
+ {"Network is down", ENETDOWN},
+ {"Network is unreachable", ENETUNREACH},
+ {"Network dropped connection on reset", ENETRESET},
+ {"Software caused connection abort", ECONNABORTED},
+ {"Connection reset by peer", ECONNRESET},
+ {"No buffer space available", ENOBUFS},
+ {"Transport endpoint is already connected", EISCONN},
+ {"Transport endpoint is not connected", ENOTCONN},
+ {"Cannot send after transport endpoint shutdown", ESHUTDOWN},
+ {"Connection timed out", ETIMEDOUT},
+ {"Connection refused", ECONNREFUSED},
+ {"Host is down", EHOSTDOWN},
+ {"No route to host", EHOSTUNREACH},
+ {"Operation already in progress", EALREADY},
+ {"Operation now in progress", EINPROGRESS},
+ {"Is a named type file", EISNAM},
+ {"Remote I/O error", EREMOTEIO},
+ {"Disk quota exceeded", EDQUOT},
+/* errors from fossil, vacfs, and u9fs */
+ {"fid unknown or out of range", EBADF},
+ {"permission denied", EACCES},
+ {"file does not exist", ENOENT},
+ {"authentication failed", ECONNREFUSED},
+ {"bad offset in directory read", ESPIPE},
+ {"bad use of fid", EBADF},
+ {"wstat can't convert between files and directories", EPERM},
+ {"directory is not empty", ENOTEMPTY},
+ {"file exists", EEXIST},
+ {"file already exists", EEXIST},
+ {"file or directory already exists", EEXIST},
+ {"fid already in use", EBADF},
+ {"file in use", ETXTBSY},
+ {"i/o error", EIO},
+ {"file already open for I/O", ETXTBSY},
+ {"illegal mode", EINVAL},
+ {"illegal name", ENAMETOOLONG},
+ {"not a directory", ENOTDIR},
+ {"not a member of proposed group", EPERM},
+ {"not owner", EACCES},
+ {"only owner can change group in wstat", EACCES},
+ {"read only file system", EROFS},
+ {"no access to special file", EPERM},
+ {"i/o count too large", EIO},
+ {"unknown group", EINVAL},
+ {"unknown user", EINVAL},
+ {"bogus wstat buffer", EPROTO},
+ {"exclusive use file already open", EAGAIN},
+ {"corrupted directory entry", EIO},
+ {"corrupted file entry", EIO},
+ {"corrupted block label", EIO},
+ {"corrupted meta data", EIO},
+ {"illegal offset", EINVAL},
+ {"illegal path element", ENOENT},
+ {"root of file system is corrupted", EIO},
+ {"corrupted super block", EIO},
+ {"protocol botch", EPROTO},
+ {"file system is full", ENOSPC},
+ {"file is in use", EAGAIN},
+ {"directory entry is not allocated", ENOENT},
+ {"file is read only", EROFS},
+ {"file has been removed", EIDRM},
+ {"only support truncation to zero length", EPERM},
+ {"cannot remove root", EPERM},
+ {"file too big", EFBIG},
+ {"venti i/o error", EIO},
+ /* these are not errors */
+ {"u9fs rhostsauth: no authentication required", 0},
+ {"u9fs authnone: no authentication required", 0},
+ {NULL, -1}
+};
+
+extern int v9fs_error_init(void);
+extern int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
new file mode 100644
index 00000000000..821c9c4d76a
--- /dev/null
+++ b/fs/9p/fid.c
@@ -0,0 +1,241 @@
+/*
+ * V9FS FID Management
+ *
+ * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "transport.h"
+#include "mux.h"
+#include "conv.h"
+#include "fid.h"
+
+/**
+ * v9fs_fid_insert - add a fid to a dentry
+ * @fid: fid to add
+ * @dentry: dentry that it is being added to
+ *
+ */
+
+static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry)
+{
+ struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
+ dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid,
+ dentry->d_iname, dentry);
+ if (dentry->d_fsdata == NULL) {
+ dentry->d_fsdata =
+ kmalloc(sizeof(struct list_head), GFP_KERNEL);
+ if (dentry->d_fsdata == NULL) {
+ dprintk(DEBUG_ERROR, "Out of memory\n");
+ return -ENOMEM;
+ }
+ fid_list = (struct list_head *)dentry->d_fsdata;
+ INIT_LIST_HEAD(fid_list); /* Initialize list head */
+ }
+
+ fid->uid = current->uid;
+ fid->pid = current->pid;
+ list_add(&fid->list, fid_list);
+ return 0;
+}
+
+/**
+ * v9fs_fid_create - allocate a FID structure
+ * @dentry - dentry to link newly created fid to
+ *
+ */
+
+struct v9fs_fid *v9fs_fid_create(struct dentry *dentry)
+{
+ struct v9fs_fid *new;
+
+ new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
+ if (new == NULL) {
+ dprintk(DEBUG_ERROR, "Out of Memory\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ new->fid = -1;
+ new->fidopen = 0;
+ new->fidcreate = 0;
+ new->fidclunked = 0;
+ new->iounit = 0;
+
+ if (v9fs_fid_insert(new, dentry) == 0)
+ return new;
+ else {
+ dprintk(DEBUG_ERROR, "Problems inserting to dentry\n");
+ kfree(new);
+ return NULL;
+ }
+}
+
+/**
+ * v9fs_fid_destroy - deallocate a FID structure
+ * @fid: fid to destroy
+ *
+ */
+
+void v9fs_fid_destroy(struct v9fs_fid *fid)
+{
+ list_del(&fid->list);
+ kfree(fid);
+}
+
+/**
+ * v9fs_fid_lookup - retrieve the right fid from a particular dentry
+ * @dentry: dentry to look for fid in
+ * @type: intent of lookup (operation or traversal)
+ *
+ * search list of fids associated with a dentry for a fid with a matching
+ * thread id or uid. If that fails, look up the dentry's parents to see if you
+ * can find a matching fid.
+ *
+ */
+
+struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type)
+{
+ struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
+ struct v9fs_fid *current_fid = NULL;
+ struct v9fs_fid *temp = NULL;
+ struct v9fs_fid *return_fid = NULL;
+ int found_parent = 0;
+ int found_user = 0;
+
+ dprintk(DEBUG_9P, " dentry: %s (%p) type %d\n", dentry->d_iname, dentry,
+ type);
+
+ if (fid_list && !list_empty(fid_list)) {
+ list_for_each_entry_safe(current_fid, temp, fid_list, list) {
+ if (current_fid->uid == current->uid) {
+ if (return_fid == NULL) {
+ if ((type == FID_OP)
+ || (!current_fid->fidopen)) {
+ return_fid = current_fid;
+ found_user = 1;
+ }
+ }
+ }
+ if (current_fid->pid == current->real_parent->pid) {
+ if ((return_fid == NULL) || (found_parent)
+ || (found_user)) {
+ if ((type == FID_OP)
+ || (!current_fid->fidopen)) {
+ return_fid = current_fid;
+ found_parent = 1;
+ found_user = 0;
+ }
+ }
+ }
+ if (current_fid->pid == current->pid) {
+ if ((type == FID_OP) ||
+ (!current_fid->fidopen)) {
+ return_fid = current_fid;
+ found_parent = 0;
+ found_user = 0;
+ }
+ }
+ }
+ }
+
+ /* we are at the root but didn't match */
+ if ((!return_fid) && (dentry->d_parent == dentry)) {
+ /* TODO: clone attach with new uid */
+ return_fid = current_fid;
+ }
+
+ if (!return_fid) {
+ struct dentry *par = current->fs->pwd->d_parent;
+ int count = 1;
+ while (par != NULL) {
+ if (par == dentry)
+ break;
+ count++;
+ if (par == par->d_parent) {
+ dprintk(DEBUG_ERROR,
+ "got to root without finding dentry\n");
+ break;
+ }
+ par = par->d_parent;
+ }
+
+/* XXX - there may be some duplication we can get rid of */
+ if (par == dentry) {
+ /* we need to fid_lookup the starting point */
+ int fidnum = -1;
+ int oldfid = -1;
+ int result = -1;
+ struct v9fs_session_info *v9ses =
+ v9fs_inode2v9ses(current->fs->pwd->d_inode);
+
+ current_fid =
+ v9fs_fid_lookup(current->fs->pwd, FID_WALK);
+ if (current_fid == NULL) {
+ dprintk(DEBUG_ERROR,
+ "process cwd doesn't have a fid\n");
+ return return_fid;
+ }
+ oldfid = current_fid->fid;
+ par = current->fs->pwd;
+ /* TODO: take advantage of multiwalk */
+
+ fidnum = v9fs_get_idpool(&v9ses->fidpool);
+ if (fidnum < 0) {
+ dprintk(DEBUG_ERROR,
+ "could not get a new fid num\n");
+ return return_fid;
+ }
+
+ while (par != dentry) {
+ result =
+ v9fs_t_walk(v9ses, oldfid, fidnum, "..",
+ NULL);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR,
+ "problem walking to parent\n");
+
+ break;
+ }
+ oldfid = fidnum;
+ if (par == par->d_parent) {
+ dprintk(DEBUG_ERROR,
+ "can't find dentry\n");
+ break;
+ }
+ par = par->d_parent;
+ }
+ if (par == dentry) {
+ return_fid = v9fs_fid_create(dentry);
+ return_fid->fid = fidnum;
+ }
+ }
+ }
+
+ return return_fid;
+}
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
new file mode 100644
index 00000000000..7db478ccca3
--- /dev/null
+++ b/fs/9p/fid.h
@@ -0,0 +1,57 @@
+/*
+ * V9FS FID Management
+ *
+ * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/list.h>
+
+#define FID_OP 0
+#define FID_WALK 1
+
+struct v9fs_fid {
+ struct list_head list; /* list of fids associated with a dentry */
+ struct list_head active; /* XXX - debug */
+
+ u32 fid;
+ unsigned char fidopen; /* set when fid is opened */
+ unsigned char fidcreate; /* set when fid was just created */
+ unsigned char fidclunked; /* set when fid has already been clunked */
+
+ struct v9fs_qid qid;
+ u32 iounit;
+
+ /* readdir stuff */
+ int rdir_fpos;
+ loff_t rdir_pos;
+ struct v9fs_fcall *rdir_fcall;
+
+ /* management stuff */
+ pid_t pid; /* thread associated with this fid */
+ uid_t uid; /* user associated with this fid */
+
+ /* private data */
+ struct file *filp; /* backpointer to File struct for open files */
+ struct v9fs_session_info *v9ses; /* session info for this FID */
+};
+
+struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type);
+void v9fs_fid_destroy(struct v9fs_fid *fid);
+struct v9fs_fid *v9fs_fid_create(struct dentry *);
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
new file mode 100644
index 00000000000..8835b576f74
--- /dev/null
+++ b/fs/9p/mux.c
@@ -0,0 +1,475 @@
+/*
+ * linux/fs/9p/mux.c
+ *
+ * Protocol Multiplexer
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kthread.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "transport.h"
+#include "conv.h"
+#include "mux.h"
+
+/**
+ * dprintcond - print condition of session info
+ * @v9ses: session info structure
+ * @req: RPC request structure
+ *
+ */
+
+static inline int
+dprintcond(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+{
+ dprintk(DEBUG_MUX, "condition: %d, %p\n", v9ses->transport->status,
+ req->rcall);
+ return 0;
+}
+
+/**
+ * xread - force read of a certain number of bytes
+ * @v9ses: session info structure
+ * @ptr: pointer to buffer
+ * @sz: number of bytes to read
+ *
+ * Chuck Cranor CS-533 project1
+ */
+
+static int xread(struct v9fs_session_info *v9ses, void *ptr, unsigned long sz)
+{
+ int rd = 0;
+ int ret = 0;
+ while (rd < sz) {
+ ret = v9ses->transport->read(v9ses->transport, ptr, sz - rd);
+ if (ret <= 0) {
+ dprintk(DEBUG_ERROR, "xread errno %d\n", ret);
+ return ret;
+ }
+ rd += ret;
+ ptr += ret;
+ }
+ return (rd);
+}
+
+/**
+ * read_message - read a full 9P2000 fcall packet
+ * @v9ses: session info structure
+ * @rcall: fcall structure to read into
+ * @rcalllen: size of fcall buffer
+ *
+ */
+
+static int
+read_message(struct v9fs_session_info *v9ses,
+ struct v9fs_fcall *rcall, int rcalllen)
+{
+ unsigned char buf[4];
+ void *data;
+ int size = 0;
+ int res = 0;
+
+ res = xread(v9ses, buf, sizeof(buf));
+ if (res < 0) {
+ dprintk(DEBUG_ERROR,
+ "Reading of count field failed returned: %d\n", res);
+ return res;
+ }
+
+ if (res < 4) {
+ dprintk(DEBUG_ERROR,
+ "Reading of count field failed returned: %d\n", res);
+ return -EIO;
+ }
+
+ size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ dprintk(DEBUG_MUX, "got a packet count: %d\n", size);
+
+ /* adjust for the four bytes of size */
+ size -= 4;
+
+ if (size > v9ses->maxdata) {
+ dprintk(DEBUG_ERROR, "packet too big: %d\n", size);
+ return -E2BIG;
+ }
+
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data) {
+ eprintk(KERN_WARNING, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ res = xread(v9ses, data, size);
+ if (res < size) {
+ dprintk(DEBUG_ERROR, "Reading of fcall failed returned: %d\n",
+ res);
+ kfree(data);
+ return res;
+ }
+
+ /* we now have an in-memory string that is the reply.
+ * deserialize it. There is very little to go wrong at this point
+ * save for v9fs_alloc errors.
+ */
+ res = v9fs_deserialize_fcall(v9ses, size, data, v9ses->maxdata,
+ rcall, rcalllen);
+
+ kfree(data);
+
+ if (res < 0)
+ return res;
+
+ return 0;
+}
+
+/**
+ * v9fs_recv - receive an RPC response for a particular tag
+ * @v9ses: session info structure
+ * @req: RPC request structure
+ *
+ */
+
+static int v9fs_recv(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+{
+ int ret = 0;
+
+ dprintk(DEBUG_MUX, "waiting for response: %d\n", req->tcall->tag);
+ ret = wait_event_interruptible(v9ses->read_wait,
+ ((v9ses->transport->status != Connected) ||
+ (req->rcall != 0) || (req->err < 0) ||
+ dprintcond(v9ses, req)));
+
+ dprintk(DEBUG_MUX, "got it: rcall %p\n", req->rcall);
+
+ spin_lock(&v9ses->muxlock);
+ list_del(&req->next);
+ spin_unlock(&v9ses->muxlock);
+
+ if (req->err < 0)
+ return req->err;
+
+ if (v9ses->transport->status == Disconnected)
+ return -ECONNRESET;
+
+ return ret;
+}
+
+/**
+ * v9fs_send - send a 9P request
+ * @v9ses: session info structure
+ * @req: RPC request to send
+ *
+ */
+
+static int v9fs_send(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+{
+ int ret = -1;
+ void *data = NULL;
+ struct v9fs_fcall *tcall = req->tcall;
+
+ data = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ tcall->size = 0; /* enforce size recalculation */
+ ret =
+ v9fs_serialize_fcall(v9ses, tcall, data,
+ v9ses->maxdata + V9FS_IOHDRSZ);
+ if (ret < 0)
+ goto free_data;
+
+ spin_lock(&v9ses->muxlock);
+ list_add(&req->next, &v9ses->mux_fcalls);
+ spin_unlock(&v9ses->muxlock);
+
+ dprintk(DEBUG_MUX, "sending message: tag %d size %d\n", tcall->tag,
+ tcall->size);
+ ret = v9ses->transport->write(v9ses->transport, data, tcall->size);
+
+ if (ret != tcall->size) {
+ spin_lock(&v9ses->muxlock);
+ list_del(&req->next);
+ kfree(req->rcall);
+
+ spin_unlock(&v9ses->muxlock);
+ if (ret >= 0)
+ ret = -EREMOTEIO;
+ } else
+ ret = 0;
+
+ free_data:
+ kfree(data);
+ return ret;
+}
+
+/**
+ * v9fs_mux_rpc - send a request, receive a response
+ * @v9ses: session info structure
+ * @tcall: fcall to send
+ * @rcall: buffer to place response into
+ *
+ */
+
+long
+v9fs_mux_rpc(struct v9fs_session_info *v9ses, struct v9fs_fcall *tcall,
+ struct v9fs_fcall **rcall)
+{
+ int tid = -1;
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_rpcreq req;
+ int ret = -1;
+
+ if (!v9ses)
+ return -EINVAL;
+
+ if (!v9ses->transport || v9ses->transport->status != Connected)
+ return -EIO;
+
+ if (rcall)
+ *rcall = NULL;
+
+ if (tcall->id != TVERSION) {
+ tid = v9fs_get_idpool(&v9ses->tidpool);
+ if (tid < 0)
+ return -ENOMEM;
+ }
+
+ tcall->tag = tid;
+
+ req.tcall = tcall;
+ req.err = 0;
+ req.rcall = NULL;
+
+ ret = v9fs_send(v9ses, &req);
+
+ if (ret < 0) {
+ if (tcall->id != TVERSION)
+ v9fs_put_idpool(tid, &v9ses->tidpool);
+ dprintk(DEBUG_MUX, "error %d\n", ret);
+ return ret;
+ }
+
+ ret = v9fs_recv(v9ses, &req);
+
+ fcall = req.rcall;
+
+ dprintk(DEBUG_MUX, "received: tag=%x, ret=%d\n", tcall->tag, ret);
+ if (ret == -ERESTARTSYS) {
+ if (v9ses->transport->status != Disconnected
+ && tcall->id != TFLUSH) {
+ unsigned long flags;
+
+ dprintk(DEBUG_MUX, "flushing the tag: %d\n",
+ tcall->tag);
+ clear_thread_flag(TIF_SIGPENDING);
+ v9fs_t_flush(v9ses, tcall->tag);
+ spin_lock_irqsave(&current->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(&current->sighand->siglock,
+ flags);
+ dprintk(DEBUG_MUX, "flushing done\n");
+ }
+
+ goto release_req;
+ } else if (ret < 0)
+ goto release_req;
+
+ if (!fcall)
+ ret = -EIO;
+ else {
+ if (fcall->id == RERROR) {
+ ret = v9fs_errstr2errno(fcall->params.rerror.error);
+ if (ret == 0) { /* string match failed */
+ if (fcall->params.rerror.errno)
+ ret = -(fcall->params.rerror.errno);
+ else
+ ret = -ESERVERFAULT;
+ }
+ } else if (fcall->id != tcall->id + 1) {
+ dprintk(DEBUG_ERROR,
+ "fcall mismatch: expected %d, got %d\n",
+ tcall->id + 1, fcall->id);
+ ret = -EIO;
+ }
+ }
+
+ release_req:
+ if (tcall->id != TVERSION)
+ v9fs_put_idpool(tid, &v9ses->tidpool);
+ if (rcall)
+ *rcall = fcall;
+ else
+ kfree(fcall);
+
+ return ret;
+}
+
+/**
+ * v9fs_mux_cancel_requests - cancels all pending requests
+ *
+ * @v9ses: session info structure
+ * @err: error code to return to the requests
+ */
+void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err)
+{
+ struct v9fs_rpcreq *rptr;
+ struct v9fs_rpcreq *rreq;
+
+ dprintk(DEBUG_MUX, " %d\n", err);
+ spin_lock(&v9ses->muxlock);
+ list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
+ rreq->err = err;
+ }
+ spin_unlock(&v9ses->muxlock);
+ wake_up_all(&v9ses->read_wait);
+}
+
+/**
+ * v9fs_recvproc - kproc to handle demultiplexing responses
+ * @data: session info structure
+ *
+ */
+
+static int v9fs_recvproc(void *data)
+{
+ struct v9fs_session_info *v9ses = (struct v9fs_session_info *)data;
+ struct v9fs_fcall *rcall = NULL;
+ struct v9fs_rpcreq *rptr;
+ struct v9fs_rpcreq *req;
+ struct v9fs_rpcreq *rreq;
+ int err = 0;
+
+ allow_signal(SIGKILL);
+ set_current_state(TASK_INTERRUPTIBLE);
+ complete(&v9ses->proccmpl);
+ while (!kthread_should_stop() && err >= 0) {
+ req = rptr = rreq = NULL;
+
+ rcall = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
+ if (!rcall) {
+ eprintk(KERN_ERR, "no memory for buffers\n");
+ break;
+ }
+
+ err = read_message(v9ses, rcall, v9ses->maxdata + V9FS_IOHDRSZ);
+ spin_lock(&v9ses->muxlock);
+ if (err < 0) {
+ list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
+ rreq->err = err;
+ }
+ if(err != -ERESTARTSYS)
+ eprintk(KERN_ERR,
+ "Transport error while reading message %d\n", err);
+ } else {
+ list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
+ if (rreq->tcall->tag == rcall->tag) {
+ req = rreq;
+ req->rcall = rcall;
+ break;
+ }
+ }
+ }
+
+ if (req && (req->tcall->id == TFLUSH)) {
+ struct v9fs_rpcreq *treq = NULL;
+ list_for_each_entry_safe(treq, rptr, &v9ses->mux_fcalls, next) {
+ if (treq->tcall->tag ==
+ req->tcall->params.tflush.oldtag) {
+ list_del(&rptr->next);
+ kfree(treq->rcall);
+ break;
+ }
+ }
+ }
+
+ spin_unlock(&v9ses->muxlock);
+
+ if (!req) {
+ if (err >= 0)
+ dprintk(DEBUG_ERROR,
+ "unexpected response: id %d tag %d\n",
+ rcall->id, rcall->tag);
+
+ kfree(rcall);
+ }
+
+ wake_up_all(&v9ses->read_wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
+ v9ses->transport->close(v9ses->transport);
+
+ /* Inform all pending processes about the failure */
+ wake_up_all(&v9ses->read_wait);
+
+ if (signal_pending(current))
+ complete(&v9ses->proccmpl);
+
+ dprintk(DEBUG_MUX, "recvproc: end\n");
+ v9ses->recvproc = NULL;
+
+ return err >= 0;
+}
+
+/**
+ * v9fs_mux_init - initialize multiplexer (spawn kproc)
+ * @v9ses: session info structure
+ * @dev_name: mount device information (to create unique kproc)
+ *
+ */
+
+int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name)
+{
+ char procname[60];
+
+ strncpy(procname, dev_name, sizeof(procname));
+ procname[sizeof(procname) - 1] = 0;
+
+ init_waitqueue_head(&v9ses->read_wait);
+ init_completion(&v9ses->fcread);
+ init_completion(&v9ses->proccmpl);
+ spin_lock_init(&v9ses->muxlock);
+ INIT_LIST_HEAD(&v9ses->mux_fcalls);
+ v9ses->recvproc = NULL;
+ v9ses->curfcall = NULL;
+
+ v9ses->recvproc = kthread_create(v9fs_recvproc, v9ses,
+ "v9fs_recvproc %s", procname);
+
+ if (IS_ERR(v9ses->recvproc)) {
+ eprintk(KERN_ERR, "cannot create receiving thread\n");
+ v9fs_session_close(v9ses);
+ return -ECONNABORTED;
+ }
+
+ wake_up_process(v9ses->recvproc);
+ wait_for_completion(&v9ses->proccmpl);
+
+ return 0;
+}
diff --git a/fs/9p/mux.h b/fs/9p/mux.h
new file mode 100644
index 00000000000..4994cb10bad
--- /dev/null
+++ b/fs/9p/mux.h
@@ -0,0 +1,41 @@
+/*
+ * linux/fs/9p/mux.h
+ *
+ * Multiplexer Definitions
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+/* structure to manage each RPC transaction */
+
+struct v9fs_rpcreq {
+ struct v9fs_fcall *tcall;
+ struct v9fs_fcall *rcall;
+ int err; /* error code if response failed */
+
+ /* XXX - could we put scatter/gather buffers here? */
+
+ struct list_head next;
+};
+
+int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name);
+long v9fs_mux_rpc(struct v9fs_session_info *v9ses,
+ struct v9fs_fcall *tcall, struct v9fs_fcall **rcall);
+void 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 00000000000..63b58ce98ff
--- /dev/null
+++ b/fs/9p/trans_fd.c
@@ -0,0 +1,172 @@
+/*
+ * linux/fs/9p/trans_fd.c
+ *
+ * File Descriptor Transport Layer
+ *
+ * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/ipv6.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/un.h>
+#include <asm/uaccess.h>
+#include <linux/inet.h>
+#include <linux/idr.h>
+#include <linux/file.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "transport.h"
+
+struct v9fs_trans_fd {
+ struct file *in_file;
+ struct file *out_file;
+};
+
+/**
+ * v9fs_fd_recv - receive from a socket
+ * @v9ses: session information
+ * @v: buffer to receive data into
+ * @len: size of receive buffer
+ *
+ */
+
+static int v9fs_fd_recv(struct v9fs_transport *trans, void *v, int len)
+{
+ struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;
+
+ if (!trans || trans->status != Connected || !ts)
+ return -EIO;
+
+ return kernel_read(ts->in_file, ts->in_file->f_pos, v, len);
+}
+
+/**
+ * v9fs_fd_send - send to a socket
+ * @v9ses: session information
+ * @v: buffer to send data from
+ * @len: size of send buffer
+ *
+ */
+
+static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len)
+{
+ struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;
+ mm_segment_t oldfs = get_fs();
+ int ret = 0;
+
+ if (!trans || trans->status != Connected || !ts)
+ return -EIO;
+
+ set_fs(get_ds());
+ /* The cast to a user pointer is valid due to the set_fs() */
+ ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos);
+ set_fs(oldfs);
+
+ return ret;
+}
+
+/**
+ * v9fs_fd_init - initialize file descriptor transport
+ * @v9ses: session information
+ * @addr: address of server to mount
+ * @data: mount options
+ *
+ */
+
+static int
+v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
+{
+ struct v9fs_trans_fd *ts = NULL;
+ struct v9fs_transport *trans = v9ses->transport;
+
+ if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) {
+ printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
+ return -ENOPROTOOPT;
+ }
+
+ sema_init(&trans->writelock, 1);
+ sema_init(&trans->readlock, 1);
+
+ ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL);
+
+ if (!ts)
+ return -ENOMEM;
+
+ ts->in_file = fget( v9ses->rfdno );
+ ts->out_file = fget( v9ses->wfdno );
+
+ if (!ts->in_file || !ts->out_file) {
+ if (ts->in_file)
+ fput(ts->in_file);
+
+ if (ts->out_file)
+ fput(ts->out_file);
+
+ kfree(ts);
+ return -EIO;
+ }
+
+ trans->priv = ts;
+ trans->status = Connected;
+
+ return 0;
+}
+
+
+/**
+ * v9fs_fd_close - shutdown file descriptor
+ * @trans: private socket structure
+ *
+ */
+
+static void v9fs_fd_close(struct v9fs_transport *trans)
+{
+ struct v9fs_trans_fd *ts;
+
+ if (!trans)
+ return;
+
+ trans->status = Disconnected;
+ ts = trans->priv;
+
+ if (!ts)
+ return;
+
+ if (ts->in_file)
+ fput(ts->in_file);
+
+ if (ts->out_file)
+ fput(ts->out_file);
+
+ kfree(ts);
+}
+
+struct v9fs_transport v9fs_trans_fd = {
+ .init = v9fs_fd_init,
+ .write = v9fs_fd_send,
+ .read = v9fs_fd_recv,
+ .close = v9fs_fd_close,
+};
+
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
new file mode 100644
index 00000000000..01e26f0013a
--- /dev/null
+++ b/fs/9p/trans_sock.c
@@ -0,0 +1,290 @@
+/*
+ * linux/fs/9p/trans_socket.c
+ *
+ * Socket Transport Layer
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
+ * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/ipv6.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/un.h>
+#include <asm/uaccess.h>
+#include <linux/inet.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "transport.h"
+
+#define V9FS_PORT 564
+
+struct v9fs_trans_sock {
+ struct socket *s;
+};
+
+/**
+ * v9fs_sock_recv - receive from a socket
+ * @v9ses: session information
+ * @v: buffer to receive data into
+ * @len: size of receive buffer
+ *
+ */
+
+static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int result;
+ mm_segment_t oldfs;
+ struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
+
+ if (trans->status == Disconnected)
+ return -EREMOTEIO;
+
+ result = -EINVAL;
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ iov.iov_base = v;
+ iov.iov_len = len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_namelen = 0;
+ msg.msg_flags = MSG_NOSIGNAL;
+
+ result = kernel_recvmsg(ts->s, &msg, &iov, 1, len, 0);
+
+ dprintk(DEBUG_TRANS, "socket state %d\n", ts->s->state);
+ set_fs(oldfs);
+
+ if (result <= 0) {
+ if (result != -ERESTARTSYS)
+ trans->status = Disconnected;
+ }
+
+ return result;
+}
+
+/**
+ * v9fs_sock_send - send to a socket
+ * @v9ses: session information
+ * @v: buffer to send data from
+ * @len: size of send buffer
+ *
+ */
+
+static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
+{
+ struct kvec iov;
+ struct msghdr msg;
+ int result = -1;
+ mm_segment_t oldfs;
+ struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
+
+ dprintk(DEBUG_TRANS, "Sending packet size %d (%x)\n", len, len);
+ dump_data(v, len);
+
+ down(&trans->writelock);
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+ iov.iov_base = v;
+ iov.iov_len = len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_namelen = 0;
+ msg.msg_flags = MSG_NOSIGNAL;
+ result = kernel_sendmsg(ts->s, &msg, &iov, 1, len);
+ set_fs(oldfs);
+
+ if (result < 0) {
+ if (result != -ERESTARTSYS)
+ trans->status = Disconnected;
+ }
+
+ up(&trans->writelock);
+ return result;
+}
+
+/**
+ * v9fs_tcp_init - initialize TCP socket
+ * @v9ses: session information
+ * @addr: address of server to mount
+ * @data: mount options
+ *
+ */
+
+static int
+v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
+{
+ struct socket *csocket = NULL;
+ struct sockaddr_in sin_server;
+ int rc = 0;
+ struct v9fs_trans_sock *ts = NULL;
+ struct v9fs_transport *trans = v9ses->transport;
+
+ sema_init(&trans->writelock, 1);
+ sema_init(&trans->readlock, 1);
+
+ ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
+
+ if (!ts)
+ return -ENOMEM;
+
+ trans->priv = ts;
+ ts->s = NULL;
+
+ if (!addr)
+ return -EINVAL;
+
+ dprintk(DEBUG_TRANS, "Connecting to %s\n", addr);
+
+ sin_server.sin_family = AF_INET;
+ sin_server.sin_addr.s_addr = in_aton(addr);
+ sin_server.sin_port = htons(v9ses->port);
+ sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
+ rc = csocket->ops->connect(csocket,
+ (struct sockaddr *)&sin_server,
+ sizeof(struct sockaddr_in), 0);
+ if (rc < 0) {
+ eprintk(KERN_ERR,
+ "v9fs_trans_tcp: problem connecting socket to %s\n",
+ addr);
+ return rc;
+ }
+ csocket->sk->sk_allocation = GFP_NOIO;
+ ts->s = csocket;
+ trans->status = Connected;
+
+ return 0;
+}
+
+/**
+ * v9fs_unix_init - initialize UNIX domain socket
+ * @v9ses: session information
+ * @dev_name: path to named pipe
+ * @data: mount options
+ *
+ */
+
+static int
+v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
+ char *data)
+{
+ int rc;
+ struct socket *csocket;
+ struct sockaddr_un sun_server;
+ struct v9fs_transport *trans;
+ struct v9fs_trans_sock *ts;
+
+ rc = 0;
+ csocket = NULL;
+ trans = v9ses->transport;
+
+ if (strlen(dev_name) > UNIX_PATH_MAX) {
+ eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
+ dev_name);
+ return -ENOMEM;
+ }
+
+ ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ trans->priv = ts;
+ ts->s = NULL;
+
+ sema_init(&trans->writelock, 1);
+ sema_init(&trans->readlock, 1);
+
+ sun_server.sun_family = PF_UNIX;
+ strcpy(sun_server.sun_path, dev_name);
+ sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
+ rc = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
+ sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */
+ if (rc < 0) {
+ eprintk(KERN_ERR,
+ "v9fs_trans_unix: problem connecting socket: %s: %d\n",
+ dev_name, rc);
+ return rc;
+ }
+ csocket->sk->sk_allocation = GFP_NOIO;
+ ts->s = csocket;
+ trans->status = Connected;
+
+ return 0;
+}
+
+/**
+ * v9fs_sock_close - shutdown socket
+ * @trans: private socket structure
+ *
+ */
+
+static void v9fs_sock_close(struct v9fs_transport *trans)
+{
+ struct v9fs_trans_sock *ts;
+
+ if (!trans)
+ return;
+
+ ts = trans->priv;
+
+ if ((ts) && (ts->s)) {
+ dprintk(DEBUG_TRANS, "closing the socket %p\n", ts->s);
+ sock_release(ts->s);
+ ts->s = NULL;
+ trans->status = Disconnected;
+ dprintk(DEBUG_TRANS, "socket closed\n");
+ }
+
+ if (ts)
+ kfree(ts);
+
+ trans->priv = NULL;
+}
+
+struct v9fs_transport v9fs_trans_tcp = {
+ .init = v9fs_tcp_init,
+ .write = v9fs_sock_send,
+ .read = v9fs_sock_recv,
+ .close = v9fs_sock_close,
+};
+
+struct v9fs_transport v9fs_trans_unix = {
+ .init = v9fs_unix_init,
+ .write = v9fs_sock_send,
+ .read = v9fs_sock_recv,
+ .close = v9fs_sock_close,
+};
diff --git a/fs/9p/transport.h b/fs/9p/transport.h
new file mode 100644
index 00000000000..9e9cd418efd
--- /dev/null
+++ b/fs/9p/transport.h
@@ -0,0 +1,46 @@
+/*
+ * linux/fs/9p/transport.h
+ *
+ * Transport Definition
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+enum v9fs_transport_status {
+ Connected,
+ Disconnected,
+ Hung,
+};
+
+struct v9fs_transport {
+ enum v9fs_transport_status status;
+ struct semaphore writelock;
+ struct semaphore readlock;
+ void *priv;
+
+ int (*init) (struct v9fs_session_info *, const char *, char *);
+ int (*write) (struct v9fs_transport *, void *, int);
+ int (*read) (struct v9fs_transport *, void *, int);
+ void (*close) (struct v9fs_transport *);
+};
+
+extern struct v9fs_transport v9fs_trans_tcp;
+extern struct v9fs_transport v9fs_trans_unix;
+extern struct v9fs_transport v9fs_trans_fd;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
new file mode 100644
index 00000000000..13bdbbab438
--- /dev/null
+++ b/fs/9p/v9fs.c
@@ -0,0 +1,452 @@
+/*
+ * linux/fs/9p/v9fs.c
+ *
+ * This file contains functions assisting in mapping VFS to 9P2000
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/parser.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "transport.h"
+#include "mux.h"
+#include "conv.h"
+
+/* TODO: sysfs or debugfs interface */
+int v9fs_debug_level = 0; /* feature-rific global debug level */
+
+/*
+ * Option Parsing (code inspired by NFS code)
+ *
+ */
+
+enum {
+ /* Options that take integer arguments */
+ Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug,
+ Opt_rfdno, Opt_wfdno,
+ /* String options */
+ Opt_name, Opt_remotename,
+ /* Options that take no arguments */
+ Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
+ /* Error token */
+ Opt_err
+};
+
+static match_table_t tokens = {
+ {Opt_port, "port=%u"},
+ {Opt_msize, "msize=%u"},
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_afid, "afid=%u"},
+ {Opt_rfdno, "rfdno=%u"},
+ {Opt_wfdno, "wfdno=%u"},
+ {Opt_debug, "debug=%u"},
+ {Opt_name, "name=%s"},
+ {Opt_remotename, "aname=%s"},
+ {Opt_unix, "proto=unix"},
+ {Opt_tcp, "proto=tcp"},
+ {Opt_fd, "proto=fd"},
+ {Opt_tcp, "tcp"},
+ {Opt_unix, "unix"},
+ {Opt_fd, "fd"},
+ {Opt_legacy, "noextend"},
+ {Opt_nodevmap, "nodevmap"},
+ {Opt_err, NULL}
+};
+
+/*
+ * Parse option string.
+ */
+
+/**
+ * v9fs_parse_options - parse mount options into session structure
+ * @options: options string passed from mount
+ * @v9ses: existing v9fs session information
+ *
+ */
+
+static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
+{
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+ int ret;
+
+ /* setup defaults */
+ v9ses->port = V9FS_PORT;
+ v9ses->maxdata = 9000;
+ v9ses->proto = PROTO_TCP;
+ v9ses->extended = 1;
+ v9ses->afid = ~0;
+ v9ses->debug = 0;
+ v9ses->rfdno = ~0;
+ v9ses->wfdno = ~0;
+
+ if (!options)
+ return;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+ token = match_token(p, tokens, args);
+ if (token < Opt_name) {
+ if ((ret = match_int(&args[0], &option)) < 0) {
+ dprintk(DEBUG_ERROR,
+ "integer field, but no integer?\n");
+ continue;
+ }
+
+ }
+ switch (token) {
+ case Opt_port:
+ v9ses->port = option;
+ break;
+ case Opt_msize:
+ v9ses->maxdata = option;
+ break;
+ case Opt_uid:
+ v9ses->uid = option;
+ break;
+ case Opt_gid:
+ v9ses->gid = option;
+ break;
+ case Opt_afid:
+ v9ses->afid = option;
+ break;
+ case Opt_rfdno:
+ v9ses->rfdno = option;
+ break;
+ case Opt_wfdno:
+ v9ses->wfdno = option;
+ break;
+ case Opt_debug:
+ v9ses->debug = option;
+ break;
+ case Opt_tcp:
+ v9ses->proto = PROTO_TCP;
+ break;
+ case Opt_unix:
+ v9ses->proto = PROTO_UNIX;
+ break;
+ case Opt_fd:
+ v9ses->proto = PROTO_FD;
+ break;
+ case Opt_name:
+ match_strcpy(v9ses->name, &args[0]);
+ break;
+ case Opt_remotename:
+ match_strcpy(v9ses->remotename, &args[0]);
+ break;
+ case Opt_legacy:
+ v9ses->extended = 0;
+ break;
+ case Opt_nodevmap:
+ v9ses->nodev = 1;
+ break;
+ default:
+ continue;
+ }
+ }
+}
+
+/**
+ * v9fs_inode2v9ses - safely extract v9fs session info from super block
+ * @inode: inode to extract information from
+ *
+ * Paranoid function to extract v9ses information from superblock,
+ * if anything is missing it will report an error.
+ *
+ */
+
+struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
+{
+ return (inode->i_sb->s_fs_info);
+}
+
+/**
+ * v9fs_get_idpool - allocate numeric id from pool
+ * @p - pool to allocate from
+ *
+ * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * the lock included in struct idr?
+ */
+
+int v9fs_get_idpool(struct v9fs_idpool *p)
+{
+ int i = 0;
+ int error;
+
+retry:
+ if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
+ return 0;
+
+ if (down_interruptible(&p->lock) == -EINTR) {
+ eprintk(KERN_WARNING, "Interrupted while locking\n");
+ return -1;
+ }
+
+ error = idr_get_new(&p->pool, NULL, &i);
+ up(&p->lock);
+
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error)
+ return -1;
+
+ return i;
+}
+
+/**
+ * v9fs_put_idpool - release numeric id from pool
+ * @p - pool to allocate from
+ *
+ * XXX - This seems to be an awful generic function, should it be in idr.c with
+ * the lock included in struct idr?
+ */
+
+void v9fs_put_idpool(int id, struct v9fs_idpool *p)
+{
+ if (down_interruptible(&p->lock) == -EINTR) {
+ eprintk(KERN_WARNING, "Interrupted while locking\n");
+ return;
+ }
+ idr_remove(&p->pool, id);
+ up(&p->lock);
+}
+
+/**
+ * v9fs_session_init - initialize session
+ * @v9ses: session information structure
+ * @dev_name: device being mounted
+ * @data: options
+ *
+ */
+
+int
+v9fs_session_init(struct v9fs_session_info *v9ses,
+ const char *dev_name, char *data)
+{
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_transport *trans_proto;
+ int n = 0;
+ int newfid = -1;
+ int retval = -EINVAL;
+
+ v9ses->name = __getname();
+ if (!v9ses->name)
+ return -ENOMEM;
+
+ v9ses->remotename = __getname();
+ if (!v9ses->remotename) {
+ putname(v9ses->name);
+ return -ENOMEM;
+ }
+
+ strcpy(v9ses->name, V9FS_DEFUSER);
+ strcpy(v9ses->remotename, V9FS_DEFANAME);
+
+ v9fs_parse_options(data, v9ses);
+
+ /* set global debug level */
+ v9fs_debug_level = v9ses->debug;
+
+ /* id pools that are session-dependent: FIDs and TIDs */
+ idr_init(&v9ses->fidpool.pool);
+ init_MUTEX(&v9ses->fidpool.lock);
+ idr_init(&v9ses->tidpool.pool);
+ init_MUTEX(&v9ses->tidpool.lock);
+
+
+ switch (v9ses->proto) {
+ case PROTO_TCP:
+ trans_proto = &v9fs_trans_tcp;
+ break;
+ case PROTO_UNIX:
+ trans_proto = &v9fs_trans_unix;
+ *v9ses->remotename = 0;
+ break;
+ case PROTO_FD:
+ trans_proto = &v9fs_trans_fd;
+ *v9ses->remotename = 0;
+ break;
+ default:
+ printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
+ retval = -ENOPROTOOPT;
+ goto SessCleanUp;
+ };
+
+ v9ses->transport = trans_proto;
+
+ if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) {
+ eprintk(KERN_ERR, "problem initializing transport\n");
+ goto SessCleanUp;
+ }
+
+ v9ses->inprogress = 0;
+ v9ses->shutdown = 0;
+ v9ses->session_hung = 0;
+
+ if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) {
+ dprintk(DEBUG_ERROR, "problem initializing mux\n");
+ goto SessCleanUp;
+ }
+
+ if (v9ses->afid == ~0) {
+ if (v9ses->extended)
+ retval =
+ v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u",
+ &fcall);
+ else
+ retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000",
+ &fcall);
+
+ if (retval < 0) {
+ dprintk(DEBUG_ERROR, "v9fs_t_version failed\n");
+ goto FreeFcall;
+ }
+
+ /* Really should check for 9P1 and report error */
+ if (!strcmp(fcall->params.rversion.version, "9P2000.u")) {
+ dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
+ v9ses->extended = 1;
+ } else {
+ dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
+ v9ses->extended = 0;
+ }
+
+ n = fcall->params.rversion.msize;
+ kfree(fcall);
+
+ if (n < v9ses->maxdata)
+ v9ses->maxdata = n;
+ }
+
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "couldn't allocate FID\n");
+ retval = -ENOMEM;
+ goto SessCleanUp;
+ }
+ /* it is a little bit ugly, but we have to prevent newfid */
+ /* being the same as afid, so if it is, get a new fid */
+ if (v9ses->afid != ~0 && newfid == v9ses->afid) {
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "couldn't allocate FID\n");
+ retval = -ENOMEM;
+ goto SessCleanUp;
+ }
+ }
+
+ if ((retval =
+ v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid,
+ v9ses->afid, NULL))
+ < 0) {
+ dprintk(DEBUG_ERROR, "cannot attach\n");
+ goto SessCleanUp;
+ }
+
+ if (v9ses->afid != ~0) {
+ if (v9fs_t_clunk(v9ses, v9ses->afid, NULL))
+ dprintk(DEBUG_ERROR, "clunk failed\n");
+ }
+
+ return newfid;
+
+ FreeFcall:
+ kfree(fcall);
+
+ SessCleanUp:
+ v9fs_session_close(v9ses);
+ return retval;
+}
+
+/**
+ * v9fs_session_close - shutdown a session
+ * @v9ses: session information structure
+ *
+ */
+
+void v9fs_session_close(struct v9fs_session_info *v9ses)
+{
+ if (v9ses->recvproc) {
+ send_sig(SIGKILL, v9ses->recvproc, 1);
+ wait_for_completion(&v9ses->proccmpl);
+ }
+
+ if (v9ses->transport)
+ v9ses->transport->close(v9ses->transport);
+
+ putname(v9ses->name);
+ putname(v9ses->remotename);
+}
+
+/**
+ * v9fs_session_cancel - mark transport as disconnected
+ * and cancel all pending requests.
+ */
+void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
+ v9ses->transport->status = Disconnected;
+ v9fs_mux_cancel_requests(v9ses, -EIO);
+}
+
+extern int v9fs_error_init(void);
+
+/**
+ * v9fs_init - Initialize module
+ *
+ */
+
+static int __init init_v9fs(void)
+{
+ v9fs_error_init();
+
+ printk(KERN_INFO "Installing v9fs 9P2000 file system support\n");
+
+ return register_filesystem(&v9fs_fs_type);
+}
+
+/**
+ * v9fs_init - shutdown module
+ *
+ */
+
+static void __exit exit_v9fs(void)
+{
+ unregister_filesystem(&v9fs_fs_type);
+}
+
+module_init(init_v9fs)
+module_exit(exit_v9fs)
+
+MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
+MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
+MODULE_LICENSE("GPL");
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
new file mode 100644
index 00000000000..45dcef42bdd
--- /dev/null
+++ b/fs/9p/v9fs.h
@@ -0,0 +1,103 @@
+/*
+ * V9FS definitions.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+/*
+ * Idpool structure provides lock and id management
+ *
+ */
+
+struct v9fs_idpool {
+ struct semaphore lock;
+ struct idr pool;
+};
+
+/*
+ * Session structure provides information for an opened session
+ *
+ */
+
+struct v9fs_session_info {
+ /* options */
+ unsigned int maxdata;
+ unsigned char extended; /* set to 1 if we are using UNIX extensions */
+ unsigned char nodev; /* set to 1 if no disable device mapping */
+ unsigned short port; /* port to connect to */
+ unsigned short debug; /* debug level */
+ unsigned short proto; /* protocol to use */
+ unsigned int afid; /* authentication fid */
+ unsigned int rfdno; /* read file descriptor number */
+ unsigned int wfdno; /* write file descriptor number */
+
+
+ char *name; /* user name to mount as */
+ char *remotename; /* name of remote hierarchy being mounted */
+ unsigned int uid; /* default uid/muid for legacy support */
+ unsigned int gid; /* default gid for legacy support */
+
+ /* book keeping */
+ struct v9fs_idpool fidpool; /* The FID pool for file descriptors */
+ struct v9fs_idpool tidpool; /* The TID pool for transactions ids */
+
+ /* transport information */
+ struct v9fs_transport *transport;
+
+ int inprogress; /* session in progress => true */
+ int shutdown; /* session shutting down. no more attaches. */
+ unsigned char session_hung;
+
+ /* mux private data */
+ struct v9fs_fcall *curfcall;
+ wait_queue_head_t read_wait;
+ struct completion fcread;
+ struct completion proccmpl;
+ struct task_struct *recvproc;
+
+ spinlock_t muxlock;
+ struct list_head mux_fcalls;
+};
+
+/* possible values of ->proto */
+enum {
+ PROTO_TCP,
+ PROTO_UNIX,
+ PROTO_FD,
+};
+
+int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
+struct v9fs_session_info *v9fs_inode2v9ses(struct inode *);
+void v9fs_session_close(struct v9fs_session_info *v9ses);
+int v9fs_get_idpool(struct v9fs_idpool *p);
+void v9fs_put_idpool(int id, struct v9fs_idpool *p);
+void v9fs_session_cancel(struct v9fs_session_info *v9ses);
+
+#define V9FS_MAGIC 0x01021997
+
+/* other default globals */
+#define V9FS_PORT 564
+#define V9FS_DEFUSER "nobody"
+#define V9FS_DEFANAME ""
+
+/* inital pool sizes for fids and tags */
+#define V9FS_START_FIDS 8192
+#define V9FS_START_TIDS 256
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
new file mode 100644
index 00000000000..2f2cea7ee3e
--- /dev/null
+++ b/fs/9p/v9fs_vfs.h
@@ -0,0 +1,53 @@
+/*
+ * V9FS VFS extensions.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+/* plan9 semantics are that created files are implicitly opened.
+ * But linux semantics are that you call create, then open.
+ * the plan9 approach is superior as it provides an atomic
+ * open.
+ * we track the create fid here. When the file is opened, if fidopen is
+ * non-zero, we use the fid and can skip some steps.
+ * there may be a better way to do this, but I don't know it.
+ * one BAD way is to clunk the fid on create, then open it again:
+ * you lose the atomicity of file open
+ */
+
+/* special case:
+ * unlink calls remove, which is an implicit clunk. So we have to track
+ * that kind of thing so that we don't try to clunk a dead fid.
+ */
+
+extern struct file_system_type v9fs_fs_type;
+extern struct file_operations v9fs_file_operations;
+extern struct file_operations v9fs_dir_operations;
+extern struct dentry_operations v9fs_dentry_operations;
+
+struct inode *v9fs_get_inode(struct super_block *sb, int mode);
+ino_t v9fs_qid2ino(struct v9fs_qid *qid);
+void v9fs_mistat2inode(struct v9fs_stat *, struct inode *,
+ struct super_block *);
+int v9fs_dir_release(struct inode *inode, struct file *filp);
+int v9fs_file_open(struct inode *inode, struct file *file);
+void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat);
+void v9fs_dentry_release(struct dentry *);
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
new file mode 100644
index 00000000000..306c96741f8
--- /dev/null
+++ b/fs/9p/vfs_dentry.c
@@ -0,0 +1,126 @@
+/*
+ * linux/fs/9p/vfs_dentry.c
+ *
+ * This file contians vfs dentry ops for the 9P2000 protocol.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/namei.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "conv.h"
+#include "fid.h"
+
+/**
+ * v9fs_dentry_validate - VFS dcache hook to validate cache
+ * @dentry: dentry that is being validated
+ * @nd: path data
+ *
+ * dcache really shouldn't be used for 9P2000 as at all due to
+ * potential attached semantics to directory traversal (walk).
+ *
+ * FUTURE: look into how to use dcache to allow multi-stage
+ * walks in Plan 9 & potential for better dcache operation which
+ * would remain valid for Plan 9 semantics. Older versions
+ * had validation via stat for those interested. However, since
+ * stat has the same approximate overhead as walk there really
+ * is no difference. The only improvement would be from a
+ * time-decay cache like NFS has and that undermines the
+ * synchronous nature of 9P2000.
+ *
+ */
+
+static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd)
+{
+ struct dentry *dc = current->fs->pwd;
+
+ dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry);
+ if (v9fs_fid_lookup(dentry, FID_OP)) {
+ dprintk(DEBUG_VFS, "VALID\n");
+ return 1;
+ }
+
+ while (dc != NULL) {
+ if (dc == dentry) {
+ dprintk(DEBUG_VFS, "VALID\n");
+ return 1;
+ }
+ if (dc == dc->d_parent)
+ break;
+
+ dc = dc->d_parent;
+ }
+
+ dprintk(DEBUG_VFS, "INVALID\n");
+ return 0;
+}
+
+/**
+ * v9fs_dentry_release - called when dentry is going to be freed
+ * @dentry: dentry that is being release
+ *
+ */
+
+void v9fs_dentry_release(struct dentry *dentry)
+{
+ dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
+ if (dentry->d_fsdata != NULL) {
+ struct list_head *fid_list = dentry->d_fsdata;
+ struct v9fs_fid *temp = NULL;
+ struct v9fs_fid *current_fid = NULL;
+ struct v9fs_fcall *fcall = NULL;
+
+ list_for_each_entry_safe(current_fid, temp, fid_list, list) {
+ if (v9fs_t_clunk
+ (current_fid->v9ses, current_fid->fid, &fcall))
+ dprintk(DEBUG_ERROR, "clunk failed: %s\n",
+ FCALL_ERROR(fcall));
+
+ v9fs_put_idpool(current_fid->fid,
+ &current_fid->v9ses->fidpool);
+
+ kfree(fcall);
+ v9fs_fid_destroy(current_fid);
+ }
+
+ kfree(dentry->d_fsdata); /* free the list_head */
+ }
+}
+
+struct dentry_operations v9fs_dentry_operations = {
+ .d_revalidate = v9fs_dentry_validate,
+ .d_release = v9fs_dentry_release,
+};
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
new file mode 100644
index 00000000000..c478a738418
--- /dev/null
+++ b/fs/9p/vfs_dir.c
@@ -0,0 +1,226 @@
+/*
+ * linux/fs/9p/vfs_dir.c
+ *
+ * This file contains vfs directory ops for the 9P2000 protocol.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "conv.h"
+#include "fid.h"
+
+/**
+ * dt_type - return file type
+ * @mistat: mistat structure
+ *
+ */
+
+static inline int dt_type(struct v9fs_stat *mistat)
+{
+ unsigned long perm = mistat->mode;
+ int rettype = DT_REG;
+
+ if (perm & V9FS_DMDIR)
+ rettype = DT_DIR;
+ if (perm & V9FS_DMSYMLINK)
+ rettype = DT_LNK;
+
+ return rettype;
+}
+
+/**
+ * v9fs_dir_readdir - read a directory
+ * @filep: opened file structure
+ * @dirent: directory structure ???
+ * @filldir: function to populate directory structure ???
+ *
+ */
+
+static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct v9fs_fcall *fcall = NULL;
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+ struct v9fs_fid *file = filp->private_data;
+ unsigned int i, n;
+ int fid = -1;
+ int ret = 0;
+ struct v9fs_stat *mi = NULL;
+ int over = 0;
+
+ dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name);
+
+ fid = file->fid;
+
+ mi = kmalloc(v9ses->maxdata, GFP_KERNEL);
+ if (!mi)
+ return -ENOMEM;
+
+ if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) {
+ kfree(file->rdir_fcall);
+ file->rdir_fcall = NULL;
+ }
+
+ if (file->rdir_fcall) {
+ n = file->rdir_fcall->params.rread.count;
+ i = file->rdir_fpos;
+ while (i < n) {
+ int s = v9fs_deserialize_stat(v9ses,
+ file->rdir_fcall->params.rread.data + i,
+ n - i, mi, v9ses->maxdata);
+
+ if (s == 0) {
+ dprintk(DEBUG_ERROR,
+ "error while deserializing mistat\n");
+ ret = -EIO;
+ goto FreeStructs;
+ }
+
+ over = filldir(dirent, mi->name, strlen(mi->name),
+ filp->f_pos, v9fs_qid2ino(&mi->qid),
+ dt_type(mi));
+
+ if (over) {
+ file->rdir_fpos = i;
+ file->rdir_pos = filp->f_pos;
+ break;
+ }
+
+ i += s;
+ filp->f_pos += s;
+ }
+
+ if (!over) {
+ kfree(file->rdir_fcall);
+ file->rdir_fcall = NULL;
+ }
+ }
+
+ while (!over) {
+ ret = v9fs_t_read(v9ses, fid, filp->f_pos,
+ v9ses->maxdata-V9FS_IOHDRSZ, &fcall);
+ if (ret < 0) {
+ dprintk(DEBUG_ERROR, "error while reading: %d: %p\n",
+ ret, fcall);
+ goto FreeStructs;
+ } else if (ret == 0)
+ break;
+
+ n = ret;
+ i = 0;
+ while (i < n) {
+ int s = v9fs_deserialize_stat(v9ses,
+ fcall->params.rread.data + i, n - i, mi,
+ v9ses->maxdata);
+
+ if (s == 0) {
+ dprintk(DEBUG_ERROR,
+ "error while deserializing mistat\n");
+ return -EIO;
+ }
+
+ over = filldir(dirent, mi->name, strlen(mi->name),
+ filp->f_pos, v9fs_qid2ino(&mi->qid),
+ dt_type(mi));
+
+ if (over) {
+ file->rdir_fcall = fcall;
+ file->rdir_fpos = i;
+ file->rdir_pos = filp->f_pos;
+ fcall = NULL;
+ break;
+ }
+
+ i += s;
+ filp->f_pos += s;
+ }
+
+ kfree(fcall);
+ }
+
+ FreeStructs:
+ kfree(fcall);
+ kfree(mi);
+ return ret;
+}
+
+/**
+ * v9fs_dir_release - close a directory
+ * @inode: inode of the directory
+ * @filp: file pointer to a directory
+ *
+ */
+
+int v9fs_dir_release(struct inode *inode, struct file *filp)
+{
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+ struct v9fs_fid *fid = filp->private_data;
+ int fidnum = -1;
+
+ dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp,
+ fid->fid);
+ fidnum = fid->fid;
+
+ filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawait(inode->i_mapping);
+
+ if (fidnum >= 0) {
+ fid->fidopen--;
+ dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
+ fid->fid);
+
+ if (fid->fidopen == 0) {
+ if (v9fs_t_clunk(v9ses, fidnum, NULL))
+ dprintk(DEBUG_ERROR, "clunk failed\n");
+
+ v9fs_put_idpool(fid->fid, &v9ses->fidpool);
+ }
+
+ kfree(fid->rdir_fcall);
+
+ filp->private_data = NULL;
+ v9fs_fid_destroy(fid);
+ }
+
+ d_drop(filp->f_dentry);
+ return 0;
+}
+
+struct file_operations v9fs_dir_operations = {
+ .read = generic_read_dir,
+ .readdir = v9fs_dir_readdir,
+ .open = v9fs_file_open,
+ .release = v9fs_dir_release,
+};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
new file mode 100644
index 00000000000..1f8ae7d580a
--- /dev/null
+++ b/fs/9p/vfs_file.c
@@ -0,0 +1,401 @@
+/*
+ * linux/fs/9p/vfs_file.c
+ *
+ * This file contians vfs file ops for 9P2000.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/version.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "fid.h"
+
+/**
+ * v9fs_file_open - open a file (or directory)
+ * @inode: inode to be opened
+ * @file: file being opened
+ *
+ */
+
+int v9fs_file_open(struct inode *inode, struct file *file)
+{
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+ struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK);
+ struct v9fs_fid *v9newfid = NULL;
+ struct v9fs_fcall *fcall = NULL;
+ int open_mode = 0;
+ unsigned int iounit = 0;
+ int newfid = -1;
+ long result = -1;
+
+ dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file,
+ v9fid);
+
+ if (!v9fid) {
+ struct dentry *dentry = file->f_dentry;
+ dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
+
+ /* XXX - some duplication from lookup, generalize later */
+ /* basically vfs_lookup is too heavy weight */
+ v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP);
+ if (!v9fid)
+ return -EBADF;
+
+ v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
+ if (!v9fid)
+ return -EBADF;
+
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "newfid fails!\n");
+ return -ENOSPC;
+ }
+
+ result =
+ v9fs_t_walk(v9ses, v9fid->fid, newfid,
+ (char *)file->f_dentry->d_name.name, NULL);
+ if (result < 0) {
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ dprintk(DEBUG_ERROR, "rewalk didn't work\n");
+ return -EBADF;
+ }
+
+ v9fid = v9fs_fid_create(dentry);
+ if (v9fid == NULL) {
+ dprintk(DEBUG_ERROR, "couldn't insert\n");
+ return -ENOMEM;
+ }
+ v9fid->fid = newfid;
+ }
+
+ if (v9fid->fidcreate) {
+ /* create case */
+ newfid = v9fid->fid;
+ iounit = v9fid->iounit;
+ v9fid->fidcreate = 0;
+ } else {
+ if (!S_ISDIR(inode->i_mode))
+ newfid = v9fid->fid;
+ else {
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "allocation failed\n");
+ return -ENOSPC;
+ }
+ /* This would be a somewhat critical clone */
+ result =
+ v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL,
+ &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "clone error: %s\n",
+ FCALL_ERROR(fcall));
+ kfree(fcall);
+ return result;
+ }
+
+ v9newfid = v9fs_fid_create(file->f_dentry);
+ v9newfid->fid = newfid;
+ v9newfid->qid = v9fid->qid;
+ v9newfid->iounit = v9fid->iounit;
+ v9newfid->fidopen = 0;
+ v9newfid->fidclunked = 0;
+ v9newfid->v9ses = v9ses;
+ v9fid = v9newfid;
+ kfree(fcall);
+ }
+
+ /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
+ /* translate open mode appropriately */
+ open_mode = file->f_flags & 0x3;
+
+ if (file->f_flags & O_EXCL)
+ open_mode |= V9FS_OEXCL;
+
+ if (v9ses->extended) {
+ if (file->f_flags & O_TRUNC)
+ open_mode |= V9FS_OTRUNC;
+
+ if (file->f_flags & O_APPEND)
+ open_mode |= V9FS_OAPPEND;
+ }
+
+ result = v9fs_t_open(v9ses, newfid, open_mode, &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR,
+ "open failed, open_mode 0x%x: %s\n", open_mode,
+ FCALL_ERROR(fcall));
+ kfree(fcall);
+ return result;
+ }
+
+ iounit = fcall->params.ropen.iounit;
+ kfree(fcall);
+ }
+
+
+ file->private_data = v9fid;
+
+ v9fid->rdir_pos = 0;
+ v9fid->rdir_fcall = NULL;
+ v9fid->fidopen = 1;
+ v9fid->filp = file;
+ v9fid->iounit = iounit;
+
+ return 0;
+}
+
+/**
+ * v9fs_file_lock - lock a file (or directory)
+ * @inode: inode to be opened
+ * @file: file being opened
+ *
+ * XXX - this looks like a local only lock, we should extend into 9P
+ * by using open exclusive
+ */
+
+static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
+{
+ int res = 0;
+ struct inode *inode = filp->f_dentry->d_inode;
+
+ dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
+
+ /* No mandatory locks */
+ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ return -ENOLCK;
+
+ if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
+ filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawait(inode->i_mapping);
+ invalidate_inode_pages(&inode->i_data);
+ }
+
+ return res;
+}
+
+/**
+ * v9fs_read - read from a file (internal)
+ * @filep: file pointer to read
+ * @data: data buffer to read data into
+ * @count: size of buffer
+ * @offset: offset at which to read data
+ *
+ */
+
+static ssize_t
+v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+ struct v9fs_fid *v9f = filp->private_data;
+ struct v9fs_fcall *fcall = NULL;
+ int fid = v9f->fid;
+ int rsize = 0;
+ int result = 0;
+ int total = 0;
+
+ dprintk(DEBUG_VFS, "\n");
+
+ rsize = v9ses->maxdata - V9FS_IOHDRSZ;
+ if (v9f->iounit != 0 && rsize > v9f->iounit)
+ rsize = v9f->iounit;
+
+ do {
+ if (count < rsize)
+ rsize = count;
+
+ result = v9fs_t_read(v9ses, fid, *offset, rsize, &fcall);
+
+ if (result < 0) {
+ printk(KERN_ERR "9P2000: v9fs_t_read returned %d\n",
+ result);
+
+ kfree(fcall);
+ return total;
+ } else
+ *offset += result;
+
+ /* XXX - extra copy */
+ memcpy(buffer, fcall->params.rread.data, result);
+ count -= result;
+ buffer += result;
+ total += result;
+
+ kfree(fcall);
+
+ if (result < rsize)
+ break;
+ } while (count);
+
+ return total;
+}
+
+/**
+ * v9fs_file_read - read from a file
+ * @filep: file pointer to read
+ * @data: data buffer to read data into
+ * @count: size of buffer
+ * @offset: offset at which to read data
+ *
+ */
+
+static ssize_t
+v9fs_file_read(struct file *filp, char __user * data, size_t count,
+ loff_t * offset)
+{
+ int retval = -1;
+ int ret = 0;
+ char *buffer;
+
+ buffer = kmalloc(count, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ retval = v9fs_read(filp, buffer, count, offset);
+ if (retval > 0) {
+ if ((ret = copy_to_user(data, buffer, retval)) != 0) {
+ dprintk(DEBUG_ERROR, "Problem copying to user %d\n",
+ ret);
+ retval = ret;
+ }
+ }
+
+ kfree(buffer);
+
+ return retval;
+}
+
+/**
+ * v9fs_write - write to a file
+ * @filep: file pointer to write
+ * @data: data buffer to write data from
+ * @count: size of buffer
+ * @offset: offset at which to write data
+ *
+ */
+
+static ssize_t
+v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+ struct v9fs_fid *v9fid = filp->private_data;
+ struct v9fs_fcall *fcall;
+ int fid = v9fid->fid;
+ int result = -EIO;
+ int rsize = 0;
+ int total = 0;
+
+ dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count,
+ (int)*offset);
+ rsize = v9ses->maxdata - V9FS_IOHDRSZ;
+ if (v9fid->iounit != 0 && rsize > v9fid->iounit)
+ rsize = v9fid->iounit;
+
+ dump_data(buffer, count);
+
+ do {
+ if (count < rsize)
+ rsize = count;
+
+ result =
+ v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall);
+ if (result < 0) {
+ eprintk(KERN_ERR, "error while writing: %s(%d)\n",
+ FCALL_ERROR(fcall), result);
+ kfree(fcall);
+ return result;
+ } else
+ *offset += result;
+
+ kfree(fcall);
+
+ if (result != rsize) {
+ eprintk(KERN_ERR,
+ "short write: v9fs_t_write returned %d\n",
+ result);
+ break;
+ }
+
+ count -= result;
+ buffer += result;
+ total += result;
+ } while (count);
+
+ return total;
+}
+
+/**
+ * v9fs_file_write - write to a file
+ * @filep: file pointer to write
+ * @data: data buffer to write data from
+ * @count: size of buffer
+ * @offset: offset at which to write data
+ *
+ */
+
+static ssize_t
+v9fs_file_write(struct file *filp, const char __user * data,
+ size_t count, loff_t * offset)
+{
+ int ret = -1;
+ char *buffer;
+
+ buffer = kmalloc(count, GFP_KERNEL);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ ret = copy_from_user(buffer, data, count);
+ if (ret) {
+ dprintk(DEBUG_ERROR, "Problem copying from user\n");
+ ret = -EFAULT;
+ } else {
+ ret = v9fs_write(filp, buffer, count, offset);
+ }
+
+ kfree(buffer);
+
+ return ret;
+}
+
+struct file_operations v9fs_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = v9fs_file_read,
+ .write = v9fs_file_write,
+ .open = v9fs_file_open,
+ .release = v9fs_dir_release,
+ .lock = v9fs_file_lock,
+};
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
new file mode 100644
index 00000000000..0c13fc60004
--- /dev/null
+++ b/fs/9p/vfs_inode.c
@@ -0,0 +1,1338 @@
+/*
+ * linux/fs/9p/vfs_inode.c
+ *
+ * This file contains vfs inode ops for the 9P2000 protocol.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/namei.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "conv.h"
+#include "fid.h"
+
+static struct inode_operations v9fs_dir_inode_operations;
+static struct inode_operations v9fs_dir_inode_operations_ext;
+static struct inode_operations v9fs_file_inode_operations;
+static struct inode_operations v9fs_symlink_inode_operations;
+
+/**
+ * unixmode2p9mode - convert unix mode bits to plan 9
+ * @v9ses: v9fs session information
+ * @mode: mode to convert
+ *
+ */
+
+static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
+{
+ int res;
+ res = mode & 0777;
+ if (S_ISDIR(mode))
+ res |= V9FS_DMDIR;
+ if (v9ses->extended) {
+ if (S_ISLNK(mode))
+ res |= V9FS_DMSYMLINK;
+ if (v9ses->nodev == 0) {
+ if (S_ISSOCK(mode))
+ res |= V9FS_DMSOCKET;
+ if (S_ISFIFO(mode))
+ res |= V9FS_DMNAMEDPIPE;
+ if (S_ISBLK(mode))
+ res |= V9FS_DMDEVICE;
+ if (S_ISCHR(mode))
+ res |= V9FS_DMDEVICE;
+ }
+
+ if ((mode & S_ISUID) == S_ISUID)
+ res |= V9FS_DMSETUID;
+ if ((mode & S_ISGID) == S_ISGID)
+ res |= V9FS_DMSETGID;
+ if ((mode & V9FS_DMLINK))
+ res |= V9FS_DMLINK;
+ }
+
+ return res;
+}
+
+/**
+ * p9mode2unixmode- convert plan9 mode bits to unix mode bits
+ * @v9ses: v9fs session information
+ * @mode: mode to convert
+ *
+ */
+
+static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
+{
+ int res;
+
+ res = mode & 0777;
+
+ if ((mode & V9FS_DMDIR) == V9FS_DMDIR)
+ res |= S_IFDIR;
+ else if ((mode & V9FS_DMSYMLINK) && (v9ses->extended))
+ res |= S_IFLNK;
+ else if ((mode & V9FS_DMSOCKET) && (v9ses->extended)
+ && (v9ses->nodev == 0))
+ res |= S_IFSOCK;
+ else if ((mode & V9FS_DMNAMEDPIPE) && (v9ses->extended)
+ && (v9ses->nodev == 0))
+ res |= S_IFIFO;
+ else if ((mode & V9FS_DMDEVICE) && (v9ses->extended)
+ && (v9ses->nodev == 0))
+ res |= S_IFBLK;
+ else
+ res |= S_IFREG;
+
+ if (v9ses->extended) {
+ if ((mode & V9FS_DMSETUID) == V9FS_DMSETUID)
+ res |= S_ISUID;
+
+ if ((mode & V9FS_DMSETGID) == V9FS_DMSETGID)
+ res |= S_ISGID;
+ }
+
+ return res;
+}
+
+/**
+ * v9fs_blank_mistat - helper function to setup a 9P stat structure
+ * @v9ses: 9P session info (for determining extended mode)
+ * @mistat: structure to initialize
+ *
+ */
+
+static void
+v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat)
+{
+ mistat->type = ~0;
+ mistat->dev = ~0;
+ mistat->qid.type = ~0;
+ mistat->qid.version = ~0;
+ *((long long *)&mistat->qid.path) = ~0;
+ mistat->mode = ~0;
+ mistat->atime = ~0;
+ mistat->mtime = ~0;
+ mistat->length = ~0;
+ mistat->name = mistat->data;
+ mistat->uid = mistat->data;
+ mistat->gid = mistat->data;
+ mistat->muid = mistat->data;
+ if (v9ses->extended) {
+ mistat->n_uid = ~0;
+ mistat->n_gid = ~0;
+ mistat->n_muid = ~0;
+ mistat->extension = mistat->data;
+ }
+ *mistat->data = 0;
+}
+
+/**
+ * v9fs_mistat2unix - convert mistat to unix stat
+ * @mistat: Plan 9 metadata (mistat) structure
+ * @buf: unix metadata (stat) structure to populate
+ * @sb: superblock
+ *
+ */
+
+static void
+v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
+ struct super_block *sb)
+{
+ struct v9fs_session_info *v9ses = sb ? sb->s_fs_info : NULL;
+
+ buf->st_nlink = 1;
+
+ buf->st_atime = mistat->atime;
+ buf->st_mtime = mistat->mtime;
+ buf->st_ctime = mistat->mtime;
+
+ buf->st_uid = (unsigned short)-1;
+ buf->st_gid = (unsigned short)-1;
+
+ if (v9ses && v9ses->extended) {
+ /* TODO: string to uid mapping via user-space daemon */
+ if (mistat->n_uid != -1)
+ sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
+
+ if (mistat->n_gid != -1)
+ sscanf(mistat->gid, "%x", (unsigned int *)&buf->st_gid);
+ }
+
+ if (buf->st_uid == (unsigned short)-1)
+ buf->st_uid = v9ses->uid;
+ if (buf->st_gid == (unsigned short)-1)
+ buf->st_gid = v9ses->gid;
+
+ buf->st_mode = p9mode2unixmode(v9ses, mistat->mode);
+ if ((S_ISBLK(buf->st_mode)) || (S_ISCHR(buf->st_mode))) {
+ char type = 0;
+ int major = -1;
+ int minor = -1;
+ sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
+ switch (type) {
+ case 'c':
+ buf->st_mode &= ~S_IFBLK;
+ buf->st_mode |= S_IFCHR;
+ break;
+ case 'b':
+ break;
+ default:
+ dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
+ type, mistat->extension);
+ };
+ buf->st_rdev = MKDEV(major, minor);
+ } else
+ buf->st_rdev = 0;
+
+ buf->st_size = mistat->length;
+
+ buf->st_blksize = sb->s_blocksize;
+ buf->st_blocks =
+ (buf->st_size + buf->st_blksize - 1) >> sb->s_blocksize_bits;
+}
+
+/**
+ * v9fs_get_inode - helper function to setup an inode
+ * @sb: superblock
+ * @mode: mode to setup inode with
+ *
+ */
+
+struct inode *v9fs_get_inode(struct super_block *sb, int mode)
+{
+ struct inode *inode = NULL;
+ struct v9fs_session_info *v9ses = sb->s_fs_info;
+
+ dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
+
+ inode = new_inode(sb);
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_blksize = sb->s_blocksize;
+ inode->i_blocks = 0;
+ inode->i_rdev = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+ switch (mode & S_IFMT) {
+ case S_IFIFO:
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFSOCK:
+ if(!v9ses->extended) {
+ dprintk(DEBUG_ERROR, "special files without extended mode\n");
+ return ERR_PTR(-EINVAL);
+ }
+ init_special_inode(inode, inode->i_mode,
+ inode->i_rdev);
+ break;
+ case S_IFREG:
+ inode->i_op = &v9fs_file_inode_operations;
+ inode->i_fop = &v9fs_file_operations;
+ break;
+ case S_IFLNK:
+ if(!v9ses->extended) {
+ dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n");
+ return ERR_PTR(-EINVAL);
+ }
+ inode->i_op = &v9fs_symlink_inode_operations;
+ break;
+ case S_IFDIR:
+ inode->i_nlink++;
+ if(v9ses->extended)
+ inode->i_op = &v9fs_dir_inode_operations_ext;
+ else
+ inode->i_op = &v9fs_dir_inode_operations;
+ inode->i_fop = &v9fs_dir_operations;
+ break;
+ default:
+ dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
+ mode, mode & S_IFMT);
+ return ERR_PTR(-EINVAL);
+ }
+ } else {
+ eprintk(KERN_WARNING, "Problem allocating inode\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ return inode;
+}
+
+/**
+ * v9fs_create - helper function to create files and directories
+ * @dir: directory inode file is being created in
+ * @file_dentry: dentry file is being created in
+ * @perm: permissions file is being created with
+ * @open_mode: resulting open mode for file
+ *
+ */
+
+static int
+v9fs_create(struct inode *dir,
+ struct dentry *file_dentry,
+ unsigned int perm, unsigned int open_mode)
+{
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
+ struct super_block *sb = dir->i_sb;
+ struct v9fs_fid *dirfid =
+ v9fs_fid_lookup(file_dentry->d_parent, FID_WALK);
+ struct v9fs_fid *fid = NULL;
+ struct inode *file_inode = NULL;
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_qid qid;
+ struct stat newstat;
+ int dirfidnum = -1;
+ long newfid = -1;
+ int result = 0;
+ unsigned int iounit = 0;
+
+ perm = unixmode2p9mode(v9ses, perm);
+
+ dprintk(DEBUG_VFS, "dir: %p dentry: %p perm: %o mode: %o\n", dir,
+ file_dentry, perm, open_mode);
+
+ if (!dirfid)
+ return -EBADF;
+
+ dirfidnum = dirfid->fid;
+ if (dirfidnum < 0) {
+ dprintk(DEBUG_ERROR, "No fid for the directory #%lu\n",
+ dir->i_ino);
+ return -EBADF;
+ }
+
+ if (file_dentry->d_inode) {
+ dprintk(DEBUG_ERROR,
+ "Odd. There is an inode for dir %lu, name :%s:\n",
+ dir->i_ino, file_dentry->d_name.name);
+ return -EEXIST;
+ }
+
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "no free fids available\n");
+ return -ENOSPC;
+ }
+
+ result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ newfid = 0;
+ goto CleanUpFid;
+ }
+
+ kfree(fcall);
+
+ result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name,
+ perm, open_mode, &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "create fails: %s(%d)\n",
+ FCALL_ERROR(fcall), result);
+
+ goto CleanUpFid;
+ }
+
+ iounit = fcall->params.rcreate.iounit;
+ qid = fcall->params.rcreate.qid;
+ kfree(fcall);
+
+ fid = v9fs_fid_create(file_dentry);
+ if (!fid) {
+ result = -ENOMEM;
+ goto CleanUpFid;
+ }
+
+ fid->fid = newfid;
+ fid->fidopen = 0;
+ fid->fidcreate = 1;
+ fid->qid = qid;
+ fid->iounit = iounit;
+ fid->rdir_pos = 0;
+ fid->rdir_fcall = NULL;
+ fid->v9ses = v9ses;
+
+ if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) ||
+ (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) ||
+ (perm & V9FS_DMDEVICE))
+ return 0;
+
+ result = v9fs_t_stat(v9ses, newfid, &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "stat error: %s(%d)\n", FCALL_ERROR(fcall),
+ result);
+ goto CleanUpFid;
+ }
+
+ v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
+
+ file_inode = v9fs_get_inode(sb, newstat.st_mode);
+ if ((!file_inode) || IS_ERR(file_inode)) {
+ dprintk(DEBUG_ERROR, "create inode failed\n");
+ result = -EBADF;
+ goto CleanUpFid;
+ }
+
+ v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb);
+ kfree(fcall);
+ d_instantiate(file_dentry, file_inode);
+
+ if (perm & V9FS_DMDIR) {
+ if (v9fs_t_clunk(v9ses, newfid, &fcall))
+ dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
+ FCALL_ERROR(fcall));
+
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ kfree(fcall);
+ fid->fidopen = 0;
+ fid->fidcreate = 0;
+ d_drop(file_dentry);
+ }
+
+ return 0;
+
+ CleanUpFid:
+ kfree(fcall);
+
+ if (newfid) {
+ if (v9fs_t_clunk(v9ses, newfid, &fcall))
+ dprintk(DEBUG_ERROR, "clunk failed: %s\n",
+ FCALL_ERROR(fcall));
+
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ kfree(fcall);
+ }
+ return result;
+}
+
+/**
+ * v9fs_remove - helper function to remove files and directories
+ * @dir: directory inode that is being deleted
+ * @file: dentry that is being deleted
+ * @rmdir: removing a directory
+ *
+ */
+
+static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
+{
+ struct v9fs_fcall *fcall = NULL;
+ struct super_block *sb = NULL;
+ struct v9fs_session_info *v9ses = NULL;
+ struct v9fs_fid *v9fid = NULL;
+ struct inode *file_inode = NULL;
+ int fid = -1;
+ int result = 0;
+
+ dprintk(DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
+ rmdir);
+
+ file_inode = file->d_inode;
+ sb = file_inode->i_sb;
+ v9ses = v9fs_inode2v9ses(file_inode);
+ v9fid = v9fs_fid_lookup(file, FID_OP);
+
+ if (!v9fid) {
+ dprintk(DEBUG_ERROR,
+ "no v9fs_fid\n");
+ return -EBADF;
+ }
+
+ fid = v9fid->fid;
+ if (fid < 0) {
+ dprintk(DEBUG_ERROR, "inode #%lu, no fid!\n",
+ file_inode->i_ino);
+ return -EBADF;
+ }
+
+ result = v9fs_t_remove(v9ses, fid, &fcall);
+ if (result < 0)
+ dprintk(DEBUG_ERROR, "remove of file fails: %s(%d)\n",
+ FCALL_ERROR(fcall), result);
+ else {
+ v9fs_put_idpool(fid, &v9ses->fidpool);
+ v9fs_fid_destroy(v9fid);
+ }
+
+ kfree(fcall);
+ return result;
+}
+
+/**
+ * v9fs_vfs_create - VFS hook to create files
+ * @inode: directory inode that is being deleted
+ * @dentry: dentry that is being deleted
+ * @perm: create permissions
+ * @nd: path information
+ *
+ */
+
+static int
+v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm,
+ struct nameidata *nd)
+{
+ return v9fs_create(inode, dentry, perm, O_RDWR);
+}
+
+/**
+ * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
+ * @inode: inode that is being unlinked
+ * @dentry: dentry that is being unlinked
+ * @mode: mode for new directory
+ *
+ */
+
+static int v9fs_vfs_mkdir(struct inode *inode, struct dentry *dentry, int mode)
+{
+ return v9fs_create(inode, dentry, mode | S_IFDIR, O_RDONLY);
+}
+
+/**
+ * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
+ * @dir: inode that is being walked from
+ * @dentry: dentry that is being walked to?
+ * @nameidata: path data
+ *
+ */
+
+static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nameidata)
+{
+ struct super_block *sb;
+ struct v9fs_session_info *v9ses;
+ struct v9fs_fid *dirfid;
+ struct v9fs_fid *fid;
+ struct inode *inode;
+ struct v9fs_fcall *fcall = NULL;
+ struct stat newstat;
+ int dirfidnum = -1;
+ int newfid = -1;
+ int result = 0;
+
+ dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
+ dir, dentry->d_iname, dentry, nameidata);
+
+ sb = dir->i_sb;
+ v9ses = v9fs_inode2v9ses(dir);
+ dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
+
+ if (!dirfid) {
+ dprintk(DEBUG_ERROR, "no dirfid\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ dirfidnum = dirfid->fid;
+
+ if (dirfidnum < 0) {
+ dprintk(DEBUG_ERROR, "no dirfid for inode %p, #%lu\n",
+ dir, dir->i_ino);
+ return ERR_PTR(-EBADF);
+ }
+
+ newfid = v9fs_get_idpool(&v9ses->fidpool);
+ if (newfid < 0) {
+ eprintk(KERN_WARNING, "newfid fails!\n");
+ return ERR_PTR(-ENOSPC);
+ }
+
+ result =
+ v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name,
+ NULL);
+ if (result < 0) {
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ if (result == -ENOENT) {
+ d_add(dentry, NULL);
+ dprintk(DEBUG_ERROR,
+ "Return negative dentry %p count %d\n",
+ dentry, atomic_read(&dentry->d_count));
+ return NULL;
+ }
+ dprintk(DEBUG_ERROR, "walk error:%d\n", result);
+ goto FreeFcall;
+ }
+
+ result = v9fs_t_stat(v9ses, newfid, &fcall);
+ if (result < 0) {
+ dprintk(DEBUG_ERROR, "stat error\n");
+ goto FreeFcall;
+ }
+
+ v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
+ inode = v9fs_get_inode(sb, newstat.st_mode);
+
+ if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) {
+ eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n",
+ PTR_ERR(inode));
+
+ result = -ENOSPC;
+ goto FreeFcall;
+ }
+
+ inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
+
+ fid = v9fs_fid_create(dentry);
+ if (fid == NULL) {
+ dprintk(DEBUG_ERROR, "couldn't insert\n");
+ result = -ENOMEM;
+ goto FreeFcall;
+ }
+
+ fid->fid = newfid;
+ fid->fidopen = 0;
+ fid->v9ses = v9ses;
+ fid->qid = fcall->params.rstat.stat->qid;
+
+ dentry->d_op = &v9fs_dentry_operations;
+ v9fs_mistat2inode(fcall->params.rstat.stat, inode, inode->i_sb);
+
+ d_add(dentry, inode);
+ kfree(fcall);
+
+ return NULL;
+
+ FreeFcall:
+ kfree(fcall);
+ return ERR_PTR(result);
+}
+
+/**
+ * v9fs_vfs_unlink - VFS unlink hook to delete an inode
+ * @i: inode that is being unlinked
+ * @d: dentry that is being unlinked
+ *
+ */
+
+static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
+{
+ return v9fs_remove(i, d, 0);
+}
+
+/**
+ * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
+ * @i: inode that is being unlinked
+ * @d: dentry that is being unlinked
+ *
+ */
+
+static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
+{
+ return v9fs_remove(i, d, 1);
+}
+
+/**
+ * v9fs_vfs_rename - VFS hook to rename an inode
+ * @old_dir: old dir inode
+ * @old_dentry: old dentry
+ * @new_dir: new dir inode
+ * @new_dentry: new dentry
+ *
+ */
+
+static int
+v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *old_inode = old_dentry->d_inode;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
+ struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK);
+ struct v9fs_fid *olddirfid =
+ v9fs_fid_lookup(old_dentry->d_parent, FID_WALK);
+ struct v9fs_fid *newdirfid =
+ v9fs_fid_lookup(new_dentry->d_parent, FID_WALK);
+ struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+ struct v9fs_fcall *fcall = NULL;
+ int fid = -1;
+ int olddirfidnum = -1;
+ int newdirfidnum = -1;
+ int retval = 0;
+
+ dprintk(DEBUG_VFS, "\n");
+
+ if (!mistat)
+ return -ENOMEM;
+
+ if ((!oldfid) || (!olddirfid) || (!newdirfid)) {
+ dprintk(DEBUG_ERROR, "problem with arguments\n");
+ return -EBADF;
+ }
+
+ /* 9P can only handle file rename in the same directory */
+ if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) {
+ dprintk(DEBUG_ERROR, "old dir and new dir are different\n");
+ retval = -EPERM;
+ goto FreeFcallnBail;
+ }
+
+ fid = oldfid->fid;
+ olddirfidnum = olddirfid->fid;
+ newdirfidnum = newdirfid->fid;
+
+ if (fid < 0) {
+ dprintk(DEBUG_ERROR, "no fid for old file #%lu\n",
+ old_inode->i_ino);
+ retval = -EBADF;
+ goto FreeFcallnBail;
+ }
+
+ v9fs_blank_mistat(v9ses, mistat);
+
+ strcpy(mistat->data + 1, v9ses->name);
+ mistat->name = mistat->data + 1 + strlen(v9ses->name);
+
+ if (new_dentry->d_name.len >
+ (v9ses->maxdata - strlen(v9ses->name) - sizeof(struct v9fs_stat))) {
+ dprintk(DEBUG_ERROR, "new name too long\n");
+ goto FreeFcallnBail;
+ }
+
+ strcpy(mistat->name, new_dentry->d_name.name);
+ retval = v9fs_t_wstat(v9ses, fid, mistat, &fcall);
+
+ FreeFcallnBail:
+ kfree(mistat);
+
+ if (retval < 0)
+ dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
+ FCALL_ERROR(fcall));
+
+ kfree(fcall);
+ return retval;
+}
+
+/**
+ * v9fs_vfs_getattr - retreive file metadata
+ * @mnt - mount information
+ * @dentry - file to get attributes on
+ * @stat - metadata structure to populate
+ *
+ */
+
+static int
+v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+ int err = -EPERM;
+
+ dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
+ if (!fid) {
+ dprintk(DEBUG_ERROR,
+ "couldn't find fid associated with dentry\n");
+ return -EBADF;
+ }
+
+ err = v9fs_t_stat(v9ses, fid->fid, &fcall);
+
+ if (err < 0)
+ dprintk(DEBUG_ERROR, "stat error\n");
+ else {
+ v9fs_mistat2inode(fcall->params.rstat.stat, dentry->d_inode,
+ dentry->d_inode->i_sb);
+ generic_fillattr(dentry->d_inode, stat);
+ }
+
+ kfree(fcall);
+ return err;
+}
+
+/**
+ * v9fs_vfs_setattr - set file metadata
+ * @dentry: file whose metadata to set
+ * @iattr: metadata assignment structure
+ *
+ */
+
+static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+ int res = -EPERM;
+
+ dprintk(DEBUG_VFS, "\n");
+
+ if (!mistat)
+ return -ENOMEM;
+
+ if (!fid) {
+ dprintk(DEBUG_ERROR,
+ "Couldn't find fid associated with dentry\n");
+ return -EBADF;
+ }
+
+ v9fs_blank_mistat(v9ses, mistat);
+ if (iattr->ia_valid & ATTR_MODE)
+ mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode);
+
+ if (iattr->ia_valid & ATTR_MTIME)
+ mistat->mtime = iattr->ia_mtime.tv_sec;
+
+ if (iattr->ia_valid & ATTR_ATIME)
+ mistat->atime = iattr->ia_atime.tv_sec;
+
+ if (iattr->ia_valid & ATTR_SIZE)
+ mistat->length = iattr->ia_size;
+
+ if (v9ses->extended) {
+ char *ptr = mistat->data+1;
+
+ if (iattr->ia_valid & ATTR_UID) {
+ mistat->uid = ptr;
+ ptr += 1+sprintf(ptr, "%08x", iattr->ia_uid);
+ mistat->n_uid = iattr->ia_uid;
+ }
+
+ if (iattr->ia_valid & ATTR_GID) {
+ mistat->gid = ptr;
+ ptr += 1+sprintf(ptr, "%08x", iattr->ia_gid);
+ mistat->n_gid = iattr->ia_gid;
+ }
+ }
+
+ res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall);
+
+ if (res < 0)
+ dprintk(DEBUG_ERROR, "wstat error: %s\n", FCALL_ERROR(fcall));
+
+ kfree(mistat);
+ kfree(fcall);
+
+ if (res >= 0)
+ res = inode_setattr(dentry->d_inode, iattr);
+
+ return res;
+}
+
+/**
+ * v9fs_mistat2inode - populate an inode structure with mistat info
+ * @mistat: Plan 9 metadata (mistat) structure
+ * @inode: inode to populate
+ * @sb: superblock of filesystem
+ *
+ */
+
+void
+v9fs_mistat2inode(struct v9fs_stat *mistat, struct inode *inode,
+ struct super_block *sb)
+{
+ struct v9fs_session_info *v9ses = sb->s_fs_info;
+
+ inode->i_nlink = 1;
+
+ inode->i_atime.tv_sec = mistat->atime;
+ inode->i_mtime.tv_sec = mistat->mtime;
+ inode->i_ctime.tv_sec = mistat->mtime;
+
+ inode->i_uid = -1;
+ inode->i_gid = -1;
+
+ if (v9ses->extended) {
+ /* TODO: string to uid mapping via user-space daemon */
+ inode->i_uid = mistat->n_uid;
+ inode->i_gid = mistat->n_gid;
+
+ if (mistat->n_uid == -1)
+ sscanf(mistat->uid, "%x", &inode->i_uid);
+
+ if (mistat->n_gid == -1)
+ sscanf(mistat->gid, "%x", &inode->i_gid);
+ }
+
+ if (inode->i_uid == -1)
+ inode->i_uid = v9ses->uid;
+ if (inode->i_gid == -1)
+ inode->i_gid = v9ses->gid;
+
+ inode->i_mode = p9mode2unixmode(v9ses, mistat->mode);
+ if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
+ char type = 0;
+ int major = -1;
+ int minor = -1;
+ sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
+ switch (type) {
+ case 'c':
+ inode->i_mode &= ~S_IFBLK;
+ inode->i_mode |= S_IFCHR;
+ break;
+ case 'b':
+ break;
+ default:
+ dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
+ type, mistat->extension);
+ };
+ inode->i_rdev = MKDEV(major, minor);
+ } else
+ inode->i_rdev = 0;
+
+ inode->i_size = mistat->length;
+
+ inode->i_blksize = sb->s_blocksize;
+ inode->i_blocks =
+ (inode->i_size + inode->i_blksize - 1) >> sb->s_blocksize_bits;
+}
+
+/**
+ * v9fs_qid2ino - convert qid into inode number
+ * @qid: qid to hash
+ *
+ * BUG: potential for inode number collisions?
+ */
+
+ino_t v9fs_qid2ino(struct v9fs_qid *qid)
+{
+ u64 path = qid->path + 2;
+ ino_t i = 0;
+
+ if (sizeof(ino_t) == sizeof(path))
+ memcpy(&i, &path, sizeof(ino_t));
+ else
+ i = (ino_t) (path ^ (path >> 32));
+
+ return i;
+}
+
+/**
+ * v9fs_vfs_symlink - helper function to create symlinks
+ * @dir: directory inode containing symlink
+ * @dentry: dentry for symlink
+ * @symname: symlink data
+ *
+ * See 9P2000.u RFC for more information
+ *
+ */
+
+static int
+v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+ int retval = -EPERM;
+ struct v9fs_fid *newfid;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+
+ dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
+ symname);
+
+ if (!mistat)
+ return -ENOMEM;
+
+ if (!v9ses->extended) {
+ dprintk(DEBUG_ERROR, "not extended\n");
+ goto FreeFcall;
+ }
+
+ /* issue a create */
+ retval = v9fs_create(dir, dentry, S_IFLNK, 0);
+ if (retval != 0)
+ goto FreeFcall;
+
+ newfid = v9fs_fid_lookup(dentry, FID_OP);
+
+ /* issue a twstat */
+ v9fs_blank_mistat(v9ses, mistat);
+ strcpy(mistat->data + 1, symname);
+ mistat->extension = mistat->data + 1;
+ retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
+ if (retval < 0) {
+ dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeFcall;
+ }
+
+ kfree(fcall);
+
+ if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
+ dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeFcall;
+ }
+
+ d_drop(dentry); /* FID - will this also clunk? */
+
+ FreeFcall:
+ kfree(mistat);
+ kfree(fcall);
+
+ return retval;
+}
+
+/**
+ * v9fs_readlink - read a symlink's location (internal version)
+ * @dentry: dentry for symlink
+ * @buffer: buffer to load symlink location into
+ * @buflen: length of buffer
+ *
+ */
+
+static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+ int retval = -EPERM;
+
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+
+ if (!fid) {
+ dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n");
+ retval = -EBADF;
+ goto FreeFcall;
+ }
+
+ if (!v9ses->extended) {
+ retval = -EBADF;
+ dprintk(DEBUG_ERROR, "not extended\n");
+ goto FreeFcall;
+ }
+
+ dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name);
+ retval = v9fs_t_stat(v9ses, fid->fid, &fcall);
+
+ if (retval < 0) {
+ dprintk(DEBUG_ERROR, "stat error\n");
+ goto FreeFcall;
+ }
+
+ if (!fcall)
+ return -EIO;
+
+ if (!(fcall->params.rstat.stat->mode & V9FS_DMSYMLINK)) {
+ retval = -EINVAL;
+ goto FreeFcall;
+ }
+
+ /* copy extension buffer into buffer */
+ if (strlen(fcall->params.rstat.stat->extension) < buflen)
+ buflen = strlen(fcall->params.rstat.stat->extension);
+
+ memcpy(buffer, fcall->params.rstat.stat->extension, buflen + 1);
+
+ retval = buflen;
+
+ FreeFcall:
+ kfree(fcall);
+
+ return retval;
+}
+
+/**
+ * v9fs_vfs_readlink - read a symlink's location
+ * @dentry: dentry for symlink
+ * @buf: buffer to load symlink location into
+ * @buflen: length of buffer
+ *
+ */
+
+static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
+ int buflen)
+{
+ int retval;
+ int ret;
+ char *link = __getname();
+
+ if (strlen(link) < buflen)
+ buflen = strlen(link);
+
+ dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+
+ retval = v9fs_readlink(dentry, link, buflen);
+
+ if (retval > 0) {
+ if ((ret = copy_to_user(buffer, link, retval)) != 0) {
+ dprintk(DEBUG_ERROR, "problem copying to user: %d\n",
+ ret);
+ retval = ret;
+ }
+ }
+
+ putname(link);
+ return retval;
+}
+
+/**
+ * v9fs_vfs_follow_link - follow a symlink path
+ * @dentry: dentry for symlink
+ * @nd: nameidata
+ *
+ */
+
+static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ int len = 0;
+ char *link = __getname();
+
+ dprintk(DEBUG_VFS, "%s n", dentry->d_name.name);
+
+ if (!link)
+ link = ERR_PTR(-ENOMEM);
+ else {
+ len = v9fs_readlink(dentry, link, strlen(link));
+
+ if (len < 0) {
+ putname(link);
+ link = ERR_PTR(len);
+ } else
+ link[len] = 0;
+ }
+ nd_set_link(nd, link);
+
+ return NULL;
+}
+
+/**
+ * v9fs_vfs_put_link - release a symlink path
+ * @dentry: dentry for symlink
+ * @nd: nameidata
+ *
+ */
+
+static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
+{
+ char *s = nd_get_link(nd);
+
+ dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
+ if (!IS_ERR(s))
+ putname(s);
+}
+
+/**
+ * v9fs_vfs_link - create a hardlink
+ * @old_dentry: dentry for file to link to
+ * @dir: inode destination for new link
+ * @dentry: dentry for link
+ *
+ */
+
+/* XXX - lots of code dup'd from symlink and creates,
+ * figure out a better reuse strategy
+ */
+
+static int
+v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ int retval = -EPERM;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+ struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP);
+ struct v9fs_fid *newfid = NULL;
+ char *symname = __getname();
+
+ dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
+ old_dentry->d_name.name);
+
+ if (!v9ses->extended) {
+ dprintk(DEBUG_ERROR, "not extended\n");
+ goto FreeMem;
+ }
+
+ /* get fid of old_dentry */
+ sprintf(symname, "hardlink(%d)\n", oldfid->fid);
+
+ /* issue a create */
+ retval = v9fs_create(dir, dentry, V9FS_DMLINK, 0);
+ if (retval != 0)
+ goto FreeMem;
+
+ newfid = v9fs_fid_lookup(dentry, FID_OP);
+ if (!newfid) {
+ dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
+ goto FreeMem;
+ }
+
+ /* issue a twstat */
+ v9fs_blank_mistat(v9ses, mistat);
+ strcpy(mistat->data + 1, symname);
+ mistat->extension = mistat->data + 1;
+ retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
+ if (retval < 0) {
+ dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeMem;
+ }
+
+ kfree(fcall);
+
+ if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
+ dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeMem;
+ }
+
+ d_drop(dentry); /* FID - will this also clunk? */
+
+ kfree(fcall);
+ fcall = NULL;
+
+ FreeMem:
+ kfree(mistat);
+ kfree(fcall);
+ putname(symname);
+ return retval;
+}
+
+/**
+ * v9fs_vfs_mknod - create a special file
+ * @dir: inode destination for new link
+ * @dentry: dentry for file
+ * @mode: mode for creation
+ * @dev_t: device associated with special file
+ *
+ */
+
+static int
+v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
+{
+ int retval = -EPERM;
+ struct v9fs_fid *newfid;
+ struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
+ struct v9fs_fcall *fcall = NULL;
+ struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+ char *symname = __getname();
+
+ dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
+ dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
+
+ if (!mistat)
+ return -ENOMEM;
+
+ if (!new_valid_dev(rdev)) {
+ retval = -EINVAL;
+ goto FreeMem;
+ }
+
+ if (!v9ses->extended) {
+ dprintk(DEBUG_ERROR, "not extended\n");
+ goto FreeMem;
+ }
+
+ /* issue a create */
+ retval = v9fs_create(dir, dentry, mode, 0);
+
+ if (retval != 0)
+ goto FreeMem;
+
+ newfid = v9fs_fid_lookup(dentry, FID_OP);
+ if (!newfid) {
+ dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
+ retval = -EINVAL;
+ goto FreeMem;
+ }
+
+ /* build extension */
+ if (S_ISBLK(mode))
+ sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev));
+ else if (S_ISCHR(mode))
+ sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev));
+ else if (S_ISFIFO(mode))
+ ; /* DO NOTHING */
+ else {
+ retval = -EINVAL;
+ goto FreeMem;
+ }
+
+ if (!S_ISFIFO(mode)) {
+ /* issue a twstat */
+ v9fs_blank_mistat(v9ses, mistat);
+ strcpy(mistat->data + 1, symname);
+ mistat->extension = mistat->data + 1;
+ retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
+ if (retval < 0) {
+ dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeMem;
+ }
+ }
+
+ /* need to update dcache so we show up */
+ kfree(fcall);
+
+ if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
+ dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
+ FCALL_ERROR(fcall));
+ goto FreeMem;
+ }
+
+ d_drop(dentry); /* FID - will this also clunk? */
+
+ FreeMem:
+ kfree(mistat);
+ kfree(fcall);
+ putname(symname);
+
+ return retval;
+}
+
+static struct inode_operations v9fs_dir_inode_operations_ext = {
+ .create = v9fs_vfs_create,
+ .lookup = v9fs_vfs_lookup,
+ .symlink = v9fs_vfs_symlink,
+ .link = v9fs_vfs_link,
+ .unlink = v9fs_vfs_unlink,
+ .mkdir = v9fs_vfs_mkdir,
+ .rmdir = v9fs_vfs_rmdir,
+ .mknod = v9fs_vfs_mknod,
+ .rename = v9fs_vfs_rename,
+ .readlink = v9fs_vfs_readlink,
+ .getattr = v9fs_vfs_getattr,
+ .setattr = v9fs_vfs_setattr,
+};
+
+static struct inode_operations v9fs_dir_inode_operations = {
+ .create = v9fs_vfs_create,
+ .lookup = v9fs_vfs_lookup,
+ .unlink = v9fs_vfs_unlink,
+ .mkdir = v9fs_vfs_mkdir,
+ .rmdir = v9fs_vfs_rmdir,
+ .mknod = v9fs_vfs_mknod,
+ .rename = v9fs_vfs_rename,
+ .getattr = v9fs_vfs_getattr,
+ .setattr = v9fs_vfs_setattr,
+};
+
+static struct inode_operations v9fs_file_inode_operations = {
+ .getattr = v9fs_vfs_getattr,
+ .setattr = v9fs_vfs_setattr,
+};
+
+static struct inode_operations v9fs_symlink_inode_operations = {
+ .readlink = v9fs_vfs_readlink,
+ .follow_link = v9fs_vfs_follow_link,
+ .put_link = v9fs_vfs_put_link,
+ .getattr = v9fs_vfs_getattr,
+ .setattr = v9fs_vfs_setattr,
+};
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
new file mode 100644
index 00000000000..868f350b2c5
--- /dev/null
+++ b/fs/9p/vfs_super.c
@@ -0,0 +1,280 @@
+/*
+ * linux/fs/9p/vfs_super.c
+ *
+ * This file contians superblock ops for 9P2000. It is intended that
+ * you mount this file system on directories.
+ *
+ * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * Free Software Foundation
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02111-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/inet.h>
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
+#include <linux/idr.h>
+
+#include "debug.h"
+#include "v9fs.h"
+#include "9p.h"
+#include "v9fs_vfs.h"
+#include "conv.h"
+#include "fid.h"
+
+static void v9fs_clear_inode(struct inode *);
+static struct super_operations v9fs_super_ops;
+
+/**
+ * v9fs_clear_inode - release an inode
+ * @inode: inode to release
+ *
+ */
+
+static void v9fs_clear_inode(struct inode *inode)
+{
+ filemap_fdatawrite(inode->i_mapping);
+}
+
+/**
+ * v9fs_set_super - set the superblock
+ * @s: super block
+ * @data: file system specific data
+ *
+ */
+
+static int v9fs_set_super(struct super_block *s, void *data)
+{
+ s->s_fs_info = data;
+ return set_anon_super(s, data);
+}
+
+/**
+ * v9fs_fill_super - populate superblock with info
+ * @sb: superblock
+ * @v9ses: session information
+ *
+ */
+
+static void
+v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
+ int flags)
+{
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize_bits = fls(v9ses->maxdata - 1);
+ sb->s_blocksize = 1 << sb->s_blocksize_bits;
+ sb->s_magic = V9FS_MAGIC;
+ sb->s_op = &v9fs_super_ops;
+
+ sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
+ MS_NODIRATIME | MS_NOATIME;
+}
+
+/**
+ * v9fs_get_sb - mount a superblock
+ * @fs_type: file system type
+ * @flags: mount flags
+ * @dev_name: device name that was mounted
+ * @data: mount options
+ *
+ */
+
+static struct super_block *v9fs_get_sb(struct file_system_type
+ *fs_type, int flags,
+ const char *dev_name, void *data)
+{
+ struct super_block *sb = NULL;
+ struct v9fs_fcall *fcall = NULL;
+ struct inode *inode = NULL;
+ struct dentry *root = NULL;
+ struct v9fs_session_info *v9ses = NULL;
+ struct v9fs_fid *root_fid = NULL;
+ int mode = S_IRWXUGO | S_ISVTX;
+ uid_t uid = current->fsuid;
+ gid_t gid = current->fsgid;
+ int stat_result = 0;
+ int newfid = 0;
+ int retval = 0;
+
+ dprintk(DEBUG_VFS, " \n");
+
+ v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL);
+ if (!v9ses)
+ return ERR_PTR(-ENOMEM);
+
+ if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
+ dprintk(DEBUG_ERROR, "problem initiating session\n");
+ retval = newfid;
+ goto free_session;
+ }
+
+ sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
+
+ v9fs_fill_super(sb, v9ses, flags);
+
+ inode = v9fs_get_inode(sb, S_IFDIR | mode);
+ if (IS_ERR(inode)) {
+ retval = PTR_ERR(inode);
+ goto put_back_sb;
+ }
+
+ inode->i_uid = uid;
+ inode->i_gid = gid;
+
+ root = d_alloc_root(inode);
+
+ if (!root) {
+ retval = -ENOMEM;
+ goto release_inode;
+ }
+
+ sb->s_root = root;
+
+ /* Setup the Root Inode */
+ root_fid = v9fs_fid_create(root);
+ if (root_fid == NULL) {
+ retval = -ENOMEM;
+ goto release_dentry;
+ }
+
+ root_fid->fidopen = 0;
+ root_fid->v9ses = v9ses;
+
+ stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
+ if (stat_result < 0) {
+ dprintk(DEBUG_ERROR, "stat error\n");
+ v9fs_t_clunk(v9ses, newfid, NULL);
+ v9fs_put_idpool(newfid, &v9ses->fidpool);
+ } else {
+ root_fid->fid = newfid;
+ root_fid->qid = fcall->params.rstat.stat->qid;
+ root->d_inode->i_ino =
+ v9fs_qid2ino(&fcall->params.rstat.stat->qid);
+ v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb);
+ }
+
+ kfree(fcall);
+
+ if (stat_result < 0) {
+ retval = stat_result;
+ goto release_dentry;
+ }
+
+ return sb;
+
+ release_dentry:
+ dput(sb->s_root);
+
+ release_inode:
+ iput(inode);
+
+ put_back_sb:
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ v9fs_session_close(v9ses);
+
+ free_session:
+ kfree(v9ses);
+
+ return ERR_PTR(retval);
+}
+
+/**
+ * v9fs_kill_super - Kill Superblock
+ * @s: superblock
+ *
+ */
+
+static void v9fs_kill_super(struct super_block *s)
+{
+ struct v9fs_session_info *v9ses = s->s_fs_info;
+
+ dprintk(DEBUG_VFS, " %p\n", s);
+
+ v9fs_dentry_release(s->s_root); /* clunk root */
+
+ kill_anon_super(s);
+
+ v9fs_session_close(v9ses);
+ kfree(v9ses);
+ dprintk(DEBUG_VFS, "exiting kill_super\n");
+}
+
+/**
+ * v9fs_show_options - Show mount options in /proc/mounts
+ * @m: seq_file to write to
+ * @mnt: mount descriptor
+ *
+ */
+
+static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+ struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
+
+ if (v9ses->debug != 0)
+ seq_printf(m, ",debug=%u", v9ses->debug);
+ if (v9ses->port != V9FS_PORT)
+ seq_printf(m, ",port=%u", v9ses->port);
+ if (v9ses->maxdata != 9000)
+ seq_printf(m, ",msize=%u", v9ses->maxdata);
+ if (v9ses->afid != ~0)
+ seq_printf(m, ",afid=%u", v9ses->afid);
+ if (v9ses->proto == PROTO_UNIX)
+ seq_puts(m, ",proto=unix");
+ if (v9ses->extended == 0)
+ seq_puts(m, ",noextend");
+ if (v9ses->nodev == 1)
+ seq_puts(m, ",nodevmap");
+ seq_printf(m, ",name=%s", v9ses->name);
+ seq_printf(m, ",aname=%s", v9ses->remotename);
+ seq_printf(m, ",uid=%u", v9ses->uid);
+ seq_printf(m, ",gid=%u", v9ses->gid);
+ return 0;
+}
+
+static void
+v9fs_umount_begin(struct super_block *sb)
+{
+ struct v9fs_session_info *v9ses = sb->s_fs_info;
+
+ v9fs_session_cancel(v9ses);
+}
+
+static struct super_operations v9fs_super_ops = {
+ .statfs = simple_statfs,
+ .clear_inode = v9fs_clear_inode,
+ .show_options = v9fs_show_options,
+ .umount_begin = v9fs_umount_begin,
+};
+
+struct file_system_type v9fs_fs_type = {
+ .name = "9P",
+ .get_sb = v9fs_get_sb,
+ .kill_sb = v9fs_kill_super,
+ .owner = THIS_MODULE,
+};
diff --git a/fs/Kconfig b/fs/Kconfig
index 5e817902cb3..068ccea2f18 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -462,6 +462,19 @@ config AUTOFS4_FS
local network, you probably do not need an automounter, and can say
N here.
+config FUSE_FS
+ tristate "Filesystem in Userspace support"
+ help
+ With FUSE it is possible to implement a fully functional filesystem
+ in a userspace program.
+
+ There's also companion library: libfuse. This library along with
+ utilities is available from the FUSE homepage:
+ <http://fuse.sourceforge.net/>
+
+ If you want to develop a userspace FS, or if you want to use
+ a filesystem based on FUSE, answer Y or M.
+
menu "CD-ROM/DVD Filesystems"
config ISO9660_FS
@@ -1703,6 +1716,17 @@ config AFS_FS
config RXRPC
tristate
+config 9P_FS
+ tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)"
+ depends on INET && EXPERIMENTAL
+ help
+ If you say Y here, you will get experimental support for
+ Plan 9 resource sharing via the 9P2000 protocol.
+
+ See <http://v9fs.sf.net> for more information.
+
+ If unsure, say N.
+
endmenu
menu "Partition Types"
diff --git a/fs/Makefile b/fs/Makefile
index 15158309dee..1972da18627 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -89,11 +89,13 @@ obj-$(CONFIG_QNX4FS_FS) += qnx4/
obj-$(CONFIG_AUTOFS_FS) += autofs/
obj-$(CONFIG_AUTOFS4_FS) += autofs4/
obj-$(CONFIG_ADFS_FS) += adfs/
+obj-$(CONFIG_FUSE_FS) += fuse/
obj-$(CONFIG_UDF_FS) += udf/
obj-$(CONFIG_RELAYFS_FS) += relayfs/
obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/
obj-$(CONFIG_JFS_FS) += jfs/
obj-$(CONFIG_XFS_FS) += xfs/
+obj-$(CONFIG_9P_FS) += 9p/
obj-$(CONFIG_AFS_FS) += afs/
obj-$(CONFIG_BEFS_FS) += befs/
obj-$(CONFIG_HOSTFS) += hostfs/
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 7aa6f200453..9ebe881c678 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -255,6 +255,7 @@ void
affs_delete_inode(struct inode *inode)
{
pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
+ truncate_inode_pages(&inode->i_data, 0);
inode->i_size = 0;
if (S_ISREG(inode->i_mode))
affs_truncate(inode);
diff --git a/fs/aio.c b/fs/aio.c
index 4f641abac3c..38f62680fd6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -29,6 +29,7 @@
#include <linux/highmem.h>
#include <linux/workqueue.h>
#include <linux/security.h>
+#include <linux/rcuref.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
@@ -499,7 +500,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
/* Must be done under the lock to serialise against cancellation.
* Call this aio_fput as it duplicates fput via the fput_work.
*/
- if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) {
+ if (unlikely(rcuref_dec_and_test(&req->ki_filp->f_count))) {
get_ioctx(ctx);
spin_lock(&fput_lock);
list_add(&req->ki_list, &fput_head);
@@ -546,6 +547,24 @@ struct kioctx *lookup_ioctx(unsigned long ctx_id)
return ioctx;
}
+static int lock_kiocb_action(void *param)
+{
+ schedule();
+ return 0;
+}
+
+static inline void lock_kiocb(struct kiocb *iocb)
+{
+ wait_on_bit_lock(&iocb->ki_flags, KIF_LOCKED, lock_kiocb_action,
+ TASK_UNINTERRUPTIBLE);
+}
+
+static inline void unlock_kiocb(struct kiocb *iocb)
+{
+ kiocbClearLocked(iocb);
+ wake_up_bit(&iocb->ki_flags, KIF_LOCKED);
+}
+
/*
* use_mm
* Makes the calling kernel thread take on the specified
@@ -786,7 +805,9 @@ static int __aio_run_iocbs(struct kioctx *ctx)
* Hold an extra reference while retrying i/o.
*/
iocb->ki_users++; /* grab extra reference */
+ lock_kiocb(iocb);
aio_run_iocb(iocb);
+ unlock_kiocb(iocb);
if (__aio_put_req(ctx, iocb)) /* drop extra ref */
put_ioctx(ctx);
}
@@ -1527,10 +1548,9 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
goto out_put_req;
spin_lock_irq(&ctx->ctx_lock);
- if (likely(list_empty(&ctx->run_list))) {
- aio_run_iocb(req);
- } else {
- list_add_tail(&req->ki_run_list, &ctx->run_list);
+ aio_run_iocb(req);
+ unlock_kiocb(req);
+ if (!list_empty(&ctx->run_list)) {
/* drain the run list */
while (__aio_run_iocbs(ctx))
;
@@ -1661,6 +1681,7 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
if (NULL != cancel) {
struct io_event tmp;
pr_debug("calling cancel\n");
+ lock_kiocb(kiocb);
memset(&tmp, 0, sizeof(tmp));
tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user;
tmp.data = kiocb->ki_user_data;
@@ -1672,8 +1693,9 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
if (copy_to_user(result, &tmp, sizeof(tmp)))
ret = -EFAULT;
}
+ unlock_kiocb(kiocb);
} else
- printk(KERN_DEBUG "iocb has no cancel operation\n");
+ ret = -EINVAL;
put_ioctx(ctx);
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 6171431272d..990c28da5ae 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -105,6 +105,7 @@ struct autofs_sb_info {
struct file *pipe;
pid_t oz_pgrp;
int catatonic;
+ struct super_block *sb;
unsigned long exp_timeout;
ino_t next_dir_ino;
struct autofs_wait_queue *queues; /* Wait queue pointer */
@@ -134,7 +135,7 @@ void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
void autofs_hash_delete(struct autofs_dir_ent *);
struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *);
void autofs_hash_dputall(struct autofs_dirhash *);
-void autofs_hash_nuke(struct autofs_dirhash *);
+void autofs_hash_nuke(struct autofs_sb_info *);
/* Expiration-handling functions */
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
index 448143fd079..5ccfcf26310 100644
--- a/fs/autofs/dirhash.c
+++ b/fs/autofs/dirhash.c
@@ -232,13 +232,13 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
/* Delete everything. This is used on filesystem destruction, so we
make no attempt to keep the pointers valid */
-void autofs_hash_nuke(struct autofs_dirhash *dh)
+void autofs_hash_nuke(struct autofs_sb_info *sbi)
{
int i;
struct autofs_dir_ent *ent, *nent;
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
- for ( ent = dh->h[i] ; ent ; ent = nent ) {
+ for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
nent = ent->next;
if ( ent->dentry )
dput(ent->dentry);
@@ -246,4 +246,5 @@ void autofs_hash_nuke(struct autofs_dirhash *dh)
kfree(ent);
}
}
+ shrink_dcache_sb(sbi->sb);
}
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index 4888c1fabbf..65e5ed42190 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -27,7 +27,7 @@ static void autofs_put_super(struct super_block *sb)
if ( !sbi->catatonic )
autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
- autofs_hash_nuke(&sbi->dirhash);
+ autofs_hash_nuke(sbi);
for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
if ( test_bit(n, sbi->symlink_bitmap) )
kfree(sbi->symlink[n].data);
@@ -148,6 +148,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
s->s_magic = AUTOFS_SUPER_MAGIC;
s->s_op = &autofs_sops;
s->s_time_gran = 1;
+ sbi->sb = s;
root_inode = iget(s, AUTOFS_ROOT_INO);
root = d_alloc_root(root_inode);
diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h
index 1020dbc88be..1fbc53f14ab 100644
--- a/fs/bfs/bfs.h
+++ b/fs/bfs/bfs.h
@@ -20,7 +20,6 @@ struct bfs_sb_info {
unsigned long si_lasti;
unsigned long * si_imap;
struct buffer_head * si_sbh; /* buffer header w/superblock */
- struct bfs_super_block * si_bfs_sb; /* superblock in si_sbh->b_data */
};
/*
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 5a1e5ce057f..e240c335eb2 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -2,6 +2,7 @@
* fs/bfs/dir.c
* BFS directory operations.
* Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
+ * Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
*/
#include <linux/time.h>
@@ -20,9 +21,9 @@
#define dprintf(x...)
#endif
-static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ino);
+static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino);
static struct buffer_head * bfs_find_entry(struct inode * dir,
- const char * name, int namelen, struct bfs_dirent ** res_dir);
+ const unsigned char * name, int namelen, struct bfs_dirent ** res_dir);
static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
{
@@ -53,7 +54,7 @@ static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir)
de = (struct bfs_dirent *)(bh->b_data + offset);
if (de->ino) {
int size = strnlen(de->name, BFS_NAMELEN);
- if (filldir(dirent, de->name, size, f->f_pos, de->ino, DT_UNKNOWN) < 0) {
+ if (filldir(dirent, de->name, size, f->f_pos, le16_to_cpu(de->ino), DT_UNKNOWN) < 0) {
brelse(bh);
unlock_kernel();
return 0;
@@ -107,7 +108,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
inode->i_mapping->a_ops = &bfs_aops;
inode->i_mode = mode;
inode->i_ino = ino;
- BFS_I(inode)->i_dsk_ino = ino;
+ BFS_I(inode)->i_dsk_ino = cpu_to_le16(ino);
BFS_I(inode)->i_sblock = 0;
BFS_I(inode)->i_eblock = 0;
insert_inode_hash(inode);
@@ -139,7 +140,7 @@ static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, st
lock_kernel();
bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
if (bh) {
- unsigned long ino = le32_to_cpu(de->ino);
+ unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
brelse(bh);
inode = iget(dir->i_sb, ino);
if (!inode) {
@@ -183,7 +184,7 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry)
inode = dentry->d_inode;
lock_kernel();
bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
- if (!bh || de->ino != inode->i_ino)
+ if (!bh || le16_to_cpu(de->ino) != inode->i_ino)
goto out_brelse;
if (!inode->i_nlink) {
@@ -224,7 +225,7 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
old_dentry->d_name.name,
old_dentry->d_name.len, &old_de);
- if (!old_bh || old_de->ino != old_inode->i_ino)
+ if (!old_bh || le16_to_cpu(old_de->ino) != old_inode->i_ino)
goto end_rename;
error = -EPERM;
@@ -270,7 +271,7 @@ struct inode_operations bfs_dir_inops = {
.rename = bfs_rename,
};
-static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int ino)
+static int bfs_add_entry(struct inode * dir, const unsigned char * name, int namelen, int ino)
{
struct buffer_head * bh;
struct bfs_dirent * de;
@@ -304,7 +305,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
}
dir->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
- de->ino = ino;
+ de->ino = cpu_to_le16((u16)ino);
for (i=0; i<BFS_NAMELEN; i++)
de->name[i] = (i < namelen) ? name[i] : 0;
mark_buffer_dirty(bh);
@@ -317,7 +318,7 @@ static int bfs_add_entry(struct inode * dir, const char * name, int namelen, int
return -ENOSPC;
}
-static inline int bfs_namecmp(int len, const char * name, const char * buffer)
+static inline int bfs_namecmp(int len, const unsigned char * name, const char * buffer)
{
if (len < BFS_NAMELEN && buffer[len])
return 0;
@@ -325,7 +326,7 @@ static inline int bfs_namecmp(int len, const char * name, const char * buffer)
}
static struct buffer_head * bfs_find_entry(struct inode * dir,
- const char * name, int namelen, struct bfs_dirent ** res_dir)
+ const unsigned char * name, int namelen, struct bfs_dirent ** res_dir)
{
unsigned long block, offset;
struct buffer_head * bh;
@@ -346,7 +347,7 @@ static struct buffer_head * bfs_find_entry(struct inode * dir,
}
de = (struct bfs_dirent *)(bh->b_data + offset);
offset += BFS_DIRENT_SIZE;
- if (de->ino && bfs_namecmp(namelen, name, de->name)) {
+ if (le16_to_cpu(de->ino) && bfs_namecmp(namelen, name, de->name)) {
*res_dir = de;
return bh;
}
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 747fd1ea55e..807723b65da 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
return 0;
}
-static int bfs_move_blocks(struct super_block *sb, unsigned long start, unsigned long end,
- unsigned long where)
+static int bfs_move_blocks(struct super_block *sb, unsigned long start,
+ unsigned long end, unsigned long where)
{
unsigned long i;
@@ -57,20 +57,21 @@ static int bfs_move_blocks(struct super_block *sb, unsigned long start, unsigned
static int bfs_get_block(struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create)
{
- long phys;
+ unsigned long phys;
int err;
struct super_block *sb = inode->i_sb;
struct bfs_sb_info *info = BFS_SB(sb);
struct bfs_inode_info *bi = BFS_I(inode);
struct buffer_head *sbh = info->si_sbh;
- if (block < 0 || block > info->si_blocks)
+ if (block > info->si_blocks)
return -EIO;
phys = bi->i_sblock + block;
if (!create) {
if (phys <= bi->i_eblock) {
- dprintf("c=%d, b=%08lx, phys=%08lx (granted)\n", create, block, phys);
+ dprintf("c=%d, b=%08lx, phys=%09lx (granted)\n",
+ create, (unsigned long)block, phys);
map_bh(bh_result, sb, phys);
}
return 0;
@@ -80,7 +81,7 @@ static int bfs_get_block(struct inode * inode, sector_t block,
of blocks allocated for this file, we can grant it */
if (inode->i_size && phys <= bi->i_eblock) {
dprintf("c=%d, b=%08lx, phys=%08lx (interim block granted)\n",
- create, block, phys);
+ create, (unsigned long)block, phys);
map_bh(bh_result, sb, phys);
return 0;
}
@@ -88,11 +89,12 @@ static int bfs_get_block(struct inode * inode, sector_t block,
/* the rest has to be protected against itself */
lock_kernel();
- /* if the last data block for this file is the last allocated block, we can
- extend the file trivially, without moving it anywhere */
+ /* if the last data block for this file is the last allocated
+ block, we can extend the file trivially, without moving it
+ anywhere */
if (bi->i_eblock == info->si_lf_eblk) {
dprintf("c=%d, b=%08lx, phys=%08lx (simple extension)\n",
- create, block, phys);
+ create, (unsigned long)block, phys);
map_bh(bh_result, sb, phys);
info->si_freeb -= phys - bi->i_eblock;
info->si_lf_eblk = bi->i_eblock = phys;
@@ -114,7 +116,8 @@ static int bfs_get_block(struct inode * inode, sector_t block,
} else
err = 0;
- dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n", create, block, phys);
+ dprintf("c=%d, b=%08lx, phys=%08lx (moved)\n",
+ create, (unsigned long)block, phys);
bi->i_sblock = phys;
phys += block;
info->si_lf_eblk = bi->i_eblock = phys;
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 64e0fb33fc0..c7b39aa279d 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -3,6 +3,8 @@
* BFS superblock and inode operations.
* Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
* From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
+ *
+ * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
*/
#include <linux/module.h>
@@ -54,46 +56,50 @@ static void bfs_read_inode(struct inode * inode)
off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
di = (struct bfs_inode *)bh->b_data + off;
- inode->i_mode = 0x0000FFFF & di->i_mode;
- if (di->i_vtype == BFS_VDIR) {
+ inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
+ if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
inode->i_mode |= S_IFDIR;
inode->i_op = &bfs_dir_inops;
inode->i_fop = &bfs_dir_operations;
- } else if (di->i_vtype == BFS_VREG) {
+ } else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
inode->i_mode |= S_IFREG;
inode->i_op = &bfs_file_inops;
inode->i_fop = &bfs_file_operations;
inode->i_mapping->a_ops = &bfs_aops;
}
- inode->i_uid = di->i_uid;
- inode->i_gid = di->i_gid;
- inode->i_nlink = di->i_nlink;
+ BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock);
+ BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock);
+ inode->i_uid = le32_to_cpu(di->i_uid);
+ inode->i_gid = le32_to_cpu(di->i_gid);
+ inode->i_nlink = le32_to_cpu(di->i_nlink);
inode->i_size = BFS_FILESIZE(di);
inode->i_blocks = BFS_FILEBLOCKS(di);
+ if (inode->i_size || inode->i_blocks) dprintf("Registered inode with %lld size, %ld blocks\n", inode->i_size, inode->i_blocks);
inode->i_blksize = PAGE_SIZE;
- inode->i_atime.tv_sec = di->i_atime;
- inode->i_mtime.tv_sec = di->i_mtime;
- inode->i_ctime.tv_sec = di->i_ctime;
+ inode->i_atime.tv_sec = le32_to_cpu(di->i_atime);
+ inode->i_mtime.tv_sec = le32_to_cpu(di->i_mtime);
+ inode->i_ctime.tv_sec = le32_to_cpu(di->i_ctime);
inode->i_atime.tv_nsec = 0;
inode->i_mtime.tv_nsec = 0;
inode->i_ctime.tv_nsec = 0;
- BFS_I(inode)->i_dsk_ino = di->i_ino; /* can be 0 so we store a copy */
- BFS_I(inode)->i_sblock = di->i_sblock;
- BFS_I(inode)->i_eblock = di->i_eblock;
+ BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we store a copy */
brelse(bh);
}
static int bfs_write_inode(struct inode * inode, int unused)
{
- unsigned long ino = inode->i_ino;
+ unsigned int ino = (u16)inode->i_ino;
+ unsigned long i_sblock;
struct bfs_inode * di;
struct buffer_head * bh;
int block, off;
+ dprintf("ino=%08x\n", ino);
+
if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
- printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
+ printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
return -EIO;
}
@@ -101,7 +107,7 @@ static int bfs_write_inode(struct inode * inode, int unused)
block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
bh = sb_bread(inode->i_sb, block);
if (!bh) {
- printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino);
+ printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino);
unlock_kernel();
return -EIO;
}
@@ -109,24 +115,26 @@ static int bfs_write_inode(struct inode * inode, int unused)
off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
di = (struct bfs_inode *)bh->b_data + off;
- if (inode->i_ino == BFS_ROOT_INO)
- di->i_vtype = BFS_VDIR;
+ if (ino == BFS_ROOT_INO)
+ di->i_vtype = cpu_to_le32(BFS_VDIR);
else
- di->i_vtype = BFS_VREG;
-
- di->i_ino = inode->i_ino;
- di->i_mode = inode->i_mode;
- di->i_uid = inode->i_uid;
- di->i_gid = inode->i_gid;
- di->i_nlink = inode->i_nlink;
- di->i_atime = inode->i_atime.tv_sec;
- di->i_mtime = inode->i_mtime.tv_sec;
- di->i_ctime = inode->i_ctime.tv_sec;
- di->i_sblock = BFS_I(inode)->i_sblock;
- di->i_eblock = BFS_I(inode)->i_eblock;
- di->i_eoffset = di->i_sblock * BFS_BSIZE + inode->i_size - 1;
+ di->i_vtype = cpu_to_le32(BFS_VREG);
+
+ di->i_ino = cpu_to_le16(ino);
+ di->i_mode = cpu_to_le32(inode->i_mode);
+ di->i_uid = cpu_to_le32(inode->i_uid);
+ di->i_gid = cpu_to_le32(inode->i_gid);
+ di->i_nlink = cpu_to_le32(inode->i_nlink);
+ di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
+ di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
+ di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
+ i_sblock = BFS_I(inode)->i_sblock;
+ di->i_sblock = cpu_to_le32(i_sblock);
+ di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
+ di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
mark_buffer_dirty(bh);
+ dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di->i_ino),block,off);
brelse(bh);
unlock_kernel();
return 0;
@@ -140,11 +148,14 @@ static void bfs_delete_inode(struct inode * inode)
int block, off;
struct super_block * s = inode->i_sb;
struct bfs_sb_info * info = BFS_SB(s);
+ struct bfs_inode_info * bi = BFS_I(inode);
- dprintf("ino=%08lx\n", inode->i_ino);
+ dprintf("ino=%08lx\n", ino);
- if (inode->i_ino < BFS_ROOT_INO || inode->i_ino > info->si_lasti) {
- printf("invalid ino=%08lx\n", inode->i_ino);
+ truncate_inode_pages(&inode->i_data, 0);
+
+ if (ino < BFS_ROOT_INO || ino > info->si_lasti) {
+ printf("invalid ino=%08lx\n", ino);
return;
}
@@ -160,13 +171,13 @@ static void bfs_delete_inode(struct inode * inode)
return;
}
off = (ino - BFS_ROOT_INO)%BFS_INODES_PER_BLOCK;
- di = (struct bfs_inode *)bh->b_data + off;
- if (di->i_ino) {
- info->si_freeb += BFS_FILEBLOCKS(di);
+ di = (struct bfs_inode *) bh->b_data + off;
+ if (bi->i_dsk_ino) {
+ info->si_freeb += 1 + bi->i_eblock - bi->i_sblock;
info->si_freei++;
- clear_bit(di->i_ino, info->si_imap);
+ clear_bit(ino, info->si_imap);
dump_imap("delete_inode", s);
- }
+ }
di->i_ino = 0;
di->i_sblock = 0;
mark_buffer_dirty(bh);
@@ -272,14 +283,14 @@ static struct super_operations bfs_sops = {
void dump_imap(const char *prefix, struct super_block * s)
{
-#if 0
+#ifdef DEBUG
int i;
char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
if (!tmpbuf)
return;
for (i=BFS_SB(s)->si_lasti; i>=0; i--) {
- if (i>PAGE_SIZE-100) break;
+ if (i > PAGE_SIZE-100) break;
if (test_bit(i, BFS_SB(s)->si_imap))
strcat(tmpbuf, "1");
else
@@ -295,7 +306,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
struct buffer_head * bh;
struct bfs_super_block * bfs_sb;
struct inode * inode;
- int i, imap_len;
+ unsigned i, imap_len;
struct bfs_sb_info * info;
info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -310,19 +321,18 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
if(!bh)
goto out;
bfs_sb = (struct bfs_super_block *)bh->b_data;
- if (bfs_sb->s_magic != BFS_MAGIC) {
+ if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
if (!silent)
printf("No BFS filesystem on %s (magic=%08x)\n",
- s->s_id, bfs_sb->s_magic);
+ s->s_id, le32_to_cpu(bfs_sb->s_magic));
goto out;
}
if (BFS_UNCLEAN(bfs_sb, s) && !silent)
printf("%s is unclean, continuing\n", s->s_id);
s->s_magic = BFS_MAGIC;
- info->si_bfs_sb = bfs_sb;
info->si_sbh = bh;
- info->si_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode)
+ info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE)/sizeof(struct bfs_inode)
+ BFS_ROOT_INO - 1;
imap_len = info->si_lasti/8 + 1;
@@ -346,8 +356,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
goto out;
}
- info->si_blocks = (bfs_sb->s_end + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
- info->si_freeb = (bfs_sb->s_end + 1 - bfs_sb->s_start)>>BFS_BSIZE_BITS;
+ info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1)>>BFS_BSIZE_BITS; /* for statfs(2) */
+ info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - cpu_to_le32(bfs_sb->s_start))>>BFS_BSIZE_BITS;
info->si_freei = 0;
info->si_lf_eblk = 0;
info->si_lf_sblk = 0;
diff --git a/fs/bio.c b/fs/bio.c
index a7d4fd3a329..83a34957456 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,
{
struct sg_iovec iov;
- iov.iov_base = (__user void *)uaddr;
+ iov.iov_base = (void __user *)uaddr;
iov.iov_len = len;
return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm);
diff --git a/fs/compat.c b/fs/compat.c
index 8c665705c6a..ac3fb9ed8ee 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
char *bits;
long timeout;
int size, max_fdset, ret = -EINVAL;
+ struct fdtable *fdt;
timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
@@ -1644,7 +1645,10 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
goto out_nofds;
/* max_fdset can increase, so grab it once to avoid race */
- max_fdset = current->files->max_fdset;
+ rcu_read_lock();
+ fdt = files_fdtable(current->files);
+ max_fdset = fdt->max_fdset;
+ rcu_read_unlock();
if (n > max_fdset)
n = max_fdset;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 155e612635f..e28a74203f3 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)
r = (void *) &r4;
}
- if (ret)
- return -EFAULT;
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
set_fs (KERNEL_DS);
ret = sys_ioctl (fd, cmd, (unsigned long) r);
set_fs (old_fs);
+out:
if (mysock)
sockfd_put(mysock);
diff --git a/fs/exec.c b/fs/exec.c
index 222ab1c572d..14dd03907cc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -798,6 +798,7 @@ no_thread_group:
static inline void flush_old_files(struct files_struct * files)
{
long j = -1;
+ struct fdtable *fdt;
spin_lock(&files->file_lock);
for (;;) {
@@ -805,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files)
j++;
i = j * __NFDBITS;
- if (i >= files->max_fds || i >= files->max_fdset)
+ fdt = files_fdtable(files);
+ if (i >= fdt->max_fds || i >= fdt->max_fdset)
break;
- set = files->close_on_exec->fds_bits[j];
+ set = fdt->close_on_exec->fds_bits[j];
if (!set)
continue;
- files->close_on_exec->fds_bits[j] = 0;
+ fdt->close_on_exec->fds_bits[j] = 0;
spin_unlock(&files->file_lock);
for ( ; set ; i++,set >>= 1) {
if (set & 1) {
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 161f156d98c..c8d07030c89 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -615,6 +615,11 @@ got:
DQUOT_DROP(inode);
goto fail2;
}
+ err = ext2_init_security(inode,dir);
+ if (err) {
+ DQUOT_FREE_INODE(inode);
+ goto fail2;
+ }
mark_inode_dirty(inode);
ext2_debug("allocating inode %lu\n", inode->i_ino);
ext2_preread_inode(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 53dceb0c659..fdba4d1d3c6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -71,6 +71,8 @@ void ext2_put_inode(struct inode *inode)
*/
void ext2_delete_inode (struct inode * inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+
if (is_bad_inode(inode))
goto no_delete;
EXT2_I(inode)->i_dtime = get_seconds();
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 5f3bfde3b81..67cfeb66e89 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -116,3 +116,11 @@ exit_ext2_xattr(void)
# endif /* CONFIG_EXT2_FS_XATTR */
+#ifdef CONFIG_EXT2_FS_SECURITY
+extern int ext2_init_security(struct inode *inode, struct inode *dir);
+#else
+static inline int ext2_init_security(struct inode *inode, struct inode *dir)
+{
+ return 0;
+}
+#endif
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 6a6c59fbe59..a2661279847 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -8,6 +8,7 @@
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/ext2_fs.h>
+#include <linux/security.h>
#include "xattr.h"
static size_t
@@ -45,6 +46,27 @@ ext2_xattr_security_set(struct inode *inode, const char *name,
value, size, flags);
}
+int
+ext2_init_security(struct inode *inode, struct inode *dir)
+{
+ int err;
+ size_t len;
+ void *value;
+ char *name;
+
+ err = security_inode_init_security(inode, dir, &name, &value, &len);
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ return 0;
+ return err;
+ }
+ err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
+ name, value, len, 0);
+ kfree(name);
+ kfree(value);
+ return err;
+}
+
struct xattr_handler ext2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list,
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 6981bd014ed..96552769d03 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -607,6 +607,11 @@ got:
DQUOT_DROP(inode);
goto fail2;
}
+ err = ext3_init_security(handle,inode, dir);
+ if (err) {
+ DQUOT_FREE_INODE(inode);
+ goto fail2;
+ }
err = ext3_mark_inode_dirty(handle, inode);
if (err) {
ext3_std_error(sb, err);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 9989fdcf4d5..b5177c90d6f 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -187,6 +187,8 @@ void ext3_delete_inode (struct inode * inode)
{
handle_t *handle;
+ truncate_inode_pages(&inode->i_data, 0);
+
if (is_bad_inode(inode))
goto no_delete;
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index eb31a69e82d..2ceae38f3d4 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -133,3 +133,14 @@ exit_ext3_xattr(void)
#define ext3_xattr_handlers NULL
# endif /* CONFIG_EXT3_FS_XATTR */
+
+#ifdef CONFIG_EXT3_FS_SECURITY
+extern int ext3_init_security(handle_t *handle, struct inode *inode,
+ struct inode *dir);
+#else
+static inline int ext3_init_security(handle_t *handle, struct inode *inode,
+ struct inode *dir)
+{
+ return 0;
+}
+#endif
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index ddc1c41750e..b9c40c15647 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -9,6 +9,7 @@
#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
+#include <linux/security.h>
#include "xattr.h"
static size_t
@@ -47,6 +48,27 @@ ext3_xattr_security_set(struct inode *inode, const char *name,
value, size, flags);
}
+int
+ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+ int err;
+ size_t len;
+ void *value;
+ char *name;
+
+ err = security_inode_init_security(inode, dir, &name, &value, &len);
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ return 0;
+ return err;
+ }
+ err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
+ name, value, len, 0);
+ kfree(name);
+ kfree(value);
+ return err;
+}
+
struct xattr_handler ext3_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext3_xattr_security_list,
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 96ae85b67eb..a7cbe68e225 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -335,6 +335,8 @@ EXPORT_SYMBOL(fat_build_inode);
static void fat_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+
if (!is_bad_inode(inode)) {
inode->i_size = 0;
fat_truncate(inode);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6fbc9d8fcc3..863b46e0d78 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -16,6 +16,7 @@
#include <linux/security.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
+#include <linux/rcupdate.h>
#include <asm/poll.h>
#include <asm/siginfo.h>
@@ -24,21 +25,25 @@
void fastcall set_close_on_exec(unsigned int fd, int flag)
{
struct files_struct *files = current->files;
+ struct fdtable *fdt;
spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
if (flag)
- FD_SET(fd, files->close_on_exec);
+ FD_SET(fd, fdt->close_on_exec);
else
- FD_CLR(fd, files->close_on_exec);
+ FD_CLR(fd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
}
static inline int get_close_on_exec(unsigned int fd)
{
struct files_struct *files = current->files;
+ struct fdtable *fdt;
int res;
- spin_lock(&files->file_lock);
- res = FD_ISSET(fd, files->close_on_exec);
- spin_unlock(&files->file_lock);
+ rcu_read_lock();
+ fdt = files_fdtable(files);
+ res = FD_ISSET(fd, fdt->close_on_exec);
+ rcu_read_unlock();
return res;
}
@@ -54,24 +59,26 @@ static int locate_fd(struct files_struct *files,
unsigned int newfd;
unsigned int start;
int error;
+ struct fdtable *fdt;
error = -EINVAL;
if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
goto out;
repeat:
+ fdt = files_fdtable(files);
/*
* Someone might have closed fd's in the range
- * orig_start..files->next_fd
+ * orig_start..fdt->next_fd
*/
start = orig_start;
- if (start < files->next_fd)
- start = files->next_fd;
+ if (start < fdt->next_fd)
+ start = fdt->next_fd;
newfd = start;
- if (start < files->max_fdset) {
- newfd = find_next_zero_bit(files->open_fds->fds_bits,
- files->max_fdset, start);
+ if (start < fdt->max_fdset) {
+ newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
+ fdt->max_fdset, start);
}
error = -EMFILE;
@@ -89,9 +96,15 @@ repeat:
if (error)
goto repeat;
- if (start <= files->next_fd)
- files->next_fd = newfd + 1;
-
+ /*
+ * We reacquired files_lock, so we are safe as long as
+ * we reacquire the fdtable pointer and use it while holding
+ * the lock, no one can free it during that time.
+ */
+ fdt = files_fdtable(files);
+ if (start <= fdt->next_fd)
+ fdt->next_fd = newfd + 1;
+
error = newfd;
out:
@@ -101,13 +114,16 @@ out:
static int dupfd(struct file *file, unsigned int start)
{
struct files_struct * files = current->files;
+ struct fdtable *fdt;
int fd;
spin_lock(&files->file_lock);
fd = locate_fd(files, file, start);
if (fd >= 0) {
- FD_SET(fd, files->open_fds);
- FD_CLR(fd, files->close_on_exec);
+ /* locate_fd() may have expanded fdtable, load the ptr */
+ fdt = files_fdtable(files);
+ FD_SET(fd, fdt->open_fds);
+ FD_CLR(fd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
fd_install(fd, file);
} else {
@@ -123,6 +139,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
int err = -EBADF;
struct file * file, *tofree;
struct files_struct * files = current->files;
+ struct fdtable *fdt;
spin_lock(&files->file_lock);
if (!(file = fcheck(oldfd)))
@@ -148,13 +165,14 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
/* Yes. It's a race. In user space. Nothing sane to do */
err = -EBUSY;
- tofree = files->fd[newfd];
- if (!tofree && FD_ISSET(newfd, files->open_fds))
+ fdt = files_fdtable(files);
+ tofree = fdt->fd[newfd];
+ if (!tofree && FD_ISSET(newfd, fdt->open_fds))
goto out_fput;
- files->fd[newfd] = file;
- FD_SET(newfd, files->open_fds);
- FD_CLR(newfd, files->close_on_exec);
+ rcu_assign_pointer(fdt->fd[newfd], file);
+ FD_SET(newfd, fdt->open_fds);
+ FD_CLR(newfd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
if (tofree)
diff --git a/fs/file.c b/fs/file.c
index 92b5f25985d..2127a7b9dc3 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -13,6 +13,25 @@
#include <linux/vmalloc.h>
#include <linux/file.h>
#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/workqueue.h>
+
+struct fdtable_defer {
+ spinlock_t lock;
+ struct work_struct wq;
+ struct timer_list timer;
+ struct fdtable *next;
+};
+
+/*
+ * We use this list to defer free fdtables that have vmalloced
+ * sets/arrays. By keeping a per-cpu list, we avoid having to embed
+ * the work_struct in fdtable itself which avoids a 64 byte (i386) increase in
+ * this per-task structure.
+ */
+static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);
/*
@@ -48,82 +67,143 @@ void free_fd_array(struct file **array, int num)
vfree(array);
}
-/*
- * Expand the fd array in the files_struct. Called with the files
- * spinlock held for write.
- */
+static void __free_fdtable(struct fdtable *fdt)
+{
+ int fdset_size, fdarray_size;
-static int expand_fd_array(struct files_struct *files, int nr)
- __releases(files->file_lock)
- __acquires(files->file_lock)
+ fdset_size = fdt->max_fdset / 8;
+ fdarray_size = fdt->max_fds * sizeof(struct file *);
+ free_fdset(fdt->open_fds, fdset_size);
+ free_fdset(fdt->close_on_exec, fdset_size);
+ free_fd_array(fdt->fd, fdarray_size);
+ kfree(fdt);
+}
+
+static void fdtable_timer(unsigned long data)
{
- struct file **new_fds;
- int error, nfds;
+ struct fdtable_defer *fddef = (struct fdtable_defer *)data;
-
- error = -EMFILE;
- if (files->max_fds >= NR_OPEN || nr >= NR_OPEN)
+ spin_lock(&fddef->lock);
+ /*
+ * If someone already emptied the queue return.
+ */
+ if (!fddef->next)
goto out;
+ if (!schedule_work(&fddef->wq))
+ mod_timer(&fddef->timer, 5);
+out:
+ spin_unlock(&fddef->lock);
+}
- nfds = files->max_fds;
- spin_unlock(&files->file_lock);
+static void free_fdtable_work(struct fdtable_defer *f)
+{
+ struct fdtable *fdt;
- /*
- * Expand to the max in easy steps, and keep expanding it until
- * we have enough for the requested fd array size.
- */
+ spin_lock_bh(&f->lock);
+ fdt = f->next;
+ f->next = NULL;
+ spin_unlock_bh(&f->lock);
+ while(fdt) {
+ struct fdtable *next = fdt->next;
+ __free_fdtable(fdt);
+ fdt = next;
+ }
+}
- do {
-#if NR_OPEN_DEFAULT < 256
- if (nfds < 256)
- nfds = 256;
- else
-#endif
- if (nfds < (PAGE_SIZE / sizeof(struct file *)))
- nfds = PAGE_SIZE / sizeof(struct file *);
- else {
- nfds = nfds * 2;
- if (nfds > NR_OPEN)
- nfds = NR_OPEN;
- }
- } while (nfds <= nr);
+static void free_fdtable_rcu(struct rcu_head *rcu)
+{
+ struct fdtable *fdt = container_of(rcu, struct fdtable, rcu);
+ int fdset_size, fdarray_size;
+ struct fdtable_defer *fddef;
- error = -ENOMEM;
- new_fds = alloc_fd_array(nfds);
- spin_lock(&files->file_lock);
- if (!new_fds)
- goto out;
+ BUG_ON(!fdt);
+ fdset_size = fdt->max_fdset / 8;
+ fdarray_size = fdt->max_fds * sizeof(struct file *);
- /* Copy the existing array and install the new pointer */
-
- if (nfds > files->max_fds) {
- struct file **old_fds;
- int i;
-
- old_fds = xchg(&files->fd, new_fds);
- i = xchg(&files->max_fds, nfds);
-
- /* Don't copy/clear the array if we are creating a new
- fd array for fork() */
- if (i) {
- memcpy(new_fds, old_fds, i * sizeof(struct file *));
- /* clear the remainder of the array */
- memset(&new_fds[i], 0,
- (nfds-i) * sizeof(struct file *));
-
- spin_unlock(&files->file_lock);
- free_fd_array(old_fds, i);
- spin_lock(&files->file_lock);
- }
+ if (fdt->free_files) {
+ /*
+ * The this fdtable was embedded in the files structure
+ * and the files structure itself was getting destroyed.
+ * It is now safe to free the files structure.
+ */
+ kmem_cache_free(files_cachep, fdt->free_files);
+ return;
+ }
+ if (fdt->max_fdset <= __FD_SETSIZE && fdt->max_fds <= NR_OPEN_DEFAULT) {
+ /*
+ * The fdtable was embedded
+ */
+ return;
+ }
+ if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) {
+ kfree(fdt->open_fds);
+ kfree(fdt->close_on_exec);
+ kfree(fdt->fd);
+ kfree(fdt);
} else {
- /* Somebody expanded the array while we slept ... */
- spin_unlock(&files->file_lock);
- free_fd_array(new_fds, nfds);
- spin_lock(&files->file_lock);
+ fddef = &get_cpu_var(fdtable_defer_list);
+ spin_lock(&fddef->lock);
+ fdt->next = fddef->next;
+ fddef->next = fdt;
+ /*
+ * vmallocs are handled from the workqueue context.
+ * If the per-cpu workqueue is running, then we
+ * defer work scheduling through a timer.
+ */
+ if (!schedule_work(&fddef->wq))
+ mod_timer(&fddef->timer, 5);
+ spin_unlock(&fddef->lock);
+ put_cpu_var(fdtable_defer_list);
}
- error = 0;
-out:
- return error;
+}
+
+void free_fdtable(struct fdtable *fdt)
+{
+ if (fdt->free_files || fdt->max_fdset > __FD_SETSIZE ||
+ fdt->max_fds > NR_OPEN_DEFAULT)
+ call_rcu(&fdt->rcu, free_fdtable_rcu);
+}
+
+/*
+ * Expand the fdset in the files_struct. Called with the files spinlock
+ * held for write.
+ */
+static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt)
+{
+ int i;
+ int count;
+
+ BUG_ON(nfdt->max_fdset < fdt->max_fdset);
+ BUG_ON(nfdt->max_fds < fdt->max_fds);
+ /* Copy the existing tables and install the new pointers */
+
+ i = fdt->max_fdset / (sizeof(unsigned long) * 8);
+ count = (nfdt->max_fdset - fdt->max_fdset) / 8;
+
+ /*
+ * Don't copy the entire array if the current fdset is
+ * not yet initialised.
+ */
+ if (i) {
+ memcpy (nfdt->open_fds, fdt->open_fds,
+ fdt->max_fdset/8);
+ memcpy (nfdt->close_on_exec, fdt->close_on_exec,
+ fdt->max_fdset/8);
+ memset (&nfdt->open_fds->fds_bits[i], 0, count);
+ memset (&nfdt->close_on_exec->fds_bits[i], 0, count);
+ }
+
+ /* Don't copy/clear the array if we are creating a new
+ fd array for fork() */
+ if (fdt->max_fds) {
+ memcpy(nfdt->fd, fdt->fd,
+ fdt->max_fds * sizeof(struct file *));
+ /* clear the remainder of the array */
+ memset(&nfdt->fd[fdt->max_fds], 0,
+ (nfdt->max_fds - fdt->max_fds) *
+ sizeof(struct file *));
+ }
+ nfdt->next_fd = fdt->next_fd;
}
/*
@@ -154,26 +234,21 @@ void free_fdset(fd_set *array, int num)
vfree(array);
}
-/*
- * Expand the fdset in the files_struct. Called with the files spinlock
- * held for write.
- */
-static int expand_fdset(struct files_struct *files, int nr)
- __releases(file->file_lock)
- __acquires(file->file_lock)
+static struct fdtable *alloc_fdtable(int nr)
{
- fd_set *new_openset = NULL, *new_execset = NULL;
- int error, nfds = 0;
-
- error = -EMFILE;
- if (files->max_fdset >= NR_OPEN || nr >= NR_OPEN)
- goto out;
+ struct fdtable *fdt = NULL;
+ int nfds = 0;
+ fd_set *new_openset = NULL, *new_execset = NULL;
+ struct file **new_fds;
- nfds = files->max_fdset;
- spin_unlock(&files->file_lock);
+ fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
+ if (!fdt)
+ goto out;
+ memset(fdt, 0, sizeof(*fdt));
- /* Expand to the max in easy steps */
- do {
+ nfds = __FD_SETSIZE;
+ /* Expand to the max in easy steps */
+ do {
if (nfds < (PAGE_SIZE * 8))
nfds = PAGE_SIZE * 8;
else {
@@ -183,49 +258,88 @@ static int expand_fdset(struct files_struct *files, int nr)
}
} while (nfds <= nr);
- error = -ENOMEM;
- new_openset = alloc_fdset(nfds);
- new_execset = alloc_fdset(nfds);
- spin_lock(&files->file_lock);
- if (!new_openset || !new_execset)
+ new_openset = alloc_fdset(nfds);
+ new_execset = alloc_fdset(nfds);
+ if (!new_openset || !new_execset)
+ goto out;
+ fdt->open_fds = new_openset;
+ fdt->close_on_exec = new_execset;
+ fdt->max_fdset = nfds;
+
+ nfds = NR_OPEN_DEFAULT;
+ /*
+ * Expand to the max in easy steps, and keep expanding it until
+ * we have enough for the requested fd array size.
+ */
+ do {
+#if NR_OPEN_DEFAULT < 256
+ if (nfds < 256)
+ nfds = 256;
+ else
+#endif
+ if (nfds < (PAGE_SIZE / sizeof(struct file *)))
+ nfds = PAGE_SIZE / sizeof(struct file *);
+ else {
+ nfds = nfds * 2;
+ if (nfds > NR_OPEN)
+ nfds = NR_OPEN;
+ }
+ } while (nfds <= nr);
+ new_fds = alloc_fd_array(nfds);
+ if (!new_fds)
+ goto out;
+ fdt->fd = new_fds;
+ fdt->max_fds = nfds;
+ fdt->free_files = NULL;
+ return fdt;
+out:
+ if (new_openset)
+ free_fdset(new_openset, nfds);
+ if (new_execset)
+ free_fdset(new_execset, nfds);
+ kfree(fdt);
+ return NULL;
+}
+
+/*
+ * Expands the file descriptor table - it will allocate a new fdtable and
+ * both fd array and fdset. It is expected to be called with the
+ * files_lock held.
+ */
+static int expand_fdtable(struct files_struct *files, int nr)
+ __releases(files->file_lock)
+ __acquires(files->file_lock)
+{
+ int error = 0;
+ struct fdtable *fdt;
+ struct fdtable *nfdt = NULL;
+
+ spin_unlock(&files->file_lock);
+ nfdt = alloc_fdtable(nr);
+ if (!nfdt) {
+ error = -ENOMEM;
+ spin_lock(&files->file_lock);
goto out;
+ }
- error = 0;
-
- /* Copy the existing tables and install the new pointers */
- if (nfds > files->max_fdset) {
- int i = files->max_fdset / (sizeof(unsigned long) * 8);
- int count = (nfds - files->max_fdset) / 8;
-
- /*
- * Don't copy the entire array if the current fdset is
- * not yet initialised.
- */
- if (i) {
- memcpy (new_openset, files->open_fds, files->max_fdset/8);
- memcpy (new_execset, files->close_on_exec, files->max_fdset/8);
- memset (&new_openset->fds_bits[i], 0, count);
- memset (&new_execset->fds_bits[i], 0, count);
- }
-
- nfds = xchg(&files->max_fdset, nfds);
- new_openset = xchg(&files->open_fds, new_openset);
- new_execset = xchg(&files->close_on_exec, new_execset);
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ /*
+ * Check again since another task may have expanded the
+ * fd table while we dropped the lock
+ */
+ if (nr >= fdt->max_fds || nr >= fdt->max_fdset) {
+ copy_fdtable(nfdt, fdt);
+ } else {
+ /* Somebody expanded while we dropped file_lock */
spin_unlock(&files->file_lock);
- free_fdset (new_openset, nfds);
- free_fdset (new_execset, nfds);
+ __free_fdtable(nfdt);
spin_lock(&files->file_lock);
- return 0;
- }
- /* Somebody expanded the array while we slept ... */
-
+ goto out;
+ }
+ rcu_assign_pointer(files->fdt, nfdt);
+ free_fdtable(fdt);
out:
- spin_unlock(&files->file_lock);
- if (new_openset)
- free_fdset(new_openset, nfds);
- if (new_execset)
- free_fdset(new_execset, nfds);
- spin_lock(&files->file_lock);
return error;
}
@@ -237,18 +351,39 @@ out:
int expand_files(struct files_struct *files, int nr)
{
int err, expand = 0;
+ struct fdtable *fdt;
- if (nr >= files->max_fdset) {
- expand = 1;
- if ((err = expand_fdset(files, nr)))
+ fdt = files_fdtable(files);
+ if (nr >= fdt->max_fdset || nr >= fdt->max_fds) {
+ if (fdt->max_fdset >= NR_OPEN ||
+ fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) {
+ err = -EMFILE;
goto out;
- }
- if (nr >= files->max_fds) {
+ }
expand = 1;
- if ((err = expand_fd_array(files, nr)))
+ if ((err = expand_fdtable(files, nr)))
goto out;
}
err = expand;
out:
return err;
}
+
+static void __devinit fdtable_defer_list_init(int cpu)
+{
+ struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu);
+ spin_lock_init(&fddef->lock);
+ INIT_WORK(&fddef->wq, (void (*)(void *))free_fdtable_work, fddef);
+ init_timer(&fddef->timer);
+ fddef->timer.data = (unsigned long)fddef;
+ fddef->timer.function = fdtable_timer;
+ fddef->next = NULL;
+}
+
+void __init files_defer_init(void)
+{
+ int i;
+ /* Really early - can't use for_each_cpu */
+ for (i = 0; i < NR_CPUS; i++)
+ fdtable_defer_list_init(i);
+}
diff --git a/fs/file_table.c b/fs/file_table.c
index 43e9e1737de..86ec8ae985b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/eventpoll.h>
+#include <linux/rcupdate.h>
#include <linux/mount.h>
#include <linux/cdev.h>
#include <linux/fsnotify.h>
@@ -53,11 +54,17 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
spin_unlock_irqrestore(&filp_count_lock, flags);
}
-static inline void file_free(struct file *f)
+static inline void file_free_rcu(struct rcu_head *head)
{
+ struct file *f = container_of(head, struct file, f_rcuhead);
kmem_cache_free(filp_cachep, f);
}
+static inline void file_free(struct file *f)
+{
+ call_rcu(&f->f_rcuhead, file_free_rcu);
+}
+
/* Find an unused file structure and return a pointer to it.
* Returns NULL, if there are no more free file structures or
* we run out of memory.
@@ -110,7 +117,7 @@ EXPORT_SYMBOL(get_empty_filp);
void fastcall fput(struct file *file)
{
- if (atomic_dec_and_test(&file->f_count))
+ if (rcuref_dec_and_test(&file->f_count))
__fput(file);
}
@@ -156,11 +163,17 @@ struct file fastcall *fget(unsigned int fd)
struct file *file;
struct files_struct *files = current->files;
- spin_lock(&files->file_lock);
+ rcu_read_lock();
file = fcheck_files(files, fd);
- if (file)
- get_file(file);
- spin_unlock(&files->file_lock);
+ if (file) {
+ if (!rcuref_inc_lf(&file->f_count)) {
+ /* File object ref couldn't be taken */
+ rcu_read_unlock();
+ return NULL;
+ }
+ }
+ rcu_read_unlock();
+
return file;
}
@@ -182,21 +195,25 @@ struct file fastcall *fget_light(unsigned int fd, int *fput_needed)
if (likely((atomic_read(&files->count) == 1))) {
file = fcheck_files(files, fd);
} else {
- spin_lock(&files->file_lock);
+ rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
- get_file(file);
- *fput_needed = 1;
+ if (rcuref_inc_lf(&file->f_count))
+ *fput_needed = 1;
+ else
+ /* Didn't get the reference, someone's freed */
+ file = NULL;
}
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
}
+
return file;
}
void put_filp(struct file *file)
{
- if (atomic_dec_and_test(&file->f_count)) {
+ if (rcuref_dec_and_test(&file->f_count)) {
security_file_free(file);
file_kill(file);
file_free(file);
@@ -257,4 +274,5 @@ void __init files_init(unsigned long mempages)
files_stat.max_files = n;
if (files_stat.max_files < NR_FILE)
files_stat.max_files = NR_FILE;
+ files_defer_init();
}
diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
new file mode 100644
index 00000000000..c3e1f760cac
--- /dev/null
+++ b/fs/fuse/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the FUSE filesystem.
+#
+
+obj-$(CONFIG_FUSE_FS) += fuse.o
+
+fuse-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 00000000000..d4c869c6d01
--- /dev/null
+++ b/fs/fuse/dev.c
@@ -0,0 +1,877 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include "fuse_i.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/uio.h>
+#include <linux/miscdevice.h>
+#include <linux/pagemap.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+
+MODULE_ALIAS_MISCDEV(FUSE_MINOR);
+
+static kmem_cache_t *fuse_req_cachep;
+
+static inline struct fuse_conn *fuse_get_conn(struct file *file)
+{
+ struct fuse_conn *fc;
+ spin_lock(&fuse_lock);
+ fc = file->private_data;
+ if (fc && !fc->mounted)
+ fc = NULL;
+ spin_unlock(&fuse_lock);
+ return fc;
+}
+
+static inline void fuse_request_init(struct fuse_req *req)
+{
+ memset(req, 0, sizeof(*req));
+ INIT_LIST_HEAD(&req->list);
+ init_waitqueue_head(&req->waitq);
+ atomic_set(&req->count, 1);
+}
+
+struct fuse_req *fuse_request_alloc(void)
+{
+ struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL);
+ if (req)
+ fuse_request_init(req);
+ return req;
+}
+
+void fuse_request_free(struct fuse_req *req)
+{
+ kmem_cache_free(fuse_req_cachep, req);
+}
+
+static inline void block_sigs(sigset_t *oldset)
+{
+ sigset_t mask;
+
+ siginitsetinv(&mask, sigmask(SIGKILL));
+ sigprocmask(SIG_BLOCK, &mask, oldset);
+}
+
+static inline void restore_sigs(sigset_t *oldset)
+{
+ sigprocmask(SIG_SETMASK, oldset, NULL);
+}
+
+void fuse_reset_request(struct fuse_req *req)
+{
+ int preallocated = req->preallocated;
+ BUG_ON(atomic_read(&req->count) != 1);
+ fuse_request_init(req);
+ req->preallocated = preallocated;
+}
+
+static void __fuse_get_request(struct fuse_req *req)
+{
+ atomic_inc(&req->count);
+}
+
+/* Must be called with > 1 refcount */
+static void __fuse_put_request(struct fuse_req *req)
+{
+ BUG_ON(atomic_read(&req->count) < 2);
+ atomic_dec(&req->count);
+}
+
+static struct fuse_req *do_get_request(struct fuse_conn *fc)
+{
+ struct fuse_req *req;
+
+ spin_lock(&fuse_lock);
+ BUG_ON(list_empty(&fc->unused_list));
+ req = list_entry(fc->unused_list.next, struct fuse_req, list);
+ list_del_init(&req->list);
+ spin_unlock(&fuse_lock);
+ fuse_request_init(req);
+ req->preallocated = 1;
+ req->in.h.uid = current->fsuid;
+ req->in.h.gid = current->fsgid;
+ req->in.h.pid = current->pid;
+ return req;
+}
+
+/* This can return NULL, but only in case it's interrupted by a SIGKILL */
+struct fuse_req *fuse_get_request(struct fuse_conn *fc)
+{
+ int intr;
+ sigset_t oldset;
+
+ block_sigs(&oldset);
+ intr = down_interruptible(&fc->outstanding_sem);
+ restore_sigs(&oldset);
+ return intr ? NULL : do_get_request(fc);
+}
+
+static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
+{
+ spin_lock(&fuse_lock);
+ if (req->preallocated)
+ list_add(&req->list, &fc->unused_list);
+ else
+ fuse_request_free(req);
+
+ /* If we are in debt decrease that first */
+ if (fc->outstanding_debt)
+ fc->outstanding_debt--;
+ else
+ up(&fc->outstanding_sem);
+ spin_unlock(&fuse_lock);
+}
+
+void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
+{
+ if (atomic_dec_and_test(&req->count))
+ fuse_putback_request(fc, req);
+}
+
+void fuse_release_background(struct fuse_req *req)
+{
+ iput(req->inode);
+ iput(req->inode2);
+ if (req->file)
+ fput(req->file);
+ spin_lock(&fuse_lock);
+ list_del(&req->bg_entry);
+ spin_unlock(&fuse_lock);
+}
+
+/*
+ * This function is called when a request is finished. Either a reply
+ * has arrived or it was interrupted (and not yet sent) or some error
+ * occured during communication with userspace, or the device file was
+ * closed. It decreases the referece count for the request. In case
+ * of a background request the referece to the stored objects are
+ * released. The requester thread is woken up (if still waiting), and
+ * finally the request is either freed or put on the unused_list
+ *
+ * Called with fuse_lock, unlocks it
+ */
+static void request_end(struct fuse_conn *fc, struct fuse_req *req)
+{
+ int putback;
+ req->finished = 1;
+ putback = atomic_dec_and_test(&req->count);
+ spin_unlock(&fuse_lock);
+ if (req->background) {
+ down_read(&fc->sbput_sem);
+ if (fc->mounted)
+ fuse_release_background(req);
+ up_read(&fc->sbput_sem);
+ }
+ wake_up(&req->waitq);
+ if (req->in.h.opcode == FUSE_INIT) {
+ int i;
+
+ if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
+ fc->conn_error = 1;
+
+ /* After INIT reply is received other requests can go
+ out. So do (FUSE_MAX_OUTSTANDING - 1) number of
+ up()s on outstanding_sem. The last up() is done in
+ fuse_putback_request() */
+ for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
+ up(&fc->outstanding_sem);
+ }
+ if (putback)
+ fuse_putback_request(fc, req);
+}
+
+/*
+ * Unfortunately request interruption not just solves the deadlock
+ * problem, it causes problems too. These stem from the fact, that an
+ * interrupted request is continued to be processed in userspace,
+ * while all the locks and object references (inode and file) held
+ * during the operation are released.
+ *
+ * To release the locks is exactly why there's a need to interrupt the
+ * request, so there's not a lot that can be done about this, except
+ * introduce additional locking in userspace.
+ *
+ * More important is to keep inode and file references until userspace
+ * has replied, otherwise FORGET and RELEASE could be sent while the
+ * inode/file is still used by the filesystem.
+ *
+ * For this reason the concept of "background" request is introduced.
+ * An interrupted request is backgrounded if it has been already sent
+ * to userspace. Backgrounding involves getting an extra reference to
+ * inode(s) or file used in the request, and adding the request to
+ * fc->background list. When a reply is received for a background
+ * request, the object references are released, and the request is
+ * removed from the list. If the filesystem is unmounted while there
+ * are still background requests, the list is walked and references
+ * are released as if a reply was received.
+ *
+ * There's one more use for a background request. The RELEASE message is
+ * always sent as background, since it doesn't return an error or
+ * data.
+ */
+static void background_request(struct fuse_conn *fc, struct fuse_req *req)
+{
+ req->background = 1;
+ list_add(&req->bg_entry, &fc->background);
+ if (req->inode)
+ req->inode = igrab(req->inode);
+ if (req->inode2)
+ req->inode2 = igrab(req->inode2);
+ if (req->file)
+ get_file(req->file);
+}
+
+/* Called with fuse_lock held. Releases, and then reacquires it. */
+static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
+{
+ sigset_t oldset;
+
+ spin_unlock(&fuse_lock);
+ block_sigs(&oldset);
+ wait_event_interruptible(req->waitq, req->finished);
+ restore_sigs(&oldset);
+ spin_lock(&fuse_lock);
+ if (req->finished)
+ return;
+
+ req->out.h.error = -EINTR;
+ req->interrupted = 1;
+ if (req->locked) {
+ /* This is uninterruptible sleep, because data is
+ being copied to/from the buffers of req. During
+ locked state, there mustn't be any filesystem
+ operation (e.g. page fault), since that could lead
+ to deadlock */
+ spin_unlock(&fuse_lock);
+ wait_event(req->waitq, !req->locked);
+ spin_lock(&fuse_lock);
+ }
+ if (!req->sent && !list_empty(&req->list)) {
+ list_del(&req->list);
+ __fuse_put_request(req);
+ } else if (!req->finished && req->sent)
+ background_request(fc, req);
+}
+
+static unsigned len_args(unsigned numargs, struct fuse_arg *args)
+{
+ unsigned nbytes = 0;
+ unsigned i;
+
+ for (i = 0; i < numargs; i++)
+ nbytes += args[i].size;
+
+ return nbytes;
+}
+
+static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
+{
+ fc->reqctr++;
+ /* zero is special */
+ if (fc->reqctr == 0)
+ fc->reqctr = 1;
+ req->in.h.unique = fc->reqctr;
+ req->in.h.len = sizeof(struct fuse_in_header) +
+ len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
+ if (!req->preallocated) {
+ /* If request is not preallocated (either FORGET or
+ RELEASE), then still decrease outstanding_sem, so
+ user can't open infinite number of files while not
+ processing the RELEASE requests. However for
+ efficiency do it without blocking, so if down()
+ would block, just increase the debt instead */
+ if (down_trylock(&fc->outstanding_sem))
+ fc->outstanding_debt++;
+ }
+ list_add_tail(&req->list, &fc->pending);
+ wake_up(&fc->waitq);
+}
+
+/*
+ * This can only be interrupted by a SIGKILL
+ */
+void request_send(struct fuse_conn *fc, struct fuse_req *req)
+{
+ req->isreply = 1;
+ spin_lock(&fuse_lock);
+ if (!fc->connected)
+ req->out.h.error = -ENOTCONN;
+ else if (fc->conn_error)
+ req->out.h.error = -ECONNREFUSED;
+ else {
+ queue_request(fc, req);
+ /* acquire extra reference, since request is still needed
+ after request_end() */
+ __fuse_get_request(req);
+
+ request_wait_answer(fc, req);
+ }
+ spin_unlock(&fuse_lock);
+}
+
+static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
+{
+ spin_lock(&fuse_lock);
+ if (fc->connected) {
+ queue_request(fc, req);
+ spin_unlock(&fuse_lock);
+ } else {
+ req->out.h.error = -ENOTCONN;
+ request_end(fc, req);
+ }
+}
+
+void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
+{
+ req->isreply = 0;
+ request_send_nowait(fc, req);
+}
+
+void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
+{
+ req->isreply = 1;
+ spin_lock(&fuse_lock);
+ background_request(fc, req);
+ spin_unlock(&fuse_lock);
+ request_send_nowait(fc, req);
+}
+
+void fuse_send_init(struct fuse_conn *fc)
+{
+ /* This is called from fuse_read_super() so there's guaranteed
+ to be a request available */
+ struct fuse_req *req = do_get_request(fc);
+ struct fuse_init_in_out *arg = &req->misc.init_in_out;
+ arg->major = FUSE_KERNEL_VERSION;
+ arg->minor = FUSE_KERNEL_MINOR_VERSION;
+ req->in.h.opcode = FUSE_INIT;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(*arg);
+ req->in.args[0].value = arg;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(*arg);
+ req->out.args[0].value = arg;
+ request_send_background(fc, req);
+}
+
+/*
+ * Lock the request. Up to the next unlock_request() there mustn't be
+ * anything that could cause a page-fault. If the request was already
+ * interrupted bail out.
+ */
+static inline int lock_request(struct fuse_req *req)
+{
+ int err = 0;
+ if (req) {
+ spin_lock(&fuse_lock);
+ if (req->interrupted)
+ err = -ENOENT;
+ else
+ req->locked = 1;
+ spin_unlock(&fuse_lock);
+ }
+ return err;
+}
+
+/*
+ * Unlock request. If it was interrupted during being locked, the
+ * requester thread is currently waiting for it to be unlocked, so
+ * wake it up.
+ */
+static inline void unlock_request(struct fuse_req *req)
+{
+ if (req) {
+ spin_lock(&fuse_lock);
+ req->locked = 0;
+ if (req->interrupted)
+ wake_up(&req->waitq);
+ spin_unlock(&fuse_lock);
+ }
+}
+
+struct fuse_copy_state {
+ int write;
+ struct fuse_req *req;
+ const struct iovec *iov;
+ unsigned long nr_segs;
+ unsigned long seglen;
+ unsigned long addr;
+ struct page *pg;
+ void *mapaddr;
+ void *buf;
+ unsigned len;
+};
+
+static void fuse_copy_init(struct fuse_copy_state *cs, int write,
+ struct fuse_req *req, const struct iovec *iov,
+ unsigned long nr_segs)
+{
+ memset(cs, 0, sizeof(*cs));
+ cs->write = write;
+ cs->req = req;
+ cs->iov = iov;
+ cs->nr_segs = nr_segs;
+}
+
+/* Unmap and put previous page of userspace buffer */
+static inline void fuse_copy_finish(struct fuse_copy_state *cs)
+{
+ if (cs->mapaddr) {
+ kunmap_atomic(cs->mapaddr, KM_USER0);
+ if (cs->write) {
+ flush_dcache_page(cs->pg);
+ set_page_dirty_lock(cs->pg);
+ }
+ put_page(cs->pg);
+ cs->mapaddr = NULL;
+ }
+}
+
+/*
+ * Get another pagefull of userspace buffer, and map it to kernel
+ * address space, and lock request
+ */
+static int fuse_copy_fill(struct fuse_copy_state *cs)
+{
+ unsigned long offset;
+ int err;
+
+ unlock_request(cs->req);
+ fuse_copy_finish(cs);
+ if (!cs->seglen) {
+ BUG_ON(!cs->nr_segs);
+ cs->seglen = cs->iov[0].iov_len;
+ cs->addr = (unsigned long) cs->iov[0].iov_base;
+ cs->iov ++;
+ cs->nr_segs --;
+ }
+ down_read(&current->mm->mmap_sem);
+ err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
+ &cs->pg, NULL);
+ up_read(&current->mm->mmap_sem);
+ if (err < 0)
+ return err;
+ BUG_ON(err != 1);
+ offset = cs->addr % PAGE_SIZE;
+ cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
+ cs->buf = cs->mapaddr + offset;
+ cs->len = min(PAGE_SIZE - offset, cs->seglen);
+ cs->seglen -= cs->len;
+ cs->addr += cs->len;
+
+ return lock_request(cs->req);
+}
+
+/* Do as much copy to/from userspace buffer as we can */
+static inline int fuse_copy_do(struct fuse_copy_state *cs, void **val,
+ unsigned *size)
+{
+ unsigned ncpy = min(*size, cs->len);
+ if (val) {
+ if (cs->write)
+ memcpy(cs->buf, *val, ncpy);
+ else
+ memcpy(*val, cs->buf, ncpy);
+ *val += ncpy;
+ }
+ *size -= ncpy;
+ cs->len -= ncpy;
+ cs->buf += ncpy;
+ return ncpy;
+}
+
+/*
+ * Copy a page in the request to/from the userspace buffer. Must be
+ * done atomically
+ */
+static inline int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
+ unsigned offset, unsigned count, int zeroing)
+{
+ if (page && zeroing && count < PAGE_SIZE) {
+ void *mapaddr = kmap_atomic(page, KM_USER1);
+ memset(mapaddr, 0, PAGE_SIZE);
+ kunmap_atomic(mapaddr, KM_USER1);
+ }
+ while (count) {
+ int err;
+ if (!cs->len && (err = fuse_copy_fill(cs)))
+ return err;
+ if (page) {
+ void *mapaddr = kmap_atomic(page, KM_USER1);
+ void *buf = mapaddr + offset;
+ offset += fuse_copy_do(cs, &buf, &count);
+ kunmap_atomic(mapaddr, KM_USER1);
+ } else
+ offset += fuse_copy_do(cs, NULL, &count);
+ }
+ if (page && !cs->write)
+ flush_dcache_page(page);
+ return 0;
+}
+
+/* Copy pages in the request to/from userspace buffer */
+static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
+ int zeroing)
+{
+ unsigned i;
+ struct fuse_req *req = cs->req;
+ unsigned offset = req->page_offset;
+ unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
+
+ for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
+ struct page *page = req->pages[i];
+ int err = fuse_copy_page(cs, page, offset, count, zeroing);
+ if (err)
+ return err;
+
+ nbytes -= count;
+ count = min(nbytes, (unsigned) PAGE_SIZE);
+ offset = 0;
+ }
+ return 0;
+}
+
+/* Copy a single argument in the request to/from userspace buffer */
+static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
+{
+ while (size) {
+ int err;
+ if (!cs->len && (err = fuse_copy_fill(cs)))
+ return err;
+ fuse_copy_do(cs, &val, &size);
+ }
+ return 0;
+}
+
+/* Copy request arguments to/from userspace buffer */
+static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
+ unsigned argpages, struct fuse_arg *args,
+ int zeroing)
+{
+ int err = 0;
+ unsigned i;
+
+ for (i = 0; !err && i < numargs; i++) {
+ struct fuse_arg *arg = &args[i];
+ if (i == numargs - 1 && argpages)
+ err = fuse_copy_pages(cs, arg->size, zeroing);
+ else
+ err = fuse_copy_one(cs, arg->value, arg->size);
+ }
+ return err;
+}
+
+/* Wait until a request is available on the pending list */
+static void request_wait(struct fuse_conn *fc)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue_exclusive(&fc->waitq, &wait);
+ while (fc->mounted && list_empty(&fc->pending)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (signal_pending(current))
+ break;
+
+ spin_unlock(&fuse_lock);
+ schedule();
+ spin_lock(&fuse_lock);
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&fc->waitq, &wait);
+}
+
+/*
+ * Read a single request into the userspace filesystem's buffer. This
+ * function waits until a request is available, then removes it from
+ * the pending list and copies request data to userspace buffer. If
+ * no reply is needed (FORGET) or request has been interrupted or
+ * there was an error during the copying then it's finished by calling
+ * request_end(). Otherwise add it to the processing list, and set
+ * the 'sent' flag.
+ */
+static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *off)
+{
+ int err;
+ struct fuse_conn *fc;
+ struct fuse_req *req;
+ struct fuse_in *in;
+ struct fuse_copy_state cs;
+ unsigned reqsize;
+
+ spin_lock(&fuse_lock);
+ fc = file->private_data;
+ err = -EPERM;
+ if (!fc)
+ goto err_unlock;
+ request_wait(fc);
+ err = -ENODEV;
+ if (!fc->mounted)
+ goto err_unlock;
+ err = -ERESTARTSYS;
+ if (list_empty(&fc->pending))
+ goto err_unlock;
+
+ req = list_entry(fc->pending.next, struct fuse_req, list);
+ list_del_init(&req->list);
+ spin_unlock(&fuse_lock);
+
+ in = &req->in;
+ reqsize = req->in.h.len;
+ fuse_copy_init(&cs, 1, req, iov, nr_segs);
+ err = -EINVAL;
+ if (iov_length(iov, nr_segs) >= reqsize) {
+ err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
+ if (!err)
+ err = fuse_copy_args(&cs, in->numargs, in->argpages,
+ (struct fuse_arg *) in->args, 0);
+ }
+ fuse_copy_finish(&cs);
+
+ spin_lock(&fuse_lock);
+ req->locked = 0;
+ if (!err && req->interrupted)
+ err = -ENOENT;
+ if (err) {
+ if (!req->interrupted)
+ req->out.h.error = -EIO;
+ request_end(fc, req);
+ return err;
+ }
+ if (!req->isreply)
+ request_end(fc, req);
+ else {
+ req->sent = 1;
+ list_add_tail(&req->list, &fc->processing);
+ spin_unlock(&fuse_lock);
+ }
+ return reqsize;
+
+ err_unlock:
+ spin_unlock(&fuse_lock);
+ return err;
+}
+
+static ssize_t fuse_dev_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *off)
+{
+ struct iovec iov;
+ iov.iov_len = nbytes;
+ iov.iov_base = buf;
+ return fuse_dev_readv(file, &iov, 1, off);
+}
+
+/* Look up request on processing list by unique ID */
+static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
+{
+ struct list_head *entry;
+
+ list_for_each(entry, &fc->processing) {
+ struct fuse_req *req;
+ req = list_entry(entry, struct fuse_req, list);
+ if (req->in.h.unique == unique)
+ return req;
+ }
+ return NULL;
+}
+
+static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
+ unsigned nbytes)
+{
+ unsigned reqsize = sizeof(struct fuse_out_header);
+
+ if (out->h.error)
+ return nbytes != reqsize ? -EINVAL : 0;
+
+ reqsize += len_args(out->numargs, out->args);
+
+ if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
+ return -EINVAL;
+ else if (reqsize > nbytes) {
+ struct fuse_arg *lastarg = &out->args[out->numargs-1];
+ unsigned diffsize = reqsize - nbytes;
+ if (diffsize > lastarg->size)
+ return -EINVAL;
+ lastarg->size -= diffsize;
+ }
+ return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
+ out->page_zeroing);
+}
+
+/*
+ * Write a single reply to a request. First the header is copied from
+ * the write buffer. The request is then searched on the processing
+ * list by the unique ID found in the header. If found, then remove
+ * it from the list and copy the rest of the buffer to the request.
+ * The request is finished by calling request_end()
+ */
+static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *off)
+{
+ int err;
+ unsigned nbytes = iov_length(iov, nr_segs);
+ struct fuse_req *req;
+ struct fuse_out_header oh;
+ struct fuse_copy_state cs;
+ struct fuse_conn *fc = fuse_get_conn(file);
+ if (!fc)
+ return -ENODEV;
+
+ fuse_copy_init(&cs, 0, NULL, iov, nr_segs);
+ if (nbytes < sizeof(struct fuse_out_header))
+ return -EINVAL;
+
+ err = fuse_copy_one(&cs, &oh, sizeof(oh));
+ if (err)
+ goto err_finish;
+ err = -EINVAL;
+ if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
+ oh.len != nbytes)
+ goto err_finish;
+
+ spin_lock(&fuse_lock);
+ req = request_find(fc, oh.unique);
+ err = -EINVAL;
+ if (!req)
+ goto err_unlock;
+
+ list_del_init(&req->list);
+ if (req->interrupted) {
+ request_end(fc, req);
+ fuse_copy_finish(&cs);
+ return -ENOENT;
+ }
+ req->out.h = oh;
+ req->locked = 1;
+ cs.req = req;
+ spin_unlock(&fuse_lock);
+
+ err = copy_out_args(&cs, &req->out, nbytes);
+ fuse_copy_finish(&cs);
+
+ spin_lock(&fuse_lock);
+ req->locked = 0;
+ if (!err) {
+ if (req->interrupted)
+ err = -ENOENT;
+ } else if (!req->interrupted)
+ req->out.h.error = -EIO;
+ request_end(fc, req);
+
+ return err ? err : nbytes;
+
+ err_unlock:
+ spin_unlock(&fuse_lock);
+ err_finish:
+ fuse_copy_finish(&cs);
+ return err;
+}
+
+static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
+ size_t nbytes, loff_t *off)
+{
+ struct iovec iov;
+ iov.iov_len = nbytes;
+ iov.iov_base = (char __user *) buf;
+ return fuse_dev_writev(file, &iov, 1, off);
+}
+
+static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
+{
+ struct fuse_conn *fc = fuse_get_conn(file);
+ unsigned mask = POLLOUT | POLLWRNORM;
+
+ if (!fc)
+ return -ENODEV;
+
+ poll_wait(file, &fc->waitq, wait);
+
+ spin_lock(&fuse_lock);
+ if (!list_empty(&fc->pending))
+ mask |= POLLIN | POLLRDNORM;
+ spin_unlock(&fuse_lock);
+
+ return mask;
+}
+
+/* Abort all requests on the given list (pending or processing) */
+static void end_requests(struct fuse_conn *fc, struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct fuse_req *req;
+ req = list_entry(head->next, struct fuse_req, list);
+ list_del_init(&req->list);
+ req->out.h.error = -ECONNABORTED;
+ request_end(fc, req);
+ spin_lock(&fuse_lock);
+ }
+}
+
+static int fuse_dev_release(struct inode *inode, struct file *file)
+{
+ struct fuse_conn *fc;
+
+ spin_lock(&fuse_lock);
+ fc = file->private_data;
+ if (fc) {
+ fc->connected = 0;
+ end_requests(fc, &fc->pending);
+ end_requests(fc, &fc->processing);
+ fuse_release_conn(fc);
+ }
+ spin_unlock(&fuse_lock);
+ return 0;
+}
+
+struct file_operations fuse_dev_operations = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = fuse_dev_read,
+ .readv = fuse_dev_readv,
+ .write = fuse_dev_write,
+ .writev = fuse_dev_writev,
+ .poll = fuse_dev_poll,
+ .release = fuse_dev_release,
+};
+
+static struct miscdevice fuse_miscdevice = {
+ .minor = FUSE_MINOR,
+ .name = "fuse",
+ .fops = &fuse_dev_operations,
+};
+
+int __init fuse_dev_init(void)
+{
+ int err = -ENOMEM;
+ fuse_req_cachep = kmem_cache_create("fuse_request",
+ sizeof(struct fuse_req),
+ 0, 0, NULL, NULL);
+ if (!fuse_req_cachep)
+ goto out;
+
+ err = misc_register(&fuse_miscdevice);
+ if (err)
+ goto out_cache_clean;
+
+ return 0;
+
+ out_cache_clean:
+ kmem_cache_destroy(fuse_req_cachep);
+ out:
+ return err;
+}
+
+void fuse_dev_cleanup(void)
+{
+ misc_deregister(&fuse_miscdevice);
+ kmem_cache_destroy(fuse_req_cachep);
+}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
new file mode 100644
index 00000000000..e79e49b3eec
--- /dev/null
+++ b/fs/fuse/dir.c
@@ -0,0 +1,982 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include "fuse_i.h"
+
+#include <linux/pagemap.h>
+#include <linux/file.h>
+#include <linux/gfp.h>
+#include <linux/sched.h>
+#include <linux/namei.h>
+
+static inline unsigned long time_to_jiffies(unsigned long sec,
+ unsigned long nsec)
+{
+ struct timespec ts = {sec, nsec};
+ return jiffies + timespec_to_jiffies(&ts);
+}
+
+static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
+ struct dentry *entry,
+ struct fuse_entry_out *outarg)
+{
+ req->in.h.opcode = FUSE_LOOKUP;
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->in.numargs = 1;
+ req->in.args[0].size = entry->d_name.len + 1;
+ req->in.args[0].value = entry->d_name.name;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(struct fuse_entry_out);
+ req->out.args[0].value = outarg;
+}
+
+static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
+{
+ if (!entry->d_inode || is_bad_inode(entry->d_inode))
+ return 0;
+ else if (time_after(jiffies, entry->d_time)) {
+ int err;
+ struct fuse_entry_out outarg;
+ struct inode *inode = entry->d_inode;
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return 0;
+
+ fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (!err) {
+ if (outarg.nodeid != get_node_id(inode)) {
+ fuse_send_forget(fc, req, outarg.nodeid, 1);
+ return 0;
+ }
+ fi->nlookup ++;
+ }
+ fuse_put_request(fc, req);
+ if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
+ return 0;
+
+ fuse_change_attributes(inode, &outarg.attr);
+ entry->d_time = time_to_jiffies(outarg.entry_valid,
+ outarg.entry_valid_nsec);
+ fi->i_time = time_to_jiffies(outarg.attr_valid,
+ outarg.attr_valid_nsec);
+ }
+ return 1;
+}
+
+static struct dentry_operations fuse_dentry_operations = {
+ .d_revalidate = fuse_dentry_revalidate,
+};
+
+static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
+ struct inode **inodep)
+{
+ int err;
+ struct fuse_entry_out outarg;
+ struct inode *inode = NULL;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req;
+
+ if (entry->d_name.len > FUSE_NAME_MAX)
+ return -ENAMETOOLONG;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ fuse_lookup_init(req, dir, entry, &outarg);
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (!err) {
+ inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
+ &outarg.attr);
+ if (!inode) {
+ fuse_send_forget(fc, req, outarg.nodeid, 1);
+ return -ENOMEM;
+ }
+ }
+ fuse_put_request(fc, req);
+ if (err && err != -ENOENT)
+ return err;
+
+ if (inode) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ entry->d_time = time_to_jiffies(outarg.entry_valid,
+ outarg.entry_valid_nsec);
+ fi->i_time = time_to_jiffies(outarg.attr_valid,
+ outarg.attr_valid_nsec);
+ }
+
+ entry->d_op = &fuse_dentry_operations;
+ *inodep = inode;
+ return 0;
+}
+
+void fuse_invalidate_attr(struct inode *inode)
+{
+ get_fuse_inode(inode)->i_time = jiffies - 1;
+}
+
+static void fuse_invalidate_entry(struct dentry *entry)
+{
+ d_invalidate(entry);
+ entry->d_time = jiffies - 1;
+}
+
+static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
+ struct inode *dir, struct dentry *entry,
+ int mode)
+{
+ struct fuse_entry_out outarg;
+ struct inode *inode;
+ struct fuse_inode *fi;
+ int err;
+
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (err) {
+ fuse_put_request(fc, req);
+ return err;
+ }
+ inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
+ &outarg.attr);
+ if (!inode) {
+ fuse_send_forget(fc, req, outarg.nodeid, 1);
+ return -ENOMEM;
+ }
+ fuse_put_request(fc, req);
+
+ /* Don't allow userspace to do really stupid things... */
+ if ((inode->i_mode ^ mode) & S_IFMT) {
+ iput(inode);
+ return -EIO;
+ }
+
+ entry->d_time = time_to_jiffies(outarg.entry_valid,
+ outarg.entry_valid_nsec);
+
+ fi = get_fuse_inode(inode);
+ fi->i_time = time_to_jiffies(outarg.attr_valid,
+ outarg.attr_valid_nsec);
+
+ d_instantiate(entry, inode);
+ fuse_invalidate_attr(dir);
+ return 0;
+}
+
+static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
+ dev_t rdev)
+{
+ struct fuse_mknod_in inarg;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.mode = mode;
+ inarg.rdev = new_encode_dev(rdev);
+ req->in.h.opcode = FUSE_MKNOD;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = entry->d_name.len + 1;
+ req->in.args[1].value = entry->d_name.name;
+ return create_new_entry(fc, req, dir, entry, mode);
+}
+
+static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
+ struct nameidata *nd)
+{
+ return fuse_mknod(dir, entry, mode, 0);
+}
+
+static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
+{
+ struct fuse_mkdir_in inarg;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.mode = mode;
+ req->in.h.opcode = FUSE_MKDIR;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = entry->d_name.len + 1;
+ req->in.args[1].value = entry->d_name.name;
+ return create_new_entry(fc, req, dir, entry, S_IFDIR);
+}
+
+static int fuse_symlink(struct inode *dir, struct dentry *entry,
+ const char *link)
+{
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ unsigned len = strlen(link) + 1;
+ struct fuse_req *req;
+
+ if (len > FUSE_SYMLINK_MAX)
+ return -ENAMETOOLONG;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.h.opcode = FUSE_SYMLINK;
+ req->in.numargs = 2;
+ req->in.args[0].size = entry->d_name.len + 1;
+ req->in.args[0].value = entry->d_name.name;
+ req->in.args[1].size = len;
+ req->in.args[1].value = link;
+ return create_new_entry(fc, req, dir, entry, S_IFLNK);
+}
+
+static int fuse_unlink(struct inode *dir, struct dentry *entry)
+{
+ int err;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.h.opcode = FUSE_UNLINK;
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->in.numargs = 1;
+ req->in.args[0].size = entry->d_name.len + 1;
+ req->in.args[0].value = entry->d_name.name;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err) {
+ struct inode *inode = entry->d_inode;
+
+ /* Set nlink to zero so the inode can be cleared, if
+ the inode does have more links this will be
+ discovered at the next lookup/getattr */
+ inode->i_nlink = 0;
+ fuse_invalidate_attr(inode);
+ fuse_invalidate_attr(dir);
+ } else if (err == -EINTR)
+ fuse_invalidate_entry(entry);
+ return err;
+}
+
+static int fuse_rmdir(struct inode *dir, struct dentry *entry)
+{
+ int err;
+ struct fuse_conn *fc = get_fuse_conn(dir);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.h.opcode = FUSE_RMDIR;
+ req->in.h.nodeid = get_node_id(dir);
+ req->inode = dir;
+ req->in.numargs = 1;
+ req->in.args[0].size = entry->d_name.len + 1;
+ req->in.args[0].value = entry->d_name.name;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err) {
+ entry->d_inode->i_nlink = 0;
+ fuse_invalidate_attr(dir);
+ } else if (err == -EINTR)
+ fuse_invalidate_entry(entry);
+ return err;
+}
+
+static int fuse_rename(struct inode *olddir, struct dentry *oldent,
+ struct inode *newdir, struct dentry *newent)
+{
+ int err;
+ struct fuse_rename_in inarg;
+ struct fuse_conn *fc = get_fuse_conn(olddir);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.newdir = get_node_id(newdir);
+ req->in.h.opcode = FUSE_RENAME;
+ req->in.h.nodeid = get_node_id(olddir);
+ req->inode = olddir;
+ req->inode2 = newdir;
+ req->in.numargs = 3;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = oldent->d_name.len + 1;
+ req->in.args[1].value = oldent->d_name.name;
+ req->in.args[2].size = newent->d_name.len + 1;
+ req->in.args[2].value = newent->d_name.name;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err) {
+ fuse_invalidate_attr(olddir);
+ if (olddir != newdir)
+ fuse_invalidate_attr(newdir);
+ } else if (err == -EINTR) {
+ /* If request was interrupted, DEITY only knows if the
+ rename actually took place. If the invalidation
+ fails (e.g. some process has CWD under the renamed
+ directory), then there can be inconsistency between
+ the dcache and the real filesystem. Tough luck. */
+ fuse_invalidate_entry(oldent);
+ if (newent->d_inode)
+ fuse_invalidate_entry(newent);
+ }
+
+ return err;
+}
+
+static int fuse_link(struct dentry *entry, struct inode *newdir,
+ struct dentry *newent)
+{
+ int err;
+ struct fuse_link_in inarg;
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.oldnodeid = get_node_id(inode);
+ req->in.h.opcode = FUSE_LINK;
+ req->inode2 = inode;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = newent->d_name.len + 1;
+ req->in.args[1].value = newent->d_name.name;
+ err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
+ /* Contrary to "normal" filesystems it can happen that link
+ makes two "logical" inodes point to the same "physical"
+ inode. We invalidate the attributes of the old one, so it
+ will reflect changes in the backing inode (link count,
+ etc.)
+ */
+ if (!err || err == -EINTR)
+ fuse_invalidate_attr(inode);
+ return err;
+}
+
+int fuse_do_getattr(struct inode *inode)
+{
+ int err;
+ struct fuse_attr_out arg;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.h.opcode = FUSE_GETATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(arg);
+ req->out.args[0].value = &arg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err) {
+ if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
+ make_bad_inode(inode);
+ err = -EIO;
+ } else {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ fuse_change_attributes(inode, &arg.attr);
+ fi->i_time = time_to_jiffies(arg.attr_valid,
+ arg.attr_valid_nsec);
+ }
+ }
+ return err;
+}
+
+/*
+ * Calling into a user-controlled filesystem gives the filesystem
+ * daemon ptrace-like capabilities over the requester process. This
+ * means, that the filesystem daemon is able to record the exact
+ * filesystem operations performed, and can also control the behavior
+ * of the requester process in otherwise impossible ways. For example
+ * it can delay the operation for arbitrary length of time allowing
+ * DoS against the requester.
+ *
+ * For this reason only those processes can call into the filesystem,
+ * for which the owner of the mount has ptrace privilege. This
+ * excludes processes started by other users, suid or sgid processes.
+ */
+static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
+{
+ if (fc->flags & FUSE_ALLOW_OTHER)
+ return 1;
+
+ if (task->euid == fc->user_id &&
+ task->suid == fc->user_id &&
+ task->uid == fc->user_id &&
+ task->egid == fc->group_id &&
+ task->sgid == fc->group_id &&
+ task->gid == fc->group_id)
+ return 1;
+
+ return 0;
+}
+
+static int fuse_revalidate(struct dentry *entry)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_conn *fc = get_fuse_conn(inode);
+
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
+ if (get_node_id(inode) != FUSE_ROOT_ID &&
+ time_before_eq(jiffies, fi->i_time))
+ return 0;
+
+ return fuse_do_getattr(inode);
+}
+
+static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
+ else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+ int err = generic_permission(inode, mask, NULL);
+
+ /* If permission is denied, try to refresh file
+ attributes. This is also needed, because the root
+ node will at first have no permissions */
+ if (err == -EACCES) {
+ err = fuse_do_getattr(inode);
+ if (!err)
+ err = generic_permission(inode, mask, NULL);
+ }
+
+ /* FIXME: Need some mechanism to revoke permissions:
+ currently if the filesystem suddenly changes the
+ file mode, we will not be informed about it, and
+ continue to allow access to the file/directory.
+
+ This is actually not so grave, since the user can
+ simply keep access to the file/directory anyway by
+ keeping it open... */
+
+ return err;
+ } else {
+ int mode = inode->i_mode;
+ if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+ return -EROFS;
+ if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
+ return -EACCES;
+ return 0;
+ }
+}
+
+static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
+ void *dstbuf, filldir_t filldir)
+{
+ while (nbytes >= FUSE_NAME_OFFSET) {
+ struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
+ size_t reclen = FUSE_DIRENT_SIZE(dirent);
+ int over;
+ if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
+ return -EIO;
+ if (reclen > nbytes)
+ break;
+
+ over = filldir(dstbuf, dirent->name, dirent->namelen,
+ file->f_pos, dirent->ino, dirent->type);
+ if (over)
+ break;
+
+ buf += reclen;
+ nbytes -= reclen;
+ file->f_pos = dirent->off;
+ }
+
+ return 0;
+}
+
+static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos,
+ size_t count)
+{
+ return fuse_send_read_common(req, file, inode, pos, count, 1);
+}
+
+static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
+{
+ int err;
+ size_t nbytes;
+ struct page *page;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ page = alloc_page(GFP_KERNEL);
+ if (!page) {
+ fuse_put_request(fc, req);
+ return -ENOMEM;
+ }
+ req->num_pages = 1;
+ req->pages[0] = page;
+ nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err)
+ err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
+ filldir);
+
+ __free_page(page);
+ fuse_invalidate_attr(inode); /* atime changed */
+ return err;
+}
+
+static char *read_link(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req = fuse_get_request(fc);
+ char *link;
+
+ if (!req)
+ return ERR_PTR(-EINTR);
+
+ link = (char *) __get_free_page(GFP_KERNEL);
+ if (!link) {
+ link = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+ req->in.h.opcode = FUSE_READLINK;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->out.argvar = 1;
+ req->out.numargs = 1;
+ req->out.args[0].size = PAGE_SIZE - 1;
+ req->out.args[0].value = link;
+ request_send(fc, req);
+ if (req->out.h.error) {
+ free_page((unsigned long) link);
+ link = ERR_PTR(req->out.h.error);
+ } else
+ link[req->out.args[0].size] = '\0';
+ out:
+ fuse_put_request(fc, req);
+ fuse_invalidate_attr(inode); /* atime changed */
+ return link;
+}
+
+static void free_link(char *link)
+{
+ if (!IS_ERR(link))
+ free_page((unsigned long) link);
+}
+
+static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ nd_set_link(nd, read_link(dentry));
+ return NULL;
+}
+
+static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
+{
+ free_link(nd_get_link(nd));
+}
+
+static int fuse_dir_open(struct inode *inode, struct file *file)
+{
+ return fuse_open_common(inode, file, 1);
+}
+
+static int fuse_dir_release(struct inode *inode, struct file *file)
+{
+ return fuse_release_common(inode, file, 1);
+}
+
+static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
+{
+ /* nfsd can call this with no file */
+ return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
+}
+
+static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
+{
+ unsigned ivalid = iattr->ia_valid;
+ unsigned fvalid = 0;
+
+ memset(fattr, 0, sizeof(*fattr));
+
+ if (ivalid & ATTR_MODE)
+ fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
+ if (ivalid & ATTR_UID)
+ fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
+ if (ivalid & ATTR_GID)
+ fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
+ if (ivalid & ATTR_SIZE)
+ fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
+ /* You can only _set_ these together (they may change by themselves) */
+ if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
+ fvalid |= FATTR_ATIME | FATTR_MTIME;
+ fattr->atime = iattr->ia_atime.tv_sec;
+ fattr->mtime = iattr->ia_mtime.tv_sec;
+ }
+
+ return fvalid;
+}
+
+static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_req *req;
+ struct fuse_setattr_in inarg;
+ struct fuse_attr_out outarg;
+ int err;
+ int is_truncate = 0;
+
+ if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+ err = inode_change_ok(inode, attr);
+ if (err)
+ return err;
+ }
+
+ if (attr->ia_valid & ATTR_SIZE) {
+ unsigned long limit;
+ is_truncate = 1;
+ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+ if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
+ send_sig(SIGXFSZ, current, 0);
+ return -EFBIG;
+ }
+ }
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.valid = iattr_to_fattr(attr, &inarg.attr);
+ req->in.h.opcode = FUSE_SETATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err) {
+ if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+ make_bad_inode(inode);
+ err = -EIO;
+ } else {
+ if (is_truncate) {
+ loff_t origsize = i_size_read(inode);
+ i_size_write(inode, outarg.attr.size);
+ if (origsize > outarg.attr.size)
+ vmtruncate(inode, outarg.attr.size);
+ }
+ fuse_change_attributes(inode, &outarg.attr);
+ fi->i_time = time_to_jiffies(outarg.attr_valid,
+ outarg.attr_valid_nsec);
+ }
+ } else if (err == -EINTR)
+ fuse_invalidate_attr(inode);
+
+ return err;
+}
+
+static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
+ struct kstat *stat)
+{
+ struct inode *inode = entry->d_inode;
+ int err = fuse_revalidate(entry);
+ if (!err)
+ generic_fillattr(inode, stat);
+
+ return err;
+}
+
+static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
+ struct nameidata *nd)
+{
+ struct inode *inode;
+ int err = fuse_lookup_iget(dir, entry, &inode);
+ if (err)
+ return ERR_PTR(err);
+ if (inode && S_ISDIR(inode->i_mode)) {
+ /* Don't allow creating an alias to a directory */
+ struct dentry *alias = d_find_alias(inode);
+ if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+ dput(alias);
+ iput(inode);
+ return ERR_PTR(-EIO);
+ }
+ }
+ return d_splice_alias(inode, entry);
+}
+
+static int fuse_setxattr(struct dentry *entry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_setxattr_in inarg;
+ int err;
+
+ if (size > FUSE_XATTR_SIZE_MAX)
+ return -E2BIG;
+
+ if (fc->no_setxattr)
+ return -EOPNOTSUPP;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.size = size;
+ inarg.flags = flags;
+ req->in.h.opcode = FUSE_SETXATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 3;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = strlen(name) + 1;
+ req->in.args[1].value = name;
+ req->in.args[2].size = size;
+ req->in.args[2].value = value;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_setxattr = 1;
+ err = -EOPNOTSUPP;
+ }
+ return err;
+}
+
+static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
+ void *value, size_t size)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_getxattr_in inarg;
+ struct fuse_getxattr_out outarg;
+ ssize_t ret;
+
+ if (fc->no_getxattr)
+ return -EOPNOTSUPP;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.size = size;
+ req->in.h.opcode = FUSE_GETXATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = strlen(name) + 1;
+ req->in.args[1].value = name;
+ /* This is really two different operations rolled into one */
+ req->out.numargs = 1;
+ if (size) {
+ req->out.argvar = 1;
+ req->out.args[0].size = size;
+ req->out.args[0].value = value;
+ } else {
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ }
+ request_send(fc, req);
+ ret = req->out.h.error;
+ if (!ret)
+ ret = size ? req->out.args[0].size : outarg.size;
+ else {
+ if (ret == -ENOSYS) {
+ fc->no_getxattr = 1;
+ ret = -EOPNOTSUPP;
+ }
+ }
+ fuse_put_request(fc, req);
+ return ret;
+}
+
+static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_getxattr_in inarg;
+ struct fuse_getxattr_out outarg;
+ ssize_t ret;
+
+ if (fc->no_listxattr)
+ return -EOPNOTSUPP;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.size = size;
+ req->in.h.opcode = FUSE_LISTXATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ /* This is really two different operations rolled into one */
+ req->out.numargs = 1;
+ if (size) {
+ req->out.argvar = 1;
+ req->out.args[0].size = size;
+ req->out.args[0].value = list;
+ } else {
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ }
+ request_send(fc, req);
+ ret = req->out.h.error;
+ if (!ret)
+ ret = size ? req->out.args[0].size : outarg.size;
+ else {
+ if (ret == -ENOSYS) {
+ fc->no_listxattr = 1;
+ ret = -EOPNOTSUPP;
+ }
+ }
+ fuse_put_request(fc, req);
+ return ret;
+}
+
+static int fuse_removexattr(struct dentry *entry, const char *name)
+{
+ struct inode *inode = entry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ int err;
+
+ if (fc->no_removexattr)
+ return -EOPNOTSUPP;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.h.opcode = FUSE_REMOVEXATTR;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = strlen(name) + 1;
+ req->in.args[0].value = name;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_removexattr = 1;
+ err = -EOPNOTSUPP;
+ }
+ return err;
+}
+
+static struct inode_operations fuse_dir_inode_operations = {
+ .lookup = fuse_lookup,
+ .mkdir = fuse_mkdir,
+ .symlink = fuse_symlink,
+ .unlink = fuse_unlink,
+ .rmdir = fuse_rmdir,
+ .rename = fuse_rename,
+ .link = fuse_link,
+ .setattr = fuse_setattr,
+ .create = fuse_create,
+ .mknod = fuse_mknod,
+ .permission = fuse_permission,
+ .getattr = fuse_getattr,
+ .setxattr = fuse_setxattr,
+ .getxattr = fuse_getxattr,
+ .listxattr = fuse_listxattr,
+ .removexattr = fuse_removexattr,
+};
+
+static struct file_operations fuse_dir_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+ .readdir = fuse_readdir,
+ .open = fuse_dir_open,
+ .release = fuse_dir_release,
+ .fsync = fuse_dir_fsync,
+};
+
+static struct inode_operations fuse_common_inode_operations = {
+ .setattr = fuse_setattr,
+ .permission = fuse_permission,
+ .getattr = fuse_getattr,
+ .setxattr = fuse_setxattr,
+ .getxattr = fuse_getxattr,
+ .listxattr = fuse_listxattr,
+ .removexattr = fuse_removexattr,
+};
+
+static struct inode_operations fuse_symlink_inode_operations = {
+ .setattr = fuse_setattr,
+ .follow_link = fuse_follow_link,
+ .put_link = fuse_put_link,
+ .readlink = generic_readlink,
+ .getattr = fuse_getattr,
+ .setxattr = fuse_setxattr,
+ .getxattr = fuse_getxattr,
+ .listxattr = fuse_listxattr,
+ .removexattr = fuse_removexattr,
+};
+
+void fuse_init_common(struct inode *inode)
+{
+ inode->i_op = &fuse_common_inode_operations;
+}
+
+void fuse_init_dir(struct inode *inode)
+{
+ inode->i_op = &fuse_dir_inode_operations;
+ inode->i_fop = &fuse_dir_operations;
+}
+
+void fuse_init_symlink(struct inode *inode)
+{
+ inode->i_op = &fuse_symlink_inode_operations;
+}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
new file mode 100644
index 00000000000..6454022b053
--- /dev/null
+++ b/fs/fuse/file.c
@@ -0,0 +1,555 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include "fuse_i.h"
+
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+
+static struct file_operations fuse_direct_io_file_operations;
+
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_req *req;
+ struct fuse_open_in inarg;
+ struct fuse_open_out outarg;
+ struct fuse_file *ff;
+ int err;
+
+ err = generic_file_open(inode, file);
+ if (err)
+ return err;
+
+ /* If opening the root node, no lookup has been performed on
+ it, so the attributes must be refreshed */
+ if (get_node_id(inode) == FUSE_ROOT_ID) {
+ int err = fuse_do_getattr(inode);
+ if (err)
+ return err;
+ }
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ err = -ENOMEM;
+ ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ if (!ff)
+ goto out_put_request;
+
+ ff->release_req = fuse_request_alloc();
+ if (!ff->release_req) {
+ kfree(ff);
+ goto out_put_request;
+ }
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (err) {
+ fuse_request_free(ff->release_req);
+ kfree(ff);
+ } else {
+ if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
+ file->f_op = &fuse_direct_io_file_operations;
+ if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages(inode->i_mapping);
+ ff->fh = outarg.fh;
+ file->private_data = ff;
+ }
+
+ out_put_request:
+ fuse_put_request(fc, req);
+ return err;
+}
+
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_req *req = ff->release_req;
+ struct fuse_release_in *inarg = &req->misc.release_in;
+
+ inarg->fh = ff->fh;
+ inarg->flags = file->f_flags & ~O_EXCL;
+ req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(struct fuse_release_in);
+ req->in.args[0].value = inarg;
+ request_send_background(fc, req);
+ kfree(ff);
+
+ /* Return value is ignored by VFS */
+ return 0;
+}
+
+static int fuse_open(struct inode *inode, struct file *file)
+{
+ return fuse_open_common(inode, file, 0);
+}
+
+static int fuse_release(struct inode *inode, struct file *file)
+{
+ return fuse_release_common(inode, file, 0);
+}
+
+static int fuse_flush(struct file *file)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_req *req;
+ struct fuse_flush_in inarg;
+ int err;
+
+ if (fc->no_flush)
+ return 0;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.fh = ff->fh;
+ req->in.h.opcode = FUSE_FLUSH;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->file = file;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ fc->no_flush = 1;
+ err = 0;
+ }
+ return err;
+}
+
+int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
+ int isdir)
+{
+ struct inode *inode = de->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_req *req;
+ struct fuse_fsync_in inarg;
+ int err;
+
+ if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
+ return 0;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ memset(&inarg, 0, sizeof(inarg));
+ inarg.fh = ff->fh;
+ inarg.fsync_flags = datasync ? 1 : 0;
+ req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->file = file;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (err == -ENOSYS) {
+ if (isdir)
+ fc->no_fsyncdir = 1;
+ else
+ fc->no_fsync = 1;
+ err = 0;
+ }
+ return err;
+}
+
+static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
+{
+ return fuse_fsync_common(file, de, datasync, 0);
+}
+
+size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos, size_t count,
+ int isdir)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_read_in inarg;
+
+ memset(&inarg, 0, sizeof(struct fuse_read_in));
+ inarg.fh = ff->fh;
+ inarg.offset = pos;
+ inarg.size = count;
+ req->in.h.opcode = isdir ? FUSE_READDIR : FUSE_READ;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->file = file;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(struct fuse_read_in);
+ req->in.args[0].value = &inarg;
+ req->out.argpages = 1;
+ req->out.argvar = 1;
+ req->out.numargs = 1;
+ req->out.args[0].size = count;
+ request_send(fc, req);
+ return req->out.args[0].size;
+}
+
+static inline size_t fuse_send_read(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos,
+ size_t count)
+{
+ return fuse_send_read_common(req, file, inode, pos, count, 0);
+}
+
+static int fuse_readpage(struct file *file, struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
+ struct fuse_req *req = fuse_get_request(fc);
+ int err = -EINTR;
+ if (!req)
+ goto out;
+
+ req->out.page_zeroing = 1;
+ req->num_pages = 1;
+ req->pages[0] = page;
+ fuse_send_read(req, file, inode, pos, PAGE_CACHE_SIZE);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err)
+ SetPageUptodate(page);
+ fuse_invalidate_attr(inode); /* atime changed */
+ out:
+ unlock_page(page);
+ return err;
+}
+
+static int fuse_send_readpages(struct fuse_req *req, struct file *file,
+ struct inode *inode)
+{
+ loff_t pos = (loff_t) req->pages[0]->index << PAGE_CACHE_SHIFT;
+ size_t count = req->num_pages << PAGE_CACHE_SHIFT;
+ unsigned i;
+ req->out.page_zeroing = 1;
+ fuse_send_read(req, file, inode, pos, count);
+ for (i = 0; i < req->num_pages; i++) {
+ struct page *page = req->pages[i];
+ if (!req->out.h.error)
+ SetPageUptodate(page);
+ unlock_page(page);
+ }
+ return req->out.h.error;
+}
+
+struct fuse_readpages_data {
+ struct fuse_req *req;
+ struct file *file;
+ struct inode *inode;
+};
+
+static int fuse_readpages_fill(void *_data, struct page *page)
+{
+ struct fuse_readpages_data *data = _data;
+ struct fuse_req *req = data->req;
+ struct inode *inode = data->inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+
+ if (req->num_pages &&
+ (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
+ (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
+ req->pages[req->num_pages - 1]->index + 1 != page->index)) {
+ int err = fuse_send_readpages(req, data->file, inode);
+ if (err) {
+ unlock_page(page);
+ return err;
+ }
+ fuse_reset_request(req);
+ }
+ req->pages[req->num_pages] = page;
+ req->num_pages ++;
+ return 0;
+}
+
+static int fuse_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ struct inode *inode = mapping->host;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_readpages_data data;
+ int err;
+ data.file = file;
+ data.inode = inode;
+ data.req = fuse_get_request(fc);
+ if (!data.req)
+ return -EINTR;
+
+ err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
+ if (!err && data.req->num_pages)
+ err = fuse_send_readpages(data.req, file, inode);
+ fuse_put_request(fc, data.req);
+ fuse_invalidate_attr(inode); /* atime changed */
+ return err;
+}
+
+static size_t fuse_send_write(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos, size_t count)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
+ struct fuse_write_in inarg;
+ struct fuse_write_out outarg;
+
+ memset(&inarg, 0, sizeof(struct fuse_write_in));
+ inarg.fh = ff->fh;
+ inarg.offset = pos;
+ inarg.size = count;
+ req->in.h.opcode = FUSE_WRITE;
+ req->in.h.nodeid = get_node_id(inode);
+ req->inode = inode;
+ req->file = file;
+ req->in.argpages = 1;
+ req->in.numargs = 2;
+ req->in.args[0].size = sizeof(struct fuse_write_in);
+ req->in.args[0].value = &inarg;
+ req->in.args[1].size = count;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(struct fuse_write_out);
+ req->out.args[0].value = &outarg;
+ request_send(fc, req);
+ return outarg.size;
+}
+
+static int fuse_prepare_write(struct file *file, struct page *page,
+ unsigned offset, unsigned to)
+{
+ /* No op */
+ return 0;
+}
+
+static int fuse_commit_write(struct file *file, struct page *page,
+ unsigned offset, unsigned to)
+{
+ int err;
+ size_t nres;
+ unsigned count = to - offset;
+ struct inode *inode = page->mapping->host;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->num_pages = 1;
+ req->pages[0] = page;
+ req->page_offset = offset;
+ nres = fuse_send_write(req, file, inode, pos, count);
+ err = req->out.h.error;
+ fuse_put_request(fc, req);
+ if (!err && nres != count)
+ err = -EIO;
+ if (!err) {
+ pos += count;
+ if (pos > i_size_read(inode))
+ i_size_write(inode, pos);
+
+ if (offset == 0 && to == PAGE_CACHE_SIZE) {
+ clear_page_dirty(page);
+ SetPageUptodate(page);
+ }
+ }
+ fuse_invalidate_attr(inode);
+ return err;
+}
+
+static void fuse_release_user_pages(struct fuse_req *req, int write)
+{
+ unsigned i;
+
+ for (i = 0; i < req->num_pages; i++) {
+ struct page *page = req->pages[i];
+ if (write)
+ set_page_dirty_lock(page);
+ put_page(page);
+ }
+}
+
+static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
+ unsigned nbytes, int write)
+{
+ unsigned long user_addr = (unsigned long) buf;
+ unsigned offset = user_addr & ~PAGE_MASK;
+ int npages;
+
+ /* This doesn't work with nfsd */
+ if (!current->mm)
+ return -EPERM;
+
+ nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
+ npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ npages = min(npages, FUSE_MAX_PAGES_PER_REQ);
+ down_read(&current->mm->mmap_sem);
+ npages = get_user_pages(current, current->mm, user_addr, npages, write,
+ 0, req->pages, NULL);
+ up_read(&current->mm->mmap_sem);
+ if (npages < 0)
+ return npages;
+
+ req->num_pages = npages;
+ req->page_offset = offset;
+ return 0;
+}
+
+static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos, int write)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ size_t nmax = write ? fc->max_write : fc->max_read;
+ loff_t pos = *ppos;
+ ssize_t res = 0;
+ struct fuse_req *req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ while (count) {
+ size_t tmp;
+ size_t nres;
+ size_t nbytes = min(count, nmax);
+ int err = fuse_get_user_pages(req, buf, nbytes, !write);
+ if (err) {
+ res = err;
+ break;
+ }
+ tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset;
+ nbytes = min(nbytes, tmp);
+ if (write)
+ nres = fuse_send_write(req, file, inode, pos, nbytes);
+ else
+ nres = fuse_send_read(req, file, inode, pos, nbytes);
+ fuse_release_user_pages(req, !write);
+ if (req->out.h.error) {
+ if (!res)
+ res = req->out.h.error;
+ break;
+ } else if (nres > nbytes) {
+ res = -EIO;
+ break;
+ }
+ count -= nres;
+ res += nres;
+ pos += nres;
+ buf += nres;
+ if (nres != nbytes)
+ break;
+ if (count)
+ fuse_reset_request(req);
+ }
+ fuse_put_request(fc, req);
+ if (res > 0) {
+ if (write && pos > i_size_read(inode))
+ i_size_write(inode, pos);
+ *ppos = pos;
+ }
+ fuse_invalidate_attr(inode);
+
+ return res;
+}
+
+static ssize_t fuse_direct_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return fuse_direct_io(file, buf, count, ppos, 0);
+}
+
+static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ ssize_t res;
+ /* Don't allow parallel writes to the same file */
+ down(&inode->i_sem);
+ res = fuse_direct_io(file, buf, count, ppos, 1);
+ up(&inode->i_sem);
+ return res;
+}
+
+static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ if ((vma->vm_flags & VM_SHARED)) {
+ if ((vma->vm_flags & VM_WRITE))
+ return -ENODEV;
+ else
+ vma->vm_flags &= ~VM_MAYWRITE;
+ }
+ return generic_file_mmap(file, vma);
+}
+
+static int fuse_set_page_dirty(struct page *page)
+{
+ printk("fuse_set_page_dirty: should not happen\n");
+ dump_stack();
+ return 0;
+}
+
+static struct file_operations fuse_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_file_read,
+ .write = generic_file_write,
+ .mmap = fuse_file_mmap,
+ .open = fuse_open,
+ .flush = fuse_flush,
+ .release = fuse_release,
+ .fsync = fuse_fsync,
+ .sendfile = generic_file_sendfile,
+};
+
+static struct file_operations fuse_direct_io_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = fuse_direct_read,
+ .write = fuse_direct_write,
+ .open = fuse_open,
+ .flush = fuse_flush,
+ .release = fuse_release,
+ .fsync = fuse_fsync,
+ /* no mmap and sendfile */
+};
+
+static struct address_space_operations fuse_file_aops = {
+ .readpage = fuse_readpage,
+ .prepare_write = fuse_prepare_write,
+ .commit_write = fuse_commit_write,
+ .readpages = fuse_readpages,
+ .set_page_dirty = fuse_set_page_dirty,
+};
+
+void fuse_init_file_inode(struct inode *inode)
+{
+ inode->i_fop = &fuse_file_operations;
+ inode->i_data.a_ops = &fuse_file_aops;
+}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
new file mode 100644
index 00000000000..24d761518d8
--- /dev/null
+++ b/fs/fuse/fuse_i.h
@@ -0,0 +1,451 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include <linux/fuse.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/backing-dev.h>
+#include <asm/semaphore.h>
+
+/** Max number of pages that can be used in a single read request */
+#define FUSE_MAX_PAGES_PER_REQ 32
+
+/** If more requests are outstanding, then the operation will block */
+#define FUSE_MAX_OUTSTANDING 10
+
+/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
+ module will check permissions based on the file mode. Otherwise no
+ permission checking is done in the kernel */
+#define FUSE_DEFAULT_PERMISSIONS (1 << 0)
+
+/** If the FUSE_ALLOW_OTHER flag is given, then not only the user
+ doing the mount will be allowed to access the filesystem */
+#define FUSE_ALLOW_OTHER (1 << 1)
+
+
+/** FUSE inode */
+struct fuse_inode {
+ /** Inode data */
+ struct inode inode;
+
+ /** Unique ID, which identifies the inode between userspace
+ * and kernel */
+ u64 nodeid;
+
+ /** Number of lookups on this inode */
+ u64 nlookup;
+
+ /** The request used for sending the FORGET message */
+ struct fuse_req *forget_req;
+
+ /** Time in jiffies until the file attributes are valid */
+ unsigned long i_time;
+};
+
+/** FUSE specific file data */
+struct fuse_file {
+ /** Request reserved for flush and release */
+ struct fuse_req *release_req;
+
+ /** File handle used by userspace */
+ u64 fh;
+};
+
+/** One input argument of a request */
+struct fuse_in_arg {
+ unsigned size;
+ const void *value;
+};
+
+/** The request input */
+struct fuse_in {
+ /** The request header */
+ struct fuse_in_header h;
+
+ /** True if the data for the last argument is in req->pages */
+ unsigned argpages:1;
+
+ /** Number of arguments */
+ unsigned numargs;
+
+ /** Array of arguments */
+ struct fuse_in_arg args[3];
+};
+
+/** One output argument of a request */
+struct fuse_arg {
+ unsigned size;
+ void *value;
+};
+
+/** The request output */
+struct fuse_out {
+ /** Header returned from userspace */
+ struct fuse_out_header h;
+
+ /** Last argument is variable length (can be shorter than
+ arg->size) */
+ unsigned argvar:1;
+
+ /** Last argument is a list of pages to copy data to */
+ unsigned argpages:1;
+
+ /** Zero partially or not copied pages */
+ unsigned page_zeroing:1;
+
+ /** Number or arguments */
+ unsigned numargs;
+
+ /** Array of arguments */
+ struct fuse_arg args[3];
+};
+
+struct fuse_req;
+struct fuse_conn;
+
+/**
+ * A request to the client
+ */
+struct fuse_req {
+ /** This can be on either unused_list, pending or processing
+ lists in fuse_conn */
+ struct list_head list;
+
+ /** Entry on the background list */
+ struct list_head bg_entry;
+
+ /** refcount */
+ atomic_t count;
+
+ /** True if the request has reply */
+ unsigned isreply:1;
+
+ /** The request is preallocated */
+ unsigned preallocated:1;
+
+ /** The request was interrupted */
+ unsigned interrupted:1;
+
+ /** Request is sent in the background */
+ unsigned background:1;
+
+ /** Data is being copied to/from the request */
+ unsigned locked:1;
+
+ /** Request has been sent to userspace */
+ unsigned sent:1;
+
+ /** The request is finished */
+ unsigned finished:1;
+
+ /** The request input */
+ struct fuse_in in;
+
+ /** The request output */
+ struct fuse_out out;
+
+ /** Used to wake up the task waiting for completion of request*/
+ wait_queue_head_t waitq;
+
+ /** Data for asynchronous requests */
+ union {
+ struct fuse_forget_in forget_in;
+ struct fuse_release_in release_in;
+ struct fuse_init_in_out init_in_out;
+ } misc;
+
+ /** page vector */
+ struct page *pages[FUSE_MAX_PAGES_PER_REQ];
+
+ /** number of pages in vector */
+ unsigned num_pages;
+
+ /** offset of data on first page */
+ unsigned page_offset;
+
+ /** Inode used in the request */
+ struct inode *inode;
+
+ /** Second inode used in the request (or NULL) */
+ struct inode *inode2;
+
+ /** File used in the request (or NULL) */
+ struct file *file;
+};
+
+/**
+ * A Fuse connection.
+ *
+ * This structure is created, when the filesystem is mounted, and is
+ * destroyed, when the client device is closed and the filesystem is
+ * unmounted.
+ */
+struct fuse_conn {
+ /** Reference count */
+ int count;
+
+ /** The user id for this mount */
+ uid_t user_id;
+
+ /** The group id for this mount */
+ gid_t group_id;
+
+ /** The fuse mount flags for this mount */
+ unsigned flags;
+
+ /** Maximum read size */
+ unsigned max_read;
+
+ /** Maximum write size */
+ unsigned max_write;
+
+ /** Readers of the connection are waiting on this */
+ wait_queue_head_t waitq;
+
+ /** The list of pending requests */
+ struct list_head pending;
+
+ /** The list of requests being processed */
+ struct list_head processing;
+
+ /** Requests put in the background (RELEASE or any other
+ interrupted request) */
+ struct list_head background;
+
+ /** Controls the maximum number of outstanding requests */
+ struct semaphore outstanding_sem;
+
+ /** This counts the number of outstanding requests if
+ outstanding_sem would go negative */
+ unsigned outstanding_debt;
+
+ /** RW semaphore for exclusion with fuse_put_super() */
+ struct rw_semaphore sbput_sem;
+
+ /** The list of unused requests */
+ struct list_head unused_list;
+
+ /** The next unique request id */
+ u64 reqctr;
+
+ /** Mount is active */
+ unsigned mounted : 1;
+
+ /** Connection established */
+ unsigned connected : 1;
+
+ /** Connection failed (version mismatch) */
+ unsigned conn_error : 1;
+
+ /** Is fsync not implemented by fs? */
+ unsigned no_fsync : 1;
+
+ /** Is fsyncdir not implemented by fs? */
+ unsigned no_fsyncdir : 1;
+
+ /** Is flush not implemented by fs? */
+ unsigned no_flush : 1;
+
+ /** Is setxattr not implemented by fs? */
+ unsigned no_setxattr : 1;
+
+ /** Is getxattr not implemented by fs? */
+ unsigned no_getxattr : 1;
+
+ /** Is listxattr not implemented by fs? */
+ unsigned no_listxattr : 1;
+
+ /** Is removexattr not implemented by fs? */
+ unsigned no_removexattr : 1;
+
+ /** Backing dev info */
+ struct backing_dev_info bdi;
+};
+
+static inline struct fuse_conn **get_fuse_conn_super_p(struct super_block *sb)
+{
+ return (struct fuse_conn **) &sb->s_fs_info;
+}
+
+static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
+{
+ return *get_fuse_conn_super_p(sb);
+}
+
+static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
+{
+ return get_fuse_conn_super(inode->i_sb);
+}
+
+static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
+{
+ return container_of(inode, struct fuse_inode, inode);
+}
+
+static inline u64 get_node_id(struct inode *inode)
+{
+ return get_fuse_inode(inode)->nodeid;
+}
+
+/** Device operations */
+extern struct file_operations fuse_dev_operations;
+
+/**
+ * This is the single global spinlock which protects FUSE's structures
+ *
+ * The following data is protected by this lock:
+ *
+ * - the private_data field of the device file
+ * - the s_fs_info field of the super block
+ * - unused_list, pending, processing lists in fuse_conn
+ * - background list in fuse_conn
+ * - the unique request ID counter reqctr in fuse_conn
+ * - the sb (super_block) field in fuse_conn
+ * - the file (device file) field in fuse_conn
+ */
+extern spinlock_t fuse_lock;
+
+/**
+ * Get a filled in inode
+ */
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+ int generation, struct fuse_attr *attr);
+
+/**
+ * Send FORGET command
+ */
+void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
+ unsigned long nodeid, u64 nlookup);
+
+/**
+ * Send READ or READDIR request
+ */
+size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos, size_t count,
+ int isdir);
+
+/**
+ * Send OPEN or OPENDIR request
+ */
+int fuse_open_common(struct inode *inode, struct file *file, int isdir);
+
+/**
+ * Send RELEASE or RELEASEDIR request
+ */
+int fuse_release_common(struct inode *inode, struct file *file, int isdir);
+
+/**
+ * Send FSYNC or FSYNCDIR request
+ */
+int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
+ int isdir);
+
+/**
+ * Initialise file operations on a regular file
+ */
+void fuse_init_file_inode(struct inode *inode);
+
+/**
+ * Initialise inode operations on regular files and special files
+ */
+void fuse_init_common(struct inode *inode);
+
+/**
+ * Initialise inode and file operations on a directory
+ */
+void fuse_init_dir(struct inode *inode);
+
+/**
+ * Initialise inode operations on a symlink
+ */
+void fuse_init_symlink(struct inode *inode);
+
+/**
+ * Change attributes of an inode
+ */
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
+
+/**
+ * Check if the connection can be released, and if yes, then free the
+ * connection structure
+ */
+void fuse_release_conn(struct fuse_conn *fc);
+
+/**
+ * Initialize the client device
+ */
+int fuse_dev_init(void);
+
+/**
+ * Cleanup the client device
+ */
+void fuse_dev_cleanup(void);
+
+/**
+ * Allocate a request
+ */
+struct fuse_req *fuse_request_alloc(void);
+
+/**
+ * Free a request
+ */
+void fuse_request_free(struct fuse_req *req);
+
+/**
+ * Reinitialize a request, the preallocated flag is left unmodified
+ */
+void fuse_reset_request(struct fuse_req *req);
+
+/**
+ * Reserve a preallocated request
+ */
+struct fuse_req *fuse_get_request(struct fuse_conn *fc);
+
+/**
+ * Decrement reference count of a request. If count goes to zero put
+ * on unused list (preallocated) or free reqest (not preallocated).
+ */
+void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
+
+/**
+ * Send a request (synchronous)
+ */
+void request_send(struct fuse_conn *fc, struct fuse_req *req);
+
+/**
+ * Send a request with no reply
+ */
+void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
+
+/**
+ * Send a request in the background
+ */
+void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
+
+/**
+ * Release inodes and file assiciated with background request
+ */
+void fuse_release_background(struct fuse_req *req);
+
+/**
+ * Get the attributes of a file
+ */
+int fuse_do_getattr(struct inode *inode);
+
+/**
+ * Invalidate inode attributes
+ */
+void fuse_invalidate_attr(struct inode *inode);
+
+/**
+ * Send the INIT message
+ */
+void fuse_send_init(struct fuse_conn *fc);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
new file mode 100644
index 00000000000..e69a546844d
--- /dev/null
+++ b/fs/fuse/inode.c
@@ -0,0 +1,591 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include "fuse_i.h"
+
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/parser.h>
+#include <linux/statfs.h>
+
+MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
+MODULE_DESCRIPTION("Filesystem in Userspace");
+MODULE_LICENSE("GPL");
+
+spinlock_t fuse_lock;
+static kmem_cache_t *fuse_inode_cachep;
+
+#define FUSE_SUPER_MAGIC 0x65735546
+
+struct fuse_mount_data {
+ int fd;
+ unsigned rootmode;
+ unsigned user_id;
+ unsigned group_id;
+ unsigned fd_present : 1;
+ unsigned rootmode_present : 1;
+ unsigned user_id_present : 1;
+ unsigned group_id_present : 1;
+ unsigned flags;
+ unsigned max_read;
+};
+
+static struct inode *fuse_alloc_inode(struct super_block *sb)
+{
+ struct inode *inode;
+ struct fuse_inode *fi;
+
+ inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL);
+ if (!inode)
+ return NULL;
+
+ fi = get_fuse_inode(inode);
+ fi->i_time = jiffies - 1;
+ fi->nodeid = 0;
+ fi->nlookup = 0;
+ fi->forget_req = fuse_request_alloc();
+ if (!fi->forget_req) {
+ kmem_cache_free(fuse_inode_cachep, inode);
+ return NULL;
+ }
+
+ return inode;
+}
+
+static void fuse_destroy_inode(struct inode *inode)
+{
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ if (fi->forget_req)
+ fuse_request_free(fi->forget_req);
+ kmem_cache_free(fuse_inode_cachep, inode);
+}
+
+static void fuse_read_inode(struct inode *inode)
+{
+ /* No op */
+}
+
+void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
+ unsigned long nodeid, u64 nlookup)
+{
+ struct fuse_forget_in *inarg = &req->misc.forget_in;
+ inarg->nlookup = nlookup;
+ req->in.h.opcode = FUSE_FORGET;
+ req->in.h.nodeid = nodeid;
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(struct fuse_forget_in);
+ req->in.args[0].value = inarg;
+ request_send_noreply(fc, req);
+}
+
+static void fuse_clear_inode(struct inode *inode)
+{
+ if (inode->i_sb->s_flags & MS_ACTIVE) {
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
+ fi->forget_req = NULL;
+ }
+}
+
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
+{
+ if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
+ invalidate_inode_pages(inode->i_mapping);
+
+ inode->i_ino = attr->ino;
+ inode->i_mode = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
+ inode->i_nlink = attr->nlink;
+ inode->i_uid = attr->uid;
+ inode->i_gid = attr->gid;
+ i_size_write(inode, attr->size);
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = attr->blocks;
+ inode->i_atime.tv_sec = attr->atime;
+ inode->i_atime.tv_nsec = attr->atimensec;
+ inode->i_mtime.tv_sec = attr->mtime;
+ inode->i_mtime.tv_nsec = attr->mtimensec;
+ inode->i_ctime.tv_sec = attr->ctime;
+ inode->i_ctime.tv_nsec = attr->ctimensec;
+}
+
+static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
+{
+ inode->i_mode = attr->mode & S_IFMT;
+ i_size_write(inode, attr->size);
+ if (S_ISREG(inode->i_mode)) {
+ fuse_init_common(inode);
+ fuse_init_file_inode(inode);
+ } else if (S_ISDIR(inode->i_mode))
+ fuse_init_dir(inode);
+ else if (S_ISLNK(inode->i_mode))
+ fuse_init_symlink(inode);
+ else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
+ S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
+ fuse_init_common(inode);
+ init_special_inode(inode, inode->i_mode,
+ new_decode_dev(attr->rdev));
+ } else {
+ /* Don't let user create weird files */
+ inode->i_mode = S_IFREG;
+ fuse_init_common(inode);
+ fuse_init_file_inode(inode);
+ }
+}
+
+static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
+{
+ unsigned long nodeid = *(unsigned long *) _nodeidp;
+ if (get_node_id(inode) == nodeid)
+ return 1;
+ else
+ return 0;
+}
+
+static int fuse_inode_set(struct inode *inode, void *_nodeidp)
+{
+ unsigned long nodeid = *(unsigned long *) _nodeidp;
+ get_fuse_inode(inode)->nodeid = nodeid;
+ return 0;
+}
+
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+ int generation, struct fuse_attr *attr)
+{
+ struct inode *inode;
+ struct fuse_inode *fi;
+ struct fuse_conn *fc = get_fuse_conn_super(sb);
+ int retried = 0;
+
+ retry:
+ inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
+ if (!inode)
+ return NULL;
+
+ if ((inode->i_state & I_NEW)) {
+ inode->i_flags |= S_NOATIME|S_NOCMTIME;
+ inode->i_generation = generation;
+ inode->i_data.backing_dev_info = &fc->bdi;
+ fuse_init_inode(inode, attr);
+ unlock_new_inode(inode);
+ } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
+ BUG_ON(retried);
+ /* Inode has changed type, any I/O on the old should fail */
+ make_bad_inode(inode);
+ iput(inode);
+ retried = 1;
+ goto retry;
+ }
+
+ fi = get_fuse_inode(inode);
+ fi->nlookup ++;
+ fuse_change_attributes(inode, attr);
+ return inode;
+}
+
+static void fuse_put_super(struct super_block *sb)
+{
+ struct fuse_conn *fc = get_fuse_conn_super(sb);
+
+ down_write(&fc->sbput_sem);
+ while (!list_empty(&fc->background))
+ fuse_release_background(list_entry(fc->background.next,
+ struct fuse_req, bg_entry));
+
+ spin_lock(&fuse_lock);
+ fc->mounted = 0;
+ fc->user_id = 0;
+ fc->group_id = 0;
+ fc->flags = 0;
+ /* Flush all readers on this fs */
+ wake_up_all(&fc->waitq);
+ up_write(&fc->sbput_sem);
+ fuse_release_conn(fc);
+ spin_unlock(&fuse_lock);
+}
+
+static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
+{
+ stbuf->f_type = FUSE_SUPER_MAGIC;
+ stbuf->f_bsize = attr->bsize;
+ stbuf->f_blocks = attr->blocks;
+ stbuf->f_bfree = attr->bfree;
+ stbuf->f_bavail = attr->bavail;
+ stbuf->f_files = attr->files;
+ stbuf->f_ffree = attr->ffree;
+ stbuf->f_namelen = attr->namelen;
+ /* fsid is left zero */
+}
+
+static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+ struct fuse_conn *fc = get_fuse_conn_super(sb);
+ struct fuse_req *req;
+ struct fuse_statfs_out outarg;
+ int err;
+
+ req = fuse_get_request(fc);
+ if (!req)
+ return -EINTR;
+
+ req->in.numargs = 0;
+ req->in.h.opcode = FUSE_STATFS;
+ req->out.numargs = 1;
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
+ request_send(fc, req);
+ err = req->out.h.error;
+ if (!err)
+ convert_fuse_statfs(buf, &outarg.st);
+ fuse_put_request(fc, req);
+ return err;
+}
+
+enum {
+ OPT_FD,
+ OPT_ROOTMODE,
+ OPT_USER_ID,
+ OPT_GROUP_ID,
+ OPT_DEFAULT_PERMISSIONS,
+ OPT_ALLOW_OTHER,
+ OPT_MAX_READ,
+ OPT_ERR
+};
+
+static match_table_t tokens = {
+ {OPT_FD, "fd=%u"},
+ {OPT_ROOTMODE, "rootmode=%o"},
+ {OPT_USER_ID, "user_id=%u"},
+ {OPT_GROUP_ID, "group_id=%u"},
+ {OPT_DEFAULT_PERMISSIONS, "default_permissions"},
+ {OPT_ALLOW_OTHER, "allow_other"},
+ {OPT_MAX_READ, "max_read=%u"},
+ {OPT_ERR, NULL}
+};
+
+static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
+{
+ char *p;
+ memset(d, 0, sizeof(struct fuse_mount_data));
+ d->max_read = ~0;
+
+ while ((p = strsep(&opt, ",")) != NULL) {
+ int token;
+ int value;
+ substring_t args[MAX_OPT_ARGS];
+ if (!*p)
+ continue;
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case OPT_FD:
+ if (match_int(&args[0], &value))
+ return 0;
+ d->fd = value;
+ d->fd_present = 1;
+ break;
+
+ case OPT_ROOTMODE:
+ if (match_octal(&args[0], &value))
+ return 0;
+ d->rootmode = value;
+ d->rootmode_present = 1;
+ break;
+
+ case OPT_USER_ID:
+ if (match_int(&args[0], &value))
+ return 0;
+ d->user_id = value;
+ d->user_id_present = 1;
+ break;
+
+ case OPT_GROUP_ID:
+ if (match_int(&args[0], &value))
+ return 0;
+ d->group_id = value;
+ d->group_id_present = 1;
+ break;
+
+ case OPT_DEFAULT_PERMISSIONS:
+ d->flags |= FUSE_DEFAULT_PERMISSIONS;
+ break;
+
+ case OPT_ALLOW_OTHER:
+ d->flags |= FUSE_ALLOW_OTHER;
+ break;
+
+ case OPT_MAX_READ:
+ if (match_int(&args[0], &value))
+ return 0;
+ d->max_read = value;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ if (!d->fd_present || !d->rootmode_present ||
+ !d->user_id_present || !d->group_id_present)
+ return 0;
+
+ return 1;
+}
+
+static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+ struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb);
+
+ seq_printf(m, ",user_id=%u", fc->user_id);
+ seq_printf(m, ",group_id=%u", fc->group_id);
+ if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
+ seq_puts(m, ",default_permissions");
+ if (fc->flags & FUSE_ALLOW_OTHER)
+ seq_puts(m, ",allow_other");
+ if (fc->max_read != ~0)
+ seq_printf(m, ",max_read=%u", fc->max_read);
+ return 0;
+}
+
+static void free_conn(struct fuse_conn *fc)
+{
+ while (!list_empty(&fc->unused_list)) {
+ struct fuse_req *req;
+ req = list_entry(fc->unused_list.next, struct fuse_req, list);
+ list_del(&req->list);
+ fuse_request_free(req);
+ }
+ kfree(fc);
+}
+
+/* Must be called with the fuse lock held */
+void fuse_release_conn(struct fuse_conn *fc)
+{
+ fc->count--;
+ if (!fc->count)
+ free_conn(fc);
+}
+
+static struct fuse_conn *new_conn(void)
+{
+ struct fuse_conn *fc;
+
+ fc = kmalloc(sizeof(*fc), GFP_KERNEL);
+ if (fc != NULL) {
+ int i;
+ memset(fc, 0, sizeof(*fc));
+ init_waitqueue_head(&fc->waitq);
+ INIT_LIST_HEAD(&fc->pending);
+ INIT_LIST_HEAD(&fc->processing);
+ INIT_LIST_HEAD(&fc->unused_list);
+ INIT_LIST_HEAD(&fc->background);
+ sema_init(&fc->outstanding_sem, 0);
+ init_rwsem(&fc->sbput_sem);
+ for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
+ struct fuse_req *req = fuse_request_alloc();
+ if (!req) {
+ free_conn(fc);
+ return NULL;
+ }
+ list_add(&req->list, &fc->unused_list);
+ }
+ fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
+ fc->bdi.unplug_io_fn = default_unplug_io_fn;
+ fc->reqctr = 0;
+ }
+ return fc;
+}
+
+static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
+{
+ struct fuse_conn *fc;
+
+ if (file->f_op != &fuse_dev_operations)
+ return ERR_PTR(-EINVAL);
+ fc = new_conn();
+ if (fc == NULL)
+ return ERR_PTR(-ENOMEM);
+ spin_lock(&fuse_lock);
+ if (file->private_data) {
+ free_conn(fc);
+ fc = ERR_PTR(-EINVAL);
+ } else {
+ file->private_data = fc;
+ *get_fuse_conn_super_p(sb) = fc;
+ fc->mounted = 1;
+ fc->connected = 1;
+ fc->count = 2;
+ }
+ spin_unlock(&fuse_lock);
+ return fc;
+}
+
+static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
+{
+ struct fuse_attr attr;
+ memset(&attr, 0, sizeof(attr));
+
+ attr.mode = mode;
+ attr.ino = FUSE_ROOT_ID;
+ return fuse_iget(sb, 1, 0, &attr);
+}
+
+static struct super_operations fuse_super_operations = {
+ .alloc_inode = fuse_alloc_inode,
+ .destroy_inode = fuse_destroy_inode,
+ .read_inode = fuse_read_inode,
+ .clear_inode = fuse_clear_inode,
+ .put_super = fuse_put_super,
+ .statfs = fuse_statfs,
+ .show_options = fuse_show_options,
+};
+
+static int fuse_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct fuse_conn *fc;
+ struct inode *root;
+ struct fuse_mount_data d;
+ struct file *file;
+ int err;
+
+ if (!parse_fuse_opt((char *) data, &d))
+ return -EINVAL;
+
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = FUSE_SUPER_MAGIC;
+ sb->s_op = &fuse_super_operations;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+
+ file = fget(d.fd);
+ if (!file)
+ return -EINVAL;
+
+ fc = get_conn(file, sb);
+ fput(file);
+ if (IS_ERR(fc))
+ return PTR_ERR(fc);
+
+ fc->flags = d.flags;
+ fc->user_id = d.user_id;
+ fc->group_id = d.group_id;
+ fc->max_read = d.max_read;
+ if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
+ fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
+ fc->max_write = FUSE_MAX_IN / 2;
+
+ err = -ENOMEM;
+ root = get_root_inode(sb, d.rootmode);
+ if (root == NULL)
+ goto err;
+
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root) {
+ iput(root);
+ goto err;
+ }
+ fuse_send_init(fc);
+ return 0;
+
+ err:
+ spin_lock(&fuse_lock);
+ fuse_release_conn(fc);
+ spin_unlock(&fuse_lock);
+ return err;
+}
+
+static struct super_block *fuse_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *raw_data)
+{
+ return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);
+}
+
+static struct file_system_type fuse_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "fuse",
+ .get_sb = fuse_get_sb,
+ .kill_sb = kill_anon_super,
+};
+
+static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep,
+ unsigned long flags)
+{
+ struct inode * inode = foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR)
+ inode_init_once(inode);
+}
+
+static int __init fuse_fs_init(void)
+{
+ int err;
+
+ err = register_filesystem(&fuse_fs_type);
+ if (err)
+ printk("fuse: failed to register filesystem\n");
+ else {
+ fuse_inode_cachep = kmem_cache_create("fuse_inode",
+ sizeof(struct fuse_inode),
+ 0, SLAB_HWCACHE_ALIGN,
+ fuse_inode_init_once, NULL);
+ if (!fuse_inode_cachep) {
+ unregister_filesystem(&fuse_fs_type);
+ err = -ENOMEM;
+ }
+ }
+
+ return err;
+}
+
+static void fuse_fs_cleanup(void)
+{
+ unregister_filesystem(&fuse_fs_type);
+ kmem_cache_destroy(fuse_inode_cachep);
+}
+
+static int __init fuse_init(void)
+{
+ int res;
+
+ printk("fuse init (API version %i.%i)\n",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+
+ spin_lock_init(&fuse_lock);
+ res = fuse_fs_init();
+ if (res)
+ goto err;
+
+ res = fuse_dev_init();
+ if (res)
+ goto err_fs_cleanup;
+
+ return 0;
+
+ err_fs_cleanup:
+ fuse_fs_cleanup();
+ err:
+ return res;
+}
+
+static void __exit fuse_exit(void)
+{
+ printk(KERN_DEBUG "fuse exit\n");
+
+ fuse_fs_cleanup();
+ fuse_dev_cleanup();
+}
+
+module_init(fuse_init);
+module_exit(fuse_exit);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index b2d18200a00..59c5062cd63 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)
static void hostfs_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
if(HOSTFS_I(inode)->fd != -1) {
close_file(&HOSTFS_I(inode)->fd);
HOSTFS_I(inode)->fd = -1;
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index 38b1741fa53..e3d17e9ea6c 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -284,6 +284,7 @@ void hpfs_write_if_changed(struct inode *inode)
void hpfs_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
lock_kernel();
hpfs_remove_fnode(inode->i_sb, inode->i_ino);
unlock_kernel();
diff --git a/fs/inode.c b/fs/inode.c
index 71df1b1e8f7..f80a79ff156 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1034,19 +1034,21 @@ void generic_delete_inode(struct inode *inode)
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
- if (inode->i_data.nrpages)
- truncate_inode_pages(&inode->i_data, 0);
-
security_inode_delete(inode);
if (op->delete_inode) {
void (*delete)(struct inode *) = op->delete_inode;
if (!is_bad_inode(inode))
DQUOT_INIT(inode);
- /* s_op->delete_inode internally recalls clear_inode() */
+ /* Filesystems implementing their own
+ * s_op->delete_inode are required to call
+ * truncate_inode_pages and clear_inode()
+ * internally */
delete(inode);
- } else
+ } else {
+ truncate_inode_pages(&inode->i_data, 0);
clear_inode(inode);
+ }
spin_lock(&inode_lock);
hlist_del_init(&inode->i_hash);
spin_unlock(&inode_lock);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 777b90057b8..3dcc6d2162c 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1744,6 +1744,7 @@ jffs_delete_inode(struct inode *inode)
D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
inode->i_ino));
+ truncate_inode_pages(&inode->i_data, 0);
lock_kernel();
inode->i_size = 0;
inode->i_blocks = 0;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 767c7ecb429..cff352f4ec1 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -132,6 +132,8 @@ void jfs_delete_inode(struct inode *inode)
(JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I)))
return;
+ truncate_inode_pages(&inode->i_data, 0);
+
if (test_cflag(COMMIT_Freewmap, inode))
jfs_free_zero_link(inode);
diff --git a/fs/locks.c b/fs/locks.c
index 11956b6179f..c2c09b4798d 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2198,21 +2198,23 @@ void steal_locks(fl_owner_t from)
{
struct files_struct *files = current->files;
int i, j;
+ struct fdtable *fdt;
if (from == files)
return;
lock_kernel();
j = 0;
+ fdt = files_fdtable(files);
for (;;) {
unsigned long set;
i = j * __NFDBITS;
- if (i >= files->max_fdset || i >= files->max_fds)
+ if (i >= fdt->max_fdset || i >= fdt->max_fds)
break;
- set = files->open_fds->fds_bits[j++];
+ set = fdt->open_fds->fds_bits[j++];
while (set) {
if (set & 1) {
- struct file *file = files->fd[i];
+ struct file *file = fdt->fd[i];
if (file)
__steal_locks(file, from);
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 3f18c21198d..790cc0d0e97 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);
static void minix_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
inode->i_size = 0;
minix_truncate(inode);
minix_free_inode(inode);
diff --git a/fs/namei.c b/fs/namei.c
index 145e852c4bd..21d85f1ac83 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1316,10 +1316,8 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
return error;
DQUOT_INIT(dir);
error = dir->i_op->create(dir, dentry, mode, nd);
- if (!error) {
+ if (!error)
fsnotify_create(dir, dentry->d_name.name);
- security_inode_post_create(dir, dentry, mode);
- }
return error;
}
@@ -1635,10 +1633,8 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
DQUOT_INIT(dir);
error = dir->i_op->mknod(dir, dentry, mode, dev);
- if (!error) {
+ if (!error)
fsnotify_create(dir, dentry->d_name.name);
- security_inode_post_mknod(dir, dentry, mode, dev);
- }
return error;
}
@@ -1708,10 +1704,8 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
DQUOT_INIT(dir);
error = dir->i_op->mkdir(dir, dentry, mode);
- if (!error) {
+ if (!error)
fsnotify_mkdir(dir, dentry->d_name.name);
- security_inode_post_mkdir(dir,dentry, mode);
- }
return error;
}
@@ -1947,10 +1941,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
DQUOT_INIT(dir);
error = dir->i_op->symlink(dir, dentry, oldname);
- if (!error) {
+ if (!error)
fsnotify_create(dir, dentry->d_name.name);
- security_inode_post_symlink(dir, dentry, oldname);
- }
return error;
}
@@ -2020,10 +2012,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
DQUOT_INIT(dir);
error = dir->i_op->link(old_dentry, dir, new_dentry);
up(&old_dentry->d_inode->i_sem);
- if (!error) {
+ if (!error)
fsnotify_create(dir, new_dentry->d_name.name);
- security_inode_post_link(old_dentry, dir, new_dentry);
- }
return error;
}
@@ -2142,11 +2132,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
d_rehash(new_dentry);
dput(new_dentry);
}
- if (!error) {
+ if (!error)
d_move(old_dentry,new_dentry);
- security_inode_post_rename(old_dir, old_dentry,
- new_dir, new_dentry);
- }
return error;
}
@@ -2172,7 +2159,6 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
/* The following d_move() should become unconditional */
if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
d_move(old_dentry, new_dentry);
- security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry);
}
if (target)
up(&target->i_sem);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 44795d2f4b3..8c8839203cd 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)
static void
ncp_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+
if (S_ISDIR(inode->i_mode)) {
DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino);
}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 541b418327c..6922469d6fc 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -146,6 +146,8 @@ nfs_delete_inode(struct inode * inode)
{
dprintk("NFS: delete_inode(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
+ truncate_inode_pages(&inode->i_data, 0);
+
nfs_wb_all(inode);
/*
* The following should never happen...
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 9eecc9939df..e4fd6134244 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -22,6 +22,76 @@ ToDo/Notes:
- Enable the code for setting the NT4 compatibility flag when we start
making NTFS 1.2 specific modifications.
+2.1.24 - Lots of bug fixes and support more clean journal states.
+
+ - Support journals ($LogFile) which have been modified by chkdsk. This
+ means users can boot into Windows after we marked the volume dirty.
+ The Windows boot will run chkdsk and then reboot. The user can then
+ immediately boot into Linux rather than having to do a full Windows
+ boot first before rebooting into Linux and we will recognize such a
+ journal and empty it as it is clean by definition.
+ - Support journals ($LogFile) with only one restart page as well as
+ journals with two different restart pages. We sanity check both and
+ either use the only sane one or the more recent one of the two in the
+ case that both are valid.
+ - Modify fs/ntfs/malloc.h::ntfs_malloc_nofs() to do the kmalloc() based
+ allocations with __GFP_HIGHMEM, analogous to how the vmalloc() based
+ allocations are done.
+ - Add fs/ntfs/malloc.h::ntfs_malloc_nofs_nofail() which is analogous to
+ ntfs_malloc_nofs() but it performs allocations with __GFP_NOFAIL and
+ hence cannot fail.
+ - Use ntfs_malloc_nofs_nofail() in the two critical regions in
+ fs/ntfs/runlist.c::ntfs_runlists_merge(). This means we no longer
+ need to panic() if the allocation fails as it now cannot fail.
+ - Fix two nasty runlist merging bugs that had gone unnoticed so far.
+ Thanks to Stefano Picerno for the bug report.
+ - Remove two bogus BUG_ON()s from fs/ntfs/mft.c.
+ - Fix handling of valid but empty mapping pairs array in
+ fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress().
+ - Report unrepresentable inodes during ntfs_readdir() as KERN_WARNING
+ messages and include the inode number. Thanks to Yura Pakhuchiy for
+ pointing this out.
+ - Change ntfs_rl_truncate_nolock() to throw away the runlist if the new
+ length is zero.
+ - Add runlist.[hc]::ntfs_rl_punch_nolock() which punches a caller
+ specified hole into a runlist.
+ - Fix a bug in fs/ntfs/index.c::ntfs_index_lookup(). When the returned
+ index entry is in the index root, we forgot to set the @ir pointer in
+ the index context. Thanks to Yura Pakhuchiy for finding this bug.
+ - Remove bogus setting of PageError in ntfs_read_compressed_block().
+ - Add fs/ntfs/attrib.[hc]::ntfs_resident_attr_value_resize().
+ - Fix a bug in ntfs_map_runlist_nolock() where we forgot to protect
+ access to the allocated size in the ntfs inode with the size lock.
+ - Fix ntfs_attr_vcn_to_lcn_nolock() and ntfs_attr_find_vcn_nolock() to
+ return LCN_ENOENT when there is no runlist and the allocated size is
+ zero.
+ - Fix load_attribute_list() to handle the case of a NULL runlist.
+ - Fix handling of sparse attributes in ntfs_attr_make_non_resident().
+ - Add BUG() checks to ntfs_attr_make_non_resident() and ntfs_attr_set()
+ to ensure that these functions are never called for compressed or
+ encrypted attributes.
+ - Fix cluster (de)allocators to work when the runlist is NULL and more
+ importantly to take a locked runlist rather than them locking it
+ which leads to lock reversal.
+ - Truncate {a,c,m}time to the ntfs supported time granularity when
+ updating the times in the inode in ntfs_setattr().
+ - Fixup handling of sparse, compressed, and encrypted attributes in
+ fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
+ fs/ntfs/aops.c::ntfs_{read,write}page().
+ - Make ntfs_write_block() not instantiate sparse blocks if they contain
+ only zeroes.
+ - Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
+ lock protection over the buffer submission for i/o which allows the
+ removal of the get_bh()/put_bh() pairs for each buffer.
+ - Fix fs/ntfs/aops.c::ntfs_{read,write}_block() to handle the case
+ where a concurrent truncate has truncated the runlist under our feet.
+ - Fix page_has_buffers()/page_buffers() handling in fs/ntfs/aops.c.
+ - In fs/ntfs/aops.c::ntfs_end_buffer_async_read(), use a bit spin lock
+ in the first buffer head instead of a driver global spin lock to
+ improve scalability.
+ - Minor fix to error handling and error message display in
+ fs/ntfs/aops.c::ntfs_prepare_nonresident_write().
+
2.1.23 - Implement extension of resident files and make writing safe as well as
many bug fixes, cleanups, and enhancements...
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index f083f27d8b6..894b2b876d3 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 \
index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
unistr.o upcase.o
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 78adad7a988..545236414d5 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -55,9 +55,8 @@
*/
static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
{
- static DEFINE_SPINLOCK(page_uptodate_lock);
unsigned long flags;
- struct buffer_head *tmp;
+ struct buffer_head *first, *tmp;
struct page *page;
ntfs_inode *ni;
int page_uptodate = 1;
@@ -89,11 +88,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
}
} else {
clear_buffer_uptodate(bh);
+ SetPageError(page);
ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.",
(unsigned long long)bh->b_blocknr);
- SetPageError(page);
}
- spin_lock_irqsave(&page_uptodate_lock, flags);
+ first = page_buffers(page);
+ local_irq_save(flags);
+ bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
clear_buffer_async_read(bh);
unlock_buffer(bh);
tmp = bh;
@@ -108,7 +109,8 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
}
tmp = tmp->b_this_page;
} while (tmp != bh);
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+ local_irq_restore(flags);
/*
* If none of the buffers had errors then we can set the page uptodate,
* 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)
unlock_page(page);
return;
still_busy:
- spin_unlock_irqrestore(&page_uptodate_lock, flags);
+ bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+ local_irq_restore(flags);
return;
}
@@ -185,13 +188,15 @@ static int ntfs_read_block(struct page *page)
blocksize_bits = VFS_I(ni)->i_blkbits;
blocksize = 1 << blocksize_bits;
- if (!page_has_buffers(page))
+ if (!page_has_buffers(page)) {
create_empty_buffers(page, blocksize, 0);
- bh = head = page_buffers(page);
- if (unlikely(!bh)) {
- unlock_page(page);
- return -ENOMEM;
+ if (unlikely(!page_has_buffers(page))) {
+ unlock_page(page);
+ return -ENOMEM;
+ }
}
+ bh = head = page_buffers(page);
+ BUG_ON(!bh);
iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
read_lock_irqsave(&ni->size_lock, flags);
@@ -204,6 +209,7 @@ static int ntfs_read_block(struct page *page)
nr = i = 0;
do {
u8 *kaddr;
+ int err;
if (unlikely(buffer_uptodate(bh)))
continue;
@@ -211,6 +217,7 @@ static int ntfs_read_block(struct page *page)
arr[nr++] = bh;
continue;
}
+ err = 0;
bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */
if (iblock < lblock) {
@@ -252,7 +259,6 @@ lock_retry_remap:
goto handle_hole;
/* If first try and runlist unmapped, map and retry. */
if (!is_retry && lcn == LCN_RL_NOT_MAPPED) {
- int err;
is_retry = TRUE;
/*
* Attempt to map runlist, dropping lock for
@@ -263,20 +269,30 @@ lock_retry_remap:
if (likely(!err))
goto lock_retry_remap;
rl = NULL;
- lcn = err;
} else if (!rl)
up_read(&ni->runlist.lock);
+ /*
+ * If buffer is outside the runlist, treat it as a
+ * hole. This can happen due to concurrent truncate
+ * for example.
+ */
+ if (err == -ENOENT || lcn == LCN_ENOENT) {
+ err = 0;
+ goto handle_hole;
+ }
/* Hard error, zero out region. */
+ if (!err)
+ err = -EIO;
bh->b_blocknr = -1;
SetPageError(page);
ntfs_error(vol->sb, "Failed to read from inode 0x%lx, "
"attribute type 0x%x, vcn 0x%llx, "
"offset 0x%x because its location on "
"disk could not be determined%s "
- "(error code %lli).", ni->mft_no,
+ "(error code %i).", ni->mft_no,
ni->type, (unsigned long long)vcn,
vcn_ofs, is_retry ? " even after "
- "retrying" : "", (long long)lcn);
+ "retrying" : "", err);
}
/*
* Either iblock was outside lblock limits or
@@ -289,9 +305,10 @@ handle_hole:
handle_zblock:
kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr + i * blocksize, 0, blocksize);
- flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
- set_buffer_uptodate(bh);
+ flush_dcache_page(page);
+ if (likely(!err))
+ set_buffer_uptodate(bh);
} while (i++, iblock++, (bh = bh->b_this_page) != head);
/* Release the lock if we took it. */
@@ -367,31 +384,38 @@ retry_readpage:
return 0;
}
ni = NTFS_I(page->mapping->host);
-
+ /*
+ * Only $DATA attributes can be encrypted and only unnamed $DATA
+ * attributes can be compressed. Index root can have the flags set but
+ * this means to create compressed/encrypted files, not that the
+ * attribute is compressed/encrypted.
+ */
+ if (ni->type != AT_INDEX_ROOT) {
+ /* If attribute is encrypted, deny access, just like NT4. */
+ if (NInoEncrypted(ni)) {
+ BUG_ON(ni->type != AT_DATA);
+ err = -EACCES;
+ goto err_out;
+ }
+ /* Compressed data streams are handled in compress.c. */
+ if (NInoNonResident(ni) && NInoCompressed(ni)) {
+ BUG_ON(ni->type != AT_DATA);
+ BUG_ON(ni->name_len);
+ return ntfs_read_compressed_block(page);
+ }
+ }
/* NInoNonResident() == NInoIndexAllocPresent() */
if (NInoNonResident(ni)) {
- /*
- * Only unnamed $DATA attributes can be compressed or
- * encrypted.
- */
- if (ni->type == AT_DATA && !ni->name_len) {
- /* If file is encrypted, deny access, just like NT4. */
- if (NInoEncrypted(ni)) {
- err = -EACCES;
- goto err_out;
- }
- /* Compressed data streams are handled in compress.c. */
- if (NInoCompressed(ni))
- return ntfs_read_compressed_block(page);
- }
- /* Normal data stream. */
+ /* Normal, non-resident data stream. */
return ntfs_read_block(page);
}
/*
* Attribute is resident, implying it is not compressed or encrypted.
* This also means the attribute is smaller than an mft record and
* hence smaller than a page, so can simply zero out any pages with
- * index above 0.
+ * index above 0. Note the attribute can actually be marked compressed
+ * but if it is resident the actual data is not compressed so we are
+ * ok to ignore the compressed flag here.
*/
if (unlikely(page->index > 0)) {
kaddr = kmap_atomic(page, KM_USER0);
@@ -511,19 +535,21 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
BUG_ON(!PageUptodate(page));
create_empty_buffers(page, blocksize,
(1 << BH_Uptodate) | (1 << BH_Dirty));
+ if (unlikely(!page_has_buffers(page))) {
+ ntfs_warning(vol->sb, "Error allocating page "
+ "buffers. Redirtying page so we try "
+ "again later.");
+ /*
+ * Put the page back on mapping->dirty_pages, but leave
+ * its buffers' dirty state as-is.
+ */
+ redirty_page_for_writepage(wbc, page);
+ unlock_page(page);
+ return 0;
+ }
}
bh = head = page_buffers(page);
- if (unlikely(!bh)) {
- ntfs_warning(vol->sb, "Error allocating page buffers. "
- "Redirtying page so we try again later.");
- /*
- * Put the page back on mapping->dirty_pages, but leave its
- * buffer's dirty state as-is.
- */
- redirty_page_for_writepage(wbc, page);
- unlock_page(page);
- return 0;
- }
+ BUG_ON(!bh);
/* NOTE: Different naming scheme to ntfs_read_block()! */
@@ -670,6 +696,27 @@ lock_retry_remap:
}
/* It is a hole, need to instantiate it. */
if (lcn == LCN_HOLE) {
+ u8 *kaddr;
+ unsigned long *bpos, *bend;
+
+ /* Check if the buffer is zero. */
+ kaddr = kmap_atomic(page, KM_USER0);
+ bpos = (unsigned long *)(kaddr + bh_offset(bh));
+ bend = (unsigned long *)((u8*)bpos + blocksize);
+ do {
+ if (unlikely(*bpos))
+ break;
+ } while (likely(++bpos < bend));
+ kunmap_atomic(kaddr, KM_USER0);
+ if (bpos == bend) {
+ /*
+ * Buffer is zero and sparse, no need to write
+ * it.
+ */
+ bh->b_blocknr = -1;
+ clear_buffer_dirty(bh);
+ continue;
+ }
// TODO: Instantiate the hole.
// clear_buffer_new(bh);
// unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
@@ -690,20 +737,37 @@ lock_retry_remap:
if (likely(!err))
goto lock_retry_remap;
rl = NULL;
- lcn = err;
} else if (!rl)
up_read(&ni->runlist.lock);
+ /*
+ * If buffer is outside the runlist, truncate has cut it out
+ * of the runlist. Just clean and clear the buffer and set it
+ * uptodate so it can get discarded by the VM.
+ */
+ if (err == -ENOENT || lcn == LCN_ENOENT) {
+ u8 *kaddr;
+
+ bh->b_blocknr = -1;
+ clear_buffer_dirty(bh);
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0, blocksize);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ set_buffer_uptodate(bh);
+ err = 0;
+ continue;
+ }
/* Failed to map the buffer, even after retrying. */
+ if (!err)
+ err = -EIO;
bh->b_blocknr = -1;
ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
"attribute type 0x%x, vcn 0x%llx, offset 0x%x "
"because its location on disk could not be "
- "determined%s (error code %lli).", ni->mft_no,
+ "determined%s (error code %i).", ni->mft_no,
ni->type, (unsigned long long)vcn,
vcn_ofs, is_retry ? " even after "
- "retrying" : "", (long long)lcn);
- if (!err)
- err = -EIO;
+ "retrying" : "", err);
break;
} while (block++, (bh = bh->b_this_page) != head);
@@ -714,7 +778,7 @@ lock_retry_remap:
/* For the error case, need to reset bh to the beginning. */
bh = head;
- /* Just an optimization, so ->readpage() isn't called later. */
+ /* Just an optimization, so ->readpage() is not called later. */
if (unlikely(!PageUptodate(page))) {
int uptodate = 1;
do {
@@ -730,7 +794,6 @@ lock_retry_remap:
/* Setup all mapped, dirty buffers for async write i/o. */
do {
- get_bh(bh);
if (buffer_mapped(bh) && buffer_dirty(bh)) {
lock_buffer(bh);
if (test_clear_buffer_dirty(bh)) {
@@ -768,14 +831,8 @@ lock_retry_remap:
BUG_ON(PageWriteback(page));
set_page_writeback(page); /* Keeps try_to_free_buffers() away. */
- unlock_page(page);
- /*
- * Submit the prepared buffers for i/o. Note the page is unlocked,
- * and the async write i/o completion handler can end_page_writeback()
- * at any time after the *first* submit_bh(). So the buffers can then
- * disappear...
- */
+ /* Submit the prepared buffers for i/o. */
need_end_writeback = TRUE;
do {
struct buffer_head *next = bh->b_this_page;
@@ -783,9 +840,9 @@ lock_retry_remap:
submit_bh(WRITE, bh);
need_end_writeback = FALSE;
}
- put_bh(bh);
bh = next;
} while (bh != head);
+ unlock_page(page);
/* If no i/o was started, need to end_page_writeback(). */
if (unlikely(need_end_writeback))
@@ -860,7 +917,6 @@ static int ntfs_write_mst_block(struct page *page,
sync = (wbc->sync_mode == WB_SYNC_ALL);
/* Make sure we have mapped buffers. */
- BUG_ON(!page_has_buffers(page));
bh = head = page_buffers(page);
BUG_ON(!bh);
@@ -1280,38 +1336,42 @@ retry_writepage:
ntfs_debug("Write outside i_size - truncated?");
return 0;
}
+ /*
+ * Only $DATA attributes can be encrypted and only unnamed $DATA
+ * attributes can be compressed. Index root can have the flags set but
+ * this means to create compressed/encrypted files, not that the
+ * attribute is compressed/encrypted.
+ */
+ if (ni->type != AT_INDEX_ROOT) {
+ /* If file is encrypted, deny access, just like NT4. */
+ if (NInoEncrypted(ni)) {
+ unlock_page(page);
+ BUG_ON(ni->type != AT_DATA);
+ ntfs_debug("Denying write access to encrypted "
+ "file.");
+ return -EACCES;
+ }
+ /* Compressed data streams are handled in compress.c. */
+ if (NInoNonResident(ni) && NInoCompressed(ni)) {
+ BUG_ON(ni->type != AT_DATA);
+ BUG_ON(ni->name_len);
+ // TODO: Implement and replace this with
+ // return ntfs_write_compressed_block(page);
+ unlock_page(page);
+ ntfs_error(vi->i_sb, "Writing to compressed files is "
+ "not supported yet. Sorry.");
+ return -EOPNOTSUPP;
+ }
+ // TODO: Implement and remove this check.
+ if (NInoNonResident(ni) && NInoSparse(ni)) {
+ unlock_page(page);
+ ntfs_error(vi->i_sb, "Writing to sparse files is not "
+ "supported yet. Sorry.");
+ return -EOPNOTSUPP;
+ }
+ }
/* NInoNonResident() == NInoIndexAllocPresent() */
if (NInoNonResident(ni)) {
- /*
- * Only unnamed $DATA attributes can be compressed, encrypted,
- * and/or sparse.
- */
- if (ni->type == AT_DATA && !ni->name_len) {
- /* If file is encrypted, deny access, just like NT4. */
- if (NInoEncrypted(ni)) {
- unlock_page(page);
- ntfs_debug("Denying write access to encrypted "
- "file.");
- return -EACCES;
- }
- /* Compressed data streams are handled in compress.c. */
- if (NInoCompressed(ni)) {
- // TODO: Implement and replace this check with
- // return ntfs_write_compressed_block(page);
- unlock_page(page);
- ntfs_error(vi->i_sb, "Writing to compressed "
- "files is not supported yet. "
- "Sorry.");
- return -EOPNOTSUPP;
- }
- // TODO: Implement and remove this check.
- if (NInoSparse(ni)) {
- unlock_page(page);
- ntfs_error(vi->i_sb, "Writing to sparse files "
- "is not supported yet. Sorry.");
- return -EOPNOTSUPP;
- }
- }
/* We have to zero every time due to mmap-at-end-of-file. */
if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) {
/* The page straddles i_size. */
@@ -1324,14 +1384,16 @@ retry_writepage:
/* Handle mst protected attributes. */
if (NInoMstProtected(ni))
return ntfs_write_mst_block(page, wbc);
- /* Normal data stream. */
+ /* Normal, non-resident data stream. */
return ntfs_write_block(page, wbc);
}
/*
- * Attribute is resident, implying it is not compressed, encrypted,
- * sparse, or mst protected. This also means the attribute is smaller
- * than an mft record and hence smaller than a page, so can simply
- * return error on any pages with index above 0.
+ * Attribute is resident, implying it is not compressed, encrypted, or
+ * mst protected. This also means the attribute is smaller than an mft
+ * record and hence smaller than a page, so can simply return error on
+ * any pages with index above 0. Note the attribute can actually be
+ * marked compressed but if it is resident the actual data is not
+ * compressed so we are ok to ignore the compressed flag here.
*/
BUG_ON(page_has_buffers(page));
BUG_ON(!PageUptodate(page));
@@ -1380,30 +1442,14 @@ retry_writepage:
BUG_ON(PageWriteback(page));
set_page_writeback(page);
unlock_page(page);
-
/*
- * Here, we don't need to zero the out of bounds area everytime because
- * the below memcpy() already takes care of the mmap-at-end-of-file
- * requirements. If the file is converted to a non-resident one, then
- * the code path use is switched to the non-resident one where the
- * zeroing happens on each ntfs_writepage() invocation.
- *
- * The above also applies nicely when i_size is decreased.
- *
- * When i_size is increased, the memory between the old and new i_size
- * _must_ be zeroed (or overwritten with new data). Otherwise we will
- * expose data to userspace/disk which should never have been exposed.
- *
- * FIXME: Ensure that i_size increases do the zeroing/overwriting and
- * if we cannot guarantee that, then enable the zeroing below. If the
- * zeroing below is enabled, we MUST move the unlock_page() from above
- * to after the kunmap_atomic(), i.e. just before the
- * end_page_writeback().
- * UPDATE: ntfs_prepare/commit_write() do the zeroing on i_size
- * increases for resident attributes so those are ok.
- * TODO: ntfs_truncate(), others?
+ * Here, we do not need to zero the out of bounds area everytime
+ * because the below memcpy() already takes care of the
+ * mmap-at-end-of-file requirements. If the file is converted to a
+ * non-resident one, then the code path use is switched to the
+ * non-resident one where the zeroing happens on each ntfs_writepage()
+ * invocation.
*/
-
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
i_size = i_size_read(vi);
if (unlikely(attr_len > i_size)) {
@@ -1681,27 +1727,25 @@ lock_retry_remap:
if (likely(!err))
goto lock_retry_remap;
rl = NULL;
- lcn = err;
} else if (!rl)
up_read(&ni->runlist.lock);
/*
* Failed to map the buffer, even after
* retrying.
*/
+ if (!err)
+ err = -EIO;
bh->b_blocknr = -1;
ntfs_error(vol->sb, "Failed to write to inode "
"0x%lx, attribute type 0x%x, "
"vcn 0x%llx, offset 0x%x "
"because its location on disk "
"could not be determined%s "
- "(error code %lli).",
+ "(error code %i).",
ni->mft_no, ni->type,
(unsigned long long)vcn,
vcn_ofs, is_retry ? " even "
- "after retrying" : "",
- (long long)lcn);
- if (!err)
- err = -EIO;
+ "after retrying" : "", err);
goto err_out;
}
/* 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) {
buffers_to_free = bh;
}
bh = head = page_buffers(page);
+ BUG_ON(!bh);
do {
bh_ofs = bh_offset(bh);
if (bh_ofs + bh_size <= ofs)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index cd0f9e740b1..3f9a4ff42ee 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -43,6 +43,9 @@
* which is not an error as such. This is -ENOENT. It means that @vcn is out
* of bounds of the runlist.
*
+ * Note the runlist can be NULL after this function returns if @vcn is zero and
+ * the attribute has zero allocated size, i.e. there simply is no runlist.
+ *
* Locking: - The runlist must be locked for writing.
* - This function modifies the runlist.
*/
@@ -54,6 +57,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
ATTR_RECORD *a;
ntfs_attr_search_ctx *ctx;
runlist_element *rl;
+ unsigned long flags;
int err = 0;
ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
@@ -85,8 +89,11 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
* ntfs_mapping_pairs_decompress() fails.
*/
end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
- if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
+ if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
+ read_lock_irqsave(&ni->size_lock, flags);
end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ }
if (unlikely(vcn >= end_vcn)) {
err = -ENOENT;
goto err_out;
@@ -165,6 +172,7 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
const BOOL write_locked)
{
LCN lcn;
+ unsigned long flags;
BOOL is_retry = FALSE;
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,
BUG_ON(!ni);
BUG_ON(!NInoNonResident(ni));
BUG_ON(vcn < 0);
+ if (!ni->runlist.rl) {
+ read_lock_irqsave(&ni->size_lock, flags);
+ if (!ni->allocated_size) {
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ return LCN_ENOENT;
+ }
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ }
retry_remap:
/* Convert vcn to lcn. If that fails map the runlist and retry once. */
lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
@@ -255,6 +271,7 @@ retry_remap:
runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
const BOOL write_locked)
{
+ unsigned long flags;
runlist_element *rl;
int err = 0;
BOOL is_retry = FALSE;
@@ -265,6 +282,14 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
BUG_ON(!ni);
BUG_ON(!NInoNonResident(ni));
BUG_ON(vcn < 0);
+ if (!ni->runlist.rl) {
+ read_lock_irqsave(&ni->size_lock, flags);
+ if (!ni->allocated_size) {
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ return ERR_PTR(-ENOENT);
+ }
+ read_unlock_irqrestore(&ni->size_lock, flags);
+ }
retry_remap:
rl = ni->runlist.rl;
if (likely(rl && vcn >= rl[0].vcn)) {
@@ -528,6 +553,11 @@ int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
block_size_bits = sb->s_blocksize_bits;
down_read(&runlist->lock);
rl = runlist->rl;
+ if (!rl) {
+ ntfs_error(sb, "Cannot read attribute list since runlist is "
+ "missing.");
+ goto err_out;
+ }
/* Read all clusters specified by the runlist one run at a time. */
while (rl->length) {
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)
}
/**
+ * ntfs_resident_attr_value_resize - resize the value of a resident attribute
+ * @m: mft record containing attribute record
+ * @a: attribute record whose value to resize
+ * @new_size: new size in bytes to which to resize the attribute value of @a
+ *
+ * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
+ * If the value is made bigger, the newly allocated space is cleared.
+ *
+ * Return 0 on success and -errno on error. The following error codes are
+ * defined:
+ * -ENOSPC - Not enough space in the mft record @m to perform the resize.
+ *
+ * Note: On error, no modifications have been performed whatsoever.
+ *
+ * Warning: If you make a record smaller without having copied all the data you
+ * are interested in the data may be overwritten.
+ */
+int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+ const u32 new_size)
+{
+ u32 old_size;
+
+ /* Resize the resident part of the attribute record. */
+ if (ntfs_attr_record_resize(m, a,
+ le16_to_cpu(a->data.resident.value_offset) + new_size))
+ return -ENOSPC;
+ /*
+ * The resize succeeded! If we made the attribute value bigger, clear
+ * the area between the old size and @new_size.
+ */
+ old_size = le32_to_cpu(a->data.resident.value_length);
+ if (new_size > old_size)
+ memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
+ old_size, 0, new_size - old_size);
+ /* Finally update the length of the attribute value. */
+ a->data.resident.value_length = cpu_to_le32(new_size);
+ return 0;
+}
+
+/**
* ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
* @ni: ntfs inode describing the attribute to convert
*
@@ -1302,6 +1372,12 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
return err;
}
/*
+ * FIXME: Compressed and encrypted attributes are not supported when
+ * writing and we should never have gotten here for them.
+ */
+ BUG_ON(NInoCompressed(ni));
+ BUG_ON(NInoEncrypted(ni));
+ /*
* The size needs to be aligned to a cluster boundary for allocation
* purposes.
*/
@@ -1377,10 +1453,15 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
BUG_ON(a->non_resident);
/*
* Calculate new offsets for the name and the mapping pairs array.
- * We assume the attribute is not compressed or sparse.
*/
- name_ofs = (offsetof(ATTR_REC,
- data.non_resident.compressed_size) + 7) & ~7;
+ if (NInoSparse(ni) || NInoCompressed(ni))
+ name_ofs = (offsetof(ATTR_REC,
+ data.non_resident.compressed_size) +
+ sizeof(a->data.non_resident.compressed_size) +
+ 7) & ~7;
+ else
+ name_ofs = (offsetof(ATTR_REC,
+ data.non_resident.compressed_size) + 7) & ~7;
mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
/*
* 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)
memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
a->name_length * sizeof(ntfschar));
a->name_offset = cpu_to_le16(name_ofs);
- /*
- * FIXME: For now just clear all of these as we do not support them
- * when writing.
- */
- a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
- ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
/* Setup the fields specific to non-resident attributes. */
a->data.non_resident.lowest_vcn = 0;
a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
vol->cluster_size_bits);
a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
- a->data.non_resident.compression_unit = 0;
memset(&a->data.non_resident.reserved, 0,
sizeof(a->data.non_resident.reserved));
a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
a->data.non_resident.data_size =
a->data.non_resident.initialized_size =
cpu_to_sle64(attr_size);
+ if (NInoSparse(ni) || NInoCompressed(ni)) {
+ a->data.non_resident.compression_unit = 4;
+ a->data.non_resident.compressed_size =
+ a->data.non_resident.allocated_size;
+ } else
+ a->data.non_resident.compression_unit = 0;
/* Generate the mapping pairs array into the attribute record. */
err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
arec_size - mp_ofs, rl, 0, -1, NULL);
@@ -1446,16 +1526,19 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
goto undo_err_out;
}
/* Setup the in-memory attribute structure to be non-resident. */
- /*
- * FIXME: For now just clear all of these as we do not support them
- * when writing.
- */
- NInoClearSparse(ni);
- NInoClearEncrypted(ni);
- NInoClearCompressed(ni);
ni->runlist.rl = rl;
write_lock_irqsave(&ni->size_lock, flags);
ni->allocated_size = new_size;
+ if (NInoSparse(ni) || NInoCompressed(ni)) {
+ ni->itype.compressed.size = ni->allocated_size;
+ ni->itype.compressed.block_size = 1U <<
+ (a->data.non_resident.compression_unit +
+ vol->cluster_size_bits);
+ ni->itype.compressed.block_size_bits =
+ ffs(ni->itype.compressed.block_size) - 1;
+ ni->itype.compressed.block_clusters = 1U <<
+ a->data.non_resident.compression_unit;
+ }
write_unlock_irqrestore(&ni->size_lock, flags);
/*
* 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)
BUG_ON(cnt < 0);
if (!cnt)
goto done;
+ /*
+ * FIXME: Compressed and encrypted attributes are not supported when
+ * writing and we should never have gotten here for them.
+ */
+ BUG_ON(NInoCompressed(ni));
+ BUG_ON(NInoEncrypted(ni));
mapping = VFS_I(ni)->i_mapping;
/* Work out the starting index and page offset. */
idx = ofs >> PAGE_CACHE_SHIFT;
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
index 0e4ac6d3c0e..0618ed6fd7b 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,
const ATTR_TYPE type);
extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
+extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
+ const u32 new_size);
extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index 6d265cfd49a..25d24106f89 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -539,7 +539,6 @@ int ntfs_read_compressed_block(struct page *page)
if (unlikely(!pages || !bhs)) {
kfree(bhs);
kfree(pages);
- SetPageError(page);
unlock_page(page);
ntfs_error(vol->sb, "Failed to allocate internal buffers.");
return -ENOMEM;
@@ -871,9 +870,6 @@ lock_retry_remap:
for (; prev_cur_page < cur_page; prev_cur_page++) {
page = pages[prev_cur_page];
if (page) {
- if (prev_cur_page == xpage &&
- !xpage_done)
- SetPageError(page);
flush_dcache_page(page);
kunmap(page);
unlock_page(page);
@@ -904,8 +900,6 @@ lock_retry_remap:
"Terminating them with extreme "
"prejudice. Inode 0x%lx, page index "
"0x%lx.", ni->mft_no, page->index);
- if (cur_page == xpage && !xpage_done)
- SetPageError(page);
flush_dcache_page(page);
kunmap(page);
unlock_page(page);
@@ -953,8 +947,6 @@ err_out:
for (i = cur_page; i < max_page; i++) {
page = pages[i];
if (page) {
- if (i == xpage && !xpage_done)
- SetPageError(page);
flush_dcache_page(page);
kunmap(page);
unlock_page(page);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 46779471c54..795c3d1930f 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,
ie->key.file_name.file_name_length, &name,
NTFS_MAX_NAME_LEN * NLS_MAX_CHARSET_SIZE + 1);
if (name_len <= 0) {
- ntfs_debug("Skipping unrepresentable file.");
+ ntfs_warning(vol->sb, "Skipping unrepresentable inode 0x%llx.",
+ (long long)MREF_LE(ie->data.dir.indexed_file));
return 0;
}
if (ie->key.file_name.file_attributes &
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index e0f530ce6b9..be9fd1dd423 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1,7 +1,7 @@
/*
- * file.c - NTFS kernel file operations. Part of the Linux-NTFS project.
+ * file.c - NTFS kernel file operations. Part of the Linux-NTFS project.
*
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* 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,
if (!datasync || !NInoNonResident(NTFS_I(vi)))
ret = ntfs_write_inode(vi, 1);
write_inode_now(vi, !datasync);
+ /*
+ * NOTE: If we were to use mapping->private_list (see ext2 and
+ * fs/buffer.c) for dirty blocks then we could optimize the below to be
+ * sync_mapping_buffers(vi->i_mapping).
+ */
err = sync_blockdev(vi->i_sb->s_bdev);
if (unlikely(err && !ret))
ret = err;
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 11fd5307d78..8f2d5727546 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,
&ie->key, key_len)) {
ir_done:
ictx->is_in_root = TRUE;
+ ictx->ir = ir;
ictx->actx = actx;
ictx->base_ni = base_ni;
ictx->ia = NULL;
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 886214a77f9..dc4bbe3acf5 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1013,41 +1013,50 @@ skip_large_dir_stuff:
}
a = ctx->attr;
/* Setup the state. */
- if (a->non_resident) {
- NInoSetNonResident(ni);
- if (a->flags & (ATTR_COMPRESSION_MASK |
- ATTR_IS_SPARSE)) {
- if (a->flags & ATTR_COMPRESSION_MASK) {
- NInoSetCompressed(ni);
- if (vol->cluster_size > 4096) {
- ntfs_error(vi->i_sb, "Found "
+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
+ if (a->flags & ATTR_COMPRESSION_MASK) {
+ NInoSetCompressed(ni);
+ if (vol->cluster_size > 4096) {
+ ntfs_error(vi->i_sb, "Found "
"compressed data but "
"compression is "
"disabled due to "
"cluster size (%i) > "
"4kiB.",
vol->cluster_size);
- goto unm_err_out;
- }
- if ((a->flags & ATTR_COMPRESSION_MASK)
- != ATTR_IS_COMPRESSED) {
- ntfs_error(vi->i_sb, "Found "
- "unknown compression "
- "method or corrupt "
- "file.");
- goto unm_err_out;
- }
+ goto unm_err_out;
+ }
+ if ((a->flags & ATTR_COMPRESSION_MASK)
+ != ATTR_IS_COMPRESSED) {
+ ntfs_error(vi->i_sb, "Found unknown "
+ "compression method "
+ "or corrupt file.");
+ goto unm_err_out;
}
- if (a->flags & ATTR_IS_SPARSE)
- NInoSetSparse(ni);
+ }
+ if (a->flags & ATTR_IS_SPARSE)
+ NInoSetSparse(ni);
+ }
+ if (a->flags & ATTR_IS_ENCRYPTED) {
+ if (NInoCompressed(ni)) {
+ ntfs_error(vi->i_sb, "Found encrypted and "
+ "compressed data.");
+ goto unm_err_out;
+ }
+ NInoSetEncrypted(ni);
+ }
+ if (a->non_resident) {
+ NInoSetNonResident(ni);
+ if (NInoCompressed(ni) || NInoSparse(ni)) {
if (a->data.non_resident.compression_unit !=
4) {
ntfs_error(vi->i_sb, "Found "
- "nonstandard compression unit "
- "(%u instead of 4). Cannot "
- "handle this.",
- a->data.non_resident.
- compression_unit);
+ "nonstandard "
+ "compression unit (%u "
+ "instead of 4). "
+ "Cannot handle this.",
+ a->data.non_resident.
+ compression_unit);
err = -EOPNOTSUPP;
goto unm_err_out;
}
@@ -1065,14 +1074,6 @@ skip_large_dir_stuff:
a->data.non_resident.
compressed_size);
}
- if (a->flags & ATTR_IS_ENCRYPTED) {
- if (a->flags & ATTR_COMPRESSION_MASK) {
- ntfs_error(vi->i_sb, "Found encrypted "
- "and compressed data.");
- goto unm_err_out;
- }
- NInoSetEncrypted(ni);
- }
if (a->data.non_resident.lowest_vcn) {
ntfs_error(vi->i_sb, "First extent of $DATA "
"attribute has non zero "
@@ -1212,6 +1213,75 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
if (unlikely(err))
goto unm_err_out;
a = ctx->attr;
+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
+ if (a->flags & ATTR_COMPRESSION_MASK) {
+ NInoSetCompressed(ni);
+ if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&
+ ni->name_len)) {
+ ntfs_error(vi->i_sb, "Found compressed "
+ "non-data or named data "
+ "attribute. Please report "
+ "you saw this message to "
+ "linux-ntfs-dev@lists."
+ "sourceforge.net");
+ goto unm_err_out;
+ }
+ if (vol->cluster_size > 4096) {
+ ntfs_error(vi->i_sb, "Found compressed "
+ "attribute but compression is "
+ "disabled due to cluster size "
+ "(%i) > 4kiB.",
+ vol->cluster_size);
+ goto unm_err_out;
+ }
+ if ((a->flags & ATTR_COMPRESSION_MASK) !=
+ ATTR_IS_COMPRESSED) {
+ ntfs_error(vi->i_sb, "Found unknown "
+ "compression method.");
+ goto unm_err_out;
+ }
+ }
+ /*
+ * The encryption flag set in an index root just means to
+ * compress all files.
+ */
+ if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
+ ntfs_error(vi->i_sb, "Found mst protected attribute "
+ "but the attribute is %s. Please "
+ "report you saw this message to "
+ "linux-ntfs-dev@lists.sourceforge.net",
+ NInoCompressed(ni) ? "compressed" :
+ "sparse");
+ goto unm_err_out;
+ }
+ if (a->flags & ATTR_IS_SPARSE)
+ NInoSetSparse(ni);
+ }
+ if (a->flags & ATTR_IS_ENCRYPTED) {
+ if (NInoCompressed(ni)) {
+ ntfs_error(vi->i_sb, "Found encrypted and compressed "
+ "data.");
+ goto unm_err_out;
+ }
+ /*
+ * The encryption flag set in an index root just means to
+ * encrypt all files.
+ */
+ if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {
+ ntfs_error(vi->i_sb, "Found mst protected attribute "
+ "but the attribute is encrypted. "
+ "Please report you saw this message "
+ "to linux-ntfs-dev@lists.sourceforge."
+ "net");
+ goto unm_err_out;
+ }
+ if (ni->type != AT_DATA) {
+ ntfs_error(vi->i_sb, "Found encrypted non-data "
+ "attribute.");
+ goto unm_err_out;
+ }
+ NInoSetEncrypted(ni);
+ }
if (!a->non_resident) {
/* Ensure the attribute name is placed before the value. */
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)
"the attribute value.");
goto unm_err_out;
}
- if (NInoMstProtected(ni) || a->flags) {
+ if (NInoMstProtected(ni)) {
ntfs_error(vi->i_sb, "Found mst protected attribute "
- "or attribute with non-zero flags but "
- "the attribute is resident. Please "
- "report you saw this message to "
+ "but the attribute is resident. "
+ "Please report you saw this message to "
"linux-ntfs-dev@lists.sourceforge.net");
goto unm_err_out;
}
@@ -1250,50 +1319,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"the mapping pairs array.");
goto unm_err_out;
}
- if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
- if (a->flags & ATTR_COMPRESSION_MASK) {
- NInoSetCompressed(ni);
- if ((ni->type != AT_DATA) || (ni->type ==
- AT_DATA && ni->name_len)) {
- ntfs_error(vi->i_sb, "Found compressed "
- "non-data or named "
- "data attribute. "
- "Please report you "
- "saw this message to "
- "linux-ntfs-dev@lists."
- "sourceforge.net");
- goto unm_err_out;
- }
- if (vol->cluster_size > 4096) {
- ntfs_error(vi->i_sb, "Found compressed "
- "attribute but "
- "compression is "
- "disabled due to "
- "cluster size (%i) > "
- "4kiB.",
- vol->cluster_size);
- goto unm_err_out;
- }
- if ((a->flags & ATTR_COMPRESSION_MASK) !=
- ATTR_IS_COMPRESSED) {
- ntfs_error(vi->i_sb, "Found unknown "
- "compression method.");
- goto unm_err_out;
- }
- }
- if (NInoMstProtected(ni)) {
- ntfs_error(vi->i_sb, "Found mst protected "
- "attribute but the attribute "
- "is %s. Please report you "
- "saw this message to "
- "linux-ntfs-dev@lists."
- "sourceforge.net",
- NInoCompressed(ni) ?
- "compressed" : "sparse");
- goto unm_err_out;
- }
- if (a->flags & ATTR_IS_SPARSE)
- NInoSetSparse(ni);
+ if ((NInoCompressed(ni) || NInoSparse(ni)) &&
+ ni->type != AT_INDEX_ROOT) {
if (a->data.non_resident.compression_unit != 4) {
ntfs_error(vi->i_sb, "Found nonstandard "
"compression unit (%u instead "
@@ -1313,23 +1340,6 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
ni->itype.compressed.size = sle64_to_cpu(
a->data.non_resident.compressed_size);
}
- if (a->flags & ATTR_IS_ENCRYPTED) {
- if (a->flags & ATTR_COMPRESSION_MASK) {
- ntfs_error(vi->i_sb, "Found encrypted and "
- "compressed data.");
- goto unm_err_out;
- }
- if (NInoMstProtected(ni)) {
- ntfs_error(vi->i_sb, "Found mst protected "
- "attribute but the attribute "
- "is encrypted. Please report "
- "you saw this message to "
- "linux-ntfs-dev@lists."
- "sourceforge.net");
- goto unm_err_out;
- }
- NInoSetEncrypted(ni);
- }
if (a->data.non_resident.lowest_vcn) {
ntfs_error(vi->i_sb, "First extent of attribute has "
"non-zero lowest_vcn.");
@@ -1348,12 +1358,12 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
vi->i_mapping->a_ops = &ntfs_mst_aops;
else
vi->i_mapping->a_ops = &ntfs_aops;
- if (NInoCompressed(ni) || NInoSparse(ni))
+ if ((NInoCompressed(ni) || NInoSparse(ni)) && ni->type != AT_INDEX_ROOT)
vi->i_blocks = ni->itype.compressed.size >> 9;
else
vi->i_blocks = ni->allocated_size >> 9;
/*
- * Make sure the base inode doesn't go away and attach it to the
+ * Make sure the base inode does not go away and attach it to the
* attribute inode.
*/
igrab(base_vi);
@@ -1480,7 +1490,10 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
"after the attribute value.");
goto unm_err_out;
}
- /* Compressed/encrypted/sparse index root is not allowed. */
+ /*
+ * Compressed/encrypted/sparse index root is not allowed, except for
+ * directories of course but those are not dealt with here.
+ */
if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
ATTR_IS_SPARSE)) {
ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "
@@ -2430,16 +2443,18 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
* We skipped the truncate but must still update
* timestamps.
*/
- ia_valid |= ATTR_MTIME|ATTR_CTIME;
+ ia_valid |= ATTR_MTIME | ATTR_CTIME;
}
}
-
if (ia_valid & ATTR_ATIME)
- vi->i_atime = attr->ia_atime;
+ vi->i_atime = timespec_trunc(attr->ia_atime,
+ vi->i_sb->s_time_gran);
if (ia_valid & ATTR_MTIME)
- vi->i_mtime = attr->ia_mtime;
+ vi->i_mtime = timespec_trunc(attr->ia_mtime,
+ vi->i_sb->s_time_gran);
if (ia_valid & ATTR_CTIME)
- vi->i_ctime = attr->ia_ctime;
+ vi->i_ctime = timespec_trunc(attr->ia_ctime,
+ vi->i_sb->s_time_gran);
mark_inode_dirty(vi);
out:
return err;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index a4bc07616e5..7b593429068 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,
int ret = 0;
ntfs_debug("Entering.");
+ if (!rl)
+ return 0;
for (; rl->length; rl++) {
int err;
@@ -163,17 +165,9 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
BUG_ON(zone < FIRST_ZONE);
BUG_ON(zone > LAST_ZONE);
- /* Return empty runlist if @count == 0 */
- // FIXME: Do we want to just return NULL instead? (AIA)
- if (!count) {
- rl = ntfs_malloc_nofs(PAGE_SIZE);
- if (!rl)
- return ERR_PTR(-ENOMEM);
- rl[0].vcn = start_vcn;
- rl[0].lcn = LCN_RL_NOT_MAPPED;
- rl[0].length = 0;
- return rl;
- }
+ /* Return NULL if @count is zero. */
+ if (!count)
+ return NULL;
/* Take the lcnbmp lock for writing. */
down_write(&vol->lcnbmp_lock);
/*
@@ -788,7 +782,8 @@ out:
* @vi: vfs inode whose runlist describes the clusters to free
* @start_vcn: vcn in the runlist of @vi at which to start freeing clusters
* @count: number of clusters to free or -1 for all clusters
- * @is_rollback: if TRUE this is a rollback operation
+ * @write_locked: true if the runlist is locked for writing
+ * @is_rollback: true if this is a rollback operation
*
* Free @count clusters starting at the cluster @start_vcn in the runlist
* described by the vfs inode @vi.
@@ -806,17 +801,17 @@ out:
* Return the number of deallocated clusters (not counting sparse ones) on
* success and -errno on error.
*
- * Locking: - The runlist described by @vi must be unlocked on entry and is
- * unlocked on return.
- * - This function takes the runlist lock of @vi for reading and
- * sometimes for writing and sometimes modifies the runlist.
+ * Locking: - The runlist described by @vi must be locked on entry and is
+ * locked on return. Note if the runlist is locked for reading the
+ * lock may be dropped and reacquired. Note the runlist may be
+ * modified when needed runlist fragments need to be mapped.
* - The volume lcn bitmap must be unlocked on entry and is unlocked
* on return.
* - This function takes the volume lcn bitmap lock for writing and
* modifies the bitmap contents.
*/
s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
- const BOOL is_rollback)
+ const BOOL write_locked, const BOOL is_rollback)
{
s64 delta, to_free, total_freed, real_freed;
ntfs_inode *ni;
@@ -848,8 +843,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
total_freed = real_freed = 0;
- down_read(&ni->runlist.lock);
- rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);
+ rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, write_locked);
if (IS_ERR(rl)) {
if (!is_rollback)
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,
/* Attempt to map runlist. */
vcn = rl->vcn;
- rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE);
+ rl = ntfs_attr_find_vcn_nolock(ni, vcn, write_locked);
if (IS_ERR(rl)) {
err = PTR_ERR(rl);
if (!is_rollback)
@@ -950,7 +944,6 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
/* Update the total done clusters. */
total_freed += to_free;
}
- up_read(&ni->runlist.lock);
if (likely(!is_rollback))
up_write(&vol->lcnbmp_lock);
@@ -960,7 +953,6 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
ntfs_debug("Done.");
return real_freed;
err_out:
- up_read(&ni->runlist.lock);
if (is_rollback)
return err;
/* If no real clusters were freed, no need to rollback. */
@@ -973,7 +965,8 @@ err_out:
* If rollback fails, set the volume errors flag, emit an error
* message, and return the error code.
*/
- delta = __ntfs_cluster_free(vi, start_vcn, total_freed, TRUE);
+ delta = __ntfs_cluster_free(vi, start_vcn, total_freed, write_locked,
+ TRUE);
if (delta < 0) {
ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
"inconsistent metadata! Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index 4cac1c024af..e4d7fb98d68 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -43,13 +43,14 @@ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
const NTFS_CLUSTER_ALLOCATION_ZONES zone);
extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
- s64 count, const BOOL is_rollback);
+ s64 count, const BOOL write_locked, const BOOL is_rollback);
/**
* ntfs_cluster_free - free clusters on an ntfs volume
* @vi: vfs inode whose runlist describes the clusters to free
* @start_vcn: vcn in the runlist of @vi at which to start freeing clusters
* @count: number of clusters to free or -1 for all clusters
+ * @write_locked: true if the runlist is locked for writing
*
* Free @count clusters starting at the cluster @start_vcn in the runlist
* described by the vfs inode @vi.
@@ -64,19 +65,19 @@ extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
* Return the number of deallocated clusters (not counting sparse ones) on
* success and -errno on error.
*
- * Locking: - The runlist described by @vi must be unlocked on entry and is
- * unlocked on return.
- * - This function takes the runlist lock of @vi for reading and
- * sometimes for writing and sometimes modifies the runlist.
+ * Locking: - The runlist described by @vi must be locked on entry and is
+ * locked on return. Note if the runlist is locked for reading the
+ * lock may be dropped and reacquired. Note the runlist may be
+ * modified when needed runlist fragments need to be mapped.
* - The volume lcn bitmap must be unlocked on entry and is unlocked
* on return.
* - This function takes the volume lcn bitmap lock for writing and
* modifies the bitmap contents.
*/
static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn,
- s64 count)
+ s64 count, const BOOL write_locked)
{
- return __ntfs_cluster_free(vi, start_vcn, count, FALSE);
+ return __ntfs_cluster_free(vi, start_vcn, count, write_locked, FALSE);
}
extern 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,
*
* Return 0 on success and -errno on error.
*
- * Locking: This function takes the volume lcn bitmap lock for writing and
- * modifies the bitmap contents.
+ * Locking: - This function takes the volume lcn bitmap lock for writing and
+ * modifies the bitmap contents.
+ * - The caller must have locked the runlist @rl for reading or
+ * writing.
*/
static inline int ntfs_cluster_free_from_rl(ntfs_volume *vol,
const runlist_element *rl)
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 8edb8e20fb0..0173e95500d 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,
*/
if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
- "chkdsk but a chkdsk LSN is specified.");
+ "by chkdsk but a chkdsk LSN is specified.");
return FALSE;
}
ntfs_debug("Done.");
@@ -312,10 +312,12 @@ err_out:
* @vi: $LogFile inode to which the restart page belongs
* @rp: restart page to check
* @pos: position in @vi at which the restart page resides
- * @wrp: copy of the multi sector transfer deprotected restart page
+ * @wrp: [OUT] copy of the multi sector transfer deprotected restart page
+ * @lsn: [OUT] set to the current logfile lsn on success
*
- * Check the restart page @rp for consistency and return TRUE if it is
- * consistent and FALSE otherwise.
+ * Check the restart page @rp for consistency and return 0 if it is consistent
+ * and -errno otherwise. The restart page may have been modified by chkdsk in
+ * which case its magic is CHKD instead of RSTR.
*
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
* require the full restart page.
@@ -323,25 +325,33 @@ err_out:
* If @wrp is not NULL, on success, *@wrp will point to a buffer containing a
* copy of the complete multi sector transfer deprotected page. On failure,
* *@wrp is undefined.
+ *
+ * Simillarly, if @lsn is not NULL, on succes *@lsn will be set to the current
+ * logfile lsn according to this restart page. On failure, *@lsn is undefined.
+ *
+ * The following error codes are defined:
+ * -EINVAL - The restart page is inconsistent.
+ * -ENOMEM - Not enough memory to load the restart page.
+ * -EIO - Failed to reading from $LogFile.
*/
-static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
- RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp)
+static int ntfs_check_and_load_restart_page(struct inode *vi,
+ RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp,
+ LSN *lsn)
{
RESTART_AREA *ra;
RESTART_PAGE_HEADER *trp;
- int size;
- BOOL ret;
+ int size, err;
ntfs_debug("Entering.");
/* Check the restart page header for consistency. */
if (!ntfs_check_restart_page_header(vi, rp, pos)) {
/* Error output already done inside the function. */
- return FALSE;
+ return -EINVAL;
}
/* Check the restart area for consistency. */
if (!ntfs_check_restart_area(vi, rp)) {
/* Error output already done inside the function. */
- return FALSE;
+ return -EINVAL;
}
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
/*
@@ -352,7 +362,7 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
if (!trp) {
ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
"restart page buffer.");
- return FALSE;
+ return -ENOMEM;
}
/*
* 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,
if (IS_ERR(page)) {
ntfs_error(vi->i_sb, "Error mapping $LogFile "
"page (index %lu).", idx);
+ err = PTR_ERR(page);
+ if (err != -EIO && err != -ENOMEM)
+ err = -EIO;
goto err_out;
}
size = min_t(int, to_read, PAGE_CACHE_SIZE);
@@ -392,29 +405,57 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
/* Perform the multi sector transfer deprotection on the buffer. */
if (post_read_mst_fixup((NTFS_RECORD*)trp,
le32_to_cpu(rp->system_page_size))) {
- ntfs_error(vi->i_sb, "Multi sector transfer error detected in "
- "$LogFile restart page.");
- goto err_out;
+ /*
+ * A multi sector tranfer error was detected. We only need to
+ * abort if the restart page contents exceed the multi sector
+ * transfer fixup of the first sector.
+ */
+ if (le16_to_cpu(rp->restart_area_offset) +
+ le16_to_cpu(ra->restart_area_length) >
+ NTFS_BLOCK_SIZE - sizeof(u16)) {
+ ntfs_error(vi->i_sb, "Multi sector transfer error "
+ "detected in $LogFile restart page.");
+ err = -EINVAL;
+ goto err_out;
+ }
+ }
+ /*
+ * If the restart page is modified by chkdsk or there are no active
+ * logfile clients, the logfile is consistent. Otherwise, need to
+ * check the log client records for consistency, too.
+ */
+ err = 0;
+ if (ntfs_is_rstr_record(rp->magic) &&
+ ra->client_in_use_list != LOGFILE_NO_CLIENT) {
+ if (!ntfs_check_log_client_array(vi, trp)) {
+ err = -EINVAL;
+ goto err_out;
+ }
+ }
+ if (lsn) {
+ if (ntfs_is_rstr_record(rp->magic))
+ *lsn = sle64_to_cpu(ra->current_lsn);
+ else /* if (ntfs_is_chkd_record(rp->magic)) */
+ *lsn = sle64_to_cpu(rp->chkdsk_lsn);
}
- /* Check the log client records for consistency. */
- ret = ntfs_check_log_client_array(vi, trp);
- if (ret && wrp)
- *wrp = trp;
- else
- ntfs_free(trp);
ntfs_debug("Done.");
- return ret;
+ if (wrp)
+ *wrp = trp;
+ else {
err_out:
- ntfs_free(trp);
- return FALSE;
+ ntfs_free(trp);
+ }
+ return err;
}
/**
* ntfs_check_logfile - check the journal for consistency
* @log_vi: struct inode of loaded journal $LogFile to check
+ * @rp: [OUT] on success this is a copy of the current restart page
*
* Check the $LogFile journal for consistency and return TRUE if it is
- * consistent and FALSE if not.
+ * consistent and FALSE if not. On success, the current restart page is
+ * returned in *@rp. Caller must call ntfs_free(*@rp) when finished with it.
*
* At present we only check the two restart pages and ignore the log record
* pages.
@@ -424,19 +465,18 @@ err_out:
* if the $LogFile was created on a system with a different page size to ours
* yet and mst deprotection would fail if our page size is smaller.
*/
-BOOL ntfs_check_logfile(struct inode *log_vi)
+BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp)
{
- s64 size, pos, rstr1_pos, rstr2_pos;
+ s64 size, pos;
+ LSN rstr1_lsn, rstr2_lsn;
ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
struct address_space *mapping = log_vi->i_mapping;
struct page *page = NULL;
u8 *kaddr = NULL;
RESTART_PAGE_HEADER *rstr1_ph = NULL;
RESTART_PAGE_HEADER *rstr2_ph = NULL;
- int log_page_size, log_page_mask, ofs;
+ int log_page_size, log_page_mask, err;
BOOL logfile_is_empty = TRUE;
- BOOL rstr1_found = FALSE;
- BOOL rstr2_found = FALSE;
u8 log_page_bits;
ntfs_debug("Entering.");
@@ -491,7 +531,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Error mapping $LogFile "
"page (index %lu).", idx);
- return FALSE;
+ goto err_out;
}
}
kaddr = (u8*)page_address(page) + (pos & ~PAGE_CACHE_MASK);
@@ -510,99 +550,95 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
*/
if (ntfs_is_rcrd_recordp((le32*)kaddr))
break;
- /*
- * A modified by chkdsk restart page means we cannot handle
- * this log file.
- */
- if (ntfs_is_chkd_recordp((le32*)kaddr)) {
- ntfs_error(vol->sb, "$LogFile has been modified by "
- "chkdsk. Mount this volume in "
- "Windows.");
- goto err_out;
- }
- /* If not a restart page, continue. */
- if (!ntfs_is_rstr_recordp((le32*)kaddr)) {
- /* Skip to the minimum page size for the next one. */
+ /* If not a (modified by chkdsk) restart page, continue. */
+ if (!ntfs_is_rstr_recordp((le32*)kaddr) &&
+ !ntfs_is_chkd_recordp((le32*)kaddr)) {
if (!pos)
pos = NTFS_BLOCK_SIZE >> 1;
continue;
}
- /* We now know we have a restart page. */
- if (!pos) {
- rstr1_found = TRUE;
- rstr1_pos = pos;
- } else {
- if (rstr2_found) {
- ntfs_error(vol->sb, "Found more than two "
- "restart pages in $LogFile.");
- goto err_out;
- }
- rstr2_found = TRUE;
- rstr2_pos = pos;
- }
/*
- * Check the restart page for consistency and get a copy of the
- * complete multi sector transfer deprotected restart page.
+ * Check the (modified by chkdsk) restart page for consistency
+ * and get a copy of the complete multi sector transfer
+ * deprotected restart page.
*/
- if (!ntfs_check_and_load_restart_page(log_vi,
+ err = ntfs_check_and_load_restart_page(log_vi,
(RESTART_PAGE_HEADER*)kaddr, pos,
- !pos ? &rstr1_ph : &rstr2_ph)) {
- /* Error output already done inside the function. */
- goto err_out;
+ !rstr1_ph ? &rstr1_ph : &rstr2_ph,
+ !rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
+ if (!err) {
+ /*
+ * If we have now found the first (modified by chkdsk)
+ * restart page, continue looking for the second one.
+ */
+ if (!pos) {
+ pos = NTFS_BLOCK_SIZE >> 1;
+ continue;
+ }
+ /*
+ * We have now found the second (modified by chkdsk)
+ * restart page, so we can stop looking.
+ */
+ break;
}
/*
- * We have a valid restart page. The next one must be after
- * a whole system page size as specified by the valid restart
- * page.
+ * Error output already done inside the function. Note, we do
+ * not abort if the restart page was invalid as we might still
+ * find a valid one further in the file.
*/
+ if (err != -EINVAL) {
+ ntfs_unmap_page(page);
+ goto err_out;
+ }
+ /* Continue looking. */
if (!pos)
- pos = le32_to_cpu(rstr1_ph->system_page_size) >> 1;
+ pos = NTFS_BLOCK_SIZE >> 1;
}
- if (page) {
+ if (page)
ntfs_unmap_page(page);
- page = NULL;
- }
if (logfile_is_empty) {
NVolSetLogFileEmpty(vol);
is_empty:
ntfs_debug("Done. ($LogFile is empty.)");
return TRUE;
}
- if (!rstr1_found || !rstr2_found) {
- ntfs_error(vol->sb, "Did not find two restart pages in "
- "$LogFile.");
- goto err_out;
+ if (!rstr1_ph) {
+ BUG_ON(rstr2_ph);
+ ntfs_error(vol->sb, "Did not find any restart pages in "
+ "$LogFile and it was not empty.");
+ return FALSE;
+ }
+ /* If both restart pages were found, use the more recent one. */
+ if (rstr2_ph) {
+ /*
+ * If the second restart area is more recent, switch to it.
+ * Otherwise just throw it away.
+ */
+ if (rstr2_lsn > rstr1_lsn) {
+ ntfs_free(rstr1_ph);
+ rstr1_ph = rstr2_ph;
+ /* rstr1_lsn = rstr2_lsn; */
+ } else
+ ntfs_free(rstr2_ph);
+ rstr2_ph = NULL;
}
- /*
- * The two restart areas must be identical except for the update
- * sequence number.
- */
- ofs = le16_to_cpu(rstr1_ph->usa_ofs);
- if (memcmp(rstr1_ph, rstr2_ph, ofs) || (ofs += sizeof(u16),
- memcmp((u8*)rstr1_ph + ofs, (u8*)rstr2_ph + ofs,
- le32_to_cpu(rstr1_ph->system_page_size) - ofs))) {
- ntfs_error(vol->sb, "The two restart pages in $LogFile do not "
- "match.");
- goto err_out;
- }
- ntfs_free(rstr1_ph);
- ntfs_free(rstr2_ph);
/* All consistency checks passed. */
+ if (rp)
+ *rp = rstr1_ph;
+ else
+ ntfs_free(rstr1_ph);
ntfs_debug("Done.");
return TRUE;
err_out:
- if (page)
- ntfs_unmap_page(page);
if (rstr1_ph)
ntfs_free(rstr1_ph);
- if (rstr2_ph)
- ntfs_free(rstr2_ph);
return FALSE;
}
/**
* ntfs_is_logfile_clean - check in the journal if the volume is clean
* @log_vi: struct inode of loaded journal $LogFile to check
+ * @rp: copy of the current restart page
*
* Analyze the $LogFile journal and return TRUE if it indicates the volume was
* shutdown cleanly and FALSE if not.
@@ -619,11 +655,9 @@ err_out:
* is empty this function requires that NVolLogFileEmpty() is true otherwise an
* empty volume will be reported as dirty.
*/
-BOOL ntfs_is_logfile_clean(struct inode *log_vi)
+BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp)
{
ntfs_volume *vol = NTFS_SB(log_vi->i_sb);
- struct page *page;
- RESTART_PAGE_HEADER *rp;
RESTART_AREA *ra;
ntfs_debug("Entering.");
@@ -632,24 +666,15 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi)
ntfs_debug("Done. ($LogFile is empty.)");
return TRUE;
}
- /*
- * Read the first restart page. It will be possibly incomplete and
- * will not be multi sector transfer deprotected but we only need the
- * first NTFS_BLOCK_SIZE bytes so it does not matter.
- */
- page = ntfs_map_page(log_vi->i_mapping, 0);
- if (IS_ERR(page)) {
- ntfs_error(vol->sb, "Error mapping $LogFile page (index 0).");
+ BUG_ON(!rp);
+ if (!ntfs_is_rstr_record(rp->magic) &&
+ !ntfs_is_chkd_record(rp->magic)) {
+ ntfs_error(vol->sb, "Restart page buffer is invalid. This is "
+ "probably a bug in that the $LogFile should "
+ "have been consistency checked before calling "
+ "this function.");
return FALSE;
}
- rp = (RESTART_PAGE_HEADER*)page_address(page);
- if (!ntfs_is_rstr_record(rp->magic)) {
- ntfs_error(vol->sb, "No restart page found at offset zero in "
- "$LogFile. This is probably a bug in that "
- "the $LogFile should have been consistency "
- "checked before calling this function.");
- goto err_out;
- }
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
/*
* 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)
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
- goto err_out;
+ return FALSE;
}
- ntfs_unmap_page(page);
/* $LogFile indicates a clean shutdown. */
ntfs_debug("Done. $LogFile indicates a clean shutdown.");
return TRUE;
-err_out:
- ntfs_unmap_page(page);
- return FALSE;
}
/**
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
index 4ee4378de06..42388f95ea6 100644
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -2,7 +2,7 @@
* logfile.h - Defines for NTFS kernel journal ($LogFile) handling. Part of
* the Linux-NTFS project.
*
- * Copyright (c) 2000-2004 Anton Altaparmakov
+ * Copyright (c) 2000-2005 Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -296,9 +296,11 @@ typedef struct {
/* sizeof() = 160 (0xa0) bytes */
} __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
-extern BOOL ntfs_check_logfile(struct inode *log_vi);
+extern BOOL ntfs_check_logfile(struct inode *log_vi,
+ RESTART_PAGE_HEADER **rp);
-extern BOOL ntfs_is_logfile_clean(struct inode *log_vi);
+extern BOOL ntfs_is_logfile_clean(struct inode *log_vi,
+ const RESTART_PAGE_HEADER *rp);
extern BOOL ntfs_empty_logfile(struct inode *log_vi);
diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
index fac5944df6d..9994e019a3c 100644
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -27,27 +27,63 @@
#include <linux/highmem.h>
/**
- * ntfs_malloc_nofs - allocate memory in multiples of pages
- * @size number of bytes to allocate
+ * __ntfs_malloc - allocate memory in multiples of pages
+ * @size: number of bytes to allocate
+ * @gfp_mask: extra flags for the allocator
+ *
+ * Internal function. You probably want ntfs_malloc_nofs()...
*
* Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
* returns a pointer to the allocated memory.
*
* If there was insufficient memory to complete the request, return NULL.
+ * Depending on @gfp_mask the allocation may be guaranteed to succeed.
*/
-static inline void *ntfs_malloc_nofs(unsigned long size)
+static inline void *__ntfs_malloc(unsigned long size,
+ unsigned int __nocast gfp_mask)
{
if (likely(size <= PAGE_SIZE)) {
BUG_ON(!size);
/* kmalloc() has per-CPU caches so is faster for now. */
- return kmalloc(PAGE_SIZE, GFP_NOFS);
- /* return (void *)__get_free_page(GFP_NOFS | __GFP_HIGHMEM); */
+ return kmalloc(PAGE_SIZE, gfp_mask);
+ /* return (void *)__get_free_page(gfp_mask); */
}
if (likely(size >> PAGE_SHIFT < num_physpages))
- return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL);
+ return __vmalloc(size, gfp_mask, PAGE_KERNEL);
return NULL;
}
+/**
+ * ntfs_malloc_nofs - allocate memory in multiples of pages
+ * @size: number of bytes to allocate
+ *
+ * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
+ * returns a pointer to the allocated memory.
+ *
+ * If there was insufficient memory to complete the request, return NULL.
+ */
+static inline void *ntfs_malloc_nofs(unsigned long size)
+{
+ return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM);
+}
+
+/**
+ * ntfs_malloc_nofs_nofail - allocate memory in multiples of pages
+ * @size: number of bytes to allocate
+ *
+ * Allocates @size bytes of memory, rounded up to multiples of PAGE_SIZE and
+ * returns a pointer to the allocated memory.
+ *
+ * This function guarantees that the allocation will succeed. It will sleep
+ * for as long as it takes to complete the allocation.
+ *
+ * If there was insufficient memory to complete the request, return NULL.
+ */
+static inline void *ntfs_malloc_nofs_nofail(unsigned long size)
+{
+ return __ntfs_malloc(size, GFP_NOFS | __GFP_HIGHMEM | __GFP_NOFAIL);
+}
+
static inline void ntfs_free(void *addr)
{
if (likely(((unsigned long)addr < VMALLOC_START) ||
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 317f7c679fd..2c32b84385a 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,
} while (bh);
tail->b_this_page = head;
attach_page_buffers(page, head);
- BUG_ON(!page_has_buffers(page));
}
bh = head = page_buffers(page);
BUG_ON(!bh);
@@ -692,7 +691,6 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
*/
if (!NInoTestClearDirty(ni))
goto done;
- BUG_ON(!page_has_buffers(page));
bh = head = page_buffers(page);
BUG_ON(!bh);
rl = NULL;
@@ -1955,7 +1953,7 @@ restore_undo_alloc:
a = ctx->attr;
a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
undo_alloc:
- if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1) < 0) {
+ if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1, TRUE) < 0) {
ntfs_error(vol->sb, "Failed to free clusters from mft data "
"attribute.%s", es);
NVolSetErrors(vol);
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index 758855b0414..f5b2ac92908 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,
int size)
{
if (likely((dst != src) && (size > 0)))
- memmove(base + dst, base + src, size * sizeof (*base));
+ memmove(base + dst, base + src, size * sizeof(*base));
}
/**
@@ -95,6 +95,51 @@ static inline runlist_element *ntfs_rl_realloc(runlist_element *rl,
}
/**
+ * ntfs_rl_realloc_nofail - Reallocate memory for runlists
+ * @rl: original runlist
+ * @old_size: number of runlist elements in the original runlist @rl
+ * @new_size: number of runlist elements we need space for
+ *
+ * As the runlists grow, more memory will be required. To prevent the
+ * kernel having to allocate and reallocate large numbers of small bits of
+ * memory, this function returns an entire page of memory.
+ *
+ * This function guarantees that the allocation will succeed. It will sleep
+ * for as long as it takes to complete the allocation.
+ *
+ * It is up to the caller to serialize access to the runlist @rl.
+ *
+ * N.B. If the new allocation doesn't require a different number of pages in
+ * memory, the function will return the original pointer.
+ *
+ * On success, return a pointer to the newly allocated, or recycled, memory.
+ * On error, return -errno. The following error codes are defined:
+ * -ENOMEM - Not enough memory to allocate runlist array.
+ * -EINVAL - Invalid parameters were passed in.
+ */
+static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl,
+ int old_size, int new_size)
+{
+ runlist_element *new_rl;
+
+ old_size = PAGE_ALIGN(old_size * sizeof(*rl));
+ new_size = PAGE_ALIGN(new_size * sizeof(*rl));
+ if (old_size == new_size)
+ return rl;
+
+ new_rl = ntfs_malloc_nofs_nofail(new_size);
+ BUG_ON(!new_rl);
+
+ if (likely(rl != NULL)) {
+ if (unlikely(old_size > new_size))
+ old_size = new_size;
+ memcpy(new_rl, rl, old_size);
+ ntfs_free(rl);
+ }
+ return new_rl;
+}
+
+/**
* ntfs_are_rl_mergeable - test if two runlists can be joined together
* @dst: original runlist
* @src: new runlist to test for mergeability with @dst
@@ -497,6 +542,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
/* Scan to the end of the source runlist. */
for (dend = 0; likely(drl[dend].length); dend++)
;
+ dend++;
drl = ntfs_rl_realloc(drl, dend, dend + 1);
if (IS_ERR(drl))
return drl;
@@ -566,8 +612,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
((drl[dins].vcn + drl[dins].length) <= /* End of hole */
(srl[send - 1].vcn + srl[send - 1].length)));
- /* Or we'll lose an end marker */
- if (start && finish && (drl[dins].length == 0))
+ /* Or we will lose an end marker. */
+ if (finish && !drl[dins].length)
ss++;
if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
finish = FALSE;
@@ -621,11 +667,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
if (drl[ds].lcn != LCN_RL_NOT_MAPPED) {
/* Add an unmapped runlist element. */
if (!slots) {
- /* FIXME/TODO: We need to have the
- * extra memory already! (AIA) */
- drl = ntfs_rl_realloc(drl, ds, ds + 2);
- if (!drl)
- goto critical_error;
+ drl = ntfs_rl_realloc_nofail(drl, ds,
+ ds + 2);
slots = 2;
}
ds++;
@@ -640,13 +683,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl,
drl[ds].length = marker_vcn - drl[ds].vcn;
/* Finally add the ENOENT terminator. */
ds++;
- if (!slots) {
- /* FIXME/TODO: We need to have the extra
- * memory already! (AIA) */
- drl = ntfs_rl_realloc(drl, ds, ds + 1);
- if (!drl)
- goto critical_error;
- }
+ if (!slots)
+ drl = ntfs_rl_realloc_nofail(drl, ds, ds + 1);
drl[ds].vcn = marker_vcn;
drl[ds].lcn = LCN_ENOENT;
drl[ds].length = (s64)0;
@@ -659,11 +697,6 @@ finished:
ntfs_debug("Merged runlist:");
ntfs_debug_dump_runlist(drl);
return drl;
-
-critical_error:
- /* Critical error! We cannot afford to fail here. */
- ntfs_error(NULL, "Critical error! Not enough memory.");
- panic("NTFS: Cannot continue.");
}
/**
@@ -727,6 +760,9 @@ runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
ntfs_error(vol->sb, "Corrupt attribute.");
return ERR_PTR(-EIO);
}
+ /* If the mapping pairs array is valid but empty, nothing to do. */
+ if (!vcn && !*buf)
+ return old_rl;
/* Current position in runlist array. */
rlpos = 0;
/* Allocate first page and set current runlist size to one page. */
@@ -1419,6 +1455,7 @@ err_out:
/**
* ntfs_rl_truncate_nolock - truncate a runlist starting at a specified vcn
+ * @vol: ntfs volume (needed for error output)
* @runlist: runlist to truncate
* @new_length: the new length of the runlist in VCNs
*
@@ -1426,12 +1463,16 @@ err_out:
* holding the runlist elements to a length of @new_length VCNs.
*
* If @new_length lies within the runlist, the runlist elements with VCNs of
- * @new_length and above are discarded.
+ * @new_length and above are discarded. As a special case if @new_length is
+ * zero, the runlist is discarded and set to NULL.
*
* If @new_length lies beyond the runlist, a sparse runlist element is added to
* the end of the runlist @runlist or if the last runlist element is a sparse
* one already, this is extended.
*
+ * Note, no checking is done for unmapped runlist elements. It is assumed that
+ * the caller has mapped any elements that need to be mapped already.
+ *
* Return 0 on success and -errno on error.
*
* 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,
BUG_ON(!runlist);
BUG_ON(new_length < 0);
rl = runlist->rl;
+ if (!new_length) {
+ ntfs_debug("Freeing runlist.");
+ runlist->rl = NULL;
+ if (rl)
+ ntfs_free(rl);
+ return 0;
+ }
if (unlikely(!rl)) {
/*
* 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,
return 0;
}
+/**
+ * ntfs_rl_punch_nolock - punch a hole into a runlist
+ * @vol: ntfs volume (needed for error output)
+ * @runlist: runlist to punch a hole into
+ * @start: starting VCN of the hole to be created
+ * @length: size of the hole to be created in units of clusters
+ *
+ * Punch a hole into the runlist @runlist starting at VCN @start and of size
+ * @length clusters.
+ *
+ * Return 0 on success and -errno on error, in which case @runlist has not been
+ * modified.
+ *
+ * If @start and/or @start + @length are outside the runlist return error code
+ * -ENOENT.
+ *
+ * If the runlist contains unmapped or error elements between @start and @start
+ * + @length return error code -EINVAL.
+ *
+ * Locking: The caller must hold @runlist->lock for writing.
+ */
+int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
+ const VCN start, const s64 length)
+{
+ const VCN end = start + length;
+ s64 delta;
+ runlist_element *rl, *rl_end, *rl_real_end, *trl;
+ int old_size;
+ BOOL lcn_fixup = FALSE;
+
+ ntfs_debug("Entering for start 0x%llx, length 0x%llx.",
+ (long long)start, (long long)length);
+ BUG_ON(!runlist);
+ BUG_ON(start < 0);
+ BUG_ON(length < 0);
+ BUG_ON(end < 0);
+ rl = runlist->rl;
+ if (unlikely(!rl)) {
+ if (likely(!start && !length))
+ return 0;
+ return -ENOENT;
+ }
+ /* Find @start in the runlist. */
+ while (likely(rl->length && start >= rl[1].vcn))
+ rl++;
+ rl_end = rl;
+ /* Find @end in the runlist. */
+ while (likely(rl_end->length && end >= rl_end[1].vcn)) {
+ /* Verify there are no unmapped or error elements. */
+ if (unlikely(rl_end->lcn < LCN_HOLE))
+ return -EINVAL;
+ rl_end++;
+ }
+ /* Check the last element. */
+ if (unlikely(rl_end->length && rl_end->lcn < LCN_HOLE))
+ return -EINVAL;
+ /* This covers @start being out of bounds, too. */
+ if (!rl_end->length && end > rl_end->vcn)
+ return -ENOENT;
+ if (!length)
+ return 0;
+ if (!rl->length)
+ return -ENOENT;
+ rl_real_end = rl_end;
+ /* Determine the runlist size. */
+ while (likely(rl_real_end->length))
+ rl_real_end++;
+ old_size = rl_real_end - runlist->rl + 1;
+ /* If @start is in a hole simply extend the hole. */
+ if (rl->lcn == LCN_HOLE) {
+ /*
+ * If both @start and @end are in the same sparse run, we are
+ * done.
+ */
+ if (end <= rl[1].vcn) {
+ ntfs_debug("Done (requested hole is already sparse).");
+ return 0;
+ }
+extend_hole:
+ /* Extend the hole. */
+ rl->length = end - rl->vcn;
+ /* If @end is in a hole, merge it with the current one. */
+ if (rl_end->lcn == LCN_HOLE) {
+ rl_end++;
+ rl->length = rl_end->vcn - rl->vcn;
+ }
+ /* We have done the hole. Now deal with the remaining tail. */
+ rl++;
+ /* Cut out all runlist elements up to @end. */
+ if (rl < rl_end)
+ memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
+ sizeof(*rl));
+ /* Adjust the beginning of the tail if necessary. */
+ if (end > rl->vcn) {
+ s64 delta = end - rl->vcn;
+ rl->vcn = end;
+ rl->length -= delta;
+ /* Only adjust the lcn if it is real. */
+ if (rl->lcn >= 0)
+ rl->lcn += delta;
+ }
+shrink_allocation:
+ /* Reallocate memory if the allocation changed. */
+ if (rl < rl_end) {
+ rl = ntfs_rl_realloc(runlist->rl, old_size,
+ old_size - (rl_end - rl));
+ if (IS_ERR(rl))
+ ntfs_warning(vol->sb, "Failed to shrink "
+ "runlist buffer. This just "
+ "wastes a bit of memory "
+ "temporarily so we ignore it "
+ "and return success.");
+ else
+ runlist->rl = rl;
+ }
+ ntfs_debug("Done (extend hole).");
+ return 0;
+ }
+ /*
+ * If @start is at the beginning of a run things are easier as there is
+ * no need to split the first run.
+ */
+ if (start == rl->vcn) {
+ /*
+ * @start is at the beginning of a run.
+ *
+ * If the previous run is sparse, extend its hole.
+ *
+ * If @end is not in the same run, switch the run to be sparse
+ * and extend the newly created hole.
+ *
+ * Thus both of these cases reduce the problem to the above
+ * case of "@start is in a hole".
+ */
+ if (rl > runlist->rl && (rl - 1)->lcn == LCN_HOLE) {
+ rl--;
+ goto extend_hole;
+ }
+ if (end >= rl[1].vcn) {
+ rl->lcn = LCN_HOLE;
+ goto extend_hole;
+ }
+ /*
+ * The final case is when @end is in the same run as @start.
+ * For this need to split the run into two. One run for the
+ * sparse region between the beginning of the old run, i.e.
+ * @start, and @end and one for the remaining non-sparse
+ * region, i.e. between @end and the end of the old run.
+ */
+ trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
+ if (IS_ERR(trl))
+ goto enomem_out;
+ old_size++;
+ if (runlist->rl != trl) {
+ rl = trl + (rl - runlist->rl);
+ rl_end = trl + (rl_end - runlist->rl);
+ rl_real_end = trl + (rl_real_end - runlist->rl);
+ runlist->rl = trl;
+ }
+split_end:
+ /* Shift all the runs up by one. */
+ memmove(rl + 1, rl, (rl_real_end - rl + 1) * sizeof(*rl));
+ /* Finally, setup the two split runs. */
+ rl->lcn = LCN_HOLE;
+ rl->length = length;
+ rl++;
+ rl->vcn += length;
+ /* Only adjust the lcn if it is real. */
+ if (rl->lcn >= 0 || lcn_fixup)
+ rl->lcn += length;
+ rl->length -= length;
+ ntfs_debug("Done (split one).");
+ return 0;
+ }
+ /*
+ * @start is neither in a hole nor at the beginning of a run.
+ *
+ * If @end is in a hole, things are easier as simply truncating the run
+ * @start is in to end at @start - 1, deleting all runs after that up
+ * to @end, and finally extending the beginning of the run @end is in
+ * to be @start is all that is needed.
+ */
+ if (rl_end->lcn == LCN_HOLE) {
+ /* Truncate the run containing @start. */
+ rl->length = start - rl->vcn;
+ rl++;
+ /* Cut out all runlist elements up to @end. */
+ if (rl < rl_end)
+ memmove(rl, rl_end, (rl_real_end - rl_end + 1) *
+ sizeof(*rl));
+ /* Extend the beginning of the run @end is in to be @start. */
+ rl->vcn = start;
+ rl->length = rl[1].vcn - start;
+ goto shrink_allocation;
+ }
+ /*
+ * If @end is not in a hole there are still two cases to distinguish.
+ * Either @end is or is not in the same run as @start.
+ *
+ * The second case is easier as it can be reduced to an already solved
+ * problem by truncating the run @start is in to end at @start - 1.
+ * Then, if @end is in the next run need to split the run into a sparse
+ * run followed by a non-sparse run (already covered above) and if @end
+ * is not in the next run switching it to be sparse, again reduces the
+ * problem to the already covered case of "@start is in a hole".
+ */
+ if (end >= rl[1].vcn) {
+ /*
+ * If @end is not in the next run, reduce the problem to the
+ * case of "@start is in a hole".
+ */
+ if (rl[1].length && end >= rl[2].vcn) {
+ /* Truncate the run containing @start. */
+ rl->length = start - rl->vcn;
+ rl++;
+ rl->vcn = start;
+ rl->lcn = LCN_HOLE;
+ goto extend_hole;
+ }
+ trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 1);
+ if (IS_ERR(trl))
+ goto enomem_out;
+ old_size++;
+ if (runlist->rl != trl) {
+ rl = trl + (rl - runlist->rl);
+ rl_end = trl + (rl_end - runlist->rl);
+ rl_real_end = trl + (rl_real_end - runlist->rl);
+ runlist->rl = trl;
+ }
+ /* Truncate the run containing @start. */
+ rl->length = start - rl->vcn;
+ rl++;
+ /*
+ * @end is in the next run, reduce the problem to the case
+ * where "@start is at the beginning of a run and @end is in
+ * the same run as @start".
+ */
+ delta = rl->vcn - start;
+ rl->vcn = start;
+ if (rl->lcn >= 0) {
+ rl->lcn -= delta;
+ /* Need this in case the lcn just became negative. */
+ lcn_fixup = TRUE;
+ }
+ rl->length += delta;
+ goto split_end;
+ }
+ /*
+ * The first case from above, i.e. @end is in the same run as @start.
+ * We need to split the run into three. One run for the non-sparse
+ * region between the beginning of the old run and @start, one for the
+ * sparse region between @start and @end, and one for the remaining
+ * non-sparse region, i.e. between @end and the end of the old run.
+ */
+ trl = ntfs_rl_realloc(runlist->rl, old_size, old_size + 2);
+ if (IS_ERR(trl))
+ goto enomem_out;
+ old_size += 2;
+ if (runlist->rl != trl) {
+ rl = trl + (rl - runlist->rl);
+ rl_end = trl + (rl_end - runlist->rl);
+ rl_real_end = trl + (rl_real_end - runlist->rl);
+ runlist->rl = trl;
+ }
+ /* Shift all the runs up by two. */
+ memmove(rl + 2, rl, (rl_real_end - rl + 1) * sizeof(*rl));
+ /* Finally, setup the three split runs. */
+ rl->length = start - rl->vcn;
+ rl++;
+ rl->vcn = start;
+ rl->lcn = LCN_HOLE;
+ rl->length = length;
+ rl++;
+ delta = end - rl->vcn;
+ rl->vcn = end;
+ rl->lcn += delta;
+ rl->length -= delta;
+ ntfs_debug("Done (split both).");
+ return 0;
+enomem_out:
+ ntfs_error(vol->sb, "Not enough memory to extend runlist buffer.");
+ return -ENOMEM;
+}
+
#endif /* NTFS_RW */
diff --git a/fs/ntfs/runlist.h b/fs/ntfs/runlist.h
index aa0ee6540e7..47728fbb610 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,
extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,
runlist *const runlist, const s64 new_length);
+int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist,
+ const VCN start, const s64 length);
+
#endif /* NTFS_RW */
#endif /* _LINUX_NTFS_RUNLIST_H */
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 41aa8eb6755..b2b39296126 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1133,7 +1133,8 @@ mft_unmap_out:
*
* Return TRUE on success or FALSE on error.
*/
-static BOOL load_and_check_logfile(ntfs_volume *vol)
+static BOOL load_and_check_logfile(ntfs_volume *vol,
+ RESTART_PAGE_HEADER **rp)
{
struct inode *tmp_ino;
@@ -1145,7 +1146,7 @@ static BOOL load_and_check_logfile(ntfs_volume *vol)
/* Caller will display error message. */
return FALSE;
}
- if (!ntfs_check_logfile(tmp_ino)) {
+ if (!ntfs_check_logfile(tmp_ino, rp)) {
iput(tmp_ino);
/* ntfs_check_logfile() will have displayed error output. */
return FALSE;
@@ -1689,6 +1690,7 @@ static BOOL load_system_files(ntfs_volume *vol)
VOLUME_INFORMATION *vi;
ntfs_attr_search_ctx *ctx;
#ifdef NTFS_RW
+ RESTART_PAGE_HEADER *rp;
int err;
#endif /* NTFS_RW */
@@ -1841,8 +1843,9 @@ get_ctx_vol_failed:
* Get the inode for the logfile, check it and determine if the volume
* was shutdown cleanly.
*/
- if (!load_and_check_logfile(vol) ||
- !ntfs_is_logfile_clean(vol->logfile_ino)) {
+ rp = NULL;
+ if (!load_and_check_logfile(vol, &rp) ||
+ !ntfs_is_logfile_clean(vol->logfile_ino, rp)) {
static const char *es1a = "Failed to load $LogFile";
static const char *es1b = "$LogFile is not clean";
static const char *es2 = ". Mount in Windows.";
@@ -1857,6 +1860,10 @@ get_ctx_vol_failed:
"continue nor on_errors="
"remount-ro was specified%s",
es1, es2);
+ if (vol->logfile_ino) {
+ BUG_ON(!rp);
+ ntfs_free(rp);
+ }
goto iput_logfile_err_out;
}
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
@@ -1867,6 +1874,7 @@ get_ctx_vol_failed:
/* This will prevent a read-write remount. */
NVolSetErrors(vol);
}
+ ntfs_free(rp);
#endif /* NTFS_RW */
/* Get the root directory inode so we can do path lookups. */
vol->root_ino = ntfs_iget(sb, FILE_root);
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index 19c42e231b4..a389a5a16c8 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,
return -EINVAL;
conversion_err:
ntfs_error(vol->sb, "Unicode name contains characters that cannot be "
- "converted to character set %s.", nls->charset);
+ "converted to character set %s. You might want to "
+ "try to use the mount option nls=utf8.", nls->charset);
if (ns != *outs)
kfree(ns);
if (wc != -ENAMETOOLONG)
diff --git a/fs/open.c b/fs/open.c
index 4ee2dcc31c2..2fac58c5191 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -24,6 +24,7 @@
#include <linux/personality.h>
#include <linux/pagemap.h>
#include <linux/syscalls.h>
+#include <linux/rcupdate.h>
#include <asm/unistd.h>
@@ -842,14 +843,16 @@ int get_unused_fd(void)
{
struct files_struct * files = current->files;
int fd, error;
+ struct fdtable *fdt;
error = -EMFILE;
spin_lock(&files->file_lock);
repeat:
- fd = find_next_zero_bit(files->open_fds->fds_bits,
- files->max_fdset,
- files->next_fd);
+ fdt = files_fdtable(files);
+ fd = find_next_zero_bit(fdt->open_fds->fds_bits,
+ fdt->max_fdset,
+ fdt->next_fd);
/*
* N.B. For clone tasks sharing a files structure, this test
@@ -872,14 +875,14 @@ repeat:
goto repeat;
}
- FD_SET(fd, files->open_fds);
- FD_CLR(fd, files->close_on_exec);
- files->next_fd = fd + 1;
+ FD_SET(fd, fdt->open_fds);
+ FD_CLR(fd, fdt->close_on_exec);
+ fdt->next_fd = fd + 1;
#if 1
/* Sanity check */
- if (files->fd[fd] != NULL) {
+ if (fdt->fd[fd] != NULL) {
printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
- files->fd[fd] = NULL;
+ fdt->fd[fd] = NULL;
}
#endif
error = fd;
@@ -893,9 +896,10 @@ EXPORT_SYMBOL(get_unused_fd);
static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
{
- __FD_CLR(fd, files->open_fds);
- if (fd < files->next_fd)
- files->next_fd = fd;
+ struct fdtable *fdt = files_fdtable(files);
+ __FD_CLR(fd, fdt->open_fds);
+ if (fd < fdt->next_fd)
+ fdt->next_fd = fd;
}
void fastcall put_unused_fd(unsigned int fd)
@@ -924,10 +928,11 @@ EXPORT_SYMBOL(put_unused_fd);
void fastcall fd_install(unsigned int fd, struct file * file)
{
struct files_struct *files = current->files;
+ struct fdtable *fdt;
spin_lock(&files->file_lock);
- if (unlikely(files->fd[fd] != NULL))
- BUG();
- files->fd[fd] = file;
+ fdt = files_fdtable(files);
+ BUG_ON(fdt->fd[fd] != NULL);
+ rcu_assign_pointer(fdt->fd[fd], file);
spin_unlock(&files->file_lock);
}
@@ -1010,15 +1015,17 @@ asmlinkage long sys_close(unsigned int fd)
{
struct file * filp;
struct files_struct *files = current->files;
+ struct fdtable *fdt;
spin_lock(&files->file_lock);
- if (fd >= files->max_fds)
+ fdt = files_fdtable(files);
+ if (fd >= fdt->max_fds)
goto out_unlock;
- filp = files->fd[fd];
+ filp = fdt->fd[fd];
if (!filp)
goto out_unlock;
- files->fd[fd] = NULL;
- FD_CLR(fd, files->close_on_exec);
+ rcu_assign_pointer(fdt->fd[fd], NULL);
+ FD_CLR(fd, fdt->close_on_exec);
__put_unused_fd(files, fd);
spin_unlock(&files->file_lock);
return filp_close(filp, files);
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 37668fe998a..d88d518d30f 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)
{
struct group_info *group_info;
int g;
+ struct fdtable *fdt = NULL;
read_lock(&tasklist_lock);
buffer += sprintf(buffer,
@@ -179,10 +180,12 @@ static inline char * task_state(struct task_struct *p, char *buffer)
p->gid, p->egid, p->sgid, p->fsgid);
read_unlock(&tasklist_lock);
task_lock(p);
+ if (p->files)
+ fdt = files_fdtable(p->files);
buffer += sprintf(buffer,
"FDSize:\t%d\n"
"Groups:\t",
- p->files ? p->files->max_fds : 0);
+ fdt ? fdt->max_fds : 0);
group_info = p->group_info;
get_group_info(group_info);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 84751f3f52d..23db452ab42 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -62,6 +62,7 @@
#include <linux/namespace.h>
#include <linux/mm.h>
#include <linux/smp_lock.h>
+#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
#include <linux/mount.h>
#include <linux/security.h>
@@ -283,16 +284,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
files = get_files_struct(task);
if (files) {
- spin_lock(&files->file_lock);
+ rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
*mnt = mntget(file->f_vfsmnt);
*dentry = dget(file->f_dentry);
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
return 0;
}
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
}
return -ENOENT;
@@ -1039,6 +1040,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
int retval;
char buf[NUMBUF];
struct files_struct * files;
+ struct fdtable *fdt;
retval = -ENOENT;
if (!pid_alive(p))
@@ -1061,15 +1063,16 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
files = get_files_struct(p);
if (!files)
goto out;
- spin_lock(&files->file_lock);
+ rcu_read_lock();
+ fdt = files_fdtable(files);
for (fd = filp->f_pos-2;
- fd < files->max_fds;
+ fd < fdt->max_fds;
fd++, filp->f_pos++) {
unsigned int i,j;
if (!fcheck_files(files, fd))
continue;
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
j = NUMBUF;
i = fd;
@@ -1081,12 +1084,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
- spin_lock(&files->file_lock);
+ rcu_read_lock();
break;
}
- spin_lock(&files->file_lock);
+ rcu_read_lock();
}
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
}
out:
@@ -1261,9 +1264,9 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
files = get_files_struct(task);
if (files) {
- spin_lock(&files->file_lock);
+ rcu_read_lock();
if (fcheck_files(files, fd)) {
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
if (task_dumpable(task)) {
inode->i_uid = task->euid;
@@ -1275,7 +1278,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
security_task_to_inode(task, inode);
return 1;
}
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
}
d_drop(dentry);
@@ -1367,7 +1370,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
if (!files)
goto out_unlock;
inode->i_mode = S_IFLNK;
- spin_lock(&files->file_lock);
+ rcu_read_lock();
file = fcheck_files(files, fd);
if (!file)
goto out_unlock2;
@@ -1375,7 +1378,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
inode->i_mode |= S_IRUSR | S_IXUSR;
if (file->f_mode & 2)
inode->i_mode |= S_IWUSR | S_IXUSR;
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
@@ -1385,7 +1388,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
return NULL;
out_unlock2:
- spin_unlock(&files->file_lock);
+ rcu_read_unlock();
put_files_struct(files);
out_unlock:
iput(inode);
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 133c2868510..effa6c0c467 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -60,6 +60,8 @@ static void proc_delete_inode(struct inode *inode)
struct proc_dir_entry *de;
struct task_struct *tsk;
+ truncate_inode_pages(&inode->i_data, 0);
+
/* Let go of any associated process */
tsk = PROC_I(inode)->task;
if (tsk)
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index b79162a3547..80f32911c0c 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -63,6 +63,7 @@ int qnx4_sync_inode(struct inode *inode)
static void qnx4_delete_inode(struct inode *inode)
{
QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
+ truncate_inode_pages(&inode->i_data, 0);
inode->i_size = 0;
qnx4_truncate(inode);
lock_kernel();
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ff291c973a5..1a8a1bf2154 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -33,6 +33,8 @@ void reiserfs_delete_inode(struct inode *inode)
2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
struct reiserfs_transaction_handle th;
+ truncate_inode_pages(&inode->i_data, 0);
+
reiserfs_write_lock(inode->i_sb);
/* 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 b80e7eb0ac0..f10a10317d5 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -22,6 +22,7 @@
#include <linux/personality.h> /* for STICKY_TIMEOUTS */
#include <linux/file.h>
#include <linux/fs.h>
+#include <linux/rcupdate.h>
#include <asm/uaccess.h>
@@ -132,11 +133,13 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds)
unsigned long *open_fds;
unsigned long set;
int max;
+ struct fdtable *fdt;
/* handle last in-complete long-word first */
set = ~(~0UL << (n & (__NFDBITS-1)));
n /= __NFDBITS;
- open_fds = current->files->open_fds->fds_bits+n;
+ fdt = files_fdtable(current->files);
+ open_fds = fdt->open_fds->fds_bits+n;
max = 0;
if (set) {
set &= BITS(fds, n);
@@ -183,9 +186,9 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
int retval, i;
long __timeout = *timeout;
- spin_lock(&current->files->file_lock);
+ rcu_read_lock();
retval = max_select_fd(n, fds);
- spin_unlock(&current->files->file_lock);
+ rcu_read_unlock();
if (retval < 0)
return retval;
@@ -299,6 +302,7 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
char *bits;
long timeout;
int ret, size, max_fdset;
+ struct fdtable *fdt;
timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
@@ -326,7 +330,10 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
goto out_nofds;
/* max_fdset can increase, so grab it once to avoid race */
- max_fdset = current->files->max_fdset;
+ rcu_read_lock();
+ fdt = files_fdtable(current->files);
+ max_fdset = fdt->max_fdset;
+ rcu_read_unlock();
if (n > max_fdset)
n = max_fdset;
@@ -464,9 +471,15 @@ asmlinkage long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long ti
unsigned int i;
struct poll_list *head;
struct poll_list *walk;
+ struct fdtable *fdt;
+ int max_fdset;
/* Do a sanity check on nfds ... */
- if (nfds > current->files->max_fdset && nfds > OPEN_MAX)
+ rcu_read_lock();
+ fdt = files_fdtable(current->files);
+ max_fdset = fdt->max_fdset;
+ rcu_read_unlock();
+ if (nfds > max_fdset && nfds > OPEN_MAX)
return -EINVAL;
if (timeout) {
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 4765aaac9fd..10b994428fe 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -331,6 +331,7 @@ static void
smb_delete_inode(struct inode *ino)
{
DEBUG1("ino=%ld\n", ino->i_ino);
+ truncate_inode_pages(&ino->i_data, 0);
lock_kernel();
if (smb_close(ino))
PARANOIA("could not close inode %ld\n", ino->i_ino);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 0530077d9dd..fa33eceb001 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -292,6 +292,7 @@ int sysv_sync_inode(struct inode * inode)
static void sysv_delete_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
inode->i_size = 0;
sysv_truncate(inode);
lock_kernel();
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 3d68de39fad..b83890beaaa 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);
*/
void udf_delete_inode(struct inode * inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+
if (is_bad_inode(inode))
goto no_delete;
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 718627ca8b5..55f4aa16e3f 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -804,6 +804,7 @@ int ufs_sync_inode (struct inode *inode)
void ufs_delete_inode (struct inode * inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
/*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
lock_kernel();
mark_inode_dirty(inode);
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 8e18ff15724..d8c87fa21ad 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+# Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as
@@ -55,7 +55,18 @@ ifeq ($(CONFIG_XFS_TRACE),y)
endif
obj-$(CONFIG_XFS_FS) += xfs.o
-xfs-$(CONFIG_XFS_QUOTA) += quota/
+
+xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
+ xfs_dquot.o \
+ xfs_dquot_item.o \
+ xfs_trans_dquot.o \
+ xfs_qm_syscalls.o \
+ xfs_qm_bhv.o \
+ xfs_qm.o)
+
+ifeq ($(CONFIG_XFS_QUOTA),y)
+xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
+endif
xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c
index 3dae14c8c55..fa8394f9437 100644
--- a/fs/xfs/support/ktrace.c
+++ b/fs/xfs/support/ktrace.c
@@ -170,7 +170,7 @@ ktrace_enter(
void *val14,
void *val15)
{
- static lock_t wrap_lock = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(wrap_lock);
unsigned long flags;
int index;
ktrace_entry_t *ktep;
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
index f681e675b82..4e115f368d5 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 *,
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
static 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 72b04d846a2..cf35721cfa4 100644
--- a/include/asm-arm/arch-pxa/hardware.h
+++ b/include/asm-arm/arch-pxa/hardware.h
@@ -44,24 +44,12 @@
#ifndef __ASSEMBLY__
-#if 0
-# define __REG(x) (*((volatile u32 *)io_p2v(x)))
-#else
-/*
- * This __REG() version gives the same results as the one above, except
- * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers. It's a shame that gcc
- * doesn't guess this by itself.
- */
-#include <asm/types.h>
-typedef struct { volatile u32 offset[4096]; } __regbase;
-# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
-# define __REG(x) __REGP(io_p2v(x))
-#endif
+# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
/* With indexed regs we don't want to feed the index through io_p2v()
especially if it is a variable, otherwise horrible code will result. */
-# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
+# define __REG2(x,y) \
+ (*(volatile unsigned long *)((unsigned long)&__REG(x) + (y)))
# define __PREG(x) (io_v2p((u32)&(x)))
diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h
new file mode 100644
index 00000000000..46ec2243974
--- /dev/null
+++ b/include/asm-arm/arch-pxa/i2c.h
@@ -0,0 +1,70 @@
+/*
+ * i2c_pxa.h
+ *
+ * Copyright (C) 2002 Intrinsyc Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef _I2C_PXA_H_
+#define _I2C_PXA_H_
+
+#if 0
+#define DEF_TIMEOUT 3
+#else
+/* need a longer timeout if we're dealing with the fact we may well be
+ * looking at a multi-master environment
+*/
+#define DEF_TIMEOUT 32
+#endif
+
+#define BUS_ERROR (-EREMOTEIO)
+#define XFER_NAKED (-ECONNREFUSED)
+#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
+
+/* ICR initialize bit values
+*
+* 15. FM 0 (100 Khz operation)
+* 14. UR 0 (No unit reset)
+* 13. SADIE 0 (Disables the unit from interrupting on slave addresses
+* matching its slave address)
+* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration
+* in master mode)
+* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
+* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
+* 9. IRFIE 1 (Enable interrupts from full buffer received)
+* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
+* 7. GCD 1 (Disables i2c unit response to general call messages as a slave)
+* 6. IUE 0 (Disable unit until we change settings)
+* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
+* 4. MA 0 (Only send stop with the ICR stop bit)
+* 3. TB 0 (We are not transmitting a byte initially)
+* 2. ACKNAK 0 (Send an ACK after the unit receives a byte)
+* 1. STOP 0 (Do not send a STOP)
+* 0. START 0 (Do not send a START)
+*
+*/
+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+
+/* I2C status register init values
+ *
+ * 10. BED 1 (Clear bus error detected)
+ * 9. SAD 1 (Clear slave address detected)
+ * 7. IRF 1 (Clear IDBR Receive Full)
+ * 6. ITE 1 (Clear IDBR Transmit Empty)
+ * 5. ALD 1 (Clear Arbitration Loss Detected)
+ * 4. SSD 1 (Clear Slave Stop Detected)
+ */
+#define I2C_ISR_INIT 0x7FF /* status register init */
+
+struct i2c_slave_client;
+
+struct i2c_pxa_platform_data {
+ unsigned int slave_addr;
+ struct i2c_slave_client *slave;
+};
+
+extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
+#endif
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
index 9718063a211..88c17dd02ed 100644
--- a/include/asm-arm/arch-pxa/mmc.h
+++ b/include/asm-arm/arch-pxa/mmc.h
@@ -9,6 +9,7 @@ struct mmc_host;
struct pxamci_platform_data {
unsigned int ocr_mask; /* available voltages */
+ unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */
int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
int (*get_ro)(struct device *);
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 27d71e9d413..21c0e16dce5 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 {
};
void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
+unsigned 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 00000000000..ac57bc887d8
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -0,0 +1,69 @@
+/* linux/include/asm/arch-s3c2410/fb.h
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Inspired by pxafb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * Changelog:
+ * 07-Sep-2004 RTP Created file
+ * 03-Nov-2004 BJD Updated and minor cleanups
+ * 03-Aug-2005 RTP Renamed to fb.h
+*/
+
+#ifndef __ASM_ARM_FB_H
+#define __ASM_ARM_FB_H
+
+#include <asm/arch/regs-lcd.h>
+
+struct s3c2410fb_val {
+ unsigned int defval;
+ unsigned int min;
+ unsigned int max;
+};
+
+struct s3c2410fb_hw {
+ unsigned long lcdcon1;
+ unsigned long lcdcon2;
+ unsigned long lcdcon3;
+ unsigned long lcdcon4;
+ unsigned long lcdcon5;
+};
+
+struct s3c2410fb_mach_info {
+ unsigned char fixed_syncs; /* do not update sync/border */
+
+ /* Screen size */
+ int width;
+ int height;
+
+ /* Screen info */
+ struct s3c2410fb_val xres;
+ struct s3c2410fb_val yres;
+ struct s3c2410fb_val bpp;
+
+ /* lcd configuration registers */
+ struct s3c2410fb_hw regs;
+
+ /* GPIOs */
+
+ unsigned long gpcup;
+ unsigned long gpcup_mask;
+ unsigned long gpccon;
+ unsigned long gpccon_mask;
+ unsigned long gpdup;
+ unsigned long gpdup_mask;
+ unsigned long gpdcon;
+ unsigned long gpdcon_mask;
+
+ /* lpc3600 control register */
+ unsigned long lpcsel;
+};
+
+void __init set_s3c2410fb_info(struct s3c2410fb_mach_info *hard_s3c2410fb_info);
+
+#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 7f882ea92b2..b6b1b4e8bbe 100644
--- a/include/asm-arm/arch-s3c2410/regs-lcd.h
+++ b/include/asm-arm/arch-s3c2410/regs-lcd.h
@@ -51,21 +51,32 @@
#define S3C2410_LCDCON1_ENVID (1)
+#define S3C2410_LCDCON1_MODEMASK 0x1E
+
#define S3C2410_LCDCON2_VBPD(x) ((x) << 24)
#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14)
#define S3C2410_LCDCON2_VFPD(x) ((x) << 6)
#define S3C2410_LCDCON2_VSPW(x) ((x) << 0)
+#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
+#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF)
+#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F)
+
#define S3C2410_LCDCON3_HBPD(x) ((x) << 19)
#define S3C2410_LCDCON3_WDLY(x) ((x) << 19)
#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8)
#define S3C2410_LCDCON3_HFPD(x) ((x) << 0)
#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
+#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
+#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF)
+
#define S3C2410_LCDCON4_MVAL(x) ((x) << 8)
#define S3C2410_LCDCON4_HSPW(x) ((x) << 0)
#define S3C2410_LCDCON4_WLH(x) ((x) << 0)
+#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF)
+
#define S3C2410_LCDCON5_BPP24BL (1<<12)
#define S3C2410_LCDCON5_FRM565 (1<<11)
#define S3C2410_LCDCON5_INVVCLK (1<<10)
@@ -100,10 +111,16 @@
#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C)
#define S3C2410_TPAL S3C2410_LCDREG(0x50)
+#define S3C2410_TPAL_EN (1<<24)
+
/* interrupt info */
#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54)
#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58)
#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C)
+#define S3C2410_LCDINT_FIWSEL (1<<2)
+#define S3C2410_LCDINT_FRSYNC (1<<1)
+#define S3C2410_LCDINT_FICNT (1<<0)
+
#define S3C2410_LPCSEL S3C2410_LCDREG(0x60)
#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 10c62db3436..19c3b1e186b 100644
--- a/include/asm-arm/arch-sa1100/hardware.h
+++ b/include/asm-arm/arch-sa1100/hardware.h
@@ -49,23 +49,9 @@
( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
#ifndef __ASSEMBLY__
-#include <asm/types.h>
-#if 0
-# define __REG(x) (*((volatile u32 *)io_p2v(x)))
-#else
-/*
- * This __REG() version gives the same results as the one above, except
- * that we are fooling gcc somehow so it generates far better and smaller
- * assembly code for access to contigous registers. It's a shame that gcc
- * doesn't guess this by itself.
- */
-typedef struct { volatile u32 offset[4096]; } __regbase;
-# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
-# define __REG(x) __REGP(io_p2v(x))
-#endif
-
-# define __PREG(x) (io_v2p((u32)&(x)))
+# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
+# define __PREG(x) (io_v2p((unsigned long)&(x)))
#else
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 035cdcff43d..e81baff4f54 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);
* Convert calls to our calling convention.
*/
#define flush_cache_all() __cpuc_flush_kern_all()
-
+#ifndef CONFIG_CPU_CACHE_VIPT
static inline void flush_cache_mm(struct mm_struct *mm)
{
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
__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
}
}
+#else
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
+#endif
/*
* 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 38ea5899a58..ead3ced38cb 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -64,6 +64,19 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index ee1d8b5d816..c36a77d3bf4 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,
res->end = region->end;
}
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
#define pcibios_scan_all_fns(a, b) 0
#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 521e227db67..06ae4d81ba6 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)
for (i = 0; i < 100; i++) {
kb_wait();
udelay(50);
- outb(0xfe, 0x64); /* pulse reset low */
+ outb(0x60, 0x64); /* write Controller Command Byte */
+ udelay(50);
+ kb_wait();
+ udelay(50);
+ outb(0x14, 0x60); /* set "System flag" */
+ udelay(50);
+ kb_wait();
+ udelay(50);
+ outb(0xfe, 0x64); /* pulse reset low */
udelay(50);
}
}
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 516421300ea..348fe3a4879 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -29,7 +29,7 @@ static inline void get_memcfg_numa(void)
#ifdef CONFIG_X86_NUMAQ
if (get_memcfg_numaq())
return;
-#elif CONFIG_ACPI_SRAT
+#elif defined(CONFIG_ACPI_SRAT)
if (get_memcfg_from_srat())
return;
#endif
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index a429fe225b0..20f98f1751a 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);
#endif /* CONFIG_HOTPLUG */
extern int gsi_to_vector (unsigned int gsi);
extern int gsi_to_irq (unsigned int gsi);
-extern void iosapic_enable_intr (unsigned int vector);
extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
unsigned long trigger);
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
extern void iosapic_unregister_intr (unsigned int irq);
-#endif
extern void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
unsigned long polarity,
unsigned long trigger);
@@ -97,7 +94,6 @@ extern int __init iosapic_register_platform_intr (u32 int_type,
unsigned long trigger);
extern unsigned int iosapic_version (char __iomem *addr);
-extern void iosapic_pci_fixup (int);
#ifdef CONFIG_NUMA
extern void __devinit map_iosapic_to_node (unsigned int, int);
#endif
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index cd984d08fd1..dbe86c0bbce 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -35,8 +35,4 @@ extern void disable_irq_nosync (unsigned int);
extern void enable_irq (unsigned int);
extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
#endif /* _ASM_IA64_IRQ_H */
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index dba9f220be7..ef616fd4cb1 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,
extern void pcibios_bus_to_resource(struct pci_dev *dev,
struct resource *res, struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
#define pcibios_scan_all_fns(a, b) 0
#endif /* _ASM_IA64_PCI_H */
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 33256db4a7c..635235fa1e3 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);
*/
#define __ARCH_WANT_UNLOCKED_CTXSW
+#define ARCH_HAS_PREFETCH_SWITCH_STACK
#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
void cpu_idle_wait(void);
diff --git a/include/asm-m68knommu/coldfire.h b/include/asm-m68knommu/coldfire.h
index 16f32cc80c4..1df3f666a28 100644
--- a/include/asm-m68knommu/coldfire.h
+++ b/include/asm-m68knommu/coldfire.h
@@ -22,7 +22,7 @@
#define MCF_MBAR2 0x80000000
#define MCF_IPSBAR 0x40000000
-#if defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#undef MCF_MBAR
#define MCF_MBAR MCF_IPSBAR
#endif
@@ -54,6 +54,8 @@
#define MCF_CLK 54000000
#elif defined(CONFIG_CLOCK_60MHz)
#define MCF_CLK 60000000
+#elif defined(CONFIG_CLOCK_62_5MHz)
+#define MCF_CLK 62500000
#elif defined(CONFIG_CLOCK_64MHz)
#define MCF_CLK 64000000
#elif defined(CONFIG_CLOCK_66MHz)
@@ -76,7 +78,7 @@
* One some ColdFire family members the bus clock (used by internal
* peripherals) is not the same as the CPU clock.
*/
-#if defined(CONFIG_M5249) || defined(CONFIG_M527x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M5249) || defined(CONFIG_M527x)
#define MCF_BUSCLK (MCF_CLK / 2)
#else
#define MCF_BUSCLK MCF_CLK
diff --git a/include/asm-m68knommu/m523xsim.h b/include/asm-m68knommu/m523xsim.h
new file mode 100644
index 00000000000..926cfb805df
--- /dev/null
+++ b/include/asm-m68knommu/m523xsim.h
@@ -0,0 +1,46 @@
+/****************************************************************************/
+
+/*
+ * m523xsim.h -- ColdFire 523x System Integration Module support.
+ *
+ * (C) Copyright 2003-2005, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef m523xsim_h
+#define m523xsim_h
+/****************************************************************************/
+
+#include <linux/config.h>
+
+/*
+ * Define the 523x SIM register set addresses.
+ */
+#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */
+#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */
+#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
+#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */
+#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */
+#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
+#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
+#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
+#define MCFINTC_IRLR 0x18 /* */
+#define MCFINTC_IACKL 0x19 /* */
+#define MCFINTC_ICR0 0x40 /* Base ICR register */
+
+#define MCFINT_VECBASE 64 /* Vector base number */
+#define MCFINT_UART0 13 /* Interrupt number for UART0 */
+#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
+#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
+
+/*
+ * SDRAM configuration registers.
+ */
+#define MCFSIM_DCR 0x44 /* SDRAM control */
+#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */
+#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */
+#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */
+#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
+
+/****************************************************************************/
+#endif /* m523xsim_h */
diff --git a/include/asm-m68knommu/mcfsim.h b/include/asm-m68knommu/mcfsim.h
index 522e513c2bc..b0c7736f7a9 100644
--- a/include/asm-m68knommu/mcfsim.h
+++ b/include/asm-m68knommu/mcfsim.h
@@ -15,13 +15,15 @@
#include <linux/config.h>
/*
- * Include 5204, 5206/e, 5249, 5270/5271, 5272, 5280/5282, 5307 or
- * 5407 specific addresses.
+ * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
+ * 5307 or 5407 specific addresses.
*/
#if defined(CONFIG_M5204)
#include <asm/m5204sim.h>
#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
#include <asm/m5206sim.h>
+#elif defined(CONFIG_M523x)
+#include <asm/m523xsim.h>
#elif defined(CONFIG_M5249)
#include <asm/m5249sim.h>
#elif defined(CONFIG_M527x)
diff --git a/include/asm-m68knommu/mcfuart.h b/include/asm-m68knommu/mcfuart.h
index 54d4a85f4fd..9c1210613bc 100644
--- a/include/asm-m68knommu/mcfuart.h
+++ b/include/asm-m68knommu/mcfuart.h
@@ -29,7 +29,7 @@
#define MCFUART_BASE1 0x140 /* Base address of UART1 */
#define MCFUART_BASE2 0x180 /* Base address of UART2 */
#endif
-#elif defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define MCFUART_BASE1 0x200 /* Base address of UART1 */
#define MCFUART_BASE2 0x240 /* Base address of UART2 */
#define MCFUART_BASE3 0x280 /* Base address of UART3 */
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index b90b11d0b88..3f2470e9e67 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -49,7 +49,4 @@ do { \
extern void arch_init_irq(void);
-struct irqaction;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
#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 00000000000..dd9832313af
--- /dev/null
+++ b/include/asm-mips/vr41xx/tb0287.h
@@ -0,0 +1,43 @@
+/*
+ * tb0287.h, Include file for TANBAC TB0287 mini-ITX board.
+ *
+ * Copyright (C) 2005 Media Lab Inc. <ito@mlb.co.jp>
+ *
+ * This code is largely based on tb0219.h.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __TANBAC_TB0287_H
+#define __TANBAC_TB0287_H
+
+#include <asm/vr41xx/vr41xx.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define TB0287_PCI_SLOT_PIN 2
+#define TB0287_SM501_PIN 3
+#define TB0287_SIL680A_PIN 8
+#define TB0287_RTL8110_PIN 13
+
+/*
+ * Interrupt Number
+ */
+#define TB0287_PCI_SLOT_IRQ GIU_IRQ(TB0287_PCI_SLOT_PIN)
+#define TB0287_SM501_IRQ GIU_IRQ(TB0287_SM501_PIN)
+#define TB0287_SIL680A_IRQ GIU_IRQ(TB0287_SIL680A_PIN)
+#define TB0287_RTL8110_IRQ GIU_IRQ(TB0287_RTL8110_PIN)
+
+#endif /* __TANBAC_TB0287_H */
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 98d79a3d54f..d0b761f690b 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -257,6 +257,19 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h
index 862708a749b..b70d6e53b30 100644
--- a/include/asm-powerpc/8253pit.h
+++ b/include/asm-powerpc/8253pit.h
@@ -1,10 +1,10 @@
+#ifndef _ASM_POWERPC_8253PIT_H
+#define _ASM_POWERPC_8253PIT_H
+
/*
* 8253/8254 Programmable Interval Timer
*/
-#ifndef _8253PIT_H
-#define _8253PIT_H
-
#define PIT_TICK_RATE 1193182UL
-#endif
+#endif /* _ASM_POWERPC_8253PIT_H */
diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h
index ca9e423307f..885b4631a6c 100644
--- a/include/asm-powerpc/agp.h
+++ b/include/asm-powerpc/agp.h
@@ -1,10 +1,8 @@
-#ifndef AGP_H
-#define AGP_H 1
+#ifndef _ASM_POWERPC_AGP_H
+#define _ASM_POWERPC_AGP_H
#include <asm/io.h>
-/* nothing much needed here */
-
#define map_page_into_agp(page)
#define unmap_page_from_agp(page)
#define flush_agp_mappings()
@@ -20,4 +18,4 @@
#define free_gatt_pages(table, order) \
free_pages((unsigned long)(table), (order))
-#endif
+#endif /* _ASM_POWERPC_AGP_H */
diff --git a/include/asm-powerpc/bugs.h b/include/asm-powerpc/bugs.h
index 310187d0e33..42fdb73e306 100644
--- a/include/asm-powerpc/bugs.h
+++ b/include/asm-powerpc/bugs.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_BUGS_H
-#define _POWERPC_BUGS_H
+#ifndef _ASM_POWERPC_BUGS_H
+#define _ASM_POWERPC_BUGS_H
/*
* This program is free software; you can redistribute it and/or
@@ -13,6 +13,6 @@
* architecture-dependent bugs.
*/
-extern void check_bugs(void);
+static inline void check_bugs(void) { }
-#endif /* _POWERPC_BUGS_H */
+#endif /* _ASM_POWERPC_BUGS_H */
diff --git a/include/asm-powerpc/errno.h b/include/asm-powerpc/errno.h
index 19f20bd41ae..8c145fd17d8 100644
--- a/include/asm-powerpc/errno.h
+++ b/include/asm-powerpc/errno.h
@@ -1,5 +1,5 @@
-#ifndef _PPC_ERRNO_H
-#define _PPC_ERRNO_H
+#ifndef _ASM_POWERPC_ERRNO_H
+#define _ASM_POWERPC_ERRNO_H
#include <asm-generic/errno.h>
@@ -8,4 +8,4 @@
#define _LAST_ERRNO 516
-#endif
+#endif /* _ASM_POWERPC_ERRNO_H */
diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h
index 93c6acfdd0f..8eb99848c40 100644
--- a/include/asm-powerpc/ioctl.h
+++ b/include/asm-powerpc/ioctl.h
@@ -1,5 +1,5 @@
-#ifndef _PPC_IOCTL_H
-#define _PPC_IOCTL_H
+#ifndef _ASM_POWERPC_IOCTL_H
+#define _ASM_POWERPC_IOCTL_H
/*
@@ -66,4 +66,4 @@ extern unsigned int __invalid_size_argument_for_IOC;
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-#endif
+#endif /* _ASM_POWERPC_IOCTL_H */
diff --git a/include/asm-powerpc/ioctls.h b/include/asm-powerpc/ioctls.h
index f5b7f2b055e..5b94ff489b8 100644
--- a/include/asm-powerpc/ioctls.h
+++ b/include/asm-powerpc/ioctls.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_PPC_IOCTLS_H
-#define _ASM_PPC_IOCTLS_H
+#ifndef _ASM_POWERPC_IOCTLS_H
+#define _ASM_POWERPC_IOCTLS_H
#include <asm/ioctl.h>
@@ -104,4 +104,4 @@
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#endif /* _ASM_PPC_IOCTLS_H */
+#endif /* _ASM_POWERPC_IOCTLS_H */
diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h
index 291c2d01c44..e1c4ac1cc4b 100644
--- a/include/asm-powerpc/linkage.h
+++ b/include/asm-powerpc/linkage.h
@@ -1,6 +1,6 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
+#ifndef _ASM_POWERPC_LINKAGE_H
+#define _ASM_POWERPC_LINKAGE_H
/* Nothing to see here... */
-#endif
+#endif /* _ASM_POWERPC_LINKAGE_H */
diff --git a/include/asm-powerpc/mc146818rtc.h b/include/asm-powerpc/mc146818rtc.h
index a5619a2a139..f2741c8b59a 100644
--- a/include/asm-powerpc/mc146818rtc.h
+++ b/include/asm-powerpc/mc146818rtc.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_MC146818RTC_H
-#define _POWERPC_MC146818RTC_H
+#ifndef _ASM_POWERPC_MC146818RTC_H
+#define _ASM_POWERPC_MC146818RTC_H
/*
* Machine dependent access functions for RTC registers.
@@ -33,4 +33,4 @@ outb_p((val),RTC_PORT(1)); \
})
#endif /* __KERNEL__ */
-#endif /* _POWERPC_MC146818RTC_H */
+#endif /* _ASM_POWERPC_MC146818RTC_H */
diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h
index f2d55988d74..f5e5342fcac 100644
--- a/include/asm-powerpc/mman.h
+++ b/include/asm-powerpc/mman.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_MMAN_H
-#define _POWERPC_MMAN_H
+#ifndef _ASM_POWERPC_MMAN_H
+#define _ASM_POWERPC_MMAN_H
/*
* This program is free software; you can redistribute it and/or
@@ -49,4 +49,4 @@
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FILE 0
-#endif /* _POWERPC_MMAN_H */
+#endif /* _ASM_POWERPC_MMAN_H */
diff --git a/include/asm-powerpc/module.h b/include/asm-powerpc/module.h
index 4438f4fd652..7ecd05e0305 100644
--- a/include/asm-powerpc/module.h
+++ b/include/asm-powerpc/module.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_MODULE_H
-#define _POWERPC_MODULE_H
+#ifndef _ASM_POWERPC_MODULE_H
+#define _ASM_POWERPC_MODULE_H
/*
* This program is free software; you can redistribute it and/or
@@ -74,4 +74,4 @@ struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
struct exception_table_entry *finish);
-#endif /* _POWERPC_MODULE_H */
+#endif /* _ASM_POWERPC_MODULE_H */
diff --git a/include/asm-ppc/msgbuf.h b/include/asm-powerpc/msgbuf.h
index 1053452a937..dd76743c753 100644
--- a/include/asm-ppc/msgbuf.h
+++ b/include/asm-powerpc/msgbuf.h
@@ -1,17 +1,25 @@
-#ifndef _PPC_MSGBUF_H
-#define _PPC_MSGBUF_H
+#ifndef _ASM_POWERPC_MSGBUF_H
+#define _ASM_POWERPC_MSGBUF_H
/*
- * The msqid64_ds structure for the PPC architecture.
+ * The msqid64_ds structure for the PowerPC architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
*/
struct msqid64_ds {
struct ipc64_perm msg_perm;
+#ifndef __powerpc64__
unsigned int __unused1;
+#endif
__kernel_time_t msg_stime; /* last msgsnd time */
+#ifndef __powerpc64__
unsigned int __unused2;
+#endif
__kernel_time_t msg_rtime; /* last msgrcv time */
+#ifndef __powerpc64__
unsigned int __unused3;
+#endif
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_cbytes; /* current number of bytes on queue */
unsigned long msg_qnum; /* number of messages in queue */
@@ -22,4 +30,4 @@ struct msqid64_ds {
unsigned long __unused5;
};
-#endif /* _PPC_MSGBUF_H */
+#endif /* _ASM_POWERPC_MSGBUF_H */
diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h
index 29c9ec83213..657443474a6 100644
--- a/include/asm-powerpc/namei.h
+++ b/include/asm-powerpc/namei.h
@@ -1,14 +1,14 @@
+#ifndef _ASM_POWERPC_NAMEI_H
+#define _ASM_POWERPC_NAMEI_H
+
+#ifdef __KERNEL__
+
/*
- * include/asm-ppc/namei.h
* Adapted from include/asm-alpha/namei.h
*
* Included from fs/namei.c
*/
-#ifdef __KERNEL__
-#ifndef __PPC_NAMEI_H
-#define __PPC_NAMEI_H
-
/* This dummy routine maybe changed to something useful
* for /usr/gnemul/ emulation stuff.
* Look at asm-sparc/namei.h for details.
@@ -16,5 +16,5 @@
#define __emul_prefix() NULL
-#endif /* __PPC_NAMEI_H */
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_NAMEI_H */
diff --git a/include/asm-ppc/param.h b/include/asm-powerpc/param.h
index 6198b1657a4..bdc724f7088 100644
--- a/include/asm-ppc/param.h
+++ b/include/asm-powerpc/param.h
@@ -1,10 +1,10 @@
-#ifndef _ASM_PPC_PARAM_H
-#define _ASM_PPC_PARAM_H
+#ifndef _ASM_POWERPC_PARAM_H
+#define _ASM_POWERPC_PARAM_H
#include <linux/config.h>
#ifdef __KERNEL__
-#define HZ CONFIG_HZ /* internal timer frequency */
+#define HZ CONFIG_HZ /* internal kernel timer frequency */
#define USER_HZ 100 /* for user interfaces in "ticks" */
#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
#endif /* __KERNEL__ */
@@ -21,4 +21,4 @@
#define MAXHOSTNAMELEN 64 /* max length of hostname */
-#endif
+#endif /* _ASM_POWERPC_PARAM_H */
diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h
index be5024913c6..edd2054da86 100644
--- a/include/asm-powerpc/poll.h
+++ b/include/asm-powerpc/poll.h
@@ -1,5 +1,5 @@
-#ifndef __PPC_POLL_H
-#define __PPC_POLL_H
+#ifndef _ASM_POWERPC_POLL_H
+#define _ASM_POWERPC_POLL_H
#define POLLIN 0x0001
#define POLLPRI 0x0002
@@ -20,4 +20,4 @@ struct pollfd {
short revents;
};
-#endif
+#endif /* _ASM_POWERPC_POLL_H */
diff --git a/include/asm-powerpc/sembuf.h b/include/asm-powerpc/sembuf.h
index c98fc18fe80..99a41938ae3 100644
--- a/include/asm-powerpc/sembuf.h
+++ b/include/asm-powerpc/sembuf.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_SEMBUF_H
-#define _POWERPC_SEMBUF_H
+#ifndef _ASM_POWERPC_SEMBUF_H
+#define _ASM_POWERPC_SEMBUF_H
/*
* This program is free software; you can redistribute it and/or
@@ -33,4 +33,4 @@ struct semid64_ds {
unsigned long __unused4;
};
-#endif /* _POWERPC_SEMBUF_H */
+#endif /* _ASM_POWERPC_SEMBUF_H */
diff --git a/include/asm-powerpc/setup.h b/include/asm-powerpc/setup.h
new file mode 100644
index 00000000000..3d9740aae01
--- /dev/null
+++ b/include/asm-powerpc/setup.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_POWERPC_SETUP_H
+#define _ASM_POWERPC_SETUP_H
+
+#ifdef __KERNEL__
+
+#define COMMAND_LINE_SIZE 512
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SETUP_H */
diff --git a/include/asm-powerpc/shmbuf.h b/include/asm-powerpc/shmbuf.h
index 29632db3b17..8efa39698b6 100644
--- a/include/asm-powerpc/shmbuf.h
+++ b/include/asm-powerpc/shmbuf.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_SHMBUF_H
-#define _POWERPC_SHMBUF_H
+#ifndef _ASM_POWERPC_SHMBUF_H
+#define _ASM_POWERPC_SHMBUF_H
/*
* This program is free software; you can redistribute it and/or
@@ -21,19 +21,19 @@
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
-#ifndef __power64__
+#ifndef __powerpc64__
unsigned long __unused1;
#endif
__kernel_time_t shm_atime; /* last attach time */
-#ifndef __power64__
+#ifndef __powerpc64__
unsigned long __unused2;
#endif
__kernel_time_t shm_dtime; /* last detach time */
-#ifndef __power64__
+#ifndef __powerpc64__
unsigned long __unused3;
#endif
__kernel_time_t shm_ctime; /* last change time */
-#ifndef __power64__
+#ifndef __powerpc64__
unsigned long __unused4;
#endif
size_t shm_segsz; /* size of segment (bytes) */
@@ -56,4 +56,4 @@ struct shminfo64 {
unsigned long __unused4;
};
-#endif /* _POWERPC_SHMBUF_H */
+#endif /* _ASM_POWERPC_SHMBUF_H */
diff --git a/include/asm-powerpc/shmparam.h b/include/asm-powerpc/shmparam.h
index d6250602ae6..5cda42a6d39 100644
--- a/include/asm-powerpc/shmparam.h
+++ b/include/asm-powerpc/shmparam.h
@@ -1,6 +1,6 @@
-#ifndef _PPC_SHMPARAM_H
-#define _PPC_SHMPARAM_H
+#ifndef _ASM_POWERPC_SHMPARAM_H
+#define _ASM_POWERPC_SHMPARAM_H
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
-#endif /* _PPC_SHMPARAM_H */
+#endif /* _ASM_POWERPC_SHMPARAM_H */
diff --git a/include/asm-powerpc/siginfo.h b/include/asm-powerpc/siginfo.h
index ae70b8010b1..538ea8ef509 100644
--- a/include/asm-powerpc/siginfo.h
+++ b/include/asm-powerpc/siginfo.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_SIGINFO_H
-#define _POWERPC_SIGINFO_H
+#ifndef _ASM_POWERPC_SIGINFO_H
+#define _ASM_POWERPC_SIGINFO_H
/*
* This program is free software; you can redistribute it and/or
@@ -15,4 +15,4 @@
#include <asm-generic/siginfo.h>
-#endif /* _POWERPC_SIGINFO_H */
+#endif /* _ASM_POWERPC_SIGINFO_H */
diff --git a/include/asm-powerpc/socket.h b/include/asm-powerpc/socket.h
index 51a0cf5ee9f..e4b8177d4ac 100644
--- a/include/asm-powerpc/socket.h
+++ b/include/asm-powerpc/socket.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_SOCKET_H
-#define _POWERPC_SOCKET_H
+#ifndef _ASM_POWERPC_SOCKET_H
+#define _ASM_POWERPC_SOCKET_H
/*
* This program is free software; you can redistribute it and/or
@@ -56,4 +56,4 @@
#define SO_PEERSEC 31
-#endif /* _POWERPC_SOCKET_H */
+#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/include/asm-powerpc/sockios.h b/include/asm-powerpc/sockios.h
index ef7ff664167..590078d8ed2 100644
--- a/include/asm-powerpc/sockios.h
+++ b/include/asm-powerpc/sockios.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_SOCKIOS_H
-#define _POWERPC_SOCKIOS_H
+#ifndef _ASM_POWERPC_SOCKIOS_H
+#define _ASM_POWERPC_SOCKIOS_H
/*
* This program is free software; you can redistribute it and/or
@@ -16,4 +16,4 @@
#define SIOCATMARK 0x8905
#define SIOCGSTAMP 0x8906 /* Get stamp */
-#endif /* _POWERPC_SOCKIOS_H */
+#endif /* _ASM_POWERPC_SOCKIOS_H */
diff --git a/include/asm-powerpc/string.h b/include/asm-powerpc/string.h
index 22557599739..8606a696c08 100644
--- a/include/asm-powerpc/string.h
+++ b/include/asm-powerpc/string.h
@@ -1,5 +1,5 @@
-#ifndef _PPC_STRING_H_
-#define _PPC_STRING_H_
+#ifndef _ASM_POWERPC_STRING_H
+#define _ASM_POWERPC_STRING_H
#ifdef __KERNEL__
@@ -29,4 +29,4 @@ extern void * memchr(const void *,int,__kernel_size_t);
#endif /* __KERNEL__ */
-#endif
+#endif /* _ASM_POWERPC_STRING_H */
diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h
index 2c5bf85a8c3..ebf6055481d 100644
--- a/include/asm-powerpc/termbits.h
+++ b/include/asm-powerpc/termbits.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_TERMBITS_H
-#define _POWERPC_TERMBITS_H
+#ifndef _ASM_POWERPC_TERMBITS_H
+#define _ASM_POWERPC_TERMBITS_H
/*
* This program is free software; you can redistribute it and/or
@@ -188,4 +188,4 @@ struct termios {
#define TCSADRAIN 1
#define TCSAFLUSH 2
-#endif /* _POWERPC_TERMBITS_H */
+#endif /* _ASM_POWERPC_TERMBITS_H */
diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h
index 237533bb0e9..c5b8e5358f8 100644
--- a/include/asm-powerpc/termios.h
+++ b/include/asm-powerpc/termios.h
@@ -1,5 +1,5 @@
-#ifndef _POWERPC_TERMIOS_H
-#define _POWERPC_TERMIOS_H
+#ifndef _ASM_POWERPC_TERMIOS_H
+#define _ASM_POWERPC_TERMIOS_H
/*
* Liberally adapted from alpha/termios.h. In particular, the c_cc[]
@@ -233,4 +233,4 @@ struct termio {
#endif /* __KERNEL__ */
-#endif /* _POWERPC_TERMIOS_H */
+#endif /* _ASM_POWERPC_TERMIOS_H */
diff --git a/include/asm-ppc/timex.h b/include/asm-powerpc/timex.h
index cffc8712077..51c5b316be5 100644
--- a/include/asm-ppc/timex.h
+++ b/include/asm-powerpc/timex.h
@@ -1,11 +1,11 @@
+#ifndef _ASM_POWERPC_TIMEX_H
+#define _ASM_POWERPC_TIMEX_H
+
+#ifdef __KERNEL__
+
/*
- * include/asm-ppc/timex.h
- *
- * ppc architecture timex specifications
+ * PowerPC architecture timex specifications
*/
-#ifdef __KERNEL__
-#ifndef _ASMppc_TIMEX_H
-#define _ASMppc_TIMEX_H
#include <linux/config.h>
#include <asm/cputable.h>
@@ -14,14 +14,21 @@
typedef unsigned long cycles_t;
-/*
- * For the "cycle" counter we use the timebase lower half.
- * Currently only used on SMP.
- */
-
static inline cycles_t get_cycles(void)
{
- cycles_t ret = 0;
+ cycles_t ret;
+
+#ifdef __powerpc64__
+
+ __asm__ __volatile__("mftb %0" : "=r" (ret) : );
+
+#else
+ /*
+ * For the "cycle" counter we use the timebase lower half.
+ * Currently only used on SMP.
+ */
+
+ ret = 0;
__asm__ __volatile__(
"98: mftb %0\n"
@@ -33,8 +40,10 @@ static inline cycles_t get_cycles(void)
" .long 99b\n"
".previous"
: "=r" (ret) : "i" (CPU_FTR_601));
+#endif
+
return ret;
}
-#endif
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_TIMEX_H */
diff --git a/include/asm-ppc64/topology.h b/include/asm-powerpc/topology.h
index 1e9b1907323..2512e3836bf 100644
--- a/include/asm-ppc64/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -1,11 +1,12 @@
-#ifndef _ASM_PPC64_TOPOLOGY_H
-#define _ASM_PPC64_TOPOLOGY_H
+#ifndef _ASM_POWERPC_TOPOLOGY_H
+#define _ASM_POWERPC_TOPOLOGY_H
#include <linux/config.h>
-#include <asm/mmzone.h>
#ifdef CONFIG_NUMA
+#include <asm/mmzone.h>
+
static inline int cpu_to_node(int cpu)
{
int node;
@@ -66,4 +67,4 @@ static inline int node_to_first_cpu(int node)
#endif /* CONFIG_NUMA */
-#endif /* _ASM_PPC64_TOPOLOGY_H */
+#endif /* _ASM_POWERPC_TOPOLOGY_H */
diff --git a/include/asm-powerpc/unaligned.h b/include/asm-powerpc/unaligned.h
index 45520d9b85d..6c95dfa2652 100644
--- a/include/asm-powerpc/unaligned.h
+++ b/include/asm-powerpc/unaligned.h
@@ -1,6 +1,7 @@
+#ifndef _ASM_POWERPC_UNALIGNED_H
+#define _ASM_POWERPC_UNALIGNED_H
+
#ifdef __KERNEL__
-#ifndef __PPC_UNALIGNED_H
-#define __PPC_UNALIGNED_H
/*
* The PowerPC can do unaligned accesses itself in big endian mode.
@@ -14,5 +15,5 @@
#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
-#endif
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_UNALIGNED_H */
diff --git a/include/asm-ppc/user.h b/include/asm-powerpc/user.h
index d662b215137..e59ade4b3df 100644
--- a/include/asm-ppc/user.h
+++ b/include/asm-powerpc/user.h
@@ -1,13 +1,14 @@
-#ifdef __KERNEL__
-#ifndef _PPC_USER_H
-#define _PPC_USER_H
+#ifndef _ASM_POWERPC_USER_H
+#define _ASM_POWERPC_USER_H
-/* Adapted from <asm-alpha/user.h> */
+#ifdef __KERNEL__
-#include <linux/ptrace.h>
+#include <asm/ptrace.h>
#include <asm/page.h>
/*
+ * Adapted from <asm-alpha/user.h>
+ *
* Core file format: The core file is written in such a way that gdb
* can understand it and provide useful information to the user (under
* linux we use the `trad-core' bfd, NOT the osf-core). The file contents
@@ -50,5 +51,5 @@ struct user {
#define HOST_DATA_START_ADDR (u.start_data)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
-#endif /* _PPC_USER_H */
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_USER_H */
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index b4b270457ed..55752474d0d 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];
extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
extern atomic_t ppc_n_lost_interrupts;
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
#endif /* _ASM_IRQ_H */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index a811e440c97..9dd06cd4009 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -109,6 +109,19 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
extern void pcibios_add_platform_entries(struct pci_dev *dev);
struct file;
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
index 88b4222154d..73c33e3ef9c 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-ppc/reg.h
@@ -366,12 +366,6 @@
#define PVR_STB03XXX 0x40310000
#define PVR_NP405H 0x41410000
#define PVR_NP405L 0x41610000
-#define PVR_440GP_RB 0x40120440
-#define PVR_440GP_RC1 0x40120481
-#define PVR_440GP_RC2 0x40200481
-#define PVR_440GX_RA 0x51b21850
-#define PVR_440GX_RB 0x51b21851
-#define PVR_440GX_RC 0x51b21892
#define PVR_601 0x00010000
#define PVR_602 0x00050000
#define PVR_603 0x00030000
diff --git a/include/asm-ppc/setup.h b/include/asm-ppc/setup.h
deleted file mode 100644
index d2d19ee103d..00000000000
--- a/include/asm-ppc/setup.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifdef __KERNEL__
-#ifndef _PPC_SETUP_H
-#define _PPC_SETUP_H
-
-#define m68k_num_memory num_memory
-#define m68k_memory memory
-
-#include <asm-m68k/setup.h>
-/* We have a bigger command line buffer. */
-#undef COMMAND_LINE_SIZE
-#define COMMAND_LINE_SIZE 512
-
-#endif /* _PPC_SETUP_H */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/topology.h b/include/asm-ppc/topology.h
deleted file mode 100644
index 6a029bbba6e..00000000000
--- a/include/asm-ppc/topology.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_PPC_TOPOLOGY_H
-#define _ASM_PPC_TOPOLOGY_H
-
-#include <asm-generic/topology.h>
-
-#endif /* _ASM_PPC_TOPOLOGY_H */
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
index 94298b106a4..40c8eb57493 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)
static inline void eeh_memset_io(volatile void __iomem *addr, int c,
unsigned long n)
{
+ void *p = (void __force *)addr;
u32 lc = c;
lc |= lc << 8;
lc |= lc << 16;
- while(n && !EEH_CHECK_ALIGN(addr, 4)) {
- *((volatile u8 *)addr) = c;
- addr = (void *)((unsigned long)addr + 1);
+ while(n && !EEH_CHECK_ALIGN(p, 4)) {
+ *((volatile u8 *)p) = c;
+ p++;
n--;
}
while(n >= 4) {
- *((volatile u32 *)addr) = lc;
- addr = (void *)((unsigned long)addr + 4);
+ *((volatile u32 *)p) = lc;
+ p += 4;
n -= 4;
}
while(n) {
- *((volatile u8 *)addr) = c;
- addr = (void *)((unsigned long)addr + 1);
+ *((volatile u8 *)p) = c;
+ p++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
@@ -250,22 +251,22 @@ static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *sr
while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
*((u8 *)dest) = *((volatile u8 *)vsrc);
__asm__ __volatile__ ("eieio" : : : "memory");
- vsrc = (void *)((unsigned long)vsrc + 1);
- dest = (void *)((unsigned long)dest + 1);
+ vsrc++;
+ dest++;
n--;
}
while(n > 4) {
*((u32 *)dest) = *((volatile u32 *)vsrc);
__asm__ __volatile__ ("eieio" : : : "memory");
- vsrc = (void *)((unsigned long)vsrc + 4);
- dest = (void *)((unsigned long)dest + 4);
+ vsrc += 4;
+ dest += 4;
n -= 4;
}
while(n) {
*((u8 *)dest) = *((volatile u8 *)vsrc);
__asm__ __volatile__ ("eieio" : : : "memory");
- vsrc = (void *)((unsigned long)vsrc + 1);
- dest = (void *)((unsigned long)dest + 1);
+ vsrc++;
+ dest++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
@@ -286,20 +287,20 @@ static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
*((volatile u8 *)vdest) = *((u8 *)src);
- src = (void *)((unsigned long)src + 1);
- vdest = (void *)((unsigned long)vdest + 1);
+ src++;
+ vdest++;
n--;
}
while(n > 4) {
*((volatile u32 *)vdest) = *((volatile u32 *)src);
- src = (void *)((unsigned long)src + 4);
- vdest = (void *)((unsigned long)vdest + 4);
+ src += 4;
+ vdest += 4;
n-=4;
}
while(n) {
*((volatile u8 *)vdest) = *((u8 *)src);
- src = (void *)((unsigned long)src + 1);
- vdest = (void *)((unsigned long)vdest + 1);
+ src++;
+ vdest++;
n--;
}
__asm__ __volatile__ ("sync" : : : "memory");
diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
index aba1dfa388b..59c958aea4d 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-ppc64/io.h
@@ -20,10 +20,10 @@
#include <asm-generic/iomap.h>
-#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 *)(p), (a), (c))
-#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 *)(p), (a), (c))
-#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 *)(p), (a), (c))
-#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 *)(p), (a), (c))
+#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c))
+#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c))
+#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c))
+#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c))
#define SIO_CONFIG_RA 0x398
@@ -71,8 +71,8 @@ extern unsigned long io_page_mask;
* Neither do the standard versions now, these are just here
* for older code.
*/
-#define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
-#define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
+#define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
+#define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
#else
static 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)
#define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns))
#define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl))
-#define outsb(port, buf, ns) _outsb((u8 *)((port)+pci_io_base), (buf), (ns))
-#define outsw(port, buf, ns) _outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
-#define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
+#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
+#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
+#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
#endif
@@ -147,16 +147,16 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
#define readl_relaxed(addr) readl(addr)
#define readq_relaxed(addr) readq(addr)
-extern void _insb(volatile u8 *port, void *buf, int ns);
-extern void _outsb(volatile u8 *port, const void *buf, int ns);
-extern void _insw(volatile u16 *port, void *buf, int ns);
-extern void _outsw(volatile u16 *port, const void *buf, int ns);
-extern void _insl(volatile u32 *port, void *buf, int nl);
-extern void _outsl(volatile u32 *port, const void *buf, int nl);
-extern void _insw_ns(volatile u16 *port, void *buf, int ns);
-extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
-extern void _insl_ns(volatile u32 *port, void *buf, int nl);
-extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
+extern void _insb(volatile u8 __iomem *port, void *buf, int ns);
+extern void _outsb(volatile u8 __iomem *port, const void *buf, int ns);
+extern void _insw(volatile u16 __iomem *port, void *buf, int ns);
+extern void _outsw(volatile u16 __iomem *port, const void *buf, int ns);
+extern void _insl(volatile u32 __iomem *port, void *buf, int nl);
+extern void _outsl(volatile u32 __iomem *port, const void *buf, int nl);
+extern void _insw_ns(volatile u16 __iomem *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 __iomem *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, int nl);
#define mmiowb()
@@ -176,8 +176,8 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
* Neither do the standard versions now, these are just here
* for older code.
*/
-#define outsw_ns(port, buf, ns) _outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
-#define outsl_ns(port, buf, nl) _outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
+#define outsw_ns(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
+#define outsl_ns(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
#define IO_SPACE_LIMIT ~(0UL)
diff --git a/include/asm-ppc64/msgbuf.h b/include/asm-ppc64/msgbuf.h
deleted file mode 100644
index 31c1cbf133c..00000000000
--- a/include/asm-ppc64/msgbuf.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _PPC64_MSGBUF_H
-#define _PPC64_MSGBUF_H
-
-/*
- * The msqid64_ds structure for the PPC architecture.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-struct msqid64_ds {
- struct ipc64_perm msg_perm;
- __kernel_time_t msg_stime; /* last msgsnd time */
- __kernel_time_t msg_rtime; /* last msgrcv time */
- __kernel_time_t msg_ctime; /* last change time */
- unsigned long msg_cbytes; /* current number of bytes on queue */
- unsigned long msg_qnum; /* number of messages in queue */
- unsigned long msg_qbytes; /* max number of bytes on queue */
- __kernel_pid_t msg_lspid; /* pid of last msgsnd */
- __kernel_pid_t msg_lrpid; /* last receive pid */
- unsigned long __unused1;
- unsigned long __unused2;
-};
-
-#endif /* _PPC64_MSGBUF_H */
diff --git a/include/asm-ppc64/param.h b/include/asm-ppc64/param.h
deleted file mode 100644
index 76c212d475b..00000000000
--- a/include/asm-ppc64/param.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _ASM_PPC64_PARAM_H
-#define _ASM_PPC64_PARAM_H
-
-#include <linux/config.h>
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif /* _ASM_PPC64_PARAM_H */
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index c4f9023ea5e..6b4a5b1f695 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -48,19 +48,52 @@ struct pci_controller {
unsigned long dma_window_size;
};
+/*
+ * PCI stuff, for nodes representing PCI devices, pointed to
+ * by device_node->data.
+ */
+struct pci_controller;
+struct iommu_table;
+
+struct pci_dn {
+ int busno; /* for pci devices */
+ int bussubno; /* for pci devices */
+ int devfn; /* for pci devices */
+ int eeh_mode; /* See eeh.h for possible EEH_MODEs */
+ int eeh_config_addr;
+ int eeh_capable; /* from firmware */
+ int eeh_check_count; /* # times driver ignored error */
+ int eeh_freeze_count; /* # times this device froze up. */
+ int eeh_is_bridge; /* device is pci-to-pci bridge */
+
+ int pci_ext_config_space; /* for pci devices */
+ struct pci_controller *phb; /* for pci devices */
+ struct iommu_table *iommu_table; /* for phb's or bridges */
+ struct pci_dev *pcidev; /* back-pointer to the pci device */
+ struct device_node *node; /* back-pointer to the device_node */
+ u32 config_space[16]; /* saved PCI config space */
+};
+
+/* Get the pointer to a device_node's pci_dn */
+#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
+
struct device_node *fetch_dev_dn(struct pci_dev *dev);
-/* Get a device_node from a pci_dev. This code must be fast except in the case
- * where the sysdata is incorrect and needs to be fixed up (hopefully just once)
+/* Get a device_node from a pci_dev. This code must be fast except
+ * in the case where the sysdata is incorrect and needs to be fixed
+ * up (this will only happen once).
+ * In this case the sysdata will have been inherited from a PCI host
+ * bridge or a PCI-PCI bridge further up the tree, so it will point
+ * to a valid struct pci_dn, just not the one we want.
*/
static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
{
struct device_node *dn = dev->sysdata;
+ struct pci_dn *pdn = dn->data;
- if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
+ if (pdn && pdn->devfn == dev->devfn && pdn->busno == dev->bus->number)
return dn; /* fast path. sysdata is good */
- else
- return fetch_dev_dn(dev);
+ return fetch_dev_dn(dev);
}
static 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)
struct device_node *busdn = bus->sysdata;
BUG_ON(busdn == NULL);
- return busdn->phb;
+ return PCI_DN(busdn)->phb;
}
#endif
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index 4d057452f59..a88bbfc2696 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -138,6 +138,19 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+
+ return root;
+}
+
extern int
unmap_bus_range(struct pci_bus *bus);
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index dc5330b3950..c02ec1d6b90 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -116,14 +116,6 @@ struct property {
struct property *next;
};
-/* NOTE: the device_node contains PCI specific info for pci devices.
- * This perhaps could be hung off the device_node with another struct,
- * but for now it is directly in the node. The phb ptr is a good
- * indication of a real PCI node. Other nodes leave these fields zeroed.
- */
-struct pci_controller;
-struct iommu_table;
-
struct device_node {
char *name;
char *type;
@@ -135,16 +127,6 @@ struct device_node {
struct interrupt_info *intrs;
char *full_name;
- /* PCI stuff probably doesn't belong here */
- int busno; /* for pci devices */
- int bussubno; /* for pci devices */
- int devfn; /* for pci devices */
- int eeh_mode; /* See eeh.h for possible EEH_MODEs */
- int eeh_config_addr;
- int pci_ext_config_space; /* for pci devices */
- struct pci_controller *phb; /* for pci devices */
- struct iommu_table *iommu_table; /* for phb's or bridges */
-
struct property *properties;
struct device_node *parent;
struct device_node *child;
@@ -154,6 +136,7 @@ struct device_node {
struct proc_dir_entry *pde; /* this node's proc directory */
struct kref kref;
unsigned long _flags;
+ void *data;
};
extern struct device_node *of_chosen;
diff --git a/include/asm-ppc64/segment.h b/include/asm-ppc64/segment.h
deleted file mode 100644
index d80fb68cc79..00000000000
--- a/include/asm-ppc64/segment.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __PPC64_SEGMENT_H
-#define __PPC64_SEGMENT_H
-
-/* Only here because we have some old header files that expect it.. */
-
-#endif /* __PPC64_SEGMENT_H */
diff --git a/include/asm-ppc64/setup.h b/include/asm-ppc64/setup.h
deleted file mode 100644
index b257b8348c7..00000000000
--- a/include/asm-ppc64/setup.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _PPC_SETUP_H
-#define _PPC_SETUP_H
-
-#define COMMAND_LINE_SIZE 512
-
-#endif /* _PPC_SETUP_H */
diff --git a/include/asm-ppc64/timex.h b/include/asm-ppc64/timex.h
deleted file mode 100644
index 8db4da4064c..00000000000
--- a/include/asm-ppc64/timex.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/include/asm-ppc/timex.h
- *
- * PPC64 architecture timex specifications
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _ASMPPC64_TIMEX_H
-#define _ASMPPC64_TIMEX_H
-
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
- cycles_t ret;
-
- __asm__ __volatile__("mftb %0" : "=r" (ret) : );
- return ret;
-}
-
-#endif
diff --git a/include/asm-ppc64/user.h b/include/asm-ppc64/user.h
deleted file mode 100644
index d7d6554a421..00000000000
--- a/include/asm-ppc64/user.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _PPC_USER_H
-#define _PPC_USER_H
-
-/* Adapted from <asm-alpha/user.h>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <asm/ptrace.h>
-#include <asm/page.h>
-
-/*
- * Core file format: The core file is written in such a way that gdb
- * can understand it and provide useful information to the user (under
- * linux we use the `trad-core' bfd, NOT the osf-core). The file contents
- * are as follows:
- *
- * upage: 1 page consisting of a user struct that tells gdb
- * what is present in the file. Directly after this is a
- * copy of the task_struct, which is currently not used by gdb,
- * but it may come in handy at some point. All of the registers
- * are stored as part of the upage. The upage should always be
- * only one page long.
- * data: The data segment follows next. We use current->end_text to
- * current->brk to pick up all of the user variables, plus any memory
- * that may have been sbrk'ed. No attempt is made to determine if a
- * page is demand-zero or if a page is totally unused, we just cover
- * the entire range. All of the addresses are rounded in such a way
- * that an integral number of pages is written.
- * stack: We need the stack information in order to get a meaningful
- * backtrace. We need to write the data from usp to
- * current->start_stack, so we round each of these in order to be able
- * to write an integer number of pages.
- */
-struct user {
- struct pt_regs regs; /* entire machine state */
- size_t u_tsize; /* text size (pages) */
- size_t u_dsize; /* data size (pages) */
- size_t u_ssize; /* stack size (pages) */
- unsigned long start_code; /* text starting address */
- unsigned long start_data; /* data starting address */
- unsigned long start_stack; /* stack starting address */
- long int signal; /* signal causing core dump */
- struct regs * u_ar0; /* help gdb find registers */
- unsigned long magic; /* identifies a core file */
- char u_comm[32]; /* user command name */
-};
-
-#define NBPG PAGE_SIZE
-#define UPAGES 1
-#define HOST_TEXT_START_ADDR (u.start_code)
-#define HOST_DATA_START_ADDR (u.start_data)
-#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
-
-#endif /* _PPC_USER_H */
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 831e52ee45b..614a8c13b72 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)
#define irq_canonicalize(irq) (irq)
#define irq_demux(irq) __irq_demux(sh_mv.mv_irq_demux(irq))
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
#if defined(CONFIG_CPU_SUBTYPE_SH73180)
#include <asm/irq-sh73180.h>
#endif
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index a4ab0ec7143..89bd71b1c0d 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -269,6 +269,8 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
+
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 5e94c05dc2f..b5417529f6f 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -28,13 +28,48 @@ enum sparc_cpu {
#define ARCH_SUN4C_SUN4 0
#define ARCH_SUN4 0
-extern void mb(void);
-extern void rmb(void);
-extern void wmb(void);
-extern void membar_storeload(void);
-extern void membar_storeload_storestore(void);
-extern void membar_storeload_loadload(void);
-extern void membar_storestore_loadstore(void);
+/* These are here in an effort to more fully work around Spitfire Errata
+ * #51. Essentially, if a memory barrier occurs soon after a mispredicted
+ * branch, the chip can stop executing instructions until a trap occurs.
+ * Therefore, if interrupts are disabled, the chip can hang forever.
+ *
+ * It used to be believed that the memory barrier had to be right in the
+ * delay slot, but a case has been traced recently wherein the memory barrier
+ * was one instruction after the branch delay slot and the chip still hung.
+ * The offending sequence was the following in sym_wakeup_done() of the
+ * sym53c8xx_2 driver:
+ *
+ * call sym_ccb_from_dsa, 0
+ * movge %icc, 0, %l0
+ * brz,pn %o0, .LL1303
+ * mov %o0, %l2
+ * membar #LoadLoad
+ *
+ * The branch has to be mispredicted for the bug to occur. Therefore, we put
+ * the memory barrier explicitly into a "branch always, predicted taken"
+ * delay slot to avoid the problem case.
+ */
+#define membar_safe(type) \
+do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
+ " membar " type "\n" \
+ "1:\n" \
+ : : : "memory"); \
+} while (0)
+
+#define mb() \
+ membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
+#define rmb() \
+ membar_safe("#LoadLoad")
+#define wmb() \
+ membar_safe("#StoreStore")
+#define membar_storeload() \
+ membar_safe("#StoreLoad")
+#define membar_storeload_storestore() \
+ membar_safe("#StoreLoad | #StoreStore")
+#define membar_storeload_loadload() \
+ membar_safe("#StoreLoad | #LoadLoad")
+#define membar_storestore_loadstore() \
+ membar_safe("#StoreStore | #LoadStore")
#endif
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
index 4482657777b..fb724ba37ae 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)
#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
#endif
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
#ifdef CONFIG_HOTPLUG_CPU
#include <linux/cpumask.h>
extern void fixup_irqs(cpumask_t map);
diff --git a/include/linux/bfs_fs.h b/include/linux/bfs_fs.h
index f7f0913cd11..c1237aa92e3 100644
--- a/include/linux/bfs_fs.h
+++ b/include/linux/bfs_fs.h
@@ -14,8 +14,9 @@
#define BFS_INODES_PER_BLOCK 8
/* SVR4 vnode type values (bfs_inode->i_vtype) */
-#define BFS_VDIR 2
-#define BFS_VREG 1
+#define BFS_VDIR 2L
+#define BFS_VREG 1L
+
/* BFS inode layout on disk */
struct bfs_inode {
@@ -58,22 +59,22 @@ struct bfs_super_block {
__u32 s_padding[118];
};
-#define BFS_NZFILESIZE(ip) \
- (((ip)->i_eoffset + 1) - (ip)->i_sblock * BFS_BSIZE)
-
-#define BFS_FILESIZE(ip) \
- ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
-
-#define BFS_FILEBLOCKS(ip) \
- ((ip)->i_sblock == 0 ? 0 : ((ip)->i_eblock + 1) - (ip)->i_sblock)
#define BFS_OFF2INO(offset) \
((((offset) - BFS_BSIZE) / sizeof(struct bfs_inode)) + BFS_ROOT_INO)
#define BFS_INO2OFF(ino) \
((__u32)(((ino) - BFS_ROOT_INO) * sizeof(struct bfs_inode)) + BFS_BSIZE)
+#define BFS_NZFILESIZE(ip) \
+ ((cpu_to_le32((ip)->i_eoffset) + 1) - cpu_to_le32((ip)->i_sblock) * BFS_BSIZE)
+
+#define BFS_FILESIZE(ip) \
+ ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
+#define BFS_FILEBLOCKS(ip) \
+ ((ip)->i_sblock == 0 ? 0 : (cpu_to_le32((ip)->i_eblock) + 1) - cpu_to_le32((ip)->i_sblock))
#define BFS_UNCLEAN(bfs_sb, sb) \
- ((bfs_sb->s_from != -1) && (bfs_sb->s_to != -1) && !(sb->s_flags & MS_RDONLY))
+ ((cpu_to_le32(bfs_sb->s_from) != -1) && (cpu_to_le32(bfs_sb->s_to) != -1) && !(sb->s_flags & MS_RDONLY))
+
#endif /* _LINUX_BFS_FS_H */
diff --git a/include/linux/crc16.h b/include/linux/crc16.h
new file mode 100644
index 00000000000..bdedf825b04
--- /dev/null
+++ b/include/linux/crc16.h
@@ -0,0 +1,44 @@
+/*
+ * crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16, as used with 1-wire devices:
+ * Width 16
+ * Poly 0x8005 (x^16 + x^15 + x^2 + 1)
+ * Init 0
+ *
+ * For 1-wire devices, the CRC is stored inverted, LSB-first
+ *
+ * Example buffer with the CRC attached:
+ * 31 32 33 34 35 36 37 38 39 C2 44
+ *
+ * The CRC over a buffer with the CRC attached is 0xB001.
+ * So, if (crc16(0, buf, size) == 0xB001) then the buffer is valid.
+ *
+ * Refer to "Application Note 937: Book of iButton Standards" for details.
+ * http://www.maxim-ic.com/appnotes.cfm/appnote_number/937
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+#include <linux/types.h>
+
+#define CRC16_INIT 0
+#define CRC16_VALID 0xb001
+
+extern u16 const crc16_table[256];
+
+extern u16 crc16(u16 crc, const u8 *buffer, size_t len);
+
+static inline u16 crc16_byte(u16 crc, const u8 data)
+{
+ return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
+}
+
+#endif /* __CRC16_H */
+
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 007c290f74d..8bf4bacb505 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -432,7 +432,10 @@ struct dccp_sock {
struct ccid *dccps_hc_rx_ccid;
struct ccid *dccps_hc_tx_ccid;
struct dccp_options_received dccps_options_received;
+ struct timeval dccps_epoch;
enum dccp_role dccps_role:2;
+ __u8 dccps_hc_rx_insert_options:1;
+ __u8 dccps_hc_tx_insert_options:1;
};
static inline struct dccp_sock *dccp_sk(const struct sock *sk)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bc24beeed97..82e39cd0c4f 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -107,6 +107,8 @@
#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */
#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */
#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */
+#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
+#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
@@ -495,6 +497,9 @@ struct fb_cursor_user {
#define FB_EVENT_BLANK 0x08
/* Private modelist is to be replaced */
#define FB_EVENT_NEW_MODELIST 0x09
+/* The resolution of the passed in fb_info about to change and
+ all vc's should be changed */
+#define FB_EVENT_MODE_CHANGE_ALL 0x0A
struct fb_event {
struct fb_info *info;
@@ -820,13 +825,29 @@ extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
u32 height, u32 shift_high, u32 shift_low, u32 mod);
extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height);
extern void fb_set_suspend(struct fb_info *info, int state);
-extern int fb_get_color_depth(struct fb_var_screeninfo *var);
+extern int fb_get_color_depth(struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix);
extern int fb_get_options(char *name, char **option);
extern int fb_new_modelist(struct fb_info *info);
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
+static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
+ u8 *src, u32 s_pitch, u32 height)
+{
+ int i, j;
+
+ d_pitch -= s_pitch;
+
+ for (i = height; i--; ) {
+ /* s_pitch is a few bytes at the most, memcpy is suboptimal */
+ for (j = 0; j < s_pitch; j++)
+ *dst++ = *src++;
+ dst += d_pitch;
+ }
+}
+
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern 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,
extern int fb_validate_mode(const struct fb_var_screeninfo *var,
struct fb_info *info);
extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var);
-extern void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs);
+extern const unsigned char *fb_firmware_edid(struct device *device);
+extern void fb_edid_to_monspecs(unsigned char *edid,
+ struct fb_monspecs *specs);
extern void fb_destroy_modedb(struct fb_videomode *modedb);
+extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
/* drivers/video/modedb.c */
#define VESA_MODEDB_SIZE 34
diff --git a/include/linux/file.h b/include/linux/file.h
index 5206beb9a80..f5bbd4c508b 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -9,6 +9,7 @@
#include <linux/posix_types.h>
#include <linux/compiler.h>
#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
/*
* The default fd array needs to be at least BITS_PER_LONG,
@@ -16,23 +17,33 @@
*/
#define NR_OPEN_DEFAULT BITS_PER_LONG
+struct fdtable {
+ unsigned int max_fds;
+ int max_fdset;
+ int next_fd;
+ struct file ** fd; /* current fd array */
+ fd_set *close_on_exec;
+ fd_set *open_fds;
+ struct rcu_head rcu;
+ struct files_struct *free_files;
+ struct fdtable *next;
+};
+
/*
* Open file table structure
*/
struct files_struct {
atomic_t count;
spinlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */
- int max_fds;
- int max_fdset;
- int next_fd;
- struct file ** fd; /* current fd array */
- fd_set *close_on_exec;
- fd_set *open_fds;
+ struct fdtable *fdt;
+ struct fdtable fdtab;
fd_set close_on_exec_init;
fd_set open_fds_init;
struct file * fd_array[NR_OPEN_DEFAULT];
};
+#define files_fdtable(files) (rcu_dereference((files)->fdt))
+
extern void FASTCALL(__fput(struct file *));
extern void FASTCALL(fput(struct file *));
@@ -59,13 +70,16 @@ extern fd_set *alloc_fdset(int);
extern void free_fdset(fd_set *, int);
extern int expand_files(struct files_struct *, int nr);
+extern void free_fdtable(struct fdtable *fdt);
+extern void __init files_defer_init(void);
static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
{
struct file * file = NULL;
+ struct fdtable *fdt = files_fdtable(files);
- if (fd < files->max_fds)
- file = files->fd[fd];
+ if (fd < fdt->max_fds)
+ file = rcu_dereference(fdt->fd[fd]);
return file;
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd93ab7da90..7f61227827d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <linux/limits.h>
#include <linux/ioctl.h>
+#include <linux/rcuref.h>
/*
* It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -597,12 +598,13 @@ struct file {
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
+ struct rcu_head f_rcuhead;
};
extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
#define file_list_unlock() spin_unlock(&files_lock);
-#define get_file(x) atomic_inc(&(x)->f_count)
+#define get_file(x) rcuref_inc(&(x)->f_count)
#define file_count(x) atomic_read(&(x)->f_count)
#define MAX_NON_LFS ((1UL<<31) - 1)
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
new file mode 100644
index 00000000000..acbeb96a335
--- /dev/null
+++ b/include/linux/fuse.h
@@ -0,0 +1,259 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+/* This file defines the kernel interface of FUSE */
+
+#include <asm/types.h>
+
+/** Version number of this interface */
+#define FUSE_KERNEL_VERSION 7
+
+/** Minor version number of this interface */
+#define FUSE_KERNEL_MINOR_VERSION 2
+
+/** The node ID of the root inode */
+#define FUSE_ROOT_ID 1
+
+/** The major number of the fuse character device */
+#define FUSE_MAJOR 10
+
+/** The minor number of the fuse character device */
+#define FUSE_MINOR 229
+
+/* Make sure all structures are padded to 64bit boundary, so 32bit
+ userspace works under 64bit kernels */
+
+struct fuse_attr {
+ __u64 ino;
+ __u64 size;
+ __u64 blocks;
+ __u64 atime;
+ __u64 mtime;
+ __u64 ctime;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 ctimensec;
+ __u32 mode;
+ __u32 nlink;
+ __u32 uid;
+ __u32 gid;
+ __u32 rdev;
+};
+
+struct fuse_kstatfs {
+ __u64 blocks;
+ __u64 bfree;
+ __u64 bavail;
+ __u64 files;
+ __u64 ffree;
+ __u32 bsize;
+ __u32 namelen;
+};
+
+#define FATTR_MODE (1 << 0)
+#define FATTR_UID (1 << 1)
+#define FATTR_GID (1 << 2)
+#define FATTR_SIZE (1 << 3)
+#define FATTR_ATIME (1 << 4)
+#define FATTR_MTIME (1 << 5)
+#define FATTR_CTIME (1 << 6)
+
+/**
+ * Flags returned by the OPEN request
+ *
+ * FOPEN_DIRECT_IO: bypass page cache for this open file
+ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ */
+#define FOPEN_DIRECT_IO (1 << 0)
+#define FOPEN_KEEP_CACHE (1 << 1)
+
+enum fuse_opcode {
+ FUSE_LOOKUP = 1,
+ FUSE_FORGET = 2, /* no reply */
+ FUSE_GETATTR = 3,
+ FUSE_SETATTR = 4,
+ FUSE_READLINK = 5,
+ FUSE_SYMLINK = 6,
+ FUSE_MKNOD = 8,
+ FUSE_MKDIR = 9,
+ FUSE_UNLINK = 10,
+ FUSE_RMDIR = 11,
+ FUSE_RENAME = 12,
+ FUSE_LINK = 13,
+ FUSE_OPEN = 14,
+ FUSE_READ = 15,
+ FUSE_WRITE = 16,
+ FUSE_STATFS = 17,
+ FUSE_RELEASE = 18,
+ FUSE_FSYNC = 20,
+ FUSE_SETXATTR = 21,
+ FUSE_GETXATTR = 22,
+ FUSE_LISTXATTR = 23,
+ FUSE_REMOVEXATTR = 24,
+ FUSE_FLUSH = 25,
+ FUSE_INIT = 26,
+ FUSE_OPENDIR = 27,
+ FUSE_READDIR = 28,
+ FUSE_RELEASEDIR = 29,
+ FUSE_FSYNCDIR = 30
+};
+
+/* Conservative buffer size for the client */
+#define FUSE_MAX_IN 8192
+
+#define FUSE_NAME_MAX 1024
+#define FUSE_SYMLINK_MAX 4096
+#define FUSE_XATTR_SIZE_MAX 4096
+
+struct fuse_entry_out {
+ __u64 nodeid; /* Inode ID */
+ __u64 generation; /* Inode generation: nodeid:gen must
+ be unique for the fs's lifetime */
+ __u64 entry_valid; /* Cache timeout for the name */
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 entry_valid_nsec;
+ __u32 attr_valid_nsec;
+ struct fuse_attr attr;
+};
+
+struct fuse_forget_in {
+ __u64 nlookup;
+};
+
+struct fuse_attr_out {
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 attr_valid_nsec;
+ __u32 dummy;
+ struct fuse_attr attr;
+};
+
+struct fuse_mknod_in {
+ __u32 mode;
+ __u32 rdev;
+};
+
+struct fuse_mkdir_in {
+ __u32 mode;
+ __u32 padding;
+};
+
+struct fuse_rename_in {
+ __u64 newdir;
+};
+
+struct fuse_link_in {
+ __u64 oldnodeid;
+};
+
+struct fuse_setattr_in {
+ __u32 valid;
+ __u32 padding;
+ struct fuse_attr attr;
+};
+
+struct fuse_open_in {
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_open_out {
+ __u64 fh;
+ __u32 open_flags;
+ __u32 padding;
+};
+
+struct fuse_release_in {
+ __u64 fh;
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_flush_in {
+ __u64 fh;
+ __u32 flush_flags;
+ __u32 padding;
+};
+
+struct fuse_read_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_write_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 write_flags;
+};
+
+struct fuse_write_out {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_statfs_out {
+ struct fuse_kstatfs st;
+};
+
+struct fuse_fsync_in {
+ __u64 fh;
+ __u32 fsync_flags;
+ __u32 padding;
+};
+
+struct fuse_setxattr_in {
+ __u32 size;
+ __u32 flags;
+};
+
+struct fuse_getxattr_in {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_getxattr_out {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_init_in_out {
+ __u32 major;
+ __u32 minor;
+};
+
+struct fuse_in_header {
+ __u32 len;
+ __u32 opcode;
+ __u64 unique;
+ __u64 nodeid;
+ __u32 uid;
+ __u32 gid;
+ __u32 pid;
+ __u32 padding;
+};
+
+struct fuse_out_header {
+ __u32 len;
+ __s32 error;
+ __u64 unique;
+};
+
+struct fuse_dirent {
+ __u64 ino;
+ __u64 off;
+ __u32 namelen;
+ __u32 type;
+ char name[0];
+};
+
+#define FUSE_NAME_OFFSET ((unsigned) ((struct fuse_dirent *) 0)->name)
+#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
+#define FUSE_DIRENT_SIZE(d) \
+ 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 00000000000..5f3eaf80222
--- /dev/null
+++ b/include/linux/i2c-pxa.h
@@ -0,0 +1,48 @@
+#ifndef _LINUX_I2C_ALGO_PXA_H
+#define _LINUX_I2C_ALGO_PXA_H
+
+struct i2c_eeprom_emu_watcher {
+ void (*write)(void *, unsigned int addr, unsigned char newval);
+};
+
+struct i2c_eeprom_emu_watch {
+ struct list_head node;
+ unsigned int start;
+ unsigned int end;
+ struct i2c_eeprom_emu_watcher *ops;
+ void *data;
+};
+
+#define I2C_EEPROM_EMU_SIZE (256)
+
+struct i2c_eeprom_emu {
+ unsigned int size;
+ unsigned int ptr;
+ unsigned int seen_start;
+ struct list_head watch;
+
+ unsigned char bytes[I2C_EEPROM_EMU_SIZE];
+};
+
+typedef enum i2c_slave_event_e {
+ I2C_SLAVE_EVENT_START_READ,
+ I2C_SLAVE_EVENT_START_WRITE,
+ I2C_SLAVE_EVENT_STOP
+} i2c_slave_event_t;
+
+struct i2c_slave_client {
+ void *data;
+ void (*event)(void *ptr, i2c_slave_event_t event);
+ int (*read) (void *ptr);
+ void (*write)(void *ptr, unsigned int val);
+};
+
+extern int i2c_eeprom_emu_addwatcher(struct i2c_eeprom_emu *, void *data,
+ unsigned int addr, unsigned int size,
+ struct i2c_eeprom_emu_watcher *);
+
+extern void i2c_eeprom_emu_delwatcher(struct i2c_eeprom_emu *, void *data, struct i2c_eeprom_emu_watcher *watcher);
+
+extern struct i2c_eeprom_emu *i2c_pxa_get_eeprom(void);
+
+#endif /* _LINUX_I2C_ALGO_PXA_H */
diff --git a/include/linux/in6.h b/include/linux/in6.h
index dcf5720ffcb..bd32b79d629 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -148,13 +148,13 @@ struct in6_flowlabel_req
*/
#define IPV6_ADDRFORM 1
-#define IPV6_PKTINFO 2
-#define IPV6_HOPOPTS 3
-#define IPV6_DSTOPTS 4
-#define IPV6_RTHDR 5
-#define IPV6_PKTOPTIONS 6
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
#define IPV6_CHECKSUM 7
-#define IPV6_HOPLIMIT 8
+#define IPV6_2292HOPLIMIT 8
#define IPV6_NEXTHOP 9
#define IPV6_AUTHHDR 10 /* obsolete */
#define IPV6_FLOWINFO 11
@@ -198,4 +198,28 @@ struct in6_flowlabel_req
* MCAST_MSFILTER 48
*/
+/* RFC3542 advanced socket options (50-67) */
+#define IPV6_RECVPKTINFO 50
+#define IPV6_PKTINFO 51
+#if 0
+#define IPV6_RECVPATHMTU 52
+#define IPV6_PATHMTU 53
+#define IPV6_DONTFRAG 54
+#define IPV6_USE_MIN_MTU 55
+#endif
+#define IPV6_RECVHOPOPTS 56
+#define IPV6_HOPOPTS 57
+#if 0
+#define IPV6_RECVRTHDRDSTOPTS 58 /* Unused, see net/ipv6/datagram.c */
+#endif
+#define IPV6_RTHDRDSTOPTS 59
+#define IPV6_RECVRTHDR 60
+#define IPV6_RTHDR 61
+#define IPV6_RECVDSTOPTS 62
+#define IPV6_DSTOPTS 63
+#define IPV6_RECVHOPLIMIT 64
+#define IPV6_HOPLIMIT 65
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
#endif
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index c727c195a91..68ab5f2ab9c 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -2,17 +2,27 @@
#define _LINUX__INIT_TASK_H
#include <linux/file.h>
+#include <linux/rcupdate.h>
-#define INIT_FILES \
-{ \
- .count = ATOMIC_INIT(1), \
- .file_lock = SPIN_LOCK_UNLOCKED, \
+#define INIT_FDTABLE \
+{ \
.max_fds = NR_OPEN_DEFAULT, \
.max_fdset = __FD_SETSIZE, \
.next_fd = 0, \
.fd = &init_files.fd_array[0], \
.close_on_exec = &init_files.close_on_exec_init, \
.open_fds = &init_files.open_fds_init, \
+ .rcu = RCU_HEAD_INIT, \
+ .free_files = NULL, \
+ .next = NULL, \
+}
+
+#define INIT_FILES \
+{ \
+ .count = ATOMIC_INIT(1), \
+ .file_lock = SPIN_LOCK_UNLOCKED, \
+ .fdt = &init_files.fdtab, \
+ .fdtab = INIT_FDTABLE, \
.close_on_exec_init = { { 0, } }, \
.open_fds_init = { { 0, } }, \
.fd_array = { NULL, } \
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 3c7dbc6a0a7..6c5f7b39a4b 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -189,6 +189,7 @@ struct inet6_skb_parm {
__u16 dst0;
__u16 srcrt;
__u16 dst1;
+ __u16 lastopt;
};
#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
@@ -234,14 +235,20 @@ struct ipv6_pinfo {
/* pktoption flags */
union {
struct {
- __u8 srcrt:2,
+ __u16 srcrt:2,
+ osrcrt:2,
rxinfo:1,
+ rxoinfo:1,
rxhlim:1,
+ rxohlim:1,
hopopts:1,
+ ohopopts:1,
dstopts:1,
- rxflow:1;
+ odstopts:1,
+ rxflow:1,
+ rxtclass:1;
} bits;
- __u8 all;
+ __u16 all;
} rxopt;
/* sockopt flags */
@@ -250,6 +257,7 @@ struct ipv6_pinfo {
sndflow:1,
pmtudisc:2,
ipv6only:1;
+ __u8 tclass;
__u32 dst_cookie;
@@ -263,6 +271,7 @@ struct ipv6_pinfo {
struct ipv6_txoptions *opt;
struct rt6_info *rt;
int hop_limit;
+ int tclass;
} cork;
};
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 94a46f38c53..58385ee1c0a 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
extern void numa_default_policy(void);
extern void numa_policy_init(void);
+extern struct mempolicy default_policy;
#else
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6014160d9c0..c1f021eddff 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -109,6 +109,8 @@ struct mmc_host {
struct mmc_card *card_selected; /* the selected MMC card */
struct work_struct detect;
+
+ unsigned long private[0] ____cacheline_aligned;
};
extern struct mmc_host *mmc_alloc_host(int extra, struct device *);
@@ -116,14 +118,18 @@ extern int mmc_add_host(struct mmc_host *);
extern void mmc_remove_host(struct mmc_host *);
extern void mmc_free_host(struct mmc_host *);
-#define mmc_priv(x) ((void *)((x) + 1))
+static inline void *mmc_priv(struct mmc_host *host)
+{
+ return (void *)host->private;
+}
+
#define mmc_dev(x) ((x)->dev)
#define mmc_hostname(x) ((x)->class_dev.class_id)
extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
extern int mmc_resume_host(struct mmc_host *);
-extern void mmc_detect_change(struct mmc_host *);
+extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bc4c40000c0..7349058ed77 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -19,436 +19,10 @@
#include <linux/mod_devicetable.h>
-/*
- * Under PCI, each device has 256 bytes of configuration address space,
- * of which the first 64 bytes are standardized as follows:
- */
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
-#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
-#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
-#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
-#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
-#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
-#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
-#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
-#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
-
-#define PCI_STATUS 0x06 /* 16 bits */
-#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
-#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
-#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
-#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
-#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
-#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
-#define PCI_STATUS_DEVSEL_FAST 0x000
-#define PCI_STATUS_DEVSEL_MEDIUM 0x200
-#define PCI_STATUS_DEVSEL_SLOW 0x400
-#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
-#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
-#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
-#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
-#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
-
-#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
- revision */
-#define PCI_REVISION_ID 0x08 /* Revision ID */
-#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-
-#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
-#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
-#define PCI_HEADER_TYPE 0x0e /* 8 bits */
-#define PCI_HEADER_TYPE_NORMAL 0
-#define PCI_HEADER_TYPE_BRIDGE 1
-#define PCI_HEADER_TYPE_CARDBUS 2
-
-#define PCI_BIST 0x0f /* 8 bits */
-#define PCI_BIST_CODE_MASK 0x0f /* Return result */
-#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
-#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
-
-/*
- * Base addresses specify locations in memory or I/O space.
- * Decoded size can be determined by writing a value of
- * 0xffffffff to the register, and reading it back. Only
- * 1 bits are decoded.
- */
-#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
-#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
-#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
-#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
-#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
-#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
-#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
-#define PCI_BASE_ADDRESS_SPACE_IO 0x01
-#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
-#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
-#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
-#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
-#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
-#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
-#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
-#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
-/* bit 1 is reserved if address_space = 1 */
-
-/* Header type 0 (normal devices) */
-#define PCI_CARDBUS_CIS 0x28
-#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
-#define PCI_SUBSYSTEM_ID 0x2e
-#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
-#define PCI_ROM_ADDRESS_ENABLE 0x01
-#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
-
-#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
-
-/* 0x35-0x3b are reserved */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-/* Header type 1 (PCI-to-PCI bridges) */
-#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
-#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
-#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
-#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
-#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
-#define PCI_IO_LIMIT 0x1d
-#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
-#define PCI_IO_RANGE_TYPE_16 0x00
-#define PCI_IO_RANGE_TYPE_32 0x01
-#define PCI_IO_RANGE_MASK (~0x0fUL)
-#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
-#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
-#define PCI_MEMORY_LIMIT 0x22
-#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
-#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
-#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
-#define PCI_PREF_MEMORY_LIMIT 0x26
-#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
-#define PCI_PREF_RANGE_TYPE_32 0x00
-#define PCI_PREF_RANGE_TYPE_64 0x01
-#define PCI_PREF_RANGE_MASK (~0x0fUL)
-#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
-#define PCI_PREF_LIMIT_UPPER32 0x2c
-#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
-#define PCI_IO_LIMIT_UPPER16 0x32
-/* 0x34 same as for htype 0 */
-/* 0x35-0x3b is reserved */
-#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
-/* 0x3c-0x3d are same as for htype 0 */
-#define PCI_BRIDGE_CONTROL 0x3e
-#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
-#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
-#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
-#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
-#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
-#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
-#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
-
-/* Header type 2 (CardBus bridges) */
-#define PCI_CB_CAPABILITY_LIST 0x14
-/* 0x15 reserved */
-#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
-#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
-#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
-#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
-#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
-#define PCI_CB_MEMORY_BASE_0 0x1c
-#define PCI_CB_MEMORY_LIMIT_0 0x20
-#define PCI_CB_MEMORY_BASE_1 0x24
-#define PCI_CB_MEMORY_LIMIT_1 0x28
-#define PCI_CB_IO_BASE_0 0x2c
-#define PCI_CB_IO_BASE_0_HI 0x2e
-#define PCI_CB_IO_LIMIT_0 0x30
-#define PCI_CB_IO_LIMIT_0_HI 0x32
-#define PCI_CB_IO_BASE_1 0x34
-#define PCI_CB_IO_BASE_1_HI 0x36
-#define PCI_CB_IO_LIMIT_1 0x38
-#define PCI_CB_IO_LIMIT_1_HI 0x3a
-#define PCI_CB_IO_RANGE_MASK (~0x03UL)
-/* 0x3c-0x3d are same as for htype 0 */
-#define PCI_CB_BRIDGE_CONTROL 0x3e
-#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
-#define PCI_CB_BRIDGE_CTL_SERR 0x02
-#define PCI_CB_BRIDGE_CTL_ISA 0x04
-#define PCI_CB_BRIDGE_CTL_VGA 0x08
-#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
-#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
-#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
-#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
-#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
-#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
-#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
-#define PCI_CB_SUBSYSTEM_ID 0x42
-#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
-/* 0x48-0x7f reserved */
-
-/* Capability lists */
-
-#define PCI_CAP_LIST_ID 0 /* Capability ID */
-#define PCI_CAP_ID_PM 0x01 /* Power Management */
-#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
-#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
-#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
-#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
-#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
-#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
-#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
-#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
-#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
-#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
-#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
-#define PCI_CAP_SIZEOF 4
-
-/* Power Management Registers */
-
-#define PCI_PM_PMC 2 /* PM Capabilities Register */
-#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
-#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
-#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
-#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
-#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
-#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
-#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
-#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
-#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
-#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
-#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
-#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
-#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
-#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
-#define PCI_PM_CTRL 4 /* PM control and status register */
-#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
-#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
-#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
-#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
-#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
-#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
-#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
-#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
-#define PCI_PM_DATA_REGISTER 7 /* (??) */
-#define PCI_PM_SIZEOF 8
-
-/* AGP registers */
-
-#define PCI_AGP_VERSION 2 /* BCD version number */
-#define PCI_AGP_RFU 3 /* Rest of capability flags */
-#define PCI_AGP_STATUS 4 /* Status register */
-#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
-#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
-#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
-#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
-#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
-#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
-#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
-#define PCI_AGP_COMMAND 8 /* Control register */
-#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
-#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
-#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
-#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
-#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
-#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
-#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
-#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
-#define PCI_AGP_SIZEOF 12
-
-/* Vital Product Data */
-
-#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
-#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
-#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
-#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
-
-/* Slot Identification */
-
-#define PCI_SID_ESR 2 /* Expansion Slot Register */
-#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
-#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
-#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
-
-/* Message Signalled Interrupts registers */
-
-#define PCI_MSI_FLAGS 2 /* Various flags */
-#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
-#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
-#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
-#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
-#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */
-#define PCI_MSI_RFU 3 /* Rest of capability flags */
-#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
-#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
-#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
-#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
-#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
-
-/* CompactPCI Hotswap Register */
-
-#define PCI_CHSWP_CSR 2 /* Control and Status Register */
-#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
-#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
-#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
-#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
-#define PCI_CHSWP_PI 0x30 /* Programming Interface */
-#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
-#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
-
-/* PCI-X registers */
-
-#define PCI_X_CMD 2 /* Modes & Features */
-#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
-#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
-#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
-#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
-#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
-#define PCI_X_STATUS 4 /* PCI-X capabilities */
-#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
-#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
-#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
-#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
-#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
-#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
-#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
-#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
-#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
-#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
-#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
-#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
-#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
-
-/* PCI Express capability registers */
-
-#define PCI_EXP_FLAGS 2 /* Capabilities register */
-#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
-#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
-#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
-#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
-#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
-#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
-#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
-#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
-#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
-#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
-#define PCI_EXP_DEVCAP 4 /* Device capabilities */
-#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
-#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
-#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
-#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
-#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
-#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
-#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
-#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
-#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
-#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
-#define PCI_EXP_DEVCTL 8 /* Device Control */
-#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
-#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
-#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
-#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
-#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
-#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
-#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
-#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
-#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
-#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
-#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
-#define PCI_EXP_DEVSTA 10 /* Device Status */
-#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
-#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
-#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
-#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
-#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
-#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
-#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
-#define PCI_EXP_LNKCTL 16 /* Link Control */
-#define PCI_EXP_LNKSTA 18 /* Link Status */
-#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
-#define PCI_EXP_SLTCTL 24 /* Slot Control */
-#define PCI_EXP_SLTSTA 26 /* Slot Status */
-#define PCI_EXP_RTCTL 28 /* Root Control */
-#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
-#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
-#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
-#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
-#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
-#define PCI_EXP_RTCAP 30 /* Root Capabilities */
-#define PCI_EXP_RTSTA 32 /* Root Status */
-
-/* Extended Capabilities (PCI-X 2.0 and Express) */
-#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
-#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
-#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
-
-#define PCI_EXT_CAP_ID_ERR 1
-#define PCI_EXT_CAP_ID_VC 2
-#define PCI_EXT_CAP_ID_DSN 3
-#define PCI_EXT_CAP_ID_PWR 4
-
-/* Advanced Error Reporting */
-#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
-#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
-#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
-#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
-#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
-#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
-#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
-#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
-#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
-#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
-#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
-#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
-#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
- /* Same bits as above */
-#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
- /* Same bits as above */
-#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
-#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
-#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
-#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
-#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
-#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
- /* Same bits as above */
-#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
-#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
-#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
-#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
-#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
-#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
-#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
-#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
-#define PCI_ERR_ROOT_STATUS 48
-#define PCI_ERR_ROOT_COR_SRC 52
-#define PCI_ERR_ROOT_SRC 54
-
-/* Virtual Channel */
-#define PCI_VC_PORT_REG1 4
-#define PCI_VC_PORT_REG2 8
-#define PCI_VC_PORT_CTRL 12
-#define PCI_VC_PORT_STATUS 14
-#define PCI_VC_RES_CAP 16
-#define PCI_VC_RES_CTRL 20
-#define PCI_VC_RES_STATUS 26
-
-/* Power Budgeting */
-#define PCI_PWR_DSR 4 /* Data Select Register */
-#define PCI_PWR_DATA 8 /* Data Register */
-#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
-#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
-#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
-#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
-#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
-#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
-#define PCI_PWR_CAP 12 /* Capability */
-#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
+/* Include the pci register defines */
+#include <linux/pci_regs.h>
/* Include the ID list */
-
#include <linux/pci_ids.h>
/*
@@ -496,11 +70,12 @@ enum pci_mmap_state {
typedef int __bitwise pci_power_t;
-#define PCI_D0 ((pci_power_t __force) 0)
-#define PCI_D1 ((pci_power_t __force) 1)
-#define PCI_D2 ((pci_power_t __force) 2)
+#define PCI_D0 ((pci_power_t __force) 0)
+#define PCI_D1 ((pci_power_t __force) 1)
+#define PCI_D2 ((pci_power_t __force) 2)
#define PCI_D3hot ((pci_power_t __force) 3)
#define PCI_D3cold ((pci_power_t __force) 4)
+#define PCI_UNKNOWN ((pci_power_t __force) 5)
#define PCI_POWER_ERROR ((pci_power_t __force) -1)
/*
@@ -562,11 +137,6 @@ struct pci_dev {
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
-#ifdef CONFIG_PCI_NAMES
-#define PCI_NAME_SIZE 255
-#define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */
- char pretty_name[PCI_NAME_SIZE]; /* pretty name for users to see */
-#endif
};
#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
@@ -582,15 +152,15 @@ struct pci_dev {
* 7-10 bridges: address space assigned to buses behind the bridge
*/
-#define PCI_ROM_RESOURCE 6
-#define PCI_BRIDGE_RESOURCES 7
-#define PCI_NUM_RESOURCES 11
+#define PCI_ROM_RESOURCE 6
+#define PCI_BRIDGE_RESOURCES 7
+#define PCI_NUM_RESOURCES 11
#ifndef PCI_BUS_NUM_RESOURCES
-#define PCI_BUS_NUM_RESOURCES 8
+#define PCI_BUS_NUM_RESOURCES 8
#endif
-
-#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
+
+#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
struct pci_bus {
struct list_head node; /* node in list of buses */
@@ -699,7 +269,7 @@ struct pci_driver {
* @dev_class_mask: the class mask for this device
*
* This macro is used to create a struct pci_device_id that matches a
- * specific PCI class. The vendor, device, subvendor, and subdevice
+ * specific PCI class. The vendor, device, subvendor, and subdevice
* fields will be set to PCI_ANY_ID.
*/
#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \
@@ -707,7 +277,7 @@ struct pci_driver {
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-/*
+/*
* pci_module_init is obsolete, this stays here till we fix up all usages of it
* in the tree.
*/
@@ -745,12 +315,13 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s
pci_bus_add_devices(root_bus);
return root_bus;
}
+struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
+struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
+void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
unsigned int pci_scan_child_bus(struct pci_bus *bus);
void pci_bus_add_device(struct pci_dev *dev);
-void pci_name_device(struct pci_dev *dev);
-char *pci_class_name(u32 class);
void pci_read_bridge_bases(struct pci_bus *child);
struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
int 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);
extern void pci_dev_put(struct pci_dev *dev);
extern void pci_remove_bus(struct pci_bus *b);
extern void pci_remove_bus_device(struct pci_dev *dev);
+void pci_setup_cardbus(struct pci_bus *bus);
/* Generic PCI functions exported to card drivers */
@@ -815,13 +387,16 @@ void pci_set_master(struct pci_dev *dev);
#define HAVE_PCI_SET_MWI
int pci_set_mwi(struct pci_dev *dev);
void pci_clear_mwi(struct pci_dev *dev);
+void pci_intx(struct pci_dev *dev, int enable);
int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
int pci_assign_resource(struct pci_dev *dev, int i);
+void pci_restore_bars(struct pci_dev *dev);
/* ROM control related routines */
-void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
-void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
+void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
+void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
void pci_remove_rom(struct pci_dev *pdev);
@@ -865,6 +440,9 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+ void *userdata);
+
/* kmem_cache style wrapper around pci_alloc_consistent() */
#include <linux/dmapool.h>
@@ -912,18 +490,26 @@ extern void pci_disable_msix(struct pci_dev *dev);
extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
#endif
-#endif /* CONFIG_PCI */
-
-/* Include architecture-dependent settings and functions */
+/*
+ * PCI domain support. Sometimes called PCI segment (eg by ACPI),
+ * a PCI domain is defined to be a set of PCI busses which share
+ * configuration space.
+ */
+#ifndef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return 0;
+}
+#endif
-#include <asm/pci.h>
+#else /* CONFIG_PCI is not enabled */
/*
* If the system does not have PCI, clearly these return errors. Define
* these as simple inline functions to avoid hair in drivers.
*/
-#ifndef CONFIG_PCI
#define _PCI_NOP(o,s,t) \
static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \
{ 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
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
-#else
+#endif /* CONFIG_PCI */
-/*
- * PCI domain support. Sometimes called PCI segment (eg by ACPI),
- * a PCI domain is defined to be a set of PCI busses which share
- * configuration space.
- */
-#ifndef CONFIG_PCI_DOMAINS
-static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
-static inline int pci_proc_domain(struct pci_bus *bus)
-{
- return 0;
-}
-#endif
-#endif /* !CONFIG_PCI */
+/* Include architecture-dependent settings and functions */
+
+#include <asm/pci.h>
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
@@ -1025,13 +601,6 @@ static inline char *pci_name(struct pci_dev *pdev)
return pdev->dev.bus_id;
}
-/* Some archs want to see the pretty pci name, so use this macro */
-#ifdef CONFIG_PCI_NAMES
-#define pci_pretty_name(dev) ((dev)->pretty_name)
-#else
-#define pci_pretty_name(dev) ""
-#endif
-
/* Some archs don't want to expose struct resource to userland as-is
* in sysfs and /proc
@@ -1067,7 +636,7 @@ enum pci_fixup_pass {
/* Anonymous variables would be nice... */
#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
- static struct pci_fixup __pci_fixup_##name __attribute_used__ \
+ static const struct pci_fixup __pci_fixup_##name __attribute_used__ \
__attribute__((__section__(#section))) = { vendor, device, hook };
#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
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 00000000000..e2a089b051e
--- /dev/null
+++ b/include/linux/pci_regs.h
@@ -0,0 +1,448 @@
+/*
+ * pci_regs.h
+ *
+ * PCI standard defines
+ * Copyright 1994, Drew Eckhardt
+ * Copyright 1997--1999 Martin Mares <mj@ucw.cz>
+ *
+ * For more information, please consult the following manuals (look at
+ * http://www.pcisig.com/ for how to get them):
+ *
+ * PCI BIOS Specification
+ * PCI Local Bus Specification
+ * PCI to PCI Bridge Specification
+ * PCI System Design Guide
+ */
+
+#ifndef LINUX_PCI_REGS_H
+#define LINUX_PCI_REGS_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID 0x00 /* 16 bits */
+#define PCI_DEVICE_ID 0x02 /* 16 bits */
+#define PCI_COMMAND 0x04 /* 16 bits */
+#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
+#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
+#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
+#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
+#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
+#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
+#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
+#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
+#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
+#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
+#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+
+#define PCI_STATUS 0x06 /* 16 bits */
+#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
+#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
+#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
+#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
+#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
+#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
+#define PCI_STATUS_DEVSEL_FAST 0x000
+#define PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define PCI_STATUS_DEVSEL_SLOW 0x400
+#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
+#define PCI_REVISION_ID 0x08 /* Revision ID */
+#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE 0x0a /* Device class */
+
+#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
+#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
+#define PCI_HEADER_TYPE 0x0e /* 8 bits */
+#define PCI_HEADER_TYPE_NORMAL 0
+#define PCI_HEADER_TYPE_BRIDGE 1
+#define PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST 0x0f /* 8 bits */
+#define PCI_BIST_CODE_MASK 0x0f /* Return result */
+#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
+#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of
+ * 0xffffffff to the register, and reading it back. Only
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
+#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
+#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
+#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS 0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
+#define PCI_ROM_ADDRESS_ENABLE 0x01
+#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
+
+/* 0x35-0x3b are reserved */
+#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
+#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
+#define PCI_MIN_GNT 0x3e /* 8 bits */
+#define PCI_MAX_LAT 0x3f /* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
+#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK (~0x0fUL)
+#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16 0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL 0x3e
+#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
+#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
+#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
+#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
+#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
+#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
+#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+#define PCI_CB_CAPABILITY_LIST 0x14
+/* 0x15 reserved */
+#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
+#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
+#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0 0x1c
+#define PCI_CB_MEMORY_LIMIT_0 0x20
+#define PCI_CB_MEMORY_BASE_1 0x24
+#define PCI_CB_MEMORY_LIMIT_1 0x28
+#define PCI_CB_IO_BASE_0 0x2c
+#define PCI_CB_IO_BASE_0_HI 0x2e
+#define PCI_CB_IO_LIMIT_0 0x30
+#define PCI_CB_IO_LIMIT_0_HI 0x32
+#define PCI_CB_IO_BASE_1 0x34
+#define PCI_CB_IO_BASE_1_HI 0x36
+#define PCI_CB_IO_LIMIT_1 0x38
+#define PCI_CB_IO_LIMIT_1_HI 0x3a
+#define PCI_CB_IO_RANGE_MASK (~0x03UL)
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL 0x3e
+#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
+#define PCI_CB_BRIDGE_CTL_SERR 0x02
+#define PCI_CB_BRIDGE_CTL_ISA 0x04
+#define PCI_CB_BRIDGE_CTL_VGA 0x08
+#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
+#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID 0x42
+#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID 0 /* Capability ID */
+#define PCI_CAP_ID_PM 0x01 /* Power Management */
+#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
+#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
+#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
+#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
+#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
+#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
+#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
+#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
+#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
+#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
+#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF 4
+
+/* Power Management Registers */
+
+#define PCI_PM_PMC 2 /* PM Capabilities Register */
+#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
+#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
+#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
+#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
+#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
+#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
+#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
+#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
+#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
+#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
+#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
+#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
+#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
+#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
+#define PCI_PM_CTRL 4 /* PM control and status register */
+#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
+#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */
+#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
+#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
+#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
+#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
+#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
+#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER 7 /* (??) */
+#define PCI_PM_SIZEOF 8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION 2 /* BCD version number */
+#define PCI_AGP_RFU 3 /* Rest of capability flags */
+#define PCI_AGP_STATUS 4 /* Status register */
+#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
+#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
+#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
+#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
+#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
+#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
+#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
+#define PCI_AGP_COMMAND 8 /* Control register */
+#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
+#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
+#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
+#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
+#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
+#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
+#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
+#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
+#define PCI_AGP_SIZEOF 12
+
+/* Vital Product Data */
+
+#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
+#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
+#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
+
+/* Slot Identification */
+
+#define PCI_SID_ESR 2 /* Expansion Slot Register */
+#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
+#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS 2 /* Various flags */
+#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
+#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
+#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
+#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
+#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */
+#define PCI_MSI_RFU 3 /* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
+#define PCI_MSI_MASK_BIT 16 /* Mask bits register */
+
+/* CompactPCI Hotswap Register */
+
+#define PCI_CHSWP_CSR 2 /* Control and Status Register */
+#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
+#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
+#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
+#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
+#define PCI_CHSWP_PI 0x30 /* Programming Interface */
+#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
+#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
+
+/* PCI-X registers */
+
+#define PCI_X_CMD 2 /* Modes & Features */
+#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
+#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
+#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
+#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
+#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
+#define PCI_X_STATUS 4 /* PCI-X capabilities */
+#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
+#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
+#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
+#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
+#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
+#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
+#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
+#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
+#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
+#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
+#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
+#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
+#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
+
+/* PCI Express capability registers */
+
+#define PCI_EXP_FLAGS 2 /* Capabilities register */
+#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
+#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
+#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
+#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
+#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
+#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
+#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
+#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
+#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
+#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
+#define PCI_EXP_DEVCAP 4 /* Device capabilities */
+#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
+#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
+#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
+#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
+#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
+#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
+#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
+#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
+#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
+#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
+#define PCI_EXP_DEVCTL 8 /* Device Control */
+#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
+#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
+#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
+#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
+#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
+#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
+#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
+#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
+#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
+#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
+#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
+#define PCI_EXP_DEVSTA 10 /* Device Status */
+#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
+#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
+#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
+#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
+#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
+#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
+#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
+#define PCI_EXP_LNKCTL 16 /* Link Control */
+#define PCI_EXP_LNKSTA 18 /* Link Status */
+#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
+#define PCI_EXP_SLTCTL 24 /* Slot Control */
+#define PCI_EXP_SLTSTA 26 /* Slot Status */
+#define PCI_EXP_RTCTL 28 /* Root Control */
+#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
+#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
+#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
+#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
+#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
+#define PCI_EXP_RTCAP 30 /* Root Capabilities */
+#define PCI_EXP_RTSTA 32 /* Root Status */
+
+/* Extended Capabilities (PCI-X 2.0 and Express) */
+#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR 1
+#define PCI_EXT_CAP_ID_VC 2
+#define PCI_EXT_CAP_ID_DSN 3
+#define PCI_EXT_CAP_ID_PWR 4
+
+/* Advanced Error Reporting */
+#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
+#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
+#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
+#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
+#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
+#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
+#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
+#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
+#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
+#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
+#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
+#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
+#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
+ /* Same bits as above */
+#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
+ /* Same bits as above */
+#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
+#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
+#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
+#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
+#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
+#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
+#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
+ /* Same bits as above */
+#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
+#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
+#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
+#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
+#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
+#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
+#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
+#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
+#define PCI_ERR_ROOT_STATUS 48
+#define PCI_ERR_ROOT_COR_SRC 52
+#define PCI_ERR_ROOT_SRC 54
+
+/* Virtual Channel */
+#define PCI_VC_PORT_REG1 4
+#define PCI_VC_PORT_REG2 8
+#define PCI_VC_PORT_CTRL 12
+#define PCI_VC_PORT_STATUS 14
+#define PCI_VC_RES_CAP 16
+#define PCI_VC_RES_CTRL 20
+#define PCI_VC_RES_STATUS 26
+
+/* Power Budgeting */
+#define PCI_PWR_DSR 4 /* Data Select Register */
+#define PCI_PWR_DATA 8 /* Data Register */
+#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
+#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
+#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
+#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
+#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
+#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
+#define PCI_PWR_CAP 12 /* Capability */
+#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
+
+#endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index fd276adf0fd..4e65eb44adf 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -52,8 +52,8 @@ struct rcu_head {
void (*func)(struct rcu_head *head);
};
-#define RCU_HEAD_INIT(head) { .next = NULL, .func = NULL }
-#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT(head)
+#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
+#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
#define INIT_RCU_HEAD(ptr) do { \
(ptr)->next = NULL; (ptr)->func = NULL; \
} while (0)
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
new file mode 100644
index 00000000000..e1adbba14b6
--- /dev/null
+++ b/include/linux/rcuref.h
@@ -0,0 +1,220 @@
+/*
+ * rcuref.h
+ *
+ * Reference counting for elements of lists/arrays protected by
+ * RCU.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2005
+ *
+ * Author: Dipankar Sarma <dipankar@in.ibm.com>
+ * Ravikiran Thirumalai <kiran_th@gmail.com>
+ *
+ * See Documentation/RCU/rcuref.txt for detailed user guide.
+ *
+ */
+
+#ifndef _RCUREF_H_
+#define _RCUREF_H_
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+/*
+ * These APIs work on traditional atomic_t counters used in the
+ * kernel for reference counting. Under special circumstances
+ * where a lock-free get() operation races with a put() operation
+ * these APIs can be used. See Documentation/RCU/rcuref.txt.
+ */
+
+#ifdef __HAVE_ARCH_CMPXCHG
+
+/**
+ * rcuref_inc - increment refcount for object.
+ * @rcuref: reference counter in the object in question.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference
+ * in a lock-free reader-side critical section.
+ */
+static inline void rcuref_inc(atomic_t *rcuref)
+{
+ atomic_inc(rcuref);
+}
+
+/**
+ * rcuref_dec - decrement refcount for object.
+ * @rcuref: reference counter in the object in question.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference
+ * in a lock-free reader-side critical section.
+ */
+static inline void rcuref_dec(atomic_t *rcuref)
+{
+ atomic_dec(rcuref);
+}
+
+/**
+ * rcuref_dec_and_test - decrement refcount for object and test
+ * @rcuref: reference counter in the object.
+ * @release: pointer to the function that will clean up the object
+ * when the last reference to the object is released.
+ * This pointer is required.
+ *
+ * Decrement the refcount, and if 0, return 1. Else return 0.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference
+ * in a lock-free reader-side critical section.
+ */
+static inline int rcuref_dec_and_test(atomic_t *rcuref)
+{
+ return atomic_dec_and_test(rcuref);
+}
+
+/*
+ * cmpxchg is needed on UP too, if deletions to the list/array can happen
+ * in interrupt context.
+ */
+
+/**
+ * rcuref_inc_lf - Take reference to an object in a read-side
+ * critical section protected by RCU.
+ * @rcuref: reference counter in the object in question.
+ *
+ * Try and increment the refcount by 1. The increment might fail if
+ * the reference counter has been through a 1 to 0 transition and
+ * is no longer part of the lock-free list.
+ * Returns non-zero on successful increment and zero otherwise.
+ */
+static inline int rcuref_inc_lf(atomic_t *rcuref)
+{
+ int c, old;
+ c = atomic_read(rcuref);
+ while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)
+ c = old;
+ return c;
+}
+
+#else /* !__HAVE_ARCH_CMPXCHG */
+
+extern spinlock_t __rcuref_hash[];
+
+/*
+ * Use a hash table of locks to protect the reference count
+ * since cmpxchg is not available in this arch.
+ */
+#ifdef CONFIG_SMP
+#define RCUREF_HASH_SIZE 4
+#define RCUREF_HASH(k) \
+ (&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])
+#else
+#define RCUREF_HASH_SIZE 1
+#define RCUREF_HASH(k) &__rcuref_hash[0]
+#endif /* CONFIG_SMP */
+
+/**
+ * rcuref_inc - increment refcount for object.
+ * @rcuref: reference counter in the object in question.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference in a lock-free
+ * reader-side critical section.
+ */
+static inline void rcuref_inc(atomic_t *rcuref)
+{
+ unsigned long flags;
+ spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
+ rcuref->counter += 1;
+ spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
+}
+
+/**
+ * rcuref_dec - decrement refcount for object.
+ * @rcuref: reference counter in the object in question.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference in a lock-free
+ * reader-side critical section.
+ */
+static inline void rcuref_dec(atomic_t *rcuref)
+{
+ unsigned long flags;
+ spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
+ rcuref->counter -= 1;
+ spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
+}
+
+/**
+ * rcuref_dec_and_test - decrement refcount for object and test
+ * @rcuref: reference counter in the object.
+ * @release: pointer to the function that will clean up the object
+ * when the last reference to the object is released.
+ * This pointer is required.
+ *
+ * Decrement the refcount, and if 0, return 1. Else return 0.
+ *
+ * This should be used only for objects where we use RCU and
+ * use the rcuref_inc_lf() api to acquire a reference in a lock-free
+ * reader-side critical section.
+ */
+static inline int rcuref_dec_and_test(atomic_t *rcuref)
+{
+ unsigned long flags;
+ spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
+ rcuref->counter--;
+ if (!rcuref->counter) {
+ spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
+ return 1;
+ } else {
+ spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
+ return 0;
+ }
+}
+
+/**
+ * rcuref_inc_lf - Take reference to an object of a lock-free collection
+ * by traversing a lock-free list/array.
+ * @rcuref: reference counter in the object in question.
+ *
+ * Try and increment the refcount by 1. The increment might fail if
+ * the reference counter has been through a 1 to 0 transition and
+ * object is no longer part of the lock-free list.
+ * Returns non-zero on successful increment and zero otherwise.
+ */
+static inline int rcuref_inc_lf(atomic_t *rcuref)
+{
+ int ret;
+ unsigned long flags;
+ spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
+ if (rcuref->counter)
+ ret = rcuref->counter++;
+ else
+ ret = 0;
+ spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
+ return ret;
+}
+
+
+#endif /* !__HAVE_ARCH_CMPXCHG */
+
+#endif /* __KERNEL__ */
+#endif /* _RCUREF_H_ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ea1b5f32ec5..c551e6a1447 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);
#define GROUP_AT(gi, i) \
((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
+#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
+extern void prefetch_stack(struct task_struct*);
+#else
+static inline void prefetch_stack(struct task_struct *t) { }
+#endif
struct audit_context; /* See audit.c */
struct mempolicy;
diff --git a/include/linux/security.h b/include/linux/security.h
index 7aab6ab7c57..55b02e1c73f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -250,29 +250,37 @@ struct swap_info_struct;
* @inode contains the inode structure.
* Deallocate the inode security structure and set @inode->i_security to
* NULL.
+ * @inode_init_security:
+ * Obtain the security attribute name suffix and value to set on a newly
+ * created inode and set up the incore security field for the new inode.
+ * This hook is called by the fs code as part of the inode creation
+ * transaction and provides for atomic labeling of the inode, unlike
+ * the post_create/mkdir/... hooks called by the VFS. The hook function
+ * is expected to allocate the name and value via kmalloc, with the caller
+ * being responsible for calling kfree after using them.
+ * If the security module does not use security attributes or does
+ * not wish to put a security attribute on this particular inode,
+ * then it should return -EOPNOTSUPP to skip this processing.
+ * @inode contains the inode structure of the newly created inode.
+ * @dir contains the inode structure of the parent directory.
+ * @name will be set to the allocated name suffix (e.g. selinux).
+ * @value will be set to the allocated attribute value.
+ * @len will be set to the length of the value.
+ * Returns 0 if @name and @value have been successfully set,
+ * -EOPNOTSUPP if no security attribute is needed, or
+ * -ENOMEM on memory allocation failure.
* @inode_create:
* Check permission to create a regular file.
* @dir contains inode structure of the parent of the new file.
* @dentry contains the dentry structure for the file to be created.
* @mode contains the file mode of the file to be created.
* Return 0 if permission is granted.
- * @inode_post_create:
- * Set the security attributes on a newly created regular file. This hook
- * is called after a file has been successfully created.
- * @dir contains the inode structure of the parent directory of the new file.
- * @dentry contains the the dentry structure for the newly created file.
- * @mode contains the file mode.
* @inode_link:
* Check permission before creating a new hard link to a file.
* @old_dentry contains the dentry structure for an existing link to the file.
* @dir contains the inode structure of the parent directory of the new link.
* @new_dentry contains the dentry structure for the new link.
* Return 0 if permission is granted.
- * @inode_post_link:
- * Set security attributes for a new hard link to a file.
- * @old_dentry contains the dentry structure for the existing link.
- * @dir contains the inode structure of the parent directory of the new file.
- * @new_dentry contains the dentry structure for the new file link.
* @inode_unlink:
* Check the permission to remove a hard link to a file.
* @dir contains the inode structure of parent directory of the file.
@@ -284,13 +292,6 @@ struct swap_info_struct;
* @dentry contains the dentry structure of the symbolic link.
* @old_name contains the pathname of file.
* Return 0 if permission is granted.
- * @inode_post_symlink:
- * @dir contains the inode structure of the parent directory of the new link.
- * @dentry contains the dentry structure of new symbolic link.
- * @old_name contains the pathname of file.
- * Set security attributes for a newly created symbolic link. Note that
- * @dentry->d_inode may be NULL, since the filesystem might not
- * instantiate the dentry (e.g. NFS).
* @inode_mkdir:
* Check permissions to create a new directory in the existing directory
* associated with inode strcture @dir.
@@ -298,11 +299,6 @@ struct swap_info_struct;
* @dentry contains the dentry structure of new directory.
* @mode contains the mode of new directory.
* Return 0 if permission is granted.
- * @inode_post_mkdir:
- * Set security attributes on a newly created directory.
- * @dir contains the inode structure of parent of the directory to be created.
- * @dentry contains the dentry structure of new directory.
- * @mode contains the mode of new directory.
* @inode_rmdir:
* Check the permission to remove a directory.
* @dir contains the inode structure of parent of the directory to be removed.
@@ -318,13 +314,6 @@ struct swap_info_struct;
* @mode contains the mode of the new file.
* @dev contains the the device number.
* Return 0 if permission is granted.
- * @inode_post_mknod:
- * Set security attributes on a newly created special file (or socket or
- * fifo file created via the mknod system call).
- * @dir contains the inode structure of parent of the new node.
- * @dentry contains the dentry structure of the new node.
- * @mode contains the mode of the new node.
- * @dev contains the the device number.
* @inode_rename:
* Check for permission to rename a file or directory.
* @old_dir contains the inode structure for parent of the old link.
@@ -332,12 +321,6 @@ struct swap_info_struct;
* @new_dir contains the inode structure for parent of the new link.
* @new_dentry contains the dentry structure of the new link.
* Return 0 if permission is granted.
- * @inode_post_rename:
- * Set security attributes on a renamed file or directory.
- * @old_dir contains the inode structure for parent of the old link.
- * @old_dentry contains the dentry structure of the old link.
- * @new_dir contains the inode structure for parent of the new link.
- * @new_dentry contains the dentry structure of the new link.
* @inode_readlink:
* Check the permission to read the symbolic link.
* @dentry contains the dentry structure for the file link.
@@ -1080,34 +1063,21 @@ struct security_operations {
int (*inode_alloc_security) (struct inode *inode);
void (*inode_free_security) (struct inode *inode);
+ int (*inode_init_security) (struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len);
int (*inode_create) (struct inode *dir,
struct dentry *dentry, int mode);
- void (*inode_post_create) (struct inode *dir,
- struct dentry *dentry, int mode);
int (*inode_link) (struct dentry *old_dentry,
struct inode *dir, struct dentry *new_dentry);
- void (*inode_post_link) (struct dentry *old_dentry,
- struct inode *dir, struct dentry *new_dentry);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
int (*inode_symlink) (struct inode *dir,
struct dentry *dentry, const char *old_name);
- void (*inode_post_symlink) (struct inode *dir,
- struct dentry *dentry,
- const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
- void (*inode_post_mkdir) (struct inode *dir, struct dentry *dentry,
- int mode);
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
int mode, dev_t dev);
- void (*inode_post_mknod) (struct inode *dir, struct dentry *dentry,
- int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
- void (*inode_post_rename) (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry);
int (*inode_readlink) (struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
@@ -1442,6 +1412,17 @@ static inline void security_inode_free (struct inode *inode)
return;
security_ops->inode_free_security (inode);
}
+
+static inline int security_inode_init_security (struct inode *inode,
+ struct inode *dir,
+ char **name,
+ void **value,
+ size_t *len)
+{
+ if (unlikely (IS_PRIVATE (inode)))
+ return -EOPNOTSUPP;
+ return security_ops->inode_init_security (inode, dir, name, value, len);
+}
static inline int security_inode_create (struct inode *dir,
struct dentry *dentry,
@@ -1452,15 +1433,6 @@ static inline int security_inode_create (struct inode *dir,
return security_ops->inode_create (dir, dentry, mode);
}
-static inline void security_inode_post_create (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_create (dir, dentry, mode);
-}
-
static inline int security_inode_link (struct dentry *old_dentry,
struct inode *dir,
struct dentry *new_dentry)
@@ -1470,15 +1442,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
return security_ops->inode_link (old_dentry, dir, new_dentry);
}
-static inline void security_inode_post_link (struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
-{
- if (new_dentry->d_inode && unlikely (IS_PRIVATE (new_dentry->d_inode)))
- return;
- security_ops->inode_post_link (old_dentry, dir, new_dentry);
-}
-
static inline int security_inode_unlink (struct inode *dir,
struct dentry *dentry)
{
@@ -1496,15 +1459,6 @@ static inline int security_inode_symlink (struct inode *dir,
return security_ops->inode_symlink (dir, dentry, old_name);
}
-static inline void security_inode_post_symlink (struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_symlink (dir, dentry, old_name);
-}
-
static inline int security_inode_mkdir (struct inode *dir,
struct dentry *dentry,
int mode)
@@ -1514,15 +1468,6 @@ static inline int security_inode_mkdir (struct inode *dir,
return security_ops->inode_mkdir (dir, dentry, mode);
}
-static inline void security_inode_post_mkdir (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_mkdir (dir, dentry, mode);
-}
-
static inline int security_inode_rmdir (struct inode *dir,
struct dentry *dentry)
{
@@ -1540,15 +1485,6 @@ static inline int security_inode_mknod (struct inode *dir,
return security_ops->inode_mknod (dir, dentry, mode, dev);
}
-static inline void security_inode_post_mknod (struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
-{
- if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_mknod (dir, dentry, mode, dev);
-}
-
static inline int security_inode_rename (struct inode *old_dir,
struct dentry *old_dentry,
struct inode *new_dir,
@@ -1561,18 +1497,6 @@ static inline int security_inode_rename (struct inode *old_dir,
new_dir, new_dentry);
}
-static inline void security_inode_post_rename (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry)
-{
- if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
- (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
- return;
- security_ops->inode_post_rename (old_dir, old_dentry,
- new_dir, new_dentry);
-}
-
static inline int security_inode_readlink (struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
@@ -2171,6 +2095,15 @@ static inline int security_inode_alloc (struct inode *inode)
static inline void security_inode_free (struct inode *inode)
{ }
+
+static inline int security_inode_init_security (struct inode *inode,
+ struct inode *dir,
+ char **name,
+ void **value,
+ size_t *len)
+{
+ return -EOPNOTSUPP;
+}
static inline int security_inode_create (struct inode *dir,
struct dentry *dentry,
@@ -2179,11 +2112,6 @@ static inline int security_inode_create (struct inode *dir,
return 0;
}
-static inline void security_inode_post_create (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{ }
-
static inline int security_inode_link (struct dentry *old_dentry,
struct inode *dir,
struct dentry *new_dentry)
@@ -2191,11 +2119,6 @@ static inline int security_inode_link (struct dentry *old_dentry,
return 0;
}
-static inline void security_inode_post_link (struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
-{ }
-
static inline int security_inode_unlink (struct inode *dir,
struct dentry *dentry)
{
@@ -2209,11 +2132,6 @@ static inline int security_inode_symlink (struct inode *dir,
return 0;
}
-static inline void security_inode_post_symlink (struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
-{ }
-
static inline int security_inode_mkdir (struct inode *dir,
struct dentry *dentry,
int mode)
@@ -2221,11 +2139,6 @@ static inline int security_inode_mkdir (struct inode *dir,
return 0;
}
-static inline void security_inode_post_mkdir (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{ }
-
static inline int security_inode_rmdir (struct inode *dir,
struct dentry *dentry)
{
@@ -2239,11 +2152,6 @@ static inline int security_inode_mknod (struct inode *dir,
return 0;
}
-static inline void security_inode_post_mknod (struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
-{ }
-
static inline int security_inode_rename (struct inode *old_dir,
struct dentry *old_dentry,
struct inode *new_dir,
@@ -2252,12 +2160,6 @@ static inline int security_inode_rename (struct inode *old_dir,
return 0;
}
-static inline void security_inode_post_rename (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry)
-{ }
-
static inline int security_inode_readlink (struct dentry *dentry)
{
return 0;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index d8a023d804d..317a979b24d 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -30,6 +30,21 @@ struct plat_serial8250_port {
};
/*
+ * Allocate 8250 platform device IDs. Nothing is implied by
+ * the numbering here, except for the legacy entry being -1.
+ */
+enum {
+ PLAT8250_DEV_LEGACY = -1,
+ PLAT8250_DEV_PLATFORM,
+ PLAT8250_DEV_PLATFORM1,
+ PLAT8250_DEV_FOURPORT,
+ PLAT8250_DEV_ACCENT,
+ PLAT8250_DEV_BOCA,
+ PLAT8250_DEV_HUB6,
+ PLAT8250_DEV_MCA,
+};
+
+/*
* This should be used by drivers which want to register
* their own 8250 ports without registering their own
* platform device. Using these will make your driver
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 9b12fe73161..27db8da43aa 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,
#endif
return 0;
}
+#ifndef SUPPORT_SYSRQ
+#define uart_handle_sysrq_char(port,ch,regs) uart_handle_sysrq_char(port, 0, NULL)
+#endif
/*
* We do the SysRQ and SAK checking like this...
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index da7da9c0ed1..2741c0c55e8 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,
static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
{
- if (len >= skb->len)
+ if (likely(len >= skb->len))
return 0;
if (skb->ip_summed == CHECKSUM_HW)
skb->ip_summed = CHECKSUM_NONE;
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 221f81ac200..3340f3bd135 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -32,6 +32,10 @@ extern struct timer_base_s __init_timer_base;
.magic = TIMER_MAGIC, \
}
+#define DEFINE_TIMER(_name, _function, _expires, _data) \
+ struct timer_list _name = \
+ TIMER_INITIALIZER(_function, _expires, _data)
+
void fastcall init_timer(struct timer_list * timer);
/***
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 59ff42c629e..1267f88ece6 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -74,7 +74,8 @@ struct screen_info {
u16 vesapm_off; /* 0x30 */
u16 pages; /* 0x32 */
u16 vesa_attributes; /* 0x34 */
- /* 0x36 -- 0x3f reserved for future expansion */
+ u32 capabilities; /* 0x36 */
+ /* 0x3a -- 0x3f reserved for future expansion */
};
extern struct screen_info screen_info;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 72463779299..4dbe580f933 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -5,6 +5,7 @@
#include <linux/usb_ch9.h>
#define USB_MAJOR 180
+#define USB_DEVICE_MAJOR 189
#ifdef __KERNEL__
@@ -349,6 +350,7 @@ struct usb_device {
char *manufacturer;
char *serial; /* static strings from the device */
struct list_head filelist;
+ struct class_device *class_dev;
struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
/*
@@ -614,7 +616,6 @@ extern int usb_disabled(void);
#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
-#define URB_ASYNC_UNLINK 0x0010 /* usb_unlink_urb() returns asap */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
#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 *);
* Initialization:
*
* All URBs submitted must initialize the dev, pipe, transfer_flags (may be
- * zero), and complete fields.
- * The URB_ASYNC_UNLINK transfer flag affects later invocations of
- * the usb_unlink_urb() routine. Note: Failure to set URB_ASYNC_UNLINK
- * with usb_unlink_urb() is deprecated. For synchronous unlinks use
- * usb_kill_urb() instead.
- *
- * All URBs must also initialize
+ * zero), and complete fields. All URBs must also initialize
* transfer_buffer and transfer_buffer_length. They may provide the
* URB_SHORT_NOT_OK transfer flag, indicating that short reads are
* 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 5f5a9d9bd6c..436dd8a2b64 100644
--- a/include/linux/usb_isp116x.h
+++ b/include/linux/usb_isp116x.h
@@ -7,36 +7,18 @@
struct isp116x_platform_data {
/* Enable internal resistors on downstream ports */
unsigned sel15Kres:1;
- /* Chip's internal clock won't be stopped in suspended state.
- Setting/unsetting this bit takes effect only if
- 'remote_wakeup_enable' below is not set. */
- unsigned clknotstop:1;
- /* On-chip overcurrent protection */
+ /* On-chip overcurrent detection */
unsigned oc_enable:1;
/* INT output polarity */
unsigned int_act_high:1;
/* INT edge or level triggered */
unsigned int_edge_triggered:1;
- /* WAKEUP pin connected - NOT SUPPORTED */
- /* unsigned remote_wakeup_connected:1; */
- /* Wakeup by devices on usb bus enabled */
+ /* Enable wakeup by devices on usb bus (e.g. wakeup
+ by attachment/detachment or by device activity
+ such as moving a mouse). When chosen, this option
+ prevents stopping internal clock, increasing
+ thereby power consumption in suspended state. */
unsigned remote_wakeup_enable:1;
- /* Switch or not to switch (keep always powered) */
- unsigned no_power_switching:1;
- /* Ganged port power switching (0) or individual port
- power switching (1) */
- unsigned power_switching_mode:1;
- /* Given port_power, msec/2 after power on till power good */
- u8 potpg;
- /* Hardware reset set/clear. If implemented, this function must:
- if set == 0, deassert chip's HW reset pin
- otherwise, assert chip's HW reset pin */
- void (*reset) (struct device * dev, int set);
- /* Hardware clock start/stop. If implemented, this function must:
- if start == 0, stop the external clock
- otherwise, start the external clock
- */
- void (*clock) (struct device * dev, int start);
/* Inter-io delay (ns). The chip is picky about access timings; it
expects at least:
150ns delay between consecutive accesses to DATA_REG,
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 9d6fbde3d29..1cc8c31b798 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -3,7 +3,6 @@
#include <linux/compiler.h>
#include <linux/types.h>
-#include <linux/version.h>
#define HAVE_V4L2 1
#include <linux/videodev2.h>
@@ -29,7 +28,6 @@ struct video_device
void (*release)(struct video_device *vfd);
-#if 1 /* to be removed in 2.7.x */
/* obsolete -- fops->owner is used instead */
struct module *owner;
/* dev->driver_data will be used instead some day.
@@ -37,7 +35,6 @@ struct video_device
* so the switch over will be transparent for you.
* Or use {pci|usb}_{get|set}_drvdata() directly. */
void *priv;
-#endif
/* for videodev.c intenal usage -- please don't touch */
int users; /* video_exclusive_{open|close} ... */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index acbfc525576..f623a33b9ab 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -270,7 +270,6 @@ struct v4l2_timecode
/* The above is based on SMPTE timecodes */
-#if 1
/*
* 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
*
@@ -357,7 +356,6 @@ struct v4l2_mpeg_compression {
/* I don't expect the above being perfect yet ;) */
__u32 reserved_5[8];
};
-#endif
struct v4l2_jpegcompression
{
@@ -871,10 +869,8 @@ struct v4l2_streamparm
#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
-#if 1 /* experimental */
#define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression)
#define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression)
-#endif
#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index cd831168fdc..a7ceee9fc5e 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,5 +1,4 @@
/*
- * $Id: audiochip.h,v 1.5 2005/06/16 22:59:16 hhackmann Exp $
*/
#ifndef AUDIOCHIP_H
diff --git a/include/media/id.h b/include/media/id.h
index 801ddef301a..6d02c94cdc0 100644
--- a/include/media/id.h
+++ b/include/media/id.h
@@ -1,5 +1,4 @@
/*
- * $Id: id.h,v 1.4 2005/06/12 04:19:19 mchehab Exp $
*/
/* 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 698670547f1..01b56822df4 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -1,5 +1,4 @@
/*
- * $Id: ir-common.h,v 1.9 2005/05/15 19:01:26 mchehab Exp $
*
* some common structs and functions to handle infrared remotes via
* input layer ...
@@ -21,11 +20,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/version.h>
#include <linux/input.h>
#define IR_TYPE_RC5 1
+#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
#define IR_TYPE_OTHER 99
#define IR_KEYTAB_TYPE u32
@@ -60,6 +59,7 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
u32 ir_extract_bits(u32 data, u32 mask);
int ir_dump_samples(u32 *samples, int count);
int ir_decode_biphase(u32 *samples, int count, int low, int high);
+int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
/*
* Local variables:
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 3dfb8d670eb..2a897c3a6a9 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -1,7 +1,6 @@
#ifndef __SAA7146__
#define __SAA7146__
-#include <linux/version.h> /* for version macros */
#include <linux/module.h> /* for module-version */
#include <linux/delay.h> /* for delay-stuff */
#include <linux/slab.h> /* for kmalloc/kfree */
@@ -15,12 +14,7 @@
#include <linux/vmalloc.h> /* for vmalloc() */
#include <linux/mm.h> /* for vmalloc_to_page() */
-/* ugly, but necessary to build the dvb stuff under 2.4. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
- #include "dvb_functions.h"
-#endif
-
-#define SAA7146_VERSION_CODE KERNEL_VERSION(0,5,0)
+#define SAA7146_VERSION_CODE 0x000500 /* 0.5.0 */
#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr)))
#define saa7146_read(sxy,adr) readl(sxy->mem+(adr))
@@ -33,13 +27,8 @@ extern unsigned int saa7146_debug;
#define DEBUG_VARIABLE saa7146_debug
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
-#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_BASENAME),__FUNCTION__)
-#define INFO(x) { printk("%s: ",__stringify(KBUILD_BASENAME)); printk x; }
-#else
#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; }
-#endif
#define ERR(x) { DEBUG_PROLOG; printk x; }
diff --git a/include/media/tuner.h b/include/media/tuner.h
index eeaa15ddee8..4ad08e24a1a 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -1,6 +1,4 @@
-
-/* $Id: tuner.h,v 1.45 2005/07/28 18:41:21 mchehab Exp $
- *
+/*
tuner.h - definition for different tuners
Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
@@ -28,88 +26,90 @@
#define ADDR_UNSET (255)
-#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
-#define TUNER_PHILIPS_PAL_I 1
-#define TUNER_PHILIPS_NTSC 2
-#define TUNER_PHILIPS_SECAM 3 /* you must actively select B/G, L, L` */
-
-#define TUNER_ABSENT 4
-#define TUNER_PHILIPS_PAL 5
-#define TUNER_TEMIC_NTSC 6 /* 4032 FY5 (3X 7004, 9498, 9789) */
-#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5 (3X 8501, 9957) */
-
-#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 (3X 1223, 1981, 7686) */
-#define TUNER_ALPS_TSBH1_NTSC 9
-#define TUNER_ALPS_TSBE1_PAL 10
-#define TUNER_ALPS_TSBB5_PAL_I 11
-
-#define TUNER_ALPS_TSBE5_PAL 12
-#define TUNER_ALPS_TSBC5_PAL 13
-#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 (3X 9500, 9501, 7291) */
-#define TUNER_ALPS_TSHC6_NTSC 15
-
-#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 (3X 1392, 1393) */
-#define TUNER_PHILIPS_NTSC_M 17
-#define TUNER_TEMIC_4066FY5_PAL_I 18 /* 4066 FY5 (3X 7032, 7035) */
-#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected (3X 7595, 7606, 7657)*/
-
-#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio (3X 7607, 7488, 7711)*/
-#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio (3X 7246, 7578, 7732)*/
-#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! (3X 7804, 7806, 8103, 8104)*/
+#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
+#define TUNER_PHILIPS_PAL_I 1
+#define TUNER_PHILIPS_NTSC 2
+#define TUNER_PHILIPS_SECAM 3 /* you must actively select B/G, L, L` */
+
+#define TUNER_ABSENT 4
+#define TUNER_PHILIPS_PAL 5
+#define TUNER_TEMIC_NTSC 6 /* 4032 FY5 (3X 7004, 9498, 9789) */
+#define TUNER_TEMIC_PAL_I 7 /* 4062 FY5 (3X 8501, 9957) */
+
+#define TUNER_TEMIC_4036FY5_NTSC 8 /* 4036 FY5 (3X 1223, 1981, 7686) */
+#define TUNER_ALPS_TSBH1_NTSC 9
+#define TUNER_ALPS_TSBE1_PAL 10
+#define TUNER_ALPS_TSBB5_PAL_I 11
+
+#define TUNER_ALPS_TSBE5_PAL 12
+#define TUNER_ALPS_TSBC5_PAL 13
+#define TUNER_TEMIC_4006FH5_PAL 14 /* 4006 FH5 (3X 9500, 9501, 7291) */
+#define TUNER_ALPS_TSHC6_NTSC 15
+
+#define TUNER_TEMIC_PAL_DK 16 /* 4016 FY5 (3X 1392, 1393) */
+#define TUNER_PHILIPS_NTSC_M 17
+#define TUNER_TEMIC_4066FY5_PAL_I 18 /* 4066 FY5 (3X 7032, 7035) */
+#define TUNER_TEMIC_4006FN5_MULTI_PAL 19 /* B/G, I and D/K autodetected (3X 7595, 7606, 7657) */
+
+#define TUNER_TEMIC_4009FR5_PAL 20 /* incl. FM radio (3X 7607, 7488, 7711) */
+#define TUNER_TEMIC_4039FR5_NTSC 21 /* incl. FM radio (3X 7246, 7578, 7732) */
+#define TUNER_TEMIC_4046FM5 22 /* you must actively select B/G, D/K, I, L, L` ! (3X 7804, 7806, 8103, 8104) */
#define TUNER_PHILIPS_PAL_DK 23
-#define TUNER_PHILIPS_FQ1216ME 24 /* you must actively select B/G/D/K, I, L, L` */
-#define TUNER_LG_PAL_I_FM 25
-#define TUNER_LG_PAL_I 26
-#define TUNER_LG_NTSC_FM 27
+#define TUNER_PHILIPS_FQ1216ME 24 /* you must actively select B/G/D/K, I, L, L` */
+#define TUNER_LG_PAL_I_FM 25
+#define TUNER_LG_PAL_I 26
+#define TUNER_LG_NTSC_FM 27
-#define TUNER_LG_PAL_FM 28
-#define TUNER_LG_PAL 29
-#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected (3X 8155, 8160, 8163)*/
-#define TUNER_SHARP_2U5JF5540_NTSC 31
+#define TUNER_LG_PAL_FM 28
+#define TUNER_LG_PAL 29
+#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30 /* B/G, I and D/K autodetected (3X 8155, 8160, 8163) */
+#define TUNER_SHARP_2U5JF5540_NTSC 31
-#define TUNER_Samsung_PAL_TCPM9091PD27 32
-#define TUNER_MT2032 33
-#define TUNER_TEMIC_4106FH5 34 /* 4106 FH5 (3X 7808, 7865)*/
-#define TUNER_TEMIC_4012FY5 35 /* 4012 FY5 (3X 0971, 1099)*/
+#define TUNER_Samsung_PAL_TCPM9091PD27 32
+#define TUNER_MT2032 33
+#define TUNER_TEMIC_4106FH5 34 /* 4106 FH5 (3X 7808, 7865) */
+#define TUNER_TEMIC_4012FY5 35 /* 4012 FY5 (3X 0971, 1099) */
-#define TUNER_TEMIC_4136FY5 36 /* 4136 FY5 (3X 7708, 7746)*/
-#define TUNER_LG_PAL_NEW_TAPC 37
-#define TUNER_PHILIPS_FM1216ME_MK3 38
-#define TUNER_LG_NTSC_NEW_TAPC 39
+#define TUNER_TEMIC_4136FY5 36 /* 4136 FY5 (3X 7708, 7746) */
+#define TUNER_LG_PAL_NEW_TAPC 37
+#define TUNER_PHILIPS_FM1216ME_MK3 38
+#define TUNER_LG_NTSC_NEW_TAPC 39
-#define TUNER_HITACHI_NTSC 40
-#define TUNER_PHILIPS_PAL_MK 41
-#define TUNER_PHILIPS_ATSC 42
-#define TUNER_PHILIPS_FM1236_MK3 43
+#define TUNER_HITACHI_NTSC 40
+#define TUNER_PHILIPS_PAL_MK 41
+#define TUNER_PHILIPS_ATSC 42
+#define TUNER_PHILIPS_FM1236_MK3 43
-#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */
+#define TUNER_PHILIPS_4IN1 44 /* ATI TV Wonder Pro - Conexant */
/* Microtune mergeged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */
-#define TUNER_MICROTUNE_4049FM5 45
-#define TUNER_LG_NTSC_TAPE 47
-
-#define TUNER_TNF_8831BGFF 48
-#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
-#define TUNER_TCL_2002N 50
-#define TUNER_PHILIPS_FM1256_IH3 51
-
-#define TUNER_THOMSON_DTT7610 52
-#define TUNER_PHILIPS_FQ1286 53
-#define TUNER_PHILIPS_TDA8290 54
-#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */
-
-#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
-#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
-
-#define TUNER_YMEC_TVF_8531MF 58
-#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
-#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */
-#define TUNER_TENA_9533_DI 61
-
-#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
-#define TUNER_PHILIPS_FMD1216ME_MK3 63
-#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
-#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
+#define TUNER_MICROTUNE_4049FM5 45
+#define TUNER_MICROTUNE_4042_FI5 46
+#define TUNER_LG_NTSC_TAPE 47
+
+#define TUNER_TNF_8831BGFF 48
+#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
+#define TUNER_TCL_2002N 50
+#define TUNER_PHILIPS_FM1256_IH3 51
+
+#define TUNER_THOMSON_DTT7610 52
+#define TUNER_PHILIPS_FQ1286 53
+#define TUNER_PHILIPS_TDA8290 54
+#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */
+
+#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
+#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_YMEC_TVF_8531MF 58
+#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
+
+#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */
+#define TUNER_TENA_9533_DI 61
+#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
+#define TUNER_PHILIPS_FMD1216ME_MK3 63
+
+#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
+#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
+#define TUNER_LG_NTSC_TALN_MINI 66
#define NOTUNER 0
#define PAL 1 /* PAL_BG */
@@ -117,7 +117,7 @@
#define NTSC 3
#define SECAM 4
#define ATSC 5
-#define RADIO 6
+#define RADIO 6
#define NoTuner 0
#define Philips 1
@@ -134,6 +134,7 @@
#define THOMSON 12
#define TUNER_SET_TYPE_ADDR _IOW('T',3,int)
+#define TUNER_SET_STANDBY _IOW('T',4,int)
#define TDA9887_SET_CONFIG _IOW('t',5,int)
/* tv card specific */
@@ -153,9 +154,6 @@
#ifdef __KERNEL__
-#define I2C_ADDR_TDA8290 0x4b
-#define I2C_ADDR_TDA8275 0x61
-
enum tuner_mode {
T_UNINITIALIZED = 0,
T_RADIO = 1 << V4L2_TUNER_RADIO,
@@ -165,21 +163,21 @@ enum tuner_mode {
};
struct tuner_setup {
- unsigned short addr;
- unsigned int type;
- unsigned int mode_mask;
+ unsigned short addr;
+ unsigned int type;
+ unsigned int mode_mask;
};
struct tuner {
/* device */
struct i2c_client i2c;
- unsigned int type; /* chip type */
+ unsigned int type; /* chip type */
- unsigned int mode;
- unsigned int mode_mask; /* Combination of allowable modes */
+ unsigned int mode;
+ unsigned int mode_mask; /* Combination of allowable modes */
- unsigned int freq; /* keep track of the current settings */
+ unsigned int freq; /* keep track of the current settings */
unsigned int audmode;
v4l2_std_id std;
@@ -198,6 +196,7 @@ struct tuner {
void (*radio_freq)(struct i2c_client *c, unsigned int freq);
int (*has_signal)(struct i2c_client *c);
int (*is_stereo)(struct i2c_client *c);
+ void (*standby)(struct i2c_client *c);
};
extern unsigned int tuner_debug;
@@ -209,16 +208,20 @@ extern int tea5767_tuner_init(struct i2c_client *c);
extern int default_tuner_init(struct i2c_client *c);
extern int tea5767_autodetection(struct i2c_client *c);
-#define tuner_warn(fmt, arg...) \
- dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg)
-#define tuner_info(fmt, arg...) \
- dev_printk(KERN_INFO , &t->i2c.dev , fmt , ## arg)
-#define tuner_dbg(fmt, arg...) \
- if (tuner_debug) dev_printk(KERN_DEBUG , &t->i2c.dev , fmt , ## arg)
+#define tuner_warn(fmt, arg...) do {\
+ printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+#define tuner_info(fmt, arg...) do {\
+ printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+#define tuner_dbg(fmt, arg...) do {\
+ if (tuner_debug) \
+ printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
+ t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
#endif /* __KERNEL__ */
-#endif
+#endif /* _TUNER_H */
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index 854a2c2f105..e2035c7da09 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,18 +1,21 @@
/*
- * $Id: tveeprom.h,v 1.2 2005/06/12 04:19:19 mchehab Exp $
*/
struct tveeprom {
u32 has_radio;
+ u32 has_ir; /* 0: no IR, 1: IR present, 2: unknown */
u32 tuner_type;
u32 tuner_formats;
+ u32 tuner2_type;
+ u32 tuner2_formats;
+
u32 digitizer;
u32 digitizer_formats;
u32 audio_processor;
- /* a_p_fmts? */
+ u32 decoder_processor;
u32 model;
u32 revision;
@@ -20,7 +23,7 @@ struct tveeprom {
char rev_str[5];
};
-void tveeprom_hauppauge_analog(struct tveeprom *tvee,
+void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
unsigned char *eeprom_data);
int 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 ae6da6de98d..ae8d7a00044 100644
--- a/include/media/video-buf.h
+++ b/include/media/video-buf.h
@@ -1,5 +1,4 @@
/*
- * $Id: video-buf.h,v 1.9 2004/11/07 13:17:15 kraxel Exp $
*
* generic helper functions for video4linux capture buffers, to handle
* memory management and PCI DMA. Right now bttv + saa7134 use it.
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 364b046e9f4..227d3378dec 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 *);
/* ax25_addr.c */
extern ax25_address null_ax25_address;
extern char *ax2asc(char *buf, ax25_address *);
-extern ax25_address *asc2ax(char *);
+extern void asc2ax(ax25_address *addr, char *callsign);
extern int ax25cmp(ax25_address *, ax25_address *);
extern int ax25digicmp(ax25_digi *, ax25_digi *);
extern 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 482eb820f13..290bab46d45 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
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
-extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *,
- int);
+
+struct sock;
+extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
#endif /* NET_COMPAT_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 3203eaff4bd..65ec86678a0 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,
extern int ipv6_parse_hopopts(struct sk_buff *skb, int);
extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
+extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
+ int newtype,
+ struct ipv6_opt_hdr __user *newopt,
+ int newoptlen);
extern int ip6_frag_nqueues;
extern atomic_t ip6_frag_mem;
@@ -373,6 +377,7 @@ extern int ip6_append_data(struct sock *sk,
int length,
int transhdrlen,
int hlimit,
+ int tclass,
struct ipv6_txoptions *opt,
struct flowi *fl,
struct rt6_info *rt,
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 8b075ab7a26..4e86f2de663 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,
extern int datagram_send_ctl(struct msghdr *msg,
struct flowi *fl,
struct ipv6_txoptions *opt,
- int *hlimit);
+ int *hlimit, int *tclass);
#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006)
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index b707a603351..cb8b6e6ce66 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -151,6 +151,8 @@ struct pcmcia_device {
uniquely define a pcmcia_device */
struct pcmcia_socket *socket;
+ char *devname;
+
u8 device_no;
/* the hardware "function" device; certain subdevices can
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 389e8ebe9c1..d6361dab037 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);
* Returns 1 if the given PCM format is CPU-endian, 0 if
* opposite, or a negative error code if endian not specified.
*/
-/* int snd_pcm_format_cpu_endian(snd_pcm_format_t format); */
#ifdef SNDRV_LITTLE_ENDIAN
-#define snd_pcm_format_cpu_endian snd_pcm_format_little_endian
+#define snd_pcm_format_cpu_endian(format) snd_pcm_format_little_endian(format)
#else
-#define snd_pcm_format_cpu_endian snd_pcm_format_big_endian
+#define snd_pcm_format_cpu_endian(format) snd_pcm_format_big_endian(format)
#endif
int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */
int 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 ad3c3be33c0..b82e408e758 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -34,9 +34,7 @@ struct snd_tea575x_ops {
struct snd_tea575x {
snd_card_t *card;
struct video_device vd; /* video device */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
struct file_operations fops;
-#endif
int dev_nr; /* requested device number + 1 */
int vd_registered; /* video device is registered */
int tea5759; /* 5759 chip is present */
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
new file mode 100644
index 00000000000..a9948232b13
--- /dev/null
+++ b/include/video/cyblafb.h
@@ -0,0 +1,171 @@
+
+#ifndef CYBLAFB_DEBUG
+#define CYBLAFB_DEBUG 0
+#endif
+
+#if CYBLAFB_DEBUG
+#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a);
+#else
+#define debug(f,a...)
+#endif
+
+#define output(f, a...) printk("cyblafb: " f, ## a)
+
+#define Kb (1024)
+#define Mb (Kb*Kb)
+
+/* PCI IDS of supported cards temporarily here */
+
+#define CYBERBLADEi1 0x8500
+
+/* these defines are for 'lcd' variable */
+#define LCD_STRETCH 0
+#define LCD_CENTER 1
+#define LCD_BIOS 2
+
+/* display types */
+#define DISPLAY_CRT 0
+#define DISPLAY_FP 1
+
+#define ROP_S 0xCC
+
+#define point(x,y) ((y)<<16|(x))
+
+//
+// Attribute Regs, ARxx, 3c0/3c1
+//
+#define AR00 0x00
+#define AR01 0x01
+#define AR02 0x02
+#define AR03 0x03
+#define AR04 0x04
+#define AR05 0x05
+#define AR06 0x06
+#define AR07 0x07
+#define AR08 0x08
+#define AR09 0x09
+#define AR0A 0x0A
+#define AR0B 0x0B
+#define AR0C 0x0C
+#define AR0D 0x0D
+#define AR0E 0x0E
+#define AR0F 0x0F
+#define AR10 0x10
+#define AR12 0x12
+#define AR13 0x13
+
+//
+// Sequencer Regs, SRxx, 3c4/3c5
+//
+#define SR00 0x00
+#define SR01 0x01
+#define SR02 0x02
+#define SR03 0x03
+#define SR04 0x04
+#define SR0D 0x0D
+#define SR0E 0x0E
+#define SR11 0x11
+#define SR18 0x18
+#define SR19 0x19
+
+//
+//
+//
+#define CR00 0x00
+#define CR01 0x01
+#define CR02 0x02
+#define CR03 0x03
+#define CR04 0x04
+#define CR05 0x05
+#define CR06 0x06
+#define CR07 0x07
+#define CR08 0x08
+#define CR09 0x09
+#define CR0A 0x0A
+#define CR0B 0x0B
+#define CR0C 0x0C
+#define CR0D 0x0D
+#define CR0E 0x0E
+#define CR0F 0x0F
+#define CR10 0x10
+#define CR11 0x11
+#define CR12 0x12
+#define CR13 0x13
+#define CR14 0x14
+#define CR15 0x15
+#define CR16 0x16
+#define CR17 0x17
+#define CR18 0x18
+#define CR19 0x19
+#define CR1A 0x1A
+#define CR1B 0x1B
+#define CR1C 0x1C
+#define CR1D 0x1D
+#define CR1E 0x1E
+#define CR1F 0x1F
+#define CR20 0x20
+#define CR21 0x21
+#define CR27 0x27
+#define CR29 0x29
+#define CR2A 0x2A
+#define CR2B 0x2B
+#define CR2D 0x2D
+#define CR2F 0x2F
+#define CR36 0x36
+#define CR38 0x38
+#define CR39 0x39
+#define CR3A 0x3A
+#define CR55 0x55
+#define CR56 0x56
+#define CR57 0x57
+#define CR58 0x58
+
+//
+//
+//
+
+#define GR00 0x01
+#define GR01 0x01
+#define GR02 0x02
+#define GR03 0x03
+#define GR04 0x04
+#define GR05 0x05
+#define GR06 0x06
+#define GR07 0x07
+#define GR08 0x08
+#define GR0F 0x0F
+#define GR20 0x20
+#define GR23 0x23
+#define GR2F 0x2F
+#define GR30 0x30
+#define GR31 0x31
+#define GR33 0x33
+#define GR52 0x52
+#define GR53 0x53
+#define GR5D 0x5d
+
+
+//
+// Graphics Engine
+//
+#define GEBase 0x2100 // could be mapped elsewhere if we like it
+#define GE00 (GEBase+0x00) // source 1, p 111
+#define GE04 (GEBase+0x04) // source 2, p 111
+#define GE08 (GEBase+0x08) // destination 1, p 111
+#define GE0C (GEBase+0x0C) // destination 2, p 112
+#define GE20 (GEBase+0x20) // engine status, p 113
+#define GE24 (GEBase+0x24) // reset all GE pointers
+#define GE44 (GEBase+0x44) // command register, p 126
+#define GE48 (GEBase+0x48) // raster operation, p 127
+#define GE60 (GEBase+0x60) // foreground color, p 128
+#define GE64 (GEBase+0x64) // background color, p 128
+#define GE6C (GEBase+0x6C) // Pattern and Style, p 129, ok
+#define GE9C (GEBase+0x9C) // pixel engine data port, p 125
+#define GEB8 (GEBase+0xB8) // Destination Stride / Buffer Base 0, p 133
+#define GEBC (GEBase+0xBC) // Destination Stride / Buffer Base 1, p 133
+#define GEC0 (GEBase+0xC0) // Destination Stride / Buffer Base 2, p 133
+#define GEC4 (GEBase+0xC4) // Destination Stride / Buffer Base 3, p 133
+#define GEC8 (GEBase+0xC8) // Source Stride / Buffer Base 0, p 133
+#define GECC (GEBase+0xCC) // Source Stride / Buffer Base 1, p 133
+#define GED0 (GEBase+0xD0) // Source Stride / Buffer Base 2, p 133
+#define GED4 (GEBase+0xD4) // Source Stride / Buffer Base 3, p 133
diff --git a/include/video/sisfb.h b/include/video/sisfb.h
index 136bf791643..e402eb5b3c7 100644
--- a/include/video/sisfb.h
+++ b/include/video/sisfb.h
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ * sisfb.h - definitions for the SiS framebuffer driver
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,8 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*/
-#ifndef _LINUX_SISFB
-#define _LINUX_SISFB
+#ifndef _LINUX_SISFB_H_
+#define _LINUX_SISFB_H_
#include <asm/ioctl.h>
#include <asm/types.h>
@@ -26,47 +28,35 @@
/* PUBLIC */
/**********************************************/
-/* vbflags */
-#define CRT2_DEFAULT 0x00000001
-#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */
-#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */
-#define CRT2_VGA 0x00000008
-#define TV_NTSC 0x00000010
-#define TV_PAL 0x00000020
-#define TV_HIVISION 0x00000040
-#define TV_YPBPR 0x00000080
-#define TV_AVIDEO 0x00000100
-#define TV_SVIDEO 0x00000200
-#define TV_SCART 0x00000400
-#define VB_CONEXANT 0x00000800 /* 661 series only */
-#define VB_TRUMPION VB_CONEXANT /* 300 series only */
-#define TV_PALM 0x00001000
-#define TV_PALN 0x00002000
+/* vbflags, public (others in sis.h) */
+#define CRT2_DEFAULT 0x00000001
+#define CRT2_LCD 0x00000002
+#define CRT2_TV 0x00000004
+#define CRT2_VGA 0x00000008
+#define TV_NTSC 0x00000010
+#define TV_PAL 0x00000020
+#define TV_HIVISION 0x00000040
+#define TV_YPBPR 0x00000080
+#define TV_AVIDEO 0x00000100
+#define TV_SVIDEO 0x00000200
+#define TV_SCART 0x00000400
+#define TV_PALM 0x00001000
+#define TV_PALN 0x00002000
#define TV_NTSCJ 0x00001000
-#define VB_302ELV 0x00004000
-#define TV_CHSCART 0x00008000
-#define TV_CHYPBPR525I 0x00010000
+#define TV_CHSCART 0x00008000
+#define TV_CHYPBPR525I 0x00010000
#define CRT1_VGA 0x00000000
#define CRT1_LCDA 0x00020000
#define VGA2_CONNECTED 0x00040000
-#define VB_DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
-#define VB_301 0x00100000 /* Video bridge type */
-#define VB_301B 0x00200000
-#define VB_302B 0x00400000
-#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */
-#define VB_LVDS 0x01000000
-#define VB_CHRONTEL 0x02000000
-#define VB_301LV 0x04000000
-#define VB_302LV 0x08000000
-#define VB_301C 0x10000000
-#define VB_SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
-#define VB_MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
-#define VB_DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
+#define VB_DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
+#define VB_SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define VB_MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
+#define VB_DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
/* Aliases: */
#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
-#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
-#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
+#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_CHSCART|TV_CHYPBPR525I)
/* Only if TV_YPBPR is set: */
#define TV_YPBPR525I TV_NTSC
@@ -75,89 +65,118 @@
#define TV_YPBPR1080I TV_PALN
#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
-#define VB_SISBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)
-#define VB_SISTVBRIDGE (VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)
-#define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT)
-
#define VB_DISPTYPE_DISP2 CRT2_ENABLE
#define VB_DISPTYPE_CRT2 CRT2_ENABLE
#define VB_DISPTYPE_DISP1 VB_DISPTYPE_CRT1
#define VB_DISPMODE_SINGLE VB_SINGLE_MODE
#define VB_DISPMODE_MIRROR VB_MIRROR_MODE
#define VB_DISPMODE_DUAL VB_DUALVIEW_MODE
-#define VB_DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+#define VB_DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
/* Structure argument for SISFB_GET_INFO ioctl */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
- __u32 sisfb_id; /* for identifying sisfb */
+struct sisfb_info {
+ __u32 sisfb_id; /* for identifying sisfb */
#ifndef SISFB_ID
#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
#endif
- __u32 chip_id; /* PCI-ID of detected chip */
- __u32 memory; /* video memory in KB which sisfb manages */
- __u32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
+ __u32 chip_id; /* PCI-ID of detected chip */
+ __u32 memory; /* total video memory in KB */
+ __u32 heapstart; /* heap start offset in KB */
__u8 fbvidmode; /* current sisfb mode */
- __u8 sisfb_version;
- __u8 sisfb_revision;
- __u8 sisfb_patchlevel;
+ __u8 sisfb_version;
+ __u8 sisfb_revision;
+ __u8 sisfb_patchlevel;
- __u8 sisfb_caps; /* sisfb capabilities */
+ __u8 sisfb_caps; /* sisfb capabilities */
__u32 sisfb_tqlen; /* turbo queue length (in KB) */
- __u32 sisfb_pcibus; /* The card's PCI ID */
- __u32 sisfb_pcislot;
- __u32 sisfb_pcifunc;
+ __u32 sisfb_pcibus; /* The card's PCI ID */
+ __u32 sisfb_pcislot;
+ __u32 sisfb_pcifunc;
+
+ __u8 sisfb_lcdpdc; /* PanelDelayCompensation */
+
+ __u8 sisfb_lcda; /* Detected status of LCDA for low res/text modes */
+
+ __u32 sisfb_vbflags;
+ __u32 sisfb_currentvbflags;
+
+ __u32 sisfb_scalelcd;
+ __u32 sisfb_specialtiming;
+
+ __u8 sisfb_haveemi;
+ __u8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+ __u8 sisfb_haveemilcd;
- __u8 sisfb_lcdpdc; /* PanelDelayCompensation */
+ __u8 sisfb_lcdpdca; /* PanelDelayCompensation for LCD-via-CRT1 */
- __u8 sisfb_lcda; /* Detected status of LCDA for low res/text modes */
+ __u16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
- __u32 sisfb_vbflags;
- __u32 sisfb_currentvbflags;
+ __u32 sisfb_heapsize; /* heap size (in KB) */
+ __u32 sisfb_videooffset; /* Offset of viewport in video memory (in bytes) */
- __u32 sisfb_scalelcd;
- __u32 sisfb_specialtiming;
+ __u32 sisfb_curfstn; /* currently running FSTN/DSTN mode */
+ __u32 sisfb_curdstn;
- __u8 sisfb_haveemi;
- __u8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
- __u8 sisfb_haveemilcd;
+ __u16 sisfb_pci_vendor; /* PCI vendor (SiS or XGI) */
- __u8 sisfb_lcdpdca; /* PanelDelayCompensation for LCD-via-CRT1 */
+ __u32 sisfb_vbflags2; /* ivideo->vbflags2 */
- __u16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
+ __u8 sisfb_can_post; /* sisfb can POST this card */
+ __u8 sisfb_card_posted; /* card is POSTED */
+ __u8 sisfb_was_boot_device; /* This card was the boot video device (ie is primary) */
- __u8 reserved[208]; /* for future use */
+ __u8 reserved[183]; /* for future use */
+};
+
+#define SISFB_CMD_GETVBFLAGS 0x55AA0001 /* no arg; result[1] = vbflags */
+#define SISFB_CMD_SWITCHCRT1 0x55AA0010 /* arg[0]: 99 = query, 0 = off, 1 = on */
+/* more to come */
+
+#define SISFB_CMD_ERR_OK 0x80000000 /* command succeeded */
+#define SISFB_CMD_ERR_LOCKED 0x80000001 /* sisfb is locked */
+#define SISFB_CMD_ERR_EARLY 0x80000002 /* request before sisfb took over gfx system */
+#define SISFB_CMD_ERR_NOVB 0x80000003 /* No video bridge */
+#define SISFB_CMD_ERR_NOCRT2 0x80000004 /* can't change CRT1 status, CRT2 disabled */
+/* more to come */
+#define SISFB_CMD_ERR_UNKNOWN 0x8000ffff /* Unknown command */
+#define SISFB_CMD_ERR_OTHER 0x80010000 /* Other error */
+
+/* Argument for SISFB_CMD ioctl */
+struct sisfb_cmd {
+ __u32 sisfb_cmd;
+ __u32 sisfb_arg[16];
+ __u32 sisfb_result[4];
};
/* Addtional IOCTLs for communication sisfb <> X driver */
/* If changing this, vgatypes.h must also be changed (for X driver) */
/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_SIZE _IOR(0xF3,0x00,__u32)
-#define SISFB_GET_INFO _IOR(0xF3,0x01,struct _SISFB_INFO)
+#define SISFB_GET_INFO_SIZE _IOR(0xF3,0x00,__u32)
+#define SISFB_GET_INFO _IOR(0xF3,0x01,struct sisfb_info)
/* ioctrl to get current vertical retrace status */
-#define SISFB_GET_VBRSTATUS _IOR(0xF3,0x02,__u32)
+#define SISFB_GET_VBRSTATUS _IOR(0xF3,0x02,__u32)
/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
-#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32)
-#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32)
+#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32)
+#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32)
/* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/
-#define SISFB_GET_TVPOSOFFSET _IOR(0xF3,0x04,__u32)
-#define SISFB_SET_TVPOSOFFSET _IOW(0xF3,0x04,__u32)
+#define SISFB_GET_TVPOSOFFSET _IOR(0xF3,0x04,__u32)
+#define SISFB_SET_TVPOSOFFSET _IOW(0xF3,0x04,__u32)
+
+/* ioctl for internal sisfb commands (sisfbctrl) */
+#define SISFB_COMMAND _IOWR(0xF3,0x05,struct sisfb_cmd)
/* ioctl for locking sisfb (no register access during lock) */
/* As of now, only used to avoid register access during
* the ioctls listed above.
*/
-#define SISFB_SET_LOCK _IOW(0xF3,0x06,__u32)
-
-/* more to come soon */
+#define SISFB_SET_LOCK _IOW(0xF3,0x06,__u32)
/* ioctls 0xF3 up to 0x3F reserved for sisfb */
@@ -165,7 +184,7 @@ struct _SISFB_INFO {
/* The following are deprecated and should not be used anymore: */
/****************************************************************/
/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO_OLD _IOR('n',0xF8,__u32)
+#define SISFB_GET_INFO_OLD _IOR('n',0xF8,__u32)
/* ioctrl to get current vertical retrace status */
#define SISFB_GET_VBRSTATUS_OLD _IOR('n',0xF9,__u32)
/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
@@ -177,8 +196,8 @@ struct _SISFB_INFO {
/* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */
struct sis_memreq {
- __u32 offset;
- __u32 size;
+ __u32 offset;
+ __u32 size;
};
/**********************************************/
@@ -187,12 +206,19 @@ struct sis_memreq {
/**********************************************/
#ifdef __KERNEL__
+
+#include <linux/pci.h>
+
#define UNKNOWN_VGA 0
#define SIS_300_VGA 1
#define SIS_315_VGA 2
+#define SISFB_HAVE_MALLOC_NEW
extern void sis_malloc(struct sis_memreq *req);
+extern void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req);
+
extern void sis_free(u32 base);
+extern void sis_free_new(struct pci_dev *pdev, u32 base);
#endif
#endif
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 1f06e769010..712d0202997 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,
*s++ = '\n';
*s = '\0';
+ /* Do nothing if *ppos is at the eof or beyond the eof. */
+ if (s - page <= *ppos)
+ return 0;
+
start = page + *ppos;
n = s - start;
retval = n - copy_to_user(buf, start, min(n, nbytes));
diff --git a/kernel/exit.c b/kernel/exit.c
index 5b0fb9f09f2..6d2089a1bce 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -368,17 +368,19 @@ EXPORT_SYMBOL(daemonize);
static inline void close_files(struct files_struct * files)
{
int i, j;
+ struct fdtable *fdt;
j = 0;
+ fdt = files_fdtable(files);
for (;;) {
unsigned long set;
i = j * __NFDBITS;
- if (i >= files->max_fdset || i >= files->max_fds)
+ if (i >= fdt->max_fdset || i >= fdt->max_fds)
break;
- set = files->open_fds->fds_bits[j++];
+ set = fdt->open_fds->fds_bits[j++];
while (set) {
if (set & 1) {
- struct file * file = xchg(&files->fd[i], NULL);
+ struct file * file = xchg(&fdt->fd[i], NULL);
if (file)
filp_close(file, files);
}
@@ -403,18 +405,22 @@ struct files_struct *get_files_struct(struct task_struct *task)
void fastcall put_files_struct(struct files_struct *files)
{
+ struct fdtable *fdt;
+
if (atomic_dec_and_test(&files->count)) {
close_files(files);
/*
* Free the fd and fdset arrays if we expanded them.
+ * If the fdtable was embedded, pass files for freeing
+ * at the end of the RCU grace period. Otherwise,
+ * you can free files immediately.
*/
- if (files->fd != &files->fd_array[0])
- free_fd_array(files->fd, files->max_fds);
- if (files->max_fdset > __FD_SETSIZE) {
- free_fdset(files->open_fds, files->max_fdset);
- free_fdset(files->close_on_exec, files->max_fdset);
- }
- kmem_cache_free(files_cachep, files);
+ fdt = files_fdtable(files);
+ if (fdt == &files->fdtab)
+ fdt->free_files = files;
+ else
+ kmem_cache_free(files_cachep, files);
+ free_fdtable(fdt);
}
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 7e1ead9a6ba..8149f360288 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -35,6 +35,7 @@
#include <linux/syscalls.h>
#include <linux/jiffies.h>
#include <linux/futex.h>
+#include <linux/rcupdate.h>
#include <linux/ptrace.h>
#include <linux/mount.h>
#include <linux/audit.h>
@@ -176,6 +177,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
/* One for us, one for whoever does the "release_task()" (usually parent) */
atomic_set(&tsk->usage,2);
+ atomic_set(&tsk->fs_excl, 0);
return tsk;
}
@@ -564,24 +566,53 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
return 0;
}
-static int count_open_files(struct files_struct *files, int size)
+static int count_open_files(struct fdtable *fdt)
{
+ int size = fdt->max_fdset;
int i;
/* Find the last open fd */
for (i = size/(8*sizeof(long)); i > 0; ) {
- if (files->open_fds->fds_bits[--i])
+ if (fdt->open_fds->fds_bits[--i])
break;
}
i = (i+1) * 8 * sizeof(long);
return i;
}
+static struct files_struct *alloc_files(void)
+{
+ struct files_struct *newf;
+ struct fdtable *fdt;
+
+ newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
+ if (!newf)
+ goto out;
+
+ atomic_set(&newf->count, 1);
+
+ spin_lock_init(&newf->file_lock);
+ fdt = &newf->fdtab;
+ fdt->next_fd = 0;
+ fdt->max_fds = NR_OPEN_DEFAULT;
+ fdt->max_fdset = __FD_SETSIZE;
+ fdt->close_on_exec = &newf->close_on_exec_init;
+ fdt->open_fds = &newf->open_fds_init;
+ fdt->fd = &newf->fd_array[0];
+ INIT_RCU_HEAD(&fdt->rcu);
+ fdt->free_files = NULL;
+ fdt->next = NULL;
+ rcu_assign_pointer(newf->fdt, fdt);
+out:
+ return newf;
+}
+
static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
{
struct files_struct *oldf, *newf;
struct file **old_fds, **new_fds;
int open_files, size, i, error = 0, expand;
+ struct fdtable *old_fdt, *new_fdt;
/*
* A background process may not have any files ...
@@ -602,35 +633,27 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
*/
tsk->files = NULL;
error = -ENOMEM;
- newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
- if (!newf)
+ newf = alloc_files();
+ if (!newf)
goto out;
- atomic_set(&newf->count, 1);
-
- spin_lock_init(&newf->file_lock);
- newf->next_fd = 0;
- newf->max_fds = NR_OPEN_DEFAULT;
- newf->max_fdset = __FD_SETSIZE;
- newf->close_on_exec = &newf->close_on_exec_init;
- newf->open_fds = &newf->open_fds_init;
- newf->fd = &newf->fd_array[0];
-
spin_lock(&oldf->file_lock);
-
- open_files = count_open_files(oldf, oldf->max_fdset);
+ old_fdt = files_fdtable(oldf);
+ new_fdt = files_fdtable(newf);
+ size = old_fdt->max_fdset;
+ open_files = count_open_files(old_fdt);
expand = 0;
/*
* Check whether we need to allocate a larger fd array or fd set.
* Note: we're not a clone task, so the open count won't change.
*/
- if (open_files > newf->max_fdset) {
- newf->max_fdset = 0;
+ if (open_files > new_fdt->max_fdset) {
+ new_fdt->max_fdset = 0;
expand = 1;
}
- if (open_files > newf->max_fds) {
- newf->max_fds = 0;
+ if (open_files > new_fdt->max_fds) {
+ new_fdt->max_fds = 0;
expand = 1;
}
@@ -642,14 +665,21 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
spin_unlock(&newf->file_lock);
if (error < 0)
goto out_release;
+ new_fdt = files_fdtable(newf);
+ /*
+ * Reacquire the oldf lock and a pointer to its fd table
+ * who knows it may have a new bigger fd table. We need
+ * the latest pointer.
+ */
spin_lock(&oldf->file_lock);
+ old_fdt = files_fdtable(oldf);
}
- old_fds = oldf->fd;
- new_fds = newf->fd;
+ old_fds = old_fdt->fd;
+ new_fds = new_fdt->fd;
- memcpy(newf->open_fds->fds_bits, oldf->open_fds->fds_bits, open_files/8);
- memcpy(newf->close_on_exec->fds_bits, oldf->close_on_exec->fds_bits, open_files/8);
+ memcpy(new_fdt->open_fds->fds_bits, old_fdt->open_fds->fds_bits, open_files/8);
+ memcpy(new_fdt->close_on_exec->fds_bits, old_fdt->close_on_exec->fds_bits, open_files/8);
for (i = open_files; i != 0; i--) {
struct file *f = *old_fds++;
@@ -662,24 +692,24 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
* is partway through open(). So make sure that this
* fd is available to the new process.
*/
- FD_CLR(open_files - i, newf->open_fds);
+ FD_CLR(open_files - i, new_fdt->open_fds);
}
- *new_fds++ = f;
+ rcu_assign_pointer(*new_fds++, f);
}
spin_unlock(&oldf->file_lock);
/* compute the remainder to be cleared */
- size = (newf->max_fds - open_files) * sizeof(struct file *);
+ size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
/* This is long word aligned thus could use a optimized version */
memset(new_fds, 0, size);
- if (newf->max_fdset > open_files) {
- int left = (newf->max_fdset-open_files)/8;
+ if (new_fdt->max_fdset > open_files) {
+ int left = (new_fdt->max_fdset-open_files)/8;
int start = open_files / (8 * sizeof(unsigned long));
- memset(&newf->open_fds->fds_bits[start], 0, left);
- memset(&newf->close_on_exec->fds_bits[start], 0, left);
+ memset(&new_fdt->open_fds->fds_bits[start], 0, left);
+ memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
}
tsk->files = newf;
@@ -688,9 +718,9 @@ out:
return error;
out_release:
- free_fdset (newf->close_on_exec, newf->max_fdset);
- free_fdset (newf->open_fds, newf->max_fdset);
- free_fd_array(newf->fd, newf->max_fds);
+ free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
+ free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
+ free_fd_array(new_fdt->fd, new_fdt->max_fds);
kmem_cache_free(files_cachep, newf);
goto out;
}
@@ -1115,6 +1145,9 @@ static task_t *copy_process(unsigned long clone_flags,
__get_cpu_var(process_counts)++;
}
+ if (!current->signal->tty && p->signal->tty)
+ p->signal->tty = NULL;
+
nr_threads++;
total_forks++;
write_unlock_irq(&tasklist_lock);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index f436993bd59..bef3b6901b7 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -45,6 +45,7 @@
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/rcupdate.h>
+#include <linux/rcuref.h>
#include <linux/cpu.h>
/* Definition for rcupdate control block. */
@@ -72,6 +73,19 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
static int maxbatch = 10;
+#ifndef __HAVE_ARCH_CMPXCHG
+/*
+ * We use an array of spinlocks for the rcurefs -- similar to ones in sparc
+ * 32 bit atomic_t implementations, and a hash function similar to that
+ * for our refcounting needs.
+ * Can't help multiprocessors which donot have cmpxchg :(
+ */
+
+spinlock_t __rcuref_hash[RCUREF_HASH_SIZE] = {
+ [0 ... (RCUREF_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
+};
+#endif
+
/**
* call_rcu - Queue an RCU callback for invocation after a grace period.
* @head: structure to be used for queueing the RCU updates.
diff --git a/kernel/sched.c b/kernel/sched.c
index 18b95520a2e..2632b812cf2 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2888,6 +2888,7 @@ switch_tasks:
if (next == rq->idle)
schedstat_inc(rq, sched_goidle);
prefetch(next);
+ prefetch_stack(next);
clear_tsk_need_resched(prev);
rcu_qsctr_inc(task_cpu(prev));
diff --git a/lib/Kconfig b/lib/Kconfig
index e43197efeb9..3de93357f5a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -12,6 +12,14 @@ config CRC_CCITT
the kernel tree does. Such modules that use library CRC-CCITT
functions require M here.
+config CRC16
+ tristate "CRC16 functions"
+ help
+ This option is provided for the case where no in-kernel-tree
+ modules require CRC16 functions, but a module built outside
+ the kernel tree does. Such modules that use library CRC16
+ functions require M here.
+
config CRC32
tristate "CRC32 functions"
default y
diff --git a/lib/Makefile b/lib/Makefile
index 3e2bd0df23b..d9c38ba05e7 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -23,11 +23,12 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
-ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
+ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
lib-y += dec_and_lock.o
endif
obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
+obj-$(CONFIG_CRC16) += crc16.o
obj-$(CONFIG_CRC32) += crc32.o
obj-$(CONFIG_LIBCRC32C) += libcrc32c.o
obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
diff --git a/lib/crc16.c b/lib/crc16.c
new file mode 100644
index 00000000000..011fe573c66
--- /dev/null
+++ b/lib/crc16.c
@@ -0,0 +1,67 @@
+/*
+ * crc16.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc16.h>
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+u16 const crc16_table[256] = {
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+EXPORT_SYMBOL(crc16_table);
+
+/**
+ * Compute the CRC-16 for the data buffer
+ *
+ * @param crc previous CRC value
+ * @param buffer data pointer
+ * @param len number of bytes in the buffer
+ * @return the updated CRC value
+ */
+u16 crc16(u16 crc, u8 const *buffer, size_t len)
+{
+ while (len--)
+ crc = crc16_byte(crc, *buffer++);
+ return crc;
+}
+EXPORT_SYMBOL(crc16);
+
+MODULE_DESCRIPTION("CRC16 calculations");
+MODULE_LICENSE("GPL");
+
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 13492d66b7c..afa06e184d8 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -88,7 +88,7 @@ static kmem_cache_t *sn_cache;
policied. */
static int policy_zone;
-static struct mempolicy default_policy = {
+struct mempolicy default_policy = {
.refcnt = ATOMIC_INIT(1), /* never free it */
.policy = MPOL_DEFAULT,
};
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a6329fa8f86..0166ea15c9e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -368,10 +368,8 @@ int wakeup_pdflush(long nr_pages)
static void wb_timer_fn(unsigned long unused);
static void laptop_timer_fn(unsigned long unused);
-static struct timer_list wb_timer =
- TIMER_INITIALIZER(wb_timer_fn, 0, 0);
-static struct timer_list laptop_mode_wb_timer =
- TIMER_INITIALIZER(laptop_timer_fn, 0, 0);
+static DEFINE_TIMER(wb_timer, wb_timer_fn, 0, 0);
+static DEFINE_TIMER(laptop_mode_wb_timer, laptop_timer_fn, 0, 0);
/*
* Periodic writeback of "old" data.
diff --git a/mm/shmem.c b/mm/shmem.c
index db2c9e8d990..1f7aeb210c7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -666,6 +666,7 @@ static void shmem_delete_inode(struct inode *inode)
struct shmem_inode_info *info = SHMEM_I(inode);
if (inode->i_op->truncate == shmem_truncate) {
+ truncate_inode_pages(inode->i_mapping, 0);
shmem_unacct_size(info->flags, inode->i_size);
inode->i_size = 0;
shmem_truncate(inode);
@@ -1607,6 +1608,15 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int error = -ENOSPC;
if (inode) {
+ error = security_inode_init_security(inode, dir, NULL, NULL,
+ NULL);
+ if (error) {
+ if (error != -EOPNOTSUPP) {
+ iput(inode);
+ return error;
+ }
+ error = 0;
+ }
if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
@@ -1616,7 +1626,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
d_instantiate(dentry, inode);
dget(dentry); /* Extra count - pin the dentry in core */
- error = 0;
}
return error;
}
@@ -1746,6 +1755,16 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
if (!inode)
return -ENOSPC;
+ error = security_inode_init_security(inode, dir, NULL, NULL,
+ NULL);
+ if (error) {
+ if (error != -EOPNOTSUPP) {
+ iput(inode);
+ return error;
+ }
+ error = 0;
+ }
+
info = SHMEM_I(inode);
inode->i_size = len-1;
if (len <= (char *)inode - (char *)info) {
diff --git a/mm/slab.c b/mm/slab.c
index d7c4443991f..05a391059fe 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -75,6 +75,15 @@
*
* At present, each engine can be growing a cache. This should be blocked.
*
+ * 15 March 2005. NUMA slab allocator.
+ * Shai Fultheim <shai@scalex86.org>.
+ * Shobhit Dayal <shobhit@calsoftinc.com>
+ * Alok N Kataria <alokk@calsoftinc.com>
+ * Christoph Lameter <christoph@lameter.com>
+ *
+ * Modified the slab allocator to be node aware on NUMA systems.
+ * Each node has its own list of partial, free and full slabs.
+ * All object allocations for a node occur from node specific slab lists.
*/
#include <linux/config.h>
@@ -93,6 +102,7 @@
#include <linux/module.h>
#include <linux/rcupdate.h>
#include <linux/string.h>
+#include <linux/nodemask.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -212,6 +222,7 @@ struct slab {
void *s_mem; /* including colour offset */
unsigned int inuse; /* num of objs active in slab */
kmem_bufctl_t free;
+ unsigned short nodeid;
};
/*
@@ -239,7 +250,6 @@ struct slab_rcu {
/*
* struct array_cache
*
- * Per cpu structures
* Purpose:
* - LIFO ordering, to hand out cache-warm objects from _alloc
* - reduce the number of linked list operations
@@ -254,6 +264,13 @@ struct array_cache {
unsigned int limit;
unsigned int batchcount;
unsigned int touched;
+ spinlock_t lock;
+ void *entry[0]; /*
+ * Must have this definition in here for the proper
+ * alignment of array_cache. Also simplifies accessing
+ * the entries.
+ * [0] is for gcc 2.95. It should really be [].
+ */
};
/* bootstrap: The caches do not work without cpuarrays anymore,
@@ -266,34 +283,83 @@ struct arraycache_init {
};
/*
- * The slab lists of all objects.
- * Hopefully reduce the internal fragmentation
- * NUMA: The spinlock could be moved from the kmem_cache_t
- * into this structure, too. Figure out what causes
- * fewer cross-node spinlock operations.
+ * The slab lists for all objects.
*/
struct kmem_list3 {
struct list_head slabs_partial; /* partial list first, better asm code */
struct list_head slabs_full;
struct list_head slabs_free;
unsigned long free_objects;
- int free_touched;
unsigned long next_reap;
- struct array_cache *shared;
+ int free_touched;
+ unsigned int free_limit;
+ spinlock_t list_lock;
+ struct array_cache *shared; /* shared per node */
+ struct array_cache **alien; /* on other nodes */
};
-#define LIST3_INIT(parent) \
- { \
- .slabs_full = LIST_HEAD_INIT(parent.slabs_full), \
- .slabs_partial = LIST_HEAD_INIT(parent.slabs_partial), \
- .slabs_free = LIST_HEAD_INIT(parent.slabs_free) \
+/*
+ * Need this for bootstrapping a per node allocator.
+ */
+#define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
+struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
+#define CACHE_CACHE 0
+#define SIZE_AC 1
+#define SIZE_L3 (1 + MAX_NUMNODES)
+
+/*
+ * This function may be completely optimized away if
+ * a constant is passed to it. Mostly the same as
+ * what is in linux/slab.h except it returns an
+ * index.
+ */
+static inline int index_of(const size_t size)
+{
+ if (__builtin_constant_p(size)) {
+ int i = 0;
+
+#define CACHE(x) \
+ if (size <=x) \
+ return i; \
+ else \
+ i++;
+#include "linux/kmalloc_sizes.h"
+#undef CACHE
+ {
+ extern void __bad_size(void);
+ __bad_size();
+ }
}
-#define list3_data(cachep) \
- (&(cachep)->lists)
+ return 0;
+}
+
+#define INDEX_AC index_of(sizeof(struct arraycache_init))
+#define INDEX_L3 index_of(sizeof(struct kmem_list3))
+
+static inline void kmem_list3_init(struct kmem_list3 *parent)
+{
+ INIT_LIST_HEAD(&parent->slabs_full);
+ INIT_LIST_HEAD(&parent->slabs_partial);
+ INIT_LIST_HEAD(&parent->slabs_free);
+ parent->shared = NULL;
+ parent->alien = NULL;
+ spin_lock_init(&parent->list_lock);
+ parent->free_objects = 0;
+ parent->free_touched = 0;
+}
-/* NUMA: per-node */
-#define list3_data_ptr(cachep, ptr) \
- list3_data(cachep)
+#define MAKE_LIST(cachep, listp, slab, nodeid) \
+ do { \
+ INIT_LIST_HEAD(listp); \
+ list_splice(&(cachep->nodelists[nodeid]->slab), listp); \
+ } while (0)
+
+#define MAKE_ALL_LISTS(cachep, ptr, nodeid) \
+ do { \
+ MAKE_LIST((cachep), (&(ptr)->slabs_full), slabs_full, nodeid); \
+ MAKE_LIST((cachep), (&(ptr)->slabs_partial), slabs_partial, nodeid); \
+ MAKE_LIST((cachep), (&(ptr)->slabs_free), slabs_free, nodeid); \
+ } while (0)
/*
* kmem_cache_t
@@ -306,13 +372,12 @@ struct kmem_cache_s {
struct array_cache *array[NR_CPUS];
unsigned int batchcount;
unsigned int limit;
-/* 2) touched by every alloc & free from the backend */
- struct kmem_list3 lists;
- /* NUMA: kmem_3list_t *nodelists[MAX_NUMNODES] */
+ unsigned int shared;
unsigned int objsize;
+/* 2) touched by every alloc & free from the backend */
+ struct kmem_list3 *nodelists[MAX_NUMNODES];
unsigned int flags; /* constant flags */
unsigned int num; /* # of objs per slab */
- unsigned int free_limit; /* upper limit of objects in the lists */
spinlock_t spinlock;
/* 3) cache_grow/shrink */
@@ -349,6 +414,7 @@ struct kmem_cache_s {
unsigned long errors;
unsigned long max_freeable;
unsigned long node_allocs;
+ unsigned long node_frees;
atomic_t allochit;
atomic_t allocmiss;
atomic_t freehit;
@@ -384,6 +450,7 @@ struct kmem_cache_s {
} while (0)
#define STATS_INC_ERR(x) ((x)->errors++)
#define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++)
+#define STATS_INC_NODEFREES(x) ((x)->node_frees++)
#define STATS_SET_FREEABLE(x, i) \
do { if ((x)->max_freeable < i) \
(x)->max_freeable = i; \
@@ -402,6 +469,7 @@ struct kmem_cache_s {
#define STATS_SET_HIGH(x) do { } while (0)
#define STATS_INC_ERR(x) do { } while (0)
#define STATS_INC_NODEALLOCS(x) do { } while (0)
+#define STATS_INC_NODEFREES(x) do { } while (0)
#define STATS_SET_FREEABLE(x, i) \
do { } while (0)
@@ -534,9 +602,9 @@ static struct arraycache_init initarray_generic =
/* internal cache of cache description objs */
static kmem_cache_t cache_cache = {
- .lists = LIST3_INIT(cache_cache.lists),
.batchcount = 1,
.limit = BOOT_CPUCACHE_ENTRIES,
+ .shared = 1,
.objsize = sizeof(kmem_cache_t),
.flags = SLAB_NO_REAP,
.spinlock = SPIN_LOCK_UNLOCKED,
@@ -557,7 +625,6 @@ static struct list_head cache_chain;
* SLAB_RECLAIM_ACCOUNT turns this on per-slab
*/
atomic_t slab_reclaim_pages;
-EXPORT_SYMBOL(slab_reclaim_pages);
/*
* chicken and egg problem: delay the per-cpu array allocation
@@ -565,7 +632,8 @@ EXPORT_SYMBOL(slab_reclaim_pages);
*/
static enum {
NONE,
- PARTIAL,
+ PARTIAL_AC,
+ PARTIAL_L3,
FULL
} g_cpucache_up;
@@ -574,11 +642,7 @@ static DEFINE_PER_CPU(struct work_struct, reap_work);
static void free_block(kmem_cache_t* cachep, void** objpp, int len);
static void enable_cpucache (kmem_cache_t *cachep);
static void cache_reap (void *unused);
-
-static inline void **ac_entry(struct array_cache *ac)
-{
- return (void**)(ac+1);
-}
+static int __node_shrink(kmem_cache_t *cachep, int node);
static inline struct array_cache *ac_data(kmem_cache_t *cachep)
{
@@ -676,48 +740,160 @@ static void __devinit start_cpu_timer(int cpu)
}
}
-static struct array_cache *alloc_arraycache(int cpu, int entries,
+static struct array_cache *alloc_arraycache(int node, int entries,
int batchcount)
{
int memsize = sizeof(void*)*entries+sizeof(struct array_cache);
struct array_cache *nc = NULL;
- if (cpu == -1)
- nc = kmalloc(memsize, GFP_KERNEL);
- else
- nc = kmalloc_node(memsize, GFP_KERNEL, cpu_to_node(cpu));
-
+ nc = kmalloc_node(memsize, GFP_KERNEL, node);
if (nc) {
nc->avail = 0;
nc->limit = entries;
nc->batchcount = batchcount;
nc->touched = 0;
+ spin_lock_init(&nc->lock);
}
return nc;
}
+#ifdef CONFIG_NUMA
+static inline struct array_cache **alloc_alien_cache(int node, int limit)
+{
+ struct array_cache **ac_ptr;
+ int memsize = sizeof(void*)*MAX_NUMNODES;
+ int i;
+
+ if (limit > 1)
+ limit = 12;
+ ac_ptr = kmalloc_node(memsize, GFP_KERNEL, node);
+ if (ac_ptr) {
+ for_each_node(i) {
+ if (i == node || !node_online(i)) {
+ ac_ptr[i] = NULL;
+ continue;
+ }
+ ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d);
+ if (!ac_ptr[i]) {
+ for (i--; i <=0; i--)
+ kfree(ac_ptr[i]);
+ kfree(ac_ptr);
+ return NULL;
+ }
+ }
+ }
+ return ac_ptr;
+}
+
+static inline void free_alien_cache(struct array_cache **ac_ptr)
+{
+ int i;
+
+ if (!ac_ptr)
+ return;
+
+ for_each_node(i)
+ kfree(ac_ptr[i]);
+
+ kfree(ac_ptr);
+}
+
+static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache *ac, int node)
+{
+ struct kmem_list3 *rl3 = cachep->nodelists[node];
+
+ if (ac->avail) {
+ spin_lock(&rl3->list_lock);
+ free_block(cachep, ac->entry, ac->avail);
+ ac->avail = 0;
+ spin_unlock(&rl3->list_lock);
+ }
+}
+
+static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
+{
+ int i=0;
+ struct array_cache *ac;
+ unsigned long flags;
+
+ for_each_online_node(i) {
+ ac = l3->alien[i];
+ if (ac) {
+ spin_lock_irqsave(&ac->lock, flags);
+ __drain_alien_cache(cachep, ac, i);
+ spin_unlock_irqrestore(&ac->lock, flags);
+ }
+ }
+}
+#else
+#define alloc_alien_cache(node, limit) do { } while (0)
+#define free_alien_cache(ac_ptr) do { } while (0)
+#define drain_alien_cache(cachep, l3) do { } while (0)
+#endif
+
static int __devinit cpuup_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
kmem_cache_t* cachep;
+ struct kmem_list3 *l3 = NULL;
+ int node = cpu_to_node(cpu);
+ int memsize = sizeof(struct kmem_list3);
+ struct array_cache *nc = NULL;
switch (action) {
case CPU_UP_PREPARE:
down(&cache_chain_sem);
+ /* we need to do this right in the beginning since
+ * alloc_arraycache's are going to use this list.
+ * kmalloc_node allows us to add the slab to the right
+ * kmem_list3 and not this cpu's kmem_list3
+ */
+
list_for_each_entry(cachep, &cache_chain, next) {
- struct array_cache *nc;
+ /* setup the size64 kmemlist for cpu before we can
+ * begin anything. Make sure some other cpu on this
+ * node has not already allocated this
+ */
+ if (!cachep->nodelists[node]) {
+ if (!(l3 = kmalloc_node(memsize,
+ GFP_KERNEL, node)))
+ goto bad;
+ kmem_list3_init(l3);
+ l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
+ ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+
+ cachep->nodelists[node] = l3;
+ }
+
+ spin_lock_irq(&cachep->nodelists[node]->list_lock);
+ cachep->nodelists[node]->free_limit =
+ (1 + nr_cpus_node(node)) *
+ cachep->batchcount + cachep->num;
+ spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+ }
- nc = alloc_arraycache(cpu, cachep->limit, cachep->batchcount);
+ /* Now we can go ahead with allocating the shared array's
+ & array cache's */
+ list_for_each_entry(cachep, &cache_chain, next) {
+ nc = alloc_arraycache(node, cachep->limit,
+ cachep->batchcount);
if (!nc)
goto bad;
-
- spin_lock_irq(&cachep->spinlock);
cachep->array[cpu] = nc;
- cachep->free_limit = (1+num_online_cpus())*cachep->batchcount
- + cachep->num;
- spin_unlock_irq(&cachep->spinlock);
+ l3 = cachep->nodelists[node];
+ BUG_ON(!l3);
+ if (!l3->shared) {
+ if (!(nc = alloc_arraycache(node,
+ cachep->shared*cachep->batchcount,
+ 0xbaadf00d)))
+ goto bad;
+
+ /* we are serialised from CPU_DEAD or
+ CPU_UP_CANCELLED by the cpucontrol lock */
+ l3->shared = nc;
+ }
}
up(&cache_chain_sem);
break;
@@ -732,13 +908,51 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
list_for_each_entry(cachep, &cache_chain, next) {
struct array_cache *nc;
+ cpumask_t mask;
+ mask = node_to_cpumask(node);
spin_lock_irq(&cachep->spinlock);
/* cpu is dead; no one can alloc from it. */
nc = cachep->array[cpu];
cachep->array[cpu] = NULL;
- cachep->free_limit -= cachep->batchcount;
- free_block(cachep, ac_entry(nc), nc->avail);
+ l3 = cachep->nodelists[node];
+
+ if (!l3)
+ goto unlock_cache;
+
+ spin_lock(&l3->list_lock);
+
+ /* Free limit for this kmem_list3 */
+ l3->free_limit -= cachep->batchcount;
+ if (nc)
+ free_block(cachep, nc->entry, nc->avail);
+
+ if (!cpus_empty(mask)) {
+ spin_unlock(&l3->list_lock);
+ goto unlock_cache;
+ }
+
+ if (l3->shared) {
+ free_block(cachep, l3->shared->entry,
+ l3->shared->avail);
+ kfree(l3->shared);
+ l3->shared = NULL;
+ }
+ if (l3->alien) {
+ drain_alien_cache(cachep, l3);
+ free_alien_cache(l3->alien);
+ l3->alien = NULL;
+ }
+
+ /* free slabs belonging to this node */
+ if (__node_shrink(cachep, node)) {
+ cachep->nodelists[node] = NULL;
+ spin_unlock(&l3->list_lock);
+ kfree(l3);
+ } else {
+ spin_unlock(&l3->list_lock);
+ }
+unlock_cache:
spin_unlock_irq(&cachep->spinlock);
kfree(nc);
}
@@ -754,6 +968,25 @@ bad:
static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 };
+/*
+ * swap the static kmem_list3 with kmalloced memory
+ */
+static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list,
+ int nodeid)
+{
+ struct kmem_list3 *ptr;
+
+ BUG_ON(cachep->nodelists[nodeid] != list);
+ ptr = kmalloc_node(sizeof(struct kmem_list3), GFP_KERNEL, nodeid);
+ BUG_ON(!ptr);
+
+ local_irq_disable();
+ memcpy(ptr, list, sizeof(struct kmem_list3));
+ MAKE_ALL_LISTS(cachep, ptr, nodeid);
+ cachep->nodelists[nodeid] = ptr;
+ local_irq_enable();
+}
+
/* Initialisation.
* Called after the gfp() functions have been enabled, and before smp_init().
*/
@@ -762,6 +995,13 @@ void __init kmem_cache_init(void)
size_t left_over;
struct cache_sizes *sizes;
struct cache_names *names;
+ int i;
+
+ for (i = 0; i < NUM_INIT_LISTS; i++) {
+ kmem_list3_init(&initkmem_list3[i]);
+ if (i < MAX_NUMNODES)
+ cache_cache.nodelists[i] = NULL;
+ }
/*
* Fragmentation resistance on low memory - only use bigger
@@ -770,21 +1010,24 @@ void __init kmem_cache_init(void)
if (num_physpages > (32 << 20) >> PAGE_SHIFT)
slab_break_gfp_order = BREAK_GFP_ORDER_HI;
-
/* Bootstrap is tricky, because several objects are allocated
* from caches that do not exist yet:
* 1) initialize the cache_cache cache: it contains the kmem_cache_t
* structures of all caches, except cache_cache itself: cache_cache
* is statically allocated.
- * Initially an __init data area is used for the head array, it's
- * replaced with a kmalloc allocated array at the end of the bootstrap.
+ * Initially an __init data area is used for the head array and the
+ * kmem_list3 structures, it's replaced with a kmalloc allocated
+ * array at the end of the bootstrap.
* 2) Create the first kmalloc cache.
- * The kmem_cache_t for the new cache is allocated normally. An __init
- * data area is used for the head array.
- * 3) Create the remaining kmalloc caches, with minimally sized head arrays.
+ * The kmem_cache_t for the new cache is allocated normally.
+ * An __init data area is used for the head array.
+ * 3) Create the remaining kmalloc caches, with minimally sized
+ * head arrays.
* 4) Replace the __init data head arrays for cache_cache and the first
* kmalloc cache with kmalloc allocated arrays.
- * 5) Resize the head arrays of the kmalloc caches to their final sizes.
+ * 5) Replace the __init data for kmem_list3 for cache_cache and
+ * the other cache's with kmalloc allocated memory.
+ * 6) Resize the head arrays of the kmalloc caches to their final sizes.
*/
/* 1) create the cache_cache */
@@ -793,6 +1036,7 @@ void __init kmem_cache_init(void)
list_add(&cache_cache.next, &cache_chain);
cache_cache.colour_off = cache_line_size();
cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
+ cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE];
cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size());
@@ -810,15 +1054,33 @@ void __init kmem_cache_init(void)
sizes = malloc_sizes;
names = cache_names;
+ /* Initialize the caches that provide memory for the array cache
+ * and the kmem_list3 structures first.
+ * Without this, further allocations will bug
+ */
+
+ sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
+ sizes[INDEX_AC].cs_size, ARCH_KMALLOC_MINALIGN,
+ (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+
+ if (INDEX_AC != INDEX_L3)
+ sizes[INDEX_L3].cs_cachep =
+ kmem_cache_create(names[INDEX_L3].name,
+ sizes[INDEX_L3].cs_size, ARCH_KMALLOC_MINALIGN,
+ (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+
while (sizes->cs_size != ULONG_MAX) {
- /* For performance, all the general caches are L1 aligned.
+ /*
+ * For performance, all the general caches are L1 aligned.
* This should be particularly beneficial on SMP boxes, as it
* eliminates "false sharing".
* Note for systems short on memory removing the alignment will
- * allow tighter packing of the smaller caches. */
- sizes->cs_cachep = kmem_cache_create(names->name,
- sizes->cs_size, ARCH_KMALLOC_MINALIGN,
- (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+ * allow tighter packing of the smaller caches.
+ */
+ if(!sizes->cs_cachep)
+ sizes->cs_cachep = kmem_cache_create(names->name,
+ sizes->cs_size, ARCH_KMALLOC_MINALIGN,
+ (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
/* Inc off-slab bufctl limit until the ceiling is hit. */
if (!(OFF_SLAB(sizes->cs_cachep))) {
@@ -837,24 +1099,47 @@ void __init kmem_cache_init(void)
/* 4) Replace the bootstrap head arrays */
{
void * ptr;
-
+
ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
+
local_irq_disable();
BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
- memcpy(ptr, ac_data(&cache_cache), sizeof(struct arraycache_init));
+ memcpy(ptr, ac_data(&cache_cache),
+ sizeof(struct arraycache_init));
cache_cache.array[smp_processor_id()] = ptr;
local_irq_enable();
-
+
ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
+
local_irq_disable();
- BUG_ON(ac_data(malloc_sizes[0].cs_cachep) != &initarray_generic.cache);
- memcpy(ptr, ac_data(malloc_sizes[0].cs_cachep),
+ BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
+ != &initarray_generic.cache);
+ memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
sizeof(struct arraycache_init));
- malloc_sizes[0].cs_cachep->array[smp_processor_id()] = ptr;
+ malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
+ ptr;
local_irq_enable();
}
+ /* 5) Replace the bootstrap kmem_list3's */
+ {
+ int node;
+ /* Replace the static kmem_list3 structures for the boot cpu */
+ init_list(&cache_cache, &initkmem_list3[CACHE_CACHE],
+ numa_node_id());
+
+ for_each_online_node(node) {
+ init_list(malloc_sizes[INDEX_AC].cs_cachep,
+ &initkmem_list3[SIZE_AC+node], node);
+
+ if (INDEX_AC != INDEX_L3) {
+ init_list(malloc_sizes[INDEX_L3].cs_cachep,
+ &initkmem_list3[SIZE_L3+node],
+ node);
+ }
+ }
+ }
- /* 5) resize the head arrays to their final sizes */
+ /* 6) resize the head arrays to their final sizes */
{
kmem_cache_t *cachep;
down(&cache_chain_sem);
@@ -870,7 +1155,6 @@ void __init kmem_cache_init(void)
* that initializes ac_data for all new cpus
*/
register_cpu_notifier(&cpucache_notifier);
-
/* The reap timers are started later, with a module init call:
* That part of the kernel is not yet operational.
@@ -885,10 +1169,8 @@ static int __init cpucache_init(void)
* Register the timers that return unneeded
* pages to gfp.
*/
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- if (cpu_online(cpu))
- start_cpu_timer(cpu);
- }
+ for_each_online_cpu(cpu)
+ start_cpu_timer(cpu);
return 0;
}
@@ -1167,6 +1449,20 @@ static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
}
}
+/* For setting up all the kmem_list3s for cache whose objsize is same
+ as size of kmem_list3. */
+static inline void set_up_list3s(kmem_cache_t *cachep, int index)
+{
+ int node;
+
+ for_each_online_node(node) {
+ cachep->nodelists[node] = &initkmem_list3[index+node];
+ cachep->nodelists[node]->next_reap = jiffies +
+ REAPTIMEOUT_LIST3 +
+ ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+ }
+}
+
/**
* kmem_cache_create - Create a cache.
* @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,
size += BYTES_PER_WORD;
}
#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
- if (size > 128 && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
+ if (size >= malloc_sizes[INDEX_L3+1].cs_size && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
cachep->dbghead += PAGE_SIZE - size;
size = PAGE_SIZE;
}
@@ -1422,10 +1718,6 @@ next:
cachep->gfpflags |= GFP_DMA;
spin_lock_init(&cachep->spinlock);
cachep->objsize = size;
- /* NUMA */
- INIT_LIST_HEAD(&cachep->lists.slabs_full);
- INIT_LIST_HEAD(&cachep->lists.slabs_partial);
- INIT_LIST_HEAD(&cachep->lists.slabs_free);
if (flags & CFLGS_OFF_SLAB)
cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
@@ -1444,11 +1736,43 @@ next:
* the cache that's used by kmalloc(24), otherwise
* the creation of further caches will BUG().
*/
- cachep->array[smp_processor_id()] = &initarray_generic.cache;
- g_cpucache_up = PARTIAL;
+ cachep->array[smp_processor_id()] =
+ &initarray_generic.cache;
+
+ /* If the cache that's used by
+ * kmalloc(sizeof(kmem_list3)) is the first cache,
+ * then we need to set up all its list3s, otherwise
+ * the creation of further caches will BUG().
+ */
+ set_up_list3s(cachep, SIZE_AC);
+ if (INDEX_AC == INDEX_L3)
+ g_cpucache_up = PARTIAL_L3;
+ else
+ g_cpucache_up = PARTIAL_AC;
} else {
- cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL);
+ cachep->array[smp_processor_id()] =
+ kmalloc(sizeof(struct arraycache_init),
+ GFP_KERNEL);
+
+ if (g_cpucache_up == PARTIAL_AC) {
+ set_up_list3s(cachep, SIZE_L3);
+ g_cpucache_up = PARTIAL_L3;
+ } else {
+ int node;
+ for_each_online_node(node) {
+
+ cachep->nodelists[node] =
+ kmalloc_node(sizeof(struct kmem_list3),
+ GFP_KERNEL, node);
+ BUG_ON(!cachep->nodelists[node]);
+ kmem_list3_init(cachep->nodelists[node]);
+ }
+ }
}
+ cachep->nodelists[numa_node_id()]->next_reap =
+ jiffies + REAPTIMEOUT_LIST3 +
+ ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+
BUG_ON(!ac_data(cachep));
ac_data(cachep)->avail = 0;
ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
@@ -1456,13 +1780,8 @@ next:
ac_data(cachep)->touched = 0;
cachep->batchcount = 1;
cachep->limit = BOOT_CPUCACHE_ENTRIES;
- cachep->free_limit = (1+num_online_cpus())*cachep->batchcount
- + cachep->num;
}
- cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
- ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
-
/* Need the semaphore to access the chain. */
down(&cache_chain_sem);
{
@@ -1519,13 +1838,23 @@ static void check_spinlock_acquired(kmem_cache_t *cachep)
{
#ifdef CONFIG_SMP
check_irq_off();
- BUG_ON(spin_trylock(&cachep->spinlock));
+ assert_spin_locked(&cachep->nodelists[numa_node_id()]->list_lock);
#endif
}
+
+static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node)
+{
+#ifdef CONFIG_SMP
+ check_irq_off();
+ assert_spin_locked(&cachep->nodelists[node]->list_lock);
+#endif
+}
+
#else
#define check_irq_off() do { } while(0)
#define check_irq_on() do { } while(0)
#define check_spinlock_acquired(x) do { } while(0)
+#define check_spinlock_acquired_node(x, y) do { } while(0)
#endif
/*
@@ -1547,7 +1876,7 @@ static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
}
static void drain_array_locked(kmem_cache_t* cachep,
- struct array_cache *ac, int force);
+ struct array_cache *ac, int force, int node);
static void do_drain(void *arg)
{
@@ -1556,59 +1885,82 @@ static void do_drain(void *arg)
check_irq_off();
ac = ac_data(cachep);
- spin_lock(&cachep->spinlock);
- free_block(cachep, &ac_entry(ac)[0], ac->avail);
- spin_unlock(&cachep->spinlock);
+ spin_lock(&cachep->nodelists[numa_node_id()]->list_lock);
+ free_block(cachep, ac->entry, ac->avail);
+ spin_unlock(&cachep->nodelists[numa_node_id()]->list_lock);
ac->avail = 0;
}
static void drain_cpu_caches(kmem_cache_t *cachep)
{
+ struct kmem_list3 *l3;
+ int node;
+
smp_call_function_all_cpus(do_drain, cachep);
check_irq_on();
spin_lock_irq(&cachep->spinlock);
- if (cachep->lists.shared)
- drain_array_locked(cachep, cachep->lists.shared, 1);
+ for_each_online_node(node) {
+ l3 = cachep->nodelists[node];
+ if (l3) {
+ spin_lock(&l3->list_lock);
+ drain_array_locked(cachep, l3->shared, 1, node);
+ spin_unlock(&l3->list_lock);
+ if (l3->alien)
+ drain_alien_cache(cachep, l3);
+ }
+ }
spin_unlock_irq(&cachep->spinlock);
}
-
-/* NUMA shrink all list3s */
-static int __cache_shrink(kmem_cache_t *cachep)
+static int __node_shrink(kmem_cache_t *cachep, int node)
{
struct slab *slabp;
+ struct kmem_list3 *l3 = cachep->nodelists[node];
int ret;
- drain_cpu_caches(cachep);
-
- check_irq_on();
- spin_lock_irq(&cachep->spinlock);
-
- for(;;) {
+ for (;;) {
struct list_head *p;
- p = cachep->lists.slabs_free.prev;
- if (p == &cachep->lists.slabs_free)
+ p = l3->slabs_free.prev;
+ if (p == &l3->slabs_free)
break;
- slabp = list_entry(cachep->lists.slabs_free.prev, struct slab, list);
+ slabp = list_entry(l3->slabs_free.prev, struct slab, list);
#if DEBUG
if (slabp->inuse)
BUG();
#endif
list_del(&slabp->list);
- cachep->lists.free_objects -= cachep->num;
- spin_unlock_irq(&cachep->spinlock);
+ l3->free_objects -= cachep->num;
+ spin_unlock_irq(&l3->list_lock);
slab_destroy(cachep, slabp);
- spin_lock_irq(&cachep->spinlock);
+ spin_lock_irq(&l3->list_lock);
}
- ret = !list_empty(&cachep->lists.slabs_full) ||
- !list_empty(&cachep->lists.slabs_partial);
- spin_unlock_irq(&cachep->spinlock);
+ ret = !list_empty(&l3->slabs_full) ||
+ !list_empty(&l3->slabs_partial);
return ret;
}
+static int __cache_shrink(kmem_cache_t *cachep)
+{
+ int ret = 0, i = 0;
+ struct kmem_list3 *l3;
+
+ drain_cpu_caches(cachep);
+
+ check_irq_on();
+ for_each_online_node(i) {
+ l3 = cachep->nodelists[i];
+ if (l3) {
+ spin_lock_irq(&l3->list_lock);
+ ret += __node_shrink(cachep, i);
+ spin_unlock_irq(&l3->list_lock);
+ }
+ }
+ return (ret ? 1 : 0);
+}
+
/**
* kmem_cache_shrink - Shrink a cache.
* @cachep: The cache to shrink.
@@ -1645,6 +1997,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
int kmem_cache_destroy(kmem_cache_t * cachep)
{
int i;
+ struct kmem_list3 *l3;
if (!cachep || in_interrupt())
BUG();
@@ -1672,15 +2025,17 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
synchronize_rcu();
- /* no cpu_online check required here since we clear the percpu
- * array on cpu offline and set this to NULL.
- */
- for (i = 0; i < NR_CPUS; i++)
+ for_each_online_cpu(i)
kfree(cachep->array[i]);
/* NUMA: free the list3 structures */
- kfree(cachep->lists.shared);
- cachep->lists.shared = NULL;
+ for_each_online_node(i) {
+ if ((l3 = cachep->nodelists[i])) {
+ kfree(l3->shared);
+ free_alien_cache(l3->alien);
+ kfree(l3);
+ }
+ }
kmem_cache_free(&cache_cache, cachep);
unlock_cpu_hotplug();
@@ -1690,8 +2045,8 @@ int kmem_cache_destroy(kmem_cache_t * cachep)
EXPORT_SYMBOL(kmem_cache_destroy);
/* Get the memory for a slab management obj. */
-static struct slab* alloc_slabmgmt(kmem_cache_t *cachep,
- void *objp, int colour_off, unsigned int __nocast local_flags)
+static struct slab* alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
+ int colour_off, unsigned int __nocast local_flags)
{
struct slab *slabp;
@@ -1722,7 +2077,7 @@ static void cache_init_objs(kmem_cache_t *cachep,
int i;
for (i = 0; i < cachep->num; i++) {
- void* objp = slabp->s_mem+cachep->objsize*i;
+ void *objp = slabp->s_mem+cachep->objsize*i;
#if DEBUG
/* need to poison the objs? */
if (cachep->flags & SLAB_POISON)
@@ -1799,6 +2154,7 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
size_t offset;
unsigned int local_flags;
unsigned long ctor_flags;
+ struct kmem_list3 *l3;
/* Be lazy and only check for valid flags here,
* 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
spin_unlock(&cachep->spinlock);
+ check_irq_off();
if (local_flags & __GFP_WAIT)
local_irq_enable();
@@ -1841,8 +2198,9 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
*/
kmem_flagcheck(cachep, flags);
-
- /* Get mem for the objs. */
+ /* Get mem for the objs.
+ * Attempt to allocate a physical page from 'nodeid',
+ */
if (!(objp = kmem_getpages(cachep, flags, nodeid)))
goto failed;
@@ -1850,6 +2208,7 @@ static int cache_grow(kmem_cache_t *cachep, unsigned int __nocast flags, int nod
if (!(slabp = alloc_slabmgmt(cachep, objp, offset, local_flags)))
goto opps1;
+ slabp->nodeid = nodeid;
set_slab_attr(cachep, slabp, objp);
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
if (local_flags & __GFP_WAIT)
local_irq_disable();
check_irq_off();
- spin_lock(&cachep->spinlock);
+ l3 = cachep->nodelists[nodeid];
+ spin_lock(&l3->list_lock);
/* Make slab active. */
- list_add_tail(&slabp->list, &(list3_data(cachep)->slabs_free));
+ list_add_tail(&slabp->list, &(l3->slabs_free));
STATS_INC_GROWN(cachep);
- list3_data(cachep)->free_objects += cachep->num;
- spin_unlock(&cachep->spinlock);
+ l3->free_objects += cachep->num;
+ spin_unlock(&l3->list_lock);
return 1;
opps1:
kmem_freepages(cachep, objp);
@@ -1969,7 +2329,6 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
kmem_bufctl_t i;
int entries = 0;
- check_spinlock_acquired(cachep);
/* Check slab's freelist to see if this obj is there. */
for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
entries++;
@@ -2012,10 +2371,11 @@ retry:
*/
batchcount = BATCHREFILL_LIMIT;
}
- l3 = list3_data(cachep);
+ l3 = cachep->nodelists[numa_node_id()];
+
+ BUG_ON(ac->avail > 0 || !l3);
+ spin_lock(&l3->list_lock);
- BUG_ON(ac->avail > 0);
- spin_lock(&cachep->spinlock);
if (l3->shared) {
struct array_cache *shared_array = l3->shared;
if (shared_array->avail) {
@@ -2023,8 +2383,9 @@ retry:
batchcount = shared_array->avail;
shared_array->avail -= batchcount;
ac->avail = batchcount;
- memcpy(ac_entry(ac), &ac_entry(shared_array)[shared_array->avail],
- sizeof(void*)*batchcount);
+ memcpy(ac->entry,
+ &(shared_array->entry[shared_array->avail]),
+ sizeof(void*)*batchcount);
shared_array->touched = 1;
goto alloc_done;
}
@@ -2051,7 +2412,8 @@ retry:
STATS_SET_HIGH(cachep);
/* get obj pointer */
- ac_entry(ac)[ac->avail++] = slabp->s_mem + slabp->free*cachep->objsize;
+ ac->entry[ac->avail++] = slabp->s_mem +
+ slabp->free*cachep->objsize;
slabp->inuse++;
next = slab_bufctl(slabp)[slabp->free];
@@ -2073,12 +2435,12 @@ retry:
must_grow:
l3->free_objects -= ac->avail;
alloc_done:
- spin_unlock(&cachep->spinlock);
+ spin_unlock(&l3->list_lock);
if (unlikely(!ac->avail)) {
int x;
- x = cache_grow(cachep, flags, -1);
-
+ x = cache_grow(cachep, flags, numa_node_id());
+
// cache_grow can reenable interrupts, then ac could change.
ac = ac_data(cachep);
if (!x && ac->avail == 0) // no objects in sight? abort
@@ -2088,7 +2450,7 @@ alloc_done:
goto retry;
}
ac->touched = 1;
- return ac_entry(ac)[--ac->avail];
+ return ac->entry[--ac->avail];
}
static inline void
@@ -2160,7 +2522,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast fl
if (likely(ac->avail)) {
STATS_INC_ALLOCHIT(cachep);
ac->touched = 1;
- objp = ac_entry(ac)[--ac->avail];
+ objp = ac->entry[--ac->avail];
} else {
STATS_INC_ALLOCMISS(cachep);
objp = cache_alloc_refill(cachep, flags);
@@ -2172,33 +2534,104 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast fl
return objp;
}
-/*
- * NUMA: different approach needed if the spinlock is moved into
- * the l3 structure
+#ifdef CONFIG_NUMA
+/*
+ * A interface to enable slab creation on nodeid
*/
+static void *__cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
+{
+ struct list_head *entry;
+ struct slab *slabp;
+ struct kmem_list3 *l3;
+ void *obj;
+ kmem_bufctl_t next;
+ int x;
+
+ l3 = cachep->nodelists[nodeid];
+ BUG_ON(!l3);
+
+retry:
+ spin_lock(&l3->list_lock);
+ entry = l3->slabs_partial.next;
+ if (entry == &l3->slabs_partial) {
+ l3->free_touched = 1;
+ entry = l3->slabs_free.next;
+ if (entry == &l3->slabs_free)
+ goto must_grow;
+ }
+
+ slabp = list_entry(entry, struct slab, list);
+ check_spinlock_acquired_node(cachep, nodeid);
+ check_slabp(cachep, slabp);
+
+ STATS_INC_NODEALLOCS(cachep);
+ STATS_INC_ACTIVE(cachep);
+ STATS_SET_HIGH(cachep);
+
+ BUG_ON(slabp->inuse == cachep->num);
+
+ /* get obj pointer */
+ obj = slabp->s_mem + slabp->free*cachep->objsize;
+ slabp->inuse++;
+ next = slab_bufctl(slabp)[slabp->free];
+#if DEBUG
+ slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+#endif
+ slabp->free = next;
+ check_slabp(cachep, slabp);
+ l3->free_objects--;
+ /* move slabp to correct slabp list: */
+ list_del(&slabp->list);
+ if (slabp->free == BUFCTL_END) {
+ list_add(&slabp->list, &l3->slabs_full);
+ } else {
+ list_add(&slabp->list, &l3->slabs_partial);
+ }
+
+ spin_unlock(&l3->list_lock);
+ goto done;
+
+must_grow:
+ spin_unlock(&l3->list_lock);
+ x = cache_grow(cachep, flags, nodeid);
+
+ if (!x)
+ return NULL;
+
+ goto retry;
+done:
+ return obj;
+}
+#endif
+
+/*
+ * Caller needs to acquire correct kmem_list's list_lock
+ */
static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
{
int i;
-
- check_spinlock_acquired(cachep);
-
- /* NUMA: move add into loop */
- cachep->lists.free_objects += nr_objects;
+ struct kmem_list3 *l3;
for (i = 0; i < nr_objects; i++) {
void *objp = objpp[i];
struct slab *slabp;
unsigned int objnr;
+ int nodeid = 0;
slabp = GET_PAGE_SLAB(virt_to_page(objp));
+ nodeid = slabp->nodeid;
+ l3 = cachep->nodelists[nodeid];
list_del(&slabp->list);
objnr = (objp - slabp->s_mem) / cachep->objsize;
+ check_spinlock_acquired_node(cachep, nodeid);
check_slabp(cachep, slabp);
+
+
#if DEBUG
if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
- printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n",
- cachep->name, objp);
+ printk(KERN_ERR "slab: double free detected in cache "
+ "'%s', objp %p\n", cachep->name, objp);
BUG();
}
#endif
@@ -2206,24 +2639,23 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
slabp->free = objnr;
STATS_DEC_ACTIVE(cachep);
slabp->inuse--;
+ l3->free_objects++;
check_slabp(cachep, slabp);
/* fixup slab chains */
if (slabp->inuse == 0) {
- if (cachep->lists.free_objects > cachep->free_limit) {
- cachep->lists.free_objects -= cachep->num;
+ if (l3->free_objects > l3->free_limit) {
+ l3->free_objects -= cachep->num;
slab_destroy(cachep, slabp);
} else {
- list_add(&slabp->list,
- &list3_data_ptr(cachep, objp)->slabs_free);
+ list_add(&slabp->list, &l3->slabs_free);
}
} else {
/* Unconditionally move a slab to the end of the
* partial list on free - maximum time for the
* other objects to be freed, too.
*/
- list_add_tail(&slabp->list,
- &list3_data_ptr(cachep, objp)->slabs_partial);
+ list_add_tail(&slabp->list, &l3->slabs_partial);
}
}
}
@@ -2231,36 +2663,38 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
{
int batchcount;
+ struct kmem_list3 *l3;
batchcount = ac->batchcount;
#if DEBUG
BUG_ON(!batchcount || batchcount > ac->avail);
#endif
check_irq_off();
- spin_lock(&cachep->spinlock);
- if (cachep->lists.shared) {
- struct array_cache *shared_array = cachep->lists.shared;
+ l3 = cachep->nodelists[numa_node_id()];
+ spin_lock(&l3->list_lock);
+ if (l3->shared) {
+ struct array_cache *shared_array = l3->shared;
int max = shared_array->limit-shared_array->avail;
if (max) {
if (batchcount > max)
batchcount = max;
- memcpy(&ac_entry(shared_array)[shared_array->avail],
- &ac_entry(ac)[0],
+ memcpy(&(shared_array->entry[shared_array->avail]),
+ ac->entry,
sizeof(void*)*batchcount);
shared_array->avail += batchcount;
goto free_done;
}
}
- free_block(cachep, &ac_entry(ac)[0], batchcount);
+ free_block(cachep, ac->entry, batchcount);
free_done:
#if STATS
{
int i = 0;
struct list_head *p;
- p = list3_data(cachep)->slabs_free.next;
- while (p != &(list3_data(cachep)->slabs_free)) {
+ p = l3->slabs_free.next;
+ while (p != &(l3->slabs_free)) {
struct slab *slabp;
slabp = list_entry(p, struct slab, list);
@@ -2272,12 +2706,13 @@ free_done:
STATS_SET_FREEABLE(cachep, i);
}
#endif
- spin_unlock(&cachep->spinlock);
+ spin_unlock(&l3->list_lock);
ac->avail -= batchcount;
- memmove(&ac_entry(ac)[0], &ac_entry(ac)[batchcount],
+ memmove(ac->entry, &(ac->entry[batchcount]),
sizeof(void*)*ac->avail);
}
+
/*
* __cache_free
* 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)
check_irq_off();
objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
+ /* Make sure we are not freeing a object from another
+ * node to the array cache on this cpu.
+ */
+#ifdef CONFIG_NUMA
+ {
+ struct slab *slabp;
+ slabp = GET_PAGE_SLAB(virt_to_page(objp));
+ if (unlikely(slabp->nodeid != numa_node_id())) {
+ struct array_cache *alien = NULL;
+ int nodeid = slabp->nodeid;
+ struct kmem_list3 *l3 = cachep->nodelists[numa_node_id()];
+
+ STATS_INC_NODEFREES(cachep);
+ if (l3->alien && l3->alien[nodeid]) {
+ alien = l3->alien[nodeid];
+ spin_lock(&alien->lock);
+ if (unlikely(alien->avail == alien->limit))
+ __drain_alien_cache(cachep,
+ alien, nodeid);
+ alien->entry[alien->avail++] = objp;
+ spin_unlock(&alien->lock);
+ } else {
+ spin_lock(&(cachep->nodelists[nodeid])->
+ list_lock);
+ free_block(cachep, &objp, 1);
+ spin_unlock(&(cachep->nodelists[nodeid])->
+ list_lock);
+ }
+ return;
+ }
+ }
+#endif
if (likely(ac->avail < ac->limit)) {
STATS_INC_FREEHIT(cachep);
- ac_entry(ac)[ac->avail++] = objp;
+ ac->entry[ac->avail++] = objp;
return;
} else {
STATS_INC_FREEMISS(cachep);
cache_flusharray(cachep, ac);
- ac_entry(ac)[ac->avail++] = objp;
+ ac->entry[ac->avail++] = objp;
}
}
@@ -2369,81 +2836,30 @@ out:
* Identical to kmem_cache_alloc, except that this function is slow
* and can sleep. And it will allocate memory on the given node, which
* can improve the performance for cpu bound structures.
+ * New and improved: it will now make sure that the object gets
+ * put on the correct node list so that there is no false sharing.
*/
void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid)
{
- int loop;
- void *objp;
- struct slab *slabp;
- kmem_bufctl_t next;
-
- if (nodeid == -1)
- return kmem_cache_alloc(cachep, flags);
-
- for (loop = 0;;loop++) {
- struct list_head *q;
-
- objp = NULL;
- check_irq_on();
- spin_lock_irq(&cachep->spinlock);
- /* walk through all partial and empty slab and find one
- * from the right node */
- list_for_each(q,&cachep->lists.slabs_partial) {
- slabp = list_entry(q, struct slab, list);
-
- if (page_to_nid(virt_to_page(slabp->s_mem)) == nodeid ||
- loop > 2)
- goto got_slabp;
- }
- list_for_each(q, &cachep->lists.slabs_free) {
- slabp = list_entry(q, struct slab, list);
+ unsigned long save_flags;
+ void *ptr;
- if (page_to_nid(virt_to_page(slabp->s_mem)) == nodeid ||
- loop > 2)
- goto got_slabp;
- }
- spin_unlock_irq(&cachep->spinlock);
+ if (nodeid == numa_node_id() || nodeid == -1)
+ return __cache_alloc(cachep, flags);
- local_irq_disable();
- if (!cache_grow(cachep, flags, nodeid)) {
- local_irq_enable();
- return NULL;
- }
- local_irq_enable();
+ if (unlikely(!cachep->nodelists[nodeid])) {
+ /* Fall back to __cache_alloc if we run into trouble */
+ printk(KERN_WARNING "slab: not allocating in inactive node %d for cache %s\n", nodeid, cachep->name);
+ return __cache_alloc(cachep,flags);
}
-got_slabp:
- /* found one: allocate object */
- check_slabp(cachep, slabp);
- check_spinlock_acquired(cachep);
-
- STATS_INC_ALLOCED(cachep);
- STATS_INC_ACTIVE(cachep);
- STATS_SET_HIGH(cachep);
- STATS_INC_NODEALLOCS(cachep);
- objp = slabp->s_mem + slabp->free*cachep->objsize;
-
- slabp->inuse++;
- next = slab_bufctl(slabp)[slabp->free];
-#if DEBUG
- slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-#endif
- slabp->free = next;
- check_slabp(cachep, slabp);
-
- /* move slabp to correct slabp list: */
- list_del(&slabp->list);
- if (slabp->free == BUFCTL_END)
- list_add(&slabp->list, &cachep->lists.slabs_full);
- else
- list_add(&slabp->list, &cachep->lists.slabs_partial);
-
- list3_data(cachep)->free_objects--;
- spin_unlock_irq(&cachep->spinlock);
+ cache_alloc_debugcheck_before(cachep, flags);
+ local_irq_save(save_flags);
+ ptr = __cache_alloc_node(cachep, flags, nodeid);
+ local_irq_restore(save_flags);
+ ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0));
- objp = cache_alloc_debugcheck_after(cachep, GFP_KERNEL, objp,
- __builtin_return_address(0));
- return objp;
+ return ptr;
}
EXPORT_SYMBOL(kmem_cache_alloc_node);
@@ -2513,11 +2929,18 @@ void *__alloc_percpu(size_t size, size_t align)
if (!pdata)
return NULL;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
- pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL,
- cpu_to_node(i));
+ /*
+ * Cannot use for_each_online_cpu since a cpu may come online
+ * and we have no way of figuring out how to fix the array
+ * that we have allocated then....
+ */
+ for_each_cpu(i) {
+ int node = cpu_to_node(i);
+
+ if (node_online(node))
+ pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL, node);
+ else
+ pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
if (!pdata->ptrs[i])
goto unwind_oom;
@@ -2575,6 +2998,8 @@ EXPORT_SYMBOL(kzalloc);
* kfree - free previously allocated memory
* @objp: pointer returned by kmalloc.
*
+ * If @objp is NULL, no operation is performed.
+ *
* Don't free memory not originally allocated by kmalloc()
* or you will run into trouble.
*/
@@ -2607,11 +3032,11 @@ free_percpu(const void *objp)
int i;
struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ /*
+ * We allocate for all cpus so we cannot use for online cpu here.
+ */
+ for_each_cpu(i)
kfree(p->ptrs[i]);
- }
kfree(p);
}
EXPORT_SYMBOL(free_percpu);
@@ -2629,6 +3054,64 @@ const char *kmem_cache_name(kmem_cache_t *cachep)
}
EXPORT_SYMBOL_GPL(kmem_cache_name);
+/*
+ * This initializes kmem_list3 for all nodes.
+ */
+static int alloc_kmemlist(kmem_cache_t *cachep)
+{
+ int node;
+ struct kmem_list3 *l3;
+ int err = 0;
+
+ for_each_online_node(node) {
+ struct array_cache *nc = NULL, *new;
+ struct array_cache **new_alien = NULL;
+#ifdef CONFIG_NUMA
+ if (!(new_alien = alloc_alien_cache(node, cachep->limit)))
+ goto fail;
+#endif
+ if (!(new = alloc_arraycache(node, (cachep->shared*
+ cachep->batchcount), 0xbaadf00d)))
+ goto fail;
+ if ((l3 = cachep->nodelists[node])) {
+
+ spin_lock_irq(&l3->list_lock);
+
+ if ((nc = cachep->nodelists[node]->shared))
+ free_block(cachep, nc->entry,
+ nc->avail);
+
+ l3->shared = new;
+ if (!cachep->nodelists[node]->alien) {
+ l3->alien = new_alien;
+ new_alien = NULL;
+ }
+ l3->free_limit = (1 + nr_cpus_node(node))*
+ cachep->batchcount + cachep->num;
+ spin_unlock_irq(&l3->list_lock);
+ kfree(nc);
+ free_alien_cache(new_alien);
+ continue;
+ }
+ if (!(l3 = kmalloc_node(sizeof(struct kmem_list3),
+ GFP_KERNEL, node)))
+ goto fail;
+
+ kmem_list3_init(l3);
+ l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
+ ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+ l3->shared = new;
+ l3->alien = new_alien;
+ l3->free_limit = (1 + nr_cpus_node(node))*
+ cachep->batchcount + cachep->num;
+ cachep->nodelists[node] = l3;
+ }
+ return err;
+fail:
+ err = -ENOMEM;
+ return err;
+}
+
struct ccupdate_struct {
kmem_cache_t *cachep;
struct array_cache *new[NR_CPUS];
@@ -2641,7 +3124,7 @@ static void do_ccupdate_local(void *info)
check_irq_off();
old = ac_data(new->cachep);
-
+
new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];
new->new[smp_processor_id()] = old;
}
@@ -2651,54 +3134,43 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
int shared)
{
struct ccupdate_struct new;
- struct array_cache *new_shared;
- int i;
+ int i, err;
memset(&new.new,0,sizeof(new.new));
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i)) {
- new.new[i] = alloc_arraycache(i, limit, batchcount);
- if (!new.new[i]) {
- for (i--; i >= 0; i--) kfree(new.new[i]);
- return -ENOMEM;
- }
- } else {
- new.new[i] = NULL;
+ for_each_online_cpu(i) {
+ new.new[i] = alloc_arraycache(cpu_to_node(i), limit, batchcount);
+ if (!new.new[i]) {
+ for (i--; i >= 0; i--) kfree(new.new[i]);
+ return -ENOMEM;
}
}
new.cachep = cachep;
smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
-
+
check_irq_on();
spin_lock_irq(&cachep->spinlock);
cachep->batchcount = batchcount;
cachep->limit = limit;
- cachep->free_limit = (1+num_online_cpus())*cachep->batchcount + cachep->num;
+ cachep->shared = shared;
spin_unlock_irq(&cachep->spinlock);
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_online_cpu(i) {
struct array_cache *ccold = new.new[i];
if (!ccold)
continue;
- spin_lock_irq(&cachep->spinlock);
- free_block(cachep, ac_entry(ccold), ccold->avail);
- spin_unlock_irq(&cachep->spinlock);
+ spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
+ free_block(cachep, ccold->entry, ccold->avail);
+ spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
kfree(ccold);
}
- new_shared = alloc_arraycache(-1, batchcount*shared, 0xbaadf00d);
- if (new_shared) {
- struct array_cache *old;
- spin_lock_irq(&cachep->spinlock);
- old = cachep->lists.shared;
- cachep->lists.shared = new_shared;
- if (old)
- free_block(cachep, ac_entry(old), old->avail);
- spin_unlock_irq(&cachep->spinlock);
- kfree(old);
+ err = alloc_kmemlist(cachep);
+ if (err) {
+ printk(KERN_ERR "alloc_kmemlist failed for %s, error %d.\n",
+ cachep->name, -err);
+ BUG();
}
-
return 0;
}
@@ -2756,11 +3228,11 @@ static void enable_cpucache(kmem_cache_t *cachep)
}
static void drain_array_locked(kmem_cache_t *cachep,
- struct array_cache *ac, int force)
+ struct array_cache *ac, int force, int node)
{
int tofree;
- check_spinlock_acquired(cachep);
+ check_spinlock_acquired_node(cachep, node);
if (ac->touched && !force) {
ac->touched = 0;
} else if (ac->avail) {
@@ -2768,9 +3240,9 @@ static void drain_array_locked(kmem_cache_t *cachep,
if (tofree > ac->avail) {
tofree = (ac->avail+1)/2;
}
- free_block(cachep, ac_entry(ac), tofree);
+ free_block(cachep, ac->entry, tofree);
ac->avail -= tofree;
- memmove(&ac_entry(ac)[0], &ac_entry(ac)[tofree],
+ memmove(ac->entry, &(ac->entry[tofree]),
sizeof(void*)*ac->avail);
}
}
@@ -2789,6 +3261,7 @@ static void drain_array_locked(kmem_cache_t *cachep,
static void cache_reap(void *unused)
{
struct list_head *walk;
+ struct kmem_list3 *l3;
if (down_trylock(&cache_chain_sem)) {
/* Give up. Setup the next iteration. */
@@ -2809,27 +3282,32 @@ static void cache_reap(void *unused)
check_irq_on();
- spin_lock_irq(&searchp->spinlock);
+ l3 = searchp->nodelists[numa_node_id()];
+ if (l3->alien)
+ drain_alien_cache(searchp, l3);
+ spin_lock_irq(&l3->list_lock);
- drain_array_locked(searchp, ac_data(searchp), 0);
+ drain_array_locked(searchp, ac_data(searchp), 0,
+ numa_node_id());
- if(time_after(searchp->lists.next_reap, jiffies))
+ if (time_after(l3->next_reap, jiffies))
goto next_unlock;
- searchp->lists.next_reap = jiffies + REAPTIMEOUT_LIST3;
+ l3->next_reap = jiffies + REAPTIMEOUT_LIST3;
- if (searchp->lists.shared)
- drain_array_locked(searchp, searchp->lists.shared, 0);
+ if (l3->shared)
+ drain_array_locked(searchp, l3->shared, 0,
+ numa_node_id());
- if (searchp->lists.free_touched) {
- searchp->lists.free_touched = 0;
+ if (l3->free_touched) {
+ l3->free_touched = 0;
goto next_unlock;
}
- tofree = (searchp->free_limit+5*searchp->num-1)/(5*searchp->num);
+ tofree = (l3->free_limit+5*searchp->num-1)/(5*searchp->num);
do {
- p = list3_data(searchp)->slabs_free.next;
- if (p == &(list3_data(searchp)->slabs_free))
+ p = l3->slabs_free.next;
+ if (p == &(l3->slabs_free))
break;
slabp = list_entry(p, struct slab, list);
@@ -2842,13 +3320,13 @@ static void cache_reap(void *unused)
* searchp cannot disappear, we hold
* cache_chain_lock
*/
- searchp->lists.free_objects -= searchp->num;
- spin_unlock_irq(&searchp->spinlock);
+ l3->free_objects -= searchp->num;
+ spin_unlock_irq(&l3->list_lock);
slab_destroy(searchp, slabp);
- spin_lock_irq(&searchp->spinlock);
+ spin_lock_irq(&l3->list_lock);
} while(--tofree > 0);
next_unlock:
- spin_unlock_irq(&searchp->spinlock);
+ spin_unlock_irq(&l3->list_lock);
next:
cond_resched();
}
@@ -2882,7 +3360,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
#if STATS
seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>"
- " <error> <maxfreeable> <freelimit> <nodeallocs>");
+ " <error> <maxfreeable> <nodeallocs> <remotefrees>");
seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
#endif
seq_putc(m, '\n');
@@ -2917,39 +3395,53 @@ static int s_show(struct seq_file *m, void *p)
unsigned long active_objs;
unsigned long num_objs;
unsigned long active_slabs = 0;
- unsigned long num_slabs;
- const char *name;
+ unsigned long num_slabs, free_objects = 0, shared_avail = 0;
+ const char *name;
char *error = NULL;
+ int node;
+ struct kmem_list3 *l3;
check_irq_on();
spin_lock_irq(&cachep->spinlock);
active_objs = 0;
num_slabs = 0;
- list_for_each(q,&cachep->lists.slabs_full) {
- slabp = list_entry(q, struct slab, list);
- if (slabp->inuse != cachep->num && !error)
- error = "slabs_full accounting error";
- active_objs += cachep->num;
- active_slabs++;
- }
- list_for_each(q,&cachep->lists.slabs_partial) {
- slabp = list_entry(q, struct slab, list);
- if (slabp->inuse == cachep->num && !error)
- error = "slabs_partial inuse accounting error";
- if (!slabp->inuse && !error)
- error = "slabs_partial/inuse accounting error";
- active_objs += slabp->inuse;
- active_slabs++;
- }
- list_for_each(q,&cachep->lists.slabs_free) {
- slabp = list_entry(q, struct slab, list);
- if (slabp->inuse && !error)
- error = "slabs_free/inuse accounting error";
- num_slabs++;
+ for_each_online_node(node) {
+ l3 = cachep->nodelists[node];
+ if (!l3)
+ continue;
+
+ spin_lock(&l3->list_lock);
+
+ list_for_each(q,&l3->slabs_full) {
+ slabp = list_entry(q, struct slab, list);
+ if (slabp->inuse != cachep->num && !error)
+ error = "slabs_full accounting error";
+ active_objs += cachep->num;
+ active_slabs++;
+ }
+ list_for_each(q,&l3->slabs_partial) {
+ slabp = list_entry(q, struct slab, list);
+ if (slabp->inuse == cachep->num && !error)
+ error = "slabs_partial inuse accounting error";
+ if (!slabp->inuse && !error)
+ error = "slabs_partial/inuse accounting error";
+ active_objs += slabp->inuse;
+ active_slabs++;
+ }
+ list_for_each(q,&l3->slabs_free) {
+ slabp = list_entry(q, struct slab, list);
+ if (slabp->inuse && !error)
+ error = "slabs_free/inuse accounting error";
+ num_slabs++;
+ }
+ free_objects += l3->free_objects;
+ shared_avail += l3->shared->avail;
+
+ spin_unlock(&l3->list_lock);
}
num_slabs+=active_slabs;
num_objs = num_slabs*cachep->num;
- if (num_objs - active_objs != cachep->lists.free_objects && !error)
+ if (num_objs - active_objs != free_objects && !error)
error = "free_objects accounting error";
name = cachep->name;
@@ -2961,9 +3453,9 @@ static int s_show(struct seq_file *m, void *p)
cachep->num, (1<<cachep->gfporder));
seq_printf(m, " : tunables %4u %4u %4u",
cachep->limit, cachep->batchcount,
- cachep->lists.shared->limit/cachep->batchcount);
- seq_printf(m, " : slabdata %6lu %6lu %6u",
- active_slabs, num_slabs, cachep->lists.shared->avail);
+ cachep->shared);
+ seq_printf(m, " : slabdata %6lu %6lu %6lu",
+ active_slabs, num_slabs, shared_avail);
#if STATS
{ /* list3 stats */
unsigned long high = cachep->high_mark;
@@ -2972,12 +3464,13 @@ static int s_show(struct seq_file *m, void *p)
unsigned long reaped = cachep->reaped;
unsigned long errors = cachep->errors;
unsigned long max_freeable = cachep->max_freeable;
- unsigned long free_limit = cachep->free_limit;
unsigned long node_allocs = cachep->node_allocs;
+ unsigned long node_frees = cachep->node_frees;
- seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu %4lu %4lu %4lu %4lu",
- allocs, high, grown, reaped, errors,
- max_freeable, free_limit, node_allocs);
+ seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \
+ %4lu %4lu %4lu %4lu",
+ allocs, high, grown, reaped, errors,
+ max_freeable, node_allocs, node_frees);
}
/* cpu stats */
{
@@ -3056,9 +3549,10 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
batchcount < 1 ||
batchcount > limit ||
shared < 0) {
- res = -EINVAL;
+ res = 0;
} else {
- res = do_tune_cpucache(cachep, limit, batchcount, shared);
+ res = do_tune_cpucache(cachep, limit,
+ batchcount, shared);
}
break;
}
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 67b358e57ef..13c3d82968a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -332,9 +332,10 @@ void __vunmap(void *addr, int deallocate_pages)
* @addr: memory base address
*
* Free the virtually contiguous memory area starting at @addr, as
- * obtained from vmalloc(), vmalloc_32() or __vmalloc().
+ * obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
+ * NULL, no operation is performed.
*
- * May not be called in interrupt context.
+ * Must not be called in interrupt context.
*/
void vfree(void *addr)
{
@@ -352,7 +353,7 @@ EXPORT_SYMBOL(vfree);
* Free the virtually contiguous memory area starting at @addr,
* which was created from the page array passed to vmap().
*
- * May not be called in interrupt context.
+ * Must not be called in interrupt context.
*/
void vunmap(void *addr)
{
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 17a81ebe7e6..526d9531411 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -105,7 +105,7 @@ extern void mpc_proc_clean(void);
struct mpoa_client *mpcs = NULL; /* FIXME */
static struct atm_mpoa_qos *qos_head = NULL;
-static struct timer_list mpc_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(mpc_timer, NULL, 0, 0);
static struct mpoa_client *find_mpc_by_itfnum(int itf)
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index dca179daf41..0164a155b8c 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -67,37 +67,34 @@ char *ax2asc(char *buf, ax25_address *a)
/*
* ascii -> ax25 conversion
*/
-ax25_address *asc2ax(char *callsign)
+void asc2ax(ax25_address *addr, char *callsign)
{
- static ax25_address addr;
char *s;
int n;
for (s = callsign, n = 0; n < 6; n++) {
if (*s != '\0' && *s != '-')
- addr.ax25_call[n] = *s++;
+ addr->ax25_call[n] = *s++;
else
- addr.ax25_call[n] = ' ';
- addr.ax25_call[n] <<= 1;
- addr.ax25_call[n] &= 0xFE;
+ addr->ax25_call[n] = ' ';
+ addr->ax25_call[n] <<= 1;
+ addr->ax25_call[n] &= 0xFE;
}
if (*s++ == '\0') {
- addr.ax25_call[6] = 0x00;
- return &addr;
+ addr->ax25_call[6] = 0x00;
+ return;
}
- addr.ax25_call[6] = *s++ - '0';
+ addr->ax25_call[6] = *s++ - '0';
if (*s != '\0') {
- addr.ax25_call[6] *= 10;
- addr.ax25_call[6] += *s++ - '0';
+ addr->ax25_call[6] *= 10;
+ addr->ax25_call[6] += *s++ - '0';
}
- addr.ax25_call[6] <<= 1;
- addr.ax25_call[6] &= 0x1E;
-
- return &addr;
+ addr->ax25_call[6] <<= 1;
+ addr->ax25_call[6] &= 0x1E;
}
/*
diff --git a/net/core/dst.c b/net/core/dst.c
index 334790da9f1..470c05bc4cb 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;
static void dst_run_gc(unsigned long);
static void ___dst_free(struct dst_entry * dst);
-static struct timer_list dst_gc_timer =
- TIMER_INITIALIZER(dst_run_gc, DST_GC_MIN, 0);
+static DEFINE_TIMER(dst_gc_timer, dst_run_gc, DST_GC_MIN, 0);
static void dst_run_gc(unsigned long dummy)
{
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a1a9a7abff5..5265dfd6992 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -645,10 +645,10 @@ int netpoll_setup(struct netpoll *np)
npinfo->rx_flags = 0;
npinfo->rx_np = NULL;
- npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&npinfo->poll_lock);
npinfo->poll_owner = -1;
npinfo->tries = MAX_RETRIES;
- npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&npinfo->rx_lock);
} else
npinfo = ndev->npinfo;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8eb083b6041..b3ad49fa7d7 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -503,7 +503,7 @@ static int pg_delay_d = 0;
static int pg_clone_skb_d = 0;
static int debug = 0;
-static spinlock_t _thread_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(_thread_lock);
static struct pktgen_thread *pktgen_threads = NULL;
static char module_fname[128];
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 7bf3b3a91e9..ea30012dd19 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -43,12 +43,22 @@
#include "ccid3.h"
/*
- * Reason for maths with 10 here is to avoid 32 bit overflow when a is big.
+ * Reason for maths here is to avoid 32 bit overflow when a is big.
+ * With this we get close to the limit.
*/
static inline u32 usecs_div(const u32 a, const u32 b)
{
- const u32 tmp = a * (USEC_PER_SEC / 10);
- return b > 20 ? tmp / (b / 10) : tmp;
+ const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 :
+ a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 :
+ a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 :
+ a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 :
+ a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
+ 100000;
+ const u32 tmp = a * (USEC_PER_SEC / div);
+ return (b >= 2 * div) ? tmp / (b / div) : tmp;
}
static int ccid3_debug;
@@ -102,8 +112,7 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
static inline void ccid3_hc_tx_set_state(struct sock *sk,
enum ccid3_hc_tx_states state)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
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)
*/
static void ccid3_hc_tx_update_x(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
/* To avoid large error in calcX */
if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
@@ -159,7 +167,7 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
} else {
struct timeval now;
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
hctx->ccid3hctx_rtt) {
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)
static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
struct sock *sk = (struct sock *)data;
- struct dccp_sock *dp = dccp_sk(sk);
unsigned long next_tmout = 0;
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
@@ -274,7 +281,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
struct sk_buff *skb, int len)
{
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct dccp_tx_hist_entry *new_packet;
struct timeval now;
long delay;
@@ -307,7 +314,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
}
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
switch (hctx->ccid3hctx_state) {
case TFRC_SSTATE_NO_SENT:
@@ -348,18 +355,20 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
}
/* Can we send? if so add options and add to packet history */
- if (rc == 0)
+ if (rc == 0) {
+ dp->dccps_hc_tx_insert_options = 1;
new_packet->dccphtx_ccval =
DCCP_SKB_CB(skb)->dccpd_ccval =
hctx->ccid3hctx_last_win_count;
+ }
out:
return rc;
}
static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct timeval now;
BUG_ON(hctx == NULL);
@@ -370,7 +379,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
return;
}
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
/* check if we have sent a data packet */
if (len > 0) {
@@ -445,10 +454,11 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
struct dccp_tx_hist_entry *packet;
+ struct timeval now;
unsigned long next_tmout;
u32 t_elapsed;
u32 pinv;
@@ -471,7 +481,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
opt_recv = &hctx->ccid3hctx_options_received;
- t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
+ t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
x_recv = opt_recv->ccid3or_receive_rate;
pinv = opt_recv->ccid3or_loss_event_rate;
@@ -496,9 +506,14 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
}
/* Update RTT */
- r_sample = timeval_now_delta(&packet->dccphtx_tstamp);
- /* FIXME: */
- // r_sample -= usecs_to_jiffies(t_elapsed * 10);
+ dccp_timestamp(sk, &now);
+ r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
+ if (unlikely(r_sample <= t_elapsed))
+ LIMIT_NETDEBUG(KERN_WARNING
+ "%s: r_sample=%uus, t_elapsed=%uus\n",
+ __FUNCTION__, r_sample, t_elapsed);
+ else
+ r_sample -= t_elapsed;
/* Update RTT estimate by
* If (No feedback recv)
@@ -591,8 +606,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
if (hctx == NULL || !(sk->sk_state == DCCP_OPEN ||
sk->sk_state == DCCP_PARTOPEN))
@@ -606,8 +620,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
unsigned char *value)
{
int rc = 0;
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
if (hctx == NULL)
@@ -670,11 +684,11 @@ static int ccid3_hc_tx_init(struct sock *sk)
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx),
- gfp_any());
- if (hctx == NULL)
+ dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
+ if (dp->dccps_hc_tx_ccid_private == NULL)
return -ENOMEM;
+ hctx = ccid3_hc_tx_sk(sk);
memset(hctx, 0, sizeof(*hctx));
if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -696,7 +710,7 @@ static int ccid3_hc_tx_init(struct sock *sk)
static void ccid3_hc_tx_exit(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
BUG_ON(hctx == NULL);
@@ -738,8 +752,7 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
static inline void ccid3_hc_rx_set_state(struct sock *sk,
enum ccid3_hc_rx_states state)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
@@ -751,14 +764,14 @@ static inline void ccid3_hc_rx_set_state(struct sock *sk,
static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
struct dccp_rx_hist_entry *packet;
struct timeval now;
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
switch (hcrx->ccid3hcrx_state) {
case TFRC_RSTATE_NO_DATA:
@@ -767,11 +780,8 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
case TFRC_RSTATE_DATA: {
const u32 delta = timeval_delta(&now,
&hcrx->ccid3hcrx_tstamp_last_feedback);
-
- hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
- USEC_PER_SEC);
- if (likely(delta > 1))
- hcrx->ccid3hcrx_x_recv /= delta;
+ hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
+ delta);
}
break;
default:
@@ -801,14 +811,14 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
hcrx->ccid3hcrx_pinv = ~0;
else
hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
+ dp->dccps_hc_rx_insert_options = 1;
dccp_send_ack(sk);
}
static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
{
- const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u32 x_recv, pinv;
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN ||
sk->sk_state == DCCP_PARTOPEN))
@@ -837,8 +847,7 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
u32 rtt, delta, x_recv, fval, p, tmp2;
struct timeval tstamp = { 0, };
@@ -889,10 +898,9 @@ found:
if (rtt == 0)
rtt = 1;
- delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback);
- x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC;
- if (likely(delta > 1))
- x_recv /= delta;
+ dccp_timestamp(sk, &tstamp);
+ delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
+ x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
tmp1 = (u64)x_recv * (u64)rtt;
do_div(tmp1,10000000);
@@ -911,8 +919,7 @@ found:
static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
if (seq_loss != DCCP_MAX_SEQNO + 1 &&
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)
static void ccid3_hc_rx_detect_loss(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u8 win_loss;
const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist,
@@ -942,13 +948,12 @@ static void ccid3_hc_rx_detect_loss(struct sock *sk)
static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
const struct dccp_options_received *opt_recv;
struct dccp_rx_hist_entry *packet;
struct timeval now;
u8 win_count;
- u32 p_prev;
+ u32 p_prev, r_sample, t_elapsed;
int ins;
if (hcrx == NULL)
@@ -957,7 +962,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
- opt_recv = &dp->dccps_options_received;
+ opt_recv = &dccp_sk(sk)->dccps_options_received;
switch (DCCP_SKB_CB(skb)->dccpd_type) {
case DCCP_PKT_ACK:
@@ -967,10 +972,24 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
if (opt_recv->dccpor_timestamp_echo == 0)
break;
p_prev = hcrx->ccid3hcrx_rtt;
- do_gettimeofday(&now);
- hcrx->ccid3hcrx_rtt = timeval_usecs(&now) -
- (opt_recv->dccpor_timestamp_echo -
- opt_recv->dccpor_elapsed_time) * 10;
+ dccp_timestamp(sk, &now);
+ timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
+ r_sample = timeval_usecs(&now);
+ t_elapsed = opt_recv->dccpor_elapsed_time * 10;
+
+ if (unlikely(r_sample <= t_elapsed))
+ LIMIT_NETDEBUG(KERN_WARNING
+ "%s: r_sample=%uus, t_elapsed=%uus\n",
+ __FUNCTION__, r_sample, t_elapsed);
+ else
+ r_sample -= t_elapsed;
+
+ if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
+ hcrx->ccid3hcrx_rtt = r_sample;
+ else
+ hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
+ r_sample / 10;
+
if (p_prev != hcrx->ccid3hcrx_rtt)
ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
dccp_role(sk), hcrx->ccid3hcrx_rtt,
@@ -985,7 +1004,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
return;
}
- packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp,
+ packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
skb, SLAB_ATOMIC);
if (packet == NULL) {
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)
if (ins != 0)
break;
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
hcrx->ccid3hcrx_rtt) {
hcrx->ccid3hcrx_tstamp_last_ack = now;
@@ -1056,11 +1075,11 @@ static int ccid3_hc_rx_init(struct sock *sk)
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx),
- gfp_any());
- if (hcrx == NULL)
+ dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
+ if (dp->dccps_hc_rx_ccid_private == NULL)
return -ENOMEM;
+ hcrx = ccid3_hc_rx_sk(sk);
memset(hcrx, 0, sizeof(*hcrx));
if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -1072,18 +1091,16 @@ static int ccid3_hc_rx_init(struct sock *sk)
hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
- /*
- * XXX this seems to be paranoid, need to think more about this, for
- * now start with something different than zero. -acme
- */
- hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5;
+ dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
+ hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
+ hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
return 0;
}
static void ccid3_hc_rx_exit(struct sock *sk)
{
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
@@ -1104,8 +1121,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
if (hcrx == NULL)
return;
@@ -1117,8 +1133,7 @@ static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
if (hctx == NULL)
return;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index ee8cbace663..d16f00d784f 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -115,7 +115,7 @@ struct ccid3_hc_rx_sock {
u64 ccid3hcrx_seqno_last_counter:48,
ccid3hcrx_state:8,
ccid3hcrx_last_counter:4;
- unsigned long ccid3hcrx_rtt;
+ u32 ccid3hcrx_rtt;
u32 ccid3hcrx_p;
u32 ccid3hcrx_bytes_recv;
struct timeval ccid3hcrx_tstamp_last_feedback;
@@ -128,10 +128,14 @@ struct ccid3_hc_rx_sock {
u32 ccid3hcrx_x_recv;
};
-#define ccid3_hc_tx_field(s,field) (s->dccps_hc_tx_ccid_private == NULL ? 0 : \
- ((struct ccid3_hc_tx_sock *)s->dccps_hc_tx_ccid_private)->ccid3hctx_##field)
+static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_hc_tx_ccid_private;
+}
-#define ccid3_hc_rx_field(s,field) (s->dccps_hc_rx_ccid_private == NULL ? 0 : \
- ((struct ccid3_hc_rx_sock *)s->dccps_hc_rx_ccid_private)->ccid3hcrx_##field)
+static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_hc_rx_ccid_private;
+}
#endif /* _DCCP_CCID3_H_ */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index fb90a91aa93..b375ebdb7dc 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 *
static inline struct dccp_rx_hist_entry *
dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
+ const struct sock *sk,
const u32 ndp,
const struct sk_buff *skb,
const unsigned int __nocast prio)
@@ -148,7 +149,7 @@ static inline struct dccp_rx_hist_entry *
entry->dccphrx_ccval = dh->dccph_ccval;
entry->dccphrx_type = dh->dccph_type;
entry->dccphrx_ndp = ndp;
- do_gettimeofday(&(entry->dccphrx_tstamp));
+ dccp_timestamp(sk, &entry->dccphrx_tstamp);
}
return entry;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 33456c0d593..95c4630b3b1 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -426,10 +426,13 @@ extern struct dccp_ackpkts *
dccp_ackpkts_alloc(unsigned int len,
const unsigned int __nocast priority);
extern void dccp_ackpkts_free(struct dccp_ackpkts *ap);
-extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state);
+extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
+ u64 ackno, u8 state);
extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
struct sock *sk, u64 ackno);
+extern void dccp_timestamp(const struct sock *sk, struct timeval *tv);
+
static inline suseconds_t timeval_usecs(const struct timeval *tv)
{
return tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
@@ -468,17 +471,6 @@ static inline void timeval_sub_usecs(struct timeval *tv,
}
}
-/*
- * Returns the difference in usecs between timeval
- * passed in and current time
- */
-static inline suseconds_t timeval_now_delta(const struct timeval *tv)
-{
- struct timeval now;
- do_gettimeofday(&now);
- return timeval_delta(&now, tv);
-}
-
#ifdef CONFIG_IP_DCCP_DEBUG
extern void dccp_ackvector_print(const u64 ackno,
const unsigned char *vector, int len);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index ef29cef1daf..c60bc3433f5 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,
if (dp->dccps_options.dccpo_send_ack_vector) {
struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
- if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
+ if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
DCCP_SKB_CB(skb)->dccpd_seq,
DCCP_ACKPKTS_STATE_RECEIVED)) {
LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable "
@@ -498,7 +498,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
* DCCP_ACKPKTS_STATE_ECN_MARKED
*/
if (dp->dccps_options.dccpo_send_ack_vector) {
- if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
+ if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
DCCP_SKB_CB(skb)->dccpd_seq,
DCCP_ACKPKTS_STATE_RECEIVED))
goto discard;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3fc75dbee4b..fee9a8c3777 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1243,6 +1243,7 @@ static int dccp_v4_init_sock(struct sock *sk)
static int dccp_ctl_socket_init = 1;
dccp_options_init(&dp->dccps_options);
+ do_gettimeofday(&dp->dccps_epoch);
if (dp->dccps_options.dccpo_send_ack_vector) {
dp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index ce5dff4ac22..18461bc04cb 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -96,6 +96,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
newdp->dccps_hc_rx_ackpkts = NULL;
newdp->dccps_role = DCCP_ROLE_SERVER;
newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
+ do_gettimeofday(&newdp->dccps_epoch);
if (newdp->dccps_options.dccpo_send_ack_vector) {
newdp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 382c5894acb..d4c4242d8dd 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)
struct dccp_options_received *opt_recv = &dp->dccps_options_received;
unsigned char opt, len;
unsigned char *value;
+ u32 elapsed_time;
memset(opt_recv, 0, sizeof(*opt_recv));
@@ -139,7 +140,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
- do_gettimeofday(&dp->dccps_timestamp_time);
+ dccp_timestamp(sk, &dp->dccps_timestamp_time);
dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
debug_prefix, opt_recv->dccpor_timestamp,
@@ -159,18 +160,18 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
(unsigned long long)
DCCP_SKB_CB(skb)->dccpd_ack_seq);
- if (len > 4) {
- if (len == 6)
- opt_recv->dccpor_elapsed_time =
- ntohs(*(u16 *)(value + 4));
- else
- opt_recv->dccpor_elapsed_time =
- ntohl(*(u32 *)(value + 4));
- dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n",
- debug_prefix,
- opt_recv->dccpor_elapsed_time);
- }
+ if (len == 4)
+ break;
+
+ if (len == 6)
+ elapsed_time = ntohs(*(u16 *)(value + 4));
+ else
+ elapsed_time = ntohl(*(u32 *)(value + 4));
+
+ /* Give precedence to the biggest ELAPSED_TIME */
+ if (elapsed_time > opt_recv->dccpor_elapsed_time)
+ opt_recv->dccpor_elapsed_time = elapsed_time;
break;
case DCCPO_ELAPSED_TIME:
if (len != 2 && len != 4)
@@ -180,14 +181,15 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
continue;
if (len == 2)
- opt_recv->dccpor_elapsed_time =
- ntohs(*(u16 *)value);
+ elapsed_time = ntohs(*(u16 *)value);
else
- opt_recv->dccpor_elapsed_time =
- ntohl(*(u32 *)value);
+ elapsed_time = ntohl(*(u32 *)value);
+
+ if (elapsed_time > opt_recv->dccpor_elapsed_time)
+ opt_recv->dccpor_elapsed_time = elapsed_time;
dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
- opt_recv->dccpor_elapsed_time);
+ elapsed_time);
break;
/*
* 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)
#endif
struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
int len = ap->dccpap_buf_vector_len + 2;
- const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10;
+ struct timeval now;
+ u32 elapsed_time;
unsigned char *to, *from;
+ dccp_timestamp(sk, &now);
+ elapsed_time = timeval_delta(&now, &ap->dccpap_time) / 10;
+
if (elapsed_time != 0)
dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
@@ -426,13 +432,29 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
(unsigned long long) ap->dccpap_ack_ackno);
}
+void dccp_timestamp(const struct sock *sk, struct timeval *tv)
+{
+ const struct dccp_sock *dp = dccp_sk(sk);
+
+ do_gettimeofday(tv);
+ tv->tv_sec -= dp->dccps_epoch.tv_sec;
+ tv->tv_usec -= dp->dccps_epoch.tv_usec;
+
+ while (tv->tv_usec < 0) {
+ tv->tv_sec--;
+ tv->tv_usec += USEC_PER_SEC;
+ }
+}
+
+EXPORT_SYMBOL_GPL(dccp_timestamp);
+
void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
{
struct timeval tv;
u32 now;
- do_gettimeofday(&tv);
- now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10;
+ dccp_timestamp(sk, &tv);
+ now = timeval_usecs(&tv) / 10;
/* yes this will overflow but that is the point as we want a
* 10 usec 32 bit timer which mean it wraps every 11.9 hours */
@@ -450,13 +472,17 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
"CLIENT TX opt: " : "server TX opt: ";
#endif
+ struct timeval now;
u32 tstamp_echo;
- const u32 elapsed_time =
- timeval_now_delta(&dp->dccps_timestamp_time) / 10;
- const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
- const int len = 6 + elapsed_time_len;
+ u32 elapsed_time;
+ int len, elapsed_time_len;
unsigned char *to;
+ dccp_timestamp(sk, &now);
+ elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10;
+ elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
+ len = 6 + elapsed_time_len;
+
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
"timestamp echo!\n");
@@ -505,13 +531,18 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
(dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno !=
DCCP_MAX_SEQNO + 1))
dccp_insert_option_ack_vector(sk, skb);
-
if (dp->dccps_timestamp_echo != 0)
dccp_insert_option_timestamp_echo(sk, skb);
}
- ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
- ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
+ if (dp->dccps_hc_rx_insert_options) {
+ ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
+ dp->dccps_hc_rx_insert_options = 0;
+ }
+ if (dp->dccps_hc_tx_insert_options) {
+ ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
+ dp->dccps_hc_tx_insert_options = 0;
+ }
/* XXX: insert other options when appropriate */
@@ -616,7 +647,8 @@ static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
/*
* Implements the draft-ietf-dccp-spec-11.txt Appendix A
*/
-int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
+int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
+ u64 ackno, u8 state)
{
/*
* 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)
}
ap->dccpap_buf_ackno = ackno;
- do_gettimeofday(&ap->dccpap_time);
+ dccp_timestamp(sk, &ap->dccpap_time);
out:
dccp_pr_debug("");
dccp_ackpkts_print(ap);
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2c915f305be..3407f190afe 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;
static unsigned dn_rt_hash_mask;
static struct timer_list dn_route_timer;
-static struct timer_list dn_rt_flush_timer =
- TIMER_INITIALIZER(dn_run_flush, 0, 0);
+static DEFINE_TIMER(dn_rt_flush_timer, dn_run_flush, 0, 0);
int decnet_dst_gc_interval = 2;
static struct dst_ops dn_dst_ops = {
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index 58ed4319e69..91b16fbf91f 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -1,6 +1,5 @@
config IEEE80211
tristate "Generic IEEE 802.11 Networking Stack"
- select NET_RADIO
---help---
This option enables the hardware independent IEEE 802.11
networking stack.
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bf147f8db39..a9d84f93442 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1248,11 +1248,6 @@ module_init(inet_init);
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
-#ifdef CONFIG_IP_FIB_TRIE
-extern int fib_stat_proc_init(void);
-extern void fib_stat_proc_exit(void);
-#endif
-
static int __init ipv4_proc_init(void)
{
int rc = 0;
@@ -1265,19 +1260,11 @@ static int __init ipv4_proc_init(void)
goto out_udp;
if (fib_proc_init())
goto out_fib;
-#ifdef CONFIG_IP_FIB_TRIE
- if (fib_stat_proc_init())
- goto out_fib_stat;
-#endif
if (ip_misc_proc_init())
goto out_misc;
out:
return rc;
out_misc:
-#ifdef CONFIG_IP_FIB_TRIE
- fib_stat_proc_exit();
-out_fib_stat:
-#endif
fib_proc_exit();
out_fib:
udp4_proc_exit();
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index b2dea4e5da7..1b63b482416 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#define VERSION "0.402"
+#define VERSION "0.403"
#include <linux/config.h>
#include <asm/uaccess.h>
@@ -164,7 +164,6 @@ static struct node *resize(struct trie *t, struct tnode *tn);
static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn);
static void tnode_free(struct tnode *tn);
-static void trie_dump_seq(struct seq_file *seq, struct trie *t);
static kmem_cache_t *fn_alias_kmem __read_mostly;
static struct trie *trie_local = NULL, *trie_main = NULL;
@@ -1971,558 +1970,525 @@ struct fib_table * __init fib_hash_init(int id)
return tb;
}
-/* Trie dump functions */
+#ifdef CONFIG_PROC_FS
+/* Depth first Trie walk iterator */
+struct fib_trie_iter {
+ struct tnode *tnode;
+ struct trie *trie;
+ unsigned index;
+ unsigned depth;
+};
-static void putspace_seq(struct seq_file *seq, int n)
+static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
{
- while (n--)
- seq_printf(seq, " ");
-}
+ struct tnode *tn = iter->tnode;
+ unsigned cindex = iter->index;
+ struct tnode *p;
-static void printbin_seq(struct seq_file *seq, unsigned int v, int bits)
-{
- while (bits--)
- seq_printf(seq, "%s", (v & (1<<bits))?"1":"0");
-}
+ pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
+ iter->tnode, iter->index, iter->depth);
+rescan:
+ while (cindex < (1<<tn->bits)) {
+ struct node *n = tnode_get_child(tn, cindex);
-static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
- int pend, int cindex, int bits)
-{
- putspace_seq(seq, indent);
- if (IS_LEAF(n))
- seq_printf(seq, "|");
- else
- seq_printf(seq, "+");
- if (bits) {
- seq_printf(seq, "%d/", cindex);
- printbin_seq(seq, cindex, bits);
- seq_printf(seq, ": ");
- } else
- seq_printf(seq, "<root>: ");
- seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n);
+ if (n) {
+ if (IS_LEAF(n)) {
+ iter->tnode = tn;
+ iter->index = cindex + 1;
+ } else {
+ /* push down one level */
+ iter->tnode = (struct tnode *) n;
+ iter->index = 0;
+ ++iter->depth;
+ }
+ return n;
+ }
- if (IS_LEAF(n)) {
- struct leaf *l = (struct leaf *)n;
- struct fib_alias *fa;
- int i;
+ ++cindex;
+ }
- seq_printf(seq, "key=%d.%d.%d.%d\n",
- n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256);
-
- for (i = 32; i >= 0; i--)
- if (find_leaf_info(&l->list, i)) {
- struct list_head *fa_head = get_fa_head(l, i);
-
- if (!fa_head)
- continue;
-
- if (list_empty(fa_head))
- continue;
-
- putspace_seq(seq, indent+2);
- seq_printf(seq, "{/%d...dumping}\n", i);
-
- list_for_each_entry_rcu(fa, fa_head, fa_list) {
- putspace_seq(seq, indent+2);
- if (fa->fa_info == NULL) {
- seq_printf(seq, "Error fa_info=NULL\n");
- continue;
- }
- if (fa->fa_info->fib_nh == NULL) {
- seq_printf(seq, "Error _fib_nh=NULL\n");
- continue;
- }
-
- seq_printf(seq, "{type=%d scope=%d TOS=%d}\n",
- fa->fa_type,
- fa->fa_scope,
- fa->fa_tos);
- }
- }
- } else {
- struct tnode *tn = (struct tnode *)n;
- int plen = ((struct tnode *)n)->pos;
- t_key prf = MASK_PFX(n->key, plen);
-
- seq_printf(seq, "key=%d.%d.%d.%d/%d\n",
- prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen);
-
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{key prefix=%08x/", tn->key & TKEY_GET_MASK(0, tn->pos));
- printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos);
- seq_printf(seq, "}\n");
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{pos=%d", tn->pos);
- seq_printf(seq, " (skip=%d bits)", tn->pos - pend);
- seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits));
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children);
+ /* Current node exhausted, pop back up */
+ p = NODE_PARENT(tn);
+ if (p) {
+ cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
+ tn = p;
+ --iter->depth;
+ goto rescan;
}
+
+ /* got root? */
+ return NULL;
}
-static void trie_dump_seq(struct seq_file *seq, struct trie *t)
+static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
+ struct trie *t)
{
- struct node *n;
- int cindex = 0;
- int indent = 1;
- int pend = 0;
- int depth = 0;
- struct tnode *tn;
-
- rcu_read_lock();
- n = rcu_dereference(t->trie);
- seq_printf(seq, "------ trie_dump of t=%p ------\n", t);
+ struct node *n = rcu_dereference(t->trie);
- if (!n) {
- seq_printf(seq, "------ trie is empty\n");
-
- rcu_read_unlock();
- return;
+ if (n && IS_TNODE(n)) {
+ iter->tnode = (struct tnode *) n;
+ iter->trie = t;
+ iter->index = 0;
+ iter->depth = 0;
+ return n;
}
+ return NULL;
+}
- printnode_seq(seq, indent, n, pend, cindex, 0);
-
- if (!IS_TNODE(n)) {
- rcu_read_unlock();
- return;
- }
-
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
- indent += 3;
- depth++;
-
- while (tn && cindex < (1 << tn->bits)) {
- struct node *child = rcu_dereference(tn->child[cindex]);
- if (!child)
- cindex++;
- else {
- /* Got a child */
- printnode_seq(seq, indent, child, pend,
- cindex, tn->bits);
-
- if (IS_LEAF(child))
- cindex++;
-
- else {
- /*
- * New tnode. Decend one level
- */
-
- depth++;
- n = child;
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- putspace_seq(seq, indent);
- seq_printf(seq, "\\--\n");
- indent += 3;
- cindex = 0;
- }
- }
-
- /*
- * Test if we are done
- */
-
- while (cindex >= (1 << tn->bits)) {
- /*
- * Move upwards and test for root
- * pop off all traversed nodes
- */
+static void trie_collect_stats(struct trie *t, struct trie_stat *s)
+{
+ struct node *n;
+ struct fib_trie_iter iter;
- if (NODE_PARENT(tn) == NULL) {
- tn = NULL;
- break;
- }
+ memset(s, 0, sizeof(*s));
- cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
- cindex++;
- tn = NODE_PARENT(tn);
- pend = tn->pos + tn->bits;
- indent -= 3;
- depth--;
+ rcu_read_lock();
+ for (n = fib_trie_get_first(&iter, t); n;
+ n = fib_trie_get_next(&iter)) {
+ if (IS_LEAF(n)) {
+ s->leaves++;
+ s->totdepth += iter.depth;
+ if (iter.depth > s->maxdepth)
+ s->maxdepth = iter.depth;
+ } else {
+ const struct tnode *tn = (const struct tnode *) n;
+ int i;
+
+ s->tnodes++;
+ s->nodesizes[tn->bits]++;
+ for (i = 0; i < (1<<tn->bits); i++)
+ if (!tn->child[i])
+ s->nullpointers++;
}
}
rcu_read_unlock();
}
-static struct trie_stat *trie_stat_new(void)
+/*
+ * This outputs /proc/net/fib_triestats
+ */
+static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
{
- struct trie_stat *s;
- int i;
+ unsigned i, max, pointers, bytes, avdepth;
- s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL);
- if (!s)
- return NULL;
+ if (stat->leaves)
+ avdepth = stat->totdepth*100 / stat->leaves;
+ else
+ avdepth = 0;
- s->totdepth = 0;
- s->maxdepth = 0;
- s->tnodes = 0;
- s->leaves = 0;
- s->nullpointers = 0;
+ seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+ seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth);
- for (i = 0; i < MAX_CHILDS; i++)
- s->nodesizes[i] = 0;
+ seq_printf(seq, "\tLeaves: %u\n", stat->leaves);
- return s;
-}
+ bytes = sizeof(struct leaf) * stat->leaves;
+ seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
+ bytes += sizeof(struct tnode) * stat->tnodes;
-static struct trie_stat *trie_collect_stats(struct trie *t)
-{
- struct node *n;
- struct trie_stat *s = trie_stat_new();
- int cindex = 0;
- int pend = 0;
- int depth = 0;
+ max = MAX_CHILDS-1;
+ while (max >= 0 && stat->nodesizes[max] == 0)
+ max--;
- if (!s)
- return NULL;
+ pointers = 0;
+ for (i = 1; i <= max; i++)
+ if (stat->nodesizes[i] != 0) {
+ seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
+ pointers += (1<<i) * stat->nodesizes[i];
+ }
+ seq_putc(seq, '\n');
+ seq_printf(seq, "\tPointers: %d\n", pointers);
- rcu_read_lock();
- n = rcu_dereference(t->trie);
+ bytes += sizeof(struct node *) * pointers;
+ seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
+ seq_printf(seq, "Total size: %d kB\n", (bytes + 1023) / 1024);
- if (!n)
- return s;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ seq_printf(seq, "Counters:\n---------\n");
+ seq_printf(seq,"gets = %d\n", t->stats.gets);
+ seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
+ seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
+ seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
+ seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
+ seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
+#ifdef CLEAR_STATS
+ memset(&(t->stats), 0, sizeof(t->stats));
+#endif
+#endif /* CONFIG_IP_FIB_TRIE_STATS */
+}
- if (IS_TNODE(n)) {
- struct tnode *tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- s->nodesizes[tn->bits]++;
- depth++;
-
- while (tn && cindex < (1 << tn->bits)) {
- struct node *ch = rcu_dereference(tn->child[cindex]);
- if (ch) {
-
- /* Got a child */
-
- if (IS_LEAF(tn->child[cindex])) {
- cindex++;
-
- /* stats */
- if (depth > s->maxdepth)
- s->maxdepth = depth;
- s->totdepth += depth;
- s->leaves++;
- } else {
- /*
- * New tnode. Decend one level
- */
-
- s->tnodes++;
- s->nodesizes[tn->bits]++;
- depth++;
-
- n = ch;
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
-
- cindex = 0;
- }
- } else {
- cindex++;
- s->nullpointers++;
- }
+static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+{
+ struct trie_stat *stat;
- /*
- * Test if we are done
- */
+ stat = kmalloc(sizeof(*stat), GFP_KERNEL);
+ if (!stat)
+ return -ENOMEM;
- while (cindex >= (1 << tn->bits)) {
- /*
- * Move upwards and test for root
- * pop off all traversed nodes
- */
+ seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+ sizeof(struct leaf), sizeof(struct tnode));
- if (NODE_PARENT(tn) == NULL) {
- tn = NULL;
- n = NULL;
- break;
- }
+ if (trie_local) {
+ seq_printf(seq, "Local:\n");
+ trie_collect_stats(trie_local, stat);
+ trie_show_stats(seq, stat);
+ }
- cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
- tn = NODE_PARENT(tn);
- cindex++;
- n = (struct node *)tn;
- pend = tn->pos+tn->bits;
- depth--;
- }
- }
+ if (trie_main) {
+ seq_printf(seq, "Main:\n");
+ trie_collect_stats(trie_main, stat);
+ trie_show_stats(seq, stat);
}
+ kfree(stat);
- rcu_read_unlock();
- return s;
+ return 0;
}
-#ifdef CONFIG_PROC_FS
-
-static struct fib_alias *fib_triestat_get_first(struct seq_file *seq)
+static int fib_triestat_seq_open(struct inode *inode, struct file *file)
{
- return NULL;
+ return single_open(file, fib_triestat_seq_show, NULL);
}
-static struct fib_alias *fib_triestat_get_next(struct seq_file *seq)
+static struct file_operations fib_triestat_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_triestat_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
+ loff_t pos)
{
+ loff_t idx = 0;
+ struct node *n;
+
+ for (n = fib_trie_get_first(iter, trie_local);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+ }
+
+ for (n = fib_trie_get_first(iter, trie_main);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+ }
return NULL;
}
-static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos)
+static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (!ip_fib_main_table)
- return NULL;
-
- if (*pos)
- return fib_triestat_get_next(seq);
- else
+ rcu_read_lock();
+ if (*pos == 0)
return SEQ_START_TOKEN;
+ return fib_trie_get_idx(seq->private, *pos - 1);
}
-static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
+ struct fib_trie_iter *iter = seq->private;
+ void *l = v;
+
++*pos;
if (v == SEQ_START_TOKEN)
- return fib_triestat_get_first(seq);
- else
- return fib_triestat_get_next(seq);
-}
+ return fib_trie_get_idx(iter, 0);
-static void fib_triestat_seq_stop(struct seq_file *seq, void *v)
-{
+ v = fib_trie_get_next(iter);
+ BUG_ON(v == l);
+ if (v)
+ return v;
-}
+ /* continue scan in next trie */
+ if (iter->trie == trie_local)
+ return fib_trie_get_first(iter, trie_main);
-/*
- * This outputs /proc/net/fib_triestats
- *
- * It always works in backward compatibility mode.
- * The format of the file is not supposed to be changed.
- */
+ return NULL;
+}
-static void collect_and_show(struct trie *t, struct seq_file *seq)
+static void fib_trie_seq_stop(struct seq_file *seq, void *v)
{
- int bytes = 0; /* How many bytes are used, a ref is 4 bytes */
- int i, max, pointers;
- struct trie_stat *stat;
- int avdepth;
-
- stat = trie_collect_stats(t);
-
- bytes = 0;
- seq_printf(seq, "trie=%p\n", t);
-
- if (stat) {
- if (stat->leaves)
- avdepth = stat->totdepth*100 / stat->leaves;
- else
- avdepth = 0;
- seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100);
- seq_printf(seq, "Max depth: %4d\n", stat->maxdepth);
+ rcu_read_unlock();
+}
- seq_printf(seq, "Leaves: %d\n", stat->leaves);
- bytes += sizeof(struct leaf) * stat->leaves;
- seq_printf(seq, "Internal nodes: %d\n", stat->tnodes);
- bytes += sizeof(struct tnode) * stat->tnodes;
+static void seq_indent(struct seq_file *seq, int n)
+{
+ while (n-- > 0) seq_puts(seq, " ");
+}
- max = MAX_CHILDS-1;
+static inline const char *rtn_scope(enum rt_scope_t s)
+{
+ static char buf[32];
- while (max >= 0 && stat->nodesizes[max] == 0)
- max--;
- pointers = 0;
+ switch(s) {
+ case RT_SCOPE_UNIVERSE: return "universe";
+ case RT_SCOPE_SITE: return "site";
+ case RT_SCOPE_LINK: return "link";
+ case RT_SCOPE_HOST: return "host";
+ case RT_SCOPE_NOWHERE: return "nowhere";
+ default:
+ snprintf(buf, sizeof(buf), "scope=%d", s);
+ return buf;
+ }
+}
- for (i = 1; i <= max; i++)
- if (stat->nodesizes[i] != 0) {
- seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
- pointers += (1<<i) * stat->nodesizes[i];
- }
- seq_printf(seq, "\n");
- seq_printf(seq, "Pointers: %d\n", pointers);
- bytes += sizeof(struct node *) * pointers;
- seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
- seq_printf(seq, "Total size: %d kB\n", bytes / 1024);
+static const char *rtn_type_names[__RTN_MAX] = {
+ [RTN_UNSPEC] = "UNSPEC",
+ [RTN_UNICAST] = "UNICAST",
+ [RTN_LOCAL] = "LOCAL",
+ [RTN_BROADCAST] = "BROADCAST",
+ [RTN_ANYCAST] = "ANYCAST",
+ [RTN_MULTICAST] = "MULTICAST",
+ [RTN_BLACKHOLE] = "BLACKHOLE",
+ [RTN_UNREACHABLE] = "UNREACHABLE",
+ [RTN_PROHIBIT] = "PROHIBIT",
+ [RTN_THROW] = "THROW",
+ [RTN_NAT] = "NAT",
+ [RTN_XRESOLVE] = "XRESOLVE",
+};
- kfree(stat);
- }
+static inline const char *rtn_type(unsigned t)
+{
+ static char buf[32];
-#ifdef CONFIG_IP_FIB_TRIE_STATS
- seq_printf(seq, "Counters:\n---------\n");
- seq_printf(seq,"gets = %d\n", t->stats.gets);
- seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
- seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
- seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
- seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
- seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
-#ifdef CLEAR_STATS
- memset(&(t->stats), 0, sizeof(t->stats));
-#endif
-#endif /* CONFIG_IP_FIB_TRIE_STATS */
+ if (t < __RTN_MAX && rtn_type_names[t])
+ return rtn_type_names[t];
+ snprintf(buf, sizeof(buf), "type %d", t);
+ return buf;
}
-static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+/* Pretty print the trie */
+static int fib_trie_seq_show(struct seq_file *seq, void *v)
{
- char bf[128];
+ const struct fib_trie_iter *iter = seq->private;
+ struct node *n = v;
- if (v == SEQ_START_TOKEN) {
- seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
- sizeof(struct leaf), sizeof(struct tnode));
- if (trie_local)
- collect_and_show(trie_local, seq);
+ if (v == SEQ_START_TOKEN)
+ return 0;
- if (trie_main)
- collect_and_show(trie_main, seq);
- } else {
- snprintf(bf, sizeof(bf), "*\t%08X\t%08X", 200, 400);
+ if (IS_TNODE(n)) {
+ struct tnode *tn = (struct tnode *) n;
+ t_key prf = ntohl(MASK_PFX(tn->key, tn->pos));
- seq_printf(seq, "%-127s\n", bf);
+ if (!NODE_PARENT(n)) {
+ if (iter->trie == trie_local)
+ seq_puts(seq, "<local>:\n");
+ else
+ seq_puts(seq, "<main>:\n");
+ } else {
+ seq_indent(seq, iter->depth-1);
+ seq_printf(seq, " +-- %d.%d.%d.%d/%d\n",
+ NIPQUAD(prf), tn->pos);
+ }
+ } else {
+ struct leaf *l = (struct leaf *) n;
+ int i;
+ u32 val = ntohl(l->key);
+
+ seq_indent(seq, iter->depth);
+ seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));
+ for (i = 32; i >= 0; i--) {
+ struct leaf_info *li = find_leaf_info(&l->list, i);
+ if (li) {
+ struct fib_alias *fa;
+ list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+ seq_indent(seq, iter->depth+1);
+ seq_printf(seq, " /%d %s %s", i,
+ rtn_scope(fa->fa_scope),
+ rtn_type(fa->fa_type));
+ if (fa->fa_tos)
+ seq_printf(seq, "tos =%d\n",
+ fa->fa_tos);
+ seq_putc(seq, '\n');
+ }
+ }
+ }
}
+
return 0;
}
-static struct seq_operations fib_triestat_seq_ops = {
- .start = fib_triestat_seq_start,
- .next = fib_triestat_seq_next,
- .stop = fib_triestat_seq_stop,
- .show = fib_triestat_seq_show,
+static struct seq_operations fib_trie_seq_ops = {
+ .start = fib_trie_seq_start,
+ .next = fib_trie_seq_next,
+ .stop = fib_trie_seq_stop,
+ .show = fib_trie_seq_show,
};
-static int fib_triestat_seq_open(struct inode *inode, struct file *file)
+static int fib_trie_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
+ struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
- rc = seq_open(file, &fib_triestat_seq_ops);
+ if (!s)
+ goto out;
+
+ rc = seq_open(file, &fib_trie_seq_ops);
if (rc)
goto out_kfree;
- seq = file->private_data;
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
+ kfree(s);
goto out;
}
-static struct file_operations fib_triestat_seq_fops = {
- .owner = THIS_MODULE,
- .open = fib_triestat_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
+static struct file_operations fib_trie_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_trie_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = seq_release_private,
};
-int __init fib_stat_proc_init(void)
-{
- if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
- return -ENOMEM;
- return 0;
-}
-
-void __init fib_stat_proc_exit(void)
+static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
{
- proc_net_remove("fib_triestat");
-}
+ static unsigned type2flags[RTN_MAX + 1] = {
+ [7] = RTF_REJECT, [8] = RTF_REJECT,
+ };
+ unsigned flags = type2flags[type];
-static struct fib_alias *fib_trie_get_first(struct seq_file *seq)
-{
- return NULL;
+ if (fi && fi->fib_nh->nh_gw)
+ flags |= RTF_GATEWAY;
+ if (mask == 0xFFFFFFFF)
+ flags |= RTF_HOST;
+ flags |= RTF_UP;
+ return flags;
}
-static struct fib_alias *fib_trie_get_next(struct seq_file *seq)
+/*
+ * This outputs /proc/net/route.
+ * The format of the file is not supposed to be changed
+ * and needs to be same as fib_hash output to avoid breaking
+ * legacy utilities
+ */
+static int fib_route_seq_show(struct seq_file *seq, void *v)
{
- return NULL;
-}
+ struct leaf *l = v;
+ int i;
+ char bf[128];
-static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
-{
- if (!ip_fib_main_table)
- return NULL;
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
+ "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
+ "\tWindow\tIRTT");
+ return 0;
+ }
- if (*pos)
- return fib_trie_get_next(seq);
- else
- return SEQ_START_TOKEN;
-}
+ if (IS_TNODE(l))
+ return 0;
-static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- ++*pos;
- if (v == SEQ_START_TOKEN)
- return fib_trie_get_first(seq);
- else
- return fib_trie_get_next(seq);
+ for (i=32; i>=0; i--) {
+ struct leaf_info *li = find_leaf_info(&l->list, i);
+ struct fib_alias *fa;
+ u32 mask, prefix;
-}
+ if (!li)
+ continue;
-static void fib_trie_seq_stop(struct seq_file *seq, void *v)
-{
-}
+ mask = inet_make_mask(li->plen);
+ prefix = htonl(l->key);
-/*
- * This outputs /proc/net/fib_trie.
- *
- * It always works in backward compatibility mode.
- * The format of the file is not supposed to be changed.
- */
+ list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+ const struct fib_info *fi = rcu_dereference(fa->fa_info);
+ unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
-static int fib_trie_seq_show(struct seq_file *seq, void *v)
-{
- char bf[128];
+ if (fa->fa_type == RTN_BROADCAST
+ || fa->fa_type == RTN_MULTICAST)
+ continue;
- if (v == SEQ_START_TOKEN) {
- if (trie_local)
- trie_dump_seq(seq, trie_local);
+ if (fi)
+ snprintf(bf, sizeof(bf),
+ "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ fi->fib_dev ? fi->fib_dev->name : "*",
+ prefix,
+ fi->fib_nh->nh_gw, flags, 0, 0,
+ fi->fib_priority,
+ mask,
+ (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
+ fi->fib_window,
+ fi->fib_rtt >> 3);
+ else
+ snprintf(bf, sizeof(bf),
+ "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ prefix, 0, flags, 0, 0, 0,
+ mask, 0, 0, 0);
- if (trie_main)
- trie_dump_seq(seq, trie_main);
- } else {
- snprintf(bf, sizeof(bf),
- "*\t%08X\t%08X", 200, 400);
- seq_printf(seq, "%-127s\n", bf);
+ seq_printf(seq, "%-127s\n", bf);
+ }
}
return 0;
}
-static struct seq_operations fib_trie_seq_ops = {
- .start = fib_trie_seq_start,
- .next = fib_trie_seq_next,
- .stop = fib_trie_seq_stop,
- .show = fib_trie_seq_show,
+static struct seq_operations fib_route_seq_ops = {
+ .start = fib_trie_seq_start,
+ .next = fib_trie_seq_next,
+ .stop = fib_trie_seq_stop,
+ .show = fib_route_seq_show,
};
-static int fib_trie_seq_open(struct inode *inode, struct file *file)
+static int fib_route_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
+ struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
- rc = seq_open(file, &fib_trie_seq_ops);
+ if (!s)
+ goto out;
+
+ rc = seq_open(file, &fib_route_seq_ops);
if (rc)
goto out_kfree;
- seq = file->private_data;
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
+ kfree(s);
goto out;
}
-static struct file_operations fib_trie_seq_fops = {
- .owner = THIS_MODULE,
- .open = fib_trie_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release= seq_release_private,
+static struct file_operations fib_route_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_route_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
};
int __init fib_proc_init(void)
{
- if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops))
- return -ENOMEM;
+ if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops))
+ goto out1;
+
+ if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops))
+ goto out2;
+
+ if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops))
+ goto out3;
+
return 0;
+
+out3:
+ proc_net_remove("fib_triestat");
+out2:
+ proc_net_remove("fib_trie");
+out1:
+ return -ENOMEM;
}
void __init fib_proc_exit(void)
{
proc_net_remove("fib_trie");
+ proc_net_remove("fib_triestat");
+ proc_net_remove("route");
}
#endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f84ba9c9655..2fc3fd38924 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -100,8 +100,7 @@ DEFINE_SPINLOCK(inet_peer_unused_lock);
#define PEER_MAX_CLEANUP_WORK 30
static void peer_check_expire(unsigned long dummy);
-static struct timer_list peer_periodic_timer =
- TIMER_INITIALIZER(peer_check_expire, 0, 0);
+static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
/* Exported for sysctl_net_ipv4. */
int 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 2b5cf9c5130..bb7246683b7 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -104,12 +104,28 @@ out:
static struct ip_conntrack_helper helper = {
.name = "netbios-ns",
.tuple = {
- .src.u.udp.port = __constant_htons(137),
- .dst.protonum = IPPROTO_UDP,
+ .src = {
+ .u = {
+ .udp = {
+ .port = __constant_htons(137),
+ }
+ }
+ },
+ .dst = {
+ .protonum = IPPROTO_UDP,
+ },
},
.mask = {
- .src.u.udp.port = 0xFFFF,
- .dst.protonum = 0xFF,
+ .src = {
+ .u = {
+ .udp = {
+ .port = 0xFFFF,
+ }
+ }
+ },
+ .dst = {
+ .protonum = 0xFF,
+ },
},
.max_expected = 1,
.me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f115a84a4ac..f057025a719 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,
fl.fl_ip_sport = tcph->dest;
fl.fl_ip_dport = tcph->source;
- if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) {
- dst_release(&rt->u.dst);
- rt = NULL;
- }
+ xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
return rt;
}
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index c1889f88262..0cee2862ed8 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/file.h>
+#include <linux/rcupdate.h>
#include <net/sock.h>
#include <linux/netfilter_ipv4/ipt_owner.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c0b14e3bee..8549f26e249 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1760,6 +1760,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
goto cleanup;
}
+ atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
if (res->fi->fib_nhs > 1)
@@ -1820,7 +1821,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
if (err)
return err;
- atomic_set(&rth->u.dst.__refcnt, 1);
/* put it into the cache */
hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
@@ -1834,8 +1834,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
u32 daddr, u32 saddr, u32 tos)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
- struct rtable* rth = NULL;
- unsigned char hop, hopcount, lasthop;
+ struct rtable* rth = NULL, *rtres;
+ unsigned char hop, hopcount;
int err = -EINVAL;
unsigned int hash;
@@ -1844,8 +1844,6 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
else
hopcount = 1;
- lasthop = hopcount - 1;
-
/* distinguish between multipath and singlepath */
if (hopcount < 2)
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,
for (hop = 0; hop < hopcount; hop++) {
res->nh_sel = hop;
+ /* put reference to previous result */
+ if (hop)
+ ip_rt_put(rtres);
+
/* create a routing cache entry */
err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
&rth);
@@ -1863,7 +1865,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
/* put it into the cache */
hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
- err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
+ err = rt_intern_hash(hash, rth, &rtres);
if (err)
return err;
@@ -1873,13 +1875,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
FIB_RES_NETMASK(*res),
res->prefixlen,
&FIB_RES_NH(*res));
-
- /* only for the last hop the reference count is handled
- * outside
- */
- if (hop == lasthop)
- atomic_set(&(skb->dst->__refcnt), 1);
}
+ skb->dst = &rtres->u.dst;
return err;
#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
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,
goto cleanup;
}
+ atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
if (res->fi) {
@@ -2290,8 +2288,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
if (err == 0) {
u32 tos = RT_FL_TOS(oldflp);
- atomic_set(&rth->u.dst.__refcnt, 1);
-
hash = rt_hash_code(oldflp->fl4_dst,
oldflp->fl4_src ^ (oldflp->oif << 5), tos);
err = rt_intern_hash(hash, rth, rp);
@@ -2326,6 +2322,10 @@ static inline int ip_mkroute_output(struct rtable** rp,
dev2nexthop = FIB_RES_DEV(*res);
dev_hold(dev2nexthop);
+ /* put reference to previous result */
+ if (hop)
+ ip_rt_put(*rp);
+
err = __mkroute_output(&rth, res, fl, oldflp,
dev2nexthop, flags);
@@ -2350,7 +2350,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
if (err != 0)
return err;
}
- atomic_set(&(*rp)->u.dst.__refcnt, 1);
return err;
} else {
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 6094db5e11b..15e1134da1b 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
/* If this packet has been sent out already, we must
* adjust the various packet counters.
*/
- if (after(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
+ if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
int diff = old_factor - tcp_skb_pcount(skb) -
tcp_skb_pcount(buff);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5beca7de86..e0bd1013cb0 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
if (ulen > len || ulen < sizeof(*uh))
goto short_packet;
- if (pskb_trim(skb, ulen))
+ if (pskb_trim_rcsum(skb, ulen))
goto short_packet;
if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6d6fb74f3b5..2fea3f4402a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -123,8 +123,7 @@ DEFINE_RWLOCK(addrconf_lock);
static void addrconf_verify(unsigned long);
-static struct timer_list addr_chk_timer =
- TIMER_INITIALIZER(addrconf_verify, 0, 0);
+static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
static DEFINE_SPINLOCK(addrconf_verify_lock);
static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 01468fab3d3..cc518405b3e 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,10 +175,8 @@ ipv4_connected:
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto out;
- }
/* source address lookup done in ip6_dst_lookup */
@@ -390,32 +388,101 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
}
+ if (np->rxopt.bits.rxtclass) {
+ int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
+ put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+ }
+
if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
}
+
+ /* HbH is allowed only once */
if (np->rxopt.bits.hopopts && opt->hop) {
u8 *ptr = skb->nh.raw + opt->hop;
put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
}
- if (np->rxopt.bits.dstopts && opt->dst0) {
+
+ if (opt->lastopt &&
+ (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
+ /*
+ * Silly enough, but we need to reparse in order to
+ * report extension headers (except for HbH)
+ * in order.
+ *
+ * Also note that IPV6_RECVRTHDRDSTOPTS is NOT
+ * (and WILL NOT be) defined because
+ * IPV6_RECVDSTOPTS is more generic. --yoshfuji
+ */
+ unsigned int off = sizeof(struct ipv6hdr);
+ u8 nexthdr = skb->nh.ipv6h->nexthdr;
+
+ while (off <= opt->lastopt) {
+ unsigned len;
+ u8 *ptr = skb->nh.raw + off;
+
+ switch(nexthdr) {
+ case IPPROTO_DSTOPTS:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ if (np->rxopt.bits.dstopts)
+ put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
+ break;
+ case IPPROTO_ROUTING:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ if (np->rxopt.bits.srcrt)
+ put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
+ break;
+ case IPPROTO_AH:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 2;
+ break;
+ default:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ break;
+ }
+
+ off += len;
+ }
+ }
+
+ /* socket options in old style */
+ if (np->rxopt.bits.rxoinfo) {
+ struct in6_pktinfo src_info;
+
+ src_info.ipi6_ifindex = opt->iif;
+ ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+ }
+ if (np->rxopt.bits.rxohlim) {
+ int hlim = skb->nh.ipv6h->hop_limit;
+ put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+ }
+ if (np->rxopt.bits.ohopopts && opt->hop) {
+ u8 *ptr = skb->nh.raw + opt->hop;
+ put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
+ }
+ if (np->rxopt.bits.odstopts && opt->dst0) {
u8 *ptr = skb->nh.raw + opt->dst0;
- put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
- if (np->rxopt.bits.srcrt && opt->srcrt) {
+ if (np->rxopt.bits.osrcrt && opt->srcrt) {
struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
- put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
}
- if (np->rxopt.bits.dstopts && opt->dst1) {
+ if (np->rxopt.bits.odstopts && opt->dst1) {
u8 *ptr = skb->nh.raw + opt->dst1;
- put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
return 0;
}
int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
struct ipv6_txoptions *opt,
- int *hlimit)
+ int *hlimit, int *tclass)
{
struct in6_pktinfo *src_info;
struct cmsghdr *cmsg;
@@ -438,6 +505,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
switch (cmsg->cmsg_type) {
case IPV6_PKTINFO:
+ case IPV6_2292PKTINFO:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
err = -EINVAL;
goto exit_f;
@@ -492,6 +560,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
break;
+ case IPV6_2292HOPOPTS:
case IPV6_HOPOPTS:
if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
err = -EINVAL;
@@ -512,7 +581,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->hopopt = hdr;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292DSTOPTS:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
err = -EINVAL;
goto exit_f;
@@ -536,6 +605,33 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->dst1opt = hdr;
break;
+ case IPV6_DSTOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+
+ hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
+ len = ((hdr->hdrlen + 1) << 3);
+ if (cmsg->cmsg_len < CMSG_LEN(len)) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+ if (!capable(CAP_NET_RAW)) {
+ err = -EPERM;
+ goto exit_f;
+ }
+ if (cmsg->cmsg_type == IPV6_DSTOPTS) {
+ opt->opt_flen += len;
+ opt->dst1opt = hdr;
+ } else {
+ opt->opt_nflen += len;
+ opt->dst0opt = hdr;
+ }
+ break;
+
+ case IPV6_2292RTHDR:
case IPV6_RTHDR:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
err = -EINVAL;
@@ -568,7 +664,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->opt_nflen += len;
opt->srcrt = rthdr;
- if (opt->dst1opt) {
+ if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
opt->opt_nflen += dsthdrlen;
@@ -579,6 +675,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
break;
+ case IPV6_2292HOPLIMIT:
case IPV6_HOPLIMIT:
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
err = -EINVAL;
@@ -588,6 +685,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
*hlimit = *(int *)CMSG_DATA(cmsg);
break;
+ case IPV6_TCLASS:
+ {
+ int tc;
+
+ err = -EINVAL;
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+ goto exit_f;
+ }
+
+ tc = *(int *)CMSG_DATA(cmsg);
+ if (tc < 0 || tc > 0xff)
+ goto exit_f;
+
+ err = 0;
+ *tclass = tc;
+
+ break;
+ }
default:
LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
cmsg->cmsg_type);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5be6da2584e..47122728212 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)
return -1;
}
+ opt->lastopt = skb->h.raw - skb->nh.raw;
opt->dst1 = skb->h.raw - skb->nh.raw;
if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
@@ -243,6 +244,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
looped_back:
if (hdr->segments_left == 0) {
+ opt->lastopt = skb->h.raw - skb->nh.raw;
opt->srcrt = skb->h.raw - skb->nh.raw;
skb->h.raw += (hdr->hdrlen + 1) << 3;
opt->dst0 = opt->dst1;
@@ -459,11 +461,10 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
}
- if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
- __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
- if (skb->ip_summed == CHECKSUM_HW)
- skb->ip_summed = CHECKSUM_NONE;
- }
+
+ if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
+ goto drop;
+
return 1;
drop:
@@ -539,10 +540,15 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto,
struct in6_addr **daddr)
{
- if (opt->srcrt)
+ if (opt->srcrt) {
ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
- if (opt->dst0opt)
- ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+ /*
+ * IPV6_RTHDRDSTOPTS is ignored
+ * unless IPV6_RTHDR is set (RFC3542).
+ */
+ if (opt->dst0opt)
+ ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+ }
if (opt->hopopt)
ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
}
@@ -573,3 +579,97 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
}
return opt2;
}
+
+static int ipv6_renew_option(void *ohdr,
+ struct ipv6_opt_hdr __user *newopt, int newoptlen,
+ int inherit,
+ struct ipv6_opt_hdr **hdr,
+ char **p)
+{
+ if (inherit) {
+ if (ohdr) {
+ memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
+ *hdr = (struct ipv6_opt_hdr *)*p;
+ *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
+ }
+ } else {
+ if (newopt) {
+ if (copy_from_user(*p, newopt, newoptlen))
+ return -EFAULT;
+ *hdr = (struct ipv6_opt_hdr *)*p;
+ if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
+ return -EINVAL;
+ *p += CMSG_ALIGN(newoptlen);
+ }
+ }
+ return 0;
+}
+
+struct ipv6_txoptions *
+ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
+ int newtype,
+ struct ipv6_opt_hdr __user *newopt, int newoptlen)
+{
+ int tot_len = 0;
+ char *p;
+ struct ipv6_txoptions *opt2;
+ int err;
+
+ if (newtype != IPV6_HOPOPTS && opt->hopopt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
+ if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
+ if (newtype != IPV6_RTHDR && opt->srcrt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
+ if (newtype != IPV6_DSTOPTS && opt->dst1opt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
+ if (newopt && newoptlen)
+ tot_len += CMSG_ALIGN(newoptlen);
+
+ if (!tot_len)
+ return NULL;
+
+ opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
+ if (!opt2)
+ return ERR_PTR(-ENOBUFS);
+
+ memset(opt2, 0, tot_len);
+
+ opt2->tot_len = tot_len;
+ p = (char *)(opt2 + 1);
+
+ err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
+ newtype != IPV6_HOPOPTS,
+ &opt2->hopopt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
+ newtype != IPV6_RTHDRDSTOPTS,
+ &opt2->dst0opt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
+ newtype != IPV6_RTHDR,
+ (struct ipv6_opt_hdr **)opt2->srcrt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
+ newtype != IPV6_DSTOPTS,
+ &opt2->dst1opt, &p);
+ if (err)
+ goto out;
+
+ opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
+ (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
+ (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
+ opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
+
+ return opt2;
+out:
+ sock_kfree_s(sk, p, tot_len);
+ return ERR_PTR(err);
+}
+
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fa8f1bb0aa5..b7185fb3377 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,
int iif = 0;
int addr_type = 0;
int len;
- int hlimit;
+ int hlimit, tclass;
int err = 0;
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,
if (err)
goto out;
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
- goto out_dst_release;
+ goto out;
if (ipv6_addr_is_multicast(&fl.fl6_dst))
hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+
msg.skb = skb;
msg.offset = skb->nh.raw - skb->data;
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
err = ip6_append_data(sk, icmpv6_getfrag, &msg,
len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr),
- hlimit, NULL, &fl, (struct rt6_info*)dst,
+ hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
MSG_DONTWAIT);
if (err) {
ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct dst_entry *dst;
int err = 0;
int hlimit;
+ int tclass;
saddr = &skb->nh.ipv6h->daddr;
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (err)
goto out;
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
- goto out_dst_release;
+ goto out;
if (ipv6_addr_is_multicast(&fl.fl6_dst))
hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+
idev = in6_dev_get(skb->dev);
msg.skb = skb;
msg.offset = 0;
err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
- sizeof(struct icmp6hdr), hlimit, NULL, &fl,
+ sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
(struct rt6_info*)dst, MSG_DONTWAIT);
if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
out_put:
if (likely(idev != NULL))
in6_dev_put(idev);
-out_dst_release:
dst_release(dst);
out:
icmpv6_xmit_unlock();
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 16af874c9e8..4fcc5a7acf6 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);
static __u32 rt_sernum;
-static struct timer_list ip6_fib_timer = TIMER_INITIALIZER(fib6_run_gc, 0, 0);
+static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b6c73da5ff3..f841bde30c1 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);
static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1];
static void ip6_fl_gc(unsigned long dummy);
-static struct timer_list ip6_fl_gc_timer = TIMER_INITIALIZER(ip6_fl_gc, 0, 0);
+static DEFINE_TIMER(ip6_fl_gc_timer, ip6_fl_gc, 0, 0);
/* FL hash table lock: it protects only of GC */
@@ -225,16 +225,20 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
struct ip6_flowlabel * fl,
struct ipv6_txoptions * fopt)
{
- struct ipv6_txoptions * fl_opt = fl->opt;
+ struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
- if (fopt == NULL || fopt->opt_flen == 0)
- return fl_opt;
+ if (fopt == NULL || fopt->opt_flen == 0) {
+ if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
+ return fl_opt;
+ }
if (fl_opt != NULL) {
opt_space->hopopt = fl_opt->hopopt;
- opt_space->dst0opt = fl_opt->dst0opt;
+ opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
opt_space->srcrt = fl_opt->srcrt;
opt_space->opt_nflen = fl_opt->opt_nflen;
+ if (fl_opt->dst0opt && !fl_opt->srcrt)
+ opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
} else {
if (fopt->opt_nflen == 0)
return fopt;
@@ -310,7 +314,7 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
msg.msg_control = (void*)(fl->opt+1);
flowi.oif = 0;
- err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+ err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
if (err)
goto done;
err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 01ef94f7c7f..2f589f24c09 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,
struct ipv6hdr *hdr;
u8 proto = fl->proto;
int seg_len = skb->len;
- int hlimit;
+ int hlimit, tclass;
u32 mtu;
if (opt) {
@@ -202,7 +202,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
* Fill in the IPv6 header
*/
- *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
hlimit = -1;
if (np)
hlimit = np->hop_limit;
@@ -211,6 +210,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = -1;
+ if (np)
+ tclass = np->tclass;
+ if (tclass < 0)
+ tclass = 0;
+
+ *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
+
hdr->payload_len = htons(seg_len);
hdr->nexthdr = proto;
hdr->hop_limit = hlimit;
@@ -762,10 +769,11 @@ out_err_release:
return err;
}
-int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
- void *from, int length, int transhdrlen,
- int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt,
- unsigned int flags)
+int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ int offset, int len, int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
+ struct rt6_info *rt, unsigned int flags)
{
struct inet_sock *inet = inet_sk(sk);
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
np->cork.rt = rt;
inet->cork.fl = *fl;
np->cork.hop_limit = hlimit;
+ np->cork.tclass = tclass;
inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path);
if (dst_allfrag(rt->u.dst.path))
inet->cork.flags |= IPCORK_ALLFRAG;
@@ -1084,7 +1093,8 @@ int ip6_push_pending_frames(struct sock *sk)
skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
- *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
+ *(u32*)hdr = fl->fl6_flowlabel |
+ htonl(0x60000000 | ((int)np->cork.tclass << 20));
if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 09613729404..cf94372d1af 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)
if ((dst = ip6_tnl_dst_check(t)) != NULL)
dst_hold(dst);
- else
+ else {
dst = ip6_route_output(NULL, &fl);
- if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
- goto tx_err_link_failure;
+ if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
+ goto tx_err_link_failure;
+ }
tdev = dst->dev;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 76466af8331..8567873d0dd 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,
retv = 0;
break;
- case IPV6_PKTINFO:
+ case IPV6_RECVPKTINFO:
np->rxopt.bits.rxinfo = valbool;
retv = 0;
break;
+
+ case IPV6_2292PKTINFO:
+ np->rxopt.bits.rxoinfo = valbool;
+ retv = 0;
+ break;
- case IPV6_HOPLIMIT:
+ case IPV6_RECVHOPLIMIT:
np->rxopt.bits.rxhlim = valbool;
retv = 0;
break;
- case IPV6_RTHDR:
+ case IPV6_2292HOPLIMIT:
+ np->rxopt.bits.rxohlim = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_RECVRTHDR:
if (val < 0 || val > 2)
goto e_inval;
np->rxopt.bits.srcrt = val;
retv = 0;
break;
- case IPV6_HOPOPTS:
+ case IPV6_2292RTHDR:
+ if (val < 0 || val > 2)
+ goto e_inval;
+ np->rxopt.bits.osrcrt = val;
+ retv = 0;
+ break;
+
+ case IPV6_RECVHOPOPTS:
np->rxopt.bits.hopopts = valbool;
retv = 0;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292HOPOPTS:
+ np->rxopt.bits.ohopopts = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_RECVDSTOPTS:
np->rxopt.bits.dstopts = valbool;
retv = 0;
break;
+ case IPV6_2292DSTOPTS:
+ np->rxopt.bits.odstopts = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_TCLASS:
+ if (val < 0 || val > 0xff)
+ goto e_inval;
+ np->tclass = val;
+ retv = 0;
+ break;
+
+ case IPV6_RECVTCLASS:
+ np->rxopt.bits.rxtclass = valbool;
+ retv = 0;
+ break;
+
case IPV6_FLOWINFO:
np->rxopt.bits.rxflow = valbool;
retv = 0;
break;
- case IPV6_PKTOPTIONS:
+ case IPV6_HOPOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ case IPV6_RTHDR:
+ case IPV6_DSTOPTS:
+ {
+ struct ipv6_txoptions *opt;
+ if (optlen == 0)
+ optval = 0;
+
+ /* hop-by-hop / destination options are privileged option */
+ retv = -EPERM;
+ if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
+ break;
+
+ retv = -EINVAL;
+ if (optlen & 0x7 || optlen > 8 * 255)
+ break;
+
+ opt = ipv6_renew_options(sk, np->opt, optname,
+ (struct ipv6_opt_hdr __user *)optval,
+ optlen);
+ if (IS_ERR(opt)) {
+ retv = PTR_ERR(opt);
+ break;
+ }
+
+ /* routing header option needs extra check */
+ if (optname == IPV6_RTHDR && opt->srcrt) {
+ struct ipv6_rt_hdr *rthdr = opt->srcrt;
+ if (rthdr->type)
+ goto sticky_done;
+ if ((rthdr->hdrlen & 1) ||
+ (rthdr->hdrlen >> 1) != rthdr->segments_left)
+ goto sticky_done;
+ }
+
+ retv = 0;
+ if (sk->sk_type == SOCK_STREAM) {
+ if (opt) {
+ struct tcp_sock *tp = tcp_sk(sk);
+ if (!((1 << sk->sk_state) &
+ (TCPF_LISTEN | TCPF_CLOSE))
+ && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
+ tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
+ tcp_sync_mss(sk, tp->pmtu_cookie);
+ }
+ }
+ opt = xchg(&np->opt, opt);
+ sk_dst_reset(sk);
+ } else {
+ write_lock(&sk->sk_dst_lock);
+ opt = xchg(&np->opt, opt);
+ write_unlock(&sk->sk_dst_lock);
+ sk_dst_reset(sk);
+ }
+sticky_done:
+ if (opt)
+ sock_kfree_s(sk, opt, opt->tot_len);
+ break;
+ }
+
+ case IPV6_2292PKTOPTIONS:
{
struct ipv6_txoptions *opt = NULL;
struct msghdr msg;
@@ -276,7 +376,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
msg.msg_controllen = optlen;
msg.msg_control = (void*)(opt+1);
- retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+ retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
if (retv)
goto done;
update:
@@ -529,6 +629,17 @@ e_inval:
return -EINVAL;
}
+int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
+ char __user *optval, int len)
+{
+ if (!hdr)
+ return 0;
+ len = min_t(int, len, ipv6_optlen(hdr));
+ if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
+ return -EFAULT;
+ return len;
+}
+
int ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -567,7 +678,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
return err;
}
- case IPV6_PKTOPTIONS:
+ case IPV6_2292PKTOPTIONS:
{
struct msghdr msg;
struct sk_buff *skb;
@@ -601,6 +712,16 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
int hlim = np->mcast_hops;
put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
}
+ if (np->rxopt.bits.rxoinfo) {
+ struct in6_pktinfo src_info;
+ src_info.ipi6_ifindex = np->mcast_oif;
+ ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
+ put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+ }
+ if (np->rxopt.bits.rxohlim) {
+ int hlim = np->mcast_hops;
+ put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+ }
}
len -= msg.msg_controllen;
return put_user(len, optlen);
@@ -625,26 +746,67 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
val = np->ipv6only;
break;
- case IPV6_PKTINFO:
+ case IPV6_RECVPKTINFO:
val = np->rxopt.bits.rxinfo;
break;
- case IPV6_HOPLIMIT:
+ case IPV6_2292PKTINFO:
+ val = np->rxopt.bits.rxoinfo;
+ break;
+
+ case IPV6_RECVHOPLIMIT:
val = np->rxopt.bits.rxhlim;
break;
- case IPV6_RTHDR:
+ case IPV6_2292HOPLIMIT:
+ val = np->rxopt.bits.rxohlim;
+ break;
+
+ case IPV6_RECVRTHDR:
val = np->rxopt.bits.srcrt;
break;
+ case IPV6_2292RTHDR:
+ val = np->rxopt.bits.osrcrt;
+ break;
+
case IPV6_HOPOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ case IPV6_RTHDR:
+ case IPV6_DSTOPTS:
+ {
+
+ lock_sock(sk);
+ len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
+ optval, len);
+ release_sock(sk);
+ return put_user(len, optlen);
+ }
+
+ case IPV6_RECVHOPOPTS:
val = np->rxopt.bits.hopopts;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292HOPOPTS:
+ val = np->rxopt.bits.ohopopts;
+ break;
+
+ case IPV6_RECVDSTOPTS:
val = np->rxopt.bits.dstopts;
break;
+ case IPV6_2292DSTOPTS:
+ val = np->rxopt.bits.odstopts;
+ break;
+
+ case IPV6_TCLASS:
+ val = np->tclass;
+ break;
+
+ case IPV6_RECVTCLASS:
+ val = np->rxopt.bits.rxtclass;
+ break;
+
case IPV6_FLOWINFO:
val = np->rxopt.bits.rxflow;
break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a7eae30f455..555a31347ed 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,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
if (inc_opt) {
if (dev->addr_len)
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
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,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
len = sizeof(struct icmp6hdr);
if (dev->addr_len)
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err) {
- dst_release(dst);
+ if (err)
return;
- }
rt = (struct rt6_info *) dst;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 14316c3ebde..b03e87adca9 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)
dst = ip6_route_output(NULL, &fl);
if (dst == NULL)
return;
- if (dst->error ||
- xfrm_lookup(&dst, &fl, NULL, 0)) {
- dst_release(dst);
+ if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
return;
- }
hh_len = (dst->dev->hard_header_len + 15)&~15;
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 9b91decbfdd..4de4cdad4b7 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/file.h>
+#include <linux/rcupdate.h>
#include <net/sock.h>
#include <linux/netfilter_ipv6/ip6t_owner.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed3a76b30fd..5aa3691c578 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,
struct flowi fl;
int addr_len = msg->msg_namelen;
int hlimit = -1;
+ int tclass = -1;
u16 proto;
int err;
@@ -740,7 +741,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions);
- err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+ err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -755,8 +756,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
}
if (opt == NULL)
opt = np->opt;
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
+ opt = fl6_merge_options(&opt_space, flowlabel, opt);
fl.proto = proto;
rawv6_probe_proto_opt(&fl, msg);
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto out;
- }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -798,6 +796,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
hlimit = ipv6_get_hoplimit(dst->dev);
}
+ if (tclass < 0) {
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
@@ -806,8 +810,9 @@ back_from_confirm:
err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
} else {
lock_sock(sk);
- err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
- hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags);
+ err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
+ len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
+ msg->msg_flags);
if (err)
ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 9d9e04344c7..e4fe9ee484d 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,
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
goto err;
- if (end-offset < skb->len) {
- if (pskb_trim(skb, end - offset))
- goto err;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY)
- skb->ip_summed = CHECKSUM_NONE;
- }
+
+ if (pskb_trim_rcsum(skb, end - offset))
+ goto err;
/* Find out which fragments are in front and at the back of us
* 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 794734f1d23..80643e6b346 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,
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto failure;
- }
if (saddr == NULL) {
saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
if (dst == NULL) {
opt = np->opt;
if (opt == NULL &&
- np->rxopt.bits.srcrt == 2 &&
+ np->rxopt.bits.osrcrt == 2 &&
treq->pktopts) {
struct sk_buff *pktopts = treq->pktopts;
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
}
done:
- dst_release(dst);
if (opt && opt != np->opt)
sock_kfree_s(sk, opt, opt->tot_len);
return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.all) {
- if ((opt->hop && np->rxopt.bits.hopopts) ||
- ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
- np->rxopt.bits.rxflow) ||
- (opt->srcrt && np->rxopt.bits.srcrt) ||
- ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
+ if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
+ ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
+ (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
+ ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
return 1;
}
return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
/* sk = NULL, but it is safe for now. RST socket required. */
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
- if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
- dst_release(buff->dst);
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
return;
- }
ip6_xmit(NULL, buff, &fl, NULL, 0);
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
fl.fl_ip_sport = t1->source;
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
- if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
- dst_release(buff->dst);
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
return;
- }
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
TCP_ECN_create_request(req, skb->h.th);
treq->pktopts = NULL;
if (ipv6_opt_accepted(sk, skb) ||
- np->rxopt.bits.rxinfo ||
- np->rxopt.bits.rxhlim) {
+ np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+ np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
atomic_inc(&skb->users);
treq->pktopts = skb;
}
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (sk_acceptq_is_full(sk))
goto out_overflow;
- if (np->rxopt.bits.srcrt == 2 &&
+ if (np->rxopt.bits.osrcrt == 2 &&
opt == NULL && treq->pktopts) {
struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
tp = tcp_sk(sk);
if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
- if (np->rxopt.bits.rxinfo)
+ if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
np->mcast_oif = inet6_iif(opt_skb);
- if (np->rxopt.bits.rxhlim)
+ if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
if (ipv6_opt_accepted(sk, opt_skb)) {
skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
sk->sk_err_soft = -err;
- dst_release(dst);
return err;
}
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
sk->sk_route_caps = 0;
- dst_release(dst);
return err;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 390d750449c..69b146843a2 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)
}
if (ulen < skb->len) {
- if (__pskb_trim(skb, ulen))
+ if (pskb_trim_rcsum(skb, ulen))
goto discard;
saddr = &skb->nh.ipv6h->saddr;
daddr = &skb->nh.ipv6h->daddr;
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
int addr_len = msg->msg_namelen;
int ulen = len;
int hlimit = -1;
+ int tclass = -1;
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int err;
@@ -758,7 +759,7 @@ do_udp_sendmsg:
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(*opt);
- err = datagram_send_ctl(msg, fl, opt, &hlimit);
+ err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -773,8 +774,7 @@ do_udp_sendmsg:
}
if (opt == NULL)
opt = np->opt;
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
+ opt = fl6_merge_options(&opt_space, flowlabel, opt);
fl->proto = IPPROTO_UDP;
ipv6_addr_copy(&fl->fl6_dst, daddr);
@@ -799,10 +799,8 @@ do_udp_sendmsg:
if (final_p)
ipv6_addr_copy(&fl->fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
goto out;
- }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -815,6 +813,12 @@ do_udp_sendmsg:
hlimit = ipv6_get_hoplimit(dst->dev);
}
+ if (tclass < 0) {
+ tclass = np->tclass;
+ if (tclass < 0)
+ tclass = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
back_from_confirm:
@@ -834,9 +838,10 @@ back_from_confirm:
do_append_data:
up->len += ulen;
- err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
- hlimit, opt, fl, (struct rt6_info*)dst,
- corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+ err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
+ sizeof(struct udphdr), hlimit, tclass, opt, fl,
+ (struct rt6_info*)dst,
+ corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err)
udp_v6_flush_pending_frames(sk);
else if (!corkreq)
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index 165b2abce11..e856ae1b360 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -17,7 +17,7 @@
static void nr_loopback_timer(unsigned long);
static struct sk_buff_head loopback_queue;
-static struct timer_list loopback_timer = TIMER_INITIALIZER(nr_loopback_timer, 0, 0);
+static DEFINE_TIMER(loopback_timer, nr_loopback_timer, 0, 0);
void __init nr_loopback_init(void)
{
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 02891ce2db3..36a77944622 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
memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
memcpy(callsign, p + 12, l - 10);
callsign[l - 10] = '\0';
- facilities->source_call = *asc2ax(callsign);
+ asc2ax(&facilities->source_call, callsign);
}
if (*p == FAC_CCITT_SRC_NSAP) {
memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
memcpy(callsign, p + 12, l - 10);
callsign[l - 10] = '\0';
- facilities->dest_call = *asc2ax(callsign);
+ asc2ax(&facilities->dest_call, callsign);
}
p += l + 2;
n += l + 2;
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 737681cb9a9..31570b9a6e9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1194,7 +1194,7 @@ EXPORT_SYMBOL(psched_time_base);
* with 32-bit get_cycles(). Safe up to 4GHz CPU.
*/
static void psched_tick(unsigned long);
-static struct timer_list psched_timer = TIMER_INITIALIZER(psched_tick, 0, 0);
+static DEFINE_TIMER(psched_timer, psched_tick, 0, 0);
static void psched_tick(unsigned long dummy)
{
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 83c8135e176..fda737d77ed 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -765,8 +765,8 @@ restart:
switch (policy->action) {
case XFRM_POLICY_BLOCK:
/* Prohibit the flow */
- xfrm_pol_put(policy);
- return -EPERM;
+ err = -EPERM;
+ goto error;
case XFRM_POLICY_ALLOW:
if (policy->xfrm_nr == 0) {
@@ -782,8 +782,8 @@ restart:
*/
dst = xfrm_find_bundle(fl, policy, family);
if (IS_ERR(dst)) {
- xfrm_pol_put(policy);
- return PTR_ERR(dst);
+ err = PTR_ERR(dst);
+ goto error;
}
if (dst)
diff --git a/security/dummy.c b/security/dummy.c
index 6ff88758647..9623a61dfc7 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -258,16 +258,16 @@ static void dummy_inode_free_security (struct inode *inode)
return;
}
-static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
- int mask)
+static int dummy_inode_init_security (struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len)
{
- return 0;
+ return -EOPNOTSUPP;
}
-static void dummy_inode_post_create (struct inode *inode, struct dentry *dentry,
- int mask)
+static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
+ int mask)
{
- return;
+ return 0;
}
static 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,
return 0;
}
-static void dummy_inode_post_link (struct dentry *old_dentry,
- struct inode *inode,
- struct dentry *new_dentry)
-{
- return;
-}
-
static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry)
{
return 0;
@@ -294,24 +287,12 @@ static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry,
return 0;
}
-static void dummy_inode_post_symlink (struct inode *inode,
- struct dentry *dentry, const char *name)
-{
- return;
-}
-
static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry,
int mask)
{
return 0;
}
-static void dummy_inode_post_mkdir (struct inode *inode, struct dentry *dentry,
- int mask)
-{
- return;
-}
-
static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry)
{
return 0;
@@ -323,12 +304,6 @@ static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry,
return 0;
}
-static void dummy_inode_post_mknod (struct inode *inode, struct dentry *dentry,
- int mode, dev_t dev)
-{
- return;
-}
-
static int dummy_inode_rename (struct inode *old_inode,
struct dentry *old_dentry,
struct inode *new_inode,
@@ -337,14 +312,6 @@ static int dummy_inode_rename (struct inode *old_inode,
return 0;
}
-static void dummy_inode_post_rename (struct inode *old_inode,
- struct dentry *old_dentry,
- struct inode *new_inode,
- struct dentry *new_dentry)
-{
- return;
-}
-
static int dummy_inode_readlink (struct dentry *dentry)
{
return 0;
@@ -886,20 +853,15 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sb_post_pivotroot);
set_to_dummy_if_null(ops, inode_alloc_security);
set_to_dummy_if_null(ops, inode_free_security);
+ set_to_dummy_if_null(ops, inode_init_security);
set_to_dummy_if_null(ops, inode_create);
- set_to_dummy_if_null(ops, inode_post_create);
set_to_dummy_if_null(ops, inode_link);
- set_to_dummy_if_null(ops, inode_post_link);
set_to_dummy_if_null(ops, inode_unlink);
set_to_dummy_if_null(ops, inode_symlink);
- set_to_dummy_if_null(ops, inode_post_symlink);
set_to_dummy_if_null(ops, inode_mkdir);
- set_to_dummy_if_null(ops, inode_post_mkdir);
set_to_dummy_if_null(ops, inode_rmdir);
set_to_dummy_if_null(ops, inode_mknod);
- set_to_dummy_if_null(ops, inode_post_mknod);
set_to_dummy_if_null(ops, inode_rename);
- set_to_dummy_if_null(ops, inode_post_rename);
set_to_dummy_if_null(ops, inode_readlink);
set_to_dummy_if_null(ops, inode_follow_link);
set_to_dummy_if_null(ops, inode_permission);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8641f8894b4..f40c8221ec1 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)
return 0;
}
-/* Set the security attributes on a newly created file. */
-static int post_create(struct inode *dir,
- struct dentry *dentry)
-{
-
- struct task_security_struct *tsec;
- struct inode *inode;
- struct inode_security_struct *dsec;
- struct superblock_security_struct *sbsec;
- u32 newsid;
- char *context;
- unsigned int len;
- int rc;
-
- tsec = current->security;
- dsec = dir->i_security;
- sbsec = dir->i_sb->s_security;
-
- inode = dentry->d_inode;
- if (!inode) {
- /* Some file system types (e.g. NFS) may not instantiate
- a dentry for all create operations (e.g. symlink),
- so we have to check to see if the inode is non-NULL. */
- printk(KERN_WARNING "post_create: no inode, dir (dev=%s, "
- "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);
- return 0;
- }
-
- if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
- newsid = tsec->create_sid;
- } else {
- rc = security_transition_sid(tsec->sid, dsec->sid,
- inode_mode_to_security_class(inode->i_mode),
- &newsid);
- if (rc) {
- printk(KERN_WARNING "post_create: "
- "security_transition_sid failed, rc=%d (dev=%s "
- "ino=%ld)\n",
- -rc, inode->i_sb->s_id, inode->i_ino);
- return rc;
- }
- }
-
- rc = inode_security_set_sid(inode, newsid);
- if (rc) {
- printk(KERN_WARNING "post_create: inode_security_set_sid "
- "failed, rc=%d (dev=%s ino=%ld)\n",
- -rc, inode->i_sb->s_id, inode->i_ino);
- return rc;
- }
-
- if (sbsec->behavior == SECURITY_FS_USE_XATTR &&
- inode->i_op->setxattr) {
- /* Use extended attributes. */
- rc = security_sid_to_context(newsid, &context, &len);
- if (rc) {
- printk(KERN_WARNING "post_create: sid_to_context "
- "failed, rc=%d (dev=%s ino=%ld)\n",
- -rc, inode->i_sb->s_id, inode->i_ino);
- return rc;
- }
- down(&inode->i_sem);
- rc = inode->i_op->setxattr(dentry,
- XATTR_NAME_SELINUX,
- context, len, 0);
- up(&inode->i_sem);
- kfree(context);
- if (rc < 0) {
- printk(KERN_WARNING "post_create: setxattr failed, "
- "rc=%d (dev=%s ino=%ld)\n",
- -rc, inode->i_sb->s_id, inode->i_ino);
- return rc;
- }
- }
-
- return 0;
-}
-
-
/* Hook functions begin here. */
static 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)
struct avc_audit_data ad;
struct file *file, *devnull = NULL;
struct tty_struct *tty = current->signal->tty;
+ struct fdtable *fdt;
long j = -1;
if (tty) {
@@ -1706,9 +1628,10 @@ static inline void flush_unauthorized_files(struct files_struct * files)
j++;
i = j * __NFDBITS;
- if (i >= files->max_fds || i >= files->max_fdset)
+ fdt = files_fdtable(files);
+ if (i >= fdt->max_fds || i >= fdt->max_fdset)
break;
- set = files->open_fds->fds_bits[j];
+ set = fdt->open_fds->fds_bits[j];
if (!set)
continue;
spin_unlock(&files->file_lock);
@@ -1729,7 +1652,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
continue;
}
if (devnull) {
- atomic_inc(&devnull->f_count);
+ rcuref_inc(&devnull->f_count);
} else {
devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
if (!devnull) {
@@ -2018,14 +1941,64 @@ static void selinux_inode_free_security(struct inode *inode)
inode_free_security(inode);
}
-static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
+static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+ char **name, void **value,
+ size_t *len)
{
- return may_create(dir, dentry, SECCLASS_FILE);
+ struct task_security_struct *tsec;
+ struct inode_security_struct *dsec;
+ struct superblock_security_struct *sbsec;
+ struct inode_security_struct *isec;
+ u32 newsid, clen;
+ int rc;
+ char *namep = NULL, *context;
+
+ tsec = current->security;
+ dsec = dir->i_security;
+ sbsec = dir->i_sb->s_security;
+ isec = inode->i_security;
+
+ if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
+ newsid = tsec->create_sid;
+ } else {
+ rc = security_transition_sid(tsec->sid, dsec->sid,
+ inode_mode_to_security_class(inode->i_mode),
+ &newsid);
+ if (rc) {
+ printk(KERN_WARNING "%s: "
+ "security_transition_sid failed, rc=%d (dev=%s "
+ "ino=%ld)\n",
+ __FUNCTION__,
+ -rc, inode->i_sb->s_id, inode->i_ino);
+ return rc;
+ }
+ }
+
+ inode_security_set_sid(inode, newsid);
+
+ if (name) {
+ namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
+ if (!namep)
+ return -ENOMEM;
+ *name = namep;
+ }
+
+ if (value && len) {
+ rc = security_sid_to_context(newsid, &context, &clen);
+ if (rc) {
+ kfree(namep);
+ return rc;
+ }
+ *value = context;
+ *len = clen;
+ }
+
+ return 0;
}
-static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask)
+static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
{
- post_create(dir, dentry);
+ return may_create(dir, dentry, SECCLASS_FILE);
}
static 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
return may_link(dir, old_dentry, MAY_LINK);
}
-static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
-{
- return;
-}
-
static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
{
int rc;
@@ -2058,21 +2026,11 @@ static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const
return may_create(dir, dentry, SECCLASS_LNK_FILE);
}
-static void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name)
-{
- post_create(dir, dentry);
-}
-
static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
{
return may_create(dir, dentry, SECCLASS_DIR);
}
-static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask)
-{
- post_create(dir, dentry);
-}
-
static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
{
return may_link(dir, dentry, MAY_RMDIR);
@@ -2089,23 +2047,12 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mod
return may_create(dir, dentry, inode_mode_to_security_class(mode));
}
-static void selinux_inode_post_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
- post_create(dir, dentry);
-}
-
static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
struct inode *new_inode, struct dentry *new_dentry)
{
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
}
-static void selinux_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry,
- struct inode *new_inode, struct dentry *new_dentry)
-{
- return;
-}
-
static int selinux_inode_readlink(struct dentry *dentry)
{
return dentry_has_perm(current, NULL, dentry, FILE__READ);
@@ -4298,20 +4245,15 @@ static struct security_operations selinux_ops = {
.inode_alloc_security = selinux_inode_alloc_security,
.inode_free_security = selinux_inode_free_security,
+ .inode_init_security = selinux_inode_init_security,
.inode_create = selinux_inode_create,
- .inode_post_create = selinux_inode_post_create,
.inode_link = selinux_inode_link,
- .inode_post_link = selinux_inode_post_link,
.inode_unlink = selinux_inode_unlink,
.inode_symlink = selinux_inode_symlink,
- .inode_post_symlink = selinux_inode_post_symlink,
.inode_mkdir = selinux_inode_mkdir,
- .inode_post_mkdir = selinux_inode_post_mkdir,
.inode_rmdir = selinux_inode_rmdir,
.inode_mknod = selinux_inode_mknod,
- .inode_post_mknod = selinux_inode_post_mknod,
.inode_rename = selinux_inode_rename,
- .inode_post_rename = selinux_inode_post_rename,
.inode_readlink = selinux_inode_readlink,
.inode_follow_link = selinux_inode_follow_link,
.inode_permission = selinux_inode_permission,
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index b2676fa3463..6982556ded5 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -50,7 +50,7 @@ static struct midi_parms parms[MAX_MIDI_DEV];
static void midi_poll(unsigned long dummy);
-static struct timer_list poll_timer = TIMER_INITIALIZER(midi_poll, 0, 0);
+static DEFINE_TIMER(poll_timer, midi_poll, 0, 0);
static volatile int open_devs;
static DEFINE_SPINLOCK(lock);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index a686be936af..95fa81e26de 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -681,8 +681,7 @@ static void do_sequencer_timer(unsigned long dummy)
}
-static struct timer_list seq_timer =
- TIMER_INITIALIZER(do_sequencer_timer, 0, 0);
+static DEFINE_TIMER(seq_timer, do_sequencer_timer, 0, 0);
void request_sound_timer(int count)
{
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index 6afe29b763b..c9d04518b17 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -28,8 +28,7 @@ static unsigned long prev_event_time;
static void poll_def_tmr(unsigned long dummy);
static DEFINE_SPINLOCK(lock);
-
-static struct timer_list def_tmr = TIMER_INITIALIZER(poll_def_tmr, 0, 0);
+static DEFINE_TIMER(def_tmr, poll_def_tmr, 0, 0);
static unsigned long
tmr2ticks(int tmr_value)
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index be00cf12865..74ae75f9e2d 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);
static void poll_uart6850(unsigned long dummy);
-static struct timer_list uart6850_timer =
- TIMER_INITIALIZER(poll_uart6850, 0, 0);
+static DEFINE_TIMER(uart6850_timer, poll_uart6850, 0, 0);
static void uart6850_input_loop(void)
{
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 5aa5fe651a8..bfbec587665 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)
if (test_bit(i, &subs->active_mask)) {
if (! test_and_set_bit(i, &subs->unlink_mask)) {
struct urb *u = subs->dataurb[i].urb;
- if (async) {
- u->transfer_flags |= URB_ASYNC_UNLINK;
+ if (async)
usb_unlink_urb(u);
- } else
+ else
usb_kill_urb(u);
}
}
@@ -748,10 +747,9 @@ static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
if (test_bit(i+16, &subs->active_mask)) {
if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
struct urb *u = subs->syncurb[i].urb;
- if (async) {
- u->transfer_flags |= URB_ASYNC_UNLINK;
+ if (async)
usb_unlink_urb(u);
- } else
+ else
usb_kill_urb(u);
}
}